• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
2index ceaf87c4d..ea05aa4b4 100644
3--- a/arch/arm/Kconfig
4+++ b/arch/arm/Kconfig
5@@ -322,7 +322,7 @@ config ARCH_MULTIPLATFORM
6 	select ARCH_SELECT_MEMORY_MODEL
7 	select ARM_HAS_SG_CHAIN
8 	select ARM_PATCH_PHYS_VIRT
9-	select AUTO_ZRELADDR
10+	#select AUTO_ZRELADDR
11 	select TIMER_OF
12 	select COMMON_CLK
13 	select GENERIC_CLOCKEVENTS
14@@ -650,6 +650,8 @@ source "arch/arm/mach-highbank/Kconfig"
15
16 source "arch/arm/mach-hisi/Kconfig"
17
18+source "arch/arm/mach-hibvt/Kconfig"
19+
20 source "arch/arm/mach-imx/Kconfig"
21
22 source "arch/arm/mach-integrator/Kconfig"
23diff --git a/arch/arm/Makefile b/arch/arm/Makefile
24index cb7c6b02f..95308da9c 100644
25--- a/arch/arm/Makefile
26+++ b/arch/arm/Makefile
27@@ -182,6 +182,7 @@ machine-$(CONFIG_ARCH_FOOTBRIDGE)	+= footbridge
28 machine-$(CONFIG_ARCH_GEMINI)		+= gemini
29 machine-$(CONFIG_ARCH_HIGHBANK)		+= highbank
30 machine-$(CONFIG_ARCH_HISI)		+= hisi
31+machine-$(CONFIG_ARCH_HISI_BVT)		+= hibvt
32 machine-$(CONFIG_ARCH_INTEGRATOR)	+= integrator
33 machine-$(CONFIG_ARCH_IOP32X)		+= iop32x
34 machine-$(CONFIG_ARCH_IXP4XX)		+= ixp4xx
35@@ -270,6 +271,10 @@ KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs) $(platdirs))
36 endif
37 endif
38
39+ifeq ($(CONFIG_ARCH_HISI_BVT),y)
40+KBUILD_CPPFLAGS += $(patsubst %,-I$(srctree)/%include,$(machdirs) $(platdirs))
41+endif
42+
43 export	TEXT_OFFSET GZFLAGS MMUEXT
44
45 core-y				+= arch/arm/
46diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile
47index 0b3cd7a33..763d37e86 100644
48--- a/arch/arm/boot/Makefile
49+++ b/arch/arm/boot/Makefile
50@@ -16,6 +16,8 @@ OBJCOPYFLAGS	:=-O binary -R .comment -S
51 ifneq ($(MACHINE),)
52 include $(MACHINE)/Makefile.boot
53 endif
54+include $(srctree)/arch/arm/mach-hibvt/Makefile.boot
55+include $(srctree)/arch/arm/boot/dts/Makefile
56
57 # Note: the following conditions must always be true:
58 #   ZRELADDR == virt_to_phys(PAGE_OFFSET + TEXT_OFFSET)
59@@ -24,10 +26,12 @@ endif
60 ZRELADDR    := $(zreladdr-y)
61 PARAMS_PHYS := $(params_phys-y)
62 INITRD_PHYS := $(initrd_phys-y)
63+DTB_OBJS ?= $(dtb-y)
64+DTB_OBJS_FULL := $(addprefix $(obj)/dts/,$(DTB_OBJS))
65
66 export ZRELADDR INITRD_PHYS PARAMS_PHYS
67
68-targets := Image zImage xipImage bootpImage uImage
69+targets := Image zImage xipImage bootpImage uImage zImage-dtb
70
71 ifeq ($(CONFIG_XIP_KERNEL),y)
72
73@@ -66,6 +70,10 @@ $(obj)/compressed/vmlinux: $(obj)/Image FORCE
74 $(obj)/zImage:	$(obj)/compressed/vmlinux FORCE
75 	$(call if_changed,objcopy)
76
77+$(obj)/zImage-dtb:	$(obj)/zImage $(DTB_OBJS_FULL) FORCE
78+	@cat $(obj)/zImage $(DTB_OBJS_FULL) > $@
79+	@$(kecho) '  Kernel: $@ is ready'
80+
81 endif
82
83 ifneq ($(LOADADDR),)
84@@ -86,7 +94,7 @@ if [ $(words $(UIMAGE_LOADADDR)) -ne 1 ]; then \
85 	false; \
86 fi
87
88-$(obj)/uImage:	$(obj)/zImage FORCE
89+$(obj)/uImage:	$(obj)/zImage-dtb FORCE
90 	@$(check_for_multiple_loadaddr)
91 	$(call if_changed,uimage)
92
93diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
94index ce66ffd5a..a84efd2d6 100644
95--- a/arch/arm/boot/dts/Makefile
96+++ b/arch/arm/boot/dts/Makefile
97@@ -239,6 +239,10 @@ dtb-$(CONFIG_ARCH_HISI) += \
98 	hi3519-demb.dtb
99 dtb-$(CONFIG_ARCH_HIX5HD2) += \
100 	hisi-x5hd2-dkb.dtb
101+
102+dtb-$(CONFIG_ARCH_HI3516DV300) += \
103+	hi3516dv300-demb.dtb
104+
105 dtb-$(CONFIG_ARCH_INTEGRATOR) += \
106 	integratorap.dtb \
107 	integratorap-im-pd1.dtb \
108@@ -1408,3 +1412,4 @@ dtb-$(CONFIG_ARCH_ASPEED) += \
109 	aspeed-bmc-opp-zaius.dtb \
110 	aspeed-bmc-portwell-neptune.dtb \
111 	aspeed-bmc-quanta-q71l.dtb
112+
113diff --git a/arch/arm/boot/dts/hi3516dv300-demb.dts b/arch/arm/boot/dts/hi3516dv300-demb.dts
114new file mode 100644
115index 000000000..bbe67651e
116--- /dev/null
117+++ b/arch/arm/boot/dts/hi3516dv300-demb.dts
118@@ -0,0 +1,270 @@
119+/*
120+ * Copyright (c) 2013-2014 Linaro Ltd.
121+ * Copyright (c) 2015-2017 HiSilicon Technologies Co., Ltd.
122+ *
123+ * This program is free software; you can redistribute  it and/or modify it
124+ * under  the terms of  the GNU General  Public License as published by the
125+ * Free Software Foundation;  either version 2 of the  License, or (at your
126+ * option) any later version.
127+ *
128+ * This program is distributed in the hope that it will be useful,
129+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
130+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
131+ * GNU General Public License for more details.
132+ *
133+ * You should have received a copy of the GNU General Public License
134+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
135+ *
136+ */
137+
138+/dts-v1/;
139+#include "hi3516dv300.dtsi"
140+#include "autoconf.h"
141+
142+/ {
143+	model = "Hisilicon HI3516DV300 DEMO Board";
144+	compatible = "hisilicon,hi3516dv300";
145+
146+	memory {
147+		device_type = "memory";
148+		reg = <0x82000000 0x20000000>;
149+	};
150+	firmware {
151+		android {
152+			compatible = "android,firmware";
153+			fstab {
154+				compatible = "android,fstab";
155+				 // delete for system as root
156+				   /*system {
157+				   compatible = "android,system";
158+				   dev = "/dev/block/platform/soc/f9830000.himciv200.MMC/by-name/system";
159+				   type = "ext4";
160+				   mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
161+				   fsmgr_flags = "wait";
162+				   };*/
163+				vendor {
164+					compatible = "android,vendor";
165+					//dev = "mmcblk0p4";
166+					//dev = "/dev/block/by-name/vendor";
167+					//dev = "/dev/block/platform/soc/100f0000.eMMC/by-name/vendor";
168+					//dev = "/dev/block/platform/soc/10100000.eMMC/by-name/vendor";
169+					dev = "/dev/block/platform/soc/10100000.himci.eMMC/by-name/vendor";
170+					//dev = "/dev/block/platform/soc/100f0000.eMMC/mmcblk0p4";
171+				        //dev = "/dev/block/platform/soc/f9830000.himciv200.MMC/by-name/vendor";
172+					type = "ext4";
173+					mnt_flags = "ro,barrier=1,inode_readahead_blks=8";
174+					fsmgr_flags = "wait";
175+				};
176+			};
177+		};
178+	};
179+};
180+
181+&uart0 {
182+	status = "okay";
183+};
184+#ifndef CONFIG_ARCH_HISI_BVT_AMP
185+&uart1 {
186+	status = "okay";
187+};
188+
189+&i2c_bus0 {
190+    status = "okay";
191+    clock-frequency = <100000>;
192+};
193+
194+&i2c_bus1 {
195+    status = "okay";
196+    clock-frequency = <100000>;
197+};
198+
199+&i2c_bus2 {
200+    status = "okay";
201+    clock-frequency = <100000>;
202+};
203+
204+&i2c_bus3 {
205+    status = "okay";
206+    clock-frequency = <100000>;
207+};
208+
209+&i2c_bus4 {
210+    status = "okay";
211+    clock-frequency = <100000>;
212+};
213+
214+&i2c_bus5 {
215+    status = "okay";
216+    clock-frequency = <100000>;
217+};
218+
219+&i2c_bus6 {
220+    status = "okay";
221+    clock-frequency = <100000>;
222+};
223+
224+&i2c_bus7 {
225+    status = "okay";
226+    clock-frequency = <100000>;
227+};
228+
229+&spi_bus0{
230+    status = "okay";
231+    num-cs = <1>;
232+
233+    spidev@0 {
234+        compatible = "rohm,dh2228fv";
235+        reg = <0>;
236+        pl022,interface = <0>;
237+        pl022,com-mode = <0>;
238+        spi-max-frequency = <25000000>;
239+    };
240+};
241+&spi_bus1{
242+    status = "okay";
243+    num-cs = <2>;
244+
245+    spidev@0 {
246+        compatible = "rohm,dh2228fv";
247+        reg = <0>;
248+        pl022,interface = <0>;
249+        pl022,com-mode = <0>;
250+        spi-max-frequency = <25000000>;
251+    };
252+    spidev@1 {
253+        compatible = "rohm,dh2228fv";
254+        reg = <1>;
255+        pl022,interface = <0>;
256+        pl022,com-mode = <0>;
257+        spi-max-frequency = <25000000>;
258+    };
259+};
260+&spi_bus2{
261+    status = "okay";
262+    num-cs = <1>;
263+
264+    spidev@0 {
265+        compatible = "rohm,dh2228fv";
266+        reg = <0>;
267+        pl022,interface = <0>;
268+        pl022,com-mode = <0>;
269+        spi-max-frequency = <25000000>;
270+    };
271+};
272+#endif
273+
274+&mdio0 {
275+	hisilicon,phy-reset-delays-us = <10000 20000 150000>;
276+	phy0: ethernet-phy@1 {
277+		reg = <1>;
278+	};
279+};
280+
281+&hisi_femac0 {
282+	mac-address = [00 00 00 00 00 00];
283+	phy-mode = "rmii";
284+	phy-handle = <&phy0>;
285+	status = "okay";
286+};
287+
288+&hisfc {
289+	hi_sfc {
290+		   compatible = "jedec,spi-nor";
291+		   reg = <0>;
292+		   spi-max-frequency = <160000000>;
293+	};
294+};
295+
296+&hisnfc {
297+	hinand {
298+		   compatible = "jedec,spi-nand";
299+		   reg = <0>;
300+		   spi-max-frequency = <160000000>;
301+	};
302+};
303+
304+&mmc0 {
305+#ifdef CONFIG_MTD
306+	status = "disabled";
307+#else
308+	status = "okay";
309+#endif
310+};
311+
312+&mmc1 {
313+	status = "okay";
314+};
315+
316+&mmc2 {
317+	status = "okay";
318+};
319+
320+&watchdog {
321+        status = "okay";
322+};
323+
324+&pwm0 {
325+        status = "okay";
326+};
327+
328+&pwm1 {
329+        status = "okay";
330+};
331+
332+&hidmac {
333+	status = "disabled";
334+};
335+
336+#ifdef CONFIG_HIEDMACV310
337+&hiedmacv310_0 {
338+    status = "okay";
339+};
340+#endif
341+
342+&gpio_chip0 {
343+	status = "okay";
344+};
345+
346+&gpio_chip1 {
347+	status = "okay";
348+};
349+
350+&gpio_chip2 {
351+	status = "okay";
352+};
353+
354+&gpio_chip3 {
355+	status = "okay";
356+};
357+
358+&gpio_chip4 {
359+	status = "okay";
360+};
361+
362+&gpio_chip5 {
363+	status = "okay";
364+};
365+
366+&gpio_chip6 {
367+	status = "okay";
368+};
369+
370+&gpio_chip7 {
371+	status = "okay";
372+};
373+
374+&gpio_chip8 {
375+	status = "okay";
376+};
377+
378+&gpio_chip9 {
379+	status = "okay";
380+};
381+
382+&gpio_chip10 {
383+	status = "okay";
384+};
385+
386+&gpio_chip11 {
387+	status = "okay";
388+};
389diff --git a/arch/arm/boot/dts/hi3516dv300.dtsi b/arch/arm/boot/dts/hi3516dv300.dtsi
390new file mode 100644
391index 000000000..c58f5b1ad
392--- /dev/null
393+++ b/arch/arm/boot/dts/hi3516dv300.dtsi
394@@ -0,0 +1,906 @@
395+/*
396+ * Copyright (c) 2013-2014 Linaro Ltd.
397+ * Copyright (c) 2015-2017 HiSilicon Technologies Co., Ltd.
398+ *
399+ * This program is free software; you can redistribute  it and/or modify it
400+ * under  the terms of  the GNU General  Public License as published by the
401+ * Free Software Foundation;  either version 2 of the  License, or (at your
402+ * option) any later version.
403+ *
404+ * This program is distributed in the hope that it will be useful,
405+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
406+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
407+ * GNU General Public License for more details.
408+ *
409+ * You should have received a copy of the GNU General Public License
410+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
411+ *
412+ */
413+#include "autoconf.h"
414+#include "skeleton.dtsi"
415+#include "clock/hi3516dv300-clock.h"
416+/ {
417+	aliases {
418+		serial0 = &uart0;
419+#ifndef CONFIG_ARCH_HISI_BVT_AMP
420+		i2c0 = &i2c_bus0;
421+		i2c1 = &i2c_bus1;
422+		i2c2 = &i2c_bus2;
423+		i2c3 = &i2c_bus3;
424+#endif
425+		i2c4 = &i2c_bus4;
426+		i2c5 = &i2c_bus5;
427+		i2c6 = &i2c_bus6;
428+		i2c7 = &i2c_bus7;
429+#ifndef CONFIG_ARCH_HISI_BVT_AMP
430+		spi0 = &spi_bus0;
431+		spi1 = &spi_bus1;
432+		spi2 = &spi_bus2;
433+#endif
434+		gpio0 = &gpio_chip0;
435+		gpio1 = &gpio_chip1;
436+		gpio2 = &gpio_chip2;
437+		gpio3 = &gpio_chip3;
438+		gpio4 = &gpio_chip4;
439+		gpio5 = &gpio_chip5;
440+		gpio6 = &gpio_chip6;
441+		gpio7 = &gpio_chip7;
442+		gpio8 = &gpio_chip8;
443+		gpio9 = &gpio_chip9;
444+		gpio10 = &gpio_chip10;
445+		gpio11 = &gpio_chip11;
446+	};
447+
448+	cpus {
449+		#address-cells = <1>;
450+		#size-cells = <0>;
451+		enable-method = "hisilicon,hi3516dv300";
452+
453+		cpu@0 {
454+			device_type = "cpu";
455+			compatible = "arm,cortex-a7";
456+			clock-frequency = <HI3516DV300_FIXED_1000M>;
457+			reg = <0>;
458+		};
459+#ifndef CONFIG_ARCH_HISI_BVT_AMP
460+		cpu@1 {
461+			device_type = "cpu";
462+			compatible = "arm,cortex-a7";
463+			clock-frequency = <HI3516DV300_FIXED_1000M>;
464+			reg = <1>;
465+		};
466+#endif
467+	};
468+
469+	clock: clock@12010000 {
470+		compatible = "hisilicon,hi3516dv300-clock";
471+		#address-cells = <1>;
472+		#size-cells = <1>;
473+		#clock-cells = <1>;
474+		#reset-cells = <2>;
475+		reg = <0x12010000 0x1000>;
476+	};
477+
478+	gic: interrupt-controller@10300000 {
479+		compatible = "arm,cortex-a7-gic";
480+		#interrupt-cells = <3>;
481+		#address-cells = <0>;
482+		interrupt-controller;
483+		/* gic dist base, gic cpu base , no virtual support */
484+		reg = <0x10301000 0x1000>, <0x10302000 0x100>;
485+	 };
486+
487+	syscounter {
488+		compatible = "arm,armv7-timer";
489+		interrupt-parent = <&gic>;
490+		interrupts = <1 13 0xf08>,
491+			<1 14 0xf08>;
492+		clock-frequency = <50000000>;
493+	};
494+
495+	soc {
496+		#address-cells = <1>;
497+		#size-cells = <1>;
498+		compatible = "simple-bus";
499+		interrupt-parent = <&gic>;
500+		ranges;
501+
502+		clk_3m: clk_3m {
503+			compatible = "fixed-clock";
504+			#clock-cells = <0>;
505+			clock-frequency = <3000000>;
506+		};
507+
508+		clk_apb: clk_apb {
509+			compatible = "fixed-clock";
510+			#clock-cells = <0>;
511+			clock-frequency = <50000000>;
512+		};
513+
514+		pmu {
515+			compatible = "arm,cortex-a7-pmu";
516+			interrupts = <0 54 4>;
517+		};
518+#ifdef CONFIG_HIEDMACV310
519+        hiedmacv310_0: hiedma-controller@10060000 {
520+			compatible = "hisilicon,hiedmacv310";
521+			reg = <0x10060000 0x1000>;
522+			interrupts = <0 28 4>;
523+			clocks = <&clock HI3516DV300_DMAC_CLK>, <&clock HI3516DV300_DMAC_AXICLK>;
524+			clock-names = "apb_pclk", "axi_aclk";
525+			#clock-cells = <2>;
526+			resets = <&clock 0x194 0>;
527+			reset-names = "dma-reset";
528+			dma-requests = <32>;
529+			dma-channels = <8>;
530+			devid = <0>;
531+			#dma-cells = <2>;
532+			status = "disabled";
533+		};
534+#endif
535+#ifdef CONFIG_HIEDMAC
536+        hiedmacv310_0: hiedma-controller@10060000 {
537+			compatible = "hisilicon,hiedmacv310_n";
538+			reg = <0x10060000 0x1000>;
539+			interrupts = <0 28 4>;
540+			clocks = <&clock HI3516DV300_DMAC_CLK>, <&clock HI3516DV300_DMAC_AXICLK>;
541+			clock-names = "apb_pclk", "axi_aclk";
542+			#clock-cells = <2>;
543+			resets = <&clock 0x194 0>;
544+			reset-names = "dma-reset";
545+			dma-requests = <32>;
546+			dma-channels = <8>;
547+			devid = <0>;
548+			#dma-cells = <2>;
549+			status = "disabled";
550+		};
551+#endif
552+
553+		sysctrl: system-controller@12020000 {
554+			compatible = "hisilicon,sysctrl";
555+			reg = <0x12020000 0x1000>;
556+			reboot-offset = <0x4>;
557+			#clock-cells = <1>;
558+		};
559+
560+		amba {
561+			#address-cells = <1>;
562+			#size-cells = <1>;
563+			compatible = "arm,amba-bus";
564+			ranges;
565+
566+			timer@hisp804 {
567+				compatible = "hisilicon,hisp804";
568+				/* timer0 & timer1 & timer2 */
569+				reg = <0x12000000 0x20>, /* clocksource */
570+					<0x12000020 0x20>, /* local timer for each cpu */
571+					<0x12001000 0x20>;
572+				interrupts = <0 1 4>, /* irq of local timer */
573+					<0 2 4>;
574+				clocks = <&clock HI3516DV300_FIXED_3M>,
575+					<&clock HI3516DV300_FIXED_3M>,
576+					<&clock HI3516DV300_FIXED_3M>;
577+				clock-names = "timer0", "timer1", "timer2";
578+			};
579+
580+			dual_timer2: dual_timer@12002000 {
581+				compatible = "arm,sp804", "arm,primecell";
582+				/* timer4 & timer5 */
583+				interrupts = <0 3 4>;
584+				reg = <0x12002000 0x1000>;
585+				clocks = <&clk_3m>, <&clk_3m>, <&clk_apb>;
586+				clock-names = "timer20", "timer21", "apb_pclk";
587+				status = "disabled";
588+			};
589+
590+			watchdog: watchdog@12051000 {
591+                                compatible = "arm,sp805-wdt", "arm,primecell";
592+                                arm,primecell-periphid = <0x00141805>;
593+                                reg = <0x12051000 0x1000>;
594+                                clocks = <&clk_3m>,<&clk_apb>;
595+                                clock-names = "wdog_clk", "apb_pclk";
596+                                status = "disabled";
597+                        };
598+
599+			uart0: uart@120a0000 {
600+				compatible = "arm,pl011", "arm,primecell";
601+				reg = <0x120a0000 0x1000>;
602+				interrupts = <0 6 4>;
603+				clocks = <&clock HI3516DV300_UART0_CLK>;
604+				clock-names = "apb_pclk";
605+				status = "disabled";
606+			};
607+#ifndef CONFIG_ARCH_HISI_BVT_AMP
608+			uart1: uart@120a1000 {
609+				compatible = "arm,pl011", "arm,primecell";
610+				reg = <0x120a1000 0x1000>;
611+				interrupts = <0 7 4>;
612+				clocks = <&clock HI3516DV300_UART1_CLK>;
613+				clock-names = "apb_pclk";
614+#ifdef CONFIG_HIEDMACV310
615+				dmas = <&hiedmacv310_0 19 19>, <&hiedmacv310_0 18 18>;
616+				dma-names = "tx","rx";
617+#endif
618+				status = "disabled";
619+			};
620+#endif
621+			uart2: uart@120a2000 {
622+				compatible = "arm,pl011", "arm,primecell";
623+				reg = <0x120a2000 0x1000>;
624+				interrupts = <0 8 4>;
625+				clocks = <&clock HI3516DV300_UART2_CLK>;
626+				clock-names = "apb_pclk";
627+#ifdef CONFIG_HIEDMACV310
628+				dmas = <&hiedmacv310_0 21 21>, <&hiedmacv310_0 20 20>;
629+				dma-names = "tx","rx";
630+#endif
631+				status = "disabled";
632+			};
633+
634+            uart3: uart@120a3000 {
635+				compatible = "arm,pl011", "arm,primecell";
636+				reg = <0x120a3000 0x1000>;
637+				interrupts = <0 9 4>;
638+				clocks = <&clock HI3516DV300_UART3_CLK>;
639+				clock-names = "apb_pclk";
640+#ifdef CONFIG_HIEDMACV310
641+				dmas = <&hiedmacv310_0 23 23>, <&hiedmacv310_0 22 22>;
642+				dma-names = "tx","rx";
643+#endif
644+				status = "disabled";
645+			};
646+
647+            uart4: uart@120a4000 {
648+				compatible = "arm,pl011", "arm,primecell";
649+				reg = <0x120a4000 0x1000>;
650+				interrupts = <0 10 4>;
651+				clocks = <&clock HI3516DV300_UART4_CLK>;
652+				clock-names = "apb_pclk";
653+#ifdef CONFIG_HIEDMACV310
654+				dmas = <&hiedmacv310_0 25 25>, <&hiedmacv310_0 24 24>;
655+				dma-names = "tx","rx";
656+#endif
657+				status = "disabled";
658+			};
659+
660+		};
661+
662+#ifndef CONFIG_ARCH_HISI_BVT_AMP
663+		i2c_bus0: i2c@120b0000 {
664+			compatible = "hisilicon,hibvt-i2c";
665+			reg = <0x120b0000 0x1000>;
666+			clocks = <&clock HI3516DV300_I2C0_CLK>;
667+#ifdef CONFIG_HIEDMAC
668+				dmas = <&hiedmacv310_0 1 1>, <&hiedmacv310_0 0 0>;
669+				dma-names = "tx","rx";
670+#endif
671+			status = "disabled";
672+		};
673+
674+		i2c_bus1: i2c@120b1000 {
675+			compatible = "hisilicon,hibvt-i2c";
676+			reg = <0x120b1000 0x1000>;
677+			clocks = <&clock HI3516DV300_I2C1_CLK>;
678+#ifdef CONFIG_HIEDMAC
679+				dmas = <&hiedmacv310_0 3 3>, <&hiedmacv310_0 2 2>;
680+				dma-names = "tx","rx";
681+#endif
682+			status = "disabled";
683+		};
684+
685+		i2c_bus2: i2c@120b2000 {
686+			compatible = "hisilicon,hibvt-i2c";
687+			reg = <0x120b2000 0x1000>;
688+			clocks = <&clock HI3516DV300_I2C2_CLK>;
689+#ifdef CONFIG_HIEDMAC
690+				dmas = <&hiedmacv310_0 5 5>, <&hiedmacv310_0 4 4>;
691+				dma-names = "tx","rx";
692+#endif
693+			status = "disabled";
694+		};
695+
696+		i2c_bus3: i2c@120b3000 {
697+			compatible = "hisilicon,hibvt-i2c";
698+			reg = <0x120b3000 0x1000>;
699+			clocks = <&clock HI3516DV300_I2C3_CLK>;
700+#ifdef CONFIG_HIEDMAC
701+				dmas = <&hiedmacv310_0 7 7>, <&hiedmacv310_0 6 6>;
702+				dma-names = "tx","rx";
703+#endif
704+			status = "disabled";
705+		};
706+#endif
707+		i2c_bus4: i2c@120b4000 {
708+			compatible = "hisilicon,hibvt-i2c";
709+			reg = <0x120b4000 0x1000>;
710+			clocks = <&clock HI3516DV300_I2C4_CLK>;
711+#ifdef CONFIG_HIEDMAC
712+				dmas = <&hiedmacv310_0 9 9>, <&hiedmacv310_0 8 8>;
713+				dma-names = "tx","rx";
714+#endif
715+			status = "disabled";
716+		};
717+		i2c_bus5: i2c@120b5000 {
718+			compatible = "hisilicon,hibvt-i2c";
719+			reg = <0x120b5000 0x1000>;
720+			clocks = <&clock HI3516DV300_I2C5_CLK>;
721+#ifdef CONFIG_HIEDMAC
722+				dmas = <&hiedmacv310_0 11 11>, <&hiedmacv310_0 10 10>;
723+				dma-names = "tx","rx";
724+#endif
725+			status = "disabled";
726+		};
727+
728+		i2c_bus6: i2c@120b6000 {
729+			compatible = "hisilicon,hibvt-i2c";
730+			reg = <0x120b6000 0x1000>;
731+			clocks = <&clock HI3516DV300_I2C6_CLK>;
732+#ifdef CONFIG_HIEDMAC
733+				dmas = <&hiedmacv310_0 13 13>, <&hiedmacv310_0 12 12>;
734+				dma-names = "tx","rx";
735+#endif
736+			status = "disabled";
737+		};
738+
739+		i2c_bus7: i2c@120b7000 {
740+			compatible = "hisilicon,hibvt-i2c";
741+			reg = <0x120b7000 0x1000>;
742+			clocks = <&clock HI3516DV300_I2C7_CLK>;
743+#ifdef CONFIG_HIEDMAC
744+				dmas = <&hiedmacv310_0 15 15>, <&hiedmacv310_0 14 14>;
745+				dma-names = "tx","rx";
746+#endif
747+			status = "disabled";
748+		};
749+
750+#ifndef CONFIG_ARCH_HISI_BVT_AMP
751+        spi_bus0: spi@120c0000 {
752+            compatible = "arm,pl022", "arm,primecell";
753+            arm,primecell-periphid = <0x00800022>;
754+            reg = <0x120c0000 0x1000>;
755+            interrupts = <0 68 4>;
756+            clocks = <&clock HI3516DV300_SPI0_CLK>;
757+            clock-names = "apb_pclk";
758+            #address-cells = <1>;
759+            #size-cells = <0>;
760+#ifdef CONFIG_HIEDMACV310
761+            dmas = <&hiedmacv310_0 27 27>, <&hiedmacv310_0 26 26>;
762+            dma-names = "tx","rx";
763+#endif
764+            status = "disabled";
765+        };
766+
767+        spi_bus1: spi@120c1000 {
768+            compatible = "arm,pl022", "arm,primecell";
769+            arm,primecell-periphid = <0x00800022>;
770+            reg = <0x120c1000 0x1000>, <0x12030000 0x4>;
771+            interrupts = <0 69 4>;
772+            clocks = <&clock HI3516DV300_SPI1_CLK>;
773+            clock-names = "apb_pclk";
774+            #address-cells = <1>;
775+            #size-cells = <0>;
776+            num-cs = <2>;
777+            hisi,spi_cs_sb = <2>;
778+            hisi,spi_cs_mask_bit = <0x4>;//0100
779+#ifdef CONFIG_HIEDMACV310
780+            dmas = <&hiedmacv310_0 29 29>, <&hiedmacv310_0 28 28>;
781+            dma-names = "tx","rx";
782+#endif
783+            status = "disabled";
784+        };
785+
786+        spi_bus2: spi@120c2000 {
787+            compatible = "arm,pl022", "arm,primecell";
788+            arm,primecell-periphid = <0x00800022>;
789+            reg = <0x120c2000 0x1000>;
790+            interrupts = <0 70 4>;
791+            clocks = <&clock HI3516DV300_SPI2_CLK>;
792+            clock-names = "apb_pclk";
793+            #address-cells = <1>;
794+            #size-cells = <0>;
795+#ifdef CONFIG_HIEDMACV310
796+            dmas = <&hiedmacv310_0 31 31>, <&hiedmacv310_0 30 30>;
797+            dma-names = "tx","rx";
798+#endif
799+            status = "disabled";
800+        };
801+#endif
802+
803+        ipcm: ipcm@045E0000 {
804+            compatible = "hisilicon,ipcm-interrupt";
805+            interrupt-parent = <&gic>;
806+            interrupts = <0 10 4>;
807+            reg = <0x10300000 0x4000>;
808+            status = "okay";
809+        };
810+
811+		mdio0: mdio@10011100 {
812+			compatible = "hisilicon,hisi-femac-mdio";
813+			reg = <0x10011100 0x10>;
814+			clocks = <&clock HI3516DV300_ETH0_CLK>;
815+			clock-names = "mdio";
816+			assigned-clocks = <&clock HI3516DV300_ETH0_CLK>;
817+			assigned-clock-rates = <54000000>;
818+			resets = <&clock 0x16c 3>;
819+			reset-names = "external-phy";
820+			#address-cells = <1>;
821+			#size-cells = <0>;
822+		};
823+
824+		hisi_femac0: ethernet@10010000 {
825+			compatible = "hisilicon,hi3516dv300-femac",
826+				"hisilicon,hisi-femac-v2";
827+			reg = <0x10010000 0x1000>,<0x10011300 0x200>;
828+			interrupts = <0 32 4>;
829+			clocks = <&clock HI3516DV300_ETH0_CLK>;
830+			resets = <&clock 0x16c 0>;
831+			reset-names = "mac";
832+		};
833+
834+		fmc: flash-memory-controller@10000000 {
835+			compatible = "hisilicon,hisi-fmc";
836+			reg = <0x10000000 0x1000>, <0x14000000 0x10000>;
837+			reg-names = "control", "memory";
838+			clocks = <&clock HI3516DV300_FMC_CLK>;
839+			max-dma-size = <0x2000>;
840+			#address-cells = <1>;
841+			#size-cells = <0>;
842+
843+			hisfc:spi-nor@0 {
844+					compatible = "hisilicon,fmc-spi-nor";
845+					assigned-clocks = <&clock HI3516DV300_FMC_CLK>;
846+					assigned-clock-rates = <24000000>;
847+					#address-cells = <1>;
848+					#size-cells = <0>;
849+			};
850+
851+			hisnfc:spi-nand@0 {
852+					compatible = "hisilicon,fmc-spi-nand";
853+					assigned-clocks = <&clock HI3516DV300_FMC_CLK>;
854+					assigned-clock-rates = <24000000>;
855+					#address-cells = <1>;
856+					#size-cells = <0>;
857+			};
858+		};
859+
860+		mmc0: himci.eMMC@0x10100000 {
861+			compatible = "hisilicon,hi3516dv300-himci";
862+			reg = <0x10100000 0x1000>;
863+			interrupts = <0 64 4>;
864+			clocks = <&clock HI3516DV300_MMC0_CLK>;
865+			clock-names = "mmc_clk";
866+			resets = <&clock 0x148 0>;
867+			reset-names = "mmc_reset";
868+			max-frequency = <100000000>;
869+			bus-width = <4>;
870+			cap-mmc-highspeed;
871+			cap-mmc-hw-reset;
872+			devid = <0>;
873+			status = "disabled";
874+		};
875+
876+		mmc1: himci.SD@0x100f0000 {
877+			compatible = "hisilicon,hi3516dv300-himci";
878+			reg = <0x100f0000 0x1000>;
879+			interrupts = <0 30 4>;
880+			clocks = <&clock HI3516DV300_MMC1_CLK>;
881+			clock-names = "mmc_clk";
882+			resets = <&clock 0x160 0>;
883+			reset-names = "mmc_reset";
884+			max-frequency = <100000000>;
885+			bus-width = <4>;
886+			cap-sd-highspeed;
887+			sd-uhs-sdr12;
888+			sd-uhs-sdr25;
889+			sd-uhs-sdr50;
890+			sd-uhs-sdr104;
891+			full-pwr-cycle;
892+			devid = <1>;
893+			status = "disabled";
894+		};
895+
896+		mmc2: himci.SD@0x10020000 {
897+			compatible = "hisilicon,hi3516dv300-himci";
898+			reg = <0x10020000 0x1000>;
899+			interrupts = <0 31 4>;
900+			clocks = <&clock HI3516DV300_MMC2_CLK>;
901+			clock-names = "mmc_clk";
902+			resets = <&clock 0x154 0>;
903+			reset-names = "mmc_reset";
904+			max-frequency = <100000000>;
905+			bus-width = <4>;
906+			cap-sd-highspeed;
907+			cap-sdio-irq;
908+			full-pwr-cycle;
909+			devid = <2>;
910+			status = "disabled";
911+		};
912+
913+		hidmac: hidma-controller@10060000 {
914+			compatible = "hisilicon,hisi-dmac";
915+			reg = <0x10060000 0x1000>;
916+			interrupts = <0 28 4>;
917+			clocks = <&clock HI3516DV300_DMAC_CLK>;
918+			clock-names = "dmac_clk";
919+			resets = <&clock 0xc8 4>;
920+			reset-names = "dma-reset";
921+			#dma-cells = <2>;
922+			status = "disabled";
923+		};
924+
925+		usb_phy: phy {
926+			compatible = "hisilicon,hisi-usb-phy";
927+			reg = <0x12010000 0x1000>;
928+			#phy-cells = <0>;
929+		};
930+
931+#ifdef CONFIG_USB_DRD0_IN_HOST
932+		xhci_0@0x100e0000 {
933+			compatible = "generic-xhci";
934+			reg = <0x100e0000 0x10000>;
935+			interrupts = <0 27 4>;
936+			usb2-lpm-disable;
937+		};
938+#endif
939+#ifdef CONFIG_USB_DRD0_IN_DEVICE
940+		hidwc3_0@0x100e0000 {
941+			compatible = "snps,dwc3";
942+			reg = <0x100e0000 0x10000>;
943+			interrupts = <0 27 4>;
944+			interrupt-names = "peripheral";
945+			maximum-speed = "high-speed";
946+			dr_mode = "otg";
947+		};
948+#endif
949+		gpio_chip0: gpio_chip@120d0000 {
950+			compatible = "arm,pl061", "arm,primecell";
951+			reg = <0x120d0000 0x1000>;
952+			interrupts = <0 16 4>;
953+			clocks = <&clock  HI3516DV300_SYSAPB_CLK>;
954+			clock-names = "apb_pclk";
955+			#gpio-cells = <2>;
956+			status = "disabled";
957+		};
958+
959+		gpio_chip1: gpio_chip@120d1000 {
960+			compatible = "arm,pl061", "arm,primecell";
961+			reg = <0x120d1000 0x1000>;
962+			interrupts = <0 17 4>;
963+			clocks = <&clock  HI3516DV300_SYSAPB_CLK>;
964+			clock-names = "apb_pclk";
965+			#gpio-cells = <2>;
966+			status = "disabled";
967+		};
968+
969+		gpio_chip2: gpio_chip@120d2000 {
970+			compatible = "arm,pl061", "arm,primecell";
971+			reg = <0x120d2000 0x1000>;
972+			interrupts = <0 18 4>;
973+			clocks = <&clock  HI3516DV300_SYSAPB_CLK>;
974+			clock-names = "apb_pclk";
975+			#gpio-cells = <2>;
976+			status = "disabled";
977+		};
978+
979+		gpio_chip3: gpio_chip@120d3000 {
980+			compatible = "arm,pl061", "arm,primecell";
981+			reg = <0x120d3000 0x1000>;
982+			interrupts = <0 19 4>;
983+			clocks = <&clock  HI3516DV300_SYSAPB_CLK>;
984+			clock-names = "apb_pclk";
985+			#gpio-cells = <2>;
986+			status = "disabled";
987+		};
988+
989+		gpio_chip4: gpio_chip@120d4000 {
990+			compatible = "arm,pl061", "arm,primecell";
991+			reg = <0x120d4000 0x1000>;
992+			interrupts = <0 20 4>;
993+			clocks = <&clock  HI3516DV300_SYSAPB_CLK>;
994+			clock-names = "apb_pclk";
995+			#gpio-cells = <2>;
996+			status = "disabled";
997+		};
998+
999+		gpio_chip5: gpio_chip@120d5000 {
1000+			compatible = "arm,pl061", "arm,primecell";
1001+			reg = <0x120d5000 0x1000>;
1002+			interrupts = <0 21 4>;
1003+			clocks = <&clock  HI3516DV300_SYSAPB_CLK>;
1004+			clock-names = "apb_pclk";
1005+			#gpio-cells = <2>;
1006+			status = "disabled";
1007+		};
1008+
1009+		gpio_chip6: gpio_chip@120d6000 {
1010+			compatible = "arm,pl061", "arm,primecell";
1011+			reg = <0x120d6000 0x1000>;
1012+			interrupts = <0 22 4>;
1013+			clocks = <&clock  HI3516DV300_SYSAPB_CLK>;
1014+			clock-names = "apb_pclk";
1015+			#gpio-cells = <2>;
1016+			status = "disabled";
1017+		};
1018+
1019+		gpio_chip7: gpio_chip@120d7000 {
1020+			compatible = "arm,pl061", "arm,primecell";
1021+			reg = <0x120d7000 0x1000>;
1022+			interrupts = <0 23 4>;
1023+			clocks = <&clock  HI3516DV300_SYSAPB_CLK>;
1024+			clock-names = "apb_pclk";
1025+			#gpio-cells = <2>;
1026+			status = "disabled";
1027+		};
1028+
1029+		gpio_chip8: gpio_chip@120d8000 {
1030+			compatible = "arm,pl061", "arm,primecell";
1031+			reg = <0x120d8000 0x1000>;
1032+			interrupts = <0 24 4>;
1033+			clocks = <&clock  HI3516DV300_SYSAPB_CLK>;
1034+			clock-names = "apb_pclk";
1035+			#gpio-cells = <2>;
1036+			status = "disabled";
1037+		};
1038+
1039+		gpio_chip9: gpio_chip@120d9000 {
1040+			compatible = "arm,pl061", "arm,primecell";
1041+			reg = <0x120d9000 0x1000>;
1042+			interrupts = <0 25 4>;
1043+			clocks = <&clock  HI3516DV300_SYSAPB_CLK>;
1044+			clock-names = "apb_pclk";
1045+			#gpio-cells = <2>;
1046+			status = "disabled";
1047+		};
1048+
1049+		gpio_chip10: gpio_chip@120da000 {
1050+			compatible = "arm,pl061", "arm,primecell";
1051+			reg = <0x120da000 0x1000>;
1052+			interrupts = <0 26 4>;
1053+			clocks = <&clock  HI3516DV300_SYSAPB_CLK>;
1054+			clock-names = "apb_pclk";
1055+			#gpio-cells = <2>;
1056+			status = "disabled";
1057+		};
1058+
1059+		gpio_chip11: gpio_chip@120db000 {
1060+			compatible = "arm,pl061", "arm,primecell";
1061+			reg = <0x120db000 0x1000>;
1062+			interrupts = <0 80 4>;
1063+			clocks = <&clock  HI3516DV300_SYSAPB_CLK>;
1064+			clock-names = "apb_pclk";
1065+			#gpio-cells = <2>;
1066+			status = "disabled";
1067+		};
1068+
1069+		cipher: cipher@0x100c0000 {
1070+			compatible = "hisilicon,hisi-cipher";
1071+			reg = <0x100c0000 0x10000>;
1072+			reg-names = "cipher";
1073+			interrupts = <0 71 4>, <0 72 4>, <0 71 4>, <0 72 4>;
1074+			interrupt-names = "cipher", "nonsec_cipher", "hash", "nonsec_hash";
1075+		};
1076+
1077+	};
1078+
1079+        hidrm {
1080+            compatible = "hisilicon,hi-drm";
1081+        };
1082+
1083+	media {
1084+		#address-cells = <1>;
1085+		#size-cells = <1>;
1086+		compatible = "simple-bus";
1087+		interrupt-parent = <&gic>;
1088+		ranges;
1089+
1090+		osal: osal {
1091+			compatible = "hisilicon,osal";
1092+		};
1093+
1094+		sys_config: sys_config {
1095+                        compatible = "hisilicon,sys_config";
1096+                };
1097+
1098+		sys: sys@12010000 {
1099+			compatible = "hisilicon,hisi-sys";
1100+			reg = <0x12010000 0x10000>, <0x12020000 0x8000>,
1101+				<0x12060000 0x10000>, <0x12030000 0x8000>;
1102+			reg-names = "crg", "sys", "ddr", "misc";
1103+		};
1104+
1105+		mipi: mipi@113a0000 {
1106+			compatible = "hisilicon,hisi-mipi";
1107+			reg = <0x113a0000 0x10000>;
1108+			reg-names = "mipi_rx";
1109+			interrupts = <0 57 4>;
1110+			interrupt-names = "mipi_rx";
1111+		};
1112+
1113+		mipi_tx: mipi_tx@11270000 {
1114+			compatible = "hisilicon,hisi-mipi_tx";
1115+			reg = <0x11270000 0x10000>;
1116+			reg-names = "mipi_tx";
1117+			interrupts = <0 63 4>;
1118+			interrupt-names = "mipi_tx";
1119+		};
1120+
1121+		vi: vi@11300000 {
1122+			compatible = "hisilicon,hisi-vi";
1123+			reg = <0x11300000 0xa0000>, <0x11000000 0x40000>;
1124+			reg-names = "VI_CAP0", "VI_PROC0";
1125+			interrupts = <0 56 4>, <0 44 4>;
1126+			interrupt-names = "VI_CAP0", "VI_PROC0";
1127+		};
1128+
1129+		isp: isp@11020000 {
1130+		 compatible = "hisilicon,hisi-isp";
1131+		 reg = <0x11020000 0x20000>;
1132+		 reg-names = "ISP";
1133+		 interrupts = <0 56 4>;
1134+		 interrupt-names = "ISP";
1135+		};
1136+
1137+		vpss: vpss@11040000 {
1138+			compatible = "hisilicon,hisi-vpss";
1139+			reg = <0x11040000 0x10000>;
1140+			reg-names = "vpss0";
1141+			interrupts = <0 43 4>;
1142+			interrupt-names = "vpss0";
1143+		};
1144+
1145+		vgs: vgs@11240000 {
1146+			compatible = "hisilicon,hisi-vgs";
1147+			reg = <0x11240000 0x10000>;
1148+			reg-names = "vgs0";
1149+			interrupts = <0 38 4>;
1150+			interrupt-names = "vgs0";
1151+		};
1152+
1153+		vo: vo@11440000 {
1154+			compatible = "hisilicon,hisi-vo";
1155+			reg = <0x11440000 0x40000>;
1156+			reg-names = "vo";
1157+			interrupts = <0 58 4>;
1158+			interrupt-names = "vo";
1159+		};
1160+
1161+		hifb: hifb@11440000 {
1162+			compatible = "hisilicon,hisi-hifb";
1163+			reg = <0x11440000 0x40000>, <0x12020000 0x8000>;
1164+			reg-names = "hifb", "sys";
1165+			interrupts = <0 59 4>, <0 51 4>;
1166+			interrupt-names = "hifb", "hifb_soft";
1167+		};
1168+
1169+		tde: tde@11210000 {
1170+			compatible = "hisilicon,hisi-tde";
1171+			reg = <0x11210000 0x10000>;
1172+			reg-names = "tde";
1173+			interrupts = <0 35 4>;
1174+			interrupt-names = "tde_osr_isr";
1175+		};
1176+
1177+		gyro_dis: gyro {
1178+			compatible = "hisilicon,hisi-gyro-dis";
1179+		};
1180+
1181+		gdc: gdc@11110000 {
1182+			compatible = "hisilicon,hisi-gdc";
1183+			reg = <0x11110000 0x10000>, <0x11100000 0x10000>;
1184+			reg-names = "gdc", "nnie0";
1185+			interrupts = <0 42 4>, <0 41 4>;
1186+			interrupt-names = "gdc", "nnie0";
1187+		};
1188+
1189+		gzip: gzip@11200000 {
1190+			compatible = "hisilicon,hisi-gzip";
1191+			reg = <0x11200000 0x10000>;
1192+			reg-names = "gzip";
1193+			interrupts = <0 34 4>;
1194+			interrupt-names = "gzip";
1195+		};
1196+
1197+		jpegd: jpegd@11260000 {
1198+			compatible = "hisilicon,hisi-jpegd";
1199+			reg = <0x11260000 0x10000>;
1200+			reg-names = "jpegd";
1201+			interrupts = <0 45 4>;
1202+			interrupt-names = "jpegd";
1203+		};
1204+
1205+		vedu: vedu@11500000 {
1206+			compatible = "hisilicon,hisi-vedu";
1207+			reg = <0x11500000 0x10000>, <0x11220000 0x10000>;
1208+			reg-names = "vedu0", "jpge";
1209+			interrupts = <0 40 4>, <0 36 4>;
1210+			interrupt-names = "vedu0","jpge";
1211+		};
1212+
1213+		venc: venc {
1214+                        compatible = "hisilicon,hisi-venc";
1215+                };
1216+
1217+		scd: scd@10030000 {
1218+			compatible = "hisilicon,hisi-scd";
1219+			reg = <0x10030000 0x10000>;
1220+			reg-names = "scd";
1221+			interrupts = <0 67 4>;
1222+			interrupt-names = "scd";
1223+		};
1224+
1225+		hdmi: hdmi@11400000 {
1226+			compatible = "hisilicon,hisi-hdmi";
1227+			reg = <0x11400000 0x30000>;
1228+			reg-names = "hdmi0";
1229+		};
1230+
1231+		aiao: aiao@113b0000 {
1232+			compatible = "hisilicon,hisi-aiao";
1233+			reg = <0x113b0000 0x10000>,<0x113c0000 0x10000>,<0x12010000 0x10000>;
1234+			reg-names = "aiao","acodec","crg";
1235+			interrupts = <0 55 4>;
1236+			interrupt-names = "AIO";
1237+		};
1238+
1239+		nnie: nnie@11100000 {
1240+			compatible = "hisilicon,hisi-nnie";
1241+			reg = <0x11100000 0x10000>,<0x11110000 0x10000>;
1242+			reg-names = "nnie0","gdc";
1243+			interrupts = <0 41 4>,<0 42 4>;
1244+			interrupt-names = "nnie0","gdc";
1245+		};
1246+
1247+		ive: ive@11230000 {
1248+			compatible = "hisilicon,hisi-ive";
1249+			reg = <0x11230000 0x10000>;
1250+			reg-names = "ive";
1251+			interrupts = <0 37 4>;
1252+			interrupt-names = "ive";
1253+		};
1254+
1255+		adc: adc@120e0000 {
1256+	     		compatible = "hisilicon,hisi-lsadc";
1257+	     		reg = <0x120e0000 0x1000>;
1258+	     		interrupts = <0 65 4>;
1259+	     		resets = <&clock 0x1bc 2>;
1260+	     		reset-names = "lsadc-crg";
1261+	     		status = "disabled";
1262+     		};
1263+		ir: ir@120f0000 {
1264+	        	compatible = "hisilicon,hi_ir";
1265+	        	reg = <0x120f0000 0x1000>;
1266+	        	interrupts = <0 75 4>;
1267+	        };
1268+
1269+		rtc: rtc@12080000 {
1270+			compatible = "hisilicon,hi35xx-rtc";
1271+			reg = <0x12080000 0x1000>;
1272+			interrupts = <0 5 4>;
1273+		};
1274+
1275+		wdg: wdg@12050000 {
1276+			compatible = "hisilicon,hi_wdg";
1277+			reg = <0x12050000 0x1000>;
1278+		};
1279+		pwm0: pwm@12070000 {
1280+			compatible = "hisilicon,pwm";
1281+			reg = <0x12070000 0x20>;
1282+			clocks = <&clock HI3516DV300_PWM_CLK>;
1283+			resets = <&clock 0x1bc 6>;
1284+		};
1285+		pwm1: pwm@12070020 {
1286+			compatible = "hisilicon,pwm";
1287+			reg = <0x12070020 0x20>;
1288+			clocks = <&clock HI3516DV300_PWM_CLK>;
1289+			resets = <&clock 0x1bc 6>;
1290+		};
1291+
1292+		irq: irq@120f0000 {
1293+	        	compatible = "hisilicon,hi_irq";
1294+				reg = <0x11240000 0x10000>,<0x11040000 0x10000>,<0x10030000 0x10000>,<0x113b0000 0x10000>,<0x113c0000 0x10000>,<0x12010000 0x10000>,<0x11500000 0x10000>, <0x11220000 0x10000>,<0x11440000 0x40000>,<0x11300000 0xa0000>, <0x11000000 0x40000>;
1295+			    reg-names =    "vgs",              "vpss0",       "scd",               "aiao",              "acodec",            "crg",                "vedu0",             "jpge",              "vo",                "VI_CAP0",            "VI_PROC0";
1296+				interrupts = <0 67 4>,<0 26 4>,<0 56 4>, <0 44 4>,<0 43 4>,<0 38 4>,<0 58 4>,<0 40 4>,<0 36 4>,<0 37 4>,<0 41 4>,<0 42 4>,<0 56 4>,<0 45 4>,<0 55 4>;
1297+				interrupt-names = "scd","new", "VI_CAP0", "VI_PROC0","vpss0","vgs0", "vo",   "vedu0",  "jpge", "ive",   "nnie0",  "gdc",  "ISP",   "jpegd" ,"AIO";
1298+	        };
1299+	};
1300+};
1301diff --git a/arch/arm/boot/dts/skeleton.dtsi b/arch/arm/boot/dts/skeleton.dtsi
1302new file mode 100644
1303index 000000000..34eda68d9
1304--- /dev/null
1305+++ b/arch/arm/boot/dts/skeleton.dtsi
1306@@ -0,0 +1,18 @@
1307+// SPDX-License-Identifier: GPL-2.0
1308+/*
1309+ * This file is deprecated, and will be removed once existing users have been
1310+ * updated. New dts{,i} files should *not* include skeleton.dtsi, and should
1311+ * instead explicitly provide the below nodes only as required.
1312+ *
1313+ * Skeleton device tree; the bare minimum needed to boot; just include and
1314+ * add a compatible value.  The bootloader will typically populate the memory
1315+ * node.
1316+ */
1317+
1318+/ {
1319+	#address-cells = <1>;
1320+	#size-cells = <1>;
1321+	chosen { };
1322+	aliases { };
1323+	memory { device_type = "memory"; reg = <0 0>; };
1324+};
1325diff --git a/arch/arm/configs/hi3516dv300_emmc_smp_defconfig b/arch/arm/configs/hi3516dv300_emmc_smp_defconfig
1326new file mode 100644
1327index 000000000..daeb1fa65
1328--- /dev/null
1329+++ b/arch/arm/configs/hi3516dv300_emmc_smp_defconfig
1330@@ -0,0 +1,3070 @@
1331+#
1332+# Automatically generated file; DO NOT EDIT.
1333+# Linux/arm 4.19.90 Kernel Configuration
1334+#
1335+
1336+#
1337+# Compiler: arm-himix410-linux-gcc (HC&C V1R3C00SPC200B041_20200707) 7.3.0
1338+#
1339+CONFIG_CC_IS_GCC=y
1340+CONFIG_GCC_VERSION=70300
1341+CONFIG_CLANG_VERSION=0
1342+CONFIG_CC_HAS_ASM_GOTO=y
1343+CONFIG_IRQ_WORK=y
1344+CONFIG_BUILDTIME_EXTABLE_SORT=y
1345+
1346+#
1347+# General setup
1348+#
1349+CONFIG_INIT_ENV_ARG_LIMIT=32
1350+# CONFIG_COMPILE_TEST is not set
1351+CONFIG_LOCALVERSION=""
1352+# CONFIG_LOCALVERSION_AUTO is not set
1353+CONFIG_BUILD_SALT=""
1354+CONFIG_HAVE_KERNEL_GZIP=y
1355+CONFIG_HAVE_KERNEL_LZMA=y
1356+CONFIG_HAVE_KERNEL_XZ=y
1357+CONFIG_HAVE_KERNEL_LZO=y
1358+CONFIG_HAVE_KERNEL_LZ4=y
1359+CONFIG_KERNEL_GZIP=y
1360+# CONFIG_KERNEL_LZMA is not set
1361+# CONFIG_KERNEL_XZ is not set
1362+# CONFIG_KERNEL_LZO is not set
1363+# CONFIG_KERNEL_LZ4 is not set
1364+CONFIG_DEFAULT_HOSTNAME="(none)"
1365+# CONFIG_SWAP is not set
1366+CONFIG_SYSVIPC=y
1367+CONFIG_SYSVIPC_SYSCTL=y
1368+# CONFIG_POSIX_MQUEUE is not set
1369+CONFIG_CROSS_MEMORY_ATTACH=y
1370+CONFIG_USELIB=y
1371+# CONFIG_AUDIT is not set
1372+
1373+#
1374+# IRQ subsystem
1375+#
1376+CONFIG_GENERIC_IRQ_PROBE=y
1377+CONFIG_GENERIC_IRQ_SHOW=y
1378+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
1379+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
1380+CONFIG_GENERIC_IRQ_MIGRATION=y
1381+CONFIG_HARDIRQS_SW_RESEND=y
1382+CONFIG_IRQ_DOMAIN=y
1383+CONFIG_IRQ_DOMAIN_HIERARCHY=y
1384+CONFIG_HANDLE_DOMAIN_IRQ=y
1385+CONFIG_IRQ_FORCED_THREADING=y
1386+CONFIG_SPARSE_IRQ=y
1387+# CONFIG_GENERIC_IRQ_DEBUGFS is not set
1388+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
1389+CONFIG_ARCH_CLOCKSOURCE_DATA=y
1390+CONFIG_GENERIC_TIME_VSYSCALL=y
1391+CONFIG_GENERIC_CLOCKEVENTS=y
1392+CONFIG_ARCH_HAS_TICK_BROADCAST=y
1393+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
1394+
1395+#
1396+# Timers subsystem
1397+#
1398+CONFIG_HZ_PERIODIC=y
1399+# CONFIG_NO_HZ_IDLE is not set
1400+# CONFIG_NO_HZ_FULL is not set
1401+# CONFIG_NO_HZ is not set
1402+# CONFIG_HIGH_RES_TIMERS is not set
1403+CONFIG_PREEMPT_NONE=y
1404+# CONFIG_PREEMPT_VOLUNTARY is not set
1405+# CONFIG_PREEMPT is not set
1406+
1407+#
1408+# CPU/Task time and stats accounting
1409+#
1410+CONFIG_TICK_CPU_ACCOUNTING=y
1411+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
1412+# CONFIG_IRQ_TIME_ACCOUNTING is not set
1413+# CONFIG_BSD_PROCESS_ACCT is not set
1414+# CONFIG_TASKSTATS is not set
1415+CONFIG_CPU_ISOLATION=y
1416+
1417+#
1418+# RCU Subsystem
1419+#
1420+CONFIG_TREE_RCU=y
1421+# CONFIG_RCU_EXPERT is not set
1422+CONFIG_SRCU=y
1423+CONFIG_TREE_SRCU=y
1424+CONFIG_RCU_STALL_COMMON=y
1425+CONFIG_RCU_NEED_SEGCBLIST=y
1426+# CONFIG_IKCONFIG is not set
1427+CONFIG_LOG_BUF_SHIFT=17
1428+CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
1429+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
1430+CONFIG_GENERIC_SCHED_CLOCK=y
1431+CONFIG_CGROUPS=y
1432+# CONFIG_MEMCG is not set
1433+# CONFIG_BLK_CGROUP is not set
1434+CONFIG_CGROUP_SCHED=y
1435+CONFIG_FAIR_GROUP_SCHED=y
1436+# CONFIG_CFS_BANDWIDTH is not set
1437+# CONFIG_RT_GROUP_SCHED is not set
1438+# CONFIG_CGROUP_PIDS is not set
1439+# CONFIG_CGROUP_RDMA is not set
1440+# CONFIG_CGROUP_FREEZER is not set
1441+# CONFIG_CPUSETS is not set
1442+# CONFIG_CGROUP_DEVICE is not set
1443+# CONFIG_CGROUP_CPUACCT is not set
1444+# CONFIG_CGROUP_DEBUG is not set
1445+CONFIG_NAMESPACES=y
1446+CONFIG_UTS_NS=y
1447+CONFIG_IPC_NS=y
1448+# CONFIG_USER_NS is not set
1449+CONFIG_PID_NS=y
1450+CONFIG_NET_NS=y
1451+# CONFIG_CHECKPOINT_RESTORE is not set
1452+# CONFIG_SCHED_AUTOGROUP is not set
1453+# CONFIG_SYSFS_DEPRECATED is not set
1454+# CONFIG_RELAY is not set
1455+# CONFIG_BLK_DEV_INITRD is not set
1456+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
1457+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
1458+CONFIG_SYSCTL=y
1459+CONFIG_ANON_INODES=y
1460+CONFIG_HAVE_UID16=y
1461+CONFIG_BPF=y
1462+# CONFIG_EXPERT is not set
1463+CONFIG_UID16=y
1464+CONFIG_MULTIUSER=y
1465+CONFIG_SYSFS_SYSCALL=y
1466+CONFIG_FHANDLE=y
1467+CONFIG_POSIX_TIMERS=y
1468+CONFIG_PRINTK=y
1469+CONFIG_PRINTK_NMI=y
1470+CONFIG_BUG=y
1471+CONFIG_ELF_CORE=y
1472+CONFIG_BASE_FULL=y
1473+CONFIG_FUTEX=y
1474+CONFIG_FUTEX_PI=y
1475+CONFIG_EPOLL=y
1476+CONFIG_SIGNALFD=y
1477+CONFIG_TIMERFD=y
1478+CONFIG_EVENTFD=y
1479+CONFIG_SHMEM=y
1480+CONFIG_AIO=y
1481+CONFIG_ADVISE_SYSCALLS=y
1482+CONFIG_MEMBARRIER=y
1483+CONFIG_KALLSYMS=y
1484+# CONFIG_KALLSYMS_ALL is not set
1485+CONFIG_KALLSYMS_BASE_RELATIVE=y
1486+# CONFIG_BPF_SYSCALL is not set
1487+# CONFIG_USERFAULTFD is not set
1488+CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
1489+CONFIG_RSEQ=y
1490+# CONFIG_EMBEDDED is not set
1491+CONFIG_HAVE_PERF_EVENTS=y
1492+CONFIG_PERF_USE_VMALLOC=y
1493+
1494+#
1495+# Kernel Performance Events And Counters
1496+#
1497+# CONFIG_PERF_EVENTS is not set
1498+CONFIG_VM_EVENT_COUNTERS=y
1499+CONFIG_SLUB_DEBUG=y
1500+CONFIG_COMPAT_BRK=y
1501+# CONFIG_SLAB is not set
1502+CONFIG_SLUB=y
1503+CONFIG_SLAB_MERGE_DEFAULT=y
1504+# CONFIG_SLAB_FREELIST_RANDOM is not set
1505+# CONFIG_SLAB_FREELIST_HARDENED is not set
1506+CONFIG_SLUB_CPU_PARTIAL=y
1507+# CONFIG_PROFILING is not set
1508+CONFIG_ARM=y
1509+CONFIG_ARM_HAS_SG_CHAIN=y
1510+CONFIG_MIGHT_HAVE_PCI=y
1511+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
1512+CONFIG_HAVE_PROC_CPU=y
1513+CONFIG_STACKTRACE_SUPPORT=y
1514+CONFIG_LOCKDEP_SUPPORT=y
1515+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
1516+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
1517+CONFIG_FIX_EARLYCON_MEM=y
1518+CONFIG_GENERIC_HWEIGHT=y
1519+CONFIG_GENERIC_CALIBRATE_DELAY=y
1520+CONFIG_ARCH_SUPPORTS_UPROBES=y
1521+CONFIG_ARM_PATCH_PHYS_VIRT=y
1522+CONFIG_GENERIC_BUG=y
1523+CONFIG_PGTABLE_LEVELS=2
1524+
1525+#
1526+# System Type
1527+#
1528+CONFIG_MMU=y
1529+CONFIG_ARCH_MMAP_RND_BITS_MIN=8
1530+CONFIG_ARCH_MMAP_RND_BITS_MAX=16
1531+CONFIG_ARCH_MULTIPLATFORM=y
1532+# CONFIG_ARCH_EBSA110 is not set
1533+# CONFIG_ARCH_EP93XX is not set
1534+# CONFIG_ARCH_FOOTBRIDGE is not set
1535+# CONFIG_ARCH_NETX is not set
1536+# CONFIG_ARCH_IOP13XX is not set
1537+# CONFIG_ARCH_IOP32X is not set
1538+# CONFIG_ARCH_IOP33X is not set
1539+# CONFIG_ARCH_IXP4XX is not set
1540+# CONFIG_ARCH_DOVE is not set
1541+# CONFIG_ARCH_KS8695 is not set
1542+# CONFIG_ARCH_W90X900 is not set
1543+# CONFIG_ARCH_LPC32XX is not set
1544+# CONFIG_ARCH_PXA is not set
1545+# CONFIG_ARCH_RPC is not set
1546+# CONFIG_ARCH_SA1100 is not set
1547+# CONFIG_ARCH_S3C24XX is not set
1548+# CONFIG_ARCH_DAVINCI is not set
1549+# CONFIG_ARCH_OMAP1 is not set
1550+
1551+#
1552+# Multiple platform selection
1553+#
1554+
1555+#
1556+# CPU Core family selection
1557+#
1558+# CONFIG_ARCH_MULTI_V6 is not set
1559+CONFIG_ARCH_MULTI_V7=y
1560+CONFIG_ARCH_MULTI_V6_V7=y
1561+# CONFIG_ARCH_VIRT is not set
1562+# CONFIG_ARCH_ACTIONS is not set
1563+# CONFIG_ARCH_ALPINE is not set
1564+# CONFIG_ARCH_ARTPEC is not set
1565+# CONFIG_ARCH_AT91 is not set
1566+# CONFIG_ARCH_BCM is not set
1567+# CONFIG_ARCH_BERLIN is not set
1568+# CONFIG_ARCH_DIGICOLOR is not set
1569+# CONFIG_ARCH_EXYNOS is not set
1570+# CONFIG_ARCH_HIGHBANK is not set
1571+# CONFIG_ARCH_HISI is not set
1572+CONFIG_ARCH_HISI_BVT=y
1573+
1574+#
1575+# Hisilicon BVT platform type
1576+#
1577+# CONFIG_ARCH_HI3521DV200 is not set
1578+# CONFIG_ARCH_HI3520DV500 is not set
1579+# CONFIG_ARCH_HI3516A is not set
1580+# CONFIG_ARCH_HI3516CV500 is not set
1581+CONFIG_ARCH_HI3516DV300=y
1582+# CONFIG_ARCH_HI3516EV200 is not set
1583+# CONFIG_ARCH_HI3516EV300 is not set
1584+# CONFIG_ARCH_HI3518EV300 is not set
1585+# CONFIG_ARCH_HI3516DV200 is not set
1586+# CONFIG_ARCH_HI3556V200 is not set
1587+# CONFIG_ARCH_HI3559V200 is not set
1588+# CONFIG_ARCH_HI3536DV100 is not set
1589+# CONFIG_ARCH_HI3521A is not set
1590+# CONFIG_ARCH_HI3531A is not set
1591+# CONFIG_ARCH_HI3556AV100 is not set
1592+# CONFIG_ARCH_HI3519AV100 is not set
1593+# CONFIG_ARCH_HI3568V100 is not set
1594+# CONFIG_ARCH_HISI_BVT_AMP is not set
1595+# CONFIG_HISI_MC is not set
1596+CONFIG_HI_ZRELADDR=0x80008000
1597+CONFIG_HI_PARAMS_PHYS=0x00000100
1598+CONFIG_HI_INITRD_PHYS=0x00800000
1599+# CONFIG_ARCH_MXC is not set
1600+# CONFIG_ARCH_KEYSTONE is not set
1601+# CONFIG_ARCH_MEDIATEK is not set
1602+# CONFIG_ARCH_MESON is not set
1603+# CONFIG_ARCH_MMP is not set
1604+# CONFIG_ARCH_MVEBU is not set
1605+# CONFIG_ARCH_NPCM is not set
1606+
1607+#
1608+# TI OMAP/AM/DM/DRA Family
1609+#
1610+# CONFIG_ARCH_OMAP3 is not set
1611+# CONFIG_ARCH_OMAP4 is not set
1612+# CONFIG_SOC_OMAP5 is not set
1613+# CONFIG_SOC_AM33XX is not set
1614+# CONFIG_SOC_AM43XX is not set
1615+# CONFIG_SOC_DRA7XX is not set
1616+# CONFIG_ARCH_SIRF is not set
1617+# CONFIG_ARCH_QCOM is not set
1618+# CONFIG_ARCH_REALVIEW is not set
1619+# CONFIG_ARCH_ROCKCHIP is not set
1620+# CONFIG_ARCH_S5PV210 is not set
1621+# CONFIG_ARCH_RENESAS is not set
1622+# CONFIG_ARCH_SOCFPGA is not set
1623+# CONFIG_PLAT_SPEAR is not set
1624+# CONFIG_ARCH_STI is not set
1625+# CONFIG_ARCH_STM32 is not set
1626+# CONFIG_ARCH_SUNXI is not set
1627+# CONFIG_ARCH_TANGO is not set
1628+# CONFIG_ARCH_TEGRA is not set
1629+# CONFIG_ARCH_UNIPHIER is not set
1630+# CONFIG_ARCH_U8500 is not set
1631+# CONFIG_ARCH_VEXPRESS is not set
1632+# CONFIG_ARCH_WM8850 is not set
1633+# CONFIG_ARCH_ZX is not set
1634+# CONFIG_ARCH_ZYNQ is not set
1635+
1636+#
1637+# Processor Type
1638+#
1639+CONFIG_CPU_V7=y
1640+CONFIG_CPU_THUMB_CAPABLE=y
1641+CONFIG_CPU_32v6K=y
1642+CONFIG_CPU_32v7=y
1643+CONFIG_CPU_ABRT_EV7=y
1644+CONFIG_CPU_PABRT_V7=y
1645+CONFIG_CPU_CACHE_V7=y
1646+CONFIG_CPU_CACHE_VIPT=y
1647+CONFIG_CPU_COPY_V6=y
1648+CONFIG_CPU_TLB_V7=y
1649+CONFIG_CPU_HAS_ASID=y
1650+CONFIG_CPU_CP15=y
1651+CONFIG_CPU_CP15_MMU=y
1652+
1653+#
1654+# Processor Features
1655+#
1656+# CONFIG_ARM_LPAE is not set
1657+CONFIG_ARM_THUMB=y
1658+# CONFIG_ARM_THUMBEE is not set
1659+CONFIG_ARM_VIRT_EXT=y
1660+CONFIG_SWP_EMULATE=y
1661+# CONFIG_CPU_ICACHE_DISABLE is not set
1662+# CONFIG_CPU_BPREDICT_DISABLE is not set
1663+CONFIG_CPU_SPECTRE=y
1664+CONFIG_HARDEN_BRANCH_PREDICTOR=y
1665+CONFIG_KUSER_HELPERS=y
1666+CONFIG_VDSO=y
1667+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
1668+# CONFIG_CACHE_L2X0 is not set
1669+CONFIG_ARM_L1_CACHE_SHIFT_6=y
1670+CONFIG_ARM_L1_CACHE_SHIFT=6
1671+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
1672+CONFIG_DEBUG_ALIGN_RODATA=y
1673+# CONFIG_ARM_ERRATA_430973 is not set
1674+# CONFIG_ARM_ERRATA_643719 is not set
1675+# CONFIG_ARM_ERRATA_720789 is not set
1676+# CONFIG_ARM_ERRATA_754322 is not set
1677+# CONFIG_ARM_ERRATA_754327 is not set
1678+# CONFIG_ARM_ERRATA_764369 is not set
1679+# CONFIG_ARM_ERRATA_775420 is not set
1680+# CONFIG_ARM_ERRATA_798181 is not set
1681+# CONFIG_ARM_ERRATA_773022 is not set
1682+# CONFIG_ARM_ERRATA_818325_852422 is not set
1683+# CONFIG_ARM_ERRATA_821420 is not set
1684+# CONFIG_ARM_ERRATA_825619 is not set
1685+# CONFIG_ARM_ERRATA_852421 is not set
1686+# CONFIG_ARM_ERRATA_852423 is not set
1687+
1688+#
1689+# Bus support
1690+#
1691+# CONFIG_PCI is not set
1692+
1693+#
1694+# PCI Endpoint
1695+#
1696+# CONFIG_PCI_ENDPOINT is not set
1697+# CONFIG_PCCARD is not set
1698+
1699+#
1700+# Kernel Features
1701+#
1702+CONFIG_HAVE_SMP=y
1703+CONFIG_SMP=y
1704+CONFIG_SMP_ON_UP=y
1705+CONFIG_ARM_CPU_TOPOLOGY=y
1706+# CONFIG_SCHED_MC is not set
1707+# CONFIG_SCHED_SMT is not set
1708+CONFIG_HAVE_ARM_ARCH_TIMER=y
1709+# CONFIG_MCPM is not set
1710+# CONFIG_BIG_LITTLE is not set
1711+CONFIG_VMSPLIT_3G=y
1712+# CONFIG_VMSPLIT_3G_OPT is not set
1713+# CONFIG_VMSPLIT_2G is not set
1714+# CONFIG_VMSPLIT_1G is not set
1715+CONFIG_PAGE_OFFSET=0xC0000000
1716+CONFIG_NR_CPUS=2
1717+CONFIG_HOTPLUG_CPU=y
1718+# CONFIG_ARM_PSCI is not set
1719+CONFIG_ARCH_NR_GPIO=0
1720+CONFIG_HZ_FIXED=0
1721+CONFIG_HZ_100=y
1722+# CONFIG_HZ_200 is not set
1723+# CONFIG_HZ_250 is not set
1724+# CONFIG_HZ_300 is not set
1725+# CONFIG_HZ_500 is not set
1726+# CONFIG_HZ_1000 is not set
1727+CONFIG_HZ=100
1728+# CONFIG_THUMB2_KERNEL is not set
1729+CONFIG_ARM_PATCH_IDIV=y
1730+CONFIG_AEABI=y
1731+CONFIG_OABI_COMPAT=y
1732+CONFIG_HAVE_ARCH_PFN_VALID=y
1733+CONFIG_HIGHMEM=y
1734+CONFIG_HIGHPTE=y
1735+CONFIG_CPU_SW_DOMAIN_PAN=y
1736+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
1737+# CONFIG_ARM_MODULE_PLTS is not set
1738+CONFIG_FORCE_MAX_ZONEORDER=11
1739+CONFIG_ALIGNMENT_TRAP=y
1740+# CONFIG_UACCESS_WITH_MEMCPY is not set
1741+# CONFIG_SECCOMP is not set
1742+# CONFIG_PARAVIRT is not set
1743+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
1744+# CONFIG_XEN is not set
1745+
1746+#
1747+# Boot options
1748+#
1749+CONFIG_USE_OF=y
1750+CONFIG_ATAGS=y
1751+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
1752+CONFIG_ZBOOT_ROM_TEXT=0
1753+CONFIG_ZBOOT_ROM_BSS=0
1754+CONFIG_ARM_APPENDED_DTB=y
1755+CONFIG_ARM_ATAG_DTB_COMPAT=y
1756+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
1757+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
1758+CONFIG_CMDLINE=""
1759+# CONFIG_KEXEC is not set
1760+# CONFIG_CRASH_DUMP is not set
1761+CONFIG_AUTO_ZRELADDR=y
1762+# CONFIG_EFI is not set
1763+
1764+#
1765+# CPU Power Management
1766+#
1767+
1768+#
1769+# CPU Frequency scaling
1770+#
1771+# CONFIG_CPU_FREQ is not set
1772+
1773+#
1774+# CPU Idle
1775+#
1776+# CONFIG_CPU_IDLE is not set
1777+
1778+#
1779+# Floating point emulation
1780+#
1781+
1782+#
1783+# At least one emulation must be selected
1784+#
1785+# CONFIG_FPE_NWFPE is not set
1786+# CONFIG_FPE_FASTFPE is not set
1787+CONFIG_VFP=y
1788+CONFIG_VFPv3=y
1789+CONFIG_NEON=y
1790+CONFIG_KERNEL_MODE_NEON=y
1791+
1792+#
1793+# Power management options
1794+#
1795+CONFIG_SUSPEND=y
1796+CONFIG_SUSPEND_FREEZER=y
1797+CONFIG_PM_SLEEP=y
1798+CONFIG_PM_SLEEP_SMP=y
1799+# CONFIG_PM_AUTOSLEEP is not set
1800+# CONFIG_PM_WAKELOCKS is not set
1801+CONFIG_PM=y
1802+# CONFIG_PM_DEBUG is not set
1803+# CONFIG_APM_EMULATION is not set
1804+CONFIG_PM_CLK=y
1805+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
1806+CONFIG_CPU_PM=y
1807+CONFIG_ARCH_SUSPEND_POSSIBLE=y
1808+CONFIG_ARM_CPU_SUSPEND=y
1809+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
1810+
1811+#
1812+# Firmware Drivers
1813+#
1814+# CONFIG_FW_CFG_SYSFS is not set
1815+CONFIG_HAVE_ARM_SMCCC=y
1816+# CONFIG_GOOGLE_FIRMWARE is not set
1817+
1818+#
1819+# Tegra firmware driver
1820+#
1821+# CONFIG_ARM_CRYPTO is not set
1822+# CONFIG_VIRTUALIZATION is not set
1823+
1824+#
1825+# General architecture-dependent options
1826+#
1827+CONFIG_HAVE_OPROFILE=y
1828+# CONFIG_KPROBES is not set
1829+# CONFIG_JUMP_LABEL is not set
1830+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
1831+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
1832+CONFIG_HAVE_KPROBES=y
1833+CONFIG_HAVE_KRETPROBES=y
1834+CONFIG_HAVE_OPTPROBES=y
1835+CONFIG_HAVE_NMI=y
1836+CONFIG_HAVE_ARCH_TRACEHOOK=y
1837+CONFIG_HAVE_DMA_CONTIGUOUS=y
1838+CONFIG_GENERIC_SMP_IDLE_THREAD=y
1839+CONFIG_GENERIC_IDLE_POLL_SETUP=y
1840+CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
1841+CONFIG_ARCH_HAS_SET_MEMORY=y
1842+CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
1843+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
1844+CONFIG_HAVE_RSEQ=y
1845+CONFIG_HAVE_CLK=y
1846+CONFIG_HAVE_PERF_REGS=y
1847+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
1848+CONFIG_HAVE_ARCH_JUMP_LABEL=y
1849+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
1850+CONFIG_HAVE_STACKPROTECTOR=y
1851+CONFIG_CC_HAS_STACKPROTECTOR_NONE=y
1852+CONFIG_STACKPROTECTOR=y
1853+CONFIG_STACKPROTECTOR_STRONG=y
1854+CONFIG_HAVE_CONTEXT_TRACKING=y
1855+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
1856+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
1857+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
1858+CONFIG_MODULES_USE_ELF_REL=y
1859+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
1860+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
1861+CONFIG_HAVE_EXIT_THREAD=y
1862+CONFIG_ARCH_MMAP_RND_BITS=8
1863+CONFIG_CLONE_BACKWARDS=y
1864+CONFIG_OLD_SIGSUSPEND3=y
1865+CONFIG_OLD_SIGACTION=y
1866+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
1867+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
1868+CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
1869+CONFIG_STRICT_KERNEL_RWX=y
1870+CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
1871+CONFIG_STRICT_MODULE_RWX=y
1872+CONFIG_ARCH_HAS_PHYS_TO_DMA=y
1873+CONFIG_REFCOUNT_FULL=y
1874+
1875+#
1876+# GCOV-based kernel profiling
1877+#
1878+# CONFIG_GCOV_KERNEL is not set
1879+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
1880+CONFIG_PLUGIN_HOSTCC=""
1881+CONFIG_HAVE_GCC_PLUGINS=y
1882+CONFIG_RT_MUTEXES=y
1883+CONFIG_BASE_SMALL=0
1884+CONFIG_MODULES=y
1885+CONFIG_MODULE_FORCE_LOAD=y
1886+CONFIG_MODULE_UNLOAD=y
1887+CONFIG_MODULE_FORCE_UNLOAD=y
1888+# CONFIG_MODVERSIONS is not set
1889+# CONFIG_MODULE_SRCVERSION_ALL is not set
1890+# CONFIG_MODULE_SIG is not set
1891+# CONFIG_MODULE_COMPRESS is not set
1892+# CONFIG_TRIM_UNUSED_KSYMS is not set
1893+CONFIG_BLOCK=y
1894+CONFIG_LBDAF=y
1895+CONFIG_BLK_SCSI_REQUEST=y
1896+CONFIG_BLK_DEV_BSG=y
1897+# CONFIG_BLK_DEV_BSGLIB is not set
1898+# CONFIG_BLK_DEV_INTEGRITY is not set
1899+# CONFIG_BLK_DEV_ZONED is not set
1900+CONFIG_BLK_CMDLINE_PARSER=y
1901+# CONFIG_BLK_WBT is not set
1902+# CONFIG_BLK_DEBUG_FS is not set
1903+# CONFIG_BLK_SED_OPAL is not set
1904+
1905+#
1906+# Partition Types
1907+#
1908+CONFIG_PARTITION_ADVANCED=y
1909+# CONFIG_ACORN_PARTITION is not set
1910+# CONFIG_AIX_PARTITION is not set
1911+# CONFIG_OSF_PARTITION is not set
1912+# CONFIG_AMIGA_PARTITION is not set
1913+# CONFIG_ATARI_PARTITION is not set
1914+# CONFIG_MAC_PARTITION is not set
1915+CONFIG_MSDOS_PARTITION=y
1916+# CONFIG_BSD_DISKLABEL is not set
1917+# CONFIG_MINIX_SUBPARTITION is not set
1918+# CONFIG_SOLARIS_X86_PARTITION is not set
1919+# CONFIG_UNIXWARE_DISKLABEL is not set
1920+# CONFIG_LDM_PARTITION is not set
1921+# CONFIG_SGI_PARTITION is not set
1922+# CONFIG_ULTRIX_PARTITION is not set
1923+# CONFIG_SUN_PARTITION is not set
1924+# CONFIG_KARMA_PARTITION is not set
1925+CONFIG_EFI_PARTITION=y
1926+# CONFIG_SYSV68_PARTITION is not set
1927+CONFIG_CMDLINE_PARTITION=y
1928+
1929+#
1930+# IO Schedulers
1931+#
1932+CONFIG_IOSCHED_NOOP=y
1933+# CONFIG_IOSCHED_DEADLINE is not set
1934+CONFIG_IOSCHED_CFQ=y
1935+CONFIG_DEFAULT_CFQ=y
1936+# CONFIG_DEFAULT_NOOP is not set
1937+CONFIG_DEFAULT_IOSCHED="cfq"
1938+CONFIG_MQ_IOSCHED_DEADLINE=y
1939+CONFIG_MQ_IOSCHED_KYBER=y
1940+# CONFIG_IOSCHED_BFQ is not set
1941+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
1942+CONFIG_INLINE_READ_UNLOCK=y
1943+CONFIG_INLINE_READ_UNLOCK_IRQ=y
1944+CONFIG_INLINE_WRITE_UNLOCK=y
1945+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
1946+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
1947+CONFIG_MUTEX_SPIN_ON_OWNER=y
1948+CONFIG_RWSEM_SPIN_ON_OWNER=y
1949+CONFIG_LOCK_SPIN_ON_OWNER=y
1950+CONFIG_FREEZER=y
1951+
1952+#
1953+# Executable file formats
1954+#
1955+CONFIG_BINFMT_ELF=y
1956+# CONFIG_BINFMT_ELF_FDPIC is not set
1957+CONFIG_ELFCORE=y
1958+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
1959+CONFIG_BINFMT_SCRIPT=y
1960+# CONFIG_BINFMT_FLAT is not set
1961+# CONFIG_BINFMT_MISC is not set
1962+CONFIG_COREDUMP=y
1963+
1964+#
1965+# Memory Management options
1966+#
1967+CONFIG_FLATMEM=y
1968+CONFIG_FLAT_NODE_MEM_MAP=y
1969+CONFIG_HAVE_MEMBLOCK=y
1970+CONFIG_NO_BOOTMEM=y
1971+CONFIG_MEMORY_ISOLATION=y
1972+CONFIG_SPLIT_PTLOCK_CPUS=4
1973+CONFIG_COMPACTION=y
1974+CONFIG_MIGRATION=y
1975+CONFIG_BOUNCE=y
1976+# CONFIG_KSM is not set
1977+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
1978+# CONFIG_CLEANCACHE is not set
1979+CONFIG_CMA=y
1980+CONFIG_CMA_DEBUG=y
1981+# CONFIG_CMA_DEBUGFS is not set
1982+CONFIG_CMA_AREAS=7
1983+# CONFIG_ZPOOL is not set
1984+# CONFIG_ZBUD is not set
1985+# CONFIG_ZSMALLOC is not set
1986+CONFIG_GENERIC_EARLY_IOREMAP=y
1987+# CONFIG_IDLE_PAGE_TRACKING is not set
1988+CONFIG_FRAME_VECTOR=y
1989+# CONFIG_PERCPU_STATS is not set
1990+# CONFIG_GUP_BENCHMARK is not set
1991+CONFIG_NET=y
1992+
1993+#
1994+# Networking options
1995+#
1996+CONFIG_PACKET=y
1997+# CONFIG_PACKET_DIAG is not set
1998+CONFIG_UNIX=y
1999+# CONFIG_UNIX_DIAG is not set
2000+# CONFIG_TLS is not set
2001+CONFIG_XFRM=y
2002+# CONFIG_XFRM_USER is not set
2003+# CONFIG_XFRM_INTERFACE is not set
2004+# CONFIG_XFRM_SUB_POLICY is not set
2005+# CONFIG_XFRM_MIGRATE is not set
2006+# CONFIG_XFRM_STATISTICS is not set
2007+# CONFIG_NET_KEY is not set
2008+CONFIG_INET=y
2009+# CONFIG_IP_MULTICAST is not set
2010+# CONFIG_IP_ADVANCED_ROUTER is not set
2011+CONFIG_IP_PNP=y
2012+CONFIG_IP_PNP_DHCP=y
2013+# CONFIG_IP_PNP_BOOTP is not set
2014+# CONFIG_IP_PNP_RARP is not set
2015+# CONFIG_NET_IPIP is not set
2016+# CONFIG_NET_IPGRE_DEMUX is not set
2017+# CONFIG_SYN_COOKIES is not set
2018+# CONFIG_NET_IPVTI is not set
2019+# CONFIG_NET_FOU is not set
2020+# CONFIG_INET_AH is not set
2021+# CONFIG_INET_ESP is not set
2022+# CONFIG_INET_IPCOMP is not set
2023+CONFIG_INET_XFRM_MODE_TRANSPORT=y
2024+CONFIG_INET_XFRM_MODE_TUNNEL=y
2025+CONFIG_INET_XFRM_MODE_BEET=y
2026+CONFIG_INET_DIAG=y
2027+CONFIG_INET_TCP_DIAG=y
2028+# CONFIG_INET_UDP_DIAG is not set
2029+# CONFIG_INET_RAW_DIAG is not set
2030+# CONFIG_INET_DIAG_DESTROY is not set
2031+# CONFIG_TCP_CONG_ADVANCED is not set
2032+CONFIG_TCP_CONG_CUBIC=y
2033+CONFIG_DEFAULT_TCP_CONG="cubic"
2034+# CONFIG_TCP_MD5SIG is not set
2035+CONFIG_IPV6=y
2036+# CONFIG_IPV6_ROUTER_PREF is not set
2037+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
2038+# CONFIG_INET6_AH is not set
2039+# CONFIG_INET6_ESP is not set
2040+# CONFIG_INET6_IPCOMP is not set
2041+# CONFIG_IPV6_MIP6 is not set
2042+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
2043+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
2044+# CONFIG_INET6_XFRM_MODE_BEET is not set
2045+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
2046+# CONFIG_IPV6_SIT is not set
2047+# CONFIG_IPV6_TUNNEL is not set
2048+# CONFIG_IPV6_MULTIPLE_TABLES is not set
2049+# CONFIG_IPV6_MROUTE is not set
2050+# CONFIG_IPV6_SEG6_LWTUNNEL is not set
2051+# CONFIG_IPV6_SEG6_HMAC is not set
2052+# CONFIG_NETWORK_SECMARK is not set
2053+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
2054+# CONFIG_NETFILTER is not set
2055+# CONFIG_BPFILTER is not set
2056+# CONFIG_IP_DCCP is not set
2057+# CONFIG_IP_SCTP is not set
2058+# CONFIG_RDS is not set
2059+# CONFIG_TIPC is not set
2060+# CONFIG_ATM is not set
2061+# CONFIG_L2TP is not set
2062+# CONFIG_BRIDGE is not set
2063+CONFIG_HAVE_NET_DSA=y
2064+# CONFIG_NET_DSA is not set
2065+CONFIG_VLAN_8021Q=y
2066+# CONFIG_VLAN_8021Q_GVRP is not set
2067+# CONFIG_VLAN_8021Q_MVRP is not set
2068+# CONFIG_DECNET is not set
2069+# CONFIG_LLC2 is not set
2070+# CONFIG_ATALK is not set
2071+# CONFIG_X25 is not set
2072+# CONFIG_LAPB is not set
2073+# CONFIG_PHONET is not set
2074+# CONFIG_6LOWPAN is not set
2075+# CONFIG_IEEE802154 is not set
2076+# CONFIG_NET_SCHED is not set
2077+# CONFIG_DCB is not set
2078+CONFIG_DNS_RESOLVER=y
2079+# CONFIG_BATMAN_ADV is not set
2080+# CONFIG_OPENVSWITCH is not set
2081+# CONFIG_VSOCKETS is not set
2082+# CONFIG_NETLINK_DIAG is not set
2083+# CONFIG_MPLS is not set
2084+# CONFIG_NET_NSH is not set
2085+# CONFIG_HSR is not set
2086+# CONFIG_NET_SWITCHDEV is not set
2087+# CONFIG_NET_L3_MASTER_DEV is not set
2088+# CONFIG_NET_NCSI is not set
2089+CONFIG_RPS=y
2090+CONFIG_RFS_ACCEL=y
2091+CONFIG_XPS=y
2092+# CONFIG_CGROUP_NET_PRIO is not set
2093+# CONFIG_CGROUP_NET_CLASSID is not set
2094+CONFIG_NET_RX_BUSY_POLL=y
2095+CONFIG_BQL=y
2096+# CONFIG_BPF_JIT is not set
2097+CONFIG_NET_FLOW_LIMIT=y
2098+
2099+#
2100+# Network testing
2101+#
2102+# CONFIG_NET_PKTGEN is not set
2103+# CONFIG_HAMRADIO is not set
2104+# CONFIG_CAN is not set
2105+# CONFIG_BT is not set
2106+# CONFIG_AF_RXRPC is not set
2107+# CONFIG_AF_KCM is not set
2108+CONFIG_WIRELESS=y
2109+# CONFIG_CFG80211 is not set
2110+
2111+#
2112+# CFG80211 needs to be enabled for MAC80211
2113+#
2114+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
2115+# CONFIG_WIMAX is not set
2116+# CONFIG_RFKILL is not set
2117+# CONFIG_NET_9P is not set
2118+# CONFIG_CAIF is not set
2119+# CONFIG_CEPH_LIB is not set
2120+# CONFIG_NFC is not set
2121+# CONFIG_PSAMPLE is not set
2122+# CONFIG_NET_IFE is not set
2123+# CONFIG_LWTUNNEL is not set
2124+CONFIG_GRO_CELLS=y
2125+# CONFIG_NET_DEVLINK is not set
2126+CONFIG_MAY_USE_DEVLINK=y
2127+# CONFIG_FAILOVER is not set
2128+CONFIG_HAVE_EBPF_JIT=y
2129+
2130+#
2131+# Device Drivers
2132+#
2133+CONFIG_ARM_AMBA=y
2134+
2135+#
2136+# Generic Driver Options
2137+#
2138+CONFIG_UEVENT_HELPER=y
2139+CONFIG_UEVENT_HELPER_PATH=""
2140+CONFIG_DEVTMPFS=y
2141+CONFIG_DEVTMPFS_MOUNT=y
2142+CONFIG_STANDALONE=y
2143+CONFIG_PREVENT_FIRMWARE_BUILD=y
2144+
2145+#
2146+# Firmware loader
2147+#
2148+CONFIG_FW_LOADER=y
2149+CONFIG_EXTRA_FIRMWARE=""
2150+# CONFIG_FW_LOADER_USER_HELPER is not set
2151+CONFIG_ALLOW_DEV_COREDUMP=y
2152+# CONFIG_DEBUG_DRIVER is not set
2153+# CONFIG_DEBUG_DEVRES is not set
2154+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set
2155+# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set
2156+CONFIG_GENERIC_CPU_AUTOPROBE=y
2157+CONFIG_REGMAP=y
2158+CONFIG_REGMAP_I2C=y
2159+CONFIG_REGMAP_SPI=y
2160+CONFIG_REGMAP_MMIO=y
2161+CONFIG_DMA_SHARED_BUFFER=y
2162+# CONFIG_DMA_FENCE_TRACE is not set
2163+CONFIG_DMA_CMA=y
2164+
2165+#
2166+# Default contiguous memory area size:
2167+#
2168+CONFIG_CMA_SIZE_MBYTES=16
2169+CONFIG_CMA_SIZE_SEL_MBYTES=y
2170+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
2171+# CONFIG_CMA_SIZE_SEL_MIN is not set
2172+# CONFIG_CMA_SIZE_SEL_MAX is not set
2173+CONFIG_CMA_ALIGNMENT=8
2174+CONFIG_GENERIC_ARCH_TOPOLOGY=y
2175+
2176+#
2177+# Bus devices
2178+#
2179+# CONFIG_BRCMSTB_GISB_ARB is not set
2180+# CONFIG_SIMPLE_PM_BUS is not set
2181+# CONFIG_VEXPRESS_CONFIG is not set
2182+# CONFIG_CONNECTOR is not set
2183+# CONFIG_GNSS is not set
2184+# CONFIG_MTD is not set
2185+CONFIG_DTC=y
2186+CONFIG_OF=y
2187+# CONFIG_OF_UNITTEST is not set
2188+CONFIG_OF_FLATTREE=y
2189+CONFIG_OF_EARLY_FLATTREE=y
2190+CONFIG_OF_KOBJ=y
2191+CONFIG_OF_ADDRESS=y
2192+CONFIG_OF_IRQ=y
2193+CONFIG_OF_NET=y
2194+CONFIG_OF_MDIO=y
2195+CONFIG_OF_RESERVED_MEM=y
2196+# CONFIG_OF_OVERLAY is not set
2197+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
2198+# CONFIG_PARPORT is not set
2199+CONFIG_BLK_DEV=y
2200+# CONFIG_BLK_DEV_NULL_BLK is not set
2201+# CONFIG_BLK_DEV_LOOP is not set
2202+# CONFIG_BLK_DEV_DRBD is not set
2203+# CONFIG_BLK_DEV_NBD is not set
2204+CONFIG_BLK_DEV_RAM=y
2205+CONFIG_BLK_DEV_RAM_COUNT=16
2206+CONFIG_BLK_DEV_RAM_SIZE=65536
2207+# CONFIG_CDROM_PKTCDVD is not set
2208+# CONFIG_ATA_OVER_ETH is not set
2209+# CONFIG_BLK_DEV_RBD is not set
2210+
2211+#
2212+# NVME Support
2213+#
2214+# CONFIG_NVME_FC is not set
2215+# CONFIG_NVME_TARGET is not set
2216+
2217+#
2218+# Misc devices
2219+#
2220+# CONFIG_AD525X_DPOT is not set
2221+# CONFIG_DUMMY_IRQ is not set
2222+# CONFIG_ICS932S401 is not set
2223+# CONFIG_ENCLOSURE_SERVICES is not set
2224+# CONFIG_APDS9802ALS is not set
2225+# CONFIG_ISL29003 is not set
2226+# CONFIG_ISL29020 is not set
2227+# CONFIG_SENSORS_TSL2550 is not set
2228+# CONFIG_SENSORS_BH1770 is not set
2229+# CONFIG_SENSORS_APDS990X is not set
2230+# CONFIG_HMC6352 is not set
2231+# CONFIG_DS1682 is not set
2232+# CONFIG_USB_SWITCH_FSA9480 is not set
2233+# CONFIG_LATTICE_ECP3_CONFIG is not set
2234+# CONFIG_SRAM is not set
2235+# CONFIG_C2PORT is not set
2236+
2237+#
2238+# EEPROM support
2239+#
2240+# CONFIG_EEPROM_AT24 is not set
2241+# CONFIG_EEPROM_AT25 is not set
2242+# CONFIG_EEPROM_LEGACY is not set
2243+# CONFIG_EEPROM_MAX6875 is not set
2244+# CONFIG_EEPROM_93CX6 is not set
2245+# CONFIG_EEPROM_93XX46 is not set
2246+# CONFIG_EEPROM_IDT_89HPESX is not set
2247+
2248+#
2249+# Texas Instruments shared transport line discipline
2250+#
2251+# CONFIG_TI_ST is not set
2252+# CONFIG_SENSORS_LIS3_SPI is not set
2253+# CONFIG_SENSORS_LIS3_I2C is not set
2254+# CONFIG_ALTERA_STAPL is not set
2255+
2256+#
2257+# Intel MIC & related support
2258+#
2259+
2260+#
2261+# Intel MIC Bus Driver
2262+#
2263+
2264+#
2265+# SCIF Bus Driver
2266+#
2267+
2268+#
2269+# VOP Bus Driver
2270+#
2271+
2272+#
2273+# Intel MIC Host Driver
2274+#
2275+
2276+#
2277+# Intel MIC Card Driver
2278+#
2279+
2280+#
2281+# SCIF Driver
2282+#
2283+
2284+#
2285+# Intel MIC Coprocessor State Management (COSM) Drivers
2286+#
2287+
2288+#
2289+# VOP Driver
2290+#
2291+# CONFIG_ECHO is not set
2292+# CONFIG_MISC_RTSX_USB is not set
2293+
2294+#
2295+# SCSI device support
2296+#
2297+CONFIG_SCSI_MOD=y
2298+# CONFIG_RAID_ATTRS is not set
2299+CONFIG_SCSI=y
2300+CONFIG_SCSI_DMA=y
2301+# CONFIG_SCSI_MQ_DEFAULT is not set
2302+CONFIG_SCSI_PROC_FS=y
2303+
2304+#
2305+# SCSI support type (disk, tape, CD-ROM)
2306+#
2307+CONFIG_BLK_DEV_SD=y
2308+# CONFIG_CHR_DEV_ST is not set
2309+# CONFIG_CHR_DEV_OSST is not set
2310+# CONFIG_BLK_DEV_SR is not set
2311+# CONFIG_CHR_DEV_SG is not set
2312+# CONFIG_CHR_DEV_SCH is not set
2313+# CONFIG_SCSI_CONSTANTS is not set
2314+# CONFIG_SCSI_LOGGING is not set
2315+# CONFIG_SCSI_SCAN_ASYNC is not set
2316+
2317+#
2318+# SCSI Transports
2319+#
2320+# CONFIG_SCSI_SPI_ATTRS is not set
2321+# CONFIG_SCSI_FC_ATTRS is not set
2322+# CONFIG_SCSI_ISCSI_ATTRS is not set
2323+# CONFIG_SCSI_SAS_ATTRS is not set
2324+# CONFIG_SCSI_SAS_LIBSAS is not set
2325+# CONFIG_SCSI_SRP_ATTRS is not set
2326+CONFIG_SCSI_LOWLEVEL=y
2327+# CONFIG_ISCSI_TCP is not set
2328+# CONFIG_ISCSI_BOOT_SYSFS is not set
2329+# CONFIG_SCSI_UFSHCD is not set
2330+# CONFIG_SCSI_DEBUG is not set
2331+# CONFIG_SCSI_DH is not set
2332+# CONFIG_SCSI_OSD_INITIATOR is not set
2333+# CONFIG_ATA is not set
2334+# CONFIG_MD is not set
2335+# CONFIG_TARGET_CORE is not set
2336+CONFIG_NETDEVICES=y
2337+CONFIG_MII=y
2338+CONFIG_NET_CORE=y
2339+# CONFIG_BONDING is not set
2340+# CONFIG_DUMMY is not set
2341+# CONFIG_EQUALIZER is not set
2342+# CONFIG_NET_TEAM is not set
2343+# CONFIG_MACVLAN is not set
2344+# CONFIG_VXLAN is not set
2345+# CONFIG_GENEVE is not set
2346+# CONFIG_GTP is not set
2347+# CONFIG_MACSEC is not set
2348+# CONFIG_NETCONSOLE is not set
2349+# CONFIG_TUN is not set
2350+# CONFIG_TUN_VNET_CROSS_LE is not set
2351+# CONFIG_VETH is not set
2352+# CONFIG_NLMON is not set
2353+
2354+#
2355+# CAIF transport drivers
2356+#
2357+
2358+#
2359+# Distributed Switch Architecture drivers
2360+#
2361+CONFIG_ETHERNET=y
2362+CONFIG_NET_VENDOR_ALACRITECH=y
2363+# CONFIG_ALTERA_TSE is not set
2364+# CONFIG_NET_VENDOR_AMAZON is not set
2365+CONFIG_NET_VENDOR_AQUANTIA=y
2366+# CONFIG_NET_VENDOR_ARC is not set
2367+# CONFIG_NET_VENDOR_AURORA is not set
2368+# CONFIG_NET_VENDOR_BROADCOM is not set
2369+CONFIG_NET_VENDOR_CADENCE=y
2370+# CONFIG_MACB is not set
2371+CONFIG_NET_VENDOR_CAVIUM=y
2372+# CONFIG_NET_VENDOR_CIRRUS is not set
2373+CONFIG_NET_VENDOR_CORTINA=y
2374+# CONFIG_GEMINI_ETHERNET is not set
2375+# CONFIG_DM9000 is not set
2376+# CONFIG_DNET is not set
2377+# CONFIG_NET_VENDOR_EZCHIP is not set
2378+# CONFIG_NET_VENDOR_FARADAY is not set
2379+CONFIG_NET_VENDOR_HISILICON=y
2380+# CONFIG_HIX5HD2_GMAC is not set
2381+CONFIG_HISI_FEMAC=y
2382+# CONFIG_HIP04_ETH is not set
2383+# CONFIG_HNS is not set
2384+# CONFIG_HNS_DSAF is not set
2385+# CONFIG_HNS_ENET is not set
2386+# CONFIG_HIETH_GMAC is not set
2387+CONFIG_NET_VENDOR_HUAWEI=y
2388+# CONFIG_NET_VENDOR_INTEL is not set
2389+# CONFIG_NET_VENDOR_MARVELL is not set
2390+CONFIG_NET_VENDOR_MELLANOX=y
2391+# CONFIG_MLXSW_CORE is not set
2392+# CONFIG_MLXFW is not set
2393+# CONFIG_NET_VENDOR_MICREL is not set
2394+# CONFIG_NET_VENDOR_MICROCHIP is not set
2395+CONFIG_NET_VENDOR_MICROSEMI=y
2396+# CONFIG_NET_VENDOR_NATSEMI is not set
2397+# CONFIG_NET_VENDOR_NETRONOME is not set
2398+CONFIG_NET_VENDOR_NI=y
2399+# CONFIG_ETHOC is not set
2400+# CONFIG_NET_VENDOR_QUALCOMM is not set
2401+# CONFIG_NET_VENDOR_RENESAS is not set
2402+# CONFIG_NET_VENDOR_ROCKER is not set
2403+# CONFIG_NET_VENDOR_SAMSUNG is not set
2404+# CONFIG_NET_VENDOR_SEEQ is not set
2405+CONFIG_NET_VENDOR_SOLARFLARE=y
2406+# CONFIG_NET_VENDOR_SMSC is not set
2407+CONFIG_NET_VENDOR_SOCIONEXT=y
2408+# CONFIG_NET_VENDOR_STMICRO is not set
2409+# CONFIG_NET_VENDOR_SYNOPSYS is not set
2410+# CONFIG_NET_VENDOR_VIA is not set
2411+# CONFIG_NET_VENDOR_WIZNET is not set
2412+CONFIG_MDIO_DEVICE=y
2413+CONFIG_MDIO_BUS=y
2414+# CONFIG_MDIO_BCM_UNIMAC is not set
2415+# CONFIG_MDIO_BITBANG is not set
2416+# CONFIG_MDIO_BUS_MUX_GPIO is not set
2417+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
2418+CONFIG_MDIO_HISI_FEMAC=y
2419+# CONFIG_MDIO_HISI_GEMAC is not set
2420+# CONFIG_MDIO_MSCC_MIIM is not set
2421+CONFIG_PHYLIB=y
2422+CONFIG_SWPHY=y
2423+
2424+#
2425+# MII PHY device drivers
2426+#
2427+# CONFIG_AMD_PHY is not set
2428+# CONFIG_AQUANTIA_PHY is not set
2429+# CONFIG_AX88796B_PHY is not set
2430+# CONFIG_AT803X_PHY is not set
2431+# CONFIG_BCM7XXX_PHY is not set
2432+# CONFIG_BCM87XX_PHY is not set
2433+# CONFIG_BROADCOM_PHY is not set
2434+# CONFIG_CICADA_PHY is not set
2435+# CONFIG_CORTINA_PHY is not set
2436+# CONFIG_DAVICOM_PHY is not set
2437+# CONFIG_DP83822_PHY is not set
2438+# CONFIG_DP83TC811_PHY is not set
2439+# CONFIG_DP83848_PHY is not set
2440+# CONFIG_DP83867_PHY is not set
2441+CONFIG_FIXED_PHY=y
2442+# CONFIG_ICPLUS_PHY is not set
2443+# CONFIG_INTEL_XWAY_PHY is not set
2444+# CONFIG_LSI_ET1011C_PHY is not set
2445+# CONFIG_LXT_PHY is not set
2446+# CONFIG_MARVELL_PHY is not set
2447+# CONFIG_MARVELL_10G_PHY is not set
2448+# CONFIG_MICREL_PHY is not set
2449+# CONFIG_MICROCHIP_PHY is not set
2450+# CONFIG_MICROCHIP_T1_PHY is not set
2451+# CONFIG_MICROSEMI_PHY is not set
2452+# CONFIG_NATIONAL_PHY is not set
2453+# CONFIG_QSEMI_PHY is not set
2454+# CONFIG_REALTEK_PHY is not set
2455+# CONFIG_RENESAS_PHY is not set
2456+# CONFIG_ROCKCHIP_PHY is not set
2457+# CONFIG_SMSC_PHY is not set
2458+# CONFIG_STE10XP is not set
2459+# CONFIG_TERANETICS_PHY is not set
2460+# CONFIG_VITESSE_PHY is not set
2461+# CONFIG_XILINX_GMII2RGMII is not set
2462+# CONFIG_MICREL_KS8995MA is not set
2463+# CONFIG_PPP is not set
2464+# CONFIG_SLIP is not set
2465+CONFIG_USB_NET_DRIVERS=y
2466+# CONFIG_USB_CATC is not set
2467+# CONFIG_USB_KAWETH is not set
2468+# CONFIG_USB_PEGASUS is not set
2469+# CONFIG_USB_RTL8150 is not set
2470+CONFIG_USB_RTL8152=y
2471+# CONFIG_USB_LAN78XX is not set
2472+# CONFIG_USB_USBNET is not set
2473+# CONFIG_USB_IPHETH is not set
2474+CONFIG_WLAN=y
2475+CONFIG_WLAN_VENDOR_ADMTEK=y
2476+CONFIG_WLAN_VENDOR_ATH=y
2477+# CONFIG_ATH_DEBUG is not set
2478+CONFIG_WLAN_VENDOR_ATMEL=y
2479+CONFIG_WLAN_VENDOR_BROADCOM=y
2480+CONFIG_WLAN_VENDOR_CISCO=y
2481+CONFIG_WLAN_VENDOR_INTEL=y
2482+CONFIG_WLAN_VENDOR_INTERSIL=y
2483+# CONFIG_HOSTAP is not set
2484+CONFIG_WLAN_VENDOR_MARVELL=y
2485+CONFIG_WLAN_VENDOR_MEDIATEK=y
2486+CONFIG_WLAN_VENDOR_RALINK=y
2487+CONFIG_WLAN_VENDOR_REALTEK=y
2488+CONFIG_WLAN_VENDOR_RSI=y
2489+CONFIG_WLAN_VENDOR_ST=y
2490+CONFIG_WLAN_VENDOR_TI=y
2491+CONFIG_WLAN_VENDOR_ZYDAS=y
2492+CONFIG_WLAN_VENDOR_QUANTENNA=y
2493+
2494+#
2495+# Enable WiMAX (Networking options) to see the WiMAX drivers
2496+#
2497+# CONFIG_WAN is not set
2498+# CONFIG_NETDEVSIM is not set
2499+# CONFIG_NET_FAILOVER is not set
2500+# CONFIG_ISDN is not set
2501+
2502+#
2503+# Input device support
2504+#
2505+CONFIG_INPUT=y
2506+CONFIG_INPUT_FF_MEMLESS=y
2507+# CONFIG_INPUT_POLLDEV is not set
2508+# CONFIG_INPUT_SPARSEKMAP is not set
2509+# CONFIG_INPUT_MATRIXKMAP is not set
2510+
2511+#
2512+# Userland interfaces
2513+#
2514+CONFIG_INPUT_MOUSEDEV=y
2515+CONFIG_INPUT_MOUSEDEV_PSAUX=y
2516+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
2517+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
2518+CONFIG_INPUT_JOYDEV=y
2519+CONFIG_INPUT_EVDEV=y
2520+# CONFIG_INPUT_EVBUG is not set
2521+
2522+#
2523+# Input Device Drivers
2524+#
2525+CONFIG_INPUT_KEYBOARD=y
2526+# CONFIG_KEYBOARD_ADP5588 is not set
2527+# CONFIG_KEYBOARD_ADP5589 is not set
2528+CONFIG_KEYBOARD_ATKBD=y
2529+# CONFIG_KEYBOARD_QT1070 is not set
2530+# CONFIG_KEYBOARD_QT2160 is not set
2531+# CONFIG_KEYBOARD_DLINK_DIR685 is not set
2532+# CONFIG_KEYBOARD_LKKBD is not set
2533+# CONFIG_KEYBOARD_GPIO is not set
2534+# CONFIG_KEYBOARD_GPIO_POLLED is not set
2535+# CONFIG_KEYBOARD_TCA6416 is not set
2536+# CONFIG_KEYBOARD_TCA8418 is not set
2537+# CONFIG_KEYBOARD_MATRIX is not set
2538+# CONFIG_KEYBOARD_LM8333 is not set
2539+# CONFIG_KEYBOARD_MAX7359 is not set
2540+# CONFIG_KEYBOARD_MCS is not set
2541+# CONFIG_KEYBOARD_MPR121 is not set
2542+# CONFIG_KEYBOARD_NEWTON is not set
2543+# CONFIG_KEYBOARD_OPENCORES is not set
2544+# CONFIG_KEYBOARD_SAMSUNG is not set
2545+# CONFIG_KEYBOARD_STOWAWAY is not set
2546+# CONFIG_KEYBOARD_SUNKBD is not set
2547+# CONFIG_KEYBOARD_OMAP4 is not set
2548+# CONFIG_KEYBOARD_XTKBD is not set
2549+# CONFIG_KEYBOARD_CAP11XX is not set
2550+# CONFIG_KEYBOARD_BCM is not set
2551+CONFIG_INPUT_MOUSE=y
2552+CONFIG_MOUSE_PS2=y
2553+CONFIG_MOUSE_PS2_ALPS=y
2554+CONFIG_MOUSE_PS2_BYD=y
2555+CONFIG_MOUSE_PS2_LOGIPS2PP=y
2556+CONFIG_MOUSE_PS2_SYNAPTICS=y
2557+CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
2558+CONFIG_MOUSE_PS2_CYPRESS=y
2559+CONFIG_MOUSE_PS2_TRACKPOINT=y
2560+# CONFIG_MOUSE_PS2_ELANTECH is not set
2561+# CONFIG_MOUSE_PS2_SENTELIC is not set
2562+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
2563+CONFIG_MOUSE_PS2_FOCALTECH=y
2564+CONFIG_MOUSE_PS2_SMBUS=y
2565+# CONFIG_MOUSE_SERIAL is not set
2566+# CONFIG_MOUSE_APPLETOUCH is not set
2567+# CONFIG_MOUSE_BCM5974 is not set
2568+# CONFIG_MOUSE_CYAPA is not set
2569+# CONFIG_MOUSE_ELAN_I2C is not set
2570+# CONFIG_MOUSE_VSXXXAA is not set
2571+# CONFIG_MOUSE_GPIO is not set
2572+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
2573+# CONFIG_MOUSE_SYNAPTICS_USB is not set
2574+CONFIG_INPUT_JOYSTICK=y
2575+# CONFIG_JOYSTICK_ANALOG is not set
2576+# CONFIG_JOYSTICK_A3D is not set
2577+# CONFIG_JOYSTICK_ADI is not set
2578+# CONFIG_JOYSTICK_COBRA is not set
2579+# CONFIG_JOYSTICK_GF2K is not set
2580+# CONFIG_JOYSTICK_GRIP is not set
2581+# CONFIG_JOYSTICK_GRIP_MP is not set
2582+# CONFIG_JOYSTICK_GUILLEMOT is not set
2583+# CONFIG_JOYSTICK_INTERACT is not set
2584+# CONFIG_JOYSTICK_SIDEWINDER is not set
2585+# CONFIG_JOYSTICK_TMDC is not set
2586+# CONFIG_JOYSTICK_IFORCE is not set
2587+# CONFIG_JOYSTICK_WARRIOR is not set
2588+# CONFIG_JOYSTICK_MAGELLAN is not set
2589+# CONFIG_JOYSTICK_SPACEORB is not set
2590+# CONFIG_JOYSTICK_SPACEBALL is not set
2591+# CONFIG_JOYSTICK_STINGER is not set
2592+# CONFIG_JOYSTICK_TWIDJOY is not set
2593+# CONFIG_JOYSTICK_ZHENHUA is not set
2594+# CONFIG_JOYSTICK_AS5011 is not set
2595+# CONFIG_JOYSTICK_JOYDUMP is not set
2596+CONFIG_JOYSTICK_XPAD=y
2597+CONFIG_JOYSTICK_XPAD_FF=y
2598+# CONFIG_JOYSTICK_PSXPAD_SPI is not set
2599+# CONFIG_JOYSTICK_PXRC is not set
2600+# CONFIG_INPUT_TABLET is not set
2601+# CONFIG_INPUT_TOUCHSCREEN is not set
2602+# CONFIG_INPUT_MISC is not set
2603+# CONFIG_RMI4_CORE is not set
2604+
2605+#
2606+# Hardware I/O ports
2607+#
2608+CONFIG_SERIO=y
2609+CONFIG_SERIO_SERPORT=y
2610+# CONFIG_SERIO_AMBAKMI is not set
2611+CONFIG_SERIO_LIBPS2=y
2612+# CONFIG_SERIO_RAW is not set
2613+# CONFIG_SERIO_ALTERA_PS2 is not set
2614+# CONFIG_SERIO_PS2MULT is not set
2615+# CONFIG_SERIO_ARC_PS2 is not set
2616+# CONFIG_SERIO_APBPS2 is not set
2617+# CONFIG_SERIO_GPIO_PS2 is not set
2618+# CONFIG_USERIO is not set
2619+# CONFIG_GAMEPORT is not set
2620+
2621+#
2622+# Character devices
2623+#
2624+CONFIG_TTY=y
2625+CONFIG_VT=y
2626+CONFIG_CONSOLE_TRANSLATIONS=y
2627+CONFIG_VT_CONSOLE=y
2628+CONFIG_VT_CONSOLE_SLEEP=y
2629+CONFIG_HW_CONSOLE=y
2630+# CONFIG_VT_HW_CONSOLE_BINDING is not set
2631+CONFIG_UNIX98_PTYS=y
2632+# CONFIG_LEGACY_PTYS is not set
2633+# CONFIG_SERIAL_NONSTANDARD is not set
2634+# CONFIG_N_GSM is not set
2635+# CONFIG_TRACE_SINK is not set
2636+CONFIG_LDISC_AUTOLOAD=y
2637+CONFIG_DEVMEM=y
2638+CONFIG_DEVKMEM=y
2639+
2640+#
2641+# Serial drivers
2642+#
2643+CONFIG_SERIAL_EARLYCON=y
2644+# CONFIG_SERIAL_8250 is not set
2645+
2646+#
2647+# Non-8250 serial port support
2648+#
2649+# CONFIG_SERIAL_AMBA_PL010 is not set
2650+CONFIG_SERIAL_AMBA_PL011=y
2651+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
2652+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set
2653+# CONFIG_SERIAL_MAX3100 is not set
2654+# CONFIG_SERIAL_MAX310X is not set
2655+# CONFIG_SERIAL_UARTLITE is not set
2656+CONFIG_SERIAL_CORE=y
2657+CONFIG_SERIAL_CORE_CONSOLE=y
2658+# CONFIG_SERIAL_SCCNXP is not set
2659+# CONFIG_SERIAL_SC16IS7XX is not set
2660+# CONFIG_SERIAL_BCM63XX is not set
2661+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
2662+# CONFIG_SERIAL_ALTERA_UART is not set
2663+# CONFIG_SERIAL_IFX6X60 is not set
2664+# CONFIG_SERIAL_XILINX_PS_UART is not set
2665+# CONFIG_SERIAL_ARC is not set
2666+# CONFIG_SERIAL_FSL_LPUART is not set
2667+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set
2668+# CONFIG_SERIAL_ST_ASC is not set
2669+# CONFIG_SERIAL_DEV_BUS is not set
2670+# CONFIG_HVC_DCC is not set
2671+# CONFIG_IPMI_HANDLER is not set
2672+# CONFIG_HW_RANDOM is not set
2673+# CONFIG_RAW_DRIVER is not set
2674+# CONFIG_TCG_TPM is not set
2675+# CONFIG_XILLYBUS is not set
2676+
2677+#
2678+# I2C support
2679+#
2680+CONFIG_I2C=y
2681+CONFIG_I2C_BOARDINFO=y
2682+# CONFIG_I2C_COMPAT is not set
2683+CONFIG_I2C_CHARDEV=y
2684+CONFIG_I2C_MUX=y
2685+
2686+#
2687+# Multiplexer I2C Chip support
2688+#
2689+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
2690+# CONFIG_I2C_MUX_GPIO is not set
2691+# CONFIG_I2C_MUX_GPMUX is not set
2692+# CONFIG_I2C_MUX_LTC4306 is not set
2693+# CONFIG_I2C_MUX_PCA9541 is not set
2694+# CONFIG_I2C_MUX_PCA954x is not set
2695+# CONFIG_I2C_MUX_PINCTRL is not set
2696+# CONFIG_I2C_MUX_REG is not set
2697+# CONFIG_I2C_DEMUX_PINCTRL is not set
2698+# CONFIG_I2C_MUX_MLXCPLD is not set
2699+# CONFIG_I2C_HELPER_AUTO is not set
2700+# CONFIG_I2C_SMBUS is not set
2701+
2702+#
2703+# I2C Algorithms
2704+#
2705+# CONFIG_I2C_ALGOBIT is not set
2706+# CONFIG_I2C_ALGOPCF is not set
2707+# CONFIG_I2C_ALGOPCA is not set
2708+
2709+#
2710+# I2C Hardware Bus support
2711+#
2712+
2713+#
2714+# I2C system bus drivers (mostly embedded / system-on-chip)
2715+#
2716+# CONFIG_I2C_CBUS_GPIO is not set
2717+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
2718+# CONFIG_I2C_EMEV2 is not set
2719+# CONFIG_I2C_GPIO is not set
2720+CONFIG_I2C_HIBVT=y
2721+# CONFIG_I2C_NOMADIK is not set
2722+# CONFIG_I2C_OCORES is not set
2723+# CONFIG_I2C_PCA_PLATFORM is not set
2724+# CONFIG_I2C_RK3X is not set
2725+# CONFIG_I2C_SIMTEC is not set
2726+# CONFIG_I2C_XILINX is not set
2727+
2728+#
2729+# External I2C/SMBus adapter drivers
2730+#
2731+# CONFIG_I2C_DIOLAN_U2C is not set
2732+# CONFIG_I2C_PARPORT_LIGHT is not set
2733+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set
2734+# CONFIG_I2C_TAOS_EVM is not set
2735+# CONFIG_I2C_TINY_USB is not set
2736+
2737+#
2738+# Other I2C/SMBus bus drivers
2739+#
2740+CONFIG_DMA_MSG_MIN_LEN=5
2741+CONFIG_DMA_MSG_MAX_LEN=4090
2742+# CONFIG_I2C_STUB is not set
2743+# CONFIG_I2C_SLAVE is not set
2744+# CONFIG_I2C_DEBUG_CORE is not set
2745+# CONFIG_I2C_DEBUG_ALGO is not set
2746+# CONFIG_I2C_DEBUG_BUS is not set
2747+CONFIG_SPI=y
2748+# CONFIG_SPI_DEBUG is not set
2749+CONFIG_SPI_MASTER=y
2750+# CONFIG_SPI_MEM is not set
2751+
2752+#
2753+# SPI Master Controller Drivers
2754+#
2755+# CONFIG_SPI_ALTERA is not set
2756+# CONFIG_SPI_AXI_SPI_ENGINE is not set
2757+# CONFIG_SPI_BITBANG is not set
2758+# CONFIG_SPI_CADENCE is not set
2759+# CONFIG_SPI_DESIGNWARE is not set
2760+# CONFIG_SPI_GPIO is not set
2761+# CONFIG_SPI_FSL_SPI is not set
2762+# CONFIG_SPI_OC_TINY is not set
2763+CONFIG_SPI_PL022=y
2764+# CONFIG_SPI_ROCKCHIP is not set
2765+# CONFIG_SPI_SC18IS602 is not set
2766+# CONFIG_SPI_XCOMM is not set
2767+# CONFIG_SPI_XILINX is not set
2768+# CONFIG_SPI_ZYNQMP_GQSPI is not set
2769+
2770+#
2771+# SPI Protocol Masters
2772+#
2773+CONFIG_SPI_SPIDEV=y
2774+# CONFIG_SPI_LOOPBACK_TEST is not set
2775+# CONFIG_SPI_TLE62X0 is not set
2776+# CONFIG_SPI_SLAVE is not set
2777+# CONFIG_SPMI is not set
2778+# CONFIG_HSI is not set
2779+# CONFIG_PPS is not set
2780+
2781+#
2782+# PTP clock support
2783+#
2784+# CONFIG_PTP_1588_CLOCK is not set
2785+
2786+#
2787+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
2788+#
2789+CONFIG_PINCTRL=y
2790+# CONFIG_DEBUG_PINCTRL is not set
2791+# CONFIG_PINCTRL_AMD is not set
2792+# CONFIG_PINCTRL_MCP23S08 is not set
2793+# CONFIG_PINCTRL_SINGLE is not set
2794+# CONFIG_PINCTRL_SX150X is not set
2795+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
2796+CONFIG_GPIOLIB=y
2797+CONFIG_GPIOLIB_FASTPATH_LIMIT=512
2798+CONFIG_OF_GPIO=y
2799+CONFIG_GPIOLIB_IRQCHIP=y
2800+# CONFIG_DEBUG_GPIO is not set
2801+CONFIG_GPIO_SYSFS=y
2802+CONFIG_GPIO_GENERIC=y
2803+
2804+#
2805+# Memory mapped GPIO drivers
2806+#
2807+# CONFIG_GPIO_74XX_MMIO is not set
2808+# CONFIG_GPIO_ALTERA is not set
2809+# CONFIG_GPIO_DWAPB is not set
2810+# CONFIG_GPIO_FTGPIO010 is not set
2811+CONFIG_GPIO_GENERIC_PLATFORM=y
2812+# CONFIG_GPIO_GRGPIO is not set
2813+# CONFIG_GPIO_HLWD is not set
2814+# CONFIG_GPIO_MB86S7X is not set
2815+# CONFIG_GPIO_MOCKUP is not set
2816+# CONFIG_GPIO_MPC8XXX is not set
2817+CONFIG_GPIO_PL061=y
2818+# CONFIG_GPIO_SYSCON is not set
2819+# CONFIG_GPIO_XILINX is not set
2820+# CONFIG_GPIO_ZEVIO is not set
2821+
2822+#
2823+# I2C GPIO expanders
2824+#
2825+# CONFIG_GPIO_ADP5588 is not set
2826+# CONFIG_GPIO_ADNP is not set
2827+# CONFIG_GPIO_MAX7300 is not set
2828+# CONFIG_GPIO_MAX732X is not set
2829+# CONFIG_GPIO_PCA953X is not set
2830+# CONFIG_GPIO_PCF857X is not set
2831+# CONFIG_GPIO_TPIC2810 is not set
2832+
2833+#
2834+# MFD GPIO expanders
2835+#
2836+# CONFIG_HTC_EGPIO is not set
2837+
2838+#
2839+# SPI GPIO expanders
2840+#
2841+# CONFIG_GPIO_74X164 is not set
2842+# CONFIG_GPIO_MAX3191X is not set
2843+# CONFIG_GPIO_MAX7301 is not set
2844+# CONFIG_GPIO_MC33880 is not set
2845+# CONFIG_GPIO_PISOSR is not set
2846+# CONFIG_GPIO_XRA1403 is not set
2847+
2848+#
2849+# USB GPIO expanders
2850+#
2851+# CONFIG_W1 is not set
2852+# CONFIG_POWER_AVS is not set
2853+CONFIG_POWER_RESET=y
2854+# CONFIG_POWER_RESET_BRCMKONA is not set
2855+# CONFIG_POWER_RESET_BRCMSTB is not set
2856+# CONFIG_POWER_RESET_GPIO is not set
2857+# CONFIG_POWER_RESET_GPIO_RESTART is not set
2858+CONFIG_POWER_RESET_HISI=y
2859+# CONFIG_POWER_RESET_LTC2952 is not set
2860+# CONFIG_POWER_RESET_RESTART is not set
2861+# CONFIG_POWER_RESET_VERSATILE is not set
2862+CONFIG_POWER_RESET_SYSCON=y
2863+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set
2864+# CONFIG_SYSCON_REBOOT_MODE is not set
2865+CONFIG_POWER_SUPPLY=y
2866+# CONFIG_POWER_SUPPLY_DEBUG is not set
2867+# CONFIG_PDA_POWER is not set
2868+# CONFIG_TEST_POWER is not set
2869+# CONFIG_CHARGER_ADP5061 is not set
2870+# CONFIG_BATTERY_DS2780 is not set
2871+# CONFIG_BATTERY_DS2781 is not set
2872+# CONFIG_BATTERY_DS2782 is not set
2873+# CONFIG_BATTERY_SBS is not set
2874+# CONFIG_CHARGER_SBS is not set
2875+# CONFIG_MANAGER_SBS is not set
2876+# CONFIG_BATTERY_BQ27XXX is not set
2877+# CONFIG_BATTERY_MAX17040 is not set
2878+# CONFIG_BATTERY_MAX17042 is not set
2879+# CONFIG_CHARGER_MAX8903 is not set
2880+# CONFIG_CHARGER_LP8727 is not set
2881+# CONFIG_CHARGER_GPIO is not set
2882+# CONFIG_CHARGER_LTC3651 is not set
2883+# CONFIG_CHARGER_DETECTOR_MAX14656 is not set
2884+# CONFIG_CHARGER_BQ2415X is not set
2885+# CONFIG_CHARGER_BQ24257 is not set
2886+# CONFIG_CHARGER_BQ24735 is not set
2887+# CONFIG_CHARGER_BQ25890 is not set
2888+# CONFIG_CHARGER_SMB347 is not set
2889+# CONFIG_BATTERY_GAUGE_LTC2941 is not set
2890+# CONFIG_CHARGER_RT9455 is not set
2891+# CONFIG_HWMON is not set
2892+# CONFIG_THERMAL is not set
2893+# CONFIG_WATCHDOG is not set
2894+CONFIG_SSB_POSSIBLE=y
2895+# CONFIG_SSB is not set
2896+CONFIG_BCMA_POSSIBLE=y
2897+# CONFIG_BCMA is not set
2898+
2899+#
2900+# Multifunction device drivers
2901+#
2902+CONFIG_MFD_CORE=y
2903+# CONFIG_MFD_ACT8945A is not set
2904+# CONFIG_MFD_AS3711 is not set
2905+# CONFIG_MFD_AS3722 is not set
2906+# CONFIG_PMIC_ADP5520 is not set
2907+# CONFIG_MFD_AAT2870_CORE is not set
2908+# CONFIG_MFD_ATMEL_FLEXCOM is not set
2909+# CONFIG_MFD_ATMEL_HLCDC is not set
2910+# CONFIG_MFD_BCM590XX is not set
2911+# CONFIG_MFD_BD9571MWV is not set
2912+# CONFIG_MFD_AXP20X_I2C is not set
2913+# CONFIG_MFD_CROS_EC is not set
2914+# CONFIG_MFD_MADERA is not set
2915+# CONFIG_MFD_ASIC3 is not set
2916+# CONFIG_PMIC_DA903X is not set
2917+# CONFIG_MFD_DA9052_SPI is not set
2918+# CONFIG_MFD_DA9052_I2C is not set
2919+# CONFIG_MFD_DA9055 is not set
2920+# CONFIG_MFD_DA9062 is not set
2921+# CONFIG_MFD_DA9063 is not set
2922+# CONFIG_MFD_DA9150 is not set
2923+# CONFIG_MFD_DLN2 is not set
2924+# CONFIG_MFD_MC13XXX_SPI is not set
2925+# CONFIG_MFD_MC13XXX_I2C is not set
2926+# CONFIG_MFD_HI6421_PMIC is not set
2927+CONFIG_MFD_HISI_FMC=y
2928+# CONFIG_HTC_PASIC3 is not set
2929+# CONFIG_HTC_I2CPLD is not set
2930+# CONFIG_MFD_KEMPLD is not set
2931+# CONFIG_MFD_88PM800 is not set
2932+# CONFIG_MFD_88PM805 is not set
2933+# CONFIG_MFD_88PM860X is not set
2934+# CONFIG_MFD_MAX14577 is not set
2935+# CONFIG_MFD_MAX77620 is not set
2936+# CONFIG_MFD_MAX77686 is not set
2937+# CONFIG_MFD_MAX77693 is not set
2938+# CONFIG_MFD_MAX77843 is not set
2939+# CONFIG_MFD_MAX8907 is not set
2940+# CONFIG_MFD_MAX8925 is not set
2941+# CONFIG_MFD_MAX8997 is not set
2942+# CONFIG_MFD_MAX8998 is not set
2943+# CONFIG_MFD_MT6397 is not set
2944+# CONFIG_MFD_MENF21BMC is not set
2945+# CONFIG_EZX_PCAP is not set
2946+# CONFIG_MFD_CPCAP is not set
2947+# CONFIG_MFD_VIPERBOARD is not set
2948+# CONFIG_MFD_RETU is not set
2949+# CONFIG_MFD_PCF50633 is not set
2950+# CONFIG_MFD_PM8XXX is not set
2951+# CONFIG_MFD_RT5033 is not set
2952+# CONFIG_MFD_RC5T583 is not set
2953+# CONFIG_MFD_RK808 is not set
2954+# CONFIG_MFD_RN5T618 is not set
2955+# CONFIG_MFD_SEC_CORE is not set
2956+# CONFIG_MFD_SI476X_CORE is not set
2957+# CONFIG_MFD_SM501 is not set
2958+# CONFIG_MFD_SKY81452 is not set
2959+# CONFIG_MFD_SMSC is not set
2960+# CONFIG_ABX500_CORE is not set
2961+# CONFIG_MFD_STMPE is not set
2962+CONFIG_MFD_SYSCON=y
2963+# CONFIG_MFD_TI_AM335X_TSCADC is not set
2964+# CONFIG_MFD_LP3943 is not set
2965+# CONFIG_MFD_LP8788 is not set
2966+# CONFIG_MFD_TI_LMU is not set
2967+# CONFIG_MFD_PALMAS is not set
2968+# CONFIG_TPS6105X is not set
2969+# CONFIG_TPS65010 is not set
2970+# CONFIG_TPS6507X is not set
2971+# CONFIG_MFD_TPS65086 is not set
2972+# CONFIG_MFD_TPS65090 is not set
2973+# CONFIG_MFD_TPS65217 is not set
2974+# CONFIG_MFD_TI_LP873X is not set
2975+# CONFIG_MFD_TI_LP87565 is not set
2976+# CONFIG_MFD_TPS65218 is not set
2977+# CONFIG_MFD_TPS6586X is not set
2978+# CONFIG_MFD_TPS65910 is not set
2979+# CONFIG_MFD_TPS65912_I2C is not set
2980+# CONFIG_MFD_TPS65912_SPI is not set
2981+# CONFIG_MFD_TPS80031 is not set
2982+# CONFIG_TWL4030_CORE is not set
2983+# CONFIG_TWL6040_CORE is not set
2984+# CONFIG_MFD_WL1273_CORE is not set
2985+# CONFIG_MFD_LM3533 is not set
2986+# CONFIG_MFD_TC3589X is not set
2987+# CONFIG_MFD_T7L66XB is not set
2988+# CONFIG_MFD_TC6387XB is not set
2989+# CONFIG_MFD_TC6393XB is not set
2990+# CONFIG_MFD_ARIZONA_I2C is not set
2991+# CONFIG_MFD_ARIZONA_SPI is not set
2992+# CONFIG_MFD_WM8400 is not set
2993+# CONFIG_MFD_WM831X_I2C is not set
2994+# CONFIG_MFD_WM831X_SPI is not set
2995+# CONFIG_MFD_WM8350_I2C is not set
2996+# CONFIG_MFD_WM8994 is not set
2997+# CONFIG_MFD_ROHM_BD718XX is not set
2998+# CONFIG_REGULATOR is not set
2999+# CONFIG_RC_CORE is not set
3000+CONFIG_MEDIA_SUPPORT=y
3001+
3002+#
3003+# Multimedia core support
3004+#
3005+CONFIG_MEDIA_CAMERA_SUPPORT=y
3006+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
3007+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
3008+# CONFIG_MEDIA_RADIO_SUPPORT is not set
3009+# CONFIG_MEDIA_SDR_SUPPORT is not set
3010+# CONFIG_MEDIA_CEC_SUPPORT is not set
3011+# CONFIG_MEDIA_CONTROLLER is not set
3012+CONFIG_VIDEO_DEV=y
3013+CONFIG_VIDEO_V4L2=y
3014+# CONFIG_VIDEO_ADV_DEBUG is not set
3015+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
3016+
3017+#
3018+# Media drivers
3019+#
3020+CONFIG_MEDIA_USB_SUPPORT=y
3021+
3022+#
3023+# Webcam devices
3024+#
3025+CONFIG_USB_VIDEO_CLASS=y
3026+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
3027+CONFIG_USB_GSPCA=m
3028+# CONFIG_USB_M5602 is not set
3029+# CONFIG_USB_STV06XX is not set
3030+# CONFIG_USB_GL860 is not set
3031+# CONFIG_USB_GSPCA_BENQ is not set
3032+# CONFIG_USB_GSPCA_CONEX is not set
3033+# CONFIG_USB_GSPCA_CPIA1 is not set
3034+# CONFIG_USB_GSPCA_DTCS033 is not set
3035+# CONFIG_USB_GSPCA_ETOMS is not set
3036+# CONFIG_USB_GSPCA_FINEPIX is not set
3037+# CONFIG_USB_GSPCA_JEILINJ is not set
3038+# CONFIG_USB_GSPCA_JL2005BCD is not set
3039+# CONFIG_USB_GSPCA_KINECT is not set
3040+# CONFIG_USB_GSPCA_KONICA is not set
3041+# CONFIG_USB_GSPCA_MARS is not set
3042+# CONFIG_USB_GSPCA_MR97310A is not set
3043+# CONFIG_USB_GSPCA_NW80X is not set
3044+# CONFIG_USB_GSPCA_OV519 is not set
3045+# CONFIG_USB_GSPCA_OV534 is not set
3046+# CONFIG_USB_GSPCA_OV534_9 is not set
3047+# CONFIG_USB_GSPCA_PAC207 is not set
3048+# CONFIG_USB_GSPCA_PAC7302 is not set
3049+# CONFIG_USB_GSPCA_PAC7311 is not set
3050+# CONFIG_USB_GSPCA_SE401 is not set
3051+# CONFIG_USB_GSPCA_SN9C2028 is not set
3052+# CONFIG_USB_GSPCA_SN9C20X is not set
3053+# CONFIG_USB_GSPCA_SONIXB is not set
3054+# CONFIG_USB_GSPCA_SONIXJ is not set
3055+# CONFIG_USB_GSPCA_SPCA500 is not set
3056+# CONFIG_USB_GSPCA_SPCA501 is not set
3057+# CONFIG_USB_GSPCA_SPCA505 is not set
3058+# CONFIG_USB_GSPCA_SPCA506 is not set
3059+# CONFIG_USB_GSPCA_SPCA508 is not set
3060+# CONFIG_USB_GSPCA_SPCA561 is not set
3061+# CONFIG_USB_GSPCA_SPCA1528 is not set
3062+# CONFIG_USB_GSPCA_SQ905 is not set
3063+# CONFIG_USB_GSPCA_SQ905C is not set
3064+# CONFIG_USB_GSPCA_SQ930X is not set
3065+# CONFIG_USB_GSPCA_STK014 is not set
3066+# CONFIG_USB_GSPCA_STK1135 is not set
3067+# CONFIG_USB_GSPCA_STV0680 is not set
3068+# CONFIG_USB_GSPCA_SUNPLUS is not set
3069+# CONFIG_USB_GSPCA_T613 is not set
3070+# CONFIG_USB_GSPCA_TOPRO is not set
3071+# CONFIG_USB_GSPCA_TOUPTEK is not set
3072+# CONFIG_USB_GSPCA_TV8532 is not set
3073+# CONFIG_USB_GSPCA_VC032X is not set
3074+# CONFIG_USB_GSPCA_VICAM is not set
3075+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
3076+# CONFIG_USB_GSPCA_ZC3XX is not set
3077+# CONFIG_USB_PWC is not set
3078+# CONFIG_VIDEO_CPIA2 is not set
3079+# CONFIG_USB_ZR364XX is not set
3080+# CONFIG_USB_STKWEBCAM is not set
3081+# CONFIG_USB_S2255 is not set
3082+# CONFIG_VIDEO_USBTV is not set
3083+
3084+#
3085+# Webcam, TV (analog/digital) USB devices
3086+#
3087+# CONFIG_VIDEO_EM28XX is not set
3088+# CONFIG_V4L_PLATFORM_DRIVERS is not set
3089+# CONFIG_V4L_MEM2MEM_DRIVERS is not set
3090+# CONFIG_V4L_TEST_DRIVERS is not set
3091+
3092+#
3093+# Supported MMC/SDIO adapters
3094+#
3095+# CONFIG_CYPRESS_FIRMWARE is not set
3096+CONFIG_VIDEOBUF2_CORE=y
3097+CONFIG_VIDEOBUF2_V4L2=y
3098+CONFIG_VIDEOBUF2_MEMOPS=y
3099+CONFIG_VIDEOBUF2_VMALLOC=y
3100+
3101+#
3102+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends)
3103+#
3104+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
3105+
3106+#
3107+# Audio decoders, processors and mixers
3108+#
3109+
3110+#
3111+# RDS decoders
3112+#
3113+
3114+#
3115+# Video decoders
3116+#
3117+
3118+#
3119+# Video and audio decoders
3120+#
3121+
3122+#
3123+# Video encoders
3124+#
3125+
3126+#
3127+# Camera sensor devices
3128+#
3129+
3130+#
3131+# Flash devices
3132+#
3133+
3134+#
3135+# Video improvement chips
3136+#
3137+
3138+#
3139+# Audio/Video compression chips
3140+#
3141+
3142+#
3143+# SDR tuner chips
3144+#
3145+
3146+#
3147+# Miscellaneous helper chips
3148+#
3149+
3150+#
3151+# Sensors used on soc_camera driver
3152+#
3153+
3154+#
3155+# Media SPI Adapters
3156+#
3157+
3158+#
3159+# Tools to develop new frontends
3160+#
3161+
3162+#
3163+# Graphics support
3164+#
3165+# CONFIG_IMX_IPUV3_CORE is not set
3166+# CONFIG_DRM is not set
3167+# CONFIG_DRM_DP_CEC is not set
3168+
3169+#
3170+# ACP (Audio CoProcessor) Configuration
3171+#
3172+
3173+#
3174+# AMD Library routines
3175+#
3176+
3177+#
3178+# Frame buffer Devices
3179+#
3180+CONFIG_FB_CMDLINE=y
3181+CONFIG_FB_NOTIFY=y
3182+CONFIG_FB=y
3183+# CONFIG_FIRMWARE_EDID is not set
3184+# CONFIG_FB_FOREIGN_ENDIAN is not set
3185+# CONFIG_FB_MODE_HELPERS is not set
3186+# CONFIG_FB_TILEBLITTING is not set
3187+
3188+#
3189+# Frame buffer hardware drivers
3190+#
3191+# CONFIG_FB_ARMCLCD is not set
3192+# CONFIG_FB_OPENCORES is not set
3193+# CONFIG_FB_S1D13XXX is not set
3194+# CONFIG_FB_SMSCUFX is not set
3195+# CONFIG_FB_UDL is not set
3196+# CONFIG_FB_IBM_GXT4500 is not set
3197+# CONFIG_FB_VIRTUAL is not set
3198+# CONFIG_FB_METRONOME is not set
3199+# CONFIG_FB_BROADSHEET is not set
3200+# CONFIG_FB_SIMPLE is not set
3201+# CONFIG_FB_SSD1307 is not set
3202+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
3203+
3204+#
3205+# Console display driver support
3206+#
3207+CONFIG_DUMMY_CONSOLE=y
3208+# CONFIG_FRAMEBUFFER_CONSOLE is not set
3209+# CONFIG_LOGO is not set
3210+CONFIG_SOUND=y
3211+CONFIG_SND=y
3212+CONFIG_SND_TIMER=y
3213+CONFIG_SND_PCM=y
3214+# CONFIG_SND_OSSEMUL is not set
3215+CONFIG_SND_PCM_TIMER=y
3216+# CONFIG_SND_DYNAMIC_MINORS is not set
3217+CONFIG_SND_SUPPORT_OLD_API=y
3218+CONFIG_SND_PROC_FS=y
3219+CONFIG_SND_VERBOSE_PROCFS=y
3220+# CONFIG_SND_VERBOSE_PRINTK is not set
3221+# CONFIG_SND_DEBUG is not set
3222+# CONFIG_SND_SEQUENCER is not set
3223+CONFIG_SND_DRIVERS=y
3224+# CONFIG_SND_DUMMY is not set
3225+# CONFIG_SND_ALOOP is not set
3226+# CONFIG_SND_MTPAV is not set
3227+# CONFIG_SND_SERIAL_U16550 is not set
3228+# CONFIG_SND_MPU401 is not set
3229+
3230+#
3231+# HD-Audio
3232+#
3233+CONFIG_SND_HDA_PREALLOC_SIZE=64
3234+CONFIG_SND_ARM=y
3235+# CONFIG_SND_ARMAACI is not set
3236+CONFIG_SND_SPI=y
3237+CONFIG_SND_USB=y
3238+# CONFIG_SND_USB_AUDIO is not set
3239+# CONFIG_SND_USB_UA101 is not set
3240+# CONFIG_SND_USB_CAIAQ is not set
3241+# CONFIG_SND_USB_6FIRE is not set
3242+# CONFIG_SND_USB_HIFACE is not set
3243+# CONFIG_SND_BCD2000 is not set
3244+# CONFIG_SND_USB_POD is not set
3245+# CONFIG_SND_USB_PODHD is not set
3246+# CONFIG_SND_USB_TONEPORT is not set
3247+# CONFIG_SND_USB_VARIAX is not set
3248+# CONFIG_SND_SOC is not set
3249+
3250+#
3251+# HID support
3252+#
3253+CONFIG_HID=y
3254+# CONFIG_HID_BATTERY_STRENGTH is not set
3255+# CONFIG_HIDRAW is not set
3256+# CONFIG_UHID is not set
3257+CONFIG_HID_GENERIC=y
3258+
3259+#
3260+# Special HID drivers
3261+#
3262+CONFIG_HID_A4TECH=y
3263+# CONFIG_HID_ACCUTOUCH is not set
3264+# CONFIG_HID_ACRUX is not set
3265+CONFIG_HID_APPLE=y
3266+# CONFIG_HID_APPLEIR is not set
3267+# CONFIG_HID_AUREAL is not set
3268+CONFIG_HID_BELKIN=y
3269+# CONFIG_HID_BETOP_FF is not set
3270+CONFIG_HID_CHERRY=y
3271+CONFIG_HID_CHICONY=y
3272+# CONFIG_HID_COUGAR is not set
3273+# CONFIG_HID_PRODIKEYS is not set
3274+# CONFIG_HID_CMEDIA is not set
3275+CONFIG_HID_CYPRESS=y
3276+# CONFIG_HID_DRAGONRISE is not set
3277+# CONFIG_HID_EMS_FF is not set
3278+# CONFIG_HID_ELECOM is not set
3279+# CONFIG_HID_ELO is not set
3280+CONFIG_HID_EZKEY=y
3281+# CONFIG_HID_GEMBIRD is not set
3282+# CONFIG_HID_GFRM is not set
3283+# CONFIG_HID_HOLTEK is not set
3284+# CONFIG_HID_KEYTOUCH is not set
3285+# CONFIG_HID_KYE is not set
3286+# CONFIG_HID_UCLOGIC is not set
3287+# CONFIG_HID_WALTOP is not set
3288+# CONFIG_HID_GYRATION is not set
3289+# CONFIG_HID_ICADE is not set
3290+CONFIG_HID_ITE=y
3291+# CONFIG_HID_JABRA is not set
3292+# CONFIG_HID_TWINHAN is not set
3293+CONFIG_HID_KENSINGTON=y
3294+# CONFIG_HID_LCPOWER is not set
3295+# CONFIG_HID_LENOVO is not set
3296+CONFIG_HID_LOGITECH=y
3297+# CONFIG_HID_LOGITECH_HIDPP is not set
3298+# CONFIG_LOGITECH_FF is not set
3299+# CONFIG_LOGIRUMBLEPAD2_FF is not set
3300+# CONFIG_LOGIG940_FF is not set
3301+# CONFIG_LOGIWHEELS_FF is not set
3302+# CONFIG_HID_MAGICMOUSE is not set
3303+# CONFIG_HID_MAYFLASH is not set
3304+CONFIG_HID_REDRAGON=y
3305+CONFIG_HID_MICROSOFT=y
3306+CONFIG_HID_MONTEREY=y
3307+# CONFIG_HID_MULTITOUCH is not set
3308+# CONFIG_HID_NTI is not set
3309+# CONFIG_HID_NTRIG is not set
3310+# CONFIG_HID_ORTEK is not set
3311+# CONFIG_HID_PANTHERLORD is not set
3312+# CONFIG_HID_PENMOUNT is not set
3313+# CONFIG_HID_PETALYNX is not set
3314+# CONFIG_HID_PICOLCD is not set
3315+# CONFIG_HID_PLANTRONICS is not set
3316+# CONFIG_HID_PRIMAX is not set
3317+# CONFIG_HID_RETRODE is not set
3318+# CONFIG_HID_ROCCAT is not set
3319+# CONFIG_HID_SAITEK is not set
3320+# CONFIG_HID_SAMSUNG is not set
3321+# CONFIG_HID_SPEEDLINK is not set
3322+# CONFIG_HID_STEAM is not set
3323+# CONFIG_HID_STEELSERIES is not set
3324+# CONFIG_HID_SUNPLUS is not set
3325+# CONFIG_HID_RMI is not set
3326+# CONFIG_HID_GREENASIA is not set
3327+# CONFIG_HID_SMARTJOYPLUS is not set
3328+# CONFIG_HID_TIVO is not set
3329+# CONFIG_HID_TOPSEED is not set
3330+# CONFIG_HID_THRUSTMASTER is not set
3331+# CONFIG_HID_UDRAW_PS3 is not set
3332+# CONFIG_HID_WACOM is not set
3333+# CONFIG_HID_XINMO is not set
3334+# CONFIG_HID_ZEROPLUS is not set
3335+# CONFIG_HID_ZYDACRON is not set
3336+# CONFIG_HID_SENSOR_HUB is not set
3337+# CONFIG_HID_ALPS is not set
3338+
3339+#
3340+# USB HID support
3341+#
3342+CONFIG_USB_HID=y
3343+# CONFIG_HID_PID is not set
3344+# CONFIG_USB_HIDDEV is not set
3345+
3346+#
3347+# I2C HID support
3348+#
3349+# CONFIG_I2C_HID is not set
3350+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
3351+CONFIG_USB_SUPPORT=y
3352+CONFIG_USB_COMMON=y
3353+CONFIG_USB_ARCH_HAS_HCD=y
3354+CONFIG_USB=y
3355+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
3356+
3357+#
3358+# Miscellaneous USB options
3359+#
3360+CONFIG_USB_DEFAULT_PERSIST=y
3361+# CONFIG_USB_DYNAMIC_MINORS is not set
3362+# CONFIG_USB_OTG is not set
3363+# CONFIG_USB_OTG_WHITELIST is not set
3364+# CONFIG_USB_MON is not set
3365+# CONFIG_USB_WUSB_CBAF is not set
3366+
3367+#
3368+# USB Host Controller Drivers
3369+#
3370+# CONFIG_USB_C67X00_HCD is not set
3371+CONFIG_USB_XHCI_HCD=y
3372+# CONFIG_USB_XHCI_DBGCAP is not set
3373+CONFIG_USB_XHCI_PLATFORM=y
3374+# CONFIG_USB_EHCI_HCD is not set
3375+# CONFIG_USB_OXU210HP_HCD is not set
3376+# CONFIG_USB_ISP116X_HCD is not set
3377+# CONFIG_USB_FOTG210_HCD is not set
3378+# CONFIG_USB_MAX3421_HCD is not set
3379+# CONFIG_USB_OHCI_HCD is not set
3380+# CONFIG_USB_SL811_HCD is not set
3381+# CONFIG_USB_R8A66597_HCD is not set
3382+# CONFIG_USB_HCD_TEST_MODE is not set
3383+
3384+#
3385+# USB Device Class drivers
3386+#
3387+# CONFIG_USB_ACM is not set
3388+# CONFIG_USB_PRINTER is not set
3389+# CONFIG_USB_WDM is not set
3390+# CONFIG_USB_TMC is not set
3391+
3392+#
3393+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
3394+#
3395+
3396+#
3397+# also be needed; see USB_STORAGE Help for more info
3398+#
3399+CONFIG_USB_STORAGE=y
3400+# CONFIG_USB_STORAGE_DEBUG is not set
3401+# CONFIG_USB_STORAGE_REALTEK is not set
3402+# CONFIG_USB_STORAGE_DATAFAB is not set
3403+# CONFIG_USB_STORAGE_FREECOM is not set
3404+# CONFIG_USB_STORAGE_ISD200 is not set
3405+# CONFIG_USB_STORAGE_USBAT is not set
3406+# CONFIG_USB_STORAGE_SDDR09 is not set
3407+# CONFIG_USB_STORAGE_SDDR55 is not set
3408+# CONFIG_USB_STORAGE_JUMPSHOT is not set
3409+# CONFIG_USB_STORAGE_ALAUDA is not set
3410+# CONFIG_USB_STORAGE_ONETOUCH is not set
3411+# CONFIG_USB_STORAGE_KARMA is not set
3412+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
3413+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
3414+# CONFIG_USB_UAS is not set
3415+
3416+#
3417+# USB Imaging devices
3418+#
3419+# CONFIG_USB_MDC800 is not set
3420+# CONFIG_USB_MICROTEK is not set
3421+# CONFIG_USBIP_CORE is not set
3422+# CONFIG_USB_MUSB_HDRC is not set
3423+CONFIG_USB_DWC3=y
3424+# CONFIG_USB_DWC3_HOST is not set
3425+CONFIG_USB_DWC3_GADGET=y
3426+
3427+#
3428+# Platform Glue Driver Support
3429+#
3430+# CONFIG_USB_DWC3_OF_SIMPLE is not set
3431+# CONFIG_USB_DWC2 is not set
3432+# CONFIG_USB_CHIPIDEA is not set
3433+# CONFIG_USB_ISP1760 is not set
3434+
3435+#
3436+# USB port drivers
3437+#
3438+# CONFIG_USB_SERIAL is not set
3439+
3440+#
3441+# USB Miscellaneous drivers
3442+#
3443+# CONFIG_USB_EMI62 is not set
3444+# CONFIG_USB_EMI26 is not set
3445+# CONFIG_USB_ADUTUX is not set
3446+# CONFIG_USB_SEVSEG is not set
3447+# CONFIG_USB_LEGOTOWER is not set
3448+# CONFIG_USB_LCD is not set
3449+# CONFIG_USB_CYPRESS_CY7C63 is not set
3450+# CONFIG_USB_CYTHERM is not set
3451+# CONFIG_USB_IDMOUSE is not set
3452+# CONFIG_USB_FTDI_ELAN is not set
3453+# CONFIG_USB_APPLEDISPLAY is not set
3454+# CONFIG_USB_LD is not set
3455+# CONFIG_USB_TRANCEVIBRATOR is not set
3456+# CONFIG_USB_IOWARRIOR is not set
3457+# CONFIG_USB_TEST is not set
3458+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
3459+# CONFIG_USB_ISIGHTFW is not set
3460+# CONFIG_USB_YUREX is not set
3461+# CONFIG_USB_EZUSB_FX2 is not set
3462+# CONFIG_USB_HUB_USB251XB is not set
3463+# CONFIG_USB_HSIC_USB3503 is not set
3464+# CONFIG_USB_HSIC_USB4604 is not set
3465+# CONFIG_USB_LINK_LAYER_TEST is not set
3466+
3467+#
3468+# USB Physical Layer drivers
3469+#
3470+# CONFIG_NOP_USB_XCEIV is not set
3471+# CONFIG_USB_GPIO_VBUS is not set
3472+# CONFIG_USB_ISP1301 is not set
3473+# CONFIG_USB_ULPI is not set
3474+CONFIG_USB_GADGET=y
3475+# CONFIG_USB_GADGET_DEBUG is not set
3476+# CONFIG_USB_GADGET_DEBUG_FILES is not set
3477+# CONFIG_USB_GADGET_DEBUG_FS is not set
3478+CONFIG_USB_GADGET_VBUS_DRAW=2
3479+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
3480+# CONFIG_U_SERIAL_CONSOLE is not set
3481+
3482+#
3483+# USB Peripheral Controller
3484+#
3485+# CONFIG_USB_FUSB300 is not set
3486+# CONFIG_USB_FOTG210_UDC is not set
3487+# CONFIG_USB_GR_UDC is not set
3488+# CONFIG_USB_R8A66597 is not set
3489+# CONFIG_USB_PXA27X is not set
3490+# CONFIG_USB_MV_UDC is not set
3491+# CONFIG_USB_MV_U3D is not set
3492+# CONFIG_USB_SNP_UDC_PLAT is not set
3493+# CONFIG_USB_M66592 is not set
3494+# CONFIG_USB_BDC_UDC is not set
3495+# CONFIG_USB_NET2272 is not set
3496+# CONFIG_USB_GADGET_XILINX is not set
3497+# CONFIG_USB_DUMMY_HCD is not set
3498+CONFIG_USB_LIBCOMPOSITE=y
3499+CONFIG_USB_F_ACM=y
3500+CONFIG_USB_U_SERIAL=y
3501+CONFIG_USB_U_ETHER=y
3502+CONFIG_USB_U_AUDIO=y
3503+CONFIG_USB_F_RNDIS=y
3504+CONFIG_USB_F_MASS_STORAGE=y
3505+CONFIG_USB_F_UAC1=y
3506+CONFIG_USB_F_UVC=y
3507+CONFIG_USB_CONFIGFS=y
3508+# CONFIG_USB_CONFIGFS_SERIAL is not set
3509+CONFIG_USB_CONFIGFS_ACM=y
3510+# CONFIG_USB_CONFIGFS_OBEX is not set
3511+# CONFIG_USB_CONFIGFS_NCM is not set
3512+# CONFIG_USB_CONFIGFS_ECM is not set
3513+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set
3514+CONFIG_USB_CONFIGFS_RNDIS=y
3515+# CONFIG_USB_CONFIGFS_EEM is not set
3516+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
3517+# CONFIG_USB_CONFIGFS_F_LB_SS is not set
3518+# CONFIG_USB_CONFIGFS_F_FS is not set
3519+CONFIG_USB_CONFIGFS_F_UAC1=y
3520+# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set
3521+# CONFIG_USB_CONFIGFS_F_UAC2 is not set
3522+# CONFIG_USB_CONFIGFS_F_MIDI is not set
3523+# CONFIG_USB_CONFIGFS_F_HID is not set
3524+CONFIG_USB_CONFIGFS_F_UVC=y
3525+# CONFIG_USB_CONFIGFS_F_PRINTER is not set
3526+# CONFIG_TYPEC is not set
3527+# CONFIG_USB_ROLE_SWITCH is not set
3528+# CONFIG_USB_ULPI_BUS is not set
3529+# CONFIG_UWB is not set
3530+CONFIG_MMC=y
3531+CONFIG_PWRSEQ_EMMC=y
3532+CONFIG_PWRSEQ_SIMPLE=y
3533+CONFIG_MMC_BLOCK=y
3534+CONFIG_MMC_BLOCK_MINORS=8
3535+# CONFIG_SDIO_UART is not set
3536+# CONFIG_MMC_TEST is not set
3537+
3538+#
3539+# MMC/SD/SDIO Host Controller Drivers
3540+#
3541+# CONFIG_MMC_DEBUG is not set
3542+# CONFIG_MMC_ARMMMCI is not set
3543+# CONFIG_MMC_SDHCI is not set
3544+# CONFIG_MMC_SPI is not set
3545+# CONFIG_MMC_DW is not set
3546+# CONFIG_MMC_VUB300 is not set
3547+# CONFIG_MMC_USHC is not set
3548+# CONFIG_MMC_USDHI6ROL0 is not set
3549+# CONFIG_MMC_CQHCI is not set
3550+# CONFIG_MMC_MTK is not set
3551+# CONFIG_MMC_CQ_HCI is not set
3552+CONFIG_HIMCI=y
3553+CONFIG_SEND_AUTO_STOP=y
3554+# CONFIG_MEMSTICK is not set
3555+# CONFIG_NEW_LEDS is not set
3556+# CONFIG_ACCESSIBILITY is not set
3557+# CONFIG_INFINIBAND is not set
3558+CONFIG_EDAC_ATOMIC_SCRUB=y
3559+CONFIG_EDAC_SUPPORT=y
3560+CONFIG_RTC_LIB=y
3561+CONFIG_RTC_CLASS=y
3562+CONFIG_RTC_HCTOSYS=y
3563+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
3564+CONFIG_RTC_SYSTOHC=y
3565+CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
3566+# CONFIG_RTC_DEBUG is not set
3567+CONFIG_RTC_NVMEM=y
3568+
3569+#
3570+# RTC interfaces
3571+#
3572+CONFIG_RTC_INTF_SYSFS=y
3573+CONFIG_RTC_INTF_PROC=y
3574+CONFIG_RTC_INTF_DEV=y
3575+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
3576+# CONFIG_RTC_DRV_TEST is not set
3577+
3578+#
3579+# I2C RTC drivers
3580+#
3581+# CONFIG_RTC_DRV_ABB5ZES3 is not set
3582+# CONFIG_RTC_DRV_ABX80X is not set
3583+# CONFIG_RTC_DRV_DS1307 is not set
3584+# CONFIG_RTC_DRV_DS1374 is not set
3585+# CONFIG_RTC_DRV_DS1672 is not set
3586+# CONFIG_RTC_DRV_HYM8563 is not set
3587+# CONFIG_RTC_DRV_MAX6900 is not set
3588+# CONFIG_RTC_DRV_RS5C372 is not set
3589+# CONFIG_RTC_DRV_ISL1208 is not set
3590+# CONFIG_RTC_DRV_ISL12022 is not set
3591+# CONFIG_RTC_DRV_ISL12026 is not set
3592+# CONFIG_RTC_DRV_X1205 is not set
3593+# CONFIG_RTC_DRV_PCF8523 is not set
3594+# CONFIG_RTC_DRV_PCF85063 is not set
3595+# CONFIG_RTC_DRV_PCF85363 is not set
3596+# CONFIG_RTC_DRV_PCF8563 is not set
3597+# CONFIG_RTC_DRV_PCF8583 is not set
3598+# CONFIG_RTC_DRV_M41T80 is not set
3599+# CONFIG_RTC_DRV_BQ32K is not set
3600+# CONFIG_RTC_DRV_S35390A is not set
3601+# CONFIG_RTC_DRV_FM3130 is not set
3602+# CONFIG_RTC_DRV_RX8010 is not set
3603+# CONFIG_RTC_DRV_RX8581 is not set
3604+# CONFIG_RTC_DRV_RX8025 is not set
3605+# CONFIG_RTC_DRV_EM3027 is not set
3606+# CONFIG_RTC_DRV_RV8803 is not set
3607+
3608+#
3609+# SPI RTC drivers
3610+#
3611+# CONFIG_RTC_DRV_M41T93 is not set
3612+# CONFIG_RTC_DRV_M41T94 is not set
3613+# CONFIG_RTC_DRV_DS1302 is not set
3614+# CONFIG_RTC_DRV_DS1305 is not set
3615+# CONFIG_RTC_DRV_DS1343 is not set
3616+# CONFIG_RTC_DRV_DS1347 is not set
3617+# CONFIG_RTC_DRV_DS1390 is not set
3618+# CONFIG_RTC_DRV_MAX6916 is not set
3619+# CONFIG_RTC_DRV_R9701 is not set
3620+# CONFIG_RTC_DRV_RX4581 is not set
3621+# CONFIG_RTC_DRV_RX6110 is not set
3622+# CONFIG_RTC_DRV_RS5C348 is not set
3623+# CONFIG_RTC_DRV_MAX6902 is not set
3624+# CONFIG_RTC_DRV_PCF2123 is not set
3625+# CONFIG_RTC_DRV_MCP795 is not set
3626+CONFIG_RTC_I2C_AND_SPI=y
3627+
3628+#
3629+# SPI and I2C RTC drivers
3630+#
3631+# CONFIG_RTC_DRV_DS3232 is not set
3632+# CONFIG_RTC_DRV_PCF2127 is not set
3633+# CONFIG_RTC_DRV_RV3029C2 is not set
3634+
3635+#
3636+# Platform RTC drivers
3637+#
3638+CONFIG_RTC_DRV_HIBVT=y
3639+# CONFIG_RTC_DRV_CMOS is not set
3640+# CONFIG_RTC_DRV_DS1286 is not set
3641+# CONFIG_RTC_DRV_DS1511 is not set
3642+# CONFIG_RTC_DRV_DS1553 is not set
3643+# CONFIG_RTC_DRV_DS1685_FAMILY is not set
3644+# CONFIG_RTC_DRV_DS1742 is not set
3645+# CONFIG_RTC_DRV_DS2404 is not set
3646+# CONFIG_RTC_DRV_STK17TA8 is not set
3647+# CONFIG_RTC_DRV_M48T86 is not set
3648+# CONFIG_RTC_DRV_M48T35 is not set
3649+# CONFIG_RTC_DRV_M48T59 is not set
3650+# CONFIG_RTC_DRV_MSM6242 is not set
3651+# CONFIG_RTC_DRV_BQ4802 is not set
3652+# CONFIG_RTC_DRV_RP5C01 is not set
3653+# CONFIG_RTC_DRV_V3020 is not set
3654+# CONFIG_RTC_DRV_ZYNQMP is not set
3655+
3656+#
3657+# on-CPU RTC drivers
3658+#
3659+# CONFIG_RTC_DRV_PL030 is not set
3660+# CONFIG_RTC_DRV_PL031 is not set
3661+# CONFIG_RTC_DRV_FTRTC010 is not set
3662+# CONFIG_RTC_DRV_SNVS is not set
3663+# CONFIG_RTC_DRV_R7301 is not set
3664+
3665+#
3666+# HID Sensor RTC drivers
3667+#
3668+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
3669+# CONFIG_DMADEVICES is not set
3670+
3671+#
3672+# DMABUF options
3673+#
3674+# CONFIG_SYNC_FILE is not set
3675+# CONFIG_AUXDISPLAY is not set
3676+# CONFIG_UIO is not set
3677+# CONFIG_VIRT_DRIVERS is not set
3678+CONFIG_VIRTIO_MENU=y
3679+# CONFIG_VIRTIO_MMIO is not set
3680+
3681+#
3682+# Microsoft Hyper-V guest support
3683+#
3684+# CONFIG_STAGING is not set
3685+# CONFIG_GOLDFISH is not set
3686+# CONFIG_CHROME_PLATFORMS is not set
3687+# CONFIG_MELLANOX_PLATFORM is not set
3688+CONFIG_CLKDEV_LOOKUP=y
3689+CONFIG_HAVE_CLK_PREPARE=y
3690+CONFIG_COMMON_CLK=y
3691+
3692+#
3693+# Common Clock Framework
3694+#
3695+# CONFIG_CLK_HSDK is not set
3696+# CONFIG_COMMON_CLK_MAX9485 is not set
3697+# CONFIG_COMMON_CLK_SI5351 is not set
3698+# CONFIG_COMMON_CLK_SI514 is not set
3699+# CONFIG_COMMON_CLK_SI544 is not set
3700+# CONFIG_COMMON_CLK_SI570 is not set
3701+# CONFIG_COMMON_CLK_CDCE706 is not set
3702+# CONFIG_COMMON_CLK_CDCE925 is not set
3703+# CONFIG_COMMON_CLK_CS2000_CP is not set
3704+# CONFIG_CLK_QORIQ is not set
3705+# CONFIG_COMMON_CLK_VC5 is not set
3706+CONFIG_COMMON_CLK_HI3516DV300=y
3707+CONFIG_RESET_HISI=y
3708+# CONFIG_HWSPINLOCK is not set
3709+
3710+#
3711+# Clock Source drivers
3712+#
3713+CONFIG_TIMER_OF=y
3714+CONFIG_TIMER_PROBE=y
3715+CONFIG_CLKSRC_MMIO=y
3716+CONFIG_ARM_ARCH_TIMER=y
3717+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
3718+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set
3719+CONFIG_ARM_TIMER_SP804=y
3720+# CONFIG_TIMER_HISP804 is not set
3721+# CONFIG_MAILBOX is not set
3722+# CONFIG_IOMMU_SUPPORT is not set
3723+
3724+#
3725+# Remoteproc drivers
3726+#
3727+# CONFIG_REMOTEPROC is not set
3728+
3729+#
3730+# Rpmsg drivers
3731+#
3732+# CONFIG_RPMSG_VIRTIO is not set
3733+
3734+#
3735+# SOC (System On Chip) specific Drivers
3736+#
3737+
3738+#
3739+# Amlogic SoC drivers
3740+#
3741+
3742+#
3743+# Broadcom SoC drivers
3744+#
3745+# CONFIG_SOC_BRCMSTB is not set
3746+
3747+#
3748+# NXP/Freescale QorIQ SoC drivers
3749+#
3750+
3751+#
3752+# i.MX SoC drivers
3753+#
3754+
3755+#
3756+# Qualcomm SoC drivers
3757+#
3758+# CONFIG_SOC_TI is not set
3759+
3760+#
3761+# Xilinx SoC drivers
3762+#
3763+# CONFIG_XILINX_VCU is not set
3764+# CONFIG_PM_DEVFREQ is not set
3765+# CONFIG_EXTCON is not set
3766+# CONFIG_MEMORY is not set
3767+# CONFIG_IIO is not set
3768+# CONFIG_PWM is not set
3769+
3770+#
3771+# IRQ chip support
3772+#
3773+CONFIG_IRQCHIP=y
3774+CONFIG_ARM_GIC=y
3775+CONFIG_ARM_GIC_MAX_NR=1
3776+# CONFIG_IPACK_BUS is not set
3777+CONFIG_RESET_CONTROLLER=y
3778+# CONFIG_RESET_TI_SYSCON is not set
3779+# CONFIG_FMC is not set
3780+
3781+#
3782+# PHY Subsystem
3783+#
3784+CONFIG_GENERIC_PHY=y
3785+# CONFIG_BCM_KONA_USB2_PHY is not set
3786+# CONFIG_PHY_PXA_28NM_HSIC is not set
3787+# CONFIG_PHY_PXA_28NM_USB2 is not set
3788+# CONFIG_PHY_MAPPHONE_MDM6600 is not set
3789+CONFIG_HI_USB_PHY=y
3790+CONFIG_PHY_HISI_USB2=y
3791+CONFIG_HIBVT_USB_PHY=y
3792+CONFIG_USB_MODE_OPTION=y
3793+CONFIG_USB_DRD0_IN_HOST=y
3794+# CONFIG_POWERCAP is not set
3795+# CONFIG_MCB is not set
3796+# CONFIG_RAS is not set
3797+# CONFIG_DAX is not set
3798+CONFIG_NVMEM=y
3799+
3800+#
3801+# HW tracing support
3802+#
3803+# CONFIG_STM is not set
3804+# CONFIG_INTEL_TH is not set
3805+# CONFIG_FPGA is not set
3806+# CONFIG_FSI is not set
3807+# CONFIG_TEE is not set
3808+# CONFIG_SIOX is not set
3809+# CONFIG_SLIMBUS is not set
3810+# CONFIG_HI_DMAC is not set
3811+# CONFIG_HIEDMAC is not set
3812+
3813+#
3814+# Hisilicon driver support
3815+#
3816+# CONFIG_CMA_MEM_SHARED is not set
3817+# CONFIG_CMA_ADVANCE_SHARE is not set
3818+
3819+#
3820+# File systems
3821+#
3822+CONFIG_DCACHE_WORD_ACCESS=y
3823+CONFIG_FS_IOMAP=y
3824+# CONFIG_EXT2_FS is not set
3825+# CONFIG_EXT3_FS is not set
3826+CONFIG_EXT4_FS=y
3827+CONFIG_EXT4_USE_FOR_EXT2=y
3828+# CONFIG_EXT4_FS_POSIX_ACL is not set
3829+# CONFIG_EXT4_FS_SECURITY is not set
3830+# CONFIG_EXT4_ENCRYPTION is not set
3831+# CONFIG_EXT4_DEBUG is not set
3832+CONFIG_JBD2=y
3833+# CONFIG_JBD2_DEBUG is not set
3834+CONFIG_FS_MBCACHE=y
3835+CONFIG_REISERFS_FS=m
3836+CONFIG_REISERFS_CHECK=y
3837+CONFIG_REISERFS_PROC_INFO=y
3838+CONFIG_REISERFS_FS_XATTR=y
3839+CONFIG_REISERFS_FS_POSIX_ACL=y
3840+CONFIG_REISERFS_FS_SECURITY=y
3841+CONFIG_JFS_FS=m
3842+CONFIG_JFS_POSIX_ACL=y
3843+CONFIG_JFS_SECURITY=y
3844+CONFIG_JFS_DEBUG=y
3845+CONFIG_JFS_STATISTICS=y
3846+CONFIG_XFS_FS=m
3847+CONFIG_XFS_QUOTA=y
3848+CONFIG_XFS_POSIX_ACL=y
3849+CONFIG_XFS_RT=y
3850+# CONFIG_XFS_ONLINE_SCRUB is not set
3851+# CONFIG_XFS_WARN is not set
3852+# CONFIG_XFS_DEBUG is not set
3853+# CONFIG_GFS2_FS is not set
3854+# CONFIG_OCFS2_FS is not set
3855+# CONFIG_BTRFS_FS is not set
3856+# CONFIG_NILFS2_FS is not set
3857+# CONFIG_F2FS_FS is not set
3858+CONFIG_FS_POSIX_ACL=y
3859+CONFIG_EXPORTFS=y
3860+# CONFIG_EXPORTFS_BLOCK_OPS is not set
3861+CONFIG_FILE_LOCKING=y
3862+CONFIG_MANDATORY_FILE_LOCKING=y
3863+# CONFIG_FS_ENCRYPTION is not set
3864+CONFIG_FSNOTIFY=y
3865+CONFIG_DNOTIFY=y
3866+CONFIG_INOTIFY_USER=y
3867+# CONFIG_FANOTIFY is not set
3868+# CONFIG_QUOTA is not set
3869+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
3870+CONFIG_QUOTACTL=y
3871+# CONFIG_AUTOFS4_FS is not set
3872+# CONFIG_AUTOFS_FS is not set
3873+# CONFIG_FUSE_FS is not set
3874+# CONFIG_OVERLAY_FS is not set
3875+
3876+#
3877+# Caches
3878+#
3879+# CONFIG_FSCACHE is not set
3880+
3881+#
3882+# CD-ROM/DVD Filesystems
3883+#
3884+# CONFIG_ISO9660_FS is not set
3885+# CONFIG_UDF_FS is not set
3886+
3887+#
3888+# DOS/FAT/NT Filesystems
3889+#
3890+CONFIG_FAT_FS=y
3891+CONFIG_MSDOS_FS=y
3892+CONFIG_VFAT_FS=y
3893+CONFIG_FAT_DEFAULT_CODEPAGE=437
3894+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
3895+# CONFIG_FAT_DEFAULT_UTF8 is not set
3896+# CONFIG_NTFS_FS is not set
3897+
3898+#
3899+# Pseudo filesystems
3900+#
3901+CONFIG_PROC_FS=y
3902+CONFIG_PROC_SYSCTL=y
3903+CONFIG_PROC_PAGE_MONITOR=y
3904+# CONFIG_PROC_CHILDREN is not set
3905+CONFIG_KERNFS=y
3906+CONFIG_SYSFS=y
3907+CONFIG_TMPFS=y
3908+# CONFIG_TMPFS_POSIX_ACL is not set
3909+# CONFIG_TMPFS_XATTR is not set
3910+CONFIG_MEMFD_CREATE=y
3911+CONFIG_CONFIGFS_FS=y
3912+CONFIG_MISC_FILESYSTEMS=y
3913+# CONFIG_ORANGEFS_FS is not set
3914+# CONFIG_ADFS_FS is not set
3915+# CONFIG_AFFS_FS is not set
3916+# CONFIG_ECRYPT_FS is not set
3917+# CONFIG_HFS_FS is not set
3918+# CONFIG_HFSPLUS_FS is not set
3919+# CONFIG_BEFS_FS is not set
3920+# CONFIG_BFS_FS is not set
3921+# CONFIG_EFS_FS is not set
3922+CONFIG_CRAMFS=y
3923+CONFIG_CRAMFS_BLOCKDEV=y
3924+# CONFIG_SQUASHFS is not set
3925+# CONFIG_VXFS_FS is not set
3926+# CONFIG_MINIX_FS is not set
3927+# CONFIG_OMFS_FS is not set
3928+# CONFIG_HPFS_FS is not set
3929+# CONFIG_QNX4FS_FS is not set
3930+# CONFIG_QNX6FS_FS is not set
3931+# CONFIG_ROMFS_FS is not set
3932+# CONFIG_PSTORE is not set
3933+# CONFIG_SYSV_FS is not set
3934+# CONFIG_UFS_FS is not set
3935+CONFIG_NETWORK_FILESYSTEMS=y
3936+CONFIG_NFS_FS=y
3937+CONFIG_NFS_V2=y
3938+CONFIG_NFS_V3=y
3939+CONFIG_NFS_V3_ACL=y
3940+CONFIG_NFS_V4=y
3941+# CONFIG_NFS_SWAP is not set
3942+# CONFIG_NFS_V4_1 is not set
3943+# CONFIG_ROOT_NFS is not set
3944+# CONFIG_NFS_USE_LEGACY_DNS is not set
3945+CONFIG_NFS_USE_KERNEL_DNS=y
3946+# CONFIG_NFSD is not set
3947+CONFIG_GRACE_PERIOD=y
3948+CONFIG_LOCKD=y
3949+CONFIG_LOCKD_V4=y
3950+CONFIG_NFS_ACL_SUPPORT=y
3951+CONFIG_NFS_COMMON=y
3952+CONFIG_SUNRPC=y
3953+CONFIG_SUNRPC_GSS=y
3954+# CONFIG_SUNRPC_DEBUG is not set
3955+# CONFIG_CEPH_FS is not set
3956+# CONFIG_CIFS is not set
3957+# CONFIG_CODA_FS is not set
3958+# CONFIG_AFS_FS is not set
3959+CONFIG_NLS=y
3960+CONFIG_NLS_DEFAULT="iso8859-1"
3961+CONFIG_NLS_CODEPAGE_437=y
3962+CONFIG_NLS_CODEPAGE_737=m
3963+CONFIG_NLS_CODEPAGE_775=m
3964+CONFIG_NLS_CODEPAGE_850=m
3965+CONFIG_NLS_CODEPAGE_852=m
3966+CONFIG_NLS_CODEPAGE_855=m
3967+CONFIG_NLS_CODEPAGE_857=m
3968+CONFIG_NLS_CODEPAGE_860=m
3969+CONFIG_NLS_CODEPAGE_861=m
3970+CONFIG_NLS_CODEPAGE_862=m
3971+CONFIG_NLS_CODEPAGE_863=m
3972+CONFIG_NLS_CODEPAGE_864=m
3973+CONFIG_NLS_CODEPAGE_865=m
3974+CONFIG_NLS_CODEPAGE_866=m
3975+CONFIG_NLS_CODEPAGE_869=m
3976+CONFIG_NLS_CODEPAGE_936=y
3977+CONFIG_NLS_CODEPAGE_950=m
3978+CONFIG_NLS_CODEPAGE_932=m
3979+CONFIG_NLS_CODEPAGE_949=m
3980+CONFIG_NLS_CODEPAGE_874=m
3981+CONFIG_NLS_ISO8859_8=m
3982+CONFIG_NLS_CODEPAGE_1250=m
3983+CONFIG_NLS_CODEPAGE_1251=m
3984+CONFIG_NLS_ASCII=y
3985+CONFIG_NLS_ISO8859_1=y
3986+CONFIG_NLS_ISO8859_2=m
3987+CONFIG_NLS_ISO8859_3=m
3988+CONFIG_NLS_ISO8859_4=m
3989+CONFIG_NLS_ISO8859_5=m
3990+CONFIG_NLS_ISO8859_6=m
3991+CONFIG_NLS_ISO8859_7=m
3992+CONFIG_NLS_ISO8859_9=m
3993+CONFIG_NLS_ISO8859_13=m
3994+CONFIG_NLS_ISO8859_14=m
3995+CONFIG_NLS_ISO8859_15=m
3996+CONFIG_NLS_KOI8_R=m
3997+CONFIG_NLS_KOI8_U=m
3998+# CONFIG_NLS_MAC_ROMAN is not set
3999+# CONFIG_NLS_MAC_CELTIC is not set
4000+# CONFIG_NLS_MAC_CENTEURO is not set
4001+# CONFIG_NLS_MAC_CROATIAN is not set
4002+# CONFIG_NLS_MAC_CYRILLIC is not set
4003+# CONFIG_NLS_MAC_GAELIC is not set
4004+# CONFIG_NLS_MAC_GREEK is not set
4005+# CONFIG_NLS_MAC_ICELAND is not set
4006+# CONFIG_NLS_MAC_INUIT is not set
4007+# CONFIG_NLS_MAC_ROMANIAN is not set
4008+# CONFIG_NLS_MAC_TURKISH is not set
4009+CONFIG_NLS_UTF8=y
4010+# CONFIG_DLM is not set
4011+
4012+#
4013+# Security options
4014+#
4015+CONFIG_KEYS=y
4016+# CONFIG_PERSISTENT_KEYRINGS is not set
4017+# CONFIG_BIG_KEYS is not set
4018+# CONFIG_ENCRYPTED_KEYS is not set
4019+# CONFIG_KEY_DH_OPERATIONS is not set
4020+# CONFIG_SECURITY_DMESG_RESTRICT is not set
4021+# CONFIG_SECURITY is not set
4022+# CONFIG_SECURITYFS is not set
4023+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
4024+# CONFIG_HARDENED_USERCOPY is not set
4025+# CONFIG_FORTIFY_SOURCE is not set
4026+# CONFIG_STATIC_USERMODEHELPER is not set
4027+CONFIG_DEFAULT_SECURITY_DAC=y
4028+CONFIG_DEFAULT_SECURITY=""
4029+CONFIG_CRYPTO=y
4030+
4031+#
4032+# Crypto core or helper
4033+#
4034+CONFIG_CRYPTO_ALGAPI=y
4035+CONFIG_CRYPTO_ALGAPI2=y
4036+CONFIG_CRYPTO_AEAD=m
4037+CONFIG_CRYPTO_AEAD2=y
4038+CONFIG_CRYPTO_BLKCIPHER2=y
4039+CONFIG_CRYPTO_HASH=y
4040+CONFIG_CRYPTO_HASH2=y
4041+CONFIG_CRYPTO_RNG=y
4042+CONFIG_CRYPTO_RNG2=y
4043+CONFIG_CRYPTO_RNG_DEFAULT=m
4044+CONFIG_CRYPTO_AKCIPHER2=y
4045+CONFIG_CRYPTO_KPP2=y
4046+CONFIG_CRYPTO_ACOMP2=y
4047+# CONFIG_CRYPTO_RSA is not set
4048+# CONFIG_CRYPTO_DH is not set
4049+# CONFIG_CRYPTO_ECDH is not set
4050+CONFIG_CRYPTO_MANAGER=m
4051+CONFIG_CRYPTO_MANAGER2=y
4052+# CONFIG_CRYPTO_USER is not set
4053+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
4054+# CONFIG_CRYPTO_GF128MUL is not set
4055+CONFIG_CRYPTO_NULL=m
4056+CONFIG_CRYPTO_NULL2=y
4057+# CONFIG_CRYPTO_PCRYPT is not set
4058+CONFIG_CRYPTO_WORKQUEUE=y
4059+# CONFIG_CRYPTO_CRYPTD is not set
4060+# CONFIG_CRYPTO_MCRYPTD is not set
4061+# CONFIG_CRYPTO_AUTHENC is not set
4062+# CONFIG_CRYPTO_TEST is not set
4063+
4064+#
4065+# Authenticated Encryption with Associated Data
4066+#
4067+# CONFIG_CRYPTO_CCM is not set
4068+# CONFIG_CRYPTO_GCM is not set
4069+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set
4070+# CONFIG_CRYPTO_AEGIS128 is not set
4071+# CONFIG_CRYPTO_AEGIS128L is not set
4072+# CONFIG_CRYPTO_AEGIS256 is not set
4073+# CONFIG_CRYPTO_MORUS640 is not set
4074+# CONFIG_CRYPTO_MORUS1280 is not set
4075+# CONFIG_CRYPTO_SEQIV is not set
4076+CONFIG_CRYPTO_ECHAINIV=m
4077+
4078+#
4079+# Block modes
4080+#
4081+# CONFIG_CRYPTO_CBC is not set
4082+# CONFIG_CRYPTO_CFB is not set
4083+# CONFIG_CRYPTO_CTR is not set
4084+# CONFIG_CRYPTO_CTS is not set
4085+# CONFIG_CRYPTO_ECB is not set
4086+# CONFIG_CRYPTO_LRW is not set
4087+# CONFIG_CRYPTO_PCBC is not set
4088+# CONFIG_CRYPTO_XTS is not set
4089+# CONFIG_CRYPTO_KEYWRAP is not set
4090+
4091+#
4092+# Hash modes
4093+#
4094+# CONFIG_CRYPTO_CMAC is not set
4095+CONFIG_CRYPTO_HMAC=m
4096+# CONFIG_CRYPTO_XCBC is not set
4097+# CONFIG_CRYPTO_VMAC is not set
4098+
4099+#
4100+# Digest
4101+#
4102+CONFIG_CRYPTO_CRC32C=y
4103+# CONFIG_CRYPTO_CRC32 is not set
4104+# CONFIG_CRYPTO_CRCT10DIF is not set
4105+# CONFIG_CRYPTO_GHASH is not set
4106+# CONFIG_CRYPTO_POLY1305 is not set
4107+# CONFIG_CRYPTO_MD4 is not set
4108+# CONFIG_CRYPTO_MD5 is not set
4109+# CONFIG_CRYPTO_MICHAEL_MIC is not set
4110+# CONFIG_CRYPTO_RMD128 is not set
4111+# CONFIG_CRYPTO_RMD160 is not set
4112+# CONFIG_CRYPTO_RMD256 is not set
4113+# CONFIG_CRYPTO_RMD320 is not set
4114+# CONFIG_CRYPTO_SHA1 is not set
4115+CONFIG_CRYPTO_SHA256=m
4116+# CONFIG_CRYPTO_SHA512 is not set
4117+# CONFIG_CRYPTO_SHA3 is not set
4118+# CONFIG_CRYPTO_SM3 is not set
4119+# CONFIG_CRYPTO_TGR192 is not set
4120+# CONFIG_CRYPTO_WP512 is not set
4121+
4122+#
4123+# Ciphers
4124+#
4125+CONFIG_CRYPTO_AES=y
4126+# CONFIG_CRYPTO_AES_TI is not set
4127+# CONFIG_CRYPTO_ANUBIS is not set
4128+# CONFIG_CRYPTO_ARC4 is not set
4129+# CONFIG_CRYPTO_BLOWFISH is not set
4130+# CONFIG_CRYPTO_CAMELLIA is not set
4131+# CONFIG_CRYPTO_CAST5 is not set
4132+# CONFIG_CRYPTO_CAST6 is not set
4133+# CONFIG_CRYPTO_DES is not set
4134+# CONFIG_CRYPTO_FCRYPT is not set
4135+# CONFIG_CRYPTO_KHAZAD is not set
4136+# CONFIG_CRYPTO_SALSA20 is not set
4137+# CONFIG_CRYPTO_CHACHA20 is not set
4138+# CONFIG_CRYPTO_SEED is not set
4139+# CONFIG_CRYPTO_SERPENT is not set
4140+# CONFIG_CRYPTO_SM4 is not set
4141+# CONFIG_CRYPTO_TEA is not set
4142+# CONFIG_CRYPTO_TWOFISH is not set
4143+
4144+#
4145+# Compression
4146+#
4147+# CONFIG_CRYPTO_DEFLATE is not set
4148+# CONFIG_CRYPTO_LZO is not set
4149+# CONFIG_CRYPTO_842 is not set
4150+# CONFIG_CRYPTO_LZ4 is not set
4151+# CONFIG_CRYPTO_LZ4HC is not set
4152+# CONFIG_CRYPTO_ZSTD is not set
4153+
4154+#
4155+# Random Number Generation
4156+#
4157+CONFIG_CRYPTO_ANSI_CPRNG=y
4158+CONFIG_CRYPTO_DRBG_MENU=m
4159+CONFIG_CRYPTO_DRBG_HMAC=y
4160+# CONFIG_CRYPTO_DRBG_HASH is not set
4161+CONFIG_CRYPTO_DRBG=m
4162+CONFIG_CRYPTO_JITTERENTROPY=m
4163+# CONFIG_CRYPTO_USER_API_HASH is not set
4164+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
4165+# CONFIG_CRYPTO_USER_API_RNG is not set
4166+# CONFIG_CRYPTO_USER_API_AEAD is not set
4167+CONFIG_CRYPTO_HW=y
4168+# CONFIG_CRYPTO_DEV_CCREE is not set
4169+# CONFIG_ASYMMETRIC_KEY_TYPE is not set
4170+
4171+#
4172+# Certificates for signature checking
4173+#
4174+# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set
4175+
4176+#
4177+# Library routines
4178+#
4179+CONFIG_BITREVERSE=y
4180+CONFIG_HAVE_ARCH_BITREVERSE=y
4181+CONFIG_RATIONAL=y
4182+CONFIG_GENERIC_STRNCPY_FROM_USER=y
4183+CONFIG_GENERIC_STRNLEN_USER=y
4184+CONFIG_GENERIC_NET_UTILS=y
4185+CONFIG_GENERIC_PCI_IOMAP=y
4186+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
4187+# CONFIG_CRC_CCITT is not set
4188+CONFIG_CRC16=y
4189+# CONFIG_CRC_T10DIF is not set
4190+# CONFIG_CRC_ITU_T is not set
4191+CONFIG_CRC32=y
4192+# CONFIG_CRC32_SELFTEST is not set
4193+CONFIG_CRC32_SLICEBY8=y
4194+# CONFIG_CRC32_SLICEBY4 is not set
4195+# CONFIG_CRC32_SARWATE is not set
4196+# CONFIG_CRC32_BIT is not set
4197+# CONFIG_CRC64 is not set
4198+# CONFIG_CRC4 is not set
4199+# CONFIG_CRC7 is not set
4200+CONFIG_LIBCRC32C=m
4201+# CONFIG_CRC8 is not set
4202+# CONFIG_RANDOM32_SELFTEST is not set
4203+CONFIG_ZLIB_INFLATE=y
4204+CONFIG_XZ_DEC=y
4205+CONFIG_XZ_DEC_X86=y
4206+CONFIG_XZ_DEC_POWERPC=y
4207+CONFIG_XZ_DEC_IA64=y
4208+CONFIG_XZ_DEC_ARM=y
4209+CONFIG_XZ_DEC_ARMTHUMB=y
4210+CONFIG_XZ_DEC_SPARC=y
4211+CONFIG_XZ_DEC_BCJ=y
4212+# CONFIG_XZ_DEC_TEST is not set
4213+CONFIG_GENERIC_ALLOCATOR=y
4214+CONFIG_ASSOCIATIVE_ARRAY=y
4215+CONFIG_HAS_IOMEM=y
4216+CONFIG_HAS_IOPORT_MAP=y
4217+CONFIG_HAS_DMA=y
4218+CONFIG_NEED_DMA_MAP_STATE=y
4219+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
4220+CONFIG_SGL_ALLOC=y
4221+CONFIG_CPU_RMAP=y
4222+CONFIG_DQL=y
4223+CONFIG_NLATTR=y
4224+# CONFIG_CORDIC is not set
4225+# CONFIG_DDR is not set
4226+# CONFIG_IRQ_POLL is not set
4227+CONFIG_LIBFDT=y
4228+CONFIG_OID_REGISTRY=y
4229+CONFIG_SG_POOL=y
4230+CONFIG_ARCH_HAS_SG_CHAIN=y
4231+CONFIG_SBITMAP=y
4232+# CONFIG_STRING_SELFTEST is not set
4233+
4234+#
4235+# Kernel hacking
4236+#
4237+
4238+#
4239+# printk and dmesg options
4240+#
4241+# CONFIG_PRINTK_TIME is not set
4242+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
4243+CONFIG_CONSOLE_LOGLEVEL_QUIET=4
4244+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
4245+# CONFIG_BOOT_PRINTK_DELAY is not set
4246+# CONFIG_DYNAMIC_DEBUG is not set
4247+
4248+#
4249+# Compile-time checks and compiler options
4250+#
4251+# CONFIG_DEBUG_INFO is not set
4252+CONFIG_ENABLE_MUST_CHECK=y
4253+CONFIG_FRAME_WARN=1024
4254+# CONFIG_STRIP_ASM_SYMS is not set
4255+# CONFIG_READABLE_ASM is not set
4256+# CONFIG_UNUSED_SYMBOLS is not set
4257+# CONFIG_PAGE_OWNER is not set
4258+# CONFIG_DEBUG_FS is not set
4259+# CONFIG_HEADERS_CHECK is not set
4260+# CONFIG_DEBUG_SECTION_MISMATCH is not set
4261+CONFIG_SECTION_MISMATCH_WARN_ONLY=y
4262+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
4263+# CONFIG_MAGIC_SYSRQ is not set
4264+CONFIG_DEBUG_KERNEL=y
4265+
4266+#
4267+# Memory Debugging
4268+#
4269+# CONFIG_PAGE_EXTENSION is not set
4270+# CONFIG_DEBUG_PAGEALLOC is not set
4271+# CONFIG_PAGE_POISONING is not set
4272+# CONFIG_DEBUG_RODATA_TEST is not set
4273+# CONFIG_DEBUG_OBJECTS is not set
4274+# CONFIG_SLUB_DEBUG_ON is not set
4275+# CONFIG_SLUB_STATS is not set
4276+CONFIG_HAVE_DEBUG_KMEMLEAK=y
4277+# CONFIG_DEBUG_KMEMLEAK is not set
4278+# CONFIG_DEBUG_STACK_USAGE is not set
4279+# CONFIG_DEBUG_VM is not set
4280+CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
4281+# CONFIG_DEBUG_VIRTUAL is not set
4282+CONFIG_DEBUG_MEMORY_INIT=y
4283+# CONFIG_DEBUG_PER_CPU_MAPS is not set
4284+# CONFIG_DEBUG_HIGHMEM is not set
4285+CONFIG_ARCH_HAS_KCOV=y
4286+CONFIG_CC_HAS_SANCOV_TRACE_PC=y
4287+# CONFIG_KCOV is not set
4288+# CONFIG_DEBUG_SHIRQ is not set
4289+
4290+#
4291+# Debug Lockups and Hangs
4292+#
4293+# CONFIG_SOFTLOCKUP_DETECTOR is not set
4294+# CONFIG_DETECT_HUNG_TASK is not set
4295+# CONFIG_WQ_WATCHDOG is not set
4296+# CONFIG_PANIC_ON_OOPS is not set
4297+CONFIG_PANIC_ON_OOPS_VALUE=0
4298+CONFIG_PANIC_TIMEOUT=0
4299+CONFIG_SCHED_DEBUG=y
4300+# CONFIG_SCHEDSTATS is not set
4301+# CONFIG_SCHED_STACK_END_CHECK is not set
4302+# CONFIG_DEBUG_TIMEKEEPING is not set
4303+
4304+#
4305+# Lock Debugging (spinlocks, mutexes, etc...)
4306+#
4307+CONFIG_LOCK_DEBUGGING_SUPPORT=y
4308+# CONFIG_PROVE_LOCKING is not set
4309+# CONFIG_LOCK_STAT is not set
4310+# CONFIG_DEBUG_RT_MUTEXES is not set
4311+# CONFIG_DEBUG_SPINLOCK is not set
4312+# CONFIG_DEBUG_MUTEXES is not set
4313+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
4314+# CONFIG_DEBUG_RWSEMS is not set
4315+# CONFIG_DEBUG_LOCK_ALLOC is not set
4316+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
4317+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
4318+# CONFIG_LOCK_TORTURE_TEST is not set
4319+# CONFIG_WW_MUTEX_SELFTEST is not set
4320+CONFIG_STACKTRACE=y
4321+# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
4322+# CONFIG_DEBUG_KOBJECT is not set
4323+CONFIG_DEBUG_BUGVERBOSE=y
4324+# CONFIG_DEBUG_LIST is not set
4325+# CONFIG_DEBUG_PI_LIST is not set
4326+# CONFIG_DEBUG_SG is not set
4327+# CONFIG_DEBUG_NOTIFIERS is not set
4328+# CONFIG_DEBUG_CREDENTIALS is not set
4329+
4330+#
4331+# RCU Debugging
4332+#
4333+# CONFIG_RCU_PERF_TEST is not set
4334+# CONFIG_RCU_TORTURE_TEST is not set
4335+CONFIG_RCU_CPU_STALL_TIMEOUT=60
4336+# CONFIG_RCU_TRACE is not set
4337+# CONFIG_RCU_EQS_DEBUG is not set
4338+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set
4339+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
4340+# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
4341+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
4342+# CONFIG_FAULT_INJECTION is not set
4343+# CONFIG_LATENCYTOP is not set
4344+CONFIG_HAVE_FUNCTION_TRACER=y
4345+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
4346+CONFIG_HAVE_DYNAMIC_FTRACE=y
4347+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
4348+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
4349+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
4350+CONFIG_HAVE_C_RECORDMCOUNT=y
4351+CONFIG_TRACING_SUPPORT=y
4352+# CONFIG_FTRACE is not set
4353+# CONFIG_DMA_API_DEBUG is not set
4354+CONFIG_RUNTIME_TESTING_MENU=y
4355+# CONFIG_LKDTM is not set
4356+# CONFIG_TEST_LIST_SORT is not set
4357+# CONFIG_TEST_SORT is not set
4358+# CONFIG_BACKTRACE_SELF_TEST is not set
4359+# CONFIG_RBTREE_TEST is not set
4360+# CONFIG_INTERVAL_TREE_TEST is not set
4361+# CONFIG_PERCPU_TEST is not set
4362+# CONFIG_ATOMIC64_SELFTEST is not set
4363+# CONFIG_TEST_HEXDUMP is not set
4364+# CONFIG_TEST_STRING_HELPERS is not set
4365+# CONFIG_TEST_KSTRTOX is not set
4366+# CONFIG_TEST_PRINTF is not set
4367+# CONFIG_TEST_BITMAP is not set
4368+# CONFIG_TEST_BITFIELD is not set
4369+# CONFIG_TEST_UUID is not set
4370+# CONFIG_TEST_OVERFLOW is not set
4371+# CONFIG_TEST_RHASHTABLE is not set
4372+# CONFIG_TEST_HASH is not set
4373+# CONFIG_TEST_IDA is not set
4374+# CONFIG_TEST_LKM is not set
4375+# CONFIG_TEST_USER_COPY is not set
4376+# CONFIG_TEST_BPF is not set
4377+# CONFIG_FIND_BIT_BENCHMARK is not set
4378+# CONFIG_TEST_FIRMWARE is not set
4379+# CONFIG_TEST_SYSCTL is not set
4380+# CONFIG_TEST_UDELAY is not set
4381+# CONFIG_TEST_STATIC_KEYS is not set
4382+# CONFIG_TEST_KMOD is not set
4383+# CONFIG_MEMTEST is not set
4384+# CONFIG_BUG_ON_DATA_CORRUPTION is not set
4385+# CONFIG_SAMPLES is not set
4386+CONFIG_HAVE_ARCH_KGDB=y
4387+# CONFIG_KGDB is not set
4388+# CONFIG_UBSAN is not set
4389+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
4390+CONFIG_STRICT_DEVMEM=y
4391+# CONFIG_IO_STRICT_DEVMEM is not set
4392+# CONFIG_ARM_PTDUMP_DEBUGFS is not set
4393+# CONFIG_DEBUG_WX is not set
4394+CONFIG_ARM_UNWIND=y
4395+# CONFIG_DEBUG_USER is not set
4396+# CONFIG_DEBUG_LL is not set
4397+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
4398+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
4399+# CONFIG_PID_IN_CONTEXTIDR is not set
4400+# CONFIG_CORESIGHT is not set
4401diff --git a/arch/arm/configs/hi3516dv300_emmc_smp_hos_l2_defconfig b/arch/arm/configs/hi3516dv300_emmc_smp_hos_l2_defconfig
4402new file mode 100644
4403index 000000000..364f69865
4404--- /dev/null
4405+++ b/arch/arm/configs/hi3516dv300_emmc_smp_hos_l2_defconfig
4406@@ -0,0 +1,3135 @@
4407+#
4408+# Automatically generated file; DO NOT EDIT.
4409+# Linux/arm 4.19.41 Kernel Configuration
4410+#
4411+
4412+#
4413+# Compiler: arm-himix400-linux-gcc (HC&C V1R3C00SPC200B041_20200707) 7.3.0
4414+#
4415+CONFIG_CC_IS_GCC=y
4416+CONFIG_GCC_VERSION=70300
4417+CONFIG_CLANG_VERSION=0
4418+CONFIG_CC_HAS_ASM_GOTO=y
4419+CONFIG_IRQ_WORK=y
4420+CONFIG_BUILDTIME_EXTABLE_SORT=y
4421+
4422+#
4423+# General setup
4424+#
4425+CONFIG_INIT_ENV_ARG_LIMIT=32
4426+# CONFIG_COMPILE_TEST is not set
4427+CONFIG_LOCALVERSION=""
4428+# CONFIG_LOCALVERSION_AUTO is not set
4429+CONFIG_BUILD_SALT=""
4430+CONFIG_HAVE_KERNEL_GZIP=y
4431+CONFIG_HAVE_KERNEL_LZMA=y
4432+CONFIG_HAVE_KERNEL_XZ=y
4433+CONFIG_HAVE_KERNEL_LZO=y
4434+CONFIG_HAVE_KERNEL_LZ4=y
4435+CONFIG_KERNEL_GZIP=y
4436+# CONFIG_KERNEL_LZMA is not set
4437+# CONFIG_KERNEL_XZ is not set
4438+# CONFIG_KERNEL_LZO is not set
4439+# CONFIG_KERNEL_LZ4 is not set
4440+CONFIG_DEFAULT_HOSTNAME="(none)"
4441+# CONFIG_SWAP is not set
4442+CONFIG_SYSVIPC=y
4443+CONFIG_SYSVIPC_SYSCTL=y
4444+# CONFIG_POSIX_MQUEUE is not set
4445+CONFIG_CROSS_MEMORY_ATTACH=y
4446+CONFIG_USELIB=y
4447+CONFIG_AUDIT=y
4448+
4449+#
4450+# IRQ subsystem
4451+#
4452+CONFIG_GENERIC_IRQ_PROBE=y
4453+CONFIG_GENERIC_IRQ_SHOW=y
4454+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
4455+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
4456+CONFIG_GENERIC_IRQ_MIGRATION=y
4457+CONFIG_HARDIRQS_SW_RESEND=y
4458+CONFIG_IRQ_DOMAIN=y
4459+CONFIG_IRQ_DOMAIN_HIERARCHY=y
4460+CONFIG_HANDLE_DOMAIN_IRQ=y
4461+CONFIG_IRQ_FORCED_THREADING=y
4462+CONFIG_SPARSE_IRQ=y
4463+# CONFIG_GENERIC_IRQ_DEBUGFS is not set
4464+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
4465+CONFIG_ARCH_CLOCKSOURCE_DATA=y
4466+CONFIG_GENERIC_TIME_VSYSCALL=y
4467+CONFIG_GENERIC_CLOCKEVENTS=y
4468+CONFIG_ARCH_HAS_TICK_BROADCAST=y
4469+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
4470+
4471+#HDF
4472+CONFIG_DRIVERS_HDF=y
4473+CONFIG_DRIVERS_HDF_PLATFORM=y
4474+CONFIG_DRIVERS_HDF_PLATFORM_MIPI_DSI=y
4475+CONFIG_DRIVERS_HDF_PLATFORM_MIPI_CSI=y
4476+CONFIG_DRIVERS_HDF_PLATFORM_GPIO=y
4477+CONFIG_DRIVERS_HDF_PLATFORM_I2C=y
4478+CONFIG_DRIVERS_HDF_PLATFORM_WATCHDOG=y
4479+CONFIG_DRIVERS_HDF_PLATFORM_PWM=y
4480+CONFIG_DRIVERS_HDF_PLATFORM_UART=y
4481+CONFIG_DRIVERS_HDF_PLATFORM_SPI=y
4482+CONFIG_DRIVERS_HDF_PLATFORM_RTC=y
4483+CONFIG_DRIVERS_HDF_DISP=y
4484+# CONFIG_DRIVERS_HDF_LCD_ST7789 is not set
4485+CONFIG_DRIVERS_HDF_LCD_ICN9700=y
4486+CONFIG_DRIVERS_HDF_INPUT=y
4487+CONFIG_DRIVERS_HDF_TP_5P5_GT911=y
4488+CONFIG_DRIVERS_HDF_TP_2P35_FT6236=y
4489+CONFIG_DRIVERS_HDF_WIFI=y
4490+CONFIG_DRIVERS_HI3881=y
4491+CONFIG_DRIVERS_HDF_USB_PNP_NOTIFY=y
4492+CONFIG_DRIVERS_HDF_SENSOR=y
4493+# CONFIG_DRIVERS_HDF_SENSOR_ACCEL is not set
4494+# CONFIG_DRIVERS_HDF_SENSOR_GYRO is not set
4495+CONFIG_DRIVERS_HDF_TEST=y
4496+CONFIG_DRIVERS_HDF_USB_F_GENERIC=y
4497+CONFIG_DRIVERS_HDF_USB_PNP_NOTIFY=y
4498+#
4499+# Timers subsystem
4500+#
4501+CONFIG_HZ_PERIODIC=y
4502+# CONFIG_NO_HZ_IDLE is not set
4503+# CONFIG_NO_HZ_FULL is not set
4504+# CONFIG_NO_HZ is not set
4505+# CONFIG_HIGH_RES_TIMERS is not set
4506+CONFIG_PREEMPT_NONE=y
4507+# CONFIG_PREEMPT_VOLUNTARY is not set
4508+# CONFIG_PREEMPT is not set
4509+
4510+#
4511+# CPU/Task time and stats accounting
4512+#
4513+CONFIG_TICK_CPU_ACCOUNTING=y
4514+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
4515+# CONFIG_IRQ_TIME_ACCOUNTING is not set
4516+# CONFIG_BSD_PROCESS_ACCT is not set
4517+# CONFIG_TASKSTATS is not set
4518+CONFIG_CPU_ISOLATION=y
4519+
4520+#
4521+# RCU Subsystem
4522+#
4523+CONFIG_TREE_RCU=y
4524+# CONFIG_RCU_EXPERT is not set
4525+CONFIG_SRCU=y
4526+CONFIG_TREE_SRCU=y
4527+CONFIG_RCU_STALL_COMMON=y
4528+CONFIG_RCU_NEED_SEGCBLIST=y
4529+# CONFIG_IKCONFIG is not set
4530+CONFIG_LOG_BUF_SHIFT=17
4531+CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
4532+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
4533+CONFIG_GENERIC_SCHED_CLOCK=y
4534+CONFIG_CGROUPS=y
4535+# CONFIG_MEMCG is not set
4536+# CONFIG_BLK_CGROUP is not set
4537+CONFIG_CGROUP_SCHED=y
4538+CONFIG_FAIR_GROUP_SCHED=y
4539+# CONFIG_CFS_BANDWIDTH is not set
4540+# CONFIG_RT_GROUP_SCHED is not set
4541+# CONFIG_CGROUP_PIDS is not set
4542+# CONFIG_CGROUP_RDMA is not set
4543+# CONFIG_CGROUP_FREEZER is not set
4544+# CONFIG_CPUSETS is not set
4545+# CONFIG_CGROUP_DEVICE is not set
4546+# CONFIG_CGROUP_CPUACCT is not set
4547+# CONFIG_CGROUP_DEBUG is not set
4548+CONFIG_NAMESPACES=y
4549+CONFIG_UTS_NS=y
4550+CONFIG_IPC_NS=y
4551+# CONFIG_USER_NS is not set
4552+CONFIG_PID_NS=y
4553+CONFIG_NET_NS=y
4554+# CONFIG_CHECKPOINT_RESTORE is not set
4555+# CONFIG_SCHED_AUTOGROUP is not set
4556+# CONFIG_SYSFS_DEPRECATED is not set
4557+# CONFIG_RELAY is not set
4558+# CONFIG_BLK_DEV_INITRD is not set
4559+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
4560+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
4561+CONFIG_SYSCTL=y
4562+CONFIG_ANON_INODES=y
4563+CONFIG_HAVE_UID16=y
4564+CONFIG_BPF=y
4565+# CONFIG_EXPERT is not set
4566+CONFIG_UID16=y
4567+CONFIG_MULTIUSER=y
4568+CONFIG_SYSFS_SYSCALL=y
4569+CONFIG_FHANDLE=y
4570+CONFIG_POSIX_TIMERS=y
4571+CONFIG_PRINTK=y
4572+CONFIG_PRINTK_NMI=y
4573+CONFIG_BUG=y
4574+CONFIG_ELF_CORE=y
4575+CONFIG_BASE_FULL=y
4576+CONFIG_FUTEX=y
4577+CONFIG_FUTEX_PI=y
4578+CONFIG_EPOLL=y
4579+CONFIG_SIGNALFD=y
4580+CONFIG_TIMERFD=y
4581+CONFIG_EVENTFD=y
4582+CONFIG_SHMEM=y
4583+CONFIG_AIO=y
4584+CONFIG_ADVISE_SYSCALLS=y
4585+CONFIG_MEMBARRIER=y
4586+CONFIG_KALLSYMS=y
4587+# CONFIG_KALLSYMS_ALL is not set
4588+CONFIG_KALLSYMS_BASE_RELATIVE=y
4589+# CONFIG_BPF_SYSCALL is not set
4590+# CONFIG_USERFAULTFD is not set
4591+CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
4592+CONFIG_RSEQ=y
4593+# CONFIG_EMBEDDED is not set
4594+CONFIG_HAVE_PERF_EVENTS=y
4595+CONFIG_PERF_USE_VMALLOC=y
4596+
4597+#
4598+# Kernel Performance Events And Counters
4599+#
4600+# CONFIG_PERF_EVENTS is not set
4601+CONFIG_VM_EVENT_COUNTERS=y
4602+CONFIG_SLUB_DEBUG=y
4603+CONFIG_COMPAT_BRK=y
4604+# CONFIG_SLAB is not set
4605+CONFIG_SLUB=y
4606+CONFIG_SLAB_MERGE_DEFAULT=y
4607+# CONFIG_SLAB_FREELIST_RANDOM is not set
4608+# CONFIG_SLAB_FREELIST_HARDENED is not set
4609+CONFIG_SLUB_CPU_PARTIAL=y
4610+# CONFIG_PROFILING is not set
4611+CONFIG_ARM=y
4612+CONFIG_ARM_HAS_SG_CHAIN=y
4613+CONFIG_MIGHT_HAVE_PCI=y
4614+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
4615+CONFIG_HAVE_PROC_CPU=y
4616+CONFIG_STACKTRACE_SUPPORT=y
4617+CONFIG_LOCKDEP_SUPPORT=y
4618+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
4619+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
4620+CONFIG_FIX_EARLYCON_MEM=y
4621+CONFIG_GENERIC_HWEIGHT=y
4622+CONFIG_GENERIC_CALIBRATE_DELAY=y
4623+CONFIG_ARCH_SUPPORTS_UPROBES=y
4624+CONFIG_ARM_PATCH_PHYS_VIRT=y
4625+CONFIG_GENERIC_BUG=y
4626+CONFIG_PGTABLE_LEVELS=2
4627+
4628+#
4629+# System Type
4630+#
4631+CONFIG_MMU=y
4632+CONFIG_ARCH_MMAP_RND_BITS_MIN=8
4633+CONFIG_ARCH_MMAP_RND_BITS_MAX=16
4634+CONFIG_ARCH_MULTIPLATFORM=y
4635+# CONFIG_ARCH_EBSA110 is not set
4636+# CONFIG_ARCH_EP93XX is not set
4637+# CONFIG_ARCH_FOOTBRIDGE is not set
4638+# CONFIG_ARCH_NETX is not set
4639+# CONFIG_ARCH_IOP13XX is not set
4640+# CONFIG_ARCH_IOP32X is not set
4641+# CONFIG_ARCH_IOP33X is not set
4642+# CONFIG_ARCH_IXP4XX is not set
4643+# CONFIG_ARCH_DOVE is not set
4644+# CONFIG_ARCH_KS8695 is not set
4645+# CONFIG_ARCH_W90X900 is not set
4646+# CONFIG_ARCH_LPC32XX is not set
4647+# CONFIG_ARCH_PXA is not set
4648+# CONFIG_ARCH_RPC is not set
4649+# CONFIG_ARCH_SA1100 is not set
4650+# CONFIG_ARCH_S3C24XX is not set
4651+# CONFIG_ARCH_DAVINCI is not set
4652+# CONFIG_ARCH_OMAP1 is not set
4653+
4654+#
4655+# Multiple platform selection
4656+#
4657+
4658+#
4659+# CPU Core family selection
4660+#
4661+# CONFIG_ARCH_MULTI_V6 is not set
4662+CONFIG_ARCH_MULTI_V7=y
4663+CONFIG_ARCH_MULTI_V6_V7=y
4664+# CONFIG_ARCH_VIRT is not set
4665+# CONFIG_ARCH_ACTIONS is not set
4666+# CONFIG_ARCH_ALPINE is not set
4667+# CONFIG_ARCH_ARTPEC is not set
4668+# CONFIG_ARCH_AT91 is not set
4669+# CONFIG_ARCH_BCM is not set
4670+# CONFIG_ARCH_BERLIN is not set
4671+# CONFIG_ARCH_DIGICOLOR is not set
4672+# CONFIG_ARCH_EXYNOS is not set
4673+# CONFIG_ARCH_HIGHBANK is not set
4674+# CONFIG_ARCH_HISI is not set
4675+CONFIG_ARCH_HISI_BVT=y
4676+
4677+#
4678+# Hisilicon BVT platform type
4679+#
4680+# CONFIG_ARCH_HI3521DV200 is not set
4681+# CONFIG_ARCH_HI3520DV500 is not set
4682+# CONFIG_ARCH_HI3516A is not set
4683+# CONFIG_ARCH_HI3516CV500 is not set
4684+CONFIG_ARCH_HI3516DV300=y
4685+# CONFIG_ARCH_HI3516EV200 is not set
4686+# CONFIG_ARCH_HI3516EV300 is not set
4687+# CONFIG_ARCH_HI3518EV300 is not set
4688+# CONFIG_ARCH_HI3516DV200 is not set
4689+# CONFIG_ARCH_HI3556V200 is not set
4690+# CONFIG_ARCH_HI3559V200 is not set
4691+# CONFIG_ARCH_HI3536DV100 is not set
4692+# CONFIG_ARCH_HI3521A is not set
4693+# CONFIG_ARCH_HI3531A is not set
4694+# CONFIG_ARCH_HI3556AV100 is not set
4695+# CONFIG_ARCH_HI3519AV100 is not set
4696+# CONFIG_ARCH_HI3568V100 is not set
4697+# CONFIG_ARCH_HISI_BVT_AMP is not set
4698+# CONFIG_HISI_MC is not set
4699+CONFIG_HI_ZRELADDR=0x80008000
4700+CONFIG_HI_PARAMS_PHYS=0x00000100
4701+CONFIG_HI_INITRD_PHYS=0x00800000
4702+# CONFIG_ARCH_MXC is not set
4703+# CONFIG_ARCH_KEYSTONE is not set
4704+# CONFIG_ARCH_MEDIATEK is not set
4705+# CONFIG_ARCH_MESON is not set
4706+# CONFIG_ARCH_MMP is not set
4707+# CONFIG_ARCH_MVEBU is not set
4708+# CONFIG_ARCH_NPCM is not set
4709+
4710+#
4711+# TI OMAP/AM/DM/DRA Family
4712+#
4713+# CONFIG_ARCH_OMAP3 is not set
4714+# CONFIG_ARCH_OMAP4 is not set
4715+# CONFIG_SOC_OMAP5 is not set
4716+# CONFIG_SOC_AM33XX is not set
4717+# CONFIG_SOC_AM43XX is not set
4718+# CONFIG_SOC_DRA7XX is not set
4719+# CONFIG_ARCH_SIRF is not set
4720+# CONFIG_ARCH_QCOM is not set
4721+# CONFIG_ARCH_REALVIEW is not set
4722+# CONFIG_ARCH_ROCKCHIP is not set
4723+# CONFIG_ARCH_S5PV210 is not set
4724+# CONFIG_ARCH_RENESAS is not set
4725+# CONFIG_ARCH_SOCFPGA is not set
4726+# CONFIG_PLAT_SPEAR is not set
4727+# CONFIG_ARCH_STI is not set
4728+# CONFIG_ARCH_STM32 is not set
4729+# CONFIG_ARCH_SUNXI is not set
4730+# CONFIG_ARCH_TANGO is not set
4731+# CONFIG_ARCH_TEGRA is not set
4732+# CONFIG_ARCH_UNIPHIER is not set
4733+# CONFIG_ARCH_U8500 is not set
4734+# CONFIG_ARCH_VEXPRESS is not set
4735+# CONFIG_ARCH_WM8850 is not set
4736+# CONFIG_ARCH_ZX is not set
4737+# CONFIG_ARCH_ZYNQ is not set
4738+
4739+#
4740+# Processor Type
4741+#
4742+CONFIG_CPU_V7=y
4743+CONFIG_CPU_THUMB_CAPABLE=y
4744+CONFIG_CPU_32v6K=y
4745+CONFIG_CPU_32v7=y
4746+CONFIG_CPU_ABRT_EV7=y
4747+CONFIG_CPU_PABRT_V7=y
4748+CONFIG_CPU_CACHE_V7=y
4749+CONFIG_CPU_CACHE_VIPT=y
4750+CONFIG_CPU_COPY_V6=y
4751+CONFIG_CPU_TLB_V7=y
4752+CONFIG_CPU_HAS_ASID=y
4753+CONFIG_CPU_CP15=y
4754+CONFIG_CPU_CP15_MMU=y
4755+
4756+#
4757+# Processor Features
4758+#
4759+# CONFIG_ARM_LPAE is not set
4760+CONFIG_ARM_THUMB=y
4761+# CONFIG_ARM_THUMBEE is not set
4762+CONFIG_ARM_VIRT_EXT=y
4763+CONFIG_SWP_EMULATE=y
4764+# CONFIG_CPU_ICACHE_DISABLE is not set
4765+# CONFIG_CPU_BPREDICT_DISABLE is not set
4766+CONFIG_CPU_SPECTRE=y
4767+CONFIG_HARDEN_BRANCH_PREDICTOR=y
4768+CONFIG_KUSER_HELPERS=y
4769+CONFIG_VDSO=y
4770+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
4771+# CONFIG_CACHE_L2X0 is not set
4772+CONFIG_ARM_L1_CACHE_SHIFT_6=y
4773+CONFIG_ARM_L1_CACHE_SHIFT=6
4774+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
4775+CONFIG_DEBUG_ALIGN_RODATA=y
4776+# CONFIG_ARM_ERRATA_430973 is not set
4777+# CONFIG_ARM_ERRATA_643719 is not set
4778+# CONFIG_ARM_ERRATA_720789 is not set
4779+# CONFIG_ARM_ERRATA_754322 is not set
4780+# CONFIG_ARM_ERRATA_754327 is not set
4781+# CONFIG_ARM_ERRATA_764369 is not set
4782+# CONFIG_ARM_ERRATA_775420 is not set
4783+# CONFIG_ARM_ERRATA_798181 is not set
4784+# CONFIG_ARM_ERRATA_773022 is not set
4785+# CONFIG_ARM_ERRATA_818325_852422 is not set
4786+# CONFIG_ARM_ERRATA_821420 is not set
4787+# CONFIG_ARM_ERRATA_825619 is not set
4788+# CONFIG_ARM_ERRATA_852421 is not set
4789+# CONFIG_ARM_ERRATA_852423 is not set
4790+
4791+#
4792+# Bus support
4793+#
4794+# CONFIG_PCI is not set
4795+
4796+#
4797+# PCI Endpoint
4798+#
4799+# CONFIG_PCI_ENDPOINT is not set
4800+# CONFIG_PCCARD is not set
4801+
4802+#
4803+# Kernel Features
4804+#
4805+CONFIG_HAVE_SMP=y
4806+CONFIG_SMP=y
4807+CONFIG_SMP_ON_UP=y
4808+CONFIG_ARM_CPU_TOPOLOGY=y
4809+# CONFIG_SCHED_MC is not set
4810+# CONFIG_SCHED_SMT is not set
4811+CONFIG_HAVE_ARM_ARCH_TIMER=y
4812+# CONFIG_MCPM is not set
4813+# CONFIG_BIG_LITTLE is not set
4814+CONFIG_VMSPLIT_3G=y
4815+# CONFIG_VMSPLIT_3G_OPT is not set
4816+# CONFIG_VMSPLIT_2G is not set
4817+# CONFIG_VMSPLIT_1G is not set
4818+CONFIG_PAGE_OFFSET=0xC0000000
4819+CONFIG_NR_CPUS=2
4820+CONFIG_HOTPLUG_CPU=y
4821+# CONFIG_ARM_PSCI is not set
4822+CONFIG_ARCH_NR_GPIO=0
4823+CONFIG_HZ_FIXED=0
4824+CONFIG_HZ_100=y
4825+# CONFIG_HZ_200 is not set
4826+# CONFIG_HZ_250 is not set
4827+# CONFIG_HZ_300 is not set
4828+# CONFIG_HZ_500 is not set
4829+# CONFIG_HZ_1000 is not set
4830+CONFIG_HZ=100
4831+# CONFIG_THUMB2_KERNEL is not set
4832+CONFIG_ARM_PATCH_IDIV=y
4833+CONFIG_AEABI=y
4834+CONFIG_OABI_COMPAT=y
4835+CONFIG_HAVE_ARCH_PFN_VALID=y
4836+CONFIG_HIGHMEM=y
4837+CONFIG_HIGHPTE=y
4838+CONFIG_CPU_SW_DOMAIN_PAN=y
4839+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
4840+# CONFIG_ARM_MODULE_PLTS is not set
4841+CONFIG_FORCE_MAX_ZONEORDER=11
4842+CONFIG_ALIGNMENT_TRAP=y
4843+# CONFIG_UACCESS_WITH_MEMCPY is not set
4844+# CONFIG_SECCOMP is not set
4845+# CONFIG_PARAVIRT is not set
4846+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
4847+# CONFIG_XEN is not set
4848+
4849+#
4850+# Boot options
4851+#
4852+CONFIG_USE_OF=y
4853+CONFIG_ATAGS=y
4854+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
4855+CONFIG_ZBOOT_ROM_TEXT=0
4856+CONFIG_ZBOOT_ROM_BSS=0
4857+CONFIG_ARM_APPENDED_DTB=y
4858+CONFIG_ARM_ATAG_DTB_COMPAT=y
4859+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
4860+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
4861+CONFIG_CMDLINE=""
4862+# CONFIG_KEXEC is not set
4863+# CONFIG_CRASH_DUMP is not set
4864+CONFIG_AUTO_ZRELADDR=y
4865+# CONFIG_EFI is not set
4866+
4867+#
4868+# CPU Power Management
4869+#
4870+
4871+#
4872+# CPU Frequency scaling
4873+#
4874+# CONFIG_CPU_FREQ is not set
4875+
4876+#
4877+# CPU Idle
4878+#
4879+# CONFIG_CPU_IDLE is not set
4880+
4881+#
4882+# Floating point emulation
4883+#
4884+
4885+#
4886+# At least one emulation must be selected
4887+#
4888+# CONFIG_FPE_NWFPE is not set
4889+# CONFIG_FPE_FASTFPE is not set
4890+CONFIG_VFP=y
4891+CONFIG_VFPv3=y
4892+CONFIG_NEON=y
4893+CONFIG_KERNEL_MODE_NEON=y
4894+
4895+#
4896+# Power management options
4897+#
4898+CONFIG_SUSPEND=y
4899+CONFIG_SUSPEND_FREEZER=y
4900+CONFIG_PM_SLEEP=y
4901+CONFIG_PM_SLEEP_SMP=y
4902+# CONFIG_PM_AUTOSLEEP is not set
4903+CONFIG_PM_WAKELOCKS=y
4904+CONFIG_PM_WAKELOCKS_GC=y
4905+CONFIG_PM=y
4906+# CONFIG_PM_DEBUG is not set
4907+# CONFIG_APM_EMULATION is not set
4908+CONFIG_PM_CLK=y
4909+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
4910+CONFIG_CPU_PM=y
4911+CONFIG_ARCH_SUSPEND_POSSIBLE=y
4912+CONFIG_ARM_CPU_SUSPEND=y
4913+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
4914+
4915+#
4916+# Firmware Drivers
4917+#
4918+# CONFIG_FW_CFG_SYSFS is not set
4919+CONFIG_HAVE_ARM_SMCCC=y
4920+# CONFIG_GOOGLE_FIRMWARE is not set
4921+
4922+#
4923+# Tegra firmware driver
4924+#
4925+# CONFIG_ARM_CRYPTO is not set
4926+# CONFIG_VIRTUALIZATION is not set
4927+
4928+#
4929+# General architecture-dependent options
4930+#
4931+CONFIG_HAVE_OPROFILE=y
4932+# CONFIG_KPROBES is not set
4933+# CONFIG_JUMP_LABEL is not set
4934+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
4935+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
4936+CONFIG_HAVE_KPROBES=y
4937+CONFIG_HAVE_KRETPROBES=y
4938+CONFIG_HAVE_OPTPROBES=y
4939+CONFIG_HAVE_NMI=y
4940+CONFIG_HAVE_ARCH_TRACEHOOK=y
4941+CONFIG_HAVE_DMA_CONTIGUOUS=y
4942+CONFIG_GENERIC_SMP_IDLE_THREAD=y
4943+CONFIG_GENERIC_IDLE_POLL_SETUP=y
4944+CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
4945+CONFIG_ARCH_HAS_SET_MEMORY=y
4946+CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
4947+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
4948+CONFIG_HAVE_RSEQ=y
4949+CONFIG_HAVE_CLK=y
4950+CONFIG_HAVE_PERF_REGS=y
4951+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
4952+CONFIG_HAVE_ARCH_JUMP_LABEL=y
4953+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
4954+CONFIG_HAVE_STACKPROTECTOR=y
4955+CONFIG_CC_HAS_STACKPROTECTOR_NONE=y
4956+CONFIG_STACKPROTECTOR=y
4957+CONFIG_STACKPROTECTOR_STRONG=y
4958+CONFIG_HAVE_CONTEXT_TRACKING=y
4959+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
4960+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
4961+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
4962+CONFIG_MODULES_USE_ELF_REL=y
4963+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
4964+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
4965+CONFIG_HAVE_EXIT_THREAD=y
4966+CONFIG_ARCH_MMAP_RND_BITS=8
4967+CONFIG_CLONE_BACKWARDS=y
4968+CONFIG_OLD_SIGSUSPEND3=y
4969+CONFIG_OLD_SIGACTION=y
4970+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
4971+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
4972+CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
4973+CONFIG_STRICT_KERNEL_RWX=y
4974+CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
4975+CONFIG_STRICT_MODULE_RWX=y
4976+CONFIG_ARCH_HAS_PHYS_TO_DMA=y
4977+CONFIG_REFCOUNT_FULL=y
4978+
4979+#
4980+# GCOV-based kernel profiling
4981+#
4982+# CONFIG_GCOV_KERNEL is not set
4983+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
4984+CONFIG_PLUGIN_HOSTCC=""
4985+CONFIG_HAVE_GCC_PLUGINS=y
4986+CONFIG_RT_MUTEXES=y
4987+CONFIG_BASE_SMALL=0
4988+CONFIG_MODULES=y
4989+CONFIG_MODULE_FORCE_LOAD=y
4990+CONFIG_MODULE_UNLOAD=y
4991+CONFIG_MODULE_FORCE_UNLOAD=y
4992+# CONFIG_MODVERSIONS is not set
4993+# CONFIG_MODULE_SRCVERSION_ALL is not set
4994+# CONFIG_MODULE_SIG is not set
4995+# CONFIG_MODULE_COMPRESS is not set
4996+# CONFIG_TRIM_UNUSED_KSYMS is not set
4997+CONFIG_BLOCK=y
4998+CONFIG_LBDAF=y
4999+CONFIG_BLK_SCSI_REQUEST=y
5000+CONFIG_BLK_DEV_BSG=y
5001+# CONFIG_BLK_DEV_BSGLIB is not set
5002+# CONFIG_BLK_DEV_INTEGRITY is not set
5003+# CONFIG_BLK_DEV_ZONED is not set
5004+CONFIG_BLK_CMDLINE_PARSER=y
5005+# CONFIG_BLK_WBT is not set
5006+# CONFIG_BLK_DEBUG_FS is not set
5007+# CONFIG_BLK_SED_OPAL is not set
5008+
5009+#
5010+# Partition Types
5011+#
5012+CONFIG_PARTITION_ADVANCED=y
5013+# CONFIG_ACORN_PARTITION is not set
5014+# CONFIG_AIX_PARTITION is not set
5015+# CONFIG_OSF_PARTITION is not set
5016+# CONFIG_AMIGA_PARTITION is not set
5017+# CONFIG_ATARI_PARTITION is not set
5018+# CONFIG_MAC_PARTITION is not set
5019+CONFIG_MSDOS_PARTITION=y
5020+# CONFIG_BSD_DISKLABEL is not set
5021+# CONFIG_MINIX_SUBPARTITION is not set
5022+# CONFIG_SOLARIS_X86_PARTITION is not set
5023+# CONFIG_UNIXWARE_DISKLABEL is not set
5024+# CONFIG_LDM_PARTITION is not set
5025+# CONFIG_SGI_PARTITION is not set
5026+# CONFIG_ULTRIX_PARTITION is not set
5027+# CONFIG_SUN_PARTITION is not set
5028+# CONFIG_KARMA_PARTITION is not set
5029+CONFIG_EFI_PARTITION=y
5030+# CONFIG_SYSV68_PARTITION is not set
5031+CONFIG_CMDLINE_PARTITION=y
5032+
5033+#
5034+# IO Schedulers
5035+#
5036+CONFIG_IOSCHED_NOOP=y
5037+CONFIG_IOSCHED_DEADLINE=y
5038+CONFIG_IOSCHED_CFQ=y
5039+# CONFIG_DEFAULT_DEADLINE is not set
5040+CONFIG_DEFAULT_CFQ=y
5041+# CONFIG_DEFAULT_NOOP is not set
5042+CONFIG_DEFAULT_IOSCHED="cfq"
5043+CONFIG_MQ_IOSCHED_DEADLINE=y
5044+CONFIG_MQ_IOSCHED_KYBER=y
5045+# CONFIG_IOSCHED_BFQ is not set
5046+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
5047+CONFIG_INLINE_READ_UNLOCK=y
5048+CONFIG_INLINE_READ_UNLOCK_IRQ=y
5049+CONFIG_INLINE_WRITE_UNLOCK=y
5050+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
5051+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
5052+CONFIG_MUTEX_SPIN_ON_OWNER=y
5053+CONFIG_RWSEM_SPIN_ON_OWNER=y
5054+CONFIG_LOCK_SPIN_ON_OWNER=y
5055+CONFIG_FREEZER=y
5056+
5057+#
5058+# Executable file formats
5059+#
5060+CONFIG_BINFMT_ELF=y
5061+# CONFIG_BINFMT_ELF_FDPIC is not set
5062+CONFIG_ELFCORE=y
5063+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
5064+CONFIG_BINFMT_SCRIPT=y
5065+# CONFIG_BINFMT_FLAT is not set
5066+# CONFIG_BINFMT_MISC is not set
5067+CONFIG_COREDUMP=y
5068+
5069+#
5070+# Memory Management options
5071+#
5072+CONFIG_FLATMEM=y
5073+CONFIG_FLAT_NODE_MEM_MAP=y
5074+CONFIG_HAVE_MEMBLOCK=y
5075+CONFIG_NO_BOOTMEM=y
5076+CONFIG_MEMORY_ISOLATION=y
5077+CONFIG_SPLIT_PTLOCK_CPUS=4
5078+CONFIG_COMPACTION=y
5079+CONFIG_MIGRATION=y
5080+CONFIG_BOUNCE=y
5081+# CONFIG_KSM is not set
5082+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
5083+# CONFIG_CLEANCACHE is not set
5084+CONFIG_CMA=y
5085+CONFIG_CMA_DEBUG=y
5086+# CONFIG_CMA_DEBUGFS is not set
5087+CONFIG_CMA_AREAS=7
5088+# CONFIG_ZPOOL is not set
5089+# CONFIG_ZBUD is not set
5090+# CONFIG_ZSMALLOC is not set
5091+CONFIG_GENERIC_EARLY_IOREMAP=y
5092+# CONFIG_IDLE_PAGE_TRACKING is not set
5093+CONFIG_FRAME_VECTOR=y
5094+# CONFIG_PERCPU_STATS is not set
5095+# CONFIG_GUP_BENCHMARK is not set
5096+CONFIG_NET=y
5097+
5098+#
5099+# Networking options
5100+#
5101+CONFIG_PACKET=y
5102+# CONFIG_PACKET_DIAG is not set
5103+CONFIG_UNIX=y
5104+# CONFIG_UNIX_DIAG is not set
5105+# CONFIG_TLS is not set
5106+CONFIG_XFRM=y
5107+# CONFIG_XFRM_USER is not set
5108+# CONFIG_XFRM_INTERFACE is not set
5109+# CONFIG_XFRM_SUB_POLICY is not set
5110+# CONFIG_XFRM_MIGRATE is not set
5111+# CONFIG_XFRM_STATISTICS is not set
5112+# CONFIG_NET_KEY is not set
5113+CONFIG_INET=y
5114+# CONFIG_IP_MULTICAST is not set
5115+# CONFIG_IP_ADVANCED_ROUTER is not set
5116+CONFIG_IP_PNP=y
5117+CONFIG_IP_PNP_DHCP=y
5118+# CONFIG_IP_PNP_BOOTP is not set
5119+# CONFIG_IP_PNP_RARP is not set
5120+# CONFIG_NET_IPIP is not set
5121+# CONFIG_NET_IPGRE_DEMUX is not set
5122+# CONFIG_SYN_COOKIES is not set
5123+# CONFIG_NET_IPVTI is not set
5124+# CONFIG_NET_FOU is not set
5125+# CONFIG_INET_AH is not set
5126+# CONFIG_INET_ESP is not set
5127+# CONFIG_INET_IPCOMP is not set
5128+CONFIG_INET_XFRM_MODE_TRANSPORT=y
5129+CONFIG_INET_XFRM_MODE_TUNNEL=y
5130+CONFIG_INET_XFRM_MODE_BEET=y
5131+CONFIG_INET_DIAG=y
5132+CONFIG_INET_TCP_DIAG=y
5133+# CONFIG_INET_UDP_DIAG is not set
5134+# CONFIG_INET_RAW_DIAG is not set
5135+# CONFIG_INET_DIAG_DESTROY is not set
5136+# CONFIG_TCP_CONG_ADVANCED is not set
5137+CONFIG_TCP_CONG_CUBIC=y
5138+CONFIG_DEFAULT_TCP_CONG="cubic"
5139+# CONFIG_TCP_MD5SIG is not set
5140+CONFIG_IPV6=y
5141+# CONFIG_IPV6_ROUTER_PREF is not set
5142+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
5143+# CONFIG_INET6_AH is not set
5144+# CONFIG_INET6_ESP is not set
5145+# CONFIG_INET6_IPCOMP is not set
5146+# CONFIG_IPV6_MIP6 is not set
5147+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
5148+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
5149+# CONFIG_INET6_XFRM_MODE_BEET is not set
5150+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
5151+# CONFIG_IPV6_SIT is not set
5152+# CONFIG_IPV6_TUNNEL is not set
5153+# CONFIG_IPV6_MULTIPLE_TABLES is not set
5154+# CONFIG_IPV6_MROUTE is not set
5155+# CONFIG_IPV6_SEG6_LWTUNNEL is not set
5156+# CONFIG_IPV6_SEG6_HMAC is not set
5157+# CONFIG_NETLABEL is not set
5158+CONFIG_NETWORK_SECMARK=y
5159+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
5160+# CONFIG_NETFILTER is not set
5161+# CONFIG_BPFILTER is not set
5162+# CONFIG_IP_DCCP is not set
5163+# CONFIG_IP_SCTP is not set
5164+# CONFIG_RDS is not set
5165+# CONFIG_TIPC is not set
5166+# CONFIG_ATM is not set
5167+# CONFIG_L2TP is not set
5168+# CONFIG_BRIDGE is not set
5169+CONFIG_HAVE_NET_DSA=y
5170+# CONFIG_NET_DSA is not set
5171+CONFIG_VLAN_8021Q=y
5172+# CONFIG_VLAN_8021Q_GVRP is not set
5173+# CONFIG_VLAN_8021Q_MVRP is not set
5174+# CONFIG_DECNET is not set
5175+# CONFIG_LLC2 is not set
5176+# CONFIG_ATALK is not set
5177+# CONFIG_X25 is not set
5178+# CONFIG_LAPB is not set
5179+# CONFIG_PHONET is not set
5180+# CONFIG_6LOWPAN is not set
5181+# CONFIG_IEEE802154 is not set
5182+# CONFIG_NET_SCHED is not set
5183+# CONFIG_DCB is not set
5184+CONFIG_DNS_RESOLVER=y
5185+# CONFIG_BATMAN_ADV is not set
5186+# CONFIG_OPENVSWITCH is not set
5187+# CONFIG_VSOCKETS is not set
5188+# CONFIG_NETLINK_DIAG is not set
5189+# CONFIG_MPLS is not set
5190+# CONFIG_NET_NSH is not set
5191+# CONFIG_HSR is not set
5192+# CONFIG_NET_SWITCHDEV is not set
5193+# CONFIG_NET_L3_MASTER_DEV is not set
5194+# CONFIG_NET_NCSI is not set
5195+CONFIG_RPS=y
5196+CONFIG_RFS_ACCEL=y
5197+CONFIG_XPS=y
5198+# CONFIG_CGROUP_NET_PRIO is not set
5199+# CONFIG_CGROUP_NET_CLASSID is not set
5200+CONFIG_NET_RX_BUSY_POLL=y
5201+CONFIG_BQL=y
5202+# CONFIG_BPF_JIT is not set
5203+CONFIG_NET_FLOW_LIMIT=y
5204+
5205+#
5206+# Network testing
5207+#
5208+# CONFIG_NET_PKTGEN is not set
5209+# CONFIG_HAMRADIO is not set
5210+# CONFIG_CAN is not set
5211+# CONFIG_BT is not set
5212+# CONFIG_AF_RXRPC is not set
5213+# CONFIG_AF_KCM is not set
5214+CONFIG_WIRELESS=y
5215+# CONFIG_CFG80211 is not set
5216+
5217+#
5218+# CFG80211 needs to be enabled for MAC80211
5219+#
5220+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
5221+# CONFIG_WIMAX is not set
5222+# CONFIG_RFKILL is not set
5223+# CONFIG_NET_9P is not set
5224+# CONFIG_CAIF is not set
5225+# CONFIG_CEPH_LIB is not set
5226+# CONFIG_NFC is not set
5227+# CONFIG_PSAMPLE is not set
5228+# CONFIG_NET_IFE is not set
5229+# CONFIG_LWTUNNEL is not set
5230+CONFIG_GRO_CELLS=y
5231+# CONFIG_NET_DEVLINK is not set
5232+CONFIG_MAY_USE_DEVLINK=y
5233+# CONFIG_FAILOVER is not set
5234+CONFIG_HAVE_EBPF_JIT=y
5235+
5236+#
5237+# Device Drivers
5238+#
5239+CONFIG_ARM_AMBA=y
5240+
5241+#
5242+# Generic Driver Options
5243+#
5244+CONFIG_UEVENT_HELPER=y
5245+CONFIG_UEVENT_HELPER_PATH=""
5246+CONFIG_DEVTMPFS=y
5247+CONFIG_DEVTMPFS_MOUNT=y
5248+CONFIG_STANDALONE=y
5249+CONFIG_PREVENT_FIRMWARE_BUILD=y
5250+
5251+#
5252+# Firmware loader
5253+#
5254+CONFIG_FW_LOADER=y
5255+CONFIG_EXTRA_FIRMWARE=""
5256+# CONFIG_FW_LOADER_USER_HELPER is not set
5257+CONFIG_ALLOW_DEV_COREDUMP=y
5258+# CONFIG_DEBUG_DRIVER is not set
5259+# CONFIG_DEBUG_DEVRES is not set
5260+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set
5261+# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set
5262+CONFIG_GENERIC_CPU_AUTOPROBE=y
5263+CONFIG_REGMAP=y
5264+CONFIG_REGMAP_I2C=y
5265+CONFIG_REGMAP_SPI=y
5266+CONFIG_REGMAP_MMIO=y
5267+CONFIG_DMA_SHARED_BUFFER=y
5268+# CONFIG_DMA_FENCE_TRACE is not set
5269+CONFIG_DMA_CMA=y
5270+
5271+#
5272+# Default contiguous memory area size:
5273+#
5274+CONFIG_CMA_SIZE_MBYTES=64
5275+CONFIG_CMA_SIZE_SEL_MBYTES=y
5276+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
5277+# CONFIG_CMA_SIZE_SEL_MIN is not set
5278+# CONFIG_CMA_SIZE_SEL_MAX is not set
5279+CONFIG_CMA_ALIGNMENT=8
5280+CONFIG_GENERIC_ARCH_TOPOLOGY=y
5281+
5282+#
5283+# Bus devices
5284+#
5285+# CONFIG_BRCMSTB_GISB_ARB is not set
5286+# CONFIG_SIMPLE_PM_BUS is not set
5287+# CONFIG_VEXPRESS_CONFIG is not set
5288+# CONFIG_CONNECTOR is not set
5289+# CONFIG_GNSS is not set
5290+# CONFIG_MTD is not set
5291+CONFIG_DTC=y
5292+CONFIG_OF=y
5293+# CONFIG_OF_UNITTEST is not set
5294+CONFIG_OF_FLATTREE=y
5295+CONFIG_OF_EARLY_FLATTREE=y
5296+CONFIG_OF_KOBJ=y
5297+CONFIG_OF_ADDRESS=y
5298+CONFIG_OF_IRQ=y
5299+CONFIG_OF_NET=y
5300+CONFIG_OF_MDIO=y
5301+CONFIG_OF_RESERVED_MEM=y
5302+# CONFIG_OF_OVERLAY is not set
5303+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
5304+# CONFIG_PARPORT is not set
5305+CONFIG_BLK_DEV=y
5306+# CONFIG_BLK_DEV_NULL_BLK is not set
5307+# CONFIG_BLK_DEV_LOOP is not set
5308+# CONFIG_BLK_DEV_DRBD is not set
5309+# CONFIG_BLK_DEV_NBD is not set
5310+CONFIG_BLK_DEV_RAM=y
5311+CONFIG_BLK_DEV_RAM_COUNT=16
5312+CONFIG_BLK_DEV_RAM_SIZE=65536
5313+# CONFIG_CDROM_PKTCDVD is not set
5314+# CONFIG_ATA_OVER_ETH is not set
5315+# CONFIG_BLK_DEV_RBD is not set
5316+
5317+#
5318+# NVME Support
5319+#
5320+# CONFIG_NVME_FC is not set
5321+# CONFIG_NVME_TARGET is not set
5322+
5323+#
5324+# Misc devices
5325+#
5326+# CONFIG_AD525X_DPOT is not set
5327+# CONFIG_DUMMY_IRQ is not set
5328+# CONFIG_ICS932S401 is not set
5329+# CONFIG_ENCLOSURE_SERVICES is not set
5330+# CONFIG_APDS9802ALS is not set
5331+# CONFIG_ISL29003 is not set
5332+# CONFIG_ISL29020 is not set
5333+# CONFIG_SENSORS_TSL2550 is not set
5334+# CONFIG_SENSORS_BH1770 is not set
5335+# CONFIG_SENSORS_APDS990X is not set
5336+# CONFIG_HMC6352 is not set
5337+# CONFIG_DS1682 is not set
5338+# CONFIG_USB_SWITCH_FSA9480 is not set
5339+# CONFIG_LATTICE_ECP3_CONFIG is not set
5340+# CONFIG_SRAM is not set
5341+# CONFIG_C2PORT is not set
5342+
5343+#
5344+# EEPROM support
5345+#
5346+# CONFIG_EEPROM_AT24 is not set
5347+# CONFIG_EEPROM_AT25 is not set
5348+# CONFIG_EEPROM_LEGACY is not set
5349+# CONFIG_EEPROM_MAX6875 is not set
5350+# CONFIG_EEPROM_93CX6 is not set
5351+# CONFIG_EEPROM_93XX46 is not set
5352+# CONFIG_EEPROM_IDT_89HPESX is not set
5353+
5354+#
5355+# Texas Instruments shared transport line discipline
5356+#
5357+# CONFIG_TI_ST is not set
5358+# CONFIG_SENSORS_LIS3_SPI is not set
5359+# CONFIG_SENSORS_LIS3_I2C is not set
5360+# CONFIG_ALTERA_STAPL is not set
5361+
5362+#
5363+# Intel MIC & related support
5364+#
5365+
5366+#
5367+# Intel MIC Bus Driver
5368+#
5369+
5370+#
5371+# SCIF Bus Driver
5372+#
5373+
5374+#
5375+# VOP Bus Driver
5376+#
5377+
5378+#
5379+# Intel MIC Host Driver
5380+#
5381+
5382+#
5383+# Intel MIC Card Driver
5384+#
5385+
5386+#
5387+# SCIF Driver
5388+#
5389+
5390+#
5391+# Intel MIC Coprocessor State Management (COSM) Drivers
5392+#
5393+
5394+#
5395+# VOP Driver
5396+#
5397+# CONFIG_ECHO is not set
5398+# CONFIG_MISC_RTSX_USB is not set
5399+
5400+#
5401+# SCSI device support
5402+#
5403+CONFIG_SCSI_MOD=y
5404+# CONFIG_RAID_ATTRS is not set
5405+CONFIG_SCSI=y
5406+CONFIG_SCSI_DMA=y
5407+# CONFIG_SCSI_MQ_DEFAULT is not set
5408+CONFIG_SCSI_PROC_FS=y
5409+
5410+#
5411+# SCSI support type (disk, tape, CD-ROM)
5412+#
5413+CONFIG_BLK_DEV_SD=y
5414+# CONFIG_CHR_DEV_ST is not set
5415+# CONFIG_CHR_DEV_OSST is not set
5416+# CONFIG_BLK_DEV_SR is not set
5417+# CONFIG_CHR_DEV_SG is not set
5418+# CONFIG_CHR_DEV_SCH is not set
5419+# CONFIG_SCSI_CONSTANTS is not set
5420+# CONFIG_SCSI_LOGGING is not set
5421+# CONFIG_SCSI_SCAN_ASYNC is not set
5422+
5423+#
5424+# SCSI Transports
5425+#
5426+# CONFIG_SCSI_SPI_ATTRS is not set
5427+# CONFIG_SCSI_FC_ATTRS is not set
5428+# CONFIG_SCSI_ISCSI_ATTRS is not set
5429+# CONFIG_SCSI_SAS_ATTRS is not set
5430+# CONFIG_SCSI_SAS_LIBSAS is not set
5431+# CONFIG_SCSI_SRP_ATTRS is not set
5432+CONFIG_SCSI_LOWLEVEL=y
5433+# CONFIG_ISCSI_TCP is not set
5434+# CONFIG_ISCSI_BOOT_SYSFS is not set
5435+# CONFIG_SCSI_UFSHCD is not set
5436+# CONFIG_SCSI_DEBUG is not set
5437+# CONFIG_SCSI_DH is not set
5438+# CONFIG_SCSI_OSD_INITIATOR is not set
5439+# CONFIG_ATA is not set
5440+# CONFIG_MD is not set
5441+# CONFIG_TARGET_CORE is not set
5442+CONFIG_NETDEVICES=y
5443+CONFIG_MII=y
5444+CONFIG_NET_CORE=y
5445+# CONFIG_BONDING is not set
5446+# CONFIG_DUMMY is not set
5447+# CONFIG_EQUALIZER is not set
5448+# CONFIG_NET_TEAM is not set
5449+# CONFIG_MACVLAN is not set
5450+# CONFIG_VXLAN is not set
5451+# CONFIG_GENEVE is not set
5452+# CONFIG_GTP is not set
5453+# CONFIG_MACSEC is not set
5454+# CONFIG_NETCONSOLE is not set
5455+# CONFIG_TUN is not set
5456+# CONFIG_TUN_VNET_CROSS_LE is not set
5457+# CONFIG_VETH is not set
5458+# CONFIG_NLMON is not set
5459+
5460+#
5461+# CAIF transport drivers
5462+#
5463+
5464+#
5465+# Distributed Switch Architecture drivers
5466+#
5467+CONFIG_ETHERNET=y
5468+CONFIG_NET_VENDOR_ALACRITECH=y
5469+# CONFIG_ALTERA_TSE is not set
5470+# CONFIG_NET_VENDOR_AMAZON is not set
5471+CONFIG_NET_VENDOR_AQUANTIA=y
5472+# CONFIG_NET_VENDOR_ARC is not set
5473+# CONFIG_NET_VENDOR_AURORA is not set
5474+# CONFIG_NET_VENDOR_BROADCOM is not set
5475+CONFIG_NET_VENDOR_CADENCE=y
5476+# CONFIG_MACB is not set
5477+CONFIG_NET_VENDOR_CAVIUM=y
5478+# CONFIG_NET_VENDOR_CIRRUS is not set
5479+CONFIG_NET_VENDOR_CORTINA=y
5480+# CONFIG_GEMINI_ETHERNET is not set
5481+# CONFIG_DM9000 is not set
5482+# CONFIG_DNET is not set
5483+# CONFIG_NET_VENDOR_EZCHIP is not set
5484+# CONFIG_NET_VENDOR_FARADAY is not set
5485+CONFIG_NET_VENDOR_HISILICON=y
5486+# CONFIG_HIX5HD2_GMAC is not set
5487+CONFIG_HISI_FEMAC=y
5488+# CONFIG_HIP04_ETH is not set
5489+# CONFIG_HNS is not set
5490+# CONFIG_HNS_DSAF is not set
5491+# CONFIG_HNS_ENET is not set
5492+# CONFIG_HIETH_GMAC is not set
5493+CONFIG_NET_VENDOR_HUAWEI=y
5494+# CONFIG_NET_VENDOR_INTEL is not set
5495+# CONFIG_NET_VENDOR_MARVELL is not set
5496+CONFIG_NET_VENDOR_MELLANOX=y
5497+# CONFIG_MLXSW_CORE is not set
5498+# CONFIG_MLXFW is not set
5499+# CONFIG_NET_VENDOR_MICREL is not set
5500+# CONFIG_NET_VENDOR_MICROCHIP is not set
5501+CONFIG_NET_VENDOR_MICROSEMI=y
5502+# CONFIG_NET_VENDOR_NATSEMI is not set
5503+# CONFIG_NET_VENDOR_NETRONOME is not set
5504+CONFIG_NET_VENDOR_NI=y
5505+# CONFIG_ETHOC is not set
5506+# CONFIG_NET_VENDOR_QUALCOMM is not set
5507+# CONFIG_NET_VENDOR_RENESAS is not set
5508+# CONFIG_NET_VENDOR_ROCKER is not set
5509+# CONFIG_NET_VENDOR_SAMSUNG is not set
5510+# CONFIG_NET_VENDOR_SEEQ is not set
5511+CONFIG_NET_VENDOR_SOLARFLARE=y
5512+# CONFIG_NET_VENDOR_SMSC is not set
5513+CONFIG_NET_VENDOR_SOCIONEXT=y
5514+# CONFIG_NET_VENDOR_STMICRO is not set
5515+# CONFIG_NET_VENDOR_SYNOPSYS is not set
5516+# CONFIG_NET_VENDOR_VIA is not set
5517+# CONFIG_NET_VENDOR_WIZNET is not set
5518+CONFIG_MDIO_DEVICE=y
5519+CONFIG_MDIO_BUS=y
5520+# CONFIG_MDIO_BCM_UNIMAC is not set
5521+# CONFIG_MDIO_BITBANG is not set
5522+# CONFIG_MDIO_BUS_MUX_GPIO is not set
5523+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
5524+CONFIG_MDIO_HISI_FEMAC=y
5525+# CONFIG_MDIO_HISI_GEMAC is not set
5526+# CONFIG_MDIO_MSCC_MIIM is not set
5527+CONFIG_PHYLIB=y
5528+CONFIG_SWPHY=y
5529+
5530+#
5531+# MII PHY device drivers
5532+#
5533+# CONFIG_AMD_PHY is not set
5534+# CONFIG_AQUANTIA_PHY is not set
5535+# CONFIG_ASIX_PHY is not set
5536+# CONFIG_AT803X_PHY is not set
5537+# CONFIG_BCM7XXX_PHY is not set
5538+# CONFIG_BCM87XX_PHY is not set
5539+# CONFIG_BROADCOM_PHY is not set
5540+# CONFIG_CICADA_PHY is not set
5541+# CONFIG_CORTINA_PHY is not set
5542+# CONFIG_DAVICOM_PHY is not set
5543+# CONFIG_DP83822_PHY is not set
5544+# CONFIG_DP83TC811_PHY is not set
5545+# CONFIG_DP83848_PHY is not set
5546+# CONFIG_DP83867_PHY is not set
5547+CONFIG_FIXED_PHY=y
5548+# CONFIG_ICPLUS_PHY is not set
5549+# CONFIG_INTEL_XWAY_PHY is not set
5550+# CONFIG_LSI_ET1011C_PHY is not set
5551+# CONFIG_LXT_PHY is not set
5552+# CONFIG_MARVELL_PHY is not set
5553+# CONFIG_MARVELL_10G_PHY is not set
5554+# CONFIG_MICREL_PHY is not set
5555+# CONFIG_MICROCHIP_PHY is not set
5556+# CONFIG_MICROCHIP_T1_PHY is not set
5557+# CONFIG_MICROSEMI_PHY is not set
5558+# CONFIG_NATIONAL_PHY is not set
5559+# CONFIG_QSEMI_PHY is not set
5560+# CONFIG_REALTEK_PHY is not set
5561+# CONFIG_RENESAS_PHY is not set
5562+# CONFIG_ROCKCHIP_PHY is not set
5563+# CONFIG_SMSC_PHY is not set
5564+# CONFIG_STE10XP is not set
5565+# CONFIG_TERANETICS_PHY is not set
5566+# CONFIG_VITESSE_PHY is not set
5567+# CONFIG_XILINX_GMII2RGMII is not set
5568+# CONFIG_MICREL_KS8995MA is not set
5569+# CONFIG_PPP is not set
5570+# CONFIG_SLIP is not set
5571+CONFIG_USB_NET_DRIVERS=y
5572+# CONFIG_USB_CATC is not set
5573+# CONFIG_USB_KAWETH is not set
5574+# CONFIG_USB_PEGASUS is not set
5575+# CONFIG_USB_RTL8150 is not set
5576+CONFIG_USB_RTL8152=y
5577+# CONFIG_USB_LAN78XX is not set
5578+# CONFIG_USB_USBNET is not set
5579+# CONFIG_USB_IPHETH is not set
5580+CONFIG_WLAN=y
5581+CONFIG_WLAN_VENDOR_ADMTEK=y
5582+CONFIG_WLAN_VENDOR_ATH=y
5583+# CONFIG_ATH_DEBUG is not set
5584+CONFIG_WLAN_VENDOR_ATMEL=y
5585+CONFIG_WLAN_VENDOR_BROADCOM=y
5586+CONFIG_WLAN_VENDOR_CISCO=y
5587+CONFIG_WLAN_VENDOR_INTEL=y
5588+CONFIG_WLAN_VENDOR_INTERSIL=y
5589+# CONFIG_HOSTAP is not set
5590+CONFIG_WLAN_VENDOR_MARVELL=y
5591+CONFIG_WLAN_VENDOR_MEDIATEK=y
5592+CONFIG_WLAN_VENDOR_RALINK=y
5593+CONFIG_WLAN_VENDOR_REALTEK=y
5594+CONFIG_WLAN_VENDOR_RSI=y
5595+CONFIG_WLAN_VENDOR_ST=y
5596+CONFIG_WLAN_VENDOR_TI=y
5597+CONFIG_WLAN_VENDOR_ZYDAS=y
5598+CONFIG_WLAN_VENDOR_QUANTENNA=y
5599+
5600+#
5601+# Enable WiMAX (Networking options) to see the WiMAX drivers
5602+#
5603+# CONFIG_WAN is not set
5604+# CONFIG_NETDEVSIM is not set
5605+# CONFIG_NET_FAILOVER is not set
5606+# CONFIG_ISDN is not set
5607+
5608+#
5609+# Input device support
5610+#
5611+CONFIG_INPUT=y
5612+CONFIG_INPUT_FF_MEMLESS=y
5613+# CONFIG_INPUT_POLLDEV is not set
5614+# CONFIG_INPUT_SPARSEKMAP is not set
5615+# CONFIG_INPUT_MATRIXKMAP is not set
5616+
5617+#
5618+# Userland interfaces
5619+#
5620+CONFIG_INPUT_MOUSEDEV=y
5621+CONFIG_INPUT_MOUSEDEV_PSAUX=y
5622+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
5623+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
5624+CONFIG_INPUT_JOYDEV=y
5625+CONFIG_INPUT_EVDEV=y
5626+# CONFIG_INPUT_EVBUG is not set
5627+
5628+#
5629+# Input Device Drivers
5630+#
5631+CONFIG_INPUT_KEYBOARD=y
5632+# CONFIG_KEYBOARD_ADP5588 is not set
5633+# CONFIG_KEYBOARD_ADP5589 is not set
5634+CONFIG_KEYBOARD_ATKBD=y
5635+# CONFIG_KEYBOARD_QT1070 is not set
5636+# CONFIG_KEYBOARD_QT2160 is not set
5637+# CONFIG_KEYBOARD_DLINK_DIR685 is not set
5638+# CONFIG_KEYBOARD_LKKBD is not set
5639+# CONFIG_KEYBOARD_GPIO is not set
5640+# CONFIG_KEYBOARD_GPIO_POLLED is not set
5641+# CONFIG_KEYBOARD_TCA6416 is not set
5642+# CONFIG_KEYBOARD_TCA8418 is not set
5643+# CONFIG_KEYBOARD_MATRIX is not set
5644+# CONFIG_KEYBOARD_LM8333 is not set
5645+# CONFIG_KEYBOARD_MAX7359 is not set
5646+# CONFIG_KEYBOARD_MCS is not set
5647+# CONFIG_KEYBOARD_MPR121 is not set
5648+# CONFIG_KEYBOARD_NEWTON is not set
5649+# CONFIG_KEYBOARD_OPENCORES is not set
5650+# CONFIG_KEYBOARD_SAMSUNG is not set
5651+# CONFIG_KEYBOARD_STOWAWAY is not set
5652+# CONFIG_KEYBOARD_SUNKBD is not set
5653+# CONFIG_KEYBOARD_OMAP4 is not set
5654+# CONFIG_KEYBOARD_XTKBD is not set
5655+# CONFIG_KEYBOARD_CAP11XX is not set
5656+# CONFIG_KEYBOARD_BCM is not set
5657+CONFIG_INPUT_MOUSE=y
5658+CONFIG_MOUSE_PS2=y
5659+CONFIG_MOUSE_PS2_ALPS=y
5660+CONFIG_MOUSE_PS2_BYD=y
5661+CONFIG_MOUSE_PS2_LOGIPS2PP=y
5662+CONFIG_MOUSE_PS2_SYNAPTICS=y
5663+CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
5664+CONFIG_MOUSE_PS2_CYPRESS=y
5665+CONFIG_MOUSE_PS2_TRACKPOINT=y
5666+# CONFIG_MOUSE_PS2_ELANTECH is not set
5667+# CONFIG_MOUSE_PS2_SENTELIC is not set
5668+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
5669+CONFIG_MOUSE_PS2_FOCALTECH=y
5670+CONFIG_MOUSE_PS2_SMBUS=y
5671+# CONFIG_MOUSE_SERIAL is not set
5672+# CONFIG_MOUSE_APPLETOUCH is not set
5673+# CONFIG_MOUSE_BCM5974 is not set
5674+# CONFIG_MOUSE_CYAPA is not set
5675+# CONFIG_MOUSE_ELAN_I2C is not set
5676+# CONFIG_MOUSE_VSXXXAA is not set
5677+# CONFIG_MOUSE_GPIO is not set
5678+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
5679+# CONFIG_MOUSE_SYNAPTICS_USB is not set
5680+CONFIG_INPUT_JOYSTICK=y
5681+# CONFIG_JOYSTICK_ANALOG is not set
5682+# CONFIG_JOYSTICK_A3D is not set
5683+# CONFIG_JOYSTICK_ADI is not set
5684+# CONFIG_JOYSTICK_COBRA is not set
5685+# CONFIG_JOYSTICK_GF2K is not set
5686+# CONFIG_JOYSTICK_GRIP is not set
5687+# CONFIG_JOYSTICK_GRIP_MP is not set
5688+# CONFIG_JOYSTICK_GUILLEMOT is not set
5689+# CONFIG_JOYSTICK_INTERACT is not set
5690+# CONFIG_JOYSTICK_SIDEWINDER is not set
5691+# CONFIG_JOYSTICK_TMDC is not set
5692+# CONFIG_JOYSTICK_IFORCE is not set
5693+# CONFIG_JOYSTICK_WARRIOR is not set
5694+# CONFIG_JOYSTICK_MAGELLAN is not set
5695+# CONFIG_JOYSTICK_SPACEORB is not set
5696+# CONFIG_JOYSTICK_SPACEBALL is not set
5697+# CONFIG_JOYSTICK_STINGER is not set
5698+# CONFIG_JOYSTICK_TWIDJOY is not set
5699+# CONFIG_JOYSTICK_ZHENHUA is not set
5700+# CONFIG_JOYSTICK_AS5011 is not set
5701+# CONFIG_JOYSTICK_JOYDUMP is not set
5702+CONFIG_JOYSTICK_XPAD=y
5703+CONFIG_JOYSTICK_XPAD_FF=y
5704+# CONFIG_JOYSTICK_PSXPAD_SPI is not set
5705+# CONFIG_JOYSTICK_PXRC is not set
5706+# CONFIG_INPUT_TABLET is not set
5707+# CONFIG_INPUT_TOUCHSCREEN is not set
5708+CONFIG_INPUT_MISC=y
5709+# CONFIG_RMI4_CORE is not set
5710+CONFIG_INPUT_UINPUT=y
5711+
5712+#
5713+# Hardware I/O ports
5714+#
5715+CONFIG_SERIO=y
5716+CONFIG_SERIO_SERPORT=y
5717+# CONFIG_SERIO_AMBAKMI is not set
5718+CONFIG_SERIO_LIBPS2=y
5719+# CONFIG_SERIO_RAW is not set
5720+# CONFIG_SERIO_ALTERA_PS2 is not set
5721+# CONFIG_SERIO_PS2MULT is not set
5722+# CONFIG_SERIO_ARC_PS2 is not set
5723+# CONFIG_SERIO_APBPS2 is not set
5724+# CONFIG_SERIO_GPIO_PS2 is not set
5725+# CONFIG_USERIO is not set
5726+# CONFIG_GAMEPORT is not set
5727+
5728+#
5729+# Character devices
5730+#
5731+CONFIG_TTY=y
5732+CONFIG_VT=y
5733+CONFIG_CONSOLE_TRANSLATIONS=y
5734+CONFIG_VT_CONSOLE=y
5735+CONFIG_VT_CONSOLE_SLEEP=y
5736+CONFIG_HW_CONSOLE=y
5737+# CONFIG_VT_HW_CONSOLE_BINDING is not set
5738+CONFIG_UNIX98_PTYS=y
5739+# CONFIG_LEGACY_PTYS is not set
5740+# CONFIG_SERIAL_NONSTANDARD is not set
5741+# CONFIG_N_GSM is not set
5742+# CONFIG_TRACE_SINK is not set
5743+CONFIG_LDISC_AUTOLOAD=y
5744+CONFIG_DEVMEM=y
5745+CONFIG_DEVKMEM=y
5746+
5747+#
5748+# Serial drivers
5749+#
5750+CONFIG_SERIAL_EARLYCON=y
5751+# CONFIG_SERIAL_8250 is not set
5752+
5753+#
5754+# Non-8250 serial port support
5755+#
5756+# CONFIG_SERIAL_AMBA_PL010 is not set
5757+CONFIG_SERIAL_AMBA_PL011=y
5758+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
5759+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set
5760+# CONFIG_SERIAL_MAX3100 is not set
5761+# CONFIG_SERIAL_MAX310X is not set
5762+# CONFIG_SERIAL_UARTLITE is not set
5763+CONFIG_SERIAL_CORE=y
5764+CONFIG_SERIAL_CORE_CONSOLE=y
5765+# CONFIG_SERIAL_SCCNXP is not set
5766+# CONFIG_SERIAL_SC16IS7XX is not set
5767+# CONFIG_SERIAL_BCM63XX is not set
5768+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
5769+# CONFIG_SERIAL_ALTERA_UART is not set
5770+# CONFIG_SERIAL_IFX6X60 is not set
5771+# CONFIG_SERIAL_XILINX_PS_UART is not set
5772+# CONFIG_SERIAL_ARC is not set
5773+# CONFIG_SERIAL_FSL_LPUART is not set
5774+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set
5775+# CONFIG_SERIAL_ST_ASC is not set
5776+# CONFIG_SERIAL_DEV_BUS is not set
5777+# CONFIG_HVC_DCC is not set
5778+# CONFIG_IPMI_HANDLER is not set
5779+# CONFIG_HW_RANDOM is not set
5780+# CONFIG_RAW_DRIVER is not set
5781+# CONFIG_TCG_TPM is not set
5782+# CONFIG_XILLYBUS is not set
5783+
5784+#
5785+# I2C support
5786+#
5787+CONFIG_I2C=y
5788+CONFIG_I2C_BOARDINFO=y
5789+# CONFIG_I2C_COMPAT is not set
5790+CONFIG_I2C_CHARDEV=y
5791+CONFIG_I2C_MUX=y
5792+
5793+#
5794+# Multiplexer I2C Chip support
5795+#
5796+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
5797+# CONFIG_I2C_MUX_GPIO is not set
5798+# CONFIG_I2C_MUX_GPMUX is not set
5799+# CONFIG_I2C_MUX_LTC4306 is not set
5800+# CONFIG_I2C_MUX_PCA9541 is not set
5801+# CONFIG_I2C_MUX_PCA954x is not set
5802+# CONFIG_I2C_MUX_PINCTRL is not set
5803+# CONFIG_I2C_MUX_REG is not set
5804+# CONFIG_I2C_DEMUX_PINCTRL is not set
5805+# CONFIG_I2C_MUX_MLXCPLD is not set
5806+# CONFIG_I2C_HELPER_AUTO is not set
5807+# CONFIG_I2C_SMBUS is not set
5808+
5809+#
5810+# I2C Algorithms
5811+#
5812+CONFIG_I2C_ALGOBIT=y
5813+# CONFIG_I2C_ALGOPCF is not set
5814+# CONFIG_I2C_ALGOPCA is not set
5815+
5816+#
5817+# I2C Hardware Bus support
5818+#
5819+
5820+#
5821+# I2C system bus drivers (mostly embedded / system-on-chip)
5822+#
5823+# CONFIG_I2C_CBUS_GPIO is not set
5824+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
5825+# CONFIG_I2C_EMEV2 is not set
5826+# CONFIG_I2C_GPIO is not set
5827+CONFIG_I2C_HIBVT=y
5828+# CONFIG_I2C_NOMADIK is not set
5829+# CONFIG_I2C_OCORES is not set
5830+# CONFIG_I2C_PCA_PLATFORM is not set
5831+# CONFIG_I2C_RK3X is not set
5832+# CONFIG_I2C_SIMTEC is not set
5833+# CONFIG_I2C_XILINX is not set
5834+
5835+#
5836+# External I2C/SMBus adapter drivers
5837+#
5838+# CONFIG_I2C_DIOLAN_U2C is not set
5839+# CONFIG_I2C_PARPORT_LIGHT is not set
5840+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set
5841+# CONFIG_I2C_TAOS_EVM is not set
5842+# CONFIG_I2C_TINY_USB is not set
5843+
5844+#
5845+# Other I2C/SMBus bus drivers
5846+#
5847+CONFIG_DMA_MSG_MIN_LEN=5
5848+CONFIG_DMA_MSG_MAX_LEN=4090
5849+# CONFIG_I2C_STUB is not set
5850+# CONFIG_I2C_SLAVE is not set
5851+# CONFIG_I2C_DEBUG_CORE is not set
5852+# CONFIG_I2C_DEBUG_ALGO is not set
5853+# CONFIG_I2C_DEBUG_BUS is not set
5854+CONFIG_SPI=y
5855+# CONFIG_SPI_DEBUG is not set
5856+CONFIG_SPI_MASTER=y
5857+# CONFIG_SPI_MEM is not set
5858+
5859+#
5860+# SPI Master Controller Drivers
5861+#
5862+# CONFIG_SPI_ALTERA is not set
5863+# CONFIG_SPI_AXI_SPI_ENGINE is not set
5864+# CONFIG_SPI_BITBANG is not set
5865+# CONFIG_SPI_CADENCE is not set
5866+# CONFIG_SPI_DESIGNWARE is not set
5867+# CONFIG_SPI_GPIO is not set
5868+# CONFIG_SPI_FSL_SPI is not set
5869+# CONFIG_SPI_OC_TINY is not set
5870+CONFIG_SPI_PL022=y
5871+# CONFIG_SPI_ROCKCHIP is not set
5872+# CONFIG_SPI_SC18IS602 is not set
5873+# CONFIG_SPI_XCOMM is not set
5874+# CONFIG_SPI_XILINX is not set
5875+# CONFIG_SPI_ZYNQMP_GQSPI is not set
5876+
5877+#
5878+# SPI Protocol Masters
5879+#
5880+CONFIG_SPI_SPIDEV=y
5881+# CONFIG_SPI_LOOPBACK_TEST is not set
5882+# CONFIG_SPI_TLE62X0 is not set
5883+# CONFIG_SPI_SLAVE is not set
5884+# CONFIG_SPMI is not set
5885+# CONFIG_HSI is not set
5886+# CONFIG_PPS is not set
5887+
5888+#
5889+# PTP clock support
5890+#
5891+# CONFIG_PTP_1588_CLOCK is not set
5892+
5893+#
5894+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
5895+#
5896+CONFIG_PINCTRL=y
5897+# CONFIG_DEBUG_PINCTRL is not set
5898+# CONFIG_PINCTRL_AMD is not set
5899+# CONFIG_PINCTRL_MCP23S08 is not set
5900+# CONFIG_PINCTRL_SINGLE is not set
5901+# CONFIG_PINCTRL_SX150X is not set
5902+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
5903+CONFIG_GPIOLIB=y
5904+CONFIG_GPIOLIB_FASTPATH_LIMIT=512
5905+CONFIG_OF_GPIO=y
5906+CONFIG_GPIOLIB_IRQCHIP=y
5907+# CONFIG_DEBUG_GPIO is not set
5908+CONFIG_GPIO_SYSFS=y
5909+CONFIG_GPIO_GENERIC=y
5910+
5911+#
5912+# Memory mapped GPIO drivers
5913+#
5914+# CONFIG_GPIO_74XX_MMIO is not set
5915+# CONFIG_GPIO_ALTERA is not set
5916+# CONFIG_GPIO_DWAPB is not set
5917+# CONFIG_GPIO_FTGPIO010 is not set
5918+CONFIG_GPIO_GENERIC_PLATFORM=y
5919+# CONFIG_GPIO_GRGPIO is not set
5920+# CONFIG_GPIO_HLWD is not set
5921+# CONFIG_GPIO_MB86S7X is not set
5922+# CONFIG_GPIO_MOCKUP is not set
5923+# CONFIG_GPIO_MPC8XXX is not set
5924+CONFIG_GPIO_PL061=y
5925+# CONFIG_GPIO_SYSCON is not set
5926+# CONFIG_GPIO_XILINX is not set
5927+# CONFIG_GPIO_ZEVIO is not set
5928+
5929+#
5930+# I2C GPIO expanders
5931+#
5932+# CONFIG_GPIO_ADP5588 is not set
5933+# CONFIG_GPIO_ADNP is not set
5934+# CONFIG_GPIO_MAX7300 is not set
5935+# CONFIG_GPIO_MAX732X is not set
5936+# CONFIG_GPIO_PCA953X is not set
5937+# CONFIG_GPIO_PCF857X is not set
5938+# CONFIG_GPIO_TPIC2810 is not set
5939+
5940+#
5941+# MFD GPIO expanders
5942+#
5943+# CONFIG_HTC_EGPIO is not set
5944+
5945+#
5946+# SPI GPIO expanders
5947+#
5948+# CONFIG_GPIO_74X164 is not set
5949+# CONFIG_GPIO_MAX3191X is not set
5950+# CONFIG_GPIO_MAX7301 is not set
5951+# CONFIG_GPIO_MC33880 is not set
5952+# CONFIG_GPIO_PISOSR is not set
5953+# CONFIG_GPIO_XRA1403 is not set
5954+
5955+#
5956+# USB GPIO expanders
5957+#
5958+# CONFIG_W1 is not set
5959+# CONFIG_POWER_AVS is not set
5960+CONFIG_POWER_RESET=y
5961+# CONFIG_POWER_RESET_BRCMKONA is not set
5962+# CONFIG_POWER_RESET_BRCMSTB is not set
5963+# CONFIG_POWER_RESET_GPIO is not set
5964+# CONFIG_POWER_RESET_GPIO_RESTART is not set
5965+CONFIG_POWER_RESET_HISI=y
5966+# CONFIG_POWER_RESET_LTC2952 is not set
5967+# CONFIG_POWER_RESET_RESTART is not set
5968+# CONFIG_POWER_RESET_VERSATILE is not set
5969+CONFIG_POWER_RESET_SYSCON=y
5970+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set
5971+# CONFIG_SYSCON_REBOOT_MODE is not set
5972+CONFIG_POWER_SUPPLY=y
5973+# CONFIG_POWER_SUPPLY_DEBUG is not set
5974+# CONFIG_PDA_POWER is not set
5975+# CONFIG_TEST_POWER is not set
5976+# CONFIG_CHARGER_ADP5061 is not set
5977+# CONFIG_BATTERY_DS2780 is not set
5978+# CONFIG_BATTERY_DS2781 is not set
5979+# CONFIG_BATTERY_DS2782 is not set
5980+# CONFIG_BATTERY_SBS is not set
5981+# CONFIG_CHARGER_SBS is not set
5982+# CONFIG_MANAGER_SBS is not set
5983+# CONFIG_BATTERY_BQ27XXX is not set
5984+# CONFIG_BATTERY_MAX17040 is not set
5985+# CONFIG_BATTERY_MAX17042 is not set
5986+# CONFIG_CHARGER_MAX8903 is not set
5987+# CONFIG_CHARGER_LP8727 is not set
5988+# CONFIG_CHARGER_GPIO is not set
5989+# CONFIG_CHARGER_LTC3651 is not set
5990+# CONFIG_CHARGER_DETECTOR_MAX14656 is not set
5991+# CONFIG_CHARGER_BQ2415X is not set
5992+# CONFIG_CHARGER_BQ24257 is not set
5993+# CONFIG_CHARGER_BQ24735 is not set
5994+# CONFIG_CHARGER_BQ25890 is not set
5995+# CONFIG_CHARGER_SMB347 is not set
5996+# CONFIG_BATTERY_GAUGE_LTC2941 is not set
5997+# CONFIG_CHARGER_RT9455 is not set
5998+# CONFIG_HWMON is not set
5999+# CONFIG_THERMAL is not set
6000+# CONFIG_WATCHDOG is not set
6001+CONFIG_SSB_POSSIBLE=y
6002+# CONFIG_SSB is not set
6003+CONFIG_BCMA_POSSIBLE=y
6004+# CONFIG_BCMA is not set
6005+
6006+#
6007+# Multifunction device drivers
6008+#
6009+CONFIG_MFD_CORE=y
6010+# CONFIG_MFD_ACT8945A is not set
6011+# CONFIG_MFD_AS3711 is not set
6012+# CONFIG_MFD_AS3722 is not set
6013+# CONFIG_PMIC_ADP5520 is not set
6014+# CONFIG_MFD_AAT2870_CORE is not set
6015+# CONFIG_MFD_ATMEL_FLEXCOM is not set
6016+# CONFIG_MFD_ATMEL_HLCDC is not set
6017+# CONFIG_MFD_BCM590XX is not set
6018+# CONFIG_MFD_BD9571MWV is not set
6019+# CONFIG_MFD_AXP20X_I2C is not set
6020+# CONFIG_MFD_CROS_EC is not set
6021+# CONFIG_MFD_MADERA is not set
6022+# CONFIG_MFD_ASIC3 is not set
6023+# CONFIG_PMIC_DA903X is not set
6024+# CONFIG_MFD_DA9052_SPI is not set
6025+# CONFIG_MFD_DA9052_I2C is not set
6026+# CONFIG_MFD_DA9055 is not set
6027+# CONFIG_MFD_DA9062 is not set
6028+# CONFIG_MFD_DA9063 is not set
6029+# CONFIG_MFD_DA9150 is not set
6030+# CONFIG_MFD_DLN2 is not set
6031+# CONFIG_MFD_MC13XXX_SPI is not set
6032+# CONFIG_MFD_MC13XXX_I2C is not set
6033+# CONFIG_MFD_HI6421_PMIC is not set
6034+CONFIG_MFD_HISI_FMC=y
6035+# CONFIG_HTC_PASIC3 is not set
6036+# CONFIG_HTC_I2CPLD is not set
6037+# CONFIG_MFD_KEMPLD is not set
6038+# CONFIG_MFD_88PM800 is not set
6039+# CONFIG_MFD_88PM805 is not set
6040+# CONFIG_MFD_88PM860X is not set
6041+# CONFIG_MFD_MAX14577 is not set
6042+# CONFIG_MFD_MAX77620 is not set
6043+# CONFIG_MFD_MAX77686 is not set
6044+# CONFIG_MFD_MAX77693 is not set
6045+# CONFIG_MFD_MAX77843 is not set
6046+# CONFIG_MFD_MAX8907 is not set
6047+# CONFIG_MFD_MAX8925 is not set
6048+# CONFIG_MFD_MAX8997 is not set
6049+# CONFIG_MFD_MAX8998 is not set
6050+# CONFIG_MFD_MT6397 is not set
6051+# CONFIG_MFD_MENF21BMC is not set
6052+# CONFIG_EZX_PCAP is not set
6053+# CONFIG_MFD_CPCAP is not set
6054+# CONFIG_MFD_VIPERBOARD is not set
6055+# CONFIG_MFD_RETU is not set
6056+# CONFIG_MFD_PCF50633 is not set
6057+# CONFIG_MFD_PM8XXX is not set
6058+# CONFIG_MFD_RT5033 is not set
6059+# CONFIG_MFD_RC5T583 is not set
6060+# CONFIG_MFD_RK808 is not set
6061+# CONFIG_MFD_RN5T618 is not set
6062+# CONFIG_MFD_SEC_CORE is not set
6063+# CONFIG_MFD_SI476X_CORE is not set
6064+# CONFIG_MFD_SM501 is not set
6065+# CONFIG_MFD_SKY81452 is not set
6066+# CONFIG_MFD_SMSC is not set
6067+# CONFIG_ABX500_CORE is not set
6068+# CONFIG_MFD_STMPE is not set
6069+CONFIG_MFD_SYSCON=y
6070+# CONFIG_MFD_TI_AM335X_TSCADC is not set
6071+# CONFIG_MFD_LP3943 is not set
6072+# CONFIG_MFD_LP8788 is not set
6073+# CONFIG_MFD_TI_LMU is not set
6074+# CONFIG_MFD_PALMAS is not set
6075+# CONFIG_TPS6105X is not set
6076+# CONFIG_TPS65010 is not set
6077+# CONFIG_TPS6507X is not set
6078+# CONFIG_MFD_TPS65086 is not set
6079+# CONFIG_MFD_TPS65090 is not set
6080+# CONFIG_MFD_TPS65217 is not set
6081+# CONFIG_MFD_TI_LP873X is not set
6082+# CONFIG_MFD_TI_LP87565 is not set
6083+# CONFIG_MFD_TPS65218 is not set
6084+# CONFIG_MFD_TPS6586X is not set
6085+# CONFIG_MFD_TPS65910 is not set
6086+# CONFIG_MFD_TPS65912_I2C is not set
6087+# CONFIG_MFD_TPS65912_SPI is not set
6088+# CONFIG_MFD_TPS80031 is not set
6089+# CONFIG_TWL4030_CORE is not set
6090+# CONFIG_TWL6040_CORE is not set
6091+# CONFIG_MFD_WL1273_CORE is not set
6092+# CONFIG_MFD_LM3533 is not set
6093+# CONFIG_MFD_TC3589X is not set
6094+# CONFIG_MFD_T7L66XB is not set
6095+# CONFIG_MFD_TC6387XB is not set
6096+# CONFIG_MFD_TC6393XB is not set
6097+# CONFIG_MFD_ARIZONA_I2C is not set
6098+# CONFIG_MFD_ARIZONA_SPI is not set
6099+# CONFIG_MFD_WM8400 is not set
6100+# CONFIG_MFD_WM831X_I2C is not set
6101+# CONFIG_MFD_WM831X_SPI is not set
6102+# CONFIG_MFD_WM8350_I2C is not set
6103+# CONFIG_MFD_WM8994 is not set
6104+# CONFIG_MFD_ROHM_BD718XX is not set
6105+# CONFIG_REGULATOR is not set
6106+# CONFIG_RC_CORE is not set
6107+CONFIG_MEDIA_SUPPORT=y
6108+
6109+#
6110+# Multimedia core support
6111+#
6112+CONFIG_MEDIA_CAMERA_SUPPORT=y
6113+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
6114+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
6115+# CONFIG_MEDIA_RADIO_SUPPORT is not set
6116+# CONFIG_MEDIA_SDR_SUPPORT is not set
6117+# CONFIG_MEDIA_CEC_SUPPORT is not set
6118+# CONFIG_MEDIA_CONTROLLER is not set
6119+CONFIG_VIDEO_DEV=y
6120+CONFIG_VIDEO_V4L2=y
6121+# CONFIG_VIDEO_ADV_DEBUG is not set
6122+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
6123+
6124+#
6125+# Media drivers
6126+#
6127+CONFIG_MEDIA_USB_SUPPORT=y
6128+
6129+#
6130+# Webcam devices
6131+#
6132+CONFIG_USB_VIDEO_CLASS=y
6133+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
6134+CONFIG_USB_GSPCA=m
6135+# CONFIG_USB_M5602 is not set
6136+# CONFIG_USB_STV06XX is not set
6137+# CONFIG_USB_GL860 is not set
6138+# CONFIG_USB_GSPCA_BENQ is not set
6139+# CONFIG_USB_GSPCA_CONEX is not set
6140+# CONFIG_USB_GSPCA_CPIA1 is not set
6141+# CONFIG_USB_GSPCA_DTCS033 is not set
6142+# CONFIG_USB_GSPCA_ETOMS is not set
6143+# CONFIG_USB_GSPCA_FINEPIX is not set
6144+# CONFIG_USB_GSPCA_JEILINJ is not set
6145+# CONFIG_USB_GSPCA_JL2005BCD is not set
6146+# CONFIG_USB_GSPCA_KINECT is not set
6147+# CONFIG_USB_GSPCA_KONICA is not set
6148+# CONFIG_USB_GSPCA_MARS is not set
6149+# CONFIG_USB_GSPCA_MR97310A is not set
6150+# CONFIG_USB_GSPCA_NW80X is not set
6151+# CONFIG_USB_GSPCA_OV519 is not set
6152+# CONFIG_USB_GSPCA_OV534 is not set
6153+# CONFIG_USB_GSPCA_OV534_9 is not set
6154+# CONFIG_USB_GSPCA_PAC207 is not set
6155+# CONFIG_USB_GSPCA_PAC7302 is not set
6156+# CONFIG_USB_GSPCA_PAC7311 is not set
6157+# CONFIG_USB_GSPCA_SE401 is not set
6158+# CONFIG_USB_GSPCA_SN9C2028 is not set
6159+# CONFIG_USB_GSPCA_SN9C20X is not set
6160+# CONFIG_USB_GSPCA_SONIXB is not set
6161+# CONFIG_USB_GSPCA_SONIXJ is not set
6162+# CONFIG_USB_GSPCA_SPCA500 is not set
6163+# CONFIG_USB_GSPCA_SPCA501 is not set
6164+# CONFIG_USB_GSPCA_SPCA505 is not set
6165+# CONFIG_USB_GSPCA_SPCA506 is not set
6166+# CONFIG_USB_GSPCA_SPCA508 is not set
6167+# CONFIG_USB_GSPCA_SPCA561 is not set
6168+# CONFIG_USB_GSPCA_SPCA1528 is not set
6169+# CONFIG_USB_GSPCA_SQ905 is not set
6170+# CONFIG_USB_GSPCA_SQ905C is not set
6171+# CONFIG_USB_GSPCA_SQ930X is not set
6172+# CONFIG_USB_GSPCA_STK014 is not set
6173+# CONFIG_USB_GSPCA_STK1135 is not set
6174+# CONFIG_USB_GSPCA_STV0680 is not set
6175+# CONFIG_USB_GSPCA_SUNPLUS is not set
6176+# CONFIG_USB_GSPCA_T613 is not set
6177+# CONFIG_USB_GSPCA_TOPRO is not set
6178+# CONFIG_USB_GSPCA_TOUPTEK is not set
6179+# CONFIG_USB_GSPCA_TV8532 is not set
6180+# CONFIG_USB_GSPCA_VC032X is not set
6181+# CONFIG_USB_GSPCA_VICAM is not set
6182+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
6183+# CONFIG_USB_GSPCA_ZC3XX is not set
6184+# CONFIG_USB_PWC is not set
6185+# CONFIG_VIDEO_CPIA2 is not set
6186+# CONFIG_USB_ZR364XX is not set
6187+# CONFIG_USB_STKWEBCAM is not set
6188+# CONFIG_USB_S2255 is not set
6189+# CONFIG_VIDEO_USBTV is not set
6190+
6191+#
6192+# Webcam, TV (analog/digital) USB devices
6193+#
6194+# CONFIG_VIDEO_EM28XX is not set
6195+# CONFIG_V4L_PLATFORM_DRIVERS is not set
6196+# CONFIG_V4L_MEM2MEM_DRIVERS is not set
6197+# CONFIG_V4L_TEST_DRIVERS is not set
6198+
6199+#
6200+# Supported MMC/SDIO adapters
6201+#
6202+# CONFIG_CYPRESS_FIRMWARE is not set
6203+CONFIG_VIDEOBUF2_CORE=y
6204+CONFIG_VIDEOBUF2_V4L2=y
6205+CONFIG_VIDEOBUF2_MEMOPS=y
6206+CONFIG_VIDEOBUF2_VMALLOC=y
6207+
6208+#
6209+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends)
6210+#
6211+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
6212+
6213+#
6214+# Audio decoders, processors and mixers
6215+#
6216+
6217+#
6218+# RDS decoders
6219+#
6220+
6221+#
6222+# Video decoders
6223+#
6224+
6225+#
6226+# Video and audio decoders
6227+#
6228+
6229+#
6230+# Video encoders
6231+#
6232+
6233+#
6234+# Camera sensor devices
6235+#
6236+
6237+#
6238+# Flash devices
6239+#
6240+
6241+#
6242+# Video improvement chips
6243+#
6244+
6245+#
6246+# Audio/Video compression chips
6247+#
6248+
6249+#
6250+# SDR tuner chips
6251+#
6252+
6253+#
6254+# Miscellaneous helper chips
6255+#
6256+
6257+#
6258+# Sensors used on soc_camera driver
6259+#
6260+
6261+#
6262+# Media SPI Adapters
6263+#
6264+
6265+#
6266+# Tools to develop new frontends
6267+#
6268+
6269+#
6270+# Graphics support
6271+#
6272+# CONFIG_IMX_IPUV3_CORE is not set
6273+CONFIG_DRM=y
6274+# CONFIG_DRM_DP_AUX_CHARDEV is not set
6275+# CONFIG_DRM_DEBUG_MM is not set
6276+# CONFIG_DRM_DEBUG_SELFTEST is not set
6277+CONFIG_DRM_KMS_HELPER=y
6278+# CONFIG_DRM_FBDEV_EMULATION is not set
6279+# CONFIG_DRM_LOAD_EDID_FIRMWARE is not set
6280+# CONFIG_DRM_DP_CEC is not set
6281+CONFIG_DRM_GEM_CMA_HELPER=y
6282+
6283+#
6284+# I2C encoder or helper chips
6285+#
6286+# CONFIG_DRM_I2C_CH7006 is not set
6287+# CONFIG_DRM_I2C_SIL164 is not set
6288+# CONFIG_DRM_I2C_NXP_TDA998X is not set
6289+# CONFIG_DRM_I2C_NXP_TDA9950 is not set
6290+# CONFIG_DRM_HDLCD is not set
6291+# CONFIG_DRM_MALI_DISPLAY is not set
6292+
6293+#
6294+# ACP (Audio CoProcessor) Configuration
6295+#
6296+
6297+#
6298+# AMD Library routines
6299+#
6300+# CONFIG_DRM_VGEM is not set
6301+# CONFIG_DRM_VKMS is not set
6302+# CONFIG_DRM_EXYNOS is not set
6303+# CONFIG_DRM_UDL is not set
6304+# CONFIG_DRM_ARMADA is not set
6305+# CONFIG_DRM_RCAR_DW_HDMI is not set
6306+# CONFIG_DRM_RCAR_LVDS is not set
6307+# CONFIG_DRM_OMAP is not set
6308+# CONFIG_DRM_TILCDC is not set
6309+# CONFIG_DRM_FSL_DCU is not set
6310+# CONFIG_DRM_STM is not set
6311+CONFIG_DRM_PANEL=y
6312+
6313+#
6314+# Display Panels
6315+#
6316+# CONFIG_DRM_PANEL_ARM_VERSATILE is not set
6317+# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set
6318+# CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set
6319+# CONFIG_DRM_PANEL_LG_LG4573 is not set
6320+# CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set
6321+CONFIG_DRM_BRIDGE=y
6322+CONFIG_DRM_PANEL_BRIDGE=y
6323+
6324+#
6325+# Display Interface Bridges
6326+#
6327+# CONFIG_DRM_ANALOGIX_ANX78XX is not set
6328+# CONFIG_DRM_CDNS_DSI is not set
6329+# CONFIG_DRM_DUMB_VGA_DAC is not set
6330+# CONFIG_DRM_LVDS_ENCODER is not set
6331+# CONFIG_DRM_MEGACHIPS_STDPXXXX_GE_B850V3_FW is not set
6332+# CONFIG_DRM_NXP_PTN3460 is not set
6333+# CONFIG_DRM_PARADE_PS8622 is not set
6334+# CONFIG_DRM_SIL_SII8620 is not set
6335+# CONFIG_DRM_SII902X is not set
6336+# CONFIG_DRM_SII9234 is not set
6337+# CONFIG_DRM_THINE_THC63LVD1024 is not set
6338+# CONFIG_DRM_TOSHIBA_TC358767 is not set
6339+# CONFIG_DRM_TI_TFP410 is not set
6340+# CONFIG_DRM_I2C_ADV7511 is not set
6341+# CONFIG_DRM_STI is not set
6342+# CONFIG_DRM_ARCPGU is not set
6343+CONFIG_DRM_HISI_HISMART=y
6344+# CONFIG_DRM_MXSFB is not set
6345+# CONFIG_DRM_TINYDRM is not set
6346+# CONFIG_DRM_PL111 is not set
6347+# CONFIG_DRM_TVE200 is not set
6348+# CONFIG_DRM_LEGACY is not set
6349+CONFIG_DRM_PANEL_ORIENTATION_QUIRKS=y
6350+
6351+#
6352+# Frame buffer Devices
6353+#
6354+CONFIG_FB_CMDLINE=y
6355+CONFIG_FB_NOTIFY=y
6356+CONFIG_FB=y
6357+# CONFIG_FIRMWARE_EDID is not set
6358+# CONFIG_FB_FOREIGN_ENDIAN is not set
6359+# CONFIG_FB_MODE_HELPERS is not set
6360+# CONFIG_FB_TILEBLITTING is not set
6361+
6362+#
6363+# Frame buffer hardware drivers
6364+#
6365+# CONFIG_FB_ARMCLCD is not set
6366+# CONFIG_FB_OPENCORES is not set
6367+# CONFIG_FB_S1D13XXX is not set
6368+# CONFIG_FB_SMSCUFX is not set
6369+# CONFIG_FB_UDL is not set
6370+# CONFIG_FB_IBM_GXT4500 is not set
6371+# CONFIG_FB_VIRTUAL is not set
6372+# CONFIG_FB_METRONOME is not set
6373+# CONFIG_FB_BROADSHEET is not set
6374+# CONFIG_FB_SIMPLE is not set
6375+# CONFIG_FB_SSD1307 is not set
6376+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
6377+CONFIG_HDMI=y
6378+
6379+#
6380+# Console display driver support
6381+#
6382+CONFIG_DUMMY_CONSOLE=y
6383+# CONFIG_FRAMEBUFFER_CONSOLE is not set
6384+# CONFIG_LOGO is not set
6385+CONFIG_SOUND=y
6386+CONFIG_SND=y
6387+CONFIG_SND_TIMER=y
6388+CONFIG_SND_PCM=y
6389+# CONFIG_SND_OSSEMUL is not set
6390+CONFIG_SND_PCM_TIMER=y
6391+# CONFIG_SND_DYNAMIC_MINORS is not set
6392+CONFIG_SND_SUPPORT_OLD_API=y
6393+CONFIG_SND_PROC_FS=y
6394+CONFIG_SND_VERBOSE_PROCFS=y
6395+# CONFIG_SND_VERBOSE_PRINTK is not set
6396+# CONFIG_SND_DEBUG is not set
6397+# CONFIG_SND_SEQUENCER is not set
6398+CONFIG_SND_DRIVERS=y
6399+# CONFIG_SND_DUMMY is not set
6400+# CONFIG_SND_ALOOP is not set
6401+# CONFIG_SND_MTPAV is not set
6402+# CONFIG_SND_SERIAL_U16550 is not set
6403+# CONFIG_SND_MPU401 is not set
6404+
6405+#
6406+# HD-Audio
6407+#
6408+CONFIG_SND_HDA_PREALLOC_SIZE=64
6409+CONFIG_SND_ARM=y
6410+# CONFIG_SND_ARMAACI is not set
6411+CONFIG_SND_SPI=y
6412+CONFIG_SND_USB=y
6413+# CONFIG_SND_USB_AUDIO is not set
6414+# CONFIG_SND_USB_UA101 is not set
6415+# CONFIG_SND_USB_CAIAQ is not set
6416+# CONFIG_SND_USB_6FIRE is not set
6417+# CONFIG_SND_USB_HIFACE is not set
6418+# CONFIG_SND_BCD2000 is not set
6419+# CONFIG_SND_USB_POD is not set
6420+# CONFIG_SND_USB_PODHD is not set
6421+# CONFIG_SND_USB_TONEPORT is not set
6422+# CONFIG_SND_USB_VARIAX is not set
6423+# CONFIG_SND_SOC is not set
6424+
6425+#
6426+# HID support
6427+#
6428+# CONFIG_HID is not set
6429+
6430+#
6431+# USB HID support
6432+#
6433+CONFIG_USB_HID=y
6434+# CONFIG_HID_PID is not set
6435+
6436+#
6437+# I2C HID support
6438+#
6439+# CONFIG_I2C_HID is not set
6440+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
6441+CONFIG_USB_SUPPORT=y
6442+CONFIG_USB_COMMON=y
6443+CONFIG_USB_ARCH_HAS_HCD=y
6444+CONFIG_USB=y
6445+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
6446+
6447+#
6448+# Miscellaneous USB options
6449+#
6450+CONFIG_USB_DEFAULT_PERSIST=y
6451+# CONFIG_USB_DYNAMIC_MINORS is not set
6452+# CONFIG_USB_OTG is not set
6453+# CONFIG_USB_OTG_WHITELIST is not set
6454+# CONFIG_USB_MON is not set
6455+# CONFIG_USB_WUSB_CBAF is not set
6456+
6457+#
6458+# USB Host Controller Drivers
6459+#
6460+# CONFIG_USB_C67X00_HCD is not set
6461+CONFIG_USB_XHCI_HCD=y
6462+# CONFIG_USB_XHCI_DBGCAP is not set
6463+CONFIG_USB_XHCI_PLATFORM=y
6464+# CONFIG_USB_EHCI_HCD is not set
6465+# CONFIG_USB_OXU210HP_HCD is not set
6466+# CONFIG_USB_ISP116X_HCD is not set
6467+# CONFIG_USB_FOTG210_HCD is not set
6468+# CONFIG_USB_MAX3421_HCD is not set
6469+# CONFIG_USB_OHCI_HCD is not set
6470+# CONFIG_USB_SL811_HCD is not set
6471+# CONFIG_USB_R8A66597_HCD is not set
6472+# CONFIG_USB_HCD_TEST_MODE is not set
6473+
6474+#
6475+# USB Device Class drivers
6476+#
6477+# CONFIG_USB_ACM is not set
6478+# CONFIG_USB_PRINTER is not set
6479+# CONFIG_USB_WDM is not set
6480+# CONFIG_USB_TMC is not set
6481+
6482+#
6483+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
6484+#
6485+
6486+#
6487+# also be needed; see USB_STORAGE Help for more info
6488+#
6489+CONFIG_USB_STORAGE=y
6490+# CONFIG_USB_STORAGE_DEBUG is not set
6491+# CONFIG_USB_STORAGE_REALTEK is not set
6492+# CONFIG_USB_STORAGE_DATAFAB is not set
6493+# CONFIG_USB_STORAGE_FREECOM is not set
6494+# CONFIG_USB_STORAGE_ISD200 is not set
6495+# CONFIG_USB_STORAGE_USBAT is not set
6496+# CONFIG_USB_STORAGE_SDDR09 is not set
6497+# CONFIG_USB_STORAGE_SDDR55 is not set
6498+# CONFIG_USB_STORAGE_JUMPSHOT is not set
6499+# CONFIG_USB_STORAGE_ALAUDA is not set
6500+# CONFIG_USB_STORAGE_ONETOUCH is not set
6501+# CONFIG_USB_STORAGE_KARMA is not set
6502+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
6503+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
6504+# CONFIG_USB_UAS is not set
6505+
6506+#
6507+# USB Imaging devices
6508+#
6509+# CONFIG_USB_MDC800 is not set
6510+# CONFIG_USB_MICROTEK is not set
6511+# CONFIG_USBIP_CORE is not set
6512+# CONFIG_USB_MUSB_HDRC is not set
6513+CONFIG_USB_DWC3=y
6514+# CONFIG_USB_DWC3_HOST is not set
6515+CONFIG_USB_DWC3_GADGET=y
6516+
6517+#
6518+# Platform Glue Driver Support
6519+#
6520+# CONFIG_USB_DWC3_OF_SIMPLE is not set
6521+# CONFIG_USB_DWC2 is not set
6522+# CONFIG_USB_CHIPIDEA is not set
6523+# CONFIG_USB_ISP1760 is not set
6524+
6525+#
6526+# USB port drivers
6527+#
6528+# CONFIG_USB_SERIAL is not set
6529+
6530+#
6531+# USB Miscellaneous drivers
6532+#
6533+# CONFIG_USB_EMI62 is not set
6534+# CONFIG_USB_EMI26 is not set
6535+# CONFIG_USB_ADUTUX is not set
6536+# CONFIG_USB_SEVSEG is not set
6537+# CONFIG_USB_RIO500 is not set
6538+# CONFIG_USB_LEGOTOWER is not set
6539+# CONFIG_USB_LCD is not set
6540+# CONFIG_USB_CYPRESS_CY7C63 is not set
6541+# CONFIG_USB_CYTHERM is not set
6542+# CONFIG_USB_IDMOUSE is not set
6543+# CONFIG_USB_FTDI_ELAN is not set
6544+# CONFIG_USB_APPLEDISPLAY is not set
6545+# CONFIG_USB_LD is not set
6546+# CONFIG_USB_TRANCEVIBRATOR is not set
6547+# CONFIG_USB_IOWARRIOR is not set
6548+# CONFIG_USB_TEST is not set
6549+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
6550+# CONFIG_USB_ISIGHTFW is not set
6551+# CONFIG_USB_YUREX is not set
6552+# CONFIG_USB_EZUSB_FX2 is not set
6553+# CONFIG_USB_HUB_USB251XB is not set
6554+# CONFIG_USB_HSIC_USB3503 is not set
6555+# CONFIG_USB_HSIC_USB4604 is not set
6556+# CONFIG_USB_LINK_LAYER_TEST is not set
6557+
6558+#
6559+# USB Physical Layer drivers
6560+#
6561+# CONFIG_NOP_USB_XCEIV is not set
6562+# CONFIG_USB_GPIO_VBUS is not set
6563+# CONFIG_USB_ISP1301 is not set
6564+# CONFIG_USB_ULPI is not set
6565+CONFIG_USB_GADGET=y
6566+# CONFIG_USB_GADGET_DEBUG is not set
6567+# CONFIG_USB_GADGET_DEBUG_FILES is not set
6568+# CONFIG_USB_GADGET_DEBUG_FS is not set
6569+CONFIG_USB_GADGET_VBUS_DRAW=2
6570+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
6571+# CONFIG_U_SERIAL_CONSOLE is not set
6572+
6573+#
6574+# USB Peripheral Controller
6575+#
6576+# CONFIG_USB_FUSB300 is not set
6577+# CONFIG_USB_FOTG210_UDC is not set
6578+# CONFIG_USB_GR_UDC is not set
6579+# CONFIG_USB_R8A66597 is not set
6580+# CONFIG_USB_PXA27X is not set
6581+# CONFIG_USB_MV_UDC is not set
6582+# CONFIG_USB_MV_U3D is not set
6583+# CONFIG_USB_SNP_UDC_PLAT is not set
6584+# CONFIG_USB_M66592 is not set
6585+# CONFIG_USB_BDC_UDC is not set
6586+# CONFIG_USB_NET2272 is not set
6587+# CONFIG_USB_GADGET_XILINX is not set
6588+# CONFIG_USB_DUMMY_HCD is not set
6589+CONFIG_USB_LIBCOMPOSITE=y
6590+CONFIG_USB_F_ACM=y
6591+CONFIG_USB_U_SERIAL=y
6592+CONFIG_USB_U_ETHER=y
6593+CONFIG_USB_U_AUDIO=y
6594+CONFIG_USB_F_RNDIS=y
6595+CONFIG_USB_F_MASS_STORAGE=y
6596+CONFIG_USB_F_FS=y
6597+CONFIG_USB_F_UAC1=y
6598+CONFIG_USB_F_UVC=y
6599+CONFIG_USB_CONFIGFS=y
6600+# CONFIG_USB_CONFIGFS_SERIAL is not set
6601+CONFIG_USB_CONFIGFS_ACM=y
6602+# CONFIG_USB_CONFIGFS_OBEX is not set
6603+# CONFIG_USB_CONFIGFS_NCM is not set
6604+# CONFIG_USB_CONFIGFS_ECM is not set
6605+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set
6606+CONFIG_USB_CONFIGFS_RNDIS=y
6607+# CONFIG_USB_CONFIGFS_EEM is not set
6608+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
6609+# CONFIG_USB_CONFIGFS_F_LB_SS is not set
6610+CONFIG_USB_CONFIGFS_F_FS=y
6611+CONFIG_USB_CONFIGFS_F_UAC1=y
6612+# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set
6613+# CONFIG_USB_CONFIGFS_F_UAC2 is not set
6614+# CONFIG_USB_CONFIGFS_F_MIDI is not set
6615+# CONFIG_USB_CONFIGFS_F_HID is not set
6616+CONFIG_USB_CONFIGFS_F_UVC=y
6617+# CONFIG_USB_CONFIGFS_F_PRINTER is not set
6618+CONFIG_TYPEC=y
6619+# CONFIG_TYPEC_TCPM is not set
6620+# CONFIG_TYPEC_UCSI is not set
6621+# CONFIG_TYPEC_TPS6598X is not set
6622+
6623+#
6624+# USB Type-C Multiplexer/DeMultiplexer Switch support
6625+#
6626+# CONFIG_TYPEC_MUX_PI3USB30532 is not set
6627+
6628+#
6629+# USB Type-C Alternate Mode drivers
6630+#
6631+# CONFIG_TYPEC_DP_ALTMODE is not set
6632+# CONFIG_USB_ROLE_SWITCH is not set
6633+# CONFIG_USB_ULPI_BUS is not set
6634+# CONFIG_UWB is not set
6635+CONFIG_MMC=y
6636+CONFIG_PWRSEQ_EMMC=y
6637+CONFIG_PWRSEQ_SIMPLE=y
6638+CONFIG_MMC_BLOCK=y
6639+CONFIG_MMC_BLOCK_MINORS=8
6640+# CONFIG_SDIO_UART is not set
6641+# CONFIG_MMC_TEST is not set
6642+
6643+#
6644+# MMC/SD/SDIO Host Controller Drivers
6645+#
6646+# CONFIG_MMC_DEBUG is not set
6647+# CONFIG_MMC_ARMMMCI is not set
6648+# CONFIG_MMC_SDHCI is not set
6649+# CONFIG_MMC_SPI is not set
6650+# CONFIG_MMC_DW is not set
6651+# CONFIG_MMC_VUB300 is not set
6652+# CONFIG_MMC_USHC is not set
6653+# CONFIG_MMC_USDHI6ROL0 is not set
6654+# CONFIG_MMC_CQHCI is not set
6655+# CONFIG_MMC_MTK is not set
6656+# CONFIG_MMC_CQ_HCI is not set
6657+CONFIG_HIMCI=y
6658+CONFIG_SEND_AUTO_STOP=y
6659+# CONFIG_MEMSTICK is not set
6660+# CONFIG_NEW_LEDS is not set
6661+# CONFIG_ACCESSIBILITY is not set
6662+# CONFIG_INFINIBAND is not set
6663+CONFIG_EDAC_ATOMIC_SCRUB=y
6664+CONFIG_EDAC_SUPPORT=y
6665+CONFIG_RTC_LIB=y
6666+CONFIG_RTC_CLASS=y
6667+CONFIG_RTC_HCTOSYS=y
6668+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
6669+CONFIG_RTC_SYSTOHC=y
6670+CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
6671+# CONFIG_RTC_DEBUG is not set
6672+CONFIG_RTC_NVMEM=y
6673+
6674+#
6675+# RTC interfaces
6676+#
6677+CONFIG_RTC_INTF_SYSFS=y
6678+CONFIG_RTC_INTF_PROC=y
6679+CONFIG_RTC_INTF_DEV=y
6680+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
6681+# CONFIG_RTC_DRV_TEST is not set
6682+
6683+#
6684+# I2C RTC drivers
6685+#
6686+# CONFIG_RTC_DRV_ABB5ZES3 is not set
6687+# CONFIG_RTC_DRV_ABX80X is not set
6688+# CONFIG_RTC_DRV_DS1307 is not set
6689+# CONFIG_RTC_DRV_DS1374 is not set
6690+# CONFIG_RTC_DRV_DS1672 is not set
6691+# CONFIG_RTC_DRV_HYM8563 is not set
6692+# CONFIG_RTC_DRV_MAX6900 is not set
6693+# CONFIG_RTC_DRV_RS5C372 is not set
6694+# CONFIG_RTC_DRV_ISL1208 is not set
6695+# CONFIG_RTC_DRV_ISL12022 is not set
6696+# CONFIG_RTC_DRV_ISL12026 is not set
6697+# CONFIG_RTC_DRV_X1205 is not set
6698+# CONFIG_RTC_DRV_PCF8523 is not set
6699+# CONFIG_RTC_DRV_PCF85063 is not set
6700+# CONFIG_RTC_DRV_PCF85363 is not set
6701+# CONFIG_RTC_DRV_PCF8563 is not set
6702+# CONFIG_RTC_DRV_PCF8583 is not set
6703+# CONFIG_RTC_DRV_M41T80 is not set
6704+# CONFIG_RTC_DRV_BQ32K is not set
6705+# CONFIG_RTC_DRV_S35390A is not set
6706+# CONFIG_RTC_DRV_FM3130 is not set
6707+# CONFIG_RTC_DRV_RX8010 is not set
6708+# CONFIG_RTC_DRV_RX8581 is not set
6709+# CONFIG_RTC_DRV_RX8025 is not set
6710+# CONFIG_RTC_DRV_EM3027 is not set
6711+# CONFIG_RTC_DRV_RV8803 is not set
6712+
6713+#
6714+# SPI RTC drivers
6715+#
6716+# CONFIG_RTC_DRV_M41T93 is not set
6717+# CONFIG_RTC_DRV_M41T94 is not set
6718+# CONFIG_RTC_DRV_DS1302 is not set
6719+# CONFIG_RTC_DRV_DS1305 is not set
6720+# CONFIG_RTC_DRV_DS1343 is not set
6721+# CONFIG_RTC_DRV_DS1347 is not set
6722+# CONFIG_RTC_DRV_DS1390 is not set
6723+# CONFIG_RTC_DRV_MAX6916 is not set
6724+# CONFIG_RTC_DRV_R9701 is not set
6725+# CONFIG_RTC_DRV_RX4581 is not set
6726+# CONFIG_RTC_DRV_RX6110 is not set
6727+# CONFIG_RTC_DRV_RS5C348 is not set
6728+# CONFIG_RTC_DRV_MAX6902 is not set
6729+# CONFIG_RTC_DRV_PCF2123 is not set
6730+# CONFIG_RTC_DRV_MCP795 is not set
6731+CONFIG_RTC_I2C_AND_SPI=y
6732+
6733+#
6734+# SPI and I2C RTC drivers
6735+#
6736+# CONFIG_RTC_DRV_DS3232 is not set
6737+# CONFIG_RTC_DRV_PCF2127 is not set
6738+# CONFIG_RTC_DRV_RV3029C2 is not set
6739+
6740+#
6741+# Platform RTC drivers
6742+#
6743+CONFIG_RTC_DRV_HIBVT=y
6744+# CONFIG_RTC_DRV_CMOS is not set
6745+# CONFIG_RTC_DRV_DS1286 is not set
6746+# CONFIG_RTC_DRV_DS1511 is not set
6747+# CONFIG_RTC_DRV_DS1553 is not set
6748+# CONFIG_RTC_DRV_DS1685_FAMILY is not set
6749+# CONFIG_RTC_DRV_DS1742 is not set
6750+# CONFIG_RTC_DRV_DS2404 is not set
6751+# CONFIG_RTC_DRV_STK17TA8 is not set
6752+# CONFIG_RTC_DRV_M48T86 is not set
6753+# CONFIG_RTC_DRV_M48T35 is not set
6754+# CONFIG_RTC_DRV_M48T59 is not set
6755+# CONFIG_RTC_DRV_MSM6242 is not set
6756+# CONFIG_RTC_DRV_BQ4802 is not set
6757+# CONFIG_RTC_DRV_RP5C01 is not set
6758+# CONFIG_RTC_DRV_V3020 is not set
6759+# CONFIG_RTC_DRV_ZYNQMP is not set
6760+
6761+#
6762+# on-CPU RTC drivers
6763+#
6764+# CONFIG_RTC_DRV_PL030 is not set
6765+# CONFIG_RTC_DRV_PL031 is not set
6766+# CONFIG_RTC_DRV_FTRTC010 is not set
6767+# CONFIG_RTC_DRV_SNVS is not set
6768+# CONFIG_RTC_DRV_R7301 is not set
6769+
6770+#
6771+# HID Sensor RTC drivers
6772+#
6773+# CONFIG_DMADEVICES is not set
6774+
6775+#
6776+# DMABUF options
6777+#
6778+CONFIG_SYNC_FILE=y
6779+# CONFIG_SW_SYNC is not set
6780+# CONFIG_AUXDISPLAY is not set
6781+# CONFIG_UIO is not set
6782+# CONFIG_VIRT_DRIVERS is not set
6783+CONFIG_VIRTIO_MENU=y
6784+# CONFIG_VIRTIO_MMIO is not set
6785+
6786+#
6787+# Microsoft Hyper-V guest support
6788+#
6789+# CONFIG_STAGING is not set
6790+# CONFIG_GOLDFISH is not set
6791+# CONFIG_CHROME_PLATFORMS is not set
6792+# CONFIG_MELLANOX_PLATFORM is not set
6793+CONFIG_CLKDEV_LOOKUP=y
6794+CONFIG_HAVE_CLK_PREPARE=y
6795+CONFIG_COMMON_CLK=y
6796+
6797+#
6798+# Common Clock Framework
6799+#
6800+# CONFIG_CLK_HSDK is not set
6801+# CONFIG_COMMON_CLK_MAX9485 is not set
6802+# CONFIG_COMMON_CLK_SI5351 is not set
6803+# CONFIG_COMMON_CLK_SI514 is not set
6804+# CONFIG_COMMON_CLK_SI544 is not set
6805+# CONFIG_COMMON_CLK_SI570 is not set
6806+# CONFIG_COMMON_CLK_CDCE706 is not set
6807+# CONFIG_COMMON_CLK_CDCE925 is not set
6808+# CONFIG_COMMON_CLK_CS2000_CP is not set
6809+# CONFIG_CLK_QORIQ is not set
6810+# CONFIG_COMMON_CLK_VC5 is not set
6811+CONFIG_COMMON_CLK_HI3516DV300=y
6812+CONFIG_RESET_HISI=y
6813+CONFIG_STAGING=y
6814+# CONFIG_HWSPINLOCK is not set
6815+#
6816+# Android
6817+#
6818+CONFIG_ANDROID=y
6819+CONFIG_ANDROID_BINDER_IPC=y
6820+CONFIG_ANDROID_BINDER_DEVICES=binder,hwbinder,vndbinder
6821+CONFIG_ASHMEM=y
6822+CONFIG_ANDROID_LOW_MEMORY_KILLER=y
6823+CONFIG_ANDROID_LOW_MEMORY_KILLER_AUTODETECT_OOM_ADJ_VALUES=y
6824+# CONFIG_ANDROID_VSOC is not set
6825+CONFIG_ION=y
6826+CONFIG_ION_TEST=y
6827+# CONFIG_ION_DUMMY is not set
6828+CONFIG_ION_HICAMERA=y
6829+CONFIG_ION_OF=y
6830+# CONFIG_FIQ_DEBUGGER is not set
6831+# CONFIG_FIQ_WATCHDOG is not set
6832+# CONFIG_STAGING_BOARD is not set
6833+# CONFIG_LTE_GDM724X is not set
6834+# CONFIG_MTD_SPINAND_MT29F is not set
6835+# CONFIG_LNET is not set
6836+# CONFIG_DGNC is not set
6837+# CONFIG_GS_FPGABOOT is not set
6838+# CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set
6839+# CONFIG_FB_TFT is not set
6840+# CONFIG_FSL_MC_BUS is not set
6841+# CONFIG_MOST is not set
6842+# CONFIG_KS7010 is not set
6843+# CONFIG_GREYBUS is not set
6844+# CONFIG_GOLDFISH is not set
6845+# CONFIG_CHROME_PLATFORMS is not set
6846+CONFIG_CLKDEV_LOOKUP=y
6847+CONFIG_HAVE_CLK_PREPARE=y
6848+CONFIG_COMMON_CLK=y
6849+#
6850+# Clock Source drivers
6851+#
6852+CONFIG_TIMER_OF=y
6853+CONFIG_TIMER_PROBE=y
6854+CONFIG_CLKSRC_MMIO=y
6855+CONFIG_ARM_ARCH_TIMER=y
6856+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
6857+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set
6858+CONFIG_ARM_TIMER_SP804=y
6859+# CONFIG_TIMER_HISP804 is not set
6860+# CONFIG_MAILBOX is not set
6861+# CONFIG_IOMMU_SUPPORT is not set
6862+
6863+#
6864+# Remoteproc drivers
6865+#
6866+# CONFIG_REMOTEPROC is not set
6867+
6868+#
6869+# Rpmsg drivers
6870+#
6871+# CONFIG_RPMSG_VIRTIO is not set
6872+# CONFIG_SOUNDWIRE is not set
6873+
6874+#
6875+# SOC (System On Chip) specific Drivers
6876+#
6877+
6878+#
6879+# Amlogic SoC drivers
6880+#
6881+
6882+#
6883+# Broadcom SoC drivers
6884+#
6885+# CONFIG_SOC_BRCMSTB is not set
6886+
6887+#
6888+# NXP/Freescale QorIQ SoC drivers
6889+#
6890+
6891+#
6892+# i.MX SoC drivers
6893+#
6894+
6895+#
6896+# Qualcomm SoC drivers
6897+#
6898+# CONFIG_SOC_TI is not set
6899+
6900+#
6901+# Xilinx SoC drivers
6902+#
6903+# CONFIG_XILINX_VCU is not set
6904+# CONFIG_PM_DEVFREQ is not set
6905+# CONFIG_EXTCON is not set
6906+# CONFIG_MEMORY is not set
6907+# CONFIG_IIO is not set
6908+CONFIG_PWM=y
6909+CONFIG_PWM_HI35XX=y
6910+
6911+#
6912+# IRQ chip support
6913+#
6914+CONFIG_IRQCHIP=y
6915+CONFIG_ARM_GIC=y
6916+CONFIG_ARM_GIC_MAX_NR=1
6917+# CONFIG_IPACK_BUS is not set
6918+CONFIG_RESET_CONTROLLER=y
6919+# CONFIG_RESET_TI_SYSCON is not set
6920+# CONFIG_FMC is not set
6921+
6922+#
6923+# PHY Subsystem
6924+#
6925+CONFIG_GENERIC_PHY=y
6926+# CONFIG_BCM_KONA_USB2_PHY is not set
6927+# CONFIG_PHY_PXA_28NM_HSIC is not set
6928+# CONFIG_PHY_PXA_28NM_USB2 is not set
6929+# CONFIG_PHY_MAPPHONE_MDM6600 is not set
6930+CONFIG_HI_USB_PHY=y
6931+CONFIG_PHY_HISI_USB2=y
6932+CONFIG_HIBVT_USB_PHY=y
6933+CONFIG_USB_MODE_OPTION=y
6934+CONFIG_USB_DRD0_IN_HOST=y
6935+CONFIG_USB_DRD0_IN_DEVICE=y
6936+# CONFIG_POWERCAP is not set
6937+# CONFIG_MCB is not set
6938+# CONFIG_RAS is not set
6939+# CONFIG_DAX is not set
6940+CONFIG_NVMEM=y
6941+
6942+#
6943+# HW tracing support
6944+#
6945+# CONFIG_STM is not set
6946+# CONFIG_INTEL_TH is not set
6947+# CONFIG_FPGA is not set
6948+# CONFIG_FSI is not set
6949+# CONFIG_TEE is not set
6950+# CONFIG_SIOX is not set
6951+# CONFIG_SLIMBUS is not set
6952+# CONFIG_HI_DMAC is not set
6953+# CONFIG_HIEDMAC is not set
6954+
6955+#
6956+# Hisilicon driver support
6957+#
6958+# CONFIG_CMA_MEM_SHARED is not set
6959+# CONFIG_CMA_ADVANCE_SHARE is not set
6960+#
6961+# File systems
6962+#
6963+CONFIG_DCACHE_WORD_ACCESS=y
6964+CONFIG_FS_IOMAP=y
6965+# CONFIG_EXT2_FS is not set
6966+# CONFIG_EXT3_FS is not set
6967+CONFIG_EXT4_FS=y
6968+CONFIG_EXT4_USE_FOR_EXT2=y
6969+CONFIG_EXT4_FS_POSIX_ACL=y
6970+CONFIG_EXT4_FS_SECURITY=y
6971+# CONFIG_EXT4_ENCRYPTION is not set
6972+# CONFIG_EXT4_DEBUG is not set
6973+CONFIG_JBD2=y
6974+# CONFIG_JBD2_DEBUG is not set
6975+CONFIG_FS_MBCACHE=y
6976+CONFIG_REISERFS_FS=m
6977+CONFIG_REISERFS_CHECK=y
6978+CONFIG_REISERFS_PROC_INFO=y
6979+CONFIG_REISERFS_FS_XATTR=y
6980+CONFIG_REISERFS_FS_POSIX_ACL=y
6981+CONFIG_REISERFS_FS_SECURITY=y
6982+CONFIG_JFS_FS=m
6983+CONFIG_JFS_POSIX_ACL=y
6984+CONFIG_JFS_SECURITY=y
6985+CONFIG_JFS_DEBUG=y
6986+CONFIG_JFS_STATISTICS=y
6987+CONFIG_XFS_FS=m
6988+CONFIG_XFS_QUOTA=y
6989+CONFIG_XFS_POSIX_ACL=y
6990+CONFIG_XFS_RT=y
6991+# CONFIG_XFS_ONLINE_SCRUB is not set
6992+# CONFIG_XFS_WARN is not set
6993+# CONFIG_XFS_DEBUG is not set
6994+# CONFIG_GFS2_FS is not set
6995+# CONFIG_OCFS2_FS is not set
6996+# CONFIG_BTRFS_FS is not set
6997+# CONFIG_NILFS2_FS is not set
6998+# CONFIG_F2FS_FS is not set
6999+CONFIG_FS_POSIX_ACL=y
7000+CONFIG_EXPORTFS=y
7001+# CONFIG_EXPORTFS_BLOCK_OPS is not set
7002+CONFIG_FILE_LOCKING=y
7003+CONFIG_MANDATORY_FILE_LOCKING=y
7004+# CONFIG_FS_ENCRYPTION is not set
7005+CONFIG_FSNOTIFY=y
7006+CONFIG_DNOTIFY=y
7007+CONFIG_INOTIFY_USER=y
7008+# CONFIG_FANOTIFY is not set
7009+# CONFIG_QUOTA is not set
7010+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
7011+CONFIG_QUOTACTL=y
7012+# CONFIG_AUTOFS4_FS is not set
7013+# CONFIG_AUTOFS_FS is not set
7014+# CONFIG_FUSE_FS is not set
7015+# CONFIG_OVERLAY_FS is not set
7016+
7017+#
7018+# Caches
7019+#
7020+# CONFIG_FSCACHE is not set
7021+
7022+#
7023+# CD-ROM/DVD Filesystems
7024+#
7025+# CONFIG_ISO9660_FS is not set
7026+# CONFIG_UDF_FS is not set
7027+
7028+#
7029+# DOS/FAT/NT Filesystems
7030+#
7031+CONFIG_FAT_FS=y
7032+CONFIG_MSDOS_FS=y
7033+CONFIG_VFAT_FS=y
7034+CONFIG_FAT_DEFAULT_CODEPAGE=437
7035+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
7036+# CONFIG_FAT_DEFAULT_UTF8 is not set
7037+# CONFIG_NTFS_FS is not set
7038+
7039+#
7040+# Pseudo filesystems
7041+#
7042+CONFIG_PROC_FS=y
7043+CONFIG_PROC_SYSCTL=y
7044+CONFIG_PROC_PAGE_MONITOR=y
7045+# CONFIG_PROC_CHILDREN is not set
7046+CONFIG_KERNFS=y
7047+CONFIG_SYSFS=y
7048+CONFIG_TMPFS=y
7049+# CONFIG_TMPFS_POSIX_ACL is not set
7050+# CONFIG_TMPFS_XATTR is not set
7051+CONFIG_MEMFD_CREATE=y
7052+CONFIG_CONFIGFS_FS=y
7053+CONFIG_MISC_FILESYSTEMS=y
7054+# CONFIG_ORANGEFS_FS is not set
7055+# CONFIG_ADFS_FS is not set
7056+# CONFIG_AFFS_FS is not set
7057+# CONFIG_ECRYPT_FS is not set
7058+# CONFIG_HFS_FS is not set
7059+# CONFIG_HFSPLUS_FS is not set
7060+# CONFIG_BEFS_FS is not set
7061+# CONFIG_BFS_FS is not set
7062+# CONFIG_EFS_FS is not set
7063+CONFIG_CRAMFS=y
7064+CONFIG_CRAMFS_BLOCKDEV=y
7065+# CONFIG_SQUASHFS is not set
7066+# CONFIG_VXFS_FS is not set
7067+# CONFIG_MINIX_FS is not set
7068+# CONFIG_OMFS_FS is not set
7069+# CONFIG_HPFS_FS is not set
7070+# CONFIG_QNX4FS_FS is not set
7071+# CONFIG_QNX6FS_FS is not set
7072+# CONFIG_ROMFS_FS is not set
7073+# CONFIG_PSTORE is not set
7074+# CONFIG_SYSV_FS is not set
7075+# CONFIG_UFS_FS is not set
7076+CONFIG_NETWORK_FILESYSTEMS=y
7077+CONFIG_NFS_FS=y
7078+CONFIG_NFS_V2=y
7079+CONFIG_NFS_V3=y
7080+CONFIG_NFS_V3_ACL=y
7081+CONFIG_NFS_V4=y
7082+# CONFIG_NFS_SWAP is not set
7083+# CONFIG_NFS_V4_1 is not set
7084+# CONFIG_ROOT_NFS is not set
7085+# CONFIG_NFS_USE_LEGACY_DNS is not set
7086+CONFIG_NFS_USE_KERNEL_DNS=y
7087+# CONFIG_NFSD is not set
7088+CONFIG_GRACE_PERIOD=y
7089+CONFIG_LOCKD=y
7090+CONFIG_LOCKD_V4=y
7091+CONFIG_NFS_ACL_SUPPORT=y
7092+CONFIG_NFS_COMMON=y
7093+CONFIG_SUNRPC=y
7094+CONFIG_SUNRPC_GSS=y
7095+# CONFIG_SUNRPC_DEBUG is not set
7096+# CONFIG_CEPH_FS is not set
7097+# CONFIG_CIFS is not set
7098+# CONFIG_CODA_FS is not set
7099+# CONFIG_AFS_FS is not set
7100+CONFIG_NLS=y
7101+CONFIG_NLS_DEFAULT="iso8859-1"
7102+CONFIG_NLS_CODEPAGE_437=y
7103+CONFIG_NLS_CODEPAGE_737=m
7104+CONFIG_NLS_CODEPAGE_775=m
7105+CONFIG_NLS_CODEPAGE_850=m
7106+CONFIG_NLS_CODEPAGE_852=m
7107+CONFIG_NLS_CODEPAGE_855=m
7108+CONFIG_NLS_CODEPAGE_857=m
7109+CONFIG_NLS_CODEPAGE_860=m
7110+CONFIG_NLS_CODEPAGE_861=m
7111+CONFIG_NLS_CODEPAGE_862=m
7112+CONFIG_NLS_CODEPAGE_863=m
7113+CONFIG_NLS_CODEPAGE_864=m
7114+CONFIG_NLS_CODEPAGE_865=m
7115+CONFIG_NLS_CODEPAGE_866=m
7116+CONFIG_NLS_CODEPAGE_869=m
7117+CONFIG_NLS_CODEPAGE_936=y
7118+CONFIG_NLS_CODEPAGE_950=m
7119+CONFIG_NLS_CODEPAGE_932=m
7120+CONFIG_NLS_CODEPAGE_949=m
7121+CONFIG_NLS_CODEPAGE_874=m
7122+CONFIG_NLS_ISO8859_8=m
7123+CONFIG_NLS_CODEPAGE_1250=m
7124+CONFIG_NLS_CODEPAGE_1251=m
7125+CONFIG_NLS_ASCII=y
7126+CONFIG_NLS_ISO8859_1=y
7127+CONFIG_NLS_ISO8859_2=m
7128+CONFIG_NLS_ISO8859_3=m
7129+CONFIG_NLS_ISO8859_4=m
7130+CONFIG_NLS_ISO8859_5=m
7131+CONFIG_NLS_ISO8859_6=m
7132+CONFIG_NLS_ISO8859_7=m
7133+CONFIG_NLS_ISO8859_9=m
7134+CONFIG_NLS_ISO8859_13=m
7135+CONFIG_NLS_ISO8859_14=m
7136+CONFIG_NLS_ISO8859_15=m
7137+CONFIG_NLS_KOI8_R=m
7138+CONFIG_NLS_KOI8_U=m
7139+# CONFIG_NLS_MAC_ROMAN is not set
7140+# CONFIG_NLS_MAC_CELTIC is not set
7141+# CONFIG_NLS_MAC_CENTEURO is not set
7142+# CONFIG_NLS_MAC_CROATIAN is not set
7143+# CONFIG_NLS_MAC_CYRILLIC is not set
7144+# CONFIG_NLS_MAC_GAELIC is not set
7145+# CONFIG_NLS_MAC_GREEK is not set
7146+# CONFIG_NLS_MAC_ICELAND is not set
7147+# CONFIG_NLS_MAC_INUIT is not set
7148+# CONFIG_NLS_MAC_ROMANIAN is not set
7149+# CONFIG_NLS_MAC_TURKISH is not set
7150+CONFIG_NLS_UTF8=y
7151+# CONFIG_DLM is not set
7152+
7153+#
7154+# Security options
7155+#
7156+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
7157+CONFIG_SECURITY=y
7158+CONFIG_SECURITYFS=y
7159+CONFIG_SECURITY_NETWORK=y
7160+#CONFIG_PAGE_TABLE_ISOLATION=y
7161+#CONFIG_SECURITY_INFINIBAND=y
7162+#CONFIG_SECURITY_NETWORK_XFRM=y
7163+#CONFIG_SECURITY_PATH=y
7164+CONFIG_SECURITY_SELINUX=y
7165+CONFIG_SECURITY_SELINUX_BOOTPARAM=y
7166+CONFIG_SECURITY_SELINUX_BOOTPARAM_VALUE=1
7167+# CONFIG_SECURITY_SELINUX_DISABLE is not set
7168+CONFIG_SECURITY_SELINUX_DEVELOP=y
7169+CONFIG_SECURITY_SELINUX_AVC_STATS=y
7170+CONFIG_SECURITY_SELINUX_CHECKREQPROT_VALUE=1
7171+CONFIG_DEFAULT_SECURITY_SELINUX=y
7172+CONFIG_DEFAULT_SECURITY="selinux"
7173+#CONFIG_SECURITY_SMACK=y
7174+# CONFIG_SECURITY_SMACK_BRINGUP is not set
7175+#CONFIG_SECURITY_SMACK_NETFILTER=y
7176+#CONFIG_SECURITY_SMACK_APPEND_SIGNALS=y
7177+#CONFIG_SECURITY_TOMOYO=y
7178+#CONFIG_SECURITY_TOMOYO_MAX_ACCEPT_ENTRY=2048
7179+#CONFIG_SECURITY_TOMOYO_MAX_AUDIT_LOG=1024
7180+#CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER is not set
7181+#CONFIG_SECURITY_TOMOYO_POLICY_LOADER="/sbin/tomoyo-init"
7182+#CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/sbin/init"
7183+CONFIG_SECURITY_APPARMOR=y
7184+CONFIG_SECURITY_APPARMOR_BOOTPARAM_VALUE=1
7185+CONFIG_SECURITY_APPARMOR_HASH=y
7186+CONFIG_SECURITY_APPARMOR_HASH_DEFAULT=y
7187+# CONFIG_SECURITY_APPARMOR_DEBUG is not set
7188+# CONFIG_SECURITY_LOADPIN is not set
7189+# CONFIG_SECURITY_YAMA=y
7190+
7191+CONFIG_CRYPTO=y
7192+
7193+#
7194+# Crypto core or helper
7195+#
7196+CONFIG_CRYPTO_ALGAPI=y
7197+CONFIG_CRYPTO_ALGAPI2=y
7198+CONFIG_CRYPTO_AEAD=m
7199+CONFIG_CRYPTO_AEAD2=y
7200+CONFIG_CRYPTO_BLKCIPHER2=y
7201+CONFIG_CRYPTO_HASH=y
7202+CONFIG_CRYPTO_HASH2=y
7203+CONFIG_CRYPTO_RNG=y
7204+CONFIG_CRYPTO_RNG2=y
7205+CONFIG_CRYPTO_RNG_DEFAULT=m
7206+CONFIG_CRYPTO_AKCIPHER2=y
7207+CONFIG_CRYPTO_KPP2=y
7208+CONFIG_CRYPTO_ACOMP2=y
7209+# CONFIG_CRYPTO_RSA is not set
7210+# CONFIG_CRYPTO_DH is not set
7211+# CONFIG_CRYPTO_ECDH is not set
7212+CONFIG_CRYPTO_MANAGER=m
7213+CONFIG_CRYPTO_MANAGER2=y
7214+# CONFIG_CRYPTO_USER is not set
7215+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
7216+# CONFIG_CRYPTO_GF128MUL is not set
7217+CONFIG_CRYPTO_NULL=m
7218+CONFIG_CRYPTO_NULL2=y
7219+# CONFIG_CRYPTO_PCRYPT is not set
7220+CONFIG_CRYPTO_WORKQUEUE=y
7221+# CONFIG_CRYPTO_CRYPTD is not set
7222+# CONFIG_CRYPTO_MCRYPTD is not set
7223+# CONFIG_CRYPTO_AUTHENC is not set
7224+# CONFIG_CRYPTO_TEST is not set
7225+
7226+#
7227+# Authenticated Encryption with Associated Data
7228+#
7229+# CONFIG_CRYPTO_CCM is not set
7230+# CONFIG_CRYPTO_GCM is not set
7231+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set
7232+# CONFIG_CRYPTO_AEGIS128 is not set
7233+# CONFIG_CRYPTO_AEGIS128L is not set
7234+# CONFIG_CRYPTO_AEGIS256 is not set
7235+# CONFIG_CRYPTO_MORUS640 is not set
7236+# CONFIG_CRYPTO_MORUS1280 is not set
7237+# CONFIG_CRYPTO_SEQIV is not set
7238+CONFIG_CRYPTO_ECHAINIV=m
7239+
7240+#
7241+# Block modes
7242+#
7243+# CONFIG_CRYPTO_CBC is not set
7244+# CONFIG_CRYPTO_CFB is not set
7245+# CONFIG_CRYPTO_CTR is not set
7246+# CONFIG_CRYPTO_CTS is not set
7247+# CONFIG_CRYPTO_ECB is not set
7248+# CONFIG_CRYPTO_LRW is not set
7249+# CONFIG_CRYPTO_PCBC is not set
7250+# CONFIG_CRYPTO_XTS is not set
7251+# CONFIG_CRYPTO_KEYWRAP is not set
7252+
7253+#
7254+# Hash modes
7255+#
7256+# CONFIG_CRYPTO_CMAC is not set
7257+CONFIG_CRYPTO_HMAC=m
7258+# CONFIG_CRYPTO_XCBC is not set
7259+# CONFIG_CRYPTO_VMAC is not set
7260+
7261+#
7262+# Digest
7263+#
7264+CONFIG_CRYPTO_CRC32C=y
7265+# CONFIG_CRYPTO_CRC32 is not set
7266+# CONFIG_CRYPTO_CRCT10DIF is not set
7267+# CONFIG_CRYPTO_GHASH is not set
7268+# CONFIG_CRYPTO_POLY1305 is not set
7269+# CONFIG_CRYPTO_MD4 is not set
7270+# CONFIG_CRYPTO_MD5 is not set
7271+# CONFIG_CRYPTO_MICHAEL_MIC is not set
7272+# CONFIG_CRYPTO_RMD128 is not set
7273+# CONFIG_CRYPTO_RMD160 is not set
7274+# CONFIG_CRYPTO_RMD256 is not set
7275+# CONFIG_CRYPTO_RMD320 is not set
7276+CONFIG_CRYPTO_SHA1=y
7277+CONFIG_CRYPTO_SHA256=m
7278+# CONFIG_CRYPTO_SHA512 is not set
7279+# CONFIG_CRYPTO_SHA3 is not set
7280+# CONFIG_CRYPTO_SM3 is not set
7281+# CONFIG_CRYPTO_TGR192 is not set
7282+# CONFIG_CRYPTO_WP512 is not set
7283+
7284+#
7285+# Ciphers
7286+#
7287+CONFIG_CRYPTO_AES=y
7288+# CONFIG_CRYPTO_AES_TI is not set
7289+# CONFIG_CRYPTO_ANUBIS is not set
7290+# CONFIG_CRYPTO_ARC4 is not set
7291+# CONFIG_CRYPTO_BLOWFISH is not set
7292+# CONFIG_CRYPTO_CAMELLIA is not set
7293+# CONFIG_CRYPTO_CAST5 is not set
7294+# CONFIG_CRYPTO_CAST6 is not set
7295+# CONFIG_CRYPTO_DES is not set
7296+# CONFIG_CRYPTO_FCRYPT is not set
7297+# CONFIG_CRYPTO_KHAZAD is not set
7298+# CONFIG_CRYPTO_SALSA20 is not set
7299+# CONFIG_CRYPTO_CHACHA20 is not set
7300+# CONFIG_CRYPTO_SEED is not set
7301+# CONFIG_CRYPTO_SERPENT is not set
7302+# CONFIG_CRYPTO_SM4 is not set
7303+# CONFIG_CRYPTO_TEA is not set
7304+# CONFIG_CRYPTO_TWOFISH is not set
7305+
7306+#
7307+# Compression
7308+#
7309+# CONFIG_CRYPTO_DEFLATE is not set
7310+# CONFIG_CRYPTO_LZO is not set
7311+# CONFIG_CRYPTO_842 is not set
7312+# CONFIG_CRYPTO_LZ4 is not set
7313+# CONFIG_CRYPTO_LZ4HC is not set
7314+# CONFIG_CRYPTO_ZSTD is not set
7315+
7316+#
7317+# Random Number Generation
7318+#
7319+CONFIG_CRYPTO_ANSI_CPRNG=y
7320+CONFIG_CRYPTO_DRBG_MENU=m
7321+CONFIG_CRYPTO_DRBG_HMAC=y
7322+# CONFIG_CRYPTO_DRBG_HASH is not set
7323+CONFIG_CRYPTO_DRBG=m
7324+CONFIG_CRYPTO_JITTERENTROPY=m
7325+# CONFIG_CRYPTO_USER_API_HASH is not set
7326+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
7327+# CONFIG_CRYPTO_USER_API_RNG is not set
7328+# CONFIG_CRYPTO_USER_API_AEAD is not set
7329+CONFIG_CRYPTO_HW=y
7330+# CONFIG_CRYPTO_DEV_CCREE is not set
7331+# CONFIG_ASYMMETRIC_KEY_TYPE is not set
7332+
7333+#
7334+# Certificates for signature checking
7335+#
7336+# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set
7337+
7338+#
7339+# Library routines
7340+#
7341+CONFIG_BITREVERSE=y
7342+CONFIG_HAVE_ARCH_BITREVERSE=y
7343+CONFIG_RATIONAL=y
7344+CONFIG_GENERIC_STRNCPY_FROM_USER=y
7345+CONFIG_GENERIC_STRNLEN_USER=y
7346+CONFIG_GENERIC_NET_UTILS=y
7347+CONFIG_GENERIC_PCI_IOMAP=y
7348+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
7349+# CONFIG_CRC_CCITT is not set
7350+CONFIG_CRC16=y
7351+# CONFIG_CRC_T10DIF is not set
7352+# CONFIG_CRC_ITU_T is not set
7353+CONFIG_CRC32=y
7354+# CONFIG_CRC32_SELFTEST is not set
7355+CONFIG_CRC32_SLICEBY8=y
7356+# CONFIG_CRC32_SLICEBY4 is not set
7357+# CONFIG_CRC32_SARWATE is not set
7358+# CONFIG_CRC32_BIT is not set
7359+# CONFIG_CRC64 is not set
7360+# CONFIG_CRC4 is not set
7361+# CONFIG_CRC7 is not set
7362+CONFIG_LIBCRC32C=m
7363+# CONFIG_CRC8 is not set
7364+CONFIG_AUDIT_GENERIC=y
7365+# CONFIG_RANDOM32_SELFTEST is not set
7366+CONFIG_ZLIB_INFLATE=y
7367+CONFIG_XZ_DEC=y
7368+CONFIG_XZ_DEC_X86=y
7369+CONFIG_XZ_DEC_POWERPC=y
7370+CONFIG_XZ_DEC_IA64=y
7371+CONFIG_XZ_DEC_ARM=y
7372+CONFIG_XZ_DEC_ARMTHUMB=y
7373+CONFIG_XZ_DEC_SPARC=y
7374+CONFIG_XZ_DEC_BCJ=y
7375+# CONFIG_XZ_DEC_TEST is not set
7376+CONFIG_GENERIC_ALLOCATOR=y
7377+CONFIG_ASSOCIATIVE_ARRAY=y
7378+CONFIG_HAS_IOMEM=y
7379+CONFIG_HAS_IOPORT_MAP=y
7380+CONFIG_HAS_DMA=y
7381+CONFIG_NEED_DMA_MAP_STATE=y
7382+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
7383+CONFIG_SGL_ALLOC=y
7384+CONFIG_CPU_RMAP=y
7385+CONFIG_DQL=y
7386+CONFIG_NLATTR=y
7387+# CONFIG_CORDIC is not set
7388+# CONFIG_DDR is not set
7389+# CONFIG_IRQ_POLL is not set
7390+CONFIG_LIBFDT=y
7391+CONFIG_OID_REGISTRY=y
7392+CONFIG_SG_POOL=y
7393+CONFIG_ARCH_HAS_SG_CHAIN=y
7394+CONFIG_SBITMAP=y
7395+# CONFIG_STRING_SELFTEST is not set
7396+
7397+#
7398+# Kernel hacking
7399+#
7400+
7401+#
7402+# printk and dmesg options
7403+#
7404+# CONFIG_PRINTK_TIME is not set
7405+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
7406+CONFIG_CONSOLE_LOGLEVEL_QUIET=4
7407+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
7408+# CONFIG_BOOT_PRINTK_DELAY is not set
7409+# CONFIG_DYNAMIC_DEBUG is not set
7410+
7411+#
7412+# Compile-time checks and compiler options
7413+#
7414+# CONFIG_DEBUG_INFO is not set
7415+CONFIG_ENABLE_MUST_CHECK=y
7416+CONFIG_FRAME_WARN=1024
7417+# CONFIG_STRIP_ASM_SYMS is not set
7418+# CONFIG_READABLE_ASM is not set
7419+# CONFIG_UNUSED_SYMBOLS is not set
7420+# CONFIG_PAGE_OWNER is not set
7421+CONFIG_DEBUG_FS=y
7422+# CONFIG_HEADERS_CHECK is not set
7423+# CONFIG_DEBUG_SECTION_MISMATCH is not set
7424+CONFIG_SECTION_MISMATCH_WARN_ONLY=y
7425+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
7426+# CONFIG_MAGIC_SYSRQ is not set
7427+CONFIG_DEBUG_KERNEL=y
7428+
7429+#
7430+# Memory Debugging
7431+#
7432+# CONFIG_PAGE_EXTENSION is not set
7433+# CONFIG_DEBUG_PAGEALLOC is not set
7434+# CONFIG_PAGE_POISONING is not set
7435+# CONFIG_DEBUG_RODATA_TEST is not set
7436+# CONFIG_DEBUG_OBJECTS is not set
7437+# CONFIG_SLUB_DEBUG_ON is not set
7438+# CONFIG_SLUB_STATS is not set
7439+CONFIG_HAVE_DEBUG_KMEMLEAK=y
7440+# CONFIG_DEBUG_KMEMLEAK is not set
7441+# CONFIG_DEBUG_STACK_USAGE is not set
7442+# CONFIG_DEBUG_VM is not set
7443+CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
7444+# CONFIG_DEBUG_VIRTUAL is not set
7445+CONFIG_DEBUG_MEMORY_INIT=y
7446+# CONFIG_DEBUG_PER_CPU_MAPS is not set
7447+# CONFIG_DEBUG_HIGHMEM is not set
7448+CONFIG_ARCH_HAS_KCOV=y
7449+CONFIG_CC_HAS_SANCOV_TRACE_PC=y
7450+# CONFIG_KCOV is not set
7451+# CONFIG_DEBUG_SHIRQ is not set
7452+
7453+#
7454+# Debug Lockups and Hangs
7455+#
7456+# CONFIG_SOFTLOCKUP_DETECTOR is not set
7457+# CONFIG_DETECT_HUNG_TASK is not set
7458+# CONFIG_WQ_WATCHDOG is not set
7459+# CONFIG_PANIC_ON_OOPS is not set
7460+CONFIG_PANIC_ON_OOPS_VALUE=0
7461+CONFIG_PANIC_TIMEOUT=0
7462+CONFIG_SCHED_DEBUG=y
7463+# CONFIG_SCHEDSTATS is not set
7464+# CONFIG_SCHED_STACK_END_CHECK is not set
7465+# CONFIG_DEBUG_TIMEKEEPING is not set
7466+
7467+#
7468+# Lock Debugging (spinlocks, mutexes, etc...)
7469+#
7470+CONFIG_LOCK_DEBUGGING_SUPPORT=y
7471+# CONFIG_PROVE_LOCKING is not set
7472+# CONFIG_LOCK_STAT is not set
7473+# CONFIG_DEBUG_RT_MUTEXES is not set
7474+# CONFIG_DEBUG_SPINLOCK is not set
7475+# CONFIG_DEBUG_MUTEXES is not set
7476+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
7477+# CONFIG_DEBUG_RWSEMS is not set
7478+# CONFIG_DEBUG_LOCK_ALLOC is not set
7479+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
7480+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
7481+# CONFIG_LOCK_TORTURE_TEST is not set
7482+# CONFIG_WW_MUTEX_SELFTEST is not set
7483+CONFIG_STACKTRACE=y
7484+# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
7485+# CONFIG_DEBUG_KOBJECT is not set
7486+CONFIG_DEBUG_BUGVERBOSE=y
7487+# CONFIG_DEBUG_LIST is not set
7488+# CONFIG_DEBUG_PI_LIST is not set
7489+# CONFIG_DEBUG_SG is not set
7490+# CONFIG_DEBUG_NOTIFIERS is not set
7491+# CONFIG_DEBUG_CREDENTIALS is not set
7492+
7493+#
7494+# RCU Debugging
7495+#
7496+# CONFIG_RCU_PERF_TEST is not set
7497+# CONFIG_RCU_TORTURE_TEST is not set
7498+CONFIG_RCU_CPU_STALL_TIMEOUT=60
7499+# CONFIG_RCU_TRACE is not set
7500+# CONFIG_RCU_EQS_DEBUG is not set
7501+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set
7502+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
7503+# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
7504+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
7505+# CONFIG_FAULT_INJECTION is not set
7506+# CONFIG_LATENCYTOP is not set
7507+CONFIG_HAVE_FUNCTION_TRACER=y
7508+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
7509+CONFIG_HAVE_DYNAMIC_FTRACE=y
7510+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
7511+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
7512+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
7513+CONFIG_HAVE_C_RECORDMCOUNT=y
7514+CONFIG_TRACING_SUPPORT=y
7515+# CONFIG_FTRACE is not set
7516+# CONFIG_DMA_API_DEBUG is not set
7517+CONFIG_RUNTIME_TESTING_MENU=y
7518+# CONFIG_LKDTM is not set
7519+# CONFIG_TEST_LIST_SORT is not set
7520+# CONFIG_TEST_SORT is not set
7521+# CONFIG_BACKTRACE_SELF_TEST is not set
7522+# CONFIG_RBTREE_TEST is not set
7523+# CONFIG_INTERVAL_TREE_TEST is not set
7524+# CONFIG_PERCPU_TEST is not set
7525+# CONFIG_ATOMIC64_SELFTEST is not set
7526+# CONFIG_TEST_HEXDUMP is not set
7527+# CONFIG_TEST_STRING_HELPERS is not set
7528+# CONFIG_TEST_KSTRTOX is not set
7529+# CONFIG_TEST_PRINTF is not set
7530+# CONFIG_TEST_BITMAP is not set
7531+# CONFIG_TEST_BITFIELD is not set
7532+# CONFIG_TEST_UUID is not set
7533+# CONFIG_TEST_OVERFLOW is not set
7534+# CONFIG_TEST_RHASHTABLE is not set
7535+# CONFIG_TEST_HASH is not set
7536+# CONFIG_TEST_IDA is not set
7537+# CONFIG_TEST_LKM is not set
7538+# CONFIG_TEST_USER_COPY is not set
7539+# CONFIG_TEST_BPF is not set
7540+# CONFIG_FIND_BIT_BENCHMARK is not set
7541+# CONFIG_TEST_FIRMWARE is not set
7542diff --git a/arch/arm/configs/hi3516dv300_smp_defconfig b/arch/arm/configs/hi3516dv300_smp_defconfig
7543new file mode 100644
7544index 000000000..109c06652
7545--- /dev/null
7546+++ b/arch/arm/configs/hi3516dv300_smp_defconfig
7547@@ -0,0 +1,3189 @@
7548+#
7549+# Automatically generated file; DO NOT EDIT.
7550+# Linux/arm 4.19.90 Kernel Configuration
7551+#
7552+
7553+#
7554+# Compiler: arm-himix410-linux-gcc (HC&C V1R3C00SPC200B041_20200707) 7.3.0
7555+#
7556+CONFIG_CC_IS_GCC=y
7557+CONFIG_GCC_VERSION=70300
7558+CONFIG_CLANG_VERSION=0
7559+CONFIG_CC_HAS_ASM_GOTO=y
7560+CONFIG_IRQ_WORK=y
7561+CONFIG_BUILDTIME_EXTABLE_SORT=y
7562+
7563+#
7564+# General setup
7565+#
7566+CONFIG_INIT_ENV_ARG_LIMIT=32
7567+# CONFIG_COMPILE_TEST is not set
7568+CONFIG_LOCALVERSION=""
7569+# CONFIG_LOCALVERSION_AUTO is not set
7570+CONFIG_BUILD_SALT=""
7571+CONFIG_HAVE_KERNEL_GZIP=y
7572+CONFIG_HAVE_KERNEL_LZMA=y
7573+CONFIG_HAVE_KERNEL_XZ=y
7574+CONFIG_HAVE_KERNEL_LZO=y
7575+CONFIG_HAVE_KERNEL_LZ4=y
7576+CONFIG_KERNEL_GZIP=y
7577+# CONFIG_KERNEL_LZMA is not set
7578+# CONFIG_KERNEL_XZ is not set
7579+# CONFIG_KERNEL_LZO is not set
7580+# CONFIG_KERNEL_LZ4 is not set
7581+CONFIG_DEFAULT_HOSTNAME="(none)"
7582+# CONFIG_SWAP is not set
7583+CONFIG_SYSVIPC=y
7584+CONFIG_SYSVIPC_SYSCTL=y
7585+# CONFIG_POSIX_MQUEUE is not set
7586+CONFIG_CROSS_MEMORY_ATTACH=y
7587+CONFIG_USELIB=y
7588+# CONFIG_AUDIT is not set
7589+
7590+#
7591+# IRQ subsystem
7592+#
7593+CONFIG_GENERIC_IRQ_PROBE=y
7594+CONFIG_GENERIC_IRQ_SHOW=y
7595+CONFIG_GENERIC_IRQ_SHOW_LEVEL=y
7596+CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y
7597+CONFIG_GENERIC_IRQ_MIGRATION=y
7598+CONFIG_HARDIRQS_SW_RESEND=y
7599+CONFIG_IRQ_DOMAIN=y
7600+CONFIG_IRQ_DOMAIN_HIERARCHY=y
7601+CONFIG_HANDLE_DOMAIN_IRQ=y
7602+CONFIG_IRQ_FORCED_THREADING=y
7603+CONFIG_SPARSE_IRQ=y
7604+# CONFIG_GENERIC_IRQ_DEBUGFS is not set
7605+CONFIG_GENERIC_IRQ_MULTI_HANDLER=y
7606+CONFIG_ARCH_CLOCKSOURCE_DATA=y
7607+CONFIG_GENERIC_TIME_VSYSCALL=y
7608+CONFIG_GENERIC_CLOCKEVENTS=y
7609+CONFIG_ARCH_HAS_TICK_BROADCAST=y
7610+CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
7611+
7612+#
7613+# Timers subsystem
7614+#
7615+CONFIG_HZ_PERIODIC=y
7616+# CONFIG_NO_HZ_IDLE is not set
7617+# CONFIG_NO_HZ_FULL is not set
7618+# CONFIG_NO_HZ is not set
7619+# CONFIG_HIGH_RES_TIMERS is not set
7620+CONFIG_PREEMPT_NONE=y
7621+# CONFIG_PREEMPT_VOLUNTARY is not set
7622+# CONFIG_PREEMPT is not set
7623+
7624+#
7625+# CPU/Task time and stats accounting
7626+#
7627+CONFIG_TICK_CPU_ACCOUNTING=y
7628+# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set
7629+# CONFIG_IRQ_TIME_ACCOUNTING is not set
7630+# CONFIG_BSD_PROCESS_ACCT is not set
7631+# CONFIG_TASKSTATS is not set
7632+CONFIG_CPU_ISOLATION=y
7633+
7634+#
7635+# RCU Subsystem
7636+#
7637+CONFIG_TREE_RCU=y
7638+# CONFIG_RCU_EXPERT is not set
7639+CONFIG_SRCU=y
7640+CONFIG_TREE_SRCU=y
7641+CONFIG_RCU_STALL_COMMON=y
7642+CONFIG_RCU_NEED_SEGCBLIST=y
7643+# CONFIG_IKCONFIG is not set
7644+CONFIG_LOG_BUF_SHIFT=17
7645+CONFIG_LOG_CPU_MAX_BUF_SHIFT=12
7646+CONFIG_PRINTK_SAFE_LOG_BUF_SHIFT=13
7647+CONFIG_GENERIC_SCHED_CLOCK=y
7648+CONFIG_CGROUPS=y
7649+# CONFIG_MEMCG is not set
7650+# CONFIG_BLK_CGROUP is not set
7651+CONFIG_CGROUP_SCHED=y
7652+CONFIG_FAIR_GROUP_SCHED=y
7653+# CONFIG_CFS_BANDWIDTH is not set
7654+# CONFIG_RT_GROUP_SCHED is not set
7655+# CONFIG_CGROUP_PIDS is not set
7656+# CONFIG_CGROUP_RDMA is not set
7657+# CONFIG_CGROUP_FREEZER is not set
7658+# CONFIG_CPUSETS is not set
7659+# CONFIG_CGROUP_DEVICE is not set
7660+# CONFIG_CGROUP_CPUACCT is not set
7661+# CONFIG_CGROUP_DEBUG is not set
7662+CONFIG_NAMESPACES=y
7663+CONFIG_UTS_NS=y
7664+CONFIG_IPC_NS=y
7665+# CONFIG_USER_NS is not set
7666+CONFIG_PID_NS=y
7667+CONFIG_NET_NS=y
7668+# CONFIG_CHECKPOINT_RESTORE is not set
7669+# CONFIG_SCHED_AUTOGROUP is not set
7670+# CONFIG_SYSFS_DEPRECATED is not set
7671+# CONFIG_RELAY is not set
7672+# CONFIG_BLK_DEV_INITRD is not set
7673+CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y
7674+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
7675+CONFIG_SYSCTL=y
7676+CONFIG_ANON_INODES=y
7677+CONFIG_HAVE_UID16=y
7678+CONFIG_BPF=y
7679+# CONFIG_EXPERT is not set
7680+CONFIG_UID16=y
7681+CONFIG_MULTIUSER=y
7682+CONFIG_SYSFS_SYSCALL=y
7683+CONFIG_FHANDLE=y
7684+CONFIG_POSIX_TIMERS=y
7685+CONFIG_PRINTK=y
7686+CONFIG_PRINTK_NMI=y
7687+CONFIG_BUG=y
7688+CONFIG_ELF_CORE=y
7689+CONFIG_BASE_FULL=y
7690+CONFIG_FUTEX=y
7691+CONFIG_FUTEX_PI=y
7692+CONFIG_EPOLL=y
7693+CONFIG_SIGNALFD=y
7694+CONFIG_TIMERFD=y
7695+CONFIG_EVENTFD=y
7696+CONFIG_SHMEM=y
7697+CONFIG_AIO=y
7698+CONFIG_ADVISE_SYSCALLS=y
7699+CONFIG_MEMBARRIER=y
7700+CONFIG_KALLSYMS=y
7701+# CONFIG_KALLSYMS_ALL is not set
7702+CONFIG_KALLSYMS_BASE_RELATIVE=y
7703+# CONFIG_BPF_SYSCALL is not set
7704+# CONFIG_USERFAULTFD is not set
7705+CONFIG_ARCH_HAS_MEMBARRIER_SYNC_CORE=y
7706+CONFIG_RSEQ=y
7707+# CONFIG_EMBEDDED is not set
7708+CONFIG_HAVE_PERF_EVENTS=y
7709+CONFIG_PERF_USE_VMALLOC=y
7710+
7711+#
7712+# Kernel Performance Events And Counters
7713+#
7714+# CONFIG_PERF_EVENTS is not set
7715+CONFIG_VM_EVENT_COUNTERS=y
7716+CONFIG_SLUB_DEBUG=y
7717+CONFIG_COMPAT_BRK=y
7718+# CONFIG_SLAB is not set
7719+CONFIG_SLUB=y
7720+CONFIG_SLAB_MERGE_DEFAULT=y
7721+# CONFIG_SLAB_FREELIST_RANDOM is not set
7722+# CONFIG_SLAB_FREELIST_HARDENED is not set
7723+CONFIG_SLUB_CPU_PARTIAL=y
7724+# CONFIG_PROFILING is not set
7725+CONFIG_ARM=y
7726+CONFIG_ARM_HAS_SG_CHAIN=y
7727+CONFIG_MIGHT_HAVE_PCI=y
7728+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
7729+CONFIG_HAVE_PROC_CPU=y
7730+CONFIG_STACKTRACE_SUPPORT=y
7731+CONFIG_LOCKDEP_SUPPORT=y
7732+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
7733+CONFIG_RWSEM_XCHGADD_ALGORITHM=y
7734+CONFIG_FIX_EARLYCON_MEM=y
7735+CONFIG_GENERIC_HWEIGHT=y
7736+CONFIG_GENERIC_CALIBRATE_DELAY=y
7737+CONFIG_ARCH_SUPPORTS_UPROBES=y
7738+CONFIG_ARM_PATCH_PHYS_VIRT=y
7739+CONFIG_GENERIC_BUG=y
7740+CONFIG_PGTABLE_LEVELS=2
7741+
7742+#
7743+# System Type
7744+#
7745+CONFIG_MMU=y
7746+CONFIG_ARCH_MMAP_RND_BITS_MIN=8
7747+CONFIG_ARCH_MMAP_RND_BITS_MAX=16
7748+CONFIG_ARCH_MULTIPLATFORM=y
7749+# CONFIG_ARCH_EBSA110 is not set
7750+# CONFIG_ARCH_EP93XX is not set
7751+# CONFIG_ARCH_FOOTBRIDGE is not set
7752+# CONFIG_ARCH_NETX is not set
7753+# CONFIG_ARCH_IOP13XX is not set
7754+# CONFIG_ARCH_IOP32X is not set
7755+# CONFIG_ARCH_IOP33X is not set
7756+# CONFIG_ARCH_IXP4XX is not set
7757+# CONFIG_ARCH_DOVE is not set
7758+# CONFIG_ARCH_KS8695 is not set
7759+# CONFIG_ARCH_W90X900 is not set
7760+# CONFIG_ARCH_LPC32XX is not set
7761+# CONFIG_ARCH_PXA is not set
7762+# CONFIG_ARCH_RPC is not set
7763+# CONFIG_ARCH_SA1100 is not set
7764+# CONFIG_ARCH_S3C24XX is not set
7765+# CONFIG_ARCH_DAVINCI is not set
7766+# CONFIG_ARCH_OMAP1 is not set
7767+
7768+#
7769+# Multiple platform selection
7770+#
7771+
7772+#
7773+# CPU Core family selection
7774+#
7775+# CONFIG_ARCH_MULTI_V6 is not set
7776+CONFIG_ARCH_MULTI_V7=y
7777+CONFIG_ARCH_MULTI_V6_V7=y
7778+# CONFIG_ARCH_VIRT is not set
7779+# CONFIG_ARCH_ACTIONS is not set
7780+# CONFIG_ARCH_ALPINE is not set
7781+# CONFIG_ARCH_ARTPEC is not set
7782+# CONFIG_ARCH_AT91 is not set
7783+# CONFIG_ARCH_BCM is not set
7784+# CONFIG_ARCH_BERLIN is not set
7785+# CONFIG_ARCH_DIGICOLOR is not set
7786+# CONFIG_ARCH_EXYNOS is not set
7787+# CONFIG_ARCH_HIGHBANK is not set
7788+# CONFIG_ARCH_HISI is not set
7789+CONFIG_ARCH_HISI_BVT=y
7790+
7791+#
7792+# Hisilicon BVT platform type
7793+#
7794+# CONFIG_ARCH_HI3521DV200 is not set
7795+# CONFIG_ARCH_HI3520DV500 is not set
7796+# CONFIG_ARCH_HI3516A is not set
7797+# CONFIG_ARCH_HI3516CV500 is not set
7798+CONFIG_ARCH_HI3516DV300=y
7799+# CONFIG_ARCH_HI3516EV200 is not set
7800+# CONFIG_ARCH_HI3516EV300 is not set
7801+# CONFIG_ARCH_HI3518EV300 is not set
7802+# CONFIG_ARCH_HI3516DV200 is not set
7803+# CONFIG_ARCH_HI3556V200 is not set
7804+# CONFIG_ARCH_HI3559V200 is not set
7805+# CONFIG_ARCH_HI3536DV100 is not set
7806+# CONFIG_ARCH_HI3521A is not set
7807+# CONFIG_ARCH_HI3531A is not set
7808+# CONFIG_ARCH_HI3556AV100 is not set
7809+# CONFIG_ARCH_HI3519AV100 is not set
7810+# CONFIG_ARCH_HI3568V100 is not set
7811+# CONFIG_ARCH_HISI_BVT_AMP is not set
7812+# CONFIG_HISI_MC is not set
7813+CONFIG_HI_ZRELADDR=0x80008000
7814+CONFIG_HI_PARAMS_PHYS=0x00000100
7815+CONFIG_HI_INITRD_PHYS=0x00800000
7816+# CONFIG_ARCH_MXC is not set
7817+# CONFIG_ARCH_KEYSTONE is not set
7818+# CONFIG_ARCH_MEDIATEK is not set
7819+# CONFIG_ARCH_MESON is not set
7820+# CONFIG_ARCH_MMP is not set
7821+# CONFIG_ARCH_MVEBU is not set
7822+# CONFIG_ARCH_NPCM is not set
7823+
7824+#
7825+# TI OMAP/AM/DM/DRA Family
7826+#
7827+# CONFIG_ARCH_OMAP3 is not set
7828+# CONFIG_ARCH_OMAP4 is not set
7829+# CONFIG_SOC_OMAP5 is not set
7830+# CONFIG_SOC_AM33XX is not set
7831+# CONFIG_SOC_AM43XX is not set
7832+# CONFIG_SOC_DRA7XX is not set
7833+# CONFIG_ARCH_SIRF is not set
7834+# CONFIG_ARCH_QCOM is not set
7835+# CONFIG_ARCH_REALVIEW is not set
7836+# CONFIG_ARCH_ROCKCHIP is not set
7837+# CONFIG_ARCH_S5PV210 is not set
7838+# CONFIG_ARCH_RENESAS is not set
7839+# CONFIG_ARCH_SOCFPGA is not set
7840+# CONFIG_PLAT_SPEAR is not set
7841+# CONFIG_ARCH_STI is not set
7842+# CONFIG_ARCH_STM32 is not set
7843+# CONFIG_ARCH_SUNXI is not set
7844+# CONFIG_ARCH_TANGO is not set
7845+# CONFIG_ARCH_TEGRA is not set
7846+# CONFIG_ARCH_UNIPHIER is not set
7847+# CONFIG_ARCH_U8500 is not set
7848+# CONFIG_ARCH_VEXPRESS is not set
7849+# CONFIG_ARCH_WM8850 is not set
7850+# CONFIG_ARCH_ZX is not set
7851+# CONFIG_ARCH_ZYNQ is not set
7852+
7853+#
7854+# Processor Type
7855+#
7856+CONFIG_CPU_V7=y
7857+CONFIG_CPU_THUMB_CAPABLE=y
7858+CONFIG_CPU_32v6K=y
7859+CONFIG_CPU_32v7=y
7860+CONFIG_CPU_ABRT_EV7=y
7861+CONFIG_CPU_PABRT_V7=y
7862+CONFIG_CPU_CACHE_V7=y
7863+CONFIG_CPU_CACHE_VIPT=y
7864+CONFIG_CPU_COPY_V6=y
7865+CONFIG_CPU_TLB_V7=y
7866+CONFIG_CPU_HAS_ASID=y
7867+CONFIG_CPU_CP15=y
7868+CONFIG_CPU_CP15_MMU=y
7869+
7870+#
7871+# Processor Features
7872+#
7873+# CONFIG_ARM_LPAE is not set
7874+CONFIG_ARM_THUMB=y
7875+# CONFIG_ARM_THUMBEE is not set
7876+CONFIG_ARM_VIRT_EXT=y
7877+CONFIG_SWP_EMULATE=y
7878+# CONFIG_CPU_ICACHE_DISABLE is not set
7879+# CONFIG_CPU_BPREDICT_DISABLE is not set
7880+CONFIG_CPU_SPECTRE=y
7881+CONFIG_HARDEN_BRANCH_PREDICTOR=y
7882+CONFIG_KUSER_HELPERS=y
7883+CONFIG_VDSO=y
7884+CONFIG_MIGHT_HAVE_CACHE_L2X0=y
7885+# CONFIG_CACHE_L2X0 is not set
7886+CONFIG_ARM_L1_CACHE_SHIFT_6=y
7887+CONFIG_ARM_L1_CACHE_SHIFT=6
7888+CONFIG_ARM_DMA_MEM_BUFFERABLE=y
7889+CONFIG_DEBUG_ALIGN_RODATA=y
7890+# CONFIG_ARM_ERRATA_430973 is not set
7891+# CONFIG_ARM_ERRATA_643719 is not set
7892+# CONFIG_ARM_ERRATA_720789 is not set
7893+# CONFIG_ARM_ERRATA_754322 is not set
7894+# CONFIG_ARM_ERRATA_754327 is not set
7895+# CONFIG_ARM_ERRATA_764369 is not set
7896+# CONFIG_ARM_ERRATA_775420 is not set
7897+# CONFIG_ARM_ERRATA_798181 is not set
7898+# CONFIG_ARM_ERRATA_773022 is not set
7899+# CONFIG_ARM_ERRATA_818325_852422 is not set
7900+# CONFIG_ARM_ERRATA_821420 is not set
7901+# CONFIG_ARM_ERRATA_825619 is not set
7902+# CONFIG_ARM_ERRATA_852421 is not set
7903+# CONFIG_ARM_ERRATA_852423 is not set
7904+
7905+#
7906+# Bus support
7907+#
7908+# CONFIG_PCI is not set
7909+
7910+#
7911+# PCI Endpoint
7912+#
7913+# CONFIG_PCI_ENDPOINT is not set
7914+# CONFIG_PCCARD is not set
7915+
7916+#
7917+# Kernel Features
7918+#
7919+CONFIG_HAVE_SMP=y
7920+CONFIG_SMP=y
7921+CONFIG_SMP_ON_UP=y
7922+CONFIG_ARM_CPU_TOPOLOGY=y
7923+# CONFIG_SCHED_MC is not set
7924+# CONFIG_SCHED_SMT is not set
7925+CONFIG_HAVE_ARM_ARCH_TIMER=y
7926+# CONFIG_MCPM is not set
7927+# CONFIG_BIG_LITTLE is not set
7928+CONFIG_VMSPLIT_3G=y
7929+# CONFIG_VMSPLIT_3G_OPT is not set
7930+# CONFIG_VMSPLIT_2G is not set
7931+# CONFIG_VMSPLIT_1G is not set
7932+CONFIG_PAGE_OFFSET=0xC0000000
7933+CONFIG_NR_CPUS=2
7934+CONFIG_HOTPLUG_CPU=y
7935+# CONFIG_ARM_PSCI is not set
7936+CONFIG_ARCH_NR_GPIO=0
7937+CONFIG_HZ_FIXED=0
7938+CONFIG_HZ_100=y
7939+# CONFIG_HZ_200 is not set
7940+# CONFIG_HZ_250 is not set
7941+# CONFIG_HZ_300 is not set
7942+# CONFIG_HZ_500 is not set
7943+# CONFIG_HZ_1000 is not set
7944+CONFIG_HZ=100
7945+# CONFIG_THUMB2_KERNEL is not set
7946+CONFIG_ARM_PATCH_IDIV=y
7947+CONFIG_AEABI=y
7948+CONFIG_OABI_COMPAT=y
7949+CONFIG_HAVE_ARCH_PFN_VALID=y
7950+CONFIG_HIGHMEM=y
7951+CONFIG_HIGHPTE=y
7952+CONFIG_CPU_SW_DOMAIN_PAN=y
7953+CONFIG_ARCH_WANT_GENERAL_HUGETLB=y
7954+# CONFIG_ARM_MODULE_PLTS is not set
7955+CONFIG_FORCE_MAX_ZONEORDER=11
7956+CONFIG_ALIGNMENT_TRAP=y
7957+# CONFIG_UACCESS_WITH_MEMCPY is not set
7958+# CONFIG_SECCOMP is not set
7959+# CONFIG_PARAVIRT is not set
7960+# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set
7961+# CONFIG_XEN is not set
7962+
7963+#
7964+# Boot options
7965+#
7966+CONFIG_USE_OF=y
7967+CONFIG_ATAGS=y
7968+# CONFIG_DEPRECATED_PARAM_STRUCT is not set
7969+CONFIG_ZBOOT_ROM_TEXT=0
7970+CONFIG_ZBOOT_ROM_BSS=0
7971+CONFIG_ARM_APPENDED_DTB=y
7972+CONFIG_ARM_ATAG_DTB_COMPAT=y
7973+CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_FROM_BOOTLOADER=y
7974+# CONFIG_ARM_ATAG_DTB_COMPAT_CMDLINE_EXTEND is not set
7975+CONFIG_CMDLINE=""
7976+# CONFIG_KEXEC is not set
7977+# CONFIG_CRASH_DUMP is not set
7978+CONFIG_AUTO_ZRELADDR=y
7979+# CONFIG_EFI is not set
7980+
7981+#
7982+# CPU Power Management
7983+#
7984+
7985+#
7986+# CPU Frequency scaling
7987+#
7988+# CONFIG_CPU_FREQ is not set
7989+
7990+#
7991+# CPU Idle
7992+#
7993+# CONFIG_CPU_IDLE is not set
7994+
7995+#
7996+# Floating point emulation
7997+#
7998+
7999+#
8000+# At least one emulation must be selected
8001+#
8002+# CONFIG_FPE_NWFPE is not set
8003+# CONFIG_FPE_FASTFPE is not set
8004+CONFIG_VFP=y
8005+CONFIG_VFPv3=y
8006+CONFIG_NEON=y
8007+CONFIG_KERNEL_MODE_NEON=y
8008+
8009+#
8010+# Power management options
8011+#
8012+CONFIG_SUSPEND=y
8013+CONFIG_SUSPEND_FREEZER=y
8014+CONFIG_PM_SLEEP=y
8015+CONFIG_PM_SLEEP_SMP=y
8016+# CONFIG_PM_AUTOSLEEP is not set
8017+# CONFIG_PM_WAKELOCKS is not set
8018+CONFIG_PM=y
8019+# CONFIG_PM_DEBUG is not set
8020+# CONFIG_APM_EMULATION is not set
8021+CONFIG_PM_CLK=y
8022+# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set
8023+CONFIG_CPU_PM=y
8024+CONFIG_ARCH_SUSPEND_POSSIBLE=y
8025+CONFIG_ARM_CPU_SUSPEND=y
8026+CONFIG_ARCH_HIBERNATION_POSSIBLE=y
8027+
8028+#
8029+# Firmware Drivers
8030+#
8031+# CONFIG_FW_CFG_SYSFS is not set
8032+CONFIG_HAVE_ARM_SMCCC=y
8033+# CONFIG_GOOGLE_FIRMWARE is not set
8034+
8035+#
8036+# Tegra firmware driver
8037+#
8038+# CONFIG_ARM_CRYPTO is not set
8039+# CONFIG_VIRTUALIZATION is not set
8040+
8041+#
8042+# General architecture-dependent options
8043+#
8044+CONFIG_HAVE_OPROFILE=y
8045+# CONFIG_KPROBES is not set
8046+# CONFIG_JUMP_LABEL is not set
8047+CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y
8048+CONFIG_ARCH_USE_BUILTIN_BSWAP=y
8049+CONFIG_HAVE_KPROBES=y
8050+CONFIG_HAVE_KRETPROBES=y
8051+CONFIG_HAVE_OPTPROBES=y
8052+CONFIG_HAVE_NMI=y
8053+CONFIG_HAVE_ARCH_TRACEHOOK=y
8054+CONFIG_HAVE_DMA_CONTIGUOUS=y
8055+CONFIG_GENERIC_SMP_IDLE_THREAD=y
8056+CONFIG_GENERIC_IDLE_POLL_SETUP=y
8057+CONFIG_ARCH_HAS_FORTIFY_SOURCE=y
8058+CONFIG_ARCH_HAS_SET_MEMORY=y
8059+CONFIG_HAVE_ARCH_THREAD_STRUCT_WHITELIST=y
8060+CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y
8061+CONFIG_HAVE_RSEQ=y
8062+CONFIG_HAVE_CLK=y
8063+CONFIG_HAVE_PERF_REGS=y
8064+CONFIG_HAVE_PERF_USER_STACK_DUMP=y
8065+CONFIG_HAVE_ARCH_JUMP_LABEL=y
8066+CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
8067+CONFIG_HAVE_STACKPROTECTOR=y
8068+CONFIG_CC_HAS_STACKPROTECTOR_NONE=y
8069+CONFIG_STACKPROTECTOR=y
8070+CONFIG_STACKPROTECTOR_STRONG=y
8071+CONFIG_HAVE_CONTEXT_TRACKING=y
8072+CONFIG_HAVE_VIRT_CPU_ACCOUNTING_GEN=y
8073+CONFIG_HAVE_IRQ_TIME_ACCOUNTING=y
8074+CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
8075+CONFIG_MODULES_USE_ELF_REL=y
8076+CONFIG_ARCH_HAS_ELF_RANDOMIZE=y
8077+CONFIG_HAVE_ARCH_MMAP_RND_BITS=y
8078+CONFIG_HAVE_EXIT_THREAD=y
8079+CONFIG_ARCH_MMAP_RND_BITS=8
8080+CONFIG_CLONE_BACKWARDS=y
8081+CONFIG_OLD_SIGSUSPEND3=y
8082+CONFIG_OLD_SIGACTION=y
8083+CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y
8084+CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y
8085+CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
8086+CONFIG_STRICT_KERNEL_RWX=y
8087+CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
8088+CONFIG_STRICT_MODULE_RWX=y
8089+CONFIG_ARCH_HAS_PHYS_TO_DMA=y
8090+CONFIG_REFCOUNT_FULL=y
8091+
8092+#
8093+# GCOV-based kernel profiling
8094+#
8095+# CONFIG_GCOV_KERNEL is not set
8096+CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y
8097+CONFIG_PLUGIN_HOSTCC=""
8098+CONFIG_HAVE_GCC_PLUGINS=y
8099+CONFIG_RT_MUTEXES=y
8100+CONFIG_BASE_SMALL=0
8101+CONFIG_MODULES=y
8102+CONFIG_MODULE_FORCE_LOAD=y
8103+CONFIG_MODULE_UNLOAD=y
8104+CONFIG_MODULE_FORCE_UNLOAD=y
8105+# CONFIG_MODVERSIONS is not set
8106+# CONFIG_MODULE_SRCVERSION_ALL is not set
8107+# CONFIG_MODULE_SIG is not set
8108+# CONFIG_MODULE_COMPRESS is not set
8109+# CONFIG_TRIM_UNUSED_KSYMS is not set
8110+CONFIG_BLOCK=y
8111+CONFIG_LBDAF=y
8112+CONFIG_BLK_SCSI_REQUEST=y
8113+CONFIG_BLK_DEV_BSG=y
8114+# CONFIG_BLK_DEV_BSGLIB is not set
8115+# CONFIG_BLK_DEV_INTEGRITY is not set
8116+# CONFIG_BLK_DEV_ZONED is not set
8117+CONFIG_BLK_CMDLINE_PARSER=y
8118+# CONFIG_BLK_WBT is not set
8119+# CONFIG_BLK_DEBUG_FS is not set
8120+# CONFIG_BLK_SED_OPAL is not set
8121+
8122+#
8123+# Partition Types
8124+#
8125+CONFIG_PARTITION_ADVANCED=y
8126+# CONFIG_ACORN_PARTITION is not set
8127+# CONFIG_AIX_PARTITION is not set
8128+# CONFIG_OSF_PARTITION is not set
8129+# CONFIG_AMIGA_PARTITION is not set
8130+# CONFIG_ATARI_PARTITION is not set
8131+# CONFIG_MAC_PARTITION is not set
8132+CONFIG_MSDOS_PARTITION=y
8133+# CONFIG_BSD_DISKLABEL is not set
8134+# CONFIG_MINIX_SUBPARTITION is not set
8135+# CONFIG_SOLARIS_X86_PARTITION is not set
8136+# CONFIG_UNIXWARE_DISKLABEL is not set
8137+# CONFIG_LDM_PARTITION is not set
8138+# CONFIG_SGI_PARTITION is not set
8139+# CONFIG_ULTRIX_PARTITION is not set
8140+# CONFIG_SUN_PARTITION is not set
8141+# CONFIG_KARMA_PARTITION is not set
8142+CONFIG_EFI_PARTITION=y
8143+# CONFIG_SYSV68_PARTITION is not set
8144+CONFIG_CMDLINE_PARTITION=y
8145+
8146+#
8147+# IO Schedulers
8148+#
8149+CONFIG_IOSCHED_NOOP=y
8150+# CONFIG_IOSCHED_DEADLINE is not set
8151+CONFIG_IOSCHED_CFQ=y
8152+CONFIG_DEFAULT_CFQ=y
8153+# CONFIG_DEFAULT_NOOP is not set
8154+CONFIG_DEFAULT_IOSCHED="cfq"
8155+CONFIG_MQ_IOSCHED_DEADLINE=y
8156+CONFIG_MQ_IOSCHED_KYBER=y
8157+# CONFIG_IOSCHED_BFQ is not set
8158+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
8159+CONFIG_INLINE_READ_UNLOCK=y
8160+CONFIG_INLINE_READ_UNLOCK_IRQ=y
8161+CONFIG_INLINE_WRITE_UNLOCK=y
8162+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
8163+CONFIG_ARCH_SUPPORTS_ATOMIC_RMW=y
8164+CONFIG_MUTEX_SPIN_ON_OWNER=y
8165+CONFIG_RWSEM_SPIN_ON_OWNER=y
8166+CONFIG_LOCK_SPIN_ON_OWNER=y
8167+CONFIG_FREEZER=y
8168+
8169+#
8170+# Executable file formats
8171+#
8172+CONFIG_BINFMT_ELF=y
8173+# CONFIG_BINFMT_ELF_FDPIC is not set
8174+CONFIG_ELFCORE=y
8175+CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y
8176+CONFIG_BINFMT_SCRIPT=y
8177+# CONFIG_BINFMT_FLAT is not set
8178+# CONFIG_BINFMT_MISC is not set
8179+CONFIG_COREDUMP=y
8180+
8181+#
8182+# Memory Management options
8183+#
8184+CONFIG_FLATMEM=y
8185+CONFIG_FLAT_NODE_MEM_MAP=y
8186+CONFIG_HAVE_MEMBLOCK=y
8187+CONFIG_NO_BOOTMEM=y
8188+CONFIG_MEMORY_ISOLATION=y
8189+CONFIG_SPLIT_PTLOCK_CPUS=4
8190+CONFIG_COMPACTION=y
8191+CONFIG_MIGRATION=y
8192+CONFIG_BOUNCE=y
8193+# CONFIG_KSM is not set
8194+CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
8195+# CONFIG_CLEANCACHE is not set
8196+CONFIG_CMA=y
8197+CONFIG_CMA_DEBUG=y
8198+# CONFIG_CMA_DEBUGFS is not set
8199+CONFIG_CMA_AREAS=7
8200+# CONFIG_ZPOOL is not set
8201+# CONFIG_ZBUD is not set
8202+# CONFIG_ZSMALLOC is not set
8203+CONFIG_GENERIC_EARLY_IOREMAP=y
8204+# CONFIG_IDLE_PAGE_TRACKING is not set
8205+CONFIG_FRAME_VECTOR=y
8206+# CONFIG_PERCPU_STATS is not set
8207+# CONFIG_GUP_BENCHMARK is not set
8208+CONFIG_NET=y
8209+
8210+#
8211+# Networking options
8212+#
8213+CONFIG_PACKET=y
8214+# CONFIG_PACKET_DIAG is not set
8215+CONFIG_UNIX=y
8216+# CONFIG_UNIX_DIAG is not set
8217+# CONFIG_TLS is not set
8218+CONFIG_XFRM=y
8219+# CONFIG_XFRM_USER is not set
8220+# CONFIG_XFRM_INTERFACE is not set
8221+# CONFIG_XFRM_SUB_POLICY is not set
8222+# CONFIG_XFRM_MIGRATE is not set
8223+# CONFIG_XFRM_STATISTICS is not set
8224+# CONFIG_NET_KEY is not set
8225+CONFIG_INET=y
8226+# CONFIG_IP_MULTICAST is not set
8227+# CONFIG_IP_ADVANCED_ROUTER is not set
8228+CONFIG_IP_PNP=y
8229+CONFIG_IP_PNP_DHCP=y
8230+# CONFIG_IP_PNP_BOOTP is not set
8231+# CONFIG_IP_PNP_RARP is not set
8232+# CONFIG_NET_IPIP is not set
8233+# CONFIG_NET_IPGRE_DEMUX is not set
8234+# CONFIG_SYN_COOKIES is not set
8235+# CONFIG_NET_IPVTI is not set
8236+# CONFIG_NET_FOU is not set
8237+# CONFIG_INET_AH is not set
8238+# CONFIG_INET_ESP is not set
8239+# CONFIG_INET_IPCOMP is not set
8240+CONFIG_INET_XFRM_MODE_TRANSPORT=y
8241+CONFIG_INET_XFRM_MODE_TUNNEL=y
8242+CONFIG_INET_XFRM_MODE_BEET=y
8243+CONFIG_INET_DIAG=y
8244+CONFIG_INET_TCP_DIAG=y
8245+# CONFIG_INET_UDP_DIAG is not set
8246+# CONFIG_INET_RAW_DIAG is not set
8247+# CONFIG_INET_DIAG_DESTROY is not set
8248+# CONFIG_TCP_CONG_ADVANCED is not set
8249+CONFIG_TCP_CONG_CUBIC=y
8250+CONFIG_DEFAULT_TCP_CONG="cubic"
8251+# CONFIG_TCP_MD5SIG is not set
8252+CONFIG_IPV6=y
8253+# CONFIG_IPV6_ROUTER_PREF is not set
8254+# CONFIG_IPV6_OPTIMISTIC_DAD is not set
8255+# CONFIG_INET6_AH is not set
8256+# CONFIG_INET6_ESP is not set
8257+# CONFIG_INET6_IPCOMP is not set
8258+# CONFIG_IPV6_MIP6 is not set
8259+# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set
8260+# CONFIG_INET6_XFRM_MODE_TUNNEL is not set
8261+# CONFIG_INET6_XFRM_MODE_BEET is not set
8262+# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
8263+# CONFIG_IPV6_SIT is not set
8264+# CONFIG_IPV6_TUNNEL is not set
8265+# CONFIG_IPV6_MULTIPLE_TABLES is not set
8266+# CONFIG_IPV6_MROUTE is not set
8267+# CONFIG_IPV6_SEG6_LWTUNNEL is not set
8268+# CONFIG_IPV6_SEG6_HMAC is not set
8269+# CONFIG_NETWORK_SECMARK is not set
8270+# CONFIG_NETWORK_PHY_TIMESTAMPING is not set
8271+# CONFIG_NETFILTER is not set
8272+# CONFIG_BPFILTER is not set
8273+# CONFIG_IP_DCCP is not set
8274+# CONFIG_IP_SCTP is not set
8275+# CONFIG_RDS is not set
8276+# CONFIG_TIPC is not set
8277+# CONFIG_ATM is not set
8278+# CONFIG_L2TP is not set
8279+# CONFIG_BRIDGE is not set
8280+CONFIG_HAVE_NET_DSA=y
8281+# CONFIG_NET_DSA is not set
8282+CONFIG_VLAN_8021Q=y
8283+# CONFIG_VLAN_8021Q_GVRP is not set
8284+# CONFIG_VLAN_8021Q_MVRP is not set
8285+# CONFIG_DECNET is not set
8286+# CONFIG_LLC2 is not set
8287+# CONFIG_ATALK is not set
8288+# CONFIG_X25 is not set
8289+# CONFIG_LAPB is not set
8290+# CONFIG_PHONET is not set
8291+# CONFIG_6LOWPAN is not set
8292+# CONFIG_IEEE802154 is not set
8293+# CONFIG_NET_SCHED is not set
8294+# CONFIG_DCB is not set
8295+CONFIG_DNS_RESOLVER=y
8296+# CONFIG_BATMAN_ADV is not set
8297+# CONFIG_OPENVSWITCH is not set
8298+# CONFIG_VSOCKETS is not set
8299+# CONFIG_NETLINK_DIAG is not set
8300+# CONFIG_MPLS is not set
8301+# CONFIG_NET_NSH is not set
8302+# CONFIG_HSR is not set
8303+# CONFIG_NET_SWITCHDEV is not set
8304+# CONFIG_NET_L3_MASTER_DEV is not set
8305+# CONFIG_NET_NCSI is not set
8306+CONFIG_RPS=y
8307+CONFIG_RFS_ACCEL=y
8308+CONFIG_XPS=y
8309+# CONFIG_CGROUP_NET_PRIO is not set
8310+# CONFIG_CGROUP_NET_CLASSID is not set
8311+CONFIG_NET_RX_BUSY_POLL=y
8312+CONFIG_BQL=y
8313+# CONFIG_BPF_JIT is not set
8314+CONFIG_NET_FLOW_LIMIT=y
8315+
8316+#
8317+# Network testing
8318+#
8319+# CONFIG_NET_PKTGEN is not set
8320+# CONFIG_HAMRADIO is not set
8321+# CONFIG_CAN is not set
8322+# CONFIG_BT is not set
8323+# CONFIG_AF_RXRPC is not set
8324+# CONFIG_AF_KCM is not set
8325+CONFIG_WIRELESS=y
8326+# CONFIG_CFG80211 is not set
8327+
8328+#
8329+# CFG80211 needs to be enabled for MAC80211
8330+#
8331+CONFIG_MAC80211_STA_HASH_MAX_SIZE=0
8332+# CONFIG_WIMAX is not set
8333+# CONFIG_RFKILL is not set
8334+# CONFIG_NET_9P is not set
8335+# CONFIG_CAIF is not set
8336+# CONFIG_CEPH_LIB is not set
8337+# CONFIG_NFC is not set
8338+# CONFIG_PSAMPLE is not set
8339+# CONFIG_NET_IFE is not set
8340+# CONFIG_LWTUNNEL is not set
8341+CONFIG_GRO_CELLS=y
8342+# CONFIG_NET_DEVLINK is not set
8343+CONFIG_MAY_USE_DEVLINK=y
8344+# CONFIG_FAILOVER is not set
8345+CONFIG_HAVE_EBPF_JIT=y
8346+
8347+#
8348+# Device Drivers
8349+#
8350+CONFIG_ARM_AMBA=y
8351+
8352+#
8353+# Generic Driver Options
8354+#
8355+CONFIG_UEVENT_HELPER=y
8356+CONFIG_UEVENT_HELPER_PATH=""
8357+CONFIG_DEVTMPFS=y
8358+CONFIG_DEVTMPFS_MOUNT=y
8359+CONFIG_STANDALONE=y
8360+CONFIG_PREVENT_FIRMWARE_BUILD=y
8361+
8362+#
8363+# Firmware loader
8364+#
8365+CONFIG_FW_LOADER=y
8366+CONFIG_EXTRA_FIRMWARE=""
8367+# CONFIG_FW_LOADER_USER_HELPER is not set
8368+CONFIG_ALLOW_DEV_COREDUMP=y
8369+# CONFIG_DEBUG_DRIVER is not set
8370+# CONFIG_DEBUG_DEVRES is not set
8371+# CONFIG_DEBUG_TEST_DRIVER_REMOVE is not set
8372+# CONFIG_TEST_ASYNC_DRIVER_PROBE is not set
8373+CONFIG_GENERIC_CPU_AUTOPROBE=y
8374+CONFIG_REGMAP=y
8375+CONFIG_REGMAP_I2C=y
8376+CONFIG_REGMAP_SPI=y
8377+CONFIG_REGMAP_MMIO=y
8378+CONFIG_DMA_SHARED_BUFFER=y
8379+# CONFIG_DMA_FENCE_TRACE is not set
8380+CONFIG_DMA_CMA=y
8381+
8382+#
8383+# Default contiguous memory area size:
8384+#
8385+CONFIG_CMA_SIZE_MBYTES=16
8386+CONFIG_CMA_SIZE_SEL_MBYTES=y
8387+# CONFIG_CMA_SIZE_SEL_PERCENTAGE is not set
8388+# CONFIG_CMA_SIZE_SEL_MIN is not set
8389+# CONFIG_CMA_SIZE_SEL_MAX is not set
8390+CONFIG_CMA_ALIGNMENT=8
8391+CONFIG_GENERIC_ARCH_TOPOLOGY=y
8392+
8393+#
8394+# Bus devices
8395+#
8396+# CONFIG_BRCMSTB_GISB_ARB is not set
8397+# CONFIG_SIMPLE_PM_BUS is not set
8398+# CONFIG_VEXPRESS_CONFIG is not set
8399+# CONFIG_CONNECTOR is not set
8400+# CONFIG_GNSS is not set
8401+CONFIG_MTD=y
8402+# CONFIG_MTD_TESTS is not set
8403+# CONFIG_MTD_REDBOOT_PARTS is not set
8404+CONFIG_MTD_CMDLINE_PARTS=y
8405+# CONFIG_MTD_AFS_PARTS is not set
8406+CONFIG_MTD_OF_PARTS=y
8407+# CONFIG_MTD_AR7_PARTS is not set
8408+
8409+#
8410+# Partition parsers
8411+#
8412+
8413+#
8414+# User Modules And Translation Layers
8415+#
8416+CONFIG_MTD_BLKDEVS=y
8417+CONFIG_MTD_BLOCK=y
8418+# CONFIG_FTL is not set
8419+# CONFIG_NFTL is not set
8420+# CONFIG_INFTL is not set
8421+# CONFIG_RFD_FTL is not set
8422+# CONFIG_SSFDC is not set
8423+# CONFIG_SM_FTL is not set
8424+# CONFIG_MTD_OOPS is not set
8425+# CONFIG_MTD_PARTITIONED_MASTER is not set
8426+
8427+#
8428+# RAM/ROM/Flash chip drivers
8429+#
8430+# CONFIG_MTD_CFI is not set
8431+# CONFIG_MTD_JEDECPROBE is not set
8432+CONFIG_MTD_MAP_BANK_WIDTH_1=y
8433+CONFIG_MTD_MAP_BANK_WIDTH_2=y
8434+CONFIG_MTD_MAP_BANK_WIDTH_4=y
8435+CONFIG_MTD_CFI_I1=y
8436+CONFIG_MTD_CFI_I2=y
8437+# CONFIG_MTD_RAM is not set
8438+# CONFIG_MTD_ROM is not set
8439+# CONFIG_MTD_ABSENT is not set
8440+
8441+#
8442+# Mapping drivers for chip access
8443+#
8444+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
8445+# CONFIG_MTD_PLATRAM is not set
8446+
8447+#
8448+# Self-contained MTD device drivers
8449+#
8450+# CONFIG_MTD_DATAFLASH is not set
8451+# CONFIG_MTD_M25P80 is not set
8452+# CONFIG_MTD_MCHP23K256 is not set
8453+# CONFIG_MTD_SST25L is not set
8454+# CONFIG_MTD_SLRAM is not set
8455+# CONFIG_MTD_PHRAM is not set
8456+# CONFIG_MTD_MTDRAM is not set
8457+# CONFIG_MTD_BLOCK2MTD is not set
8458+
8459+#
8460+# Disk-On-Chip Device Drivers
8461+#
8462+# CONFIG_MTD_DOCG3 is not set
8463+# CONFIG_MTD_ONENAND is not set
8464+CONFIG_MTD_SPI_NAND_HISI_BVT=y
8465+# CONFIG_HISI_NAND_ECC_STATUS_REPORT is not set
8466+# CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2 is not set
8467+CONFIG_MTD_NAND_ECC=y
8468+# CONFIG_MTD_NAND_ECC_SMC is not set
8469+CONFIG_MTD_NAND=y
8470+# CONFIG_MTD_NAND_ECC_BCH is not set
8471+# CONFIG_MTD_NAND_DENALI_DT is not set
8472+# CONFIG_MTD_NAND_GPIO is not set
8473+# CONFIG_MTD_NAND_DISKONCHIP is not set
8474+# CONFIG_MTD_NAND_DOCG4 is not set
8475+# CONFIG_MTD_NAND_NANDSIM is not set
8476+# CONFIG_MTD_NAND_BRCMNAND is not set
8477+# CONFIG_MTD_NAND_PLATFORM is not set
8478+CONFIG_MTD_SPI_NAND_HIFMC100=y
8479+# CONFIG_MTD_SPI_NAND is not set
8480+
8481+#
8482+# LPDDR & LPDDR2 PCM memory drivers
8483+#
8484+# CONFIG_MTD_LPDDR is not set
8485+# CONFIG_MTD_LPDDR2_NVM is not set
8486+CONFIG_MTD_SPI_NOR=y
8487+# CONFIG_MTD_MT81xx_NOR is not set
8488+# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set
8489+# CONFIG_SPI_CADENCE_QUADSPI is not set
8490+CONFIG_SPI_HISI_SFC=y
8491+# CONFIG_MTD_SPI_IDS is not set
8492+# CONFIG_CLOSE_SPI_8PIN_4IO is not set
8493+CONFIG_HISI_SPI_BLOCK_PROTECT=y
8494+CONFIG_MTD_UBI=y
8495+CONFIG_MTD_UBI_WL_THRESHOLD=4096
8496+CONFIG_MTD_UBI_BEB_LIMIT=20
8497+# CONFIG_MTD_UBI_FASTMAP is not set
8498+# CONFIG_MTD_UBI_GLUEBI is not set
8499+# CONFIG_MTD_UBI_BLOCK is not set
8500+CONFIG_DTC=y
8501+CONFIG_OF=y
8502+# CONFIG_OF_UNITTEST is not set
8503+CONFIG_OF_FLATTREE=y
8504+CONFIG_OF_EARLY_FLATTREE=y
8505+CONFIG_OF_KOBJ=y
8506+CONFIG_OF_ADDRESS=y
8507+CONFIG_OF_IRQ=y
8508+CONFIG_OF_NET=y
8509+CONFIG_OF_MDIO=y
8510+CONFIG_OF_RESERVED_MEM=y
8511+# CONFIG_OF_OVERLAY is not set
8512+CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
8513+# CONFIG_PARPORT is not set
8514+CONFIG_BLK_DEV=y
8515+# CONFIG_BLK_DEV_NULL_BLK is not set
8516+# CONFIG_BLK_DEV_LOOP is not set
8517+# CONFIG_BLK_DEV_DRBD is not set
8518+# CONFIG_BLK_DEV_NBD is not set
8519+CONFIG_BLK_DEV_RAM=y
8520+CONFIG_BLK_DEV_RAM_COUNT=16
8521+CONFIG_BLK_DEV_RAM_SIZE=65536
8522+# CONFIG_CDROM_PKTCDVD is not set
8523+# CONFIG_ATA_OVER_ETH is not set
8524+# CONFIG_BLK_DEV_RBD is not set
8525+
8526+#
8527+# NVME Support
8528+#
8529+# CONFIG_NVME_FC is not set
8530+# CONFIG_NVME_TARGET is not set
8531+
8532+#
8533+# Misc devices
8534+#
8535+# CONFIG_AD525X_DPOT is not set
8536+# CONFIG_DUMMY_IRQ is not set
8537+# CONFIG_ICS932S401 is not set
8538+# CONFIG_ENCLOSURE_SERVICES is not set
8539+# CONFIG_APDS9802ALS is not set
8540+# CONFIG_ISL29003 is not set
8541+# CONFIG_ISL29020 is not set
8542+# CONFIG_SENSORS_TSL2550 is not set
8543+# CONFIG_SENSORS_BH1770 is not set
8544+# CONFIG_SENSORS_APDS990X is not set
8545+# CONFIG_HMC6352 is not set
8546+# CONFIG_DS1682 is not set
8547+# CONFIG_USB_SWITCH_FSA9480 is not set
8548+# CONFIG_LATTICE_ECP3_CONFIG is not set
8549+# CONFIG_SRAM is not set
8550+# CONFIG_C2PORT is not set
8551+
8552+#
8553+# EEPROM support
8554+#
8555+# CONFIG_EEPROM_AT24 is not set
8556+# CONFIG_EEPROM_AT25 is not set
8557+# CONFIG_EEPROM_LEGACY is not set
8558+# CONFIG_EEPROM_MAX6875 is not set
8559+# CONFIG_EEPROM_93CX6 is not set
8560+# CONFIG_EEPROM_93XX46 is not set
8561+# CONFIG_EEPROM_IDT_89HPESX is not set
8562+
8563+#
8564+# Texas Instruments shared transport line discipline
8565+#
8566+# CONFIG_TI_ST is not set
8567+# CONFIG_SENSORS_LIS3_SPI is not set
8568+# CONFIG_SENSORS_LIS3_I2C is not set
8569+# CONFIG_ALTERA_STAPL is not set
8570+
8571+#
8572+# Intel MIC & related support
8573+#
8574+
8575+#
8576+# Intel MIC Bus Driver
8577+#
8578+
8579+#
8580+# SCIF Bus Driver
8581+#
8582+
8583+#
8584+# VOP Bus Driver
8585+#
8586+
8587+#
8588+# Intel MIC Host Driver
8589+#
8590+
8591+#
8592+# Intel MIC Card Driver
8593+#
8594+
8595+#
8596+# SCIF Driver
8597+#
8598+
8599+#
8600+# Intel MIC Coprocessor State Management (COSM) Drivers
8601+#
8602+
8603+#
8604+# VOP Driver
8605+#
8606+# CONFIG_ECHO is not set
8607+# CONFIG_MISC_RTSX_USB is not set
8608+
8609+#
8610+# SCSI device support
8611+#
8612+CONFIG_SCSI_MOD=y
8613+# CONFIG_RAID_ATTRS is not set
8614+CONFIG_SCSI=y
8615+CONFIG_SCSI_DMA=y
8616+# CONFIG_SCSI_MQ_DEFAULT is not set
8617+CONFIG_SCSI_PROC_FS=y
8618+
8619+#
8620+# SCSI support type (disk, tape, CD-ROM)
8621+#
8622+CONFIG_BLK_DEV_SD=y
8623+# CONFIG_CHR_DEV_ST is not set
8624+# CONFIG_CHR_DEV_OSST is not set
8625+# CONFIG_BLK_DEV_SR is not set
8626+# CONFIG_CHR_DEV_SG is not set
8627+# CONFIG_CHR_DEV_SCH is not set
8628+# CONFIG_SCSI_CONSTANTS is not set
8629+# CONFIG_SCSI_LOGGING is not set
8630+# CONFIG_SCSI_SCAN_ASYNC is not set
8631+
8632+#
8633+# SCSI Transports
8634+#
8635+# CONFIG_SCSI_SPI_ATTRS is not set
8636+# CONFIG_SCSI_FC_ATTRS is not set
8637+# CONFIG_SCSI_ISCSI_ATTRS is not set
8638+# CONFIG_SCSI_SAS_ATTRS is not set
8639+# CONFIG_SCSI_SAS_LIBSAS is not set
8640+# CONFIG_SCSI_SRP_ATTRS is not set
8641+CONFIG_SCSI_LOWLEVEL=y
8642+# CONFIG_ISCSI_TCP is not set
8643+# CONFIG_ISCSI_BOOT_SYSFS is not set
8644+# CONFIG_SCSI_UFSHCD is not set
8645+# CONFIG_SCSI_DEBUG is not set
8646+# CONFIG_SCSI_DH is not set
8647+# CONFIG_SCSI_OSD_INITIATOR is not set
8648+# CONFIG_ATA is not set
8649+# CONFIG_MD is not set
8650+# CONFIG_TARGET_CORE is not set
8651+CONFIG_NETDEVICES=y
8652+CONFIG_MII=y
8653+CONFIG_NET_CORE=y
8654+# CONFIG_BONDING is not set
8655+# CONFIG_DUMMY is not set
8656+# CONFIG_EQUALIZER is not set
8657+# CONFIG_NET_TEAM is not set
8658+# CONFIG_MACVLAN is not set
8659+# CONFIG_VXLAN is not set
8660+# CONFIG_GENEVE is not set
8661+# CONFIG_GTP is not set
8662+# CONFIG_MACSEC is not set
8663+# CONFIG_NETCONSOLE is not set
8664+# CONFIG_TUN is not set
8665+# CONFIG_TUN_VNET_CROSS_LE is not set
8666+# CONFIG_VETH is not set
8667+# CONFIG_NLMON is not set
8668+
8669+#
8670+# CAIF transport drivers
8671+#
8672+
8673+#
8674+# Distributed Switch Architecture drivers
8675+#
8676+CONFIG_ETHERNET=y
8677+CONFIG_NET_VENDOR_ALACRITECH=y
8678+# CONFIG_ALTERA_TSE is not set
8679+# CONFIG_NET_VENDOR_AMAZON is not set
8680+CONFIG_NET_VENDOR_AQUANTIA=y
8681+# CONFIG_NET_VENDOR_ARC is not set
8682+# CONFIG_NET_VENDOR_AURORA is not set
8683+# CONFIG_NET_VENDOR_BROADCOM is not set
8684+CONFIG_NET_VENDOR_CADENCE=y
8685+# CONFIG_MACB is not set
8686+CONFIG_NET_VENDOR_CAVIUM=y
8687+# CONFIG_NET_VENDOR_CIRRUS is not set
8688+CONFIG_NET_VENDOR_CORTINA=y
8689+# CONFIG_GEMINI_ETHERNET is not set
8690+# CONFIG_DM9000 is not set
8691+# CONFIG_DNET is not set
8692+# CONFIG_NET_VENDOR_EZCHIP is not set
8693+# CONFIG_NET_VENDOR_FARADAY is not set
8694+CONFIG_NET_VENDOR_HISILICON=y
8695+# CONFIG_HIX5HD2_GMAC is not set
8696+CONFIG_HISI_FEMAC=y
8697+# CONFIG_HIP04_ETH is not set
8698+# CONFIG_HNS is not set
8699+# CONFIG_HNS_DSAF is not set
8700+# CONFIG_HNS_ENET is not set
8701+# CONFIG_HIETH_GMAC is not set
8702+CONFIG_NET_VENDOR_HUAWEI=y
8703+# CONFIG_NET_VENDOR_INTEL is not set
8704+# CONFIG_NET_VENDOR_MARVELL is not set
8705+CONFIG_NET_VENDOR_MELLANOX=y
8706+# CONFIG_MLXSW_CORE is not set
8707+# CONFIG_MLXFW is not set
8708+# CONFIG_NET_VENDOR_MICREL is not set
8709+# CONFIG_NET_VENDOR_MICROCHIP is not set
8710+CONFIG_NET_VENDOR_MICROSEMI=y
8711+# CONFIG_NET_VENDOR_NATSEMI is not set
8712+# CONFIG_NET_VENDOR_NETRONOME is not set
8713+CONFIG_NET_VENDOR_NI=y
8714+# CONFIG_ETHOC is not set
8715+# CONFIG_NET_VENDOR_QUALCOMM is not set
8716+# CONFIG_NET_VENDOR_RENESAS is not set
8717+# CONFIG_NET_VENDOR_ROCKER is not set
8718+# CONFIG_NET_VENDOR_SAMSUNG is not set
8719+# CONFIG_NET_VENDOR_SEEQ is not set
8720+CONFIG_NET_VENDOR_SOLARFLARE=y
8721+# CONFIG_NET_VENDOR_SMSC is not set
8722+CONFIG_NET_VENDOR_SOCIONEXT=y
8723+# CONFIG_NET_VENDOR_STMICRO is not set
8724+# CONFIG_NET_VENDOR_SYNOPSYS is not set
8725+# CONFIG_NET_VENDOR_VIA is not set
8726+# CONFIG_NET_VENDOR_WIZNET is not set
8727+CONFIG_MDIO_DEVICE=y
8728+CONFIG_MDIO_BUS=y
8729+# CONFIG_MDIO_BCM_UNIMAC is not set
8730+# CONFIG_MDIO_BITBANG is not set
8731+# CONFIG_MDIO_BUS_MUX_GPIO is not set
8732+# CONFIG_MDIO_BUS_MUX_MMIOREG is not set
8733+CONFIG_MDIO_HISI_FEMAC=y
8734+# CONFIG_MDIO_HISI_GEMAC is not set
8735+# CONFIG_MDIO_MSCC_MIIM is not set
8736+CONFIG_PHYLIB=y
8737+CONFIG_SWPHY=y
8738+
8739+#
8740+# MII PHY device drivers
8741+#
8742+# CONFIG_AMD_PHY is not set
8743+# CONFIG_AQUANTIA_PHY is not set
8744+# CONFIG_AX88796B_PHY is not set
8745+# CONFIG_AT803X_PHY is not set
8746+# CONFIG_BCM7XXX_PHY is not set
8747+# CONFIG_BCM87XX_PHY is not set
8748+# CONFIG_BROADCOM_PHY is not set
8749+# CONFIG_CICADA_PHY is not set
8750+# CONFIG_CORTINA_PHY is not set
8751+# CONFIG_DAVICOM_PHY is not set
8752+# CONFIG_DP83822_PHY is not set
8753+# CONFIG_DP83TC811_PHY is not set
8754+# CONFIG_DP83848_PHY is not set
8755+# CONFIG_DP83867_PHY is not set
8756+CONFIG_FIXED_PHY=y
8757+# CONFIG_ICPLUS_PHY is not set
8758+# CONFIG_INTEL_XWAY_PHY is not set
8759+# CONFIG_LSI_ET1011C_PHY is not set
8760+# CONFIG_LXT_PHY is not set
8761+# CONFIG_MARVELL_PHY is not set
8762+# CONFIG_MARVELL_10G_PHY is not set
8763+# CONFIG_MICREL_PHY is not set
8764+# CONFIG_MICROCHIP_PHY is not set
8765+# CONFIG_MICROCHIP_T1_PHY is not set
8766+# CONFIG_MICROSEMI_PHY is not set
8767+# CONFIG_NATIONAL_PHY is not set
8768+# CONFIG_QSEMI_PHY is not set
8769+# CONFIG_REALTEK_PHY is not set
8770+# CONFIG_RENESAS_PHY is not set
8771+# CONFIG_ROCKCHIP_PHY is not set
8772+# CONFIG_SMSC_PHY is not set
8773+# CONFIG_STE10XP is not set
8774+# CONFIG_TERANETICS_PHY is not set
8775+# CONFIG_VITESSE_PHY is not set
8776+# CONFIG_XILINX_GMII2RGMII is not set
8777+# CONFIG_MICREL_KS8995MA is not set
8778+# CONFIG_PPP is not set
8779+# CONFIG_SLIP is not set
8780+CONFIG_USB_NET_DRIVERS=y
8781+# CONFIG_USB_CATC is not set
8782+# CONFIG_USB_KAWETH is not set
8783+# CONFIG_USB_PEGASUS is not set
8784+# CONFIG_USB_RTL8150 is not set
8785+CONFIG_USB_RTL8152=y
8786+# CONFIG_USB_LAN78XX is not set
8787+# CONFIG_USB_USBNET is not set
8788+# CONFIG_USB_IPHETH is not set
8789+CONFIG_WLAN=y
8790+CONFIG_WLAN_VENDOR_ADMTEK=y
8791+CONFIG_WLAN_VENDOR_ATH=y
8792+# CONFIG_ATH_DEBUG is not set
8793+CONFIG_WLAN_VENDOR_ATMEL=y
8794+CONFIG_WLAN_VENDOR_BROADCOM=y
8795+CONFIG_WLAN_VENDOR_CISCO=y
8796+CONFIG_WLAN_VENDOR_INTEL=y
8797+CONFIG_WLAN_VENDOR_INTERSIL=y
8798+# CONFIG_HOSTAP is not set
8799+CONFIG_WLAN_VENDOR_MARVELL=y
8800+CONFIG_WLAN_VENDOR_MEDIATEK=y
8801+CONFIG_WLAN_VENDOR_RALINK=y
8802+CONFIG_WLAN_VENDOR_REALTEK=y
8803+CONFIG_WLAN_VENDOR_RSI=y
8804+CONFIG_WLAN_VENDOR_ST=y
8805+CONFIG_WLAN_VENDOR_TI=y
8806+CONFIG_WLAN_VENDOR_ZYDAS=y
8807+CONFIG_WLAN_VENDOR_QUANTENNA=y
8808+
8809+#
8810+# Enable WiMAX (Networking options) to see the WiMAX drivers
8811+#
8812+# CONFIG_WAN is not set
8813+# CONFIG_NETDEVSIM is not set
8814+# CONFIG_NET_FAILOVER is not set
8815+# CONFIG_ISDN is not set
8816+
8817+#
8818+# Input device support
8819+#
8820+CONFIG_INPUT=y
8821+CONFIG_INPUT_FF_MEMLESS=y
8822+# CONFIG_INPUT_POLLDEV is not set
8823+# CONFIG_INPUT_SPARSEKMAP is not set
8824+# CONFIG_INPUT_MATRIXKMAP is not set
8825+
8826+#
8827+# Userland interfaces
8828+#
8829+CONFIG_INPUT_MOUSEDEV=y
8830+CONFIG_INPUT_MOUSEDEV_PSAUX=y
8831+CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
8832+CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
8833+CONFIG_INPUT_JOYDEV=y
8834+CONFIG_INPUT_EVDEV=y
8835+# CONFIG_INPUT_EVBUG is not set
8836+
8837+#
8838+# Input Device Drivers
8839+#
8840+CONFIG_INPUT_KEYBOARD=y
8841+# CONFIG_KEYBOARD_ADP5588 is not set
8842+# CONFIG_KEYBOARD_ADP5589 is not set
8843+CONFIG_KEYBOARD_ATKBD=y
8844+# CONFIG_KEYBOARD_QT1070 is not set
8845+# CONFIG_KEYBOARD_QT2160 is not set
8846+# CONFIG_KEYBOARD_DLINK_DIR685 is not set
8847+# CONFIG_KEYBOARD_LKKBD is not set
8848+# CONFIG_KEYBOARD_GPIO is not set
8849+# CONFIG_KEYBOARD_GPIO_POLLED is not set
8850+# CONFIG_KEYBOARD_TCA6416 is not set
8851+# CONFIG_KEYBOARD_TCA8418 is not set
8852+# CONFIG_KEYBOARD_MATRIX is not set
8853+# CONFIG_KEYBOARD_LM8333 is not set
8854+# CONFIG_KEYBOARD_MAX7359 is not set
8855+# CONFIG_KEYBOARD_MCS is not set
8856+# CONFIG_KEYBOARD_MPR121 is not set
8857+# CONFIG_KEYBOARD_NEWTON is not set
8858+# CONFIG_KEYBOARD_OPENCORES is not set
8859+# CONFIG_KEYBOARD_SAMSUNG is not set
8860+# CONFIG_KEYBOARD_STOWAWAY is not set
8861+# CONFIG_KEYBOARD_SUNKBD is not set
8862+# CONFIG_KEYBOARD_OMAP4 is not set
8863+# CONFIG_KEYBOARD_XTKBD is not set
8864+# CONFIG_KEYBOARD_CAP11XX is not set
8865+# CONFIG_KEYBOARD_BCM is not set
8866+CONFIG_INPUT_MOUSE=y
8867+CONFIG_MOUSE_PS2=y
8868+CONFIG_MOUSE_PS2_ALPS=y
8869+CONFIG_MOUSE_PS2_BYD=y
8870+CONFIG_MOUSE_PS2_LOGIPS2PP=y
8871+CONFIG_MOUSE_PS2_SYNAPTICS=y
8872+CONFIG_MOUSE_PS2_SYNAPTICS_SMBUS=y
8873+CONFIG_MOUSE_PS2_CYPRESS=y
8874+CONFIG_MOUSE_PS2_TRACKPOINT=y
8875+# CONFIG_MOUSE_PS2_ELANTECH is not set
8876+# CONFIG_MOUSE_PS2_SENTELIC is not set
8877+# CONFIG_MOUSE_PS2_TOUCHKIT is not set
8878+CONFIG_MOUSE_PS2_FOCALTECH=y
8879+CONFIG_MOUSE_PS2_SMBUS=y
8880+# CONFIG_MOUSE_SERIAL is not set
8881+# CONFIG_MOUSE_APPLETOUCH is not set
8882+# CONFIG_MOUSE_BCM5974 is not set
8883+# CONFIG_MOUSE_CYAPA is not set
8884+# CONFIG_MOUSE_ELAN_I2C is not set
8885+# CONFIG_MOUSE_VSXXXAA is not set
8886+# CONFIG_MOUSE_GPIO is not set
8887+# CONFIG_MOUSE_SYNAPTICS_I2C is not set
8888+# CONFIG_MOUSE_SYNAPTICS_USB is not set
8889+CONFIG_INPUT_JOYSTICK=y
8890+# CONFIG_JOYSTICK_ANALOG is not set
8891+# CONFIG_JOYSTICK_A3D is not set
8892+# CONFIG_JOYSTICK_ADI is not set
8893+# CONFIG_JOYSTICK_COBRA is not set
8894+# CONFIG_JOYSTICK_GF2K is not set
8895+# CONFIG_JOYSTICK_GRIP is not set
8896+# CONFIG_JOYSTICK_GRIP_MP is not set
8897+# CONFIG_JOYSTICK_GUILLEMOT is not set
8898+# CONFIG_JOYSTICK_INTERACT is not set
8899+# CONFIG_JOYSTICK_SIDEWINDER is not set
8900+# CONFIG_JOYSTICK_TMDC is not set
8901+# CONFIG_JOYSTICK_IFORCE is not set
8902+# CONFIG_JOYSTICK_WARRIOR is not set
8903+# CONFIG_JOYSTICK_MAGELLAN is not set
8904+# CONFIG_JOYSTICK_SPACEORB is not set
8905+# CONFIG_JOYSTICK_SPACEBALL is not set
8906+# CONFIG_JOYSTICK_STINGER is not set
8907+# CONFIG_JOYSTICK_TWIDJOY is not set
8908+# CONFIG_JOYSTICK_ZHENHUA is not set
8909+# CONFIG_JOYSTICK_AS5011 is not set
8910+# CONFIG_JOYSTICK_JOYDUMP is not set
8911+CONFIG_JOYSTICK_XPAD=y
8912+CONFIG_JOYSTICK_XPAD_FF=y
8913+# CONFIG_JOYSTICK_PSXPAD_SPI is not set
8914+# CONFIG_JOYSTICK_PXRC is not set
8915+# CONFIG_INPUT_TABLET is not set
8916+# CONFIG_INPUT_TOUCHSCREEN is not set
8917+# CONFIG_INPUT_MISC is not set
8918+# CONFIG_RMI4_CORE is not set
8919+
8920+#
8921+# Hardware I/O ports
8922+#
8923+CONFIG_SERIO=y
8924+CONFIG_SERIO_SERPORT=y
8925+# CONFIG_SERIO_AMBAKMI is not set
8926+CONFIG_SERIO_LIBPS2=y
8927+# CONFIG_SERIO_RAW is not set
8928+# CONFIG_SERIO_ALTERA_PS2 is not set
8929+# CONFIG_SERIO_PS2MULT is not set
8930+# CONFIG_SERIO_ARC_PS2 is not set
8931+# CONFIG_SERIO_APBPS2 is not set
8932+# CONFIG_SERIO_GPIO_PS2 is not set
8933+# CONFIG_USERIO is not set
8934+# CONFIG_GAMEPORT is not set
8935+
8936+#
8937+# Character devices
8938+#
8939+CONFIG_TTY=y
8940+CONFIG_VT=y
8941+CONFIG_CONSOLE_TRANSLATIONS=y
8942+CONFIG_VT_CONSOLE=y
8943+CONFIG_VT_CONSOLE_SLEEP=y
8944+CONFIG_HW_CONSOLE=y
8945+# CONFIG_VT_HW_CONSOLE_BINDING is not set
8946+CONFIG_UNIX98_PTYS=y
8947+# CONFIG_LEGACY_PTYS is not set
8948+# CONFIG_SERIAL_NONSTANDARD is not set
8949+# CONFIG_N_GSM is not set
8950+# CONFIG_TRACE_SINK is not set
8951+CONFIG_LDISC_AUTOLOAD=y
8952+CONFIG_DEVMEM=y
8953+CONFIG_DEVKMEM=y
8954+
8955+#
8956+# Serial drivers
8957+#
8958+CONFIG_SERIAL_EARLYCON=y
8959+# CONFIG_SERIAL_8250 is not set
8960+
8961+#
8962+# Non-8250 serial port support
8963+#
8964+# CONFIG_SERIAL_AMBA_PL010 is not set
8965+CONFIG_SERIAL_AMBA_PL011=y
8966+CONFIG_SERIAL_AMBA_PL011_CONSOLE=y
8967+# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set
8968+# CONFIG_SERIAL_MAX3100 is not set
8969+# CONFIG_SERIAL_MAX310X is not set
8970+# CONFIG_SERIAL_UARTLITE is not set
8971+CONFIG_SERIAL_CORE=y
8972+CONFIG_SERIAL_CORE_CONSOLE=y
8973+# CONFIG_SERIAL_SCCNXP is not set
8974+# CONFIG_SERIAL_SC16IS7XX is not set
8975+# CONFIG_SERIAL_BCM63XX is not set
8976+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
8977+# CONFIG_SERIAL_ALTERA_UART is not set
8978+# CONFIG_SERIAL_IFX6X60 is not set
8979+# CONFIG_SERIAL_XILINX_PS_UART is not set
8980+# CONFIG_SERIAL_ARC is not set
8981+# CONFIG_SERIAL_FSL_LPUART is not set
8982+# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set
8983+# CONFIG_SERIAL_ST_ASC is not set
8984+# CONFIG_SERIAL_DEV_BUS is not set
8985+# CONFIG_HVC_DCC is not set
8986+# CONFIG_IPMI_HANDLER is not set
8987+# CONFIG_HW_RANDOM is not set
8988+# CONFIG_RAW_DRIVER is not set
8989+# CONFIG_TCG_TPM is not set
8990+# CONFIG_XILLYBUS is not set
8991+
8992+#
8993+# I2C support
8994+#
8995+CONFIG_I2C=y
8996+CONFIG_I2C_BOARDINFO=y
8997+# CONFIG_I2C_COMPAT is not set
8998+CONFIG_I2C_CHARDEV=y
8999+CONFIG_I2C_MUX=y
9000+
9001+#
9002+# Multiplexer I2C Chip support
9003+#
9004+# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set
9005+# CONFIG_I2C_MUX_GPIO is not set
9006+# CONFIG_I2C_MUX_GPMUX is not set
9007+# CONFIG_I2C_MUX_LTC4306 is not set
9008+# CONFIG_I2C_MUX_PCA9541 is not set
9009+# CONFIG_I2C_MUX_PCA954x is not set
9010+# CONFIG_I2C_MUX_PINCTRL is not set
9011+# CONFIG_I2C_MUX_REG is not set
9012+# CONFIG_I2C_DEMUX_PINCTRL is not set
9013+# CONFIG_I2C_MUX_MLXCPLD is not set
9014+# CONFIG_I2C_HELPER_AUTO is not set
9015+# CONFIG_I2C_SMBUS is not set
9016+
9017+#
9018+# I2C Algorithms
9019+#
9020+# CONFIG_I2C_ALGOBIT is not set
9021+# CONFIG_I2C_ALGOPCF is not set
9022+# CONFIG_I2C_ALGOPCA is not set
9023+
9024+#
9025+# I2C Hardware Bus support
9026+#
9027+
9028+#
9029+# I2C system bus drivers (mostly embedded / system-on-chip)
9030+#
9031+# CONFIG_I2C_CBUS_GPIO is not set
9032+# CONFIG_I2C_DESIGNWARE_PLATFORM is not set
9033+# CONFIG_I2C_EMEV2 is not set
9034+# CONFIG_I2C_GPIO is not set
9035+CONFIG_I2C_HIBVT=y
9036+# CONFIG_I2C_NOMADIK is not set
9037+# CONFIG_I2C_OCORES is not set
9038+# CONFIG_I2C_PCA_PLATFORM is not set
9039+# CONFIG_I2C_RK3X is not set
9040+# CONFIG_I2C_SIMTEC is not set
9041+# CONFIG_I2C_XILINX is not set
9042+
9043+#
9044+# External I2C/SMBus adapter drivers
9045+#
9046+# CONFIG_I2C_DIOLAN_U2C is not set
9047+# CONFIG_I2C_PARPORT_LIGHT is not set
9048+# CONFIG_I2C_ROBOTFUZZ_OSIF is not set
9049+# CONFIG_I2C_TAOS_EVM is not set
9050+# CONFIG_I2C_TINY_USB is not set
9051+
9052+#
9053+# Other I2C/SMBus bus drivers
9054+#
9055+CONFIG_DMA_MSG_MIN_LEN=5
9056+CONFIG_DMA_MSG_MAX_LEN=4090
9057+# CONFIG_I2C_STUB is not set
9058+# CONFIG_I2C_SLAVE is not set
9059+# CONFIG_I2C_DEBUG_CORE is not set
9060+# CONFIG_I2C_DEBUG_ALGO is not set
9061+# CONFIG_I2C_DEBUG_BUS is not set
9062+CONFIG_SPI=y
9063+# CONFIG_SPI_DEBUG is not set
9064+CONFIG_SPI_MASTER=y
9065+# CONFIG_SPI_MEM is not set
9066+
9067+#
9068+# SPI Master Controller Drivers
9069+#
9070+# CONFIG_SPI_ALTERA is not set
9071+# CONFIG_SPI_AXI_SPI_ENGINE is not set
9072+# CONFIG_SPI_BITBANG is not set
9073+# CONFIG_SPI_CADENCE is not set
9074+# CONFIG_SPI_DESIGNWARE is not set
9075+# CONFIG_SPI_GPIO is not set
9076+# CONFIG_SPI_FSL_SPI is not set
9077+# CONFIG_SPI_OC_TINY is not set
9078+CONFIG_SPI_PL022=y
9079+# CONFIG_SPI_ROCKCHIP is not set
9080+# CONFIG_SPI_SC18IS602 is not set
9081+# CONFIG_SPI_XCOMM is not set
9082+# CONFIG_SPI_XILINX is not set
9083+# CONFIG_SPI_ZYNQMP_GQSPI is not set
9084+
9085+#
9086+# SPI Protocol Masters
9087+#
9088+CONFIG_SPI_SPIDEV=y
9089+# CONFIG_SPI_LOOPBACK_TEST is not set
9090+# CONFIG_SPI_TLE62X0 is not set
9091+# CONFIG_SPI_SLAVE is not set
9092+# CONFIG_SPMI is not set
9093+# CONFIG_HSI is not set
9094+# CONFIG_PPS is not set
9095+
9096+#
9097+# PTP clock support
9098+#
9099+# CONFIG_PTP_1588_CLOCK is not set
9100+
9101+#
9102+# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks.
9103+#
9104+CONFIG_PINCTRL=y
9105+# CONFIG_DEBUG_PINCTRL is not set
9106+# CONFIG_PINCTRL_AMD is not set
9107+# CONFIG_PINCTRL_MCP23S08 is not set
9108+# CONFIG_PINCTRL_SINGLE is not set
9109+# CONFIG_PINCTRL_SX150X is not set
9110+CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
9111+CONFIG_GPIOLIB=y
9112+CONFIG_GPIOLIB_FASTPATH_LIMIT=512
9113+CONFIG_OF_GPIO=y
9114+CONFIG_GPIOLIB_IRQCHIP=y
9115+# CONFIG_DEBUG_GPIO is not set
9116+CONFIG_GPIO_SYSFS=y
9117+CONFIG_GPIO_GENERIC=y
9118+
9119+#
9120+# Memory mapped GPIO drivers
9121+#
9122+# CONFIG_GPIO_74XX_MMIO is not set
9123+# CONFIG_GPIO_ALTERA is not set
9124+# CONFIG_GPIO_DWAPB is not set
9125+# CONFIG_GPIO_FTGPIO010 is not set
9126+CONFIG_GPIO_GENERIC_PLATFORM=y
9127+# CONFIG_GPIO_GRGPIO is not set
9128+# CONFIG_GPIO_HLWD is not set
9129+# CONFIG_GPIO_MB86S7X is not set
9130+# CONFIG_GPIO_MOCKUP is not set
9131+# CONFIG_GPIO_MPC8XXX is not set
9132+CONFIG_GPIO_PL061=y
9133+# CONFIG_GPIO_SYSCON is not set
9134+# CONFIG_GPIO_XILINX is not set
9135+# CONFIG_GPIO_ZEVIO is not set
9136+
9137+#
9138+# I2C GPIO expanders
9139+#
9140+# CONFIG_GPIO_ADP5588 is not set
9141+# CONFIG_GPIO_ADNP is not set
9142+# CONFIG_GPIO_MAX7300 is not set
9143+# CONFIG_GPIO_MAX732X is not set
9144+# CONFIG_GPIO_PCA953X is not set
9145+# CONFIG_GPIO_PCF857X is not set
9146+# CONFIG_GPIO_TPIC2810 is not set
9147+
9148+#
9149+# MFD GPIO expanders
9150+#
9151+# CONFIG_HTC_EGPIO is not set
9152+
9153+#
9154+# SPI GPIO expanders
9155+#
9156+# CONFIG_GPIO_74X164 is not set
9157+# CONFIG_GPIO_MAX3191X is not set
9158+# CONFIG_GPIO_MAX7301 is not set
9159+# CONFIG_GPIO_MC33880 is not set
9160+# CONFIG_GPIO_PISOSR is not set
9161+# CONFIG_GPIO_XRA1403 is not set
9162+
9163+#
9164+# USB GPIO expanders
9165+#
9166+# CONFIG_W1 is not set
9167+# CONFIG_POWER_AVS is not set
9168+CONFIG_POWER_RESET=y
9169+# CONFIG_POWER_RESET_BRCMKONA is not set
9170+# CONFIG_POWER_RESET_BRCMSTB is not set
9171+# CONFIG_POWER_RESET_GPIO is not set
9172+# CONFIG_POWER_RESET_GPIO_RESTART is not set
9173+CONFIG_POWER_RESET_HISI=y
9174+# CONFIG_POWER_RESET_LTC2952 is not set
9175+# CONFIG_POWER_RESET_RESTART is not set
9176+# CONFIG_POWER_RESET_VERSATILE is not set
9177+CONFIG_POWER_RESET_SYSCON=y
9178+# CONFIG_POWER_RESET_SYSCON_POWEROFF is not set
9179+# CONFIG_SYSCON_REBOOT_MODE is not set
9180+CONFIG_POWER_SUPPLY=y
9181+# CONFIG_POWER_SUPPLY_DEBUG is not set
9182+# CONFIG_PDA_POWER is not set
9183+# CONFIG_TEST_POWER is not set
9184+# CONFIG_CHARGER_ADP5061 is not set
9185+# CONFIG_BATTERY_DS2780 is not set
9186+# CONFIG_BATTERY_DS2781 is not set
9187+# CONFIG_BATTERY_DS2782 is not set
9188+# CONFIG_BATTERY_SBS is not set
9189+# CONFIG_CHARGER_SBS is not set
9190+# CONFIG_MANAGER_SBS is not set
9191+# CONFIG_BATTERY_BQ27XXX is not set
9192+# CONFIG_BATTERY_MAX17040 is not set
9193+# CONFIG_BATTERY_MAX17042 is not set
9194+# CONFIG_CHARGER_MAX8903 is not set
9195+# CONFIG_CHARGER_LP8727 is not set
9196+# CONFIG_CHARGER_GPIO is not set
9197+# CONFIG_CHARGER_LTC3651 is not set
9198+# CONFIG_CHARGER_DETECTOR_MAX14656 is not set
9199+# CONFIG_CHARGER_BQ2415X is not set
9200+# CONFIG_CHARGER_BQ24257 is not set
9201+# CONFIG_CHARGER_BQ24735 is not set
9202+# CONFIG_CHARGER_BQ25890 is not set
9203+# CONFIG_CHARGER_SMB347 is not set
9204+# CONFIG_BATTERY_GAUGE_LTC2941 is not set
9205+# CONFIG_CHARGER_RT9455 is not set
9206+# CONFIG_HWMON is not set
9207+# CONFIG_THERMAL is not set
9208+# CONFIG_WATCHDOG is not set
9209+CONFIG_SSB_POSSIBLE=y
9210+# CONFIG_SSB is not set
9211+CONFIG_BCMA_POSSIBLE=y
9212+# CONFIG_BCMA is not set
9213+
9214+#
9215+# Multifunction device drivers
9216+#
9217+CONFIG_MFD_CORE=y
9218+# CONFIG_MFD_ACT8945A is not set
9219+# CONFIG_MFD_AS3711 is not set
9220+# CONFIG_MFD_AS3722 is not set
9221+# CONFIG_PMIC_ADP5520 is not set
9222+# CONFIG_MFD_AAT2870_CORE is not set
9223+# CONFIG_MFD_ATMEL_FLEXCOM is not set
9224+# CONFIG_MFD_ATMEL_HLCDC is not set
9225+# CONFIG_MFD_BCM590XX is not set
9226+# CONFIG_MFD_BD9571MWV is not set
9227+# CONFIG_MFD_AXP20X_I2C is not set
9228+# CONFIG_MFD_CROS_EC is not set
9229+# CONFIG_MFD_MADERA is not set
9230+# CONFIG_MFD_ASIC3 is not set
9231+# CONFIG_PMIC_DA903X is not set
9232+# CONFIG_MFD_DA9052_SPI is not set
9233+# CONFIG_MFD_DA9052_I2C is not set
9234+# CONFIG_MFD_DA9055 is not set
9235+# CONFIG_MFD_DA9062 is not set
9236+# CONFIG_MFD_DA9063 is not set
9237+# CONFIG_MFD_DA9150 is not set
9238+# CONFIG_MFD_DLN2 is not set
9239+# CONFIG_MFD_MC13XXX_SPI is not set
9240+# CONFIG_MFD_MC13XXX_I2C is not set
9241+# CONFIG_MFD_HI6421_PMIC is not set
9242+CONFIG_MFD_HISI_FMC=y
9243+# CONFIG_HTC_PASIC3 is not set
9244+# CONFIG_HTC_I2CPLD is not set
9245+# CONFIG_MFD_KEMPLD is not set
9246+# CONFIG_MFD_88PM800 is not set
9247+# CONFIG_MFD_88PM805 is not set
9248+# CONFIG_MFD_88PM860X is not set
9249+# CONFIG_MFD_MAX14577 is not set
9250+# CONFIG_MFD_MAX77620 is not set
9251+# CONFIG_MFD_MAX77686 is not set
9252+# CONFIG_MFD_MAX77693 is not set
9253+# CONFIG_MFD_MAX77843 is not set
9254+# CONFIG_MFD_MAX8907 is not set
9255+# CONFIG_MFD_MAX8925 is not set
9256+# CONFIG_MFD_MAX8997 is not set
9257+# CONFIG_MFD_MAX8998 is not set
9258+# CONFIG_MFD_MT6397 is not set
9259+# CONFIG_MFD_MENF21BMC is not set
9260+# CONFIG_EZX_PCAP is not set
9261+# CONFIG_MFD_CPCAP is not set
9262+# CONFIG_MFD_VIPERBOARD is not set
9263+# CONFIG_MFD_RETU is not set
9264+# CONFIG_MFD_PCF50633 is not set
9265+# CONFIG_MFD_PM8XXX is not set
9266+# CONFIG_MFD_RT5033 is not set
9267+# CONFIG_MFD_RC5T583 is not set
9268+# CONFIG_MFD_RK808 is not set
9269+# CONFIG_MFD_RN5T618 is not set
9270+# CONFIG_MFD_SEC_CORE is not set
9271+# CONFIG_MFD_SI476X_CORE is not set
9272+# CONFIG_MFD_SM501 is not set
9273+# CONFIG_MFD_SKY81452 is not set
9274+# CONFIG_MFD_SMSC is not set
9275+# CONFIG_ABX500_CORE is not set
9276+# CONFIG_MFD_STMPE is not set
9277+CONFIG_MFD_SYSCON=y
9278+# CONFIG_MFD_TI_AM335X_TSCADC is not set
9279+# CONFIG_MFD_LP3943 is not set
9280+# CONFIG_MFD_LP8788 is not set
9281+# CONFIG_MFD_TI_LMU is not set
9282+# CONFIG_MFD_PALMAS is not set
9283+# CONFIG_TPS6105X is not set
9284+# CONFIG_TPS65010 is not set
9285+# CONFIG_TPS6507X is not set
9286+# CONFIG_MFD_TPS65086 is not set
9287+# CONFIG_MFD_TPS65090 is not set
9288+# CONFIG_MFD_TPS65217 is not set
9289+# CONFIG_MFD_TI_LP873X is not set
9290+# CONFIG_MFD_TI_LP87565 is not set
9291+# CONFIG_MFD_TPS65218 is not set
9292+# CONFIG_MFD_TPS6586X is not set
9293+# CONFIG_MFD_TPS65910 is not set
9294+# CONFIG_MFD_TPS65912_I2C is not set
9295+# CONFIG_MFD_TPS65912_SPI is not set
9296+# CONFIG_MFD_TPS80031 is not set
9297+# CONFIG_TWL4030_CORE is not set
9298+# CONFIG_TWL6040_CORE is not set
9299+# CONFIG_MFD_WL1273_CORE is not set
9300+# CONFIG_MFD_LM3533 is not set
9301+# CONFIG_MFD_TC3589X is not set
9302+# CONFIG_MFD_T7L66XB is not set
9303+# CONFIG_MFD_TC6387XB is not set
9304+# CONFIG_MFD_TC6393XB is not set
9305+# CONFIG_MFD_ARIZONA_I2C is not set
9306+# CONFIG_MFD_ARIZONA_SPI is not set
9307+# CONFIG_MFD_WM8400 is not set
9308+# CONFIG_MFD_WM831X_I2C is not set
9309+# CONFIG_MFD_WM831X_SPI is not set
9310+# CONFIG_MFD_WM8350_I2C is not set
9311+# CONFIG_MFD_WM8994 is not set
9312+# CONFIG_MFD_ROHM_BD718XX is not set
9313+# CONFIG_REGULATOR is not set
9314+# CONFIG_RC_CORE is not set
9315+CONFIG_MEDIA_SUPPORT=y
9316+
9317+#
9318+# Multimedia core support
9319+#
9320+CONFIG_MEDIA_CAMERA_SUPPORT=y
9321+# CONFIG_MEDIA_ANALOG_TV_SUPPORT is not set
9322+# CONFIG_MEDIA_DIGITAL_TV_SUPPORT is not set
9323+# CONFIG_MEDIA_RADIO_SUPPORT is not set
9324+# CONFIG_MEDIA_SDR_SUPPORT is not set
9325+# CONFIG_MEDIA_CEC_SUPPORT is not set
9326+# CONFIG_MEDIA_CONTROLLER is not set
9327+CONFIG_VIDEO_DEV=y
9328+CONFIG_VIDEO_V4L2=y
9329+# CONFIG_VIDEO_ADV_DEBUG is not set
9330+# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
9331+
9332+#
9333+# Media drivers
9334+#
9335+CONFIG_MEDIA_USB_SUPPORT=y
9336+
9337+#
9338+# Webcam devices
9339+#
9340+CONFIG_USB_VIDEO_CLASS=y
9341+CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y
9342+CONFIG_USB_GSPCA=m
9343+# CONFIG_USB_M5602 is not set
9344+# CONFIG_USB_STV06XX is not set
9345+# CONFIG_USB_GL860 is not set
9346+# CONFIG_USB_GSPCA_BENQ is not set
9347+# CONFIG_USB_GSPCA_CONEX is not set
9348+# CONFIG_USB_GSPCA_CPIA1 is not set
9349+# CONFIG_USB_GSPCA_DTCS033 is not set
9350+# CONFIG_USB_GSPCA_ETOMS is not set
9351+# CONFIG_USB_GSPCA_FINEPIX is not set
9352+# CONFIG_USB_GSPCA_JEILINJ is not set
9353+# CONFIG_USB_GSPCA_JL2005BCD is not set
9354+# CONFIG_USB_GSPCA_KINECT is not set
9355+# CONFIG_USB_GSPCA_KONICA is not set
9356+# CONFIG_USB_GSPCA_MARS is not set
9357+# CONFIG_USB_GSPCA_MR97310A is not set
9358+# CONFIG_USB_GSPCA_NW80X is not set
9359+# CONFIG_USB_GSPCA_OV519 is not set
9360+# CONFIG_USB_GSPCA_OV534 is not set
9361+# CONFIG_USB_GSPCA_OV534_9 is not set
9362+# CONFIG_USB_GSPCA_PAC207 is not set
9363+# CONFIG_USB_GSPCA_PAC7302 is not set
9364+# CONFIG_USB_GSPCA_PAC7311 is not set
9365+# CONFIG_USB_GSPCA_SE401 is not set
9366+# CONFIG_USB_GSPCA_SN9C2028 is not set
9367+# CONFIG_USB_GSPCA_SN9C20X is not set
9368+# CONFIG_USB_GSPCA_SONIXB is not set
9369+# CONFIG_USB_GSPCA_SONIXJ is not set
9370+# CONFIG_USB_GSPCA_SPCA500 is not set
9371+# CONFIG_USB_GSPCA_SPCA501 is not set
9372+# CONFIG_USB_GSPCA_SPCA505 is not set
9373+# CONFIG_USB_GSPCA_SPCA506 is not set
9374+# CONFIG_USB_GSPCA_SPCA508 is not set
9375+# CONFIG_USB_GSPCA_SPCA561 is not set
9376+# CONFIG_USB_GSPCA_SPCA1528 is not set
9377+# CONFIG_USB_GSPCA_SQ905 is not set
9378+# CONFIG_USB_GSPCA_SQ905C is not set
9379+# CONFIG_USB_GSPCA_SQ930X is not set
9380+# CONFIG_USB_GSPCA_STK014 is not set
9381+# CONFIG_USB_GSPCA_STK1135 is not set
9382+# CONFIG_USB_GSPCA_STV0680 is not set
9383+# CONFIG_USB_GSPCA_SUNPLUS is not set
9384+# CONFIG_USB_GSPCA_T613 is not set
9385+# CONFIG_USB_GSPCA_TOPRO is not set
9386+# CONFIG_USB_GSPCA_TOUPTEK is not set
9387+# CONFIG_USB_GSPCA_TV8532 is not set
9388+# CONFIG_USB_GSPCA_VC032X is not set
9389+# CONFIG_USB_GSPCA_VICAM is not set
9390+# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
9391+# CONFIG_USB_GSPCA_ZC3XX is not set
9392+# CONFIG_USB_PWC is not set
9393+# CONFIG_VIDEO_CPIA2 is not set
9394+# CONFIG_USB_ZR364XX is not set
9395+# CONFIG_USB_STKWEBCAM is not set
9396+# CONFIG_USB_S2255 is not set
9397+# CONFIG_VIDEO_USBTV is not set
9398+
9399+#
9400+# Webcam, TV (analog/digital) USB devices
9401+#
9402+# CONFIG_VIDEO_EM28XX is not set
9403+# CONFIG_V4L_PLATFORM_DRIVERS is not set
9404+# CONFIG_V4L_MEM2MEM_DRIVERS is not set
9405+# CONFIG_V4L_TEST_DRIVERS is not set
9406+
9407+#
9408+# Supported MMC/SDIO adapters
9409+#
9410+# CONFIG_CYPRESS_FIRMWARE is not set
9411+CONFIG_VIDEOBUF2_CORE=y
9412+CONFIG_VIDEOBUF2_V4L2=y
9413+CONFIG_VIDEOBUF2_MEMOPS=y
9414+CONFIG_VIDEOBUF2_VMALLOC=y
9415+
9416+#
9417+# Media ancillary drivers (tuners, sensors, i2c, spi, frontends)
9418+#
9419+CONFIG_MEDIA_SUBDRV_AUTOSELECT=y
9420+
9421+#
9422+# Audio decoders, processors and mixers
9423+#
9424+
9425+#
9426+# RDS decoders
9427+#
9428+
9429+#
9430+# Video decoders
9431+#
9432+
9433+#
9434+# Video and audio decoders
9435+#
9436+
9437+#
9438+# Video encoders
9439+#
9440+
9441+#
9442+# Camera sensor devices
9443+#
9444+
9445+#
9446+# Flash devices
9447+#
9448+
9449+#
9450+# Video improvement chips
9451+#
9452+
9453+#
9454+# Audio/Video compression chips
9455+#
9456+
9457+#
9458+# SDR tuner chips
9459+#
9460+
9461+#
9462+# Miscellaneous helper chips
9463+#
9464+
9465+#
9466+# Sensors used on soc_camera driver
9467+#
9468+
9469+#
9470+# Media SPI Adapters
9471+#
9472+
9473+#
9474+# Tools to develop new frontends
9475+#
9476+
9477+#
9478+# Graphics support
9479+#
9480+# CONFIG_IMX_IPUV3_CORE is not set
9481+# CONFIG_DRM is not set
9482+# CONFIG_DRM_DP_CEC is not set
9483+
9484+#
9485+# ACP (Audio CoProcessor) Configuration
9486+#
9487+
9488+#
9489+# AMD Library routines
9490+#
9491+
9492+#
9493+# Frame buffer Devices
9494+#
9495+CONFIG_FB_CMDLINE=y
9496+CONFIG_FB_NOTIFY=y
9497+CONFIG_FB=y
9498+# CONFIG_FIRMWARE_EDID is not set
9499+# CONFIG_FB_FOREIGN_ENDIAN is not set
9500+# CONFIG_FB_MODE_HELPERS is not set
9501+# CONFIG_FB_TILEBLITTING is not set
9502+
9503+#
9504+# Frame buffer hardware drivers
9505+#
9506+# CONFIG_FB_ARMCLCD is not set
9507+# CONFIG_FB_OPENCORES is not set
9508+# CONFIG_FB_S1D13XXX is not set
9509+# CONFIG_FB_SMSCUFX is not set
9510+# CONFIG_FB_UDL is not set
9511+# CONFIG_FB_IBM_GXT4500 is not set
9512+# CONFIG_FB_VIRTUAL is not set
9513+# CONFIG_FB_METRONOME is not set
9514+# CONFIG_FB_BROADSHEET is not set
9515+# CONFIG_FB_SIMPLE is not set
9516+# CONFIG_FB_SSD1307 is not set
9517+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
9518+
9519+#
9520+# Console display driver support
9521+#
9522+CONFIG_DUMMY_CONSOLE=y
9523+# CONFIG_FRAMEBUFFER_CONSOLE is not set
9524+# CONFIG_LOGO is not set
9525+CONFIG_SOUND=y
9526+CONFIG_SND=y
9527+CONFIG_SND_TIMER=y
9528+CONFIG_SND_PCM=y
9529+# CONFIG_SND_OSSEMUL is not set
9530+CONFIG_SND_PCM_TIMER=y
9531+# CONFIG_SND_DYNAMIC_MINORS is not set
9532+CONFIG_SND_SUPPORT_OLD_API=y
9533+CONFIG_SND_PROC_FS=y
9534+CONFIG_SND_VERBOSE_PROCFS=y
9535+# CONFIG_SND_VERBOSE_PRINTK is not set
9536+# CONFIG_SND_DEBUG is not set
9537+# CONFIG_SND_SEQUENCER is not set
9538+CONFIG_SND_DRIVERS=y
9539+# CONFIG_SND_DUMMY is not set
9540+# CONFIG_SND_ALOOP is not set
9541+# CONFIG_SND_MTPAV is not set
9542+# CONFIG_SND_SERIAL_U16550 is not set
9543+# CONFIG_SND_MPU401 is not set
9544+
9545+#
9546+# HD-Audio
9547+#
9548+CONFIG_SND_HDA_PREALLOC_SIZE=64
9549+CONFIG_SND_ARM=y
9550+# CONFIG_SND_ARMAACI is not set
9551+CONFIG_SND_SPI=y
9552+CONFIG_SND_USB=y
9553+# CONFIG_SND_USB_AUDIO is not set
9554+# CONFIG_SND_USB_UA101 is not set
9555+# CONFIG_SND_USB_CAIAQ is not set
9556+# CONFIG_SND_USB_6FIRE is not set
9557+# CONFIG_SND_USB_HIFACE is not set
9558+# CONFIG_SND_BCD2000 is not set
9559+# CONFIG_SND_USB_POD is not set
9560+# CONFIG_SND_USB_PODHD is not set
9561+# CONFIG_SND_USB_TONEPORT is not set
9562+# CONFIG_SND_USB_VARIAX is not set
9563+# CONFIG_SND_SOC is not set
9564+
9565+#
9566+# HID support
9567+#
9568+CONFIG_HID=y
9569+# CONFIG_HID_BATTERY_STRENGTH is not set
9570+# CONFIG_HIDRAW is not set
9571+# CONFIG_UHID is not set
9572+CONFIG_HID_GENERIC=y
9573+
9574+#
9575+# Special HID drivers
9576+#
9577+CONFIG_HID_A4TECH=y
9578+# CONFIG_HID_ACCUTOUCH is not set
9579+# CONFIG_HID_ACRUX is not set
9580+CONFIG_HID_APPLE=y
9581+# CONFIG_HID_APPLEIR is not set
9582+# CONFIG_HID_AUREAL is not set
9583+CONFIG_HID_BELKIN=y
9584+# CONFIG_HID_BETOP_FF is not set
9585+CONFIG_HID_CHERRY=y
9586+CONFIG_HID_CHICONY=y
9587+# CONFIG_HID_COUGAR is not set
9588+# CONFIG_HID_PRODIKEYS is not set
9589+# CONFIG_HID_CMEDIA is not set
9590+CONFIG_HID_CYPRESS=y
9591+# CONFIG_HID_DRAGONRISE is not set
9592+# CONFIG_HID_EMS_FF is not set
9593+# CONFIG_HID_ELECOM is not set
9594+# CONFIG_HID_ELO is not set
9595+CONFIG_HID_EZKEY=y
9596+# CONFIG_HID_GEMBIRD is not set
9597+# CONFIG_HID_GFRM is not set
9598+# CONFIG_HID_HOLTEK is not set
9599+# CONFIG_HID_KEYTOUCH is not set
9600+# CONFIG_HID_KYE is not set
9601+# CONFIG_HID_UCLOGIC is not set
9602+# CONFIG_HID_WALTOP is not set
9603+# CONFIG_HID_GYRATION is not set
9604+# CONFIG_HID_ICADE is not set
9605+CONFIG_HID_ITE=y
9606+# CONFIG_HID_JABRA is not set
9607+# CONFIG_HID_TWINHAN is not set
9608+CONFIG_HID_KENSINGTON=y
9609+# CONFIG_HID_LCPOWER is not set
9610+# CONFIG_HID_LENOVO is not set
9611+CONFIG_HID_LOGITECH=y
9612+# CONFIG_HID_LOGITECH_HIDPP is not set
9613+# CONFIG_LOGITECH_FF is not set
9614+# CONFIG_LOGIRUMBLEPAD2_FF is not set
9615+# CONFIG_LOGIG940_FF is not set
9616+# CONFIG_LOGIWHEELS_FF is not set
9617+# CONFIG_HID_MAGICMOUSE is not set
9618+# CONFIG_HID_MAYFLASH is not set
9619+CONFIG_HID_REDRAGON=y
9620+CONFIG_HID_MICROSOFT=y
9621+CONFIG_HID_MONTEREY=y
9622+# CONFIG_HID_MULTITOUCH is not set
9623+# CONFIG_HID_NTI is not set
9624+# CONFIG_HID_NTRIG is not set
9625+# CONFIG_HID_ORTEK is not set
9626+# CONFIG_HID_PANTHERLORD is not set
9627+# CONFIG_HID_PENMOUNT is not set
9628+# CONFIG_HID_PETALYNX is not set
9629+# CONFIG_HID_PICOLCD is not set
9630+# CONFIG_HID_PLANTRONICS is not set
9631+# CONFIG_HID_PRIMAX is not set
9632+# CONFIG_HID_RETRODE is not set
9633+# CONFIG_HID_ROCCAT is not set
9634+# CONFIG_HID_SAITEK is not set
9635+# CONFIG_HID_SAMSUNG is not set
9636+# CONFIG_HID_SPEEDLINK is not set
9637+# CONFIG_HID_STEAM is not set
9638+# CONFIG_HID_STEELSERIES is not set
9639+# CONFIG_HID_SUNPLUS is not set
9640+# CONFIG_HID_RMI is not set
9641+# CONFIG_HID_GREENASIA is not set
9642+# CONFIG_HID_SMARTJOYPLUS is not set
9643+# CONFIG_HID_TIVO is not set
9644+# CONFIG_HID_TOPSEED is not set
9645+# CONFIG_HID_THRUSTMASTER is not set
9646+# CONFIG_HID_UDRAW_PS3 is not set
9647+# CONFIG_HID_WACOM is not set
9648+# CONFIG_HID_XINMO is not set
9649+# CONFIG_HID_ZEROPLUS is not set
9650+# CONFIG_HID_ZYDACRON is not set
9651+# CONFIG_HID_SENSOR_HUB is not set
9652+# CONFIG_HID_ALPS is not set
9653+
9654+#
9655+# USB HID support
9656+#
9657+CONFIG_USB_HID=y
9658+# CONFIG_HID_PID is not set
9659+# CONFIG_USB_HIDDEV is not set
9660+
9661+#
9662+# I2C HID support
9663+#
9664+# CONFIG_I2C_HID is not set
9665+CONFIG_USB_OHCI_LITTLE_ENDIAN=y
9666+CONFIG_USB_SUPPORT=y
9667+CONFIG_USB_COMMON=y
9668+CONFIG_USB_ARCH_HAS_HCD=y
9669+CONFIG_USB=y
9670+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
9671+
9672+#
9673+# Miscellaneous USB options
9674+#
9675+CONFIG_USB_DEFAULT_PERSIST=y
9676+# CONFIG_USB_DYNAMIC_MINORS is not set
9677+# CONFIG_USB_OTG is not set
9678+# CONFIG_USB_OTG_WHITELIST is not set
9679+# CONFIG_USB_MON is not set
9680+# CONFIG_USB_WUSB_CBAF is not set
9681+
9682+#
9683+# USB Host Controller Drivers
9684+#
9685+# CONFIG_USB_C67X00_HCD is not set
9686+CONFIG_USB_XHCI_HCD=y
9687+# CONFIG_USB_XHCI_DBGCAP is not set
9688+CONFIG_USB_XHCI_PLATFORM=y
9689+# CONFIG_USB_EHCI_HCD is not set
9690+# CONFIG_USB_OXU210HP_HCD is not set
9691+# CONFIG_USB_ISP116X_HCD is not set
9692+# CONFIG_USB_FOTG210_HCD is not set
9693+# CONFIG_USB_MAX3421_HCD is not set
9694+# CONFIG_USB_OHCI_HCD is not set
9695+# CONFIG_USB_SL811_HCD is not set
9696+# CONFIG_USB_R8A66597_HCD is not set
9697+# CONFIG_USB_HCD_TEST_MODE is not set
9698+
9699+#
9700+# USB Device Class drivers
9701+#
9702+# CONFIG_USB_ACM is not set
9703+# CONFIG_USB_PRINTER is not set
9704+# CONFIG_USB_WDM is not set
9705+# CONFIG_USB_TMC is not set
9706+
9707+#
9708+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may
9709+#
9710+
9711+#
9712+# also be needed; see USB_STORAGE Help for more info
9713+#
9714+CONFIG_USB_STORAGE=y
9715+# CONFIG_USB_STORAGE_DEBUG is not set
9716+# CONFIG_USB_STORAGE_REALTEK is not set
9717+# CONFIG_USB_STORAGE_DATAFAB is not set
9718+# CONFIG_USB_STORAGE_FREECOM is not set
9719+# CONFIG_USB_STORAGE_ISD200 is not set
9720+# CONFIG_USB_STORAGE_USBAT is not set
9721+# CONFIG_USB_STORAGE_SDDR09 is not set
9722+# CONFIG_USB_STORAGE_SDDR55 is not set
9723+# CONFIG_USB_STORAGE_JUMPSHOT is not set
9724+# CONFIG_USB_STORAGE_ALAUDA is not set
9725+# CONFIG_USB_STORAGE_ONETOUCH is not set
9726+# CONFIG_USB_STORAGE_KARMA is not set
9727+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
9728+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
9729+# CONFIG_USB_UAS is not set
9730+
9731+#
9732+# USB Imaging devices
9733+#
9734+# CONFIG_USB_MDC800 is not set
9735+# CONFIG_USB_MICROTEK is not set
9736+# CONFIG_USBIP_CORE is not set
9737+# CONFIG_USB_MUSB_HDRC is not set
9738+CONFIG_USB_DWC3=y
9739+# CONFIG_USB_DWC3_HOST is not set
9740+CONFIG_USB_DWC3_GADGET=y
9741+
9742+#
9743+# Platform Glue Driver Support
9744+#
9745+# CONFIG_USB_DWC3_OF_SIMPLE is not set
9746+# CONFIG_USB_DWC2 is not set
9747+# CONFIG_USB_CHIPIDEA is not set
9748+# CONFIG_USB_ISP1760 is not set
9749+
9750+#
9751+# USB port drivers
9752+#
9753+# CONFIG_USB_SERIAL is not set
9754+
9755+#
9756+# USB Miscellaneous drivers
9757+#
9758+# CONFIG_USB_EMI62 is not set
9759+# CONFIG_USB_EMI26 is not set
9760+# CONFIG_USB_ADUTUX is not set
9761+# CONFIG_USB_SEVSEG is not set
9762+# CONFIG_USB_LEGOTOWER is not set
9763+# CONFIG_USB_LCD is not set
9764+# CONFIG_USB_CYPRESS_CY7C63 is not set
9765+# CONFIG_USB_CYTHERM is not set
9766+# CONFIG_USB_IDMOUSE is not set
9767+# CONFIG_USB_FTDI_ELAN is not set
9768+# CONFIG_USB_APPLEDISPLAY is not set
9769+# CONFIG_USB_LD is not set
9770+# CONFIG_USB_TRANCEVIBRATOR is not set
9771+# CONFIG_USB_IOWARRIOR is not set
9772+# CONFIG_USB_TEST is not set
9773+# CONFIG_USB_EHSET_TEST_FIXTURE is not set
9774+# CONFIG_USB_ISIGHTFW is not set
9775+# CONFIG_USB_YUREX is not set
9776+# CONFIG_USB_EZUSB_FX2 is not set
9777+# CONFIG_USB_HUB_USB251XB is not set
9778+# CONFIG_USB_HSIC_USB3503 is not set
9779+# CONFIG_USB_HSIC_USB4604 is not set
9780+# CONFIG_USB_LINK_LAYER_TEST is not set
9781+
9782+#
9783+# USB Physical Layer drivers
9784+#
9785+# CONFIG_NOP_USB_XCEIV is not set
9786+# CONFIG_USB_GPIO_VBUS is not set
9787+# CONFIG_USB_ISP1301 is not set
9788+# CONFIG_USB_ULPI is not set
9789+CONFIG_USB_GADGET=y
9790+# CONFIG_USB_GADGET_DEBUG is not set
9791+# CONFIG_USB_GADGET_DEBUG_FILES is not set
9792+# CONFIG_USB_GADGET_DEBUG_FS is not set
9793+CONFIG_USB_GADGET_VBUS_DRAW=2
9794+CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2
9795+# CONFIG_U_SERIAL_CONSOLE is not set
9796+
9797+#
9798+# USB Peripheral Controller
9799+#
9800+# CONFIG_USB_FUSB300 is not set
9801+# CONFIG_USB_FOTG210_UDC is not set
9802+# CONFIG_USB_GR_UDC is not set
9803+# CONFIG_USB_R8A66597 is not set
9804+# CONFIG_USB_PXA27X is not set
9805+# CONFIG_USB_MV_UDC is not set
9806+# CONFIG_USB_MV_U3D is not set
9807+# CONFIG_USB_SNP_UDC_PLAT is not set
9808+# CONFIG_USB_M66592 is not set
9809+# CONFIG_USB_BDC_UDC is not set
9810+# CONFIG_USB_NET2272 is not set
9811+# CONFIG_USB_GADGET_XILINX is not set
9812+# CONFIG_USB_DUMMY_HCD is not set
9813+CONFIG_USB_LIBCOMPOSITE=y
9814+CONFIG_USB_F_ACM=y
9815+CONFIG_USB_U_SERIAL=y
9816+CONFIG_USB_U_ETHER=y
9817+CONFIG_USB_U_AUDIO=y
9818+CONFIG_USB_F_RNDIS=y
9819+CONFIG_USB_F_MASS_STORAGE=y
9820+CONFIG_USB_F_UAC1=y
9821+CONFIG_USB_F_UVC=y
9822+CONFIG_USB_CONFIGFS=y
9823+# CONFIG_USB_CONFIGFS_SERIAL is not set
9824+CONFIG_USB_CONFIGFS_ACM=y
9825+# CONFIG_USB_CONFIGFS_OBEX is not set
9826+# CONFIG_USB_CONFIGFS_NCM is not set
9827+# CONFIG_USB_CONFIGFS_ECM is not set
9828+# CONFIG_USB_CONFIGFS_ECM_SUBSET is not set
9829+CONFIG_USB_CONFIGFS_RNDIS=y
9830+# CONFIG_USB_CONFIGFS_EEM is not set
9831+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
9832+# CONFIG_USB_CONFIGFS_F_LB_SS is not set
9833+# CONFIG_USB_CONFIGFS_F_FS is not set
9834+CONFIG_USB_CONFIGFS_F_UAC1=y
9835+# CONFIG_USB_CONFIGFS_F_UAC1_LEGACY is not set
9836+# CONFIG_USB_CONFIGFS_F_UAC2 is not set
9837+# CONFIG_USB_CONFIGFS_F_MIDI is not set
9838+# CONFIG_USB_CONFIGFS_F_HID is not set
9839+CONFIG_USB_CONFIGFS_F_UVC=y
9840+# CONFIG_USB_CONFIGFS_F_PRINTER is not set
9841+# CONFIG_TYPEC is not set
9842+# CONFIG_USB_ROLE_SWITCH is not set
9843+# CONFIG_USB_ULPI_BUS is not set
9844+# CONFIG_UWB is not set
9845+CONFIG_MMC=y
9846+CONFIG_PWRSEQ_EMMC=y
9847+CONFIG_PWRSEQ_SIMPLE=y
9848+CONFIG_MMC_BLOCK=y
9849+CONFIG_MMC_BLOCK_MINORS=8
9850+# CONFIG_SDIO_UART is not set
9851+# CONFIG_MMC_TEST is not set
9852+
9853+#
9854+# MMC/SD/SDIO Host Controller Drivers
9855+#
9856+# CONFIG_MMC_DEBUG is not set
9857+# CONFIG_MMC_ARMMMCI is not set
9858+# CONFIG_MMC_SDHCI is not set
9859+# CONFIG_MMC_SPI is not set
9860+# CONFIG_MMC_DW is not set
9861+# CONFIG_MMC_VUB300 is not set
9862+# CONFIG_MMC_USHC is not set
9863+# CONFIG_MMC_USDHI6ROL0 is not set
9864+# CONFIG_MMC_CQHCI is not set
9865+# CONFIG_MMC_MTK is not set
9866+# CONFIG_MMC_CQ_HCI is not set
9867+CONFIG_HIMCI=y
9868+CONFIG_SEND_AUTO_STOP=y
9869+# CONFIG_MEMSTICK is not set
9870+# CONFIG_NEW_LEDS is not set
9871+# CONFIG_ACCESSIBILITY is not set
9872+# CONFIG_INFINIBAND is not set
9873+CONFIG_EDAC_ATOMIC_SCRUB=y
9874+CONFIG_EDAC_SUPPORT=y
9875+CONFIG_RTC_LIB=y
9876+CONFIG_RTC_CLASS=y
9877+CONFIG_RTC_HCTOSYS=y
9878+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
9879+CONFIG_RTC_SYSTOHC=y
9880+CONFIG_RTC_SYSTOHC_DEVICE="rtc0"
9881+# CONFIG_RTC_DEBUG is not set
9882+CONFIG_RTC_NVMEM=y
9883+
9884+#
9885+# RTC interfaces
9886+#
9887+CONFIG_RTC_INTF_SYSFS=y
9888+CONFIG_RTC_INTF_PROC=y
9889+CONFIG_RTC_INTF_DEV=y
9890+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
9891+# CONFIG_RTC_DRV_TEST is not set
9892+
9893+#
9894+# I2C RTC drivers
9895+#
9896+# CONFIG_RTC_DRV_ABB5ZES3 is not set
9897+# CONFIG_RTC_DRV_ABX80X is not set
9898+# CONFIG_RTC_DRV_DS1307 is not set
9899+# CONFIG_RTC_DRV_DS1374 is not set
9900+# CONFIG_RTC_DRV_DS1672 is not set
9901+# CONFIG_RTC_DRV_HYM8563 is not set
9902+# CONFIG_RTC_DRV_MAX6900 is not set
9903+# CONFIG_RTC_DRV_RS5C372 is not set
9904+# CONFIG_RTC_DRV_ISL1208 is not set
9905+# CONFIG_RTC_DRV_ISL12022 is not set
9906+# CONFIG_RTC_DRV_ISL12026 is not set
9907+# CONFIG_RTC_DRV_X1205 is not set
9908+# CONFIG_RTC_DRV_PCF8523 is not set
9909+# CONFIG_RTC_DRV_PCF85063 is not set
9910+# CONFIG_RTC_DRV_PCF85363 is not set
9911+# CONFIG_RTC_DRV_PCF8563 is not set
9912+# CONFIG_RTC_DRV_PCF8583 is not set
9913+# CONFIG_RTC_DRV_M41T80 is not set
9914+# CONFIG_RTC_DRV_BQ32K is not set
9915+# CONFIG_RTC_DRV_S35390A is not set
9916+# CONFIG_RTC_DRV_FM3130 is not set
9917+# CONFIG_RTC_DRV_RX8010 is not set
9918+# CONFIG_RTC_DRV_RX8581 is not set
9919+# CONFIG_RTC_DRV_RX8025 is not set
9920+# CONFIG_RTC_DRV_EM3027 is not set
9921+# CONFIG_RTC_DRV_RV8803 is not set
9922+
9923+#
9924+# SPI RTC drivers
9925+#
9926+# CONFIG_RTC_DRV_M41T93 is not set
9927+# CONFIG_RTC_DRV_M41T94 is not set
9928+# CONFIG_RTC_DRV_DS1302 is not set
9929+# CONFIG_RTC_DRV_DS1305 is not set
9930+# CONFIG_RTC_DRV_DS1343 is not set
9931+# CONFIG_RTC_DRV_DS1347 is not set
9932+# CONFIG_RTC_DRV_DS1390 is not set
9933+# CONFIG_RTC_DRV_MAX6916 is not set
9934+# CONFIG_RTC_DRV_R9701 is not set
9935+# CONFIG_RTC_DRV_RX4581 is not set
9936+# CONFIG_RTC_DRV_RX6110 is not set
9937+# CONFIG_RTC_DRV_RS5C348 is not set
9938+# CONFIG_RTC_DRV_MAX6902 is not set
9939+# CONFIG_RTC_DRV_PCF2123 is not set
9940+# CONFIG_RTC_DRV_MCP795 is not set
9941+CONFIG_RTC_I2C_AND_SPI=y
9942+
9943+#
9944+# SPI and I2C RTC drivers
9945+#
9946+# CONFIG_RTC_DRV_DS3232 is not set
9947+# CONFIG_RTC_DRV_PCF2127 is not set
9948+# CONFIG_RTC_DRV_RV3029C2 is not set
9949+
9950+#
9951+# Platform RTC drivers
9952+#
9953+CONFIG_RTC_DRV_HIBVT=y
9954+# CONFIG_RTC_DRV_CMOS is not set
9955+# CONFIG_RTC_DRV_DS1286 is not set
9956+# CONFIG_RTC_DRV_DS1511 is not set
9957+# CONFIG_RTC_DRV_DS1553 is not set
9958+# CONFIG_RTC_DRV_DS1685_FAMILY is not set
9959+# CONFIG_RTC_DRV_DS1742 is not set
9960+# CONFIG_RTC_DRV_DS2404 is not set
9961+# CONFIG_RTC_DRV_STK17TA8 is not set
9962+# CONFIG_RTC_DRV_M48T86 is not set
9963+# CONFIG_RTC_DRV_M48T35 is not set
9964+# CONFIG_RTC_DRV_M48T59 is not set
9965+# CONFIG_RTC_DRV_MSM6242 is not set
9966+# CONFIG_RTC_DRV_BQ4802 is not set
9967+# CONFIG_RTC_DRV_RP5C01 is not set
9968+# CONFIG_RTC_DRV_V3020 is not set
9969+# CONFIG_RTC_DRV_ZYNQMP is not set
9970+
9971+#
9972+# on-CPU RTC drivers
9973+#
9974+# CONFIG_RTC_DRV_PL030 is not set
9975+# CONFIG_RTC_DRV_PL031 is not set
9976+# CONFIG_RTC_DRV_FTRTC010 is not set
9977+# CONFIG_RTC_DRV_SNVS is not set
9978+# CONFIG_RTC_DRV_R7301 is not set
9979+
9980+#
9981+# HID Sensor RTC drivers
9982+#
9983+# CONFIG_RTC_DRV_HID_SENSOR_TIME is not set
9984+# CONFIG_DMADEVICES is not set
9985+
9986+#
9987+# DMABUF options
9988+#
9989+# CONFIG_SYNC_FILE is not set
9990+# CONFIG_AUXDISPLAY is not set
9991+# CONFIG_UIO is not set
9992+# CONFIG_VIRT_DRIVERS is not set
9993+CONFIG_VIRTIO_MENU=y
9994+# CONFIG_VIRTIO_MMIO is not set
9995+
9996+#
9997+# Microsoft Hyper-V guest support
9998+#
9999+# CONFIG_STAGING is not set
10000+# CONFIG_GOLDFISH is not set
10001+# CONFIG_CHROME_PLATFORMS is not set
10002+# CONFIG_MELLANOX_PLATFORM is not set
10003+CONFIG_CLKDEV_LOOKUP=y
10004+CONFIG_HAVE_CLK_PREPARE=y
10005+CONFIG_COMMON_CLK=y
10006+
10007+#
10008+# Common Clock Framework
10009+#
10010+# CONFIG_CLK_HSDK is not set
10011+# CONFIG_COMMON_CLK_MAX9485 is not set
10012+# CONFIG_COMMON_CLK_SI5351 is not set
10013+# CONFIG_COMMON_CLK_SI514 is not set
10014+# CONFIG_COMMON_CLK_SI544 is not set
10015+# CONFIG_COMMON_CLK_SI570 is not set
10016+# CONFIG_COMMON_CLK_CDCE706 is not set
10017+# CONFIG_COMMON_CLK_CDCE925 is not set
10018+# CONFIG_COMMON_CLK_CS2000_CP is not set
10019+# CONFIG_CLK_QORIQ is not set
10020+# CONFIG_COMMON_CLK_VC5 is not set
10021+CONFIG_COMMON_CLK_HI3516DV300=y
10022+CONFIG_RESET_HISI=y
10023+# CONFIG_HWSPINLOCK is not set
10024+
10025+#
10026+# Clock Source drivers
10027+#
10028+CONFIG_TIMER_OF=y
10029+CONFIG_TIMER_PROBE=y
10030+CONFIG_CLKSRC_MMIO=y
10031+CONFIG_ARM_ARCH_TIMER=y
10032+CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y
10033+# CONFIG_ARM_ARCH_TIMER_VCT_ACCESS is not set
10034+CONFIG_ARM_TIMER_SP804=y
10035+# CONFIG_TIMER_HISP804 is not set
10036+# CONFIG_MAILBOX is not set
10037+# CONFIG_IOMMU_SUPPORT is not set
10038+
10039+#
10040+# Remoteproc drivers
10041+#
10042+# CONFIG_REMOTEPROC is not set
10043+
10044+#
10045+# Rpmsg drivers
10046+#
10047+# CONFIG_RPMSG_VIRTIO is not set
10048+
10049+#
10050+# SOC (System On Chip) specific Drivers
10051+#
10052+
10053+#
10054+# Amlogic SoC drivers
10055+#
10056+
10057+#
10058+# Broadcom SoC drivers
10059+#
10060+# CONFIG_SOC_BRCMSTB is not set
10061+
10062+#
10063+# NXP/Freescale QorIQ SoC drivers
10064+#
10065+
10066+#
10067+# i.MX SoC drivers
10068+#
10069+
10070+#
10071+# Qualcomm SoC drivers
10072+#
10073+# CONFIG_SOC_TI is not set
10074+
10075+#
10076+# Xilinx SoC drivers
10077+#
10078+# CONFIG_XILINX_VCU is not set
10079+# CONFIG_PM_DEVFREQ is not set
10080+# CONFIG_EXTCON is not set
10081+# CONFIG_MEMORY is not set
10082+# CONFIG_IIO is not set
10083+# CONFIG_PWM is not set
10084+
10085+#
10086+# IRQ chip support
10087+#
10088+CONFIG_IRQCHIP=y
10089+CONFIG_ARM_GIC=y
10090+CONFIG_ARM_GIC_MAX_NR=1
10091+# CONFIG_IPACK_BUS is not set
10092+CONFIG_RESET_CONTROLLER=y
10093+# CONFIG_RESET_TI_SYSCON is not set
10094+# CONFIG_FMC is not set
10095+
10096+#
10097+# PHY Subsystem
10098+#
10099+CONFIG_GENERIC_PHY=y
10100+# CONFIG_BCM_KONA_USB2_PHY is not set
10101+# CONFIG_PHY_PXA_28NM_HSIC is not set
10102+# CONFIG_PHY_PXA_28NM_USB2 is not set
10103+# CONFIG_PHY_MAPPHONE_MDM6600 is not set
10104+CONFIG_HI_USB_PHY=y
10105+CONFIG_PHY_HISI_USB2=y
10106+CONFIG_HIBVT_USB_PHY=y
10107+CONFIG_USB_MODE_OPTION=y
10108+CONFIG_USB_DRD0_IN_HOST=y
10109+# CONFIG_POWERCAP is not set
10110+# CONFIG_MCB is not set
10111+# CONFIG_RAS is not set
10112+# CONFIG_DAX is not set
10113+CONFIG_NVMEM=y
10114+
10115+#
10116+# HW tracing support
10117+#
10118+# CONFIG_STM is not set
10119+# CONFIG_INTEL_TH is not set
10120+# CONFIG_FPGA is not set
10121+# CONFIG_FSI is not set
10122+# CONFIG_TEE is not set
10123+# CONFIG_SIOX is not set
10124+# CONFIG_SLIMBUS is not set
10125+# CONFIG_HI_DMAC is not set
10126+# CONFIG_HIEDMAC is not set
10127+
10128+#
10129+# Hisilicon driver support
10130+#
10131+# CONFIG_CMA_MEM_SHARED is not set
10132+# CONFIG_CMA_ADVANCE_SHARE is not set
10133+
10134+#
10135+# File systems
10136+#
10137+CONFIG_DCACHE_WORD_ACCESS=y
10138+CONFIG_FS_IOMAP=y
10139+# CONFIG_EXT2_FS is not set
10140+# CONFIG_EXT3_FS is not set
10141+CONFIG_EXT4_FS=y
10142+CONFIG_EXT4_USE_FOR_EXT2=y
10143+# CONFIG_EXT4_FS_POSIX_ACL is not set
10144+# CONFIG_EXT4_FS_SECURITY is not set
10145+# CONFIG_EXT4_ENCRYPTION is not set
10146+# CONFIG_EXT4_DEBUG is not set
10147+CONFIG_JBD2=y
10148+# CONFIG_JBD2_DEBUG is not set
10149+CONFIG_FS_MBCACHE=y
10150+CONFIG_REISERFS_FS=m
10151+CONFIG_REISERFS_CHECK=y
10152+CONFIG_REISERFS_PROC_INFO=y
10153+CONFIG_REISERFS_FS_XATTR=y
10154+CONFIG_REISERFS_FS_POSIX_ACL=y
10155+CONFIG_REISERFS_FS_SECURITY=y
10156+CONFIG_JFS_FS=m
10157+CONFIG_JFS_POSIX_ACL=y
10158+CONFIG_JFS_SECURITY=y
10159+CONFIG_JFS_DEBUG=y
10160+CONFIG_JFS_STATISTICS=y
10161+CONFIG_XFS_FS=m
10162+CONFIG_XFS_QUOTA=y
10163+CONFIG_XFS_POSIX_ACL=y
10164+CONFIG_XFS_RT=y
10165+# CONFIG_XFS_ONLINE_SCRUB is not set
10166+# CONFIG_XFS_WARN is not set
10167+# CONFIG_XFS_DEBUG is not set
10168+# CONFIG_GFS2_FS is not set
10169+# CONFIG_OCFS2_FS is not set
10170+# CONFIG_BTRFS_FS is not set
10171+# CONFIG_NILFS2_FS is not set
10172+# CONFIG_F2FS_FS is not set
10173+CONFIG_FS_POSIX_ACL=y
10174+CONFIG_EXPORTFS=y
10175+# CONFIG_EXPORTFS_BLOCK_OPS is not set
10176+CONFIG_FILE_LOCKING=y
10177+CONFIG_MANDATORY_FILE_LOCKING=y
10178+# CONFIG_FS_ENCRYPTION is not set
10179+CONFIG_FSNOTIFY=y
10180+CONFIG_DNOTIFY=y
10181+CONFIG_INOTIFY_USER=y
10182+# CONFIG_FANOTIFY is not set
10183+# CONFIG_QUOTA is not set
10184+# CONFIG_QUOTA_NETLINK_INTERFACE is not set
10185+CONFIG_QUOTACTL=y
10186+# CONFIG_AUTOFS4_FS is not set
10187+# CONFIG_AUTOFS_FS is not set
10188+# CONFIG_FUSE_FS is not set
10189+# CONFIG_OVERLAY_FS is not set
10190+
10191+#
10192+# Caches
10193+#
10194+# CONFIG_FSCACHE is not set
10195+
10196+#
10197+# CD-ROM/DVD Filesystems
10198+#
10199+# CONFIG_ISO9660_FS is not set
10200+# CONFIG_UDF_FS is not set
10201+
10202+#
10203+# DOS/FAT/NT Filesystems
10204+#
10205+CONFIG_FAT_FS=y
10206+CONFIG_MSDOS_FS=y
10207+CONFIG_VFAT_FS=y
10208+CONFIG_FAT_DEFAULT_CODEPAGE=437
10209+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
10210+# CONFIG_FAT_DEFAULT_UTF8 is not set
10211+# CONFIG_NTFS_FS is not set
10212+
10213+#
10214+# Pseudo filesystems
10215+#
10216+CONFIG_PROC_FS=y
10217+CONFIG_PROC_SYSCTL=y
10218+CONFIG_PROC_PAGE_MONITOR=y
10219+# CONFIG_PROC_CHILDREN is not set
10220+CONFIG_KERNFS=y
10221+CONFIG_SYSFS=y
10222+CONFIG_TMPFS=y
10223+# CONFIG_TMPFS_POSIX_ACL is not set
10224+# CONFIG_TMPFS_XATTR is not set
10225+CONFIG_MEMFD_CREATE=y
10226+CONFIG_CONFIGFS_FS=y
10227+CONFIG_MISC_FILESYSTEMS=y
10228+# CONFIG_ORANGEFS_FS is not set
10229+# CONFIG_ADFS_FS is not set
10230+# CONFIG_AFFS_FS is not set
10231+# CONFIG_ECRYPT_FS is not set
10232+# CONFIG_HFS_FS is not set
10233+# CONFIG_HFSPLUS_FS is not set
10234+# CONFIG_BEFS_FS is not set
10235+# CONFIG_BFS_FS is not set
10236+# CONFIG_EFS_FS is not set
10237+CONFIG_JFFS2_FS=y
10238+CONFIG_JFFS2_FS_DEBUG=0
10239+CONFIG_JFFS2_FS_WRITEBUFFER=y
10240+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
10241+# CONFIG_JFFS2_SUMMARY is not set
10242+# CONFIG_JFFS2_FS_XATTR is not set
10243+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
10244+CONFIG_JFFS2_ZLIB=y
10245+CONFIG_JFFS2_RTIME=y
10246+CONFIG_UBIFS_FS=y
10247+# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set
10248+CONFIG_UBIFS_FS_LZO=y
10249+CONFIG_UBIFS_FS_ZLIB=y
10250+# CONFIG_UBIFS_ATIME_SUPPORT is not set
10251+CONFIG_UBIFS_FS_XATTR=y
10252+# CONFIG_UBIFS_FS_ENCRYPTION is not set
10253+CONFIG_UBIFS_FS_SECURITY=y
10254+CONFIG_CRAMFS=y
10255+CONFIG_CRAMFS_BLOCKDEV=y
10256+# CONFIG_CRAMFS_MTD is not set
10257+# CONFIG_SQUASHFS is not set
10258+# CONFIG_VXFS_FS is not set
10259+# CONFIG_MINIX_FS is not set
10260+# CONFIG_OMFS_FS is not set
10261+# CONFIG_HPFS_FS is not set
10262+# CONFIG_QNX4FS_FS is not set
10263+# CONFIG_QNX6FS_FS is not set
10264+# CONFIG_ROMFS_FS is not set
10265+# CONFIG_PSTORE is not set
10266+# CONFIG_SYSV_FS is not set
10267+# CONFIG_UFS_FS is not set
10268+CONFIG_NETWORK_FILESYSTEMS=y
10269+CONFIG_NFS_FS=y
10270+CONFIG_NFS_V2=y
10271+CONFIG_NFS_V3=y
10272+CONFIG_NFS_V3_ACL=y
10273+CONFIG_NFS_V4=y
10274+# CONFIG_NFS_SWAP is not set
10275+# CONFIG_NFS_V4_1 is not set
10276+# CONFIG_ROOT_NFS is not set
10277+# CONFIG_NFS_USE_LEGACY_DNS is not set
10278+CONFIG_NFS_USE_KERNEL_DNS=y
10279+# CONFIG_NFSD is not set
10280+CONFIG_GRACE_PERIOD=y
10281+CONFIG_LOCKD=y
10282+CONFIG_LOCKD_V4=y
10283+CONFIG_NFS_ACL_SUPPORT=y
10284+CONFIG_NFS_COMMON=y
10285+CONFIG_SUNRPC=y
10286+CONFIG_SUNRPC_GSS=y
10287+# CONFIG_SUNRPC_DEBUG is not set
10288+# CONFIG_CEPH_FS is not set
10289+# CONFIG_CIFS is not set
10290+# CONFIG_CODA_FS is not set
10291+# CONFIG_AFS_FS is not set
10292+CONFIG_NLS=y
10293+CONFIG_NLS_DEFAULT="iso8859-1"
10294+CONFIG_NLS_CODEPAGE_437=y
10295+CONFIG_NLS_CODEPAGE_737=m
10296+CONFIG_NLS_CODEPAGE_775=m
10297+CONFIG_NLS_CODEPAGE_850=m
10298+CONFIG_NLS_CODEPAGE_852=m
10299+CONFIG_NLS_CODEPAGE_855=m
10300+CONFIG_NLS_CODEPAGE_857=m
10301+CONFIG_NLS_CODEPAGE_860=m
10302+CONFIG_NLS_CODEPAGE_861=m
10303+CONFIG_NLS_CODEPAGE_862=m
10304+CONFIG_NLS_CODEPAGE_863=m
10305+CONFIG_NLS_CODEPAGE_864=m
10306+CONFIG_NLS_CODEPAGE_865=m
10307+CONFIG_NLS_CODEPAGE_866=m
10308+CONFIG_NLS_CODEPAGE_869=m
10309+CONFIG_NLS_CODEPAGE_936=y
10310+CONFIG_NLS_CODEPAGE_950=m
10311+CONFIG_NLS_CODEPAGE_932=m
10312+CONFIG_NLS_CODEPAGE_949=m
10313+CONFIG_NLS_CODEPAGE_874=m
10314+CONFIG_NLS_ISO8859_8=m
10315+CONFIG_NLS_CODEPAGE_1250=m
10316+CONFIG_NLS_CODEPAGE_1251=m
10317+CONFIG_NLS_ASCII=y
10318+CONFIG_NLS_ISO8859_1=y
10319+CONFIG_NLS_ISO8859_2=m
10320+CONFIG_NLS_ISO8859_3=m
10321+CONFIG_NLS_ISO8859_4=m
10322+CONFIG_NLS_ISO8859_5=m
10323+CONFIG_NLS_ISO8859_6=m
10324+CONFIG_NLS_ISO8859_7=m
10325+CONFIG_NLS_ISO8859_9=m
10326+CONFIG_NLS_ISO8859_13=m
10327+CONFIG_NLS_ISO8859_14=m
10328+CONFIG_NLS_ISO8859_15=m
10329+CONFIG_NLS_KOI8_R=m
10330+CONFIG_NLS_KOI8_U=m
10331+# CONFIG_NLS_MAC_ROMAN is not set
10332+# CONFIG_NLS_MAC_CELTIC is not set
10333+# CONFIG_NLS_MAC_CENTEURO is not set
10334+# CONFIG_NLS_MAC_CROATIAN is not set
10335+# CONFIG_NLS_MAC_CYRILLIC is not set
10336+# CONFIG_NLS_MAC_GAELIC is not set
10337+# CONFIG_NLS_MAC_GREEK is not set
10338+# CONFIG_NLS_MAC_ICELAND is not set
10339+# CONFIG_NLS_MAC_INUIT is not set
10340+# CONFIG_NLS_MAC_ROMANIAN is not set
10341+# CONFIG_NLS_MAC_TURKISH is not set
10342+CONFIG_NLS_UTF8=y
10343+# CONFIG_DLM is not set
10344+
10345+#
10346+# Security options
10347+#
10348+CONFIG_KEYS=y
10349+# CONFIG_PERSISTENT_KEYRINGS is not set
10350+# CONFIG_BIG_KEYS is not set
10351+# CONFIG_ENCRYPTED_KEYS is not set
10352+# CONFIG_KEY_DH_OPERATIONS is not set
10353+# CONFIG_SECURITY_DMESG_RESTRICT is not set
10354+# CONFIG_SECURITY is not set
10355+# CONFIG_SECURITYFS is not set
10356+CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y
10357+# CONFIG_HARDENED_USERCOPY is not set
10358+# CONFIG_FORTIFY_SOURCE is not set
10359+# CONFIG_STATIC_USERMODEHELPER is not set
10360+CONFIG_DEFAULT_SECURITY_DAC=y
10361+CONFIG_DEFAULT_SECURITY=""
10362+CONFIG_CRYPTO=y
10363+
10364+#
10365+# Crypto core or helper
10366+#
10367+CONFIG_CRYPTO_ALGAPI=y
10368+CONFIG_CRYPTO_ALGAPI2=y
10369+CONFIG_CRYPTO_AEAD=m
10370+CONFIG_CRYPTO_AEAD2=y
10371+CONFIG_CRYPTO_BLKCIPHER2=y
10372+CONFIG_CRYPTO_HASH=y
10373+CONFIG_CRYPTO_HASH2=y
10374+CONFIG_CRYPTO_RNG=y
10375+CONFIG_CRYPTO_RNG2=y
10376+CONFIG_CRYPTO_RNG_DEFAULT=m
10377+CONFIG_CRYPTO_AKCIPHER2=y
10378+CONFIG_CRYPTO_KPP2=y
10379+CONFIG_CRYPTO_ACOMP2=y
10380+# CONFIG_CRYPTO_RSA is not set
10381+# CONFIG_CRYPTO_DH is not set
10382+# CONFIG_CRYPTO_ECDH is not set
10383+CONFIG_CRYPTO_MANAGER=m
10384+CONFIG_CRYPTO_MANAGER2=y
10385+# CONFIG_CRYPTO_USER is not set
10386+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
10387+# CONFIG_CRYPTO_GF128MUL is not set
10388+CONFIG_CRYPTO_NULL=m
10389+CONFIG_CRYPTO_NULL2=y
10390+# CONFIG_CRYPTO_PCRYPT is not set
10391+CONFIG_CRYPTO_WORKQUEUE=y
10392+# CONFIG_CRYPTO_CRYPTD is not set
10393+# CONFIG_CRYPTO_MCRYPTD is not set
10394+# CONFIG_CRYPTO_AUTHENC is not set
10395+# CONFIG_CRYPTO_TEST is not set
10396+
10397+#
10398+# Authenticated Encryption with Associated Data
10399+#
10400+# CONFIG_CRYPTO_CCM is not set
10401+# CONFIG_CRYPTO_GCM is not set
10402+# CONFIG_CRYPTO_CHACHA20POLY1305 is not set
10403+# CONFIG_CRYPTO_AEGIS128 is not set
10404+# CONFIG_CRYPTO_AEGIS128L is not set
10405+# CONFIG_CRYPTO_AEGIS256 is not set
10406+# CONFIG_CRYPTO_MORUS640 is not set
10407+# CONFIG_CRYPTO_MORUS1280 is not set
10408+# CONFIG_CRYPTO_SEQIV is not set
10409+CONFIG_CRYPTO_ECHAINIV=m
10410+
10411+#
10412+# Block modes
10413+#
10414+# CONFIG_CRYPTO_CBC is not set
10415+# CONFIG_CRYPTO_CFB is not set
10416+# CONFIG_CRYPTO_CTR is not set
10417+# CONFIG_CRYPTO_CTS is not set
10418+# CONFIG_CRYPTO_ECB is not set
10419+# CONFIG_CRYPTO_LRW is not set
10420+# CONFIG_CRYPTO_PCBC is not set
10421+# CONFIG_CRYPTO_XTS is not set
10422+# CONFIG_CRYPTO_KEYWRAP is not set
10423+
10424+#
10425+# Hash modes
10426+#
10427+# CONFIG_CRYPTO_CMAC is not set
10428+CONFIG_CRYPTO_HMAC=m
10429+# CONFIG_CRYPTO_XCBC is not set
10430+# CONFIG_CRYPTO_VMAC is not set
10431+
10432+#
10433+# Digest
10434+#
10435+CONFIG_CRYPTO_CRC32C=y
10436+# CONFIG_CRYPTO_CRC32 is not set
10437+# CONFIG_CRYPTO_CRCT10DIF is not set
10438+# CONFIG_CRYPTO_GHASH is not set
10439+# CONFIG_CRYPTO_POLY1305 is not set
10440+# CONFIG_CRYPTO_MD4 is not set
10441+# CONFIG_CRYPTO_MD5 is not set
10442+# CONFIG_CRYPTO_MICHAEL_MIC is not set
10443+# CONFIG_CRYPTO_RMD128 is not set
10444+# CONFIG_CRYPTO_RMD160 is not set
10445+# CONFIG_CRYPTO_RMD256 is not set
10446+# CONFIG_CRYPTO_RMD320 is not set
10447+# CONFIG_CRYPTO_SHA1 is not set
10448+CONFIG_CRYPTO_SHA256=m
10449+# CONFIG_CRYPTO_SHA512 is not set
10450+# CONFIG_CRYPTO_SHA3 is not set
10451+# CONFIG_CRYPTO_SM3 is not set
10452+# CONFIG_CRYPTO_TGR192 is not set
10453+# CONFIG_CRYPTO_WP512 is not set
10454+
10455+#
10456+# Ciphers
10457+#
10458+CONFIG_CRYPTO_AES=y
10459+# CONFIG_CRYPTO_AES_TI is not set
10460+# CONFIG_CRYPTO_ANUBIS is not set
10461+# CONFIG_CRYPTO_ARC4 is not set
10462+# CONFIG_CRYPTO_BLOWFISH is not set
10463+# CONFIG_CRYPTO_CAMELLIA is not set
10464+# CONFIG_CRYPTO_CAST5 is not set
10465+# CONFIG_CRYPTO_CAST6 is not set
10466+# CONFIG_CRYPTO_DES is not set
10467+# CONFIG_CRYPTO_FCRYPT is not set
10468+# CONFIG_CRYPTO_KHAZAD is not set
10469+# CONFIG_CRYPTO_SALSA20 is not set
10470+# CONFIG_CRYPTO_CHACHA20 is not set
10471+# CONFIG_CRYPTO_SEED is not set
10472+# CONFIG_CRYPTO_SERPENT is not set
10473+# CONFIG_CRYPTO_SM4 is not set
10474+# CONFIG_CRYPTO_TEA is not set
10475+# CONFIG_CRYPTO_TWOFISH is not set
10476+
10477+#
10478+# Compression
10479+#
10480+CONFIG_CRYPTO_DEFLATE=y
10481+CONFIG_CRYPTO_LZO=y
10482+# CONFIG_CRYPTO_842 is not set
10483+# CONFIG_CRYPTO_LZ4 is not set
10484+# CONFIG_CRYPTO_LZ4HC is not set
10485+# CONFIG_CRYPTO_ZSTD is not set
10486+
10487+#
10488+# Random Number Generation
10489+#
10490+CONFIG_CRYPTO_ANSI_CPRNG=y
10491+CONFIG_CRYPTO_DRBG_MENU=m
10492+CONFIG_CRYPTO_DRBG_HMAC=y
10493+# CONFIG_CRYPTO_DRBG_HASH is not set
10494+CONFIG_CRYPTO_DRBG=m
10495+CONFIG_CRYPTO_JITTERENTROPY=m
10496+# CONFIG_CRYPTO_USER_API_HASH is not set
10497+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
10498+# CONFIG_CRYPTO_USER_API_RNG is not set
10499+# CONFIG_CRYPTO_USER_API_AEAD is not set
10500+CONFIG_CRYPTO_HW=y
10501+# CONFIG_CRYPTO_DEV_CCREE is not set
10502+# CONFIG_ASYMMETRIC_KEY_TYPE is not set
10503+
10504+#
10505+# Certificates for signature checking
10506+#
10507+# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set
10508+
10509+#
10510+# Library routines
10511+#
10512+CONFIG_BITREVERSE=y
10513+CONFIG_HAVE_ARCH_BITREVERSE=y
10514+CONFIG_RATIONAL=y
10515+CONFIG_GENERIC_STRNCPY_FROM_USER=y
10516+CONFIG_GENERIC_STRNLEN_USER=y
10517+CONFIG_GENERIC_NET_UTILS=y
10518+CONFIG_GENERIC_PCI_IOMAP=y
10519+CONFIG_ARCH_USE_CMPXCHG_LOCKREF=y
10520+# CONFIG_CRC_CCITT is not set
10521+CONFIG_CRC16=y
10522+# CONFIG_CRC_T10DIF is not set
10523+# CONFIG_CRC_ITU_T is not set
10524+CONFIG_CRC32=y
10525+# CONFIG_CRC32_SELFTEST is not set
10526+CONFIG_CRC32_SLICEBY8=y
10527+# CONFIG_CRC32_SLICEBY4 is not set
10528+# CONFIG_CRC32_SARWATE is not set
10529+# CONFIG_CRC32_BIT is not set
10530+# CONFIG_CRC64 is not set
10531+# CONFIG_CRC4 is not set
10532+# CONFIG_CRC7 is not set
10533+CONFIG_LIBCRC32C=m
10534+# CONFIG_CRC8 is not set
10535+# CONFIG_RANDOM32_SELFTEST is not set
10536+CONFIG_ZLIB_INFLATE=y
10537+CONFIG_ZLIB_DEFLATE=y
10538+CONFIG_LZO_COMPRESS=y
10539+CONFIG_LZO_DECOMPRESS=y
10540+CONFIG_XZ_DEC=y
10541+CONFIG_XZ_DEC_X86=y
10542+CONFIG_XZ_DEC_POWERPC=y
10543+CONFIG_XZ_DEC_IA64=y
10544+CONFIG_XZ_DEC_ARM=y
10545+CONFIG_XZ_DEC_ARMTHUMB=y
10546+CONFIG_XZ_DEC_SPARC=y
10547+CONFIG_XZ_DEC_BCJ=y
10548+# CONFIG_XZ_DEC_TEST is not set
10549+CONFIG_GENERIC_ALLOCATOR=y
10550+CONFIG_ASSOCIATIVE_ARRAY=y
10551+CONFIG_HAS_IOMEM=y
10552+CONFIG_HAS_IOPORT_MAP=y
10553+CONFIG_HAS_DMA=y
10554+CONFIG_NEED_DMA_MAP_STATE=y
10555+CONFIG_HAVE_GENERIC_DMA_COHERENT=y
10556+CONFIG_SGL_ALLOC=y
10557+CONFIG_CPU_RMAP=y
10558+CONFIG_DQL=y
10559+CONFIG_NLATTR=y
10560+# CONFIG_CORDIC is not set
10561+# CONFIG_DDR is not set
10562+# CONFIG_IRQ_POLL is not set
10563+CONFIG_LIBFDT=y
10564+CONFIG_OID_REGISTRY=y
10565+CONFIG_SG_POOL=y
10566+CONFIG_ARCH_HAS_SG_CHAIN=y
10567+CONFIG_SBITMAP=y
10568+# CONFIG_STRING_SELFTEST is not set
10569+
10570+#
10571+# Kernel hacking
10572+#
10573+
10574+#
10575+# printk and dmesg options
10576+#
10577+# CONFIG_PRINTK_TIME is not set
10578+CONFIG_CONSOLE_LOGLEVEL_DEFAULT=7
10579+CONFIG_CONSOLE_LOGLEVEL_QUIET=4
10580+CONFIG_MESSAGE_LOGLEVEL_DEFAULT=4
10581+# CONFIG_BOOT_PRINTK_DELAY is not set
10582+# CONFIG_DYNAMIC_DEBUG is not set
10583+
10584+#
10585+# Compile-time checks and compiler options
10586+#
10587+# CONFIG_DEBUG_INFO is not set
10588+CONFIG_ENABLE_MUST_CHECK=y
10589+CONFIG_FRAME_WARN=1024
10590+# CONFIG_STRIP_ASM_SYMS is not set
10591+# CONFIG_READABLE_ASM is not set
10592+# CONFIG_UNUSED_SYMBOLS is not set
10593+# CONFIG_PAGE_OWNER is not set
10594+# CONFIG_DEBUG_FS is not set
10595+# CONFIG_HEADERS_CHECK is not set
10596+# CONFIG_DEBUG_SECTION_MISMATCH is not set
10597+CONFIG_SECTION_MISMATCH_WARN_ONLY=y
10598+# CONFIG_DEBUG_FORCE_WEAK_PER_CPU is not set
10599+# CONFIG_MAGIC_SYSRQ is not set
10600+CONFIG_DEBUG_KERNEL=y
10601+
10602+#
10603+# Memory Debugging
10604+#
10605+# CONFIG_PAGE_EXTENSION is not set
10606+# CONFIG_DEBUG_PAGEALLOC is not set
10607+# CONFIG_PAGE_POISONING is not set
10608+# CONFIG_DEBUG_RODATA_TEST is not set
10609+# CONFIG_DEBUG_OBJECTS is not set
10610+# CONFIG_SLUB_DEBUG_ON is not set
10611+# CONFIG_SLUB_STATS is not set
10612+CONFIG_HAVE_DEBUG_KMEMLEAK=y
10613+# CONFIG_DEBUG_KMEMLEAK is not set
10614+# CONFIG_DEBUG_STACK_USAGE is not set
10615+# CONFIG_DEBUG_VM is not set
10616+CONFIG_ARCH_HAS_DEBUG_VIRTUAL=y
10617+# CONFIG_DEBUG_VIRTUAL is not set
10618+CONFIG_DEBUG_MEMORY_INIT=y
10619+# CONFIG_DEBUG_PER_CPU_MAPS is not set
10620+# CONFIG_DEBUG_HIGHMEM is not set
10621+CONFIG_ARCH_HAS_KCOV=y
10622+CONFIG_CC_HAS_SANCOV_TRACE_PC=y
10623+# CONFIG_KCOV is not set
10624+# CONFIG_DEBUG_SHIRQ is not set
10625+
10626+#
10627+# Debug Lockups and Hangs
10628+#
10629+# CONFIG_SOFTLOCKUP_DETECTOR is not set
10630+# CONFIG_DETECT_HUNG_TASK is not set
10631+# CONFIG_WQ_WATCHDOG is not set
10632+# CONFIG_PANIC_ON_OOPS is not set
10633+CONFIG_PANIC_ON_OOPS_VALUE=0
10634+CONFIG_PANIC_TIMEOUT=0
10635+CONFIG_SCHED_DEBUG=y
10636+# CONFIG_SCHEDSTATS is not set
10637+# CONFIG_SCHED_STACK_END_CHECK is not set
10638+# CONFIG_DEBUG_TIMEKEEPING is not set
10639+
10640+#
10641+# Lock Debugging (spinlocks, mutexes, etc...)
10642+#
10643+CONFIG_LOCK_DEBUGGING_SUPPORT=y
10644+# CONFIG_PROVE_LOCKING is not set
10645+# CONFIG_LOCK_STAT is not set
10646+# CONFIG_DEBUG_RT_MUTEXES is not set
10647+# CONFIG_DEBUG_SPINLOCK is not set
10648+# CONFIG_DEBUG_MUTEXES is not set
10649+# CONFIG_DEBUG_WW_MUTEX_SLOWPATH is not set
10650+# CONFIG_DEBUG_RWSEMS is not set
10651+# CONFIG_DEBUG_LOCK_ALLOC is not set
10652+# CONFIG_DEBUG_ATOMIC_SLEEP is not set
10653+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
10654+# CONFIG_LOCK_TORTURE_TEST is not set
10655+# CONFIG_WW_MUTEX_SELFTEST is not set
10656+CONFIG_STACKTRACE=y
10657+# CONFIG_WARN_ALL_UNSEEDED_RANDOM is not set
10658+# CONFIG_DEBUG_KOBJECT is not set
10659+CONFIG_DEBUG_BUGVERBOSE=y
10660+# CONFIG_DEBUG_LIST is not set
10661+# CONFIG_DEBUG_PI_LIST is not set
10662+# CONFIG_DEBUG_SG is not set
10663+# CONFIG_DEBUG_NOTIFIERS is not set
10664+# CONFIG_DEBUG_CREDENTIALS is not set
10665+
10666+#
10667+# RCU Debugging
10668+#
10669+# CONFIG_RCU_PERF_TEST is not set
10670+# CONFIG_RCU_TORTURE_TEST is not set
10671+CONFIG_RCU_CPU_STALL_TIMEOUT=60
10672+# CONFIG_RCU_TRACE is not set
10673+# CONFIG_RCU_EQS_DEBUG is not set
10674+# CONFIG_DEBUG_WQ_FORCE_RR_CPU is not set
10675+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
10676+# CONFIG_CPU_HOTPLUG_STATE_CONTROL is not set
10677+# CONFIG_NOTIFIER_ERROR_INJECTION is not set
10678+# CONFIG_FAULT_INJECTION is not set
10679+# CONFIG_LATENCYTOP is not set
10680+CONFIG_HAVE_FUNCTION_TRACER=y
10681+CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
10682+CONFIG_HAVE_DYNAMIC_FTRACE=y
10683+CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y
10684+CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
10685+CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
10686+CONFIG_HAVE_C_RECORDMCOUNT=y
10687+CONFIG_TRACING_SUPPORT=y
10688+# CONFIG_FTRACE is not set
10689+# CONFIG_DMA_API_DEBUG is not set
10690+CONFIG_RUNTIME_TESTING_MENU=y
10691+# CONFIG_LKDTM is not set
10692+# CONFIG_TEST_LIST_SORT is not set
10693+# CONFIG_TEST_SORT is not set
10694+# CONFIG_BACKTRACE_SELF_TEST is not set
10695+# CONFIG_RBTREE_TEST is not set
10696+# CONFIG_INTERVAL_TREE_TEST is not set
10697+# CONFIG_PERCPU_TEST is not set
10698+# CONFIG_ATOMIC64_SELFTEST is not set
10699+# CONFIG_TEST_HEXDUMP is not set
10700+# CONFIG_TEST_STRING_HELPERS is not set
10701+# CONFIG_TEST_KSTRTOX is not set
10702+# CONFIG_TEST_PRINTF is not set
10703+# CONFIG_TEST_BITMAP is not set
10704+# CONFIG_TEST_BITFIELD is not set
10705+# CONFIG_TEST_UUID is not set
10706+# CONFIG_TEST_OVERFLOW is not set
10707+# CONFIG_TEST_RHASHTABLE is not set
10708+# CONFIG_TEST_HASH is not set
10709+# CONFIG_TEST_IDA is not set
10710+# CONFIG_TEST_LKM is not set
10711+# CONFIG_TEST_USER_COPY is not set
10712+# CONFIG_TEST_BPF is not set
10713+# CONFIG_FIND_BIT_BENCHMARK is not set
10714+# CONFIG_TEST_FIRMWARE is not set
10715+# CONFIG_TEST_SYSCTL is not set
10716+# CONFIG_TEST_UDELAY is not set
10717+# CONFIG_TEST_STATIC_KEYS is not set
10718+# CONFIG_TEST_KMOD is not set
10719+# CONFIG_MEMTEST is not set
10720+# CONFIG_BUG_ON_DATA_CORRUPTION is not set
10721+# CONFIG_SAMPLES is not set
10722+CONFIG_HAVE_ARCH_KGDB=y
10723+# CONFIG_KGDB is not set
10724+# CONFIG_UBSAN is not set
10725+CONFIG_ARCH_HAS_DEVMEM_IS_ALLOWED=y
10726+CONFIG_STRICT_DEVMEM=y
10727+# CONFIG_IO_STRICT_DEVMEM is not set
10728+# CONFIG_ARM_PTDUMP_DEBUGFS is not set
10729+# CONFIG_DEBUG_WX is not set
10730+CONFIG_ARM_UNWIND=y
10731+# CONFIG_DEBUG_USER is not set
10732+# CONFIG_DEBUG_LL is not set
10733+CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S"
10734+CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h"
10735+# CONFIG_PID_IN_CONTEXTIDR is not set
10736+# CONFIG_CORESIGHT is not set
10737diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
10738index ea9bd0889..dbe96664b 100644
10739--- a/arch/arm/include/asm/mach/pci.h
10740+++ b/arch/arm/include/asm/mach/pci.h
10741@@ -9,6 +9,7 @@
10742 #define __ASM_MACH_PCI_H
10743
10744 #include <linux/ioport.h>
10745+#include <linux/msi.h>
10746
10747 struct pci_sys_data;
10748 struct pci_ops;
10749@@ -16,7 +17,25 @@ struct pci_bus;
10750 struct pci_host_bridge;
10751 struct device;
10752
10753+#ifdef CONFIG_PCI_MSI
10754+#define HISI_PCI_MSI_NR (8 * 32)
10755+struct hisi_msi {
10756+	struct msi_controller chip;
10757+	DECLARE_BITMAP(used, HISI_PCI_MSI_NR);
10758+	struct irq_domain *domain;
10759+	unsigned long pages;
10760+	struct mutex lock;
10761+	int irq;
10762+};
10763+#endif
10764 struct hw_pci {
10765+#ifdef CONFIG_PCI_DOMAINS
10766+	int     domain;
10767+#endif
10768+#ifdef CONFIG_PCI_MSI
10769+	struct hisi_msi msi;
10770+#endif
10771+	struct device *dev;
10772 	struct pci_ops	*ops;
10773 	int		nr_controllers;
10774 	void		**private_data;
10775@@ -26,12 +45,17 @@ struct hw_pci {
10776 	void		(*postinit)(void);
10777 	u8		(*swizzle)(struct pci_dev *dev, u8 *pin);
10778 	int		(*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
10779+	void		(*add_bus)(struct pci_bus *bus);
10780+	void		(*remove_bus)(struct pci_bus *bus);
10781 };
10782
10783 /*
10784  * Per-controller structure
10785  */
10786 struct pci_sys_data {
10787+#ifdef CONFIG_PCI_DOMAINS
10788+	int     domain;
10789+#endif
10790 	struct list_head node;
10791 	int		busnr;		/* primary bus number			*/
10792 	u64		mem_offset;	/* bus->cpu memory mapping offset	*/
10793diff --git a/arch/arm/include/asm/vdso/gettimeofday.h b/arch/arm/include/asm/vdso/gettimeofday.h
10794index 2134cbd54..6f078fedb 100644
10795--- a/arch/arm/include/asm/vdso/gettimeofday.h
10796+++ b/arch/arm/include/asm/vdso/gettimeofday.h
10797@@ -109,14 +109,14 @@ static __always_inline int clock_getres32_fallback(
10798
10799 static inline bool arm_vdso_hres_capable(void)
10800 {
10801-	return IS_ENABLED(CONFIG_ARM_ARCH_TIMER);
10802+    return 0;
10803 }
10804 #define __arch_vdso_hres_capable arm_vdso_hres_capable
10805
10806 static __always_inline u64 __arch_get_hw_counter(int clock_mode,
10807 						 const struct vdso_data *vd)
10808 {
10809-#ifdef CONFIG_ARM_ARCH_TIMER
10810+#if defined (CONFIG_ARM_ARCH_TIMER) && defined(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS)
10811 	u64 cycle_now;
10812
10813 	/*
10814diff --git a/arch/arm/mach-hibvt/Kconfig b/arch/arm/mach-hibvt/Kconfig
10815new file mode 100644
10816index 000000000..89bedcb95
10817--- /dev/null
10818+++ b/arch/arm/mach-hibvt/Kconfig
10819@@ -0,0 +1,269 @@
10820+config ARCH_HISI_BVT
10821+	bool "Hisilicon BVT SoC Support"
10822+	select ARM_AMBA
10823+	select ARM_GIC if ARCH_MULTI_V7
10824+	select ARM_VIC if ARCH_MULTI_V5
10825+	select ARM_TIMER_SP804
10826+	select POWER_RESET
10827+	select POWER_SUPPLY
10828+
10829+if ARCH_HISI_BVT
10830+
10831+menu "Hisilicon BVT platform type"
10832+
10833+config ARCH_HI3521DV200
10834+	bool "Hisilicon Hi3521DV200 Cortex-A7 family"
10835+	depends on ARCH_MULTI_V7
10836+	select HAVE_ARM_ARCH_TIMER
10837+	select PINCTRL
10838+	select POWER_RESET_HISI
10839+	help
10840+		Support for Hisilicon Hi3521DV200 Soc family.
10841+
10842+config ARCH_HI3520DV500
10843+	bool "Hisilicon Hi3520DV500 Cortex-A7 family"
10844+	depends on ARCH_MULTI_V7
10845+	select HAVE_ARM_ARCH_TIMER
10846+	select PINCTRL
10847+	select POWER_RESET_HISI
10848+	help
10849+		Support for Hisilicon Hi3520DV500 Soc family.
10850+
10851+config ARCH_HI3516A
10852+	bool "Hisilicon Hi3516A Cortex-A7(Single) family"
10853+	depends on ARCH_MULTI_V7
10854+	select HAVE_ARM_ARCH_TIMER
10855+	select ARM_GIC
10856+	select ARCH_HAS_RESET_CONTROLLER
10857+	select RESET_CONTROLLER
10858+	help
10859+		Support for Hisilicon Hi3516A Soc family.
10860+
10861+config ARCH_HI3516CV500
10862+	bool "Hisilicon Hi3516CV500 Cortex-A7 family"
10863+	depends on ARCH_MULTI_V7
10864+	select HAVE_ARM_ARCH_TIMER
10865+	select PINCTRL
10866+    select POWER_RESET_HISI
10867+	help
10868+		Support for Hisilicon Hi3516CV500 Soc family.
10869+
10870+config ARCH_HI3516DV300
10871+	bool "Hisilicon Hi3516DV300 Cortex-A7 family"
10872+	depends on ARCH_MULTI_V7
10873+	select HAVE_ARM_ARCH_TIMER
10874+	select PINCTRL
10875+    select POWER_RESET_HISI
10876+	help
10877+		Support for Hisilicon Hi3516DV300 Soc family.
10878+
10879+config ARCH_HI3516EV200
10880+	bool "Hisilicon Hi3516EV200 Cortex-A7 family"
10881+	depends on ARCH_MULTI_V7
10882+	select HAVE_ARM_ARCH_TIMER
10883+	select PINCTRL
10884+    select POWER_RESET_HISI
10885+	help
10886+		Support for Hisilicon Hi3516EV200 Soc family.
10887+
10888+config ARCH_HI3516EV300
10889+	bool "Hisilicon Hi3516EV300 Cortex-A7 family"
10890+	depends on ARCH_MULTI_V7
10891+	select HAVE_ARM_ARCH_TIMER
10892+	select PINCTRL
10893+    select POWER_RESET_HISI
10894+	help
10895+		Support for Hisilicon Hi3516EV300 Soc family.
10896+
10897+config ARCH_HI3518EV300
10898+	bool "Hisilicon Hi3518EV300 Cortex-A7 family"
10899+	depends on ARCH_MULTI_V7
10900+	select HAVE_ARM_ARCH_TIMER
10901+	select PINCTRL
10902+    select POWER_RESET_HISI
10903+	help
10904+		Support for Hisilicon Hi3518EV300 Soc family.
10905+
10906+config ARCH_HI3516DV200
10907+	bool "Hisilicon Hi3516DV200 Cortex-A7 family"
10908+	depends on ARCH_MULTI_V7
10909+	select HAVE_ARM_ARCH_TIMER
10910+	select PINCTRL
10911+    select POWER_RESET_HISI
10912+	help
10913+		Support for Hisilicon Hi3516DV200 Soc family.
10914+config ARCH_HI3556V200
10915+	bool "Hisilicon Hi3556V200 Cortex-A7 family"
10916+	depends on ARCH_MULTI_V7
10917+	select HAVE_ARM_ARCH_TIMER
10918+	select PINCTRL
10919+    select POWER_RESET_HISI
10920+	help
10921+		Support for Hisilicon Hi3556V200 Soc family.
10922+
10923+config ARCH_HI3559V200
10924+	bool "Hisilicon Hi3559V200 Cortex-A7 family"
10925+	depends on ARCH_MULTI_V7
10926+	select HAVE_ARM_ARCH_TIMER
10927+	select PINCTRL
10928+    select POWER_RESET_HISI
10929+	help
10930+		Support for Hisilicon Hi3559V200 Soc family.
10931+
10932+config ARCH_HI3518EV20X
10933+	bool "Hisilicon Hi3518ev20x ARM926T(Single) family"
10934+	depends on ARCH_MULTI_V5
10935+	select PINCTRL
10936+	select PINCTRL_SINGLE
10937+	help
10938+		Support for Hisilicon Hi3518ev20x Soc family.
10939+
10940+config ARCH_HI3536DV100
10941+	bool "Hisilicon Hi3536DV100 Cortex-A7(Single) family"
10942+	depends on ARCH_MULTI_V7
10943+	select HAVE_ARM_ARCH_TIMER
10944+	select PINCTRL
10945+	help
10946+		Support for Hisilicon Hi3536DV100 Soc family.
10947+
10948+config ARCH_HI3521A
10949+	bool "Hisilicon Hi3521A A7(Single) family"
10950+	depends on ARCH_MULTI_V7
10951+	select HAVE_ARM_ARCH_TIMER
10952+	select ARM_GIC
10953+	select PINCTRL
10954+	select PINCTRL_SINGLE
10955+	help
10956+		Support for Hisilicon Hi3521a Soc family.
10957+
10958+config ARCH_HI3531A
10959+   bool "Hisilicon Hi3531A A9 family" if ARCH_MULTI_V7
10960+   select HAVE_ARM_ARCH_TIMER
10961+   select ARM_GIC
10962+   select CACHE_L2X0
10963+   select PINCTRL
10964+   select PINCTRL_SINGLE
10965+   select HAVE_ARM_SCU if SMP
10966+   select NEED_MACH_IO_H if PCI
10967+   help
10968+       Support for Hisilicon Hi3531a Soc family.
10969+
10970+config ARCH_HI3556AV100
10971+	bool "Hisilicon Hi3556AV100 Cortex-a53 family" if ARCH_MULTI_V7
10972+	select HAVE_ARM_ARCH_TIMER
10973+	select ARM_CCI
10974+	select ARCH_HAS_RESET_CONTROLLER
10975+	select RESET_CONTROLLER
10976+	select PMC if SMP
10977+	help
10978+	  Support for Hisilicon Hi3556AV100 Soc family
10979+if ARCH_HI3556AV100
10980+
10981+config PMC
10982+	bool
10983+	depends on ARCH_HI3556AV100
10984+	help
10985+	  support power control for Hi3556AV100 Cortex-a53
10986+
10987+endif
10988+
10989+config ARCH_HI3519AV100
10990+	bool "Hisilicon Hi3519AV100 Cortex-a53 family" if ARCH_MULTI_V7
10991+	select HAVE_ARM_ARCH_TIMER
10992+	select ARM_CCI
10993+	select ARM_GIC
10994+	select ARCH_HAS_RESET_CONTROLLER
10995+	select RESET_CONTROLLER
10996+	select NEED_MACH_IO_H if PCI
10997+	select PMC if SMP
10998+	help
10999+	  Support for Hisilicon Hi3519AV100 Soc family
11000+if ARCH_HI3519AV100
11001+
11002+config PMC
11003+	bool
11004+	depends on ARCH_HI3519AV100
11005+	help
11006+	  support power control for Hi3519AV100 Cortex-a53
11007+
11008+endif
11009+
11010+config ARCH_HI3568V100
11011+	bool "Hisilicon Hi3568V100 Cortex-a53 family" if ARCH_MULTI_V7
11012+	select HAVE_ARM_ARCH_TIMER
11013+	select ARM_CCI
11014+	select ARM_GIC
11015+	select ARCH_HAS_RESET_CONTROLLER
11016+	select RESET_CONTROLLER
11017+	select NEED_MACH_IO_H if PCI
11018+	select PMC if SMP
11019+	help
11020+	  Support for Hisilicon Hi3568V100 Soc family
11021+if ARCH_HI3568V100
11022+
11023+config PMC
11024+	bool
11025+	depends on ARCH_HI3568V100
11026+	help
11027+	  support power control for Hi3568V100 Cortex-a53
11028+
11029+endif
11030+
11031+config ARCH_HISI_BVT_AMP
11032+	bool "Hisilicon AMP solution support"
11033+      depends on ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3516CV500 || ARCH_HI3516DV300 || ARCH_HI3556V200 || ARCH_HI3559V200 || ARCH_HI3562V100 || ARCH_HI3566V100 || ARCH_HI3568V100
11034+	help
11035+	  support for Hisilicon AMP solution
11036+
11037+config HISI_MC
11038+	bool "Hisilicon mc platform solution"
11039+	default n
11040+	help
11041+	  support for Hisilicon mc platform solution
11042+
11043+config AMP_ZRELADDR
11044+	hex 'amp zreladdr'
11045+	depends on ARCH_HISI_BVT_AMP
11046+	default "0x32008000" if ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100
11047+	default "0x82008000" if ARCH_HI3516CV500 || ARCH_HI3516DV300 || ARCH_HI3556V200 || ARCH_HI3559V200 || ARCH_HI3562V100 || ARCH_HI3566V100
11048+	default "0x42008000" if ARCH_HI3516EV200 || ARCH_HI3516EV300 || ARCH_HI3518EV300 || ARCH_HI3516DV200
11049+config HI_ZRELADDR
11050+       hex 'zreladdr'
11051+       default "0x40008000" if ARCH_HI3521DV200
11052+       default "0x40008000" if ARCH_HI3520DV500
11053+       default "0x80008000" if ARCH_HI3516CV500
11054+       default "0x80008000" if ARCH_HI3516DV300
11055+       default "0x80008000" if ARCH_HI3556V200
11056+       default "0x80008000" if ARCH_HI3559V200
11057+       default "0x80008000" if ARCH_HI3562V100
11058+       default "0x80008000" if ARCH_HI3566V100
11059+       default "0x80008000" if ARCH_HI3516A
11060+       default "0x80008000" if ARCH_HI3518EV20X
11061+       default "0x80008000" if ARCH_HI3536DV100
11062+       default "0x80008000" if ARCH_HI3521A
11063+       default "0x40008000" if ARCH_HI3531A
11064+       default "0x40008000" if ARCH_HI3516EV200 || ARCH_HI3516EV300 || ARCH_HI3518EV300 || ARCH_HI3516DV200
11065+       default "0x22008000" if ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100
11066+
11067+config HI_PARAMS_PHYS
11068+       hex 'params_phys'
11069+       default "0x00000100"
11070+
11071+config HI_INITRD_PHYS
11072+       hex 'initrd_phys'
11073+       default "0x00800000"
11074+
11075+endmenu
11076+
11077+if ARCH_HI3516DV300
11078+
11079+config BLACKBOX_HI3516DV300
11080+	bool "Support BlackBox saving fault logs with pstore for hi3516dv300"
11081+	depends on PSTORE_BLACKBOX
11082+	depends on BLACKBOX_STORAGE_BY_PSTORE_BLK
11083+	help
11084+		Save fault logs with pstore for Hi3516DV300 when oops or panic occurs.
11085+
11086+endif
11087+
11088+endif
11089diff --git a/arch/arm/mach-hibvt/Makefile b/arch/arm/mach-hibvt/Makefile
11090new file mode 100644
11091index 000000000..8c4802fd1
11092--- /dev/null
11093+++ b/arch/arm/mach-hibvt/Makefile
11094@@ -0,0 +1,34 @@
11095+#
11096+# Makefile for Hisilicon processors family
11097+#
11098+
11099+obj-$(CONFIG_ARCH_HI3521DV200) += mach-hi3521dv200.o
11100+obj-$(CONFIG_ARCH_HI3520DV500) += mach-hi3521dv200.o
11101+obj-$(CONFIG_ARCH_HI3516A) += mach-hi3516a.o
11102+obj-$(CONFIG_ARCH_HI3516CV500) += mach-hi3516cv500.o
11103+obj-$(CONFIG_ARCH_HI3516EV200) += mach-hi3516ev200.o
11104+obj-$(CONFIG_ARCH_HI3516EV300) += mach-hi3516ev300.o
11105+obj-$(CONFIG_ARCH_HI3518EV300) += mach-hi3518ev300.o
11106+obj-$(CONFIG_ARCH_HI3516DV200) += mach-hi3516dv200.o
11107+obj-$(CONFIG_ARCH_HI3516DV300) += mach-hi3516dv300.o
11108+obj-$(CONFIG_ARCH_HI3556V200) += mach-hi3556v200.o
11109+obj-$(CONFIG_ARCH_HI3559V200) += mach-hi3559v200.o
11110+obj-$(CONFIG_ARCH_HI3562V100) += mach-hi3559v200.o
11111+obj-$(CONFIG_ARCH_HI3566V100) += mach-hi3559v200.o
11112+obj-$(CONFIG_ARCH_HI3518EV20X) += mach-hi3518ev20x.o
11113+obj-$(CONFIG_ARCH_HI3536DV100) += mach-hi3536dv100.o
11114+obj-$(CONFIG_ARCH_HI3521A) += mach-hi3521a.o
11115+obj-$(CONFIG_ARCH_HI3531A) += mach-hi3531a.o
11116+obj-$(CONFIG_ARCH_HI3556AV100) += mach-hi3556av100.o
11117+obj-$(CONFIG_ARCH_HI3519AV100) += mach-hi3519av100.o
11118+obj-$(CONFIG_ARCH_HI3568V100) += mach-hi3519av100.o
11119+
11120+
11121+obj-$(CONFIG_SMP)	+= platsmp.o
11122+
11123+ifdef CONFIG_BLACKBOX_HI3516DV300
11124+
11125+obj-$(CONFIG_BLACKBOX_STORAGE_BY_PSTORE_BLK) += system_adapter.o
11126+obj-$(CONFIG_BLACKBOX_STORAGE_BY_MEMORY) += system_adapter_by_memory.o
11127+
11128+endif
11129diff --git a/arch/arm/mach-hibvt/Makefile.boot b/arch/arm/mach-hibvt/Makefile.boot
11130new file mode 100644
11131index 000000000..8c8b30077
11132--- /dev/null
11133+++ b/arch/arm/mach-hibvt/Makefile.boot
11134@@ -0,0 +1,7 @@
11135+ifeq ($(CONFIG_ARCH_HISI_BVT_AMP), y)
11136+zreladdr-$(CONFIG_ARCH_HISI_BVT)      := $(CONFIG_AMP_ZRELADDR)
11137+else
11138+zreladdr-$(CONFIG_ARCH_HISI_BVT)      := $(CONFIG_HI_ZRELADDR)
11139+endif
11140+params_phys-$(CONFIG_ARCH_HISI_BVT)   := $(CONFIG_HI_PARAMS_PHYS)
11141+initrd_phys-$(CONFIG_ARCH_HISI_BVT)   := $(CONFIG_HI_INITRD_PHYS)
11142diff --git a/arch/arm/mach-hibvt/include/mach/hi3516dv300_io.h b/arch/arm/mach-hibvt/include/mach/hi3516dv300_io.h
11143new file mode 100644
11144index 000000000..72ab47e83
11145--- /dev/null
11146+++ b/arch/arm/mach-hibvt/include/mach/hi3516dv300_io.h
11147@@ -0,0 +1,26 @@
11148+#ifndef __HI3516DV300_IO_H
11149+#define __HI3516DV300_IO_H
11150+
11151+/*
11152+ * phy: 0x20000000 ~ 0x20700000
11153+ * vir: 0xFE100000 ~ 0xFE800000
11154+ */
11155+#define HI3516DV300_IOCH2_PHYS  0x20000000
11156+#define IO_OFFSET_HIGH      0xDE100000
11157+#define HI3516DV300_IOCH2_VIRT (HI3516DV300_IOCH2_PHYS + IO_OFFSET_HIGH)
11158+#define HI3516DV300_IOCH2_SIZE 0x700000
11159+
11160+/* phy: 0x10000000 ~ 0x100E0000
11161+ * vir: 0xFE000000 ~ 0xFE0E0000
11162+ */
11163+#define HI3516DV300_IOCH1_PHYS  0x10000000
11164+#define IO_OFFSET_LOW       0xEE000000
11165+#define HI3516DV300_IOCH1_VIRT (HI3516DV300_IOCH1_PHYS + IO_OFFSET_LOW)
11166+#define HI3516DV300_IOCH1_SIZE 0xE0000
11167+
11168+#define IO_ADDRESS(x) ((x) >= HI3516DV300_IOCH2_PHYS ? (x) + IO_OFFSET_HIGH \
11169+                                : (x) + IO_OFFSET_LOW)
11170+
11171+#define __io_address(n)     ((void __iomem __force *)IO_ADDRESS(n))
11172+
11173+#endif
11174diff --git a/arch/arm/mach-hibvt/include/mach/hi3516dv300_platform.h b/arch/arm/mach-hibvt/include/mach/hi3516dv300_platform.h
11175new file mode 100644
11176index 000000000..94c48064b
11177--- /dev/null
11178+++ b/arch/arm/mach-hibvt/include/mach/hi3516dv300_platform.h
11179@@ -0,0 +1,4 @@
11180+#ifndef __HI3516DV300_CHIP_REGS_H__
11181+#define __HI3516DV300_CHIP_REGS_H__
11182+
11183+#endif /* End of __HI3516DV300_CHIP_REGS_H__ */
11184diff --git a/arch/arm/mach-hibvt/include/mach/io.h b/arch/arm/mach-hibvt/include/mach/io.h
11185new file mode 100644
11186index 000000000..b5fd58c7b
11187--- /dev/null
11188+++ b/arch/arm/mach-hibvt/include/mach/io.h
11189@@ -0,0 +1,52 @@
11190+#ifndef __ASM_ARM_ARCH_IO_H
11191+#define __ASM_ARM_ARCH_IO_H
11192+
11193+#ifdef CONFIG_ARCH_HI3516A
11194+#include <mach/hi3516a_io.h>
11195+#endif
11196+
11197+#ifdef CONFIG_ARCH_HI3518EV20X
11198+#include <mach/hi3518ev20x_io.h>
11199+#endif
11200+
11201+#ifdef CONFIG_ARCH_HI3536DV100
11202+#include <mach/hi3536dv100_io.h>
11203+#endif
11204+
11205+#ifdef CONFIG_ARCH_HI3521A
11206+#include <mach/hi3521a_io.h>
11207+#endif
11208+
11209+#ifdef CONFIG_ARCH_HI3531A
11210+#include <mach/hi3531a_io.h>
11211+#endif
11212+
11213+#ifdef CONFIG_ARCH_HI3516CV500
11214+#include <mach/hi3516cv500_io.h>
11215+#endif
11216+
11217+#ifdef CONFIG_ARCH_HI3516DV300
11218+#include <mach/hi3516dv300_io.h>
11219+#endif
11220+
11221+#ifdef CONFIG_ARCH_HI3556V200
11222+#include <mach/hi3556v200_io.h>
11223+#endif
11224+
11225+#ifdef CONFIG_ARCH_HI3559V200
11226+#include <mach/hi3559v200_io.h>
11227+#endif
11228+
11229+#ifdef CONFIG_ARCH_HI3562V100
11230+#include <mach/hi3559v200_io.h>
11231+#endif
11232+
11233+#ifdef CONFIG_ARCH_HI3566V100
11234+#include <mach/hi3559v200_io.h>
11235+#endif
11236+
11237+#ifdef CONFIG_ARCH_HI3519AV100
11238+#include <mach/hi3519av100_io.h>
11239+#endif
11240+
11241+#endif
11242diff --git a/arch/arm/mach-hibvt/include/mach/platform.h b/arch/arm/mach-hibvt/include/mach/platform.h
11243new file mode 100644
11244index 000000000..5e41d2696
11245--- /dev/null
11246+++ b/arch/arm/mach-hibvt/include/mach/platform.h
11247@@ -0,0 +1,52 @@
11248+#ifndef __HISI_PLATFORM_H__
11249+#define __HISI_PLATFORM_H__
11250+
11251+#ifdef CONFIG_ARCH_HI3536DV100
11252+#include <mach/hi3536dv100_platform.h>
11253+#endif
11254+
11255+#ifdef CONFIG_ARCH_HI3521A
11256+#include <mach/hi3521a_platform.h>
11257+#endif
11258+
11259+#ifdef CONFIG_ARCH_HI3531A
11260+#include <mach/hi3531a_platform.h>
11261+#endif
11262+
11263+#ifdef CONFIG_ARCH_HI3516DV300
11264+#include <mach/hi3516dv300_platform.h>
11265+#endif
11266+
11267+#ifdef CONFIG_ARCH_HI3516CV500
11268+#include <mach/hi3516cv500_platform.h>
11269+#endif
11270+
11271+#ifdef CONFIG_ARCH_HI3556V200
11272+#include <mach/hi3556v200_platform.h>
11273+#endif
11274+
11275+#ifdef CONFIG_ARCH_HI3559V200
11276+#include <mach/hi3559v200_platform.h>
11277+#endif
11278+
11279+#ifdef CONFIG_ARCH_HI3562V100
11280+#include <mach/hi3559v200_platform.h>
11281+#endif
11282+
11283+#ifdef CONFIG_ARCH_HI3566V100
11284+#include <mach/hi3559v200_platform.h>
11285+#endif
11286+
11287+#ifdef CONFIG_ARCH_HI3556AV100
11288+#include <mach/hi3556av100_platform.h>
11289+#endif
11290+
11291+#ifdef CONFIG_ARCH_HI3519AV100
11292+#include <mach/hi3519av100_platform.h>
11293+#endif
11294+
11295+#ifdef CONFIG_ARCH_HI3568V100
11296+#include <mach/hi3519av100_platform.h>
11297+#endif
11298+
11299+#endif /* End of __HISI_PLATFORM_H__ */
11300diff --git a/arch/arm/mach-hibvt/mach-common.h b/arch/arm/mach-hibvt/mach-common.h
11301new file mode 100644
11302index 000000000..f5edadb0f
11303--- /dev/null
11304+++ b/arch/arm/mach-hibvt/mach-common.h
11305@@ -0,0 +1,9 @@
11306+#ifndef __SMP_COMMON_H
11307+#define __SMP_COMMON_H
11308+
11309+#ifdef CONFIG_SMP
11310+void hi35xx_set_cpu(unsigned int cpu, bool enable);
11311+void __init hi35xx_smp_prepare_cpus(unsigned int max_cpus);
11312+int hi35xx_boot_secondary(unsigned int cpu, struct task_struct *idle);
11313+#endif /* CONFIG_SMP */
11314+#endif /* __SMP_COMMON_H */
11315diff --git a/arch/arm/mach-hibvt/mach-hi3516dv300.c b/arch/arm/mach-hibvt/mach-hi3516dv300.c
11316new file mode 100644
11317index 000000000..3061683bb
11318--- /dev/null
11319+++ b/arch/arm/mach-hibvt/mach-hi3516dv300.c
11320@@ -0,0 +1,68 @@
11321+/*
11322+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
11323+ *
11324+ * This program is free software; you can redistribute it and/or modify
11325+ * it under the terms of the GNU General Public License as published by
11326+ * the Free Software Foundation; either version 2 of the License, or
11327+ * (at your option) any later version.
11328+ *
11329+ * This program is distributed in the hope that it will be useful,
11330+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
11331+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11332+ * GNU General Public License for more details.
11333+ *
11334+ * You should have received a copy of the GNU General Public License
11335+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
11336+ *
11337+*/
11338+
11339+#include <linux/of_address.h>
11340+#include <asm/smp_scu.h>
11341+
11342+#include "mach-common.h"
11343+
11344+#ifdef CONFIG_SMP
11345+
11346+#define REG_CPU_SRST_CRG    0x78
11347+#define CPU1_SRST_REQ       BIT(2)
11348+#define DBG1_SRST_REQ       BIT(4)
11349+
11350+void hi35xx_set_cpu(unsigned int cpu, bool enable)
11351+{
11352+	struct device_node *np = NULL;
11353+	unsigned int regval;
11354+	void __iomem *crg_base;
11355+
11356+	np = of_find_compatible_node(NULL, NULL, "hisilicon,hi3516dv300-clock");
11357+	if (!np) {
11358+		pr_err("failed to find hisilicon clock node\n");
11359+		return;
11360+	}
11361+
11362+	crg_base = of_iomap(np, 0);
11363+	if (!crg_base) {
11364+		pr_err("failed to map address\n");
11365+		return;
11366+	}
11367+
11368+	if (enable) {
11369+		/* clear the slave cpu reset */
11370+		regval = readl(crg_base + REG_CPU_SRST_CRG);
11371+		regval &= ~CPU1_SRST_REQ;
11372+		writel(regval, (crg_base + REG_CPU_SRST_CRG));
11373+	} else {
11374+		regval = readl(crg_base + REG_CPU_SRST_CRG);
11375+		regval |= (DBG1_SRST_REQ | CPU1_SRST_REQ);
11376+		writel(regval, (crg_base + REG_CPU_SRST_CRG));
11377+	}
11378+	iounmap(crg_base);
11379+}
11380+
11381+static const struct smp_operations hi35xx_smp_ops __initconst = {
11382+	.smp_prepare_cpus       = hi35xx_smp_prepare_cpus,
11383+	.smp_boot_secondary     = hi35xx_boot_secondary,
11384+};
11385+
11386+CPU_METHOD_OF_DECLARE(hi3516dv300_smp, "hisilicon,hi3516dv300",
11387+		      &hi35xx_smp_ops);
11388+#endif /* CONFIG_SMP */
11389diff --git a/arch/arm/mach-hibvt/platsmp.c b/arch/arm/mach-hibvt/platsmp.c
11390new file mode 100644
11391index 000000000..a73be20b1
11392--- /dev/null
11393+++ b/arch/arm/mach-hibvt/platsmp.c
11394@@ -0,0 +1,62 @@
11395+/*
11396+ * Copyright (c) 2013 Linaro Ltd.
11397+ * Copyright (c) 2013 Hisilicon Limited.
11398+ * Based on arch/arm/mach-vexpress/platsmp.c, Copyright (C) 2002 ARM Ltd.
11399+ *
11400+ * This program is free software; you can redistribute it and/or modify it
11401+ * under the terms and conditions of the GNU General Public License,
11402+ * version 2, as published by the Free Software Foundation.
11403+ */
11404+
11405+#include <linux/io.h>
11406+#include <linux/smp.h>
11407+#include <asm/smp_scu.h>
11408+
11409+#include "mach-common.h"
11410+
11411+#define HI35XX_BOOT_ADDRESS 0x00000000
11412+
11413+void __init hi35xx_smp_prepare_cpus(unsigned int max_cpus)
11414+{
11415+	unsigned long base = 0;
11416+	void __iomem *scu_base = NULL;
11417+
11418+	if (scu_a9_has_base()) {
11419+		base = scu_a9_get_base();
11420+		scu_base = ioremap(base, PAGE_SIZE);
11421+		if (!scu_base) {
11422+			pr_err("ioremap(scu_base) failed\n");
11423+			return;
11424+		}
11425+
11426+		scu_enable(scu_base);
11427+		iounmap(scu_base);
11428+	}
11429+}
11430+
11431+void hi35xx_set_scu_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr)
11432+{
11433+	void __iomem *virt;
11434+
11435+	virt = ioremap(start_addr, PAGE_SIZE);
11436+	if (!virt) {
11437+		pr_err("ioremap(start_addr) failed\n");
11438+		return;
11439+	}
11440+
11441+	writel_relaxed(0xe51ff004, virt);   /* ldr pc, [rc, #-4] */
11442+	writel_relaxed(jump_addr, virt + 4);    /* pc jump phy address */
11443+	iounmap(virt);
11444+}
11445+
11446+int hi35xx_boot_secondary(unsigned int cpu, struct task_struct *idle)
11447+{
11448+	phys_addr_t jumpaddr;
11449+
11450+	jumpaddr = virt_to_phys(secondary_startup);
11451+	hi35xx_set_scu_boot_addr(HI35XX_BOOT_ADDRESS, jumpaddr);
11452+	hi35xx_set_cpu(cpu, true);
11453+	arch_send_wakeup_ipi_mask(cpumask_of(cpu));
11454+	return 0;
11455+}
11456+
11457diff --git a/arch/arm/mach-hibvt/system_adapter.c b/arch/arm/mach-hibvt/system_adapter.c
11458new file mode 100644
11459index 000000000..58fe574b3
11460--- /dev/null
11461+++ b/arch/arm/mach-hibvt/system_adapter.c
11462@@ -0,0 +1,340 @@
11463+// SPDX-License-Identifier: GPL-2.0
11464+/*
11465+ * Copyright (C) 2021 Huawei Technologies Co., Ltd. All rights reserved.
11466+ */
11467+
11468+#include <asm/cacheflush.h>
11469+#include <linux/blackbox.h>
11470+#include <linux/kmsg_dump.h>
11471+#include <linux/semaphore.h>
11472+#include <linux/slab.h>
11473+#include <linux/module.h>
11474+#include <linux/stacktrace.h>
11475+#include <linux/reboot.h>
11476+#include <linux/vmalloc.h>
11477+#include <linux/ctype.h>
11478+#include <linux/blackbox_common.h>
11479+#include <linux/blackbox_storage.h>
11480+
11481+/* ---- local macroes ---- */
11482+#define BOOTLOADER_LOG_NAME       "fastboot_log"
11483+#define KERNEL_LOG_NAME           "last_kmsg"
11484+#define SIZE_1K                   1024
11485+#define KERNEL_LOG_MAX_SIZE               \
11486+	round_up((0x80000 + sizeof(struct fault_log_info)), SIZE_1K)
11487+#define CALLSTACK_MAX_ENTRIES     20
11488+
11489+/* ---- local prototypes ---- */
11490+
11491+/* ---- local function prototypes ---- */
11492+static int save_kmsg_from_buffer(const char *log_dir,
11493+				const char *file_name, int clean_buf);
11494+static void dump(const char *log_dir, struct error_info *info);
11495+static void reset(struct error_info *info);
11496+static int get_last_log_info(struct error_info *info);
11497+static int save_last_log(const char *log_dir, struct error_info *info);
11498+static int bbox_reboot_notify(struct notifier_block *nb,
11499+					unsigned long code, void *unused);
11500+static int bbox_task_panic(struct notifier_block *this,
11501+					unsigned long event, void *ptr);
11502+
11503+/* ---- local variables ---- */
11504+static char *kernel_log;
11505+static DEFINE_SEMAPHORE(kmsg_sem);
11506+static struct notifier_block bbox_reboot_nb = {
11507+	.notifier_call = bbox_reboot_notify,
11508+};
11509+
11510+static struct notifier_block bbox_panic_block = {
11511+	.notifier_call = bbox_task_panic,
11512+};
11513+
11514+/* ---- function definitions ---- */
11515+static void dump_stacktrace(char *pbuf, size_t buf_size, bool is_panic)
11516+{
11517+	int i;
11518+	size_t stack_len = 0;
11519+	size_t com_len = 0;
11520+	unsigned long entries[CALLSTACK_MAX_ENTRIES];
11521+	unsigned int nr_entries;
11522+	char tmp_buf[ERROR_DESC_MAX_LEN];
11523+	bool find_panic = false;
11524+
11525+	if (unlikely(!pbuf || !buf_size))
11526+		return;
11527+
11528+	memset(pbuf, 0, buf_size);
11529+	memset(tmp_buf, 0, sizeof(tmp_buf));
11530+	nr_entries = stack_trace_save(entries, ARRAY_SIZE(entries), 0);
11531+	com_len = scnprintf(pbuf, buf_size, "Comm:%s,CPU:%d,Stack:",
11532+						current->comm, raw_smp_processor_id());
11533+	for (i = 0; i < nr_entries; i++) {
11534+		if (stack_len >= sizeof(tmp_buf)) {
11535+			tmp_buf[sizeof(tmp_buf) - 1] = '\0';
11536+			break;
11537+		}
11538+		stack_len += scnprintf(tmp_buf + stack_len, sizeof(tmp_buf) - stack_len,
11539+				"%pS-", (void *)entries[i]);
11540+		if (!find_panic && is_panic) {
11541+			if (strncmp(tmp_buf, "panic", strlen("panic")) == 0)
11542+				find_panic = true;
11543+			else
11544+				(void)memset(tmp_buf, 0, sizeof(tmp_buf));
11545+		}
11546+	}
11547+	if (com_len >= buf_size)
11548+		return;
11549+	stack_len = min(buf_size - com_len, strlen(tmp_buf));
11550+	memcpy(pbuf + com_len, tmp_buf, stack_len);
11551+	*(pbuf + buf_size - 1) = '\0';
11552+}
11553+
11554+static int save_kmsg_from_buffer(const char *log_dir,
11555+				const char *file_name, int clean_buf)
11556+{
11557+	int ret = -1;
11558+	char path[PATH_MAX_LEN];
11559+	struct fault_log_info *pinfo = NULL;
11560+
11561+	if (unlikely(!log_dir || !file_name)) {
11562+		bbox_print_err("log_dir: %p, file_name: %p!\n", log_dir, file_name);
11563+		return -EINVAL;
11564+	}
11565+
11566+	memset(path, 0, sizeof(path));
11567+	(void)scnprintf(path, sizeof(path) - 1, "%s/%s", log_dir, file_name);
11568+	down(&kmsg_sem);
11569+	if (kernel_log) {
11570+		pinfo = (struct fault_log_info *)kernel_log;
11571+		ret = full_write_file(path, kernel_log + sizeof(*pinfo),
11572+					min(KERNEL_LOG_MAX_SIZE - sizeof(*pinfo),
11573+						(size_t)pinfo->len), 0);
11574+		if (clean_buf)
11575+			memset(kernel_log, 0, KERNEL_LOG_MAX_SIZE);
11576+	} else {
11577+		bbox_print_err("kernel_log: %p!\n", kernel_log);
11578+	}
11579+	up(&kmsg_sem);
11580+	if (ret == 0)
11581+		change_own(path, AID_ROOT, AID_SYSTEM);
11582+
11583+	return ret;
11584+}
11585+
11586+static void dump(const char *log_dir, struct error_info *info)
11587+{
11588+	if (unlikely(!log_dir || !info)) {
11589+		bbox_print_err("log_dir: %p, info: %p!\n", log_dir, info);
11590+		return;
11591+	}
11592+
11593+	if (!strcmp(info->event, EVENT_PANIC) ||
11594+		!strcmp(info->event, EVENT_SYSREBOOT) ||
11595+		!strcmp(info->event, EVENT_POWEROFF)) {
11596+		struct fault_log_info *pinfo = (struct fault_log_info *)kernel_log;
11597+
11598+		if (down_trylock(&kmsg_sem) != 0) {
11599+			bbox_print_err("down_trylock failed!\n");
11600+			return;
11601+		}
11602+
11603+		if (kernel_log) {
11604+			memcpy(pinfo->flag, LOG_FLAG, strlen(LOG_FLAG));
11605+			memcpy(&pinfo->info, info, sizeof(*info));
11606+
11607+#if  __BITS_PER_LONG == 64
11608+			__flush_dcache_area(kernel_log, KERNEL_LOG_MAX_SIZE);
11609+#else
11610+			__cpuc_flush_dcache_area(kernel_log, KERNEL_LOG_MAX_SIZE);
11611+#endif
11612+		}
11613+
11614+		up(&kmsg_sem);
11615+	} else {
11616+		bbox_print_info("module [%s] starts saving log for event [%s]!\n",
11617+				info->module, info->event);
11618+		save_kmsg_from_buffer(log_dir, KERNEL_LOG_NAME, 0);
11619+		bbox_print_info("module [%s] ends saving log for event [%s]!\n",
11620+				info->module, info->event);
11621+	}
11622+}
11623+
11624+static void reset(struct error_info *info)
11625+{
11626+	if (unlikely(!info)) {
11627+		bbox_print_err("info: %p!\n", info);
11628+		return;
11629+	}
11630+
11631+	if (!strcmp(info->event, EVENT_PANIC))
11632+		emergency_restart();
11633+}
11634+
11635+static int get_last_log_info(struct error_info *info)
11636+{
11637+	struct fault_log_info *pinfo = (struct fault_log_info *)kernel_log;
11638+	int log_size = KERNEL_LOG_MAX_SIZE;
11639+	unsigned int i = 0;
11640+
11641+	if (unlikely(!info || !kernel_log))
11642+		return -EINVAL;
11643+
11644+	if (storage_lastword->get_log((void *)kernel_log, log_size) < 0) {
11645+		bbox_print_err("Get last log from strorage failed!\n");
11646+		return -ENOENT;
11647+	}
11648+
11649+	down(&kmsg_sem);
11650+	if (!memcmp(pinfo->flag, LOG_FLAG, strlen(LOG_FLAG))) {
11651+		memcpy(info, &pinfo->info, sizeof(*info));
11652+		for (i = 0; i < strlen((*info).event); i++)
11653+			(*info).event[i] = toupper((*info).event[i]);
11654+
11655+		if (strncmp((*info).module, "PSTORE", strlen("PSTORE")) == 0)
11656+			memcpy((*info).module, MODULE_SYSTEM, sizeof((*info).module));
11657+
11658+		up(&kmsg_sem);
11659+		return 0;
11660+	}
11661+	up(&kmsg_sem);
11662+	bbox_print_info("There's no valid fault log!\n");
11663+
11664+	return -ENOMSG;
11665+}
11666+
11667+static int save_last_log(const char *log_dir, struct error_info *info)
11668+{
11669+	int ret = -1;
11670+
11671+	if (unlikely(!log_dir || !info)) {
11672+		bbox_print_err("log_dir: %p, info: %p!\n", log_dir, info);
11673+		return -EINVAL;
11674+	}
11675+
11676+	ret = save_kmsg_from_buffer(log_dir, KERNEL_LOG_NAME, 1);
11677+	bbox_print_info("save last fault log %s!\n",
11678+			ret ? "failed" : "successfully");
11679+
11680+	return ret;
11681+}
11682+
11683+static int bbox_reboot_notify(struct notifier_block *nb,
11684+					unsigned long code, void *unused)
11685+{
11686+	char error_desc[ERROR_DESC_MAX_LEN];
11687+
11688+	/* notify blackbox to do dump */
11689+	memset(error_desc, 0, sizeof(error_desc));
11690+	dump_stacktrace(error_desc, sizeof(error_desc), false);
11691+	kmsg_dump(KMSG_DUMP_UNDEF);
11692+
11693+	switch (code) {
11694+	case SYS_RESTART:
11695+		bbox_notify_error(EVENT_SYSREBOOT, MODULE_SYSTEM, error_desc, 1);
11696+		break;
11697+	case SYS_POWER_OFF:
11698+		bbox_notify_error(EVENT_POWEROFF, MODULE_SYSTEM, error_desc, 0);
11699+		break;
11700+	default:
11701+		bbox_print_err("Invalid event code: %lu!\n", code);
11702+		break;
11703+	}
11704+
11705+	return NOTIFY_DONE;
11706+}
11707+
11708+static int bbox_task_panic(struct notifier_block *this,
11709+				unsigned long event, void *ptr)
11710+{
11711+	char error_desc[ERROR_DESC_MAX_LEN];
11712+
11713+	/* notify blackbox to do dump */
11714+	kmsg_dump(KMSG_DUMP_OOPS);
11715+	memset(error_desc, 0, sizeof(error_desc));
11716+	bbox_notify_error(EVENT_PANIC, MODULE_SYSTEM, error_desc, 1);
11717+
11718+	return NOTIFY_DONE;
11719+}
11720+
11721+#ifdef CONFIG_BLACKBOX_TEST
11722+static void test_bbox(void)
11723+{
11724+	struct module_ops ops = {
11725+		.module = "TEST",
11726+		.dump = NULL,
11727+		.reset = NULL,
11728+		.get_last_log_info = NULL,
11729+		.save_last_log = NULL,
11730+	};
11731+
11732+	if (bbox_register_module_ops(&ops) != 0) {
11733+		bbox_print_err("bbox_register_module_ops failed!\n");
11734+		return -EINVAL;
11735+	}
11736+	kmsg_dump(KMSG_DUMP_OOPS);
11737+	bbox_notify_error("EVENT_TEST", "TEST", "Test bbox_notify_error", 0);
11738+
11739+}
11740+#endif
11741+
11742+static int __init blackbox_init(void)
11743+{
11744+	int ret = -1;
11745+	struct kmsg_dumper *dumper = NULL;
11746+	struct module_ops ops = {
11747+		.module = MODULE_SYSTEM,
11748+		.dump = dump,
11749+		.reset = reset,
11750+		.get_last_log_info = get_last_log_info,
11751+		.save_last_log = save_last_log,
11752+	};
11753+
11754+	if (bbox_register_module_ops(&ops) != 0) {
11755+		bbox_print_err("bbox_register_module_ops failed!\n");
11756+		return -EINVAL;
11757+	}
11758+
11759+	/* allocate buffer for kmsg */
11760+	kernel_log = kmalloc(KERNEL_LOG_MAX_SIZE, GFP_KERNEL);
11761+	if (!kernel_log)
11762+		goto __err;
11763+
11764+	bbox_print_info("kernel_log: %p for blackbox!\n", kernel_log);
11765+
11766+	/* register kdumper */
11767+	dumper = vmalloc(sizeof(*dumper));
11768+	if (!dumper)
11769+		goto __err;
11770+
11771+	memset(dumper, 0, sizeof(*dumper));
11772+	dumper->max_reason = KMSG_DUMP_MAX;
11773+	dumper->dump = storage_lastword->blackbox_dump;
11774+	ret = kmsg_dump_register(dumper);
11775+	if (ret != 0) {
11776+		bbox_print_err("kmsg_dump_register failed!\n");
11777+		goto __err;
11778+	}
11779+	atomic_notifier_chain_register(&panic_notifier_list, &bbox_panic_block);
11780+
11781+	register_reboot_notifier(&bbox_reboot_nb);
11782+#ifdef CONFIG_BLACKBOX_TEST
11783+	test_bbox();
11784+#endif
11785+	return 0;
11786+
11787+__err:
11788+	kfree(kernel_log);
11789+	kernel_log = NULL;
11790+
11791+	if (dumper) {
11792+		vfree(dumper);
11793+		dumper = NULL;
11794+	}
11795+
11796+	return ret;
11797+}
11798+
11799+postcore_initcall(blackbox_init);
11800+MODULE_LICENSE("GPL v2");
11801+MODULE_DESCRIPTION("Blackbox for system");
11802+MODULE_AUTHOR("OHOS hi3516dv300");
11803diff --git a/arch/arm/mach-hibvt/system_adapter_by_memory.c b/arch/arm/mach-hibvt/system_adapter_by_memory.c
11804new file mode 100644
11805index 000000000..92a680a9e
11806--- /dev/null
11807+++ b/arch/arm/mach-hibvt/system_adapter_by_memory.c
11808@@ -0,0 +1,339 @@
11809+// SPDX-License-Identifier: GPL-2.0
11810+/*
11811+ * Copyright (C) 2021 Huawei Technologies Co., Ltd. All rights reserved.
11812+ */
11813+
11814+#include <asm/cacheflush.h>
11815+#include <linux/blackbox.h>
11816+#include <linux/kmsg_dump.h>
11817+#include <linux/semaphore.h>
11818+#include <linux/slab.h>
11819+#include <linux/module.h>
11820+#include <linux/stacktrace.h>
11821+#include <linux/reboot.h>
11822+#include <linux/vmalloc.h>
11823+#include <linux/ctype.h>
11824+#include <linux/blackbox_common.h>
11825+#include <linux/blackbox_storage.h>
11826+
11827+/* ---- local macroes ---- */
11828+#define BOOTLOADER_LOG_NAME       "fastboot_log"
11829+#define KERNEL_LOG_NAME           "last_kmsg"
11830+#define SIZE_1K                   1024
11831+#define KERNEL_LOG_MAX_SIZE               \
11832+	round_up((0x80000 + sizeof(struct fault_log_info)), SIZE_1K)
11833+#define CALLSTACK_MAX_ENTRIES     20
11834+
11835+/* ---- local prototypes ---- */
11836+
11837+/* ---- local function prototypes ---- */
11838+static int save_kmsg_from_buffer(const char *log_dir,
11839+				const char *file_name, int clean_buf);
11840+static void dump(const char *log_dir, struct error_info *info);
11841+static void reset(struct error_info *info);
11842+static int get_last_log_info(struct error_info *info);
11843+static int save_last_log(const char *log_dir, struct error_info *info);
11844+static int bbox_reboot_notify(struct notifier_block *nb,
11845+					unsigned long code, void *unused);
11846+static int bbox_task_panic(struct notifier_block *this,
11847+					unsigned long event, void *ptr);
11848+
11849+/* ---- local variables ---- */
11850+static char *kernel_log;
11851+static DEFINE_SEMAPHORE(kmsg_sem);
11852+static struct notifier_block bbox_reboot_nb = {
11853+	.notifier_call = bbox_reboot_notify,
11854+};
11855+
11856+static struct notifier_block bbox_panic_block = {
11857+	.notifier_call = bbox_task_panic,
11858+};
11859+
11860+/* ---- function definitions ---- */
11861+static void dump_stacktrace(char *pbuf, size_t buf_size, bool is_panic)
11862+{
11863+	int i;
11864+	size_t stack_len = 0;
11865+	size_t com_len = 0;
11866+	unsigned long entries[CALLSTACK_MAX_ENTRIES];
11867+	unsigned int nr_entries;
11868+	char tmp_buf[ERROR_DESC_MAX_LEN];
11869+	bool find_panic = false;
11870+
11871+	if (unlikely(!pbuf || !buf_size))
11872+		return;
11873+
11874+	memset(pbuf, 0, buf_size);
11875+	memset(tmp_buf, 0, sizeof(tmp_buf));
11876+	nr_entries = stack_trace_save(entries, ARRAY_SIZE(entries), 0);
11877+	com_len = scnprintf(pbuf, buf_size, "Comm:%s,CPU:%d,Stack:",
11878+						current->comm, raw_smp_processor_id());
11879+	for (i = 0; i < nr_entries; i++) {
11880+		if (stack_len >= sizeof(tmp_buf)) {
11881+			tmp_buf[sizeof(tmp_buf) - 1] = '\0';
11882+			break;
11883+		}
11884+		stack_len += scnprintf(tmp_buf + stack_len, sizeof(tmp_buf) - stack_len,
11885+				"%pS-", (void *)entries[i]);
11886+		if (!find_panic && is_panic) {
11887+			if (strncmp(tmp_buf, "panic", strlen("panic")) == 0)
11888+				find_panic = true;
11889+			else
11890+				(void)memset(tmp_buf, 0, sizeof(tmp_buf));
11891+		}
11892+	}
11893+	if (com_len >= buf_size)
11894+		return;
11895+	stack_len = min(buf_size - com_len, strlen(tmp_buf));
11896+	memcpy(pbuf + com_len, tmp_buf, stack_len);
11897+	*(pbuf + buf_size - 1) = '\0';
11898+}
11899+
11900+static int save_kmsg_from_buffer(const char *log_dir,
11901+				const char *file_name, int clean_buf)
11902+{
11903+	int ret = -1;
11904+	char path[PATH_MAX_LEN];
11905+	struct fault_log_info *pinfo = NULL;
11906+
11907+	if (unlikely(!log_dir || !file_name)) {
11908+		bbox_print_err("log_dir: %p, file_name: %p!\n", log_dir, file_name);
11909+		return -EINVAL;
11910+	}
11911+
11912+	memset(path, 0, sizeof(path));
11913+	(void)scnprintf(path, sizeof(path) - 1, "%s/%s", log_dir, file_name);
11914+	down(&kmsg_sem);
11915+	if (kernel_log) {
11916+		pinfo = (struct fault_log_info *)kernel_log;
11917+		ret = full_write_file(path, kernel_log + sizeof(*pinfo),
11918+					min(KERNEL_LOG_MAX_SIZE - sizeof(*pinfo),
11919+						(size_t)pinfo->len), 0);
11920+		if (clean_buf)
11921+			memset(kernel_log, 0, KERNEL_LOG_MAX_SIZE);
11922+	} else {
11923+		bbox_print_err("kernel_log: %p!\n", kernel_log);
11924+	}
11925+	up(&kmsg_sem);
11926+	if (ret == 0)
11927+		change_own(path, AID_ROOT, AID_SYSTEM);
11928+
11929+	return ret;
11930+}
11931+
11932+static void dump(const char *log_dir, struct error_info *info)
11933+{
11934+	if (unlikely(!log_dir || !info)) {
11935+		bbox_print_err("log_dir: %p, info: %p!\n", log_dir, info);
11936+		return;
11937+	}
11938+
11939+	if (!strcmp(info->event, EVENT_PANIC) ||
11940+		!strcmp(info->event, EVENT_SYSREBOOT) ||
11941+		!strcmp(info->event, EVENT_POWEROFF)) {
11942+		struct fault_log_info *pinfo = (struct fault_log_info *)kernel_log;
11943+
11944+		if (down_trylock(&kmsg_sem) != 0) {
11945+			bbox_print_err("down_trylock failed!\n");
11946+			return;
11947+		}
11948+
11949+		if (kernel_log) {
11950+			memcpy(pinfo->flag, LOG_FLAG, strlen(LOG_FLAG));
11951+			memcpy(&pinfo->info, info, sizeof(*info));
11952+
11953+#if  __BITS_PER_LONG == 64
11954+			__flush_dcache_area(kernel_log, KERNEL_LOG_MAX_SIZE);
11955+#else
11956+			__cpuc_flush_dcache_area(kernel_log, KERNEL_LOG_MAX_SIZE);
11957+#endif
11958+		}
11959+
11960+		up(&kmsg_sem);
11961+	} else {
11962+		bbox_print_info("module [%s] starts saving log for event [%s]!\n",
11963+				info->module, info->event);
11964+		save_kmsg_from_buffer(log_dir, KERNEL_LOG_NAME, 0);
11965+		bbox_print_info("module [%s] ends saving log for event [%s]!\n",
11966+				info->module, info->event);
11967+	}
11968+}
11969+
11970+static void reset(struct error_info *info)
11971+{
11972+	if (unlikely(!info)) {
11973+		bbox_print_err("info: %p!\n", info);
11974+		return;
11975+	}
11976+
11977+	if (!strcmp(info->event, EVENT_PANIC))
11978+		emergency_restart();
11979+}
11980+
11981+static int get_last_log_info(struct error_info *info)
11982+{
11983+	struct fault_log_info *pinfo = (struct fault_log_info *)kernel_log;
11984+	int log_size = KERNEL_LOG_MAX_SIZE;
11985+
11986+	if (unlikely(!info || !kernel_log))
11987+		return -EINVAL;
11988+
11989+	if (storage_lastword->get_log((void *)kernel_log, log_size) < 0) {
11990+		bbox_print_err("Get last log from strorage failed!\n");
11991+		return -ENOENT;
11992+	}
11993+
11994+	down(&kmsg_sem);
11995+	if (!memcmp(pinfo->flag, LOG_FLAG, strlen(LOG_FLAG))) {
11996+		memcpy(info, &pinfo->info, sizeof(*info));
11997+
11998+		up(&kmsg_sem);
11999+		return 0;
12000+	}
12001+	up(&kmsg_sem);
12002+	bbox_print_info("There's no valid fault log!\n");
12003+
12004+	return -ENOMSG;
12005+}
12006+
12007+static int save_last_log(const char *log_dir, struct error_info *info)
12008+{
12009+	int ret = -1;
12010+
12011+	if (unlikely(!log_dir || !info)) {
12012+		bbox_print_err("log_dir: %p, info: %p!\n", log_dir, info);
12013+		return -EINVAL;
12014+	}
12015+
12016+	ret = save_kmsg_from_buffer(log_dir, KERNEL_LOG_NAME, 1);
12017+	bbox_print_info("save last fault log %s!\n",
12018+			ret ? "failed" : "successfully");
12019+
12020+	return ret;
12021+}
12022+
12023+static int bbox_reboot_notify(struct notifier_block *nb,
12024+					unsigned long code, void *unused)
12025+{
12026+	char error_desc[ERROR_DESC_MAX_LEN];
12027+
12028+	/* notify blackbox to do dump */
12029+	memset(error_desc, 0, sizeof(error_desc));
12030+	dump_stacktrace(error_desc, sizeof(error_desc), false);
12031+	kmsg_dump(KMSG_DUMP_UNDEF);
12032+
12033+	switch (code) {
12034+	case SYS_RESTART:
12035+		bbox_notify_error(EVENT_SYSREBOOT, MODULE_SYSTEM, error_desc, 1);
12036+		break;
12037+	case SYS_POWER_OFF:
12038+		bbox_notify_error(EVENT_POWEROFF, MODULE_SYSTEM, error_desc, 0);
12039+		break;
12040+	default:
12041+		bbox_print_err("Invalid event code: %lu!\n", code);
12042+		break;
12043+	}
12044+
12045+	return NOTIFY_DONE;
12046+}
12047+
12048+static int bbox_task_panic(struct notifier_block *this,
12049+				unsigned long event, void *ptr)
12050+{
12051+	char error_desc[ERROR_DESC_MAX_LEN];
12052+
12053+	/* notify blackbox to do dump */
12054+	kmsg_dump(KMSG_DUMP_OOPS);
12055+	memset(error_desc, 0, sizeof(error_desc));
12056+	bbox_notify_error(EVENT_PANIC, MODULE_SYSTEM, error_desc, 1);
12057+
12058+	return NOTIFY_DONE;
12059+}
12060+
12061+#ifdef CONFIG_BLACKBOX_TEST
12062+static void test_bbox(void)
12063+{
12064+	struct module_ops ops = {
12065+		.module = "TEST",
12066+		.dump = NULL,
12067+		.reset = NULL,
12068+		.get_last_log_info = NULL,
12069+		.save_last_log = NULL,
12070+	};
12071+
12072+	if (bbox_register_module_ops(&ops) != 0) {
12073+		bbox_print_err("bbox_register_module_ops failed!\n");
12074+		return -EINVAL;
12075+	}
12076+	kmsg_dump(KMSG_DUMP_OOPS);
12077+	bbox_notify_error("EVENT_TEST", "TEST", "Test bbox_notify_error", 0);
12078+
12079+}
12080+#endif
12081+
12082+static int __init blackbox_init(void)
12083+{
12084+	int ret = -1;
12085+	struct kmsg_dumper *dumper = NULL;
12086+	struct module_ops ops = {
12087+		.module = MODULE_SYSTEM,
12088+		.dump = dump,
12089+		.reset = reset,
12090+		.get_last_log_info = get_last_log_info,
12091+		.save_last_log = save_last_log,
12092+	};
12093+
12094+	if (bbox_register_module_ops(&ops) != 0) {
12095+		bbox_print_err("bbox_register_module_ops failed!\n");
12096+		return -EINVAL;
12097+	}
12098+
12099+	/* allocate buffer for kmsg */
12100+	kernel_log = kmalloc(KERNEL_LOG_MAX_SIZE, GFP_KERNEL);
12101+	if (!kernel_log)
12102+		goto __err;
12103+
12104+	bbox_print_info("kernel_log: %p for blackbox!\n", kernel_log);
12105+
12106+	if (storage_lastword->storage_log(kernel_log, KERNEL_LOG_MAX_SIZE) < 0) {
12107+		bbox_print_err("storage_log failed!\n");
12108+		goto __err;
12109+	}
12110+
12111+	/* register kdumper */
12112+	dumper = vmalloc(sizeof(*dumper));
12113+	if (!dumper)
12114+		goto __err;
12115+
12116+	memset(dumper, 0, sizeof(*dumper));
12117+	dumper->max_reason = KMSG_DUMP_MAX;
12118+	dumper->dump = storage_lastword->blackbox_dump;
12119+	ret = kmsg_dump_register(dumper);
12120+	if (ret != 0) {
12121+		bbox_print_err("kmsg_dump_register failed!\n");
12122+		goto __err;
12123+	}
12124+	atomic_notifier_chain_register(&panic_notifier_list, &bbox_panic_block);
12125+
12126+	register_reboot_notifier(&bbox_reboot_nb);
12127+#ifdef CONFIG_BLACKBOX_TEST
12128+	test_bbox();
12129+#endif
12130+	return 0;
12131+
12132+__err:
12133+	kfree(kernel_log);
12134+	kernel_log = NULL;
12135+
12136+	if (dumper) {
12137+		vfree(dumper);
12138+		dumper = NULL;
12139+	}
12140+
12141+	return ret;
12142+}
12143+
12144+postcore_initcall(blackbox_init);
12145+MODULE_LICENSE("GPL v2");
12146+MODULE_DESCRIPTION("Blackbox for system");
12147+MODULE_AUTHOR("OHOS");
12148diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
12149index c4b8df2ad..374737bd5 100644
12150--- a/arch/arm/mm/dma-mapping.c
12151+++ b/arch/arm/mm/dma-mapping.c
12152@@ -237,7 +237,7 @@ const struct dma_map_ops arm_coherent_dma_ops = {
12153 };
12154 EXPORT_SYMBOL(arm_coherent_dma_ops);
12155
12156-static void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag)
12157+void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag)
12158 {
12159 	/*
12160 	 * Ensure that the allocated pages are zeroed, and that any data
12161@@ -266,6 +266,7 @@ static void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag
12162 		}
12163 	}
12164 }
12165+EXPORT_SYMBOL(__dma_clear_buffer);
12166
12167 /*
12168  * Allocate a DMA buffer for 'dev' of size 'size' using the
12169@@ -454,6 +455,12 @@ static void __dma_remap(struct page *page, size_t size, pgprot_t prot)
12170 	flush_tlb_kernel_range(start, end);
12171 }
12172
12173+void hisi_flush_tlb_kernel_range(unsigned long start, unsigned long end)
12174+{
12175+	flush_tlb_kernel_range(start, end);
12176+}
12177+EXPORT_SYMBOL(hisi_flush_tlb_kernel_range);
12178+
12179 static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
12180 				 pgprot_t prot, struct page **ret_page,
12181 				 const void *caller, bool want_vaddr)
12182@@ -2296,6 +2303,13 @@ void arch_teardown_dma_ops(struct device *dev)
12183 	set_dma_ops(dev, NULL);
12184 }
12185
12186+void hi_dmac_map_area(const void *kaddr, size_t size,
12187+			enum dma_data_direction dir)
12188+{
12189+	dmac_map_area(kaddr, size, dir);
12190+}
12191+EXPORT_SYMBOL(hi_dmac_map_area);
12192+
12193 #ifdef CONFIG_SWIOTLB
12194 void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
12195 		enum dma_data_direction dir)
12196diff --git a/arch/arm/vdso/vgettimeofday.c b/arch/arm/vdso/vgettimeofday.c
12197old mode 100644
12198new mode 100755
12199diff --git a/arch/arm64/Makefile b/arch/arm64/Makefile
12200index 485b7dbd4..65b9f45c8 100644
12201--- a/arch/arm64/Makefile
12202+++ b/arch/arm64/Makefile
12203@@ -11,6 +11,7 @@
12204 # Copyright (C) 1995-2001 by Russell King
12205
12206 LDFLAGS_vmlinux	:=--no-undefined -X
12207+OBJCOPYFLAGS	:=-O binary -R .note -R .note.gnu.build-id -R .comment -S
12208
12209 ifeq ($(CONFIG_RELOCATABLE), y)
12210 # Pass --no-apply-dynamic-relocs to restore pre-binutils-2.27 behaviour
12211diff --git a/arch/arm64/boot/Makefile b/arch/arm64/boot/Makefile
12212index cd3414898..f3e98628b 100644
12213--- a/arch/arm64/boot/Makefile
12214+++ b/arch/arm64/boot/Makefile
12215@@ -18,12 +18,28 @@ OBJCOPYFLAGS_Image :=-O binary -R .note -R .note.gnu.build-id -R .comment -S
12216
12217 targets := Image Image.bz2 Image.gz Image.lz4 Image.lzma Image.lzo
12218
12219+dtstree := $(srctree)/$(src)/dts
12220+
12221+dtb-$(CONFIG_OF_ALL_DTBS) := $(patsubst $(dtstree)/%.dts,%.dtb, $(foreach d,$(dts-dirs), $(wildcard $(dtstree)/$(d)/*.dts)))
12222+
12223+DTB_NAMES := $(subst $\",,$(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE_NAMES))
12224+ifneq ($(DTB_NAMES),)
12225+DTB_LIST := $(addsuffix .dtb,$(DTB_NAMES))
12226+else
12227+DTB_LIST := $(dtb-y)
12228+endif
12229+
12230+DTB_OBJS := $(addprefix $(obj)/dts/,$(DTB_LIST))
12231+
12232 $(obj)/Image: vmlinux FORCE
12233 	$(call if_changed,objcopy)
12234
12235 $(obj)/Image.bz2: $(obj)/Image FORCE
12236 	$(call if_changed,bzip2)
12237
12238+$(obj)/Image-dtb: $(obj)/Image $(DTB_OBJS) FORCE
12239+	$(call if_changed,cat)
12240+
12241 $(obj)/Image.gz: $(obj)/Image FORCE
12242 	$(call if_changed,gzip)
12243
12244@@ -36,10 +52,35 @@ $(obj)/Image.lzma: $(obj)/Image FORCE
12245 $(obj)/Image.lzo: $(obj)/Image FORCE
12246 	$(call if_changed,lzo)
12247
12248-install:
12249+$(obj)/Image.gz-dtb: $(obj)/Image.gz $(DTB_OBJS) FORCE
12250+	$(call if_changed,cat)
12251+
12252+UIMAGE_LOADADDR=$(TEXT_OFFSET)
12253+UIMAGE_ENTRYADDR=$(TEXT_OFFSET)
12254+#UIMAGE_COMPRESSION = gzip
12255+check_for_multiple_loadaddr = \
12256+if [ $(words $(UIMAGE_LOADADDR)) -ne 1 ]; then \
12257+	echo 'multiple (or no) load addresses: $(UIMAGE_LOADADDR)'; \
12258+	echo 'This is incompatible with uImages'; \
12259+	echo 'Specify LOADADDR on the commandline to build an uImage'; \
12260+	false; \
12261+fi
12262+
12263+rm_uimage:
12264+	@rm -f $(obj)/uImage
12265+
12266+$(obj)/uImage: $(obj)/Image rm_uimage FORCE
12267+	@$(check_for_multiple_loadaddr)
12268+	@dd if=$< of=$<.dd ibs=4096 conv=sync && mv $<.dd $<
12269+	$(call if_changed,uimage)
12270+	$(if $(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE),@$(kecho) '  CAT   $(DTB_OBJS) to $@')
12271+	$(if $(CONFIG_BUILD_ARM64_APPENDED_DTB_IMAGE),@cat $(DTB_OBJS) >>$@,)
12272+	@$(kecho) '  Image $@ is ready'
12273+
12274+install:$(obj)/uImage
12275 	$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
12276 	$(obj)/Image System.map "$(INSTALL_PATH)"
12277
12278-zinstall:
12279+zinstall:$(obj)/uImage
12280 	$(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \
12281 	$(obj)/Image.gz System.map "$(INSTALL_PATH)"
12282diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile
12283index 9b1170658..9520bb244 100644
12284--- a/arch/arm64/boot/dts/Makefile
12285+++ b/arch/arm64/boot/dts/Makefile
12286@@ -30,3 +30,5 @@ subdir-y += ti
12287 subdir-y += toshiba
12288 subdir-y += xilinx
12289 subdir-y += zte
12290+dtbs: $(addprefix $(obj)/, $(DTB_LIST))
12291+clean-files := dts/*.dtb *.dtb
12292diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c
12293index 1006ed2d7..aa1d2f2b9 100644
12294--- a/arch/arm64/kernel/pci.c
12295+++ b/arch/arm64/kernel/pci.c
12296@@ -29,6 +29,18 @@ int pcibios_alloc_irq(struct pci_dev *dev)
12297
12298 	return 0;
12299 }
12300+#else
12301+#ifdef CONFIG_ARCH_HISI_BVT
12302+/*
12303+ * Try to assign the IRQ number when probing a new device
12304+ */
12305+int pcibios_alloc_irq(struct pci_dev *dev)
12306+{
12307+	dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
12308+
12309+	return 0;
12310+}
12311+#endif
12312 #endif
12313
12314 /*
12315diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
12316index c0a7f0d90..a5ca33ad8 100644
12317--- a/arch/arm64/mm/init.c
12318+++ b/arch/arm64/mm/init.c
12319@@ -180,6 +180,10 @@ static void __init reserve_elfcorehdr(void)
12320  */
12321 static phys_addr_t __init max_zone_phys(unsigned int zone_bits)
12322 {
12323+#ifdef CONFIG_ARCH_HISI_BVT
12324+	phys_addr_t max_dma_phys;
12325+	extern phys_addr_t hisi_get_zones_start(void);
12326+#endif
12327 	phys_addr_t zone_mask = DMA_BIT_MASK(zone_bits);
12328 	phys_addr_t phys_start = memblock_start_of_DRAM();
12329
12330@@ -188,7 +192,12 @@ static phys_addr_t __init max_zone_phys(unsigned int zone_bits)
12331 	else if (phys_start > zone_mask)
12332 		zone_mask = U32_MAX;
12333
12334+#ifdef CONFIG_ARCH_HISI_BVT
12335+	max_dma_phys = min(zone_mask, memblock_end_of_DRAM() - 1) + 1;
12336+	return min(max_dma_phys, hisi_get_zones_start());
12337+#else
12338 	return min(zone_mask, memblock_end_of_DRAM() - 1) + 1;
12339+#endif
12340 }
12341
12342 static void __init zone_sizes_init(unsigned long min, unsigned long max)
12343diff --git a/drivers/Kconfig b/drivers/Kconfig
12344index abf8938eb..2e65f9182 100644
12345--- a/drivers/Kconfig
12346+++ b/drivers/Kconfig
12347@@ -244,4 +244,11 @@ source "drivers/hooks/Kconfig"
12348
12349 source "drivers/hck/Kconfig"
12350
12351+source "drivers/hidmac/Kconfig"
12352+
12353+source "drivers/hiedmac/Kconfig"
12354+
12355+source "drivers/hisilicon/Kconfig"
12356+
12357+source "drivers/hi_vdmav100/Kconfig"
12358 endmenu
12359diff --git a/drivers/Makefile b/drivers/Makefile
12360index d9e92b5e3..e9e62665f 100644
12361--- a/drivers/Makefile
12362+++ b/drivers/Makefile
12363@@ -195,3 +195,7 @@ obj-$(CONFIG_MOST)		+= most/
12364 obj-$(CONFIG_ACCESS_TOKENID)	+= accesstokenid/
12365 obj-$(CONFIG_VENDOR_HOOKS)	+= hooks/
12366 obj-$(CONFIG_HCK_VENDOR_HOOKS)	+= hck/
12367+obj-$(CONFIG_HI_DMAC)          += hidmac/
12368+obj-$(CONFIG_HIEDMAC)          += hiedmac/
12369+obj-$(CONFIG_ARCH_HISI_BVT)    += hisilicon/
12370+obj-$(CONFIG_HI_VDMA_V100)     += hi_vdmav100/
12371diff --git a/drivers/android/binder.c b/drivers/android/binder.c
12372index 3604f0df6..2108d6686 100644
12373--- a/drivers/android/binder.c
12374+++ b/drivers/android/binder.c
12375@@ -2966,7 +2966,7 @@ static void binder_transaction(struct binder_proc *proc,
12376 				return_error = BR_FAILED_REPLY;
12377 				return_error_param = -EINVAL;
12378 				return_error_line = __LINE__;
12379-				goto err_invalid_target_handle;
12380+				//goto err_invalid_target_handle;
12381 			}
12382 		}
12383 		if (!target_node) {
12384diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
12385index 030cb32da..97d530d3e 100644
12386--- a/drivers/ata/Kconfig
12387+++ b/drivers/ata/Kconfig
12388@@ -2,6 +2,7 @@
12389 #
12390 # SATA/PATA driver configuration
12391 #
12392+source "drivers/ata/Kconfig.hiahci"
12393
12394 config HAVE_PATA_PLATFORM
12395 	bool
12396diff --git a/drivers/ata/Kconfig.hiahci b/drivers/ata/Kconfig.hiahci
12397new file mode 100644
12398index 000000000..030de3fc9
12399--- /dev/null
12400+++ b/drivers/ata/Kconfig.hiahci
12401@@ -0,0 +1,44 @@
12402+menuconfig HISI_SATA
12403+	bool "Hisilicon sata device support"
12404+	depends on (ARCH_HI3531DV200 || ARCH_HI3535AV100 || ARCH_HI3521DV200 || ARCH_HI3520DV500)
12405+	default n
12406+	select ATA
12407+	select ATA_VERBOSE_ERROR
12408+	select SATA_PMP
12409+	select SATA_AHCI_PLATFORM
12410+
12411+if HISI_SATA
12412+config HISI_SATA_IOBASE
12413+	hex "Hisi sata IO address"
12414+	default "0x10390000" if (ARCH_HI3531DV200 || ARCH_HI3535AV100)
12415+	default "0x10390000" if (ARCH_HI3521DV200 || ARCH_HI3520DV500)
12416+	help
12417+	  hisilicon sata io base address.
12418+
12419+config HISI_SATA_FBS
12420+	int "Hisi sata FIS-Based switching"
12421+	default 1
12422+	range 0 1
12423+	help
12424+	  Hisatav200 supports FBS.
12425+	  FBS is FIS-Based switching.
12426+	  Choose y if you want to use it.
12427+
12428+config HISI_SATA_NCQ
12429+	int "Hisi sata Native Command Queuing"
12430+	default 1
12431+	range 0 1
12432+	help
12433+	  Hisatav200 supports NCQ.
12434+	  NCQ is Native Command Queuing.
12435+	  Choose y if you want to use it.
12436+
12437+config HISI_ESATA
12438+	bool "Support Hisi eSATA"
12439+	default n
12440+	help
12441+	  Hisatav200 supports eSATA.
12442+	  Choose y if you want to use it.
12443+
12444+endif
12445+
12446diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
12447index b8aebfb14..f81f2d66b 100644
12448--- a/drivers/ata/Makefile
12449+++ b/drivers/ata/Makefile
12450@@ -1,6 +1,7 @@
12451 # SPDX-License-Identifier: GPL-2.0
12452
12453 obj-$(CONFIG_ATA)		+= libata.o
12454+obj-$(CONFIG_HISI_SATA)       += hisi_sata_dbg.o
12455
12456 # non-SFF interface
12457 obj-$(CONFIG_SATA_AHCI)		+= ahci.o libahci.o
12458diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h
12459index d1f284f0c..af7963b12 100644
12460--- a/drivers/ata/ahci.h
12461+++ b/drivers/ata/ahci.h
12462@@ -224,6 +224,9 @@ enum {
12463 						        error-handling stage) */
12464 	AHCI_HFLAG_NO_DEVSLP		= (1 << 17), /* no device sleep */
12465 	AHCI_HFLAG_NO_FBS		= (1 << 18), /* no FBS */
12466+#ifdef CONFIG_HISI_SATA
12467+	AHCI_HFLAG_NO_SXS		= (1 << 19), /* do not support External SATA */
12468+#endif
12469
12470 #ifdef CONFIG_PCI_MSI
12471 	AHCI_HFLAG_MULTI_MSI		= (1 << 20), /* per-port MSI(-X) */
12472@@ -346,6 +349,12 @@ struct ahci_host_priv {
12473 	struct regulator	**target_pwrs;	/* Optional */
12474 	struct regulator	*ahci_regulator;/* Optional */
12475 	struct regulator	*phy_regulator;/* Optional */
12476+#ifdef CONFIG_HISI_SATA
12477+#define PCI_AHCI 0
12478+#define ORI_AHCI 1
12479+	u32			type;
12480+#endif
12481+
12482 	/*
12483 	 * If platform uses PHYs. There is a 1:1 relation between the port number and
12484 	 * the PHY position in this array.
12485diff --git a/drivers/ata/ahci_platform.c b/drivers/ata/ahci_platform.c
12486index 3aab2e3d5..385d3d7d5 100644
12487--- a/drivers/ata/ahci_platform.c
12488+++ b/drivers/ata/ahci_platform.c
12489@@ -22,6 +22,16 @@
12490
12491 #define DRV_NAME "ahci"
12492
12493+#ifdef CONFIG_HISI_SATA_NCQ
12494+static unsigned int ncq_en = CONFIG_HISI_SATA_NCQ;
12495+module_param(ncq_en, uint, 0600);
12496+MODULE_PARM_DESC(ncq_en, "ahci ncq flag (default:1)");
12497+#endif
12498+
12499+#ifdef CONFIG_HISI_SATA
12500+extern unsigned int sata_port_map;
12501+#endif
12502+
12503 static const struct ata_port_info ahci_port_info = {
12504 	.flags		= AHCI_FLAG_COMMON,
12505 	.pio_mask	= ATA_PIO4,
12506@@ -59,8 +69,21 @@ static int ahci_probe(struct platform_device *pdev)
12507 	of_property_read_u32(dev->of_node,
12508 			     "ports-implemented", &hpriv->force_port_map);
12509
12510+#ifdef CONFIG_HISI_SATA
12511+	hpriv->type = ORI_AHCI;
12512+	hpriv->force_port_map = sata_port_map;
12513+#ifndef CONFIG_HISI_ESATA
12514+	hpriv->flags |= AHCI_HFLAG_NO_SXS;
12515+#endif
12516+
12517+#ifdef CONFIG_HISI_SATA_NCQ
12518+	if (!ncq_en)
12519+		 hpriv->flags |= AHCI_HFLAG_NO_NCQ;
12520+#endif
12521+#else
12522 	if (of_device_is_compatible(dev->of_node, "hisilicon,hisi-ahci"))
12523 		hpriv->flags |= AHCI_HFLAG_NO_FBS | AHCI_HFLAG_NO_NCQ;
12524+#endif
12525
12526 	port = acpi_device_get_match_data(dev);
12527 	if (!port)
12528diff --git a/drivers/ata/hisi_sata_dbg.c b/drivers/ata/hisi_sata_dbg.c
12529new file mode 100644
12530index 000000000..935c71689
12531--- /dev/null
12532+++ b/drivers/ata/hisi_sata_dbg.c
12533@@ -0,0 +1,174 @@
12534+/*
12535+ * Copyright (c) 2009-2014 HiSilicon Technologies Co., Ltd.
12536+ *
12537+ * This program is free software; you can redistribute it and/or modify
12538+ * it under the terms of the GNU General Public License as published by
12539+ * the Free Software Foundation; either version 2 of the License, or
12540+ * (at your option) any later version.
12541+ *
12542+ * This program is distributed in the hope that it will be useful,
12543+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12544+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12545+ * GNU General Public License for more details.
12546+ *
12547+ * You should have received a copy of the GNU General Public License
12548+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
12549+ */
12550+
12551+#include <linux/kernel.h>
12552+#include <linux/delay.h>
12553+#include <linux/module.h>
12554+#include <linux/libata.h>
12555+#include <linux/io.h>
12556+
12557+#include "ahci.h"
12558+#include "hisi_sata_dbg.h"
12559+
12560+void hisi_sata_mem_dump(unsigned int *addr, unsigned int size)
12561+{
12562+	unsigned int ix;
12563+
12564+	for (ix = 0; ix < size; ix += 0x04, addr++) {
12565+		if (!(ix & 0x0F))
12566+			pr_debug("\n0x%08X: ",
12567+				 (unsigned int)virt_to_phys(addr));
12568+		pr_debug("%08X ", *addr);
12569+	}
12570+}
12571+EXPORT_SYMBOL(hisi_sata_mem_dump);
12572+
12573+void hisi_sata_phys_mem_dump(unsigned int addr, unsigned int size)
12574+{
12575+	hisi_sata_mem_dump(phys_to_virt(addr), size);
12576+}
12577+EXPORT_SYMBOL(hisi_sata_phys_mem_dump);
12578+
12579+void hisi_ahci_reg_dump(void)
12580+{
12581+	unsigned int ix;
12582+	unsigned int regbase;
12583+
12584+	regbase = CONFIG_HISI_SATA_IOBASE;
12585+	pr_debug("AHCI GHC Register dump:");
12586+	for (ix = 0; ix <= 0x28; ix += 0x04) {
12587+		if (!(ix & 0x0F))
12588+			pr_debug("\n0x%08X: ", (regbase + ix));
12589+	}
12590+	pr_debug("\n");
12591+
12592+	regbase = CONFIG_HISI_SATA_IOBASE + 0x0100;
12593+	pr_debug("AHCI PORT 0 Register dump:");
12594+	for (ix = 0; ix <= 0x7F; ix += 0x04) {
12595+		if (!(ix & 0x0F))
12596+			pr_debug("\n0x%08X: ", (regbase + ix));
12597+	}
12598+	pr_debug("\n");
12599+}
12600+EXPORT_SYMBOL(hisi_ahci_reg_dump);
12601+
12602+void hisi_ahci_rx_fis_dump(struct ata_link *link, int pmp_port_num)
12603+{
12604+	struct ahci_port_priv *pp = NULL;
12605+
12606+	pp = link->ap->private_data;
12607+	if (NULL == pp) {
12608+		pr_debug("Error: pp=NULL\n");
12609+		return;
12610+	}
12611+	pr_debug("ACHI Received FIS:");
12612+	hisi_sata_phys_mem_dump((unsigned int)(pp->rx_fis_dma),
12613+				AHCI_RX_FIS_SZ * pmp_port_num);
12614+	pr_debug("\n");
12615+}
12616+EXPORT_SYMBOL_GPL(hisi_ahci_rx_fis_dump);
12617+
12618+void hisi_ata_taskfile_dump(struct ata_taskfile *tf)
12619+{
12620+	if (NULL == tf) {
12621+		pr_debug("Error: tf=NULL\n");
12622+		return;
12623+	}
12624+
12625+	pr_debug("Taskfile dump:\n");
12626+	pr_debug("flags:0x%08lX, protocol:0x%02X, command:0x%02X, device:0x%02X, ctl:0x%02X\n",
12627+		 tf->flags, tf->protocol, tf->command, tf->device, tf->ctl);
12628+	pr_debug("feature:0x%08X, nsect:0x%02X, lbal:0x%02X, lbam:0x%02X, lbah:0x%02X\n",
12629+		 tf->feature, tf->nsect, tf->lbal, tf->lbam, tf->lbah);
12630+	pr_debug("hob_feature:0x%08X, hob_nsect:0x%02X, hob_lbal:0x%02X, hob_lbam:0x%02X, hob_lbah:0x%02X\n",
12631+		 tf->hob_feature, tf->hob_nsect, tf->hob_lbal,
12632+		 tf->hob_lbam, tf->hob_lbah);
12633+}
12634+EXPORT_SYMBOL_GPL(hisi_ata_taskfile_dump);
12635+
12636+static void __hisi_ahci_st_md(void __iomem *addr)
12637+{
12638+	unsigned int *addr_v = NULL;
12639+	unsigned int *tmp = NULL;
12640+	unsigned int i;
12641+
12642+	addr_v = (unsigned int *)addr;
12643+
12644+	pr_debug("\n\n");
12645+	for (i = 0; i < 16; i++) {
12646+		tmp = addr_v + i * 4;
12647+		pr_debug("%8x: %8x %8x %8x %8x\n",
12648+			 (unsigned int)(uintptr_t)(addr + i * 16),
12649+			 *tmp, *(tmp + 1), *(tmp + 2), *(tmp + 3));
12650+	}
12651+
12652+	pr_debug("\n");
12653+}
12654+
12655+void hisi_ahci_st_dump(const void __iomem *port_base)
12656+{
12657+	unsigned int tmp;
12658+
12659+	pr_debug("\n**********Dmac status**********\n");
12660+	tmp = readl(port_base + 0x58);
12661+	pr_debug("txdmac_curr_st:0x%2x\n", (tmp >> 24) & 0xf);
12662+	tmp = readl(port_base + 0x64);
12663+	pr_debug("rxdmac_curr_st:0x%2x\n", (tmp >> 24) & 0xf);
12664+	tmp = readl(port_base + 0x70);
12665+	pr_debug("dmac tx fifo:count-0x%x-empty-%x-ful-%x\n",
12666+		 (tmp >> 0) & 0xff,
12667+		 (tmp >> 16) & 0x1, (tmp >> 17) & 0x1);
12668+	pr_debug("dmac rx fifo:count-0x%x-empty-%x-ful-%x\n",
12669+		 (tmp >> 8) & 0xff,
12670+		 (tmp >> 18) & 0x1, (tmp >> 19) & 0x1);
12671+
12672+	pr_debug("\n");
12673+	pr_debug("**********HBA status**********\n");
12674+	tmp = readl(port_base + 0x50);
12675+	pr_debug("pxxx_curr_st:0x%2x      ndrx_curr_st:0x%2x\n",
12676+		 (tmp >> 24) & 0xf,
12677+		 (tmp >> 16) & 0xff);
12678+	pr_debug("cfis_curr_st:0x%2x      piox_curr_st:0x%2x\n",
12679+		 (tmp >> 12) & 0xf,
12680+		 (tmp >> 8) & 0xf);
12681+	pr_debug("pmxx_curr_st:0x%2x      errx_curr_st:0x%2x\n",
12682+		 (tmp >> 4) & 0xf,
12683+		 (tmp >> 0) & 0xf);
12684+
12685+	pr_debug("\n");
12686+	pr_debug("**********Link status**********\n");
12687+	tmp = readl(port_base + 0x54);
12688+	pr_debug("link_curr_st:0x%2x\n", (tmp >> 24) & 0x1f);
12689+	pr_debug("link tx fifo:count-0x%x-empty-%x-ful-%x\n",
12690+		 (tmp >> 0) & 0x1f,
12691+		 (tmp >> 5) & 0x1, (tmp >> 6) & 0x1);
12692+	pr_debug("link rx fifo:count-0x%x-empty-%x-ful-%x\n",
12693+		 (tmp >> 8) & 0x1f,
12694+		 (tmp >> 13) & 0x1, (tmp >> 14) & 0x1);
12695+	pr_debug("link df fifo:count-0x%x-empty-%x-ful-%x\n\n",
12696+		 (tmp >> 16) & 0x1f,
12697+		 (tmp >> 21) & 0x1, (tmp >> 22) & 0x1);
12698+
12699+	pr_debug("**********CMD header**********\n");
12700+	tmp = readl(port_base + 0x0);
12701+	__hisi_ahci_st_md(phys_to_virt(tmp));
12702+	__hisi_ahci_st_md(phys_to_virt(tmp + 0x100));
12703+	__hisi_ahci_st_md(phys_to_virt(tmp + 0x200));
12704+	__hisi_ahci_st_md(phys_to_virt(tmp + 0x300));
12705+}
12706+EXPORT_SYMBOL_GPL(hisi_ahci_st_dump);
12707+
12708diff --git a/drivers/ata/hisi_sata_dbg.h b/drivers/ata/hisi_sata_dbg.h
12709new file mode 100644
12710index 000000000..5103658a4
12711--- /dev/null
12712+++ b/drivers/ata/hisi_sata_dbg.h
12713@@ -0,0 +1,58 @@
12714+/*
12715+ * Copyright (c) 2009-2014 HiSilicon Technologies Co., Ltd.
12716+ *
12717+ * This program is free software; you can redistribute it and/or modify
12718+ * it under the terms of the GNU General Public License as published by
12719+ * the Free Software Foundation; either version 2 of the License, or
12720+ * (at your option) any later version.
12721+ *
12722+ * This program is distributed in the hope that it will be useful,
12723+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
12724+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12725+ * GNU General Public License for more details.
12726+ *
12727+ * You should have received a copy of the GNU General Public License
12728+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
12729+ */
12730+
12731+#ifndef _HISI_SATA_DBG_H
12732+#define _HISI_SATA_DBG_H
12733+#include <linux/kernel.h>
12734+#include <linux/delay.h>
12735+#include <linux/libata.h>
12736+#include "ahci.h"
12737+
12738+void hisi_sata_mem_dump(unsigned int *addr, unsigned int size);
12739+void hisi_sata_phys_mem_dump(unsigned int addr, unsigned int size);
12740+void hisi_ahci_rx_fis_dump(struct ata_link *link, int pmp_port_num);
12741+void hisi_ata_taskfile_dump(struct ata_taskfile *tf);
12742+void hisi_ahci_st_dump(const void __iomem *port_base);
12743+void hisi_ahci_reg_dump(void);
12744+
12745+#define HISI_AHCI_REG_DUMP(X) \
12746+do { \
12747+	pr_debug("------------------[ Start ]--------------------\n"); \
12748+	pr_debug("Dump AHCI registers at %s %d\n", __func__, __LINE__); \
12749+	hisi_ahci_reg_dump(); \
12750+	pr_debug("------------------[  End  ]--------------------\n"); \
12751+} while (0)
12752+
12753+#define hisi_sata_readl(addr) do { \
12754+		unsigned int reg = readl((unsigned int)addr); \
12755+		pr_debug("HI_AHCI(REG) %s:%d: readl(0x%08X) = 0x%08X\n", \
12756+		__func__, __LINE__, (unsigned int)addr, reg); \
12757+		reg; \
12758+	} while (0)
12759+
12760+#define hisi_sata_writel(v, addr) do { writel(v, (unsigned int)addr); \
12761+	pr_debug("HI_AHCI(REG) %s:%d: writel(0x%08X) = 0x%08X\n", \
12762+		__func__, __LINE__, (unsigned int)addr, \
12763+		(unsigned int)(v)); \
12764+	} while (0)
12765+
12766+#undef HISI_DUMP_AHCI_REG_OPS
12767+#ifdef HISI_DUMP_AHCI_REG_OPS
12768+#define readl(addr) hisi_sata_readl(addr)
12769+#define write(v, addr) hisi_sata_writel(v, addr)
12770+#endif
12771+#endif /* _HISI_SATA_DBG_H */
12772diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
12773index fec2e9754..bff99aebd 100644
12774--- a/drivers/ata/libahci.c
12775+++ b/drivers/ata/libahci.c
12776@@ -31,6 +31,7 @@
12777 #include <linux/pci.h>
12778 #include "ahci.h"
12779 #include "libata.h"
12780+#include "hisi_sata_dbg.h"
12781
12782 static int ahci_skip_host_reset;
12783 int ahci_ignore_sss;
12784@@ -42,6 +43,33 @@ MODULE_PARM_DESC(skip_host_reset, "skip global host reset (0=don't skip, 1=skip)
12785 module_param_named(ignore_sss, ahci_ignore_sss, int, 0444);
12786 MODULE_PARM_DESC(ignore_sss, "Ignore staggered spinup flag (0=don't ignore, 1=ignore)");
12787
12788+#ifdef CONFIG_HISI_SATA_FBS
12789+static int fbs_en = CONFIG_HISI_SATA_FBS;
12790+module_param(fbs_en, uint, 0600);
12791+MODULE_PARM_DESC(fbs_en, "ahci fbs flags (default:1)");
12792+
12793+#define AHCI_TIMEOUT_COUNT	10
12794+#define AHCI_POLL_TIMER		(20 * HZ)
12795+
12796+struct ata_fbs_ctrl {
12797+	unsigned int fbs_enable_ctrl; /* fbs enable or disable control switch */
12798+	unsigned int fbs_mode_ctrl;   /* 1.5G: fbs disable, 3G/6G: fbs enable */
12799+	unsigned int fbs_enable_flag;
12800+	unsigned int fbs_disable_flag;
12801+	unsigned int fbs_cmd_issue_flag;
12802+	struct timer_list poll_timer;
12803+#ifdef CONFIG_HISI_SATA
12804+	struct ata_port *ap;
12805+#endif
12806+};
12807+static struct ata_fbs_ctrl fbs_ctrl[4];
12808+extern void hisi_sata_set_fifoth(void *mmio);
12809+#endif
12810+#ifdef CONFIG_HISI_SATA
12811+extern void hisi_sata_reset_rxtx_assert(unsigned int port_no);
12812+extern void hisi_sata_reset_rxtx_deassert(unsigned int port_no);
12813+#endif
12814+
12815 static int ahci_set_lpm(struct ata_link *link, enum ata_lpm_policy policy,
12816 			unsigned hints);
12817 static ssize_t ahci_led_show(struct ata_port *ap, char *buf);
12818@@ -460,6 +488,13 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)
12819 		cap |= HOST_CAP_NCQ;
12820 	}
12821
12822+#ifdef CONFIG_HISI_SATA
12823+	if ((cap & HOST_CAP_SXS) && (hpriv->flags & AHCI_HFLAG_NO_SXS)) {
12824+		dev_info(dev, "controller can't support eSATA, turning off CAP_SXS\n");
12825+		cap &= ~HOST_CAP_SXS;
12826+	}
12827+#endif
12828+
12829 	if ((cap & HOST_CAP_PMP) && (hpriv->flags & AHCI_HFLAG_NO_PMP)) {
12830 		dev_info(dev, "controller can't do PMP, turning off CAP_PMP\n");
12831 		cap &= ~HOST_CAP_PMP;
12832@@ -1396,8 +1431,28 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
12833 	bool fbs_disabled = false;
12834 	int rc;
12835
12836+#ifdef CONFIG_HISI_SATA_FBS
12837+	unsigned int port_num = ap->port_no;
12838+#endif
12839+
12840 	DPRINTK("ENTER\n");
12841
12842+#ifdef CONFIG_HISI_SATA_FBS
12843+	if (fbs_ctrl[port_num].fbs_enable_ctrl &&
12844+			(link->pmp == SATA_PMP_CTRL_PORT) &&
12845+			(hpriv->type == ORI_AHCI)) {
12846+		struct ahci_port_priv *pp = ap->private_data;
12847+
12848+		if (pp->fbs_enabled == false)
12849+			ahci_enable_fbs(ap);
12850+
12851+		fbs_ctrl[port_num].fbs_enable_flag = 0;
12852+		fbs_ctrl[port_num].fbs_disable_flag = 0;
12853+		fbs_ctrl[port_num].fbs_cmd_issue_flag = 0;
12854+
12855+	}
12856+#endif
12857+
12858 	/* prepare for SRST (AHCI-1.1 10.4.1) */
12859 	rc = ahci_kick_engine(ap);
12860 	if (rc && rc != -EOPNOTSUPP)
12861@@ -1426,6 +1481,10 @@ int ahci_do_softreset(struct ata_link *link, unsigned int *class,
12862 				 AHCI_CMD_RESET | AHCI_CMD_CLR_BUSY, msecs)) {
12863 		rc = -EIO;
12864 		reason = "1st FIS failed";
12865+#ifdef CONFIG_HISI_SATA
12866+		hisi_sata_reset_rxtx_assert(ap->port_no);
12867+		hisi_sata_reset_rxtx_deassert(ap->port_no);
12868+#endif
12869 		goto fail;
12870 	}
12871
12872@@ -1623,6 +1682,68 @@ static int ahci_pmp_qc_defer(struct ata_queued_cmd *qc)
12873 	struct ata_port *ap = qc->ap;
12874 	struct ahci_port_priv *pp = ap->private_data;
12875
12876+#ifdef CONFIG_HISI_SATA_FBS
12877+	struct ahci_host_priv *hpriv = ap->host->private_data;
12878+	int is_atapi = ata_is_atapi(qc->tf.protocol);
12879+	void __iomem *port_mmio = ahci_port_base(ap);
12880+	unsigned int port_num = ap->port_no;
12881+	unsigned int cmd_timeout_count;
12882+
12883+	if (fbs_ctrl[port_num].fbs_enable_ctrl &&
12884+			(ap->link.pmp == SATA_PMP_CTRL_PORT) &&
12885+			(hpriv->type == ORI_AHCI)) {
12886+		if (is_atapi || fbs_ctrl[ap->port_no].fbs_cmd_issue_flag) {
12887+			mod_timer(&fbs_ctrl[port_num].poll_timer,
12888+					jiffies + AHCI_POLL_TIMER);
12889+
12890+			if (!fbs_ctrl[port_num].fbs_disable_flag) {
12891+				cmd_timeout_count = 0;
12892+				while (readl(port_mmio + PORT_SCR_ACT)
12893+						|| readl(port_mmio
12894+							+ PORT_CMD_ISSUE)
12895+						|| readl(port_mmio
12896+							+ PORT_IRQ_STAT)) {
12897+					cmd_timeout_count++;
12898+					if (cmd_timeout_count >=
12899+							AHCI_TIMEOUT_COUNT) {
12900+						fbs_ctrl[ap->port_no].
12901+							fbs_cmd_issue_flag = 1;
12902+						return ATA_DEFER_LINK;
12903+					}
12904+				}
12905+
12906+				if (pp->fbs_enabled == true)
12907+					ahci_disable_fbs(ap);
12908+
12909+				ap->excl_link = NULL;
12910+				ap->nr_active_links = 0;
12911+				fbs_ctrl[port_num].fbs_disable_flag = 1;
12912+				fbs_ctrl[port_num].fbs_enable_flag = 0;
12913+				fbs_ctrl[ap->port_no].fbs_cmd_issue_flag = 0;
12914+			}
12915+		} else {
12916+			if (fbs_ctrl[port_num].fbs_enable_flag) {
12917+				cmd_timeout_count = 0;
12918+				while (readl(port_mmio + PORT_SCR_ACT)
12919+						|| readl(port_mmio
12920+							+ PORT_CMD_ISSUE)
12921+						|| readl(port_mmio
12922+							+ PORT_IRQ_STAT)) {
12923+					cmd_timeout_count++;
12924+					if (cmd_timeout_count >=
12925+							AHCI_TIMEOUT_COUNT) {
12926+						return ATA_DEFER_LINK;
12927+					}
12928+				}
12929+
12930+				if (pp->fbs_enabled == false)
12931+					ahci_enable_fbs(ap);
12932+				fbs_ctrl[port_num].fbs_enable_flag = 0;
12933+				fbs_ctrl[port_num].fbs_disable_flag = 0;
12934+			}
12935+		}
12936+	}
12937+#endif
12938 	if (!sata_pmp_attached(ap) || pp->fbs_enabled)
12939 		return ata_std_qc_defer(qc);
12940 	else
12941@@ -1669,6 +1790,7 @@ static enum ata_completion_errors ahci_qc_prep(struct ata_queued_cmd *qc)
12942 	return AC_ERR_OK;
12943 }
12944
12945+#ifndef CONFIG_HISI_SATA_FBS
12946 static void ahci_fbs_dec_intr(struct ata_port *ap)
12947 {
12948 	struct ahci_port_priv *pp = ap->private_data;
12949@@ -1692,6 +1814,7 @@ static void ahci_fbs_dec_intr(struct ata_port *ap)
12950 	if (fbs & PORT_FBS_DEC)
12951 		dev_err(ap->host->dev, "failed to clear device error\n");
12952 }
12953+#endif
12954
12955 static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
12956 {
12957@@ -1799,7 +1922,9 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
12958 		ata_port_freeze(ap);
12959 	else if (fbs_need_dec) {
12960 		ata_link_abort(link);
12961+#ifndef CONFIG_HISI_SATA_FBS
12962 		ahci_fbs_dec_intr(ap);
12963+#endif
12964 	} else
12965 		ata_port_abort(ap);
12966 }
12967@@ -2200,7 +2325,9 @@ static void ahci_enable_fbs(struct ata_port *ap)
12968 	writel(fbs | PORT_FBS_EN, port_mmio + PORT_FBS);
12969 	fbs = readl(port_mmio + PORT_FBS);
12970 	if (fbs & PORT_FBS_EN) {
12971+#ifndef CONFIG_HISI_SATA_FBS
12972 		dev_info(ap->host->dev, "FBS is enabled\n");
12973+#endif
12974 		pp->fbs_enabled = true;
12975 		pp->fbs_last_dev = -1; /* initialization */
12976 	} else
12977@@ -2240,6 +2367,9 @@ static void ahci_disable_fbs(struct ata_port *ap)
12978 	}
12979
12980 	hpriv->start_engine(ap);
12981+#ifdef CONFIG_HISI_SATA_FBS
12982+	hisi_sata_set_fifoth(port_mmio);
12983+#endif
12984 }
12985
12986 static void ahci_pmp_attach(struct ata_port *ap)
12987@@ -2248,12 +2378,24 @@ static void ahci_pmp_attach(struct ata_port *ap)
12988 	struct ahci_port_priv *pp = ap->private_data;
12989 	u32 cmd;
12990
12991+#ifdef CONFIG_HISI_SATA_FBS
12992+	struct ahci_host_priv *hpriv = ap->host->private_data;
12993+	unsigned int port_num = ap->port_no;
12994+#endif
12995+
12996 	cmd = readl(port_mmio + PORT_CMD);
12997 	cmd |= PORT_CMD_PMP;
12998 	writel(cmd, port_mmio + PORT_CMD);
12999
13000 	ahci_enable_fbs(ap);
13001
13002+#ifdef CONFIG_HISI_SATA_FBS
13003+	if (hpriv->type == ORI_AHCI) {
13004+		if (!fbs_ctrl[port_num].fbs_enable_ctrl)
13005+			ahci_disable_fbs(ap);
13006+	}
13007+#endif
13008+
13009 	pp->intr_mask |= PORT_IRQ_BAD_PMP;
13010
13011 	/*
13012@@ -2322,6 +2464,32 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
13013 }
13014 #endif
13015
13016+#ifdef CONFIG_HISI_SATA_FBS
13017+static void ahci_poll_func(unsigned long arg)
13018+{
13019+	struct ata_port *ap = (struct ata_port *)arg;
13020+	unsigned int port_num = ap->port_no;
13021+
13022+	if (ap->link.pmp == SATA_PMP_CTRL_PORT) {
13023+		fbs_ctrl[port_num].fbs_enable_flag = 1;
13024+		fbs_ctrl[port_num].fbs_disable_flag = 0;
13025+	}
13026+}
13027+
13028+static void ahci_poll_timerout(struct timer_list *t)
13029+{
13030+	struct ata_fbs_ctrl *ata_fbs_ctrl_ptr = from_timer(ata_fbs_ctrl_ptr, t, poll_timer);
13031+	struct ata_port *ap = ata_fbs_ctrl_ptr->ap;
13032+
13033+	if (ap == NULL) {
13034+		pr_err("%s:poll_timer parameter is error!\n", __func__);
13035+		return;
13036+	}
13037+
13038+	ahci_poll_func((uintptr_t)ap);
13039+}
13040+#endif
13041+
13042 static int ahci_port_start(struct ata_port *ap)
13043 {
13044 	struct ahci_host_priv *hpriv = ap->host->private_data;
13045@@ -2414,6 +2582,19 @@ static int ahci_port_start(struct ata_port *ap)
13046
13047 	ap->private_data = pp;
13048
13049+#ifdef CONFIG_HISI_SATA_FBS
13050+	if (hpriv->type == ORI_AHCI) {
13051+		fbs_ctrl[ap->port_no].fbs_enable_ctrl = fbs_en;
13052+		fbs_ctrl[ap->port_no].fbs_enable_flag = 0;
13053+		fbs_ctrl[ap->port_no].fbs_disable_flag = 0;
13054+		fbs_ctrl[ap->port_no].fbs_cmd_issue_flag = 0;
13055+		fbs_ctrl[ap->port_no].ap = ap;
13056+
13057+		timer_setup(&fbs_ctrl[ap->port_no].poll_timer, ahci_poll_timerout, 0);
13058+		fbs_ctrl[ap->port_no].poll_timer.expires = jiffies + AHCI_POLL_TIMER;
13059+	}
13060+#endif
13061+
13062 	/* engage engines, captain */
13063 	return ahci_port_resume(ap);
13064 }
13065diff --git a/drivers/block/paride/pcd.c b/drivers/block/paride/pcd.c
13066index 70da8b86c..5725b026b 100644
13067--- a/drivers/block/paride/pcd.c
13068+++ b/drivers/block/paride/pcd.c
13069@@ -1031,6 +1031,9 @@ static int __init pcd_init(void)
13070 	}
13071
13072 	for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
13073+		if (!cd->disk)
13074+			continue;
13075+
13076 		if (cd->present) {
13077 			register_cdrom(cd->disk, &cd->info);
13078 			cd->disk->private_data = cd;
13079diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
13080index da8fcf147..04bbcd945 100644
13081--- a/drivers/clk/Makefile
13082+++ b/drivers/clk/Makefile
13083@@ -82,6 +82,7 @@ obj-$(CONFIG_ARCH_BERLIN)		+= berlin/
13084 obj-$(CONFIG_ARCH_DAVINCI)		+= davinci/
13085 obj-$(CONFIG_H8300)			+= h8300/
13086 obj-$(CONFIG_ARCH_HISI)			+= hisilicon/
13087+obj-$(CONFIG_ARCH_HISI_BVT)		+= hisilicon/
13088 obj-y					+= imgtec/
13089 obj-y					+= imx/
13090 obj-y					+= ingenic/
13091diff --git a/drivers/clk/hisilicon/Kconfig b/drivers/clk/hisilicon/Kconfig
13092index 6a9e93a0b..4d212e5a1 100644
13093--- a/drivers/clk/hisilicon/Kconfig
13094+++ b/drivers/clk/hisilicon/Kconfig
13095@@ -22,6 +22,38 @@ config COMMON_CLK_HI3660
13096 	help
13097 	  Build the clock driver for hi3660.
13098
13099+config COMMON_CLK_HI3531DV200
13100+	tristate "Hi3531DV200 Clock Driver"
13101+	depends on ARCH_HI3531DV200 || COMPILE_TEST
13102+	select RESET_HISI
13103+	default ARCH_HISI_BVT
13104+	help
13105+	  Build the clock driver for Hi3531DV200.
13106+
13107+config COMMON_CLK_HI3535AV100
13108+	tristate "Hi3535AV100 Clock Driver"
13109+	depends on ARCH_HI3535AV100 || COMPILE_TEST
13110+	select RESET_HISI
13111+	default ARCH_HISI_BVT
13112+	help
13113+	  Build the clock driver for Hi3535AV100.
13114+
13115+config COMMON_CLK_HI3521DV200
13116+	tristate "Hi3521DV200 Clock Driver"
13117+	depends on ARCH_HI3521DV200 || COMPILE_TEST
13118+	select RESET_HISI
13119+	default ARCH_HISI_BVT
13120+	help
13121+	  Build the clock driver for hi3521DV200.
13122+
13123+config COMMON_CLK_HI3520DV500
13124+	tristate "Hi3520DV500 Clock Driver"
13125+	depends on ARCH_HI3520DV500 || COMPILE_TEST
13126+	select RESET_HISI
13127+	default ARCH_HISI_BVT
13128+	help
13129+	  Build the clock driver for hi3520DV500.
13130+
13131 config COMMON_CLK_HI3670
13132 	bool "Hi3670 Clock Driver"
13133 	depends on ARCH_HISI || COMPILE_TEST
13134@@ -37,6 +69,166 @@ config COMMON_CLK_HI3798CV200
13135 	help
13136 	  Build the clock driver for hi3798cv200.
13137
13138+config COMMON_CLK_HI3516A
13139+	tristate "Hi3516A Clock Driver"
13140+	depends on ARCH_HI3516A || COMPILE_TEST
13141+	select RESET_HISI
13142+	default ARCH_HISI
13143+	help
13144+	  Build the clock driver for hi3516A.
13145+
13146+config COMMON_CLK_HI3516CV500
13147+	tristate "Hi3516CV500 Clock Driver"
13148+	depends on ARCH_HI3516CV500 || COMPILE_TEST
13149+	select RESET_HISI
13150+	default ARCH_HISI_BVT
13151+	help
13152+	  Build the clock driver for hi3516CV500.
13153+
13154+config COMMON_CLK_HI3516EV200
13155+	tristate "Hi3516EV200 Clock Driver"
13156+	depends on ARCH_HI3516EV200 || COMPILE_TEST
13157+	select RESET_HISI
13158+	default ARCH_HISI
13159+	help
13160+	  Build the clock driver for hi3516EV200.
13161+
13162+config COMMON_CLK_HI3516EV300
13163+	tristate "Hi3516EV300 Clock Driver"
13164+	depends on ARCH_HI3516EV300 || COMPILE_TEST
13165+	select RESET_HISI
13166+	default ARCH_HISI
13167+	help
13168+	  Build the clock driver for hi3516EV300.
13169+
13170+config COMMON_CLK_HI3518EV300
13171+	tristate "Hi3518EV300 Clock Driver"
13172+	depends on ARCH_HI3518EV300 || COMPILE_TEST
13173+	select RESET_HISI
13174+	default ARCH_HISI
13175+	help
13176+	  Build the clock driver for hi3518EV300.
13177+
13178+config COMMON_CLK_HI3516DV200
13179+	tristate "Hi3516DV200 Clock Driver"
13180+	depends on ARCH_HI3516DV200 || COMPILE_TEST
13181+	select RESET_HISI
13182+	default ARCH_HISI
13183+	help
13184+	  Build the clock driver for hi3516DV200.
13185+
13186+config COMMON_CLK_HI3516DV300
13187+	tristate "Hi3516DV300 Clock Driver"
13188+	depends on ARCH_HI3516DV300 || COMPILE_TEST
13189+	select RESET_HISI
13190+	default ARCH_HISI_BVT
13191+	help
13192+	  Build the clock driver for hi3516DV300.
13193+
13194+config COMMON_CLK_HI3556V200
13195+	tristate "Hi3556V200 Clock Driver"
13196+	depends on ARCH_HI3556V200 || COMPILE_TEST
13197+	select RESET_HISI
13198+	default ARCH_HISI_BVT
13199+	help
13200+	  Build the clock driver for hi3556V200.
13201+
13202+config COMMON_CLK_HI3559V200
13203+	tristate "Hi3559V200 Clock Driver"
13204+	depends on ARCH_HI3559V200 || COMPILE_TEST
13205+	select RESET_HISI
13206+	default ARCH_HISI_BVT
13207+	help
13208+	  Build the clock driver for hi3559V200.
13209+
13210+config COMMON_CLK_HI3562V100
13211+	tristate "Hi3562V100 Clock Driver"
13212+	depends on ARCH_HI3562V100 || COMPILE_TEST
13213+	select RESET_HISI
13214+	default ARCH_HISI_BVT
13215+	help
13216+	  Build the clock driver for hi3562V100.
13217+
13218+config COMMON_CLK_HI3566V100
13219+	tristate "Hi3566V100 Clock Driver"
13220+	depends on ARCH_HI3566V100 || COMPILE_TEST
13221+	select RESET_HISI
13222+	default ARCH_HISI_BVT
13223+	help
13224+	  Build the clock driver for hi3566V100.
13225+
13226+config COMMON_CLK_HI3518EV20X
13227+	tristate "Hi3518EV20X Clock Driver"
13228+	depends on ARCH_HI3518EV20X || COMPILE_TEST
13229+	select RESET_HISI
13230+	default ARCH_HISI_BVT
13231+	help
13232+	  Build the clock driver for hi3516A.
13233+
13234+config COMMON_CLK_HI3536DV100
13235+	tristate "Hi3536DV100 Clock Driver"
13236+	depends on ARCH_HI3536DV100 || COMPILE_TEST
13237+	select RESET_HISI
13238+	default ARCH_HISI
13239+	help
13240+	  Build the clock driver for hi3536DV100.
13241+
13242+config COMMON_CLK_HI3559AV100
13243+	tristate "Hi3559AV100 Clock Driver"
13244+	depends on ARCH_HI3559AV100 || COMPILE_TEST
13245+	select RESET_HISI
13246+	default ARCH_HISI_BVT
13247+	help
13248+	  Build the clock driver for hi3559av100.
13249+
13250+config COMMON_CLK_HI3569V100
13251+	tristate "Hi3569V100 Clock Driver"
13252+	depends on ARCH_HI3569V100 || COMPILE_TEST
13253+	select RESET_HISI
13254+	default ARCH_HISI_BVT
13255+	help
13256+	  Build the clock driver for hi3569v100.
13257+
13258+config COMMON_CLK_HI3521A
13259+	tristate "Hi3521A Clock Driver"
13260+	depends on ARCH_HI3521A || COMPILE_TEST
13261+	select RESET_HISI
13262+	default ARCH_HISI_BVT
13263+	help
13264+	  Build the clock driver for hi3521A.
13265+
13266+config COMMON_CLK_HI3531A
13267+	tristate "Hi3531A Clock Driver"
13268+	depends on ARCH_HI3531A || COMPILE_TEST
13269+	select RESET_HISI
13270+	default ARCH_HISI_BVT
13271+	help
13272+	  Build the clock driver for hi3531A.
13273+
13274+config COMMON_CLK_HI3556AV100
13275+	tristate "Hi3556AV100 Clock Driver"
13276+	depends on ARCH_HI3556AV100 || COMPILE_TEST
13277+	select RESET_HISI
13278+	default ARCH_HISI
13279+	help
13280+	  Build the clock driver for hi3556av100.
13281+
13282+config COMMON_CLK_HI3519AV100
13283+	tristate "Hi3519AV100 Clock Driver"
13284+	depends on ARCH_HI3519AV100 || COMPILE_TEST
13285+	select RESET_HISI
13286+	default ARCH_HISI
13287+	help
13288+	  Build the clock driver for hi3519av100.
13289+
13290+config COMMON_CLK_HI3568V100
13291+	tristate "Hi3568V100 Clock Driver"
13292+	depends on ARCH_HI3568V100 || COMPILE_TEST
13293+	select RESET_HISI
13294+	default ARCH_HISI
13295+	help
13296+	  Build the clock driver for hi3568v100.
13297+
13298 config COMMON_CLK_HI6220
13299 	bool "Hi6220 Clock Driver"
13300 	depends on ARCH_HISI || COMPILE_TEST
13301@@ -46,7 +238,7 @@ config COMMON_CLK_HI6220
13302
13303 config RESET_HISI
13304 	bool "HiSilicon Reset Controller Driver"
13305-	depends on ARCH_HISI || COMPILE_TEST
13306+	depends on ARCH_HISI || COMPILE_TEST || ARCH_HISI_BVT
13307 	select RESET_CONTROLLER
13308 	help
13309 	  Build reset controller driver for HiSilicon device chipsets.
13310diff --git a/drivers/clk/hisilicon/Makefile b/drivers/clk/hisilicon/Makefile
13311index b2441b99f..91dc23fdb 100644
13312--- a/drivers/clk/hisilicon/Makefile
13313+++ b/drivers/clk/hisilicon/Makefile
13314@@ -14,6 +14,7 @@ obj-$(CONFIG_COMMON_CLK_HI3660) += clk-hi3660.o
13315 obj-$(CONFIG_COMMON_CLK_HI3670) += clk-hi3670.o
13316 obj-$(CONFIG_COMMON_CLK_HI3798CV200)	+= crg-hi3798cv200.o
13317 obj-$(CONFIG_COMMON_CLK_HI6220)	+= clk-hi6220.o
13318+obj-$(CONFIG_COMMON_CLK_HI3516DV300)  += clk-hi3516dv300.o
13319 obj-$(CONFIG_RESET_HISI)	+= reset.o
13320 obj-$(CONFIG_STUB_CLK_HI6220)	+= clk-hi6220-stub.o
13321 obj-$(CONFIG_STUB_CLK_HI3660)	+= clk-hi3660-stub.o
13322diff --git a/drivers/clk/hisilicon/clk-hi3516dv300.c b/drivers/clk/hisilicon/clk-hi3516dv300.c
13323new file mode 100644
13324index 000000000..1a2ab9975
13325--- /dev/null
13326+++ b/drivers/clk/hisilicon/clk-hi3516dv300.c
13327@@ -0,0 +1,271 @@
13328+/*
13329+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
13330+ *
13331+ * This program is free software; you can redistribute  it and/or modify it
13332+ * under  the terms of  the GNU General Public License as published by the
13333+ * Free Software Foundation;  either version 2 of the  License, or (at your
13334+ * option) any later version.
13335+ *
13336+ * This program is distributed in the hope that it will be useful,
13337+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13338+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13339+ * GNU General Public License for more details.
13340+ *
13341+ * You should have received a copy of the GNU General Public License
13342+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
13343+ *
13344+ */
13345+
13346+#include <dt-bindings/clock/hi3516dv300-clock.h>
13347+#include <linux/clk-provider.h>
13348+#include <linux/module.h>
13349+#include <linux/of_device.h>
13350+#include <linux/platform_device.h>
13351+#include "clk.h"
13352+#include "crg.h"
13353+#include "reset.h"
13354+
13355+static struct hisi_fixed_rate_clock hi3516dv300_fixed_rate_clks[] __initdata = {
13356+	{ HI3516DV300_FIXED_3M, "3m", NULL, 0, 3000000, },
13357+	{ HI3516DV300_FIXED_6M, "6m", NULL, 0, 6000000, },
13358+	{ HI3516DV300_FIXED_12M, "12m", NULL, 0, 12000000, },
13359+	{ HI3516DV300_FIXED_24M, "24m", NULL, 0, 24000000, },
13360+	{ HI3516DV300_FIXED_25M, "25m", NULL, 0, 25000000, },
13361+	{ HI3516DV300_FIXED_50M, "50m", NULL, 0, 50000000, },
13362+	{ HI3516DV300_FIXED_54M, "54m", NULL, 0, 54000000, },
13363+	{ HI3516DV300_FIXED_83P3M, "83.3m", NULL, 0, 83300000, },
13364+	{ HI3516DV300_FIXED_100M, "100m", NULL, 0, 100000000, },
13365+	{ HI3516DV300_FIXED_125M, "125m", NULL, 0, 125000000, },
13366+	{ HI3516DV300_FIXED_150M, "150m", NULL, 0, 150000000, },
13367+	{ HI3516DV300_FIXED_163M, "163m", NULL, 0, 163000000, },
13368+	{ HI3516DV300_FIXED_200M, "200m", NULL, 0, 200000000, },
13369+	{ HI3516DV300_FIXED_250M, "250m", NULL, 0, 250000000, },
13370+	{ HI3516DV300_FIXED_257M, "257m", NULL, 0, 257000000, },
13371+	{ HI3516DV300_FIXED_300M, "300m", NULL, 0, 300000000, },
13372+	{ HI3516DV300_FIXED_324M, "324m", NULL, 0, 324000000, },
13373+	{ HI3516DV300_FIXED_342M, "342m", NULL, 0, 342000000, },
13374+	{ HI3516DV300_FIXED_342M, "375m", NULL, 0, 375000000, },
13375+	{ HI3516DV300_FIXED_396M, "396m", NULL, 0, 396000000, },
13376+	{ HI3516DV300_FIXED_400M, "400m", NULL, 0, 400000000, },
13377+	{ HI3516DV300_FIXED_448M, "448m", NULL, 0, 448000000, },
13378+	{ HI3516DV300_FIXED_500M, "500m", NULL, 0, 500000000, },
13379+	{ HI3516DV300_FIXED_540M, "540m", NULL, 0, 540000000, },
13380+	{ HI3516DV300_FIXED_600M, "600m", NULL, 0, 600000000, },
13381+	{ HI3516DV300_FIXED_750M, "750m", NULL, 0, 750000000, },
13382+	{ HI3516DV300_FIXED_1000M, "1000m", NULL, 0, 1000000000, },
13383+	{ HI3516DV300_FIXED_1500M, "1500m", NULL, 0, 1500000000UL, },
13384+};
13385+
13386+static const char *sysaxi_mux_p[] __initconst = {
13387+	"24m", "200m", "300m"
13388+};
13389+static const char *sysapb_mux_p[] __initconst = {"24m", "50m"};
13390+static const char *uart_mux_p[] __initconst = {"24m", "6m"};
13391+static const char *fmc_mux_p[] __initconst = {"24m", "100m", "150m", "163m", "200m", "257m", "300m", "396m"};
13392+static const char *eth_mux_p[] __initconst = {"100m", "54m"};
13393+static const char *mmc_mux_p[] __initconst = {"100m", "50m", "25m"};
13394+static const char *pwm_mux_p[] __initconst = {"3m", "50m", "24m", "24m"};
13395+
13396+static u32 sysaxi_mux_table[] = {0, 1, 2};
13397+static u32 sysapb_mux_table[] = {0, 1};
13398+static u32 uart_mux_table[] = {0, 1};
13399+static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7};
13400+static u32 eth_mux_table[] = {0, 1};
13401+static u32 mmc_mux_table[] = {1, 2, 3};
13402+static u32 pwm_mux_table[] = {0, 1, 2, 3};
13403+
13404+static struct hisi_mux_clock hi3516dv300_mux_clks[] __initdata = {
13405+	{
13406+		HI3516DV300_SYSAXI_CLK, "sysaxi_mux", sysaxi_mux_p,
13407+		ARRAY_SIZE(sysaxi_mux_p),
13408+		CLK_SET_RATE_PARENT, 0x80, 6, 2, 0, sysaxi_mux_table,
13409+	},
13410+	{
13411+		HI3516DV300_SYSAPB_CLK, "sysapb_mux", sysapb_mux_p,
13412+		ARRAY_SIZE(sysapb_mux_p),
13413+		CLK_SET_RATE_PARENT, 0x80, 10, 1, 0, sysapb_mux_table,
13414+	},
13415+	{
13416+		HI3516DV300_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p),
13417+		CLK_SET_RATE_PARENT, 0x144, 2, 3, 0, fmc_mux_table,
13418+	},
13419+	{
13420+		HI3516DV300_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p),
13421+		CLK_SET_RATE_PARENT, 0x148, 2, 2, 0, mmc_mux_table,
13422+	},
13423+	{
13424+		HI3516DV300_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p),
13425+		CLK_SET_RATE_PARENT, 0x160, 2, 2, 0, mmc_mux_table,
13426+	},
13427+	{
13428+		HI3516DV300_MMC2_MUX, "mmc2_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p),
13429+		CLK_SET_RATE_PARENT, 0x154, 2, 2, 0, mmc_mux_table,
13430+	},
13431+	{
13432+		HI3516DV300_UART_MUX, "uart_mux0", uart_mux_p,
13433+		ARRAY_SIZE(uart_mux_p),
13434+		CLK_SET_RATE_PARENT, 0x1bc, 18, 1, 0, uart_mux_table,
13435+	},
13436+	{
13437+		HI3516DV300_UART1_MUX, "uart_mux1", uart_mux_p,
13438+		ARRAY_SIZE(uart_mux_p),
13439+		CLK_SET_RATE_PARENT, 0x1bc, 19, 1, 0, uart_mux_table,
13440+	},
13441+	{
13442+		HI3516DV300_UART2_MUX, "uart_mux2", uart_mux_p,
13443+		ARRAY_SIZE(uart_mux_p),
13444+		CLK_SET_RATE_PARENT, 0x1bc, 20, 1, 0, uart_mux_table,
13445+	},
13446+	{
13447+		HI3516DV300_UART3_MUX, "uart_mux3", uart_mux_p,
13448+		ARRAY_SIZE(uart_mux_p),
13449+		CLK_SET_RATE_PARENT, 0x1bc, 21, 1, 0, uart_mux_table,
13450+	},
13451+	{
13452+		HI3516DV300_UART4_MUX, "uart_mux4", uart_mux_p,
13453+		ARRAY_SIZE(uart_mux_p),
13454+		CLK_SET_RATE_PARENT, 0x1bc, 22, 1, 0, uart_mux_table,
13455+	},
13456+	{
13457+		HI3516DV300_PWM_MUX, "pwm_mux", pwm_mux_p,
13458+		ARRAY_SIZE(pwm_mux_p),
13459+		CLK_SET_RATE_PARENT, 0x1bc, 8, 2, 0, pwm_mux_table,
13460+	},
13461+	/* ethernet clock select */
13462+	{
13463+		HI3516DV300_ETH_MUX, "eth_mux", eth_mux_p, ARRAY_SIZE(eth_mux_p),
13464+		CLK_SET_RATE_PARENT, 0x16c, 7, 1, 0, eth_mux_table,
13465+	},
13466+};
13467+
13468+static struct hisi_fixed_factor_clock hi3516dv300_fixed_factor_clks[] __initdata
13469+	= {
13470+	{
13471+		HI3516DV300_SYSAXI_CLK, "clk_sysaxi", "sysaxi_mux", 1, 4,
13472+		CLK_SET_RATE_PARENT
13473+	},
13474+};
13475+
13476+static struct hisi_gate_clock hi3516dv300_gate_clks[] __initdata = {
13477+	{
13478+		HI3516DV300_FMC_CLK, "clk_fmc", "fmc_mux",
13479+		CLK_SET_RATE_PARENT, 0x144, 1, 0,
13480+	},
13481+	{
13482+		HI3516DV300_MMC0_CLK, "clk_mmc0", "mmc0_mux",
13483+		CLK_SET_RATE_PARENT, 0x148, 1, 0,
13484+	},
13485+	{
13486+		HI3516DV300_MMC1_CLK, "clk_mmc1", "mmc1_mux",
13487+		CLK_SET_RATE_PARENT, 0x160, 1, 0,
13488+	},
13489+	{
13490+		HI3516DV300_MMC2_CLK, "clk_mmc2", "mmc2_mux",
13491+		CLK_SET_RATE_PARENT, 0x154, 1, 0,
13492+	},
13493+	{
13494+		HI3516DV300_UART0_CLK, "clk_uart0", "uart_mux0",
13495+		CLK_SET_RATE_PARENT, 0x1b8, 0, 0,
13496+	},
13497+	{
13498+		HI3516DV300_UART1_CLK, "clk_uart1", "uart_mux1",
13499+		CLK_SET_RATE_PARENT, 0x1b8, 1, 0,
13500+	},
13501+	{
13502+		HI3516DV300_UART2_CLK, "clk_uart2", "uart_mux2",
13503+		CLK_SET_RATE_PARENT, 0x1b8, 2, 0,
13504+	},
13505+	{
13506+		HI3516DV300_UART3_CLK, "clk_uart3", "uart_mux3",
13507+		CLK_SET_RATE_PARENT, 0x1b8, 3, 0,
13508+	},
13509+	{
13510+		HI3516DV300_UART4_CLK, "clk_uart4", "uart_mux4",
13511+		CLK_SET_RATE_PARENT, 0x1b8, 4, 0,
13512+	},
13513+	{
13514+		HI3516DV300_I2C0_CLK, "clk_i2c0", "50m",
13515+		CLK_SET_RATE_PARENT, 0x1b8, 11, 0,
13516+	},
13517+	{
13518+		HI3516DV300_I2C1_CLK, "clk_i2c1", "50m",
13519+		CLK_SET_RATE_PARENT, 0x1b8, 12, 0,
13520+	},
13521+	{
13522+		HI3516DV300_I2C2_CLK, "clk_i2c2", "50m",
13523+		CLK_SET_RATE_PARENT, 0x1b8, 13, 0,
13524+	},
13525+	{
13526+		HI3516DV300_I2C3_CLK, "clk_i2c3", "50m",
13527+		CLK_SET_RATE_PARENT, 0x1b8, 14, 0,
13528+	},
13529+	{
13530+		HI3516DV300_I2C4_CLK, "clk_i2c4", "50m",
13531+		CLK_SET_RATE_PARENT, 0x1b8, 15, 0,
13532+	},
13533+	{
13534+		HI3516DV300_I2C5_CLK, "clk_i2c5", "50m",
13535+		CLK_SET_RATE_PARENT, 0x1b8, 16, 0,
13536+	},
13537+	{
13538+		HI3516DV300_I2C6_CLK, "clk_i2c6", "50m",
13539+		CLK_SET_RATE_PARENT, 0x1b8, 17, 0,
13540+	},
13541+	{
13542+		HI3516DV300_I2C7_CLK, "clk_i2c7", "50m",
13543+		CLK_SET_RATE_PARENT, 0x1b8, 18, 0,
13544+	},
13545+	{
13546+		HI3516DV300_SPI0_CLK, "clk_spi0", "100m",
13547+		CLK_SET_RATE_PARENT, 0x1bc, 12, 0,
13548+	},
13549+	{
13550+		HI3516DV300_SPI1_CLK, "clk_spi1", "100m",
13551+		CLK_SET_RATE_PARENT, 0x1bc, 13, 0,
13552+	},
13553+	{
13554+		HI3516DV300_SPI2_CLK, "clk_spi2", "100m",
13555+		CLK_SET_RATE_PARENT, 0x1bc, 14, 0,
13556+	},
13557+	{
13558+		HI3516DV300_ETH0_CLK, "clk_eth0", "eth_mux",
13559+		CLK_SET_RATE_PARENT, 0x16c, 1, 0,
13560+	},
13561+	{
13562+		HI3516DV300_DMAC_CLK, "clk_dmac", NULL,
13563+		CLK_SET_RATE_PARENT, 0x194, 1, 0,
13564+	},
13565+	{
13566+		HI3516DV300_DMAC_AXICLK, "axiclk_dmac", NULL,
13567+		CLK_SET_RATE_PARENT, 0x194, 2, 0,
13568+	},
13569+	{
13570+		HI3516DV300_PWM_CLK, "clk_pwm", "pwm_mux",
13571+		CLK_SET_RATE_PARENT, 0x1bc, 7, 0,
13572+	},
13573+};
13574+
13575+static void __init hi3516dv300_clk_init(struct device_node *np)
13576+{
13577+	struct hisi_clock_data *clk_data;
13578+
13579+	clk_data = hisi_clk_init(np, HI3516DV300_NR_CLKS);
13580+	if (!clk_data)
13581+		return;
13582+	if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
13583+		hibvt_reset_init(np, HI3516DV300_NR_RSTS);
13584+
13585+	hisi_clk_register_fixed_rate(hi3516dv300_fixed_rate_clks,
13586+				     ARRAY_SIZE(hi3516dv300_fixed_rate_clks),
13587+				     clk_data);
13588+	hisi_clk_register_mux(hi3516dv300_mux_clks, ARRAY_SIZE(hi3516dv300_mux_clks),
13589+			      clk_data);
13590+	hisi_clk_register_fixed_factor(hi3516dv300_fixed_factor_clks,
13591+				       ARRAY_SIZE(hi3516dv300_fixed_factor_clks), clk_data);
13592+	hisi_clk_register_gate(hi3516dv300_gate_clks,
13593+			       ARRAY_SIZE(hi3516dv300_gate_clks), clk_data);
13594+}
13595+
13596+CLK_OF_DECLARE(hi3516dv300_clk, "hisilicon,hi3516dv300-clock",
13597+	       hi3516dv300_clk_init);
13598+
13599diff --git a/drivers/clk/hisilicon/clk-hi3519av100.c b/drivers/clk/hisilicon/clk-hi3519av100.c
13600new file mode 100644
13601index 000000000..657767941
13602--- /dev/null
13603+++ b/drivers/clk/hisilicon/clk-hi3519av100.c
13604@@ -0,0 +1,559 @@
13605+/*
13606+ * Hi3519A Clock Driver
13607+ *
13608+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
13609+ *
13610+ * This program is free software; you can redistribute  it and/or modify it
13611+ * under  the terms of  the GNU General Public License as published by the
13612+ * Free Software Foundation;  either version 2 of the  License, or (at your
13613+ * option) any later version.
13614+ *
13615+ * This program is distributed in the hope that it will be useful,
13616+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
13617+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13618+ * GNU General Public License for more details.
13619+ *
13620+ * You should have received a copy of the GNU General Public License
13621+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
13622+ *
13623+ */
13624+
13625+#include <linux/of_address.h>
13626+#include <dt-bindings/clock/hi3519av100-clock.h>
13627+#include <linux/slab.h>
13628+#include <linux/delay.h>
13629+#include "clk.h"
13630+#include "reset.h"
13631+
13632+struct hi3519av100_pll_clock {
13633+	u32             id;
13634+	const char      *name;
13635+	const char      *parent_name;
13636+	u32             ctrl_reg1;
13637+	u8              frac_shift;
13638+	u8              frac_width;
13639+	u8              postdiv1_shift;
13640+	u8              postdiv1_width;
13641+	u8              postdiv2_shift;
13642+	u8              postdiv2_width;
13643+	u32             ctrl_reg2;
13644+	u8              fbdiv_shift;
13645+	u8              fbdiv_width;
13646+	u8              refdiv_shift;
13647+	u8              refdiv_width;
13648+};
13649+
13650+struct hi3519av100_clk_pll {
13651+	struct clk_hw   hw;
13652+	u32             id;
13653+	void __iomem    *ctrl_reg1;
13654+	u8              frac_shift;
13655+	u8              frac_width;
13656+	u8              postdiv1_shift;
13657+	u8              postdiv1_width;
13658+	u8              postdiv2_shift;
13659+	u8              postdiv2_width;
13660+	void __iomem    *ctrl_reg2;
13661+	u8              fbdiv_shift;
13662+	u8              fbdiv_width;
13663+	u8              refdiv_shift;
13664+	u8              refdiv_width;
13665+};
13666+
13667+static struct hi3519av100_pll_clock hi3519av100_pll_clks[] __initdata = {
13668+	{
13669+		HI3519AV100_APLL_CLK, "apll", NULL, 0x0, 0, 24, 24, 3, 28, 3,
13670+		0x4, 0, 12, 12, 6
13671+	},
13672+};
13673+
13674+#define to_pll_clk(_hw) container_of(_hw, struct hi3519av100_clk_pll, hw)
13675+
13676+/* soc clk config */
13677+static struct hisi_fixed_rate_clock hi3519av100_fixed_rate_clks[] __initdata = {
13678+	{ HI3519AV100_FIXED_2376M, "2376m", NULL, 0, 2376000000UL, },
13679+	{ HI3519AV100_FIXED_1188M, "1188m", NULL, 0, 1188000000, },
13680+	{ HI3519AV100_FIXED_594M, "594m", NULL, 0, 594000000, },
13681+	{ HI3519AV100_FIXED_297M, "297m", NULL, 0, 297000000, },
13682+	{ HI3519AV100_FIXED_148P5M, "148p5m", NULL, 0, 148500000, },
13683+	{ HI3519AV100_FIXED_74P25M, "74p25m", NULL, 0, 74250000, },
13684+	{ HI3519AV100_FIXED_792M, "792m", NULL, 0, 792000000, },
13685+	{ HI3519AV100_FIXED_475M, "475m", NULL, 0, 475000000, },
13686+	{ HI3519AV100_FIXED_340M, "340m", NULL, 0, 340000000, },
13687+	{ HI3519AV100_FIXED_72M, "72m", NULL, 0, 72000000, },
13688+	{ HI3519AV100_FIXED_400M, "400m", NULL, 0, 400000000, },
13689+	{ HI3519AV100_FIXED_200M, "200m", NULL, 0, 200000000, },
13690+	{ HI3519AV100_FIXED_54M, "54m", NULL, 0, 54000000, },
13691+	{ HI3519AV100_FIXED_27M, "27m", NULL, 0, 1188000000, },
13692+	{ HI3519AV100_FIXED_37P125M, "37p125m", NULL, 0, 37125000, },
13693+	{ HI3519AV100_FIXED_3000M, "3000m", NULL, 0, 3000000000UL, },
13694+	{ HI3519AV100_FIXED_1500M, "1500m", NULL, 0, 1500000000, },
13695+	{ HI3519AV100_FIXED_500M, "500m", NULL, 0, 500000000, },
13696+	{ HI3519AV100_FIXED_250M, "250m", NULL, 0, 250000000, },
13697+	{ HI3519AV100_FIXED_125M, "125m", NULL, 0, 125000000, },
13698+	{ HI3519AV100_FIXED_1000M, "1000m", NULL, 0, 1000000000, },
13699+	{ HI3519AV100_FIXED_600M, "600m", NULL, 0, 600000000, },
13700+	{ HI3519AV100_FIXED_750M, "750m", NULL, 0, 750000000, },
13701+	{ HI3519AV100_FIXED_150M, "150m", NULL, 0, 150000000, },
13702+	{ HI3519AV100_FIXED_75M, "75m", NULL, 0, 75000000, },
13703+	{ HI3519AV100_FIXED_300M, "300m", NULL, 0, 300000000, },
13704+	{ HI3519AV100_FIXED_60M, "60m", NULL, 0, 60000000, },
13705+	{ HI3519AV100_FIXED_214M, "214m", NULL, 0, 214000000, },
13706+	{ HI3519AV100_FIXED_107M, "107m", NULL, 0, 107000000, },
13707+	{ HI3519AV100_FIXED_100M, "100m", NULL, 0, 100000000, },
13708+	{ HI3519AV100_FIXED_50M, "50m", NULL, 0, 50000000, },
13709+	{ HI3519AV100_FIXED_25M, "25m", NULL, 0, 25000000, },
13710+	{ HI3519AV100_FIXED_24M, "24m", NULL, 0, 24000000, },
13711+	{ HI3519AV100_FIXED_3M, "3m", NULL, 0, 3000000, },
13712+	{ HI3519AV100_FIXED_100K, "100k", NULL, 0, 100000, },
13713+	{ HI3519AV100_FIXED_400K, "400k", NULL, 0, 400000, },
13714+	{ HI3519AV100_FIXED_49P5M, "49p5m", NULL, 0, 49500000, },
13715+	{ HI3519AV100_FIXED_99M, "99m", NULL, 0, 99000000, },
13716+	{ HI3519AV100_FIXED_187P5M, "187p5m", NULL, 0, 187500000, },
13717+	{ HI3519AV100_FIXED_198M, "198m", NULL, 0, 198000000, },
13718+};
13719+
13720+
13721+static const char *fmc_mux_p[] __initdata = {
13722+	"24m", "100m", "150m", "198m", "250m", "300m", "396m"
13723+};
13724+static u32 fmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6};
13725+
13726+static const char *mmc_mux_p[] __initdata = {
13727+	"100k", "25m", "49p5m", "99m", "187p5m", "150m", "198m", "400k"
13728+};
13729+static u32 mmc_mux_table[] = {0, 1, 2, 3, 4, 5, 6, 7};
13730+
13731+static const char *sysapb_mux_p[] __initdata = {
13732+	"24m", "50m",
13733+};
13734+static u32 sysapb_mux_table[] = {0, 1};
13735+
13736+static const char *sysbus_mux_p[] __initdata = {
13737+	"24m", "300m"
13738+};
13739+static u32 sysbus_mux_table[] = {0, 1};
13740+
13741+static const char *uart_mux_p[] __initdata = {"50m", "24m", "3m"};
13742+static u32 uart_mux_table[] = {0, 1, 2};
13743+
13744+static const char *a53_1_clksel_mux_p[] __initdata = {
13745+	"24m", "apll", "vpll", "792m"
13746+};
13747+static u32 a53_1_clksel_mux_table[] = {0, 1, 2, 3};
13748+
13749+static struct hisi_mux_clock hi3519av100_mux_clks[] __initdata = {
13750+	{
13751+		HI3519AV100_FMC_MUX, "fmc_mux", fmc_mux_p, ARRAY_SIZE(fmc_mux_p),
13752+		CLK_SET_RATE_PARENT, 0x170, 2, 3, 0, fmc_mux_table,
13753+	},
13754+
13755+	{
13756+		HI3519AV100_MMC0_MUX, "mmc0_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p),
13757+		CLK_SET_RATE_PARENT, 0x1a8, 24, 3, 0, mmc_mux_table,
13758+	},
13759+
13760+	{
13761+		HI3519AV100_MMC1_MUX, "mmc1_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p),
13762+		CLK_SET_RATE_PARENT, 0x1ec, 24, 3, 0, mmc_mux_table,
13763+	},
13764+
13765+	{
13766+		HI3519AV100_MMC2_MUX, "mmc2_mux", mmc_mux_p, ARRAY_SIZE(mmc_mux_p),
13767+		CLK_SET_RATE_PARENT, 0x214, 24, 3, 0, mmc_mux_table,
13768+	},
13769+
13770+	{
13771+		HI3519AV100_SYSAPB_MUX, "sysapb_mux", sysapb_mux_p, ARRAY_SIZE(sysapb_mux_p),
13772+		CLK_SET_RATE_PARENT, 0xe8, 3, 1, 0, sysapb_mux_table
13773+	},
13774+
13775+	{
13776+		HI3519AV100_SYSBUS_MUX, "sysbus_mux", sysbus_mux_p, ARRAY_SIZE(sysbus_mux_p),
13777+		CLK_SET_RATE_PARENT, 0xe8, 0, 1, 1, sysbus_mux_table
13778+	},
13779+
13780+	{
13781+		HI3519AV100_UART0_MUX, "uart0_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p),
13782+		CLK_SET_RATE_PARENT, 0x1a4, 0, 2, 1, uart_mux_table
13783+	},
13784+
13785+	{
13786+		HI3519AV100_UART1_MUX, "uart1_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p),
13787+		CLK_SET_RATE_PARENT, 0x1a4, 2, 2, 1, uart_mux_table
13788+	},
13789+
13790+	{
13791+		HI3519AV100_UART2_MUX, "uart2_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p),
13792+		CLK_SET_RATE_PARENT, 0x1a4, 4, 2, 1, uart_mux_table
13793+	},
13794+
13795+	{
13796+		HI3519AV100_UART3_MUX, "uart3_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p),
13797+		CLK_SET_RATE_PARENT, 0x1a4, 6, 2, 1, uart_mux_table
13798+	},
13799+
13800+	{
13801+		HI3519AV100_UART4_MUX, "uart4_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p),
13802+		CLK_SET_RATE_PARENT, 0x1a4, 8, 2, 1, uart_mux_table
13803+	},
13804+
13805+	{
13806+		HI3519AV100_UART5_MUX, "uart5_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p),
13807+		CLK_SET_RATE_PARENT, 0x1a4, 10, 2, 1, uart_mux_table
13808+	},
13809+
13810+	{
13811+		HI3519AV100_UART6_MUX, "uart6_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p),
13812+		CLK_SET_RATE_PARENT, 0x1a4, 12, 2, 1, uart_mux_table
13813+	},
13814+
13815+	{
13816+		HI3519AV100_UART7_MUX, "uart7_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p),
13817+		CLK_SET_RATE_PARENT, 0x1a4, 14, 2, 1, uart_mux_table
13818+	},
13819+
13820+	{
13821+		HI3519AV100_UART8_MUX, "uart8_mux", uart_mux_p, ARRAY_SIZE(uart_mux_p),
13822+		CLK_SET_RATE_PARENT, 0x1a4, 28, 2, 1, uart_mux_table
13823+	},
13824+
13825+	{
13826+		HI3519AV100_A53_1_MUX, "a53_1_mux", a53_1_clksel_mux_p, ARRAY_SIZE(a53_1_clksel_mux_p),
13827+		CLK_SET_RATE_PARENT, 0xe4, 10, 2, 3, a53_1_clksel_mux_table
13828+	},
13829+
13830+};
13831+
13832+static struct hisi_fixed_factor_clock hi3519av100_fixed_factor_clks[] __initdata
13833+	= {
13834+
13835+};
13836+
13837+static struct hisi_gate_clock hi3519av100_gate_clks[] __initdata = {
13838+	{
13839+		HI3519AV100_FMC_CLK, "clk_fmc", "fmc_mux",
13840+		CLK_SET_RATE_PARENT, 0x170, 1, 0,
13841+	},
13842+	{
13843+		HI3519AV100_MMC0_CLK, "clk_mmc0", "mmc0_mux",
13844+		CLK_SET_RATE_PARENT, 0x1a8, 28, 0,
13845+	},
13846+	{
13847+		HI3519AV100_MMC1_CLK, "clk_mmc1", "mmc1_mux",
13848+		CLK_SET_RATE_PARENT, 0x1ec, 28, 0,
13849+	},
13850+	{
13851+		HI3519AV100_MMC2_CLK, "clk_mmc2", "mmc2_mux",
13852+		CLK_SET_RATE_PARENT, 0x214, 28, 0,
13853+	},
13854+	{
13855+		HI3519AV100_UART0_CLK, "clk_uart0", "uart0_mux",
13856+		CLK_SET_RATE_PARENT, 0x198, 16, 0,
13857+	},
13858+	{
13859+		HI3519AV100_UART1_CLK, "clk_uart1", "uart1_mux",
13860+		CLK_SET_RATE_PARENT, 0x198, 17, 0,
13861+	},
13862+	{
13863+		HI3519AV100_UART2_CLK, "clk_uart2", "uart2_mux",
13864+		CLK_SET_RATE_PARENT, 0x198, 18, 0,
13865+	},
13866+	{
13867+		HI3519AV100_UART3_CLK, "clk_uart3", "uart3_mux",
13868+		CLK_SET_RATE_PARENT, 0x198, 19, 0,
13869+	},
13870+	{
13871+		HI3519AV100_UART4_CLK, "clk_uart4", "uart4_mux",
13872+		CLK_SET_RATE_PARENT, 0x198, 20, 0,
13873+	},
13874+	{
13875+		HI3519AV100_UART5_CLK, "clk_uart5", "uart5_mux",
13876+		CLK_SET_RATE_PARENT, 0x198, 21, 0,
13877+	},
13878+	{
13879+		HI3519AV100_UART6_CLK, "clk_uart6", "uart6_mux",
13880+		CLK_SET_RATE_PARENT, 0x198, 22, 0,
13881+	},
13882+	{
13883+		HI3519AV100_UART7_CLK, "clk_uart7", "uart7_mux",
13884+		CLK_SET_RATE_PARENT, 0x198, 23, 0,
13885+	},
13886+	{
13887+		HI3519AV100_UART8_CLK, "clk_uart8", "uart8_mux",
13888+		CLK_SET_RATE_PARENT, 0x198, 29, 0,
13889+	},
13890+	{
13891+		HI3519AV100_ETH_CLK, "clk_eth", NULL,
13892+		CLK_SET_RATE_PARENT, 0x0174, 1, 0,
13893+	},
13894+	{
13895+		HI3519AV100_ETH_MACIF_CLK, "clk_eth_macif", NULL,
13896+		CLK_SET_RATE_PARENT, 0x0174, 5, 0,
13897+	},
13898+	/* i2c */
13899+	{
13900+		HI3519AV100_I2C0_CLK, "clk_i2c0", "50m",
13901+		CLK_SET_RATE_PARENT, 0x01a0, 16, 0,
13902+	},
13903+	{
13904+		HI3519AV100_I2C1_CLK, "clk_i2c1", "50m",
13905+		CLK_SET_RATE_PARENT, 0x01a0, 17, 0,
13906+	},
13907+	{
13908+		HI3519AV100_I2C2_CLK, "clk_i2c2", "50m",
13909+		CLK_SET_RATE_PARENT, 0x01a0, 18, 0,
13910+	},
13911+	{
13912+		HI3519AV100_I2C3_CLK, "clk_i2c3", "50m",
13913+		CLK_SET_RATE_PARENT, 0x01a0, 19, 0,
13914+	},
13915+	{
13916+		HI3519AV100_I2C4_CLK, "clk_i2c4", "50m",
13917+		CLK_SET_RATE_PARENT, 0x01a0, 20, 0,
13918+	},
13919+	{
13920+		HI3519AV100_I2C5_CLK, "clk_i2c5", "50m",
13921+		CLK_SET_RATE_PARENT, 0x01a0, 21, 0,
13922+	},
13923+	{
13924+		HI3519AV100_I2C6_CLK, "clk_i2c6", "50m",
13925+		CLK_SET_RATE_PARENT, 0x01a0, 22, 0,
13926+	},
13927+	{
13928+		HI3519AV100_I2C7_CLK, "clk_i2c7", "50m",
13929+		CLK_SET_RATE_PARENT, 0x01a0, 23, 0,
13930+	},
13931+	{
13932+		HI3519AV100_I2C8_CLK, "clk_i2c8", "50m",
13933+		CLK_SET_RATE_PARENT, 0x01a0, 24, 0,
13934+	},
13935+	{
13936+		HI3519AV100_I2C9_CLK, "clk_i2c9", "50m",
13937+		CLK_SET_RATE_PARENT, 0x01a0, 25, 0,
13938+	},
13939+	{
13940+		HI3519AV100_SPI0_CLK, "clk_spi0", "100m",
13941+		CLK_SET_RATE_PARENT, 0x0198, 24, 0,
13942+	},
13943+	{
13944+		HI3519AV100_SPI1_CLK, "clk_spi1", "100m",
13945+		CLK_SET_RATE_PARENT, 0x0198, 25, 0,
13946+	},
13947+	{
13948+		HI3519AV100_SPI2_CLK, "clk_spi2", "100m",
13949+		CLK_SET_RATE_PARENT, 0x0198, 26, 0,
13950+	},
13951+	{
13952+		HI3519AV100_SPI3_CLK, "clk_spi3", "100m",
13953+		CLK_SET_RATE_PARENT, 0x0198, 27, 0,
13954+	},
13955+	{
13956+		HI3519AV100_SPI4_CLK, "clk_spi4", "100m",
13957+		CLK_SET_RATE_PARENT, 0x0198, 28, 0,
13958+	},
13959+	{
13960+		HI3519AV100_EDMAC_AXICLK, "axi_clk_edmac", NULL,
13961+		CLK_SET_RATE_PARENT, 0x16c, 6, 0,
13962+	},
13963+	{
13964+		HI3519AV100_EDMAC_CLK, "clk_edmac", NULL,
13965+		CLK_SET_RATE_PARENT, 0x16c, 5, 0,
13966+	},
13967+	{
13968+		HI3519AV100_EDMAC1_AXICLK, "axi_clk_edmac1", NULL,
13969+		CLK_SET_RATE_PARENT, 0x16c, 9, 0,
13970+	},
13971+	{
13972+		HI3519AV100_EDMAC1_CLK, "clk_edmac1", NULL,
13973+		CLK_SET_RATE_PARENT, 0x16c, 8, 0,
13974+	},
13975+	{
13976+		HI3519AV100_VDMAC_CLK, "clk_vdmac", NULL,
13977+		CLK_SET_RATE_PARENT, 0x14c, 5, 0,
13978+	},
13979+};
13980+
13981+static void hi3519av100_calc_pll(u32 *frac_val,
13982+				 u32 *postdiv1_val,
13983+				 u32 *postdiv2_val,
13984+				 u32 *fbdiv_val,
13985+				 u32 *refdiv_val,
13986+				 u64 rate)
13987+{
13988+	u64 rem;
13989+	*frac_val = 0;
13990+	rem = do_div(rate, 1000000);
13991+	*fbdiv_val = rate;
13992+	*refdiv_val = 24;
13993+	if ((rem * (1 << 24)) > ULLONG_MAX) {
13994+		pr_err("Data over limits!\n");
13995+		return;
13996+        }
13997+	rem = rem * (1 << 24);
13998+	do_div(rem, 1000000);
13999+	*frac_val = rem;
14000+}
14001+
14002+static int clk_pll_set_rate(struct clk_hw *hw,
14003+			    unsigned long rate,
14004+			    unsigned long parent_rate)
14005+{
14006+	struct hi3519av100_clk_pll *clk = to_pll_clk(hw);
14007+	u32 frac_val, postdiv1_val, postdiv2_val, fbdiv_val, refdiv_val;
14008+	u32 val;
14009+
14010+	postdiv1_val = postdiv2_val = 0;
14011+
14012+	hi3519av100_calc_pll(&frac_val, &postdiv1_val, &postdiv2_val,
14013+			     &fbdiv_val, &refdiv_val, rate);
14014+
14015+	val = readl_relaxed(clk->ctrl_reg1);
14016+	val &= ~(((1 << clk->frac_width) - 1) << clk->frac_shift);
14017+	val &= ~(((1 << clk->postdiv1_width) - 1) << clk->postdiv1_shift);
14018+	val &= ~(((1 << clk->postdiv2_width) - 1) << clk->postdiv2_shift);
14019+
14020+	val |= frac_val << clk->frac_shift;
14021+	val |= postdiv1_val << clk->postdiv1_shift;
14022+	val |= postdiv2_val << clk->postdiv2_shift;
14023+	writel_relaxed(val, clk->ctrl_reg1);
14024+
14025+	val = readl_relaxed(clk->ctrl_reg2);
14026+	val &= ~(((1 << clk->fbdiv_width) - 1) << clk->fbdiv_shift);
14027+	val &= ~(((1 << clk->refdiv_width) - 1) << clk->refdiv_shift);
14028+
14029+	val |= fbdiv_val << clk->fbdiv_shift;
14030+	val |= refdiv_val << clk->refdiv_shift;
14031+	writel_relaxed(val, clk->ctrl_reg2);
14032+
14033+	return 0;
14034+}
14035+
14036+static unsigned long clk_pll_recalc_rate(struct clk_hw *hw,
14037+		unsigned long parent_rate)
14038+{
14039+	struct hi3519av100_clk_pll *clk = to_pll_clk(hw);
14040+	u64 frac_val, fbdiv_val;
14041+	u32 val;
14042+	u64 tmp, rate;
14043+	u32 refdiv_val;
14044+
14045+	val = readl_relaxed(clk->ctrl_reg1);
14046+	val = val >> clk->frac_shift;
14047+	val &= ((1 << clk->frac_width) - 1);
14048+	frac_val = val;
14049+
14050+	val = readl_relaxed(clk->ctrl_reg2);
14051+	val = val >> clk->fbdiv_shift;
14052+	val &= ((1 << clk->fbdiv_width) - 1);
14053+	fbdiv_val = val;
14054+
14055+	val = readl_relaxed(clk->ctrl_reg2);
14056+	val = val >> clk->refdiv_shift;
14057+	val &= ((1 << clk->refdiv_width) - 1);
14058+	refdiv_val = val;
14059+
14060+	/* rate = 24000000 * (fbdiv + frac / (1<<24) ) / refdiv  */
14061+	rate = 0;
14062+	if ((24000000 * fbdiv_val) > ULLONG_MAX) {
14063+		pr_err("Data over limits!\n");
14064+		return 0;
14065+        }
14066+	tmp = 24000000 * fbdiv_val;
14067+	rate += tmp;
14068+	do_div(rate, refdiv_val);
14069+
14070+	return rate;
14071+}
14072+
14073+static int clk_pll_determine_rate(struct clk_hw *hw,
14074+				  struct clk_rate_request *req)
14075+{
14076+	return req->rate;
14077+}
14078+
14079+static struct clk_ops clk_pll_ops = {
14080+	.set_rate = clk_pll_set_rate,
14081+	.determine_rate = clk_pll_determine_rate,
14082+	.recalc_rate = clk_pll_recalc_rate,
14083+};
14084+
14085+void __init hi3519av100_clk_register_pll(struct hi3519av100_pll_clock *clks,
14086+		int nums, struct hisi_clock_data *data)
14087+{
14088+	int i;
14089+	void __iomem *base = NULL;
14090+
14091+	if (clks == NULL || data == NULL)
14092+		return;
14093+
14094+	base = data->base;
14095+	for (i = 0; i < nums; i++) {
14096+		struct hi3519av100_clk_pll *p_clk = NULL;
14097+		struct clk *clk = NULL;
14098+		struct clk_init_data init;
14099+
14100+		p_clk = kzalloc(sizeof(*p_clk), GFP_KERNEL);
14101+		if (!p_clk)
14102+			return;
14103+
14104+		init.name = clks[i].name;
14105+		init.flags = CLK_IS_BASIC | CLK_SET_RATE_PARENT;
14106+		init.parent_names =
14107+			(clks[i].parent_name ? &clks[i].parent_name : NULL);
14108+		init.num_parents = (clks[i].parent_name ? 1 : 0);
14109+		init.ops = &clk_pll_ops;
14110+
14111+		p_clk->ctrl_reg1 = base + clks[i].ctrl_reg1;
14112+		p_clk->frac_shift = clks[i].frac_shift;
14113+		p_clk->frac_width = clks[i].frac_width;
14114+		p_clk->postdiv1_shift = clks[i].postdiv1_shift;
14115+		p_clk->postdiv1_width = clks[i].postdiv1_width;
14116+		p_clk->postdiv2_shift = clks[i].postdiv2_shift;
14117+		p_clk->postdiv2_width = clks[i].postdiv2_width;
14118+
14119+		p_clk->ctrl_reg2 = base + clks[i].ctrl_reg2;
14120+		p_clk->fbdiv_shift = clks[i].fbdiv_shift;
14121+		p_clk->fbdiv_width = clks[i].fbdiv_width;
14122+		p_clk->refdiv_shift = clks[i].refdiv_shift;
14123+		p_clk->refdiv_width = clks[i].refdiv_width;
14124+		p_clk->hw.init = &init;
14125+
14126+		clk = clk_register(NULL, &p_clk->hw);
14127+		if (IS_ERR(clk)) {
14128+			kfree(p_clk);
14129+			pr_err("%s: failed to register clock %s\n",
14130+			       __func__, clks[i].name);
14131+			continue;
14132+		}
14133+
14134+		data->clk_data.clks[clks[i].id] = clk;
14135+	}
14136+}
14137+
14138+static void __init hi3519av100_clk_init(struct device_node *np)
14139+{
14140+	struct hisi_clock_data *clk_data;
14141+
14142+	clk_data = hisi_clk_init(np, HI3519AV100_NR_CLKS);
14143+	if (!clk_data)
14144+		return;
14145+	if (IS_ENABLED(CONFIG_RESET_CONTROLLER))
14146+		hibvt_reset_init(np, HI3519AV100_NR_RSTS);
14147+
14148+	hisi_clk_register_fixed_rate(hi3519av100_fixed_rate_clks,
14149+				     ARRAY_SIZE(hi3519av100_fixed_rate_clks),
14150+				     clk_data);
14151+	hisi_clk_register_mux(hi3519av100_mux_clks, ARRAY_SIZE(hi3519av100_mux_clks),
14152+			      clk_data);
14153+	hisi_clk_register_fixed_factor(hi3519av100_fixed_factor_clks,
14154+				       ARRAY_SIZE(hi3519av100_fixed_factor_clks), clk_data);
14155+	hisi_clk_register_gate(hi3519av100_gate_clks,
14156+			       ARRAY_SIZE(hi3519av100_gate_clks), clk_data);
14157+
14158+	hi3519av100_clk_register_pll(hi3519av100_pll_clks,
14159+				     ARRAY_SIZE(hi3519av100_pll_clks), clk_data);
14160+}
14161+
14162+CLK_OF_DECLARE(hi3519av100_clk, "hisilicon,hi3519av100-clock",
14163+	       hi3519av100_clk_init);
14164diff --git a/drivers/clk/hisilicon/clk-hisi-phase.c b/drivers/clk/hisilicon/clk-hisi-phase.c
14165index ba6afad66..b13b91609 100644
14166--- a/drivers/clk/hisilicon/clk-hisi-phase.c
14167+++ b/drivers/clk/hisilicon/clk-hisi-phase.c
14168@@ -77,7 +77,7 @@ static int hisi_clk_set_phase(struct clk_hw *hw, int degrees)
14169
14170 	val = readl(phase->reg);
14171 	val &= ~phase->mask;
14172-	val |= regval << phase->shift;
14173+	val |= (unsigned int)regval << phase->shift;
14174 	writel(val, phase->reg);
14175
14176 	spin_unlock_irqrestore(phase->lock, flags);
14177diff --git a/drivers/clk/hisilicon/clk.c b/drivers/clk/hisilicon/clk.c
14178index 54d9fdc93..9ca4fc05f 100644
14179--- a/drivers/clk/hisilicon/clk.c
14180+++ b/drivers/clk/hisilicon/clk.c
14181@@ -82,6 +82,10 @@ struct hisi_clock_data *hisi_clk_init(struct device_node *np,
14182 	of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data->clk_data);
14183 	return clk_data;
14184 err_data:
14185+	if (base) {
14186+		iounmap(base);
14187+		base = NULL;
14188+	}
14189 	kfree(clk_data);
14190 err:
14191 	return NULL;
14192diff --git a/drivers/clk/hisilicon/crg.h b/drivers/clk/hisilicon/crg.h
14193index 803f6ba6d..a84758660 100644
14194--- a/drivers/clk/hisilicon/crg.h
14195+++ b/drivers/clk/hisilicon/crg.h
14196@@ -13,7 +13,7 @@ struct hisi_reset_controller;
14197
14198 struct hisi_crg_funcs {
14199 	struct hisi_clock_data*	(*register_clks)(struct platform_device *pdev);
14200-	void (*unregister_clks)(struct platform_device *pdev);
14201+	void (*unregister_clks)(const struct platform_device *pdev);
14202 };
14203
14204 struct hisi_crg_dev {
14205diff --git a/drivers/clk/hisilicon/reset.c b/drivers/clk/hisilicon/reset.c
14206index 93cee17db..e9a03d924 100644
14207--- a/drivers/clk/hisilicon/reset.c
14208+++ b/drivers/clk/hisilicon/reset.c
14209@@ -87,6 +87,36 @@ static const struct reset_control_ops hisi_reset_ops = {
14210 	.deassert	= hisi_reset_deassert,
14211 };
14212
14213+#ifdef CONFIG_ARCH_HISI_BVT
14214+int __init hibvt_reset_init(struct device_node *np,
14215+		int nr_rsts)
14216+{
14217+	struct hisi_reset_controller *rstc;
14218+
14219+	rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
14220+	if (!rstc)
14221+		return -ENOMEM;
14222+
14223+	rstc->membase = of_iomap(np, 0);
14224+	if (!rstc->membase){
14225+		kfree(rstc);
14226+		return -EINVAL;
14227+	}
14228+
14229+	spin_lock_init(&rstc->lock);
14230+
14231+	rstc->rcdev.owner = THIS_MODULE;
14232+	rstc->rcdev.nr_resets = nr_rsts;
14233+	rstc->rcdev.ops = &hisi_reset_ops;
14234+	rstc->rcdev.of_node = np;
14235+	rstc->rcdev.of_reset_n_cells = 2;
14236+	rstc->rcdev.of_xlate = hisi_reset_of_xlate;
14237+
14238+	return reset_controller_register(&rstc->rcdev);
14239+}
14240+EXPORT_SYMBOL_GPL(hibvt_reset_init);
14241+#endif
14242+
14243 struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev)
14244 {
14245 	struct hisi_reset_controller *rstc;
14246diff --git a/drivers/clk/hisilicon/reset.h b/drivers/clk/hisilicon/reset.h
14247index 81ff9e9e3..5954bdf91 100644
14248--- a/drivers/clk/hisilicon/reset.h
14249+++ b/drivers/clk/hisilicon/reset.h
14250@@ -11,6 +11,9 @@ struct hisi_reset_controller;
14251
14252 #ifdef CONFIG_RESET_CONTROLLER
14253 struct hisi_reset_controller *hisi_reset_init(struct platform_device *pdev);
14254+#ifdef CONFIG_ARCH_HISI_BVT
14255+int __init hibvt_reset_init(struct device_node *np, int nr_rsts);
14256+#endif
14257 void hisi_reset_exit(struct hisi_reset_controller *rstc);
14258 #else
14259 static inline
14260diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig
14261index 39f4d8866..ddf6f7373 100644
14262--- a/drivers/clocksource/Kconfig
14263+++ b/drivers/clocksource/Kconfig
14264@@ -347,6 +347,14 @@ config ARM_ARCH_TIMER_EVTSTREAM
14265 config ARM_ARCH_TIMER_OOL_WORKAROUND
14266 	bool
14267
14268+config ARM_ARCH_TIMER_VCT_ACCESS
14269+	bool "Support for ARM architected timer virtual counter access in userspace"
14270+	default n
14271+	depends on ARM_ARCH_TIMER
14272+	help
14273+	  This option enables support for reading the ARM architected timer's
14274+	  virtual counter in userspace.
14275+
14276 config FSL_ERRATUM_A008585
14277 	bool "Workaround for Freescale/NXP Erratum A-008585"
14278 	default y
14279@@ -402,6 +410,12 @@ config ARM_TIMER_SP804
14280 	select CLKSRC_MMIO
14281 	select TIMER_OF if OF
14282
14283+config TIMER_HISP804
14284+	bool "Support for hisilicon SP804 module"
14285+	depends on GENERIC_SCHED_CLOCK && CLKDEV_LOOKUP
14286+	select CLKSRC_MMIO
14287+	select TIMER_OF if OF
14288+
14289 config CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
14290 	bool
14291 	depends on ARM_GLOBAL_TIMER
14292diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
14293index 1c444cc3b..1a184f6ba 100644
14294--- a/drivers/clocksource/Makefile
14295+++ b/drivers/clocksource/Makefile
14296@@ -69,6 +69,7 @@ obj-$(CONFIG_ARM_ARCH_TIMER)		+= arm_arch_timer.o
14297 obj-$(CONFIG_ARM_GLOBAL_TIMER)		+= arm_global_timer.o
14298 obj-$(CONFIG_ARMV7M_SYSTICK)		+= armv7m_systick.o
14299 obj-$(CONFIG_ARM_TIMER_SP804)		+= timer-sp804.o
14300+obj-$(CONFIG_TIMER_HISP804)		+= timer-hisp804.o
14301 obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST)	+= dummy_timer.o
14302 obj-$(CONFIG_KEYSTONE_TIMER)		+= timer-keystone.o
14303 obj-$(CONFIG_INTEGRATOR_AP_TIMER)	+= timer-integrator-ap.o
14304diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c
14305index f4881764b..d435d1266 100644
14306--- a/drivers/clocksource/arm_arch_timer.c
14307+++ b/drivers/clocksource/arm_arch_timer.c
14308@@ -631,7 +631,8 @@ static bool arch_timer_counter_has_wa(void)
14309 }
14310 #else
14311 #define arch_timer_check_ool_workaround(t,a)		do { } while(0)
14312-#define arch_timer_this_cpu_has_cntvct_wa()		({false;})
14313+#define arch_timer_this_cpu_has_cntvct_wa()		\
14314+	({IS_ENABLED(CONFIG_ARM_ARCH_TIMER_VCT_ACCESS) ? false : true;})
14315 #define arch_timer_counter_has_wa()			({false;})
14316 #endif /* CONFIG_ARM_ARCH_TIMER_OOL_WORKAROUND */
14317
14318diff --git a/drivers/clocksource/timer-hisp804.c b/drivers/clocksource/timer-hisp804.c
14319new file mode 100644
14320index 000000000..b2c857a41
14321--- /dev/null
14322+++ b/drivers/clocksource/timer-hisp804.c
14323@@ -0,0 +1,356 @@
14324+/******************************************************************************
14325+ *  Copyright (C) 2017 Hisilicon Technologies CO.,LTD.
14326+ *
14327+ * Licensed under the Apache License, Version 2.0 (the "License");
14328+ * you may not use this file except in compliance with the License.
14329+ * You may obtain a copy of the License at
14330+ *
14331+ * http://www.apache.org/licenses/LICENSE-2.0
14332+ *
14333+ * Unless required by applicable law or agreed to in writing, software
14334+ * distributed under the License is distributed on an "AS IS" BASIS,
14335+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14336+ * See the License for the specific language governing permissions and
14337+ * limitations under the License.
14338+ *
14339+ * Create By Cai Zhiying 2017.2.4
14340+ *
14341+******************************************************************************/
14342+
14343+#define pr_fmt(fmt) "hisp804: " fmt
14344+
14345+#include <linux/clk.h>
14346+#include <linux/clocksource.h>
14347+#include <linux/clockchips.h>
14348+#include <linux/err.h>
14349+#include <linux/interrupt.h>
14350+#include <linux/irq.h>
14351+#include <linux/cpu.h>
14352+#include <linux/io.h>
14353+#include <linux/smp.h>
14354+#include <linux/of.h>
14355+#include <linux/of_address.h>
14356+#include <linux/of_irq.h>
14357+#include <linux/sched_clock.h>
14358+
14359+#define TIMER_LOAD      0x00             /* ACVR rw */
14360+#define TIMER_VALUE     0x04             /* ACVR ro */
14361+#define TIMER_CTRL      0x08             /* ACVR rw */
14362+#define TIMER_CTRL_ONESHOT      (1 << 0) /*  CVR */
14363+#define TIMER_CTRL_32BIT        (1 << 1) /*  CVR */
14364+#define TIMER_CTRL_DIV1         (0 << 2) /* ACVR */
14365+#define TIMER_CTRL_DIV16        (1 << 2) /* ACVR */
14366+#define TIMER_CTRL_DIV256       (2 << 2) /* ACVR */
14367+#define TIMER_CTRL_IE           (1 << 5) /*   VR */
14368+#define TIMER_CTRL_PERIODIC     (1 << 6) /* ACVR */
14369+#define TIMER_CTRL_ENABLE       (1 << 7) /* ACVR */
14370+
14371+#define TIMER_INTCLR    0x0c             /* ACVR wo */
14372+#define TIMER_RIS       0x10             /*  CVR ro */
14373+#define TIMER_MIS       0x14             /*  CVR ro */
14374+#define TIMER_BGLOAD    0x18             /*  CVR rw */
14375+
14376+#define CPU_TASKS_FROZEN        0x0010
14377+
14378+struct hisp804_clocksource {
14379+	void __iomem *base;
14380+	struct clocksource clksrc;
14381+};
14382+
14383+#define to_hiclksrc(e) \
14384+	container_of(e, struct hisp804_clocksource, clksrc)
14385+
14386+static struct hisp804_clocksource hisp804_clksrc;
14387+
14388+static void __iomem *hisp804_sched_clock_base;
14389+
14390+struct hisp804_clockevent_device {
14391+	struct clock_event_device clkevt;
14392+	struct irqaction action;
14393+	void __iomem *base;
14394+	unsigned long rate;
14395+	unsigned long reload;
14396+	char name[16];
14397+};
14398+
14399+#define to_hiclkevt(e) \
14400+	container_of(e, struct hisp804_clockevent_device, clkevt)
14401+
14402+static struct hisp804_clockevent_device __percpu *hisp804_clkevt;
14403+
14404+static void hisp804_clocksource_enable(void __iomem *base)
14405+{
14406+	writel(0, base + TIMER_CTRL);
14407+	writel(0xffffffff, base + TIMER_LOAD);
14408+	writel(0xffffffff, base + TIMER_VALUE);
14409+	writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_PERIODIC,
14410+	       base + TIMER_CTRL);
14411+}
14412+
14413+static void hisp804_clocksource_resume(struct clocksource *cs)
14414+{
14415+	hisp804_clocksource_enable(to_hiclksrc(cs)->base);
14416+}
14417+
14418+static u64 notrace hisp804_sched_clock_read(void)
14419+{
14420+	return ~readl_relaxed(hisp804_sched_clock_base + TIMER_VALUE);
14421+}
14422+
14423+static cycle_t hisp804_clocksource_read(struct clocksource *cs)
14424+{
14425+	return ~(cycle_t)readl_relaxed(to_hiclksrc(cs)->base + TIMER_VALUE);
14426+}
14427+
14428+static void __init hisp804_clocksource_init(void __iomem *base,
14429+					    unsigned long rate)
14430+{
14431+	hisp804_clksrc.base = base;
14432+	hisp804_clksrc.clksrc.name = "hisp804";
14433+	hisp804_clksrc.clksrc.rating = 499;
14434+	hisp804_clksrc.clksrc.read = hisp804_clocksource_read;
14435+	hisp804_clksrc.clksrc.resume = hisp804_clocksource_resume;
14436+	hisp804_clksrc.clksrc.mask = CLOCKSOURCE_MASK(32);
14437+	hisp804_clksrc.clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
14438+
14439+	hisp804_clocksource_enable(base);
14440+
14441+	clocksource_register_hz(&hisp804_clksrc.clksrc, rate);
14442+
14443+	hisp804_sched_clock_base = base;
14444+	sched_clock_register(hisp804_sched_clock_read, 32, rate);
14445+}
14446+
14447+static int hisp804_clockevent_shutdown(struct clock_event_device *clkevt)
14448+{
14449+	struct hisp804_clockevent_device *hiclkevt = to_hiclkevt(clkevt);
14450+
14451+	writel(0, hiclkevt->base + TIMER_CTRL);
14452+
14453+	return 0;
14454+}
14455+
14456+static int hisp804_clockevent_set_next_event(unsigned long next,
14457+					     struct clock_event_device *clkevt)
14458+{
14459+	unsigned long ctrl;
14460+	struct hisp804_clockevent_device *hiclkevt = to_hiclkevt(clkevt);
14461+
14462+	writel(TIMER_CTRL_32BIT, hiclkevt->base + TIMER_CTRL);
14463+
14464+	writel(next, hiclkevt->base + TIMER_LOAD);
14465+	writel(next, hiclkevt->base + TIMER_LOAD);
14466+
14467+	ctrl = TIMER_CTRL_32BIT |
14468+	       TIMER_CTRL_IE |
14469+	       TIMER_CTRL_ONESHOT |
14470+	       TIMER_CTRL_ENABLE;
14471+	writel(ctrl, hiclkevt->base + TIMER_CTRL);
14472+
14473+	return 0;
14474+}
14475+
14476+static int sp804_clockevent_set_periodic(struct clock_event_device *clkevt)
14477+{
14478+	unsigned long ctrl;
14479+	struct hisp804_clockevent_device *hiclkevt = to_hiclkevt(clkevt);
14480+
14481+	writel(TIMER_CTRL_32BIT, hiclkevt->base + TIMER_CTRL);
14482+
14483+	writel(hiclkevt->reload, hiclkevt->base + TIMER_LOAD);
14484+	writel(hiclkevt->reload, hiclkevt->base + TIMER_LOAD);
14485+
14486+	ctrl = TIMER_CTRL_32BIT |
14487+	       TIMER_CTRL_IE |
14488+	       TIMER_CTRL_PERIODIC |
14489+	       TIMER_CTRL_ENABLE;
14490+	writel(ctrl, hiclkevt->base + TIMER_CTRL);
14491+
14492+	return 0;
14493+}
14494+
14495+static irqreturn_t hisp804_clockevent_timer_interrupt(int irq, void *dev_id)
14496+{
14497+	struct clock_event_device *clkevt = dev_id;
14498+	struct hisp804_clockevent_device *hiclkevt = to_hiclkevt(clkevt);
14499+
14500+	/* clear the interrupt */
14501+	writel(1, hiclkevt->base + TIMER_INTCLR);
14502+
14503+	clkevt->event_handler(clkevt);
14504+
14505+	return IRQ_HANDLED;
14506+}
14507+
14508+static int hisp804_clockevent_setup(struct hisp804_clockevent_device *hiclkevt)
14509+{
14510+	struct clock_event_device *clkevt = &hiclkevt->clkevt;
14511+
14512+	writel(0, hiclkevt->base + TIMER_CTRL);
14513+
14514+	BUG_ON(setup_irq(clkevt->irq, &hiclkevt->action));
14515+
14516+	irq_force_affinity(clkevt->irq, clkevt->cpumask);
14517+
14518+	clockevents_config_and_register(clkevt, hiclkevt->rate, 0xf,
14519+					0x7fffffff);
14520+
14521+	return 0;
14522+}
14523+
14524+static void hisp804_clockevent_stop(struct hisp804_clockevent_device *hiclkevt)
14525+{
14526+	struct clock_event_device *clkevt = &hiclkevt->clkevt;
14527+
14528+	pr_info("disable IRQ%d cpu #%d\n", clkevt->irq, smp_processor_id());
14529+
14530+	disable_irq(clkevt->irq);
14531+
14532+	remove_irq(clkevt->irq, &hiclkevt->action);
14533+
14534+	clkevt->set_state_shutdown(clkevt);
14535+}
14536+
14537+static int hisp804_clockevent_cpu_notify(struct notifier_block *self,
14538+					 unsigned long action, void *hcpu)
14539+{
14540+	/*
14541+	 * Grab cpu pointer in each case to avoid spurious
14542+	 * preemptible warnings
14543+	 */
14544+	switch (action & ~CPU_TASKS_FROZEN) {
14545+	case CPU_ONLINE:
14546+		hisp804_clockevent_setup(this_cpu_ptr(hisp804_clkevt));
14547+		break;
14548+	case CPU_DEAD:
14549+		hisp804_clockevent_stop(this_cpu_ptr(hisp804_clkevt));
14550+		break;
14551+	default:
14552+		break;
14553+	}
14554+
14555+	return NOTIFY_OK;
14556+}
14557+
14558+static struct notifier_block hisp804_clockevent_cpu_nb = {
14559+	.notifier_call = hisp804_clockevent_cpu_notify,
14560+};
14561+
14562+static void __init clockevent_init(struct hisp804_clockevent_device *hiclkevt,
14563+				   void __iomem *base, int irq, int cpu,
14564+				   unsigned long rate, unsigned long reload)
14565+{
14566+	struct irqaction *action = NULL;
14567+	struct clock_event_device *clkevt = NULL;
14568+
14569+	hiclkevt->base = base;
14570+	hiclkevt->rate = rate;
14571+	hiclkevt->reload = reload;
14572+	snprintf(hiclkevt->name, sizeof(hiclkevt->name), "clockevent %d", cpu);
14573+
14574+	clkevt = &hiclkevt->clkevt;
14575+
14576+	clkevt->name = hiclkevt->name;
14577+	clkevt->cpumask = cpumask_of(cpu);
14578+	clkevt->irq = irq;
14579+	clkevt->set_next_event = hisp804_clockevent_set_next_event;
14580+	clkevt->set_state_shutdown = hisp804_clockevent_shutdown;
14581+	clkevt->set_state_periodic = sp804_clockevent_set_periodic;
14582+	clkevt->features = CLOCK_EVT_FEAT_PERIODIC |
14583+			   CLOCK_EVT_FEAT_ONESHOT |
14584+			   CLOCK_EVT_FEAT_DYNIRQ;
14585+	clkevt->rating = 400;
14586+
14587+	action = &hiclkevt->action;
14588+
14589+	action->name = hiclkevt->name;
14590+	action->dev_id = hiclkevt;
14591+	action->irq = irq;
14592+	action->flags = IRQF_TIMER | IRQF_NOBALANCING;
14593+	action->handler = hisp804_clockevent_timer_interrupt;
14594+}
14595+
14596+static int __init hisp804_timer_init(struct device_node *node)
14597+{
14598+	int ret, irq, ix, nr_cpus;
14599+	struct clk *clk1 = NULL, *clk2 = NULL;
14600+	void __iomem *base = NULL;
14601+	unsigned long rate1, rate2, reload1, reload2;
14602+
14603+	hisp804_clkevt = alloc_percpu(struct hisp804_clockevent_device);
14604+	if (!hisp804_clkevt) {
14605+		pr_err("can't alloc memory.\n");
14606+		goto out;
14607+	}
14608+
14609+	clk1 = of_clk_get(node, 0);
14610+	if (IS_ERR(clk1))
14611+		goto out_free;
14612+
14613+	clk_prepare_enable(clk1);
14614+
14615+	rate1 = clk_get_rate(clk1);
14616+	reload1 = DIV_ROUND_CLOSEST(rate1, HZ);
14617+
14618+	/* Get the 2nd clock if the timer has 3 timer clocks */
14619+	if (of_count_phandle_with_args(node, "clocks", "#clock-cells") == 3) {
14620+		clk2 = of_clk_get(node, 1);
14621+		if (IS_ERR(clk2)) {
14622+			pr_err("hisp804: %s clock not found: %d\n", node->name,
14623+			       (int)PTR_ERR(clk2));
14624+			goto out_free;
14625+		}
14626+		clk_prepare_enable(clk2);
14627+		rate2 = clk_get_rate(clk2);
14628+		reload2 = DIV_ROUND_CLOSEST(rate2, HZ);
14629+	} else {
14630+		rate2 = rate1;
14631+		reload2 = rate2;
14632+	}
14633+
14634+	nr_cpus = of_irq_count(node);
14635+	if (nr_cpus > num_possible_cpus())
14636+		nr_cpus = num_possible_cpus();
14637+
14638+	/* local timer for each CPU */
14639+	for (ix = 0; ix < nr_cpus; ix++) {
14640+		irq = irq_of_parse_and_map(node, ix);
14641+		base = of_iomap(node, ix + 1);
14642+		if (!base) {
14643+			pr_err("can't iomap timer %d\n", ix);
14644+			while (--ix >= 0)
14645+				iounmap(per_cpu_ptr(hisp804_clkevt, ix)->base);
14646+			goto out_free;
14647+		}
14648+
14649+		clockevent_init(per_cpu_ptr(hisp804_clkevt, ix), base, irq,
14650+				ix, rate2, reload2);
14651+	}
14652+
14653+	base = of_iomap(node, 0);
14654+	if (!base) {
14655+		pr_err("can't iomap timer %d\n", 0);
14656+		goto out_unmap;
14657+	}
14658+
14659+	hisp804_clocksource_init(base, rate1);
14660+
14661+	ret = hi_register_cpu_notifier(&hisp804_clockevent_cpu_nb);
14662+	if (ret)
14663+		goto out_notifier;
14664+
14665+	hisp804_clockevent_setup(this_cpu_ptr(hisp804_clkevt));
14666+
14667+	return 0;
14668+
14669+out_notifier:
14670+	iounmap(base);
14671+out_unmap:
14672+	for (ix = 0; ix < nr_irqs; ix++)
14673+		iounmap(per_cpu_ptr(hisp804_clkevt, ix)->base);
14674+out_free:
14675+	free_percpu(hisp804_clkevt);
14676+out:
14677+	return -ENODEV;
14678+}
14679+CLOCKSOURCE_OF_DECLARE(hisp804, "hisilicon,hisp804", hisp804_timer_init);
14680\ No newline at end of file
14681diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
14682index 08013345d..96107fbef 100644
14683--- a/drivers/dma/Kconfig
14684+++ b/drivers/dma/Kconfig
14685@@ -328,6 +328,20 @@ config K3_DMA
14686 	  Support the DMA engine for Hisilicon K3 platform
14687 	  devices.
14688
14689+config HIEDMACV310
14690+	tristate "Hisilicon EDMAC Controller support"
14691+	depends on ARCH_HISI_BVT
14692+	select DMA_ENGINE
14693+	select DMA_VIRTUAL_CHANNELS
14694+	help
14695+		The Direction Memory Access(EDMA) is a high-speed data transfer
14696+		operation. It supports data read/write between peripherals and
14697+		memories without using the CPU.
14698+		Hisilicon EDMA Controller(EDMAC) directly transfers data between
14699+		a memory and a peripheral, between peripherals, or between memories.
14700+		This avoids the CPU intervention and reduces the interrupt handling
14701+		overhead of the CPU.
14702+
14703 config LPC18XX_DMAMUX
14704 	bool "NXP LPC18xx/43xx DMA MUX for PL080"
14705 	depends on ARCH_LPC18XX || COMPILE_TEST
14706@@ -710,7 +724,6 @@ config ZX_DMA
14707 	help
14708 	  Support the DMA engine for ZTE ZX family platform devices.
14709
14710-
14711 # driver files
14712 source "drivers/dma/bestcomm/Kconfig"
14713
14714diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
14715index 948a8da05..c5f89432d 100644
14716--- a/drivers/dma/Makefile
14717+++ b/drivers/dma/Makefile
14718@@ -82,7 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o
14719 obj-$(CONFIG_ZX_DMA) += zx_dma.o
14720 obj-$(CONFIG_ST_FDMA) += st_fdma.o
14721 obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/
14722-
14723+obj-$(CONFIG_HIEDMACV310) += hiedmacv310.o
14724 obj-y += mediatek/
14725 obj-y += qcom/
14726 obj-y += ti/
14727diff --git a/drivers/dma/hiedmacv310.c b/drivers/dma/hiedmacv310.c
14728new file mode 100644
14729index 000000000..a198c9224
14730--- /dev/null
14731+++ b/drivers/dma/hiedmacv310.c
14732@@ -0,0 +1,1443 @@
14733+/*
14734+ * driver/dma/hiedmacv310.c
14735+ *
14736+ * The Hiedma Controller v310 Device Driver for HiSilicon
14737+ *
14738+ * Copyright (c) 2020 HiSilicon Technologies Co., Ltd.
14739+ *
14740+ * This program is free software; you can redistribute  it and/or modify it
14741+ * under  the terms of  the GNU General  Public License as published by the
14742+ * Free Software Foundation;  either version 2 of the  License, or (at your
14743+ * option) any later version.
14744+ *
14745+ * This program is distributed in the hope that it will be useful,
14746+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
14747+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14748+ * GNU General Public License for more details.
14749+ *
14750+ * You should have received a copy of the GNU General Public License
14751+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
14752+ *
14753+ */
14754+#include <linux/debugfs.h>
14755+#include <linux/delay.h>
14756+#include <linux/clk.h>
14757+#include <linux/reset.h>
14758+#include <linux/platform_device.h>
14759+#include <linux/device.h>
14760+#include <linux/dmaengine.h>
14761+#include <linux/dmapool.h>
14762+#include <linux/dma-mapping.h>
14763+#include <linux/export.h>
14764+#include <linux/init.h>
14765+#include <linux/interrupt.h>
14766+#include <linux/module.h>
14767+#include <linux/of.h>
14768+#include <linux/of_dma.h>
14769+#include <linux/pm_runtime.h>
14770+#include <linux/seq_file.h>
14771+#include <linux/slab.h>
14772+#include <linux/io.h>
14773+#include <linux/regmap.h>
14774+#include <linux/mfd/syscon.h>
14775+
14776+#include "hiedmacv310.h"
14777+#include "dmaengine.h"
14778+#include "virt-dma.h"
14779+
14780+#define DRIVER_NAME "hiedmacv310"
14781+
14782+#define MAX_TSFR_LLIS           512
14783+#define EDMACV300_LLI_WORDS     64
14784+#define EDMACV300_POOL_ALIGN    64
14785+#define BITS_PER_HALF_WORD 32
14786+#define ERR_STATUS_REG_NUM 3
14787+
14788+typedef struct hiedmac_lli {
14789+	u64 next_lli;
14790+	u32 reserved[5];
14791+	u32 count;
14792+	u64 src_addr;
14793+	u64 dest_addr;
14794+	u32 config;
14795+	u32 pad[3];
14796+} hiedmac_lli;
14797+
14798+struct hiedmac_sg {
14799+	dma_addr_t src_addr;
14800+	dma_addr_t dst_addr;
14801+	size_t len;
14802+	struct list_head node;
14803+};
14804+
14805+struct transfer_desc {
14806+	struct virt_dma_desc virt_desc;
14807+	dma_addr_t llis_busaddr;
14808+	u64 *llis_vaddr;
14809+	u32 ccfg;
14810+	size_t size;
14811+	bool done;
14812+	bool cyclic;
14813+};
14814+
14815+enum edmac_dma_chan_state {
14816+	HIEDMAC_CHAN_IDLE,
14817+	HIEDMAC_CHAN_RUNNING,
14818+	HIEDMAC_CHAN_PAUSED,
14819+	HIEDMAC_CHAN_WAITING,
14820+};
14821+
14822+struct hiedmacv310_dma_chan {
14823+	bool slave;
14824+	int signal;
14825+	int id;
14826+	struct virt_dma_chan virt_chan;
14827+	struct hiedmacv310_phy_chan *phychan;
14828+	struct dma_slave_config cfg;
14829+	struct transfer_desc *at;
14830+	struct hiedmacv310_driver_data *host;
14831+	enum edmac_dma_chan_state state;
14832+};
14833+
14834+struct hiedmacv310_phy_chan {
14835+	unsigned int id;
14836+	void __iomem *base;
14837+	spinlock_t lock;
14838+	struct hiedmacv310_dma_chan *serving;
14839+};
14840+
14841+struct hiedmacv310_driver_data {
14842+	struct platform_device *dev;
14843+	struct dma_device slave;
14844+	struct dma_device memcpy;
14845+	void __iomem *base;
14846+	struct regmap *misc_regmap;
14847+	void __iomem *crg_ctrl;
14848+	struct hiedmacv310_phy_chan *phy_chans;
14849+	struct dma_pool *pool;
14850+	unsigned int misc_ctrl_base;
14851+	int irq;
14852+	unsigned int id;
14853+	struct clk *clk;
14854+	struct clk *axi_clk;
14855+	struct reset_control *rstc;
14856+	unsigned int channels;
14857+	unsigned int slave_requests;
14858+	unsigned int max_transfer_size;
14859+};
14860+
14861+#ifdef DEBUG_HIEDMAC
14862+void dump_lli(const u64 *llis_vaddr, unsigned int num)
14863+{
14864+	hiedmac_lli *plli = (hiedmac_lli *)llis_vaddr;
14865+	unsigned int i;
14866+
14867+	hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "lli num = 0%d\n", num);
14868+	for (i = 0; i < num; i++) {
14869+		printk("lli%d:lli_L:      0x%llx\n", i, plli[i].next_lli & 0xffffffff);
14870+		printk("lli%d:lli_H:      0x%llx\n", i, (plli[i].next_lli >> BITS_PER_HALF_WORD) & 0xffffffff);
14871+		printk("lli%d:count:      0x%x\n", i, plli[i].count);
14872+		printk("lli%d:src_addr_L: 0x%llx\n", i, plli[i].src_addr & 0xffffffff);
14873+		printk("lli%d:src_addr_H: 0x%llx\n", i, (plli[i].src_addr >> BITS_PER_HALF_WORD) & 0xffffffff);
14874+		printk("lli%d:dst_addr_L: 0x%llx\n", i, plli[i].dest_addr & 0xffffffff);
14875+		printk("lli%d:dst_addr_H: 0x%llx\n", i, (plli[i].dest_addr >> BITS_PER_HALF_WORD) & 0xffffffff);
14876+		printk("lli%d:CONFIG:	  0x%x\n", i, plli[i].config);
14877+	}
14878+}
14879+
14880+#else
14881+void dump_lli(u64 *llis_vaddr, unsigned int num)
14882+{
14883+}
14884+#endif
14885+
14886+static inline struct hiedmacv310_dma_chan *to_edamc_chan(const struct dma_chan *chan)
14887+{
14888+	return container_of(chan, struct hiedmacv310_dma_chan, virt_chan.chan);
14889+}
14890+
14891+static inline struct transfer_desc *to_edmac_transfer_desc(
14892+	const struct dma_async_tx_descriptor *tx)
14893+{
14894+	return container_of(tx, struct transfer_desc, virt_desc.tx);
14895+}
14896+
14897+static struct dma_chan *hiedmac_find_chan_id(
14898+	const struct hiedmacv310_driver_data *hiedmac,
14899+	int request_num)
14900+{
14901+	struct hiedmacv310_dma_chan *edmac_dma_chan = NULL;
14902+
14903+	list_for_each_entry(edmac_dma_chan, &hiedmac->slave.channels,
14904+			    virt_chan.chan.device_node) {
14905+		if (edmac_dma_chan->id == request_num)
14906+			return &edmac_dma_chan->virt_chan.chan;
14907+	}
14908+	return NULL;
14909+}
14910+
14911+static struct dma_chan *hiedma_of_xlate(struct of_phandle_args *dma_spec,
14912+					struct of_dma *ofdma)
14913+{
14914+	struct hiedmacv310_driver_data *hiedmac = ofdma->of_dma_data;
14915+	struct hiedmacv310_dma_chan *edmac_dma_chan = NULL;
14916+	struct dma_chan *dma_chan = NULL;
14917+	struct regmap *misc = NULL;
14918+	unsigned int signal, request_num;
14919+	unsigned int reg = 0;
14920+	unsigned int offset = 0;
14921+
14922+	if (!hiedmac)
14923+		return NULL;
14924+
14925+	misc = hiedmac->misc_regmap;
14926+
14927+	if (dma_spec->args_count != 2) { /* check num of dts node args */
14928+		hiedmacv310_error("args count not true!\n");
14929+		return NULL;
14930+	}
14931+
14932+	request_num = dma_spec->args[0];
14933+	signal = dma_spec->args[1];
14934+
14935+	hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "host->id = %d,signal = %d, request_num = %d\n",
14936+			  hiedmac->id, signal, request_num);
14937+
14938+	if (misc != NULL) {
14939+#ifdef CONFIG_ACCESS_M7_DEV
14940+		offset = hiedmac->misc_ctrl_base;
14941+		reg = 0xc0;
14942+		regmap_write(misc, offset, reg);
14943+#else
14944+		offset = hiedmac->misc_ctrl_base + (request_num & (~0x3));
14945+		regmap_read(misc, offset, &reg);
14946+		/* set misc for signal line */
14947+		reg &= ~(0x3f << ((request_num & 0x3) << 3));
14948+		reg |= signal << ((request_num & 0x3) << 3);
14949+		regmap_write(misc, offset, reg);
14950+#endif
14951+	}
14952+
14953+	hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "offset = 0x%x, reg = 0x%x\n", offset, reg);
14954+
14955+	dma_chan = hiedmac_find_chan_id(hiedmac, request_num);
14956+	if (!dma_chan) {
14957+		hiedmacv310_error("DMA slave channel is not found!\n");
14958+		return NULL;
14959+	}
14960+
14961+	edmac_dma_chan = to_edamc_chan(dma_chan);
14962+	edmac_dma_chan->signal = request_num;
14963+	return dma_get_slave_channel(dma_chan);
14964+}
14965+
14966+static int hiedmacv310_devm_get(struct hiedmacv310_driver_data *hiedmac)
14967+{
14968+	struct platform_device *platdev = hiedmac->dev;
14969+	struct resource *res = NULL;
14970+
14971+	hiedmac->clk = devm_clk_get(&(platdev->dev), "apb_pclk");
14972+	if (IS_ERR(hiedmac->clk)) {
14973+		return PTR_ERR(hiedmac->clk);
14974+	}
14975+
14976+	hiedmac->axi_clk = devm_clk_get(&(platdev->dev), "axi_aclk");
14977+	if (IS_ERR(hiedmac->axi_clk)) {
14978+		return PTR_ERR(hiedmac->axi_clk);
14979+	}
14980+
14981+	hiedmac->irq = platform_get_irq(platdev, 0);
14982+	if (unlikely(hiedmac->irq < 0))
14983+		return -ENODEV;
14984+
14985+	hiedmac->rstc = devm_reset_control_get(&(platdev->dev), "dma-reset");
14986+	if (IS_ERR(hiedmac->rstc))
14987+		return PTR_ERR(hiedmac->rstc);
14988+
14989+	res = platform_get_resource(platdev, IORESOURCE_MEM, 0);
14990+	if (!res) {
14991+		hiedmacv310_error("no reg resource\n");
14992+		return -ENODEV;
14993+	}
14994+
14995+	hiedmac->base = devm_ioremap_resource(&(platdev->dev), res);
14996+	if (IS_ERR(hiedmac->base))
14997+		return PTR_ERR(hiedmac->base);
14998+	return 0;
14999+}
15000+
15001+static int hiedmacv310_of_property_read(struct hiedmacv310_driver_data *hiedmac)
15002+{
15003+	struct platform_device *platdev = hiedmac->dev;
15004+	struct device_node *np = platdev->dev.of_node;
15005+	int ret;
15006+
15007+	if (!of_find_property(np, "misc_regmap", NULL) ||
15008+		!of_find_property(np, "misc_ctrl_base", NULL))
15009+		hiedmac->misc_regmap = 0;
15010+	else {
15011+		hiedmac->misc_regmap = syscon_regmap_lookup_by_phandle(np, "misc_regmap");
15012+		if (IS_ERR(hiedmac->misc_regmap))
15013+			return PTR_ERR(hiedmac->misc_regmap);
15014+
15015+		ret = of_property_read_u32(np, "misc_ctrl_base", &(hiedmac->misc_ctrl_base));
15016+		if (ret) {
15017+			hiedmacv310_error("get dma-misc_ctrl_base fail\n");
15018+			return -ENODEV;
15019+		}
15020+	}
15021+	ret = of_property_read_u32(np, "devid", &(hiedmac->id));
15022+	if (ret) {
15023+		hiedmacv310_error("get hiedmac id fail\n");
15024+		return -ENODEV;
15025+	}
15026+	ret = of_property_read_u32(np, "dma-channels", &(hiedmac->channels));
15027+	if (ret) {
15028+		hiedmacv310_error("get dma-channels fail\n");
15029+		return -ENODEV;
15030+	}
15031+	ret = of_property_read_u32(np, "dma-requests", &(hiedmac->slave_requests));
15032+	if (ret) {
15033+		hiedmacv310_error("get dma-requests fail\n");
15034+		return -ENODEV;
15035+	}
15036+	hiedmacv310_trace(HIEDMACV310_REG_TRACE_LEVEL, "dma-channels = %d, dma-requests = %d\n",
15037+			  hiedmac->channels, hiedmac->slave_requests);
15038+	return 0;
15039+}
15040+
15041+static int get_of_probe(struct hiedmacv310_driver_data *hiedmac)
15042+{
15043+	struct platform_device *platdev = hiedmac->dev;
15044+	int ret;
15045+
15046+	ret = hiedmacv310_devm_get(hiedmac);
15047+	if (ret) {
15048+		return ret;
15049+	}
15050+
15051+	ret = hiedmacv310_of_property_read(hiedmac);
15052+	if (ret) {
15053+		return ret;
15054+	}
15055+
15056+	return of_dma_controller_register(platdev->dev.of_node,
15057+					  hiedma_of_xlate, hiedmac);
15058+}
15059+
15060+static void hiedmac_free_chan_resources(struct dma_chan *chan)
15061+{
15062+	vchan_free_chan_resources(to_virt_chan(chan));
15063+}
15064+
15065+static size_t read_residue_from_phychan(
15066+	struct hiedmacv310_dma_chan *edmac_dma_chan,
15067+	struct transfer_desc *tsf_desc)
15068+{
15069+	size_t bytes;
15070+	u64 next_lli;
15071+	struct hiedmacv310_phy_chan *phychan = edmac_dma_chan->phychan;
15072+	unsigned int i, index;
15073+	struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host;
15074+	hiedmac_lli *plli = NULL;
15075+
15076+	next_lli = (hiedmacv310_readl(hiedmac->base + hiedmac_cx_lli_l(phychan->id)) &
15077+			(~(HIEDMAC_LLI_ALIGN - 1)));
15078+	next_lli |= ((u64)(hiedmacv310_readl(hiedmac->base + hiedmac_cx_lli_h(
15079+			phychan->id)) & 0xffffffff) << BITS_PER_HALF_WORD);
15080+	bytes = hiedmacv310_readl(hiedmac->base + hiedmac_cx_curr_cnt0(
15081+			phychan->id));
15082+	if (next_lli != 0) {
15083+		/* It means lli mode */
15084+		bytes += tsf_desc->size;
15085+		index = (next_lli - tsf_desc->llis_busaddr) / sizeof(*plli);
15086+		plli = (hiedmac_lli *)(tsf_desc->llis_vaddr);
15087+		for (i = 0; i < index; i++)
15088+			bytes -= plli[i].count;
15089+	}
15090+	return bytes;
15091+}
15092+
15093+static enum dma_status hiedmac_tx_status(struct dma_chan *chan,
15094+					 dma_cookie_t cookie,
15095+					 struct dma_tx_state *txstate)
15096+{
15097+	enum dma_status ret;
15098+	struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan);
15099+	struct virt_dma_desc *vd = NULL;
15100+	struct transfer_desc *tsf_desc = NULL;
15101+	unsigned long flags;
15102+	size_t bytes;
15103+
15104+	ret = dma_cookie_status(chan, cookie, txstate);
15105+	if (ret == DMA_COMPLETE) {
15106+		return ret;
15107+	}
15108+
15109+	if (edmac_dma_chan->state == HIEDMAC_CHAN_PAUSED && ret == DMA_IN_PROGRESS) {
15110+		ret = DMA_PAUSED;
15111+		return ret;
15112+	}
15113+
15114+	spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags);
15115+	vd = vchan_find_desc(&edmac_dma_chan->virt_chan, cookie);
15116+	if (vd) {
15117+		/* no been trasfer */
15118+		tsf_desc = to_edmac_transfer_desc(&vd->tx);
15119+		bytes = tsf_desc->size;
15120+	} else {
15121+		/* trasfering */
15122+		tsf_desc = edmac_dma_chan->at;
15123+
15124+		if (!(edmac_dma_chan->phychan) || !tsf_desc) {
15125+			spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags);
15126+			return ret;
15127+		}
15128+		bytes = read_residue_from_phychan(edmac_dma_chan, tsf_desc);
15129+	}
15130+	spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags);
15131+	dma_set_residue(txstate, bytes);
15132+	return ret;
15133+}
15134+
15135+static struct hiedmacv310_phy_chan *hiedmac_get_phy_channel(
15136+	const struct hiedmacv310_driver_data *hiedmac,
15137+	struct hiedmacv310_dma_chan *edmac_dma_chan)
15138+{
15139+	struct hiedmacv310_phy_chan *ch = NULL;
15140+	unsigned long flags;
15141+	int i;
15142+
15143+	for (i = 0; i < hiedmac->channels; i++) {
15144+		ch = &hiedmac->phy_chans[i];
15145+
15146+		spin_lock_irqsave(&ch->lock, flags);
15147+
15148+		if (!ch->serving) {
15149+			ch->serving = edmac_dma_chan;
15150+			spin_unlock_irqrestore(&ch->lock, flags);
15151+			break;
15152+		}
15153+		spin_unlock_irqrestore(&ch->lock, flags);
15154+	}
15155+
15156+	if (i == hiedmac->channels) {
15157+		return NULL;
15158+	}
15159+
15160+	return ch;
15161+}
15162+
15163+static void hiedmac_write_lli(const struct hiedmacv310_driver_data *hiedmac,
15164+			      const struct hiedmacv310_phy_chan *phychan,
15165+			      const struct transfer_desc *tsf_desc)
15166+{
15167+	hiedmac_lli *plli = (hiedmac_lli *)tsf_desc->llis_vaddr;
15168+
15169+	if (plli->next_lli != 0x0)
15170+		hiedmacv310_writel((plli->next_lli & 0xffffffff) | HIEDMAC_LLI_ENABLE,
15171+				   hiedmac->base + hiedmac_cx_lli_l(phychan->id));
15172+	else
15173+		hiedmacv310_writel((plli->next_lli & 0xffffffff),
15174+				   hiedmac->base + hiedmac_cx_lli_l(phychan->id));
15175+
15176+	hiedmacv310_writel(((plli->next_lli >> 32) & 0xffffffff),
15177+			   hiedmac->base + hiedmac_cx_lli_h(phychan->id));
15178+	hiedmacv310_writel(plli->count, hiedmac->base + hiedmac_cx_cnt0(phychan->id));
15179+	hiedmacv310_writel(plli->src_addr & 0xffffffff,
15180+			   hiedmac->base + hiedmac_cx_src_addr_l(phychan->id));
15181+	hiedmacv310_writel((plli->src_addr >> 32) & 0xffffffff,
15182+			   hiedmac->base + hiedmac_cx_src_addr_h(phychan->id));
15183+	hiedmacv310_writel(plli->dest_addr & 0xffffffff,
15184+			   hiedmac->base + hiedmac_cx_dest_addr_l(phychan->id));
15185+	hiedmacv310_writel((plli->dest_addr >> 32) & 0xffffffff,
15186+			   hiedmac->base + hiedmac_cx_dest_addr_h(phychan->id));
15187+	hiedmacv310_writel(plli->config,
15188+			   hiedmac->base + hiedmac_cx_config(phychan->id));
15189+}
15190+
15191+static void hiedmac_start_next_txd(struct hiedmacv310_dma_chan *edmac_dma_chan)
15192+{
15193+	struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host;
15194+	struct hiedmacv310_phy_chan *phychan = edmac_dma_chan->phychan;
15195+	struct virt_dma_desc *vd = vchan_next_desc(&edmac_dma_chan->virt_chan);
15196+	struct transfer_desc *tsf_desc = to_edmac_transfer_desc(&vd->tx);
15197+	unsigned int val;
15198+	list_del(&tsf_desc->virt_desc.node);
15199+	edmac_dma_chan->at = tsf_desc;
15200+	hiedmac_write_lli(hiedmac, phychan, tsf_desc);
15201+	val = hiedmacv310_readl(hiedmac->base + hiedmac_cx_config(phychan->id));
15202+	hiedmacv310_trace(HIEDMACV310_REG_TRACE_LEVEL, " HIEDMAC_Cx_CONFIG  = 0x%x\n", val);
15203+	hiedmacv310_writel(val | HIEDMAC_CXCONFIG_LLI_START,
15204+			   hiedmac->base + hiedmac_cx_config(phychan->id));
15205+}
15206+
15207+static void hiedmac_start(struct hiedmacv310_dma_chan *edmac_dma_chan)
15208+{
15209+	struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host;
15210+	struct hiedmacv310_phy_chan *ch;
15211+	ch = hiedmac_get_phy_channel(hiedmac, edmac_dma_chan);
15212+	if (!ch) {
15213+		hiedmacv310_error("no phy channel available !\n");
15214+		edmac_dma_chan->state = HIEDMAC_CHAN_WAITING;
15215+		return;
15216+	}
15217+	edmac_dma_chan->phychan = ch;
15218+	edmac_dma_chan->state = HIEDMAC_CHAN_RUNNING;
15219+	hiedmac_start_next_txd(edmac_dma_chan);
15220+}
15221+
15222+static void hiedmac_issue_pending(struct dma_chan *chan)
15223+{
15224+	struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan);
15225+	unsigned long flags;
15226+	spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags);
15227+	if (vchan_issue_pending(&edmac_dma_chan->virt_chan)) {
15228+		if (!edmac_dma_chan->phychan && edmac_dma_chan->state != HIEDMAC_CHAN_WAITING)
15229+			hiedmac_start(edmac_dma_chan);
15230+	}
15231+	spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags);
15232+}
15233+
15234+static void hiedmac_free_txd_list(struct hiedmacv310_dma_chan *edmac_dma_chan)
15235+{
15236+	LIST_HEAD(head);
15237+	vchan_get_all_descriptors(&edmac_dma_chan->virt_chan, &head);
15238+	vchan_dma_desc_free_list(&edmac_dma_chan->virt_chan, &head);
15239+}
15240+
15241+static int hiedmac_config(struct dma_chan *chan,
15242+			  struct dma_slave_config *config)
15243+{
15244+	struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan);
15245+	if (!edmac_dma_chan->slave) {
15246+		hiedmacv310_error("slave is null!");
15247+		return -EINVAL;
15248+	}
15249+	edmac_dma_chan->cfg = *config;
15250+	return 0;
15251+}
15252+
15253+static void hiedmac_pause_phy_chan(const struct hiedmacv310_dma_chan *edmac_dma_chan)
15254+{
15255+	struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host;
15256+	struct hiedmacv310_phy_chan *phychan = edmac_dma_chan->phychan;
15257+	unsigned int val;
15258+	int timeout;
15259+
15260+	val = hiedmacv310_readl(hiedmac->base + hiedmac_cx_config(phychan->id));
15261+	val &= ~CCFG_EN;
15262+	hiedmacv310_writel(val, hiedmac->base + hiedmac_cx_config(phychan->id));
15263+	/* Wait for channel inactive */
15264+	for (timeout = 2000; timeout > 0; timeout--) {
15265+		if (!((0x1 << phychan->id) & hiedmacv310_readl(hiedmac->base + HIEDMAC_CH_STAT)))
15266+			break;
15267+		hiedmacv310_writel(val, hiedmac->base + hiedmac_cx_config(phychan->id));
15268+		udelay(1);
15269+	}
15270+	if (timeout == 0)
15271+		hiedmacv310_error(":channel%u timeout waiting for pause, timeout:%d\n",
15272+				  phychan->id, timeout);
15273+}
15274+
15275+static int hiedmac_pause(struct dma_chan *chan)
15276+{
15277+	struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan);
15278+	unsigned long flags;
15279+
15280+	spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags);
15281+	if (!edmac_dma_chan->phychan) {
15282+		spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags);
15283+		return 0;
15284+	}
15285+	hiedmac_pause_phy_chan(edmac_dma_chan);
15286+	edmac_dma_chan->state = HIEDMAC_CHAN_PAUSED;
15287+	spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags);
15288+	return 0;
15289+}
15290+
15291+static void hiedmac_resume_phy_chan(const struct hiedmacv310_dma_chan *edmac_dma_chan)
15292+{
15293+	struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host;
15294+	struct hiedmacv310_phy_chan *phychan = edmac_dma_chan->phychan;
15295+	unsigned int val;
15296+	val = hiedmacv310_readl(hiedmac->base + hiedmac_cx_config(phychan->id));
15297+	val |= CCFG_EN;
15298+	hiedmacv310_writel(val, hiedmac->base + hiedmac_cx_config(phychan->id));
15299+}
15300+
15301+static int hiedmac_resume(struct dma_chan *chan)
15302+{
15303+	struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan);
15304+	unsigned long flags;
15305+
15306+	spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags);
15307+
15308+	if (!edmac_dma_chan->phychan) {
15309+		spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags);
15310+		return 0;
15311+	}
15312+
15313+	hiedmac_resume_phy_chan(edmac_dma_chan);
15314+	edmac_dma_chan->state = HIEDMAC_CHAN_RUNNING;
15315+	spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags);
15316+
15317+	return 0;
15318+}
15319+
15320+void hiedmac_phy_free(struct hiedmacv310_dma_chan *chan);
15321+static void hiedmac_desc_free(struct virt_dma_desc *vd);
15322+static int hiedmac_terminate_all(struct dma_chan *chan)
15323+{
15324+	struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan);
15325+	unsigned long flags;
15326+
15327+	spin_lock_irqsave(&edmac_dma_chan->virt_chan.lock, flags);
15328+	if (!edmac_dma_chan->phychan && !edmac_dma_chan->at) {
15329+		spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags);
15330+		return 0;
15331+	}
15332+
15333+	edmac_dma_chan->state = HIEDMAC_CHAN_IDLE;
15334+
15335+	if (edmac_dma_chan->phychan)
15336+		hiedmac_phy_free(edmac_dma_chan);
15337+	if (edmac_dma_chan->at) {
15338+		hiedmac_desc_free(&edmac_dma_chan->at->virt_desc);
15339+		edmac_dma_chan->at = NULL;
15340+	}
15341+	hiedmac_free_txd_list(edmac_dma_chan);
15342+	spin_unlock_irqrestore(&edmac_dma_chan->virt_chan.lock, flags);
15343+
15344+	return 0;
15345+}
15346+
15347+static u32 get_width(enum dma_slave_buswidth width)
15348+{
15349+	switch (width) {
15350+	case DMA_SLAVE_BUSWIDTH_1_BYTE:
15351+		return HIEDMAC_WIDTH_8BIT;
15352+	case DMA_SLAVE_BUSWIDTH_2_BYTES:
15353+		return HIEDMAC_WIDTH_16BIT;
15354+	case DMA_SLAVE_BUSWIDTH_4_BYTES:
15355+		return HIEDMAC_WIDTH_32BIT;
15356+	case DMA_SLAVE_BUSWIDTH_8_BYTES:
15357+		return HIEDMAC_WIDTH_64BIT;
15358+	default:
15359+		hiedmacv310_error("check here, width warning!\n");
15360+		return ~0;
15361+	}
15362+}
15363+
15364+static unsigned int hiedmac_set_config_value(enum dma_transfer_direction direction,
15365+					     unsigned int addr_width,
15366+					     unsigned int burst,
15367+					     unsigned int signal)
15368+{
15369+	unsigned int config, width;
15370+
15371+	if (direction == DMA_MEM_TO_DEV) {
15372+		config = HIEDMAC_CONFIG_SRC_INC;
15373+	} else {
15374+		config = HIEDMAC_CONFIG_DST_INC;
15375+	}
15376+	hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "addr_width = 0x%x\n", addr_width);
15377+	width = get_width(addr_width);
15378+	hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "width = 0x%x\n", width);
15379+	config |= width << HIEDMAC_CONFIG_SRC_WIDTH_SHIFT;
15380+	config |= width << HIEDMAC_CONFIG_DST_WIDTH_SHIFT;
15381+	hiedmacv310_trace(HIEDMACV310_REG_TRACE_LEVEL, "tsf_desc->ccfg = 0x%x\n", config);
15382+	hiedmacv310_trace(HIEDMACV310_CONFIG_TRACE_LEVEL, "burst = 0x%x\n", burst);
15383+	config |= burst << HIEDMAC_CONFIG_SRC_BURST_SHIFT;
15384+	config |= burst << HIEDMAC_CONFIG_DST_BURST_SHIFT;
15385+	if (signal >= 0) {
15386+		hiedmacv310_trace(HIEDMACV310_REG_TRACE_LEVEL, "edmac_dma_chan->signal = %d\n", signal);
15387+		config |= (unsigned int)signal << HIEDMAC_CXCONFIG_SIGNAL_SHIFT;
15388+	}
15389+	config |= HIEDMAC_CXCONFIG_DEV_MEM_TYPE << HIEDMAC_CXCONFIG_TSF_TYPE_SHIFT;
15390+	return config;
15391+}
15392+
15393+struct transfer_desc *hiedmac_init_tsf_desc(struct dma_chan *chan,
15394+	enum dma_transfer_direction direction,
15395+	dma_addr_t *slave_addr)
15396+{
15397+	struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan);
15398+	struct transfer_desc *tsf_desc;
15399+	unsigned int burst = 0;
15400+	unsigned int addr_width = 0;
15401+	unsigned int maxburst = 0;
15402+	tsf_desc = kzalloc(sizeof(*tsf_desc), GFP_NOWAIT);
15403+	if (!tsf_desc)
15404+		return NULL;
15405+	if (direction == DMA_MEM_TO_DEV) {
15406+		*slave_addr = edmac_dma_chan->cfg.dst_addr;
15407+		addr_width = edmac_dma_chan->cfg.dst_addr_width;
15408+		maxburst = edmac_dma_chan->cfg.dst_maxburst;
15409+	} else if (direction == DMA_DEV_TO_MEM) {
15410+		*slave_addr = edmac_dma_chan->cfg.src_addr;
15411+		addr_width = edmac_dma_chan->cfg.src_addr_width;
15412+		maxburst = edmac_dma_chan->cfg.src_maxburst;
15413+	} else {
15414+		kfree(tsf_desc);
15415+		hiedmacv310_error("direction unsupported!\n");
15416+		return NULL;
15417+	}
15418+
15419+	if (maxburst > (HIEDMAC_MAX_BURST_WIDTH))
15420+		burst |= (HIEDMAC_MAX_BURST_WIDTH - 1);
15421+	else if (maxburst == 0)
15422+		burst |= HIEDMAC_MIN_BURST_WIDTH;
15423+	else
15424+		burst |= (maxburst - 1);
15425+
15426+	tsf_desc->ccfg = hiedmac_set_config_value(direction, addr_width,
15427+				 burst, edmac_dma_chan->signal);
15428+	hiedmacv310_trace(HIEDMACV310_REG_TRACE_LEVEL, "tsf_desc->ccfg = 0x%x\n", tsf_desc->ccfg);
15429+	return tsf_desc;
15430+}
15431+
15432+static int hiedmac_fill_desc(const struct hiedmac_sg *dsg,
15433+			     struct transfer_desc *tsf_desc,
15434+			     unsigned int length, unsigned int num)
15435+{
15436+	hiedmac_lli *plli = NULL;
15437+
15438+	if (num >= MAX_TSFR_LLIS) {
15439+		hiedmacv310_error("lli out of range. \n");
15440+		return -ENOMEM;
15441+	}
15442+
15443+	plli = (hiedmac_lli*)(tsf_desc->llis_vaddr);
15444+	memset(&plli[num], 0x0, sizeof(*plli));
15445+
15446+	plli[num].src_addr = dsg->src_addr;
15447+	plli[num].dest_addr = dsg->dst_addr;
15448+	plli[num].config = tsf_desc->ccfg;
15449+	plli[num].count = length;
15450+	tsf_desc->size += length;
15451+
15452+	if (num > 0) {
15453+		plli[num - 1].next_lli = (tsf_desc->llis_busaddr + (num) * sizeof(
15454+					  *plli)) & (~(HIEDMAC_LLI_ALIGN - 1));
15455+		plli[num - 1].next_lli |= HIEDMAC_LLI_ENABLE;
15456+	}
15457+	return 0;
15458+}
15459+
15460+static void free_dsg(struct list_head *dsg_head)
15461+{
15462+	struct hiedmac_sg *dsg = NULL;
15463+	struct hiedmac_sg *_dsg = NULL;
15464+
15465+	list_for_each_entry_safe(dsg, _dsg, dsg_head, node) {
15466+		list_del(&dsg->node);
15467+		kfree(dsg);
15468+	}
15469+}
15470+
15471+static int hiedmac_add_sg(struct list_head *sg_head,
15472+			  dma_addr_t dst, dma_addr_t src,
15473+			  size_t len)
15474+{
15475+	struct hiedmac_sg *dsg = NULL;
15476+
15477+	if (len == 0) {
15478+		hiedmacv310_error("Transfer length is 0. \n");
15479+		return -ENOMEM;
15480+	}
15481+
15482+	dsg = (struct hiedmac_sg *)kzalloc(sizeof(*dsg), GFP_NOWAIT);
15483+	if (!dsg) {
15484+		free_dsg(sg_head);
15485+		hiedmacv310_error("alloc memory for dsg fail.\n");
15486+		return -ENOMEM;
15487+	}
15488+
15489+	list_add_tail(&dsg->node, sg_head);
15490+	dsg->src_addr = src;
15491+	dsg->dst_addr = dst;
15492+	dsg->len = len;
15493+	return 0;
15494+}
15495+
15496+static int hiedmac_add_sg_slave(struct list_head *sg_head,
15497+			        dma_addr_t slave_addr, dma_addr_t addr,
15498+			        size_t length,
15499+				enum dma_transfer_direction direction)
15500+{
15501+	dma_addr_t src = 0;
15502+	dma_addr_t dst = 0;
15503+	if (direction == DMA_MEM_TO_DEV) {
15504+		src = addr;
15505+		dst = slave_addr;
15506+	} else if (direction == DMA_DEV_TO_MEM) {
15507+		src = slave_addr;
15508+		dst = addr;
15509+	} else {
15510+		hiedmacv310_error("invali dma_transfer_direction.\n");
15511+		return -ENOMEM;
15512+	}
15513+	return hiedmac_add_sg(sg_head, dst, src, length);
15514+}
15515+
15516+static int hiedmac_fill_sg_for_slave(struct list_head *sg_head,
15517+				     dma_addr_t slave_addr,
15518+				     struct scatterlist *sgl,
15519+				     unsigned int sg_len,
15520+				     enum dma_transfer_direction direction)
15521+{
15522+	struct scatterlist *sg = NULL;
15523+	int tmp, ret;
15524+	size_t length;
15525+	dma_addr_t addr;
15526+	if (sgl == NULL) {
15527+		hiedmacv310_error("sgl is null!\n");
15528+		return -ENOMEM;
15529+	}
15530+
15531+	for_each_sg(sgl, sg, sg_len, tmp) {
15532+		addr = sg_dma_address(sg);
15533+		length = sg_dma_len(sg);
15534+		ret = hiedmac_add_sg_slave(sg_head, slave_addr, addr, length, direction);
15535+		if (ret)
15536+			break;
15537+	}
15538+	return ret;
15539+}
15540+
15541+static inline int hiedmac_fill_sg_for_m2m_copy(struct list_head *sg_head,
15542+					     dma_addr_t dst, dma_addr_t src,
15543+					     size_t len)
15544+{
15545+	return hiedmac_add_sg(sg_head, dst, src, len);
15546+}
15547+
15548+static int hiedmac_fill_sg_for_cyclic(struct list_head *sg_head,
15549+				      dma_addr_t slave_addr,
15550+				      dma_addr_t buf_addr, size_t buf_len,
15551+				      size_t period_len,
15552+				      enum dma_transfer_direction direction)
15553+{
15554+	size_t count_in_sg = 0;
15555+	size_t trans_bytes;
15556+	int ret;
15557+	while (count_in_sg < buf_len) {
15558+		trans_bytes = min(period_len, buf_len - count_in_sg);
15559+		count_in_sg += trans_bytes;
15560+		ret = hiedmac_add_sg_slave(sg_head, slave_addr, buf_addr + count_in_sg, count_in_sg, direction);
15561+		if (ret)
15562+			return ret;
15563+	}
15564+	return 0;
15565+}
15566+
15567+static inline unsigned short get_max_width(dma_addr_t ccfg)
15568+{
15569+	unsigned short src_width = (ccfg & HIEDMAC_CONTROL_SRC_WIDTH_MASK) >> HIEDMAC_CONFIG_SRC_WIDTH_SHIFT;
15570+	unsigned short dst_width = (ccfg & HIEDMAC_CONTROL_DST_WIDTH_MASK) >> HIEDMAC_CONFIG_DST_WIDTH_SHIFT;
15571+	return 1 << max(src_width, dst_width); /* to byte */
15572+}
15573+
15574+static int hiedmac_fill_asg_lli_for_desc(struct hiedmac_sg *dsg,
15575+					 struct transfer_desc *tsf_desc,
15576+					 unsigned int *lli_count)
15577+{
15578+	int ret;
15579+	unsigned short width = get_max_width(tsf_desc->ccfg);
15580+
15581+	while (dsg->len != 0) {
15582+		size_t lli_len = MAX_TRANSFER_BYTES;
15583+		lli_len = (lli_len / width) * width; /* bus width align */
15584+		lli_len = min(lli_len, dsg->len);
15585+		ret = hiedmac_fill_desc(dsg, tsf_desc, lli_len, *lli_count);
15586+		if (ret)
15587+			return ret;
15588+
15589+		if (tsf_desc->ccfg & HIEDMAC_CONFIG_SRC_INC)
15590+			dsg->src_addr += lli_len;
15591+		if (tsf_desc->ccfg & HIEDMAC_CONFIG_DST_INC)
15592+			dsg->dst_addr += lli_len;
15593+		dsg->len -= lli_len;
15594+		(*lli_count)++;
15595+	}
15596+	return 0;
15597+}
15598+
15599+static int hiedmac_fill_lli_for_desc(struct list_head *sg_head,
15600+				     struct transfer_desc *tsf_desc)
15601+{
15602+	struct hiedmac_sg *dsg = NULL;
15603+	struct hiedmac_lli *last_plli = NULL;
15604+	unsigned int lli_count = 0;
15605+	int ret;
15606+
15607+	list_for_each_entry(dsg, sg_head, node) {
15608+		ret = hiedmac_fill_asg_lli_for_desc(dsg, tsf_desc, &lli_count);
15609+		if (ret)
15610+			return ret;
15611+	}
15612+
15613+	if (tsf_desc->cyclic) {
15614+		last_plli = (hiedmac_lli *)((uintptr_t)tsf_desc->llis_vaddr +
15615+					    (lli_count - 1) * sizeof(*last_plli));
15616+		last_plli->next_lli = tsf_desc->llis_busaddr | HIEDMAC_LLI_ENABLE;
15617+	} else {
15618+		last_plli = (hiedmac_lli *)((uintptr_t)tsf_desc->llis_vaddr +
15619+					    (lli_count - 1) * sizeof(*last_plli));
15620+		last_plli->next_lli = 0;
15621+	}
15622+	dump_lli(tsf_desc->llis_vaddr, lli_count);
15623+	return 0;
15624+}
15625+
15626+static struct dma_async_tx_descriptor *hiedmac_prep_slave_sg(
15627+	struct dma_chan *chan, struct scatterlist *sgl,
15628+	unsigned int sg_len, enum dma_transfer_direction direction,
15629+	unsigned long flags, void *context)
15630+{
15631+	struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan);
15632+	struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host;
15633+	struct transfer_desc *tsf_desc = NULL;
15634+	dma_addr_t slave_addr = 0;
15635+	int ret;
15636+	LIST_HEAD(sg_head);
15637+	if (sgl == NULL) {
15638+		hiedmacv310_error("sgl is null!\n");
15639+		return NULL;
15640+	}
15641+
15642+	tsf_desc = hiedmac_init_tsf_desc(chan, direction, &slave_addr);
15643+	if (!tsf_desc)
15644+		return NULL;
15645+
15646+	tsf_desc->llis_vaddr = dma_pool_alloc(hiedmac->pool, GFP_NOWAIT,
15647+					      &tsf_desc->llis_busaddr);
15648+	if (!tsf_desc->llis_vaddr) {
15649+		hiedmacv310_error("malloc memory from pool fail !\n");
15650+		goto err_alloc_lli;
15651+	}
15652+
15653+	ret = hiedmac_fill_sg_for_slave(&sg_head, slave_addr, sgl, sg_len, direction);
15654+	if (ret)
15655+		goto err_fill_sg;
15656+	ret = hiedmac_fill_lli_for_desc(&sg_head, tsf_desc);
15657+	free_dsg(&sg_head);
15658+	if (ret)
15659+		goto err_fill_sg;
15660+	return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags);
15661+
15662+err_fill_sg:
15663+	dma_pool_free(hiedmac->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr);
15664+err_alloc_lli:
15665+	kfree(tsf_desc);
15666+	return NULL;
15667+}
15668+
15669+static struct dma_async_tx_descriptor *hiedmac_prep_dma_m2m_copy(
15670+	struct dma_chan *chan, dma_addr_t dst, dma_addr_t src,
15671+	size_t len, unsigned long flags)
15672+{
15673+	struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan);
15674+	struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host;
15675+	struct transfer_desc *tsf_desc = NULL;
15676+	LIST_HEAD(sg_head);
15677+	u32 config = 0;
15678+	int ret;
15679+
15680+	if (!len)
15681+		return NULL;
15682+
15683+	tsf_desc = kzalloc(sizeof(*tsf_desc), GFP_NOWAIT);
15684+	if (tsf_desc == NULL) {
15685+		hiedmacv310_error("get tsf desc fail!\n");
15686+		return NULL;
15687+	}
15688+
15689+	tsf_desc->llis_vaddr = dma_pool_alloc(hiedmac->pool, GFP_NOWAIT,
15690+					      &tsf_desc->llis_busaddr);
15691+	if (!tsf_desc->llis_vaddr) {
15692+		hiedmacv310_error("malloc memory from pool fail !\n");
15693+		goto err_alloc_lli;
15694+	}
15695+
15696+	config |= HIEDMAC_CONFIG_SRC_INC | HIEDMAC_CONFIG_DST_INC;
15697+	config |= HIEDMAC_CXCONFIG_MEM_TYPE << HIEDMAC_CXCONFIG_TSF_TYPE_SHIFT;
15698+	/*  max burst width is 16 ,but reg value set 0xf */
15699+	config |= (HIEDMAC_MAX_BURST_WIDTH - 1) << HIEDMAC_CONFIG_SRC_BURST_SHIFT;
15700+	config |= (HIEDMAC_MAX_BURST_WIDTH - 1) << HIEDMAC_CONFIG_DST_BURST_SHIFT;
15701+	config |= HIEDMAC_MEM_BIT_WIDTH << HIEDMAC_CONFIG_SRC_WIDTH_SHIFT;
15702+	config |= HIEDMAC_MEM_BIT_WIDTH << HIEDMAC_CONFIG_DST_WIDTH_SHIFT;
15703+	tsf_desc->ccfg = config;
15704+	ret = hiedmac_fill_sg_for_m2m_copy(&sg_head, dst, src, len);
15705+	if (ret)
15706+		goto err_fill_sg;
15707+	ret = hiedmac_fill_lli_for_desc(&sg_head, tsf_desc);
15708+	free_dsg(&sg_head);
15709+	if (ret)
15710+		goto err_fill_sg;
15711+	return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags);
15712+
15713+err_fill_sg:
15714+	dma_pool_free(hiedmac->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr);
15715+err_alloc_lli:
15716+	kfree(tsf_desc);
15717+	return NULL;
15718+}
15719+
15720+
15721+static struct dma_async_tx_descriptor *hiedmac_prep_dma_cyclic(
15722+	struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len,
15723+	size_t period_len, enum dma_transfer_direction direction,
15724+	unsigned long flags)
15725+{
15726+	struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(chan);
15727+	struct hiedmacv310_driver_data *hiedmac = edmac_dma_chan->host;
15728+	struct transfer_desc *tsf_desc = NULL;
15729+	dma_addr_t slave_addr = 0;
15730+	LIST_HEAD(sg_head);
15731+	int ret;
15732+
15733+	tsf_desc = hiedmac_init_tsf_desc(chan, direction, &slave_addr);
15734+	if (!tsf_desc)
15735+		return NULL;
15736+
15737+	tsf_desc->llis_vaddr = dma_pool_alloc(hiedmac->pool, GFP_NOWAIT,
15738+			&tsf_desc->llis_busaddr);
15739+	if (!tsf_desc->llis_vaddr) {
15740+		hiedmacv310_error("malloc memory from pool fail !\n");
15741+		goto err_alloc_lli;
15742+	}
15743+
15744+	tsf_desc->cyclic = true;
15745+	ret = hiedmac_fill_sg_for_cyclic(&sg_head, slave_addr, buf_addr, buf_len, period_len, direction);
15746+	if (ret)
15747+		goto err_fill_sg;
15748+	ret = hiedmac_fill_lli_for_desc(&sg_head, tsf_desc);
15749+	free_dsg(&sg_head);
15750+	if (ret)
15751+		goto err_fill_sg;
15752+	return vchan_tx_prep(&edmac_dma_chan->virt_chan, &tsf_desc->virt_desc, flags);
15753+
15754+err_fill_sg:
15755+	dma_pool_free(hiedmac->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr);
15756+err_alloc_lli:
15757+	kfree(tsf_desc);
15758+	return NULL;
15759+}
15760+
15761+static void hiedmac_phy_reassign(struct hiedmacv310_phy_chan *phy_chan,
15762+				 struct hiedmacv310_dma_chan *chan)
15763+{
15764+	phy_chan->serving = chan;
15765+	chan->phychan = phy_chan;
15766+	chan->state = HIEDMAC_CHAN_RUNNING;
15767+
15768+	hiedmac_start_next_txd(chan);
15769+}
15770+
15771+static void hiedmac_terminate_phy_chan(struct hiedmacv310_driver_data *hiedmac,
15772+				       const struct hiedmacv310_dma_chan *edmac_dma_chan)
15773+{
15774+	unsigned int val;
15775+	struct hiedmacv310_phy_chan *phychan = edmac_dma_chan->phychan;
15776+	hiedmac_pause_phy_chan(edmac_dma_chan);
15777+	val = 0x1 << phychan->id;
15778+	hiedmacv310_writel(val, hiedmac->base + HIEDMAC_INT_TC1_RAW);
15779+	hiedmacv310_writel(val, hiedmac->base + HIEDMAC_INT_ERR1_RAW);
15780+	hiedmacv310_writel(val, hiedmac->base + HIEDMAC_INT_ERR2_RAW);
15781+}
15782+
15783+void hiedmac_phy_free(struct hiedmacv310_dma_chan *chan)
15784+{
15785+	struct hiedmacv310_driver_data *hiedmac = chan->host;
15786+	struct hiedmacv310_dma_chan *p = NULL;
15787+	struct hiedmacv310_dma_chan *next = NULL;
15788+
15789+	list_for_each_entry(p, &hiedmac->memcpy.channels, virt_chan.chan.device_node) {
15790+		if (p->state == HIEDMAC_CHAN_WAITING) {
15791+			next = p;
15792+			break;
15793+		}
15794+	}
15795+
15796+	if (!next) {
15797+		list_for_each_entry(p, &hiedmac->slave.channels, virt_chan.chan.device_node) {
15798+			if (p->state == HIEDMAC_CHAN_WAITING) {
15799+				next = p;
15800+				break;
15801+			}
15802+		}
15803+	}
15804+	hiedmac_terminate_phy_chan(hiedmac, chan);
15805+
15806+	if (next) {
15807+		spin_lock(&next->virt_chan.lock);
15808+		hiedmac_phy_reassign(chan->phychan, next);
15809+		spin_unlock(&next->virt_chan.lock);
15810+	} else {
15811+		chan->phychan->serving = NULL;
15812+	}
15813+
15814+	chan->phychan = NULL;
15815+	chan->state = HIEDMAC_CHAN_IDLE;
15816+}
15817+
15818+bool handle_irq(struct hiedmacv310_driver_data *hiedmac, int chan_id)
15819+{
15820+	struct hiedmacv310_dma_chan *chan = NULL;
15821+	struct hiedmacv310_phy_chan *phy_chan = NULL;
15822+	struct transfer_desc *tsf_desc = NULL;
15823+	unsigned int channel_tc_status, channel_err_status[ERR_STATUS_REG_NUM];
15824+
15825+	phy_chan = &hiedmac->phy_chans[chan_id];
15826+	chan = phy_chan->serving;
15827+	if (!chan) {
15828+		hiedmacv310_error("error interrupt on chan: %d!\n", chan_id);
15829+		return 0;
15830+	}
15831+	tsf_desc = chan->at;
15832+
15833+	channel_tc_status = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_TC1_RAW);
15834+	channel_tc_status = (channel_tc_status >> chan_id) & 0x01;
15835+	if (channel_tc_status)
15836+		hiedmacv310_writel(channel_tc_status << chan_id, hiedmac->base + HIEDMAC_INT_TC1_RAW);
15837+
15838+	channel_tc_status = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_TC2);
15839+	channel_tc_status = (channel_tc_status >> chan_id) & 0x01;
15840+	if (channel_tc_status)
15841+		hiedmacv310_writel(channel_tc_status << chan_id, hiedmac->base + HIEDMAC_INT_TC2_RAW);
15842+	channel_err_status[0] = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_ERR1);
15843+	channel_err_status[1] = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_ERR2);
15844+	channel_err_status[2] = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_ERR3);
15845+	if ((channel_err_status[0] | channel_err_status[1] | channel_err_status[2]) & (1 << chan_id)) {
15846+		hiedmacv310_error("Error in hiedmac %d!,ERR1 = 0x%x,ERR2 = 0x%x,ERR3 = 0x%x\n",
15847+				  chan_id, channel_err_status[0],
15848+				  channel_err_status[1], channel_err_status[2]);
15849+		hiedmacv310_writel(1 << chan_id, hiedmac->base + HIEDMAC_INT_ERR1_RAW);
15850+		hiedmacv310_writel(1 << chan_id, hiedmac->base + HIEDMAC_INT_ERR2_RAW);
15851+		hiedmacv310_writel(1 << chan_id, hiedmac->base + HIEDMAC_INT_ERR3_RAW);
15852+	}
15853+
15854+	spin_lock(&chan->virt_chan.lock);
15855+
15856+	if (tsf_desc->cyclic) {
15857+		vchan_cyclic_callback(&tsf_desc->virt_desc);
15858+		spin_unlock(&chan->virt_chan.lock);
15859+		return 1;
15860+	}
15861+	chan->at = NULL;
15862+	tsf_desc->done = true;
15863+	vchan_cookie_complete(&tsf_desc->virt_desc);
15864+
15865+	if (vchan_next_desc(&chan->virt_chan))
15866+		hiedmac_start_next_txd(chan);
15867+	else
15868+		hiedmac_phy_free(chan);
15869+	spin_unlock(&chan->virt_chan.lock);
15870+	return 1;
15871+}
15872+
15873+static irqreturn_t hiemdacv310_irq(int irq, void *dev)
15874+{
15875+	struct hiedmacv310_driver_data *hiedmac = (struct hiedmacv310_driver_data *)dev;
15876+	u32 mask = 0;
15877+	unsigned int channel_status, temp, i;
15878+
15879+	channel_status = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_STAT);
15880+	if (!channel_status) {
15881+		hiedmacv310_error("channel_status = 0x%x\n", channel_status);
15882+		return IRQ_NONE;
15883+	}
15884+
15885+	for (i = 0; i < hiedmac->channels; i++) {
15886+		temp = (channel_status >> i) & 0x1;
15887+		if (temp)
15888+			mask |= handle_irq(hiedmac, i) << i;
15889+	}
15890+	return mask ? IRQ_HANDLED : IRQ_NONE;
15891+}
15892+
15893+static inline void hiedmac_dma_slave_init(struct hiedmacv310_dma_chan *chan)
15894+{
15895+	chan->slave = true;
15896+}
15897+
15898+static void hiedmac_desc_free(struct virt_dma_desc *vd)
15899+{
15900+	struct transfer_desc *tsf_desc = to_edmac_transfer_desc(&vd->tx);
15901+	struct hiedmacv310_dma_chan *edmac_dma_chan = to_edamc_chan(vd->tx.chan);
15902+	dma_descriptor_unmap(&vd->tx);
15903+	dma_pool_free(edmac_dma_chan->host->pool, tsf_desc->llis_vaddr, tsf_desc->llis_busaddr);
15904+	kfree(tsf_desc);
15905+}
15906+
15907+static int hiedmac_init_virt_channels(struct hiedmacv310_driver_data *hiedmac,
15908+				      struct dma_device *dmadev,
15909+				      unsigned int channels, bool slave)
15910+{
15911+	struct hiedmacv310_dma_chan *chan = NULL;
15912+	int i;
15913+	INIT_LIST_HEAD(&dmadev->channels);
15914+
15915+	for (i = 0; i < channels; i++) {
15916+		chan = kzalloc(sizeof(struct hiedmacv310_dma_chan), GFP_KERNEL);
15917+		if (!chan) {
15918+			hiedmacv310_error("fail to allocate memory for virt channels!");
15919+			return -1;
15920+		}
15921+
15922+		chan->host = hiedmac;
15923+		chan->state = HIEDMAC_CHAN_IDLE;
15924+		chan->signal = -1;
15925+
15926+		if (slave) {
15927+			chan->id = i;
15928+			hiedmac_dma_slave_init(chan);
15929+		}
15930+		chan->virt_chan.desc_free = hiedmac_desc_free;
15931+		vchan_init(&chan->virt_chan, dmadev);
15932+	}
15933+	return 0;
15934+}
15935+
15936+void hiedmac_free_virt_channels(struct dma_device *dmadev)
15937+{
15938+	struct hiedmacv310_dma_chan *chan = NULL;
15939+	struct hiedmacv310_dma_chan *next = NULL;
15940+
15941+	list_for_each_entry_safe(chan, next, &dmadev->channels, virt_chan.chan.device_node) {
15942+		list_del(&chan->virt_chan.chan.device_node);
15943+		kfree(chan);
15944+	}
15945+}
15946+
15947+static void hiedmacv310_prep_dma_device(struct platform_device *pdev,
15948+					struct hiedmacv310_driver_data *hiedmac)
15949+{
15950+	dma_cap_set(DMA_MEMCPY, hiedmac->memcpy.cap_mask);
15951+	hiedmac->memcpy.dev = &pdev->dev;
15952+	hiedmac->memcpy.device_free_chan_resources = hiedmac_free_chan_resources;
15953+	hiedmac->memcpy.device_prep_dma_memcpy = hiedmac_prep_dma_m2m_copy;
15954+	hiedmac->memcpy.device_tx_status = hiedmac_tx_status;
15955+	hiedmac->memcpy.device_issue_pending = hiedmac_issue_pending;
15956+	hiedmac->memcpy.device_config = hiedmac_config;
15957+	hiedmac->memcpy.device_pause = hiedmac_pause;
15958+	hiedmac->memcpy.device_resume = hiedmac_resume;
15959+	hiedmac->memcpy.device_terminate_all = hiedmac_terminate_all;
15960+	hiedmac->memcpy.directions = BIT(DMA_MEM_TO_MEM);
15961+	hiedmac->memcpy.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
15962+
15963+	dma_cap_set(DMA_SLAVE, hiedmac->slave.cap_mask);
15964+	dma_cap_set(DMA_CYCLIC, hiedmac->slave.cap_mask);
15965+	hiedmac->slave.dev = &pdev->dev;
15966+	hiedmac->slave.device_free_chan_resources = hiedmac_free_chan_resources;
15967+	hiedmac->slave.device_tx_status = hiedmac_tx_status;
15968+	hiedmac->slave.device_issue_pending = hiedmac_issue_pending;
15969+	hiedmac->slave.device_prep_slave_sg = hiedmac_prep_slave_sg;
15970+	hiedmac->slave.device_prep_dma_cyclic = hiedmac_prep_dma_cyclic;
15971+	hiedmac->slave.device_config = hiedmac_config;
15972+	hiedmac->slave.device_resume = hiedmac_resume;
15973+	hiedmac->slave.device_pause = hiedmac_pause;
15974+	hiedmac->slave.device_terminate_all = hiedmac_terminate_all;
15975+	hiedmac->slave.directions = BIT(DMA_DEV_TO_MEM) | BIT(DMA_MEM_TO_DEV);
15976+	hiedmac->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT;
15977+}
15978+
15979+static int hiedmacv310_init_chan(struct hiedmacv310_driver_data *hiedmac)
15980+{
15981+	int i, ret;
15982+	hiedmac->phy_chans = kzalloc((hiedmac->channels * sizeof(
15983+				     struct hiedmacv310_phy_chan)),
15984+				     GFP_KERNEL);
15985+	if (!hiedmac->phy_chans) {
15986+		hiedmacv310_error("malloc for phy chans fail!");
15987+		return -ENOMEM;
15988+	}
15989+
15990+	for (i = 0; i < hiedmac->channels; i++) {
15991+		struct hiedmacv310_phy_chan *phy_ch = &hiedmac->phy_chans[i];
15992+		phy_ch->id = i;
15993+		phy_ch->base = hiedmac->base + hiedmac_cx_base(i);
15994+		spin_lock_init(&phy_ch->lock);
15995+		phy_ch->serving = NULL;
15996+	}
15997+
15998+	ret = hiedmac_init_virt_channels(hiedmac, &hiedmac->memcpy, hiedmac->channels,
15999+					 false);
16000+	if (ret) {
16001+		hiedmacv310_error("fail to init memory virt channels!");
16002+		goto  free_phychans;
16003+	}
16004+
16005+	ret = hiedmac_init_virt_channels(hiedmac, &hiedmac->slave, hiedmac->slave_requests,
16006+					 true);
16007+	if (ret) {
16008+		hiedmacv310_error("fail to init slave virt channels!");
16009+		goto  free_memory_virt_channels;
16010+	}
16011+	return 0;
16012+
16013+free_memory_virt_channels:
16014+	hiedmac_free_virt_channels(&hiedmac->memcpy);
16015+free_phychans:
16016+	kfree(hiedmac->phy_chans);
16017+	return -ENOMEM;
16018+}
16019+
16020+static void hiedmacv310_free_chan(struct hiedmacv310_driver_data *hiedmac)
16021+{
16022+	hiedmac_free_virt_channels(&hiedmac->slave);
16023+	hiedmac_free_virt_channels(&hiedmac->memcpy);
16024+	kfree(hiedmac->phy_chans);
16025+}
16026+
16027+static void hiedmacv310_prep_phy_device(const struct hiedmacv310_driver_data *hiedmac)
16028+{
16029+	clk_prepare_enable(hiedmac->clk);
16030+	clk_prepare_enable(hiedmac->axi_clk);
16031+	reset_control_deassert(hiedmac->rstc);
16032+
16033+	hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_TC1_RAW);
16034+	hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_TC2_RAW);
16035+	hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_ERR1_RAW);
16036+	hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_ERR2_RAW);
16037+	hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_ERR3_RAW);
16038+	hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN,
16039+			   hiedmac->base + HIEDMAC_INT_TC1_MASK);
16040+	hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN,
16041+			   hiedmac->base + HIEDMAC_INT_TC2_MASK);
16042+	hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN,
16043+			   hiedmac->base + HIEDMAC_INT_ERR1_MASK);
16044+	hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN,
16045+			   hiedmac->base + HIEDMAC_INT_ERR2_MASK);
16046+	hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN,
16047+			   hiedmac->base + HIEDMAC_INT_ERR3_MASK);
16048+}
16049+
16050+static struct hiedmacv310_driver_data* hiedmacv310_prep_hiedmac_device(struct platform_device *pdev)
16051+{
16052+	int ret;
16053+	struct hiedmacv310_driver_data *hiedmac = NULL;
16054+	ssize_t trasfer_size;
16055+
16056+	ret = dma_set_mask_and_coherent(&(pdev->dev), DMA_BIT_MASK(64));
16057+	if (ret)
16058+		return NULL;
16059+
16060+	hiedmac = kzalloc(sizeof(*hiedmac), GFP_KERNEL);
16061+	if (!hiedmac) {
16062+		hiedmacv310_error("malloc for hiedmac fail!");
16063+		return NULL;
16064+	}
16065+
16066+	hiedmac->dev = pdev;
16067+
16068+	ret = get_of_probe(hiedmac);
16069+	if (ret) {
16070+		hiedmacv310_error("get dts info fail!");
16071+		goto free_hiedmac;
16072+	}
16073+
16074+	hiedmacv310_prep_dma_device(pdev, hiedmac);
16075+	hiedmac->max_transfer_size = MAX_TRANSFER_BYTES;
16076+	trasfer_size = MAX_TSFR_LLIS * EDMACV300_LLI_WORDS * sizeof(u32);
16077+
16078+	hiedmac->pool = dma_pool_create(DRIVER_NAME, &(pdev->dev),
16079+					trasfer_size, EDMACV300_POOL_ALIGN, 0);
16080+	if (!hiedmac->pool) {
16081+		hiedmacv310_error("create pool fail!");
16082+		goto free_hiedmac;
16083+	}
16084+
16085+	ret = hiedmacv310_init_chan(hiedmac);
16086+	if (ret) {
16087+		goto free_pool;
16088+	}
16089+	return hiedmac;
16090+
16091+free_pool:
16092+	dma_pool_destroy(hiedmac->pool);
16093+free_hiedmac:
16094+	kfree(hiedmac);
16095+	return NULL;
16096+}
16097+
16098+static void free_hiedmac_device(struct hiedmacv310_driver_data *hiedmac)
16099+{
16100+	hiedmacv310_free_chan(hiedmac);
16101+	dma_pool_destroy(hiedmac->pool);
16102+	kfree(hiedmac);
16103+}
16104+
16105+static int __init hiedmacv310_probe(struct platform_device *pdev)
16106+{
16107+	int ret;
16108+	struct hiedmacv310_driver_data *hiedmac = NULL;
16109+
16110+	hiedmac = hiedmacv310_prep_hiedmac_device(pdev);
16111+	if (hiedmac == NULL) {
16112+		return -ENOMEM;
16113+	}
16114+
16115+	ret = request_irq(hiedmac->irq, hiemdacv310_irq, 0, DRIVER_NAME, hiedmac);
16116+	if (ret) {
16117+		hiedmacv310_error("fail to request irq");
16118+		goto free_hiedmac;
16119+	}
16120+	hiedmacv310_prep_phy_device(hiedmac);
16121+	ret = dma_async_device_register(&hiedmac->memcpy);
16122+	if (ret) {
16123+		hiedmacv310_error("%s failed to register memcpy as an async device - %d\n", __func__, ret);
16124+		goto free_irq_res;
16125+	}
16126+
16127+	ret = dma_async_device_register(&hiedmac->slave);
16128+	if (ret) {
16129+		hiedmacv310_error("%s failed to register slave as an async device - %d\n", __func__, ret);
16130+		goto free_memcpy_device;
16131+	}
16132+	return 0;
16133+
16134+free_memcpy_device:
16135+	dma_async_device_unregister(&hiedmac->memcpy);
16136+free_irq_res:
16137+	free_irq(hiedmac->irq, hiedmac);
16138+free_hiedmac:
16139+	free_hiedmac_device(hiedmac);
16140+	return -ENOMEM;
16141+}
16142+
16143+static int hiemda_remove(struct platform_device *pdev)
16144+{
16145+	int err = 0;
16146+	return err;
16147+}
16148+
16149+static const struct of_device_id hiedmacv310_match[] = {
16150+	{ .compatible = "hisilicon,hiedmacv310" },
16151+	{},
16152+};
16153+
16154+static struct platform_driver hiedmacv310_driver = {
16155+	.remove = hiemda_remove,
16156+	.driver = {
16157+		.name = "hiedmacv310",
16158+		.of_match_table = hiedmacv310_match,
16159+	},
16160+};
16161+
16162+static int __init hiedmacv310_init(void)
16163+{
16164+	return platform_driver_probe(&hiedmacv310_driver, hiedmacv310_probe);
16165+}
16166+subsys_initcall(hiedmacv310_init);
16167+
16168+static void __exit hiedmacv310_exit(void)
16169+{
16170+	platform_driver_unregister(&hiedmacv310_driver);
16171+}
16172+module_exit(hiedmacv310_exit);
16173+
16174+MODULE_LICENSE("GPL");
16175+MODULE_AUTHOR("Hisilicon");
16176diff --git a/drivers/dma/hiedmacv310.h b/drivers/dma/hiedmacv310.h
16177new file mode 100644
16178index 000000000..1fc093945
16179--- /dev/null
16180+++ b/drivers/dma/hiedmacv310.h
16181@@ -0,0 +1,153 @@
16182+/*
16183+ * driver/dma/hiedmacv310.h
16184+ *
16185+ * The Hiedma Controller v310 Device Driver for HiSilicon
16186+ *
16187+ * Copyright (c) 2020 HiSilicon Technologies Co., Ltd.
16188+ *
16189+ * This program is free software; you can redistribute  it and/or modify it
16190+ * under  the terms of  the GNU General  Public License as published by the
16191+ * Free Software Foundation;  either version 2 of the  License, or (at your
16192+ * option) any later version.
16193+ *
16194+ * This program is distributed in the hope that it will be useful,
16195+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
16196+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16197+ * GNU General Public License for more details.
16198+ *
16199+ * You should have received a copy of the GNU General Public License
16200+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16201+ *
16202+ */
16203+#ifndef __HIEDMACV310_H__
16204+#define __HIEDMACV310_H__
16205+
16206+/* debug control */
16207+#define HIEDMACV310_CONFIG_TRACE_LEVEL 3
16208+#define HIEDMACV310_TRACE_LEVEL 0
16209+#define HIEDMACV310_REG_TRACE_LEVEL 3
16210+#define HIEDMACV310_TRACE_FMT KERN_INFO
16211+
16212+#ifdef DEBUG_HIEDMAC
16213+#define hiedmacv310_trace(level, msg...) do { \
16214+	if ((level) >= HIEDMACV310_TRACE_LEVEL) { \
16215+		printk(HIEDMACV310_TRACE_FMT"%s:%d: ", __func__, __LINE__); \
16216+		printk(msg); \
16217+		printk("\n"); \
16218+	} \
16219+} while (0)
16220+
16221+
16222+#define hiedmacv310_assert(cond) do { \
16223+	if (!(cond)) { \
16224+		printk(KERN_ERR "Assert:hiedmacv310:%s:%d\n", \
16225+				__func__, \
16226+				__LINE__); \
16227+		BUG(); \
16228+	} \
16229+} while (0)
16230+
16231+#define hiedmacv310_error(s...) do { \
16232+	printk(KERN_ERR "hiedmacv310:%s:%d: ", __func__, __LINE__); \
16233+	printk(s); \
16234+	printk("\n"); \
16235+} while (0)
16236+
16237+#else
16238+
16239+#define hiedmacv310_trace(level, msg...)
16240+#define hiedmacv310_assert(level, msg...)
16241+#define hiedmacv310_error(level, msg...)
16242+
16243+#endif
16244+
16245+#define hiedmacv310_readl(addr) ((unsigned int)readl((void *)(addr)))
16246+
16247+#define hiedmacv310_writel(v, addr) do { writel(v, (void *)(addr)); \
16248+} while (0)
16249+
16250+
16251+#define MAX_TRANSFER_BYTES  0xffff
16252+
16253+/* reg offset */
16254+#define HIEDMAC_INT_STAT                  0x0
16255+#define HIEDMAC_INT_TC1                   0x4
16256+#define HIEDMAC_INT_TC2                   0x8
16257+#define HIEDMAC_INT_ERR1                  0xc
16258+#define HIEDMAC_INT_ERR2                  0x10
16259+#define HIEDMAC_INT_ERR3                  0x14
16260+
16261+#define HIEDMAC_INT_TC1_MASK              0x18
16262+#define HIEDMAC_INT_TC2_MASK              0x1c
16263+#define HIEDMAC_INT_ERR1_MASK             0x20
16264+#define HIEDMAC_INT_ERR2_MASK             0x24
16265+#define HIEDMAC_INT_ERR3_MASK             0x28
16266+
16267+#define HIEDMAC_INT_TC1_RAW               0x600
16268+#define HIEDMAC_INT_TC2_RAW               0x608
16269+#define HIEDMAC_INT_ERR1_RAW              0x610
16270+#define HIEDMAC_INT_ERR2_RAW              0x618
16271+#define HIEDMAC_INT_ERR3_RAW              0x620
16272+
16273+#define hiedmac_cx_curr_cnt0(cn)          (0x404 + (cn) * 0x20)
16274+#define hiedmac_cx_curr_src_addr_l(cn)    (0x408 + (cn) * 0x20)
16275+#define hiedmac_cx_curr_src_addr_h(cn)    (0x40c + (cn) * 0x20)
16276+#define hiedmac_cx_curr_dest_addr_l(cn)    (0x410 + (cn) * 0x20)
16277+#define hiedmac_cx_curr_dest_addr_h(cn)    (0x414 + (cn) * 0x20)
16278+
16279+#define HIEDMAC_CH_PRI                    0x688
16280+#define HIEDMAC_CH_STAT                   0x690
16281+#define HIEDMAC_DMA_CTRL                  0x698
16282+
16283+#define hiedmac_cx_base(cn)               (0x800 + (cn) * 0x40)
16284+#define hiedmac_cx_lli_l(cn)              (0x800 + (cn) * 0x40)
16285+#define hiedmac_cx_lli_h(cn)              (0x804 + (cn) * 0x40)
16286+#define hiedmac_cx_cnt0(cn)               (0x81c + (cn) * 0x40)
16287+#define hiedmac_cx_src_addr_l(cn)         (0x820 + (cn) * 0x40)
16288+#define hiedmac_cx_src_addr_h(cn)         (0x824 + (cn) * 0x40)
16289+#define hiedmac_cx_dest_addr_l(cn)        (0x828 + (cn) * 0x40)
16290+#define hiedmac_cx_dest_addr_h(cn)        (0x82c + (cn) * 0x40)
16291+#define hiedmac_cx_config(cn)             (0x830 + (cn) * 0x40)
16292+
16293+#define HIEDMAC_ALL_CHAN_CLR        0xff
16294+#define HIEDMAC_INT_ENABLE_ALL_CHAN 0xff
16295+
16296+
16297+#define HIEDMAC_CONFIG_SRC_INC          (1 << 31)
16298+#define HIEDMAC_CONFIG_DST_INC          (1 << 30)
16299+
16300+#define HIEDMAC_CONFIG_SRC_WIDTH_SHIFT  16
16301+#define HIEDMAC_CONFIG_DST_WIDTH_SHIFT  12
16302+#define HIEDMAC_WIDTH_8BIT              0b0
16303+#define HIEDMAC_WIDTH_16BIT             0b1
16304+#define HIEDMAC_WIDTH_32BIT             0b10
16305+#define HIEDMAC_WIDTH_64BIT             0b11
16306+#ifdef CONFIG_64BIT
16307+#define HIEDMAC_MEM_BIT_WIDTH HIEDMAC_WIDTH_64BIT
16308+#else
16309+#define HIEDMAC_MEM_BIT_WIDTH HIEDMAC_WIDTH_32BIT
16310+#endif
16311+
16312+#define HIEDMAC_MAX_BURST_WIDTH         16
16313+#define HIEDMAC_MIN_BURST_WIDTH         1
16314+#define HIEDMAC_CONFIG_SRC_BURST_SHIFT  24
16315+#define HIEDMAC_CONFIG_DST_BURST_SHIFT  20
16316+
16317+#define HIEDMAC_LLI_ALIGN   0x40
16318+#define HIEDMAC_LLI_DISABLE 0x0
16319+#define HIEDMAC_LLI_ENABLE 0x2
16320+
16321+#define HIEDMAC_CXCONFIG_SIGNAL_SHIFT   0x4
16322+#define HIEDMAC_CXCONFIG_MEM_TYPE       0x0
16323+#define HIEDMAC_CXCONFIG_DEV_MEM_TYPE   0x1
16324+#define HIEDMAC_CXCONFIG_TSF_TYPE_SHIFT 0x2
16325+#define HIEDMAC_CXCONFIG_LLI_START      0x1
16326+
16327+#define HIEDMAC_CXCONFIG_ITC_EN     0x1
16328+#define HIEDMAC_CXCONFIG_ITC_EN_SHIFT   0x1
16329+
16330+#define CCFG_EN 0x1
16331+
16332+#define HIEDMAC_CONTROL_SRC_WIDTH_MASK GENMASK(18, 16)
16333+#define HIEDMAC_CONTROL_DST_WIDTH_MASK GENMASK(14, 12)
16334+#endif
16335diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
16336index f1b53dd1d..0825ad601 100644
16337--- a/drivers/gpio/gpio-pl061.c
16338+++ b/drivers/gpio/gpio-pl061.c
16339@@ -289,6 +289,9 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
16340 	struct pl061 *pl061;
16341 	struct gpio_irq_chip *girq;
16342 	int ret, irq;
16343+#ifdef CONFIG_ARCH_HISI_BVT
16344+	int gpio_idx;
16345+#endif
16346
16347 	pl061 = devm_kzalloc(dev, sizeof(*pl061), GFP_KERNEL);
16348 	if (pl061 == NULL)
16349@@ -301,7 +304,20 @@ static int pl061_probe(struct amba_device *adev, const struct amba_id *id)
16350 	raw_spin_lock_init(&pl061->lock);
16351 	pl061->gc.request = gpiochip_generic_request;
16352 	pl061->gc.free = gpiochip_generic_free;
16353+#ifdef CONFIG_ARCH_HISI_BVT
16354+	if (dev->of_node) {
16355+		gpio_idx = of_alias_get_id(dev->of_node, "gpio");
16356+		if (gpio_idx < 0)
16357+			return -ENOMEM;
16358+		pl061->gc.base = gpio_idx * PL061_GPIO_NR;
16359+	}
16360+
16361+	if (pl061->gc.base < 0)
16362+		pl061->gc.base = -1;
16363+#else
16364 	pl061->gc.base = -1;
16365+#endif
16366+
16367 	pl061->gc.get_direction = pl061_get_direction;
16368 	pl061->gc.direction_input = pl061_direction_input;
16369 	pl061->gc.direction_output = pl061_direction_output;
16370diff --git a/drivers/gpu/drm/hisilicon/Kconfig b/drivers/gpu/drm/hisilicon/Kconfig
16371index cc5a244db..d69de65db 100644
16372--- a/drivers/gpu/drm/hisilicon/Kconfig
16373+++ b/drivers/gpu/drm/hisilicon/Kconfig
16374@@ -5,3 +5,4 @@
16375
16376 source "drivers/gpu/drm/hisilicon/hibmc/Kconfig"
16377 source "drivers/gpu/drm/hisilicon/kirin/Kconfig"
16378+source "drivers/gpu/drm/hisilicon/hismart/Kconfig"
16379diff --git a/drivers/gpu/drm/hisilicon/Makefile b/drivers/gpu/drm/hisilicon/Makefile
16380index 69dec6084..4d4968e65 100644
16381--- a/drivers/gpu/drm/hisilicon/Makefile
16382+++ b/drivers/gpu/drm/hisilicon/Makefile
16383@@ -5,3 +5,4 @@
16384
16385 obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc/
16386 obj-$(CONFIG_DRM_HISI_KIRIN) += kirin/
16387+obj-$(CONFIG_DRM_HISI_HISMART) += hismart/
16388diff --git a/drivers/gpu/drm/hisilicon/hismart/Kconfig b/drivers/gpu/drm/hisilicon/hismart/Kconfig
16389new file mode 100644
16390index 000000000..ffc8564a8
16391--- /dev/null
16392+++ b/drivers/gpu/drm/hisilicon/hismart/Kconfig
16393@@ -0,0 +1,8 @@
16394+config DRM_HISI_HISMART
16395+	tristate "DRM Support for Hisilicon Smart Media / Smart Vision SoC chipset"
16396+	depends on DRM && (ARM || ARM64)
16397+	select DRM_KMS_HELPER
16398+	select DRM_GEM_CMA_HELPER
16399+	help
16400+	  Choose this option to enable DRM on Hisilicon Smart Media / Smart Vision SoC chipset
16401+
16402diff --git a/drivers/gpu/drm/hisilicon/hismart/Makefile b/drivers/gpu/drm/hisilicon/hismart/Makefile
16403new file mode 100644
16404index 000000000..e89172f24
16405--- /dev/null
16406+++ b/drivers/gpu/drm/hisilicon/hismart/Makefile
16407@@ -0,0 +1,27 @@
16408+KERNEL_DIR := $(srctree)
16409+SDK_ROOT_DIR = $(shell cd $(KERNEL_DIR)/../../../../../device/soc/hisilicon/hi3516dv300/sdk_linux/drv && /bin/pwd)
16410+$(warning SDK_ROOT_DIR=  $(SDK_ROOT_DIR))
16411+EXTRA_CFLAGS +=  -I$(SDK_ROOT_DIR)/mpp/cbb/vo/vo_dev/drm_hal \
16412+		 -I$(SDK_ROOT_DIR)/mpp/component/hifb/drm_hal \
16413+		 -I$(SDK_ROOT_DIR)/mpp/component/hdmi/src/mkp/drm_hal \
16414+		 -I$(SDK_ROOT_DIR)/mpp/cbb/include \
16415+		 -I$(SDK_ROOT_DIR)/mpp/cbb/include/adapt \
16416+		 -I$(SDK_ROOT_DIR)/mpp/cbb/based/arch/hi3516cv500/include/hi3516cv500 \
16417+		 -I$(SDK_ROOT_DIR)/mpp/cbb/vo/vo_dev/include \
16418+		 -I$(SDK_ROOT_DIR)/mpp/cbb/vo/vo_dev/include/adapt \
16419+		 -I$(SDK_ROOT_DIR)/mpp/cbb/vo/include/adapt \
16420+		 -I$(SDK_ROOT_DIR)/mpp/cbb/vo/include \
16421+		 -I$(SDK_ROOT_DIR)/osal/include
16422+$(warning CONFIG_DRM_HISI_HISMART = $(CONFIG_DRM_HISI_HISMART))
16423+hi_drm-y := \
16424+	hi_drm_drv.o \
16425+	hi_drm_crtc.o \
16426+	hi_adp_crtc.o \
16427+	hi_drm_hdmitx.o \
16428+	hi_adp_hdmitx.o \
16429+	hi_drm_func_ext.o \
16430+	hi_drm_mipitx.o \
16431+	hi_adp_mipitx.o
16432+
16433+obj-y += hi_drm.o
16434+
16435diff --git a/drivers/gpu/drm/hisilicon/hismart/drm_hal_mipitx.h b/drivers/gpu/drm/hisilicon/hismart/drm_hal_mipitx.h
16436new file mode 100644
16437index 000000000..88192d01f
16438--- /dev/null
16439+++ b/drivers/gpu/drm/hisilicon/hismart/drm_hal_mipitx.h
16440@@ -0,0 +1,91 @@
16441+/*
16442+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
16443+ * Description: Hisilicon DRM driver
16444+ * Author: Hisilicon multimedia software group
16445+ * Create: 2020-7-29
16446+ */
16447+
16448+#ifndef __DRM_HAL_MIPITX_H__
16449+#define __DRM_HAL_MIPITX_H__
16450+
16451+/* output timming */
16452+enum IntfSync {
16453+    OUTPUT_USER = 0,          /* User timing */
16454+    OUTPUT_PAL,               /* PAL standard */
16455+    OUTPUT_NTSC,              /* NTSC standard */
16456+    OUTPUT_1080P24,           /* 1920 x 1080 at 24 Hz. */
16457+    OUTPUT_1080P25,           /* 1920 x 1080 at 25 Hz. */
16458+    OUTPUT_1080P30,           /* 1920 x 1080 at 30 Hz. */
16459+    OUTPUT_720P50,            /* 1280 x  720 at 50 Hz. */
16460+    OUTPUT_720P60,            /* 1280 x  720 at 60 Hz. */
16461+    OUTPUT_1080I50,           /* 1920 x 1080 at 50 Hz, interlace. */
16462+    OUTPUT_1080I60,           /* 1920 x 1080 at 60 Hz, interlace. */
16463+    OUTPUT_1080P50,           /* 1920 x 1080 at 50 Hz. */
16464+    OUTPUT_1080P60,           /* 1920 x 1080 at 60 Hz. */
16465+    OUTPUT_576P50,            /* 720  x  576 at 50 Hz. */
16466+    OUTPUT_480P60,            /* 720  x  480 at 60 Hz. */
16467+    OUTPUT_800X600_60,        /* VESA 800 x 600 at 60 Hz (non-interlaced) */
16468+    OUTPUT_1024X768_60,       /* VESA 1024 x 768 at 60 Hz (non-interlaced) */
16469+    OUTPUT_1280X1024_60,      /* VESA 1280 x 1024 at 60 Hz (non-interlaced) */
16470+    OUTPUT_1366X768_60,       /* VESA 1366 x 768 at 60 Hz (non-interlaced) */
16471+    OUTPUT_1440X900_60,       /* VESA 1440 x 900 at 60 Hz (non-interlaced) CVT Compliant */
16472+    OUTPUT_1280X800_60,       /* 1280*800@60Hz VGA@60Hz */
16473+    OUTPUT_1600X1200_60,      /* VESA 1600 x 1200 at 60 Hz (non-interlaced) */
16474+    OUTPUT_1680X1050_60,      /* VESA 1680 x 1050 at 60 Hz (non-interlaced) */
16475+    OUTPUT_1920X1200_60,      /* VESA 1920 x 1600 at 60 Hz (non-interlaced) CVT (Reduced Blanking) */
16476+    OUTPUT_640X480_60,        /* VESA 640 x 480 at 60 Hz (non-interlaced) CVT */
16477+    OUTPUT_960H_PAL,          /* ITU-R BT.1302 960 x 576 at 50 Hz (interlaced) */
16478+    OUTPUT_960H_NTSC,         /* ITU-R BT.1302 960 x 480 at 60 Hz (interlaced) */
16479+    OUTPUT_1920X2160_30,      /* 1920x2160_30 */
16480+    OUTPUT_2560X1440_30,      /* 2560x1440_30 */
16481+    OUTPUT_2560X1440_60,      /* 2560x1440_60 */
16482+    OUTPUT_2560X1600_60,      /* 2560x1600_60 */
16483+    OUTPUT_3840X2160_24,      /* 3840x2160_24 */
16484+    OUTPUT_3840X2160_25,      /* 3840x2160_25 */
16485+    OUTPUT_3840X2160_30,      /* 3840x2160_30 */
16486+    OUTPUT_3840X2160_50,      /* 3840x2160_50 */
16487+    OUTPUT_3840X2160_60,      /* 3840x2160_60 */
16488+    OUTPUT_4096X2160_24,      /* 4096x2160_24 */
16489+    OUTPUT_4096X2160_25,      /* 4096x2160_25 */
16490+    OUTPUT_4096X2160_30,      /* 4096x2160_30 */
16491+    OUTPUT_4096X2160_50,      /* 4096x2160_50 */
16492+    OUTPUT_4096X2160_60,      /* 4096x2160_60 */
16493+    OUTPUT_320X240_60,        /* For ota5182 at 60 Hz (8bit) */
16494+    OUTPUT_320X240_50,        /* For ili9342 at 50 Hz (6bit) */
16495+    OUTPUT_240X320_50,        /* Hi3559AV100: For ili9341 at 50 Hz (6bit) */
16496+    OUTPUT_240X320_60,        /* For ili9341 at 60 Hz (16bit) */
16497+    OUTPUT_800X600_50,        /* For LCD     at 50 Hz (24bit) */
16498+    OUTPUT_720X1280_60,       /* For MIPI DSI Tx 720 x1280 at 60 Hz */
16499+    OUTPUT_1080X1920_60,      /* For MIPI DSI Tx 1080x1920 at 60 Hz */
16500+    OUTPUT_7680X4320_30,      /* For HDMI2.1 at 30 Hz */
16501+};
16502+
16503+struct DispInfo {
16504+    unsigned int width;
16505+    unsigned int hbp;
16506+    unsigned int hfp;
16507+    unsigned int hsw;
16508+    unsigned int height;
16509+    unsigned int vbp;
16510+    unsigned int vfp;
16511+    unsigned int vsw;
16512+    unsigned int frameRate;
16513+    unsigned int intfType;
16514+    enum IntfSync intfSync;
16515+    unsigned int minLevel;
16516+    unsigned int maxLevel;
16517+    unsigned int defLevel;
16518+};
16519+
16520+struct DispOperations {
16521+    int (*init)(unsigned int dev_id);
16522+    int (*on)(unsigned int dev_id);
16523+    int (*off)(unsigned int dev_id);
16524+    int (*setBacklight)(unsigned int dev_id, unsigned int level);
16525+    int (*getDispInfo)(unsigned int dev_id, struct DispInfo *info);
16526+};
16527+
16528+struct DispOperations *GetDispOps(void);
16529+
16530+#endif /* __DRM_HAL_MIPITX_H__ */
16531+
16532diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_adp_crtc.c b/drivers/gpu/drm/hisilicon/hismart/hi_adp_crtc.c
16533new file mode 100755
16534index 000000000..897f7838f
16535--- /dev/null
16536+++ b/drivers/gpu/drm/hisilicon/hismart/hi_adp_crtc.c
16537@@ -0,0 +1,777 @@
16538+/*
16539+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
16540+ * Description: Hisilicon DRM driver
16541+ * Author: Hisilicon multimedia software group
16542+ * Create: 2020-7-29
16543+ */
16544+
16545+#include "hi_adp_crtc.h"
16546+#include <linux/clk.h>
16547+#include <linux/component.h>
16548+#include <linux/of_address.h>
16549+#include <video/videomode.h>
16550+#include <drm/drm_atomic_helper.h>
16551+#include <drm/drm_crtc.h>
16552+#include <drm/drm_crtc_helper.h>
16553+#include <drm/drm_fb_cma_helper.h>
16554+#include <drm/drm_fb_helper.h>
16555+#include <drm/drm_gem_cma_helper.h>
16556+#include <drm/drm_of.h>
16557+#include <drm/drm_plane_helper.h>
16558+#include <drm/drm_util.h>
16559+#include <drm/drm_framebuffer.h>
16560+#include <drm/drm_fourcc.h>
16561+#include <drm/drm_gem_framebuffer_helper.h>
16562+#include "hi_drm_drv.h"
16563+#include "drm_hal_common.h"
16564+#include "drm_hal_display.h"
16565+#include "drm_hal_gfx.h"
16566+#include "hi_drm_func_ext.h"
16567+
16568+struct hi_drm_plane {
16569+    struct drm_plane base;
16570+    struct hi_drm_crtc *root_hi_crtc; /* which hi_crtc this plane belongs to */
16571+    enum drm_hal_gfx_layer id; /* layer id */
16572+    unsigned int status; /* 0: closed, 1: opened */
16573+};
16574+
16575+struct hi_drm_crtc {
16576+    struct drm_crtc base;
16577+    /* each crtc can have several planes */
16578+    struct hi_drm_plane primary[HI_DRM_MAX_PRIMARY_NUM];
16579+    struct hi_drm_plane cursor;
16580+    struct hi_drm_plane overlay[HI_DRM_MAX_OVERLAY_NUM];
16581+    enum drm_hal_disp_chn id; /* display id */
16582+    adp_crtc_callback adp_crtc_cb;
16583+    unsigned int status; /* 0: closed, 1: opened */
16584+    bool vb_enable;
16585+};
16586+
16587+struct hi_drm_crtc_global {
16588+    struct hi_drm_crtc crtcs[HI_DRM_MAX_CRTC_NUM];
16589+    struct drm_hal_disp_dev *disp_dev; /* the pointer to drm hal display api */
16590+    struct drm_hal_gfx_dev *gfx_dev; /* the pointer to drm hal graphics api */
16591+};
16592+
16593+#define to_hi_crtc(x) container_of(x, struct hi_drm_crtc, base)
16594+#define to_hi_plane(x) container_of(x, struct hi_drm_plane, base)
16595+
16596+static struct hi_drm_crtc_global *g_hi_crtcs = NULL;
16597+
16598+static struct drm_hal_disp_dev* adp_crtc_get_disp_func(void)
16599+{
16600+    int ret;
16601+
16602+    if (g_hi_crtcs->disp_dev != NULL) {
16603+        return g_hi_crtcs->disp_dev;
16604+    }
16605+
16606+    ret = drm_get_export_func(MOD_ID_DISP, (hi_void **)&g_hi_crtcs->disp_dev);
16607+    if (ret != HI_SUCCESS) {
16608+        return NULL;
16609+    }
16610+
16611+    return (struct drm_hal_disp_dev *)g_hi_crtcs->disp_dev;
16612+}
16613+
16614+static struct drm_hal_gfx_dev* adp_crtc_get_gfx_func(void)
16615+{
16616+    int ret;
16617+
16618+    if (g_hi_crtcs->gfx_dev != NULL) {
16619+        return g_hi_crtcs->gfx_dev;
16620+    }
16621+
16622+    ret = drm_get_export_func(MOD_ID_GFX, (hi_void **)&g_hi_crtcs->gfx_dev);
16623+    if (ret != HI_SUCCESS) {
16624+        return NULL;
16625+    }
16626+
16627+    return (struct drm_hal_gfx_dev *)g_hi_crtcs->gfx_dev;
16628+}
16629+
16630+static void adp_gfx_get_capability(struct drm_hal_gfx_capability *cap)
16631+{
16632+    cap->layer_cap[DRM_HAL_GFX_G0].available = 1;
16633+    cap->layer_cap[DRM_HAL_GFX_G0].connected_disp_chn = DRM_HAL_DISP_0;
16634+    cap->layer_cap[DRM_HAL_GFX_G0].max_w = 1920; /* 1920 max width */
16635+    cap->layer_cap[DRM_HAL_GFX_G0].max_h = 1080; /* 1080 max height */
16636+    cap->layer_cap[DRM_HAL_GFX_G0].format_num = 2; /* 2:support 2 color format */
16637+    cap->layer_cap[DRM_HAL_GFX_G0].formats[0] = DRM_HAL_FMT_ARGB8888;
16638+    cap->layer_cap[DRM_HAL_GFX_G0].formats[1] = DRM_HAL_FMT_ARGB1555;
16639+
16640+    cap->layer_cap[DRM_HAL_GFX_G1].available = 0;
16641+
16642+    cap->layer_cap[DRM_HAL_GFX_G2].available = 0;
16643+
16644+    cap->layer_cap[DRM_HAL_GFX_G3].available = 1;
16645+    cap->layer_cap[DRM_HAL_GFX_G3].connected_disp_chn = DRM_HAL_DISP_0;
16646+    cap->layer_cap[DRM_HAL_GFX_G3].max_w = 256; /* 256 max width */
16647+    cap->layer_cap[DRM_HAL_GFX_G3].max_h = 256; /* 256 max height */
16648+    cap->layer_cap[DRM_HAL_GFX_G3].format_num = 2; /* 2:support 2 color format */
16649+    cap->layer_cap[DRM_HAL_GFX_G3].formats[0] = DRM_HAL_FMT_ARGB8888;
16650+    cap->layer_cap[DRM_HAL_GFX_G3].formats[1] = DRM_HAL_FMT_ARGB1555;
16651+
16652+    return;
16653+}
16654+
16655+int hi_adp_plane_get_by_index(struct drm_crtc *crtc, struct drm_plane **plane, enum drm_plane_type type, int index)
16656+{
16657+    int i;
16658+    int matched = 0;
16659+    struct drm_hal_gfx_capability cap;
16660+    struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc);
16661+
16662+    HI_DRM_CHECK_PTR_RETURN(hi_crtc);
16663+
16664+    /* currently only support primary plane, need support cursor plane later */
16665+    if (type != DRM_PLANE_TYPE_PRIMARY) {
16666+        HI_DRM_ERR("plane type %d not support!\n", type);
16667+        return -1;
16668+    }
16669+
16670+    if (index >= HI_DRM_MAX_PRIMARY_NUM) {
16671+        HI_DRM_ERR("invalid index: %d!\n", index);
16672+        return -1;
16673+    }
16674+
16675+    adp_gfx_get_capability(&cap);
16676+
16677+    for (i = 0; i < DRM_HAL_GFX_MAX; i++) {
16678+        if (cap.layer_cap[i].available != 0 &&
16679+            cap.layer_cap[i].connected_disp_chn == hi_crtc->id) {
16680+            if (matched++ == index)
16681+                break;
16682+        }
16683+    }
16684+    hi_crtc->primary[index].id = i;
16685+    hi_crtc->primary[index].root_hi_crtc = hi_crtc;
16686+    *plane = &hi_crtc->primary[index].base;
16687+
16688+    return 0;
16689+}
16690+
16691+static int hi_adp_crtc_set_csc(void)
16692+{
16693+    int ret;
16694+    hi_vo_csc csc = {0};
16695+    struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func();
16696+
16697+    HI_DRM_CHECK_PTR_RETURN(disp_dev);
16698+    HI_DRM_CHECK_PTR_RETURN(disp_dev->get_csc);
16699+    HI_DRM_CHECK_PTR_RETURN(disp_dev->set_csc);
16700+
16701+    ret = disp_dev->get_csc(DRM_HAL_GFX_G0, &csc);
16702+    if (ret != 0) {
16703+        HI_DRM_ERR("disp_dev->get_csc error, ret=%#x\n", ret);
16704+        return ret;
16705+    }
16706+
16707+    csc.csc_matrix = VO_CSC_MATRIX_IDENTITY;
16708+    ret = disp_dev->set_csc(DRM_HAL_GFX_G0, &csc);
16709+    if (ret != 0) {
16710+        HI_DRM_ERR("disp_dev->set_csc error, ret=%#x\n", ret);
16711+        return ret;
16712+    }
16713+    return 0;
16714+}
16715+
16716+int hi_adp_plane_reset_csc(struct drm_plane *plane)
16717+{
16718+    int ret = 0;
16719+    struct drm_connector *connector;
16720+    struct drm_connector_list_iter conn_iter;
16721+    enum drm_connector_status mipi_status = 0;
16722+    enum drm_connector_status hdmi_status = 0;
16723+
16724+    drm_connector_list_iter_begin(plane->dev, &conn_iter);
16725+    drm_for_each_connector_iter(connector, &conn_iter) {
16726+        if (connector->connector_type == DRM_MODE_CONNECTOR_DSI) {
16727+            mipi_status = connector->status;
16728+        } else if (connector->connector_type == DRM_MODE_CONNECTOR_HDMIA) {
16729+            hdmi_status = connector->status;
16730+        }
16731+    }
16732+    if (hdmi_status != connector_status_connected && mipi_status == connector_status_connected) {
16733+        ret = hi_adp_crtc_set_csc();
16734+    }
16735+    drm_connector_list_iter_end(&conn_iter);
16736+    return ret;
16737+}
16738+
16739+int hi_adp_plane_open(struct drm_plane *plane)
16740+{
16741+    int ret;
16742+    struct hi_drm_plane *hi_plane = to_hi_plane(plane);
16743+    struct drm_hal_gfx_dev *gfx_dev = adp_crtc_get_gfx_func();
16744+
16745+    HI_DRM_CHECK_PTR_RETURN(hi_plane);
16746+    HI_DRM_CHECK_PTR_RETURN(gfx_dev);
16747+    HI_DRM_CHECK_PTR_RETURN(gfx_dev->open);
16748+    HI_DRM_CHECK_PTR_RETURN(gfx_dev->enable);
16749+    HI_DRM_CHECK_PTR_RETURN(gfx_dev->close);
16750+
16751+    /* plane already opened */
16752+    if (hi_plane->status == 1) {
16753+        return 0;
16754+    }
16755+    /* ensure the relied crtc has been opened */
16756+    ret = hi_adp_crtc_open(&hi_plane->root_hi_crtc->base);
16757+    if (ret != 0) {
16758+        return -1;
16759+    }
16760+
16761+    ret = gfx_dev->open(hi_plane->id);
16762+    if (ret != 0) {
16763+        goto err_crtc_close;
16764+    }
16765+
16766+    ret = gfx_dev->enable(hi_plane->id);
16767+    if (ret != 0) {
16768+        goto err_dev_close;
16769+    }
16770+    hi_plane->status = 1;
16771+
16772+    return 0;
16773+
16774+err_dev_close:
16775+    gfx_dev->close(hi_plane->id);
16776+err_crtc_close:
16777+    hi_adp_crtc_close(&hi_plane->root_hi_crtc->base);
16778+    return ret;
16779+}
16780+
16781+static int adp_plane_close(struct drm_plane *plane)
16782+{
16783+    int ret;
16784+    struct hi_drm_plane *hi_plane = to_hi_plane(plane);
16785+    struct drm_hal_gfx_dev *gfx_dev = adp_crtc_get_gfx_func();
16786+
16787+    HI_DRM_CHECK_PTR_RETURN(hi_plane);
16788+    HI_DRM_CHECK_PTR_RETURN(gfx_dev);
16789+    HI_DRM_CHECK_PTR_RETURN(gfx_dev->disable);
16790+    HI_DRM_CHECK_PTR_RETURN(gfx_dev->close);
16791+
16792+    /* plane already closed */
16793+    if (hi_plane->status == 0) {
16794+        return 0;
16795+    }
16796+
16797+    ret = gfx_dev->disable(hi_plane->id);
16798+    if (ret != 0) {
16799+        return -1;
16800+    }
16801+
16802+    ret = gfx_dev->close(hi_plane->id);
16803+    if (ret != 0) {
16804+        return -1;
16805+    }
16806+    hi_plane->status = 0;
16807+    return 0;
16808+}
16809+
16810+int hi_adp_plane_close(struct drm_plane *plane)
16811+{
16812+    return adp_plane_close(plane);
16813+}
16814+
16815+static void adp_format_translate(u32 drm_fmt, enum drm_hal_color_fmt *hal_fmt)
16816+{
16817+    switch (drm_fmt) {
16818+        case DRM_FORMAT_ARGB8888:
16819+            /* fall-through */
16820+        case DRM_FORMAT_XRGB8888:
16821+            *hal_fmt = DRM_HAL_FMT_ARGB8888;
16822+            break;
16823+        case DRM_FORMAT_RGB888:
16824+            *hal_fmt = DRM_HAL_FMT_RGB888;
16825+            break;
16826+        case DRM_FORMAT_RGB565:
16827+            *hal_fmt = DRM_HAL_FMT_RGB565;
16828+            break;
16829+        case DRM_FORMAT_ARGB1555:
16830+            /* fall-through */
16831+        case DRM_FORMAT_XRGB1555:
16832+            *hal_fmt = DRM_HAL_FMT_ARGB1555;
16833+            break;
16834+        default:
16835+            *hal_fmt = DRM_HAL_FMT_MAX;
16836+            break;
16837+    }
16838+    return;
16839+}
16840+
16841+void hi_adp_plane_update(struct drm_plane *plane)
16842+{
16843+    int ret;
16844+    struct drm_plane_state *state = plane->state;
16845+    struct drm_framebuffer *fb = state->fb;
16846+    struct hi_drm_plane *hi_plane = to_hi_plane(plane);
16847+    struct drm_hal_rect hal_rect;
16848+    enum drm_hal_color_fmt hal_fmt;
16849+    struct drm_gem_object *gem = NULL;
16850+    struct drm_gem_cma_object *cma_gem = NULL;
16851+    struct drm_hal_gfx_dev *gfx_dev = adp_crtc_get_gfx_func();
16852+
16853+    HI_DRM_FUNC_ENTER();
16854+    /* no framebuffer or status not ready */
16855+    if (fb == NULL || IS_ERR_OR_NULL(hi_plane) || IS_ERR_OR_NULL(hi_plane->root_hi_crtc) ||
16856+        IS_ERR_OR_NULL(gfx_dev) || IS_ERR_OR_NULL(gfx_dev->set_attr) || IS_ERR_OR_NULL(gfx_dev->refresh) ||
16857+        hi_plane->root_hi_crtc->status == 0) {
16858+        return;
16859+    }
16860+
16861+    /* for cma gem only. */
16862+    gem = drm_gem_fb_get_obj(fb, 0);
16863+    cma_gem = to_drm_gem_cma_obj(gem);
16864+    /* no memory */
16865+    if (IS_ERR_OR_NULL(cma_gem)) {
16866+        return;
16867+    }
16868+
16869+    /* rect */
16870+    hal_rect.x = 0;
16871+    hal_rect.y = 0;
16872+    hal_rect.w = fb->width;
16873+    hal_rect.h = fb->height;
16874+    ret = gfx_dev->set_attr(hi_plane->id, DRM_HAL_GFX_ATTR_SIZE, &hal_rect);
16875+    if (ret != 0) {
16876+        drm_hal_err("error, ret=%#x!\n", ret);
16877+    }
16878+
16879+    /* format */
16880+    adp_format_translate(fb->format->format, &hal_fmt);
16881+    ret = gfx_dev->set_attr(hi_plane->id, DRM_HAL_GFX_ATTR_FORMAT, &hal_fmt);
16882+    if (ret != 0) {
16883+        drm_hal_err("error, ret=%#x!\n", ret);
16884+    }
16885+
16886+    /* stride */
16887+    ret = gfx_dev->set_attr(hi_plane->id, DRM_HAL_GFX_ATTR_STRIDE, &fb->pitches[0]);
16888+    if (ret != 0) {
16889+        drm_hal_err("error, ret=%#x!\n", ret);
16890+    }
16891+
16892+    /* buffer address */
16893+    ret = gfx_dev->set_attr(hi_plane->id, DRM_HAL_GFX_ATTR_BUFFER, &cma_gem->paddr);
16894+    if (ret != 0) {
16895+        drm_hal_err("error, ret=%#x!\n", ret);
16896+    }
16897+
16898+    /* enable the registers */
16899+    ret = gfx_dev->refresh(hi_plane->id);
16900+    if (ret != 0) {
16901+        drm_hal_err("error, ret=%#x!\n", ret);
16902+    }
16903+    HI_DRM_FUNC_EXIT();
16904+    return;
16905+}
16906+
16907+/* adp crtc global init */
16908+int hi_adp_crtc_init(void)
16909+{
16910+    g_hi_crtcs = kzalloc(sizeof(struct hi_drm_crtc_global), GFP_KERNEL);
16911+    if (g_hi_crtcs == NULL) {
16912+        return -ENOMEM;
16913+    }
16914+
16915+    return 0;
16916+}
16917+
16918+void hi_adp_crtc_deinit(void)
16919+{
16920+    struct drm_hal_gfx_dev *gfx_dev = adp_crtc_get_gfx_func();
16921+    struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func();
16922+
16923+    if (gfx_dev->deinit != NULL) {
16924+        gfx_dev->deinit();
16925+    }
16926+    if (disp_dev->deinit != NULL) {
16927+        disp_dev->deinit();
16928+    }
16929+    if (g_hi_crtcs != NULL) {
16930+        kfree(g_hi_crtcs);
16931+        g_hi_crtcs = NULL;
16932+    }
16933+    return;
16934+}
16935+
16936+void hi_adp_crtc_get_cap(struct hi_adp_crtc_cap *cap)
16937+{
16938+    if (cap != NULL) {
16939+        cap->crtc_num = 1;
16940+    }
16941+    return;
16942+}
16943+
16944+int hi_adp_crtc_get_by_index(struct drm_crtc **crtc, int index)
16945+{
16946+    if (index >= HI_DRM_MAX_CRTC_NUM) {
16947+        HI_DRM_ERR("invalid index %d\n", index);
16948+        return -1;
16949+    }
16950+
16951+    HI_DRM_CHECK_PTR_RETURN(g_hi_crtcs);
16952+    *crtc = &g_hi_crtcs->crtcs[index].base;
16953+    /* translate the index to drm hal enum */
16954+    switch (index) {
16955+        case 0:
16956+            g_hi_crtcs->crtcs[index].id = DRM_HAL_DISP_0;
16957+            break;
16958+        case 1:
16959+            g_hi_crtcs->crtcs[index].id = DRM_HAL_DISP_1;
16960+            break;
16961+        default:
16962+            return -1;
16963+    }
16964+    return 0;
16965+}
16966+
16967+int hi_adp_crtc_open(struct drm_crtc *crtc)
16968+{
16969+    int ret;
16970+    struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc);
16971+    struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func();
16972+
16973+    HI_DRM_CHECK_PTR_RETURN(hi_crtc);
16974+    HI_DRM_CHECK_PTR_RETURN(disp_dev);
16975+    HI_DRM_CHECK_PTR_RETURN(disp_dev->open);
16976+    HI_DRM_CHECK_PTR_RETURN(disp_dev->enable);
16977+    HI_DRM_CHECK_PTR_RETURN(disp_dev->close);
16978+
16979+    if (hi_crtc->status >= 1) {
16980+        HI_DRM_INFO("crtc already opened!\n");
16981+        return 0;
16982+    }
16983+
16984+    HI_DRM_INFO("prepare to open display: %d\n", hi_crtc->id);
16985+
16986+    ret = disp_dev->open(hi_crtc->id);
16987+    if (ret != 0) {
16988+        HI_DRM_ERR("disp_dev->open error, ret=%#x\n", ret);
16989+        goto err_ret;
16990+    }
16991+
16992+    ret = disp_dev->enable(hi_crtc->id);
16993+    if (ret != 0) {
16994+        HI_DRM_ERR("disp_dev->enable error, ret=%#x\n", ret);
16995+        goto err_disp_close;
16996+    }
16997+
16998+    hi_crtc->status = 1;
16999+    hi_crtc->vb_enable = false;
17000+
17001+    return 0;
17002+err_disp_close:
17003+    (void)disp_dev->close(hi_crtc->id);
17004+err_ret:
17005+    return ret;
17006+}
17007+
17008+int hi_adp_crtc_close(struct drm_crtc *crtc)
17009+{
17010+    int ret;
17011+    int i;
17012+    struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc);
17013+    struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func();
17014+
17015+    HI_DRM_CHECK_PTR_RETURN(hi_crtc);
17016+    HI_DRM_CHECK_PTR_RETURN(disp_dev);
17017+    HI_DRM_CHECK_PTR_RETURN(disp_dev->disable);
17018+    HI_DRM_CHECK_PTR_RETURN(disp_dev->close);
17019+
17020+    if (hi_crtc->status == 0) {
17021+        HI_DRM_INFO("crtc already closed!\n");
17022+        return 0;
17023+    }
17024+
17025+    ret = disp_dev->disable(hi_crtc->id);
17026+    if (ret != 0) {
17027+        HI_DRM_ERR("disp_dev->disable error, ret=%#x\n", ret);
17028+    }
17029+
17030+    /* close the crtc planes here to avoid the crtc vblank timeout issue!!! */
17031+    for (i = 0; i < HI_DRM_MAX_PRIMARY_NUM; i++) {
17032+        if (hi_crtc->primary[i].status == 1) {
17033+            (void)adp_plane_close(&hi_crtc->primary[i].base);
17034+        }
17035+    }
17036+
17037+    if (hi_crtc->cursor.status == 1) {
17038+        (void)adp_plane_close(&hi_crtc->cursor.base);
17039+    }
17040+
17041+    ret |= disp_dev->close(hi_crtc->id);
17042+    if (ret != 0) {
17043+        HI_DRM_ERR("disp_dev->close error, ret=%#x\n", ret);
17044+    }
17045+    hi_crtc->status = 0;
17046+    return ret;
17047+}
17048+
17049+int hi_adp_crtc_set_mode(struct drm_crtc *crtc, const struct drm_display_mode *mode)
17050+{
17051+    int ret;
17052+    struct drm_hal_timing timing;
17053+    enum drm_hal_timing_fmt fmt;
17054+    struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc);
17055+    struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func();
17056+
17057+    HI_DRM_CHECK_PTR_RETURN(hi_crtc);
17058+    HI_DRM_CHECK_PTR_RETURN(disp_dev);
17059+    HI_DRM_CHECK_PTR_RETURN(disp_dev->set_attr);
17060+
17061+    timing.clock = mode->clock;
17062+    timing.hdisplay = mode->hdisplay;
17063+    timing.hskew = mode->hskew;
17064+    timing.hsync_end = mode->hsync_end;
17065+    timing.hsync_start = mode->hsync_start;
17066+    timing.htotal = mode->htotal;
17067+    timing.vdisplay = mode->vdisplay;
17068+    timing.vscan = mode->vscan;
17069+    timing.vsync_end = mode->vsync_end;
17070+    timing.vsync_start = mode->vsync_start;
17071+    timing.vtotal = mode->vtotal;
17072+
17073+    fmt = hi_adp_crtc_timing_translate(&timing);
17074+    ret = disp_dev->set_attr(hi_crtc->id, DRM_HAL_DISP_ATTR_TIMING, (void *)&fmt);
17075+    if (ret != 0) {
17076+        HI_DRM_ERR("disp_dev->set_attr timing error, ret=%#x\n", ret);
17077+        return ret;
17078+    }
17079+    return 0;
17080+}
17081+
17082+/* userfor mipitx */
17083+int hi_adp_crtc_add_user_intf(struct drm_crtc *crtc)
17084+{
17085+    int ret;
17086+    struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc);
17087+    hi_vo_user_intfsync_info intf_sync_attr = {0};
17088+    struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func();
17089+
17090+    HI_DRM_CHECK_PTR_RETURN(crtc);
17091+    HI_DRM_CHECK_PTR_RETURN(hi_crtc);
17092+    HI_DRM_CHECK_PTR_RETURN(disp_dev);
17093+    HI_DRM_CHECK_PTR_RETURN(disp_dev->attach_user_intf_sync);
17094+
17095+    HI_DRM_CHECK_PTR_RETURN(disp_dev->attach_user_intf_sync);
17096+    intf_sync_attr.clk_reverse = HI_TRUE;
17097+    intf_sync_attr.dev_div = 1;
17098+    intf_sync_attr.pre_div = 1;
17099+    intf_sync_attr.user_intf_sync_attr.clk_source = VO_CLK_SOURCE_PLL;
17100+    intf_sync_attr.user_intf_sync_attr.user_sync_pll.fbdiv = 257;
17101+    intf_sync_attr.user_intf_sync_attr.user_sync_pll.frac = 10442139;
17102+    intf_sync_attr.user_intf_sync_attr.user_sync_pll.refdiv = 4;
17103+    intf_sync_attr.user_intf_sync_attr.user_sync_pll.postdiv1 = 7;
17104+    intf_sync_attr.user_intf_sync_attr.user_sync_pll.postdiv2 = 7;
17105+    ret = disp_dev->attach_user_intf_sync(hi_crtc->id, &intf_sync_attr, 0);
17106+    if (ret != 0) {
17107+        HI_DRM_ERR("attach_user_intf_sync error, ret=%#x\n", ret);
17108+        return ret;
17109+    }
17110+    return 0;
17111+}
17112+
17113+int hi_adp_crtc_add_intf(struct drm_crtc *crtc, unsigned int intf_type, unsigned int intf_id)
17114+{
17115+    int ret;
17116+    struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc);
17117+    struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func();
17118+
17119+    HI_DRM_CHECK_PTR_RETURN(hi_crtc);
17120+    HI_DRM_CHECK_PTR_RETURN(disp_dev);
17121+    HI_DRM_CHECK_PTR_RETURN(disp_dev->attach_intf);
17122+
17123+    ret = disp_dev->attach_intf(hi_crtc->id, intf_type, (void *)(&intf_id));
17124+    if (ret != 0) {
17125+        HI_DRM_ERR("dd->attach_intf error, ret=%#x\n", ret);
17126+        return ret;
17127+    }
17128+    return 0;
17129+}
17130+
17131+int hi_adp_crtc_del_intf(struct drm_crtc *crtc, unsigned int intf_type, unsigned int intf_id)
17132+{
17133+    int ret;
17134+    struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc);
17135+    struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func();
17136+
17137+    HI_DRM_CHECK_PTR_RETURN(hi_crtc);
17138+    HI_DRM_CHECK_PTR_RETURN(disp_dev);
17139+    HI_DRM_CHECK_PTR_RETURN(disp_dev->detach_intf);
17140+
17141+    ret = disp_dev->detach_intf(hi_crtc->id, intf_type, (void *)(&intf_id));
17142+    if (ret != 0) {
17143+        HI_DRM_ERR("dd->detach_intf error, ret=%#x\n", ret);
17144+        return ret;
17145+    }
17146+    return 0;
17147+}
17148+
17149+int hi_adp_crtc_add_user_intf_sync(struct drm_crtc *crtc, hi_vo_user_intfsync_info *intf_sync_attr,
17150+    unsigned int intf_id)
17151+{
17152+    int ret;
17153+    struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc);
17154+    struct drm_hal_disp_dev *disp_dev = adp_crtc_get_disp_func();
17155+
17156+    HI_DRM_CHECK_PTR_RETURN(hi_crtc);
17157+    HI_DRM_CHECK_PTR_RETURN(disp_dev);
17158+    HI_DRM_CHECK_PTR_RETURN(disp_dev->attach_user_intf_sync);
17159+    ret = disp_dev->attach_user_intf_sync(hi_crtc->id, intf_sync_attr, (void *)(&intf_id));
17160+    if (ret != 0) {
17161+        HI_DRM_ERR("attach_user_intf_sync error, ret=%#x\n", ret);
17162+        return ret;
17163+    }
17164+    return 0;
17165+}
17166+
17167+
17168+static struct hi_drm_crtc *adp_get_crtc_by_layer(enum drm_hal_gfx_layer layer)
17169+{
17170+    int i;
17171+    struct drm_hal_gfx_capability cap = {0};
17172+
17173+    if (layer >= DRM_HAL_GFX_MAX) {
17174+        return NULL;
17175+    }
17176+
17177+    adp_gfx_get_capability(&cap);
17178+
17179+    if (cap.layer_cap[layer].available == 0) {
17180+        return NULL;
17181+    }
17182+
17183+    for (i = 0; i < HI_DRM_MAX_CRTC_NUM; i++) {
17184+        if (g_hi_crtcs->crtcs[i].id == cap.layer_cap[layer].connected_disp_chn) {
17185+            return &g_hi_crtcs->crtcs[i];
17186+        }
17187+    }
17188+    return NULL;
17189+}
17190+
17191+int hi_adp_disp_cb(enum drm_hal_gfx_layer layer, enum drm_hal_gfx_cb_type type, void *para)
17192+{
17193+    struct hi_drm_crtc *hi_crtc = adp_get_crtc_by_layer(layer);
17194+
17195+    HI_DRM_CHECK_PTR_RETURN(hi_crtc);
17196+
17197+    if (type == DRM_HAL_GFX_CB_INTR_100 && hi_crtc->adp_crtc_cb != NULL && hi_crtc->status != 0) {
17198+        return hi_crtc->adp_crtc_cb(&hi_crtc->base, HI_ADP_CRTC_VBLANK, para);
17199+    }
17200+    return 0;
17201+}
17202+
17203+int hi_adp_crtc_reg_callback(struct drm_crtc *crtc, adp_crtc_callback cb)
17204+{
17205+    int ret;
17206+    struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc);
17207+    struct drm_plane *primary = crtc->primary;
17208+    struct hi_drm_plane *hi_plane = to_hi_plane(primary);
17209+    struct drm_hal_gfx_dev *gfx_dev = adp_crtc_get_gfx_func();
17210+
17211+    if (IS_ERR_OR_NULL(hi_crtc) || IS_ERR_OR_NULL(hi_plane) ||
17212+        IS_ERR_OR_NULL(gfx_dev) || IS_ERR_OR_NULL(gfx_dev->register_cb)) {
17213+        return -1;
17214+    }
17215+
17216+    /* the callback function has already be refistered */
17217+    if (hi_crtc->adp_crtc_cb != NULL) {
17218+        return 0;
17219+    }
17220+    /*
17221+     * register the callback to the layer of primary plane
17222+     * it is better that we can use the DHD interrupts from the display API, maybe we can improve this later
17223+     */
17224+    ret = gfx_dev->register_cb(hi_plane->id, DRM_HAL_GFX_CB_INTR_100, hi_adp_disp_cb);
17225+    if (ret != 0) {
17226+        HI_DRM_ERR("gfx dev register callback error\n");
17227+        return ret;
17228+    }
17229+    hi_crtc->adp_crtc_cb = cb;
17230+    return 0;
17231+}
17232+
17233+void hi_adp_crtc_set_vblank(struct drm_crtc *crtc, bool enable)
17234+{
17235+    struct hi_drm_crtc *hi_crtc = to_hi_crtc(crtc);
17236+    hi_crtc->vb_enable = enable;
17237+    return;
17238+}
17239+
17240+struct adp_crtc_timing_map {
17241+    enum drm_hal_timing_fmt timing_fmt;
17242+    struct drm_hal_timing timing;
17243+};
17244+
17245+static struct adp_crtc_timing_map g_adp_crtc_timing_map[] = {
17246+    {DRM_HAL_TIMING_FMT_1080P_60, {148500, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0}},
17247+    {DRM_HAL_TIMING_FMT_1080P_50, {148500, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1089, 1125, 0}},
17248+    {DRM_HAL_TIMING_FMT_1080P_59_94, {148352, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0}},
17249+    {DRM_HAL_TIMING_FMT_1080P_30, {74250, 1920, 2008, 2052, 2200, 0, 1080, 1084, 1089, 1125, 0}},
17250+    {DRM_HAL_TIMING_FMT_1080P_25, {74250, 1920, 2448, 2492, 2640, 0, 1080, 1084, 1089, 1125, 0}},
17251+    {DRM_HAL_TIMING_FMT_1080P_24, {74250, 1920, 2558, 2602, 2750, 0, 1080, 1084, 1089, 1125, 0}},
17252+    {DRM_HAL_TIMING_FMT_1080I_60, {74250, 1920, 2008, 2052, 2200, 0, 540, 542, 547, 562, 0}},
17253+    {DRM_HAL_TIMING_FMT_1080I_50, {74250, 1920, 2448, 2492, 2640, 0, 540, 542, 547, 562, 0}},
17254+    {DRM_HAL_TIMING_FMT_720P_60, {74250, 1280, 1390, 1430, 1650, 0, 720, 725, 730, 750, 0}},
17255+    {DRM_HAL_TIMING_FMT_720P_50, {74250, 1280, 1720, 1760, 1980, 0, 720, 725, 730, 750, 0}},
17256+    {DRM_HAL_TIMING_FMT_576P_50, {27000, 720, 732, 796, 864, 0, 576, 581, 586, 625, 0}},
17257+    {DRM_HAL_TIMING_FMT_480P_60, {27000, 720, 736, 798, 858, 0, 480, 489, 495, 525, 0}},
17258+    {DRM_HAL_TIMING_FMT_PAL, {13500, 720, 732, 795, 864, 0, 288, 290, 293, 312, 0}},
17259+    {DRM_HAL_TIMING_FMT_NTSC, {13500, 720, 739, 801, 858, 0, 240, 244, 247, 262, 0}},
17260+    {DRM_HAL_TIMING_FMT_VESA_800X600_60, {40000, 800, 840, 968, 1056, 0, 600, 601, 605, 628, 0}},
17261+    {DRM_HAL_TIMING_FMT_VESA_1024X768_60, {48400, 1024, 1048, 1184, 1344, 0, 768, 771, 777, 806, 0}},
17262+    {DRM_HAL_TIMING_FMT_VESA_1280X800_60, {83500, 1280, 1352, 1480, 1680, 0, 800, 803, 809, 831, 0}},
17263+    {DRM_HAL_TIMING_FMT_VESA_1280X1024_60, {108000, 1280, 1328, 1440, 1688, 0, 1024, 1025, 1028, 1066, 0}},
17264+    {DRM_HAL_TIMING_FMT_VESA_1366X768_60, {85500, 1366, 1436, 1579, 1792, 0, 768, 771, 774, 798, 0}},
17265+    {DRM_HAL_TIMING_FMT_VESA_1440X900_60, {106500, 1440, 1488, 1520, 1600, 0, 900, 903, 909, 926, 0}},
17266+    {DRM_HAL_TIMING_FMT_VESA_1600X1200_60, {162000, 1600, 1664, 1856, 2160, 0, 1200, 1201, 1204, 1250, 0}},
17267+    {DRM_HAL_TIMING_FMT_VESA_1680X1050_60, {146250, 1680, 1784, 1960, 2240, 0, 1050, 1053, 1059, 1089, 0}},
17268+    {DRM_HAL_TIMING_FMT_VESA_1920X1200_60, {193250, 1920, 1968, 2000, 2080, 0, 1200, 1203, 1209, 1235, 0}},
17269+    {DRM_HAL_TIMING_FMT_2560X1440_60, {238750, 2560, 2608, 2640, 2720, 0, 1440, 1442, 1447, 1481, 0}},
17270+    {DRM_HAL_TIMING_FMT_2560X1600_60, {268500, 2560, 2608, 2640, 2720, 0, 1600, 1603, 1609, 1646, 0}},
17271+    {DRM_HAL_TIMING_FMT_3840X2160P_24, {297000, 3840, 5116, 5204, 5500, 0, 2160, 2168, 2178, 2250, 0}},
17272+    {DRM_HAL_TIMING_FMT_3840X2160P_25, {297000, 3840, 4896, 4984, 5280, 0, 2160, 2168, 2178, 2250, 0}},
17273+    {DRM_HAL_TIMING_FMT_3840X2160P_30, {297000, 3840, 4016, 4104, 4400, 0, 2160, 2168, 2178, 2250, 0}},
17274+    {DRM_HAL_TIMING_FMT_3840X2160P_50, {594000, 3840, 4896, 4984, 5280, 0, 2160, 2168, 2178, 2250, 0}},
17275+    {DRM_HAL_TIMING_FMT_3840X2160P_60, {594000, 3840, 4016, 4104, 4400, 0, 2160, 2168, 2178, 2250, 0}},
17276+    {DRM_HAL_TIMING_FMT_4096X2160P_24, {297000, 4096, 5116, 5204, 5500, 0, 2160, 2168, 2178, 2250, 0}},
17277+    {DRM_HAL_TIMING_FMT_4096X2160P_25, {297000, 4096, 5064, 5152, 5280, 0, 2160, 2168, 2178, 2250, 0}},
17278+    {DRM_HAL_TIMING_FMT_4096X2160P_30, {297000, 4096, 4184, 4272, 4400, 0, 2160, 2168, 2178, 2250, 0}},
17279+    {DRM_HAL_TIMING_FMT_4096X2160P_50, {594000, 4096, 5064, 5152, 5280, 0, 2160, 2168, 2178, 2250, 0}},
17280+    {DRM_HAL_TIMING_FMT_4096X2160P_60, {594000, 4096, 4184, 4272, 4400, 0, 2160, 2168, 2178, 2250, 0}},
17281+    {DRM_HAL_TIMING_FMT_USER, {155493, 480, 528, 560, 620, 0, 960, 963, 968, 974, 0}},
17282+};
17283+
17284+enum drm_hal_timing_fmt hi_adp_crtc_timing_translate(struct drm_hal_timing *timing)
17285+{
17286+    int i;
17287+
17288+    for (i = 0; i < sizeof(g_adp_crtc_timing_map) / sizeof(struct adp_crtc_timing_map); i++) {
17289+        if (g_adp_crtc_timing_map[i].timing.clock == timing->clock &&
17290+            g_adp_crtc_timing_map[i].timing.hdisplay == timing->hdisplay &&
17291+            g_adp_crtc_timing_map[i].timing.hsync_start == timing->hsync_start &&
17292+            g_adp_crtc_timing_map[i].timing.hsync_end == timing->hsync_end &&
17293+            g_adp_crtc_timing_map[i].timing.htotal == timing->htotal &&
17294+            g_adp_crtc_timing_map[i].timing.hskew == timing->hskew &&
17295+            g_adp_crtc_timing_map[i].timing.vdisplay == timing->vdisplay &&
17296+            g_adp_crtc_timing_map[i].timing.vsync_start == timing->vsync_start &&
17297+            g_adp_crtc_timing_map[i].timing.vsync_end == timing->vsync_end &&
17298+            g_adp_crtc_timing_map[i].timing.vtotal == timing->vtotal &&
17299+            g_adp_crtc_timing_map[i].timing.vscan == timing->vscan) {
17300+            break;
17301+        }
17302+    }
17303+
17304+    HI_DRM_INFO("find matched: i = %d!\n", i);
17305+
17306+    if (i == sizeof(g_adp_crtc_timing_map) / sizeof(struct adp_crtc_timing_map)) {
17307+        HI_DRM_ERR("can not find the matched format!\n");
17308+        HI_DRM_ERR("org timing: %d %d %d %d %d %d %d %d %d %d %d\n", timing->clock, timing->hdisplay,
17309+            timing->hsync_start, timing->hsync_end, timing->htotal, timing->hskew, timing->vdisplay,
17310+            timing->vsync_start, timing->vsync_end, timing->vtotal, timing->vscan);
17311+        return DRM_HAL_TIMING_FMT_MAX;
17312+    }
17313+    return g_adp_crtc_timing_map[i].timing_fmt;
17314+}
17315diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_adp_crtc.h b/drivers/gpu/drm/hisilicon/hismart/hi_adp_crtc.h
17316new file mode 100644
17317index 000000000..31f13ff5f
17318--- /dev/null
17319+++ b/drivers/gpu/drm/hisilicon/hismart/hi_adp_crtc.h
17320@@ -0,0 +1,69 @@
17321+/*
17322+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
17323+ * Description: Hisilicon DRM driver
17324+ * Author: Hisilicon multimedia software group
17325+ * Create: 2020-7-29
17326+ */
17327+
17328+#ifndef __HI_ADP_CRTC_H__
17329+#define __HI_ADP_CRTC_H__
17330+
17331+#include <drm/drm_crtc.h>
17332+#include <drm/drm_mode.h>
17333+#include "drm_hal_common.h"
17334+#include "hi_comm_vo_adapt.h"
17335+
17336+#define HI_DRM_MAX_CRTC_NUM     2
17337+#define HI_DRM_MAX_PRIMARY_NUM  2
17338+#define HI_DRM_MAX_OVERLAY_NUM  2
17339+
17340+enum hi_adp_crtc_event {
17341+    HI_ADP_CRTC_VBLANK,
17342+};
17343+
17344+struct hi_adp_crtc_cap {
17345+    int crtc_num;
17346+};
17347+
17348+int hi_adp_crtc_init(void);
17349+
17350+void hi_adp_crtc_deinit(void);
17351+
17352+void hi_adp_crtc_get_cap(struct hi_adp_crtc_cap *cap);
17353+
17354+int hi_adp_plane_get_by_index(struct drm_crtc *crtc, struct drm_plane **plane, enum drm_plane_type type, int index);
17355+
17356+int hi_adp_plane_open(struct drm_plane *plane);
17357+
17358+int hi_adp_plane_close(struct drm_plane *plane);
17359+
17360+void hi_adp_plane_update(struct drm_plane *plane);
17361+
17362+int hi_adp_crtc_get_by_index(struct drm_crtc **crtc, int index);
17363+
17364+int hi_adp_crtc_open(struct drm_crtc *crtc);
17365+
17366+int hi_adp_crtc_close(struct drm_crtc *crtc);
17367+
17368+int hi_adp_crtc_set_mode(struct drm_crtc *crtc, const struct drm_display_mode *mode);
17369+
17370+int hi_adp_crtc_add_user_intf(struct drm_crtc *crtc);
17371+
17372+int hi_adp_crtc_add_intf(struct drm_crtc *crtc, unsigned int intf_type, unsigned int intf_id);
17373+
17374+int hi_adp_crtc_del_intf(struct drm_crtc *crtc, unsigned int intf_type, unsigned int intf_id);
17375+
17376+int hi_adp_crtc_add_user_intf_sync(struct drm_crtc *crtc, hi_vo_user_intfsync_info *intf_sync_attr,
17377+    unsigned int intf_id);
17378+
17379+typedef int (*adp_crtc_callback)(struct drm_crtc *crtc, enum hi_adp_crtc_event event, void *para);
17380+
17381+int hi_adp_crtc_reg_callback(struct drm_crtc *crtc, adp_crtc_callback cb);
17382+
17383+void hi_adp_crtc_set_vblank(struct drm_crtc *crtc, bool enable);
17384+
17385+enum drm_hal_timing_fmt hi_adp_crtc_timing_translate(struct drm_hal_timing *timing);
17386+
17387+int hi_adp_plane_reset_csc(struct drm_plane *plane);
17388+
17389+#endif /* __HI_ADP_CRTC_H__ */
17390diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_adp_hdmitx.c b/drivers/gpu/drm/hisilicon/hismart/hi_adp_hdmitx.c
17391new file mode 100644
17392index 000000000..7b72a0639
17393--- /dev/null
17394+++ b/drivers/gpu/drm/hisilicon/hismart/hi_adp_hdmitx.c
17395@@ -0,0 +1,345 @@
17396+/*
17397+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
17398+ * Description: Hisilicon DRM driver
17399+ * Author: Hisilicon multimedia software group
17400+ * Create: 2020-7-29
17401+ */
17402+
17403+#include "hi_adp_hdmitx.h"
17404+#include <linux/clk.h>
17405+#include <linux/component.h>
17406+#include <linux/of_address.h>
17407+#include <video/videomode.h>
17408+#include <drm/drm_atomic_helper.h>
17409+#include <drm/drm_crtc.h>
17410+#include <drm/drm_crtc_helper.h>
17411+#include <drm/drm_fb_cma_helper.h>
17412+#include <drm/drm_fb_helper.h>
17413+#include <drm/drm_gem_cma_helper.h>
17414+#include <drm/drm_of.h>
17415+#include <drm/drm_plane_helper.h>
17416+#include <drm/drm_util.h>
17417+#include "hi_drm_drv.h"
17418+#include "hi_adp_crtc.h"
17419+#include "drm_hal_common.h"
17420+#include "drm_hal_hdmitx.h"
17421+#include "drm_hal_display.h"
17422+#include "hi_drm_func_ext.h"
17423+
17424+#define HI_DRM_MAX_EDID_NUM   10
17425+
17426+struct hi_drm_hdmitx {
17427+    struct drm_connector conn;
17428+    struct drm_encoder encoder;
17429+
17430+    unsigned int drm_hdmi_id;
17431+    enum drm_hal_hdmitx_id hi_hdmi_id;
17432+
17433+    unsigned int open; /* 0: close, 1: open */
17434+    unsigned int enable; /* 0: disable, 1: enable */
17435+};
17436+
17437+#define to_hi_hdmitx_by_conn(x) container_of(x, struct hi_drm_hdmitx, conn)
17438+#define to_hi_hdmitx_by_encoder(x) container_of(x, struct hi_drm_hdmitx, encoder)
17439+
17440+struct hi_drm_hdmitx_global {
17441+    struct hi_drm_hdmitx hdmitx[HI_DRM_MAX_HDMI_NUM];
17442+    struct drm_hal_hdmitx_dev *hdmi_dev;
17443+};
17444+
17445+static struct hi_drm_hdmitx_global *g_hi_hdmitx = NULL;
17446+
17447+static struct drm_hal_hdmitx_dev* adp_hdmitx_get_intf_func(void)
17448+{
17449+    int ret;
17450+
17451+    if (g_hi_hdmitx->hdmi_dev != NULL) {
17452+        return g_hi_hdmitx->hdmi_dev;
17453+    }
17454+
17455+    ret = drm_get_export_func(MOD_ID_HDMI, (hi_void **)&g_hi_hdmitx->hdmi_dev);
17456+    if (ret != HI_SUCCESS) {
17457+        return NULL;
17458+    }
17459+
17460+    return (struct drm_hal_hdmitx_dev *)g_hi_hdmitx->hdmi_dev;
17461+}
17462+
17463+static int hdmitx_channel_check_open(struct hi_drm_hdmitx *hdmitx)
17464+{
17465+    int ret;
17466+    struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func();
17467+
17468+    HI_DRM_CHECK_PTR_RETURN(hdmitx);
17469+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev);
17470+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev->open);
17471+
17472+    if (hdmitx->open == 1) {
17473+        return 0;
17474+    }
17475+
17476+    ret = hdmi_dev->open(hdmitx->hi_hdmi_id);
17477+    if (ret != 0) {
17478+        drm_hal_err("error, ret=%#x!\n", ret);
17479+        return ret;
17480+    }
17481+    hdmitx->open = 1;
17482+    return 0;
17483+}
17484+
17485+static int hdmitx_channel_check_close(struct hi_drm_hdmitx *hdmitx)
17486+{
17487+    int ret;
17488+    struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func();
17489+
17490+    HI_DRM_CHECK_PTR_RETURN(hdmitx);
17491+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev);
17492+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev->close);
17493+
17494+    if (hdmitx->open == 0) {
17495+        return 0;
17496+    }
17497+
17498+    ret = hdmi_dev->close(hdmitx->hi_hdmi_id);
17499+    if (ret != 0) {
17500+        drm_hal_err("error, ret=%#x!\n", ret);
17501+        return ret;
17502+    }
17503+    hdmitx->open = 0;
17504+    return 0;
17505+}
17506+
17507+static int hdmitx_channel_check_enable(struct hi_drm_hdmitx *hdmitx)
17508+{
17509+    int ret;
17510+    struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func();
17511+
17512+    HI_DRM_CHECK_PTR_RETURN(hdmitx);
17513+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev);
17514+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev->enable);
17515+
17516+    if (hdmitx->enable == 1) {
17517+        return 0;
17518+    }
17519+
17520+    ret = hdmi_dev->enable(hdmitx->hi_hdmi_id);
17521+    if (ret != 0) {
17522+        drm_hal_err("error, ret=%#x!\n", ret);
17523+        return ret;
17524+    }
17525+    hdmitx->enable = 1;
17526+    return 0;
17527+}
17528+
17529+static int hdmitx_channel_check_disable(struct hi_drm_hdmitx *hdmitx)
17530+{
17531+    int ret;
17532+    struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func();
17533+
17534+    HI_DRM_CHECK_PTR_RETURN(hdmitx);
17535+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev);
17536+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev->disable);
17537+
17538+    if (hdmitx->enable == 0) {
17539+        return 0;
17540+    }
17541+
17542+    ret = hdmi_dev->disable(hdmitx->hi_hdmi_id);
17543+    if (ret != 0) {
17544+        drm_hal_err("error, ret=%#x!\n", ret);
17545+        return ret;
17546+    }
17547+    hdmitx->enable = 0;
17548+    return 0;
17549+}
17550+
17551+int hi_adp_hdmitx_get_edid(struct drm_connector *conn, void *edid, int len)
17552+{
17553+    int ret;
17554+    struct hi_drm_hdmitx *hi_hdmitx = to_hi_hdmitx_by_conn(conn);
17555+    struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func();
17556+
17557+    HI_DRM_CHECK_PTR_RETURN(edid);
17558+    HI_DRM_CHECK_PTR_RETURN(hi_hdmitx);
17559+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev);
17560+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev->read_edid);
17561+
17562+    ret = hdmitx_channel_check_open(hi_hdmitx);
17563+    if (ret != 0) {
17564+        return ret;
17565+    }
17566+
17567+    ret = hdmi_dev->read_edid(hi_hdmitx->hi_hdmi_id, edid, len);
17568+    if (ret <= 0) {
17569+        return -1;
17570+    }
17571+    return 0;
17572+}
17573+
17574+enum drm_connector_status hi_adp_hdmitx_detect(struct drm_connector *conn, bool force)
17575+{
17576+    int ret;
17577+    enum drm_hal_hdmitx_connect_status stat;
17578+    struct hi_drm_hdmitx *hi_hdmitx = to_hi_hdmitx_by_conn(conn);
17579+    struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func();
17580+
17581+    HI_DRM_CHECK_PTR_RETURN(hi_hdmitx);
17582+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev);
17583+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev->get_status);
17584+
17585+    ret = hdmitx_channel_check_open(hi_hdmitx);
17586+    if (ret != 0) {
17587+        return ret;
17588+    }
17589+
17590+    ret = hdmi_dev->get_status(hi_hdmitx->hi_hdmi_id, DRM_HAL_HDMITX_STAT_CONNECTOR, &stat);
17591+    if (ret != 0) {
17592+        return connector_status_unknown;
17593+    }
17594+
17595+    HI_DRM_INFO("hdmitx status detected: %d\n", stat);
17596+
17597+    switch (stat) {
17598+        case DRM_HAL_HDMITX_CONNECTED:
17599+            return connector_status_connected;
17600+        case DRM_HAL_HDMITX_DISCONNECTED:
17601+            return connector_status_disconnected;
17602+        case DRM_HAL_HDMITX_UNKNOWN:
17603+            return connector_status_unknown;
17604+        default:
17605+            return connector_status_unknown;
17606+    }
17607+    return connector_status_unknown;
17608+}
17609+
17610+int hi_adp_hdmitx_enable(struct drm_encoder *encoder)
17611+{
17612+    int ret;
17613+    struct hi_drm_hdmitx *hi_hdmitx = to_hi_hdmitx_by_encoder(encoder);
17614+
17615+    HI_DRM_CHECK_PTR_RETURN(hi_hdmitx);
17616+
17617+    ret = hdmitx_channel_check_open(hi_hdmitx);
17618+    if (ret != 0) {
17619+        return ret;
17620+    }
17621+
17622+    ret = hdmitx_channel_check_enable(hi_hdmitx);
17623+    if (ret != 0) {
17624+        goto err_check_close;
17625+    }
17626+    return 0;
17627+err_check_close:
17628+    hdmitx_channel_check_close(hi_hdmitx);
17629+    return ret;
17630+}
17631+
17632+int hi_adp_hdmitx_disable(struct drm_encoder *encoder)
17633+{
17634+    int ret;
17635+    struct hi_drm_hdmitx *hi_hdmitx = to_hi_hdmitx_by_encoder(encoder);
17636+
17637+    HI_DRM_CHECK_PTR_RETURN(hi_hdmitx);
17638+
17639+    ret = hdmitx_channel_check_disable(hi_hdmitx);
17640+    if (ret != 0) {
17641+        return ret;
17642+    }
17643+
17644+    ret = hdmitx_channel_check_close(hi_hdmitx);
17645+    if (ret != 0) {
17646+        return ret;
17647+    }
17648+    return 0;
17649+}
17650+
17651+int hi_adp_hdmitx_set_mode(struct drm_encoder *encoder, struct drm_display_mode *mode,
17652+    struct drm_connector_state *conn_state)
17653+{
17654+    int ret;
17655+    struct drm_hal_hdmitx_attr hdmi_attr = {0};
17656+    struct drm_hal_timing timing;
17657+    struct hi_drm_hdmitx *hi_hdmitx = to_hi_hdmitx_by_encoder(encoder);
17658+    struct drm_hal_hdmitx_dev *hdmi_dev = adp_hdmitx_get_intf_func();
17659+
17660+    HI_DRM_CHECK_PTR_RETURN(hi_hdmitx);
17661+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev);
17662+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev->get_attr);
17663+    HI_DRM_CHECK_PTR_RETURN(hdmi_dev->set_attr);
17664+
17665+    ret = hdmitx_channel_check_open(hi_hdmitx);
17666+    if (ret != 0) {
17667+        return ret;
17668+    }
17669+
17670+    if (hi_hdmitx->enable == 1) {
17671+        return 0;
17672+    }
17673+
17674+    /* dispatch the mode to the connected crtc */
17675+    ret = hi_adp_crtc_set_mode(conn_state->crtc, mode);
17676+    if (ret != 0) {
17677+        drm_hal_err("error, ret=%#x!\n", ret);
17678+    }
17679+
17680+    /* attach the interface to crtc */
17681+    ret = hi_adp_crtc_add_intf(conn_state->crtc, DRM_HAL_DISP_INTF_HDMITX, hi_hdmitx->hi_hdmi_id);
17682+    if (ret != 0) {
17683+        drm_hal_err("error, ret=%#x!\n", ret);
17684+    }
17685+
17686+    ret = hdmi_dev->get_attr(hi_hdmitx->hi_hdmi_id, &hdmi_attr);
17687+    if (ret != 0) {
17688+        drm_hal_err("error, ret=%#x!\n", ret);
17689+    }
17690+
17691+    timing.clock = mode->clock;
17692+    timing.hdisplay = mode->hdisplay;
17693+    timing.hskew = mode->hskew;
17694+    timing.hsync_end = mode->hsync_end;
17695+    timing.hsync_start = mode->hsync_start;
17696+    timing.htotal = mode->htotal;
17697+    timing.vdisplay = mode->vdisplay;
17698+    timing.vscan = mode->vscan;
17699+    timing.vsync_end = mode->vsync_end;
17700+    timing.vsync_start = mode->vsync_start;
17701+    timing.vtotal = mode->vtotal;
17702+    hdmi_attr.fmt = hi_adp_crtc_timing_translate(&timing);
17703+    ret = hdmi_dev->set_attr(hi_hdmitx->hi_hdmi_id, &hdmi_attr);
17704+    if (ret != 0) {
17705+        drm_hal_err("error, ret=%#x!\n", ret);
17706+    }
17707+    return 0;
17708+}
17709+
17710+int hi_adp_hdmitx_get_by_index(unsigned int drm_hdmi_id, struct drm_connector **conn, struct drm_encoder **encoder)
17711+{
17712+    HI_DRM_CHECK_PTR_RETURN(g_hi_hdmitx);
17713+
17714+    /* only support 1xHDMI yet */
17715+    if (drm_hdmi_id != DRM_MODE_CONNECTOR_HDMIA) {
17716+        return -1;
17717+    }
17718+
17719+    g_hi_hdmitx->hdmitx[0].drm_hdmi_id = drm_hdmi_id;
17720+    g_hi_hdmitx->hdmitx[0].hi_hdmi_id = DRM_HAL_HDMITX_0;
17721+    *conn = &g_hi_hdmitx->hdmitx[0].conn;
17722+    *encoder = &g_hi_hdmitx->hdmitx[0].encoder;
17723+    return 0;
17724+}
17725+
17726+int hi_adp_hdmitx_init(void)
17727+{
17728+    g_hi_hdmitx = kzalloc(sizeof(struct hi_drm_hdmitx_global), GFP_KERNEL);
17729+    if (g_hi_hdmitx == NULL) {
17730+        return -ENOMEM;
17731+    }
17732+
17733+    return 0;
17734+}
17735+
17736+void hi_adp_hdmitx_deinit(void)
17737+{
17738+    kfree(g_hi_hdmitx);
17739+    g_hi_hdmitx = NULL;
17740+}
17741diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_adp_hdmitx.h b/drivers/gpu/drm/hisilicon/hismart/hi_adp_hdmitx.h
17742new file mode 100644
17743index 000000000..4c7f08883
17744--- /dev/null
17745+++ b/drivers/gpu/drm/hisilicon/hismart/hi_adp_hdmitx.h
17746@@ -0,0 +1,28 @@
17747+/*
17748+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
17749+ * Description: Hisilicon DRM driver
17750+ * Author: Hisilicon multimedia software group
17751+ * Create: 2020-7-29
17752+ */
17753+
17754+#ifndef __HI_ADP_HDMITX_H__
17755+#define __HI_ADP_HDMITX_H__
17756+
17757+#include <drm/drm_connector.h>
17758+#include <drm/drm_encoder.h>
17759+#include <drm/drm_modes.h>
17760+
17761+#define HI_DRM_MAX_HDMI_NUM 2
17762+
17763+int hi_adp_hdmitx_init(void);
17764+void hi_adp_hdmitx_deinit(void);
17765+int hi_adp_hdmitx_get_by_index(unsigned int drm_hdmi_id, struct drm_connector **conn, struct drm_encoder **encoder);
17766+int hi_adp_hdmitx_get_edid(struct drm_connector *conn, void *edid, int len);
17767+enum drm_connector_status hi_adp_hdmitx_detect(struct drm_connector *conn, bool force);
17768+int hi_adp_hdmitx_enable(struct drm_encoder *encoder);
17769+int hi_adp_hdmitx_disable(struct drm_encoder *encoder);
17770+int hi_adp_hdmitx_set_mode(struct drm_encoder *encoder, struct drm_display_mode *mode,
17771+    struct drm_connector_state *conn_state);
17772+
17773+#endif /* __HI_ADP_HDMITX_H__ */
17774+
17775diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_adp_mipitx.c b/drivers/gpu/drm/hisilicon/hismart/hi_adp_mipitx.c
17776new file mode 100755
17777index 000000000..1902f1e8f
17778--- /dev/null
17779+++ b/drivers/gpu/drm/hisilicon/hismart/hi_adp_mipitx.c
17780@@ -0,0 +1,300 @@
17781+/*
17782+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
17783+ * Description: Hisilicon DRM driver
17784+ * Author: Hisilicon multimedia software group
17785+ * Create: 2020-7-29
17786+ */
17787+
17788+#include "hi_adp_mipitx.h"
17789+#include <linux/clk.h>
17790+#include <linux/component.h>
17791+#include <linux/of_address.h>
17792+#include <video/videomode.h>
17793+#include <drm/drm_atomic_helper.h>
17794+#include <drm/drm_crtc.h>
17795+#include <drm/drm_crtc_helper.h>
17796+#include <drm/drm_fb_cma_helper.h>
17797+#include <drm/drm_fb_helper.h>
17798+#include <drm/drm_gem_cma_helper.h>
17799+#include <drm/drm_of.h>
17800+#include <drm/drm_plane_helper.h>
17801+#include <drm/drm_util.h>
17802+#include <drm/drm_panel.h>
17803+#include "hi_drm_drv.h"
17804+#include "hi_adp_crtc.h"
17805+#include "drm_hal_mipitx.h"
17806+#include "drm_hal_display.h"
17807+
17808+#define MIPI_PHYSICAL_WIDTH 60
17809+#define MIPI_PHYSICAL_HEIGHT 120
17810+#define BRIGHTNESS_MAX       255
17811+#define DEFAULT_BRIGHTNESS   255
17812+
17813+struct ext_drm_tv_property {
17814+    struct drm_property *tv_brightness_property;
17815+};
17816+
17817+struct hi_drm_mipitx {
17818+    struct drm_connector conn;
17819+    struct drm_encoder encoder;
17820+
17821+    unsigned int drm_mipi_id;
17822+    unsigned int enable; /* 0: disable, 1: enable */
17823+    struct ext_drm_tv_property private;
17824+};
17825+
17826+#define to_hi_mipitx_by_conn(x) container_of(x, struct hi_drm_mipitx, conn)
17827+#define to_hi_mipitx_by_encoder(x) container_of(x, struct hi_drm_mipitx, encoder)
17828+
17829+struct hi_drm_mipitx_global {
17830+    struct hi_drm_mipitx mipitx;
17831+    struct DispOperations *mipi_dev;
17832+};
17833+
17834+static struct drm_display_mode default_mode = {
17835+    .clock = 155493, /* 155493 khz */
17836+    .hdisplay = 480, /* 480 width */
17837+    .hsync_start = 480 + 48, /* 480 48 alg data */
17838+    .hsync_end = 480 + 48 + 32, /* 480 48 32 alg data */
17839+    .htotal = 480 + 48 + 32 + 60, /* 480 48 32 60 alg data */
17840+    .vdisplay = 960, /* 960 height */
17841+    .vsync_start = 960 + 3, /* 960 3 alg data */
17842+    .vsync_end = 960 + 3 + 5, /* 960 3 5 alg data */
17843+    .vtotal = 960 + 3 + 5 + 6, /* 960 3  5 6 alg data */
17844+    .flags = 0, /* 0 alg data */
17845+};
17846+
17847+static struct hi_drm_mipitx_global *g_hi_mipitx = NULL;
17848+
17849+static struct DispOperations *adp_get_mipitx_func(void)
17850+{
17851+    int ret;
17852+
17853+    if (g_hi_mipitx->mipi_dev != NULL) {
17854+        return g_hi_mipitx->mipi_dev;
17855+    }
17856+
17857+    ///TODO:
17858+    g_hi_mipitx->mipi_dev = GetDispOps();
17859+    if (IS_ERR_OR_NULL(g_hi_mipitx->mipi_dev) || IS_ERR_OR_NULL(g_hi_mipitx->mipi_dev->init)) {
17860+        drm_hal_err("error, ret=%#x!\n", ret);
17861+        return NULL;
17862+    }
17863+
17864+    ret = g_hi_mipitx->mipi_dev->init(DRM_HAL_GFX_G0);
17865+    if (ret != 0) {
17866+        drm_hal_err("error, ret=%#x!\n", ret);
17867+        return NULL;
17868+    }
17869+
17870+    return (struct DispOperations *)g_hi_mipitx->mipi_dev;
17871+}
17872+
17873+
17874+int hi_adp_mipitx_get_modes(struct drm_connector *connector)
17875+{
17876+    struct drm_display_mode *mode;
17877+    mode = drm_mode_duplicate(connector->dev, &default_mode);
17878+    if (mode == NULL) {
17879+        drm_hal_err("drm_mode_duplicate failure!\n");
17880+        return -ENOMEM;
17881+    }
17882+    drm_mode_set_name(mode);
17883+    drm_mode_probed_add(connector, mode);
17884+    connector->display_info.width_mm = MIPI_PHYSICAL_WIDTH;
17885+    connector->display_info.height_mm = MIPI_PHYSICAL_HEIGHT;
17886+    return 1;
17887+}
17888+
17889+int hi_adp_mipitx_set_mode(struct drm_encoder *encoder, struct drm_display_mode *mode,
17890+    struct drm_connector_state *conn_state)
17891+{
17892+    int ret;
17893+    struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_encoder(encoder);
17894+
17895+    HI_DRM_CHECK_PTR_RETURN(hi_mipitx);
17896+
17897+    if (hi_mipitx->enable == 1) {
17898+        return 0;
17899+    }
17900+
17901+    ret = hi_adp_crtc_add_user_intf(conn_state->crtc);
17902+    if (ret != 0) {
17903+        return ret;
17904+    }
17905+    /* dispatch the mode to the connected crtc */
17906+    ret = hi_adp_crtc_set_mode(conn_state->crtc, mode);
17907+    if (ret != 0) {
17908+        drm_hal_err("error, ret=%#x!\n", ret);
17909+    }
17910+
17911+    /* attach the interface to crtc */
17912+    ret = hi_adp_crtc_add_intf(conn_state->crtc, DRM_HAL_DISP_INTF_MIPITX, hi_mipitx->drm_mipi_id);
17913+    if (ret != 0) {
17914+        drm_hal_err("error, ret=%#x!\n", ret);
17915+    }
17916+
17917+    return 0;
17918+}
17919+
17920+int hi_adp_mipitx_enable(struct drm_encoder *encoder)
17921+{
17922+    int ret;
17923+    struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_encoder(encoder);
17924+    struct DispOperations *mipi_dev = adp_get_mipitx_func();
17925+    HI_DRM_CHECK_PTR_RETURN(hi_mipitx);
17926+    HI_DRM_CHECK_PTR_RETURN(mipi_dev);
17927+    HI_DRM_CHECK_PTR_RETURN(mipi_dev->setBacklight);
17928+
17929+    if (hi_mipitx->enable == 1) {
17930+        return 0;
17931+    }
17932+
17933+    ret = mipi_dev->on(DRM_HAL_GFX_G0);
17934+    if (ret != 0) {
17935+        drm_hal_err("error, ret=%#x!\n", ret);
17936+        return ret;
17937+    }
17938+
17939+    hi_mipitx->enable = 1;
17940+    return 0;
17941+}
17942+
17943+int hi_adp_mipitx_disable(struct drm_encoder *encoder)
17944+{
17945+    int ret;
17946+    struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_encoder(encoder);
17947+    struct DispOperations *mipi_dev = adp_get_mipitx_func();
17948+
17949+    HI_DRM_CHECK_PTR_RETURN(hi_mipitx);
17950+    HI_DRM_CHECK_PTR_RETURN(mipi_dev);
17951+    HI_DRM_CHECK_PTR_RETURN(mipi_dev->off);
17952+
17953+    if (hi_mipitx->enable == 0) {
17954+        return 0;
17955+    }
17956+
17957+    ret = mipi_dev->off(DRM_HAL_GFX_G0);
17958+    if (ret != 0) {
17959+        drm_hal_err("error, ret=%#x!\n", ret);
17960+        return ret;
17961+    }
17962+
17963+    hi_mipitx->enable = 0;
17964+    return 0;
17965+}
17966+
17967+int adp_conn_atomic_set_property(struct drm_connector *connector, struct drm_connector_state *state,
17968+    struct drm_property *property, uint64_t val)
17969+{
17970+    struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_conn(connector);
17971+    if (property == hi_mipitx->private.tv_brightness_property) {
17972+        state->tv.brightness = val;
17973+    } else {
17974+        HI_DRM_ERR("[CONNECTOR:%d:%s] unknown property [PROP:%d%s]\n", connector->base.id,
17975+            connector->name, property->base.id, property->name);
17976+        return -EINVAL;
17977+    }
17978+    return 0;
17979+}
17980+
17981+int adp_conn_atomic_get_property(struct drm_connector *connector, const struct drm_connector_state *state,
17982+    struct drm_property *property, uint64_t *val)
17983+{
17984+    struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_conn(connector);
17985+
17986+    if (property == hi_mipitx->private.tv_brightness_property) {
17987+        *val = state->tv.brightness;
17988+    } else {
17989+        HI_DRM_ERR("[CONNECTOR:%d:%s] unknown property [PROP:%d%s]\n", connector->base.id,
17990+            connector->name, property->base.id, property->name);
17991+        return -EINVAL;
17992+    }
17993+    return 0;
17994+}
17995+
17996+int adp_mipi_set_brightness(struct drm_connector *connector,uint32_t brightness)
17997+{
17998+    int ret;
17999+    struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_conn(connector);
18000+    struct DispOperations *mipi_dev = adp_get_mipitx_func();
18001+
18002+    HI_DRM_CHECK_PTR_RETURN(hi_mipitx);
18003+    HI_DRM_CHECK_PTR_RETURN(mipi_dev);
18004+    HI_DRM_CHECK_PTR_RETURN(mipi_dev->setBacklight);
18005+    if (connector == NULL) {
18006+        return 0;
18007+    }
18008+    if (brightness < 0 || brightness >255) {
18009+        HI_DRM_INFO("brightness value out of range[0~255]!");
18010+        return 0;
18011+    }
18012+    ret = mipi_dev->setBacklight(DRM_HAL_GFX_G0, brightness);
18013+    if (ret != 0) {
18014+        drm_hal_err("error, ret = %#x!\n", ret);
18015+        return ret;
18016+    }
18017+    return 0;
18018+}
18019+
18020+int adp_conn_private_properties_init(struct drm_device *dev, struct drm_connector *connector)
18021+{
18022+    struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_conn(connector);
18023+
18024+    hi_mipitx->private.tv_brightness_property = drm_property_create_range(dev, 0, "brightness", 0, BRIGHTNESS_MAX);
18025+    if (hi_mipitx->private.tv_brightness_property == NULL) {
18026+        HI_DRM_ERR("tv_brightness_property create error\n");
18027+        return -ENOMEM;
18028+    }
18029+    drm_object_attach_property(&connector->base, hi_mipitx->private.tv_brightness_property, DEFAULT_BRIGHTNESS);
18030+    return 0;
18031+}
18032+
18033+void adp_conn_private_properties_deinit(struct drm_device *dev, struct drm_connector *connector)
18034+{
18035+    struct hi_drm_mipitx *hi_mipitx = to_hi_mipitx_by_conn(connector);
18036+
18037+    if (hi_mipitx->private.tv_brightness_property != NULL) {
18038+        drm_property_destroy(dev, hi_mipitx->private.tv_brightness_property);
18039+        hi_mipitx->private.tv_brightness_property = NULL;
18040+    }
18041+    return;
18042+}
18043+
18044+int hi_adp_mipitx_get_by_index(unsigned int drm_mipi_id, struct drm_connector **conn, struct drm_encoder **encoder)
18045+{
18046+    HI_DRM_CHECK_PTR_RETURN(g_hi_mipitx);
18047+
18048+    if (drm_mipi_id != DRM_MODE_CONNECTOR_DSI) {
18049+        return -1;
18050+    }
18051+
18052+    g_hi_mipitx->mipitx.drm_mipi_id = drm_mipi_id;
18053+    *conn = &g_hi_mipitx->mipitx.conn;
18054+    *encoder = &g_hi_mipitx->mipitx.encoder;
18055+
18056+    return 0;
18057+}
18058+
18059+int hi_adp_mipitx_init(void)
18060+{
18061+    int ret = -1;
18062+    g_hi_mipitx = kzalloc(sizeof(struct hi_drm_mipitx_global), GFP_KERNEL);
18063+    if (g_hi_mipitx == NULL) {
18064+        drm_hal_err("error, ret=%#x!\n", ret);
18065+        return -ENOMEM;
18066+    }
18067+
18068+    return 0;
18069+}
18070+
18071+void hi_adp_mipitx_deinit(void)
18072+{
18073+    if (IS_ERR_OR_NULL(g_hi_mipitx)) {
18074+        return;
18075+    }
18076+
18077+    kfree(g_hi_mipitx);
18078+    g_hi_mipitx = NULL;
18079+}
18080+
18081diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_adp_mipitx.h b/drivers/gpu/drm/hisilicon/hismart/hi_adp_mipitx.h
18082new file mode 100644
18083index 000000000..a006da477
18084--- /dev/null
18085+++ b/drivers/gpu/drm/hisilicon/hismart/hi_adp_mipitx.h
18086@@ -0,0 +1,32 @@
18087+/*
18088+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
18089+ * Description: Hisilicon DRM driver
18090+ * Author: Hisilicon multimedia software group
18091+ * Create: 2020-7-29
18092+ */
18093+
18094+#ifndef __HI_ADP_MIPITX_H__
18095+#define __HI_ADP_MIPITX_H__
18096+
18097+#include <drm/drm_connector.h>
18098+#include <drm/drm_encoder.h>
18099+
18100+int hi_adp_mipitx_init(void);
18101+void hi_adp_mipitx_deinit(void);
18102+int hi_adp_mipitx_get_by_index(unsigned int drm_mipi_id, struct drm_connector **conn, struct drm_encoder **encoder);
18103+int hi_adp_mipitx_enable(struct drm_encoder *encoder);
18104+int hi_adp_mipitx_disable(struct drm_encoder *encoder);
18105+int hi_adp_mipitx_get_modes(struct drm_connector *connector);
18106+int hi_adp_mipitx_set_mode(struct drm_encoder *encoder, struct drm_display_mode *mode,
18107+    struct drm_connector_state *conn_state);
18108+
18109+int adp_conn_private_properties_init(struct drm_device *dev, struct drm_connector *connector);
18110+void adp_conn_private_properties_deinit(struct drm_device *dev, struct drm_connector *connector);
18111+int adp_conn_atomic_set_property(struct drm_connector *connector, struct drm_connector_state *state,
18112+    struct drm_property *property, uint64_t val);
18113+int adp_conn_atomic_get_property(struct drm_connector *connector, const struct drm_connector_state *state,
18114+    struct drm_property *property, uint64_t *val);
18115+int adp_mipi_set_brightness(struct drm_connector *connector,uint32_t brightness);
18116+
18117+#endif /* __HI_ADP_MIPITX_H__ */
18118+
18119diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_crtc.c b/drivers/gpu/drm/hisilicon/hismart/hi_drm_crtc.c
18120new file mode 100755
18121index 000000000..ee41abf3b
18122--- /dev/null
18123+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_crtc.c
18124@@ -0,0 +1,389 @@
18125+/*
18126+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
18127+ * Description: Hisilicon DRM driver
18128+ * Author: Hisilicon multimedia software group
18129+ * Create: 2020-7-29
18130+ */
18131+
18132+#include "hi_drm_crtc.h"
18133+#include <linux/clk.h>
18134+#include <linux/component.h>
18135+#include <linux/of_address.h>
18136+#include <video/videomode.h>
18137+#include <drm/drm_atomic_helper.h>
18138+#include <drm/drm_crtc.h>
18139+#include <drm/drm_crtc_helper.h>
18140+#include <drm/drm_gem_cma_helper.h>
18141+#include <drm/drm_of.h>
18142+#include <drm/drm_plane_helper.h>
18143+#include <drm/drm_util.h>
18144+#include <drm/drm_vblank.h>
18145+#include "hi_drm_drv.h"
18146+#include "hi_adp_crtc.h"
18147+
18148+static const uint32_t hi_graphics_formats[] = {
18149+    DRM_FORMAT_ARGB8888,
18150+    DRM_FORMAT_XRGB8888,
18151+    DRM_FORMAT_RGB888,
18152+    DRM_FORMAT_RGB565,
18153+    DRM_FORMAT_ARGB1555,
18154+    DRM_FORMAT_ARGB4444,
18155+};
18156+
18157+static int hi_drm_plane_atomic_check(struct drm_plane *plane, struct drm_plane_state *state)
18158+{
18159+    int ret;
18160+    HI_DRM_FUNC_ENTER();
18161+    /* open the plane at the begining */
18162+    ret = hi_adp_plane_open(plane);
18163+    if (ret != 0) {
18164+        HI_DRM_ERR("hi_adp_plane_open err, ret=%#x\n", ret);
18165+        return ret;
18166+    }
18167+
18168+    /*
18169+     * 1. after open gfx,default csc is RGB to YUV
18170+     * 2. hdmi use default csc
18171+     * 3. mipi close csc
18172+     */
18173+    ret = hi_adp_plane_reset_csc(plane);
18174+    if (ret != 0) {
18175+        HI_DRM_ERR("hi_adp_plane_reset_csc err, ret=%#x\n", ret);
18176+        return ret;
18177+    }
18178+
18179+    HI_DRM_FUNC_EXIT();
18180+    return 0;
18181+}
18182+
18183+static void hi_drm_plane_atomic_update(struct drm_plane *plane, struct drm_plane_state *old_state)
18184+{
18185+    HI_DRM_FUNC_ENTER();
18186+    hi_adp_plane_update(plane);
18187+    HI_DRM_FUNC_EXIT();
18188+}
18189+
18190+static const struct drm_plane_helper_funcs hi_drm_plane_helper_funcs = {
18191+    .atomic_check = hi_drm_plane_atomic_check,
18192+    .atomic_update = hi_drm_plane_atomic_update,
18193+};
18194+
18195+static void hi_drm_plane_destroy(struct drm_plane *plane)
18196+{
18197+    int ret;
18198+    HI_DRM_FUNC_ENTER();
18199+    ret = hi_adp_plane_close(plane);
18200+    if (ret != 0) {
18201+        HI_DRM_ERR("hi_adp_plane_close err, ret=%#x\n", ret);
18202+    }
18203+    drm_plane_cleanup(plane);
18204+    HI_DRM_FUNC_EXIT();
18205+}
18206+
18207+static const struct drm_plane_funcs hi_drm_plane_funcs = {
18208+    .update_plane = drm_atomic_helper_update_plane,
18209+    .disable_plane = drm_atomic_helper_disable_plane,
18210+    .destroy = hi_drm_plane_destroy,
18211+    .reset = drm_atomic_helper_plane_reset,
18212+    .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
18213+    .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
18214+};
18215+
18216+static int hi_drm_plane_init(struct drm_device *drm, struct drm_plane *plane, uint32_t possible_crtcs)
18217+{
18218+    int ret;
18219+    HI_DRM_FUNC_ENTER();
18220+    ret = drm_universal_plane_init(drm, plane, possible_crtcs, &hi_drm_plane_funcs, hi_graphics_formats,
18221+        ARRAY_SIZE(hi_graphics_formats), NULL, DRM_PLANE_TYPE_PRIMARY, NULL);
18222+    if (ret != 0) {
18223+        HI_DRM_ERR("drm_universal_plane_init err, ret=%#x\n", ret);
18224+        return ret;
18225+    }
18226+    drm_plane_helper_add(plane, &hi_drm_plane_helper_funcs);
18227+    HI_DRM_FUNC_EXIT();
18228+    return 0;
18229+}
18230+
18231+static void hi_drm_crtc_atomic_enable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
18232+{
18233+    int ret;
18234+    HI_DRM_FUNC_ENTER();
18235+    ret = hi_adp_crtc_open(crtc);
18236+    if (ret != 0) {
18237+        HI_DRM_ERR("hi_adp_crtc_open error, ret = %#x\n", ret);
18238+        return;
18239+    }
18240+    drm_crtc_vblank_on(crtc);
18241+    HI_DRM_FUNC_EXIT();
18242+}
18243+
18244+static void hi_drm_crtc_atomic_disable(struct drm_crtc *crtc, struct drm_crtc_state *old_state)
18245+{
18246+    int ret;
18247+    HI_DRM_FUNC_ENTER();
18248+    ret = hi_adp_crtc_close(crtc);
18249+    if (ret != 0) {
18250+        HI_DRM_ERR("hi_adp_crtc_close err, ret=%#x\n", ret);
18251+        return;
18252+    }
18253+    drm_crtc_vblank_off(crtc);
18254+    HI_DRM_FUNC_EXIT();
18255+}
18256+
18257+static void hi_drm_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state)
18258+{
18259+    struct drm_pending_vblank_event *event = crtc->state->event;
18260+    HI_DRM_FUNC_ENTER();
18261+
18262+    if (event == NULL) {
18263+        return;
18264+    }
18265+    crtc->state->event = NULL;
18266+    spin_lock_irq(&crtc->dev->event_lock);
18267+    if (drm_crtc_vblank_get(crtc) == 0) {
18268+        drm_crtc_arm_vblank_event(crtc, event);
18269+    } else {
18270+        drm_crtc_send_vblank_event(crtc, event);
18271+    }
18272+    spin_unlock_irq(&crtc->dev->event_lock);
18273+    HI_DRM_FUNC_EXIT();
18274+}
18275+
18276+static bool hi_drm_crtc_mode_fixup(struct drm_crtc *crtc,
18277+				const struct drm_display_mode *mode,
18278+				struct drm_display_mode *adjusted_mode)
18279+{
18280+    int ret;
18281+    HI_DRM_FUNC_ENTER();
18282+    HI_DRM_INFO("mode: %d %d %d %d %d %d %d %d %d %d %d\n",
18283+                crtc->state->mode.clock,
18284+                crtc->state->mode.hdisplay,
18285+                crtc->state->mode.hsync_start,
18286+                crtc->state->mode.hsync_end,
18287+                crtc->state->mode.htotal,
18288+                crtc->state->mode.hskew,
18289+                crtc->state->mode.vdisplay,
18290+                crtc->state->mode.vsync_start,
18291+                crtc->state->mode.vsync_end,
18292+                crtc->state->mode.vtotal,
18293+                crtc->state->mode.vscan);
18294+
18295+    HI_DRM_INFO("mode: %d %d %d %d %d %d %d %d %d %d %d\n",
18296+                mode->clock,
18297+                mode->hdisplay,
18298+                mode->hsync_start,
18299+                mode->hsync_end,
18300+                mode->htotal,
18301+                mode->hskew,
18302+                mode->vdisplay,
18303+                mode->vsync_start,
18304+                mode->vsync_end,
18305+                mode->vtotal,
18306+                mode->vscan);
18307+    ret = hi_adp_crtc_set_mode(crtc, mode);
18308+    if (ret != 0) {
18309+        HI_DRM_ERR("hi_adp_crtc_set_mode err, ret=%#x\n", ret);
18310+    }
18311+    HI_DRM_FUNC_EXIT();
18312+    return true;
18313+}
18314+
18315+static void hi_drm_crtc_atomic_begin(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state)
18316+{
18317+    HI_DRM_FUNC_ENTER();
18318+    HI_DRM_FUNC_EXIT();
18319+    return;
18320+}
18321+
18322+static const struct drm_crtc_helper_funcs hi_drm_crtc_helper_funcs = {
18323+    .mode_fixup = hi_drm_crtc_mode_fixup,
18324+    .atomic_enable = hi_drm_crtc_atomic_enable,
18325+    .atomic_disable = hi_drm_crtc_atomic_disable,
18326+    .atomic_begin = hi_drm_crtc_atomic_begin,
18327+    .atomic_flush = hi_drm_crtc_atomic_flush,
18328+};
18329+
18330+int hi_drm_crtc_callback(struct drm_crtc *crtc, enum hi_adp_crtc_event event, void *para)
18331+{
18332+    if (event != HI_ADP_CRTC_VBLANK) {
18333+        return -1;
18334+    }
18335+
18336+    if (drm_crtc_handle_vblank(crtc) != true) {
18337+        return -1;
18338+    }
18339+    return 0;
18340+}
18341+
18342+static int hi_drm_crtc_enable_vblank(struct drm_crtc *crtc)
18343+{
18344+    int ret;
18345+    HI_DRM_FUNC_ENTER();
18346+
18347+    ret = hi_adp_crtc_reg_callback(crtc, hi_drm_crtc_callback);
18348+    if (ret != 0) {
18349+        return ret;
18350+    }
18351+
18352+    hi_adp_crtc_set_vblank(crtc, true);
18353+
18354+    HI_DRM_FUNC_EXIT();
18355+
18356+    return 0;
18357+}
18358+
18359+static void hi_drm_crtc_disable_vblank(struct drm_crtc *crtc)
18360+{
18361+    HI_DRM_FUNC_ENTER();
18362+
18363+    hi_adp_crtc_set_vblank(crtc, false);
18364+
18365+    hi_adp_crtc_reg_callback(crtc, NULL);
18366+
18367+    HI_DRM_FUNC_EXIT();
18368+}
18369+
18370+static void hi_drm_crtc_destroy(struct drm_crtc *crtc)
18371+{
18372+    int ret;
18373+
18374+    HI_DRM_FUNC_ENTER();
18375+    /* ensure the crtc closed in the final cleanup call */
18376+    ret = hi_adp_crtc_close(crtc);
18377+    if (ret != 0) {
18378+        HI_DRM_ERR("hi_adp_crtc_close err, ret=%#x\n", ret);
18379+    }
18380+    drm_crtc_cleanup(crtc);
18381+    HI_DRM_FUNC_EXIT();
18382+}
18383+
18384+static const struct drm_crtc_funcs hi_drm_crtc_funcs = {
18385+    .set_config = drm_atomic_helper_set_config,
18386+    .page_flip = drm_atomic_helper_page_flip,
18387+    .destroy = hi_drm_crtc_destroy,
18388+    .reset = drm_atomic_helper_crtc_reset,
18389+    .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
18390+    .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
18391+    .enable_vblank = hi_drm_crtc_enable_vblank,
18392+    .disable_vblank = hi_drm_crtc_disable_vblank,
18393+};
18394+
18395+static void hi_drm_crtc_init_by_index(struct drm_device *drm, int index)
18396+{
18397+    int ret;
18398+    struct drm_plane *primary = NULL;
18399+    struct drm_crtc *crtc = NULL;
18400+
18401+    HI_DRM_FUNC_ENTER();
18402+    /* get the crtc resource */
18403+    ret = hi_adp_crtc_get_by_index(&crtc, index);
18404+    if (ret != 0) {
18405+        HI_DRM_ERR("hi_adp_crtc_get_by_index err, ret=%#x\n", ret);
18406+        return;
18407+    }
18408+
18409+    /* get the primary 0 plane on this crtc */
18410+    ret = hi_adp_plane_get_by_index(crtc, &primary, DRM_PLANE_TYPE_PRIMARY, 0);
18411+    if (ret != 0) {
18412+        HI_DRM_ERR("hi_adp_plane_get_by_index err, ret=%#x\n", ret);
18413+        return;
18414+    }
18415+
18416+    ret = hi_drm_plane_init(drm, primary, index + 1);
18417+    if (ret != 0) {
18418+        HI_DRM_ERR("hi_drm_plane_init err, ret=%#x\n", ret);
18419+        return;
18420+    }
18421+
18422+    ret = drm_crtc_init_with_planes(drm, crtc, primary, NULL, &hi_drm_crtc_funcs, NULL);
18423+    if (ret != 0) {
18424+        HI_DRM_ERR("drm_crtc_init_with_planes error, ret = %#x\n", ret);
18425+        return;
18426+    }
18427+    drm_crtc_helper_add(crtc, &hi_drm_crtc_helper_funcs);
18428+    HI_DRM_INFO("crtc %p index %d, plane id %d\n", crtc, crtc->index, primary->index);
18429+    HI_DRM_FUNC_EXIT();
18430+    return;
18431+}
18432+
18433+static void hi_drm_crtc_cleanup_by_index(struct drm_device *drm, int index)
18434+{
18435+    int ret;
18436+    struct drm_crtc *crtc = NULL;
18437+
18438+    ret = hi_adp_crtc_get_by_index(&crtc, index);
18439+    if (ret != 0) {
18440+        HI_DRM_ERR("hi_adp_crtc_get_by_index err, ret=%#x\n", ret);
18441+        return;
18442+    }
18443+    hi_drm_plane_destroy(crtc->primary);
18444+    hi_drm_crtc_destroy(crtc);
18445+}
18446+
18447+int hi_drm_crtc_init(struct drm_device *drm)
18448+{
18449+    int ret;
18450+    int i;
18451+    struct hi_adp_crtc_cap cap;
18452+
18453+    HI_DRM_FUNC_ENTER();
18454+    ret = hi_adp_crtc_init();
18455+    if (ret != 0) {
18456+        HI_DRM_ERR("hi_adp_crtc_init error, ret=%#x\n", ret);
18457+        return ret;
18458+    }
18459+
18460+    hi_adp_crtc_get_cap(&cap);
18461+
18462+    for (i = 0; i < cap.crtc_num; i++) {
18463+        hi_drm_crtc_init_by_index(drm, i);
18464+    }
18465+    HI_DRM_FUNC_EXIT();
18466+    return 0;
18467+}
18468+
18469+void hi_drm_crtc_cleanup(struct drm_device *drm)
18470+{
18471+    int i;
18472+    struct hi_adp_crtc_cap cap;
18473+
18474+    HI_DRM_FUNC_ENTER();
18475+    hi_adp_crtc_get_cap(&cap);
18476+    for (i = 0; i < cap.crtc_num; i++) {
18477+        hi_drm_crtc_cleanup_by_index(drm, i);
18478+    }
18479+    hi_adp_crtc_deinit();
18480+    HI_DRM_FUNC_EXIT();
18481+}
18482+
18483+void hi_drm_crtc_lastclose(struct drm_device *drm)
18484+{
18485+    int ret;
18486+    int i;
18487+    int j;
18488+    struct hi_adp_crtc_cap cap;
18489+    struct drm_crtc *crtc = NULL;
18490+    struct drm_plane *plane = NULL;
18491+
18492+    HI_DRM_FUNC_ENTER();
18493+
18494+    hi_adp_crtc_get_cap(&cap);
18495+    for (i = 0; i < cap.crtc_num; i++) {
18496+        ret = hi_adp_crtc_get_by_index(&crtc, i);
18497+        if (ret != 0) {
18498+            continue;
18499+        }
18500+        HI_DRM_INFO("now close the crtc, id=%d\n", i);
18501+        (void)hi_adp_crtc_close(crtc);
18502+        /* only support primary plane yet */
18503+        for (j = 0; j < HI_DRM_MAX_PRIMARY_NUM; j++) {
18504+            ret = hi_adp_plane_get_by_index(crtc, &plane, DRM_PLANE_TYPE_PRIMARY, j);
18505+            if (ret != 0) {
18506+                continue;
18507+            }
18508+            HI_DRM_INFO("now close the plane, id=%d\n", j);
18509+            (void)hi_adp_plane_close(plane);
18510+        }
18511+    }
18512+    HI_DRM_FUNC_EXIT();
18513+}
18514diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_crtc.h b/drivers/gpu/drm/hisilicon/hismart/hi_drm_crtc.h
18515new file mode 100644
18516index 000000000..ebe7aac6f
18517--- /dev/null
18518+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_crtc.h
18519@@ -0,0 +1,17 @@
18520+/*
18521+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
18522+ * Description: Hisilicon DRM driver
18523+ * Author: Hisilicon multimedia software group
18524+ * Create: 2020-7-29
18525+ */
18526+
18527+#ifndef __HI_DRM_CTRC_H__
18528+#define __HI_DRM_CTRC_H__
18529+
18530+#include <drm/drm_device.h>
18531+
18532+int hi_drm_crtc_init(struct drm_device *drm);
18533+void hi_drm_crtc_cleanup(struct drm_device *drm);
18534+void hi_drm_crtc_lastclose(struct drm_device *drm);
18535+
18536+#endif /* __HI_DRM_CTRC_H__ */
18537diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_drv.c b/drivers/gpu/drm/hisilicon/hismart/hi_drm_drv.c
18538new file mode 100755
18539index 000000000..075cb248c
18540--- /dev/null
18541+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_drv.c
18542@@ -0,0 +1,385 @@
18543+/*
18544+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
18545+ * Description: Hisilicon DRM driver
18546+ * Author: Hisilicon multimedia software group
18547+ * Create: 2020-7-29
18548+ */
18549+
18550+#include "hi_drm_drv.h"
18551+#include <linux/clk.h>
18552+#include <linux/component.h>
18553+#include <linux/list.h>
18554+#include <linux/module.h>
18555+#include <linux/of_graph.h>
18556+#include <linux/of_platform.h>
18557+#include <linux/spinlock.h>
18558+#include <drm/drm_atomic_helper.h>
18559+#include <drm/drm_crtc.h>
18560+#include <drm/drm_crtc_helper.h>
18561+#include <drm/drm_gem_cma_helper.h>
18562+#include <drm/drm_of.h>
18563+#include <drm/drm_util.h>
18564+#include <drm/drm_gem_framebuffer_helper.h>
18565+#include <drm/drm_drv.h>
18566+#include <drm/drm_vblank.h>
18567+#include "hi_drm_crtc.h"
18568+#include "hi_drm_hdmitx.h"
18569+#include "hi_drm_mipitx.h"
18570+#include "hisilicon_drm.h"
18571+#include "osal_list.h"
18572+#include "hi_adp_mipitx.h"
18573+#define DRIVER_NAME "hisilicon"
18574+#define DRIVER_DESC "hisilicon Soc DRM"
18575+#define DRIVER_DATE "20200602"
18576+#define DRIVER_MAJOR    1
18577+#define DRIVER_MINOR    0
18578+
18579+#define HI_DRM_MAX_WIDTH    8192
18580+#define HI_DRM_MAX_HEIGHT   8192
18581+
18582+struct hi_drm_phys {
18583+    unsigned long long phys_addr;
18584+    unsigned long long size;
18585+    struct osal_list_head list;
18586+};
18587+OSAL_LIST_HEAD(g_phys_addr);
18588+
18589+static struct drm_device *drm_dev;
18590+
18591+static const struct file_operations hi_drm_driver_fops = {
18592+    .owner = THIS_MODULE,
18593+    .open = drm_open,
18594+    .poll = drm_poll,
18595+    .read = drm_read,
18596+    .unlocked_ioctl = drm_ioctl,
18597+    .compat_ioctl = drm_compat_ioctl,
18598+    .release = drm_release,
18599+    .mmap = drm_gem_cma_mmap,
18600+};
18601+
18602+static void hi_drm_lastclose(struct drm_device *dev)
18603+{
18604+    HI_DRM_INFO("=========== come to the last close! ===========\n");
18605+
18606+    hi_drm_crtc_lastclose(dev);
18607+}
18608+
18609+static int hi_drm_get_prime_phyaddr(struct drm_device *dev, void *data, struct drm_file *file)
18610+{
18611+    struct drm_hisilicon_phyaddr *arg = data;
18612+    struct drm_gem_object *gem_obj = NULL;
18613+    struct sg_table *sgt = NULL;
18614+    struct page *page = NULL;
18615+    int ret;
18616+    uint32_t handle = 0;
18617+    ret = drm_gem_prime_fd_to_handle(dev, file, arg->fd, &handle);
18618+    if (ret) {
18619+        HI_DRM_ERR("fd %d to handle failed", arg->fd);
18620+        return -1;
18621+    }
18622+    gem_obj = drm_gem_object_lookup(file, handle);
18623+    if (gem_obj == NULL) {
18624+        HI_DRM_ERR("gem object not finde fd %d, handle 0x%x", arg->fd, handle);
18625+        return -1;
18626+    }
18627+    sgt = drm_gem_cma_prime_get_sg_table(gem_obj);
18628+    if (sgt == NULL) {
18629+        HI_DRM_ERR("gem prime get sg_table failed");
18630+        drm_gem_object_put(gem_obj);
18631+        return -1;
18632+    }
18633+    page = sg_page(sgt->sgl);
18634+    arg->phyaddr = PFN_PHYS(page_to_pfn(page));
18635+    drm_gem_object_put(gem_obj);
18636+    return 0;
18637+}
18638+
18639+static const struct drm_ioctl_desc hidrm_ioctls[] = {
18640+    DRM_IOCTL_DEF_DRV(HISILICON_GEM_FD_TO_PHYADDR, hi_drm_get_prime_phyaddr, DRM_UNLOCKED),
18641+};
18642+
18643+int drm_check_dumb_phy_addr(unsigned long long addr_start, unsigned long long size)
18644+{
18645+    struct hi_drm_phys *p = NULL;
18646+    unsigned long long addr_end = addr_start + size;
18647+    unsigned long long temp_start, temp_end;
18648+    /* if address is valid */
18649+    osal_list_for_each_entry(p, &g_phys_addr, list) {
18650+        temp_start = p->phys_addr;
18651+        temp_end = p->phys_addr + p->size;
18652+        if ((addr_start >= temp_start) && (addr_end <= temp_end)) {
18653+            return 0;
18654+        }
18655+    }
18656+    HI_DRM_ERR("drm_check_dumb_phy_addr, addr_start-addr_end [0x%llx-0x%llx]\n", addr_start, addr_end);
18657+    return -1;
18658+}
18659+EXPORT_SYMBOL(drm_check_dumb_phy_addr);
18660+
18661+static int hi_drm_gem_cma_dumb_create(struct drm_file *file_priv, struct drm_device *drm,
18662+    struct drm_mode_create_dumb *args)
18663+{
18664+    int ret;
18665+    struct drm_gem_object *gem_obj = NULL;
18666+    struct sg_table *sgt = NULL;
18667+    struct page *page = NULL;
18668+    struct hi_drm_phys *node = NULL;
18669+    ret = drm_gem_cma_dumb_create(file_priv, drm, args);
18670+    if (ret != 0) {
18671+        return ret;
18672+    }
18673+
18674+    node = kmalloc(sizeof(struct hi_drm_phys), GFP_KERNEL);
18675+    if (node == NULL) {
18676+        HI_DRM_ERR("kmalloc node failed\n");
18677+        return 0;
18678+    }
18679+    (void)memset(node, 0, sizeof(struct hi_drm_phys));
18680+
18681+    /* get phyaddr and size */
18682+    gem_obj = drm_gem_object_lookup(file_priv, args->handle);
18683+    if (gem_obj == NULL) {
18684+        HI_DRM_ERR("gem object not finde handle 0x%x", args->handle);
18685+        kfree(node);
18686+        return -1;
18687+    }
18688+    sgt = drm_gem_cma_prime_get_sg_table(gem_obj);
18689+    if (sgt == NULL) {
18690+        HI_DRM_ERR("gem prime get sg_table failed");
18691+        drm_gem_object_put(gem_obj);
18692+        kfree(node);
18693+        return -1;
18694+    }
18695+    page = sg_page(sgt->sgl);
18696+    node->phys_addr = PFN_PHYS(page_to_pfn(page));
18697+    node->size = args->size;
18698+    drm_gem_object_put(gem_obj);
18699+    osal_list_add(&node->list, &g_phys_addr);
18700+    return 0;
18701+}
18702+
18703+static void hi_drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
18704+{
18705+    struct sg_table *sgt = NULL;
18706+    struct page *page = NULL;
18707+    struct hi_drm_phys *p = NULL;
18708+    unsigned long long phyaddr;
18709+
18710+    sgt = drm_gem_cma_prime_get_sg_table(gem_obj);
18711+    if (sgt == NULL) {
18712+        HI_DRM_ERR("gem prime get sg_table failed");
18713+        return;
18714+    }
18715+    page = sg_page(sgt->sgl);
18716+    phyaddr = PFN_PHYS(page_to_pfn(page));
18717+
18718+    drm_gem_cma_free_object(gem_obj);
18719+    osal_list_for_each_entry(p, &g_phys_addr, list) {
18720+        if (p->phys_addr == phyaddr) {
18721+            osal_list_del(&p->list);
18722+            kfree(p);
18723+            return;
18724+        }
18725+    }
18726+    HI_DRM_ERR("list has no node to del\n");
18727+    return;
18728+}
18729+
18730+static struct drm_driver hi_drm_driver = {
18731+    .driver_features = DRIVER_GEM | DRIVER_MODESET | DRIVER_RENDER | DRIVER_ATOMIC,
18732+    .lastclose = hi_drm_lastclose,
18733+    .dumb_create = hi_drm_gem_cma_dumb_create,
18734+    .gem_vm_ops = &drm_gem_cma_vm_ops,
18735+    .gem_free_object_unlocked = hi_drm_gem_cma_free_object,
18736+    .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
18737+    .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
18738+    .gem_prime_import = drm_gem_prime_import,
18739+    .gem_prime_export = drm_gem_prime_export,
18740+    .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
18741+    .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
18742+    .gem_prime_vmap = drm_gem_cma_prime_vmap,
18743+    .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
18744+    .gem_prime_mmap = drm_gem_cma_prime_mmap,
18745+    .fops = &hi_drm_driver_fops,
18746+    .name = DRIVER_NAME,
18747+    .desc = DRIVER_DESC,
18748+    .date = DRIVER_DATE,
18749+    .major = DRIVER_MAJOR,
18750+    .minor = DRIVER_MINOR,
18751+    .ioctls = hidrm_ioctls,
18752+    .num_ioctls = ARRAY_SIZE(hidrm_ioctls),
18753+};
18754+
18755+static struct drm_framebuffer *hi_drm_fb_create(struct drm_device *dev,
18756+    struct drm_file *file_priv, const struct drm_mode_fb_cmd2 *mode_cmd)
18757+{
18758+    return drm_gem_fb_create(dev, file_priv, mode_cmd);
18759+}
18760+
18761+int hi_drm_atomic_helper_commit(struct drm_device *dev, struct drm_atomic_state *state, bool nonblock)
18762+{
18763+    struct drm_connector *connector = NULL;
18764+    struct drm_connector_state *old_connector_state = NULL;
18765+    struct drm_connector_state *new_connector_state = NULL;
18766+    int i;
18767+
18768+    for_each_oldnew_connector_in_state(state, connector, old_connector_state, new_connector_state, i) {
18769+        if ((connector->connector_type == DRM_MODE_CONNECTOR_DSI) &&
18770+            (old_connector_state->tv.brightness != new_connector_state->tv.brightness)) {
18771+            adp_mipi_set_brightness(connector, new_connector_state->tv.brightness);
18772+        }
18773+    }
18774+    return drm_atomic_helper_commit(dev, state, nonblock);
18775+}
18776+
18777+static const struct drm_mode_config_funcs hi_drm_mode_config_funcs = {
18778+    .fb_create = hi_drm_fb_create,
18779+    .atomic_check = drm_atomic_helper_check,
18780+    .atomic_commit = hi_drm_atomic_helper_commit,
18781+};
18782+
18783+static void hi_drm_mode_config_init(struct drm_device *dev)
18784+{
18785+    dev->mode_config.min_width = 0;
18786+    dev->mode_config.min_height = 0;
18787+    dev->mode_config.max_width = HI_DRM_MAX_WIDTH;
18788+    dev->mode_config.max_height = HI_DRM_MAX_HEIGHT;
18789+    dev->mode_config.funcs = &hi_drm_mode_config_funcs;
18790+}
18791+
18792+static int hi_drm_kms_init(struct drm_device *drm)
18793+{
18794+    int ret;
18795+    HI_DRM_FUNC_ENTER();
18796+    drm_mode_config_init(drm);
18797+    hi_drm_mode_config_init(drm);
18798+    ret = hi_drm_crtc_init(drm);
18799+    if (ret != 0) {
18800+        HI_DRM_ERR("hi_drm_crtc_init err, ret=%#x\n", ret);
18801+        goto err_mode_cleanup;
18802+    }
18803+    ret = hi_drm_hdmitx_init(drm);
18804+    if (ret != 0) {
18805+        HI_DRM_ERR("hi_drm_hdmitx_init err, ret=%#x\n", ret);
18806+        goto err_crtc_cleanup;
18807+    }
18808+    ret = hi_drm_mipitx_init(drm);
18809+    if (ret != 0) {
18810+        HI_DRM_ERR("hi_drm_mipitx_init err, ret=%#x\n", ret);
18811+        goto err_hdmi_connector_cleanup;
18812+    }
18813+    ret = drm_vblank_init(drm, drm->mode_config.num_crtc);
18814+    if (ret != 0) {
18815+        HI_DRM_ERR("drm_vblank_init err, ret=%#x\n", ret);
18816+        goto err_all_connector_cleanup;
18817+    }
18818+
18819+    drm->irq_enabled = true;
18820+    drm_mode_config_reset(drm);
18821+    HI_DRM_FUNC_EXIT();
18822+    return 0;
18823+err_all_connector_cleanup:
18824+    hi_drm_mipitx_cleanup(drm);
18825+err_hdmi_connector_cleanup:
18826+    hi_drm_hdmitx_cleanup(drm);
18827+err_crtc_cleanup:
18828+    hi_drm_crtc_cleanup(drm);
18829+err_mode_cleanup:
18830+    drm_mode_config_cleanup(drm);
18831+    return ret;
18832+}
18833+
18834+static void hi_drm_kms_cleanup(struct drm_device *drm)
18835+{
18836+    HI_DRM_FUNC_ENTER();
18837+
18838+    hi_drm_hdmitx_cleanup(drm);
18839+
18840+    hi_drm_crtc_cleanup(drm);
18841+
18842+    drm_mode_config_cleanup(drm);
18843+
18844+    HI_DRM_FUNC_EXIT();
18845+}
18846+
18847+static int hi_drm_platform_probe(struct platform_device *pdev)
18848+{
18849+    struct drm_driver *driver = &hi_drm_driver;
18850+    struct hi_drm_private *private = NULL;
18851+    struct device *dev = &pdev->dev;
18852+    int ret;
18853+
18854+    HI_DRM_FUNC_ENTER();
18855+
18856+    drm_dev = drm_dev_alloc(driver, dev);
18857+    if (IS_ERR(drm_dev)) {
18858+        return PTR_ERR(drm_dev);
18859+    }
18860+
18861+    private = devm_kzalloc(drm_dev->dev, sizeof(struct hi_drm_private), GFP_KERNEL);
18862+    if (private == NULL) {
18863+        ret = -ENOMEM;
18864+        goto err_put_drm_dev;
18865+    }
18866+
18867+    drm_dev->dev_private = private;
18868+
18869+    ret = hi_drm_kms_init(drm_dev);
18870+    if (ret != 0) {
18871+        HI_DRM_ERR("hi_drm_kms_init err, ret=%#x\n", ret);
18872+        goto err_drm_priv_free;
18873+    }
18874+
18875+    ret = drm_dev_register(drm_dev, 0);
18876+    if (ret != 0) {
18877+        HI_DRM_ERR("drm_dev_init err, ret=%#x\n", ret);
18878+        goto err_drm_kms_cleanup;
18879+    }
18880+
18881+    HI_DRM_FUNC_EXIT();
18882+
18883+    return 0;
18884+
18885+err_drm_kms_cleanup:
18886+    hi_drm_kms_cleanup(drm_dev);
18887+err_drm_priv_free:
18888+    devm_kfree(drm_dev->dev, drm_dev->dev_private);
18889+    drm_dev->dev_private = NULL;
18890+err_put_drm_dev:
18891+    drm_dev_put(drm_dev);
18892+    return ret;
18893+}
18894+
18895+static int hi_drm_platform_remove(struct platform_device *pdev)
18896+{
18897+    devm_kfree(drm_dev->dev, drm_dev->dev_private);
18898+    drm_dev->dev_private = NULL;
18899+
18900+    drm_dev_unregister(drm_dev);
18901+
18902+    hi_drm_kms_cleanup(drm_dev);
18903+
18904+    drm_dev_put(drm_dev);
18905+
18906+    return 0;
18907+}
18908+
18909+static const struct of_device_id hi_drm_dt_ids[] = {
18910+    { .compatible = "hisilicon,hi-drm", },
18911+    { /* sentinel */ },
18912+};
18913+
18914+static struct platform_driver hi_drm_platform_driver = {
18915+    .probe = hi_drm_platform_probe,
18916+    .remove = hi_drm_platform_remove,
18917+    .driver = {
18918+        .name = "hi-drm",
18919+        .of_match_table = hi_drm_dt_ids,
18920+    },
18921+};
18922+
18923+module_platform_driver(hi_drm_platform_driver);
18924+
18925+MODULE_DESCRIPTION("hisilicon DRM driver");
18926+MODULE_LICENSE("GPL v2");
18927+
18928diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_drv.h b/drivers/gpu/drm/hisilicon/hismart/hi_drm_drv.h
18929new file mode 100755
18930index 000000000..c399f78b6
18931--- /dev/null
18932+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_drv.h
18933@@ -0,0 +1,29 @@
18934+/*
18935+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
18936+ * Description: Hisilicon DRM driver
18937+ * Author: Hisilicon multimedia software group
18938+ * Create: 2020-7-29
18939+ */
18940+
18941+#ifndef __HI_DRM_DRV_H__
18942+#define __HI_DRM_DRV_H__
18943+
18944+#include <drm/drm_util.h>
18945+
18946+#define HI_DRM_FUNC_ENTER() DRM_DEBUG("function %s enter...\n", __FUNCTION__)
18947+#define HI_DRM_FUNC_EXIT() DRM_DEBUG("function %s exit...\n", __FUNCTION__)
18948+#define HI_DRM_ERR(fmt...) DRM_ERROR(fmt)
18949+#define HI_DRM_WARN(fmt...) DRM_WARN(fmt)
18950+#define HI_DRM_INFO(fmt...) DRM_DEBUG(fmt)
18951+
18952+#define HI_DRM_CHECK_PTR_RETURN(ptr) do { \
18953+    if (IS_ERR_OR_NULL(ptr)) { \
18954+        return -PTR_ERR(ptr); \
18955+    } \
18956+} while (0)
18957+
18958+struct hi_drm_private {
18959+    void *reserved;
18960+};
18961+
18962+#endif /* __HI_DRM_DRV_H__ */
18963diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_func_ext.c b/drivers/gpu/drm/hisilicon/hismart/hi_drm_func_ext.c
18964new file mode 100644
18965index 000000000..f29e7f998
18966--- /dev/null
18967+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_func_ext.c
18968@@ -0,0 +1,43 @@
18969+/*
18970+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
18971+ * Description: Hisilicon DRM driver
18972+ * Author: Hisilicon multimedia software group
18973+ * Create: 2020-7-29
18974+ */
18975+
18976+#include "hi_drm_func_ext.h"
18977+#include <linux/module.h>
18978+#include <linux/stddef.h>
18979+
18980+hi_drm_export_func g_drm_ext_func = {
18981+    .disp_func = NULL,
18982+    .gfx_func = NULL,
18983+    .hdmi_func = NULL,
18984+};
18985+
18986+int drm_get_export_func(enum hi_mod_ext_id mod_id, void **func)
18987+{
18988+    if (func == NULL) {
18989+        return -1;
18990+    }
18991+    switch (mod_id) {
18992+        case MOD_ID_DISP:
18993+            *func = g_drm_ext_func.disp_func;
18994+            break;
18995+        case MOD_ID_GFX:
18996+            *func = g_drm_ext_func.gfx_func;
18997+            break;
18998+        case MOD_ID_HDMI:
18999+            *func = g_drm_ext_func.hdmi_func;
19000+            break;
19001+        default:
19002+            return -1;
19003+    }
19004+    return 0;
19005+}
19006+
19007+hi_drm_export_func *drm_export_func_register()
19008+{
19009+    return &g_drm_ext_func;
19010+}
19011+EXPORT_SYMBOL(drm_export_func_register);
19012\ No newline at end of file
19013diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_func_ext.h b/drivers/gpu/drm/hisilicon/hismart/hi_drm_func_ext.h
19014new file mode 100644
19015index 000000000..83a96b22b
19016--- /dev/null
19017+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_func_ext.h
19018@@ -0,0 +1,27 @@
19019+/*
19020+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
19021+ * Description: Hisilicon DRM driver
19022+ * Author: Hisilicon multimedia software group
19023+ * Create: 2020-7-29
19024+ */
19025+
19026+#ifndef __HI_DRM_FUNC_EXT_H__
19027+#define __HI_DRM_FUNC_EXT_H__
19028+
19029+enum hi_mod_ext_id {
19030+    MOD_ID_DISP,
19031+    MOD_ID_GFX,
19032+    MOD_ID_HDMI,
19033+    MOD_ID_MAX
19034+};
19035+
19036+typedef struct {
19037+    void *disp_func;
19038+    void *gfx_func;
19039+    void *hdmi_func;
19040+}hi_drm_export_func;
19041+
19042+int drm_get_export_func(enum hi_mod_ext_id, void **);
19043+hi_drm_export_func *drm_export_func_register(void);
19044+
19045+#endif /* __HI_DRM_FUNC_EXT_H__ */
19046diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_hdmitx.c b/drivers/gpu/drm/hisilicon/hismart/hi_drm_hdmitx.c
19047new file mode 100755
19048index 000000000..1d11d98a2
19049--- /dev/null
19050+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_hdmitx.c
19051@@ -0,0 +1,233 @@
19052+/*
19053+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
19054+ * Description: Hisilicon DRM driver
19055+ * Author: Hisilicon multimedia software group
19056+ * Create: 2020-7-29
19057+ */
19058+
19059+#include "hi_drm_hdmitx.h"
19060+#include <linux/clk.h>
19061+#include <linux/component.h>
19062+#include <linux/of_address.h>
19063+#include <video/videomode.h>
19064+#include <drm/drm_atomic_helper.h>
19065+#include <drm/drm_crtc.h>
19066+#include <drm/drm_crtc_helper.h>
19067+#include <drm/drm_fb_cma_helper.h>
19068+#include <drm/drm_fb_helper.h>
19069+#include <drm/drm_gem_cma_helper.h>
19070+#include <drm/drm_of.h>
19071+#include <drm/drm_plane_helper.h>
19072+#include <drm/drm_util.h>
19073+#include <drm/drm_probe_helper.h>
19074+#include "hi_drm_drv.h"
19075+#include "hi_adp_hdmitx.h"
19076+#include "hi_adp_crtc.h"
19077+
19078+static int hi_conn_get_modes(struct drm_connector *connector)
19079+{
19080+    int ret;
19081+    int count;
19082+    struct edid *edid = NULL;
19083+    void *data = NULL;
19084+    const int max_edid_num = 4;
19085+
19086+    HI_DRM_FUNC_ENTER();
19087+    data = kzalloc(sizeof(struct edid) * max_edid_num, GFP_KERNEL);
19088+    if (data == NULL) {
19089+        return -ENOMEM;
19090+    }
19091+
19092+    ret = hi_adp_hdmitx_get_edid(connector, data, sizeof(struct edid) * max_edid_num);
19093+    if (ret != 0) {
19094+        HI_DRM_ERR("hi_adp_hdmitx_get_edid err, ret=%#x\n", ret);
19095+        goto hdmitx_free_data;
19096+    }
19097+
19098+    edid = (struct edid *)data;
19099+    ret = drm_connector_update_edid_property(connector, edid);
19100+    if (ret != 0) {
19101+        HI_DRM_ERR("drm_mode_connector_update_edid_property err, ret=%#x\n", ret);
19102+        goto hdmitx_free_data;
19103+    }
19104+    count = drm_add_edid_modes(connector, edid);
19105+    kfree(data);
19106+    HI_DRM_FUNC_EXIT();
19107+    return count;
19108+hdmitx_free_data:
19109+    kfree(data);
19110+    return ret;
19111+}
19112+
19113+static enum drm_connector_status hi_conn_detect(struct drm_connector *connector, bool force)
19114+{
19115+    HI_DRM_FUNC_ENTER();
19116+    HI_DRM_FUNC_EXIT();
19117+    return hi_adp_hdmitx_detect(connector, force);
19118+}
19119+
19120+static const struct drm_connector_helper_funcs hi_conn_helper_funcs = {
19121+    .get_modes = hi_conn_get_modes,
19122+};
19123+
19124+static const struct drm_connector_funcs hi_connector_funcs = {
19125+    .fill_modes = drm_helper_probe_single_connector_modes,
19126+    .detect = hi_conn_detect,
19127+    .destroy = drm_connector_cleanup,
19128+    .reset = drm_atomic_helper_connector_reset,
19129+    .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
19130+    .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
19131+};
19132+
19133+static int hi_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state,
19134+    struct drm_connector_state *conn_state)
19135+{
19136+    HI_DRM_FUNC_ENTER();
19137+    HI_DRM_INFO("mode: %d %d %d %d %d %d %d %d %d %d %d\n",
19138+                crtc_state->mode.clock,
19139+                crtc_state->mode.hdisplay,
19140+                crtc_state->mode.hsync_start,
19141+                crtc_state->mode.hsync_end,
19142+                crtc_state->mode.htotal,
19143+                crtc_state->mode.hskew,
19144+                crtc_state->mode.vdisplay,
19145+                crtc_state->mode.vsync_start,
19146+                crtc_state->mode.vsync_end,
19147+                crtc_state->mode.vtotal,
19148+                crtc_state->mode.vscan);
19149+    hi_adp_hdmitx_set_mode(encoder, &crtc_state->mode, conn_state);
19150+    HI_DRM_FUNC_EXIT();
19151+
19152+    return 0;
19153+}
19154+
19155+static void hi_encoder_enable(struct drm_encoder *encoder)
19156+{
19157+    int ret;
19158+    HI_DRM_FUNC_ENTER();
19159+    ret = hi_adp_hdmitx_enable(encoder);
19160+    if (ret != 0) {
19161+        HI_DRM_ERR("hi_adp_hdmitx_enable err, ret=%#x\n", ret);
19162+    }
19163+    HI_DRM_FUNC_EXIT();
19164+}
19165+
19166+static void hi_encoder_disable(struct drm_encoder *encoder)
19167+{
19168+    int ret;
19169+    HI_DRM_FUNC_ENTER();
19170+
19171+    ret = hi_adp_hdmitx_disable(encoder);
19172+    if (ret != 0) {
19173+        HI_DRM_ERR("hi_adp_hdmitx_enable err, ret=%#x\n", ret);
19174+    }
19175+    HI_DRM_FUNC_EXIT();
19176+}
19177+
19178+static enum drm_mode_status hi_encoder_mode_valid(struct drm_encoder *encoder, const struct drm_display_mode *mode)
19179+{
19180+    HI_DRM_FUNC_ENTER();
19181+    HI_DRM_FUNC_EXIT();
19182+    return MODE_OK;
19183+}
19184+
19185+static void hi_encoder_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
19186+    struct drm_display_mode *adj_mode)
19187+{
19188+    HI_DRM_FUNC_ENTER();
19189+    HI_DRM_FUNC_EXIT();
19190+}
19191+
19192+static const struct drm_encoder_helper_funcs hi_encoder_helper_funcs = {
19193+    .atomic_check = hi_encoder_atomic_check,
19194+    .mode_valid = hi_encoder_mode_valid,
19195+    .mode_set = hi_encoder_mode_set,
19196+    .enable = hi_encoder_enable,
19197+    .disable = hi_encoder_disable
19198+};
19199+
19200+static void hi_drm_encoder_destroy(struct drm_encoder *encoder)
19201+{
19202+    int ret;
19203+    HI_DRM_FUNC_ENTER();
19204+
19205+    ret = hi_adp_hdmitx_disable(encoder);
19206+    if (ret != 0) {
19207+        HI_DRM_ERR("hi_adp_hdmitx_disable err, ret=%#x\n", ret);
19208+    }
19209+    drm_encoder_cleanup(encoder);
19210+    HI_DRM_FUNC_EXIT();
19211+}
19212+
19213+static const struct drm_encoder_funcs hi_encoder_funcs = {
19214+    .destroy = hi_drm_encoder_destroy,
19215+};
19216+
19217+static void hdmitx_init_by_index(struct drm_device *drm, unsigned int id)
19218+{
19219+    int ret;
19220+    struct drm_connector *conn = NULL;
19221+    struct drm_encoder *encoder = NULL;
19222+    HI_DRM_FUNC_ENTER();
19223+    ret = hi_adp_hdmitx_get_by_index(id, &conn, &encoder);
19224+    if (ret != 0) {
19225+        HI_DRM_INFO("hdmi id %u not support!\n", id);
19226+        return;
19227+    }
19228+
19229+    if (id == DRM_MODE_CONNECTOR_HDMIA) {
19230+        encoder->possible_crtcs = 1; /* 1: dhd0 */
19231+    } else {
19232+        encoder->possible_crtcs = 2; /* 2: dhd1 */
19233+    }
19234+
19235+    drm_encoder_init(drm, encoder, &hi_encoder_funcs, DRM_MODE_ENCODER_TMDS, NULL);
19236+    drm_encoder_helper_add(encoder, &hi_encoder_helper_funcs);
19237+    drm_connector_init(drm, conn, &hi_connector_funcs, id);
19238+    drm_connector_helper_add(conn, &hi_conn_helper_funcs);
19239+    drm_connector_attach_encoder(conn, encoder);
19240+    HI_DRM_FUNC_EXIT();
19241+}
19242+
19243+static void hdmitx_deinit_by_index(struct drm_device *drm, unsigned int id)
19244+{
19245+    int ret;
19246+    struct drm_connector *conn = NULL;
19247+    struct drm_encoder *encoder = NULL;
19248+    HI_DRM_FUNC_ENTER();
19249+    ret = hi_adp_hdmitx_get_by_index(id, &conn, &encoder);
19250+    if (ret != 0) {
19251+        HI_DRM_INFO("hdmi id %u not support!\n", id);
19252+        return;
19253+    }
19254+    /* ensure disabled at the final cleanup call */
19255+    ret = hi_adp_hdmitx_disable(encoder);
19256+    if (ret != 0) {
19257+        HI_DRM_ERR("hi_adp_hdmitx_disable err, ret=%#x\n", ret);
19258+    }
19259+
19260+    drm_connector_cleanup(conn);
19261+    drm_encoder_cleanup(encoder);
19262+    HI_DRM_FUNC_EXIT();
19263+}
19264+
19265+int hi_drm_hdmitx_init(struct drm_device *drm)
19266+{
19267+    int ret;
19268+    HI_DRM_FUNC_ENTER();
19269+    ret = hi_adp_hdmitx_init();
19270+    if (ret != 0) {
19271+        return ret;
19272+    }
19273+    hdmitx_init_by_index(drm, DRM_MODE_CONNECTOR_HDMIA);
19274+    HI_DRM_FUNC_EXIT();
19275+    return 0;
19276+}
19277+
19278+void hi_drm_hdmitx_cleanup(struct drm_device *drm)
19279+{
19280+    HI_DRM_FUNC_ENTER();
19281+    hdmitx_deinit_by_index(drm, DRM_MODE_CONNECTOR_HDMIA);
19282+    hi_adp_hdmitx_deinit();
19283+    HI_DRM_FUNC_EXIT();
19284+}
19285diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_hdmitx.h b/drivers/gpu/drm/hisilicon/hismart/hi_drm_hdmitx.h
19286new file mode 100644
19287index 000000000..22285a50e
19288--- /dev/null
19289+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_hdmitx.h
19290@@ -0,0 +1,16 @@
19291+/*
19292+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
19293+ * Description: Hisilicon DRM driver
19294+ * Author: Hisilicon multimedia software group
19295+ * Create: 2020-7-29
19296+ */
19297+
19298+#ifndef __HI_DRM_HDMITX_H__
19299+#define __HI_DRM_HDMITX_H__
19300+
19301+#include <drm/drm_device.h>
19302+
19303+int hi_drm_hdmitx_init(struct drm_device *drm);
19304+void hi_drm_hdmitx_cleanup(struct drm_device *drm);
19305+
19306+#endif /* __HI_DRM_HDMITX_H__ */
19307diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_mipitx.c b/drivers/gpu/drm/hisilicon/hismart/hi_drm_mipitx.c
19308new file mode 100755
19309index 000000000..7f5d10cc3
19310--- /dev/null
19311+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_mipitx.c
19312@@ -0,0 +1,189 @@
19313+/*
19314+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
19315+ * Description: Hisilicon DRM driver
19316+ * Author: Hisilicon multimedia software group
19317+ * Create: 2020-7-29
19318+ */
19319+
19320+#include "hi_drm_mipitx.h"
19321+#include <linux/clk.h>
19322+#include <linux/component.h>
19323+#include <linux/of_address.h>
19324+#include <video/videomode.h>
19325+#include <drm/drm_atomic_helper.h>
19326+#include <drm/drm_crtc.h>
19327+#include <drm/drm_crtc_helper.h>
19328+#include <drm/drm_fb_cma_helper.h>
19329+#include <drm/drm_fb_helper.h>
19330+#include <drm/drm_gem_cma_helper.h>
19331+#include <drm/drm_of.h>
19332+#include <drm/drm_plane_helper.h>
19333+#include <drm/drm_util.h>
19334+#include <drm/drm_probe_helper.h>
19335+#include "hi_drm_drv.h"
19336+#include "hi_adp_mipitx.h"
19337+#include "hi_adp_crtc.h"
19338+
19339+static int hi_dsi_conn_get_modes(struct drm_connector *connector)
19340+{
19341+    HI_DRM_FUNC_ENTER();
19342+    HI_DRM_FUNC_EXIT();
19343+    return hi_adp_mipitx_get_modes(connector);
19344+}
19345+
19346+static const struct drm_connector_helper_funcs hi_mipi_dsi_conn_helper_funcs = {
19347+    .get_modes = hi_dsi_conn_get_modes,
19348+};
19349+
19350+static enum drm_connector_status hi_dsi_connector_detect(struct drm_connector *connector, bool force)
19351+{
19352+    HI_DRM_FUNC_ENTER();
19353+    HI_DRM_FUNC_EXIT();
19354+    return connector_status_connected;
19355+}
19356+
19357+static const struct drm_connector_funcs hi_mipi_dsi_connector_funcs = {
19358+    .detect = hi_dsi_connector_detect,
19359+    .fill_modes = drm_helper_probe_single_connector_modes,
19360+    .destroy = drm_connector_cleanup,
19361+    .reset = drm_atomic_helper_connector_reset,
19362+    .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
19363+    .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
19364+    .atomic_set_property = adp_conn_atomic_set_property,
19365+    .atomic_get_property = adp_conn_atomic_get_property,
19366+};
19367+
19368+static int hi_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state,
19369+    struct drm_connector_state *conn_state)
19370+{
19371+    HI_DRM_FUNC_ENTER();
19372+    /* set mode,  attach the interface to crtc, mipi on and set blacklight */
19373+    hi_adp_mipitx_set_mode(encoder, &crtc_state->mode, conn_state);
19374+    HI_DRM_FUNC_EXIT();
19375+    return 0;
19376+}
19377+
19378+static enum drm_mode_status hi_mipi_dsi_encoder_mode_valid(struct drm_encoder *encoder,
19379+    const struct drm_display_mode *mode)
19380+{
19381+    HI_DRM_FUNC_ENTER();
19382+    HI_DRM_FUNC_EXIT();
19383+    return MODE_OK;
19384+}
19385+
19386+static void hi_mipi_dsi_encoder_enable(struct drm_encoder *encoder)
19387+{
19388+    int ret;
19389+    HI_DRM_FUNC_ENTER();
19390+    ret = hi_adp_mipitx_enable(encoder);
19391+    if (ret != 0) {
19392+        HI_DRM_ERR("hi_mipi_dsi_encoder_enable err, ret=%#x\n", ret);
19393+    }
19394+    HI_DRM_FUNC_EXIT();
19395+    return;
19396+}
19397+
19398+static void hi_mipi_dsi_encoder_disable(struct drm_encoder *encoder)
19399+{
19400+    int ret;
19401+    HI_DRM_FUNC_ENTER();
19402+    ret = hi_adp_mipitx_disable(encoder);
19403+    if (ret != 0) {
19404+        HI_DRM_ERR("hi_mipi_dsi_encoder_disable err, ret=%#x\n", ret);
19405+    }
19406+    HI_DRM_FUNC_EXIT();
19407+    return;
19408+}
19409+
19410+static const struct drm_encoder_helper_funcs hi_mipi_dsi_encoder_helper_funcs = {
19411+    .atomic_check = hi_mipi_dsi_encoder_atomic_check,
19412+    .mode_valid = hi_mipi_dsi_encoder_mode_valid,
19413+    .enable = hi_mipi_dsi_encoder_enable, /* SetBacklight */
19414+    .disable = hi_mipi_dsi_encoder_disable, /* off */
19415+};
19416+
19417+static const struct drm_encoder_funcs hi_mipi_dsi_encoder_funcs = {
19418+    .destroy = drm_encoder_cleanup,
19419+};
19420+
19421+static void mipitx_init_by_index(struct drm_device *drm, unsigned int id)
19422+{
19423+    int ret;
19424+    struct drm_connector *conn = NULL;
19425+    struct drm_encoder *encoder = NULL;
19426+    HI_DRM_FUNC_ENTER();
19427+    ret = hi_adp_mipitx_get_by_index(id, &conn, &encoder);
19428+    if (ret != 0) {
19429+        HI_DRM_INFO("mipi id %u not support!\n", id);
19430+        return;
19431+    }
19432+
19433+    /* bind crtc */
19434+    if (id == DRM_MODE_CONNECTOR_DSI) {
19435+        encoder->possible_crtcs = 1; /* 1: dhd0 */
19436+    } else {
19437+        encoder->possible_crtcs = 2; /* 2: dhd1 */
19438+    }
19439+
19440+    drm_encoder_init(drm, encoder, &hi_mipi_dsi_encoder_funcs, DRM_MODE_ENCODER_DSI, NULL);
19441+    drm_encoder_helper_add(encoder, &hi_mipi_dsi_encoder_helper_funcs);
19442+    drm_connector_init(drm, conn, &hi_mipi_dsi_connector_funcs, id);
19443+    drm_connector_helper_add(conn, &hi_mipi_dsi_conn_helper_funcs);
19444+    drm_connector_attach_encoder(conn, encoder);
19445+    ret = adp_conn_private_properties_init(drm, conn);
19446+    if (ret != 0) {
19447+        HI_DRM_ERR("adp_conn_private_properties_init failed\n");
19448+        drm_connector_cleanup(conn);
19449+        return;
19450+    }
19451+    HI_DRM_FUNC_EXIT();
19452+    return;
19453+}
19454+
19455+static void mipitx_deinit_by_index(struct drm_device *drm, unsigned int id)
19456+{
19457+    int ret;
19458+    struct drm_connector *conn = NULL;
19459+    struct drm_encoder *encoder = NULL;
19460+    HI_DRM_FUNC_ENTER();
19461+    ret = hi_adp_mipitx_get_by_index(id, &conn, &encoder);
19462+    if (ret != 0) {
19463+        HI_DRM_INFO("mipi id %u not support!\n", id);
19464+        return;
19465+    }
19466+
19467+    /* ensure disabled at the final cleanup call */
19468+    ret = hi_adp_mipitx_disable(encoder);
19469+    if (ret != 0) {
19470+        HI_DRM_ERR("hi_adp_hdmitx_disable err, ret=%#x\n", ret);
19471+    }
19472+    adp_conn_private_properties_deinit(drm, conn);
19473+    drm_connector_cleanup(conn);
19474+    drm_encoder_cleanup(encoder);
19475+    HI_DRM_FUNC_EXIT();
19476+    return;
19477+}
19478+
19479+int hi_drm_mipitx_init(struct drm_device *drm)
19480+{
19481+    int ret;
19482+    HI_DRM_FUNC_ENTER();
19483+    ret = hi_adp_mipitx_init();
19484+    if (ret != 0) {
19485+        HI_DRM_ERR("hi_adp_mipitx_init err, ret=%#x\n", ret);
19486+        return ret;
19487+    }
19488+    mipitx_init_by_index(drm, DRM_MODE_CONNECTOR_DSI);
19489+    HI_DRM_FUNC_EXIT();
19490+    return 0;
19491+}
19492+
19493+void hi_drm_mipitx_cleanup(struct drm_device *drm)
19494+{
19495+    HI_DRM_FUNC_ENTER();
19496+    mipitx_deinit_by_index(drm, DRM_MODE_CONNECTOR_DSI);
19497+    hi_adp_mipitx_deinit();
19498+    HI_DRM_FUNC_EXIT();
19499+    return;
19500+}
19501+
19502diff --git a/drivers/gpu/drm/hisilicon/hismart/hi_drm_mipitx.h b/drivers/gpu/drm/hisilicon/hismart/hi_drm_mipitx.h
19503new file mode 100644
19504index 000000000..34d2f0a37
19505--- /dev/null
19506+++ b/drivers/gpu/drm/hisilicon/hismart/hi_drm_mipitx.h
19507@@ -0,0 +1,17 @@
19508+/*
19509+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
19510+ * Description: Hisilicon DRM driver
19511+ * Author: Hisilicon multimedia software group
19512+ * Create: 2020-7-29
19513+ */
19514+
19515+#ifndef __HI_DRM_MIPITX_H__
19516+#define __HI_DRM_MIPITX_H__
19517+
19518+#include <drm/drm_device.h>
19519+
19520+int hi_drm_mipitx_init(struct drm_device *drm);
19521+void hi_drm_mipitx_cleanup(struct drm_device *drm);
19522+
19523+#endif /* __HI_DRM_MIPITX_H__ */
19524+
19525diff --git a/drivers/gpu/drm/hisilicon/hismart/hisilicon_drm.h b/drivers/gpu/drm/hisilicon/hismart/hisilicon_drm.h
19526new file mode 100644
19527index 000000000..5f247a1a9
19528--- /dev/null
19529+++ b/drivers/gpu/drm/hisilicon/hismart/hisilicon_drm.h
19530@@ -0,0 +1,31 @@
19531+/*
19532+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2016-2019. All rights reserved.
19533+ * Description: On behalf of a display device, hwcomposer is called for composition and sent for display
19534+ * Author: Hisilicon gfx group
19535+ * Created: 2021.01.01
19536+ */
19537+#ifndef HISILICON_DRM_H
19538+#define HISILICON_DRM_H
19539+
19540+#include <drm/drm.h>
19541+
19542+#if defined(__cplusplus)
19543+extern "C" {
19544+#endif
19545+#define DRM_HISILICON_GEM_FD_TO_PHYADDR 0x1
19546+
19547+struct drm_hisilicon_phyaddr {
19548+    /* * return the physical address */
19549+    __u64 phyaddr;
19550+    /* * dmabuf file descriptor */
19551+    __s32 fd;
19552+};
19553+
19554+#define DRM_IOCTL_HISILICON_GEM_FD_TO_PHYADDR \
19555+    DRM_IOWR(DRM_COMMAND_BASE + DRM_HISILICON_GEM_FD_TO_PHYADDR, struct drm_hisilicon_phyaddr)
19556+
19557+#if defined(__cplusplus)
19558+}
19559+#endif
19560+
19561+#endif /* HISILICON_DRM_H */
19562diff --git a/drivers/hi_vdmav100/Kconfig b/drivers/hi_vdmav100/Kconfig
19563new file mode 100644
19564index 000000000..ecaa952b9
19565--- /dev/null
19566+++ b/drivers/hi_vdmav100/Kconfig
19567@@ -0,0 +1,26 @@
19568+menuconfig HI_VDMA_V100
19569+	tristate "Hisilicon VDMA Controller V100"
19570+	depends on ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100
19571+	default n if ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100
19572+	help
19573+	  This is the driver for hisilicon VDMA controoller
19574+	  IP.
19575+
19576+if HI_VDMA_V100
19577+
19578+config HI_VDMA_CHN_NUM
19579+	int "HI_VDMAV100 max channel number"
19580+	default 32
19581+
19582+config HI_VDMA_TRANSFER_THRESHOLD
19583+        int "Hi VDMA data transfer threshold KBytes"
19584+        range 4 16384
19585+        default "128" if (ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100)
19586+
19587+config HI_VDMA_MISC_DEV
19588+	bool "HI_VDMAV100 misc dev"
19589+	default y if (ARCH_HI3556AV100 || ARCH_HI3519AV100 || ARCH_HI3568V100)
19590+	depends on HI_VDMA_V100
19591+
19592+
19593+endif
19594diff --git a/drivers/hi_vdmav100/Makefile b/drivers/hi_vdmav100/Makefile
19595new file mode 100644
19596index 000000000..ccac799b5
19597--- /dev/null
19598+++ b/drivers/hi_vdmav100/Makefile
19599@@ -0,0 +1,2 @@
19600+obj-$(CONFIG_HI_VDMA_V100) += hi_vdmav100.o
19601+obj-$(CONFIG_HI_VDMA_MISC_DEV) += hi_vdmav100_misc.o
19602diff --git a/drivers/hi_vdmav100/hi_vdma.h b/drivers/hi_vdmav100/hi_vdma.h
19603new file mode 100644
19604index 000000000..3644fe621
19605--- /dev/null
19606+++ b/drivers/hi_vdmav100/hi_vdma.h
19607@@ -0,0 +1,41 @@
19608+/*
19609+ * Copyright (c) 2015 HiSilicon Technologies Co., Ltd.
19610+ *
19611+ * This program is free software; you can redistribute it and/or modify
19612+ * it under the terms of the GNU General Public License as published by
19613+ * the Free Software Foundation; either version 2 of the License, or
19614+ * (at your option) any later version.
19615+ *
19616+ * This program is distributed in the hope that it will be useful,
19617+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19618+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19619+ * GNU General Public License for more details.
19620+ *
19621+ * You should have received a copy of the GNU General Public License
19622+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19623+ */
19624+
19625+#ifndef __VDMA_USER_H__
19626+#define __VDMA_USER_H__
19627+
19628+struct hivdmac_host {
19629+	struct device *dev;
19630+	struct clk *clk;
19631+	struct reset_control *rstc;
19632+	void __iomem *regbase;
19633+
19634+	int irq;
19635+};
19636+
19637+#define VDMA_DATA_CMD   0x6
19638+
19639+struct dmac_user_para {
19640+	uintptr_t src;
19641+	uintptr_t dst;
19642+	unsigned int size;
19643+};
19644+
19645+extern int hi_vdma_m2m_copy(void *dst, const void *src, size_t count);
19646+
19647+
19648+#endif
19649diff --git a/drivers/hi_vdmav100/hi_vdmav100.c b/drivers/hi_vdmav100/hi_vdmav100.c
19650new file mode 100644
19651index 000000000..0199ddd23
19652--- /dev/null
19653+++ b/drivers/hi_vdmav100/hi_vdmav100.c
19654@@ -0,0 +1,534 @@
19655+/*
19656+ * clock driver for hisilicon hi3519 or hi3559 soc
19657+ *
19658+ * Copyright (c) 2015 HiSilicon Technologies Co., Ltd.
19659+ *
19660+ *
19661+ * This program is free software; you can redistribute  it and/or modify it
19662+ * under  the terms of  the GNU General  Public License as published by the
19663+ * Free Software Foundation;  either version 2 of the  License, or (at your
19664+ * option) any later version.
19665+ *
19666+ * This program is distributed in the hope that it will be useful,
19667+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
19668+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19669+ * GNU General Public License for more details.
19670+ *
19671+ * You should have received a copy of the GNU General Public License
19672+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19673+ *
19674+ */
19675+#include <linux/kernel.h>
19676+#include <linux/module.h>
19677+#include <linux/init.h>
19678+#include <linux/types.h>
19679+#include <linux/errno.h>
19680+#include <linux/fcntl.h>
19681+#include <linux/mm.h>
19682+#include <linux/miscdevice.h>
19683+#include <linux/proc_fs.h>
19684+#include <linux/fs.h>
19685+#include <linux/slab.h>
19686+#include <linux/spinlock.h>
19687+#include <linux/delay.h>
19688+#include <linux/uaccess.h>
19689+#include <linux/io.h>
19690+#include <linux/wait.h>
19691+#include <linux/sched.h>
19692+#include <linux/interrupt.h>
19693+#include <linux/ioport.h>
19694+#include <linux/string.h>
19695+#include <linux/dma-mapping.h>
19696+#include <linux/platform_device.h>
19697+#include <linux/mod_devicetable.h>
19698+#include <linux/vmalloc.h>
19699+#include <asm/pgtable.h>
19700+#include <asm/page.h>
19701+#include <linux/mm_types.h>
19702+#include <linux/mmu_context.h>
19703+#include <asm/tlbflush.h>
19704+#include <linux/clk.h>
19705+#include <linux/reset.h>
19706+
19707+#include "hi_vdmav100.h"
19708+#include "hi_vdma.h"
19709+
19710+#define user_addr(ptr)   (((uintptr_t)ptr < TASK_SIZE) \
19711+            && ((uintptr_t)ptr > 0))
19712+
19713+int vdma_flag = 0;
19714+EXPORT_SYMBOL(vdma_flag);
19715+
19716+void __iomem *hi_reg_vdma_base_va;
19717+
19718+spinlock_t my_lock;
19719+spinlock_t reg_lock;
19720+
19721+unsigned int irq_flag;
19722+
19723+unsigned int wake_channel_flag[DMAC_MAX_CHANNELS];
19724+
19725+wait_queue_head_t dmac_wait_queue[DMAC_MAX_CHANNELS];
19726+
19727+int hi_g_channel_status[DMAC_MAX_CHANNELS];
19728+
19729+/*
19730+ *  dmac interrupt handle function
19731+ */
19732+irqreturn_t vdma_isr(int irq, void *dev_id)
19733+{
19734+	unsigned int dma_intr_status, channel_intr_status;
19735+	unsigned int i;
19736+
19737+	if (hi_reg_vdma_base_va == NULL)
19738+		return -1;
19739+	dmac_readw(hi_reg_vdma_base_va + DMAC_INT_STATUS, dma_intr_status);
19740+
19741+	/* decide which channel has trigger the interrupt */
19742+	for (i = 0; i < DMAC_MAX_CHANNELS; i++) {
19743+		if (((dma_intr_status >> i) & 0x1) == 1) {
19744+			dmac_readw(hi_reg_vdma_base_va
19745+				   + DMAC_CxINTR_RAW(i),
19746+				   channel_intr_status);
19747+
19748+			/* clear the channel error interrupt */
19749+			dmac_writew(hi_reg_vdma_base_va
19750+				    + DMAC_CxINTR_RAW(i),
19751+				    channel_intr_status);
19752+
19753+			if ((channel_intr_status & CX_INT_STAT)
19754+					== CX_INT_STAT) {
19755+				/* transfer finish interrupt */
19756+				if ((channel_intr_status & CX_INT_TC_RAW)
19757+						== CX_INT_TC_RAW) {
19758+					wake_channel_flag[i] = DMA_TRANS_OK;
19759+
19760+					/* save the current channel transfer *
19761+					 * status to hi_g_channel_status[i] */
19762+					hi_g_channel_status[i] =
19763+						DMAC_CHN_SUCCESS;
19764+
19765+					wake_up(&dmac_wait_queue[i]);
19766+					goto exit;
19767+				}
19768+
19769+				wake_channel_flag[i] = DMA_TRANS_FAULT;
19770+				pr_err("%d channel!,intr_raw=%x\n",
19771+				       i, channel_intr_status);
19772+				hi_g_channel_status[i] =
19773+					-DMAC_CHN_CONFIG_ERROR;
19774+
19775+				wake_up(&dmac_wait_queue[i]);
19776+				goto exit;
19777+			}
19778+		}
19779+	}
19780+
19781+exit:
19782+	return IRQ_HANDLED;
19783+}
19784+
19785+/*
19786+ *  allocate channel.
19787+ */
19788+int hi_vdma_channel_allocate(void *pisr)
19789+{
19790+	unsigned int  i, channelinfo, tmp, channel_intr;
19791+	unsigned long flags;
19792+
19793+	spin_lock_irqsave(&my_lock, flags);
19794+
19795+	if (hi_reg_vdma_base_va == NULL)
19796+		return 0;
19797+	dmac_readw(hi_reg_vdma_base_va + DMAC_CHANNEL_STATUS, channelinfo);
19798+
19799+	for (i = 0; i < CHANNEL_NUM; i++) {
19800+		if (hi_g_channel_status[i] == DMAC_CHN_VACANCY) {
19801+			dmac_readw(hi_reg_vdma_base_va + DMAC_CxINTR_RAW(i),
19802+				   channel_intr);
19803+			tmp = channelinfo >> i;
19804+			/* check the vdma channel data transfer is finished ? */
19805+			if (((tmp & 0x01) == 0x00) && (channel_intr == 0x00)) {
19806+				hi_g_channel_status[i] = DMAC_CHN_ALLOCAT;
19807+				spin_unlock_irqrestore(&my_lock, flags);
19808+				return i; /* return channel number */
19809+			}
19810+		}
19811+	}
19812+
19813+	spin_unlock_irqrestore(&my_lock, flags);
19814+	return DMAC_CHANNEL_INVALID;
19815+}
19816+
19817+/*
19818+ *  free channel
19819+ */
19820+int hi_vdma_channel_free(unsigned int channel)
19821+{
19822+	hi_g_channel_status[channel] = DMAC_CHN_VACANCY;
19823+
19824+	return 0;
19825+}
19826+
19827+/*
19828+ *  channel enable
19829+ *  start a vdma transfer immediately
19830+ */
19831+int hi_vdma_channelstart(unsigned int channel,
19832+			 const unsigned int *src, const unsigned int *dest)
19833+{
19834+	struct mm_struct *mm = NULL;
19835+	unsigned int reg[DMAC_MAX_CHANNELS];
19836+
19837+	if (channel >= DMAC_MAX_CHANNELS) {
19838+		pr_err("channel number is out of scope(%d).\n",
19839+		       DMAC_MAX_CHANNELS);
19840+		return -EINVAL;
19841+	}
19842+
19843+	hi_g_channel_status[channel] = DMAC_NOT_FINISHED;
19844+
19845+	mm = current->mm;
19846+	if (!mm) {
19847+		mm = &init_mm;
19848+	}
19849+
19850+	if (mm->pgd == NULL)
19851+		return -EINVAL;
19852+	/* set ttbr */
19853+	/* get TTBR from the page */
19854+	reg[channel] = __pa(mm->pgd);
19855+
19856+	/* only [31:10] is the ttbr */
19857+	reg[channel] &= 0xfffffc00;
19858+
19859+	/* set the RGN,AFE,AFFD,TRE */
19860+	reg[channel] |= TTB_RGN | AFE | TRE;
19861+
19862+	if (user_addr(dest)) {
19863+		reg[channel] &= ~DEST_IS_KERNEL;
19864+	} else {
19865+		reg[channel] |= DEST_IS_KERNEL;
19866+	}
19867+
19868+	if (user_addr(src)) {
19869+		reg[channel] &= ~SRC_IS_KERNEL;
19870+	} else {
19871+		reg[channel] |= SRC_IS_KERNEL;
19872+	}
19873+
19874+	if (in_atomic() || in_interrupt()) {
19875+		/* disable the channel interrupt */
19876+		reg[channel] &= ~DMAC_INTR_ENABLE;
19877+	} else {
19878+		/* enable the channel interrupt */
19879+		reg[channel] |= DMAC_INTR_ENABLE;
19880+	}
19881+
19882+	reg[channel] |= DMAC_CHANNEL_ENABLE;
19883+
19884+	if (hi_reg_vdma_base_va == NULL)
19885+		return 0;
19886+	/* set the TTBR register */
19887+	dmac_writew(hi_reg_vdma_base_va + DMAC_CxTTBR(channel),
19888+		    reg[channel]);
19889+	return 0;
19890+}
19891+
19892+/*
19893+ *  Apply VDMA interrupt resource
19894+ *  init channel state
19895+ */
19896+int hi_vdma_driver_init(struct hivdmac_host *dma)
19897+{
19898+	unsigned int i;
19899+	unsigned int tmp_reg = 0;
19900+
19901+	if (hi_reg_vdma_base_va == NULL)
19902+		return 0;
19903+	dmac_readw(hi_reg_vdma_base_va + DMAC_GLOBLE_CTRL, tmp_reg);
19904+	tmp_reg |= AUTO_CLK_GT_EN;
19905+	dmac_writew(hi_reg_vdma_base_va + DMAC_GLOBLE_CTRL, tmp_reg);
19906+
19907+	/* set rd dust address is ram 0 */
19908+	dmac_writew(hi_reg_vdma_base_va + DMAC_RD_DUSTB_ADDR, 0x04c11000);
19909+
19910+	/* set wr dust address is ram 0x1000 */
19911+	dmac_writew(hi_reg_vdma_base_va + DMAC_WR_DUSTB_ADDR, 0x04c11000);
19912+
19913+	/* set prrr register */
19914+	dmac_writew(hi_reg_vdma_base_va + DMAC_MMU_PRRR, PRRR);
19915+	/* set nmrr register */
19916+	dmac_writew(hi_reg_vdma_base_va + DMAC_MMU_NMRR, NMRR);
19917+
19918+	/* config global reg for VDMA */
19919+	tmp_reg |= EVENT_BROADCAST_EN | WR_CMD_NUM_PER_ARB |
19920+		   RD_CMD_NUM_PER_ARB | WR_OTD_NUM | RD_OTD_NUM | WFE_EN;
19921+	dmac_writew(hi_reg_vdma_base_va + DMAC_GLOBLE_CTRL, tmp_reg);
19922+
19923+	for (i = 0; i < CHANNEL_NUM; i++) {
19924+		hi_g_channel_status[i] = DMAC_CHN_VACANCY;
19925+		init_waitqueue_head(&dmac_wait_queue[i]);
19926+	}
19927+
19928+	spin_lock_init(&my_lock);
19929+	spin_lock_init(&reg_lock);
19930+
19931+	return 0;
19932+}
19933+
19934+/*
19935+ *  wait for transfer end
19936+ */
19937+int hi_vdma_wait(unsigned int channel)
19938+{
19939+	unsigned long data_jiffies_timeout = jiffies + DMA_TIMEOUT_HZ;
19940+	unsigned int channel_intr_raw;
19941+
19942+	while (1) {
19943+		if (hi_reg_vdma_base_va == NULL)
19944+			return 0;
19945+		/* read the status of current interrupt */
19946+		dmac_readw(hi_reg_vdma_base_va + DMAC_CxINTR_RAW(channel),
19947+			   channel_intr_raw);
19948+
19949+		/* clear the interrupt */
19950+		dmac_writew(hi_reg_vdma_base_va
19951+			    + DMAC_CxINTR_RAW(channel),
19952+			    channel_intr_raw);
19953+
19954+		if (channel >= DMAC_MAX_CHANNELS)
19955+			return 0;
19956+		/* save the current channel transfer status to *
19957+		 * hi_g_channel_status[i] */
19958+		if ((channel_intr_raw & CX_INT_STAT) == CX_INT_STAT) {
19959+			/* transfer finish interrupt */
19960+			if ((channel_intr_raw & CX_INT_TC_RAW) ==
19961+					CX_INT_TC_RAW) {
19962+				hi_g_channel_status[channel] = DMAC_CHN_SUCCESS;
19963+				return DMAC_CHN_SUCCESS;
19964+			}
19965+
19966+			/* transfer abort interrupt */
19967+			pr_debug("data transfer error in VDMA %x channel!",
19968+				 channel);
19969+			pr_debug("intr_raw=%x\n", channel_intr_raw);
19970+			hi_g_channel_status[channel] =
19971+				-DMAC_CHN_CONFIG_ERROR;
19972+			return -DMAC_CHN_CONFIG_ERROR;
19973+		}
19974+
19975+		if (!time_before(jiffies, data_jiffies_timeout)) { /* timeout */
19976+			pr_err("wait interrupt timeout, channel=%d, func:%s, line:%d\n",
19977+			       channel, __func__, __LINE__);
19978+			return -1;
19979+		}
19980+	}
19981+
19982+	return -1;
19983+}
19984+
19985+/*
19986+ *  execute memory to memory vdma transfer
19987+ */
19988+static int hi_vdma_m2m_transfer(const unsigned int *psource,
19989+				const unsigned int *pdest,
19990+				unsigned int uwtransfersize)
19991+{
19992+	unsigned int ulchnn;
19993+	int ret = 0;
19994+
19995+	ulchnn = (unsigned int)hi_vdma_channel_allocate(NULL);
19996+
19997+	if (ulchnn == DMAC_CHANNEL_INVALID) {
19998+		pr_err("DMAC_CHANNEL_INVALID.\n");
19999+
20000+		return -1;
20001+	}
20002+
20003+	wake_channel_flag[ulchnn] = 0;
20004+
20005+	dmac_writew(hi_reg_vdma_base_va + DMAC_CxLENGTH(ulchnn),
20006+		    uwtransfersize);
20007+	dmac_writew(hi_reg_vdma_base_va + DMAC_CxSRCADDR(ulchnn),
20008+		    (uintptr_t)psource);
20009+	dmac_writew(hi_reg_vdma_base_va + DMAC_CxDESTADDR(ulchnn),
20010+		    (uintptr_t)pdest);
20011+
20012+	if (hi_vdma_channelstart(ulchnn, psource, pdest) != 0) {
20013+		ret = -1;
20014+		goto exit;
20015+	}
20016+
20017+	if (hi_vdma_wait(ulchnn) != DMAC_CHN_SUCCESS) {
20018+		ret = -1;
20019+		goto exit;
20020+	}
20021+
20022+exit:
20023+	hi_vdma_channel_free(ulchnn);
20024+
20025+	return ret;
20026+}
20027+EXPORT_SYMBOL(hi_vdma_m2m_transfer);
20028+
20029+int hi_vdma_m2m_copy(void *dst, const void *src, size_t count)
20030+{
20031+	int ret;
20032+
20033+	if (((uintptr_t)dst & 0xff) || ((uintptr_t)src & 0xff)) {
20034+		return -1;
20035+	}
20036+	if (((uintptr_t)src < (uintptr_t)dst) &&
20037+			(((uintptr_t)src + count) > (uintptr_t)dst)) {
20038+		return -1;
20039+	}
20040+	if (((uintptr_t)src >= (uintptr_t)dst) &&
20041+			((uintptr_t)src < ((uintptr_t)dst + count))) {
20042+		return -1;
20043+	}
20044+	if (abs((uintptr_t)dst - (uintptr_t)src) < PAGE_SIZE) {
20045+		return -1;
20046+	}
20047+
20048+	ret = hi_vdma_m2m_transfer((unsigned int *)src, dst, count);
20049+
20050+	if (ret < 0) {
20051+		return ret;
20052+	} else {
20053+		return 0;
20054+	}
20055+}
20056+EXPORT_SYMBOL(hi_vdma_m2m_copy);
20057+
20058+static int hivdmac_probe(struct platform_device *platdev)
20059+{
20060+	unsigned int i;
20061+	struct hivdmac_host *dma = NULL;
20062+	struct resource *res = NULL;
20063+	int ret;
20064+	dma = devm_kzalloc(&platdev->dev, sizeof(*dma), GFP_KERNEL);
20065+	if (!dma) {
20066+		return -ENOMEM;
20067+	}
20068+
20069+	res = platform_get_resource(platdev, IORESOURCE_MEM, 0);
20070+	if (!res) {
20071+		dev_err(&platdev->dev, "no mmio resource\n");
20072+		return -ENODEV;
20073+	}
20074+
20075+	dma->regbase = devm_ioremap_resource(&platdev->dev, res);
20076+	if (IS_ERR(dma->regbase)) {
20077+		return PTR_ERR(dma->regbase);
20078+	}
20079+
20080+	dma->clk = devm_clk_get(&platdev->dev, NULL);
20081+	if (IS_ERR(dma->clk)) {
20082+		return PTR_ERR(dma->clk);
20083+	}
20084+
20085+	clk_prepare_enable(dma->clk);
20086+
20087+	dma->rstc = devm_reset_control_get(&platdev->dev, "dma-reset");
20088+	if (IS_ERR(dma->rstc)) {
20089+		return PTR_ERR(dma->rstc);
20090+	}
20091+
20092+	dma->irq = platform_get_irq(platdev, 0);
20093+	if (unlikely(dma->irq < 0)) {
20094+		return -ENODEV;
20095+	}
20096+	hi_reg_vdma_base_va = dma->regbase;
20097+	pr_debug("vdma reg base is %p\n", hi_reg_vdma_base_va);
20098+	dma->dev = &platdev->dev;
20099+
20100+	ret = hi_vdma_driver_init(dma);
20101+	if (ret) {
20102+		return -ENODEV;
20103+	}
20104+
20105+	platform_set_drvdata(platdev, dma);
20106+
20107+	for (i = 0; i < CONFIG_HI_VDMA_CHN_NUM; i++) {
20108+		hi_g_channel_status[i] = DMAC_CHN_VACANCY;
20109+	}
20110+
20111+	vdma_flag = 1;
20112+	printk("hivdmav100 driver inited.\n");
20113+	return ret;
20114+}
20115+
20116+static int hivdmac_remove(struct platform_device *platdev)
20117+{
20118+	int i;
20119+	struct hivdmac_host *dma = platform_get_drvdata(platdev);
20120+
20121+	clk_disable_unprepare(dma->clk);
20122+
20123+	for (i = 0; i < CONFIG_HI_VDMA_CHN_NUM; i++) {
20124+		hi_g_channel_status[i] = DMAC_CHN_VACANCY;
20125+	}
20126+
20127+	vdma_flag = 0;
20128+	printk("hivdmav100 driver deinited.\n");
20129+
20130+	return 0;
20131+}
20132+
20133+static int hivdmac_suspend(struct platform_device *platdev,
20134+			   pm_message_t state)
20135+{
20136+	int i;
20137+	struct hivdmac_host *dma = platform_get_drvdata(platdev);
20138+
20139+	clk_prepare_enable(dma->clk);
20140+
20141+	for (i = 0; i < CONFIG_HI_VDMA_CHN_NUM; i++) {
20142+		hi_g_channel_status[i] = DMAC_CHN_VACANCY;
20143+	}
20144+
20145+	clk_disable_unprepare(dma->clk);
20146+
20147+	vdma_flag = 0;
20148+
20149+	return 0;
20150+}
20151+
20152+static int hivdmac_resume(struct platform_device *platdev)
20153+{
20154+	int i;
20155+	struct hivdmac_host *dma = platform_get_drvdata(platdev);
20156+
20157+	hi_vdma_driver_init(dma);
20158+
20159+	for (i = 0; i < CONFIG_HI_VDMA_CHN_NUM; i++) {
20160+		hi_g_channel_status[i] = DMAC_CHN_VACANCY;
20161+	}
20162+
20163+	vdma_flag = 1;
20164+
20165+	return 0;
20166+}
20167+
20168+static const struct of_device_id hisi_vdmac_dt_ids[] = {
20169+	{.compatible = "hisilicon,hisi-vdmac"},
20170+	{ },
20171+};
20172+MODULE_DEVICE_TABLE(of, hisi_vdmac_dt_ids);
20173+
20174+static struct platform_driver hisi_vdmac_driver = {
20175+	.driver = {
20176+		.name   = "hisi-vdmac",
20177+		.of_match_table = hisi_vdmac_dt_ids,
20178+	},
20179+	.probe      = hivdmac_probe,
20180+	.remove     = hivdmac_remove,
20181+	.suspend    = hivdmac_suspend,
20182+	.resume     = hivdmac_resume,
20183+};
20184+
20185+module_platform_driver(hisi_vdmac_driver);
20186+
20187+MODULE_LICENSE("GPL");
20188+MODULE_AUTHOR("BVT_OSDRV");
20189diff --git a/drivers/hi_vdmav100/hi_vdmav100.h b/drivers/hi_vdmav100/hi_vdmav100.h
20190new file mode 100644
20191index 000000000..8b8d3e6c0
20192--- /dev/null
20193+++ b/drivers/hi_vdmav100/hi_vdmav100.h
20194@@ -0,0 +1,122 @@
20195+/*
20196+ * Copyright (c) 2015 HiSilicon Technologies Co., Ltd.
20197+ *
20198+ * This program is free software; you can redistribute it and/or modify
20199+ * it under the terms of the GNU General Public License as published by
20200+ * the Free Software Foundation; either version 2 of the License, or
20201+ * (at your option) any later version.
20202+ *
20203+ * This program is distributed in the hope that it will be useful,
20204+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20205+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20206+ * GNU General Public License for more details.
20207+ *
20208+ * You should have received a copy of the GNU General Public License
20209+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20210+ */
20211+#ifndef __HI_VDMA_H__
20212+#define __HI_VDMA_H__
20213+
20214+#define  dmac_writew(addr, value) \
20215+    ((*(volatile unsigned int *)(addr)) = (value))
20216+
20217+#define  dmac_readw(addr, v) \
20218+    (v = (*(volatile unsigned int *)(addr)))
20219+
20220+#define DMAC_GLOBLE_CTRL    0x000
20221+#define WFE_EN          (0x1 << 23)
20222+#define EVENT_BROADCAST_EN  (0x1 << 21)
20223+#define AUTO_CLK_GT_EN      (0x1 << 17)
20224+#define AUTO_PRI_EN     (0x1 << 16)
20225+#define WR_CMD_NUM_PER_ARB  (0x4 << 12)
20226+#define RD_CMD_NUM_PER_ARB  (0x4 << 8)
20227+#define WR_OTD_NUM      (0xF << 4)
20228+#define RD_OTD_NUM      (0xF)
20229+
20230+#define DMAC_PRI_THRESHOLD  0x004
20231+/* PRRR and NMRR define */
20232+#define DMAC_MMU_NMRR  0x008
20233+#define DMAC_MMU_PRRR  0x00C
20234+/* read and write dustb address register define */
20235+#define DMAC_RD_DUSTB_ADDR      0x010
20236+#define DMAC_WR_DUSTB_ADDR      0x014
20237+/* channel status register define */
20238+#define DMAC_CHANNEL_STATUS     0x01c
20239+#define DMAC_WORK_DURATION      0x020
20240+#define DMAC_INT_STATUS       0x02c
20241+/* the definition for DMAC channel register */
20242+#define DMAC_CHANNEL_BASE           0x100
20243+#define DMAC_CxSRCADDR(i)   (DMAC_CHANNEL_BASE + 0x00 + 0x20 * i)
20244+#define DMAC_CxDESTADDR(i)  (DMAC_CHANNEL_BASE + 0x04 + 0x20 * i)
20245+#define DMAC_CxLENGTH(i)    (DMAC_CHANNEL_BASE + 0x08 + 0x20 * i)
20246+#define DMAC_CxTTBR(i)      (DMAC_CHANNEL_BASE + 0x0C + 0x20 * i)
20247+#define DMAC_CxMISC(i)      (DMAC_CHANNEL_BASE + 0x10 + 0x20 * i)
20248+#define DMAC_CxINTR_RAW(i)  (DMAC_CHANNEL_BASE + 0x14 + 0x20 * i)
20249+#define CX_INT_STAT    (0x1 << 4)
20250+#define CX_INT_TC_RAW  (0x1 << 3)
20251+#define CX_INT_TE_RAW  (0x1 << 2)
20252+#define CX_INT_TM_RAW  (0x1 << 1)
20253+#define CX_INT_AP_RAW  (0x1 << 0)
20254+
20255+#define DMAC_INTR_ENABLE               (0x1 << 8)
20256+
20257+/* channel enable */
20258+#define DMAC_CHANNEL_ENABLE     (0x1 << 9)
20259+
20260+/* access flag enable */
20261+#define AFE         (0x1 << 6)
20262+
20263+/* user and kernel define */
20264+#define DEST_IS_KERNEL      (0x1 << 2)
20265+#define SRC_IS_KERNEL       (0x1 << 1)
20266+
20267+/* for TTBR */
20268+#define TTB_RGN         (0x1 << 3) /* outer cache write back allocate */
20269+
20270+/* for ap and cache remap */
20271+
20272+/* remap enable,ap access check enable */
20273+#define TRE 0x001
20274+
20275+#define PRRR     0xff0a81a8
20276+#define NMRR     0x40e040e0
20277+
20278+#define DMAC_SYNC_VAL               0x0
20279+
20280+/* definition for the return value */
20281+#define DMAC_ERROR_BASE             100
20282+#define DMAC_CHANNEL_INVALID            (DMAC_ERROR_BASE + 1)
20283+
20284+#define DMAC_TRXFERSIZE_INVALID         (DMAC_ERROR_BASE + 2)
20285+#define DMAC_SOURCE_ADDRESS_INVALID     (DMAC_ERROR_BASE + 3)
20286+#define DMAC_DESTINATION_ADDRESS_INVALID    (DMAC_ERROR_BASE + 4)
20287+#define DMAC_MEMORY_ADDRESS_INVALID     (DMAC_ERROR_BASE + 5)
20288+#define DMAC_PERIPHERAL_ID_INVALID      (DMAC_ERROR_BASE + 6)
20289+#define DMAC_DIRECTION_ERROR            (DMAC_ERROR_BASE + 7)
20290+#define DMAC_TRXFER_ERROR           (DMAC_ERROR_BASE + 8)
20291+#define DMAC_LLIHEAD_ERROR          (DMAC_ERROR_BASE + 9)
20292+#define DMAC_SWIDTH_ERROR           (DMAC_ERROR_BASE + 0xa)
20293+#define DMAC_LLI_ADDRESS_INVALID        (DMAC_ERROR_BASE + 0xb)
20294+#define DMAC_TRANS_CONTROL_INVALID      (DMAC_ERROR_BASE + 0xc)
20295+#define DMAC_MEMORY_ALLOCATE_ERROR      (DMAC_ERROR_BASE + 0xd)
20296+#define DMAC_NOT_FINISHED           (DMAC_ERROR_BASE + 0xe)
20297+
20298+#define DMAC_TIMEOUT                (DMAC_ERROR_BASE + 0xf)
20299+#define DMAC_CHN_SUCCESS            (DMAC_ERROR_BASE + 0x10)
20300+#define DMAC_CHN_CONFIG_ERROR           (DMAC_ERROR_BASE + 0x11)
20301+#define DMAC_CHN_DATA_ERROR         (DMAC_ERROR_BASE + 0x12)
20302+#define DMAC_CHN_TIMEOUT            (DMAC_ERROR_BASE + 0x13)
20303+#define DMAC_CHN_ALLOCAT            (DMAC_ERROR_BASE + 0x14)
20304+#define DMAC_CHN_VACANCY            (DMAC_ERROR_BASE + 0x15)
20305+
20306+#define DMAC_MAX_CHANNELS           CONFIG_HI_VDMA_CHN_NUM
20307+
20308+#define CHANNEL_NUM DMAC_MAX_CHANNELS
20309+
20310+#define DMA_TRANS_OK          0x1
20311+#define DMA_PAGE_FAULT      0x2
20312+#define DMA_TRANS_FAULT     0x3
20313+#define DMA_TIMEOUT_HZ      (3 * HZ)
20314+
20315+extern int g_channel_status[DMAC_MAX_CHANNELS];
20316+#endif
20317diff --git a/drivers/hi_vdmav100/hi_vdmav100_misc.c b/drivers/hi_vdmav100/hi_vdmav100_misc.c
20318new file mode 100644
20319index 000000000..777a7c47c
20320--- /dev/null
20321+++ b/drivers/hi_vdmav100/hi_vdmav100_misc.c
20322@@ -0,0 +1,109 @@
20323+/*
20324+ * Copyright (c) 2015 HiSilicon Technologies Co., Ltd.
20325+ *
20326+ * This program is free software; you can redistribute it and/or modify
20327+ * it under the terms of the GNU General Public License as published by
20328+ * the Free Software Foundation; either version 2 of the License, or
20329+ * (at your option) any later version.
20330+ *
20331+ * This program is distributed in the hope that it will be useful,
20332+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20333+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20334+ * GNU General Public License for more details.
20335+ *
20336+ * You should have received a copy of the GNU General Public License
20337+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20338+ */
20339+
20340+#include <linux/init.h>
20341+#include <linux/module.h>
20342+#include <linux/delay.h>
20343+#include <linux/vmalloc.h>
20344+#include <asm/pgtable.h>
20345+#include <linux/slab.h>
20346+#include <linux/mm.h>
20347+#include <asm/page.h>
20348+#include <linux/spinlock.h>
20349+#include <linux/kernel.h>
20350+#include <linux/ioctl.h>
20351+#include <linux/slab.h>
20352+#include <linux/fs.h>
20353+#include <linux/miscdevice.h>
20354+#include <linux/mm_types.h>
20355+#include <linux/mmu_context.h>
20356+#include <asm/tlbflush.h>
20357+#include <linux/uaccess.h>
20358+
20359+#include "hi_vdma.h"
20360+
20361+#define hidmac_error(s...) do { \
20362+    pr_err("hidmac:%s:%d: ", __func__, __LINE__); \
20363+    printk(s); \
20364+    printk("\n"); \
20365+} while (0)
20366+
20367+
20368+static long hi_vdma_ioctl(struct file *filep, unsigned int cmd,
20369+			  unsigned long arg)
20370+{
20371+	long ret = 0;
20372+	struct dmac_user_para para;
20373+
20374+	if (copy_from_user((void *)&para, (void *)(uintptr_t)arg, sizeof(para))) {
20375+		return -EINVAL;
20376+	}
20377+
20378+	switch (cmd) {
20379+	case VDMA_DATA_CMD:
20380+		ret = hi_vdma_m2m_copy((void *)para.dst, (void *)para.src, para.size);
20381+		break;
20382+	default:
20383+		hidmac_error("unknown command :%x\n", cmd);
20384+		ret = -1;
20385+		break;
20386+	}
20387+
20388+	return ret;
20389+}
20390+
20391+static int hi_vdma_open(struct inode *inode, struct file *file)
20392+{
20393+	return 0;
20394+}
20395+
20396+static int hi_vdma_release(struct inode *inode, struct file *file)
20397+{
20398+	return 0;
20399+}
20400+
20401+static const struct file_operations hi_vdma_fops = {
20402+	.owner = THIS_MODULE,
20403+	.unlocked_ioctl = hi_vdma_ioctl,
20404+	.open = hi_vdma_open,
20405+	.release = hi_vdma_release,
20406+};
20407+
20408+static struct miscdevice hi_vdma_misc_device = {
20409+	.minor = MISC_DYNAMIC_MINOR,
20410+	.name = "hi_vdma",
20411+	.fops = &hi_vdma_fops,
20412+};
20413+
20414+static int __init hi_vdma_init(void)
20415+{
20416+	int ret;
20417+
20418+	ret = misc_register(&hi_vdma_misc_device);
20419+
20420+	return ret;
20421+}
20422+
20423+static void __exit hi_vdma_exit(void)
20424+{
20425+	misc_deregister(&hi_vdma_misc_device);
20426+}
20427+
20428+module_init(hi_vdma_init);
20429+module_exit(hi_vdma_exit);
20430+MODULE_LICENSE("GPL");
20431+MODULE_DESCRIPTION("Hisilicon VDMA MISC Driver");
20432diff --git a/drivers/hidmac/Kconfig b/drivers/hidmac/Kconfig
20433new file mode 100644
20434index 000000000..dcb3e08bf
20435--- /dev/null
20436+++ b/drivers/hidmac/Kconfig
20437@@ -0,0 +1,21 @@
20438+#
20439+# Sensor device configuration
20440+#
20441+
20442+config HI_DMAC
20443+	tristate "Hisilicon DMAC Controller support"
20444+	depends on (ARCH_HISI_BVT)
20445+	help
20446+	  The Direction Memory Access(DMA) is a high-speed data transfer
20447+	  operation. It supports data read/write between peripherals and
20448+	  memories without using the CPU.
20449+	  Hisilicon DMA Controller(DMAC) directly transfers data between
20450+	  a memory and a peripheral, between peripherals, or between memories.
20451+	  This avoids the CPU intervention and reduces the interrupt handling
20452+	  overhead of the CPU.
20453+
20454+if HI_DMAC
20455+config HI_DMAC_CHANNEL_NUM
20456+	int "hi dmac channel num"
20457+	default "4"
20458+endif
20459diff --git a/drivers/hidmac/Makefile b/drivers/hidmac/Makefile
20460new file mode 100644
20461index 000000000..7e41f4c37
20462--- /dev/null
20463+++ b/drivers/hidmac/Makefile
20464@@ -0,0 +1,6 @@
20465+#
20466+# Makefile for the hi dmac drivers.
20467+#
20468+
20469+obj-$(CONFIG_HI_DMAC)	+= hi_pl08x.o
20470+
20471diff --git a/drivers/hidmac/hi_pl08x.c b/drivers/hidmac/hi_pl08x.c
20472new file mode 100644
20473index 000000000..4281caf7e
20474--- /dev/null
20475+++ b/drivers/hidmac/hi_pl08x.c
20476@@ -0,0 +1,1303 @@
20477+/*
20478+ *
20479+ * Copyright (c) 2017 HiSilicon Technologies Co., Ltd.
20480+ *
20481+ * This program is free software; you can redistribute it and/or modify
20482+ * it under the terms of the GNU General Public License as published by
20483+ * the Free Software Foundation; either version 2 of the License, or
20484+ * (at your option) any later version.
20485+ *
20486+ * This program is distributed in the hope that it will be useful,
20487+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
20488+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20489+ * GNU General Public License for more details.
20490+ *
20491+ * You should have received a copy of the GNU General Public License
20492+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
20493+ *
20494+ */
20495+
20496+#include <linux/gfp.h>
20497+#include <linux/kernel.h>
20498+#include <linux/module.h>
20499+#include <linux/i2c.h>
20500+#include <linux/init.h>
20501+#include <linux/time.h>
20502+#include <linux/interrupt.h>
20503+#include <linux/delay.h>
20504+#include <linux/errno.h>
20505+#include <linux/err.h>
20506+#include <linux/platform_device.h>
20507+#include <linux/dma-mapping.h>
20508+#include <linux/pm_runtime.h>
20509+#include <linux/slab.h>
20510+#include <linux/of.h>
20511+#include <linux/clk.h>
20512+#include <linux/reset.h>
20513+#include <asm/io.h>
20514+#include <linux/hidmac.h>
20515+
20516+#include "hi_pl08x.h"
20517+
20518+#ifdef CONFIG_ARCH_HI3536DV100
20519+#include "hidmac_hi3536dv100.h"
20520+#endif
20521+
20522+#ifdef CONFIG_ARCH_HI3518EV20X
20523+#include "hidmac_hi3518ev20x.h"
20524+#endif
20525+
20526+#ifdef CONFIG_ARCH_HI3516A
20527+#include "hidmac_hi3516a.h"
20528+#endif
20529+
20530+#ifdef CONFIG_ARCH_HI3521A
20531+#include "hidmac_hi3521a.h"
20532+#endif
20533+
20534+#ifdef CONFIG_ARCH_HI3531A
20535+#include "hidmac_hi3531a.h"
20536+#endif
20537+
20538+#define RX  0
20539+#define TX  1
20540+static int dmac_channel[CHANNEL_NUM] = {0, 1, 2, 3};
20541+int g_channel_status[CHANNEL_NUM];
20542+
20543+/* #define DEBUG */
20544+
20545+#define DEBUG
20546+#ifdef DEBUG
20547+#define dma_err printk
20548+#else
20549+#define dma_err(fmt, ...) do {} while (0)
20550+#endif
20551+
20552+/*
20553+ * Define Memory range
20554+ */
20555+mem_addr mem_num[MEM_MAX_NUM] = {
20556+	{DDRAM_ADRS, DDRAM_SIZE},
20557+	{FLASH_BASE, FLASH_SIZE}
20558+};
20559+
20560+typedef void REG_ISR(int *p_dma_chn, int *p_dma_status);
20561+REG_ISR *function[CHANNEL_NUM];
20562+
20563+struct hidmac_host {
20564+	struct clk *clk;
20565+	struct reset_control *rstc;
20566+	void __iomem *regbase;
20567+
20568+	int irq;
20569+};
20570+
20571+void __iomem *dma_regbase;
20572+unsigned int pllihead[2];
20573+
20574+#define CLR_INT(i)  ((*(unsigned int *)(dma_regbase+0x008)) = (1 << i))
20575+
20576+/*
20577+ * dmac interrupt handle function
20578+ */
20579+irqreturn_t dmac_isr(int irq, void *dev_id)
20580+{
20581+	struct hidmac_host *dma = dev_id;
20582+	unsigned int channel_status;
20583+	unsigned int channel_tc_status, channel_err_status;
20584+	unsigned int i;
20585+
20586+	/* read the status of current interrupt */
20587+	dmac_readw(dma->regbase + DMAC_INTSTATUS, channel_status);
20588+
20589+	/* decide which channel has trigger the interrupt */
20590+	for (i = 0; i < DMAC_MAX_CHANNELS; i++) {
20591+		if ((((channel_status >> i) & 0x1) == 0x01)) {
20592+			/* The INT status should be read first then clear it */
20593+			dmac_readw(dma->regbase + DMAC_INTTCSTATUS, channel_tc_status);
20594+			dmac_readw(dma->regbase + DMAC_INTERRORSTATUS, channel_err_status);
20595+			CLR_INT(i);
20596+			if (g_channel_status[i] == DMAC_CHN_VACANCY
20597+					&& (function[i]) == NULL) {
20598+				if ((0x01 == ((channel_tc_status >> i) & 0x01)))
20599+					dmac_writew(dma->regbase + DMAC_INTTCCLEAR,
20600+						    (0x01 << i));
20601+				else if ((0x01 == ((channel_err_status
20602+						    >> i) & 0x01)))
20603+					dmac_writew(dma->regbase + DMAC_INTERRCLR,
20604+						    (0x01 << i));
20605+				continue;
20606+			}
20607+
20608+			/* save the current channel transfer */
20609+			/* status to g_channel_status[i] */
20610+			if ((0x01 == ((channel_tc_status >> i) & 0x01))) {
20611+				g_channel_status[i] = DMAC_CHN_SUCCESS;
20612+				dmac_writew(dma->regbase + DMAC_INTTCCLEAR, (0x01 << i));
20613+			} else if ((0x01 == ((channel_err_status >> i) & 0x01))) {
20614+				g_channel_status[i] = -DMAC_CHN_ERROR;
20615+				dmac_writew(dma->regbase + DMAC_INTERRCLR, (0x01 << i));
20616+			} else {
20617+				pr_err("Isr Error in DMAC_IntHandeler");
20618+				pr_err("%d! channel\n", i);
20619+			}
20620+
20621+			if ((function[i]) != NULL) {
20622+				function[i](&i, &g_channel_status[i]);
20623+			}
20624+		}
20625+	}
20626+
20627+	return IRQ_RETVAL(1);
20628+}
20629+
20630+/*
20631+ *  update the state of channels
20632+ */
20633+#define HI_DMA_UPDATE_TIMEOUT  5000000
20634+static int dma_update_status(unsigned int channel)
20635+{
20636+	unsigned int channel_status;
20637+	unsigned int channel_tc_status[3];
20638+	unsigned int channel_err_status[3];
20639+	unsigned int i = channel;
20640+	unsigned int time = 0;
20641+	unsigned int j;
20642+
20643+	while (1) {
20644+		for (j = 0; j < 3; j++) {
20645+			dmac_readw(dma_regbase + DMAC_RAWINTTCSTATUS, channel_status);
20646+			channel_tc_status[j] = (channel_status >> i) & 0x01;
20647+			dmac_readw(dma_regbase + DMAC_RAWINTERRORSTATUS, channel_status);
20648+			channel_err_status[j] = (channel_status >> i) & 0x01;
20649+		}
20650+
20651+		if ((channel_tc_status[0] == 0x1) &&
20652+				(channel_tc_status[1] == 0x1) &&
20653+				(channel_tc_status[2] == 0x1)) {
20654+			g_channel_status[i] = DMAC_CHN_SUCCESS;
20655+			dmac_writew(dma_regbase + DMAC_INTTCCLEAR, (0x01 << i));
20656+			break;
20657+		} else if ((channel_err_status[0] == 0x1) &&
20658+				(channel_err_status[1] == 0x1) &&
20659+				(channel_err_status[2] == 0x1)) {
20660+			g_channel_status[i] = -DMAC_CHN_ERROR;
20661+			dma_err("Error in DMAC %d finish!\n", i);
20662+			dmac_writew(dma_regbase + DMAC_INTERRCLR, (0x01 << i));
20663+			break;
20664+		}
20665+
20666+		if (++time == HI_DMA_UPDATE_TIMEOUT) {
20667+			dma_err("Timeout in DMAC %d!\n", i);
20668+			g_channel_status[i] = -DMAC_CHN_TIMEOUT;
20669+			break;
20670+		}
20671+	}
20672+
20673+	return g_channel_status[i];
20674+}
20675+
20676+/*
20677+ *  check the state of channels
20678+ */
20679+static int dmac_check_over(unsigned int channel)
20680+{
20681+	int status = 0;
20682+
20683+	if (-DMAC_CHN_ERROR == g_channel_status[channel]) {
20684+		dma_err("Error transfer %d finished\n", channel);
20685+		dmac_writew(dma_regbase + DMAC_CxCONFIG(channel), DMAC_CxDISABLE);
20686+		g_channel_status[channel] = DMAC_CHN_VACANCY;
20687+		status = -DMAC_CHN_ERROR;
20688+	} else if (g_channel_status[channel] == DMAC_NOT_FINISHED) {
20689+		status = DMAC_NOT_FINISHED;
20690+	} else if (g_channel_status[channel] == DMAC_CHN_ALLOCAT) {
20691+		status = DMAC_CHN_ALLOCAT;
20692+	} else if (g_channel_status[channel] == DMAC_CHN_VACANCY) {
20693+		status = DMAC_CHN_VACANCY;
20694+	} else if (-DMAC_CHN_TIMEOUT == g_channel_status[channel]) {
20695+		dma_err("transfer %d timeout!\n", channel);
20696+		status = -DMAC_CHN_TIMEOUT;
20697+	} else if (g_channel_status[channel] == DMAC_CHN_SUCCESS) {
20698+		/* The transfer of Channel %d has finished successfully! */
20699+		status = DMAC_CHN_SUCCESS;
20700+	} else {
20701+		dmac_writew(dma_regbase + DMAC_CxCONFIG(channel), DMAC_CxDISABLE);
20702+		g_channel_status[channel] = DMAC_CHN_VACANCY;
20703+		status = -DMAC_CHN_ERROR;
20704+	}
20705+	return status;
20706+}
20707+
20708+spinlock_t my_lcok = __SPIN_LOCK_UNLOCKED(old_style_spin_init);
20709+unsigned long flags;
20710+
20711+/*
20712+ *  allocate channel.
20713+ */
20714+int dmac_channel_allocate(void *pisr)
20715+{
20716+	unsigned int i, channelinfo, g_channelinfo;
20717+
20718+	for (i = 0; i < CHANNEL_NUM; i++) {
20719+		dmac_check_over(dmac_channel[i]);
20720+	}
20721+
20722+	dmac_readw(dma_regbase + DMAC_ENBLDCHNS, g_channelinfo);
20723+	g_channelinfo = g_channelinfo & 0x00ff;
20724+
20725+	for (i = 0; i < CHANNEL_NUM; i++) {
20726+		if (g_channel_status[dmac_channel[i]] == DMAC_CHN_VACANCY) {
20727+			channelinfo = g_channelinfo >> dmac_channel[i];
20728+			if (0x00 == (channelinfo & 0x01)) {
20729+				/* clear the interrupt in this channel */
20730+				dmac_writew(dma_regbase + DMAC_INTERRCLR,
20731+					    (0x01 << dmac_channel[i]));
20732+				dmac_writew(dma_regbase + DMAC_INTTCCLEAR,
20733+					    (0x01 << dmac_channel[i]));
20734+
20735+				g_channel_status[dmac_channel[i]]
20736+					= DMAC_CHN_ALLOCAT;
20737+				return dmac_channel[i];
20738+			}
20739+		}
20740+	}
20741+
20742+	dma_err("no to alloc\n");
20743+	return -EINVAL;
20744+}
20745+EXPORT_SYMBOL(dmac_channel_allocate);
20746+
20747+int dmac_register_isr(unsigned int channel, void *pisr)
20748+{
20749+	if (channel > CHANNEL_NUM - 1) {
20750+		dma_err("channel which choosed %d is error !\n", channel);
20751+		return -1;
20752+	}
20753+
20754+	if (g_channel_status[channel] != DMAC_CHN_VACANCY) {
20755+		dma_err("dma chn %d is in used!\n", channel);
20756+		return -1;
20757+	}
20758+
20759+	/* clear the interrupt in this channel */
20760+	dmac_writew(dma_regbase + DMAC_INTERRCLR, (0x01 << channel));
20761+	dmac_writew(dma_regbase + DMAC_INTTCCLEAR, (0x01 << channel));
20762+
20763+	function[channel] = (void *)pisr;
20764+	g_channel_status[channel] = DMAC_CHN_ALLOCAT;
20765+
20766+	return 0;
20767+}
20768+EXPORT_SYMBOL(dmac_register_isr);
20769+
20770+/*
20771+ *  free channel
20772+ */
20773+int dmac_channel_free(unsigned int channel)
20774+{
20775+	if (channel >= DMAC_MAX_CHANNELS) {
20776+		dma_err("channel larger than total.\n");
20777+		return -EINVAL;
20778+	}
20779+
20780+	g_channel_status[channel] = DMAC_CHN_VACANCY;
20781+	return 0;
20782+}
20783+EXPORT_SYMBOL(dmac_channel_free);
20784+
20785+static unsigned int dmac_check_request(unsigned int peripheral_addr,
20786+				       int direction)
20787+{
20788+	int i;
20789+	/* check request pipe with peripheral_addr */
20790+	for (i = direction; i < DMAC_MAX_PERIPHERALS; i = i + 2) {
20791+		if (g_peripheral[i].peri_addr == peripheral_addr) {
20792+			return i;
20793+		}
20794+	}
20795+
20796+	dma_err("Invalid devaddr\n");
20797+
20798+	return -1;
20799+}
20800+
20801+/*
20802+ *  init dmac register
20803+ *  clear interrupt flags
20804+ *  called by dma_driver_init
20805+ */
20806+int dmac_init(struct hidmac_host *dma)
20807+{
20808+	unsigned int i, tempvalue;
20809+	int ret;
20810+
20811+	clk_prepare_enable(dma->clk);
20812+	reset_control_deassert(dma->rstc);
20813+
20814+	dmac_readw(dma->regbase + DMAC_CONFIG, tempvalue);
20815+	if (tempvalue == 0) {
20816+		dmac_writew(dma->regbase + DMAC_CONFIG,
20817+			    DMAC_CONFIG_VAL);
20818+		dmac_writew(dma->regbase + DMAC_INTTCCLEAR, 0xFF);
20819+		dmac_writew(dma->regbase + DMAC_INTERRCLR, 0xFF);
20820+		for (i = 0; i < DMAC_MAX_CHANNELS; i++) {
20821+			dmac_writew(dma->regbase + DMAC_CxCONFIG(i),
20822+				    DMAC_CxDISABLE);
20823+			function[i] = NULL;
20824+		}
20825+	}
20826+
20827+	/* creat LLI */
20828+	/* alloc space for dma lli, as the source is uncontinuous, so... */
20829+	ret = allocate_dmalli_space(pllihead, 1);
20830+	if (ret < 0) {
20831+		return -1;
20832+	}
20833+
20834+	if (request_irq(dma->irq, dmac_isr, 0, "hi_dma", dma)) {
20835+		dma_err("DMA Irq %d request failed\n", dma->irq);
20836+		free_dmalli_space(pllihead, 1);
20837+		return -1;
20838+	}
20839+
20840+	return 0;
20841+}
20842+
20843+/*
20844+ *  alloc_dma_lli_space
20845+ *  output:
20846+ *             ppheadlli[0]: memory physics address
20847+ *             ppheadlli[1]: virtual address
20848+ *
20849+ */
20850+int allocate_dmalli_space(unsigned int *ppheadlli, unsigned int page_num)
20851+{
20852+	dma_addr_t dma_phys;
20853+	void *dma_virt;
20854+
20855+	dma_virt = dma_alloc_coherent(NULL, page_num * PAGE_SIZE,
20856+				      &dma_phys, GFP_DMA | GFP_KERNEL);
20857+	if (dma_virt == NULL) {
20858+		dma_err("can't get dma mem from system\n");
20859+		return -1;
20860+	}
20861+
20862+	ppheadlli[0] = (unsigned int)(dma_phys);
20863+	ppheadlli[1] = (unsigned int)(dma_virt);
20864+
20865+	return 0;
20866+}
20867+EXPORT_SYMBOL(allocate_dmalli_space);
20868+
20869+/*
20870+ *  free_dma_lli_space
20871+ */
20872+int free_dmalli_space(unsigned int *ppheadlli, unsigned int page_num)
20873+{
20874+	dma_addr_t dma_phys;
20875+	unsigned int dma_virt;
20876+
20877+	dma_phys = (dma_addr_t)(ppheadlli[0]);
20878+	dma_virt = ppheadlli[1];
20879+
20880+	dma_free_coherent(NULL, page_num * PAGE_SIZE,
20881+			  (void *)dma_virt, dma_phys);
20882+
20883+	ppheadlli[0] = 0;
20884+	ppheadlli[1] = 0;
20885+	return 0;
20886+}
20887+EXPORT_SYMBOL(free_dmalli_space);
20888+
20889+/*
20890+ * config register for memory to memory DMA transfer without LLI
20891+ * note:
20892+ * it is necessary to call dmac_channelstart for channel enable
20893+ */
20894+int dmac_start_m2m(unsigned int  channel, unsigned int psource,
20895+		   unsigned int pdest, unsigned int uwnumtransfers)
20896+{
20897+	unsigned int uwchannel_num, tmp_trasnsfer;
20898+
20899+	if (uwnumtransfers > (MAXTRANSFERSIZE << 2)) {
20900+		dma_err("Invalidate transfer size,size=%x\n", uwnumtransfers);
20901+		return -EINVAL;
20902+	}
20903+
20904+	uwchannel_num = channel;
20905+
20906+	if ((uwchannel_num == DMAC_CHANNEL_INVALID) ||
20907+			(uwchannel_num > CHANNEL_NUM)) {
20908+		pr_err("failure of DMAC channel allocation in M2M function!\n");
20909+		return -EFAULT;
20910+	}
20911+
20912+	dmac_writew(dma_regbase + DMAC_CxSRCADDR(uwchannel_num), psource);
20913+	dmac_writew(dma_regbase + DMAC_CxDESTADDR(uwchannel_num), pdest);
20914+	dmac_writew(dma_regbase + DMAC_CxLLI(uwchannel_num), 0);
20915+	tmp_trasnsfer = (uwnumtransfers >> 2) & 0xfff;
20916+	tmp_trasnsfer = tmp_trasnsfer | (DMAC_CxCONTROL_M2M & (~0xfff));
20917+	dmac_writew(dma_regbase + DMAC_CxCONTROL(uwchannel_num), tmp_trasnsfer);
20918+	dmac_writew(dma_regbase + DMAC_CxCONFIG(uwchannel_num), DMAC_CxCONFIG_M2M);
20919+
20920+	return 0;
20921+}
20922+EXPORT_SYMBOL(dmac_start_m2m);
20923+
20924+/*
20925+ *  channel enable
20926+ *  start a dma transfer immediately
20927+ */
20928+int dmac_channelstart(unsigned int u32channel)
20929+{
20930+	unsigned int reg_value;
20931+
20932+	if (u32channel >= DMAC_MAX_CHANNELS) {
20933+		dma_err("channel larger %d\n", DMAC_MAX_CHANNELS);
20934+		return -EINVAL;
20935+	}
20936+
20937+	g_channel_status[u32channel] = DMAC_NOT_FINISHED;
20938+	dmac_readw(dma_regbase + DMAC_CxCONFIG(u32channel), reg_value);
20939+	dmac_writew(dma_regbase + DMAC_CxCONFIG(u32channel),
20940+		    (reg_value | DMAC_CHANNEL_ENABLE));
20941+
20942+	return 0;
20943+}
20944+EXPORT_SYMBOL(dmac_channelstart);
20945+
20946+/*
20947+ *  wait for transfer end
20948+ */
20949+int dmac_wait(int channel)
20950+{
20951+	int ret_result;
20952+	int ret = 0;
20953+
20954+	if (channel < 0) {
20955+		return -1;
20956+	}
20957+
20958+	while (1) {
20959+		ret_result = dma_update_status(channel);
20960+		if (ret_result == -DMAC_CHN_ERROR) {
20961+			dma_err("Transfer Error.\n");
20962+			ret = -1;
20963+			goto end;
20964+		} else  if (ret_result == DMAC_NOT_FINISHED) {
20965+			udelay(10);
20966+		} else if (ret_result == DMAC_CHN_SUCCESS) {
20967+			ret = DMAC_CHN_SUCCESS;
20968+			goto end;
20969+		} else if (ret_result == DMAC_CHN_VACANCY) {
20970+			ret = DMAC_CHN_SUCCESS;
20971+			goto end;
20972+		} else if (ret_result == -DMAC_CHN_TIMEOUT) {
20973+			dma_err("Timeout.\n");
20974+			dmac_writew(dma_regbase + DMAC_CxCONFIG(channel), DMAC_CxDISABLE);
20975+			g_channel_status[channel] = DMAC_CHN_VACANCY;
20976+			ret = -1;
20977+			goto end;
20978+		}
20979+	}
20980+end:
20981+	dmac_channelclose(channel);
20982+	return ret;
20983+}
20984+EXPORT_SYMBOL(dmac_wait);
20985+
20986+/*
20987+ *  buile LLI for memory to memory DMA transfer
20988+ */
20989+int dmac_buildllim2m_isp(unsigned int *ppheadlli, unsigned int *psource,
20990+			 unsigned int *pdest, unsigned int *length,
20991+			 unsigned int lli_num)
20992+{
20993+	unsigned int address, phy_address;
20994+	unsigned int j;
20995+
20996+	if (ppheadlli != NULL) {
20997+		phy_address = (unsigned int)(ppheadlli[0]);
20998+		dma_debug("phy_address: 0x%X\n", phy_address);
20999+		address = (unsigned int)(ppheadlli[1]);
21000+		dma_debug("address: 0x%X\n", address);
21001+		for (j = 0; j < lli_num; j++) {
21002+			dma_debug("psource[%d]: 0x%X\n", j, psource[j]);
21003+			dmac_writew(address, psource[j]);
21004+			address += 4;
21005+			phy_address += 4;
21006+			dma_debug("pdest[%d]: 0x%X\n", j, pdest[j]);
21007+			dmac_writew(address, pdest[j]);
21008+			address += 4;
21009+			phy_address += 4;
21010+
21011+			/* if the last node, next_lli_addr = 0 */
21012+			if (j == (lli_num - 1)) {
21013+				dmac_writew(address, 0);
21014+			} else
21015+				dmac_writew(address,
21016+					    (((phy_address + 8) & (~0x03)) |
21017+					    DMAC_CxLLI_LM));
21018+
21019+			address += 4;
21020+			phy_address += 4;
21021+
21022+			if (j == (lli_num - 1)) {
21023+				dmac_writew(address,
21024+					    ((DMAC_CxCONTROL_LLIM2M_ISP &
21025+					      (~0xfff)) | (length[j]) |
21026+					      0x80000000));
21027+			} else {
21028+				dmac_writew(address,
21029+					    (((DMAC_CxCONTROL_LLIM2M_ISP & (~0xfff)) |
21030+					      (length[j])) & 0x7fffffff));
21031+			}
21032+
21033+			address += 4;
21034+			phy_address += 4;
21035+		}
21036+	}
21037+
21038+	return 0;
21039+}
21040+EXPORT_SYMBOL(dmac_buildllim2m_isp);
21041+
21042+/*
21043+ *  buile LLI for memory to memory DMA transfer
21044+ */
21045+int dmac_buildllim2m(unsigned int *ppheadlli, unsigned int pdest,
21046+		     unsigned int psource, unsigned int totaltransfersize,
21047+		     unsigned int uwnumtransfers)
21048+{
21049+	unsigned int lli_num = 0;
21050+	unsigned int last_lli = 0;
21051+	unsigned int address, phy_address, srcaddr, denstaddr;
21052+	unsigned int j;
21053+
21054+	lli_num = (totaltransfersize / uwnumtransfers);
21055+
21056+	if ((totaltransfersize % uwnumtransfers) != 0) {
21057+		last_lli = 1, ++lli_num;
21058+	}
21059+
21060+	if (ppheadlli != NULL) {
21061+		phy_address = (unsigned int)(ppheadlli[0]);
21062+		address = (unsigned int)(ppheadlli[1]);
21063+		for (j = 0; j < lli_num; j++) {
21064+			srcaddr = (psource + (j * uwnumtransfers));
21065+			dmac_writew(address, srcaddr);
21066+			address += 4;
21067+			phy_address += 4;
21068+			denstaddr = (pdest + (j * uwnumtransfers));
21069+			dmac_writew(address, denstaddr);
21070+			address += 4;
21071+			phy_address += 4;
21072+			if (j == (lli_num - 1)) {
21073+				dmac_writew(address, 0);
21074+			} else
21075+				dmac_writew(address,
21076+					    (((phy_address + 8) & (~0x03)) |
21077+					     DMAC_CxLLI_LM));
21078+
21079+			address += 4;
21080+			phy_address += 4;
21081+
21082+			if ((j == (lli_num - 1)) && (last_lli == 0))
21083+				dmac_writew(address, ((DMAC_CxCONTROL_LLIM2M &
21084+						      (~0xfff)) |
21085+						      (uwnumtransfers >> 2) |
21086+						      0x80000000));
21087+			else if ((j == (lli_num - 1)) && (last_lli == 1))
21088+				dmac_writew(address,
21089+					    ((DMAC_CxCONTROL_LLIM2M &
21090+					     (~0xfff)) |
21091+					     ((totaltransfersize %
21092+					       uwnumtransfers) >> 2) |
21093+					     0x80000000));
21094+			else
21095+				dmac_writew(address,
21096+					    (((DMAC_CxCONTROL_LLIM2M & (~0xfff)) |
21097+					      (uwnumtransfers >> 2)) & 0x7fffffff));
21098+
21099+			address += 4;
21100+			phy_address += 4;
21101+		}
21102+	}
21103+
21104+	return 0;
21105+}
21106+EXPORT_SYMBOL(dmac_buildllim2m);
21107+
21108+/*
21109+ *  disable channel
21110+ *  used before the operation of register configuration
21111+ */
21112+int dmac_channelclose(unsigned int channel)
21113+{
21114+	unsigned int reg_value, count;
21115+
21116+	if (channel >= DMAC_MAX_CHANNELS) {
21117+		dma_err("channel larger than total.\n");
21118+		return -EINVAL;
21119+	}
21120+
21121+	dmac_readw(dma_regbase + DMAC_CxCONFIG(channel), reg_value);
21122+
21123+#define CHANNEL_CLOSE_IMMEDIATE
21124+#ifdef CHANNEL_CLOSE_IMMEDIATE
21125+	reg_value &= 0xFFFFFFFE;
21126+	dmac_writew(dma_regbase + DMAC_CxCONFIG(channel), reg_value);
21127+#else
21128+	reg_value |= DMAC_CONFIGURATIONx_HALT_DMA_ENABLE;
21129+	/* ignore incoming dma request */
21130+	dmac_writew(dma_regbase + DMAC_CxCONFIG(channel), reg_value);
21131+	dmac_readw(dma_regbase + DMAC_CxCONFIG(channel), reg_value);
21132+	/* if FIFO is empty */
21133+	while ((reg_value & DMAC_CONFIGURATIONx_ACTIVE)
21134+			== DMAC_CONFIGURATIONx_ACTIVE) {
21135+		dmac_readw(dma_regbase + DMAC_CxCONFIG(channel), reg_value);
21136+	}
21137+	reg_value &= 0xFFFFFFFE;
21138+	dmac_writew(dma_regbase + DMAC_CxCONFIG(channel), reg_value);
21139+#endif
21140+
21141+	dmac_readw(dma_regbase + DMAC_ENBLDCHNS, reg_value);
21142+	reg_value = reg_value & 0x00ff;
21143+	count = 0;
21144+	while (((reg_value >> channel) & 0x1) == 1) {
21145+		dmac_readw(dma_regbase + DMAC_ENBLDCHNS, reg_value);
21146+		reg_value = reg_value & 0x00ff;
21147+		if (count++ > 10000) {
21148+			dma_err("close failure.\n");
21149+			return -1;
21150+		}
21151+	}
21152+
21153+	return 0;
21154+}
21155+EXPORT_SYMBOL(dmac_channelclose);
21156+
21157+/*
21158+ *  load configuration from LLI for memory to memory
21159+ */
21160+int dmac_start_llim2m(unsigned int channel, unsigned int *pfirst_lli)
21161+{
21162+	unsigned int uwchannel_num;
21163+	dmac_lli  plli;
21164+	unsigned int first_lli;
21165+
21166+	if (pfirst_lli == NULL) {
21167+		dma_err("Invalidate LLI head!\n");
21168+		return -EFAULT;
21169+	}
21170+
21171+	uwchannel_num = channel;
21172+	if ((uwchannel_num == DMAC_CHANNEL_INVALID) ||
21173+			(uwchannel_num > 7)) {
21174+		dma_err("failure of DMAC channel allocation in");
21175+		dma_err("LLIM2M function,channel=%x!\n ", uwchannel_num);
21176+		return -EINVAL;
21177+	}
21178+
21179+	memset(&plli, 0, sizeof(plli));
21180+	first_lli = (unsigned int)pfirst_lli[1];
21181+	dmac_readw(first_lli, plli.src_addr);
21182+	dmac_readw(first_lli + 4, plli.dst_addr);
21183+	dmac_readw(first_lli + 8, plli.next_lli);
21184+	dmac_readw(first_lli + 12, plli.lli_transfer_ctrl);
21185+
21186+	dmac_channelclose(uwchannel_num);
21187+	dmac_writew(dma_regbase + DMAC_INTTCCLEAR, (0x1 << uwchannel_num));
21188+	dmac_writew(dma_regbase + DMAC_INTERRCLR, (0x1 << uwchannel_num));
21189+	dmac_writew(dma_regbase + DMAC_SYNC, 0x0);
21190+
21191+	dmac_writew(dma_regbase + DMAC_CxCONFIG(uwchannel_num),
21192+		    DMAC_CxDISABLE);
21193+	dmac_writew(dma_regbase + DMAC_CxSRCADDR(uwchannel_num),
21194+		    (unsigned int)(plli.src_addr));
21195+	dmac_writew(dma_regbase + DMAC_CxDESTADDR(uwchannel_num),
21196+		    (unsigned int)(plli.dst_addr));
21197+	dmac_writew(dma_regbase + DMAC_CxLLI(uwchannel_num),
21198+		    (unsigned int)(plli.next_lli));
21199+	dmac_writew(dma_regbase + DMAC_CxCONTROL(uwchannel_num),
21200+		    (unsigned int)(plli.lli_transfer_ctrl));
21201+	dmac_writew(dma_regbase + DMAC_CxCONFIG(uwchannel_num),
21202+		    DMAC_CxCONFIG_LLIM2M);
21203+
21204+	return 0;
21205+}
21206+EXPORT_SYMBOL(dmac_start_llim2m);
21207+
21208+/*
21209+ *  load configuration from LLI for memory and peripheral
21210+ */
21211+int dmac_start_llim2p(unsigned int channel, unsigned int *pfirst_lli,
21212+		      unsigned int uwperipheralid)
21213+{
21214+	unsigned int uwchannel_num;
21215+	dmac_lli plli;
21216+	unsigned int first_lli;
21217+	unsigned int temp = 0;
21218+
21219+	if (pfirst_lli == NULL) {
21220+		dma_err("Invalidate LLI head!\n");
21221+		return -EINVAL;
21222+	}
21223+	uwchannel_num = channel;
21224+	if ((uwchannel_num == DMAC_CHANNEL_INVALID) ||
21225+	    (uwchannel_num > CHANNEL_NUM)) {
21226+		dma_err("failure of DMAC channel allocation in");
21227+		dma_err("LLIM2P function, channel=%x!\n ", uwchannel_num);
21228+		return -EINVAL;
21229+	}
21230+
21231+	memset(&plli, 0, sizeof(plli));
21232+	first_lli = (unsigned int)pfirst_lli[1];
21233+	dmac_readw(first_lli, plli.src_addr);
21234+	dmac_readw(first_lli + 4, plli.dst_addr);
21235+	dmac_readw(first_lli + 8, plli.next_lli);
21236+	dmac_readw(first_lli + 12, plli.lli_transfer_ctrl);
21237+
21238+	dmac_channelclose(uwchannel_num);
21239+	dmac_writew(dma_regbase + DMAC_INTTCCLEAR, (0x1 << uwchannel_num));
21240+	dmac_writew(dma_regbase + DMAC_INTERRCLR, (0x1 << uwchannel_num));
21241+	dmac_writew(dma_regbase + DMAC_SYNC, 0x0);
21242+
21243+	dmac_readw(dma_regbase + DMAC_CxCONFIG(uwchannel_num), temp);
21244+	dmac_writew(dma_regbase + DMAC_CxCONFIG(uwchannel_num),
21245+		    temp | DMAC_CxDISABLE);
21246+	dmac_writew(dma_regbase + DMAC_CxSRCADDR(uwchannel_num),
21247+		    plli.src_addr);
21248+	dmac_writew(dma_regbase + DMAC_CxDESTADDR(uwchannel_num),
21249+		    plli.dst_addr);
21250+	dmac_writew(dma_regbase + DMAC_CxLLI(uwchannel_num),
21251+		    plli.next_lli);
21252+	dmac_writew(dma_regbase + DMAC_CxCONTROL(uwchannel_num),
21253+		    plli.lli_transfer_ctrl);
21254+
21255+	return 0;
21256+}
21257+EXPORT_SYMBOL(dmac_start_llim2p);
21258+
21259+/*
21260+ *  enable memory and peripheral dma transfer
21261+ *  note:
21262+ *  it is necessary to call dmac_channelstart to enable channel
21263+ */
21264+int dmac_start_m2p(unsigned int channel, unsigned int memaddr,
21265+		   unsigned int uwperipheralid, unsigned int uwnumtransfers,
21266+		   unsigned int next_lli_addr)
21267+{
21268+	unsigned int uwtrans_control = 0;
21269+	unsigned int addtmp, tmp;
21270+	unsigned int uwdst_addr = 0;
21271+	unsigned int uwsrc_addr = 0;
21272+	unsigned int uwwidth;
21273+	int uwchannel_num;
21274+
21275+	addtmp = memaddr;
21276+
21277+	if ((uwperipheralid > 15)) {
21278+		dma_err("Invalid peripheral id%x\n", uwperipheralid);
21279+		return -EINVAL;
21280+	}
21281+
21282+	uwchannel_num = (int)channel;
21283+	if ((uwchannel_num == DMAC_CHANNEL_INVALID) ||
21284+	    (uwchannel_num > CHANNEL_NUM) || (uwchannel_num < 0)) {
21285+		dma_err("failure alloc\n");
21286+		return -EFAULT;
21287+	}
21288+
21289+	/* must modified with different peripheral */
21290+	uwwidth = g_peripheral[uwperipheralid].transfer_width;
21291+
21292+	/* check transfer direction *
21293+	 * even number-->TX, odd number-->RX */
21294+	uwsrc_addr = memaddr;
21295+	uwdst_addr = (unsigned int)(g_peripheral[uwperipheralid].peri_addr);
21296+
21297+	tmp = uwnumtransfers >> uwwidth;
21298+	if (tmp & (~0x0fff)) {
21299+		dma_err("Invalidate size%x\n", uwnumtransfers);
21300+		return -EINVAL;
21301+	}
21302+
21303+	tmp = tmp & 0xfff;
21304+	uwtrans_control = tmp |
21305+			  (g_peripheral[uwperipheralid].transfer_ctrl & (~0xfff));
21306+	dmac_writew(dma_regbase + DMAC_INTTCCLEAR,
21307+		    (0x1 << (unsigned int)uwchannel_num));
21308+	dmac_writew(dma_regbase + DMAC_INTERRCLR, (0x1 << (unsigned int)uwchannel_num));
21309+	dmac_writew(dma_regbase + DMAC_CxSRCADDR(uwchannel_num),
21310+		    (unsigned int)uwsrc_addr);
21311+	dmac_writew(dma_regbase + DMAC_CxDESTADDR(uwchannel_num),
21312+		    (unsigned int)uwdst_addr);
21313+	dmac_writew(dma_regbase + DMAC_CxCONTROL(uwchannel_num),
21314+		    (unsigned int)uwtrans_control);
21315+	dmac_writew(dma_regbase + DMAC_CxCONFIG(uwchannel_num),
21316+		    (g_peripheral[uwperipheralid].transfer_cfg));
21317+
21318+	return 0;
21319+}
21320+
21321+/*
21322+ *  enable memory and peripheral dma transfer
21323+ *  note:
21324+ *  it is necessary to call dmac_channelstart to enable channel
21325+ */
21326+int dmac_start_p2m(unsigned int channel, unsigned int memaddr,
21327+		   unsigned int uwperipheralid, unsigned int uwnumtransfers,
21328+		   unsigned int next_lli_addr)
21329+{
21330+	unsigned int uwtrans_control = 0;
21331+	unsigned int addtmp, tmp;
21332+	unsigned int uwdst_addr = 0;
21333+	unsigned int uwsrc_addr = 0;
21334+	unsigned int uwwidth;
21335+	int uwchannel_num;
21336+
21337+	addtmp = memaddr;
21338+
21339+	if ((uwperipheralid > 15)) {
21340+		dma_err("Invalid peripheral id%x\n", uwperipheralid);
21341+		return -EINVAL;
21342+	}
21343+
21344+	uwchannel_num = (int)channel;
21345+	if ((uwchannel_num == DMAC_CHANNEL_INVALID) ||
21346+			(uwchannel_num > 3) || (uwchannel_num < 0)) {
21347+		dma_err("failure alloc\n");
21348+		return -EFAULT;
21349+	}
21350+
21351+	/* must modified with different peripheral */
21352+	uwwidth = g_peripheral[uwperipheralid].transfer_width;
21353+
21354+	/* check transfer direction *
21355+	 * even number-->TX, odd number-->RX */
21356+	uwsrc_addr = (unsigned int)(g_peripheral[uwperipheralid].peri_addr);
21357+	uwdst_addr = memaddr;
21358+
21359+	tmp = uwnumtransfers >> uwwidth;
21360+	if (tmp & (~0x0fff)) {
21361+		dma_err("Invalidate size%x\n", uwnumtransfers);
21362+		return -EINVAL;
21363+	}
21364+
21365+	tmp = tmp & 0xfff;
21366+	uwtrans_control = tmp |
21367+			  (g_peripheral[uwperipheralid].transfer_ctrl & (~0xfff));
21368+	dmac_writew(dma_regbase + DMAC_INTTCCLEAR,
21369+		    (0x1 << (unsigned int)uwchannel_num));
21370+	dmac_writew(dma_regbase + DMAC_INTERRCLR, (0x1 << (unsigned int)uwchannel_num));
21371+	dmac_writew(dma_regbase + DMAC_CxSRCADDR(uwchannel_num),
21372+		    (unsigned int)uwsrc_addr);
21373+	dmac_writew(dma_regbase + DMAC_CxDESTADDR(uwchannel_num),
21374+		    (unsigned int)uwdst_addr);
21375+	dmac_writew(dma_regbase + DMAC_CxCONTROL(uwchannel_num),
21376+		    (unsigned int)uwtrans_control);
21377+	dmac_writew(dma_regbase + DMAC_CxCONFIG(uwchannel_num),
21378+		    (g_peripheral[uwperipheralid].transfer_cfg));
21379+
21380+	return 0;
21381+}
21382+
21383+/*
21384+ *  execute memory to memory dma transfer without LLI
21385+ */
21386+int dmac_m2m_transfer(unsigned int source, unsigned int dest,
21387+		      unsigned int length)
21388+{
21389+	unsigned int ulchnn;
21390+	unsigned int dma_size = 0;
21391+	unsigned int dma_count, left_size;
21392+
21393+	left_size = length;
21394+	dma_count = 0;
21395+	ulchnn = dmac_channel_allocate(NULL);
21396+
21397+	ulchnn = 2;
21398+
21399+	dma_err("use channel %d\n", ulchnn);
21400+
21401+	while ((left_size >> 2) >= 0xffc) {
21402+		dma_size   = 0xffc;
21403+		left_size -= (dma_size << 2);
21404+		dma_err("left_size is %x.", left_size);
21405+		dmac_start_m2m(ulchnn,
21406+			       (unsigned int)(source +
21407+					      dma_count *
21408+					      (dma_size << 2)),
21409+			       (unsigned int)(dest +
21410+					      dma_count *
21411+					      (dma_size << 2)),
21412+			       (dma_size << 2));
21413+		if (dmac_channelstart(ulchnn) != 0) {
21414+			dma_err("start channel error...\n");
21415+			return -1;
21416+		}
21417+
21418+		if (dmac_wait(ulchnn) != DMAC_CHN_SUCCESS) {
21419+			dma_err("dma transfer error...\n");
21420+			return -1;
21421+		}
21422+
21423+		dma_count++;
21424+	}
21425+
21426+	dmac_start_m2m(ulchnn, (source + dma_count * (dma_size << 2)),
21427+		       (dest + dma_count * (dma_size << 2)), (left_size << 2));
21428+
21429+	if (dmac_channelstart(ulchnn) != 0) {
21430+		return -1;
21431+	}
21432+
21433+	if (dmac_wait(ulchnn) != DMAC_CHN_SUCCESS) {
21434+		return -1;
21435+	}
21436+
21437+	return 0;
21438+}
21439+EXPORT_SYMBOL(dmac_m2m_transfer);
21440+
21441+/*
21442+ *  execute memory to peripheral dma transfer without LLI
21443+ */
21444+int dmac_m2p_transfer(unsigned int memaddr, unsigned int uwperipheralid,
21445+		      unsigned int length)
21446+{
21447+	unsigned int dma_size = 0;
21448+	unsigned int dma_count, left_size, ulchnn, uwwidth;
21449+
21450+	left_size = length;
21451+	dma_count = 0;
21452+
21453+	ulchnn = dmac_channel_allocate(NULL);
21454+	if (ulchnn == DMAC_CHANNEL_INVALID) {
21455+		return -1;
21456+	}
21457+
21458+	uwwidth = g_peripheral[uwperipheralid].transfer_width;
21459+
21460+	while ((left_size >> uwwidth) >= 0xffc) {
21461+		dma_size = 0xffc;
21462+		left_size -= (dma_size << uwwidth);
21463+
21464+		if (dmac_start_m2p(ulchnn,
21465+				   (unsigned int)(memaddr + dma_count * dma_size),
21466+				   uwperipheralid, (dma_size << uwwidth), 0) < 0) {
21467+			return -1;
21468+		}
21469+
21470+		if (dmac_channelstart(ulchnn) != 0) {
21471+			return -1;
21472+		}
21473+
21474+		if (dmac_wait(ulchnn) != DMAC_CHN_SUCCESS) {
21475+			dmac_channel_free(ulchnn);
21476+			return -1;
21477+		}
21478+
21479+		dma_count++;
21480+	}
21481+
21482+	pr_debug("memaddr=0x%x\n", (unsigned int)(memaddr +
21483+			dma_count * dma_size));
21484+
21485+	if (dmac_start_m2p(ulchnn,
21486+			   (unsigned int)(memaddr + dma_count * dma_size),
21487+			   uwperipheralid, left_size, 0) < 0) {
21488+		return -1;
21489+	}
21490+
21491+	if (dmac_channelstart(ulchnn) != 0) {
21492+		return -1;
21493+	}
21494+
21495+	return ulchnn;
21496+}
21497+
21498+/*
21499+ *  execute memory to peripheral dma transfer without LLI
21500+ */
21501+int dmac_p2m_transfer(unsigned int memaddr, unsigned int uwperipheralid,
21502+		      unsigned int length)
21503+{
21504+	unsigned int dma_size = 0;
21505+	unsigned int ulchnn, dma_count, left_size;
21506+	unsigned int uwwidth;
21507+
21508+	left_size = length;
21509+	dma_count = 0;
21510+
21511+	ulchnn = dmac_channel_allocate(NULL);
21512+	if (ulchnn == DMAC_CHANNEL_INVALID) {
21513+		return -1;
21514+	}
21515+
21516+	uwwidth = g_peripheral[uwperipheralid].transfer_width;
21517+
21518+	while ((left_size >> uwwidth) >= 0xffc) {
21519+		dma_size = 0xffc;
21520+		left_size -= (dma_size << uwwidth);
21521+
21522+		if (dmac_start_p2m(ulchnn,
21523+				   (unsigned int)(memaddr + dma_count * dma_size),
21524+				   uwperipheralid, (dma_size << uwwidth), 0) < 0) {
21525+			return -1;
21526+		}
21527+
21528+		if (dmac_channelstart(ulchnn) != 0) {
21529+			return -1;
21530+		}
21531+
21532+		if (dmac_wait(ulchnn) != DMAC_CHN_SUCCESS) {
21533+			dmac_channel_free(ulchnn);
21534+			return -1;
21535+		}
21536+
21537+		dma_count++;
21538+	}
21539+
21540+	pr_debug("memaddr=0x%x\n", (unsigned int)(memaddr +
21541+						  dma_count * dma_size));
21542+
21543+	if (dmac_start_p2m(ulchnn,
21544+			   (unsigned int)(memaddr + dma_count * dma_size),
21545+			   uwperipheralid, left_size, 0) < 0) {
21546+		return -1;
21547+	}
21548+
21549+	if (dmac_channelstart(ulchnn) != 0) {
21550+		return -1;
21551+	}
21552+
21553+	return ulchnn;
21554+}
21555+
21556+/*
21557+ * memory to memory dma transfer with LLI
21558+ *
21559+ * @source
21560+ * @dest
21561+ * @length
21562+ * @num
21563+ * */
21564+int do_dma_llim2m_isp(unsigned int *source,
21565+		      unsigned int *dest,
21566+		      unsigned int *length,
21567+		      unsigned int num)
21568+{
21569+	unsigned int chnn;
21570+	int ret;
21571+
21572+	/* the dma channel is default using 2 */
21573+	chnn = 2;
21574+
21575+	ret = dmac_buildllim2m_isp(pllihead, source, dest, length, num);
21576+	if (ret) {
21577+		dma_err("build lli error...\n");
21578+		return -1;
21579+	}
21580+
21581+	ret = dmac_start_llim2m(chnn, pllihead);
21582+	if (ret) {
21583+		return -1;
21584+	}
21585+
21586+	if (dmac_channelstart(chnn) != 0) {
21587+		dma_err("start channel error...\n");
21588+		return -1;
21589+	}
21590+
21591+	return ret;
21592+}
21593+EXPORT_SYMBOL(do_dma_llim2m_isp);
21594+
21595+int do_dma_m2p(unsigned int memaddr, unsigned int peripheral_addr,
21596+	       unsigned int length)
21597+{
21598+	int ret = 0;
21599+	int uwperipheralid;
21600+
21601+	uwperipheralid = dmac_check_request(peripheral_addr, TX);
21602+	if (uwperipheralid < 0) {
21603+		dma_err("m2p:Invalid devaddr\n");
21604+		return -1;
21605+	}
21606+
21607+	ret = dmac_m2p_transfer(memaddr, uwperipheralid, length);
21608+	if (ret == -1) {
21609+		dma_err("m2p:trans err\n");
21610+		return -1;
21611+	}
21612+
21613+	return ret;
21614+}
21615+
21616+int do_dma_p2m(unsigned int memaddr, unsigned int peripheral_addr,
21617+	       unsigned int length)
21618+{
21619+	int ret = -1;
21620+	int uwperipheralid;
21621+
21622+	uwperipheralid = dmac_check_request(peripheral_addr, RX);
21623+	if (uwperipheralid < 0) {
21624+		dma_err("p2m:Invalid devaddr.\n");
21625+		return -1;
21626+	}
21627+
21628+	ret = dmac_p2m_transfer(memaddr, uwperipheralid, length);
21629+	if (ret == -1) {
21630+		dma_err("p2m:trans err\n");
21631+		return -1;
21632+	}
21633+
21634+	return ret;
21635+}
21636+
21637+/*
21638+ *  Apply DMA interrupt resource
21639+ *  init channel state
21640+ */
21641+static int hi_dmac_probe(struct platform_device *platdev)
21642+{
21643+	unsigned int i;
21644+	struct hidmac_host *dma;
21645+	struct resource *res;
21646+	int ret;
21647+
21648+	dma = devm_kzalloc(&platdev->dev, sizeof(*dma), GFP_KERNEL);
21649+	if (!dma) {
21650+		return -ENOMEM;
21651+	}
21652+
21653+	res = platform_get_resource(platdev, IORESOURCE_MEM, 0);
21654+	if (!res) {
21655+		dev_err(&platdev->dev, "no mmio resource\n");
21656+		return -ENODEV;
21657+	}
21658+
21659+	dma->regbase = devm_ioremap_resource(&platdev->dev, res);
21660+	if (IS_ERR(dma->regbase)) {
21661+		return PTR_ERR(dma->regbase);
21662+	}
21663+
21664+	dma->clk = devm_clk_get(&platdev->dev, NULL);
21665+	if (IS_ERR(dma->clk)) {
21666+		return PTR_ERR(dma->clk);
21667+	}
21668+
21669+	dma->rstc = devm_reset_control_get(&platdev->dev, "dma-reset");
21670+	if (IS_ERR(dma->rstc)) {
21671+		return PTR_ERR(dma->rstc);
21672+	}
21673+
21674+	dma->irq = platform_get_irq(platdev, 0);
21675+	if (unlikely(dma->irq < 0)) {
21676+		return -ENODEV;
21677+	}
21678+
21679+	dma_regbase = dma->regbase;
21680+
21681+	ret = dmac_init(dma);
21682+	if (ret) {
21683+		return -ENODEV;
21684+	}
21685+
21686+	platform_set_drvdata(platdev, dma);
21687+
21688+	for (i = 0; i < DMAC_MAX_CHANNELS; i++) {
21689+		g_channel_status[i] = DMAC_CHN_VACANCY;
21690+	}
21691+
21692+	dev_info(&platdev->dev, "hidmac probe!\n");
21693+	return ret;
21694+}
21695+
21696+static int hi_dmac_remove(struct platform_device *platdev)
21697+{
21698+	int i;
21699+	struct hidmac_host *dma = platform_get_drvdata(platdev);
21700+
21701+	clk_disable_unprepare(dma->clk);
21702+
21703+	for (i = 0; i < DMAC_MAX_CHANNELS; i++) {
21704+		g_channel_status[i] = DMAC_CHN_VACANCY;
21705+	}
21706+
21707+	free_dmalli_space(pllihead, 1);
21708+
21709+	return 0;
21710+}
21711+
21712+static int hi_dmac_suspend(struct platform_device *platdev,
21713+			   pm_message_t state)
21714+{
21715+	int i;
21716+	struct hidmac_host *dma = platform_get_drvdata(platdev);
21717+
21718+	clk_prepare_enable(dma->clk);
21719+
21720+	for (i = 0; i < DMAC_MAX_CHANNELS; i++) {
21721+		g_channel_status[i] = DMAC_CHN_VACANCY;
21722+	}
21723+
21724+	clk_disable_unprepare(dma->clk);
21725+
21726+	return 0;
21727+}
21728+
21729+static int hi_dmac_resume(struct platform_device *platdev)
21730+{
21731+	int i;
21732+	struct hidmac_host *dma = platform_get_drvdata(platdev);
21733+	unsigned int tempvalue;
21734+
21735+	clk_prepare_enable(dma->clk);
21736+	reset_control_deassert(dma->rstc);
21737+
21738+	dmac_readw(dma->regbase + DMAC_CONFIG, tempvalue);
21739+	if (tempvalue == 0) {
21740+		dmac_writew(dma->regbase + DMAC_CONFIG,
21741+			    DMAC_CONFIG_VAL);
21742+		dmac_writew(dma->regbase + DMAC_INTTCCLEAR, 0xFF);
21743+		dmac_writew(dma->regbase + DMAC_INTERRCLR, 0xFF);
21744+		for (i = 0; i < DMAC_MAX_CHANNELS; i++) {
21745+			dmac_writew(dma->regbase + DMAC_CxCONFIG(i),
21746+				    DMAC_CxDISABLE);
21747+			function[i] = NULL;
21748+		}
21749+	}
21750+
21751+	for (i = 0; i < DMAC_MAX_CHANNELS; i++) {
21752+		g_channel_status[i] = DMAC_CHN_VACANCY;
21753+	}
21754+
21755+	return 0;
21756+}
21757+
21758+static const struct of_device_id hisi_dmac_dt_ids[] = {
21759+	{ .compatible = "hisilicon,hisi-dmac" },
21760+	{ }
21761+};
21762+MODULE_DEVICE_TABLE(of, hisi_dmac_dt_ids);
21763+
21764+static struct platform_driver hisi_dmac_driver = {
21765+	.driver = {
21766+		.name   = "hisi-dmac",
21767+		.of_match_table = hisi_dmac_dt_ids,
21768+	},
21769+	.probe      = hi_dmac_probe,
21770+	.remove     = hi_dmac_remove,
21771+	.suspend    = hi_dmac_suspend,
21772+	.resume     = hi_dmac_resume,
21773+};
21774+
21775+module_platform_driver(hisi_dmac_driver);
21776+
21777+MODULE_LICENSE("GPL");
21778+MODULE_AUTHOR("Hisilicon");
21779+MODULE_DESCRIPTION("HiSilicon DMA Controller driver");
21780diff --git a/drivers/hidmac/hi_pl08x.h b/drivers/hidmac/hi_pl08x.h
21781new file mode 100644
21782index 000000000..1c3babf22
21783--- /dev/null
21784+++ b/drivers/hidmac/hi_pl08x.h
21785@@ -0,0 +1,90 @@
21786+/*
21787+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
21788+ *
21789+ * This program is free software; you can redistribute it and/or modify
21790+ * it under the terms of the GNU General Public License as published by
21791+ * the Free Software Foundation; either version 2 of the License, or
21792+ * (at your option) any later version.
21793+ *
21794+ * This program is distributed in the hope that it will be useful,
21795+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21796+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21797+ * GNU General Public License for more details.
21798+ *
21799+ * You should have received a copy of the GNU General Public License
21800+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
21801+ */
21802+
21803+
21804+#ifndef __HI_DMAC_H__
21805+#define __HI_DMAC_H__
21806+
21807+#define  dmac_writew(addr, value) \
21808+    writel(value, (void *)(addr))
21809+#define  dmac_readw(addr, v) \
21810+    v = readl((void *)(addr))
21811+
21812+#ifdef DMA_DEBUG
21813+#define dma_debug printk
21814+#else
21815+#define dma_debug(fmt, ...) do {} while (0);
21816+#endif
21817+
21818+#define DMAC_CONFIGURATIONx_HALT_DMA_ENABLE (0x01L<<18)
21819+#define DMAC_CONFIGURATIONx_ACTIVE      (0x01L<<17)
21820+#define DMAC_CONFIGURATIONx_CHANNEL_ENABLE  1
21821+#define DMAC_CONFIGURATIONx_CHANNEL_DISABLE 0
21822+
21823+/* definition for the return value */
21824+#define DMAC_ERROR_BASE             100
21825+#define DMAC_CHANNEL_INVALID            (DMAC_ERROR_BASE+1)
21826+
21827+#define DMAC_TRXFERSIZE_INVALID         (DMAC_ERROR_BASE+2)
21828+#define DMAC_SOURCE_ADDRESS_INVALID     (DMAC_ERROR_BASE+3)
21829+#define DMAC_DESTINATION_ADDRESS_INVALID    (DMAC_ERROR_BASE+4)
21830+#define DMAC_MEMORY_ADDRESS_INVALID     (DMAC_ERROR_BASE+5)
21831+#define DMAC_PERIPHERAL_ID_INVALID      (DMAC_ERROR_BASE+6)
21832+#define DMAC_DIRECTION_ERROR            (DMAC_ERROR_BASE+7)
21833+#define DMAC_TRXFER_ERROR           (DMAC_ERROR_BASE+8)
21834+#define DMAC_LLIHEAD_ERROR          (DMAC_ERROR_BASE+9)
21835+#define DMAC_SWIDTH_ERROR           (DMAC_ERROR_BASE+0xa)
21836+#define DMAC_LLI_ADDRESS_INVALID        (DMAC_ERROR_BASE+0xb)
21837+#define DMAC_TRANS_CONTROL_INVALID      (DMAC_ERROR_BASE+0xc)
21838+#define DMAC_MEMORY_ALLOCATE_ERROR      (DMAC_ERROR_BASE+0xd)
21839+#define DMAC_NOT_FINISHED           (DMAC_ERROR_BASE+0xe)
21840+
21841+#define DMAC_TIMEOUT                (DMAC_ERROR_BASE+0xf)
21842+#define DMAC_CHN_SUCCESS            (DMAC_ERROR_BASE+0x10)
21843+#define DMAC_CHN_ERROR              (DMAC_ERROR_BASE+0x11)
21844+#define DMAC_CHN_TIMEOUT            (DMAC_ERROR_BASE+0x12)
21845+#define DMAC_CHN_ALLOCAT            (DMAC_ERROR_BASE+0x13)
21846+#define DMAC_CHN_VACANCY            (DMAC_ERROR_BASE+0x14)
21847+
21848+#define DMAC_CONFIGURATIONx_ACTIVE_NOT      0
21849+
21850+/* the means the bit in the channel control register */
21851+#define DMAC_TRANS_SIZE         0xff0
21852+
21853+/* DMAC peripheral structure */
21854+typedef struct dmac_peripheral {
21855+	/* peripherial ID */
21856+	unsigned int peri_id;
21857+	/* peripheral data register address */
21858+	unsigned int peri_addr;
21859+	/* default channel control word */
21860+	unsigned int transfer_ctrl;
21861+	/* default channel configuration word */
21862+	unsigned int transfer_cfg;
21863+	/* default channel configuration word */
21864+	unsigned int transfer_width;
21865+} dmac_peripheral;
21866+
21867+typedef struct mem_addr {
21868+	unsigned int addr_base;
21869+	unsigned int size;
21870+} mem_addr;
21871+
21872+typedef unsigned int dma_addr_t;
21873+/* #define PAGE_SIZE 0x1000 */
21874+
21875+#endif /* End of #ifndef __HI_INC_ECSDMACC_H__ */
21876diff --git a/drivers/hiedmac/Kconfig b/drivers/hiedmac/Kconfig
21877new file mode 100644
21878index 000000000..183747be8
21879--- /dev/null
21880+++ b/drivers/hiedmac/Kconfig
21881@@ -0,0 +1,29 @@
21882+#
21883+# Sensor device configuration
21884+#
21885+
21886+config HIEDMAC
21887+	tristate "Hisilicon EDMAC Controller support"
21888+	depends on (ARCH_HISI_BVT && !HIEDMACV310)
21889+	help
21890+	  The Direction Memory Access(EDMA) is a high-speed data transfer
21891+	  operation. It supports data read/write between peripherals and
21892+	  memories without using the CPU.
21893+	  Hisilicon EDMA Controller(EDMAC) directly transfers data between
21894+	  a memory and a peripheral, between peripherals, or between memories.
21895+	  This avoids the CPU intervention and reduces the interrupt handling
21896+	  overhead of the CPU.
21897+
21898+if HIEDMAC
21899+
21900+config HIEDMAC_CHANNEL_NUM
21901+	int "hiedmac channel num"
21902+	default "8"
21903+
21904+config HIEDMAC_INTERRUPT
21905+	bool "Hisilicon EDMAC Controller interrupt mode support"
21906+	depends on HIEDMAC
21907+	help
21908+	  open Hisilicon EDMAC Controller interrupt mode
21909+
21910+endif
21911diff --git a/drivers/hiedmac/Makefile b/drivers/hiedmac/Makefile
21912new file mode 100644
21913index 000000000..a1b4b8b76
21914--- /dev/null
21915+++ b/drivers/hiedmac/Makefile
21916@@ -0,0 +1,4 @@
21917+#
21918+# Makefile for the hiedmac drivers.
21919+#
21920+obj-$(CONFIG_HIEDMAC)	+= hiedmacv310.o
21921diff --git a/drivers/hiedmac/hiedmacv310.c b/drivers/hiedmac/hiedmacv310.c
21922new file mode 100644
21923index 000000000..282ac3eaa
21924--- /dev/null
21925+++ b/drivers/hiedmac/hiedmacv310.c
21926@@ -0,0 +1,946 @@
21927+/*
21928+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
21929+ *
21930+ * This program is free software; you can redistribute it and/or modify
21931+ * it under the terms of the GNU General Public License as published by
21932+ * the Free Software Foundation; either version 2 of the License, or
21933+ * (at your option) any later version.
21934+ *
21935+ * This program is distributed in the hope that it will be useful,
21936+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21937+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21938+ * GNU General Public License for more details.
21939+ *
21940+ * You should have received a copy of the GNU General Public License
21941+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
21942+ */
21943+
21944+#include <linux/debugfs.h>
21945+#include <linux/delay.h>
21946+#include <linux/clk.h>
21947+#include <linux/reset.h>
21948+#include <linux/platform_device.h>
21949+#include <linux/device.h>
21950+#include <linux/export.h>
21951+#include <linux/init.h>
21952+#include <linux/interrupt.h>
21953+#include <linux/module.h>
21954+#include <linux/of.h>
21955+#include <linux/of_dma.h>
21956+#include <linux/pm_runtime.h>
21957+#include <linux/seq_file.h>
21958+#include <linux/dma-mapping.h>
21959+#include <linux/slab.h>
21960+#include <linux/io.h>
21961+#include <linux/regmap.h>
21962+#include <linux/mfd/syscon.h>
21963+#include <linux/hiedmac.h>
21964+
21965+#include "hiedmacv310.h"
21966+
21967+#if defined(CONFIG_ARCH_HI3531DV200) || defined(CONFIG_ARCH_HI3535AV100)
21968+#include "hiedma_hi3531dv200.h"
21969+#endif
21970+
21971+#if defined(CONFIG_ARCH_HI3521DV200) || defined(CONFIG_ARCH_HI3520DV500)
21972+#include "hiedma_hi3521dv200.h"
21973+#endif
21974+
21975+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100)
21976+#include "hiedma_hi3559av100.h"
21977+#endif
21978+
21979+#if defined(CONFIG_ARCH_HI3519AV100) || defined(CONFIG_ARCH_HI3556AV100) || \
21980+    defined(CONFIG_ARCH_HI3568V100)
21981+#include "hiedma_hi3519av100.h"
21982+#endif
21983+
21984+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \
21985+    defined(CONFIG_ARCH_HI3556V200)  || defined(CONFIG_ARCH_HI3559V200)  || \
21986+    defined(CONFIG_ARCH_HI3562V100)  || defined(CONFIG_ARCH_HI3566V100)
21987+#include "hiedma_hi3516cv500.h"
21988+#endif
21989+
21990+#if defined(CONFIG_ARCH_HI3516EV200) || defined(CONFIG_ARCH_HI3516EV300) || \
21991+    defined(CONFIG_ARCH_HI3518EV300) || defined(CONFIG_ARCH_HI3516DV200)
21992+#include "hiedma_hi3516ev200.h"
21993+#endif
21994+
21995+int g_channel_status[HIEDMAC_CHANNEL_NUM];
21996+DMAC_ISR *function[HIEDMAC_CHANNEL_NUM];
21997+unsigned long pllihead[2] = {0, 0};
21998+void __iomem *dma_regbase;
21999+int hiedmacv310_trace_level_n = HIEDMACV310_TRACE_LEVEL;
22000+
22001+struct hiedmac_host {
22002+	struct platform_device *pdev;
22003+	void __iomem *base;
22004+	struct regmap *misc_regmap;
22005+	unsigned int misc_ctrl_base;
22006+	void __iomem *crg_ctrl;
22007+	unsigned int id;
22008+	struct clk *clk;
22009+	struct clk *axi_clk;
22010+	unsigned int irq;
22011+	struct reset_control *rstc;
22012+	unsigned int channels;
22013+	unsigned int slave_requests;
22014+};
22015+
22016+#define DRIVER_NAME "hiedmacv310"
22017+
22018+int dmac_channel_allocate(void)
22019+{
22020+	unsigned int i;
22021+
22022+	for (i = 0; i < HIEDMAC_CHANNEL_NUM; i++) {
22023+		if (g_channel_status[i] == DMAC_CHN_VACANCY) {
22024+			g_channel_status[i] = DMAC_CHN_ALLOCAT;
22025+			return i;
22026+		}
22027+	}
22028+
22029+	hiedmacv310_error("no to alloc\n");
22030+	return -1;
22031+}
22032+EXPORT_SYMBOL(dmac_channel_allocate);
22033+
22034+/*
22035+ *	update the state of channels
22036+ */
22037+static int hiedmac_update_status(unsigned int channel)
22038+{
22039+	unsigned int channel_status;
22040+	unsigned int channel_tc_status;
22041+	unsigned int channel_err_status[3];
22042+	unsigned int i = channel;
22043+	unsigned long update_jiffies_timeout;
22044+
22045+	update_jiffies_timeout = jiffies + HIEDMAC_UPDATE_TIMEOUT;
22046+
22047+	while (1) {
22048+		channel_status = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_STAT);
22049+		channel_status = (channel_status >> i) & 0x01;
22050+		if (channel_status) {
22051+			channel_tc_status = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_TC1);
22052+			channel_tc_status = (channel_tc_status >> i) & 0x01;
22053+			if (channel_tc_status) {
22054+				hiedmacv310_writel(1 << i, dma_regbase + HIEDMAC_INT_TC1_RAW);
22055+				g_channel_status[i] = DMAC_CHN_SUCCESS;
22056+				break;
22057+			}
22058+
22059+			channel_tc_status = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_TC2);
22060+			channel_tc_status = (channel_tc_status >> i) & 0x01;
22061+			if (channel_tc_status) {
22062+				hiedmacv310_writel(1 << i, dma_regbase + HIEDMAC_INT_TC2_RAW);
22063+				g_channel_status[i] = DMAC_CHN_SUCCESS;
22064+				break;
22065+			}
22066+
22067+			channel_err_status[0] = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_ERR1);
22068+			channel_err_status[0] = (channel_err_status[0] >> i) & 0x01;
22069+			channel_err_status[1] = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_ERR2);
22070+			channel_err_status[1] = (channel_err_status[1] >> i) & 0x01;
22071+			channel_err_status[2] = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_ERR3);
22072+			channel_err_status[2] = (channel_err_status[2] >> i) & 0x01;
22073+
22074+			if (channel_err_status[0] | channel_err_status[1] | channel_err_status[2]) {
22075+				hiedmacv310_error("Error in HIEDMAC %d finish!\n", i);
22076+				channel_err_status[0] = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_ERR1);
22077+				channel_err_status[1] = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_ERR2);
22078+				channel_err_status[2] = hiedmacv310_readl(dma_regbase + HIEDMAC_INT_ERR3);
22079+				g_channel_status[i] = -DMAC_CHN_ERROR;
22080+				hiedmacv310_writel(1 << i, dma_regbase + HIEDMAC_INT_ERR1_RAW);
22081+				hiedmacv310_writel(1 << i, dma_regbase + HIEDMAC_INT_ERR2_RAW);
22082+				hiedmacv310_writel(1 << i, dma_regbase + HIEDMAC_INT_ERR3_RAW);
22083+				break;
22084+			}
22085+		}
22086+
22087+		if (!time_before(jiffies, update_jiffies_timeout)) {
22088+			hiedmacv310_error("Timeout in DMAC %d!\n", i);
22089+			g_channel_status[i] = -DMAC_CHN_TIMEOUT;
22090+			break;
22091+		}
22092+	}
22093+
22094+	return g_channel_status[i];
22095+}
22096+
22097+/*
22098+ * register user's function
22099+ */
22100+int dmac_register_isr(unsigned int channel, void *pisr)
22101+{
22102+	if (channel < 0 || channel > HIEDMAC_CHANNEL_NUM - 1) {
22103+		hiedmacv310_error("invalid channel,channel=%0d\n", channel);
22104+		return -EINVAL;
22105+	}
22106+
22107+	function[channel] = (void *)pisr;
22108+
22109+	return 0;
22110+}
22111+EXPORT_SYMBOL(dmac_register_isr);
22112+
22113+/*
22114+ *	free channel
22115+ */
22116+int dmac_channel_free(unsigned int channel)
22117+{
22118+	if ((channel >= 0) && (channel < HIEDMAC_CHANNEL_NUM))
22119+		g_channel_status[channel] = DMAC_CHN_VACANCY;
22120+
22121+	return 0;
22122+}
22123+EXPORT_SYMBOL(dmac_channel_free);
22124+
22125+static unsigned int dmac_check_request(unsigned int peripheral_addr,
22126+				       int direction)
22127+{
22128+	int i;
22129+
22130+	for (i = direction; i < EDMAC_MAX_PERIPHERALS; i += 2) {
22131+		if (g_peripheral[i].peri_addr == peripheral_addr)
22132+			return i;
22133+	}
22134+	hiedmacv310_error("Invalid devaddr\n");
22135+	return -1;
22136+}
22137+
22138+void edmac_channel_free(int channel)
22139+{
22140+	if ((channel >= 0) && (channel < HIEDMAC_CHANNEL_NUM))
22141+		g_channel_status[channel] = DMAC_CHN_VACANCY;
22142+}
22143+/*
22144+ *	wait for transfer end
22145+ */
22146+int dmac_wait(int channel)
22147+{
22148+	int ret_result;
22149+	int ret = 0;
22150+
22151+	if (channel < 0)
22152+		return -1;
22153+
22154+	while (1) {
22155+		ret_result = hiedmac_update_status(channel);
22156+		if (ret_result == -DMAC_CHN_ERROR) {
22157+			hiedmacv310_error("Transfer Error.\n");
22158+			ret = -1;
22159+			goto end;
22160+		} else  if (ret_result == DMAC_NOT_FINISHED)
22161+			udelay(10);
22162+		else if (ret_result == DMAC_CHN_SUCCESS) {
22163+			ret = DMAC_CHN_SUCCESS;
22164+			goto end;
22165+		} else if (ret_result == DMAC_CHN_VACANCY) {
22166+			ret = DMAC_CHN_SUCCESS;
22167+			goto end;
22168+		} else if (ret_result == -DMAC_CHN_TIMEOUT) {
22169+			hiedmacv310_error("Timeout.\n");
22170+			hiedmacv310_writel(HIEDMAC_Cx_DISABLE,
22171+					   dma_regbase + HIEDMAC_Cx_CONFIG(channel));
22172+			g_channel_status[channel] = DMAC_CHN_VACANCY;
22173+			ret = -1;
22174+			return ret;
22175+		}
22176+	}
22177+end:
22178+	hiedmacv310_writel(HIEDMAC_Cx_DISABLE,
22179+			   dma_regbase + HIEDMAC_Cx_CONFIG(channel));
22180+	edmac_channel_free(channel);
22181+	return ret;
22182+}
22183+EXPORT_SYMBOL(dmac_wait);
22184+
22185+/*
22186+ *	execute memory to peripheral dma transfer without LLI
22187+ */
22188+int dmac_m2p_transfer(unsigned long long memaddr, unsigned int uwperipheralid,
22189+		      unsigned int length)
22190+{
22191+	unsigned int ulchnn;
22192+	unsigned int uwwidth;
22193+	unsigned int temp;
22194+
22195+	ulchnn = dmac_channel_allocate();
22196+	if (-1 == ulchnn)
22197+		return -1;
22198+
22199+	hiedmacv310_trace(4, "ulchnn = %d\n", ulchnn);
22200+	uwwidth = g_peripheral[uwperipheralid].transfer_width;
22201+	if (length >> uwwidth >= HIEDMAC_TRANS_MAXSIZE) {
22202+		hiedmacv310_error("The length is more than 64k!\n");
22203+		return -1;
22204+	}
22205+
22206+	hiedmacv310_writel(memaddr & 0xffffffff,
22207+			   dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(ulchnn));
22208+#ifdef CONFIG_ARM64
22209+	hiedmacv310_writel((memaddr >> 32) & 0xffffffff,
22210+			   dma_regbase + HIEDMAC_Cx_SRC_ADDR_H(ulchnn));
22211+#endif
22212+	hiedmacv310_trace(4, "HIEDMAC_Cx_SRC_ADDR_L = 0x%x\n",
22213+			  hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(ulchnn)));
22214+
22215+	hiedmacv310_writel(g_peripheral[uwperipheralid].peri_addr & 0xffffffff,
22216+			   dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(ulchnn));
22217+#ifdef CONFIG_ARM64
22218+	hiedmacv310_writel((g_peripheral[uwperipheralid].peri_addr >> 32) & 0xffffffff,
22219+			   dma_regbase + HIEDMAC_Cx_DEST_ADDR_H(ulchnn));
22220+#endif
22221+	hiedmacv310_trace(4, "HIEDMAC_Cx_DEST_ADDR_L = 0x%x\n",
22222+			  hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(ulchnn)));
22223+
22224+	hiedmacv310_writel(0, dma_regbase + HIEDMAC_Cx_LLI_L(ulchnn));
22225+	hiedmacv310_trace(4, "HIEDMAC_Cx_LLI_L = 0x%x\n",
22226+			  hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_LLI_L(ulchnn)));
22227+
22228+	hiedmacv310_writel(length, dma_regbase + HIEDMAC_Cx_CNT0(ulchnn));
22229+	hiedmacv310_trace(4, "HIEDMAC_Cx_CNT0 = 0x%x\n",
22230+			  hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_CNT0(ulchnn)));
22231+
22232+	temp = g_peripheral[uwperipheralid].transfer_cfg | uwwidth <<
22233+	       EDMA_SRC_WIDTH_OFFSET |
22234+	       (uwperipheralid << PERI_ID_OFFSET) |
22235+	       EDMA_CH_ENABLE;
22236+	hiedmacv310_trace(4, "HIEDMAC_Cx_CONFIG = 0x%x\n", temp);
22237+	hiedmacv310_writel(temp, dma_regbase + HIEDMAC_Cx_CONFIG(ulchnn));
22238+	return ulchnn;
22239+}
22240+
22241+/*
22242+ *	execute memory to peripheral dma transfer without LLI
22243+ */
22244+int dmac_p2m_transfer(unsigned long memaddr, unsigned int uwperipheralid,
22245+		      unsigned int length)
22246+{
22247+	unsigned int ulchnn;
22248+	unsigned int uwwidth;
22249+	unsigned int temp;
22250+
22251+	ulchnn = dmac_channel_allocate();
22252+	if (-1 == ulchnn)
22253+		return -1;
22254+
22255+	hiedmacv310_trace(4, "ulchnn = %d\n", ulchnn);
22256+	uwwidth = g_peripheral[uwperipheralid].transfer_width;
22257+	if (length >> uwwidth >= HIEDMAC_TRANS_MAXSIZE) {
22258+		hiedmacv310_error("The length is more than 64k!\n");
22259+		return -1;
22260+	}
22261+
22262+	hiedmacv310_writel(memaddr & 0xffffffff,
22263+			   dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(ulchnn));
22264+#ifdef CONFIG_ARM64
22265+	hiedmacv310_writel((memaddr >> 32) & 0xffffffff,
22266+			   dma_regbase + HIEDMAC_Cx_DEST_ADDR_H(ulchnn));
22267+#endif
22268+	hiedmacv310_trace(4, "HIEDMAC_Cx_DEST_ADDR_L = 0x%x\n",
22269+			  hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(ulchnn)));
22270+
22271+	hiedmacv310_writel(g_peripheral[uwperipheralid].peri_addr & 0xffffffff,
22272+			   dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(ulchnn));
22273+#ifdef CONFIG_ARM64
22274+	hiedmacv310_writel(0, dma_regbase + HIEDMAC_Cx_SRC_ADDR_H(ulchnn));
22275+#endif
22276+	hiedmacv310_trace(4, "HIEDMAC_Cx_SRC_ADDR_L = 0x%x\n",
22277+			  hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(ulchnn)));
22278+
22279+	hiedmacv310_writel(0, dma_regbase + HIEDMAC_Cx_LLI_L(ulchnn));
22280+	hiedmacv310_trace(4, "HIEDMAC_Cx_LLI_L = 0x%x\n",
22281+			  hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_LLI_L(ulchnn)));
22282+
22283+	hiedmacv310_writel(length, dma_regbase + HIEDMAC_Cx_CNT0(ulchnn));
22284+	hiedmacv310_trace(4, "HIEDMAC_Cx_CNT0 = 0x%x\n",
22285+			  hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_CNT0(ulchnn)));
22286+
22287+	temp = g_peripheral[uwperipheralid].transfer_cfg | uwwidth <<
22288+	       EDMA_SRC_WIDTH_OFFSET |
22289+	       (uwperipheralid << PERI_ID_OFFSET) |
22290+	       EDMA_CH_ENABLE;
22291+	hiedmacv310_trace(4, "HIEDMAC_Cx_CONFIG = 0x%x\n", temp);
22292+	hiedmacv310_writel(temp, dma_regbase + HIEDMAC_Cx_CONFIG(ulchnn));
22293+	return ulchnn;
22294+}
22295+
22296+int do_dma_m2p(unsigned long long memaddr, unsigned int peripheral_addr,
22297+	       unsigned int length)
22298+{
22299+	int ret = 0;
22300+	int uwperipheralid;
22301+
22302+	uwperipheralid = dmac_check_request(peripheral_addr, EDMAC_TX);
22303+	if (uwperipheralid < 0) {
22304+		hiedmacv310_error("m2p:Invalid devaddr\n");
22305+		return -1;
22306+	}
22307+
22308+	ret = dmac_m2p_transfer(memaddr, uwperipheralid, length);
22309+	if (ret == -1) {
22310+		hiedmacv310_error("m2p:trans err\n");
22311+		return -1;
22312+	}
22313+
22314+	return ret;
22315+}
22316+EXPORT_SYMBOL(do_dma_m2p);
22317+
22318+int do_dma_p2m(unsigned long memaddr, unsigned int peripheral_addr,
22319+	       unsigned int length)
22320+{
22321+	int ret = -1;
22322+	int uwperipheralid;
22323+
22324+	uwperipheralid = dmac_check_request(peripheral_addr, EDMAC_RX);
22325+	if (uwperipheralid < 0) {
22326+		hiedmacv310_error("p2m:Invalid devaddr.\n");
22327+		return -1;
22328+	}
22329+
22330+	ret = dmac_p2m_transfer(memaddr, uwperipheralid, length);
22331+	if (ret == -1) {
22332+		hiedmacv310_error("p2m:trans err\n");
22333+		return -1;
22334+	}
22335+
22336+	return ret;
22337+}
22338+EXPORT_SYMBOL(do_dma_p2m);
22339+
22340+/*
22341+ *	buile LLI for memory to memory DMA transfer
22342+ */
22343+int dmac_buildllim2m(unsigned long *ppheadlli,
22344+		     unsigned long psource,
22345+		     unsigned long pdest,
22346+		     unsigned int totaltransfersize,
22347+		     unsigned int uwnumtransfers)
22348+{
22349+	int lli_num = 0;
22350+	unsigned long phy_address;
22351+	int j;
22352+	dmac_lli  *plli = NULL;
22353+
22354+	if (uwnumtransfers == 0)
22355+		return -EINVAL;
22356+
22357+	lli_num = (totaltransfersize / uwnumtransfers);
22358+	if ((totaltransfersize % uwnumtransfers) != 0)
22359+		lli_num++;
22360+
22361+	hiedmacv310_trace(4, "lli_num:%d\n", lli_num);
22362+
22363+	phy_address = ppheadlli[0];
22364+	plli = (dmac_lli *)ppheadlli[1];
22365+	hiedmacv310_trace(4, "phy_address: 0x%lx\n", phy_address);
22366+	hiedmacv310_trace(4, "address: 0x%p\n", plli);
22367+	for (j = 0; j < lli_num; j++) {
22368+		memset(plli, 0x0, sizeof(dmac_lli));
22369+		/*
22370+		 * at the last transfer, chain_en should be set to 0x0;
22371+		 * others tansfer,chain_en should be set to 0x2;
22372+		 */
22373+		plli->next_lli = (phy_address + (j + 1) * sizeof(dmac_lli)) &
22374+				  (~(HIEDMAC_LLI_ALIGN - 1));
22375+		if (j < lli_num - 1) {
22376+			plli->next_lli |= HIEDMAC_LLI_ENABLE;
22377+			plli->count = uwnumtransfers;
22378+		} else {
22379+			plli->next_lli |= HIEDMAC_LLI_DISABLE;
22380+			plli->count = totaltransfersize % uwnumtransfers;
22381+		}
22382+
22383+		plli->src_addr = psource;
22384+		plli->dest_addr = pdest;
22385+		plli->config = HIEDMAC_CxCONFIG_M2M_LLI;
22386+
22387+		psource += uwnumtransfers;
22388+		pdest += uwnumtransfers;
22389+		plli++;
22390+	}
22391+
22392+	return 0;
22393+}
22394+EXPORT_SYMBOL(dmac_buildllim2m);
22395+
22396+/*
22397+ *	load configuration from LLI for memory to memory
22398+ */
22399+int dmac_start_llim2m(unsigned int channel, unsigned long *pfirst_lli)
22400+{
22401+	unsigned int i = channel;
22402+	dmac_lli  *plli;
22403+
22404+	plli = (dmac_lli *)pfirst_lli[1];
22405+	hiedmacv310_trace(4, "plli.src_addr: 0x%lx\n", plli->src_addr);
22406+	hiedmacv310_trace(4, "plli.dst_addr: 0x%lx\n", plli->dest_addr);
22407+	hiedmacv310_trace(4, "plli.next_lli: 0x%lx\n", plli->next_lli);
22408+	hiedmacv310_trace(4, "plli.count: 0x%d\n", plli->count);
22409+
22410+	hiedmacv310_writel(plli->dest_addr & 0xffffffff,
22411+			   dma_regbase + HIEDMAC_Cx_LLI_L(i));
22412+#ifdef CONFIG_ARM64
22413+	hiedmacv310_writel((plli->dest_addr >> 32) & 0xffffffff,
22414+			   dma_regbase + HIEDMAC_Cx_LLI_H(i));
22415+#endif
22416+	hiedmacv310_writel(plli->count, dma_regbase + HIEDMAC_Cx_CNT0(i));
22417+
22418+	hiedmacv310_writel(plli->src_addr & 0xffffffff,
22419+			   dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(i));
22420+#ifdef CONFIG_ARM64
22421+	hiedmacv310_writel((plli->src_addr >> 32) & 0xffffffff,
22422+			   dma_regbase + HIEDMAC_Cx_SRC_ADDR_H(i));
22423+#endif
22424+	hiedmacv310_writel(plli->dest_addr & 0xffffffff,
22425+			   dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(i));
22426+#ifdef CONFIG_ARM64
22427+	hiedmacv310_writel((plli->dest_addr >> 32) & 0xffffffff,
22428+			   dma_regbase + HIEDMAC_Cx_DEST_ADDR_H(i));
22429+#endif
22430+	hiedmacv310_writel(plli->config | EDMA_CH_ENABLE,
22431+			   dma_regbase + HIEDMAC_Cx_CONFIG(i));
22432+
22433+	return 0;
22434+}
22435+EXPORT_SYMBOL(dmac_start_llim2m);
22436+
22437+/*
22438+ * config register for memory to memory DMA transfer without LLI
22439+ */
22440+int dmac_start_m2m(unsigned int  channel, unsigned long psource,
22441+		   unsigned long pdest, unsigned int uwnumtransfers)
22442+{
22443+	unsigned int i = channel;
22444+
22445+	if (uwnumtransfers > HIEDMAC_TRANS_MAXSIZE || uwnumtransfers == 0) {
22446+		hiedmacv310_error("Invalidate transfer size,size=%x\n", uwnumtransfers);
22447+		return -EINVAL;
22448+	}
22449+	hiedmacv310_trace(4, "channel[%d],source=0x%lx,dest=0x%lx,length=%d\n",
22450+			  channel, psource, pdest, uwnumtransfers);
22451+
22452+	hiedmacv310_writel(psource & 0xffffffff,
22453+			   dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(i));
22454+	hiedmacv310_trace(4, "HIEDMAC_Cx_SRC_ADDR_L = 0x%x\n",
22455+			  hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_SRC_ADDR_L(i)));
22456+#ifdef CONFIG_ARM64
22457+	hiedmacv310_writel((psource >> 32) & 0xffffffff,
22458+			   dma_regbase + HIEDMAC_Cx_SRC_ADDR_H(i));
22459+	hiedmacv310_trace(4, "HIEDMAC_Cx_SRC_ADDR_H = 0x%x\n",
22460+			  hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_SRC_ADDR_H(i)));
22461+#endif
22462+	hiedmacv310_writel(pdest & 0xffffffff, dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(i));
22463+	hiedmacv310_trace(4, "HIEDMAC_Cx_DEST_ADDR_L = 0x%x\n",
22464+			  hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_DEST_ADDR_L(i)));
22465+#ifdef CONFIG_ARM64
22466+	hiedmacv310_writel((pdest >> 32) & 0xffffffff,
22467+			   dma_regbase + HIEDMAC_Cx_DEST_ADDR_H(i));
22468+	hiedmacv310_trace(4, "HIEDMAC_Cx_DEST_ADDR_H = 0x%x\n",
22469+			  hiedmacv310_readl(dma_regbase + HIEDMAC_Cx_DEST_ADDR_H(i)));
22470+#endif
22471+	hiedmacv310_writel(0, dma_regbase + HIEDMAC_Cx_LLI_L(i));
22472+
22473+	hiedmacv310_writel(uwnumtransfers, dma_regbase + HIEDMAC_Cx_CNT0(i));
22474+
22475+	hiedmacv310_writel(HIEDMAC_CxCONFIG_M2M | EDMA_CH_ENABLE,
22476+			   dma_regbase + HIEDMAC_Cx_CONFIG(i));
22477+
22478+	return 0;
22479+}
22480+EXPORT_SYMBOL(dmac_start_m2m);
22481+
22482+/*
22483+ *	execute memory to memory dma transfer without LLI
22484+ */
22485+int dmac_m2m_transfer(unsigned long source, unsigned long dest,
22486+		      unsigned int length)
22487+{
22488+	unsigned int dma_size = 0;
22489+	unsigned int ulchnn, dma_count, left_size;
22490+
22491+	left_size = length;
22492+	dma_count = 0;
22493+	ulchnn = dmac_channel_allocate();
22494+	if (ulchnn < 0) {
22495+		return -EINVAL;
22496+	}
22497+
22498+	hiedmacv310_trace(6, "using channel[%d],source=0x%lx,dest=0x%lx,length=%d\n",
22499+			  ulchnn, source, dest, length);
22500+
22501+	while (left_size) {
22502+		if (left_size >= HIEDMAC_TRANS_MAXSIZE)
22503+			dma_size = HIEDMAC_TRANS_MAXSIZE;
22504+		else
22505+			dma_size = left_size;
22506+		dmac_start_m2m(ulchnn,
22507+			       source + dma_count * dma_size,
22508+			       dest + dma_count * dma_size,
22509+			       dma_size);
22510+
22511+		if (dmac_wait(ulchnn) != DMAC_CHN_SUCCESS) {
22512+			hiedmacv310_error("dma transfer error...\n");
22513+			return -1;
22514+		}
22515+		left_size -= dma_size;
22516+		dma_count++;
22517+		hiedmacv310_trace(4, "left_size is %d.\n", left_size);
22518+	}
22519+
22520+	return 0;
22521+}
22522+EXPORT_SYMBOL(dmac_m2m_transfer);
22523+
22524+/*
22525+ * memory to memory dma transfer with LLI
22526+ *
22527+ * @source
22528+ * @dest
22529+ * @length
22530+ * */
22531+int do_dma_llim2m(unsigned long source,
22532+		  unsigned long dest,
22533+		  unsigned long length)
22534+{
22535+	int ret = 0;
22536+	unsigned chnn;
22537+
22538+	chnn = dmac_channel_allocate();
22539+	if (chnn < 0) {
22540+		ret = -1;
22541+		goto end;
22542+	}
22543+	hiedmacv310_trace(4, "chnn:%d,src:%lx,dst:%lx,len:%ld.\n", chnn, source, dest,
22544+			  length);
22545+
22546+	if (pllihead[0] == 0) {
22547+		hiedmacv310_error("ppheadlli[0] is NULL.\n");
22548+		ret = -ENOMEM;
22549+		goto end;
22550+	}
22551+
22552+	ret = dmac_buildllim2m(pllihead, source, dest, length, HIEDMAC_TRANS_MAXSIZE);
22553+	if (ret) {
22554+		hiedmacv310_error("build lli error...\n");
22555+		ret = -EIO;
22556+		goto end;
22557+	}
22558+	ret = dmac_start_llim2m(chnn, pllihead);
22559+	if (ret) {
22560+		hiedmacv310_error("start lli error...\n");
22561+		ret = -EIO;
22562+		goto end;
22563+	}
22564+
22565+end:
22566+	return ret;
22567+}
22568+EXPORT_SYMBOL(do_dma_llim2m);
22569+
22570+/*
22571+ *	alloc_dma_lli_space
22572+ *	output:
22573+ *             ppheadlli[0]: memory physics address
22574+ *             ppheadlli[1]: virtual address
22575+ *
22576+ */
22577+int allocate_dmalli_space(struct device *dev, unsigned long *ppheadlli,
22578+			  unsigned int page_num)
22579+{
22580+	dma_addr_t dma_phys;
22581+	void *dma_virt;
22582+
22583+	dma_virt = dma_alloc_coherent(dev, page_num * PAGE_SIZE,
22584+				      &dma_phys, GFP_DMA);
22585+	if (dma_virt == NULL) {
22586+		hiedmacv310_error("can't get dma mem from system\n");
22587+		return -1;
22588+	}
22589+
22590+	ppheadlli[0] = (unsigned long)(dma_phys);
22591+	ppheadlli[1] = (unsigned long)(dma_virt);
22592+
22593+	if (dma_phys & (HIEDMAC_LLI_ALIGN - 1)) {
22594+		return -1;
22595+	}
22596+
22597+	return 0;
22598+}
22599+EXPORT_SYMBOL(allocate_dmalli_space);
22600+
22601+static int hiedmac_priv_init(struct hiedmac_host *hiedmac,
22602+			     edmac_peripheral *peripheral_info)
22603+{
22604+	struct regmap *misc = hiedmac->misc_regmap;
22605+	int i = 0;
22606+	unsigned int count = 0;
22607+	unsigned int offset = 0;
22608+	unsigned ctrl = 0;
22609+
22610+	for (i = 0; i < EDMAC_MAX_PERIPHERALS; i++) {
22611+		if (peripheral_info[i].host_sel == hiedmac->id) {
22612+			if (count > 32) {
22613+				hiedmacv310_error("request table is not true!\n");
22614+				return -1;
22615+			}
22616+			if (misc != NULL) {
22617+				offset = hiedmac->misc_ctrl_base + (count & (~0x3));
22618+				regmap_read(misc, offset, &ctrl);
22619+				ctrl &= ~(0x3f << ((count & 0x3) << 3));
22620+				ctrl |= peripheral_info[i].peri_id << ((count & 0x3) << 3);
22621+				regmap_write(misc, offset, ctrl);
22622+			}
22623+			peripheral_info[i].dynamic_periphery_num = count;
22624+			count++;
22625+		}
22626+	}
22627+
22628+	return 0;
22629+}
22630+
22631+static int get_of_probe(struct hiedmac_host *hiedmac)
22632+{
22633+	struct resource *res = NULL;
22634+	struct platform_device *platdev = hiedmac->pdev;
22635+	struct device_node *np = platdev->dev.of_node;
22636+	int ret;
22637+
22638+	ret = of_property_read_u32((&platdev->dev)->of_node,
22639+				   "devid", &(hiedmac->id));
22640+	if (ret) {
22641+		hiedmacv310_error("get hiedmac id fail\n");
22642+		return -ENODEV;
22643+	}
22644+
22645+	hiedmac->clk = devm_clk_get(&(platdev->dev), "apb_pclk");
22646+	if (IS_ERR(hiedmac->clk)) {
22647+		hiedmacv310_error("get hiedmac clk fail\n");
22648+		return PTR_ERR(hiedmac->clk);
22649+	}
22650+
22651+	hiedmac->axi_clk = devm_clk_get(&(platdev->dev), "axi_aclk");
22652+	if (IS_ERR(hiedmac->axi_clk)) {
22653+		hiedmacv310_error("get hiedmac axi clk fail\n");
22654+		return PTR_ERR(hiedmac->axi_clk);
22655+	}
22656+
22657+	hiedmac->rstc = devm_reset_control_get(&(platdev->dev), "dma-reset");
22658+	if (IS_ERR(hiedmac->rstc)) {
22659+		hiedmacv310_error("get hiedmac rstc fail\n");
22660+		return PTR_ERR(hiedmac->rstc);
22661+	}
22662+
22663+	res = platform_get_resource(platdev, IORESOURCE_MEM, 0);
22664+	if (!res) {
22665+		hiedmacv310_error("no reg resource\n");
22666+		return -ENODEV;
22667+	}
22668+
22669+	hiedmac->base = devm_ioremap_resource(&(platdev->dev), res);
22670+	if (IS_ERR(hiedmac->base)) {
22671+		hiedmacv310_error("get hiedmac base fail\n");
22672+		return PTR_ERR(hiedmac->base);
22673+	}
22674+	if (!of_find_property(np, "misc_regmap", NULL) ||
22675+			!of_find_property(np, "misc_ctrl_base", NULL)) {
22676+		hiedmac->misc_regmap = 0;
22677+	} else {
22678+		hiedmac->misc_regmap = syscon_regmap_lookup_by_phandle(np, "misc_regmap");
22679+		if (IS_ERR(hiedmac->misc_regmap)) {
22680+			hiedmacv310_error("get hiedmac misc fail\n");
22681+			return PTR_ERR(hiedmac->misc_regmap);
22682+		}
22683+
22684+		ret = of_property_read_u32((&platdev->dev)->of_node,
22685+					   "misc_ctrl_base", &(hiedmac->misc_ctrl_base));
22686+		if (ret) {
22687+			hiedmacv310_error("get dma-misc_ctrl_base fail\n");
22688+			return -ENODEV;
22689+		}
22690+	}
22691+	hiedmac->irq = platform_get_irq(platdev, 0);
22692+	if (unlikely(hiedmac->irq < 0))
22693+		return -ENODEV;
22694+
22695+	ret = of_property_read_u32((&platdev->dev)->of_node,
22696+				   "dma-channels", &(hiedmac->channels));
22697+	if (ret) {
22698+		hiedmacv310_error("get dma-channels fail\n");
22699+		return -ENODEV;
22700+	}
22701+	ret = of_property_read_u32((&platdev->dev)->of_node,
22702+				   "dma-requests", &(hiedmac->slave_requests));
22703+	if (ret) {
22704+		hiedmacv310_error("get dma-requests fail\n");
22705+		return -ENODEV;
22706+	}
22707+	hiedmacv310_trace(2, "dma-channels = %d, dma-requests = %d\n",
22708+			  hiedmac->channels, hiedmac->slave_requests);
22709+
22710+	hiedmac_priv_init(hiedmac, (edmac_peripheral *)&g_peripheral);
22711+
22712+	return 0;
22713+}
22714+
22715+/* Don't need irq mode now */
22716+#if defined(CONFIG_HIEDMAC_INTERRUPT)
22717+static irqreturn_t hiemdacv310_irq(int irq, void *dev)
22718+{
22719+	struct hiedmac_host *hiedmac = (struct hiedmac_host *)dev;
22720+	unsigned int channel_err_status[3];
22721+	unsigned int channel_tc_status = 0;
22722+	unsigned int channel_status = 0;
22723+	int i = 0;
22724+	unsigned int mask = 0;
22725+
22726+	channel_status = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_STAT);
22727+	if (!channel_status) {
22728+		hiedmacv310_error("channel_status = 0x%x\n", channel_status);
22729+		return IRQ_NONE;
22730+	}
22731+
22732+	for (i = 0; i < hiedmac->channels; i++) {
22733+		channel_status = (channel_status >> i) & 0x1;
22734+		if (channel_status) {
22735+			channel_tc_status = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_TC1_RAW);
22736+			channel_tc_status = (channel_tc_status >> i) & 0x01;
22737+			if (channel_tc_status)
22738+				hiedmacv310_writel(channel_tc_status << i, hiedmac->base + HIEDMAC_INT_TC1_RAW);
22739+
22740+			channel_tc_status = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_TC2);
22741+			channel_tc_status = (channel_tc_status >> i) & 0x01;
22742+			if (channel_tc_status)
22743+				hiedmacv310_writel(channel_tc_status << i, hiedmac->base + HIEDMAC_INT_TC2_RAW);
22744+
22745+			channel_err_status[0] = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_ERR1);
22746+			channel_err_status[0] = (channel_err_status[0] >> i) & 0x01;
22747+			channel_err_status[1] = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_ERR2);
22748+			channel_err_status[1] = (channel_err_status[1] >> i) & 0x01;
22749+			channel_err_status[2] = hiedmacv310_readl(hiedmac->base + HIEDMAC_INT_ERR3);
22750+			channel_err_status[2] = (channel_err_status[2] >> i) & 0x01;
22751+
22752+			if (channel_err_status[0] | channel_err_status[1] | channel_err_status[2]) {
22753+				hiedmacv310_error("Error in hiedmac %d finish!,ERR1 = 0x%x,ERR2 = 0x%x,ERR3 = 0x%x\n",
22754+						  i, channel_err_status[0], channel_err_status[1], channel_err_status[2]);
22755+				hiedmacv310_writel(1 << i, hiedmac->base + HIEDMAC_INT_ERR1_RAW);
22756+				hiedmacv310_writel(1 << i, hiedmac->base + HIEDMAC_INT_ERR2_RAW);
22757+				hiedmacv310_writel(1 << i, hiedmac->base + HIEDMAC_INT_ERR3_RAW);
22758+			}
22759+			if ((function[i]) != NULL)
22760+				function[i](i, g_channel_status[i]);
22761+
22762+			mask |= (1 << i);
22763+			hiedmacv310_writel(HIEDMAC_Cx_DISABLE, dma_regbase + HIEDMAC_Cx_CONFIG(i));
22764+			edmac_channel_free(i);
22765+		}
22766+	}
22767+
22768+	return mask ? IRQ_HANDLED : IRQ_NONE;
22769+}
22770+#endif
22771+
22772+static int __init hiedmacv310_probe(struct platform_device *pdev)
22773+{
22774+	int ret = 0;
22775+	int i = 0;
22776+	struct hiedmac_host *hiedmac = NULL;
22777+
22778+	hiedmac = kzalloc(sizeof(*hiedmac), GFP_KERNEL);
22779+	if (!hiedmac) {
22780+		hiedmacv310_error("malloc for hiedmac fail!");
22781+		ret = -ENOMEM;
22782+		return ret;
22783+	}
22784+	hiedmac->pdev = pdev;
22785+
22786+	ret = get_of_probe(hiedmac);
22787+	if (ret) {
22788+		hiedmacv310_error("get dts info fail!");
22789+		goto free_hiedmac;
22790+	}
22791+
22792+	clk_prepare_enable(hiedmac->clk);
22793+	clk_prepare_enable(hiedmac->axi_clk);
22794+
22795+	reset_control_deassert(hiedmac->rstc);
22796+
22797+	hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_TC1_RAW);
22798+	hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_TC2_RAW);
22799+	hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_ERR1_RAW);
22800+	hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_ERR2_RAW);
22801+	hiedmacv310_writel(HIEDMAC_ALL_CHAN_CLR, hiedmac->base + HIEDMAC_INT_ERR3_RAW);
22802+
22803+	hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN,
22804+			   hiedmac->base + HIEDMAC_INT_TC1_MASK);
22805+	hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN,
22806+			   hiedmac->base + HIEDMAC_INT_TC2_MASK);
22807+	hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN,
22808+			   hiedmac->base + HIEDMAC_INT_ERR1_MASK);
22809+	hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN,
22810+			   hiedmac->base + HIEDMAC_INT_ERR2_MASK);
22811+	hiedmacv310_writel(HIEDMAC_INT_ENABLE_ALL_CHAN,
22812+			   hiedmac->base + HIEDMAC_INT_ERR3_MASK);
22813+
22814+	for (i = 0; i < HIEDMAC_CHANNEL_NUM; i++)
22815+		g_channel_status[i] = DMAC_CHN_VACANCY;
22816+
22817+	dma_regbase = hiedmac->base;
22818+
22819+	ret = allocate_dmalli_space(&(hiedmac->pdev->dev), pllihead,
22820+				    HIEDMAC_LLI_PAGE_NUM);
22821+	if (ret < 0)
22822+		goto free_hiedmac;
22823+
22824+#if defined(CONFIG_HIEDMAC_INTERRUPT)
22825+	/* register irq if necessary !*/
22826+	ret = request_irq(hiedmac->irq, hiemdacv310_irq, 0, DRIVER_NAME, hiedmac);
22827+	if (ret) {
22828+		hiedmacv310_error("fail to request irq");
22829+		goto free_hiedmac;
22830+	}
22831+#endif
22832+	return 0;
22833+
22834+free_hiedmac:
22835+	kfree(hiedmac);
22836+
22837+	return ret;
22838+}
22839+
22840+static int hiemda_remove(struct platform_device *pdev)
22841+{
22842+	int err = 0;
22843+	return err;
22844+}
22845+
22846+static const struct of_device_id hiedmacv310_match[] = {
22847+	{ .compatible = "hisilicon,hiedmacv310_n" },
22848+	{},
22849+};
22850+
22851+static struct platform_driver hiedmacv310_driver = {
22852+	.remove = hiemda_remove,
22853+	.driver = {
22854+		.name   = "hiedmacv310_n",
22855+		.of_match_table = hiedmacv310_match,
22856+	},
22857+};
22858+
22859+static int __init hiedmacv310_init(void)
22860+{
22861+	return platform_driver_probe(&hiedmacv310_driver, hiedmacv310_probe);
22862+}
22863+subsys_initcall(hiedmacv310_init);
22864+
22865+static void __exit hiedmacv310_exit(void)
22866+{
22867+	platform_driver_unregister(&hiedmacv310_driver);
22868+}
22869+module_exit(hiedmacv310_exit);
22870+
22871+MODULE_LICENSE("GPL");
22872+MODULE_AUTHOR("Hisilicon");
22873diff --git a/drivers/hiedmac/hiedmacv310.h b/drivers/hiedmac/hiedmacv310.h
22874new file mode 100644
22875index 000000000..4344d8940
22876--- /dev/null
22877+++ b/drivers/hiedmac/hiedmacv310.h
22878@@ -0,0 +1,184 @@
22879+/*
22880+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
22881+ *
22882+ * This program is free software; you can redistribute it and/or modify
22883+ * it under the terms of the GNU General Public License as published by
22884+ * the Free Software Foundation; either version 2 of the License, or
22885+ * (at your option) any later version.
22886+ *
22887+ * This program is distributed in the hope that it will be useful,
22888+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
22889+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22890+ * GNU General Public License for more details.
22891+ *
22892+ * You should have received a copy of the GNU General Public License
22893+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
22894+ */
22895+
22896+#ifndef __HIEDMACV310_H__
22897+#define __HIEDMACV310_H__
22898+
22899+/* debug control */
22900+extern int hiedmacv310_trace_level_n;
22901+#define HIEDMACV310_TRACE_LEVEL 5
22902+
22903+#define HIEDMACV310_TRACE_FMT KERN_INFO
22904+
22905+typedef void DMAC_ISR(unsigned int channel, int status);
22906+
22907+#define HIEDMAC_UPDATE_TIMEOUT  (30 * HZ)
22908+#define HIEDMAC_TRANS_MAXSIZE     (64 * 1024 - 1)
22909+
22910+#define DEBUG_HIEDMAC
22911+#ifdef  DEBUG_HIEDMAC
22912+
22913+#define hiedmacv310_trace(level, msg...) do { \
22914+    if ((level) >= hiedmacv310_trace_level_n) { \
22915+        printk(HIEDMACV310_TRACE_FMT"%s:%d: ", __func__, __LINE__); \
22916+        printk(msg); \
22917+        printk("\n"); \
22918+    } \
22919+} while (0)
22920+
22921+
22922+#define hiedmacv310_assert(cond) do { \
22923+    if (!(cond)) { \
22924+        printk(KERN_ERR "Assert:hiedmacv310:%s:%d\n", \
22925+                __func__, \
22926+                __LINE__); \
22927+        BUG(); \
22928+    } \
22929+} while (0)
22930+
22931+#define hiedmacv310_error(s...) do { \
22932+    printk(KERN_ERR "hiedmacv310:%s:%d: ", __func__, __LINE__); \
22933+    printk(s); \
22934+    printk("\n"); \
22935+} while (0)
22936+
22937+#else
22938+
22939+#define hiedmacv310_trace(level, msg...) do { } while (0)
22940+#define hiedmacv310_assert(level, msg...) do { } while (0)
22941+#define hiedmacv310_error(level, msg...) do { } while (0)
22942+
22943+#endif
22944+
22945+#define hiedmacv310_readl(addr) ({unsigned int reg = readl((void *)(addr)); \
22946+        reg; })
22947+
22948+#define hiedmacv310_writel(v, addr) do { writel(v, (void *)(addr)); \
22949+} while (0)
22950+
22951+
22952+#define MAX_TRANSFER_BYTES  0xffff
22953+
22954+/* reg offset */
22955+#define HIEDMAC_INT_STAT                  (0x0)
22956+#define HIEDMAC_INT_TC1                   (0x4)
22957+#define HIEDMAC_INT_TC2                   (0x8)
22958+#define HIEDMAC_INT_ERR1                  (0xc)
22959+#define HIEDMAC_INT_ERR2                  (0x10)
22960+#define HIEDMAC_INT_ERR3                  (0x14)
22961+#define HIEDMAC_INT_TC1_MASK              (0x18)
22962+#define HIEDMAC_INT_TC2_MASK              (0x1c)
22963+#define HIEDMAC_INT_ERR1_MASK             (0x20)
22964+#define HIEDMAC_INT_ERR2_MASK             (0x24)
22965+#define HIEDMAC_INT_ERR3_MASK             (0x28)
22966+
22967+#define HIEDMAC_INT_TC1_RAW               (0x600)
22968+#define HIEDMAC_INT_TC2_RAW               (0x608)
22969+#define HIEDMAC_INT_ERR1_RAW              (0x610)
22970+#define HIEDMAC_INT_ERR2_RAW              (0x618)
22971+#define HIEDMAC_INT_ERR3_RAW              (0x620)
22972+
22973+#define HIEDMAC_Cx_CURR_CNT0(cn)          (0x404 + cn * 0x20)
22974+#define HIEDMAC_Cx_CURR_SRC_ADDR_L(cn)    (0x408 + cn * 0x20)
22975+#define HIEDMAC_Cx_CURR_SRC_ADDR_H(cn)    (0x40c + cn * 0x20)
22976+#define HIEDMAC_Cx_CURR_DEST_ADDR_L(cn)    (0x410 + cn * 0x20)
22977+#define HIEDMAC_Cx_CURR_DEST_ADDR_H(cn)    (0x414 + cn * 0x20)
22978+
22979+#define HIEDMAC_CH_PRI                    (0x688)
22980+#define HIEDMAC_CH_STAT                   (0x690)
22981+#define HIEDMAC_DMA_CTRL                  (0x698)
22982+
22983+#define HIEDMAC_Cx_BASE(cn)               (0x800 + cn * 0x40)
22984+#define HIEDMAC_Cx_LLI_L(cn)              (0x800 + cn * 0x40)
22985+#define HIEDMAC_Cx_LLI_H(cn)              (0x804 + cn * 0x40)
22986+#define HIEDMAC_Cx_CNT0(cn)               (0x81c + cn * 0x40)
22987+#define HIEDMAC_Cx_SRC_ADDR_L(cn)         (0x820 + cn * 0x40)
22988+#define HIEDMAC_Cx_SRC_ADDR_H(cn)         (0x824 + cn * 0x40)
22989+#define HIEDMAC_Cx_DEST_ADDR_L(cn)         (0x828 + cn * 0x40)
22990+#define HIEDMAC_Cx_DEST_ADDR_H(cn)         (0x82c + cn * 0x40)
22991+#define HIEDMAC_Cx_CONFIG(cn)             (0x830 + cn * 0x40)
22992+
22993+#define HIEDMAC_CxCONFIG_M2M            0xCFF33000
22994+#define HIEDMAC_CxCONFIG_M2M_LLI        0xCFF00000
22995+#define HIEDMAC_CxCONFIG_CHN_START  0x1
22996+#define HIEDMAC_Cx_DISABLE           0x0
22997+
22998+#define HIEDMAC_ALL_CHAN_CLR        (0xff)
22999+#define HIEDMAC_INT_ENABLE_ALL_CHAN (0xff)
23000+
23001+
23002+#define HIEDMAC_CONFIG_SRC_INC          (1<<31)
23003+#define HIEDMAC_CONFIG_DST_INC          (1<<30)
23004+
23005+#define HIEDMAC_CONFIG_SRC_WIDTH_SHIFT  (16)
23006+#define HIEDMAC_CONFIG_DST_WIDTH_SHIFT  (12)
23007+#define HIEDMAC_WIDTH_8BIT              (0x0)
23008+#define HIEDMAC_WIDTH_16BIT             (0x1)
23009+#define HIEDMAC_WIDTH_32BIT             (0x10)
23010+#define HIEDMAC_WIDTH_64BIT             (0x11)
23011+
23012+#define HIEDMAC_MAX_BURST_WIDTH         (16)
23013+#define HIEDMAC_MIN_BURST_WIDTH         (1)
23014+#define HIEDMAC_CONFIG_SRC_BURST_SHIFT  (24)
23015+#define HIEDMAC_CONFIG_DST_BURST_SHIFT  (20)
23016+
23017+#define HIEDMAC_LLI_ALIGN   0x40
23018+#define HIEDMAC_LLI_DISABLE 0x0
23019+#define HIEDMAC_LLI_ENABLE 0x2
23020+
23021+#define HIEDMAC_CXCONFIG_SIGNAL_SHIFT   (0x4)
23022+#define HIEDMAC_CXCONFIG_MEM_TYPE       (0x0)
23023+#define HIEDMAC_CXCONFIG_DEV_MEM_TYPE   (0x1)
23024+#define HIEDMAC_CXCONFIG_TSF_TYPE_SHIFT (0x2)
23025+#define HIEDMAC_CxCONFIG_LLI_START      (0x1)
23026+
23027+#define HIEDMAC_CXCONFIG_ITC_EN     (0x1)
23028+#define HIEDMAC_CXCONFIG_ITC_EN_SHIFT   (0x1)
23029+
23030+#define CCFG_EN 0x1
23031+
23032+/* DMAC peripheral structure */
23033+typedef struct edmac_peripheral {
23034+	/* peripherial ID */
23035+	unsigned int peri_id;
23036+	/* peripheral data register address */
23037+	unsigned long peri_addr;
23038+	/* config requset */
23039+	int host_sel;
23040+#define DMAC_HOST0 0
23041+#define DMAC_HOST1 1
23042+#define DMAC_NOT_USE (-1)
23043+	/* default channel configuration word */
23044+	unsigned int transfer_cfg;
23045+	/* default channel configuration word */
23046+	unsigned int transfer_width;
23047+	unsigned int dynamic_periphery_num;
23048+} edmac_peripheral;
23049+
23050+
23051+#define PERI_ID_OFFSET  4
23052+#define EDMA_SRC_WIDTH_OFFSET 16
23053+#define EDMA_DST_WIDTH_OFFSET 12
23054+#define EDMA_CH_ENABLE  1
23055+
23056+#define PERI_8BIT_MODE  0
23057+#define PERI_16BIT_MODE 1
23058+#define PERI_32BIT_MODE 2
23059+#define PERI_64BIT_MODE 3
23060+
23061+#define HIEDMAC_LLI_PAGE_NUM 0x4 /* 4*4K*65535B/64≈16MB */
23062+#endif
23063diff --git a/drivers/hisilicon/Kconfig b/drivers/hisilicon/Kconfig
23064new file mode 100644
23065index 000000000..ab5884c08
23066--- /dev/null
23067+++ b/drivers/hisilicon/Kconfig
23068@@ -0,0 +1,4 @@
23069+menu "Hisilicon driver support"
23070+
23071+source "drivers/hisilicon/cma/Kconfig"
23072+endmenu
23073diff --git a/drivers/hisilicon/Makefile b/drivers/hisilicon/Makefile
23074new file mode 100644
23075index 000000000..0ba50a756
23076--- /dev/null
23077+++ b/drivers/hisilicon/Makefile
23078@@ -0,0 +1 @@
23079+obj-$(CONFIG_CMA)			+= cma/
23080diff --git a/drivers/hisilicon/cma/Kconfig b/drivers/hisilicon/cma/Kconfig
23081new file mode 100644
23082index 000000000..7472dccd8
23083--- /dev/null
23084+++ b/drivers/hisilicon/cma/Kconfig
23085@@ -0,0 +1,16 @@
23086+
23087+config CMA_MEM_SHARED
23088+	bool "Support sharing CMA memory with the heap"
23089+	depends on CMA && DMA_CMA
23090+	default no
23091+	help
23092+	  Support sharing CMA memory with the heap.
23093+
23094+config CMA_ADVANCE_SHARE
23095+	bool "Support cma advance share"
23096+	depends on CMA && DMA_CMA
23097+	select CMA_MEM_SHARED
23098+	default no
23099+	help
23100+	  Support advance sharing CMA memory with the heap.
23101+	  CMA Multiplex Ratio will be improved when this macro defined.
23102diff --git a/drivers/hisilicon/cma/Makefile b/drivers/hisilicon/cma/Makefile
23103new file mode 100644
23104index 000000000..eefda7f57
23105--- /dev/null
23106+++ b/drivers/hisilicon/cma/Makefile
23107@@ -0,0 +1,2 @@
23108+
23109+obj-$(CONFIG_CMA) += hi_cma.o
23110diff --git a/drivers/hisilicon/cma/hi_cma.c b/drivers/hisilicon/cma/hi_cma.c
23111new file mode 100644
23112index 000000000..6ce2e2b45
23113--- /dev/null
23114+++ b/drivers/hisilicon/cma/hi_cma.c
23115@@ -0,0 +1,203 @@
23116+/*
23117+ * hi_cma.c
23118+ *
23119+ * Copyright (c) 2019 HiSilicon Technologies Co., Ltd.
23120+ *
23121+ * This program is free software; you can redistribute it and/or modify
23122+ * it under the terms of the GNU General Public License as published by
23123+ * the Free Software Foundation; either version 2 of the License, or
23124+ * (at your option) any later version.
23125+ *
23126+ * This program is distributed in the hope that it will be useful,
23127+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23128+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23129+ * GNU General Public License for more details.
23130+ *
23131+ * You should have received a copy of the GNU General Public License
23132+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
23133+ */
23134+#include <linux/hi_cma.h>
23135+
23136+static u32 num_zones;
23137+static struct cma_zone hisi_zone[ZONE_MAX];
23138+static int use_bootargs;
23139+
23140+unsigned int get_cma_size(void)
23141+{
23142+	u32 i;
23143+	u64 total = 0;
23144+
23145+	for (i = 0; i < num_zones; i++) {
23146+		total += hisi_zone[i].nbytes;
23147+	}
23148+
23149+	/* unit is M */
23150+	return (unsigned int)(total >> 20);
23151+}
23152+
23153+int is_hicma_address(phys_addr_t phys, unsigned long size)
23154+{
23155+	phys_addr_t start, end;
23156+	u32 i;
23157+
23158+	for (i = 0; i < num_zones; i++) {
23159+		start = hisi_zone[i].phys_start;
23160+		end = hisi_zone[i].phys_start + hisi_zone[i].nbytes;
23161+
23162+		if ((phys >= start) && ((phys + size) <= end)) {
23163+			/*
23164+			 * Yes, found!
23165+			 */
23166+			return 1;
23167+		}
23168+	}
23169+
23170+	return 0;
23171+}
23172+EXPORT_SYMBOL(is_hicma_address);
23173+
23174+static int __init hisi_mmz_parse_cmdline(char *s)
23175+{
23176+	char *line = NULL, *tmp = NULL;
23177+	char tmpline[256];
23178+
23179+	if (s == NULL) {
23180+		pr_info("There is no cma zone!\n");
23181+		return 0;
23182+	}
23183+	strncpy(tmpline, s, sizeof(tmpline) - 1);
23184+	tmpline[sizeof(tmpline) - 1] = '\0';
23185+	tmp = tmpline;
23186+
23187+	while ((line = strsep(&tmp, ":")) != NULL) {
23188+		int i;
23189+		char *argv[6];
23190+
23191+		for (i = 0; (argv[i] = strsep(&line, ",")) != NULL;)
23192+			if (++i == ARRAY_SIZE(argv)) {
23193+				break;
23194+			}
23195+
23196+		if (num_zones >= ZONE_MAX)
23197+			return 0;
23198+		hisi_zone[num_zones].pdev.coherent_dma_mask = DMA_BIT_MASK(64);
23199+		if (i == 4) {
23200+			strlcpy(hisi_zone[num_zones].name, argv[0], NAME_LEN_MAX);
23201+			hisi_zone[num_zones].gfp = (uintptr_t)memparse(argv[1], NULL);
23202+			hisi_zone[num_zones].phys_start = (uintptr_t)memparse(argv[2], NULL);
23203+			hisi_zone[num_zones].nbytes = (uintptr_t)memparse(argv[3], NULL);
23204+		}
23205+
23206+		else if (i == 6) {
23207+			strlcpy(hisi_zone[num_zones].name, argv[0], NAME_LEN_MAX);
23208+			hisi_zone[num_zones].gfp = (uintptr_t)memparse(argv[1], NULL);
23209+			hisi_zone[num_zones].phys_start = (uintptr_t)memparse(argv[2], NULL);
23210+			hisi_zone[num_zones].nbytes = (uintptr_t)memparse(argv[3], NULL);
23211+			hisi_zone[num_zones].alloc_type = (uintptr_t)memparse(argv[4], NULL);
23212+			hisi_zone[num_zones].block_align = (uintptr_t)memparse(argv[5], NULL);
23213+		} else {
23214+			pr_err("hisi ion parameter is not correct\n");
23215+			continue;
23216+		}
23217+
23218+		num_zones++;
23219+	}
23220+	if (num_zones != 0) {
23221+		use_bootargs = 1;
23222+	}
23223+
23224+	return 0;
23225+}
23226+early_param("mmz", hisi_mmz_parse_cmdline);
23227+
23228+phys_addr_t hisi_get_zones_start(void)
23229+{
23230+	u32 i;
23231+	phys_addr_t lowest_zone_base = memblock_end_of_DRAM();
23232+
23233+	for (i = 0; i < num_zones; i++) {
23234+		if (lowest_zone_base > hisi_zone[i].phys_start) {
23235+			lowest_zone_base = hisi_zone[i].phys_start;
23236+		}
23237+	}
23238+
23239+	return lowest_zone_base;
23240+}
23241+EXPORT_SYMBOL(hisi_get_zones_start);
23242+
23243+struct cma_zone *hisi_get_cma_zone(const char *name)
23244+{
23245+	u32 i = 0;
23246+
23247+	if (name == NULL)
23248+		return NULL;
23249+	for (i = 0; i < num_zones; i++)
23250+		if (strcmp(hisi_zone[i].name, name) == 0) {
23251+			break;
23252+		}
23253+
23254+	if (i == num_zones) {
23255+		return NULL;
23256+	}
23257+
23258+	return &hisi_zone[i];
23259+}
23260+EXPORT_SYMBOL(hisi_get_cma_zone);
23261+
23262+struct device *hisi_get_cma_device(const char *name)
23263+{
23264+	u32 i = 0;
23265+
23266+	 if (name == NULL)
23267+                 return NULL;
23268+
23269+	for (i = 0; i < num_zones; i++)
23270+		if (strcmp(hisi_zone[i].name, name) == 0) {
23271+			break;
23272+		}
23273+
23274+	if (i == num_zones) {
23275+		return NULL;
23276+	}
23277+
23278+	return &hisi_zone[i].pdev;
23279+}
23280+EXPORT_SYMBOL(hisi_get_cma_device);
23281+
23282+int __init hisi_declare_heap_memory(void)
23283+{
23284+	struct cma *cma;
23285+	u32 i;
23286+	int ret = 0;
23287+
23288+	if (use_bootargs == 0) {
23289+		pr_info("cma zone is not set!\n");
23290+		return ret;
23291+	}
23292+
23293+	for (i = 0; i < num_zones; i++) {
23294+		ret = dma_contiguous_reserve_area(hisi_zone[i].nbytes,
23295+			hisi_zone[i].phys_start, 0, &cma, true);
23296+		if (ret) {
23297+			panic("declare cma zone %s base: %lux size:%lux MB failed. ret:%d",
23298+				hisi_zone[i].name, (unsigned long)hisi_zone[i].phys_start,
23299+				(unsigned long)hisi_zone[i].nbytes >> 20, ret);
23300+		} else {
23301+			hisi_zone[i].pdev.cma_area = cma;
23302+		}
23303+
23304+		hisi_zone[i].phys_start =
23305+			cma_get_base(hisi_zone[i].pdev.cma_area);
23306+		hisi_zone[i].nbytes = cma_get_size(hisi_zone[i].pdev.cma_area);
23307+	}
23308+
23309+	return ret;
23310+}
23311+EXPORT_SYMBOL(hisi_declare_heap_memory);
23312+
23313+static int hisi_mmz_setup(struct reserved_mem *rmem)
23314+{
23315+	return 0;
23316+}
23317+RESERVEDMEM_OF_DECLARE(cma, "hisi-mmz", hisi_mmz_setup);
23318+
23319diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig
23320index 7e693dcbd..c428abba0 100644
23321--- a/drivers/i2c/busses/Kconfig
23322+++ b/drivers/i2c/busses/Kconfig
23323@@ -640,6 +640,16 @@ config I2C_GPIO_FAULT_INJECTOR
23324 	  faults to an I2C bus, so another bus master can be stress-tested.
23325 	  This is for debugging. If unsure, say 'no'.
23326
23327+config I2C_HIBVT
23328+	tristate "Hisilicon BVT I2C Controller"
23329+	depends on ARCH_HISI_BVT
23330+	help
23331+	  Say Y here to include support for Hisilicon BVT I2C controller in the
23332+	  Hisilicon BVT SoCs.
23333+
23334+	  This driver can also be built as a module.  If so, the module
23335+	  will be called i2c-hibvt.
23336+
23337 config I2C_HIGHLANDER
23338 	tristate "Highlander FPGA SMBus interface"
23339 	depends on SH_HIGHLANDER || COMPILE_TEST
23340@@ -1420,4 +1430,20 @@ config I2C_FSI
23341 	  This driver can also be built as a module. If so, the module will be
23342 	  called as i2c-fsi.
23343
23344+config DMA_MSG_MIN_LEN
23345+	int "Hisilicon I2C support DMA minimum LEN"
23346+	depends on I2C_HIBVT
23347+	range 1 4090
23348+	default 5
23349+	help
23350+		The i2c_msg minimum LEN of i2c support DMA,range from 1 to 4091
23351+
23352+config DMA_MSG_MAX_LEN
23353+	int "Hisilicon I2C support DMA maximum LEN"
23354+	depends on I2C_HIBVT
23355+	range DMA_MSG_MIN_LEN 4090
23356+	default 4090
23357+	help
23358+		The i2c_msg maximum LEN of i2c support DMA,range from i2c_msg minimum LEN to 4090,
23359+		because DMA for 0xFFC one-time  largest data transfers;
23360 endmenu
23361diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile
23362index 683c49fac..2c615a7c1 100644
23363--- a/drivers/i2c/busses/Makefile
23364+++ b/drivers/i2c/busses/Makefile
23365@@ -63,6 +63,7 @@ obj-$(CONFIG_I2C_EG20T)		+= i2c-eg20t.o
23366 obj-$(CONFIG_I2C_EMEV2)		+= i2c-emev2.o
23367 obj-$(CONFIG_I2C_EXYNOS5)	+= i2c-exynos5.o
23368 obj-$(CONFIG_I2C_GPIO)		+= i2c-gpio.o
23369+obj-$(CONFIG_I2C_HIBVT)		+= i2c-hibvt.o
23370 obj-$(CONFIG_I2C_HIGHLANDER)	+= i2c-highlander.o
23371 obj-$(CONFIG_I2C_HIX5HD2)	+= i2c-hix5hd2.o
23372 obj-$(CONFIG_I2C_IBM_IIC)	+= i2c-ibm_iic.o
23373diff --git a/drivers/i2c/busses/i2c-hibvt.c b/drivers/i2c/busses/i2c-hibvt.c
23374new file mode 100644
23375index 000000000..4c7cd494a
23376--- /dev/null
23377+++ b/drivers/i2c/busses/i2c-hibvt.c
23378@@ -0,0 +1,1451 @@
23379+/*
23380+ * Hisilicon BVT I2C Controller Driver
23381+ *
23382+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
23383+ *
23384+ * This program is free software; you can redistribute  it and/or modify it
23385+ * under  the terms of  the GNU General Public License as published by the
23386+ * Free Software Foundation;  either version 2 of the  License, or (at your
23387+ * option) any later version.
23388+ *
23389+ * This program is distributed in the hope that it will be useful,
23390+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
23391+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23392+ * GNU General Public License for more details.
23393+ *
23394+ * You should have received a copy of the GNU General Public License
23395+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
23396+ *
23397+ */
23398+#include <linux/slab.h>
23399+#include <linux/clk.h>
23400+#include <linux/delay.h>
23401+#include <linux/i2c.h>
23402+#include <linux/interrupt.h>
23403+#include <linux/io.h>
23404+#include <linux/module.h>
23405+#include <linux/platform_device.h>
23406+#include <linux/dma-mapping.h>
23407+#include <asm/string.h>
23408+
23409+#if defined(CONFIG_HI_DMAC)
23410+#include <linux/hidmac.h>
23411+#endif
23412+
23413+#if defined(CONFIG_HIEDMAC)
23414+#include <linux/hiedmac.h>
23415+#endif
23416+
23417+/*
23418+ * I2C Registers offsets
23419+ */
23420+#define HIBVT_I2C_GLB		0x0
23421+#define HIBVT_I2C_SCL_H		0x4
23422+#define HIBVT_I2C_SCL_L		0x8
23423+#define HIBVT_I2C_DATA1		0x10
23424+#define HIBVT_I2C_TXF		0x20
23425+#define HIBVT_I2C_RXF		0x24
23426+#define HIBVT_I2C_CMD_BASE	0x30
23427+#define HIBVT_I2C_LOOP1		0xb0
23428+#define HIBVT_I2C_DST1		0xb4
23429+#define HIBVT_I2C_LOOP2     0xb8
23430+#define HIBVT_I2C_DST2      0xbc
23431+#define HIBVT_I2C_TX_WATER	0xc8
23432+#define HIBVT_I2C_RX_WATER	0xcc
23433+#define HIBVT_I2C_CTRL1		0xd0
23434+#define HIBVT_I2C_CTRL2		0xd4
23435+#define HIBVT_I2C_STAT		0xd8
23436+#define HIBVT_I2C_INTR_RAW	0xe0
23437+#define HIBVT_I2C_INTR_EN	0xe4
23438+#define HIBVT_I2C_INTR_STAT	0xe8
23439+
23440+/*
23441+ * I2C Global Config Register -- HIBVT_I2C_GLB
23442+ */
23443+#define GLB_EN_MASK		BIT(0)
23444+#define GLB_SDA_HOLD_MASK	GENMASK(23, 8)
23445+#define GLB_SDA_HOLD_SHIFT	(8)
23446+#define should_copy_to_continuous_mem(addr) true
23447+
23448+/*
23449+ * I2C Timing CMD Register -- HIBVT_I2C_CMD_BASE + n * 4 (n = 0, 1, 2, ... 31)
23450+ */
23451+#define CMD_EXIT	0x0
23452+#define CMD_TX_S	0x1
23453+#define CMD_TX_D1_2	0x4
23454+#define CMD_TX_D1_1	0x5
23455+#define CMD_TX_FIFO	0x9
23456+#define CMD_RX_FIFO	0x12
23457+#define CMD_RX_ACK	0x13
23458+#define CMD_IGN_ACK	0x15
23459+#define CMD_TX_ACK	0x16
23460+#define CMD_TX_NACK	0x17
23461+#define CMD_JMP1	0x18
23462+#define CMD_JMP2    0x19
23463+#define CMD_UP_TXF	0x1d
23464+#define CMD_TX_RS	0x1e
23465+#define CMD_TX_P	0x1f
23466+
23467+/*
23468+ * I2C Control Register 1 -- HIBVT_I2C_CTRL1
23469+ */
23470+#define CTRL1_CMD_START_MASK	BIT(0)
23471+#define CTRL1_DMA_OP_MASK	(0x3 << 8)
23472+#define CTRL1_DMA_R		(0x3 << 8)
23473+#define CTRL1_DMA_W		(0x2 << 8)
23474+
23475+/*
23476+ * I2C Status Register -- HIBVT_I2C_STAT
23477+ */
23478+#define STAT_RXF_NOE_MASK	BIT(16) /* RX FIFO not empty flag */
23479+#define STAT_TXF_NOF_MASK	BIT(19) /* TX FIFO not full flag */
23480+
23481+/*
23482+ * I2C Interrupt status and mask Register --
23483+ * HIBVT_I2C_INTR_RAW, HIBVT_I2C_STAT, HIBVT_I2C_INTR_STAT
23484+ */
23485+#define INTR_ABORT_MASK		(BIT(0) | BIT(11))
23486+#define INTR_RX_MASK		BIT(2)
23487+#define INTR_TX_MASK		BIT(4)
23488+#define INTR_CMD_DONE_MASK	BIT(12)
23489+#define INTR_USE_MASK		(INTR_ABORT_MASK \
23490+				|INTR_RX_MASK \
23491+				| INTR_TX_MASK \
23492+				| INTR_CMD_DONE_MASK)
23493+#define INTR_ALL_MASK		GENMASK(31, 0)
23494+
23495+#define I2C_DEFAULT_FREQUENCY	100000
23496+#define I2C_TXF_DEPTH		64
23497+#define I2C_RXF_DEPTH		64
23498+#define I2C_TXF_WATER		32
23499+#define I2C_RXF_WATER		32
23500+#define I2C_WAIT_TIMEOUT	0x400
23501+#define I2C_IRQ_TIMEOUT		(msecs_to_jiffies(1000))
23502+
23503+struct hibvt_i2c_dev {
23504+	struct device *dev;
23505+	struct i2c_adapter adap;
23506+	resource_size_t phybase;
23507+	void __iomem *base;
23508+	struct clk *clk;
23509+	int irq;
23510+
23511+	unsigned int		freq;
23512+	struct i2c_msg *msg;
23513+	unsigned int		msg_num;
23514+	unsigned int		msg_idx;
23515+	unsigned int		msg_buf_ptr;
23516+	struct completion	msg_complete;
23517+
23518+	spinlock_t		lock;
23519+	int			status;
23520+};
23521+static inline void hibvt_i2c_disable(const struct hibvt_i2c_dev *i2c);
23522+static inline void hibvt_i2c_cfg_irq(const struct hibvt_i2c_dev *i2c,
23523+				     unsigned int flag);
23524+static inline unsigned int hibvt_i2c_clr_irq(const struct hibvt_i2c_dev *i2c);
23525+static inline void hibvt_i2c_enable(const struct hibvt_i2c_dev *i2c);
23526+
23527+#define CHECK_SDA_IN_SHIFT     (16)
23528+#define GPIO_MODE_SHIFT        (8)
23529+#define FORCE_SCL_OEN_SHIFT    (4)
23530+#define FORCE_SDA_OEN_SHIFT    (0)
23531+
23532+static void hibvt_i2c_rescue(const struct hibvt_i2c_dev *i2c)
23533+{
23534+	unsigned int val;
23535+	unsigned int time_cnt;
23536+	int index;
23537+
23538+	hibvt_i2c_disable(i2c);
23539+	hibvt_i2c_cfg_irq(i2c, 0);
23540+	hibvt_i2c_clr_irq(i2c);
23541+
23542+	val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) |
23543+	      (0x1 << FORCE_SDA_OEN_SHIFT);
23544+	writel(val, i2c->base + HIBVT_I2C_CTRL2);
23545+
23546+	time_cnt = 0;
23547+	do {
23548+		for (index = 0; index < 9; index++) {
23549+			val = (0x1 << GPIO_MODE_SHIFT) | 0x1;
23550+			writel(val, i2c->base + HIBVT_I2C_CTRL2);
23551+
23552+			udelay(5);
23553+
23554+			val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) |
23555+			      (0x1 << FORCE_SDA_OEN_SHIFT);
23556+			writel(val, i2c->base + HIBVT_I2C_CTRL2);
23557+
23558+			udelay(5);
23559+		}
23560+
23561+		time_cnt++;
23562+		if (time_cnt > I2C_WAIT_TIMEOUT) {
23563+			dev_err(i2c->dev, "wait Timeout!\n");
23564+			goto disable_rescue;
23565+		}
23566+
23567+		val = readl(i2c->base + HIBVT_I2C_CTRL2);
23568+	} while (!(val & (0x1 << CHECK_SDA_IN_SHIFT)));
23569+
23570+	val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) |
23571+	      (0x1 << FORCE_SDA_OEN_SHIFT);
23572+	writel(val, i2c->base + HIBVT_I2C_CTRL2);
23573+
23574+	val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT);
23575+	writel(val, i2c->base + HIBVT_I2C_CTRL2);
23576+
23577+	udelay(10);
23578+
23579+	val = (0x1 << GPIO_MODE_SHIFT) | (0x1 << FORCE_SCL_OEN_SHIFT) |
23580+	      (0x1 << FORCE_SDA_OEN_SHIFT);
23581+	writel(val, i2c->base + HIBVT_I2C_CTRL2);
23582+
23583+disable_rescue:
23584+	val = (0x1 << FORCE_SCL_OEN_SHIFT) | 0x1;
23585+	writel(val, i2c->base + HIBVT_I2C_CTRL2);
23586+}
23587+
23588+static inline void hibvt_i2c_disable(const struct hibvt_i2c_dev *i2c)
23589+{
23590+	unsigned int val;
23591+
23592+	val = readl(i2c->base + HIBVT_I2C_GLB);
23593+	val &= ~GLB_EN_MASK;
23594+	writel(val, i2c->base + HIBVT_I2C_GLB);
23595+}
23596+
23597+static inline void hibvt_i2c_enable(const struct hibvt_i2c_dev *i2c)
23598+{
23599+	unsigned int val;
23600+
23601+	val = readl(i2c->base + HIBVT_I2C_GLB);
23602+	val |= GLB_EN_MASK;
23603+	writel(val, i2c->base + HIBVT_I2C_GLB);
23604+}
23605+
23606+static inline void hibvt_i2c_cfg_irq(const struct hibvt_i2c_dev *i2c,
23607+				     unsigned int flag)
23608+{
23609+	writel(flag, i2c->base + HIBVT_I2C_INTR_EN);
23610+}
23611+
23612+static inline void hibvt_i2c_disable_irq(const struct hibvt_i2c_dev *i2c,
23613+		unsigned int flag)
23614+{
23615+	unsigned int val;
23616+
23617+	val = readl(i2c->base + HIBVT_I2C_INTR_EN);
23618+	val &= ~flag;
23619+	writel(val, i2c->base + HIBVT_I2C_INTR_EN);
23620+}
23621+
23622+static inline unsigned int hibvt_i2c_clr_irq(const struct hibvt_i2c_dev *i2c)
23623+{
23624+	unsigned int val;
23625+
23626+	val = readl(i2c->base + HIBVT_I2C_INTR_STAT);
23627+	writel(INTR_ALL_MASK, i2c->base + HIBVT_I2C_INTR_RAW);
23628+
23629+	return val;
23630+}
23631+
23632+static inline void hibvt_i2c_cmdreg_set(const struct hibvt_i2c_dev *i2c,
23633+					unsigned int cmd, unsigned int *offset)
23634+{
23635+	dev_dbg(i2c->dev, "hii2c reg: offset=0x%x, cmd=0x%x...\n",
23636+		*offset * 4, cmd);
23637+	writel(cmd, i2c->base + HIBVT_I2C_CMD_BASE + *offset * 4);
23638+	(*offset)++;
23639+}
23640+
23641+/*
23642+ * config i2c slave addr
23643+ */
23644+static inline void hibvt_i2c_set_addr(const struct hibvt_i2c_dev *i2c)
23645+{
23646+	struct i2c_msg *msg = i2c->msg;
23647+	u16 addr;
23648+
23649+	if (msg->flags & I2C_M_TEN) {
23650+		/* First byte is 11110XX0 where XX is upper 2 bits */
23651+		addr = ((msg->addr & 0x300) << 1) | 0xf000;
23652+		if (msg->flags & I2C_M_RD)
23653+			addr |= 1 << 8;
23654+
23655+		/* Second byte is the remaining 8 bits */
23656+		addr |= msg->addr & 0xff;
23657+	} else {
23658+		addr = (msg->addr & 0x7f) << 1;
23659+		if (msg->flags & I2C_M_RD)
23660+			addr |= 1;
23661+	}
23662+
23663+	writel(addr, i2c->base + HIBVT_I2C_DATA1);
23664+}
23665+
23666+/*
23667+ * Start command sequence
23668+ */
23669+static inline void hibvt_i2c_start_cmd(const struct hibvt_i2c_dev *i2c)
23670+{
23671+	unsigned int val;
23672+
23673+	val = readl(i2c->base + HIBVT_I2C_CTRL1);
23674+	val |= CTRL1_CMD_START_MASK;
23675+	writel(val, i2c->base + HIBVT_I2C_CTRL1);
23676+}
23677+
23678+static int hibvt_i2c_wait_rx_noempty(const struct hibvt_i2c_dev *i2c)
23679+{
23680+	unsigned int time_cnt = 0;
23681+	unsigned int val;
23682+
23683+	do {
23684+		val = readl(i2c->base + HIBVT_I2C_STAT);
23685+		if (val & STAT_RXF_NOE_MASK)
23686+			return 0;
23687+
23688+		udelay(50);
23689+	} while (time_cnt++ < I2C_WAIT_TIMEOUT);
23690+
23691+	hibvt_i2c_rescue(i2c);
23692+
23693+	dev_err(i2c->dev, "wait rx no empty timeout, RIS: 0x%x, SR: 0x%x\n",
23694+		readl(i2c->base + HIBVT_I2C_INTR_RAW), val);
23695+	return -EIO;
23696+}
23697+
23698+static int hibvt_i2c_wait_tx_nofull(const struct hibvt_i2c_dev *i2c)
23699+{
23700+	unsigned int time_cnt = 0;
23701+	unsigned int val;
23702+
23703+	do {
23704+		val = readl(i2c->base + HIBVT_I2C_STAT);
23705+		if (val & STAT_TXF_NOF_MASK)
23706+			return 0;
23707+
23708+		udelay(50);
23709+	} while (time_cnt++ < I2C_WAIT_TIMEOUT);
23710+
23711+	hibvt_i2c_rescue(i2c);
23712+
23713+	dev_err(i2c->dev, "wait rx no empty timeout, RIS: 0x%x, SR: 0x%x\n",
23714+		readl(i2c->base + HIBVT_I2C_INTR_RAW), val);
23715+	return -EIO;
23716+}
23717+
23718+static int hibvt_i2c_wait_idle(const struct hibvt_i2c_dev *i2c)
23719+{
23720+	unsigned int time_cnt = 0;
23721+	unsigned int val;
23722+
23723+	do {
23724+		val = readl(i2c->base + HIBVT_I2C_INTR_RAW);
23725+		if (val & (INTR_ABORT_MASK)) {
23726+			dev_err(i2c->dev, "wait idle abort!, RIS: 0x%x\n",
23727+				val);
23728+			return -EIO;
23729+		}
23730+
23731+		if (val & INTR_CMD_DONE_MASK)
23732+			return 0;
23733+
23734+		udelay(50);
23735+	} while (time_cnt++ < I2C_WAIT_TIMEOUT);
23736+
23737+	hibvt_i2c_rescue(i2c);
23738+
23739+	dev_err(i2c->dev, "wait idle timeout, RIS: 0x%x, SR: 0x%x\n",
23740+		val, readl(i2c->base + HIBVT_I2C_STAT));
23741+
23742+	return -EIO;
23743+}
23744+
23745+static void hibvt_i2c_set_freq(struct hibvt_i2c_dev *i2c)
23746+{
23747+	unsigned int max_freq, freq;
23748+	unsigned int clk_rate;
23749+	unsigned int val;
23750+
23751+	freq = i2c->freq;
23752+	clk_rate = clk_get_rate(i2c->clk);
23753+	max_freq = clk_rate >> 1;
23754+
23755+	if (freq > max_freq) {
23756+		i2c->freq = max_freq;
23757+		freq = i2c->freq;
23758+	}
23759+
23760+	if (!freq) {
23761+		pr_err("hibvt_i2c_set_freq:freq can't be zero!");
23762+		return;
23763+	}
23764+
23765+	if (freq <= 100000) {
23766+		/* in normal mode               F_scl: freq
23767+		   i2c_scl_hcnt = (F_i2c / F_scl) * 0.5
23768+		   i2c_scl_hcnt = (F_i2c / F_scl) * 0.5
23769+		 */
23770+		val = clk_rate / (freq * 2);
23771+		writel(val, i2c->base + HIBVT_I2C_SCL_H);
23772+		writel(val, i2c->base + HIBVT_I2C_SCL_L);
23773+	} else {
23774+		/* in fast mode         F_scl: freq
23775+		   i2c_scl_hcnt = (F_i2c / F_scl) * 0.36
23776+		   i2c_scl_hcnt = (F_i2c / F_scl) * 0.64
23777+		 */
23778+		val = ((clk_rate / 100) * 36) / freq;
23779+		writel(val, i2c->base + HIBVT_I2C_SCL_H);
23780+		val = ((clk_rate / 100) * 64) / freq;
23781+		writel(val, i2c->base + HIBVT_I2C_SCL_L);
23782+	}
23783+
23784+	val = readl(i2c->base + HIBVT_I2C_GLB);
23785+	val &= ~GLB_SDA_HOLD_MASK;
23786+	val |= ((0xa << GLB_SDA_HOLD_SHIFT) & GLB_SDA_HOLD_MASK);
23787+	writel(val, i2c->base + HIBVT_I2C_GLB);
23788+}
23789+
23790+/*
23791+ * set i2c controller TX and RX FIFO water
23792+ */
23793+static inline void hibvt_i2c_set_water(const struct hibvt_i2c_dev *i2c)
23794+{
23795+	writel(I2C_TXF_WATER, i2c->base + HIBVT_I2C_TX_WATER);
23796+	writel(I2C_RXF_WATER, i2c->base + HIBVT_I2C_RX_WATER);
23797+}
23798+
23799+/*
23800+ * initialise the controller, set i2c bus interface freq
23801+ */
23802+static void hibvt_i2c_hw_init(struct hibvt_i2c_dev *i2c)
23803+{
23804+	hibvt_i2c_disable(i2c);
23805+	hibvt_i2c_disable_irq(i2c, INTR_ALL_MASK);
23806+	hibvt_i2c_set_freq(i2c);
23807+	hibvt_i2c_set_water(i2c);
23808+}
23809+
23810+/*
23811+ * hibvt_i2c_cfg_cmd - config i2c controller command sequence
23812+ *
23813+ * After all the timing command is configured,
23814+ * and then start the command, you can i2c communication,
23815+ * and then only need to read and write i2c fifo.
23816+ */
23817+static void hibvt_i2c_cfg_cmd(const struct hibvt_i2c_dev *i2c)
23818+{
23819+	struct i2c_msg *msg = i2c->msg;
23820+	int offset = 0;
23821+
23822+	if (i2c->msg_idx == 0)
23823+		hibvt_i2c_cmdreg_set(i2c, CMD_TX_S, &offset);
23824+	else
23825+		hibvt_i2c_cmdreg_set(i2c, CMD_TX_RS, &offset);
23826+
23827+	if (msg->flags & I2C_M_TEN) {
23828+		if (i2c->msg_idx == 0) {
23829+			hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset);
23830+			hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset);
23831+		} else {
23832+			hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset);
23833+		}
23834+	} else {
23835+		hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset);
23836+	}
23837+
23838+	if (msg->flags & I2C_M_IGNORE_NAK)
23839+		hibvt_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset);
23840+	else
23841+		hibvt_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset);
23842+
23843+	if (msg->flags & I2C_M_RD) {
23844+		if (msg->len >= 2) {
23845+			writel(offset, i2c->base + HIBVT_I2C_DST1);
23846+			writel(msg->len - 2, i2c->base + HIBVT_I2C_LOOP1);
23847+			hibvt_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset);
23848+			hibvt_i2c_cmdreg_set(i2c, CMD_TX_ACK, &offset);
23849+			hibvt_i2c_cmdreg_set(i2c, CMD_JMP1, &offset);
23850+		}
23851+		hibvt_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset);
23852+		hibvt_i2c_cmdreg_set(i2c, CMD_TX_NACK, &offset);
23853+	} else {
23854+		writel(offset, i2c->base + HIBVT_I2C_DST1);
23855+		writel(msg->len - 1, i2c->base + HIBVT_I2C_LOOP1);
23856+		hibvt_i2c_cmdreg_set(i2c, CMD_UP_TXF, &offset);
23857+		hibvt_i2c_cmdreg_set(i2c, CMD_TX_FIFO, &offset);
23858+
23859+		if (msg->flags & I2C_M_IGNORE_NAK)
23860+			hibvt_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset);
23861+		else
23862+			hibvt_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset);
23863+
23864+		hibvt_i2c_cmdreg_set(i2c, CMD_JMP1, &offset);
23865+	}
23866+
23867+	if ((i2c->msg_idx == (i2c->msg_num - 1)) || (msg->flags & I2C_M_STOP)) {
23868+		dev_dbg(i2c->dev, "run to %s %d...TX STOP\n",
23869+			__func__, __LINE__);
23870+		hibvt_i2c_cmdreg_set(i2c, CMD_TX_P, &offset);
23871+	}
23872+
23873+	hibvt_i2c_cmdreg_set(i2c, CMD_EXIT, &offset);
23874+}
23875+
23876+static void hibvt_i2c_cfg_cmd_mul_reg(struct hibvt_i2c_dev *i2c,unsigned int reg_data_width)
23877+{
23878+	struct i2c_msg *msg = i2c->msg;
23879+	int offset = 0;
23880+	int i;
23881+
23882+	if (i2c->msg_idx == 0) {
23883+		hibvt_i2c_cmdreg_set(i2c, CMD_TX_S, &offset);
23884+	} else {
23885+		hibvt_i2c_cmdreg_set(i2c, CMD_TX_RS, &offset);
23886+	}
23887+
23888+	if (msg->flags & I2C_M_TEN) {
23889+		if (i2c->msg_idx == 0) {
23890+			hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset);
23891+			hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset);
23892+		} else {
23893+			hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_2, &offset);
23894+		}
23895+	} else {
23896+		hibvt_i2c_cmdreg_set(i2c, CMD_TX_D1_1, &offset);
23897+	}
23898+
23899+	if (msg->flags & I2C_M_IGNORE_NAK) {
23900+		hibvt_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset);
23901+	} else {
23902+		hibvt_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset);
23903+	}
23904+
23905+	if (msg->flags & I2C_M_RD) {
23906+		if (msg->len >= 2) {
23907+			writel(offset, i2c->base + HIBVT_I2C_DST1);
23908+			writel(msg->len - 2, i2c->base + HIBVT_I2C_LOOP1);
23909+			hibvt_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset);
23910+			hibvt_i2c_cmdreg_set(i2c, CMD_TX_ACK, &offset);
23911+			hibvt_i2c_cmdreg_set(i2c, CMD_JMP1, &offset);
23912+		}
23913+		hibvt_i2c_cmdreg_set(i2c, CMD_RX_FIFO, &offset);
23914+		hibvt_i2c_cmdreg_set(i2c, CMD_TX_NACK, &offset);
23915+	} else {
23916+		for(i = 0; i < reg_data_width - 1; i++){
23917+			hibvt_i2c_cmdreg_set(i2c, CMD_UP_TXF, &offset);
23918+			hibvt_i2c_cmdreg_set(i2c, CMD_TX_FIFO, &offset);
23919+			hibvt_i2c_cmdreg_set(i2c, CMD_RX_ACK, &offset);
23920+		}
23921+		hibvt_i2c_cmdreg_set(i2c, CMD_UP_TXF, &offset);
23922+		hibvt_i2c_cmdreg_set(i2c, CMD_TX_FIFO, &offset);
23923+		hibvt_i2c_cmdreg_set(i2c, CMD_IGN_ACK, &offset);
23924+	}
23925+
23926+	hibvt_i2c_cmdreg_set(i2c, CMD_TX_P, &offset);
23927+	if(((msg->len / reg_data_width) - 1) > 0){
23928+		writel(0, i2c->base + HIBVT_I2C_DST2);
23929+		writel((msg->len / reg_data_width) - 1, i2c->base + HIBVT_I2C_LOOP2);
23930+		hibvt_i2c_cmdreg_set(i2c, CMD_JMP2, &offset);
23931+	}
23932+	hibvt_i2c_cmdreg_set(i2c, CMD_EXIT, &offset);
23933+}
23934+
23935+static inline void check_i2c_send_complete(struct hibvt_i2c_dev *i2c)
23936+{
23937+	unsigned int val;
23938+	val = readl(i2c->base + HIBVT_I2C_GLB);
23939+	if(val & GLB_EN_MASK){
23940+		hibvt_i2c_wait_idle(i2c);
23941+		hibvt_i2c_disable(i2c);
23942+	}
23943+}
23944+
23945+#if defined(CONFIG_HI_DMAC) || defined(CONFIG_HIEDMAC)
23946+int dma_to_i2c(unsigned long src, unsigned int dst, unsigned int length)
23947+{
23948+	int chan;
23949+
23950+	chan = do_dma_m2p(src, dst, length);
23951+	if (chan == -1)
23952+		pr_err("dma_to_i2c error\n");
23953+
23954+	return chan;
23955+}
23956+
23957+int i2c_to_dma(unsigned int src, unsigned long dst,
23958+	       unsigned int length)
23959+{
23960+	int chan;
23961+
23962+	chan = do_dma_p2m(dst, src, length);
23963+	if (chan == -1)
23964+		pr_err("dma_p2m error...\n");
23965+
23966+	return chan;
23967+}
23968+
23969+static int hibvt_i2c_do_dma_write(struct hibvt_i2c_dev *i2c,
23970+				  unsigned long dma_dst_addr)
23971+{
23972+	int chan, val;
23973+	int status = 0;
23974+	struct i2c_msg *msg = i2c->msg;
23975+
23976+	check_i2c_send_complete(i2c);
23977+	hibvt_i2c_set_freq(i2c);
23978+	writel(0x1, i2c->base + HIBVT_I2C_TX_WATER);
23979+	hibvt_i2c_enable(i2c);
23980+	hibvt_i2c_clr_irq(i2c);
23981+	hibvt_i2c_set_addr(i2c);
23982+	hibvt_i2c_cfg_cmd(i2c);
23983+
23984+	/*  transmit DATA from DMAC to I2C in DMA mode */
23985+	chan = dma_to_i2c(dma_dst_addr, (i2c->phybase + HIBVT_I2C_TXF),
23986+			  msg->len);
23987+	if (chan == -1) {
23988+		status = -1;
23989+		goto fail_0;
23990+	}
23991+
23992+	val = readl(i2c->base + HIBVT_I2C_CTRL1);
23993+	val &= ~CTRL1_DMA_OP_MASK;
23994+	val |= CTRL1_DMA_W | CTRL1_CMD_START_MASK;
23995+	writel(val, i2c->base + HIBVT_I2C_CTRL1);
23996+
23997+	if (dmac_wait(chan) != DMAC_CHN_SUCCESS) {
23998+		status = -1;
23999+		goto fail_1;
24000+	}
24001+
24002+	status = hibvt_i2c_wait_idle(i2c);
24003+
24004+fail_1:
24005+	dmac_channel_free((unsigned int)chan);
24006+fail_0:
24007+	hibvt_i2c_disable(i2c);
24008+
24009+	return status;
24010+}
24011+
24012+static int hibvt_i2c_do_dma_write_mul_reg(struct hibvt_i2c_dev *i2c,
24013+				  unsigned long dma_dst_addr, unsigned int reg_data_width)
24014+{
24015+	int chan, val, status = 0;
24016+	struct i2c_msg *msg = i2c->msg;
24017+
24018+
24019+	check_i2c_send_complete(i2c);
24020+	hibvt_i2c_set_freq(i2c);
24021+	writel(0x1, i2c->base + HIBVT_I2C_TX_WATER);
24022+	hibvt_i2c_enable(i2c);
24023+	hibvt_i2c_clr_irq(i2c);
24024+	hibvt_i2c_set_addr(i2c);
24025+	hibvt_i2c_cfg_cmd_mul_reg(i2c, reg_data_width);
24026+
24027+	/*  transmit DATA from DMAC to I2C in DMA mode */
24028+	chan = dma_to_i2c(dma_dst_addr, (i2c->phybase + HIBVT_I2C_TXF),
24029+			  msg->len);
24030+	if (chan == -1) {
24031+		status = -1;
24032+		goto fail_0;
24033+	}
24034+
24035+	val = readl(i2c->base + HIBVT_I2C_CTRL1);
24036+	val &= ~CTRL1_DMA_OP_MASK;
24037+	val |= CTRL1_DMA_W | CTRL1_CMD_START_MASK;
24038+	writel(val, i2c->base + HIBVT_I2C_CTRL1);
24039+
24040+fail_0:
24041+	return status;
24042+}
24043+
24044+static int hibvt_i2c_do_dma_read(struct hibvt_i2c_dev *i2c,
24045+				 unsigned long dma_dst_addr)
24046+{
24047+	int val, chan;
24048+	int status = 0;
24049+	struct i2c_msg *msg = i2c->msg;
24050+
24051+	check_i2c_send_complete(i2c);
24052+	hibvt_i2c_set_freq(i2c);
24053+	writel(0x0, i2c->base + HIBVT_I2C_RX_WATER);
24054+	hibvt_i2c_enable(i2c);
24055+	hibvt_i2c_clr_irq(i2c);
24056+	hibvt_i2c_set_addr(i2c);
24057+	hibvt_i2c_cfg_cmd(i2c);
24058+
24059+	/* transmit DATA from I2C to DMAC in DMA mode */
24060+	chan = i2c_to_dma((i2c->phybase + HIBVT_I2C_RXF),
24061+			  dma_dst_addr, msg->len);
24062+	if (chan == -1) {
24063+		status = -1;
24064+		goto fail_0;
24065+	}
24066+
24067+	val = readl(i2c->base + HIBVT_I2C_CTRL1);
24068+	val &= ~CTRL1_DMA_OP_MASK;
24069+	val |= CTRL1_CMD_START_MASK | CTRL1_DMA_R;
24070+	writel(val, i2c->base + HIBVT_I2C_CTRL1);
24071+
24072+	if (dmac_wait(chan) != DMAC_CHN_SUCCESS) {
24073+		status = -1;
24074+		goto fail_1;
24075+	}
24076+
24077+	status = hibvt_i2c_wait_idle(i2c);
24078+
24079+fail_1:
24080+	dmac_channel_free((unsigned int)chan);
24081+fail_0:
24082+	hibvt_i2c_disable(i2c);
24083+
24084+	return status;
24085+}
24086+
24087+static int copy_to_continuous_mem(struct hibvt_i2c_dev *i2c)
24088+{
24089+	if (should_copy_to_continuous_mem(i2c->msg->buf)) {
24090+		i2c->msg->highmem_buf = i2c->msg->buf;
24091+		i2c->msg->buf = kmalloc(i2c->msg->len, GFP_KERNEL | __GFP_ATOMIC);
24092+		if (i2c->msg->buf == NULL) {
24093+			i2c->msg->buf = i2c->msg->highmem_buf;
24094+			dev_err(i2c->dev, "Allocate continuous memory fail.\n");
24095+			return -EINVAL;
24096+		}
24097+	} else {
24098+		i2c->msg->highmem_buf = NULL;
24099+	}
24100+	return 0;
24101+}
24102+
24103+static int hibvt_i2c_dma_xfer_one_msg(struct hibvt_i2c_dev *i2c)
24104+{
24105+	unsigned int status;
24106+	struct i2c_msg *msg = i2c->msg;
24107+	dma_addr_t dma_dst_addr;
24108+
24109+	dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n",
24110+		__func__, __LINE__, msg->flags, msg->len);
24111+
24112+	if (copy_to_continuous_mem(i2c))
24113+		return -EINVAL;
24114+
24115+	if (msg->flags & I2C_M_RD) {
24116+		mb();
24117+		dma_dst_addr = dma_map_single(i2c->dev, msg->buf,
24118+					      msg->len, DMA_FROM_DEVICE);
24119+		status = dma_mapping_error(i2c->dev, dma_dst_addr);
24120+		if (status) {
24121+			dev_err(i2c->dev, "DMA mapping failed\n");
24122+			goto out;
24123+		}
24124+
24125+		status = hibvt_i2c_do_dma_read(i2c, dma_dst_addr);
24126+
24127+		dma_unmap_single(i2c->dev, dma_dst_addr, msg->len, DMA_FROM_DEVICE);
24128+		mb();
24129+		if (i2c->msg->highmem_buf)
24130+			memcpy(msg->highmem_buf, msg->buf, msg->len);
24131+	} else {
24132+		if (i2c->msg->highmem_buf)
24133+			memcpy(msg->buf, msg->highmem_buf, msg->len);
24134+		mb();
24135+		dma_dst_addr = dma_map_single(i2c->dev, msg->buf,
24136+					      msg->len, DMA_TO_DEVICE);
24137+		status = dma_mapping_error(i2c->dev, dma_dst_addr);
24138+		if (status) {
24139+			dev_err(i2c->dev, "DMA mapping failed\n");
24140+			goto out;
24141+		}
24142+
24143+		status = hibvt_i2c_do_dma_write(i2c, dma_dst_addr);
24144+		dma_unmap_single(i2c->dev, dma_dst_addr, msg->len, DMA_TO_DEVICE);
24145+		mb();
24146+	}
24147+
24148+out:
24149+	if (i2c->msg->highmem_buf) {
24150+		kfree(msg->buf);
24151+		msg->buf = msg->highmem_buf;
24152+		msg->highmem_buf = NULL;
24153+	}
24154+
24155+	if (!status) {
24156+		status = hibvt_i2c_wait_idle(i2c);
24157+		hibvt_i2c_disable(i2c);
24158+	}
24159+
24160+	return status;
24161+}
24162+
24163+static int hibvt_i2c_dma_xfer_one_msg_mul_reg(struct hibvt_i2c_dev *i2c, unsigned int reg_data_width)
24164+{
24165+	unsigned int status;
24166+	struct i2c_msg *msg = i2c->msg;
24167+	dma_addr_t dma_dst_addr;
24168+
24169+
24170+	dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n",
24171+		__func__, __LINE__, msg->flags, msg->len);
24172+
24173+	if (copy_to_continuous_mem(i2c))
24174+		return -EINVAL;
24175+
24176+	if (msg->flags & I2C_M_RD) {
24177+		mb();
24178+		dma_dst_addr = dma_map_single(i2c->dev, msg->buf,
24179+					      msg->len, DMA_FROM_DEVICE);
24180+		status = dma_mapping_error(i2c->dev, dma_dst_addr);
24181+		if (status) {
24182+			dev_err(i2c->dev, "DMA mapping failed\n");
24183+			goto out;
24184+		}
24185+
24186+		status = hibvt_i2c_do_dma_read(i2c, dma_dst_addr);
24187+
24188+		dma_unmap_single(i2c->dev, dma_dst_addr, msg->len, DMA_FROM_DEVICE);
24189+		mb();
24190+		if (i2c->msg->highmem_buf)
24191+			memcpy(msg->highmem_buf, msg->buf, msg->len);
24192+	} else {
24193+		if (i2c->msg->highmem_buf)
24194+			memcpy(msg->buf, msg->highmem_buf, msg->len);
24195+		mb();
24196+		dma_dst_addr = dma_map_single(i2c->dev, msg->buf,
24197+					      msg->len, DMA_TO_DEVICE);
24198+		status = dma_mapping_error(i2c->dev, dma_dst_addr);
24199+		if (status) {
24200+			dev_err(i2c->dev, "DMA mapping failed\n");
24201+			goto out;
24202+		}
24203+
24204+		status = hibvt_i2c_do_dma_write_mul_reg(i2c, dma_dst_addr, reg_data_width);
24205+		dma_unmap_single(i2c->dev, dma_dst_addr, msg->len, DMA_TO_DEVICE);
24206+		mb();
24207+	}
24208+
24209+out:
24210+	if (i2c->msg->highmem_buf) {
24211+		kfree(msg->buf);
24212+		msg->buf = msg->highmem_buf;
24213+		msg->highmem_buf = NULL;
24214+	}
24215+	return status;
24216+}
24217+#endif
24218+static int hibvt_i2c_polling_xfer_one_msg(struct hibvt_i2c_dev *i2c)
24219+{
24220+	int status;
24221+	unsigned int val;
24222+	struct i2c_msg *msg = i2c->msg;
24223+
24224+	dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n",
24225+		__func__, __LINE__, msg->flags, msg->len);
24226+
24227+	check_i2c_send_complete(i2c);
24228+	hibvt_i2c_enable(i2c);
24229+	hibvt_i2c_clr_irq(i2c);
24230+	hibvt_i2c_set_addr(i2c);
24231+	hibvt_i2c_cfg_cmd(i2c);
24232+	hibvt_i2c_start_cmd(i2c);
24233+
24234+	i2c->msg_buf_ptr = 0;
24235+
24236+	if (msg->flags & I2C_M_RD) {
24237+		while (i2c->msg_buf_ptr < msg->len) {
24238+			status = hibvt_i2c_wait_rx_noempty(i2c);
24239+			if (status)
24240+				goto end;
24241+
24242+			val = readl(i2c->base + HIBVT_I2C_RXF);
24243+			msg->buf[i2c->msg_buf_ptr] = val;
24244+			i2c->msg_buf_ptr++;
24245+		}
24246+	} else {
24247+		while (i2c->msg_buf_ptr < msg->len) {
24248+			status = hibvt_i2c_wait_tx_nofull(i2c);
24249+			if (status)
24250+				goto end;
24251+
24252+			val = msg->buf[i2c->msg_buf_ptr];
24253+			writel(val, i2c->base + HIBVT_I2C_TXF);
24254+			i2c->msg_buf_ptr++;
24255+		}
24256+	}
24257+
24258+	status = hibvt_i2c_wait_idle(i2c);
24259+end:
24260+	hibvt_i2c_disable(i2c);
24261+
24262+	return status;
24263+}
24264+
24265+static int hibvt_i2c_polling_xfer_one_msg_mul_reg(struct hibvt_i2c_dev *i2c, unsigned int reg_data_width)
24266+{
24267+	int status;
24268+	unsigned int val;
24269+	struct i2c_msg *msg = i2c->msg;
24270+
24271+	dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n",
24272+		__func__, __LINE__, msg->flags, msg->len);
24273+
24274+	check_i2c_send_complete(i2c);
24275+	hibvt_i2c_enable(i2c);
24276+	hibvt_i2c_clr_irq(i2c);
24277+	hibvt_i2c_set_addr(i2c);
24278+	hibvt_i2c_cfg_cmd_mul_reg(i2c, reg_data_width);
24279+	hibvt_i2c_start_cmd(i2c);
24280+
24281+	i2c->msg_buf_ptr = 0;
24282+
24283+	if (msg->flags & I2C_M_RD) {
24284+		while (i2c->msg_buf_ptr < msg->len) {
24285+			status = hibvt_i2c_wait_rx_noempty(i2c);
24286+			if (status) {
24287+				goto end;
24288+			}
24289+
24290+			val = readl(i2c->base + HIBVT_I2C_RXF);
24291+			msg->buf[i2c->msg_buf_ptr] = val;
24292+			i2c->msg_buf_ptr++;
24293+
24294+		}
24295+	} else {
24296+		while (i2c->msg_buf_ptr < msg->len) {
24297+			status = hibvt_i2c_wait_tx_nofull(i2c);
24298+			if (status) {
24299+				goto end;
24300+			}
24301+
24302+			val = msg->buf[i2c->msg_buf_ptr];
24303+			writel(val, i2c->base + HIBVT_I2C_TXF);
24304+			i2c->msg_buf_ptr++;
24305+		}
24306+	}
24307+
24308+end:
24309+	return status;
24310+}
24311+
24312+static irqreturn_t hibvt_i2c_isr(int irq, void *dev_id)
24313+{
24314+	struct hibvt_i2c_dev *i2c = dev_id;
24315+	unsigned int irq_status;
24316+	struct i2c_msg *msg = i2c->msg;
24317+
24318+	spin_lock(&i2c->lock);
24319+
24320+	irq_status = hibvt_i2c_clr_irq(i2c);
24321+	dev_dbg(i2c->dev, "%s RIS:  0x%x\n", __func__, irq_status);
24322+
24323+	if (!irq_status) {
24324+		dev_dbg(i2c->dev, "no irq\n");
24325+		goto end;
24326+	}
24327+
24328+	if (irq_status & INTR_ABORT_MASK) {
24329+		dev_err(i2c->dev, "irq handle abort, RIS: 0x%x\n",
24330+			irq_status);
24331+		i2c->status = -EIO;
24332+		hibvt_i2c_disable_irq(i2c, INTR_ALL_MASK);
24333+
24334+		complete(&i2c->msg_complete);
24335+		goto end;
24336+	}
24337+
24338+	if (msg->flags & I2C_M_RD) {
24339+		while ((readl(i2c->base + HIBVT_I2C_STAT) & STAT_RXF_NOE_MASK)
24340+				&& (i2c->msg_buf_ptr < msg->len)) {
24341+			msg->buf[i2c->msg_buf_ptr] =
24342+				readl(i2c->base + HIBVT_I2C_RXF);
24343+			i2c->msg_buf_ptr++;
24344+		}
24345+	} else {
24346+		while ((readl(i2c->base + HIBVT_I2C_STAT) & STAT_TXF_NOF_MASK)
24347+				&& (i2c->msg_buf_ptr < msg->len)) {
24348+			writel(msg->buf[i2c->msg_buf_ptr],
24349+			       i2c->base + HIBVT_I2C_TXF);
24350+			i2c->msg_buf_ptr++;
24351+		}
24352+	}
24353+
24354+	if (i2c->msg_buf_ptr >= msg->len)
24355+		hibvt_i2c_disable_irq(i2c, INTR_TX_MASK | INTR_RX_MASK);
24356+
24357+	if (irq_status & INTR_CMD_DONE_MASK) {
24358+		dev_dbg(i2c->dev, "cmd done\n");
24359+		i2c->status =  0;
24360+		hibvt_i2c_disable_irq(i2c, INTR_ALL_MASK);
24361+
24362+		complete(&i2c->msg_complete);
24363+	}
24364+
24365+end:
24366+	spin_unlock(&i2c->lock);
24367+
24368+	return IRQ_HANDLED;
24369+}
24370+
24371+static int hibvt_i2c_interrupt_xfer_one_msg(struct hibvt_i2c_dev *i2c)
24372+{
24373+	int status;
24374+	struct i2c_msg *msg = i2c->msg;
24375+	unsigned long timeout;
24376+	unsigned long flags;
24377+
24378+	dev_dbg(i2c->dev, "[%s,%d]msg->flags=0x%x, len=0x%x\n",
24379+		__func__, __LINE__, msg->flags, msg->len);
24380+
24381+	reinit_completion(&i2c->msg_complete);
24382+	i2c->msg_buf_ptr = 0;
24383+	i2c->status = -EIO;
24384+
24385+	spin_lock_irqsave(&i2c->lock, flags);
24386+	check_i2c_send_complete(i2c);
24387+	hibvt_i2c_enable(i2c);
24388+	hibvt_i2c_clr_irq(i2c);
24389+	if (msg->flags & I2C_M_RD)
24390+		hibvt_i2c_cfg_irq(i2c, INTR_USE_MASK & ~INTR_TX_MASK);
24391+	else
24392+		hibvt_i2c_cfg_irq(i2c, INTR_USE_MASK & ~INTR_RX_MASK);
24393+
24394+	hibvt_i2c_set_addr(i2c);
24395+	hibvt_i2c_cfg_cmd(i2c);
24396+	hibvt_i2c_start_cmd(i2c);
24397+	spin_unlock_irqrestore(&i2c->lock, flags);
24398+
24399+	timeout = wait_for_completion_timeout(&i2c->msg_complete,
24400+					      I2C_IRQ_TIMEOUT);
24401+
24402+	spin_lock_irqsave(&i2c->lock, flags);
24403+	if (timeout == 0) {
24404+		hibvt_i2c_disable_irq(i2c, INTR_ALL_MASK);
24405+		status = -EIO;
24406+		dev_err(i2c->dev, "%s timeout\n",
24407+			msg->flags & I2C_M_RD ? "rx" : "tx");
24408+	} else {
24409+		status = i2c->status;
24410+	}
24411+
24412+	hibvt_i2c_disable(i2c);
24413+
24414+	spin_unlock_irqrestore(&i2c->lock, flags);
24415+	return status;
24416+}
24417+
24418+/*
24419+ * Master transfer function
24420+ */
24421+static int hibvt_i2c_xfer(struct i2c_adapter *adap,
24422+			  struct i2c_msg *msgs, int num)
24423+{
24424+	struct hibvt_i2c_dev *i2c = i2c_get_adapdata(adap);
24425+	int status = -EINVAL;
24426+	unsigned long flags;
24427+
24428+	if (!msgs || (num <= 0)) {
24429+		dev_err(i2c->dev, "msgs == NULL || num <= 0, Invalid argument!\n");
24430+		return -EINVAL;
24431+	}
24432+
24433+	spin_lock_irqsave(&i2c->lock, flags);
24434+
24435+	i2c->msg = msgs;
24436+	i2c->msg_num = num;
24437+	i2c->msg_idx = 0;
24438+
24439+	while (i2c->msg_idx < i2c->msg_num) {
24440+#if defined(CONFIG_HI_DMAC) || defined(CONFIG_HIEDMAC)
24441+		if ((i2c->msg->len >= CONFIG_DMA_MSG_MIN_LEN) &&
24442+				(i2c->msg->len <= CONFIG_DMA_MSG_MAX_LEN)) {
24443+			status = hibvt_i2c_dma_xfer_one_msg(i2c);
24444+			if (status)
24445+				break;
24446+		} else if (i2c->irq >= 0) {
24447+#else
24448+		if (i2c->irq >= 0) {
24449+#endif
24450+			spin_unlock_irqrestore(&i2c->lock, flags);
24451+			status = hibvt_i2c_interrupt_xfer_one_msg(i2c);
24452+			spin_lock_irqsave(&i2c->lock, flags);
24453+			if (status)
24454+				break;
24455+		} else {
24456+			status = hibvt_i2c_polling_xfer_one_msg(i2c);
24457+			if (status)
24458+				break;
24459+		}
24460+		i2c->msg++;
24461+		i2c->msg_idx++;
24462+	}
24463+
24464+	if (!status || i2c->msg_idx > 0)
24465+		status = i2c->msg_idx;
24466+
24467+	spin_unlock_irqrestore(&i2c->lock, flags);
24468+	return status;
24469+}
24470+
24471+/* hibvt_i2c_break_polling_xfer
24472+ *
24473+ * I2c polling independent branch, Shielding interrupt interface
24474+ */
24475+static int hibvt_i2c_break_polling_xfer(const struct i2c_adapter *adap,
24476+					struct i2c_msg *msgs, int num)
24477+{
24478+	struct hibvt_i2c_dev *i2c = i2c_get_adapdata(adap);
24479+	int status = -EINVAL;
24480+	unsigned long flags;
24481+	if (!msgs || (num <= 0)) {
24482+		dev_err(i2c->dev, "msgs == NULL || num <= 0, Invalid argument!\n");
24483+		return -EINVAL;
24484+	}
24485+	spin_lock_irqsave(&i2c->lock, flags);
24486+	i2c->msg = msgs;
24487+	i2c->msg_num = num;
24488+	i2c->msg_idx = 0;
24489+	while (i2c->msg_idx < i2c->msg_num) {
24490+#if defined(CONFIG_HI_DMAC) || defined(CONFIG_HIEDMAC)
24491+		if ((i2c->msg->len >= CONFIG_DMA_MSG_MIN_LEN) &&
24492+				(i2c->msg->len <= CONFIG_DMA_MSG_MAX_LEN)) {
24493+			status = hibvt_i2c_dma_xfer_one_msg(i2c);
24494+			if (status)
24495+				break;
24496+		}
24497+#else
24498+		status = hibvt_i2c_polling_xfer_one_msg(i2c);
24499+		if (status)
24500+			break;
24501+#endif
24502+		i2c->msg++;
24503+		i2c->msg_idx++;
24504+	}
24505+	if (!status || i2c->msg_idx > 0)
24506+		status = i2c->msg_idx;
24507+	spin_unlock_irqrestore(&i2c->lock, flags);
24508+	return status;
24509+}
24510+
24511+static int hibvt_i2c_mul_reg_xfer(struct i2c_adapter *adap,
24512+				 struct i2c_msg *msgs, int num, unsigned int reg_data_width)
24513+{
24514+	struct hibvt_i2c_dev *i2c = i2c_get_adapdata(adap);
24515+	int status = -EINVAL;
24516+	unsigned long flags;
24517+	if (!msgs || (num <= 0)) {
24518+		dev_err(i2c->dev, "msgs == NULL || num <= 0, Invalid argument!\n");
24519+		return -EINVAL;
24520+	}
24521+	spin_lock_irqsave(&i2c->lock, flags);
24522+	i2c->msg = msgs;
24523+	i2c->msg_num = num;
24524+	i2c->msg_idx = 0;
24525+	while (i2c->msg_idx < i2c->msg_num) {
24526+		if ((i2c->msg->len >= CONFIG_DMA_MSG_MIN_LEN) && (i2c->msg->len <= CONFIG_DMA_MSG_MAX_LEN) && (i2c->msg->flags & I2C_M_DMA)) {
24527+#if defined(CONFIG_HIEDMAC) && defined(CONFIG_HIEDMAC_INTERRUPT)
24528+			status = hibvt_i2c_dma_xfer_one_msg_mul_reg(i2c, reg_data_width);
24529+#endif
24530+			if (status) {
24531+				break;
24532+			}
24533+		} else {
24534+			status = hibvt_i2c_polling_xfer_one_msg_mul_reg(i2c, reg_data_width);
24535+			if (status) {
24536+				break;
24537+			}
24538+		}
24539+		i2c->msg++;
24540+		i2c->msg_idx++;
24541+	}
24542+	if (!status || i2c->msg_idx > 0) {
24543+		status = i2c->msg_idx;
24544+	}
24545+	spin_unlock_irqrestore(&i2c->lock, flags);
24546+	return status;
24547+}
24548+/* HI I2C READ *
24549+ * hi_i2c_master_recv - issue a single I2C message in master receive mode
24550+ * @client: Handle to slave device
24551+ * @buf: Where to store data read from slave
24552+ * @count: How many bytes to read, must be less than 64k since msg.len is u16
24553+ *
24554+ * Returns negative errno, or else the number of bytes read.
24555+ */
24556+int hi_i2c_master_recv(const struct i2c_client *client, char *buf,
24557+		       int count)
24558+{
24559+	printk("Wrong interface call."
24560+	       "hi_i2c_transfer is the only interface to i2c read!!!\n");
24561+
24562+	return -EIO;
24563+}
24564+EXPORT_SYMBOL(hi_i2c_master_recv);
24565+
24566+/* HI I2C WRITE *
24567+ * hi_i2c_master_send - issue a single I2C message in master transmit mode
24568+ * @client: Handle to slave device
24569+ * @buf: Data that will be written to the slave
24570+ * @count: How many bytes to write, must be less than 64k since msg.len is u16
24571+ *
24572+ * Returns negative errno, or else the number of bytes written.
24573+ */
24574+int hi_i2c_master_send(const struct i2c_client *client,
24575+		       const char *buf, int count)
24576+{
24577+	struct i2c_adapter *adap = NULL;
24578+	struct i2c_msg msg;
24579+	int msgs_count;
24580+
24581+	if ((client == NULL) || (buf == NULL) || (client->adapter == NULL) ||
24582+			(count < 0)) {
24583+		printk(KERN_ERR "invalid args\n");
24584+		return -EINVAL;
24585+	}
24586+
24587+	if ((client->addr > 0x3ff) ||
24588+			(((client->flags & I2C_M_TEN) == 0) && (client->addr > 0x7f))) {
24589+		printk(KERN_ERR "dev address out of range\n");
24590+		return -EINVAL;
24591+	}
24592+
24593+	adap = client->adapter;
24594+	msg.addr = client->addr;
24595+	msg.flags = client->flags;
24596+	msg.len = count;
24597+
24598+	msg.buf = (__u8 *)buf;
24599+
24600+	msgs_count = hibvt_i2c_break_polling_xfer(adap, &msg, 1);
24601+
24602+	return (msgs_count == 1) ? count : -EIO;
24603+}
24604+EXPORT_SYMBOL(hi_i2c_master_send);
24605+
24606+
24607+int hi_i2c_master_send_mul_reg(const struct i2c_client *client,
24608+		       const char *buf, unsigned int count, unsigned int reg_data_width)
24609+{
24610+	struct i2c_adapter *adap = client->adapter;
24611+	struct i2c_msg msg;
24612+	int msgs_count;
24613+
24614+	if ((client->addr > 0x3ff)
24615+	    || (((client->flags & I2C_M_TEN) == 0) && (client->addr > 0x7f))) {
24616+		printk(KERN_ERR "dev address out of range\n");
24617+		return -EINVAL;
24618+	}
24619+
24620+	msg.addr = client->addr;
24621+	msg.flags = client->flags;
24622+	msg.len = count;
24623+
24624+	if ((!buf)||(count < 0)) {
24625+		printk(KERN_ERR "buf == NULL || count < 0, Invalid argument!\n");
24626+		return -EINVAL;
24627+	}
24628+	msg.buf = (__u8 *)buf;
24629+
24630+	msgs_count = hibvt_i2c_mul_reg_xfer(adap, &msg, 1,reg_data_width);
24631+
24632+	return (msgs_count == 1) ? count : -EIO;
24633+}
24634+EXPORT_SYMBOL(hi_i2c_master_send_mul_reg);
24635+/**
24636+ * hi_i2c_transfer - execute a single or combined I2C message
24637+ * @adap: Handle to I2C bus
24638+ * @msgs: One or more messages to execute before STOP is issued to
24639+ *  terminate the operation; each message begins with a START.
24640+ * @num: Number of messages to be executed.
24641+ *
24642+ * Returns negative errno, else the number of messages executed.
24643+ *
24644+ * Note that there is no requirement that each message be sent to
24645+ * the same slave address, although that is the most common model.
24646+ */
24647+int hi_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
24648+		    int num)
24649+{
24650+	int msgs_count;
24651+
24652+	if ((!adap) || (!msgs)) {
24653+		printk(KERN_ERR "adap == NULL || msgs == NULL, Invalid argument!\n");
24654+		return -EINVAL;
24655+	}
24656+
24657+	if ((msgs[0].addr > 0x3ff) ||
24658+			(((msgs[0].flags & I2C_M_TEN) == 0) && (msgs[0].addr > 0x7f))) {
24659+		printk(KERN_ERR "msgs[0] dev address out of range\n");
24660+		return -EINVAL;
24661+	}
24662+
24663+	if ((msgs[1].addr > 0x3ff) ||
24664+			(((msgs[1].flags & I2C_M_TEN) == 0) && (msgs[1].addr > 0x7f))) {
24665+		printk(KERN_ERR "msgs[1] dev address out of range\n");
24666+		return -EINVAL;
24667+	}
24668+
24669+	msgs_count = hibvt_i2c_xfer(adap, msgs, num);
24670+
24671+	return msgs_count;
24672+}
24673+EXPORT_SYMBOL(hi_i2c_transfer);
24674+
24675+static u32 hibvt_i2c_func(struct i2c_adapter *adap)
24676+{
24677+	return I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
24678+	       I2C_FUNC_PROTOCOL_MANGLING |
24679+	       I2C_FUNC_SMBUS_WORD_DATA |
24680+	       I2C_FUNC_SMBUS_BYTE_DATA |
24681+	       I2C_FUNC_SMBUS_BYTE |
24682+	       I2C_FUNC_SMBUS_I2C_BLOCK;
24683+}
24684+
24685+static const struct i2c_algorithm hibvt_i2c_algo = {
24686+	.master_xfer		= hibvt_i2c_xfer,
24687+	.functionality		= hibvt_i2c_func,
24688+};
24689+
24690+static int hibvt_i2c_probe(struct platform_device *pdev)
24691+{
24692+	int status;
24693+	struct hibvt_i2c_dev *i2c;
24694+	struct i2c_adapter *adap = NULL;
24695+	struct resource *res = NULL;
24696+
24697+	i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL);
24698+	if (!i2c)
24699+		return -ENOMEM;
24700+
24701+	platform_set_drvdata(pdev, i2c);
24702+	i2c->dev = &pdev->dev;
24703+	spin_lock_init(&i2c->lock);
24704+	init_completion(&i2c->msg_complete);
24705+
24706+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
24707+	if (!res) {
24708+		dev_err(i2c->dev, "Invalid mem resource./n");
24709+		return -ENODEV;
24710+	}
24711+
24712+	i2c->phybase = res->start;
24713+	i2c->base = devm_ioremap_resource(&pdev->dev, res);
24714+	if (IS_ERR(i2c->base)) {
24715+		dev_err(i2c->dev, "cannot ioremap resource\n");
24716+		return -ENOMEM;
24717+	}
24718+
24719+	i2c->clk = devm_clk_get(&pdev->dev, NULL);
24720+	if (IS_ERR(i2c->clk)) {
24721+		dev_err(i2c->dev, "cannot get clock\n");
24722+		return -ENOENT;
24723+	}
24724+	clk_prepare_enable(i2c->clk);
24725+
24726+	if (of_property_read_u32(pdev->dev.of_node, "clock-frequency",
24727+				 &i2c->freq)) {
24728+		dev_warn(i2c->dev, "setting default clock-frequency@%dHz\n",
24729+			 I2C_DEFAULT_FREQUENCY);
24730+		i2c->freq = I2C_DEFAULT_FREQUENCY;
24731+	}
24732+
24733+	/* i2c controller initialization, disable interrupt */
24734+	hibvt_i2c_hw_init(i2c);
24735+
24736+	i2c->irq = platform_get_irq(pdev, 0);
24737+	status = devm_request_irq(&pdev->dev, i2c->irq, hibvt_i2c_isr,
24738+				  IRQF_SHARED, dev_name(&pdev->dev), i2c);
24739+	if (status) {
24740+		dev_dbg(i2c->dev, "falling back to polling mode");
24741+		i2c->irq = -1;
24742+	}
24743+
24744+	adap = &i2c->adap;
24745+	i2c_set_adapdata(adap, i2c);
24746+	adap->owner = THIS_MODULE;
24747+	strlcpy(adap->name, "hibvt-i2c", sizeof(adap->name));
24748+	adap->dev.parent = &pdev->dev;
24749+	adap->dev.of_node = pdev->dev.of_node;
24750+	adap->algo = &hibvt_i2c_algo;
24751+
24752+	/* Add the i2c adapter */
24753+	status = i2c_add_adapter(adap);
24754+	if (status) {
24755+		dev_err(i2c->dev, "failed to add bus to i2c core\n");
24756+		goto err_add_adapter;
24757+	}
24758+
24759+	dev_info(i2c->dev, "%s%d@%dhz registered\n",
24760+		 adap->name, adap->nr, i2c->freq);
24761+
24762+	return 0;
24763+
24764+err_add_adapter:
24765+	clk_disable_unprepare(i2c->clk);
24766+	return status;
24767+}
24768+
24769+static int hibvt_i2c_remove(struct platform_device *pdev)
24770+{
24771+	struct hibvt_i2c_dev *i2c = platform_get_drvdata(pdev);
24772+
24773+	clk_disable_unprepare(i2c->clk);
24774+	i2c_del_adapter(&i2c->adap);
24775+
24776+	return 0;
24777+}
24778+
24779+#ifdef CONFIG_PM_SLEEP
24780+static int hibvt_i2c_suspend(struct device *dev)
24781+{
24782+	struct hibvt_i2c_dev *i2c = dev_get_drvdata(dev);
24783+
24784+	i2c_lock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
24785+	clk_disable_unprepare(i2c->clk);
24786+	i2c_unlock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
24787+
24788+	return 0;
24789+}
24790+
24791+static int hibvt_i2c_resume(struct device *dev)
24792+{
24793+	struct hibvt_i2c_dev *i2c = dev_get_drvdata(dev);
24794+
24795+	i2c_lock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
24796+	clk_prepare_enable(i2c->clk);
24797+	hibvt_i2c_hw_init(i2c);
24798+	i2c_unlock_bus(&i2c->adap, I2C_LOCK_ROOT_ADAPTER);
24799+
24800+	return 0;
24801+}
24802+#endif
24803+
24804+static SIMPLE_DEV_PM_OPS(hibvt_i2c_dev_pm, hibvt_i2c_suspend,
24805+			 hibvt_i2c_resume);
24806+
24807+static const struct of_device_id hibvt_i2c_match[] = {
24808+	{ .compatible = "hisilicon,hibvt-i2c" },
24809+	{ .compatible = "hisilicon,hi3516cv300-i2c" },
24810+	{ .compatible = "hisilicon,hi3536dv100-i2c" },
24811+	{},
24812+};
24813+MODULE_DEVICE_TABLE(of, hibvt_i2c_match);
24814+
24815+static struct platform_driver hibvt_i2c_driver = {
24816+	.driver		= {
24817+		.name	= "hibvt-i2c",
24818+		.of_match_table = hibvt_i2c_match,
24819+		.pm	= &hibvt_i2c_dev_pm,
24820+	},
24821+	.probe		= hibvt_i2c_probe,
24822+	.remove		= hibvt_i2c_remove,
24823+};
24824+
24825+module_platform_driver(hibvt_i2c_driver);
24826+
24827+MODULE_AUTHOR("Hisilicon");
24828+MODULE_DESCRIPTION("HISILICON BVT I2C Bus driver");
24829+MODULE_LICENSE("GPL v2");
24830diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
24831index f358120d5..0693b4917 100644
24832--- a/drivers/i2c/i2c-dev.c
24833+++ b/drivers/i2c/i2c-dev.c
24834@@ -232,7 +232,42 @@ static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
24835
24836 	return result;
24837 }
24838+static noinline int i2c_config_mul_reg(struct i2c_client *client, unsigned long arg)
24839+{
24840+	struct i2c_msg msg;
24841+	unsigned int reg_width;
24842+	unsigned int data_width;
24843+	unsigned int reg_data_width;
24844+
24845+	if (copy_from_user(&msg,
24846+			   (struct i2c_msg __user *)arg,
24847+			   sizeof(msg)))
24848+		return -EFAULT;
24849+
24850+	if(client->flags & I2C_M_16BIT_REG)
24851+		reg_width = 2;
24852+	else
24853+		reg_width = 1;
24854+
24855+	if(client->flags & I2C_M_16BIT_DATA)
24856+		data_width = 2;
24857+	else
24858+		data_width = 1;
24859+
24860+	reg_data_width = reg_width + data_width;
24861+
24862+	msg.buf = memdup_user(msg.buf,msg.len);
24863+
24864+	if(msg.len == 0 || reg_data_width > msg.len || msg.len % reg_data_width != 0){
24865+		printk(KERN_ERR "msg.len err!!!\n");
24866+		return -EINVAL;
24867+	}
24868+
24869+	hi_i2c_master_send_mul_reg(client, msg.buf, msg.len, reg_data_width);
24870
24871+	return 0;
24872+
24873+}
24874 static noinline int i2cdev_ioctl_rdwr(struct i2c_client *client,
24875 		unsigned nmsgs, struct i2c_msg *msgs)
24876 {
24877@@ -485,6 +520,24 @@ static long i2cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
24878 		 */
24879 		client->adapter->timeout = msecs_to_jiffies(arg * 10);
24880 		break;
24881+	case I2C_CONFIG_FLAGS:
24882+		if (arg & I2C_M_16BIT_REG)
24883+			client->flags |= I2C_M_16BIT_REG;
24884+		else
24885+			client->flags &= ~I2C_M_16BIT_REG;
24886+
24887+		if (arg & I2C_M_16BIT_DATA)
24888+			client->flags |= I2C_M_16BIT_DATA;
24889+		else
24890+			client->flags &= ~I2C_M_16BIT_DATA;
24891+
24892+		if (arg & I2C_M_DMA)
24893+			client->flags |= I2C_M_DMA;
24894+		else
24895+			client->flags &= ~I2C_M_DMA;
24896+		return 0;
24897+	case I2C_CONFIG_MUL_REG:
24898+		return i2c_config_mul_reg(client, arg);
24899 	default:
24900 		/* NOTE:  returning a fault code here could cause trouble
24901 		 * in buggy userspace code.  Some old kernel bugs returned
24902diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c
24903index 176f5f064..24dd82c4b 100644
24904--- a/drivers/irqchip/irq-gic.c
24905+++ b/drivers/irqchip/irq-gic.c
24906@@ -118,6 +118,24 @@ static DEFINE_STATIC_KEY_FALSE(needs_rmw_access);
24907 static u8 gic_cpu_map[NR_GIC_CPU_IF] __read_mostly;
24908
24909 static DEFINE_STATIC_KEY_TRUE(supports_deactivate_key);
24910+#if defined(CONFIG_ARCH_HI3556V200) || defined(CONFIG_ARCH_HI3559V200) || \
24911+    defined(CONFIG_ARCH_HI3516CV500)|| defined(CONFIG_ARCH_HI3516DV300)|| \
24912+    defined(CONFIG_ARCH_HI3562V100) || defined(CONFIG_ARCH_HI3566V100)
24913+#ifdef CONFIG_ARCH_HISI_BVT_AMP
24914+/*
24915+ *Uesed to process gic sgi interrupt *
24916+ */
24917+#define DIS_IRQ_CNT	6
24918+struct gic_sgi_handle {
24919+	unsigned int irq;
24920+	void (*handle)(unsigned int cpu_intrf,
24921+			unsigned int irq_num,
24922+			struct pt_regs *regs);
24923+};
24924+struct gic_sgi_handle dis_irq_handle[DIS_IRQ_CNT];
24925+EXPORT_SYMBOL(dis_irq_handle);
24926+#endif
24927+#endif
24928
24929 static struct gic_chip_data gic_data[CONFIG_ARM_GIC_MAX_NR] __read_mostly;
24930
24931@@ -333,6 +351,29 @@ static int gic_retrigger(struct irq_data *data)
24932 	return !gic_irq_set_irqchip_state(data, IRQCHIP_STATE_PENDING, true);
24933 }
24934
24935+#if defined(CONFIG_ARCH_HI3556V200)  || defined(CONFIG_ARCH_HI3559V200)  || \
24936+    defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \
24937+    defined(CONFIG_ARCH_HI3562V100)  || defined(CONFIG_ARCH_HI3566V100)
24938+#ifdef CONFIG_ARCH_HISI_BVT_AMP
24939+/* used to process dis irq */
24940+int dis_irq_proc(u32 irqnr, u32 irqstat, struct pt_regs *regs)
24941+{
24942+	u32 idx;
24943+
24944+	for (idx = 0; idx < DIS_IRQ_CNT; idx++) {
24945+		if ((irqnr == dis_irq_handle[idx].irq)
24946+				&& (dis_irq_handle[idx].handle)) {
24947+			dis_irq_handle[idx].handle(((irqstat >> 10) & 0x7),
24948+					irqnr, regs);
24949+			return 1;
24950+		}
24951+	}
24952+
24953+	return 0;
24954+}
24955+#endif
24956+#endif
24957+
24958 static void __exception_irq_entry gic_handle_irq(struct pt_regs *regs)
24959 {
24960 	u32 irqstat, irqnr;
24961@@ -468,7 +509,31 @@ static void gic_cpu_if_up(struct gic_chip_data *gic)
24962 	writel_relaxed(bypass | mode | GICC_ENABLE, cpu_base + GIC_CPU_CTRL);
24963 }
24964
24965+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100)
24966+#include "irq-map-hi3559av100.h"
24967+static void gic_dist_init_amp(struct gic_chip_data *gic)
24968+{
24969+	unsigned int i;
24970+	u32 cpumask;
24971+	unsigned int *irq_map_int = (unsigned int *)irq_map;
24972+	unsigned int gic_irqs = gic->gic_irqs;
24973+	void __iomem *base = gic_data_dist_base(gic);
24974
24975+	writel_relaxed(GICD_DISABLE, base + GIC_DIST_CTRL);
24976+
24977+	/*
24978+	 * Set all global interrupts to this CPU only.
24979+	 */
24980+	for (i = 32; i < gic_irqs; i += 4) {
24981+	    cpumask = irq_map_int[i / 4];
24982+		writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4);
24983+	}
24984+
24985+	gic_dist_config(base, gic_irqs, NULL);
24986+
24987+	writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL);
24988+}
24989+#else
24990 static void gic_dist_init(struct gic_chip_data *gic)
24991 {
24992 	unsigned int i;
24993@@ -491,6 +556,7 @@ static void gic_dist_init(struct gic_chip_data *gic)
24994
24995 	writel_relaxed(GICD_ENABLE, base + GIC_DIST_CTRL);
24996 }
24997+#endif
24998
24999 static int gic_cpu_init(struct gic_chip_data *gic)
25000 {
25001@@ -1161,6 +1227,9 @@ static int gic_init_bases(struct gic_chip_data *gic,
25002 {
25003 	int gic_irqs, ret;
25004
25005+	struct device_node *np;
25006+	void * sysctrl_reg_base;
25007+	int gic_dist_init_flag;
25008 	if (IS_ENABLED(CONFIG_GIC_NON_BANKED) && gic->percpu_offset) {
25009 		/* Frankein-GIC without banked registers... */
25010 		unsigned int cpu;
25011@@ -1232,7 +1301,25 @@ static int gic_init_bases(struct gic_chip_data *gic,
25012 		goto error;
25013 	}
25014
25015-	gic_dist_init(gic);
25016+#define GIC_DIST_INIT_FLAG 0x47444946
25017+#define GIC_DIST_INIT_FLAG_OFFSET 0x0130
25018+	/* 0x47444946('G''D''I''F') is abbreviation of GIC_DIST_INIT_FLAG. */
25019+
25020+	np = of_find_compatible_node(NULL, NULL, "hisilicon,sysctrl");
25021+	sysctrl_reg_base = of_iomap(np, 0);
25022+	gic_dist_init_flag = readl(sysctrl_reg_base + GIC_DIST_INIT_FLAG_OFFSET);
25023+
25024+	if(gic_dist_init_flag != GIC_DIST_INIT_FLAG) {
25025+		printk("Gic dist init...\n");
25026+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100)
25027+		gic_dist_init_amp(gic);
25028+#else
25029+		gic_dist_init(gic);
25030+#endif
25031+		writel_relaxed(GIC_DIST_INIT_FLAG, sysctrl_reg_base + GIC_DIST_INIT_FLAG_OFFSET);
25032+	} else
25033+		printk("Gic dist not init...\n");
25034+
25035 	ret = gic_cpu_init(gic);
25036 	if (ret)
25037 		goto error;
25038diff --git a/drivers/media/usb/gspca/ov519.c b/drivers/media/usb/gspca/ov519.c
25039index cd6776c31..8d06332bb 100644
25040--- a/drivers/media/usb/gspca/ov519.c
25041+++ b/drivers/media/usb/gspca/ov519.c
25042@@ -3482,6 +3482,11 @@ static void ov511_mode_init_regs(struct sd *sd)
25043 		return;
25044 	}
25045
25046+	if (alt->desc.bNumEndpoints < 1) {
25047+		sd->gspca_dev.usb_err = -ENODEV;
25048+		return;
25049+	}
25050+
25051 	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
25052 	reg_w(sd, R51x_FIFO_PSIZE, packet_size >> 5);
25053
25054@@ -3613,6 +3618,11 @@ static void ov518_mode_init_regs(struct sd *sd)
25055 		return;
25056 	}
25057
25058+	if (alt->desc.bNumEndpoints < 1) {
25059+		sd->gspca_dev.usb_err = -ENODEV;
25060+		return;
25061+	}
25062+
25063 	packet_size = le16_to_cpu(alt->endpoint[0].desc.wMaxPacketSize);
25064 	ov518_reg_w32(sd, R51x_FIFO_PSIZE, packet_size & ~7, 2);
25065
25066diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
25067index b8847ae04..e6bf07fe1 100644
25068--- a/drivers/mfd/Kconfig
25069+++ b/drivers/mfd/Kconfig
25070@@ -520,6 +520,17 @@ config MFD_HI655X_PMIC
25071 	help
25072 	  Select this option to enable Hisilicon hi655x series pmic driver.
25073
25074+config MFD_HISI_FMC
25075+	tristate "HiSilicon Flash Memory Controller"
25076+	depends on OF
25077+	depends on ARCH_HISI_BVT
25078+	select MFD_CORE
25079+	select REGMAP_MMIO
25080+	help
25081+	  Select this option to enable the HiSilicon Flash Memory
25082+	  Controller(FMC) driver.
25083+
25084+
25085 config HTC_PASIC3
25086 	tristate "HTC PASIC3 LED/DS1WM chip support"
25087 	select MFD_CORE
25088diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
25089index 1780019d2..992e1895f 100644
25090--- a/drivers/mfd/Makefile
25091+++ b/drivers/mfd/Makefile
25092@@ -211,6 +211,7 @@ obj-$(CONFIG_MFD_AT91_USART)	+= at91-usart.o
25093 obj-$(CONFIG_MFD_ATMEL_FLEXCOM)	+= atmel-flexcom.o
25094 obj-$(CONFIG_MFD_ATMEL_HLCDC)	+= atmel-hlcdc.o
25095 obj-$(CONFIG_MFD_ATMEL_SMC)	+= atmel-smc.o
25096+obj-$(CONFIG_MFD_HISI_FMC)	+= hisi_fmc.o
25097 obj-$(CONFIG_MFD_INTEL_LPSS)	+= intel-lpss.o
25098 obj-$(CONFIG_MFD_INTEL_LPSS_PCI)	+= intel-lpss-pci.o
25099 obj-$(CONFIG_MFD_INTEL_LPSS_ACPI)	+= intel-lpss-acpi.o
25100diff --git a/drivers/mfd/hisi_fmc.c b/drivers/mfd/hisi_fmc.c
25101new file mode 100644
25102index 000000000..7aa23e56d
25103--- /dev/null
25104+++ b/drivers/mfd/hisi_fmc.c
25105@@ -0,0 +1,134 @@
25106+/* HiSilicon Flash Memory Controller Driver
25107+ *
25108+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
25109+ *
25110+ * This program is free software; you can redistribute it and/or modify
25111+ * it under the terms of the GNU General Public License as published by
25112+ * the Free Software Foundation; either version 2 of the License, or
25113+ * (at your option) any later version.
25114+ *
25115+ * This program is distributed in the hope that it will be useful,
25116+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25117+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25118+ * GNU General Public License for more details.
25119+ *
25120+ * You should have received a copy of the GNU General Public License
25121+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
25122+ */
25123+
25124+#include <linux/clk.h>
25125+#include <linux/device.h>
25126+#include <linux/dma-mapping.h>
25127+#include <linux/err.h>
25128+#include <linux/mfd/core.h>
25129+#include <linux/mfd/hisi_fmc.h>
25130+#include <linux/module.h>
25131+#include <linux/of.h>
25132+#include <linux/platform_device.h>
25133+
25134+unsigned char hifmc_cs_user[HIFMC_MAX_CHIP_NUM];
25135+
25136+DEFINE_MUTEX(fmc_switch_mutex);
25137+EXPORT_SYMBOL_GPL(fmc_switch_mutex);
25138+
25139+/* ------------------------------------------------------------------------ */
25140+static const struct mfd_cell hisi_fmc_devs[] = {
25141+	{
25142+		.name = "hisi_spi_nor",
25143+		.of_compatible = "hisilicon,fmc-spi-nor",
25144+	},
25145+	{
25146+		.name = "hisi_spi_nand",
25147+		.of_compatible = "hisilicon,fmc-spi-nand",
25148+	},
25149+	{
25150+		.name = "hisi_nand",
25151+		.of_compatible = "hisilicon,fmc-nand",
25152+	},
25153+};
25154+
25155+static int hisi_fmc_probe(struct platform_device *pdev)
25156+{
25157+	struct hisi_fmc *fmc = NULL;
25158+	struct resource *res = NULL;
25159+	struct device *dev = &pdev->dev;
25160+	int ret;
25161+
25162+	fmc = devm_kzalloc(dev, sizeof(*fmc), GFP_KERNEL);
25163+	if (!fmc)
25164+		return -ENOMEM;
25165+
25166+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "control");
25167+	fmc->regbase = devm_ioremap_resource(dev, res);
25168+	if (IS_ERR(fmc->regbase))
25169+		return PTR_ERR(fmc->regbase);
25170+
25171+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "memory");
25172+	fmc->iobase = devm_ioremap_resource(dev, res);
25173+	if (IS_ERR(fmc->iobase))
25174+		return PTR_ERR(fmc->iobase);
25175+
25176+	fmc->clk = devm_clk_get(dev, NULL);
25177+	if (IS_ERR(fmc->clk))
25178+		return PTR_ERR(fmc->clk);
25179+
25180+	if (of_property_read_u32(dev->of_node, "max-dma-size", &fmc->dma_len)) {
25181+		dev_err(dev, "Please set the suitable max-dma-size value !!!\n");
25182+		return -ENOMEM;
25183+	}
25184+
25185+	ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
25186+	if (ret) {
25187+		dev_warn(dev, "Unable to set dma mask\n");
25188+		return ret;
25189+	}
25190+
25191+	fmc->buffer = dmam_alloc_coherent(dev, fmc->dma_len,
25192+					  &fmc->dma_buffer, GFP_KERNEL);
25193+	if (IS_ERR(fmc->buffer))
25194+		return PTR_ERR(fmc->buffer);
25195+
25196+	mutex_init(&fmc->lock);
25197+
25198+	platform_set_drvdata(pdev, fmc);
25199+
25200+	ret = mfd_add_devices(dev, 0, hisi_fmc_devs,
25201+			      ARRAY_SIZE(hisi_fmc_devs), NULL, 0, NULL);
25202+	if (ret) {
25203+		dev_err(dev, "add mfd devices failed: %d\n", ret);
25204+		return ret;
25205+	}
25206+
25207+	return 0;
25208+}
25209+
25210+static int hisi_fmc_remove(struct platform_device *pdev)
25211+{
25212+	struct hisi_fmc *fmc = platform_get_drvdata(pdev);
25213+
25214+	dmam_free_coherent(&pdev->dev, fmc->dma_len,
25215+			   fmc->buffer, fmc->dma_buffer);
25216+	mfd_remove_devices(&pdev->dev);
25217+	mutex_destroy(&fmc->lock);
25218+
25219+	return 0;
25220+}
25221+
25222+static const struct of_device_id hisi_fmc_of_match_tbl[] = {
25223+	{.compatible = "hisilicon,hisi-fmc"},
25224+	{ }
25225+};
25226+MODULE_DEVICE_TABLE(of, hisi_fmc_of_match_tbl);
25227+
25228+static struct platform_driver hisi_fmc_driver = {
25229+	.driver = {
25230+		.name = "hifmc",
25231+		.of_match_table = hisi_fmc_of_match_tbl,
25232+	},
25233+	.probe = hisi_fmc_probe,
25234+	.remove = hisi_fmc_remove,
25235+};
25236+module_platform_driver(hisi_fmc_driver);
25237+
25238+MODULE_LICENSE("GPL v2");
25239+MODULE_DESCRIPTION("HiSilicon Flash Memory Controller Driver");
25240diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c
25241index 94caee49d..c69c59dcb 100644
25242--- a/drivers/mmc/core/block.c
25243+++ b/drivers/mmc/core/block.c
25244@@ -537,18 +537,16 @@ static int __mmc_blk_ioctl_cmd(struct mmc_card *card, struct mmc_blk_data *md,
25245 			return err;
25246 	}
25247
25248-	if (idata->rpmb || prev_idata) {
25249-		sbc.opcode = MMC_SET_BLOCK_COUNT;
25250-		/*
25251-		 * We don't do any blockcount validation because the max size
25252-		 * may be increased by a future standard. We just copy the
25253-		 * 'Reliable Write' bit here.
25254-		 */
25255-		sbc.arg = data.blocks | (idata->ic.write_flag & BIT(31));
25256-		if (prev_idata)
25257-			sbc.arg = prev_idata->ic.arg;
25258-		sbc.flags = MMC_RSP_R1 | MMC_CMD_AC;
25259-		mrq.sbc = &sbc;
25260+	if (idata->rpmb) {
25261+		struct mmc_command mmc_cmd = {};
25262+		mmc_cmd.opcode = MMC_SET_BLOCK_COUNT;
25263+		mmc_cmd.arg = data.blocks & 0x0000FFFF;
25264+		if (idata->ic.write_flag & (1 << 31))
25265+			mmc_cmd.arg |= 1 << 31;
25266+		mmc_cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_AC;
25267+		err = mmc_wait_for_cmd(card->host, &mmc_cmd, 5);
25268+		if (err)
25269+			return err;
25270 	}
25271
25272 	if ((MMC_EXTRACT_INDEX_FROM_ARG(cmd.arg) == EXT_CSD_SANITIZE_START) &&
25273diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c
25274index b5f3f160c..0b0e367bc 100644
25275--- a/drivers/mmc/core/core.c
25276+++ b/drivers/mmc/core/core.c
25277@@ -1371,6 +1371,9 @@ void mmc_power_off(struct mmc_host *host)
25278
25279 void mmc_power_cycle(struct mmc_host *host, u32 ocr)
25280 {
25281+	if (host->type == MMC_HOST_TYPE_MMC)
25282+		return;
25283+
25284 	mmc_power_off(host);
25285 	/* Wait at least 1 ms according to SD spec */
25286 	mmc_delay(1);
25287@@ -2286,9 +2289,12 @@ void mmc_rescan(struct work_struct *work)
25288 	mmc_bus_put(host);
25289
25290 	mmc_claim_host(host);
25291+	host->card_status = MMC_CARD_UNINIT;
25292 	if (mmc_card_is_removable(host) && host->ops->get_cd &&
25293 			host->ops->get_cd(host) == 0) {
25294 		mmc_power_off(host);
25295+		if (host->ops->card_info_save)
25296+			host->ops->card_info_save(host);
25297 		mmc_release_host(host);
25298 		goto out;
25299 	}
25300@@ -2300,8 +2306,17 @@ void mmc_rescan(struct work_struct *work)
25301 				continue;
25302 			freq = host->f_max;
25303 		}
25304-		if (!mmc_rescan_try_freq(host, max(freq, host->f_min)))
25305+
25306+		if (!mmc_rescan_try_freq(host, max(freqs[i], host->f_min))) {
25307+			host->card_status = MMC_CARD_INIT;
25308+			if (host->ops->card_info_save)
25309+				host->ops->card_info_save(host);
25310 			break;
25311+		} else if ((i == (ARRAY_SIZE(freqs) - 1)) ||
25312+			(freqs[i] <= host->f_min)) {
25313+			host->card_status = MMC_CARD_INIT_FAIL;
25314+		}
25315+
25316 		if (freqs[i] <= host->f_min)
25317 			break;
25318 	}
25319diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c
25320index 7494d5950..416fc6723 100644
25321--- a/drivers/mmc/core/mmc.c
25322+++ b/drivers/mmc/core/mmc.c
25323@@ -1414,7 +1414,9 @@ static int mmc_select_hs400es(struct mmc_card *card)
25324
25325 	/* Set host controller to HS400 timing and frequency */
25326 	mmc_set_timing(host, MMC_TIMING_MMC_HS400);
25327-
25328+#if defined(CONFIG_MMC_SDHCI_HISI) || (defined(MODULE) && defined(CONFIG_MMC_SDHCI_HISI_MODULE))
25329+	mmc_set_bus_speed(card);
25330+#endif
25331 	/* Controller enable enhanced strobe function */
25332 	host->ios.enhanced_strobe = true;
25333 	if (host->ops->hs400_enhanced_strobe)
25334@@ -1512,7 +1514,8 @@ static int mmc_select_timing(struct mmc_card *card)
25335 	if (!mmc_can_ext_csd(card))
25336 		goto bus_speed;
25337
25338-	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES)
25339+	if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS400ES &&
25340+	    card->host->caps & MMC_CAP_8_BIT_DATA)
25341 		err = mmc_select_hs400es(card);
25342 	else if (card->mmc_avail_type & EXT_CSD_CARD_TYPE_HS200)
25343 		err = mmc_select_hs200(card);
25344@@ -2239,6 +2242,7 @@ int mmc_attach_mmc(struct mmc_host *host)
25345 	if (err)
25346 		return err;
25347
25348+	host->type = MMC_HOST_TYPE_MMC;
25349 	mmc_attach_bus(host, &mmc_ops);
25350 	if (host->ocr_avail_mmc)
25351 		host->ocr_avail = host->ocr_avail_mmc;
25352diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
25353index bac343a8d..af8bf24cd 100644
25354--- a/drivers/mmc/core/sd.c
25355+++ b/drivers/mmc/core/sd.c
25356@@ -1349,6 +1349,7 @@ int mmc_attach_sd(struct mmc_host *host)
25357 	if (err)
25358 		return err;
25359
25360+	host->type = MMC_HOST_TYPE_SD;
25361 	mmc_attach_bus(host, &mmc_sd_ops);
25362 	if (host->ocr_avail_sd)
25363 		host->ocr_avail = host->ocr_avail_sd;
25364diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c
25365index 1b0853a82..3e452090d 100644
25366--- a/drivers/mmc/core/sdio.c
25367+++ b/drivers/mmc/core/sdio.c
25368@@ -1193,6 +1193,7 @@ int mmc_attach_sdio(struct mmc_host *host)
25369 	if (err)
25370 		return err;
25371
25372+	host->type = MMC_HOST_TYPE_SDIO;
25373 	mmc_attach_bus(host, &mmc_sdio_ops);
25374 	if (host->ocr_avail_sdio)
25375 		host->ocr_avail = host->ocr_avail_sdio;
25376@@ -1306,3 +1307,40 @@ int mmc_attach_sdio(struct mmc_host *host)
25377 	return err;
25378 }
25379
25380+#ifdef CONFIG_ARCH_HISI_BVT
25381+/* sdio_reset_comm has been fixed in latest kernel/msm.git for Linux
25382+ * 2.6.27. The implementation prior to that buggy, and needs broadcom's
25383+ * patch for it*/
25384+int sdio_reset_comm(struct mmc_card *card)
25385+{
25386+	struct mmc_host *host = card->host;
25387+	u32 ocr;
25388+	u32 rocr;
25389+	int err;
25390+
25391+	mmc_claim_host(host);
25392+	mmc_retune_disable(host);
25393+	mmc_go_idle(host);
25394+	mmc_set_clock(host, host->f_min);
25395+	err = mmc_send_io_op_cond(host, 0, &ocr);
25396+	if (err)
25397+		goto err;
25398+	rocr = mmc_select_voltage(host, ocr);
25399+	if (!rocr) {
25400+		err = -EINVAL;
25401+		goto err;
25402+	}
25403+	err = mmc_sdio_init_card(host, rocr, card);
25404+	if (err)
25405+		goto err;
25406+	mmc_release_host(host);
25407+	return 0;
25408+err:
25409+	printk("%s: Error resetting SDIO communications: %d\n",
25410+			mmc_hostname(host), err);
25411+	mmc_release_host(host);
25412+	return err;
25413+}
25414+EXPORT_SYMBOL(sdio_reset_comm);
25415+#endif
25416+
25417diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig
25418index 31481c9fc..299758712 100644
25419--- a/drivers/mmc/host/Kconfig
25420+++ b/drivers/mmc/host/Kconfig
25421@@ -247,6 +247,21 @@ config MMC_SDHCI_CNS3XXX
25422
25423 	  If unsure, say N.
25424
25425+config MMC_SDHCI_HISI
25426+	tristate "SDHCI support on the Hisilicon Hi35xx SoC"
25427+	depends on ARCH_HI3531DV200 || ARCH_HI3535AV100 || ARCH_HI3521DV200 ||\
25428+		   ARCH_HI3520DV500 || ARCH_HI3559AV100 || ARCH_HI3556AV100 ||\
25429+		   ARCH_HI3519AV100 || ARCH_HI3516EV200 || ARCH_HI3516EV300 ||\
25430+                   ARCH_HI3518EV300 || ARCH_HI3516DV200 || ARCH_HI3569V100  ||\
25431+		   ARCH_HI3568V100
25432+	depends on MMC_SDHCI_PLTFM
25433+	help
25434+	  This selects the SDHCI support for Hi35xx System-on-Chip devices.
25435+
25436+	  If you have a controller with this interface, say Y or M here.
25437+
25438+	  If unsure, say N.
25439+
25440 config MMC_SDHCI_ESDHC_MCF
25441 	tristate "SDHCI support for the Freescale eSDHC ColdFire controller"
25442 	depends on M5441x
25443@@ -1077,6 +1092,21 @@ config MMC_SDHCI_OMAP
25444
25445 	  If unsure, say N.
25446
25447+config MMC_CQ_HCI
25448+	tristate "Command Queue Support"
25449+	depends on HAS_DMA
25450+	help
25451+	  This selects the Command Queue Host Controller Interface (CQHCI)
25452+	  support present in host controllers of Qualcomm Technologies, Inc
25453+	  amongst others.
25454+	  This controller supports eMMC devices with command queue support.
25455+
25456+	  If you have a controller with this interface, say Y or M here.
25457+
25458+	  If unsure, say N.
25459+
25460+source "drivers/mmc/host/himci/Kconfig"
25461+
25462 config MMC_SDHCI_AM654
25463 	tristate "Support for the SDHCI Controller in TI's AM654 SOCs"
25464 	depends on MMC_SDHCI_PLTFM && OF && REGMAP_MMIO
25465diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile
25466index 451c25fc2..e7ec6250e 100644
25467--- a/drivers/mmc/host/Makefile
25468+++ b/drivers/mmc/host/Makefile
25469@@ -94,6 +94,21 @@ obj-$(CONFIG_MMC_SDHCI_OF_AT91)		+= sdhci-of-at91.o
25470 obj-$(CONFIG_MMC_SDHCI_OF_ESDHC)	+= sdhci-of-esdhc.o
25471 obj-$(CONFIG_MMC_SDHCI_OF_HLWD)		+= sdhci-of-hlwd.o
25472 obj-$(CONFIG_MMC_SDHCI_OF_DWCMSHC)	+= sdhci-of-dwcmshc.o
25473+obj-$(CONFIG_MMC_SDHCI_HISI)		+= sdhci-of-hisi.o
25474+sdhci-of-hisi-objs			:= sdhci-hisi.o mci_proc.o
25475+sdhci-of-hisi-$(CONFIG_ARCH_HI3531DV200)	+= sdhci-hi3531dv200.o
25476+sdhci-of-hisi-$(CONFIG_ARCH_HI3535AV100)	+= sdhci-hi3531dv200.o
25477+sdhci-of-hisi-$(CONFIG_ARCH_HI3521DV200)	+= sdhci-hi3521dv200.o
25478+sdhci-of-hisi-$(CONFIG_ARCH_HI3520DV500)	+= sdhci-hi3521dv200.o
25479+sdhci-of-hisi-$(CONFIG_ARCH_HI3559AV100)	+= sdhci-hi3559av100.o
25480+sdhci-of-hisi-$(CONFIG_ARCH_HI3556AV100)	+= sdhci-hi3556av100.o
25481+sdhci-of-hisi-$(CONFIG_ARCH_HI3519AV100)	+= sdhci-hi3556av100.o
25482+sdhci-of-hisi-$(CONFIG_ARCH_HI3516EV200)	+= sdhci-hi3516ev200.o
25483+sdhci-of-hisi-$(CONFIG_ARCH_HI3516EV300)	+= sdhci-hi3516ev300.o
25484+sdhci-of-hisi-$(CONFIG_ARCH_HI3518EV300)	+= sdhci-hi3518ev300.o
25485+sdhci-of-hisi-$(CONFIG_ARCH_HI3516DV200)	+= sdhci-hi3516dv200.o
25486+sdhci-of-hisi-$(CONFIG_ARCH_HI3568V100)		+= sdhci-hi3556av100.o
25487+sdhci-of-hisi-$(CONFIG_ARCH_HI3569V100)		+= sdhci-hi3559av100.o
25488 obj-$(CONFIG_MMC_SDHCI_OF_SPARX5)	+= sdhci-of-sparx5.o
25489 obj-$(CONFIG_MMC_SDHCI_BCM_KONA)	+= sdhci-bcm-kona.o
25490 obj-$(CONFIG_MMC_SDHCI_IPROC)		+= sdhci-iproc.o
25491@@ -112,3 +127,5 @@ endif
25492
25493 obj-$(CONFIG_MMC_SDHCI_XENON)	+= sdhci-xenon-driver.o
25494 sdhci-xenon-driver-y		+= sdhci-xenon.o sdhci-xenon-phy.o
25495+
25496+obj-$(CONFIG_HIMCI)	+= himci/
25497diff --git a/drivers/mmc/host/cqhci.c b/drivers/mmc/host/cqhci.c
25498index 7ba4f7141..f5614efa4 100644
25499--- a/drivers/mmc/host/cqhci.c
25500+++ b/drivers/mmc/host/cqhci.c
25501@@ -46,6 +46,11 @@ static inline u8 *get_link_desc(struct cqhci_host *cq_host, u8 tag)
25502
25503 static inline dma_addr_t get_trans_desc_dma(struct cqhci_host *cq_host, u8 tag)
25504 {
25505+	if (cq_host->quirks & CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT)
25506+		return cq_host->trans_desc_dma_base +
25507+		(cq_host->mmc->max_segs * tag * 2 *
25508+		 cq_host->trans_desc_len);
25509+
25510 	return cq_host->trans_desc_dma_base +
25511 		(cq_host->mmc->max_segs * tag *
25512 		 cq_host->trans_desc_len);
25513@@ -53,6 +58,11 @@ static inline dma_addr_t get_trans_desc_dma(struct cqhci_host *cq_host, u8 tag)
25514
25515 static inline u8 *get_trans_desc(struct cqhci_host *cq_host, u8 tag)
25516 {
25517+	if (cq_host->quirks & CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT)
25518+		return cq_host->trans_desc_base +
25519+			(cq_host->trans_desc_len *
25520+			 cq_host->mmc->max_segs * 2 * tag);
25521+
25522 	return cq_host->trans_desc_base +
25523 		(cq_host->trans_desc_len * cq_host->mmc->max_segs * tag);
25524 }
25525@@ -193,8 +203,12 @@ static int cqhci_host_alloc_tdl(struct cqhci_host *cq_host)
25526
25527 	cq_host->desc_size = cq_host->slot_sz * cq_host->num_slots;
25528
25529-	cq_host->data_size = cq_host->trans_desc_len * cq_host->mmc->max_segs *
25530-		cq_host->mmc->cqe_qdepth;
25531+	if (cq_host->quirks & CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT)
25532+		cq_host->data_size = cq_host->trans_desc_len *
25533+			cq_host->mmc->max_segs * 2 * cq_host->mmc->cqe_qdepth;
25534+	else
25535+		cq_host->data_size = cq_host->trans_desc_len *
25536+			cq_host->mmc->max_segs * cq_host->mmc->cqe_qdepth;
25537
25538 	pr_debug("%s: cqhci: desc_size: %zu data_sz: %zu slot-sz: %d\n",
25539 		 mmc_hostname(cq_host->mmc), cq_host->desc_size, cq_host->data_size,
25540@@ -267,6 +281,8 @@ static void __cqhci_enable(struct cqhci_host *cq_host)
25541
25542 	cqhci_writel(cq_host, cq_host->rca, CQHCI_SSC2);
25543
25544+	cqhci_writel(cq_host, SEND_QSR_INTERVAL, CQHCI_SSC1);
25545+
25546 	cqhci_set_irqs(cq_host, 0);
25547
25548 	cqcfg |= CQHCI_ENABLE;
25549@@ -276,8 +292,6 @@ static void __cqhci_enable(struct cqhci_host *cq_host)
25550 	if (cqhci_readl(cq_host, CQHCI_CTL) & CQHCI_HALT)
25551 		cqhci_writel(cq_host, 0, CQHCI_CTL);
25552
25553-	mmc->cqe_on = true;
25554-
25555 	if (cq_host->ops->enable)
25556 		cq_host->ops->enable(mmc);
25557
25558@@ -452,7 +466,7 @@ static int cqhci_dma_map(struct mmc_host *host, struct mmc_request *mrq)
25559 	return sg_count;
25560 }
25561
25562-static void cqhci_set_tran_desc(u8 *desc, dma_addr_t addr, int len, bool end,
25563+static void _cqhci_set_tran_desc(u8 *desc, dma_addr_t addr, int len, bool end,
25564 				bool dma64)
25565 {
25566 	__le32 *attr = (__le32 __force *)desc;
25567@@ -474,6 +488,27 @@ static void cqhci_set_tran_desc(u8 *desc, dma_addr_t addr, int len, bool end,
25568 	}
25569 }
25570
25571+static void cqhci_set_tran_desc(struct cqhci_host *cq_host, u8 **desc,
25572+		dma_addr_t addr, int len, bool end, bool dma64, unsigned int blksz)
25573+{
25574+	int desc_len;
25575+
25576+	if (cq_host->quirks & CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT &&
25577+		addr % SYNOPSYS_DMA_LIMIT + len > SYNOPSYS_DMA_LIMIT) {
25578+		if ((addr + (unsigned int)len) % SYNOPSYS_DMA_LIMIT < blksz)
25579+			BUG_ON(1);
25580+
25581+		desc_len = (SYNOPSYS_DMA_LIMIT - addr % SYNOPSYS_DMA_LIMIT);
25582+		_cqhci_set_tran_desc(*desc, addr, desc_len, false, dma64);
25583+
25584+		*desc = *desc + cq_host->trans_desc_len;
25585+		len -= desc_len;
25586+		addr += desc_len;
25587+	}
25588+
25589+	_cqhci_set_tran_desc(*desc, addr, len, end, dma64);
25590+}
25591+
25592 static int cqhci_prep_tran_desc(struct mmc_request *mrq,
25593 			       struct cqhci_host *cq_host, int tag)
25594 {
25595@@ -500,7 +535,7 @@ static int cqhci_prep_tran_desc(struct mmc_request *mrq,
25596
25597 		if ((i+1) == sg_count)
25598 			end = true;
25599-		cqhci_set_tran_desc(desc, addr, len, end, dma64);
25600+		cqhci_set_tran_desc(cq_host, &desc, addr, len, end, dma64, data->blksz);
25601 		desc += cq_host->trans_desc_len;
25602 	}
25603
25604@@ -951,6 +986,9 @@ static void cqhci_recovery_start(struct mmc_host *mmc)
25605 		cq_host->ops->disable(mmc, true);
25606
25607 	mmc->cqe_on = false;
25608+
25609+	cqhci_deactivate(mmc);
25610+
25611 }
25612
25613 static int cqhci_error_from_flags(unsigned int flags)
25614diff --git a/drivers/mmc/host/cqhci.h b/drivers/mmc/host/cqhci.h
25615index 89bf6adbc..05571faf0 100644
25616--- a/drivers/mmc/host/cqhci.h
25617+++ b/drivers/mmc/host/cqhci.h
25618@@ -80,6 +80,12 @@
25619
25620 /* send status config 1 */
25621 #define CQHCI_SSC1			0x40
25622+/*
25623+ * Value n means CQE would send CMD13 during the transfer of data block
25624+ * BLOCK_CNT-n
25625+ */
25626+#define SEND_QSR_INTERVAL 0x70001
25627+
25628 #define CQHCI_SSC1_CBC_MASK		GENMASK(19, 16)
25629
25630 /* send status config 2 */
25631@@ -138,6 +144,7 @@
25632 #define CQHCI_DAT_ADDR_LO(x)		(((x) & 0xFFFFFFFF) << 32)
25633 #define CQHCI_DAT_ADDR_HI(x)		(((x) & 0xFFFFFFFF) << 0)
25634
25635+#define SYNOPSYS_DMA_LIMIT		0x8000000
25636 struct cqhci_host_ops;
25637 struct mmc_host;
25638 struct mmc_request;
25639@@ -164,6 +171,7 @@ struct cqhci_host {
25640
25641 	u32 quirks;
25642 #define CQHCI_QUIRK_SHORT_TXFR_DESC_SZ	0x1
25643+#define CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT	0x2
25644
25645 	bool enabled;
25646 	bool halted;
25647diff --git a/drivers/mmc/host/himci/Kconfig b/drivers/mmc/host/himci/Kconfig
25648new file mode 100644
25649index 000000000..f3331c862
25650--- /dev/null
25651+++ b/drivers/mmc/host/himci/Kconfig
25652@@ -0,0 +1,23 @@
25653+#
25654+#  himci family SD/MMC device configuration
25655+#
25656+menuconfig HIMCI
25657+	tristate "himci driver support"
25658+	depends on ARCH_HI3516A || ARCH_HI3518EV20X || ARCH_HI3516CV500 || ARCH_HI3516DV300 || ARCH_HI3556V200 || ARCH_HI3559V200 || ARCH_HI3562V100 || ARCH_HI3566V100
25659+	default y if ARCH_HI3516A
25660+	select MMC_UNSAFE_RESUME
25661+	select MMC_EMBEDDED_SDIO
25662+	select MMC_BLOCK
25663+	select MMC_BLOCK_BOUNCE
25664+	help
25665+	  This selects the Hisilicon Synopsys MultiMedia Card Driver
25666+	  support. If you want use SD/MMC/SDIO driver,
25667+	  Say Y or M here.
25668+
25669+	  default is Y.
25670+
25671+config SEND_AUTO_STOP
25672+	bool "Send Auto Stop to terminate data transfer between host and SD card"
25673+	depends on HIMCI
25674+	default y
25675+
25676diff --git a/drivers/mmc/host/himci/Makefile b/drivers/mmc/host/himci/Makefile
25677new file mode 100644
25678index 000000000..6858bfcef
25679--- /dev/null
25680+++ b/drivers/mmc/host/himci/Makefile
25681@@ -0,0 +1,2 @@
25682+obj-$(CONFIG_HIMCI) += hisi_mci.o
25683+hisi_mci-y	:= himci.o himci_proc.o
25684diff --git a/drivers/mmc/host/himci/himci.c b/drivers/mmc/host/himci/himci.c
25685new file mode 100644
25686index 000000000..65aa8d24e
25687--- /dev/null
25688+++ b/drivers/mmc/host/himci/himci.c
25689@@ -0,0 +1,2580 @@
25690+/*
25691+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
25692+ *
25693+ * This program is free software; you can redistribute it and/or modify
25694+ * it under the terms of the GNU General Public License as published by
25695+ * the Free Software Foundation; either version 2 of the License, or
25696+ * (at your option) any later version.
25697+ *
25698+ * This program is distributed in the hope that it will be useful,
25699+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
25700+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
25701+ * GNU General Public License for more details.
25702+ *
25703+ * You should have received a copy of the GNU General Public License
25704+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
25705+ */
25706+#define pr_fmt(fmt) "himci: " fmt
25707+
25708+#include <linux/module.h>
25709+#include <linux/kernel.h>
25710+#include <linux/init.h>
25711+#include <linux/platform_device.h>
25712+#include <linux/mm.h>
25713+#include <linux/interrupt.h>
25714+#include <linux/dma-mapping.h>
25715+#include <linux/scatterlist.h>
25716+
25717+#include <linux/mmc/host.h>
25718+#include <linux/mmc/mmc.h>
25719+#include <linux/mmc/card.h>
25720+#include <linux/mmc/core.h>
25721+#include <linux/mmc/sd.h>
25722+#include <linux/slab.h>
25723+
25724+#include <linux/ioport.h>
25725+#include <linux/device.h>
25726+#include <linux/spinlock.h>
25727+
25728+#include <linux/delay.h>
25729+#include <linux/dma-mapping.h>
25730+#include <linux/kthread.h>
25731+#include <linux/workqueue.h>
25732+#include <linux/freezer.h>
25733+#include <asm/dma.h>
25734+#include <asm/irq.h>
25735+#include <linux/sizes.h>
25736+#include <mach/io.h>
25737+
25738+#include <linux/io.h>
25739+#include <linux/of.h>
25740+#include <linux/clk.h>
25741+#include <linux/clk-provider.h>
25742+#include <linux/reset.h>
25743+
25744+#include "himci_reg.h"
25745+#include "himci.h"
25746+#include "himci_proc.h"
25747+
25748+#ifdef CONFIG_ARCH_HI3516A
25749+#include "himci_hi3516a.c"
25750+#endif
25751+
25752+#ifdef CONFIG_ARCH_HI3518EV20X
25753+#include "himci_hi3518ev20x.c"
25754+#endif
25755+
25756+#ifdef CONFIG_ARCH_HI3516CV500
25757+#include "himci_hi3516cv500.c"
25758+#endif
25759+
25760+#ifdef CONFIG_ARCH_HI3516DV300
25761+#include "himci_hi3516dv300.c"
25762+#endif
25763+
25764+#ifdef CONFIG_ARCH_HI3556V200
25765+#include "himci_hi3556v200.c"
25766+#endif
25767+
25768+#ifdef CONFIG_ARCH_HI3559V200
25769+#include "himci_hi3559v200.c"
25770+#endif
25771+
25772+#ifdef CONFIG_ARCH_HI3562V100
25773+#include "himci_hi3559v200.c"
25774+#endif
25775+
25776+#ifdef CONFIG_ARCH_HI3566V100
25777+#include "himci_hi3559v200.c"
25778+#endif
25779+
25780+#define DRIVER_NAME "himci"
25781+
25782+#ifndef CONFIG_HISI_MC
25783+#define CMD_DES_PAGE_SIZE	(3 * PAGE_SIZE)
25784+#else
25785+#define CMD_DES_PAGE_SIZE	(8 * PAGE_SIZE)
25786+#endif
25787+
25788+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \
25789+    defined(CONFIG_ARCH_HI3556V200)  || defined(CONFIG_ARCH_HI3559V200)  || \
25790+    defined(CONFIG_ARCH_HI3562V100)  || defined(CONFIG_ARCH_HI3566V100)
25791+void __iomem *crg_ctrl, *misc_ctrl_1;
25792+#endif
25793+
25794+#if defined(CONFIG_ARCH_HI3516DV300)
25795+#define PWR_CTRL0_REG 0x12090000
25796+#define GPIO_AT_PMC_ENABLE_BIT 0x80
25797+#define REG_SLEEP_TIME_MS 0x30
25798+#endif
25799+
25800+static unsigned int detect_time = HI_MCI_DETECT_TIMEOUT;
25801+static unsigned int retry_count = MAX_RETRY_COUNT;
25802+static unsigned int request_timeout = HI_MCI_REQUEST_TIMEOUT;
25803+int trace_level = HIMCI_TRACE_LEVEL;
25804+unsigned int slot_index = 0;
25805+struct himci_host *mci_host[HIMCI_SLOT_NUM] = {NULL};
25806+#ifdef MODULE
25807+
25808+module_param(detect_time, uint, 0600);
25809+MODULE_PARM_DESC(detect_timer, "card detect time (default:500ms))");
25810+
25811+module_param(retry_count, uint, 0600);
25812+MODULE_PARM_DESC(retry_count, "retry count times (default:100))");
25813+
25814+module_param(request_timeout, uint, 0600);
25815+MODULE_PARM_DESC(request_timeout, "Request timeout time (default:3s))");
25816+
25817+module_param(trace_level, int, 0600);
25818+MODULE_PARM_DESC(trace_level, "HIMCI_TRACE_LEVEL");
25819+
25820+#endif
25821+
25822+/* reset MMC host controller */
25823+static void himci_sys_reset(struct himci_host *host)
25824+{
25825+	unsigned int reg_value;
25826+	unsigned long flags;
25827+
25828+	himci_trace(2, "reset");
25829+
25830+	local_irq_save(flags);
25831+
25832+	reg_value = himci_readl(host->base + MCI_BMOD);
25833+	reg_value |= BMOD_SWR;
25834+	himci_writel(reg_value, host->base + MCI_BMOD);
25835+	mdelay(10);
25836+
25837+	reg_value = himci_readl(host->base + MCI_BMOD);
25838+	reg_value |= BURST_16 | BURST_INCR;
25839+	himci_writel(reg_value, host->base + MCI_BMOD);
25840+
25841+	reg_value = himci_readl(host->base + MCI_CTRL);
25842+	reg_value |=  CTRL_RESET | FIFO_RESET | DMA_RESET;
25843+	himci_writel(reg_value, host->base + MCI_CTRL);
25844+
25845+	local_irq_restore(flags);
25846+}
25847+
25848+static void himci_ctrl_power(struct himci_host *host,
25849+			     unsigned int flag, unsigned int force)
25850+{
25851+	unsigned int port;
25852+
25853+	himci_trace(2, "begin");
25854+
25855+	port = host->port;
25856+
25857+	if (host->power_status != flag || force == FORCE_ENABLE) {
25858+		unsigned int reg_value;
25859+
25860+		if (flag == POWER_OFF) {
25861+			reg_value = himci_readl(host->base + MCI_RESET_N);
25862+			reg_value &= ~(MMC_RST_N << port);
25863+			himci_writel(reg_value, host->base + MCI_RESET_N);
25864+		}
25865+
25866+		reg_value = himci_readl(host->base + MCI_PWREN);
25867+		if (flag == POWER_OFF)
25868+			reg_value &= ~(0x1 << port);
25869+		else
25870+			reg_value |= (0x1 << port);
25871+
25872+		himci_writel(reg_value, host->base + MCI_PWREN);
25873+
25874+		if (flag == POWER_ON) {
25875+			reg_value = himci_readl(host->base + MCI_RESET_N);
25876+			reg_value |= (MMC_RST_N << port);
25877+			himci_writel(reg_value, host->base + MCI_RESET_N);
25878+		}
25879+
25880+		if (in_interrupt())
25881+			mdelay(100);
25882+		else
25883+			msleep(100);
25884+
25885+		host->power_status = flag;
25886+	}
25887+}
25888+
25889+/**********************************************
25890+ * 1: card off
25891+ * 0: card on
25892+ ***********************************************/
25893+static unsigned int himci_sys_card_detect(struct himci_host *host)
25894+{
25895+	unsigned int card_status;
25896+
25897+	card_status = readl(host->base + MCI_CDETECT);
25898+	card_status &= (HIMCI_CARD0 << host->port);
25899+	if (card_status)
25900+		card_status = 1;
25901+	else
25902+		card_status = 0;
25903+
25904+	return card_status;
25905+}
25906+
25907+/**********************************************
25908+ * 1: card readonly
25909+ * 0: card read/write
25910+ ***********************************************/
25911+static unsigned int himci_ctrl_card_readonly(struct himci_host *host)
25912+{
25913+	unsigned int card_value = himci_readl(host->base + MCI_WRTPRT);
25914+	return card_value & (HIMCI_CARD0 << host->port);
25915+}
25916+
25917+static int tuning_reset_flag = 0;
25918+
25919+static int himci_wait_cmd(struct himci_host *host)
25920+{
25921+	int wait_retry_count = 0;
25922+	int retry_count_cmd = 500;
25923+	unsigned int reg_data = 0;
25924+	unsigned long flags;
25925+
25926+	himci_trace(2, "begin");
25927+	himci_assert(host);
25928+
25929+	while (1) {
25930+		/*
25931+		 * Check if CMD::start_cmd bit is clear.
25932+		 * start_cmd = 0 means MMC Host controller has loaded registers
25933+		 * and next command can be loaded in.
25934+		 */
25935+		reg_data = himci_readl(host->base + MCI_CMD);
25936+		if ((reg_data & START_CMD) == 0)
25937+			return 0;
25938+
25939+		/* Check if Raw_Intr_Status::HLE bit is set. */
25940+		spin_lock_irqsave(&host->lock, flags);
25941+		reg_data = himci_readl(host->base + MCI_RINTSTS);
25942+		if (reg_data & HLE_INT_STATUS) {
25943+			reg_data |= HLE_INT_STATUS;
25944+			himci_writel(reg_data, host->base + MCI_RINTSTS);
25945+			spin_unlock_irqrestore(&host->lock, flags);
25946+
25947+			himci_trace(5, "Other CMD is running,"
25948+				    "please operate cmd again!");
25949+			return 1;
25950+		}
25951+
25952+		spin_unlock_irqrestore(&host->lock, flags);
25953+		udelay(1);
25954+
25955+		/* Check if number of retries for this are over. */
25956+		wait_retry_count++;
25957+		if (wait_retry_count >= retry_count_cmd) {
25958+			if (host->is_tuning)
25959+				tuning_reset_flag = 1;
25960+			himci_trace(3, "send cmd is timeout!");
25961+			return -1;
25962+		}
25963+	}
25964+}
25965+
25966+static int himci_control_cclk(struct himci_host *host, unsigned int flag)
25967+{
25968+	unsigned int reg;
25969+	union cmd_arg_u cmd_reg;
25970+
25971+	himci_trace(2, "begin");
25972+	himci_assert(host);
25973+
25974+	reg = himci_readl(host->base + MCI_CLKENA);
25975+	if (flag == ENABLE) {
25976+		reg |= (CCLK_ENABLE << host->port);
25977+		reg |= (CCLK_LOW_POWER << host->port);
25978+	} else {
25979+		reg &= ~(CCLK_ENABLE << host->port);
25980+		reg &= ~(CCLK_LOW_POWER << host->port);
25981+	}
25982+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \
25983+    defined(CONFIG_ARCH_HI3556V200)  || defined(CONFIG_ARCH_HI3559V200)  || \
25984+    defined(CONFIG_ARCH_HI3562V100)  || defined(CONFIG_ARCH_HI3566V100)
25985+	if (host->devid == 2)
25986+		reg &= ~(CCLK_LOW_POWER << host->port);
25987+#endif
25988+	himci_writel(reg, host->base + MCI_CLKENA);
25989+
25990+	cmd_reg.cmd_arg = himci_readl(host->base + MCI_CMD);
25991+	cmd_reg.bits.start_cmd = 1;
25992+	cmd_reg.bits.card_number = host->port;
25993+	cmd_reg.bits.cmd_index = 0;
25994+	cmd_reg.bits.data_transfer_expected = 0;
25995+	cmd_reg.bits.update_clk_reg_only = 1;
25996+	cmd_reg.bits.response_expect = 0;
25997+	cmd_reg.bits.send_auto_stop = 0;
25998+	cmd_reg.bits.wait_prvdata_complete = 0;
25999+	cmd_reg.bits.check_response_crc = 0;
26000+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \
26001+    defined(CONFIG_ARCH_HI3556V200)  || defined(CONFIG_ARCH_HI3559V200)  || \
26002+    defined(CONFIG_ARCH_HI3562V100)  || defined(CONFIG_ARCH_HI3566V100)
26003+	cmd_reg.bits.use_hold_reg = 1;
26004+#endif
26005+	himci_writel(cmd_reg.cmd_arg, host->base + MCI_CMD);
26006+	if (himci_wait_cmd(host) != 0) {
26007+		himci_trace(3, "disable or enable clk is timeout!");
26008+		return -ETIMEDOUT;
26009+	} else {
26010+		return 0;
26011+	}
26012+}
26013+
26014+static void himci_set_cclk(struct himci_host *host, unsigned int cclk)
26015+{
26016+	unsigned int reg_value;
26017+	union cmd_arg_u clk_cmd;
26018+	unsigned int hclk;
26019+
26020+	himci_trace(2, "begin");
26021+	himci_assert(host);
26022+	himci_assert(cclk);
26023+
26024+	hclk = cclk > MMC_CRG_MIN ? cclk : MMC_CRG_MIN;
26025+	clk_set_rate(host->clk, hclk);
26026+
26027+	hclk = clk_get_rate(host->clk);
26028+	host->mmc->actual_clock = hclk;
26029+
26030+	/*
26031+	 * set card clk divider value,
26032+	 * clk_divider = Fmmcclk/(Fmmc_cclk * 2)
26033+	 */
26034+	reg_value = hclk / (cclk * 2);
26035+	if ((hclk % (cclk * 2)) && (hclk > cclk))
26036+		reg_value++;
26037+	if (reg_value > 0xFF)
26038+		reg_value = 0xFF;
26039+
26040+	host->hclk = hclk;
26041+	host->cclk = reg_value ? (hclk / (reg_value * 2)) : hclk;
26042+	himci_writel((reg_value << (host->port * 8)),
26043+		     host->base + MCI_CLKDIV);
26044+
26045+	clk_cmd.cmd_arg = himci_readl(host->base + MCI_CMD);
26046+	clk_cmd.bits.start_cmd = 1;
26047+	clk_cmd.bits.card_number = host->port;
26048+	clk_cmd.bits.update_clk_reg_only = 1;
26049+	clk_cmd.bits.cmd_index = 0;
26050+	clk_cmd.bits.data_transfer_expected = 0;
26051+	clk_cmd.bits.response_expect = 0;
26052+	himci_writel(clk_cmd.cmd_arg, host->base + MCI_CMD);
26053+	if (himci_wait_cmd(host) != 0)
26054+		himci_trace(5, "set card clk divider is failed!");
26055+}
26056+
26057+static void himci_sys_ctrl_init(struct himci_host *host)
26058+{
26059+	reset_control_assert(host->crg_rst);
26060+	udelay(100);
26061+	reset_control_deassert(host->crg_rst);
26062+}
26063+
26064+static void himci_init_host(struct himci_host *host)
26065+{
26066+	unsigned int tmp_reg = 0;
26067+	unsigned long flags;
26068+
26069+	himci_trace(2, "begin");
26070+	himci_assert(host);
26071+
26072+	himci_sys_reset(host);
26073+
26074+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \
26075+    defined(CONFIG_ARCH_HI3556V200)  || defined(CONFIG_ARCH_HI3559V200)  || \
26076+    defined(CONFIG_ARCH_HI3562V100)  || defined(CONFIG_ARCH_HI3566V100)
26077+	/* controller config gpio */
26078+	tmp_reg = himci_readl(host->base + MCI_GPIO);
26079+	tmp_reg |= DTO_FIX_BYPASS;
26080+	himci_writel(tmp_reg, host->base + MCI_GPIO);
26081+#endif
26082+
26083+#ifdef CONFIG_ARCH_HI3518EV20X
26084+	/* sd use clk0 emmc use clk1 */
26085+	himci_writel(0x4, host->base + MCI_CLKSRC);
26086+#endif
26087+
26088+	/* set drv/smpl phase shift */
26089+	tmp_reg = 0;
26090+	tmp_reg |= SMPL_PHASE_DFLT | DRV_PHASE_DFLT;
26091+	himci_writel(tmp_reg, host->base + MCI_UHS_REG_EXT);
26092+
26093+	/* set card read threshold */
26094+	himci_writel(RW_THRESHOLD_SIZE, host->base + MCI_CARDTHRCTL);
26095+
26096+	/* clear MMC host intr */
26097+	himci_writel(ALL_INT_CLR, host->base + MCI_RINTSTS);
26098+
26099+	spin_lock_irqsave(&host->lock, flags);
26100+	host->pending_events = 0;
26101+	spin_unlock_irqrestore(&host->lock, flags);
26102+
26103+	/* MASK MMC all host intr */
26104+	tmp_reg = himci_readl(host->base + MCI_INTMASK);
26105+	tmp_reg &= ~ALL_INT_MASK;
26106+	tmp_reg |= DATA_INT_MASK;
26107+	himci_writel(tmp_reg, host->base + MCI_INTMASK);
26108+
26109+	/* enable inner DMA mode and close intr of MMC host controler */
26110+	tmp_reg = himci_readl(host->base + MCI_CTRL);
26111+	tmp_reg &= ~INTR_EN;
26112+	tmp_reg |= USE_INTERNAL_DMA | INTR_EN;
26113+	himci_writel(tmp_reg, host->base + MCI_CTRL);
26114+
26115+	/* set timeout param */
26116+	himci_writel(DATA_TIMEOUT | RESPONSE_TIMEOUT, host->base + MCI_TIMEOUT);
26117+
26118+	/* set FIFO param */
26119+	tmp_reg = 0;
26120+	tmp_reg |= BURST_SIZE | RX_WMARK | TX_WMARK;
26121+	himci_writel(tmp_reg, host->base + MCI_FIFOTH);
26122+
26123+	host->error_count = 0;
26124+	host->data_error_count = 0;
26125+}
26126+
26127+static void himci_detect_card(struct timer_list *timer)
26128+{
26129+	struct himci_host *host = container_of(timer, struct himci_host, timer);
26130+	unsigned int i, curr_status, status[5];
26131+	unsigned int detect_retry_count = 0;
26132+
26133+	himci_assert(host);
26134+
26135+	while (1) {
26136+		for (i = 0; i < 5; i++) {
26137+			status[i] = himci_sys_card_detect(host);
26138+			udelay(10);
26139+		}
26140+		if ((status[0] == status[1])
26141+				&& (status[0] == status[2])
26142+				&& (status[0] == status[3])
26143+				&& (status[0] == status[4]))
26144+			break;
26145+
26146+		detect_retry_count++;
26147+		if (detect_retry_count >= retry_count) {
26148+			himci_error("this is a dithering, card detect error!");
26149+			goto err;
26150+		}
26151+	}
26152+	curr_status = status[0];
26153+	if (curr_status != host->card_status) {
26154+		himci_trace(2, "begin card_status = %d\n", host->card_status);
26155+		host->card_status = curr_status;
26156+		if (curr_status != CARD_UNPLUGED) {
26157+			himci_sys_ctrl_init(host);
26158+			himci_init_host(host);
26159+			pr_info("card connected!\n");
26160+		} else {
26161+			pr_info("card disconnected!\n");
26162+		}
26163+
26164+		mmc_detect_change(host->mmc, 0);
26165+	}
26166+err:
26167+	mod_timer(timer, jiffies + detect_time);
26168+}
26169+
26170+static void himci_idma_start(struct himci_host *host)
26171+{
26172+	unsigned int tmp;
26173+
26174+	himci_trace(2, "begin");
26175+	himci_writel(host->dma_paddr, host->base + MCI_DBADDR);
26176+	tmp = himci_readl(host->base + MCI_BMOD);
26177+	tmp |= BMOD_DMA_EN;
26178+	himci_writel(tmp, host->base + MCI_BMOD);
26179+}
26180+
26181+static void himci_idma_stop(struct himci_host *host)
26182+{
26183+	unsigned int tmp_reg;
26184+
26185+	himci_trace(2, "begin");
26186+	tmp_reg = himci_readl(host->base + MCI_BMOD);
26187+	tmp_reg &= ~BMOD_DMA_EN;
26188+	himci_writel(tmp_reg, host->base + MCI_BMOD);
26189+}
26190+
26191+static void himci_idma_reset(struct himci_host *host)
26192+{
26193+	u32 regval;
26194+
26195+	regval = himci_readl(host->base + MCI_BMOD);
26196+	regval |= BMOD_SWR;
26197+	himci_writel(regval, host->base + MCI_BMOD);
26198+
26199+	regval = himci_readl(host->base + MCI_CTRL);
26200+	regval |= CTRL_RESET | FIFO_RESET | DMA_RESET;
26201+	himci_writel(regval, host->base + MCI_CTRL);
26202+
26203+	udelay(1);
26204+	himci_writel(ALL_INT_CLR, host->base + MCI_RINTSTS);
26205+}
26206+
26207+static int himci_setup_data(struct himci_host *host, struct mmc_data *data)
26208+{
26209+	unsigned int sg_phyaddr, sg_length;
26210+	unsigned int i;
26211+	unsigned int ret = 0;
26212+	unsigned int data_size;
26213+	unsigned int max_des, des_cnt;
26214+	struct himci_des *des = NULL;
26215+
26216+	himci_trace(2, "begin");
26217+	himci_assert(host);
26218+	himci_assert(data);
26219+
26220+	host->data = data;
26221+
26222+	if (data->flags & MMC_DATA_READ)
26223+		host->dma_dir = DMA_FROM_DEVICE;
26224+	else
26225+		host->dma_dir = DMA_TO_DEVICE;
26226+
26227+	host->dma_sg = data->sg;
26228+	host->dma_sg_num = dma_map_sg(mmc_dev(host->mmc),
26229+				      data->sg, data->sg_len, host->dma_dir);
26230+	himci_assert(host->dma_sg_num);
26231+	himci_trace(2, "host->dma_sg_num is %d\n", host->dma_sg_num);
26232+	data_size = data->blksz * data->blocks;
26233+
26234+	if (data_size > (DMA_BUFFER * MAX_DMA_DES)) {
26235+		himci_error("mci request data_size is too big!\n");
26236+		ret = -1;
26237+		goto out;
26238+	}
26239+
26240+	himci_trace(2, "host->dma_paddr is 0x%08lx,host->dma_vaddr is 0x%08lx\n",
26241+		    (uintptr_t)host->dma_paddr,
26242+		    (uintptr_t)host->dma_vaddr);
26243+
26244+	max_des = (CMD_DES_PAGE_SIZE / sizeof(struct himci_des));
26245+	des = (struct himci_des *)host->dma_vaddr;
26246+	des_cnt = 0;
26247+
26248+	for (i = 0; i < host->dma_sg_num; i++) {
26249+		sg_length = sg_dma_len(&data->sg[i]);
26250+		sg_phyaddr = sg_dma_address(&data->sg[i]);
26251+		himci_trace(2, "sg[%d] sg_length is 0x%08X, " \
26252+			    "sg_phyaddr is 0x%08X\n", \
26253+			    i, (unsigned int)sg_length, \
26254+			    (unsigned int)sg_phyaddr);
26255+		while (sg_length) {
26256+			des[des_cnt].idmac_des_ctrl = DMA_DES_OWN
26257+						      | DMA_DES_NEXT_DES;
26258+			des[des_cnt].idmac_des_buf_addr = sg_phyaddr;
26259+			/* idmac_des_next_addr is paddr for dma */
26260+			des[des_cnt].idmac_des_next_addr = host->dma_paddr
26261+							   + (des_cnt + 1) * sizeof(struct himci_des);
26262+
26263+			/* buffer size <= 4k */
26264+			if (sg_length >= 0x1000) {
26265+				des[des_cnt].idmac_des_buf_size = 0x1000;
26266+				sg_length -= 0x1000;
26267+				sg_phyaddr += 0x1000;
26268+			} else {
26269+				/* data alignment */
26270+				des[des_cnt].idmac_des_buf_size = sg_length;
26271+				sg_length = 0;
26272+			}
26273+
26274+			himci_trace(2, "des[%d] vaddr  is 0x%08X", i,
26275+				    (unsigned int)(uintptr_t)&des[i]);
26276+			himci_trace(2, "des[%d].idmac_des_ctrl is 0x%08X",
26277+				    i, (unsigned int)des[i].idmac_des_ctrl);
26278+			himci_trace(2, "des[%d].idmac_des_buf_size is 0x%08X",
26279+				    i, (unsigned int)des[i].idmac_des_buf_size);
26280+			himci_trace(2, "des[%d].idmac_des_buf_addr 0x%08X",
26281+				    i, (unsigned int)des[i].idmac_des_buf_addr);
26282+			himci_trace(2, "des[%d].idmac_des_next_addr is 0x%08X",
26283+				    i, (unsigned int)des[i].idmac_des_next_addr);
26284+			des_cnt++;
26285+		}
26286+
26287+		himci_assert(des_cnt < max_des);
26288+	}
26289+	des[0].idmac_des_ctrl |= DMA_DES_FIRST_DES;
26290+	des[des_cnt - 1].idmac_des_ctrl |= DMA_DES_LAST_DES;
26291+	des[des_cnt - 1].idmac_des_next_addr = 0;
26292+out:
26293+	return ret;
26294+}
26295+
26296+static int himci_exec_cmd(struct himci_host *host,
26297+			  struct mmc_command *cmd, struct mmc_data *data)
26298+{
26299+	volatile union cmd_arg_u  cmd_regs;
26300+
26301+	himci_trace(2, "begin");
26302+	himci_assert(host);
26303+	himci_assert(cmd);
26304+
26305+	host->cmd = cmd;
26306+
26307+	himci_writel(cmd->arg, host->base + MCI_CMDARG);
26308+	himci_trace(4, "arg_reg 0x%x, val 0x%x", MCI_CMDARG, cmd->arg);
26309+	cmd_regs.cmd_arg = himci_readl(host->base + MCI_CMD);
26310+	if (data) {
26311+		cmd_regs.bits.data_transfer_expected = 1;
26312+		if (data->flags & (MMC_DATA_WRITE | MMC_DATA_READ))
26313+			cmd_regs.bits.transfer_mode = 0;
26314+
26315+		if (data->flags & MMC_DATA_WRITE)
26316+			cmd_regs.bits.read_write = 1;
26317+		else if (data->flags & MMC_DATA_READ)
26318+			cmd_regs.bits.read_write = 0;
26319+	} else {
26320+		cmd_regs.bits.data_transfer_expected = 0;
26321+		cmd_regs.bits.transfer_mode = 0;
26322+		cmd_regs.bits.read_write = 0;
26323+	}
26324+
26325+	cmd_regs.bits.send_auto_stop = 0;
26326+#ifdef CONFIG_SEND_AUTO_STOP
26327+	if ((host->mrq->stop) && (!(host->is_tuning)))
26328+		cmd_regs.bits.send_auto_stop = 1;
26329+#endif
26330+
26331+	if (cmd == host->mrq->stop ||
26332+			cmd->opcode == MMC_STOP_TRANSMISSION) {
26333+		cmd_regs.bits.stop_abort_cmd = 1;
26334+		cmd_regs.bits.wait_prvdata_complete = 0;
26335+	} else if (cmd->opcode == MMC_SEND_STATUS) {
26336+		cmd_regs.bits.stop_abort_cmd = 0;
26337+		cmd_regs.bits.wait_prvdata_complete = 0;
26338+	} else {
26339+		cmd_regs.bits.stop_abort_cmd = 0;
26340+		cmd_regs.bits.wait_prvdata_complete = 1;
26341+	}
26342+
26343+	switch (mmc_resp_type(cmd)) {
26344+	case MMC_RSP_NONE:
26345+		cmd_regs.bits.response_expect = 0;
26346+		cmd_regs.bits.response_length = 0;
26347+		cmd_regs.bits.check_response_crc = 0;
26348+		break;
26349+	case MMC_RSP_R1:
26350+	case MMC_RSP_R1B:
26351+		cmd_regs.bits.response_expect = 1;
26352+		cmd_regs.bits.response_length = 0;
26353+		cmd_regs.bits.check_response_crc = 1;
26354+		break;
26355+	case MMC_RSP_R2:
26356+		cmd_regs.bits.response_expect = 1;
26357+		cmd_regs.bits.response_length = 1;
26358+		cmd_regs.bits.check_response_crc = 1;
26359+		break;
26360+	case MMC_RSP_R3:
26361+	case MMC_RSP_R1 & (~MMC_RSP_CRC):
26362+		cmd_regs.bits.response_expect = 1;
26363+		cmd_regs.bits.response_length = 0;
26364+		cmd_regs.bits.check_response_crc = 0;
26365+		break;
26366+	default:
26367+		host->cmd->error = -EINVAL;
26368+		himci_error("himci: unhandled response type %02x\n",
26369+			    mmc_resp_type(cmd));
26370+		return -EINVAL;
26371+	}
26372+
26373+	himci_trace(3, "cmd->opcode = %d cmd->arg = 0x%X\n",
26374+		    cmd->opcode, cmd->arg);
26375+	if (cmd->opcode == MMC_SELECT_CARD) {
26376+		host->card_rca = (cmd->arg >> 16);
26377+	}
26378+	if (cmd->opcode == MMC_GO_IDLE_STATE)
26379+		cmd_regs.bits.send_initialization = 1;
26380+	else
26381+		cmd_regs.bits.send_initialization = 0;
26382+	/* CMD 11 check switch voltage */
26383+	if (cmd->opcode == SD_SWITCH_VOLTAGE)
26384+		cmd_regs.bits.volt_switch = 1;
26385+	else
26386+		cmd_regs.bits.volt_switch = 0;
26387+
26388+	cmd_regs.bits.card_number = host->port;
26389+	cmd_regs.bits.cmd_index = cmd->opcode;
26390+	cmd_regs.bits.start_cmd = 1;
26391+	cmd_regs.bits.update_clk_reg_only = 0;
26392+
26393+	himci_writel(DATA_INT_MASK, host->base + MCI_RINTSTS);
26394+	himci_writel(cmd_regs.cmd_arg, host->base + MCI_CMD);
26395+	himci_trace(4, "cmd_reg 0x%x, val 0x%x\n", MCI_CMD, cmd_regs.cmd_arg);
26396+
26397+	if (himci_wait_cmd(host) != 0) {
26398+		himci_trace(3, "send card cmd is failed!");
26399+		return -EINVAL;
26400+	}
26401+	return 0;
26402+}
26403+
26404+static void himci_finish_request(struct himci_host *host,
26405+				 struct mmc_request *mrq)
26406+{
26407+	himci_trace(2, "begin");
26408+	himci_assert(host);
26409+	himci_assert(mrq);
26410+
26411+	host->mrq = NULL;
26412+	host->cmd = NULL;
26413+	host->data = NULL;
26414+	mmc_request_done(host->mmc, mrq);
26415+}
26416+
26417+#define CMD_ERRORS                          \
26418+    (R1_OUT_OF_RANGE |  /* Command argument out of range */ \
26419+     R1_ADDRESS_ERROR | /* Misaligned address */        \
26420+     R1_BLOCK_LEN_ERROR |   /* Transferred block length incorrect */ \
26421+     R1_WP_VIOLATION |  /* Tried to write to protected block */ \
26422+     R1_CC_ERROR |      /* Card controller error */     \
26423+     R1_ERROR)      /* General/unknown error */
26424+
26425+static void himci_cmd_done(struct himci_host *host, unsigned int stat)
26426+{
26427+	unsigned int i;
26428+	struct mmc_command *cmd = host->cmd;
26429+
26430+	himci_trace(2, "begin");
26431+	himci_assert(host);
26432+	himci_assert(cmd);
26433+
26434+	for (i = 0; i < 4; i++) {
26435+		if (mmc_resp_type(cmd) == MMC_RSP_R2) {
26436+			cmd->resp[i] = himci_readl(host->base +
26437+						   MCI_RESP3 - i * 0x4);
26438+			/* R2 must delay some time here ,when use UHI card,
26439+			   need check why */
26440+			udelay(1000);
26441+		} else
26442+			cmd->resp[i] = himci_readl(host->base +
26443+						   MCI_RESP0 + i * 0x4);
26444+	}
26445+
26446+	if (stat & RTO_INT_STATUS) {
26447+		cmd->error = -ETIMEDOUT;
26448+		himci_trace(3, "irq cmd status stat = 0x%x is timeout error!",
26449+			    stat);
26450+	} else if (stat & (RCRC_INT_STATUS | RE_INT_STATUS)) {
26451+		cmd->error = -EILSEQ;
26452+		himci_trace(3, "irq cmd status stat = 0x%x is response error!",
26453+			    stat);
26454+	}
26455+
26456+	if (((cmd->flags & MMC_RSP_R1) == MMC_RSP_R1) &&
26457+			((cmd->flags & MMC_CMD_MASK) != MMC_CMD_BCR)) {
26458+		if ((cmd->resp[0] & CMD_ERRORS) && !host->is_tuning) {
26459+			host->error_count++;
26460+			host->mrq->cmd->error = -EACCES;
26461+			himci_trace(5, "The status of the card is abnormal, cmd->resp[0]: %x",
26462+				    cmd->resp[0]);
26463+		}
26464+
26465+		/* bad card situation: the TF card returns the contradictory card statut.
26466+		 * that is, the card is in the ready state and in the programming state.
26467+		 */
26468+		if ((cmd->resp[0] & R1_READY_FOR_DATA) && (R1_CURRENT_STATE(cmd->resp[0]) ==
26469+					R1_STATE_PRG)) {
26470+			host->error_count++;
26471+			host->mrq->cmd->error = -EACCES;
26472+			himci_trace(5, "The status of the card is abnormal, cmd->resp[0]: %x",
26473+					cmd->resp[0]);
26474+		}
26475+	}
26476+
26477+	host->cmd = NULL;
26478+}
26479+
26480+static void himci_data_done(struct himci_host *host, unsigned int stat)
26481+{
26482+	struct mmc_data *data = host->data;
26483+
26484+	himci_trace(2, "begin");
26485+	himci_assert(host);
26486+	himci_assert(data);
26487+
26488+	dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, host->dma_dir);
26489+
26490+	if (stat & (HTO_INT_STATUS | DRTO_INT_STATUS)) {
26491+		data->error = -ETIMEDOUT;
26492+		himci_trace(3, "irq data status stat = 0x%x is timeout error!",
26493+			    stat);
26494+	} else if (stat & (EBE_INT_STATUS | SBE_INT_STATUS |
26495+			   FRUN_INT_STATUS | DCRC_INT_STATUS)) {
26496+		data->error = -EILSEQ;
26497+		himci_trace(3, "irq data status stat = 0x%x is data error!",
26498+			    stat);
26499+	}
26500+
26501+	if (!data->error)
26502+		data->bytes_xfered = data->blocks * data->blksz;
26503+	else
26504+		data->bytes_xfered = 0;
26505+
26506+	host->data = NULL;
26507+}
26508+
26509+static int himci_wait_cmd_complete(struct himci_host *host)
26510+{
26511+	unsigned int cmd_retry_count = 0;
26512+	unsigned long cmd_jiffies_timeout;
26513+	unsigned int cmd_irq_reg = 0;
26514+	struct mmc_command *cmd = host->cmd;
26515+	unsigned long flags;
26516+
26517+	himci_trace(2, "begin");
26518+	himci_assert(host);
26519+	himci_assert(cmd);
26520+
26521+	cmd_jiffies_timeout = jiffies + request_timeout;
26522+	while (1) {
26523+		do {
26524+			spin_lock_irqsave(&host->lock, flags);
26525+			cmd_irq_reg = readl(host->base + MCI_RINTSTS);
26526+
26527+			if (cmd_irq_reg & CD_INT_STATUS) {
26528+				himci_writel((CD_INT_STATUS | RTO_INT_STATUS
26529+					      | RCRC_INT_STATUS | RE_INT_STATUS),
26530+					     host->base + MCI_RINTSTS);
26531+				spin_unlock_irqrestore(&host->lock, flags);
26532+				himci_cmd_done(host, cmd_irq_reg);
26533+				return 0;
26534+			} else if (cmd_irq_reg & VOLT_SWITCH_INT_STATUS) {
26535+				himci_writel(VOLT_SWITCH_INT_STATUS,
26536+					     host->base + MCI_RINTSTS);
26537+				spin_unlock_irqrestore(&host->lock, flags);
26538+				himci_cmd_done(host, cmd_irq_reg);
26539+				return 0;
26540+			}
26541+			spin_unlock_irqrestore(&host->lock, flags);
26542+			cmd_retry_count++;
26543+		} while (cmd_retry_count < retry_count);
26544+
26545+		cmd_retry_count = 0;
26546+
26547+		if (host->card_status == CARD_UNPLUGED) {
26548+			cmd->error = -ETIMEDOUT;
26549+			return -1;
26550+		}
26551+
26552+		if (!time_before(jiffies, cmd_jiffies_timeout)) {
26553+			unsigned int i = 0;
26554+			for (i = 0; i < 4; i++) {
26555+				cmd->resp[i] = himci_readl(host->base +
26556+							   MCI_RESP0 +
26557+							   i * 0x4);
26558+				pr_err("voltage switch read MCI_RESP");
26559+				pr_err("%d : 0x%x\n", i, cmd->resp[i]);
26560+			}
26561+			cmd->error = -ETIMEDOUT;
26562+			himci_trace(3, "wait cmd request complete is timeout!");
26563+			return -1;
26564+		}
26565+
26566+		schedule();
26567+	}
26568+}
26569+/*
26570+ * designware support send stop command automatically when
26571+ * read or wirte multi blocks
26572+ */
26573+#ifdef CONFIG_SEND_AUTO_STOP
26574+static int himci_wait_auto_stop_complete(struct himci_host *host)
26575+{
26576+	unsigned int cmd_retry_count = 0;
26577+	unsigned long cmd_jiffies_timeout;
26578+	unsigned int cmd_irq_reg = 0;
26579+	unsigned long flags;
26580+
26581+	himci_trace(2, "begin");
26582+	himci_assert(host);
26583+
26584+	cmd_jiffies_timeout = jiffies + request_timeout;
26585+	while (1) {
26586+		do {
26587+			spin_lock_irqsave(&host->lock, flags);
26588+			cmd_irq_reg = readl(host->base + MCI_RINTSTS);
26589+			if (cmd_irq_reg & ACD_INT_STATUS) {
26590+				himci_writel((ACD_INT_STATUS | RTO_INT_STATUS |
26591+					      RCRC_INT_STATUS |
26592+					      RE_INT_STATUS),
26593+					     host->base + MCI_RINTSTS);
26594+				spin_unlock_irqrestore(&host->lock, flags);
26595+				return 0;
26596+			}
26597+			spin_unlock_irqrestore(&host->lock, flags);
26598+			cmd_retry_count++;
26599+		} while (cmd_retry_count < retry_count);
26600+
26601+		cmd_retry_count = 0;
26602+		if (host->card_status == CARD_UNPLUGED)
26603+			return -1;
26604+		if (!time_before(jiffies, cmd_jiffies_timeout)) {
26605+			himci_trace(3, "wait auto stop complete is timeout!");
26606+			return -1;
26607+		}
26608+
26609+		schedule();
26610+	}
26611+}
26612+#endif
26613+
26614+static int himci_wait_data_complete(struct himci_host *host)
26615+{
26616+	unsigned int tmp_reg;
26617+	struct mmc_data *data = host->data;
26618+	long time = request_timeout;
26619+	unsigned long flags;
26620+
26621+	himci_trace(2, "begin");
26622+	himci_assert(host);
26623+	himci_assert(data);
26624+
26625+	time = wait_event_timeout(host->intr_wait,
26626+				  test_bit(HIMCI_PEND_DTO_B,
26627+					   &host->pending_events), time);
26628+
26629+	/* Mask MMC host data intr */
26630+	spin_lock_irqsave(&host->lock, flags);
26631+	tmp_reg = himci_readl(host->base + MCI_INTMASK);
26632+	tmp_reg &= ~DATA_INT_MASK;
26633+	himci_writel(tmp_reg, host->base + MCI_INTMASK);
26634+	host->pending_events &= ~HIMCI_PEND_DTO_M;
26635+	spin_unlock_irqrestore(&host->lock, flags);
26636+
26637+	if (((time <= 0)
26638+			&& (!test_bit(HIMCI_PEND_DTO_B, &host->pending_events)))
26639+			|| (host->card_status == CARD_UNPLUGED)) {
26640+		data->error = -ETIMEDOUT;
26641+		himci_trace(5, "wait data request complete is timeout! 0x%08X",
26642+			    host->irq_status);
26643+		himci_idma_stop(host);
26644+		himci_data_done(host, host->irq_status);
26645+		return -1;
26646+	}
26647+
26648+	himci_idma_stop(host);
26649+	himci_data_done(host, host->irq_status);
26650+	return 0;
26651+}
26652+
26653+static int himci_wait_card_complete(struct himci_host *host,
26654+				    struct mmc_data *data)
26655+{
26656+	unsigned int card_retry_count = 0;
26657+	unsigned long card_jiffies_timeout;
26658+	unsigned int card_status_reg = 0;
26659+
26660+	himci_trace(2, "begin");
26661+	himci_assert(host);
26662+
26663+	card_jiffies_timeout = jiffies + request_timeout;
26664+	while (1) {
26665+		do {
26666+			card_status_reg = readl(host->base + MCI_STATUS);
26667+			if (!(card_status_reg & DATA_BUSY)) {
26668+				himci_trace(2, "end");
26669+				return 0;
26670+			}
26671+			card_retry_count++;
26672+		} while (card_retry_count < retry_count);
26673+
26674+		card_retry_count = 0;
26675+
26676+		if (host->card_status == CARD_UNPLUGED) {
26677+			host->mrq->cmd->error = -ETIMEDOUT;
26678+			himci_trace(3, "card is unpluged!");
26679+			return -1;
26680+		}
26681+
26682+		if (!time_before(jiffies, card_jiffies_timeout)) {
26683+			host->mrq->cmd->error = -ETIMEDOUT;
26684+			himci_trace(3, "wait card ready complete is timeout!");
26685+			return -1;
26686+		}
26687+
26688+		schedule();
26689+	}
26690+}
26691+
26692+static void himci_request(struct mmc_host *mmc, struct mmc_request *mrq)
26693+{
26694+	struct himci_host *host = mmc_priv(mmc);
26695+	int byte_cnt = 0;
26696+	int fifo_count = 0;
26697+	int ret = 0;
26698+	unsigned int tmp_reg;
26699+	unsigned long flags;
26700+
26701+	himci_trace(2, "begin");
26702+	himci_assert(mmc);
26703+	himci_assert(mrq);
26704+	himci_assert(host);
26705+
26706+	host->mrq = mrq;
26707+	host->irq_status = 0;
26708+
26709+	if (host->card_status == CARD_UNPLUGED) {
26710+		mrq->cmd->error = -ENODEV;
26711+		goto request_end;
26712+	}
26713+
26714+	ret = himci_wait_card_complete(host, mrq->data);
26715+	if (ret) {
26716+		mrq->cmd->error = ret;
26717+		goto request_end;
26718+	}
26719+
26720+	/* prepare data */
26721+	if (mrq->data) {
26722+		ret = himci_setup_data(host, mrq->data);
26723+		if (ret) {
26724+			mrq->data->error = ret;
26725+			himci_trace(3, "data setup is error!");
26726+			goto request_end;
26727+		}
26728+
26729+		byte_cnt = mrq->data->blksz * mrq->data->blocks;
26730+		himci_writel(byte_cnt, host->base + MCI_BYTCNT);
26731+		himci_writel(mrq->data->blksz, host->base + MCI_BLKSIZ);
26732+
26733+		/* reset fifo */
26734+		tmp_reg = himci_readl(host->base + MCI_CTRL);
26735+		tmp_reg |= FIFO_RESET;
26736+		himci_writel(tmp_reg, host->base + MCI_CTRL);
26737+
26738+		do {
26739+			tmp_reg = himci_readl(host->base + MCI_CTRL);
26740+			fifo_count++;
26741+			if (fifo_count >= retry_count) {
26742+				pr_info("fifo reset is timeout!");
26743+				return;
26744+			}
26745+		} while (tmp_reg & FIFO_RESET);
26746+
26747+		/* start DMA */
26748+		himci_idma_start(host);
26749+	} else {
26750+		himci_writel(0, host->base + MCI_BYTCNT);
26751+		himci_writel(0, host->base + MCI_BLKSIZ);
26752+	}
26753+	if (mrq->sbc) {
26754+		ret = himci_exec_cmd(host, mrq->sbc, NULL);
26755+		if (ret) {
26756+			mrq->sbc->error = ret;
26757+			goto request_end;
26758+		}
26759+
26760+		/* wait command send complete */
26761+		ret = himci_wait_cmd_complete(host);
26762+		if (ret) {
26763+			mrq->sbc->error = ret;
26764+			goto request_end;
26765+		}
26766+	}
26767+	/* send command */
26768+	ret = himci_exec_cmd(host, mrq->cmd, mrq->data);
26769+	if (ret) {
26770+		mrq->cmd->error = ret;
26771+		himci_idma_stop(host);
26772+		himci_trace(3, "can't send card cmd! ret = %d", ret);
26773+		goto request_end;
26774+	}
26775+
26776+	/* wait command send complete */
26777+	himci_wait_cmd_complete(host);
26778+
26779+	/* start data transfer */
26780+	if (mrq->data) {
26781+		if (!(mrq->cmd->error)) {
26782+			/* Open MMC host data intr */
26783+			spin_lock_irqsave(&host->lock, flags);
26784+			tmp_reg = himci_readl(host->base + MCI_INTMASK);
26785+			tmp_reg |= DATA_INT_MASK;
26786+			himci_writel(tmp_reg, host->base + MCI_INTMASK);
26787+			spin_unlock_irqrestore(&host->lock, flags);
26788+
26789+			/* wait data transfer complete */
26790+			himci_wait_data_complete(host);
26791+		} else if (host->is_tuning) {
26792+			unsigned int stat;
26793+			unsigned int wait_retry_count = 0;
26794+
26795+			do {
26796+				stat = himci_readl(host->base + MCI_RINTSTS);
26797+				if (stat & (HTO_INT_STATUS | DRTO_INT_STATUS |
26798+						EBE_INT_STATUS | SBE_INT_STATUS |
26799+						FRUN_INT_STATUS | DCRC_INT_STATUS)) {
26800+					himci_writel(stat, host->base + MCI_RINTSTS);
26801+					himci_trace(3, "data status = 0x%x is error!", stat);
26802+					himci_trace(3, "udelay count = %d is error!", wait_retry_count);
26803+					break;
26804+				}
26805+				udelay(100);
26806+				wait_retry_count++;
26807+			} while (wait_retry_count < 1000);
26808+
26809+			/* CMD error in data command */
26810+			himci_idma_stop(host);
26811+		} else {
26812+			/* CMD error in data command */
26813+			himci_idma_stop(host);
26814+		}
26815+
26816+		if (mrq->stop && (!mrq->sbc
26817+				  || (mrq->sbc && (mrq->cmd->error || mrq->data->error)))) {
26818+#ifdef CONFIG_SEND_AUTO_STOP
26819+			int trans_cnt;
26820+
26821+			trans_cnt = himci_readl(host->base + MCI_TCBCNT);
26822+			/* send auto stop */
26823+			if ((trans_cnt == byte_cnt) && (!(host->is_tuning))) {
26824+				himci_trace(3, "byte_cnt = %d, trans_cnt = %d",
26825+					    byte_cnt, trans_cnt);
26826+				ret = himci_wait_auto_stop_complete(host);
26827+				if (ret) {
26828+					mrq->stop->error = -ETIMEDOUT;
26829+					goto request_end;
26830+				}
26831+			} else {
26832+#endif
26833+				/* send soft stop command */
26834+				himci_trace(3, "this time, send soft stop");
26835+				ret = himci_exec_cmd(host, host->mrq->stop,
26836+						     host->data);
26837+				if (ret) {
26838+					mrq->stop->error = ret;
26839+					goto request_end;
26840+				}
26841+				ret = himci_wait_cmd_complete(host);
26842+				if (ret)
26843+					goto request_end;
26844+#ifdef CONFIG_SEND_AUTO_STOP
26845+			}
26846+#endif
26847+		}
26848+	}
26849+
26850+request_end:
26851+	/* clear MMC host intr */
26852+	spin_lock_irqsave(&host->lock, flags);
26853+	himci_writel(ALL_SD_INT_CLR, host->base + MCI_RINTSTS);
26854+	spin_unlock_irqrestore(&host->lock, flags);
26855+
26856+	if (mrq->data && mrq->data->error && !host->is_tuning)
26857+		host->data_error_count++;
26858+	himci_finish_request(host, mrq);
26859+}
26860+
26861+static int himci_do_voltage_switch(struct himci_host *host,
26862+				   struct mmc_ios *ios)
26863+{
26864+	u32 ctrl;
26865+
26866+	/*
26867+	 * We first check whether the request is to set signalling voltage
26868+	 * to 3.3V. If so, we change the voltage to 3.3V and return quickly.
26869+	 */
26870+	ctrl = himci_readl(host->base + MCI_UHS_REG);
26871+	if (ios->signal_voltage == MMC_SIGNAL_VOLTAGE_330) {
26872+		/* Set 1.8V Signal Enable in the MCI_UHS_REG to 1 */
26873+		himci_trace(3, "switch voltage 330");
26874+		ctrl &= ~(HI_SDXC_CTRL_VDD_180 << host->port);
26875+		himci_writel(ctrl, host->base + MCI_UHS_REG);
26876+
26877+		/* Wait for 5ms */
26878+		usleep_range(5000, 5500);
26879+
26880+		/* 3.3V regulator output should be stable within 5 ms */
26881+		ctrl = himci_readl(host->base + MCI_UHS_REG);
26882+		if (!(ctrl & (HI_SDXC_CTRL_VDD_180 << host->port))) {
26883+			/* config Pin drive capability */
26884+			himci_set_drv_cap(host, 0);
26885+			return 0;
26886+		} else {
26887+			himci_error(": Switching to 3.3V ");
26888+			himci_error("signalling voltage failed\n");
26889+			return -EIO;
26890+		}
26891+	} else if (!(ctrl & (HI_SDXC_CTRL_VDD_180 << host->port)) &&
26892+			(ios->signal_voltage == MMC_SIGNAL_VOLTAGE_180)) {
26893+		/* Stop SDCLK */
26894+		himci_trace(3, "switch voltage 180");
26895+		himci_control_cclk(host, DISABLE);
26896+
26897+		/*
26898+		 * Enable 1.8V Signal Enable in the MCI_UHS_REG
26899+		 */
26900+		ctrl |= (HI_SDXC_CTRL_VDD_180 << host->port);
26901+		himci_writel(ctrl, host->base + MCI_UHS_REG);
26902+
26903+		/* Wait for 5ms */
26904+		usleep_range(8000, 8500);
26905+
26906+		ctrl = himci_readl(host->base + MCI_UHS_REG);
26907+		if (ctrl & (HI_SDXC_CTRL_VDD_180 << host->port)) {
26908+			/* Provide SDCLK again and wait for 1ms */
26909+			himci_control_cclk(host, ENABLE);
26910+			usleep_range(1000, 1500);
26911+
26912+			if (host->mmc->caps2 & MMC_CAP2_HS200) {
26913+				/* eMMC needn't to check the int status */
26914+				return 0;
26915+			}
26916+			/*
26917+			 * If CMD11 return CMD down, then the card
26918+			 * was successfully switched to 1.8V signaling.
26919+			 */
26920+			ctrl = himci_readl(host->base + MCI_RINTSTS);
26921+			if ((ctrl & VOLT_SWITCH_INT_STATUS)
26922+					&& (ctrl & CD_INT_STATUS)) {
26923+				himci_writel(VOLT_SWITCH_INT_STATUS | CD_INT_STATUS,
26924+					     host->base + MCI_RINTSTS);
26925+				/* config Pin drive capability */
26926+				himci_set_drv_cap(host, 1);
26927+				return 0;
26928+			}
26929+		}
26930+
26931+		/*
26932+		 * If we are here, that means the switch to 1.8V signaling
26933+		 * failed. We power cycle the card, and retry initialization
26934+		 * sequence by setting S18R to 0.
26935+		 */
26936+
26937+		ctrl &= ~(HI_SDXC_CTRL_VDD_180 << host->port);
26938+		himci_writel(ctrl, host->base + MCI_UHS_REG);
26939+
26940+		/* Wait for 5ms */
26941+		usleep_range(5000, 5500);
26942+
26943+		himci_ctrl_power(host, POWER_OFF, FORCE_DISABLE);
26944+		/* Wait for 1ms as per the spec */
26945+		usleep_range(1000, 1500);
26946+		himci_ctrl_power(host, POWER_ON, FORCE_DISABLE);
26947+
26948+		himci_control_cclk(host, DISABLE);
26949+
26950+		/* Wait for 1ms as per the spec */
26951+		usleep_range(1000, 1500);
26952+		himci_control_cclk(host, ENABLE);
26953+
26954+		himci_error(": Switching to 1.8V signalling ");
26955+		himci_error("voltage failed, retrying with S18R set to 0\n");
26956+		return -EAGAIN;
26957+	} else
26958+		/* No signal voltage switch required */
26959+		return 0;
26960+}
26961+
26962+static int himci_start_signal_voltage_switch(struct mmc_host *mmc,
26963+		struct mmc_ios *ios)
26964+{
26965+	struct himci_host *host = mmc_priv(mmc);
26966+	int err;
26967+
26968+	err = himci_do_voltage_switch(host, ios);
26969+	return err;
26970+}
26971+
26972+static int himci_send_stop(struct mmc_host *host)
26973+{
26974+	struct mmc_command cmd = {0};
26975+	int err;
26976+
26977+	cmd.opcode = MMC_STOP_TRANSMISSION;
26978+	cmd.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;
26979+	err = mmc_wait_for_cmd(host, &cmd, 0);
26980+	return err;
26981+}
26982+
26983+static void himci_set_sap_phase(struct himci_host *host, u32 phase)
26984+{
26985+	unsigned int reg_value;
26986+	unsigned long flags;
26987+
26988+	spin_lock_irqsave(&host->lock, flags);
26989+
26990+	reg_value = himci_readl(host->base + MCI_UHS_REG_EXT);
26991+	reg_value &= ~CLK_SMPL_PHS_MASK;
26992+	reg_value |= (phase << CLK_SMPL_PHS_SHIFT);
26993+	himci_writel(reg_value, host->base + MCI_UHS_REG_EXT);
26994+
26995+	spin_unlock_irqrestore(&host->lock, flags);
26996+}
26997+
26998+#if defined(CONFIG_ARCH_HI3516DV300) || defined(CONFIG_ARCH_HI3516CV500) || \
26999+    defined(CONFIG_ARCH_HI3559V200)  || defined(CONFIG_ARCH_HI3556V200)  || \
27000+    defined(CONFIG_ARCH_HI3562V100)  || defined(CONFIG_ARCH_HI3566V100)
27001+static void himci_edge_tuning_enable(struct himci_host *host)
27002+{
27003+	unsigned int val;
27004+	void __iomem *tmp_reg = 0;
27005+
27006+	if (host->devid == 0)
27007+		tmp_reg  = crg_ctrl + 0x14c;
27008+	else if (host->devid == 1)
27009+		tmp_reg = crg_ctrl + 0x164;
27010+	else if (host->devid == 2)
27011+		tmp_reg = crg_ctrl + 0x158;
27012+	else {
27013+		himci_trace(5, "Devid error, host->devid: %x", host->devid);
27014+		return;
27015+	}
27016+
27017+	himci_writel(0x80001, tmp_reg);
27018+
27019+	val = himci_readl(host->base + MCI_TUNING_CTRL);
27020+	val |= HW_TUNING_EN;
27021+	himci_writel(val, host->base + MCI_TUNING_CTRL);
27022+}
27023+
27024+static void himci_edge_tuning_disable(struct himci_host *host)
27025+{
27026+	unsigned int val;
27027+	void __iomem *tmp_reg = 0;
27028+
27029+	if (host->devid == 0)
27030+		tmp_reg  = crg_ctrl + 0x14c;
27031+	else if (host->devid == 1)
27032+		tmp_reg = crg_ctrl + 0x164;
27033+	else if (host->devid == 2)
27034+		tmp_reg = crg_ctrl + 0x158;
27035+	else {
27036+		himci_trace(5, "Devid error, host->devid: %x", host->devid);
27037+		return;
27038+	}
27039+	val = himci_readl(tmp_reg);
27040+	val |= (1 << 16);
27041+	himci_writel(val, tmp_reg);
27042+
27043+	val = himci_readl(host->base + MCI_TUNING_CTRL);
27044+	val &= ~HW_TUNING_EN;
27045+	himci_writel(val, host->base + MCI_TUNING_CTRL);
27046+}
27047+
27048+static int himci_send_status(struct mmc_host *mmc)
27049+{
27050+	int err;
27051+	struct mmc_command cmd = {0};
27052+	struct himci_host *host = NULL;
27053+
27054+	BUG_ON(!mmc);
27055+
27056+	host = mmc_priv(mmc);
27057+	cmd.opcode = MMC_SEND_STATUS;
27058+	if (!mmc_host_is_spi(mmc))
27059+		cmd.arg = (host->card_rca << 16);
27060+	cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC;
27061+
27062+	err = mmc_wait_for_cmd(mmc, &cmd, 1);
27063+	if (err)
27064+		return err;
27065+
27066+	return 0;
27067+}
27068+
27069+static int himci_send_tuning(struct mmc_host *mmc, u32 opcode)
27070+{
27071+	int err = 0;
27072+	struct himci_host *host;
27073+	/* fix a problem that When the I/O voltage is increased to 1.89 V or 1.91V
27074+	 * at high and low temperatures, the system is suspended during the reboot test.
27075+	 */
27076+	unsigned cmd_count = 1000;
27077+
27078+	host = mmc_priv(mmc);
27079+	himci_control_cclk(host, DISABLE);
27080+tuning_retry:
27081+	himci_idma_reset(host);
27082+	himci_writel(ALL_INT_CLR, host->base + MCI_RINTSTS);
27083+	himci_control_cclk(host, ENABLE);
27084+	if (tuning_reset_flag == 1) {
27085+		tuning_reset_flag = 0;
27086+		cmd_count--;
27087+		if (cmd_count == 0) {
27088+			printk("BUG_ON:controller reset is failed!!!\n");
27089+			return -EINVAL;
27090+		}
27091+		goto tuning_retry;
27092+	}
27093+
27094+	err = mmc_send_tuning(mmc, opcode, NULL);
27095+	himci_send_stop(mmc);
27096+	himci_send_status(mmc);
27097+	return err;
27098+}
27099+
27100+static u32 himci_get_sap_dll_taps(struct himci_host *host)
27101+{
27102+	u32 regval = 0;
27103+	void __iomem *reg_sap_dll_status = 0;
27104+
27105+	if (host->devid == 0)
27106+		reg_sap_dll_status = crg_ctrl + 0x150;
27107+	else if (host->devid == 1)
27108+		reg_sap_dll_status = crg_ctrl + 0x168;
27109+	else if (host->devid == 2)
27110+		reg_sap_dll_status = crg_ctrl + 0x15c;
27111+	else {
27112+		himci_trace(5, "Devid error, host->devid: %x", host->devid);
27113+		return 0;
27114+	}
27115+	regval = himci_readl(reg_sap_dll_status);
27116+
27117+	return (regval & 0xff);
27118+}
27119+
27120+static void himci_set_dll_element(struct himci_host *host, u32 element)
27121+{
27122+	u32 regval;
27123+	void __iomem *reg_sap_dll_ctrl = 0;
27124+
27125+	if (host->devid == 0)
27126+		reg_sap_dll_ctrl = crg_ctrl + 0x14c;
27127+	else if (host->devid == 1)
27128+		reg_sap_dll_ctrl = crg_ctrl + 0x164;
27129+	else if (host->devid == 2)
27130+		reg_sap_dll_ctrl = crg_ctrl + 0x158;
27131+	else {
27132+		himci_trace(5, "Devid error, host->devid: %x", host->devid);
27133+		return;
27134+	}
27135+	regval = himci_readl(reg_sap_dll_ctrl);
27136+	regval &= ~(0xFF << 8);
27137+	regval |= (element << 8);
27138+	himci_writel(regval, reg_sap_dll_ctrl);
27139+}
27140+
27141+/*********************************************
27142+ *********************************************
27143+ EdgeMode A:
27144+ |<---- totalphases(ele) ---->|
27145+        _____________
27146+ ______|||||||||||||||_______
27147+ edge_p2f       edge_f2p
27148+ (endp)         (startp)
27149+
27150+ EdgeMode B:
27151+ |<---- totalphases(ele) ---->|
27152+  ________           _________
27153+ ||||||||||_________|||||||||||
27154+ edge_f2p     edge_p2f
27155+ (startp)     (endp)
27156+
27157+ BestPhase:
27158+ if(endp < startp)
27159+ endp = endp + totalphases;
27160+ Best = ((startp + endp) / 2) % totalphases
27161+**********************************************
27162+**********************************************/
27163+static int himci_edgedll_mode_tuning(struct himci_host *host, u32 opcode,
27164+				     int edge_p2f, int edge_f2p)
27165+{
27166+	u32 index;
27167+	u32 found = 0;
27168+	u32 startp = -1;
27169+	u32 endp = -1;
27170+	u32 startp_init = 0;
27171+	u32 endp_init = 0;
27172+	u32 phaseoffset = 0;
27173+	u32 totalphases = 0;
27174+	u16 ele, start_ele, phase_dll_elements;
27175+	u8 mdly_tap_flag = 0;
27176+	int prev_err = 0, err = 0;
27177+	u32 phase_num = HIMCI_PHASE_SCALE;
27178+
27179+	himci_trace(3, "begin");
27180+
27181+	mdly_tap_flag = himci_get_sap_dll_taps(host);
27182+	phase_dll_elements = mdly_tap_flag / HIMCI_PHASE_SCALE;
27183+	totalphases = phase_dll_elements * phase_num;
27184+
27185+	startp_init = edge_f2p * phase_dll_elements;
27186+	endp_init = edge_p2f * phase_dll_elements;
27187+	startp = startp_init;
27188+	endp = endp_init;
27189+
27190+	found = 1;
27191+	start_ele = 2;
27192+
27193+	/* Note: edgedll tuning must from edge_p2f to edge_f2p */
27194+	if (edge_f2p >=  edge_p2f) {
27195+		phaseoffset = edge_p2f * phase_dll_elements;
27196+		for (index = edge_p2f; index < edge_f2p; index++) {
27197+			/* set phase shift */
27198+			himci_set_sap_phase(host, index);
27199+			for (ele = start_ele; ele <= phase_dll_elements; ele++) {
27200+				himci_set_dll_element(host, ele);
27201+				err = himci_send_tuning(host->mmc, opcode);
27202+
27203+				if (!err)
27204+					found = 1;
27205+
27206+				if (!prev_err && err && (endp == endp_init))
27207+					endp = phaseoffset + ele;
27208+
27209+				if (err)
27210+					startp = phaseoffset + ele;
27211+
27212+#ifdef TUNING_PROC_DEBUG
27213+				printk("\tphase:%01d ele:%02d st:%03d end:%03d error:%d\n", index, ele, startp,
27214+				       endp, err);
27215+#endif
27216+
27217+				prev_err = err;
27218+				err = 0;
27219+			}
27220+			phaseoffset += phase_dll_elements;
27221+		}
27222+	} else {
27223+		phaseoffset = edge_p2f * phase_dll_elements;
27224+		for (index = edge_p2f; index < phase_num; index++) {
27225+			/* set phase shift */
27226+			himci_set_sap_phase(host, index);
27227+			for (ele = start_ele; ele <= phase_dll_elements; ele++) {
27228+				himci_set_dll_element(host, ele);
27229+				err = himci_send_tuning(host->mmc, opcode);
27230+				if (!err)
27231+					found = 1;
27232+
27233+				if (!prev_err && err && (endp == endp_init))
27234+					endp = phaseoffset + ele;
27235+
27236+				if (err)
27237+					startp = phaseoffset + ele;
27238+
27239+#ifdef TUNING_PROC_DEBUG
27240+				printk("\tphase:%02d ele:%02d st:%03d end:%03d error:%d\n", index, ele, startp,
27241+				       endp, err);
27242+#endif
27243+
27244+				prev_err = err;
27245+				err = 0;
27246+			}
27247+			phaseoffset += phase_dll_elements;
27248+		}
27249+
27250+		phaseoffset = 0;
27251+		for (index = 0; index < edge_f2p; index++) {
27252+			/* set phase shift */
27253+			himci_set_sap_phase(host, index);
27254+			for (ele = start_ele; ele <= phase_dll_elements; ele++) {
27255+				himci_set_dll_element(host, ele);
27256+				err = himci_send_tuning(host->mmc, opcode);
27257+				if (!err)
27258+					found = 1;
27259+
27260+				if (!prev_err && err && (endp == endp_init))
27261+					endp = phaseoffset + ele;
27262+
27263+				if (err)
27264+					startp = phaseoffset + ele;
27265+
27266+#ifdef TUNING_PROC_DEBUG
27267+				printk("\tphase:%02d ele:%02d st:%03d end:%03d error:%d\n", index, ele, startp,
27268+				       endp, err);
27269+#endif
27270+
27271+				prev_err = err;
27272+				err = 0;
27273+			}
27274+			phaseoffset += phase_dll_elements;
27275+		}
27276+	}
27277+
27278+	if (found) {
27279+		printk("scan elemnts: startp:%d endp:%d\n", startp, endp);
27280+
27281+		if (endp <= startp)
27282+			endp += totalphases;
27283+
27284+		if (totalphases == 0) {
27285+			printk(KERN_NOTICE "totalphases is zero\n");
27286+			return -1;
27287+		}
27288+		phaseoffset = ((startp + endp) / 2) % totalphases;
27289+		index = (phaseoffset / phase_dll_elements);
27290+		ele = (phaseoffset % phase_dll_elements);
27291+		ele = ((ele > start_ele) ? ele : start_ele);
27292+
27293+		himci_set_sap_phase(host, index);
27294+		himci_set_dll_element(host, ele);
27295+
27296+		printk(KERN_NOTICE
27297+		       "Tuning SampleClock. mix set phase:[%02d/%02d] ele:[%02d/%02d] \n", index,
27298+		       (phase_num - 1), ele,
27299+		       phase_dll_elements);
27300+		himci_writel(ALL_INT_CLR, host->base + MCI_RINTSTS);
27301+		return 0;
27302+	}
27303+	printk(KERN_NOTICE "No valid phase shift! use default\n");
27304+	return -1;
27305+}
27306+
27307+static void himci_tuning_feedback(struct mmc_host *mmc)
27308+{
27309+	struct himci_host *host = mmc_priv(mmc);
27310+
27311+	himci_control_cclk(host, DISABLE);
27312+	msleep(1);
27313+	himci_sys_reset(host);
27314+	msleep(1);
27315+	himci_writel(ALL_INT_CLR, host->base + MCI_RINTSTS);
27316+	himci_control_cclk(host, ENABLE);
27317+	msleep(1);
27318+	host->pending_events = 0;
27319+}
27320+
27321+static int himci_check_tuning(struct mmc_host *mmc, u32 opcode)
27322+{
27323+	int err;
27324+
27325+	err = himci_send_tuning(mmc, opcode);
27326+
27327+	return 	err;
27328+}
27329+
27330+static int himci_execute_mix_mode_tuning(struct mmc_host *mmc, u32 opcode)
27331+{
27332+	struct himci_host *host = mmc_priv(mmc);
27333+	u32 index, regval;
27334+	u32 found = 0, prefound = 0;
27335+	u32 edge_p2f, edge_f2p;
27336+	u32 edge_num = 0;
27337+	int err;
27338+	u32 phase_num = HIMCI_PHASE_SCALE;
27339+
27340+	himci_trace(3, "begin");
27341+	edge_p2f = 0;
27342+	edge_f2p = phase_num;
27343+
27344+	himci_edge_tuning_enable(host);
27345+
27346+	for (index = 0; index < HIMCI_PHASE_SCALE; index++) {
27347+		/* set phase shift */
27348+		himci_set_sap_phase(host, index);
27349+		err = himci_send_tuning(mmc, opcode);
27350+		if (!err) {
27351+			regval = himci_readl(host->base + MCI_TUNING_CTRL);
27352+			found = ((regval & FOUND_EDGE) == FOUND_EDGE);
27353+		} else {
27354+			found = 1;
27355+		}
27356+
27357+		if (found) {
27358+			edge_num++;
27359+		}
27360+		if (prefound && !found) {
27361+			edge_f2p = index;
27362+		} else if (!prefound && found) {
27363+			edge_p2f = index;
27364+		}
27365+#ifdef TUNING_PROC_DEBUG
27366+		printk("\tphase:%02d found:%02d p2f:%d f2p:%d error:%d\n", index, found,
27367+		       edge_p2f, edge_f2p, err);
27368+#endif
27369+		if ((edge_p2f != 0) && (edge_f2p != phase_num))
27370+			break;
27371+
27372+		prefound = found;
27373+		found = 0;
27374+	}
27375+
27376+	if ((edge_p2f == 0) && (edge_f2p == phase_num)) {
27377+		printk("unfound correct edge! check your config is correct!!\n");
27378+		return -1;
27379+	}
27380+	printk("scan edges:%d p2f:%d f2p:%d\n", edge_num, edge_p2f, edge_f2p);
27381+
27382+	if (edge_f2p < edge_p2f)
27383+		index = (edge_f2p + edge_p2f) / 2 % phase_num;
27384+	else
27385+		index = (edge_f2p + phase_num + edge_p2f) / 2 % phase_num;
27386+	printk("mix set temp-phase %d\n", index);
27387+	himci_set_sap_phase(host, index);
27388+	err = himci_send_tuning(mmc, opcode);
27389+
27390+	himci_edge_tuning_disable(host);
27391+
27392+	err = himci_edgedll_mode_tuning(host, opcode, edge_p2f, edge_f2p);
27393+	return err;
27394+}
27395+#if 0
27396+static int himci_execute_edge_tuning(struct mmc_host *mmc, u32 opcode)
27397+{
27398+	struct himci_host *host = mmc_priv(mmc);
27399+	unsigned int index, val;
27400+	unsigned int found = 0;
27401+	unsigned int prev_found = 0;
27402+	unsigned int prev_point = 0;
27403+	unsigned int start_point = NOT_FOUND, end_point = NOT_FOUND;
27404+	unsigned int phase = 0;
27405+
27406+	himci_trace(3, "begin");
27407+
27408+	himci_edge_tuning_enable(host);
27409+
27410+	for (index = 0; index < HIMCI_PHASE_SCALE; index++) {
27411+		himci_set_sap_phase(host, index);
27412+
27413+		mmc_send_tuning(mmc, opcode, NULL);
27414+
27415+		himci_send_stop(mmc);
27416+
27417+		val = himci_readl(host->base + MCI_TUNING_CTRL);
27418+		found = val & FOUND_EDGE;
27419+
27420+		himci_trace(3, "try phase:%02d, found:0x%x\n", index, found);
27421+
27422+		if (prev_found && !found) {
27423+			end_point = prev_point;
27424+		} else if (!prev_found && found) {
27425+			if (index != 0)
27426+				start_point = index;
27427+		}
27428+		if ((start_point != NOT_FOUND) && (end_point != NOT_FOUND))
27429+			goto scan_out;
27430+
27431+		prev_point = index;
27432+		prev_found = found;
27433+		found = 0;
27434+	}
27435+
27436+scan_out:
27437+	if ((start_point == NOT_FOUND) && (end_point == NOT_FOUND)) {
27438+		himci_trace(5, "%s: no valid phase shift! use default",
27439+			    mmc_hostname(mmc));
27440+		return 0;
27441+	}
27442+
27443+	if (start_point == NOT_FOUND)
27444+		start_point = end_point;
27445+
27446+	if (end_point == NOT_FOUND)
27447+		end_point = start_point;
27448+
27449+	pr_info("tuning %s: found edge on (s:%d, e:%d)",
27450+		mmc_hostname(mmc), start_point, end_point);
27451+
27452+	if (start_point > end_point)
27453+		end_point += HIMCI_PHASE_SCALE;
27454+
27455+	phase = ((start_point + end_point) / 2) % HIMCI_PHASE_SCALE;
27456+
27457+	phase += HIMCI_PHASE_SCALE / 2;
27458+	phase %= HIMCI_PHASE_SCALE;
27459+
27460+	himci_set_sap_phase(host, phase);
27461+
27462+	himci_edge_tuning_disable(host);
27463+
27464+	himci_writel(ALL_INT_CLR, host->base + MCI_RINTSTS);
27465+
27466+	pr_info("determing final phase %d\n", phase);
27467+
27468+	return 0;
27469+}
27470+#endif
27471+
27472+/*
27473+ * The procedure of tuning the phase shift of sampling clock
27474+ *
27475+ * 1.Set a phase shift of 0° on cclk_in_sample
27476+ * 2.Send the Tuning command to the card
27477+ * 3.increase the phase shift value of cclk_in_sample until the
27478+ *   correct sampling point is received such that the host does not
27479+ *   see any of the errors.
27480+ * 4.Mark this phase shift value as the starting point of the sampling
27481+ *   window.
27482+ * 5.increase the phase shift value of cclk_in_sample until the host
27483+ *   sees the errors starting to come again or the phase shift value
27484+ *   reaches 360°.
27485+ * 6.Mark the last successful phase shift value as the ending
27486+ *   point of the sampling window.
27487+ *
27488+ *     A window is established where the tuning block is matched.
27489+ * For example, for a scenario where the tuning block is received
27490+ * correctly for a phase shift window of 90°and 180°, then an appropriate
27491+ * sampling point is established as 135°. Once a sampling point is
27492+ * established, no errors should be visible in the tuning block.
27493+ *
27494+ */
27495+static int himci_execute_tuning(struct mmc_host *mmc, u32 opcode)
27496+{
27497+	struct himci_host *host = mmc_priv(mmc);
27498+	int err;
27499+
27500+	himci_trace(3, "begin");
27501+
27502+	host->is_tuning = 1;
27503+	err = himci_execute_mix_mode_tuning(mmc, opcode);
27504+	himci_tuning_feedback(mmc);
27505+	if (!err)
27506+		err = himci_check_tuning(mmc, opcode);
27507+	host->is_tuning = 0;
27508+	return err;
27509+}
27510+#else
27511+static int himci_execute_tuning(struct mmc_host *mmc, u32 opcode)
27512+{
27513+	struct himci_host *host;
27514+	unsigned int index, count;
27515+	unsigned int err = 0;
27516+	unsigned int found = 0; /* identify if we have found a valid phase */
27517+	unsigned int start_point;
27518+	unsigned int end_point;
27519+	unsigned int prev_err = NOT_FOUND;
27520+	unsigned int raise_point = NOT_FOUND;
27521+	unsigned int fall_point = NOT_FOUND;
27522+	int phase, ret;
27523+
27524+	start_point = TUNING_START_PHASE;
27525+	end_point = TUNING_END_PHASE;
27526+
27527+	host = mmc_priv(mmc);
27528+
27529+	himci_writel(0x1, host->base + MCI_CARDTHRCTL);
27530+
27531+	himci_trace(3, "start sd3.0 phase tuning...");
27532+	host->is_tuning = 1;
27533+	for (index = start_point; index <= end_point; index++) {
27534+		/* set sample clk phase shift */
27535+		himci_set_sap_phase(host, index);
27536+
27537+		count = 0;
27538+		do {
27539+			ret = mmc_send_tuning(mmc, opcode, NULL);
27540+			himci_send_stop(mmc); /* send soft_stop tail */
27541+
27542+			if (ret) {
27543+				himci_trace(3, "send tuning CMD%u fail! phase:%d err:%d\n",
27544+					    opcode, index, ret);
27545+				err = 1;
27546+				break;
27547+			}
27548+			count++;
27549+		} while (count < 1);
27550+
27551+		if (!err)
27552+			found = 1; /* found a valid phase */
27553+
27554+		if (index > start_point) {
27555+			if (err && !prev_err)
27556+				fall_point = index - 1;
27557+
27558+			if (!err && prev_err)
27559+				raise_point = index;
27560+		}
27561+
27562+		if ((raise_point != NOT_FOUND) && (fall_point != NOT_FOUND))
27563+			goto tuning_out;
27564+
27565+		prev_err = err;
27566+		err = 0;
27567+	}
27568+
27569+tuning_out:
27570+	host->is_tuning = 0;
27571+	if (!found) {
27572+		himci_trace(5, "%s: no valid phase shift! use default",
27573+			    mmc_hostname(mmc));
27574+		himci_writel(DEFAULT_PHASE, host->base + MCI_UHS_REG_EXT);
27575+	} else {
27576+		himci_trace(3, "Tuning finished!!");
27577+
27578+		if (NOT_FOUND == raise_point)
27579+			raise_point = start_point;
27580+		if (NOT_FOUND == fall_point)
27581+			fall_point = end_point;
27582+
27583+		if (fall_point < raise_point) {
27584+			phase = (raise_point + fall_point) / 2;
27585+			phase = phase - (HIMCI_PHASE_SCALE / 2);
27586+			phase = (phase < 0) ? (HIMCI_PHASE_SCALE + phase) : phase;
27587+		} else
27588+			phase = (raise_point + fall_point) / 2;
27589+
27590+		himci_set_sap_phase(host, phase);
27591+
27592+		pr_info("tuning %s: valid phase shift [%d, %d] Final Phase %d\n",
27593+			mmc_hostname(mmc), raise_point, fall_point, phase);
27594+	}
27595+
27596+	himci_writel(RW_THRESHOLD_SIZE, host->base + MCI_CARDTHRCTL);
27597+
27598+	return 0;
27599+}
27600+#endif
27601+
27602+static void himci_set_bus_width(struct himci_host *host, struct mmc_ios *ios)
27603+{
27604+	unsigned int tmp_reg;
27605+
27606+	/* set bus_width */
27607+	himci_trace(3, "ios->bus_width = %d ", ios->bus_width);
27608+	tmp_reg = himci_readl(host->base + MCI_CTYPE);
27609+	tmp_reg &= ~((CARD_WIDTH_0 | CARD_WIDTH_1) << host->port);
27610+
27611+	if (ios->bus_width == MMC_BUS_WIDTH_8) {
27612+		tmp_reg |= (CARD_WIDTH_0 << host->port);
27613+		himci_writel(tmp_reg, host->base + MCI_CTYPE);
27614+	} else if (ios->bus_width == MMC_BUS_WIDTH_4) {
27615+		tmp_reg |= (CARD_WIDTH_1 << host->port);
27616+		himci_writel(tmp_reg, host->base + MCI_CTYPE);
27617+	} else {
27618+		himci_writel(tmp_reg, host->base + MCI_CTYPE);
27619+	}
27620+}
27621+
27622+static void himci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
27623+{
27624+	struct himci_host *host = mmc_priv(mmc);
27625+	u32 ctrl;
27626+	int ret = 0;
27627+
27628+	himci_trace(2, "begin");
27629+	himci_assert(mmc);
27630+	himci_assert(ios);
27631+	himci_assert(host);
27632+
27633+	himci_trace(3, "ios->power_mode = %d ", ios->power_mode);
27634+	if (!ios->clock) {
27635+		ret = himci_control_cclk(host, DISABLE);
27636+		if (ret)
27637+			return;
27638+	}
27639+
27640+	switch (ios->power_mode) {
27641+	case MMC_POWER_OFF:
27642+		himci_ctrl_power(host, POWER_OFF, FORCE_DISABLE);
27643+		break;
27644+	case MMC_POWER_UP:
27645+	case MMC_POWER_ON:
27646+		himci_ctrl_power(host, POWER_ON, FORCE_DISABLE);
27647+		break;
27648+	default:
27649+		break;
27650+	}
27651+	himci_trace(3, "ios->clock = %d ", ios->clock);
27652+	if (ios->clock) {
27653+		ret = himci_control_cclk(host, DISABLE);
27654+		if (ret)
27655+			return;
27656+		himci_set_cclk(host, ios->clock);
27657+		ret = himci_control_cclk(host, ENABLE);
27658+		if (ret)
27659+			return;
27660+
27661+		himci_set_default_phase(host);
27662+
27663+		/* speed mode check, if it is DDR50 set DDR mode */
27664+		if (ios->timing == MMC_TIMING_UHS_DDR50) {
27665+			ctrl = himci_readl(host->base + MCI_UHS_REG);
27666+			if (!((HI_SDXC_CTRL_DDR_REG << host->port) & ctrl)) {
27667+				ctrl |= (HI_SDXC_CTRL_DDR_REG << host->port);
27668+				himci_writel(ctrl, host->base + MCI_UHS_REG);
27669+			}
27670+		}
27671+	} else {
27672+		ret = himci_control_cclk(host, DISABLE);
27673+		if (ret)
27674+			return;
27675+		if (ios->timing != MMC_TIMING_UHS_DDR50) {
27676+			ctrl = himci_readl(host->base + MCI_UHS_REG);
27677+			if ((HI_SDXC_CTRL_DDR_REG << host->port) & ctrl) {
27678+				ctrl &= ~(HI_SDXC_CTRL_DDR_REG << host->port);
27679+				himci_writel(ctrl, host->base + MCI_UHS_REG);
27680+			}
27681+		}
27682+	}
27683+
27684+	himci_set_drv_cap(host, 0);
27685+
27686+	himci_set_bus_width(host, ios);
27687+}
27688+
27689+static void himci_enable_sdio_irq(struct mmc_host *mmc, int enable)
27690+{
27691+	struct himci_host *host = mmc_priv(mmc);
27692+	unsigned int reg_value;
27693+	unsigned long flags;
27694+
27695+	spin_lock_irqsave(&host->lock, flags);
27696+	reg_value = himci_readl(host->base + MCI_INTMASK);
27697+	if (enable)
27698+		reg_value |= SDIO_INT_MASK;
27699+	else
27700+		reg_value &= ~SDIO_INT_MASK;
27701+	himci_writel(reg_value, host->base + MCI_INTMASK);
27702+	spin_unlock_irqrestore(&host->lock, flags);
27703+}
27704+
27705+static int himci_get_card_detect(struct mmc_host *mmc)
27706+{
27707+	unsigned ret;
27708+	struct himci_host *host = mmc_priv(mmc);
27709+
27710+	himci_trace(2, "begin");
27711+	ret = himci_sys_card_detect(host);
27712+
27713+	if (ret)
27714+		return 0;
27715+	else
27716+		return 1;
27717+}
27718+
27719+static int himci_get_ro(struct mmc_host *mmc)
27720+{
27721+	unsigned ret;
27722+	struct himci_host *host = mmc_priv(mmc);
27723+
27724+	himci_trace(2, "begin");
27725+	himci_assert(mmc);
27726+
27727+	ret = himci_ctrl_card_readonly(host);
27728+
27729+	return ret;
27730+}
27731+
27732+static void himci_hw_reset(struct mmc_host *mmc)
27733+{
27734+	unsigned int reg_value;
27735+	struct himci_host *host = mmc_priv(mmc);
27736+	unsigned int port = host->port;
27737+
27738+	reg_value = himci_readl(host->base + MCI_RESET_N);
27739+	reg_value &= ~(MMC_RST_N << port);
27740+	himci_writel(reg_value, host->base + MCI_RESET_N);
27741+
27742+	/* For eMMC, minimum is 1us but give it 10us for good measure */
27743+	udelay(10);
27744+	reg_value = himci_readl(host->base + MCI_RESET_N);
27745+	reg_value |= (MMC_RST_N << port);
27746+	himci_writel(reg_value, host->base + MCI_RESET_N);
27747+
27748+	/* For eMMC, minimum is 200us but give it 300us for good measure */
27749+	usleep_range(300, 1000);
27750+}
27751+
27752+static int himci_card_busy(struct mmc_host *mmc)
27753+{
27754+	struct himci_host *host = mmc_priv(mmc);
27755+	u32 regval;
27756+
27757+	himci_trace(2, "begin");
27758+
27759+	regval = himci_readl(host->base + MCI_STATUS);
27760+	regval &= DATA_BUSY;
27761+
27762+	return regval;
27763+}
27764+
27765+static int himci_card_info_save(struct mmc_host *mmc)
27766+{
27767+	struct mmc_card *card = mmc->card;
27768+	struct himci_host *host = mmc_priv(mmc);
27769+	struct card_info *c_info = &host->c_info;
27770+
27771+	if (!card) {
27772+		memset(c_info, 0, sizeof(struct card_info));
27773+		c_info->card_connect = CARD_DISCONNECT;
27774+		goto out;
27775+	}
27776+
27777+	c_info->card_type = card->type;
27778+	c_info->card_state = card->state;
27779+
27780+	c_info->timing = mmc->ios.timing;
27781+	c_info->card_support_clock = mmc->ios.clock;
27782+
27783+	c_info->sd_bus_speed = card->sd_bus_speed;
27784+
27785+	memcpy(c_info->ssr, card->raw_ssr, ARRAY_SIZE(c_info->ssr));
27786+
27787+	c_info->card_connect = CARD_CONNECT;
27788+out:
27789+	return 0;
27790+}
27791+
27792+static const struct mmc_host_ops himci_ops = {
27793+	.request = himci_request,
27794+	.set_ios = himci_set_ios,
27795+	.get_ro = himci_get_ro,
27796+	.card_busy = himci_card_busy,
27797+	.start_signal_voltage_switch = himci_start_signal_voltage_switch,
27798+	.execute_tuning	= himci_execute_tuning,
27799+	.enable_sdio_irq = himci_enable_sdio_irq,
27800+	.hw_reset = himci_hw_reset,
27801+	.get_cd = himci_get_card_detect,
27802+	.card_info_save = himci_card_info_save,
27803+};
27804+
27805+static irqreturn_t hisd_irq(int irq, void *dev_id)
27806+{
27807+	struct himci_host *host = dev_id;
27808+	u32 state = 0;
27809+	int handle = 0;
27810+	u32 mstate = 0;
27811+
27812+	spin_lock(&host->lock);
27813+	state = himci_readl(host->base + MCI_RINTSTS);
27814+	spin_unlock(&host->lock);
27815+
27816+	/* bugfix: when send soft stop to SD Card, Host will report
27817+	   sdio interrupt, This situation needs to be avoided */
27818+	if (host->mmc->caps & MMC_CAP_SDIO_IRQ) {
27819+		if ((host->mmc->card != NULL)
27820+				&& (host->mmc->card->type == MMC_TYPE_SDIO)) {
27821+			mstate = himci_readl(host->base + MCI_INTMASK);
27822+			if ((state & SDIO_INT_STATUS) &&
27823+					(mstate & SDIO_INT_MASK)) {
27824+				spin_lock(&host->lock);
27825+				himci_writel(SDIO_INT_STATUS,
27826+					     host->base + MCI_RINTSTS);
27827+				spin_unlock(&host->lock);
27828+				handle = 1;
27829+				mmc_signal_sdio_irq(host->mmc);
27830+			}
27831+		}
27832+	}
27833+
27834+	if (state & DATA_INT_MASK) {
27835+		handle = 1;
27836+		host->pending_events |= HIMCI_PEND_DTO_M;
27837+
27838+		spin_lock(&host->lock);
27839+		host->irq_status = himci_readl(host->base + MCI_RINTSTS);
27840+		himci_writel(DATA_INT_MASK, host->base + MCI_RINTSTS);
27841+		spin_unlock(&host->lock);
27842+
27843+		wake_up(&host->intr_wait);
27844+	}
27845+
27846+	if (handle)
27847+		return IRQ_HANDLED;
27848+
27849+	return IRQ_NONE;
27850+}
27851+
27852+static int himci_of_parse(struct device_node *np, struct mmc_host *mmc)
27853+{
27854+	struct himci_host *host = mmc_priv(mmc);
27855+	int ret = mmc_of_parse(mmc);
27856+	int len;
27857+
27858+	if (ret)
27859+		return ret;
27860+
27861+	if (of_property_read_u32(np, "min-frequency", &mmc->f_min))
27862+		mmc->f_min = MMC_CCLK_MIN;
27863+
27864+	if (of_property_read_u32(np, "devid", &host->devid))
27865+		return -EINVAL;
27866+
27867+	if (of_find_property(np, "cap-mmc-hw-reset", &len))
27868+		mmc->caps |= MMC_CAP_HW_RESET;
27869+
27870+	if (host->devid == 0 || host->devid == 1)
27871+		mmc->caps |= MMC_CAP_CMD23;
27872+	return 0;
27873+}
27874+
27875+static void himci_sdio_setup(void)
27876+{
27877+#if defined(CONFIG_ARCH_HI3516DV300)
27878+	void __iomem *pwr_ctrl;
27879+	/* enable GPIO pin multiplexing in PMC module */
27880+	unsigned int val;
27881+
27882+	pwr_ctrl = ioremap(PWR_CTRL0_REG, 0x4);
27883+	if (!pwr_ctrl) {
27884+		printk("%s ioremap fail\n", __func__);
27885+		return;
27886+	}
27887+	val = readl(pwr_ctrl);
27888+	val = val | GPIO_AT_PMC_ENABLE_BIT;
27889+	writel(val, pwr_ctrl);
27890+	msleep(REG_SLEEP_TIME_MS);
27891+	iounmap(pwr_ctrl);
27892+#endif
27893+}
27894+
27895+static int himci_probe(struct platform_device *pdev)
27896+{
27897+	struct mmc_host *mmc = NULL;
27898+	struct himci_host *host = NULL;
27899+	struct resource *host_ioaddr_res = NULL;
27900+	int ret = 0, irq;
27901+	struct device_node *np = pdev->dev.of_node;
27902+	unsigned int regval;
27903+	static bool sdio_setup = false;
27904+
27905+	himci_trace(2, "begin");
27906+	pr_info("mmc host probe\n");
27907+	himci_assert(pdev);
27908+
27909+	if (sdio_setup == false) {
27910+		pr_info("sdio_setup entry!\n");
27911+		himci_sdio_setup();
27912+		sdio_setup = true;
27913+	}
27914+
27915+	mmc = mmc_alloc_host(sizeof(struct himci_host), &pdev->dev);
27916+	if (!mmc) {
27917+		himci_error("no mem for hi mci host controller!\n");
27918+		ret = -ENOMEM;
27919+		goto out;
27920+	}
27921+
27922+	platform_set_drvdata(pdev, mmc);
27923+
27924+	mmc->ops = &himci_ops;
27925+
27926+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \
27927+    defined(CONFIG_ARCH_HI3556V200)  || defined(CONFIG_ARCH_HI3559V200)  || \
27928+    defined(CONFIG_ARCH_HI3562V100)  || defined(CONFIG_ARCH_HI3566V100)
27929+
27930+	crg_ctrl = ioremap(0x12010000, 0x1000);
27931+	if (!crg_ctrl) {
27932+		printk("%s ioremap fail\n", __func__);
27933+		ret = -ENOMEM;
27934+		goto out;
27935+	}
27936+
27937+	misc_ctrl_1 = ioremap(0x12030004, 0x4);
27938+	if (!misc_ctrl_1) {
27939+		printk("%s ioremap fail\n", __func__);
27940+		ret = -ENOMEM;
27941+		goto out;
27942+	}
27943+	regval = readl(misc_ctrl_1);
27944+	/* clear sdio0_pswitch_ctrl_sel bit */
27945+	regval &= ~(0x1 << 2);
27946+	writel(regval, misc_ctrl_1);
27947+	iounmap(misc_ctrl_1);
27948+#endif
27949+
27950+	host_ioaddr_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
27951+	if (NULL == host_ioaddr_res) {
27952+		himci_error("no ioaddr rescources config!\n");
27953+		ret = -ENODEV;
27954+		goto out;
27955+	}
27956+
27957+	if (himci_of_parse(np, mmc)) {
27958+		himci_error("failed to parse mmc dts!\n");
27959+		ret = -EINVAL;
27960+		goto out;
27961+	}
27962+
27963+	/* reload by this controller */
27964+#ifndef CONFIG_HISI_MC
27965+	mmc->max_blk_count = 2048;
27966+#else
27967+	mmc->max_blk_count = 4096;
27968+#endif
27969+	mmc->max_segs = 1024;
27970+	mmc->max_seg_size = mmc->max_blk_size * mmc->max_blk_count;
27971+	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
27972+	mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
27973+
27974+	host = mmc_priv(mmc);
27975+	pdev->id = host->devid;
27976+    if (host->devid >= HIMCI_SLOT_NUM) {
27977+        himci_error("devid is invalid!\n");
27978+		ret = -EINVAL;
27979+		goto out;
27980+    }
27981+   mci_host[host->devid] = host;
27982+	host->pdev = pdev;
27983+	host->mmc = mmc;
27984+#ifdef CONFIG_ARCH_HI3518EV20X
27985+	if (host->mmc->caps & MMC_CAP_HW_RESET)
27986+		host->port = 1;
27987+	else
27988+		host->port = 0;
27989+#else
27990+	host->port = 0;
27991+#endif
27992+	host->dma_vaddr = dma_alloc_coherent(&pdev->dev, CMD_DES_PAGE_SIZE,
27993+					     &host->dma_paddr, GFP_KERNEL);
27994+	if (!host->dma_vaddr) {
27995+		himci_error("no mem for himci dma!\n");
27996+		ret = -ENOMEM;
27997+		goto out;
27998+	}
27999+
28000+	host->base = devm_ioremap_resource(&pdev->dev, host_ioaddr_res);
28001+	if (IS_ERR_OR_NULL(host->base)) {
28002+		himci_error("no mem for himci base!\n");
28003+		ret = -ENOMEM;
28004+		goto out;
28005+	}
28006+
28007+	spin_lock_init(&host->lock);
28008+
28009+	host->crg_rst = devm_reset_control_get(&pdev->dev, "mmc_reset");
28010+	if (IS_ERR_OR_NULL(host->crg_rst)) {
28011+		himci_error("get rst fail.\n");
28012+		ret = PTR_ERR(host->crg_rst);
28013+		goto out;
28014+	}
28015+
28016+	reset_control_assert(host->crg_rst);
28017+	usleep_range(50, 60);
28018+	reset_control_deassert(host->crg_rst);
28019+
28020+	host->clk = devm_clk_get(&pdev->dev, "mmc_clk");
28021+	if (IS_ERR_OR_NULL(host->clk)) {
28022+		himci_error("get clock fail.\n");
28023+		ret = PTR_ERR(host->clk);
28024+		goto out;
28025+	}
28026+
28027+	clk_prepare_enable(host->clk);
28028+
28029+	host->power_status = POWER_OFF;
28030+
28031+	/* enable card */
28032+	himci_init_host(host);
28033+	host->card_status = himci_sys_card_detect(host);
28034+
28035+	timer_setup(&host->timer, himci_detect_card, 0);
28036+	host->timer.expires = jiffies + detect_time;
28037+	add_timer(&host->timer);
28038+
28039+	init_waitqueue_head(&host->intr_wait);
28040+	irq = platform_get_irq(pdev, 0);
28041+	if (irq < 0) {
28042+		pr_err("no IRQ defined!\n");
28043+		goto out;
28044+	}
28045+
28046+	host->irq = irq;
28047+	ret = request_irq(irq, hisd_irq, 0, DRIVER_NAME, host);
28048+	if (ret) {
28049+		pr_err("request_irq error!\n");
28050+		goto out;
28051+	}
28052+
28053+	mmc_add_host(mmc);
28054+	return 0;
28055+out:
28056+	if (host) {
28057+		del_timer(&host->timer);
28058+
28059+		if (host->base)
28060+			devm_iounmap(&pdev->dev, host->base);
28061+
28062+		if (host->dma_vaddr)
28063+			dma_free_coherent(&pdev->dev, CMD_DES_PAGE_SIZE,
28064+					  host->dma_vaddr, host->dma_paddr);
28065+	}
28066+	if (mmc)
28067+		mmc_free_host(mmc);
28068+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \
28069+    defined(CONFIG_ARCH_HI3556V200)  || defined(CONFIG_ARCH_HI3559V200)  || \
28070+    defined(CONFIG_ARCH_HI3562V100)  || defined(CONFIG_ARCH_HI3566V100)
28071+	if (crg_ctrl)
28072+		iounmap(crg_ctrl);
28073+#endif
28074+	return ret;
28075+}
28076+
28077+static int __exit himci_remove(struct platform_device *pdev)
28078+{
28079+	struct mmc_host *mmc = platform_get_drvdata(pdev);
28080+
28081+	himci_trace(2, "begin");
28082+	himci_assert(pdev);
28083+
28084+	platform_set_drvdata(pdev, NULL);
28085+
28086+	if (mmc) {
28087+		struct himci_host *host = mmc_priv(mmc);
28088+
28089+		mmc_remove_host(mmc);
28090+		free_irq(host->irq, host);
28091+		del_timer_sync(&host->timer);
28092+		himci_ctrl_power(host, POWER_OFF, FORCE_DISABLE);
28093+		himci_control_cclk(host, DISABLE);
28094+		devm_iounmap(&pdev->dev, host->base);
28095+		dma_free_coherent(&pdev->dev, CMD_DES_PAGE_SIZE, host->dma_vaddr,
28096+				  host->dma_paddr);
28097+		mmc_free_host(mmc);
28098+	}
28099+	return 0;
28100+}
28101+
28102+static void himci_shutdown(struct platform_device *pdev)
28103+{
28104+	struct mmc_host *mmc = platform_get_drvdata(pdev);
28105+
28106+	himci_trace(3, "shutdown");
28107+	if (mmc) {
28108+		unsigned int val;
28109+		struct himci_host *host = mmc_priv(mmc);
28110+
28111+		/* bugfix: host reset can trigger error intr */
28112+		himci_writel(0, host->base + MCI_IDINTEN);
28113+		himci_writel(0, host->base + MCI_INTMASK);
28114+
28115+		val = himci_readl(host->base + MCI_CTRL);
28116+		val |= CTRL_RESET | FIFO_RESET | DMA_RESET;
28117+		himci_writel(val, host->base + MCI_CTRL);
28118+	}
28119+}
28120+
28121+#ifdef CONFIG_PM
28122+static int himci_pltm_suspend(struct platform_device *pdev,
28123+			      pm_message_t state)
28124+{
28125+	struct mmc_host *mmc = platform_get_drvdata(pdev);
28126+	struct himci_host *host = NULL;
28127+	int ret = 0;
28128+
28129+	if (mmc) {
28130+		host = mmc_priv(mmc);
28131+		del_timer_sync(&host->timer);
28132+
28133+		if (__clk_is_enabled(host->clk))
28134+			clk_disable_unprepare(host->clk);
28135+	}
28136+
28137+	return ret;
28138+}
28139+
28140+static int himci_pltm_resume(struct platform_device *pdev)
28141+{
28142+	struct mmc_host *mmc = platform_get_drvdata(pdev);
28143+	struct himci_host *host = NULL;
28144+	int ret = 0;
28145+
28146+	if (mmc) {
28147+		host = mmc_priv(mmc);
28148+
28149+		if (!__clk_is_enabled(host->clk))
28150+			clk_prepare_enable(host->clk);
28151+
28152+		himci_sys_ctrl_init(host);
28153+		himci_init_host(host);
28154+
28155+		add_timer(&host->timer);
28156+	}
28157+
28158+	return ret;
28159+}
28160+#else
28161+#define himci_pltm_suspend    NULL
28162+#define himci_pltm_resume     NULL
28163+#endif
28164+
28165+void hisi_sdio_rescan(int slot)
28166+{
28167+	struct mmc_host *mmc = NULL;
28168+	struct himci_host *host;
28169+
28170+	host = mci_host[slot];
28171+	if (!host || !host->mmc) {
28172+		himci_trace(5, "mmc%d: invalid slot!\n", slot);
28173+		return;
28174+	}
28175+
28176+	mmc = host->mmc;
28177+	del_timer_sync(&host->timer);
28178+
28179+	mmc_remove_host(mmc);
28180+
28181+	mmc_add_host(mmc);
28182+
28183+	add_timer(&host->timer);
28184+}
28185+EXPORT_SYMBOL(hisi_sdio_rescan);
28186+
28187+struct mmc_host *himci_get_mmc_host(int slot)
28188+{
28189+	struct himci_host *host = NULL;
28190+
28191+	if (slot >= HIMCI_SLOT_NUM || slot < 0) {
28192+		return NULL;
28193+	}
28194+
28195+	host = mci_host[slot];
28196+	if (host == NULL) {
28197+		return NULL;
28198+	}
28199+	return host->mmc;
28200+}
28201+EXPORT_SYMBOL(himci_get_mmc_host);
28202+
28203+static const struct of_device_id
28204+	himci_match[] __maybe_unused = {
28205+	{.compatible = "hisilicon,hi3516a-himci"},
28206+	{.compatible = "hisilicon,hi3518ev20x-himci"},
28207+	{.compatible = "hisilicon,hi3516cv500-himci"},
28208+	{.compatible = "hisilicon,hi3516dv300-himci"},
28209+	{.compatible = "hisilicon,hi3556v200-himci"},
28210+	{.compatible = "hisilicon,hi3559v200-himci"},
28211+	{},
28212+};
28213+
28214+static struct platform_driver himci_driver = {
28215+	.probe = himci_probe,
28216+	.remove = himci_remove,
28217+	.shutdown = himci_shutdown,
28218+	.suspend = himci_pltm_suspend,
28219+	.resume = himci_pltm_resume,
28220+	.driver = {
28221+		.name = DRIVER_NAME,
28222+		.owner = THIS_MODULE,
28223+		.of_match_table = of_match_ptr(himci_match),
28224+	},
28225+};
28226+
28227+static int __init himci_init(void)
28228+{
28229+	int ret;
28230+
28231+	himci_trace(2, "begin");
28232+
28233+	/*
28234+	 * We should register SDIO1 first to make sure that
28235+	 * the eMMC device,which connected to SDIO1 is mmcblk0.
28236+	 */
28237+
28238+	ret = platform_driver_register(&himci_driver);
28239+	if (ret) {
28240+		platform_driver_unregister(&himci_driver);
28241+		himci_error("Himci driver register failed!");
28242+		return ret;
28243+	}
28244+
28245+	/* device proc entry */
28246+	ret = mci_proc_init();
28247+	if (ret)
28248+		himci_error("device proc init is failed!");
28249+
28250+	return ret;
28251+}
28252+
28253+static void __exit himci_exit(void)
28254+{
28255+	himci_trace(2, "begin");
28256+
28257+	mci_proc_shutdown();
28258+
28259+	platform_driver_unregister(&himci_driver);
28260+}
28261+
28262+module_init(himci_init);
28263+module_exit(himci_exit);
28264+
28265+#ifdef MODULE
28266+MODULE_AUTHOR("Hisilicon Drive Group");
28267+MODULE_DESCRIPTION("MMC/SD driver for the Hisilicon MMC/SD Host Controller");
28268+MODULE_LICENSE("GPL");
28269+#endif
28270diff --git a/drivers/mmc/host/himci/himci.h b/drivers/mmc/host/himci/himci.h
28271new file mode 100644
28272index 000000000..d882e847f
28273--- /dev/null
28274+++ b/drivers/mmc/host/himci/himci.h
28275@@ -0,0 +1,156 @@
28276+#ifndef _HI_MCI_H_
28277+#define _HI_MCI_H_
28278+
28279+#include <linux/mmc/mmc.h>
28280+
28281+extern int trace_level;
28282+#define HIMCI_TRACE_LEVEL 5
28283+/*
28284+   0 - all message
28285+   1 - dump all register read/write
28286+   2 - flow trace
28287+   3 - timeout err and protocol err
28288+   */
28289+
28290+#define HIMCI_TRACE_FMT KERN_INFO
28291+
28292+#define NOT_FOUND -1
28293+#define POWER_ON 1
28294+#define POWER_OFF 0
28295+#define FORCE_ENABLE 1
28296+#define FORCE_DISABLE 0
28297+
28298+#define CARD_UNPLUGED 1
28299+#define CARD_PLUGED 0
28300+
28301+#define ENABLE 1
28302+#define DISABLE 0
28303+
28304+#define HI_MCI_DETECT_TIMEOUT (HZ / 2)
28305+
28306+#define HI_MCI_REQUEST_TIMEOUT (30 * HZ)
28307+
28308+#define MAX_RETRY_COUNT 100
28309+
28310+#define MMC_CCLK_MIN  100000
28311+
28312+/* Base address of SD card register */
28313+#define HI_MCI_INTR (49 + 32)
28314+
28315+#define himci_trace(level, msg...) do { \
28316+	if ((level) >= trace_level) { \
28317+		printk(HIMCI_TRACE_FMT "%s:%d: ", __func__, __LINE__); \
28318+		printk(msg); \
28319+		printk("\n"); \
28320+	} \
28321+} while (0)
28322+
28323+#define himci_assert(cond) do { \
28324+	if (!(cond)) { \
28325+		printk(KERN_ERR "Assert:himci:%s:%d\n", \
28326+				__func__, \
28327+				__LINE__); \
28328+		BUG(); \
28329+	} \
28330+} while (0)
28331+
28332+#define himci_error(s...) do { \
28333+	printk(KERN_ERR "himci:%s:%d: ", __func__, __LINE__); \
28334+	printk(s); \
28335+	printk("\n"); \
28336+} while (0)
28337+
28338+#define himci_readl(addr) ({unsigned int reg = readl(IOMEM((uintptr_t)addr)); \
28339+	himci_trace(1, "readl(0x%04X) = 0x%08X", (unsigned int)(uintptr_t)addr, reg); \
28340+	reg; })
28341+
28342+#define himci_writel(v, addr) do { writel(v, IOMEM((uintptr_t)addr)); \
28343+	himci_trace(1, "writel(0x%04X) = 0x%08X", (unsigned int)(uintptr_t)addr, \
28344+			(unsigned int)(uintptr_t)(v)); \
28345+} while (0)
28346+
28347+struct himci_des {
28348+	unsigned long idmac_des_ctrl;
28349+	unsigned long idmac_des_buf_size;
28350+	unsigned long idmac_des_buf_addr;
28351+	unsigned long idmac_des_next_addr;
28352+};
28353+
28354+struct card_info {
28355+	unsigned int     card_type;
28356+	unsigned char    timing;
28357+	unsigned char    card_connect;
28358+#define CARD_CONNECT    1
28359+#define CARD_DISCONNECT 0
28360+	unsigned int     card_support_clock; /* clock rate */
28361+	unsigned int     card_state;      /* (our) card state */
28362+	unsigned int     sd_bus_speed;
28363+	unsigned int     ssr[16];
28364+};
28365+
28366+struct himci_host {
28367+	struct mmc_host *mmc;
28368+	struct platform_device *pdev;
28369+	spinlock_t lock;
28370+	struct mmc_request *mrq;
28371+	struct mmc_command *cmd;
28372+	struct mmc_data *data;
28373+	void __iomem *base;
28374+	struct scatterlist *dma_sg;
28375+	unsigned int dma_sg_num;
28376+	unsigned int dma_dir;
28377+	dma_addr_t dma_paddr;
28378+	unsigned int *dma_vaddr;
28379+	struct timer_list timer;
28380+	unsigned int irq;
28381+	unsigned int irq_status;
28382+	unsigned int is_tuning;
28383+	wait_queue_head_t intr_wait;
28384+#define HIMCI_PEND_DTO_B (0)
28385+#define HIMCI_PEND_DTO_M (1 << HIMCI_PEND_DTO_B)
28386+	unsigned long pending_events;
28387+	unsigned int power_status;
28388+	unsigned int card_rca;
28389+	unsigned int card_status;
28390+	unsigned int devid;
28391+	unsigned int hclk;
28392+	unsigned int cclk;
28393+	struct clk *clk;
28394+	struct reset_control *crg_rst;
28395+	unsigned int port;
28396+	unsigned int error_count;
28397+	unsigned int data_error_count;
28398+	struct card_info c_info;
28399+};
28400+
28401+union cmd_arg_u {
28402+	unsigned int cmd_arg;
28403+	struct cmd_bits_arg {
28404+		unsigned int cmd_index : 6;
28405+		unsigned int response_expect : 1;
28406+		unsigned int response_length : 1;
28407+		unsigned int check_response_crc : 1;
28408+		unsigned int data_transfer_expected : 1;
28409+		unsigned int read_write : 1;
28410+		unsigned int transfer_mode : 1;
28411+		unsigned int send_auto_stop : 1;
28412+		unsigned int wait_prvdata_complete : 1;
28413+		unsigned int stop_abort_cmd : 1;
28414+		unsigned int send_initialization : 1;
28415+		unsigned int card_number : 5;
28416+		unsigned int update_clk_reg_only : 1; /* bit 21 */
28417+		unsigned int read_ceata_device : 1;
28418+		unsigned int ccs_expected : 1;
28419+		unsigned int enable_boot : 1;
28420+		unsigned int expect_boot_ack : 1;
28421+		unsigned int disable_boot : 1;
28422+		unsigned int boot_mode : 1;
28423+		unsigned int volt_switch : 1;
28424+		unsigned int use_hold_reg : 1;
28425+		unsigned int reserved : 1;
28426+		unsigned int start_cmd : 1; /* HSB */
28427+	} bits;
28428+};
28429+
28430+struct mmc_host *get_mmchost(int hostid);
28431+#endif
28432diff --git a/drivers/mmc/host/himci/himci_hi3516dv300.c b/drivers/mmc/host/himci/himci_hi3516dv300.c
28433new file mode 100644
28434index 000000000..bb312d601
28435--- /dev/null
28436+++ b/drivers/mmc/host/himci/himci_hi3516dv300.c
28437@@ -0,0 +1,160 @@
28438+/*
28439+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
28440+ *
28441+ * This program is free software; you can redistribute  it and/or modify it
28442+ * under  the terms of  the GNU General Public License as published by the
28443+ * Free Software Foundation;  either version 2 of the  License, or (at your
28444+ * option) any later version.
28445+ *
28446+ * This program is distributed in the hope that it will be useful,
28447+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28448+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28449+ * GNU General Public License for more details.
28450+ *
28451+ * You should have received a copy of the GNU General Public License
28452+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
28453+ *
28454+ */
28455+#define MMC_CRG_MIN 25000000
28456+
28457+#define TUNING_START_PHASE 0
28458+#define TUNING_END_PHASE 7
28459+#define HIMCI_PHASE_SCALE 8
28460+#define DRV_PHASE_DFLT (0x4<<23)
28461+#define SMPL_PHASE_DFLT (0x0<<16)
28462+
28463+/* eMMC pad ctrl reg */
28464+#define REG_CTRL_EMMC_START (0x10ff0000 + 0x0)
28465+/* sdio0 pad ctrl reg */
28466+#define REG_CTRL_SDIO0_START (0x10ff0000 + 0x24)
28467+/* sdio1 pad ctrl reg */
28468+#define REG_CTRL_SDIO1_START (0x112f0000 + 0x8)
28469+
28470+static unsigned int pad_ctrl_start[] = {REG_CTRL_EMMC_START, REG_CTRL_SDIO0_START, REG_CTRL_SDIO1_START};
28471+
28472+/*  clk   cmd   data0  data1  data2  data3 */
28473+static unsigned int emmc_hs200_drv[] = {0x2b0, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0};
28474+static unsigned int emmc_hs_drv[] = {0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0};
28475+static unsigned int emmc_ds_drv[] = {0x6b0, 0x5f0, 0x5f0, 0x5f0, 0x5f0, 0x5f0};
28476+static unsigned int emmc_ds_400k_drv[] = {0x6c0, 0x5f0, 0x5f0, 0x5f0, 0x5f0, 0x5f0};
28477+
28478+static unsigned int sdio0_sdr104_drv[] = {0x290, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0};
28479+static unsigned int sdio0_sdr50_drv[] = {0x290, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0};
28480+static unsigned int sdio0_sdr25_drv[] = {0x6b0, 0x5d0, 0x5d0, 0x5d0, 0x5d0, 0x5d0};
28481+static unsigned int sdio0_sdr12_drv[] = {0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0};
28482+static unsigned int sdio0_hs_drv[] = {0x6d0, 0x5f0, 0x5f0, 0x5f0, 0x5f0, 0x5f0};
28483+static unsigned int sdio0_ds_drv[] = {0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0};
28484+
28485+static unsigned int sdio1_sdr104_drv[] = {0x290, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0};
28486+static unsigned int sdio1_sdr50_drv[] = {0x290, 0x1c0, 0x1c0, 0x1c0, 0x1c0, 0x1c0};
28487+static unsigned int sdio1_sdr25_drv[] = {0x6b0, 0x5d0, 0x5d0, 0x5d0, 0x5d0, 0x5d0};
28488+static unsigned int sdio1_sdr12_drv[] = {0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0};
28489+static unsigned int sdio1_hs_drv[] = {0x6d0, 0x5f0, 0x5f0, 0x5f0, 0x5f0, 0x5f0};
28490+static unsigned int sdio1_ds_drv[] = {0x6b0, 0x5e0, 0x5e0, 0x5e0, 0x5e0, 0x5e0};
28491+
28492+static void himci_set_drv_cap(struct himci_host *host, unsigned int vdd_180)
28493+{
28494+	struct mmc_host *mmc = host->mmc;
28495+	struct mmc_ios *ios = &(mmc->ios);
28496+	unsigned int devid = host->devid;
28497+	unsigned char timing = ios->timing;
28498+	unsigned int i, j, start;
28499+	unsigned int *pin_drv_cap = NULL;
28500+
28501+	if (devid == 0) {
28502+		if (timing == MMC_TIMING_MMC_HS200)
28503+			pin_drv_cap = emmc_hs200_drv;
28504+		else if (timing == MMC_TIMING_MMC_HS)
28505+			pin_drv_cap = emmc_hs_drv;
28506+		else {
28507+			if (ios->clock == 400000) /* 400K */
28508+				pin_drv_cap = emmc_ds_400k_drv;
28509+			else
28510+				pin_drv_cap = emmc_ds_drv;
28511+		}
28512+	} else if (devid == 1) {
28513+		if (timing == MMC_TIMING_UHS_SDR104)
28514+			pin_drv_cap = sdio0_sdr104_drv;
28515+		else if (timing == MMC_TIMING_UHS_SDR50)
28516+			pin_drv_cap = sdio0_sdr50_drv;
28517+		else if (timing == MMC_TIMING_UHS_SDR25)
28518+			pin_drv_cap = sdio0_sdr25_drv;
28519+		else if (timing == MMC_TIMING_UHS_SDR12)
28520+			pin_drv_cap = sdio0_sdr12_drv;
28521+		else if (timing == MMC_TIMING_SD_HS)
28522+			pin_drv_cap = sdio0_hs_drv;
28523+		else
28524+			pin_drv_cap = sdio0_ds_drv;
28525+	} else {
28526+		if (timing == MMC_TIMING_UHS_SDR104)
28527+			pin_drv_cap = sdio1_sdr104_drv;
28528+		else if (timing == MMC_TIMING_UHS_SDR50)
28529+			pin_drv_cap = sdio1_sdr50_drv;
28530+		else if (timing == MMC_TIMING_UHS_SDR25)
28531+			pin_drv_cap = sdio1_sdr25_drv;
28532+		else if (timing == MMC_TIMING_UHS_SDR12)
28533+			pin_drv_cap = sdio1_sdr12_drv;
28534+		else if (timing == MMC_TIMING_SD_HS)
28535+			pin_drv_cap = sdio1_hs_drv;
28536+		else
28537+			pin_drv_cap = sdio1_ds_drv;
28538+	}
28539+
28540+	start = (unsigned int)(long)ioremap((resource_size_t)pad_ctrl_start[devid],
28541+					    (size_t)0x1000);
28542+	for (i = start, j = 0; j < 6; i = i + 4, j++) {
28543+		unsigned int reg = himci_readl(i);
28544+		/*
28545+		 * [10]:SR
28546+		 * [9]:internel pull down
28547+		 * [8]:internel pull up
28548+		 * [7:4]:
28549+		 * */
28550+		reg = reg & (~(0x7f0));
28551+		reg |= pin_drv_cap[j];
28552+		himci_writel(reg, i);
28553+	}
28554+	iounmap((void *)(long)start);
28555+}
28556+
28557+#define DRV_PHASE_180   (0x4<<23)
28558+#define DRV_PHASE_135   (0x3<<23)
28559+#define DRV_PHASE_90    (0x2<<23)
28560+
28561+#define SMP_PHASE_45    (0x1<<16)
28562+#define SMP_PHASE_0     (0x0<<16)
28563+
28564+static void himci_set_default_phase(struct himci_host *host)
28565+{
28566+	struct mmc_host *mmc = host->mmc;
28567+	struct mmc_ios *ios = &(mmc->ios);
28568+	unsigned int devid = host->devid;
28569+	unsigned char timing = ios->timing;
28570+	unsigned int phase_cfg, reg_value;
28571+	if (devid == 0) {
28572+		if (timing == MMC_TIMING_MMC_HS200)
28573+			phase_cfg = DRV_PHASE_135 | SMP_PHASE_0;
28574+		else if (timing == MMC_TIMING_MMC_HS)
28575+			phase_cfg = DRV_PHASE_180 | SMP_PHASE_45;
28576+		else {
28577+			phase_cfg = DRV_PHASE_180 | SMP_PHASE_0;
28578+		}
28579+	} else {
28580+		if (timing == MMC_TIMING_UHS_SDR104)
28581+			phase_cfg = DRV_PHASE_135 | SMP_PHASE_0;
28582+		else if (timing == MMC_TIMING_UHS_SDR50)
28583+			phase_cfg = DRV_PHASE_90 | SMP_PHASE_0;
28584+		else if (timing == MMC_TIMING_UHS_SDR25)
28585+			phase_cfg = DRV_PHASE_180 | SMP_PHASE_45;
28586+		else if (timing == MMC_TIMING_SD_HS)
28587+			phase_cfg = DRV_PHASE_135 | SMP_PHASE_45;
28588+		else
28589+			phase_cfg = DRV_PHASE_180 | SMP_PHASE_0;
28590+	}
28591+
28592+	reg_value = himci_readl(host->base + MCI_UHS_REG_EXT);
28593+	reg_value &= ~CLK_SMPL_PHS_MASK;
28594+	reg_value &= ~CLK_DRV_PHS_MASK;
28595+	reg_value |= phase_cfg;
28596+	himci_writel(reg_value, host->base + MCI_UHS_REG_EXT);
28597+}
28598diff --git a/drivers/mmc/host/himci/himci_proc.c b/drivers/mmc/host/himci/himci_proc.c
28599new file mode 100644
28600index 000000000..ac339c4da
28601--- /dev/null
28602+++ b/drivers/mmc/host/himci/himci_proc.c
28603@@ -0,0 +1,246 @@
28604+/*
28605+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
28606+ *
28607+ * This program is free software; you can redistribute it and/or modify
28608+ * it under the terms of the GNU General Public License as published by
28609+ * the Free Software Foundation; either version 2 of the License, or
28610+ * (at your option) any later version.
28611+ *
28612+ * This program is distributed in the hope that it will be useful,
28613+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28614+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28615+ * GNU General Public License for more details.
28616+ *
28617+ * You should have received a copy of the GNU General Public License
28618+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
28619+ */
28620+
28621+#include <linux/proc_fs.h>
28622+#include <linux/seq_file.h>
28623+#include <linux/device.h>
28624+#include <linux/io.h>
28625+#include <linux/platform_device.h>
28626+
28627+#include <linux/mmc/card.h>
28628+
28629+#include <linux/export.h>
28630+#include <linux/mmc/host.h>
28631+#include "himci.h"
28632+#include "himci_reg.h"
28633+#include "himci_proc.h"
28634+
28635+#define MCI_PARENT       "mci"
28636+#define MCI_STATS_PROC   "mci_info"
28637+#define MAX_CLOCK_SCALE	(4)
28638+#define UNSTUFF_BITS(resp, start, size)                   \
28639+	({                              \
28640+	 const int __size = size;                \
28641+	 const u32 __mask = (__size < 32 ? 1 << __size : 0) - 1; \
28642+	 const int __off = 3 - ((start) / 32);           \
28643+	 const int __shft = (start) & 31;            \
28644+	 u32 __res;                      \
28645+	 \
28646+	 __res = resp[__off] >> __shft;              \
28647+	 if (__size + __shft > 32)               \
28648+	 __res |= resp[__off-1] << ((32 - __shft) % 32); \
28649+	 __res & __mask;                     \
28650+	 })
28651+
28652+extern unsigned int slot_index;
28653+static struct proc_dir_entry *proc_mci_dir;
28654+
28655+static char *card_type[MAX_CARD_TYPE + 1] = {
28656+	"MMC card",
28657+	"SD card",
28658+	"SDIO card",
28659+	"SD combo (IO+mem) card",
28660+	"unknown"
28661+};
28662+static char *clock_unit[MAX_CLOCK_SCALE] = {
28663+	"Hz",
28664+	"KHz",
28665+	"MHz",
28666+	"GHz"
28667+};
28668+
28669+static char *mci_get_card_type(unsigned int sd_type)
28670+{
28671+	if (MAX_CARD_TYPE <= sd_type)
28672+		return card_type[MAX_CARD_TYPE];
28673+	else
28674+		return card_type[sd_type];
28675+}
28676+
28677+static unsigned int analyze_clock_scale(unsigned int clock,
28678+					unsigned int *clock_val)
28679+{
28680+	unsigned int scale = 0;
28681+	unsigned int tmp = clock;
28682+
28683+	while (1) {
28684+		tmp = tmp / 1000;
28685+		if (0 < tmp) {
28686+			*clock_val = tmp;
28687+			scale++;
28688+		} else {
28689+			break;
28690+		}
28691+	}
28692+	return scale;
28693+}
28694+
28695+static inline int is_card_uhs(unsigned char timing)
28696+{
28697+	return timing >= MMC_TIMING_UHS_SDR12 &&
28698+	       timing <= MMC_TIMING_UHS_DDR50;
28699+};
28700+
28701+static inline int is_card_hs(unsigned char timing)
28702+{
28703+	return timing == MMC_TIMING_SD_HS || timing == MMC_TIMING_MMC_HS;
28704+};
28705+
28706+static void mci_stats_seq_printout(struct seq_file *s)
28707+{
28708+	unsigned int index_mci;
28709+	unsigned int clock;
28710+	unsigned int clock_scale;
28711+	unsigned int clock_value = 0;
28712+	const char *type = NULL;
28713+	unsigned int present;
28714+	struct himci_host *host = NULL;
28715+	struct card_info *c_info = NULL;
28716+	const char *uhs_bus_speed_mode = "";
28717+	u32 speed_class, grade_speed_uhs;
28718+	static const char *const uhs_speeds[] = {
28719+		[UHS_SDR12_BUS_SPEED] = "SDR12 ",
28720+		[UHS_SDR25_BUS_SPEED] = "SDR25 ",
28721+		[UHS_SDR50_BUS_SPEED] = "SDR50 ",
28722+		[UHS_SDR104_BUS_SPEED] = "SDR104 ",
28723+		[UHS_DDR50_BUS_SPEED] = "DDR50 ",
28724+	};
28725+
28726+	for (index_mci = 0; index_mci < HIMCI_SLOT_NUM; index_mci++) {
28727+		host = mci_host[index_mci];
28728+		if (!host || !host->mmc) {
28729+			seq_printf(s, "MCI%d: invalid\n", index_mci);
28730+			continue;
28731+		} else {
28732+			seq_printf(s, "MCI%d", index_mci);
28733+		}
28734+		c_info = &host->c_info;
28735+
28736+		present = host->mmc->ops->get_cd(host->mmc);
28737+		if (present) {
28738+			seq_puts(s, ": pluged");
28739+		} else {
28740+			seq_puts(s, ": unplugged");
28741+		}
28742+
28743+		if (CARD_CONNECT != c_info->card_connect) {
28744+			if (host->mmc->card_status == MMC_CARD_INIT_FAIL)
28745+				seq_puts(s, "_init_failed\n");
28746+			else
28747+				seq_puts(s, "_disconnected\n");
28748+		} else {
28749+			seq_puts(s, "_connected\n");
28750+			seq_printf(s,
28751+				   "\tType: %s",
28752+				   mci_get_card_type(c_info->card_type)
28753+				  );
28754+
28755+			if (c_info->card_state & MMC_STATE_BLOCKADDR) {
28756+				if (c_info->card_state & MMC_CARD_SDXC)
28757+					type = "SDXC";
28758+				else
28759+					type = "SDHC";
28760+				seq_printf(s, "(%s)\n", type);
28761+			}
28762+
28763+			if (is_card_uhs(c_info->timing) &&
28764+					c_info->sd_bus_speed < ARRAY_SIZE(uhs_speeds))
28765+				uhs_bus_speed_mode = uhs_speeds[c_info->sd_bus_speed];
28766+
28767+			seq_printf(s, "\tMode: %s%s%s%s\n",
28768+				   is_card_uhs(c_info->timing) ? "UHS " :
28769+				   (is_card_hs(c_info->timing) ? "HS " : ""),
28770+				   c_info->timing == MMC_TIMING_MMC_HS400 ? "HS400 " :
28771+				   (c_info->timing == MMC_TIMING_MMC_HS200 ? "HS200 " : ""),
28772+				   c_info->timing == MMC_TIMING_MMC_DDR52 ? "DDR " : "",
28773+				   uhs_bus_speed_mode);
28774+
28775+			speed_class = UNSTUFF_BITS(c_info->ssr, 440 - 384, 8);
28776+			grade_speed_uhs = UNSTUFF_BITS(c_info->ssr, 396 - 384, 4);
28777+			seq_printf(s, "\tSpeed Class: Class %s\n",
28778+				   (0x00 == speed_class) ? "0" :
28779+				   (0x01 == speed_class) ? "2" :
28780+				   (0x02 == speed_class) ? "4" :
28781+				   (0x03 == speed_class) ? "6" :
28782+				   (0x04 == speed_class) ? "10" :
28783+				   "Reserved");
28784+			seq_printf(s, "\tUhs Speed Grade: %s\n",
28785+				   (0x00 == grade_speed_uhs) ?
28786+				   "Less than 10MB/sec(0h)" :
28787+				   (0x01 == grade_speed_uhs) ?
28788+				   "10MB/sec and above(1h)" :
28789+				   "Reserved");
28790+
28791+			clock = host->hclk;
28792+			clock_scale = analyze_clock_scale(clock, &clock_value);
28793+			seq_printf(s, "\tHost work clock: %d%s\n",
28794+				   clock_value, clock_unit[clock_scale]);
28795+
28796+			clock = c_info->card_support_clock;
28797+			clock_scale = analyze_clock_scale(clock, &clock_value);
28798+			seq_printf(s, "\tCard support clock: %d%s\n",
28799+				   clock_value, clock_unit[clock_scale]);
28800+
28801+			clock = host->cclk;
28802+			clock_scale = analyze_clock_scale(clock, &clock_value);
28803+			seq_printf(s, "\tCard work clock: %d%s\n",
28804+				   clock_value, clock_unit[clock_scale]);
28805+			/* add card read/write error count */
28806+			seq_printf(s, "\tCard error count: %d\n",
28807+				   host->error_count);
28808+			seq_printf(s, "\tCard data error count: %d\n",
28809+				   host->data_error_count);
28810+		}
28811+	}
28812+}
28813+
28814+/* define parameters where showed in proc file */
28815+static int mci_stats_seq_show(struct seq_file *s, void *v)
28816+{
28817+	mci_stats_seq_printout(s);
28818+	return 0;
28819+}
28820+
28821+int mci_proc_init(void)
28822+{
28823+	struct proc_dir_entry *proc_stats_entry = NULL;
28824+	proc_mci_dir = proc_mkdir(MCI_PARENT, NULL);
28825+	if (!proc_mci_dir) {
28826+		pr_err("%s: failed to create proc file %s\n",
28827+				__func__, MCI_PARENT);
28828+		return 1;
28829+	}
28830+	proc_stats_entry = proc_create_single_data(MCI_STATS_PROC, 0,
28831+			proc_mci_dir, mci_stats_seq_show, NULL);
28832+	if (!proc_stats_entry) {
28833+		pr_err("%s: failed to create proc file %s\n",
28834+				__func__, MCI_STATS_PROC);
28835+		return 1;
28836+	}
28837+	return 0;
28838+}
28839+
28840+int mci_proc_shutdown(void)
28841+{
28842+	if (proc_mci_dir) {
28843+		remove_proc_entry(MCI_STATS_PROC, proc_mci_dir);
28844+		remove_proc_entry(MCI_PARENT, NULL);
28845+		proc_mci_dir = NULL;
28846+	}
28847+
28848+	return 0;
28849+}
28850diff --git a/drivers/mmc/host/himci/himci_proc.h b/drivers/mmc/host/himci/himci_proc.h
28851new file mode 100644
28852index 000000000..e6ea9a137
28853--- /dev/null
28854+++ b/drivers/mmc/host/himci/himci_proc.h
28855@@ -0,0 +1,36 @@
28856+/*
28857+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
28858+ *
28859+ * This program is free software; you can redistribute it and/or modify
28860+ * it under the terms of the GNU General Public License as published by
28861+ * the Free Software Foundation; either version 2 of the License, or
28862+ * (at your option) any later version.
28863+ *
28864+ * This program is distributed in the hope that it will be useful,
28865+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28866+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28867+ * GNU General Public License for more details.
28868+ *
28869+ * You should have received a copy of the GNU General Public License
28870+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
28871+ */
28872+
28873+/*
28874+ *  MCI connection table manager
28875+ */
28876+#ifndef __MCI_PROC_H__
28877+#define __MCI_PROC_H__
28878+
28879+#include <linux/proc_fs.h>
28880+
28881+#define MAX_CARD_TYPE 4
28882+#define MAX_SPEED_MODE 5
28883+#define MMC_STATE_BLOCKADDR (1<<2) /* card uses block-addressing copy from core/card.h */
28884+#define MMC_CARD_SDXC (1<<3) /* card is SDXC copy from core/card.h */
28885+#define HIMCI_SLOT_NUM 3
28886+
28887+extern struct himci_host *mci_host[HIMCI_SLOT_NUM];
28888+int mci_proc_init(void);
28889+int mci_proc_shutdown(void);
28890+
28891+#endif /*  __MCI_PROC_H__ */
28892diff --git a/drivers/mmc/host/himci/himci_reg.h b/drivers/mmc/host/himci/himci_reg.h
28893new file mode 100644
28894index 000000000..d1d8f9f9d
28895--- /dev/null
28896+++ b/drivers/mmc/host/himci/himci_reg.h
28897@@ -0,0 +1,241 @@
28898+/*
28899+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
28900+ *
28901+ * This program is free software; you can redistribute it and/or modify
28902+ * it under the terms of the GNU General Public License as published by
28903+ * the Free Software Foundation; either version 2 of the License, or
28904+ * (at your option) any later version.
28905+ *
28906+ * This program is distributed in the hope that it will be useful,
28907+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
28908+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
28909+ * GNU General Public License for more details.
28910+ *
28911+ * You should have received a copy of the GNU General Public License
28912+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
28913+ */
28914+
28915+#ifndef _HI_MCI_REG_H_
28916+#define _HI_MCI_REG_H_
28917+
28918+#define HI_MCI_IO_SIZE 0x1000
28919+
28920+#define MCI_CTRL 0x00
28921+#define MCI_PWREN 0x04
28922+#define MCI_CLKDIV 0x08
28923+#define MCI_CLKSRC 0x0C
28924+#define MCI_CLKENA 0x10
28925+#define MCI_TIMEOUT 0x14
28926+#define MCI_CTYPE 0x18
28927+#define MCI_BLKSIZ 0x1c
28928+#define MCI_BYTCNT 0x20
28929+#define MCI_INTMASK 0x24
28930+#define MCI_CMDARG 0x28
28931+#define MCI_CMD 0x2C
28932+#define MCI_RESP0 0x30
28933+#define MCI_RESP1 0x34
28934+#define MCI_RESP2 0x38
28935+#define MCI_RESP3 0x3C
28936+#define MCI_MINTSTS 0x40
28937+#define MCI_RINTSTS 0x44
28938+#define MCI_STATUS 0x48
28939+#define MCI_FIFOTH 0x4C
28940+#define MCI_CDETECT 0x50
28941+#define MCI_WRTPRT 0x54
28942+#define MCI_GPIO 0x58
28943+#define MCI_TCBCNT 0x5C
28944+#define MCI_TBBCNT 0x60
28945+#define MCI_DEBNCE 0x64
28946+#define MCI_USRID 0x68
28947+#define MCI_VERID 0x6C
28948+#define MCI_HCON 0x70
28949+#define MCI_UHS_REG 0x74
28950+#define MCI_RESET_N 0x78
28951+#define MCI_BMOD 0x80
28952+#define MCI_DBADDR 0x88
28953+#define MCI_IDSTS 0x8C
28954+#define MCI_IDINTEN 0x90
28955+#define MCI_DSCADDR 0x94
28956+#define MCI_BUFADDR 0x98
28957+#define MCI_CARDTHRCTL 0x100
28958+#define MCI_UHS_REG_EXT 0x108
28959+
28960+#define MCI_TUNING_CTRL 0x118
28961+
28962+/* MCI_IDSTS(0x8c) detals */
28963+#define CMD_LOCK_ERR (0x1 << 29)
28964+#define OWNBIT_ERR (0x1 << 28)
28965+#define QUEUE_OVERFLOW (0x1 << 27)
28966+#define RESP_CHECK_ERR (0x1 << 26)
28967+#define PACKET_INT (0x1 << 25)
28968+#define PACKET_TO_INT (0x1 << 24)
28969+#define AUTO_STOP_ERR (0x1 << 23)
28970+#define QUEUE_FULL (0x1 << 22)
28971+#define QUEUE_EMPTY (0x1 << 21)
28972+#define ADMA3_FSM_SHIFT (17)
28973+#define FSM_SHIFT (13)
28974+#define CES (0x1 << 5)
28975+#define DU (0x1 << 4)
28976+#define FBE (0x1 << 2)
28977+
28978+/* MCI_BMOD(0x80) details */
28979+#define BMOD_SWR (0x1 << 0)
28980+#define BURST_INCR (0x1 << 1)
28981+#define BMOD_DMA_EN (0x1 << 7)
28982+#define BURST_8 (0x2 << 8)
28983+#define BURST_16 (0x3 << 8)
28984+/* IDMAC DEST1 details */
28985+#define DMA_BUFFER (0x2000)
28986+#define MAX_DMA_DES (20480)
28987+
28988+/* IDMAC DEST0 details */
28989+#define DMA_DES_OWN (1 << 31)
28990+#define DMA_DES_NEXT_DES (1 << 4)
28991+#define DMA_DES_FIRST_DES (1 << 3)
28992+#define DMA_DES_LAST_DES (1 << 2)
28993+
28994+/* MCI_CTRL(0x00) details */
28995+#define CTRL_RESET (1 << 0)
28996+#define FIFO_RESET (1 << 1)
28997+#define DMA_RESET (1 << 2)
28998+#define INTR_EN (1 << 4)
28999+#define USE_INTERNAL_DMA (1 << 25)
29000+
29001+/* MCI_CLKENA(0x10) details */
29002+#define CCLK_ENABLE (0x1 << 0)
29003+#define CCLK_LOW_POWER (0x1 << 16)
29004+
29005+/* MCI_TIMEOUT(0x14) details: */
29006+/* bit 31-8: data read timeout param */
29007+#define DATA_TIMEOUT (0xffffff << 8)
29008+/* bit 7-0: response timeout param */
29009+#define RESPONSE_TIMEOUT 0xff
29010+
29011+/* MCI_CTYPE(0x18) details */
29012+#define CARD_WIDTH_0 (0x1 << 16)
29013+#define CARD_WIDTH_1 (0x1 << 0)
29014+
29015+/* MCI_INTMASK(0x24) details:
29016+   bit 16-1: mask MMC host controller each interrupt
29017+*/
29018+#define ALL_INT_MASK 0x1ffff
29019+#define DTO_INT_MASK (0x1 << 3)
29020+#define SDIO_INT_MASK (0x1 << 16)
29021+
29022+/* MCI_UHS_REG_EXT(0x108) details */
29023+/* bit[19:16] sampling phase */
29024+#define CLK_SMPL_PHS_SHIFT (16)
29025+#define CLK_SMPL_PHS_MASK (0x7 << 16)
29026+
29027+/* bit[26:23] drv phase */
29028+#define CLK_DRV_PHS_SHIFT (23)
29029+#define CLK_DRV_PHS_MASK (0x7 << 23)
29030+#define DEFAULT_PHASE 0x1050000
29031+
29032+/* MCI_CMD(0x2c) details:
29033+   bit 31: cmd execute or load start param of interface clk bit
29034+*/
29035+#define START_CMD (0x1<<31)
29036+
29037+/* MCI_INTSTS(0x44) details */
29038+
29039+/* bit 16: sdio interrupt status */
29040+#define SDIO_INT_STATUS (0x1 << 16)
29041+
29042+/* bit 15: end-bit error (read)/write no CRC interrupt status */
29043+#define EBE_INT_STATUS (0x1 << 15)
29044+
29045+/* bit 14: auto command done interrupt status */
29046+#define ACD_INT_STATUS (0x1 << 14)
29047+
29048+/* bit 13: start bit error interrupt status */
29049+#define SBE_INT_STATUS (0x1 << 13)
29050+
29051+/* bit 12: hardware locked write error interrupt status */
29052+#define HLE_INT_STATUS (0x1 << 12)
29053+
29054+/* bit 11: FIFO underrun/overrun error interrupt status */
29055+#define FRUN_INT_STATUS (0x1 << 11)
29056+
29057+/* bit 10: data starvation-by-host timeout interrupt status */
29058+#define HTO_INT_STATUS (0x1 << 10)
29059+
29060+/* bit 10: volt_switch to 1.8v for sdxc */
29061+#define VOLT_SWITCH_INT_STATUS (0x1 << 10)
29062+
29063+/* bit 9: data read timeout interrupt status */
29064+#define DRTO_INT_STATUS (0x1 << 9)
29065+
29066+/* bit 8: response timeout interrupt status */
29067+#define RTO_INT_STATUS (0x1 << 8)
29068+
29069+/* bit 7: data CRC error interrupt status */
29070+#define DCRC_INT_STATUS (0x1 << 7)
29071+
29072+/* bit 6: response CRC error interrupt status */
29073+#define RCRC_INT_STATUS    (0x1<<6)
29074+
29075+/* bit 5: receive FIFO data request interrupt status */
29076+#define RXDR_INT_STATUS    (0x1<<5)
29077+
29078+/* bit 4: transmit FIFO data request interrupt status */
29079+#define TXDR_INT_STATUS    (0x1<<4)
29080+
29081+/* bit 3: data transfer Over interrupt status */
29082+#define DTO_INT_STATUS    (0x1<<3)
29083+
29084+/* bit 2: command done interrupt status */
29085+#define CD_INT_STATUS    (0x1<<2)
29086+
29087+/* bit 1: response error interrupt status */
29088+#define RE_INT_STATUS    (0x1<<1)
29089+
29090+#define CMD_INT_MASK	(RTO_INT_STATUS | RCRC_INT_STATUS | RE_INT_STATUS)
29091+#define DATA_INT_MASK	(DTO_INT_STATUS | DCRC_INT_STATUS \
29092+		| SBE_INT_STATUS | EBE_INT_STATUS)
29093+
29094+
29095+/* MCI_RINTSTS(0x44) details:bit 16-1: clear
29096+   MMC host controller each interrupt but
29097+   hardware locked write error interrupt
29098+*/
29099+#define ALL_INT_CLR       0x1efff
29100+#define ALL_SD_INT_CLR    0xefff
29101+
29102+/* MCI_STATUS(0x48) details */
29103+#define DATA_BUSY		(0x1<<9)
29104+
29105+/* MCI_FIFOTH(0x4c) details */
29106+#define BURST_SIZE		(0x6<<28)
29107+#define RX_WMARK		(0x7f<<16)
29108+#define TX_WMARK          (0x80)
29109+
29110+/* MCI_CDETECT(0x50) details */
29111+#define HIMCI_CARD0		(0x1<<0)
29112+
29113+/* MCI_GPIO(0x58) details */
29114+#define DTO_FIX_BYPASS      (0x1<<23)
29115+#define CMD_OUT_EN_FIX_BYPASS   (0x1<<8)
29116+
29117+/* MCI_UHS_REG(0x74) details */
29118+#define HI_SDXC_CTRL_VDD_180	(0x1<<0)
29119+#define HI_SDXC_CTRL_DDR_REG	(0x1<<16)
29120+
29121+/* MCI_RESET_N(0x78) details */
29122+#define MMC_RST_N   (0x1<<0)
29123+
29124+/* MCI_CARDTHRCTL(0x100) details */
29125+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \
29126+    defined(CONFIG_ARCH_HI3556V200)  || defined(CONFIG_ARCH_HI3559V200)  || \
29127+    defined(CONFIG_ARCH_HI3562V100)  || defined(CONFIG_ARCH_HI3566V100)
29128+#define RW_THRESHOLD_SIZE	(0x2000005)
29129+#else
29130+#define RW_THRESHOLD_SIZE	(0x2000001)
29131+#endif
29132+
29133+/* MCI_TUNING_CTRL(0x118) details */
29134+#define HW_TUNING_EN	(0x1 << 0)
29135+#define EDGE_CTRL		(0x1 << 1)
29136+#define FOUND_EDGE		(0x1 << 5)
29137+
29138+#endif
29139diff --git a/drivers/mmc/host/mci_proc.c b/drivers/mmc/host/mci_proc.c
29140new file mode 100644
29141index 000000000..9465ad3fe
29142--- /dev/null
29143+++ b/drivers/mmc/host/mci_proc.c
29144@@ -0,0 +1,301 @@
29145+/*
29146+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2016-2020. All rights reserved.
29147+ * Description: mci driver
29148+ *
29149+ * This program is free software; you can redistribute it and/or modify
29150+ * it under the terms of the GNU General Public License as published by
29151+ * the Free Software Foundation; either version 2 of the License, or
29152+ * (at your option) any later version.
29153+ *
29154+ * This program is distributed in the hope that it will be useful,
29155+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29156+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29157+ * GNU General Public License for more details.
29158+ *
29159+ * You should have received a copy of the GNU General Public License
29160+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
29161+ */
29162+
29163+#include <linux/proc_fs.h>
29164+#include <linux/seq_file.h>
29165+#include <linux/device.h>
29166+#include <linux/io.h>
29167+#include <linux/platform_device.h>
29168+#include <linux/mmc/card.h>
29169+#include <linux/mmc/host.h>
29170+#include "../core/card.h"
29171+#include "sdhci.h"
29172+#include "mci_proc.h"
29173+
29174+#define MCI_PARENT       "mci"
29175+#define MCI_STATS_PROC   "mci_info"
29176+#define MAX_CLOCK_SCALE	 4
29177+
29178+unsigned int slot_index;
29179+struct mmc_host *mci_host[MCI_SLOT_NUM] = {NULL};
29180+static struct proc_dir_entry *proc_mci_dir;
29181+
29182+static char *card_type[MAX_CARD_TYPE + 1] = {
29183+	"MMC card",
29184+	"SD card",
29185+	"SDIO card",
29186+	"SD combo (IO+mem) card",
29187+	"unknown"
29188+};
29189+static char *clock_unit[MAX_CLOCK_SCALE] = {
29190+	"Hz",
29191+	"KHz",
29192+	"MHz",
29193+	"GHz"
29194+};
29195+
29196+#define BIT_WIDTH	32
29197+static unsigned int unstuff_bits(const u32 *resp, u32 start, u32 size)
29198+{
29199+	const u32 mask = ((size < BIT_WIDTH) ? 1 << size : 0) - 1;
29200+	const int off = 0x3 - ((start) / BIT_WIDTH);
29201+	const int shft = (start) & 31; /* max shift value 31 */
29202+	u32 res;
29203+
29204+	res = resp[off] >> shft;
29205+	if (size + shft > BIT_WIDTH)
29206+		res |= resp[off - 1] << ((BIT_WIDTH - shft) % BIT_WIDTH);
29207+	res = res & mask;
29208+
29209+	return res;
29210+}
29211+
29212+static char *mci_get_card_type(unsigned int sd_type)
29213+{
29214+	if (sd_type >= MAX_CARD_TYPE)
29215+		return card_type[MAX_CARD_TYPE];
29216+	else
29217+		return card_type[sd_type];
29218+}
29219+
29220+static unsigned int analyze_clock_scale(unsigned int clock,
29221+    unsigned int *clock_val)
29222+{
29223+	unsigned int scale = 0;
29224+	unsigned int tmp = clock;
29225+
29226+	while (1) {
29227+		tmp = tmp / 1000; /* Cal freq by dividing 1000 */
29228+		if (tmp > 0) {
29229+			*clock_val = tmp;
29230+			scale++;
29231+		} else {
29232+			break;
29233+		}
29234+	}
29235+	return scale;
29236+}
29237+
29238+static inline int is_card_uhs(unsigned char timing)
29239+{
29240+	return timing >= MMC_TIMING_UHS_SDR12 &&
29241+	       timing <= MMC_TIMING_UHS_DDR50;
29242+};
29243+
29244+static inline int is_card_hs(unsigned char timing)
29245+{
29246+	return timing == MMC_TIMING_SD_HS || timing == MMC_TIMING_MMC_HS;
29247+};
29248+
29249+static void mci_stats_seq_printout(struct seq_file *s)
29250+{
29251+	unsigned int index_mci;
29252+	unsigned int clock;
29253+	unsigned int clock_scale;
29254+	unsigned int clock_value = 0;
29255+	const char *type = NULL;
29256+	struct mmc_host *mmc = NULL;
29257+	const char *uhs_bus_speed_mode = "";
29258+	static const char * const uhs_speeds[] = {
29259+		[UHS_SDR12_BUS_SPEED] = "SDR12 ",
29260+		[UHS_SDR25_BUS_SPEED] = "SDR25 ",
29261+		[UHS_SDR50_BUS_SPEED] = "SDR50 ",
29262+		[UHS_SDR104_BUS_SPEED] = "SDR104 ",
29263+		[UHS_DDR50_BUS_SPEED] = "DDR50 ",
29264+	};
29265+	unsigned int speed_class, grade_speed_uhs;
29266+	unsigned int present;
29267+	struct card_info *info = NULL;
29268+	struct sdhci_host *host = NULL;
29269+
29270+	for (index_mci = 0; index_mci < MCI_SLOT_NUM; index_mci++) {
29271+		mmc = mci_host[index_mci];
29272+		if (mmc == NULL) {
29273+			seq_printf(s, "MCI%d: invalid\n", index_mci);
29274+			continue;
29275+		} else {
29276+			seq_printf(s, "MCI%d", index_mci);
29277+		}
29278+
29279+		host = mmc_priv(mmc);
29280+		info = &host->c_info;
29281+
29282+		present = host->mmc->ops->get_cd(host->mmc);
29283+		if (present)
29284+			seq_puts(s, ": pluged");
29285+		else
29286+			seq_puts(s, ": unplugged");
29287+
29288+		if (info->card_connect != CARD_CONNECT) {
29289+			if (mmc->card_status == MMC_CARD_INIT_FAIL)
29290+				seq_puts(s, "_init_failed\n");
29291+			else
29292+				seq_puts(s, "_disconnected\n");
29293+		} else {
29294+			seq_puts(s, "_connected\n");
29295+
29296+			seq_printf(s, "\tType: %s",
29297+				   mci_get_card_type(info->card_type));
29298+
29299+			if (info->card_state & MMC_STATE_BLOCKADDR) {
29300+				type = (info->card_state & MMC_CARD_SDXC) ?
29301+				       "SDXC" : "SDHC";
29302+				seq_printf(s, "(%s)\n", type);
29303+			}
29304+
29305+			if (is_card_uhs(info->timing) &&
29306+					info->sd_bus_speed < ARRAY_SIZE(uhs_speeds))
29307+				uhs_bus_speed_mode =
29308+					uhs_speeds[info->sd_bus_speed];
29309+
29310+			seq_printf(s, "\tMode: %s %s\n",
29311+				   is_card_uhs(info->timing) ? "UHS" :
29312+				   is_card_hs(info->timing) ? "HS" :
29313+				   (info->enhanced_strobe == true) ? "HS400ES" :
29314+				   (info->timing == MMC_TIMING_MMC_HS400) ? "HS400" :
29315+				   (info->timing == MMC_TIMING_MMC_HS200) ? "HS200" :
29316+				   (info->timing == MMC_TIMING_MMC_DDR52) ? "DDR" :
29317+				   "DS", uhs_bus_speed_mode);
29318+
29319+			speed_class = unstuff_bits(info->ssr, 56, 8); /* 56 = 440 - 384 */
29320+			grade_speed_uhs = unstuff_bits(info->ssr, 12, 4); /* 12 = 396 - 384 */
29321+			seq_printf(s, "\tSpeed Class: Class %s\n",
29322+				   (speed_class == 0x00) ? "0" :
29323+				   (speed_class == 0x01) ? "2" :
29324+				   (speed_class == 0x02) ? "4" :
29325+				   (speed_class == 0x03) ? "6" :
29326+				   (speed_class == 0x04) ? "10" :
29327+				   "Reserved");
29328+			seq_printf(s, "\tUhs Speed Grade: %s\n",
29329+				   (grade_speed_uhs == 0x00) ?
29330+				   "Less than 10MB/sec(0h)" :
29331+				   (grade_speed_uhs == 0x01) ?
29332+				   "10MB/sec and above(1h)" :
29333+				   "Reserved");
29334+
29335+			clock = info->card_support_clock;
29336+			clock_scale = analyze_clock_scale(clock, &clock_value);
29337+			seq_printf(s, "\tHost work clock: %d%s\n",
29338+				   clock_value, clock_unit[clock_scale]);
29339+
29340+			clock = info->card_support_clock;
29341+			clock_scale = analyze_clock_scale(clock, &clock_value);
29342+			seq_printf(s, "\tCard support clock: %d%s\n",
29343+				   clock_value, clock_unit[clock_scale]);
29344+
29345+			clock = mmc->actual_clock;
29346+			clock_scale = analyze_clock_scale(clock, &clock_value);
29347+			seq_printf(s, "\tCard work clock: %d%s\n",
29348+				   clock_value, clock_unit[clock_scale]);
29349+
29350+			/* add card read/write error count */
29351+			seq_printf(s, "\tCard error count: %d\n",
29352+				   host->error_count);
29353+		}
29354+	}
29355+}
29356+
29357+/* proc interface setup */
29358+static void *mci_seq_start(struct seq_file *s, loff_t *pos)
29359+{
29360+	/*  counter is used to tracking multi proc interfaces
29361+	 *  We have only one interface so return zero
29362+	 *  pointer to start the sequence.
29363+	 */
29364+	static unsigned long counter;
29365+
29366+	if (*pos == 0)
29367+		return &counter;
29368+
29369+	return NULL;
29370+}
29371+
29372+/* proc interface next */
29373+static void *mci_seq_next(struct seq_file *s, void *v, loff_t *pos)
29374+{
29375+	(*pos)++;
29376+
29377+	return mci_seq_start(s, pos);
29378+}
29379+
29380+/* define parameters where showed in proc file */
29381+static int mci_stats_seq_show(struct seq_file *s, void *v)
29382+{
29383+	mci_stats_seq_printout(s);
29384+	return 0;
29385+}
29386+
29387+/* proc interface stop */
29388+static void mci_seq_stop(struct seq_file *s, void *v)
29389+{
29390+}
29391+
29392+/* proc interface operation */
29393+static const struct seq_operations mci_stats_seq_ops = {
29394+	.start = mci_seq_start,
29395+	.next = mci_seq_next,
29396+	.stop = mci_seq_stop,
29397+	.show = mci_stats_seq_show
29398+};
29399+
29400+/* proc file open */
29401+static int mci_stats_proc_open(struct inode *inode, struct file *file)
29402+{
29403+	return seq_open(file, &mci_stats_seq_ops);
29404+};
29405+
29406+/* proc file operation */
29407+static const struct file_operations mci_stats_proc_ops = {
29408+	.owner = THIS_MODULE,
29409+	.open = mci_stats_proc_open,
29410+	.read = seq_read,
29411+	.release = seq_release
29412+};
29413+
29414+int mci_proc_init(void)
29415+{
29416+	struct proc_dir_entry *proc_stats_entry = NULL;
29417+
29418+	proc_mci_dir = proc_mkdir(MCI_PARENT, NULL);
29419+	if (proc_mci_dir == NULL) {
29420+		pr_err("%s: failed to create proc file %s\n",
29421+		       __func__, MCI_PARENT);
29422+		return 1;
29423+	}
29424+
29425+	proc_stats_entry = proc_create(MCI_STATS_PROC,
29426+				       0, proc_mci_dir, &mci_stats_proc_ops);
29427+	if (proc_stats_entry == NULL) {
29428+		pr_err("%s: failed to create proc file %s\n",
29429+		       __func__, MCI_STATS_PROC);
29430+		return 1;
29431+	}
29432+
29433+	return 0;
29434+}
29435+
29436+int mci_proc_shutdown(void)
29437+{
29438+	if (proc_mci_dir != NULL) {
29439+		remove_proc_entry(MCI_STATS_PROC, proc_mci_dir);
29440+		remove_proc_entry(MCI_PARENT, NULL);
29441+		proc_mci_dir = NULL;
29442+	}
29443+
29444+	return 0;
29445+}
29446diff --git a/drivers/mmc/host/mci_proc.h b/drivers/mmc/host/mci_proc.h
29447new file mode 100644
29448index 000000000..459c5d767
29449--- /dev/null
29450+++ b/drivers/mmc/host/mci_proc.h
29451@@ -0,0 +1,50 @@
29452+/*
29453+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2016-2020. All rights reserved.
29454+ * Description: mci header
29455+ *
29456+ * This program is free software; you can redistribute it and/or modify
29457+ * it under the terms of the GNU General Public License as published by
29458+ * the Free Software Foundation; either version 2 of the License, or
29459+ * (at your option) any later version.
29460+ *
29461+ * This program is distributed in the hope that it will be useful,
29462+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29463+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29464+ * GNU General Public License for more details.
29465+ *
29466+ * You should have received a copy of the GNU General Public License
29467+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
29468+ */
29469+
29470+/*
29471+ *  MCI connection table manager
29472+ */
29473+#ifndef __MCI_PROC_H__
29474+#define __MCI_PROC_H__
29475+
29476+#include <linux/proc_fs.h>
29477+
29478+#define MAX_CARD_TYPE	4
29479+#define MAX_SPEED_MODE	5
29480+
29481+#if defined(CONFIG_ARCH_HI3531DV200) || defined(CONFIG_ARCH_HI3535AV100) ||\
29482+	defined(CONFIG_ARCH_HI3521DV200) || defined(CONFIG_ARCH_HI3520DV500)
29483+#define MCI_SLOT_NUM 1
29484+#elif defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100)
29485+#define MCI_SLOT_NUM 4
29486+#elif defined(CONFIG_ARCH_HI3556AV100) || defined(CONFIG_ARCH_HI3519AV100) ||\
29487+    defined(CONFIG_ARCH_HI3516EV200) || defined(CONFIG_ARCH_HI3516EV300) ||\
29488+	defined(CONFIG_ARCH_HI3518EV300) || defined(CONFIG_ARCH_HI3516DV200) ||\
29489+	defined(CONFIG_ARCH_HI3568V100)
29490+#define MCI_SLOT_NUM 3
29491+#else
29492+#error MCI_SLOT_NUM should not be zero!
29493+#endif
29494+
29495+extern unsigned int slot_index;
29496+extern struct mmc_host *mci_host[MCI_SLOT_NUM];
29497+
29498+int mci_proc_init(void);
29499+int mci_proc_shutdown(void);
29500+
29501+#endif /*  __MCI_PROC_H__ */
29502diff --git a/drivers/mmc/host/sdhci-hisi.c b/drivers/mmc/host/sdhci-hisi.c
29503new file mode 100644
29504index 000000000..be2a903ac
29505--- /dev/null
29506+++ b/drivers/mmc/host/sdhci-hisi.c
29507@@ -0,0 +1,783 @@
29508+/*
29509+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2017-2020. All rights reserved.
29510+ * Description: hisi sdhci driver
29511+ *
29512+ * This program is free software; you can redistribute it and/or modify
29513+ * it under the terms of the GNU General Public License as published by
29514+ * the Free Software Foundation; either version 2 of the License, or
29515+ * (at your option) any later version.
29516+ *
29517+ * This program is distributed in the hope that it will be useful,
29518+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
29519+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
29520+ * GNU General Public License for more details.
29521+ *
29522+ * You should have received a copy of the GNU General Public License
29523+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
29524+ */
29525+
29526+#include "sdhci-hisi.h"
29527+#include "cqhci.h"
29528+#include "mci_proc.h"
29529+
29530+int sdhci_hisi_parse_dt(struct sdhci_host *host)
29531+{
29532+	struct sdhci_hisi_priv *priv = sdhci_get_pltfm_priv(host);
29533+	struct device_node *np = host->mmc->parent->of_node;
29534+	u32 bus_width;
29535+	int ret;
29536+
29537+	ret = mmc_of_parse(host->mmc);
29538+	if (ret)
29539+		return ret;
29540+
29541+#ifdef CONFIG_MMC_CQHCI
29542+	if (of_get_property(np, "mmc-cmd-queue", NULL))
29543+		host->mmc->caps2 |= MMC_CAP2_CQE | MMC_CAP2_CQE_DCMD;
29544+#endif
29545+	if (of_get_property(np, "mmc-broken-cmd23", NULL))
29546+		host->quirks2 |= SDHCI_QUIRK2_HOST_NO_CMD23;
29547+
29548+	if (of_property_read_u32(np, "bus-width", &bus_width) == 0) {
29549+		priv->bus_width = bus_width;
29550+	} else {
29551+		pr_err("%s: \"bus-width\" property is missing, assuming 1 bit.\n",
29552+		       mmc_hostname(host->mmc));
29553+		priv->bus_width = 1;
29554+	}
29555+
29556+	if (of_get_property(np, "sdhci,1-bit-only", NULL) ||
29557+			(priv->bus_width == 1)) {
29558+		priv->bus_width = 1;
29559+		host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;
29560+	}
29561+
29562+	return 0;
29563+}
29564+
29565+void hisi_enable_sample(struct sdhci_host *host)
29566+{
29567+	unsigned int reg;
29568+
29569+	reg = sdhci_readl(host, SDHCI_AT_CTRL);
29570+	reg |= SDHCI_SAMPLE_EN;
29571+	sdhci_writel(host, reg, SDHCI_AT_CTRL);
29572+}
29573+
29574+void hisi_set_sample_phase(struct sdhci_host *host, u32 phase)
29575+{
29576+	unsigned int reg;
29577+
29578+	reg = sdhci_readl(host, SDHCI_AT_STAT);
29579+	reg &= ~SDHCI_PHASE_SEL_MASK;
29580+	reg |= phase;
29581+	sdhci_writel(host, reg, SDHCI_AT_STAT);
29582+}
29583+
29584+void hisi_disable_card_clk(struct sdhci_host *host)
29585+{
29586+	u16 clk;
29587+
29588+	clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
29589+	clk &= ~SDHCI_CLOCK_CARD_EN;
29590+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
29591+}
29592+
29593+void hisi_enable_card_clk(struct sdhci_host *host)
29594+{
29595+	u16 clk;
29596+
29597+	clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
29598+	clk |= SDHCI_CLOCK_CARD_EN;
29599+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
29600+}
29601+
29602+void hisi_disable_internal_clk(struct sdhci_host *host)
29603+{
29604+	u16 clk;
29605+
29606+	clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
29607+	clk &= ~SDHCI_CLOCK_INT_EN;
29608+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
29609+}
29610+
29611+void hisi_enable_internal_clk(struct sdhci_host *host)
29612+{
29613+	unsigned int timeout = 20;
29614+	u16 clk;
29615+
29616+	clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
29617+	clk |= SDHCI_CLOCK_INT_EN | SDHCI_CLOCK_PLL_EN;
29618+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
29619+
29620+	clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
29621+	while (!(clk & SDHCI_CLOCK_INT_STABLE)) {
29622+		if (timeout == 0) {
29623+			pr_err("%s: Internal clock never stabilised.\n",
29624+			       __func__);
29625+			return;
29626+		}
29627+		timeout--;
29628+		udelay(1000); /* delay 1000us */
29629+		clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
29630+	}
29631+}
29632+
29633+static void hisi_select_sample_phase(struct sdhci_host *host,
29634+    unsigned int phase)
29635+{
29636+	hisi_disable_card_clk(host);
29637+	hisi_set_sample_phase(host, phase);
29638+	hisi_wait_sample_dll_ready(host);
29639+	hisi_enable_card_clk(host);
29640+	udelay(1);
29641+}
29642+
29643+static int hisi_send_tuning(struct sdhci_host *host, u32 opcode)
29644+{
29645+	int count, err;
29646+
29647+	count = 0;
29648+	do {
29649+		err = mmc_send_tuning(host->mmc, opcode, NULL);
29650+		if (err) {
29651+			mmc_abort_tuning(host->mmc, opcode);
29652+			break;
29653+		}
29654+		count++;
29655+	} while (count < MAX_TUNING_NUM);
29656+
29657+	return err;
29658+}
29659+
29660+static void hisi_pre_tuning(struct sdhci_host *host)
29661+{
29662+	sdhci_writel(host, host->ier | SDHCI_INT_DATA_AVAIL, SDHCI_INT_ENABLE);
29663+	sdhci_writel(host, host->ier | SDHCI_INT_DATA_AVAIL, SDHCI_SIGNAL_ENABLE);
29664+
29665+	hisi_enable_sample(host);
29666+	host->is_tuning = 1;
29667+}
29668+
29669+static void hisi_post_tuning(struct sdhci_host *host)
29670+{
29671+	unsigned short ctrl;
29672+
29673+	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
29674+	ctrl |= SDHCI_CTRL_TUNED_CLK;
29675+	sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
29676+
29677+	sdhci_writel(host, host->ier, SDHCI_INT_ENABLE);
29678+	sdhci_writel(host, host->ier, SDHCI_SIGNAL_ENABLE);
29679+	host->is_tuning = 0;
29680+}
29681+
29682+#ifndef SDHCI_HISI_EDGE_TUNING
29683+static int hisi_get_best_sample(u32 candidates)
29684+{
29685+	int rise = NOT_FOUND;
29686+	int fall, i, win;
29687+	int win_max_r = NOT_FOUND;
29688+	int win_max_f = NOT_FOUND;
29689+	int end_fall = NOT_FOUND;
29690+	int found = NOT_FOUND;
29691+	int win_max = 0;
29692+
29693+	for (i = 0; i < PHASE_SCALE; i++) {
29694+		if ((candidates & 0x3) == 0x2)
29695+			rise = (i + 1) % PHASE_SCALE;
29696+
29697+		if ((candidates & 0x3) == 0x1) {
29698+			fall = i;
29699+			if (rise != NOT_FOUND) {
29700+				win = fall - rise + 1;
29701+				if (win > win_max) {
29702+					win_max = win;
29703+					found = (fall + rise) / 2; /* Get window center by devide 2 */
29704+					win_max_r = rise;
29705+					win_max_f = fall;
29706+					rise = NOT_FOUND;
29707+					fall = NOT_FOUND;
29708+				}
29709+			} else {
29710+				end_fall = fall;
29711+			}
29712+		}
29713+		candidates = ror32(candidates, 1);
29714+	}
29715+
29716+	if (end_fall != NOT_FOUND && rise != NOT_FOUND) {
29717+		fall = end_fall;
29718+		if (end_fall < rise)
29719+			end_fall += PHASE_SCALE;
29720+
29721+		win = end_fall - rise + 1;
29722+		if (win > win_max) {
29723+			found = (rise + (win / 2)) % PHASE_SCALE; /* Get window center by devide 2 */
29724+			win_max_r = rise;
29725+			win_max_f = fall;
29726+		}
29727+	}
29728+
29729+	if (found != NOT_FOUND)
29730+		pr_err("valid phase shift [%d, %d] Final Phase:%d\n",
29731+		       win_max_r, win_max_f, found);
29732+
29733+	return found;
29734+}
29735+
29736+static int sdhci_hisi_exec_tuning(struct sdhci_host *host, u32 opcode)
29737+{
29738+	struct sdhci_hisi_priv *priv = sdhci_get_pltfm_priv(host);
29739+	unsigned int sample;
29740+	unsigned int candidates = 0;
29741+	int phase, err;
29742+
29743+	hisi_pre_tuning(host);
29744+
29745+	for (sample = 0; sample < PHASE_SCALE; sample++) {
29746+		hisi_select_sample_phase(host, sample);
29747+
29748+		err = hisi_send_tuning(host, opcode);
29749+		if (err)
29750+			pr_debug("send tuning CMD%u fail! phase:%d err:%d\n",
29751+				 opcode, sample, err);
29752+		else
29753+			candidates |= (0x1 << sample);
29754+	}
29755+
29756+	pr_info("%s: tuning done! candidates 0x%X: ",
29757+		mmc_hostname(host->mmc), candidates);
29758+
29759+	phase = hisi_get_best_sample(candidates);
29760+	if (phase == NOT_FOUND) {
29761+		phase = priv->sample_phase;
29762+		pr_err("no valid phase shift! use default %d\n", phase);
29763+	}
29764+
29765+	priv->tuning_phase = phase;
29766+	hisi_select_sample_phase(host, phase);
29767+	hisi_post_tuning(host);
29768+
29769+	return 0;
29770+}
29771+#else
29772+static void hisi_enable_edge_tuning(struct sdhci_host *host)
29773+{
29774+	unsigned int reg;
29775+
29776+	reg = sdhci_readl(host, SDHCI_MULTI_CYCLE);
29777+	reg |= SDHCI_EDGE_DETECT_EN;
29778+	sdhci_writel(host, reg, SDHCI_MULTI_CYCLE);
29779+}
29780+
29781+static void hisi_disable_edge_tuning(struct sdhci_host *host)
29782+{
29783+	unsigned int reg;
29784+
29785+	reg = sdhci_readl(host, SDHCI_MULTI_CYCLE);
29786+	reg &= ~SDHCI_EDGE_DETECT_EN;
29787+	sdhci_writel(host, reg, SDHCI_MULTI_CYCLE);
29788+}
29789+
29790+static int sdhci_hisi_exec_edge_tuning(struct sdhci_host *host, u32 opcode)
29791+{
29792+	struct sdhci_hisi_priv *priv = sdhci_get_pltfm_priv(host);
29793+	unsigned int index, val;
29794+	unsigned int found;
29795+	unsigned int prev_found = 0;
29796+	unsigned int edge_p2f, edge_f2p, start, end;
29797+	unsigned int phase, fall, rise;
29798+	unsigned int fall_updat_flag = 0;
29799+	int err;
29800+	int prev_err = 0;
29801+
29802+	hisi_pre_tuning(host);
29803+	hisi_enable_edge_tuning(host);
29804+
29805+	start = 0;
29806+	end = PHASE_SCALE / EDGE_TUNING_PHASE_STEP;
29807+
29808+	edge_p2f = start;
29809+	edge_f2p = end;
29810+	for (index = 0; index <= end; index++) {
29811+		hisi_select_sample_phase(host, index * EDGE_TUNING_PHASE_STEP);
29812+		err = hisi_send_tuning(host, opcode);
29813+		if (!err) {
29814+			val = sdhci_readl(host, SDHCI_MULTI_CYCLE);
29815+			found = val & SDHCI_FOUND_EDGE;
29816+		} else {
29817+			found = 1;
29818+		}
29819+
29820+		if (prev_found && !found)
29821+			edge_f2p = index;
29822+		else if (!prev_found && found)
29823+			edge_p2f = index;
29824+
29825+		if ((edge_p2f != start) && (edge_f2p != end))
29826+			break;
29827+
29828+		prev_found = found;
29829+	}
29830+
29831+	if ((edge_p2f == start) && (edge_f2p == end)) {
29832+		pr_err("%s: tuning failed! can not found edge!\n",
29833+		       mmc_hostname(host->mmc));
29834+		return -1;
29835+	}
29836+
29837+	hisi_disable_edge_tuning(host);
29838+
29839+	start = edge_p2f * EDGE_TUNING_PHASE_STEP;
29840+	end = edge_f2p * EDGE_TUNING_PHASE_STEP;
29841+	if (end <= start)
29842+		end += PHASE_SCALE;
29843+
29844+	fall = start;
29845+	rise = end;
29846+	for (index = start; index <= end; index++) {
29847+		hisi_select_sample_phase(host, index % PHASE_SCALE);
29848+		err = hisi_send_tuning(host, opcode);
29849+		if (err)
29850+			pr_debug("send tuning CMD%u fail! phase:%d err:%d\n",
29851+				 opcode, index, err);
29852+
29853+		if (err && index == start) {
29854+			if (!fall_updat_flag) {
29855+				fall_updat_flag = 1;
29856+				fall = start;
29857+			}
29858+		} else if (!prev_err && err) {
29859+			if (!fall_updat_flag) {
29860+				fall_updat_flag = 1;
29861+				fall = index;
29862+			}
29863+		}
29864+
29865+		if (prev_err && !err)
29866+			rise = index;
29867+
29868+		if (err && index == end)
29869+			rise = end;
29870+
29871+		prev_err = err;
29872+	}
29873+
29874+	phase = ((fall + rise) / 2 + PHASE_SCALE / 2) % /* 2 for cal average */
29875+		PHASE_SCALE;
29876+
29877+	pr_info("%s: tuning done! valid phase shift [%d, %d] Final Phase:%d\n",
29878+		mmc_hostname(host->mmc), rise % PHASE_SCALE,
29879+		fall % PHASE_SCALE, phase);
29880+
29881+	priv->tuning_phase = phase;
29882+	hisi_select_sample_phase(host, phase);
29883+	hisi_post_tuning(host);
29884+
29885+	return 0;
29886+}
29887+#endif
29888+
29889+static int sdhci_hisi_execute_tuning(struct sdhci_host *host, u32 opcode)
29890+{
29891+#ifdef SDHCI_HISI_EDGE_TUNING
29892+	return sdhci_hisi_exec_edge_tuning(host, opcode);
29893+#else
29894+	return sdhci_hisi_exec_tuning(host, opcode);
29895+#endif
29896+}
29897+
29898+static void hisi_set_emmc_card(struct sdhci_host *host)
29899+{
29900+	unsigned int reg;
29901+
29902+	if (host->timing == MMC_TIMING_MMC_HS ||
29903+			host->timing == MMC_TIMING_MMC_DDR52 ||
29904+			host->timing == MMC_TIMING_MMC_HS200 ||
29905+			host->timing == MMC_TIMING_MMC_HS400) {
29906+		reg = sdhci_readl(host, SDHCI_EMMC_CTRL);
29907+		reg |= SDHCI_CARD_IS_EMMC;
29908+		sdhci_writel(host, reg, SDHCI_EMMC_CTRL);
29909+	}
29910+}
29911+
29912+static void sdhci_hisi_set_uhs_signaling(struct sdhci_host *host,
29913+    unsigned int timing)
29914+{
29915+	sdhci_set_uhs_signaling(host, timing);
29916+	host->timing = timing;
29917+	hisi_set_emmc_card(host);
29918+	hisi_set_drv_cap(host);
29919+}
29920+
29921+static void sdhci_hisi_hw_reset(struct sdhci_host *host)
29922+{
29923+	sdhci_writel(host, 0x0, SDHCI_EMMC_HW_RESET);
29924+	udelay(10);  /* delay 10us */
29925+	sdhci_writel(host, 0x1, SDHCI_EMMC_HW_RESET);
29926+	udelay(200); /* delay 200us */
29927+}
29928+
29929+/*
29930+ * This api is for wifi driver rescan the sdio device
29931+ */
29932+int hisi_sdio_rescan(int slot)
29933+{
29934+	struct mmc_host *mmc = NULL;
29935+
29936+	if ((slot >= MCI_SLOT_NUM) || (slot <= 0)) {
29937+		pr_err("invalid mmc slot, please check the argument\n");
29938+		return -EINVAL;
29939+	}
29940+
29941+	mmc = mci_host[slot];
29942+	if (mmc == NULL) {
29943+		pr_err("invalid mmc, please check the argument\n");
29944+		return -EINVAL;
29945+	}
29946+
29947+	mmc_detect_change(mmc, 0);
29948+	return 0;
29949+}
29950+EXPORT_SYMBOL_GPL(hisi_sdio_rescan);
29951+
29952+static const struct of_device_id sdhci_hisi_match[] = {
29953+	{ .compatible = "hisilicon,sdhci" },
29954+	{},
29955+};
29956+
29957+MODULE_DEVICE_TABLE(of, sdhci_hisi_match);
29958+
29959+static struct sdhci_ops sdhci_hisi_ops = {
29960+	.platform_execute_tuning = sdhci_hisi_execute_tuning,
29961+	.reset = sdhci_reset,
29962+	.set_clock = sdhci_hisi_set_clock,
29963+	.set_bus_width = sdhci_set_bus_width,
29964+	.set_uhs_signaling = sdhci_hisi_set_uhs_signaling,
29965+	.hw_reset = sdhci_hisi_hw_reset,
29966+#if defined(CONFIG_ARCH_HI3556AV100) || defined(CONFIG_ARCH_HI3559AV100) || \
29967+	defined(CONFIG_ARCH_HI3519AV100) || defined(CONFIG_ARCH_HI3569V100) || \
29968+	defined(CONFIG_ARCH_HI3568V100)
29969+	.start_signal_voltage_switch = sdhci_hisi_start_signal_voltage_switch,
29970+#endif
29971+	.init = sdhci_hisi_extra_init,
29972+};
29973+
29974+static const struct sdhci_pltfm_data sdhci_hisi_pdata = {
29975+	.ops = &sdhci_hisi_ops,
29976+	.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
29977+	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
29978+};
29979+
29980+#ifdef CONFIG_MMC_CQHCI
29981+static u32 sdhci_hisi_cqhci_irq(struct sdhci_host *host, u32 intmask)
29982+{
29983+	int cmd_error = 0;
29984+	int data_error = 0;
29985+
29986+	if (!sdhci_cqe_irq(host, intmask, &cmd_error, &data_error))
29987+		return intmask;
29988+
29989+	cqhci_irq(host->mmc, intmask, cmd_error, data_error);
29990+
29991+	return 0;
29992+}
29993+
29994+static void sdhci_hisi_controller_v4_enable(struct sdhci_host *host, int enable)
29995+{
29996+	u16 ctrl;
29997+
29998+	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
29999+	if (enable)
30000+		ctrl |= SDHCI_CTRL_HOST_VER4_ENABLE;
30001+	else
30002+		ctrl &= ~SDHCI_CTRL_HOST_VER4_ENABLE;
30003+
30004+	if (host->flags & SDHCI_USE_64_BIT_DMA)
30005+		ctrl |= SDHCI_CTRL_64BIT_ADDR;
30006+
30007+	sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
30008+}
30009+
30010+static void sdhci_hisi_cqe_enable(struct mmc_host *mmc)
30011+{
30012+	struct sdhci_host *host = mmc_priv(mmc);
30013+	unsigned int timeout = 10000;
30014+	u16 reg, clk;
30015+	u8 ctrl;
30016+
30017+	/* SW_RST_DAT */
30018+	sdhci_reset(host, SDHCI_RESET_DATA);
30019+
30020+	sdhci_hisi_controller_v4_enable(host, 1);
30021+
30022+	/* Set the DMA boundary value and block size */
30023+	sdhci_writew(host, SDHCI_MAKE_BLKSZ(host->sdma_boundary,
30024+					    MMC_BLOCK_SIZE), SDHCI_BLOCK_SIZE);
30025+
30026+	/* need to set multitransfer for cmdq */
30027+	reg = sdhci_readw(host, SDHCI_TRANSFER_MODE);
30028+	reg |= SDHCI_TRNS_MULTI;
30029+	reg |= SDHCI_TRNS_BLK_CNT_EN;
30030+	sdhci_writew(host, reg, SDHCI_TRANSFER_MODE);
30031+
30032+	/* ADMA2 only */
30033+	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
30034+	ctrl &= ~SDHCI_CTRL_DMA_MASK;
30035+	ctrl |= SDHCI_CTRL_ADMA32;
30036+	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
30037+
30038+	clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
30039+	clk |= SDHCI_CLOCK_PLL_EN;
30040+	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
30041+
30042+	while (mmc->ops->card_busy(mmc)) {
30043+		timeout--;
30044+		if (!timeout) {
30045+			pr_err("%s: wait busy timeout\n", __func__);
30046+			break;
30047+		}
30048+		udelay(1);
30049+	}
30050+
30051+	sdhci_cqe_enable(mmc);
30052+}
30053+
30054+static void sdhci_hisi_cqe_disable(struct mmc_host *mmc, bool recovery)
30055+{
30056+	int timeout = 10000;
30057+
30058+	while (mmc->ops->card_busy(mmc)) {
30059+		timeout--;
30060+		if (!timeout) {
30061+			pr_err("%s: wait busy timeout\n", __func__);
30062+			break;
30063+		}
30064+		udelay(1);
30065+	}
30066+
30067+	sdhci_hisi_controller_v4_enable(mmc_priv(mmc), 0);
30068+
30069+	sdhci_cqe_disable(mmc, recovery);
30070+}
30071+
30072+static void sdhci_hisi_dumpregs(struct mmc_host *mmc)
30073+{
30074+	sdhci_dumpregs(mmc_priv(mmc));
30075+}
30076+
30077+static const struct cqhci_host_ops sdhci_hisi_cqhci_ops = {
30078+	.enable = sdhci_hisi_cqe_enable,
30079+	.disable = sdhci_hisi_cqe_disable,
30080+	.dumpregs = sdhci_hisi_dumpregs,
30081+};
30082+
30083+static const struct sdhci_ops sdhci_hisi_cqe_ops = {
30084+	.platform_execute_tuning = sdhci_hisi_execute_tuning,
30085+	.reset = sdhci_reset,
30086+	.set_clock = sdhci_hisi_set_clock,
30087+	.set_bus_width = sdhci_set_bus_width,
30088+	.set_uhs_signaling = sdhci_hisi_set_uhs_signaling,
30089+	.hw_reset = sdhci_hisi_hw_reset,
30090+	.irq = sdhci_hisi_cqhci_irq,
30091+	.init = sdhci_hisi_extra_init,
30092+};
30093+
30094+static const struct sdhci_pltfm_data sdhci_hisi_cqe_pdata = {
30095+	.ops = &sdhci_hisi_cqe_ops,
30096+	.quirks = SDHCI_QUIRK_BROKEN_TIMEOUT_VAL,
30097+	.quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN,
30098+};
30099+
30100+static int sdhci_hisi_add_host(struct sdhci_host *host)
30101+{
30102+	struct cqhci_host *cq_host = NULL;
30103+	bool dma64 = false;
30104+	int ret;
30105+
30106+	if (!(host->mmc->caps2 & MMC_CAP2_CQE))
30107+		return sdhci_add_host(host);
30108+
30109+	ret = sdhci_setup_host(host);
30110+	if (ret)
30111+		return ret;
30112+
30113+	cq_host = devm_kzalloc(host->mmc->parent, sizeof(*cq_host), GFP_KERNEL);
30114+	if (cq_host == NULL) {
30115+		pr_err("%s: allocate memory for CQE fail\n", __func__);
30116+		ret = -ENOMEM;
30117+		goto cleanup;
30118+	}
30119+
30120+	cq_host->mmio = host->ioaddr + 0x180;
30121+	cq_host->ops = &sdhci_hisi_cqhci_ops;
30122+
30123+	/*
30124+	 * synopsys controller has dma 128M algin limit,
30125+	 * may split the trans descriptors
30126+	 */
30127+	cq_host->quirks |= CQHCI_QUIRK_TXFR_DESC_SZ_SPLIT;
30128+
30129+	dma64 = host->flags & SDHCI_USE_64_BIT_DMA;
30130+	if (dma64)
30131+		cq_host->caps |= CQHCI_TASK_DESC_SZ_128;
30132+
30133+	ret = cqhci_init(cq_host, host->mmc, dma64);
30134+	if (ret) {
30135+		pr_err("%s: CQE init fail\n", __func__);
30136+		return ret;
30137+	}
30138+
30139+	ret = __sdhci_add_host(host);
30140+	if (ret)
30141+		return ret;
30142+
30143+	return 0;
30144+
30145+cleanup:
30146+	sdhci_cleanup_host(host);
30147+	return ret;
30148+}
30149+#else
30150+static int sdhci_hisi_add_host(struct sdhci_host *host)
30151+{
30152+	return sdhci_add_host(host);
30153+}
30154+#endif
30155+
30156+static int sdhci_hisi_probe(struct platform_device *pdev)
30157+{
30158+	struct sdhci_host *host = NULL;
30159+	const struct sdhci_pltfm_data *pdata = NULL;
30160+	int ret;
30161+
30162+#ifdef CONFIG_MMC_CQHCI
30163+	if (of_get_property(pdev->dev.of_node, "mmc-cmd-queue", NULL))
30164+		pdata = &sdhci_hisi_cqe_pdata;
30165+	else
30166+		pdata = &sdhci_hisi_pdata;
30167+#else
30168+	pdata = &sdhci_hisi_pdata;
30169+#endif
30170+	host = sdhci_pltfm_init(pdev, pdata, sizeof(struct sdhci_hisi_priv));
30171+	if (IS_ERR(host))
30172+		return PTR_ERR(host);
30173+
30174+	ret = sdhci_hisi_pltfm_init(pdev, host);
30175+	if (ret)
30176+		goto pltfm_free;
30177+
30178+	if (hisi_support_runtime_pm(host)) {
30179+		pm_runtime_get_noresume(&pdev->dev);
30180+		pm_runtime_set_autosuspend_delay(&pdev->dev, HISI_MMC_AUTOSUSPEND_DELAY_MS);
30181+		pm_runtime_use_autosuspend(&pdev->dev);
30182+		pm_runtime_set_active(&pdev->dev);
30183+		pm_runtime_enable(&pdev->dev);
30184+	}
30185+
30186+	ret = sdhci_hisi_add_host(host);
30187+	if (ret)
30188+		goto pm_runtime_disable;
30189+
30190+	if (hisi_support_runtime_pm(host)) {
30191+		pm_runtime_mark_last_busy(&pdev->dev);
30192+		pm_runtime_put_autosuspend(&pdev->dev);
30193+	}
30194+
30195+	return 0;
30196+
30197+pm_runtime_disable:
30198+	if (hisi_support_runtime_pm(host)) {
30199+		pm_runtime_disable(&pdev->dev);
30200+		pm_runtime_set_suspended(&pdev->dev);
30201+		pm_runtime_put_noidle(&pdev->dev);
30202+	}
30203+
30204+pltfm_free:
30205+	sdhci_pltfm_free(pdev);
30206+	return ret;
30207+}
30208+
30209+static int sdhci_hisi_remove(struct platform_device *pdev)
30210+{
30211+	struct sdhci_host *host = platform_get_drvdata(pdev);
30212+	int dead = (readl_relaxed(host->ioaddr + SDHCI_INT_STATUS) ==
30213+		    0xffffffff);
30214+
30215+	if (hisi_support_runtime_pm(host)) {
30216+		pm_runtime_get_sync(&pdev->dev);
30217+		pm_runtime_disable(&pdev->dev);
30218+		pm_runtime_put_noidle(&pdev->dev);
30219+	}
30220+
30221+	sdhci_remove_host(host, dead);
30222+	sdhci_pltfm_free(pdev);
30223+
30224+	return 0;
30225+}
30226+
30227+#ifdef CONFIG_PM
30228+static int sdhci_hisi_runtime_suspend(struct device *dev)
30229+{
30230+	struct sdhci_host *host = dev_get_drvdata(dev);
30231+
30232+	hisi_disable_card_clk(host);
30233+	return 0;
30234+}
30235+
30236+static int sdhci_hisi_runtime_resume(struct device *dev)
30237+{
30238+	struct sdhci_host *host = dev_get_drvdata(dev);
30239+
30240+	hisi_enable_card_clk(host);
30241+	return 0;
30242+}
30243+#endif
30244+
30245+static const struct dev_pm_ops sdhci_hisi_pm_ops = {
30246+	SET_SYSTEM_SLEEP_PM_OPS(sdhci_pltfm_suspend,
30247+				sdhci_pltfm_resume)
30248+
30249+	SET_RUNTIME_PM_OPS(sdhci_hisi_runtime_suspend,
30250+			   sdhci_hisi_runtime_resume,
30251+			   NULL)
30252+};
30253+
30254+static struct platform_driver sdhci_hisi_driver = {
30255+	.probe = sdhci_hisi_probe,
30256+	.remove = sdhci_hisi_remove,
30257+	.driver = {
30258+		.name = "sdhci_hisi",
30259+		.of_match_table = sdhci_hisi_match,
30260+		.pm = &sdhci_hisi_pm_ops,
30261+	},
30262+};
30263+
30264+static int __init sdhci_hisi_init(void)
30265+{
30266+	int ret;
30267+
30268+	ret = platform_driver_register(&sdhci_hisi_driver);
30269+	if (ret)
30270+		return ret;
30271+
30272+	ret = mci_proc_init();
30273+	if (ret)
30274+		platform_driver_unregister(&sdhci_hisi_driver);
30275+
30276+	return ret;
30277+}
30278+
30279+static void __exit sdhci_hisi_exit(void)
30280+{
30281+	mci_proc_shutdown();
30282+
30283+	platform_driver_unregister(&sdhci_hisi_driver);
30284+}
30285+
30286+module_init(sdhci_hisi_init);
30287+module_exit(sdhci_hisi_exit);
30288+MODULE_DESCRIPTION("SDHCI driver for Hisilicon");
30289+MODULE_AUTHOR("HiSilicon Technologies Co., Ltd..");
30290+MODULE_LICENSE("GPL v2");
30291diff --git a/drivers/mmc/host/sdhci-hisi.h b/drivers/mmc/host/sdhci-hisi.h
30292new file mode 100644
30293index 000000000..19cea6dc5
30294--- /dev/null
30295+++ b/drivers/mmc/host/sdhci-hisi.h
30296@@ -0,0 +1,126 @@
30297+/*
30298+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2017-2020. All rights reserved.
30299+ * Description: hisi sdhci header
30300+ *
30301+ * This program is free software; you can redistribute it and/or modify
30302+ * it under the terms of the GNU General Public License as published by
30303+ * the Free Software Foundation; either version 2 of the License, or
30304+ * (at your option) any later version.
30305+ *
30306+ * This program is distributed in the hope that it will be useful,
30307+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
30308+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30309+ * GNU General Public License for more details.
30310+ *
30311+ * You should have received a copy of the GNU General Public License
30312+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
30313+ */
30314+
30315+#ifndef _DRIVERS_MMC_SDHCI_HISI_H
30316+#define _DRIVERS_MMC_SDHCI_HISI_H
30317+
30318+#include <linux/delay.h>
30319+#include <linux/device.h>
30320+#include <linux/of.h>
30321+#include <linux/module.h>
30322+#include <linux/regmap.h>
30323+#include <linux/mfd/syscon.h>
30324+#include <linux/reset.h>
30325+#include <linux/mmc/host.h>
30326+#include <linux/pm_runtime.h>
30327+#include "sdhci-pltfm.h"
30328+
30329+#define SDHCI_HISI_EDGE_TUNING /* enable edge tuning */
30330+
30331+#define PHASE_SCALE	32
30332+#define NOT_FOUND	(-1)
30333+#define MAX_TUNING_NUM	1
30334+#define MAX_FREQ	200000000
30335+#define EDGE_TUNING_PHASE_STEP	4
30336+#define MMC_BLOCK_SIZE	512
30337+
30338+/* Software auto suspend delay */
30339+#define HISI_MMC_AUTOSUSPEND_DELAY_MS 50
30340+
30341+static inline void *sdhci_get_pltfm_priv(struct sdhci_host *host)
30342+{
30343+	return sdhci_pltfm_priv(sdhci_priv(host));
30344+}
30345+
30346+struct sdhci_hisi_priv {
30347+	struct reset_control *crg_rst;
30348+	struct reset_control *dll_rst;
30349+	struct reset_control *sampl_rst;
30350+	struct regmap *crg_regmap;
30351+	struct regmap *misc_regmap;
30352+	struct regmap *iocfg_regmap;
30353+	void __iomem *phy_addr;
30354+	unsigned int devid;
30355+	unsigned int drv_phase;
30356+	unsigned int sample_phase;
30357+	unsigned int tuning_phase;
30358+	unsigned int bus_width;
30359+};
30360+
30361+/* Hisilicon extended host controller registers. */
30362+#define  SDHCI_CTRL_HOST_VER4_ENABLE	0x1000
30363+#define  SDHCI_CLOCK_PLL_EN	0x0008
30364+#define  SDHCI_CTRL_64BIT_ADDR	0x2000
30365+#define  SDHCI_CAN_DO_ADMA3	0x08000000
30366+
30367+/* Hisilicon extended registers */
30368+#define SDHCI_MSHC_CTRL		0x508
30369+#define SDHCI_CMD_CONFLIT_CHECK	0x01
30370+
30371+#define SDHCI_AXI_MBIIU_CTRL	0x510
30372+#define SDHCI_GM_WR_OSRC_LMT_MASK	(0x7 << 24)
30373+#define SDHCI_GM_WR_OSRC_LMT_SEL(x)	((x) << 24)
30374+#define SDHCI_GM_RD_OSRC_LMT_MASK	(0x7 << 16)
30375+#define SDHCI_GM_RD_OSRC_LMT_SEL(x)	((x) << 16)
30376+#define SDHCI_UNDEFL_INCR_EN		0x1
30377+
30378+#define SDHCI_EMMC_CTRL		0x52C
30379+#define  SDHCI_CARD_IS_EMMC	0x0001
30380+#define  SDHCI_ENH_STROBE_EN	0x0100
30381+
30382+#define SDHCI_EMMC_HW_RESET	0x534
30383+
30384+#define SDHCI_AT_CTRL		0x540
30385+#define  SDHCI_SAMPLE_EN	0x00000010
30386+
30387+#define SDHCI_AT_STAT		0x544
30388+#define  SDHCI_PHASE_SEL_MASK	0x000000FF
30389+
30390+#define SDHCI_MULTI_CYCLE	0x54C
30391+#define  SDHCI_FOUND_EDGE	(0x1 << 11)
30392+#define  SDHCI_EDGE_DETECT_EN	(0x1 << 8)
30393+#define  SDHCI_DOUT_EN_F_EDGE	(0x1 << 6)
30394+#define  SDHCI_DATA_DLY_EN	(0x1 << 3)
30395+#define  SDHCI_CMD_DLY_EN	(0x1 << 2)
30396+
30397+void hisi_set_drv_cap(struct sdhci_host *host);
30398+void hisi_get_phase(struct sdhci_host *host);
30399+void hisi_set_drv_phase(struct sdhci_host *host, unsigned int phase);
30400+void hisi_enable_sample(struct sdhci_host *host);
30401+void hisi_set_sample_phase(struct sdhci_host *host, u32 phase);
30402+void hisi_disable_card_clk(struct sdhci_host *host);
30403+void hisi_enable_card_clk(struct sdhci_host *host);
30404+void hisi_disable_internal_clk(struct sdhci_host *host);
30405+void hisi_enable_internal_clk(struct sdhci_host *host);
30406+void hisi_enable_sample_dll_slave(struct sdhci_host *host);
30407+void hisi_wait_sample_dll_ready(struct sdhci_host *host);
30408+void hisi_wait_p4_dll_lock(struct sdhci_host *host);
30409+void hisi_wait_ds_dll_ready(struct sdhci_host *host);
30410+void hisi_wait_ds_180_dll_ready(struct sdhci_host *host);
30411+void hisi_wait_ds_dll_lock(struct sdhci_host *host);
30412+void hisi_set_ds_dll_delay(struct sdhci_host *host);
30413+void sdhci_hisi_set_clock(struct sdhci_host *host, unsigned int clk);
30414+int hisi_support_runtime_pm(struct sdhci_host *host);
30415+int sdhci_hisi_pltfm_init(struct platform_device *pdev,
30416+    struct sdhci_host *host);
30417+void sdhci_hisi_extra_init(struct sdhci_host *host);
30418+int sdhci_hisi_parse_dt(struct sdhci_host *host);
30419+int sdhci_hisi_start_signal_voltage_switch(struct sdhci_host *host,
30420+    struct mmc_ios *ios);
30421+
30422+#endif /* _DRIVERS_MMC_SDHCI_HISI_H */
30423diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
30424index 07d131fac..49ee7d99b 100644
30425--- a/drivers/mmc/host/sdhci.c
30426+++ b/drivers/mmc/host/sdhci.c
30427@@ -261,7 +261,7 @@ static void sdhci_set_default_irqs(struct sdhci_host *host)
30428 		    SDHCI_INT_DATA_CRC | SDHCI_INT_DATA_TIMEOUT |
30429 		    SDHCI_INT_INDEX | SDHCI_INT_END_BIT | SDHCI_INT_CRC |
30430 		    SDHCI_INT_TIMEOUT | SDHCI_INT_DATA_END |
30431-		    SDHCI_INT_RESPONSE;
30432+		    SDHCI_INT_RESPONSE | SDHCI_INT_AUTO_CMD_ERR;
30433
30434 	if (host->tuning_mode == SDHCI_TUNING_MODE_2 ||
30435 	    host->tuning_mode == SDHCI_TUNING_MODE_3)
30436@@ -291,8 +291,12 @@ static void sdhci_config_dma(struct sdhci_host *host)
30437 		goto out;
30438
30439 	/* Note if DMA Select is zero then SDMA is selected */
30440-	if (host->flags & SDHCI_USE_ADMA)
30441+	if (host->flags & SDHCI_USE_ADMA) {
30442 		ctrl |= SDHCI_CTRL_ADMA32;
30443+		if (host->flags & SDHCI_USE_ADMA3) {
30444+			ctrl |= SDHCI_CTRL_ADMA3;
30445+		}
30446+	}
30447
30448 	if (host->flags & SDHCI_USE_64_BIT_DMA) {
30449 		/*
30450@@ -341,6 +345,9 @@ static void sdhci_init(struct sdhci_host *host, int soft)
30451 		host->clock = 0;
30452 		mmc->ops->set_ios(mmc, &mmc->ios);
30453 	}
30454+
30455+	if (host->ops->init)
30456+		host->ops->init(host);
30457 }
30458
30459 static void sdhci_reinit(struct sdhci_host *host)
30460@@ -478,6 +485,28 @@ static void sdhci_del_timer(struct sdhci_host *host, struct mmc_request *mrq)
30461 		del_timer(&host->timer);
30462 }
30463
30464+static void __sdhci_noadma3_set_cmd_arg(struct sdhci_host *host, struct mmc_command *cmd)
30465+{
30466+	if (!(host->flags & SDHCI_USE_ADMA3) || !cmd->data)
30467+		sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
30468+}
30469+
30470+static void __sdhci_prep_adma3(struct sdhci_host *host,
30471+		struct mmc_command *cmd, int *flags)
30472+{
30473+	if ((host->flags & SDHCI_USE_ADMA3) && cmd->data) {
30474+		sdhci_prep_adma3_desc(host, cmd, *flags);
30475+
30476+		sdhci_writel(host, (u32)host->adma3_addr,
30477+				SDHCI_ADMA3_ID_ADDR_LOW);
30478+		if (host->flags & SDHCI_USE_64_BIT_DMA)
30479+			sdhci_writel(host, (u32)((u64)host->adma3_addr >> 32),  // right shift 32
30480+					SDHCI_ADMA3_ID_ADDR_HI);
30481+	} else {
30482+		sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, *flags), SDHCI_COMMAND);
30483+	}
30484+}
30485+
30486 static inline bool sdhci_has_requests(struct sdhci_host *host)
30487 {
30488 	return host->cmd || host->data_cmd;
30489@@ -700,6 +729,60 @@ void sdhci_adma_write_desc(struct sdhci_host *host, void **desc,
30490 }
30491 EXPORT_SYMBOL_GPL(sdhci_adma_write_desc);
30492
30493+static void sdhci_write_cmd_table(u8 *desc, u32 reg, u32 attr)
30494+{
30495+	__le32 *reg_addr = (__le32 __force *)(desc + 4);  // offset 4
30496+	__le32 *attr_addr = (__le32 __force *)desc;
30497+
30498+	attr_addr[0] = cpu_to_le32(attr);
30499+	reg_addr[0] = cpu_to_le32(reg);
30500+}
30501+
30502+static void sdhci_write_adma3_desc(struct sdhci_host *host, u8 *desc,
30503+		dma_addr_t addr, unsigned int attr)
30504+{
30505+	__le32 *attr_addr = (__le32 __force *)desc;
30506+
30507+	attr_addr[0] = cpu_to_le32(attr);
30508+
30509+	if (host->flags & SDHCI_USE_64_BIT_DMA) {
30510+		__le64 *cmd_ddr = (__le64 __force *)(desc + 4);  // offset 4
30511+		cmd_ddr[0] = cpu_to_le64(addr);
30512+	} else {
30513+		__le32 *cmd_ddr = (__le32 __force *)(desc + 4);  // offset 4
30514+		cmd_ddr[0] = cpu_to_le32(addr);
30515+	}
30516+}
30517+
30518+static void sdhci_prep_adma3_desc(struct sdhci_host *host,
30519+		struct mmc_command *cmd, int flags)
30520+{
30521+	struct mmc_data *data = cmd->data;
30522+	unsigned int ctrl_2, cmd_xfer, blksz;
30523+	u16 mode;
30524+
30525+	blksz = SDHCI_MAKE_BLKSZ(0, data->blksz);
30526+	mode = sdhci_readw(host, SDHCI_TRANSFER_MODE);
30527+	cmd_xfer = (SDHCI_MAKE_CMD(cmd->opcode, flags) << 16) | mode;  // left shift 16
30528+
30529+	sdhci_write_cmd_table(host->cmd_table, data->blocks, ADMA3_CMD_VALID);
30530+	sdhci_write_cmd_table(host->cmd_table + 0x8, blksz, ADMA3_CMD_VALID);  // add 0x8
30531+	sdhci_write_cmd_table(host->cmd_table + 0x10,    // add 0x10
30532+			cmd->arg, ADMA3_CMD_VALID);
30533+	sdhci_write_cmd_table(host->cmd_table + 0x18,  // add 0x18
30534+			cmd_xfer, ADMA3_CMD_VALID);
30535+	sdhci_adma_write_desc(host, host->cmd_table + 0x20,  // add 0x20
30536+			host->adma_addr, 0x0, ADMA2_LINK_VALID);
30537+	sdhci_write_adma3_desc(host, host->adma3_table,
30538+			host->cmd_addr, ADMA3_END);
30539+
30540+	ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
30541+	ctrl_2 |= SDHCI_CTRL_HOST_VER4_ENABLE;
30542+	if (host->flags & SDHCI_USE_64_BIT_DMA)
30543+		ctrl_2 |= SDHCI_CTRL_ADDRESSING_64BIT;
30544+	sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
30545+}
30546+
30547 static inline void __sdhci_adma_write_desc(struct sdhci_host *host,
30548 					   void **desc, dma_addr_t addr,
30549 					   int len, unsigned int cmd)
30550@@ -774,10 +857,22 @@ static void sdhci_adma_table_pre(struct sdhci_host *host,
30551
30552 		BUG_ON(len > 65536);
30553
30554-		/* tran, valid */
30555-		if (len)
30556-			__sdhci_adma_write_desc(host, &desc, addr, len,
30557+ 		if (len) {
30558+			/* work around for buffer across 128M boundary, split the buffer */
30559+			if (((addr & (SDHCI_DMA_BOUNDARY_SIZE - 1)) + len) >
30560+					SDHCI_DMA_BOUNDARY_SIZE) {
30561+				offset = SDHCI_DMA_BOUNDARY_SIZE -
30562+					(addr & (SDHCI_DMA_BOUNDARY_SIZE - 1));
30563+				sdhci_adma_write_desc(host, desc, addr, offset,
30564 						ADMA2_TRAN_VALID);
30565+				desc += host->desc_sz;
30566+				addr += offset;
30567+				len -= offset;
30568+			}
30569+ 			/* tran, valid */
30570+ 			sdhci_adma_write_desc(host, desc, addr, len,
30571+ 					      ADMA2_TRAN_VALID);
30572+		}
30573
30574 		/*
30575 		 * If this triggers then we have a calculation bug
30576@@ -1040,6 +1135,18 @@ static void sdhci_set_timeout(struct sdhci_host *host, struct mmc_command *cmd)
30577 		__sdhci_set_timeout(host, cmd);
30578 }
30579
30580+static void __sdhci_select_adma3_mode(struct sdhci_host *host, u8 *ctrl)
30581+{
30582+	if (host->flags & SDHCI_USE_ADMA3) {
30583+		*ctrl |= SDHCI_CTRL_ADMA3;
30584+	} else {
30585+		if (host->flags & SDHCI_USE_64_BIT_DMA)
30586+			*ctrl |= SDHCI_CTRL_ADMA64;
30587+		else
30588+			*ctrl |= SDHCI_CTRL_ADMA32;
30589+	}
30590+}
30591+
30592 static void sdhci_initialize_data(struct sdhci_host *host,
30593 				  struct mmc_data *data)
30594 {
30595@@ -1134,7 +1241,6 @@ static void sdhci_prepare_data(struct sdhci_host *host, struct mmc_command *cmd)
30596
30597 	if (host->flags & SDHCI_REQ_USE_DMA) {
30598 		int sg_cnt = sdhci_pre_dma_transfer(host, data, COOKIE_MAPPED);
30599-
30600 		if (sg_cnt <= 0) {
30601 			/*
30602 			 * This only happens when someone fed
30603@@ -1633,7 +1739,7 @@ static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
30604 			sdhci_prepare_data(host, cmd);
30605 	}
30606
30607-	sdhci_writel(host, cmd->arg, SDHCI_ARGUMENT);
30608+	__sdhci_noadma3_set_cmd_arg(host, cmd);
30609
30610 	sdhci_set_transfer_mode(host, cmd);
30611
30612@@ -1678,7 +1784,7 @@ static bool sdhci_send_command(struct sdhci_host *host, struct mmc_command *cmd)
30613 	if (host->use_external_dma)
30614 		sdhci_external_dma_pre_transfer(host, cmd);
30615
30616-	sdhci_writew(host, SDHCI_MAKE_CMD(cmd->opcode, flags), SDHCI_COMMAND);
30617+	__sdhci_prep_adma3(host, cmd, &flags);
30618
30619 	return true;
30620 }
30621@@ -1755,6 +1861,14 @@ static void sdhci_read_rsp_136(struct sdhci_host *host, struct mmc_command *cmd)
30622 	}
30623 }
30624
30625+#define CMD_ERRORS                          \
30626+	(R1_OUT_OF_RANGE |  /* Command argument out of range */ \
30627+	 R1_ADDRESS_ERROR | /* Misaligned address */        \
30628+	 R1_BLOCK_LEN_ERROR |   /* Transferred block length incorrect */\
30629+	 R1_WP_VIOLATION |  /* Tried to write to protected block */ \
30630+	 R1_CC_ERROR |      /* Card controller error */     \
30631+	 R1_ERROR)      /* General/unknown error */
30632+
30633 static void sdhci_finish_command(struct sdhci_host *host)
30634 {
30635 	struct mmc_command *cmd = host->cmd;
30636@@ -1767,6 +1881,12 @@ static void sdhci_finish_command(struct sdhci_host *host)
30637 		} else {
30638 			cmd->resp[0] = sdhci_readl(host, SDHCI_RESPONSE);
30639 		}
30640+
30641+		if (((cmd->flags & MMC_RSP_R1) == MMC_RSP_R1) &&
30642+			((cmd->flags & MMC_CMD_MASK) != MMC_CMD_BCR)) {
30643+			if ((cmd->resp[0] & CMD_ERRORS) && !host->is_tuning)
30644+				host->error_count++;
30645+		}
30646 	}
30647
30648 	if (cmd->mrq->cap_cmd_during_tfr && cmd == cmd->mrq->cmd)
30649@@ -2067,6 +2187,12 @@ void sdhci_set_power_noreg(struct sdhci_host *host, unsigned char mode,
30650 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
30651 		if (host->quirks2 & SDHCI_QUIRK2_CARD_ON_NEEDS_BUS_ON)
30652 			sdhci_runtime_pm_bus_off(host);
30653+		/*
30654+		 * Controllers need an extra 100ms delay to ensure power off
30655+		 * completely
30656+		 */
30657+		msleep(100);
30658+
30659 	} else {
30660 		/*
30661 		 * Spec says that we should clear the power reg before setting
30662@@ -2388,7 +2514,9 @@ void sdhci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
30663 		}
30664
30665 		/* Re-enable SD Clock */
30666-		host->ops->set_clock(host, host->clock);
30667+		clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL);
30668+		clk |= SDHCI_CLOCK_CARD_EN;
30669+		sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
30670 	} else
30671 		sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
30672
30673@@ -2529,6 +2657,9 @@ int sdhci_start_signal_voltage_switch(struct mmc_host *mmc,
30674 	u16 ctrl;
30675 	int ret;
30676
30677+	if (host->ops->start_signal_voltage_switch)
30678+		return host->ops->start_signal_voltage_switch(host, ios);
30679+
30680 	/*
30681 	 * Signal Voltage Switching is only applicable for Host Controllers
30682 	 * v3.00 and above.
30683@@ -2966,6 +3097,34 @@ static void sdhci_card_event(struct mmc_host *mmc)
30684 	spin_unlock_irqrestore(&host->lock, flags);
30685 }
30686
30687+static int sdhci_card_info_save(struct mmc_host *mmc)
30688+{
30689+	struct mmc_card *card = mmc->card;
30690+	struct sdhci_host *host= mmc_priv(mmc);
30691+	struct card_info *c_info = &host->c_info;
30692+
30693+	if (!card) {
30694+		memset(c_info,0,sizeof(struct card_info));
30695+		c_info->card_connect = CARD_DISCONNECT;
30696+		goto out;
30697+	}
30698+
30699+	c_info->card_type = card->type;
30700+	c_info->card_state = card->state;
30701+
30702+	c_info->timing = mmc->ios.timing;
30703+	c_info->enhanced_strobe = mmc->ios.enhanced_strobe;
30704+	c_info->card_support_clock = mmc->ios.clock;
30705+
30706+	c_info->sd_bus_speed = card->sd_bus_speed;
30707+
30708+	memcpy(c_info->ssr, card->raw_ssr, ARRAY_SIZE(c_info->ssr));
30709+
30710+	c_info->card_connect = CARD_CONNECT;
30711+out:
30712+	return 0;
30713+}
30714+
30715 static const struct mmc_host_ops sdhci_ops = {
30716 	.request	= sdhci_request,
30717 	.post_req	= sdhci_post_req,
30718@@ -2981,6 +3140,7 @@ static const struct mmc_host_ops sdhci_ops = {
30719 	.execute_tuning			= sdhci_execute_tuning,
30720 	.card_event			= sdhci_card_event,
30721 	.card_busy	= sdhci_card_busy,
30722+	.card_info_save = sdhci_card_info_save,
30723 };
30724
30725 /*****************************************************************************\
30726@@ -3039,6 +3199,9 @@ static bool sdhci_request_done(struct sdhci_host *host)
30727 		host->pending_reset = false;
30728 	}
30729
30730+	if (mrq->data && mrq->data->error && !host->is_tuning)
30731+		host->error_count++;
30732+
30733 	/*
30734 	 * Always unmap the data buffers if they were mapped by
30735 	 * sdhci_prepare_data() whenever we finish with a request.
30736@@ -3181,6 +3344,24 @@ static void sdhci_timeout_data_timer(struct timer_list *t)
30737  *                                                                           *
30738 \*****************************************************************************/
30739
30740+static void __sdhci_handle_auto_cmd_err(struct sdhci_host *host, u32 *intmask)
30741+{
30742+	if (*intmask & SDHCI_INT_AUTO_CMD_ERR) {
30743+		u16 acmd_stat = sdhci_readw(host, SDHCI_AUTO_CMD_STATUS);
30744+		if (acmd_stat & (SDHCI_AUTO_CMD12_NOT_EXEC |
30745+					SDHCI_AUTO_CMD_INDEX |
30746+					SDHCI_AUTO_CMD12_NOT_ISSUED))
30747+			host->cmd->error = -EIO;
30748+		else if (acmd_stat & SDHCI_AUTO_CMD_TIMEOUT)
30749+			host->cmd->error = -ETIMEDOUT;
30750+		else
30751+			host->cmd->error = -EILSEQ;
30752+
30753+	} else {
30754+		host->cmd->error = -EILSEQ;
30755+	}
30756+}
30757+
30758 static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p)
30759 {
30760 	/* Handle auto-CMD12 error */
30761@@ -3206,18 +3387,21 @@ static void sdhci_cmd_irq(struct sdhci_host *host, u32 intmask, u32 *intmask_p)
30762 		 */
30763 		if (host->pending_reset)
30764 			return;
30765-		pr_err("%s: Got command interrupt 0x%08x even though no command operation was in progress.\n",
30766+
30767+		/*pr_err("%s: Got command interrupt 0x%08x even though no command operation was in progress.\n",
30768 		       mmc_hostname(host->mmc), (unsigned)intmask);
30769-		sdhci_dumpregs(host);
30770+		sdhci_dumpregs(host);*/
30771+
30772 		return;
30773 	}
30774
30775 	if (intmask & (SDHCI_INT_TIMEOUT | SDHCI_INT_CRC |
30776-		       SDHCI_INT_END_BIT | SDHCI_INT_INDEX)) {
30777+		       SDHCI_INT_END_BIT | SDHCI_INT_INDEX |
30778+		       SDHCI_INT_AUTO_CMD_ERR)) {
30779 		if (intmask & SDHCI_INT_TIMEOUT)
30780 			host->cmd->error = -ETIMEDOUT;
30781 		else
30782-			host->cmd->error = -EILSEQ;
30783+			__sdhci_handle_auto_cmd_err(host, &intmask);
30784
30785 		/* Treat data command CRC error the same as data CRC error */
30786 		if (host->cmd->data &&
30787@@ -3442,6 +3626,9 @@ static irqreturn_t sdhci_irq(int irq, void *dev_id)
30788 	do {
30789 		DBG("IRQ status 0x%08x\n", intmask);
30790
30791+		if ((intmask & SDHCI_INT_ERROR) && !host->is_tuning)
30792+			host->error_count++;
30793+
30794 		if (host->ops->irq) {
30795 			intmask = host->ops->irq(host, intmask);
30796 			if (!intmask)
30797@@ -3801,10 +3988,11 @@ void sdhci_cqe_enable(struct mmc_host *mmc)
30798 {
30799 	struct sdhci_host *host = mmc_priv(mmc);
30800 	unsigned long flags;
30801+#ifndef CONFIG_MMC_SDHCI_HISI
30802 	u8 ctrl;
30803-
30804+#endif
30805 	spin_lock_irqsave(&host->lock, flags);
30806-
30807+#ifndef CONFIG_MMC_SDHCI_HISI
30808 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
30809 	ctrl &= ~SDHCI_CTRL_DMA_MASK;
30810 	/*
30811@@ -3822,7 +4010,7 @@ void sdhci_cqe_enable(struct mmc_host *mmc)
30812
30813 	sdhci_writew(host, SDHCI_MAKE_BLKSZ(host->sdma_boundary, 512),
30814 		     SDHCI_BLOCK_SIZE);
30815-
30816+#endif
30817 	/* Set maximum timeout */
30818 	sdhci_set_timeout(host, NULL);
30819
30820@@ -4099,6 +4287,72 @@ static void sdhci_allocate_bounce_buffer(struct sdhci_host *host)
30821 		mmc_hostname(mmc), max_blocks, bounce_size);
30822 }
30823
30824+static void __sdhci_support_adma3(struct sdhci_host *host)
30825+{
30826+	if ((host->version >= SDHCI_SPEC_400) &&
30827+		(host->caps1 & SDHCI_CAN_DO_ADMA3))
30828+		host->flags |= SDHCI_USE_ADMA3 | SDHCI_HOST_VER4_ENABLE;
30829+
30830+	if ((host->quirks2 & SDHCI_QUIRK2_BROKEN_ADMA3) &&
30831+			(host->flags & SDHCI_USE_ADMA3)) {
30832+		DBG("Disabling ADMA3 as it is marked broken\n");
30833+		host->flags &= ~(SDHCI_USE_ADMA3 | SDHCI_HOST_VER4_ENABLE);
30834+	}
30835+}
30836+
30837+static void __sdhci_set_dma_descriptor_size(struct sdhci_host *host)
30838+{
30839+	if (host->flags & SDHCI_HOST_VER4_ENABLE)
30840+		host->desc_sz = 16;  //descriptor size 16
30841+	else
30842+		host->desc_sz = SDHCI_ADMA2_64_DESC_SZ;
30843+}
30844+
30845+static void __sdhci_set_adma_cmd_table(struct sdhci_host *host,
30846+		void *buf, dma_addr_t *dma, struct mmc_host *mmc)
30847+{
30848+	if (!(host->flags & SDHCI_USE_ADMA))
30849+		host->flags &= ~SDHCI_USE_ADMA3;
30850+
30851+	if (host->flags & SDHCI_USE_ADMA3) {
30852+#define MAX_CMD_NUM	32
30853+#define SDHCI_CMD_DESC_SZ	16
30854+		if (host->flags & SDHCI_USE_64_BIT_DMA)
30855+			host->adma3_desc_sz = SDHCI_ADMA3_64_DESC_SZ;
30856+		else
30857+			host->adma3_desc_sz = SDHCI_ADMA3_32_DESC_SZ;
30858+
30859+		host->adma3_table_sz = MAX_CMD_NUM * host->adma3_desc_sz;
30860+		host->cmd_table_sz = MAX_CMD_NUM *
30861+					(SDHCI_CMD_DESC_SZ + 16);  // offset 16
30862+		buf = dma_alloc_coherent(mmc_dev(mmc), host->adma3_table_sz +
30863+				host->cmd_table_sz, dma, GFP_KERNEL);
30864+		if (!buf) {
30865+			pr_warn("%s: Unable to allocate ADMA3 buffers - falling back \
30866+					to standard DMA\n", mmc_hostname(mmc));
30867+			host->flags &= ~SDHCI_USE_ADMA3;
30868+		} else {
30869+			host->adma3_table = buf;
30870+			host->adma3_addr = *dma;
30871+
30872+			host->cmd_table = buf + host->adma3_desc_sz;
30873+			host->cmd_addr = *dma + host->adma3_desc_sz;
30874+		}
30875+	}
30876+}
30877+
30878+static void __sdhci_release_adma3_cmd_table(struct sdhci_host *host,
30879+		struct mmc_host *mmc)
30880+{
30881+	if (host->adma3_table)
30882+		dma_free_coherent(mmc_dev(mmc), host->adma3_table_sz +
30883+				  host->cmd_table_sz, host->adma3_table,
30884+				  host->adma3_addr);
30885+
30886+	host->adma3_table = NULL;
30887+	host->cmd_table = NULL;
30888+}
30889+
30890 static inline bool sdhci_can_64bit_dma(struct sdhci_host *host)
30891 {
30892 	/*
30893@@ -4180,6 +4434,8 @@ int sdhci_setup_host(struct sdhci_host *host)
30894 		host->flags &= ~SDHCI_USE_ADMA;
30895 	}
30896
30897+	__sdhci_support_adma3(host);
30898+
30899 	if (sdhci_can_64bit_dma(host))
30900 		host->flags |= SDHCI_USE_64_BIT_DMA;
30901
30902@@ -4258,6 +4514,7 @@ int sdhci_setup_host(struct sdhci_host *host)
30903 			host->adma_table = buf + host->align_buffer_sz;
30904 			host->adma_addr = dma + host->align_buffer_sz;
30905 		}
30906+		__sdhci_set_adma_cmd_table(host, buf, &dma, mmc);
30907 	}
30908
30909 	/*
30910@@ -4506,7 +4763,6 @@ int sdhci_setup_host(struct sdhci_host *host)
30911 	if (!max_current_caps && !IS_ERR(mmc->supply.vmmc)) {
30912 		int curr = regulator_get_current_limit(mmc->supply.vmmc);
30913 		if (curr > 0) {
30914-
30915 			/* convert to SDHCI_MAX_CURRENT format */
30916 			curr = curr/1000;  /* convert to mA */
30917 			curr = curr/SDHCI_MAX_CURRENT_MULTIPLIER;
30918@@ -4659,6 +4915,8 @@ int sdhci_setup_host(struct sdhci_host *host)
30919 	host->adma_table = NULL;
30920 	host->align_buffer = NULL;
30921
30922+	__sdhci_release_adma3_cmd_table(host, mmc);
30923+
30924 	return ret;
30925 }
30926 EXPORT_SYMBOL_GPL(sdhci_setup_host);
30927@@ -4680,6 +4938,8 @@ void sdhci_cleanup_host(struct sdhci_host *host)
30928
30929 	host->adma_table = NULL;
30930 	host->align_buffer = NULL;
30931+
30932+	__sdhci_release_adma3_cmd_table(host, mmc);
30933 }
30934 EXPORT_SYMBOL_GPL(sdhci_cleanup_host);
30935
30936@@ -4729,6 +4989,7 @@ int __sdhci_add_host(struct sdhci_host *host)
30937
30938 	pr_info("%s: SDHCI controller on %s [%s] using %s\n",
30939 		mmc_hostname(mmc), host->hw_name, dev_name(mmc_dev(mmc)),
30940+		(host->flags & SDHCI_USE_ADMA3) ? "ADMA3" :
30941 		host->use_external_dma ? "External DMA" :
30942 		(host->flags & SDHCI_USE_ADMA) ?
30943 		(host->flags & SDHCI_USE_64_BIT_DMA) ? "ADMA 64-bit" : "ADMA" :
30944@@ -4794,6 +5055,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
30945
30946 	sdhci_disable_card_detection(host);
30947
30948+	free_irq(host->irq, host);
30949+
30950 	mmc_remove_host(mmc);
30951
30952 	sdhci_led_unregister(host);
30953@@ -4803,7 +5066,6 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
30954
30955 	sdhci_writel(host, 0, SDHCI_INT_ENABLE);
30956 	sdhci_writel(host, 0, SDHCI_SIGNAL_ENABLE);
30957-	free_irq(host->irq, host);
30958
30959 	del_timer_sync(&host->timer);
30960 	del_timer_sync(&host->data_timer);
30961@@ -4823,6 +5085,8 @@ void sdhci_remove_host(struct sdhci_host *host, int dead)
30962
30963 	host->adma_table = NULL;
30964 	host->align_buffer = NULL;
30965+
30966+	__sdhci_release_adma3_cmd_table(host, mmc);
30967 }
30968
30969 EXPORT_SYMBOL_GPL(sdhci_remove_host);
30970diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
30971index 960fed785..4688a612b 100644
30972--- a/drivers/mmc/host/sdhci.h
30973+++ b/drivers/mmc/host/sdhci.h
30974@@ -140,6 +140,7 @@
30975 #define  SDHCI_INT_CARD_INT	0x00000100
30976 #define  SDHCI_INT_RETUNE	0x00001000
30977 #define  SDHCI_INT_CQE		0x00004000
30978+#define  SDHCI_INT_CQE		0x00004000
30979 #define  SDHCI_INT_ERROR	0x00008000
30980 #define  SDHCI_INT_TIMEOUT	0x00010000
30981 #define  SDHCI_INT_CRC		0x00020000
30982@@ -173,10 +174,12 @@
30983 #define SDHCI_CQE_INT_MASK (SDHCI_CQE_INT_ERR_MASK | SDHCI_INT_CQE)
30984
30985 #define SDHCI_AUTO_CMD_STATUS	0x3C
30986+#define SDHCI_AUTO_CMD12_NOT_EXEC	0x0001
30987 #define  SDHCI_AUTO_CMD_TIMEOUT	0x00000002
30988 #define  SDHCI_AUTO_CMD_CRC	0x00000004
30989 #define  SDHCI_AUTO_CMD_END_BIT	0x00000008
30990 #define  SDHCI_AUTO_CMD_INDEX	0x00000010
30991+#define SDHCI_AUTO_CMD12_NOT_ISSUED	0x0080
30992
30993 #define SDHCI_HOST_CONTROL2		0x3E
30994 #define  SDHCI_CTRL_UHS_MASK		0x0007
30995@@ -185,7 +188,7 @@
30996 #define   SDHCI_CTRL_UHS_SDR50		0x0002
30997 #define   SDHCI_CTRL_UHS_SDR104		0x0003
30998 #define   SDHCI_CTRL_UHS_DDR50		0x0004
30999-#define   SDHCI_CTRL_HS400		0x0005 /* Non-standard */
31000+#define   SDHCI_CTRL_HS400		0x0007 /* Non-standard */
31001 #define  SDHCI_CTRL_VDD_180		0x0008
31002 #define  SDHCI_CTRL_DRV_TYPE_MASK	0x0030
31003 #define   SDHCI_CTRL_DRV_TYPE_B		0x0000
31004@@ -194,6 +197,9 @@
31005 #define   SDHCI_CTRL_DRV_TYPE_D		0x0030
31006 #define  SDHCI_CTRL_EXEC_TUNING		0x0040
31007 #define  SDHCI_CTRL_TUNED_CLK		0x0080
31008+#define  SDHCI_CTRL_HOST_VER4_ENABLE	0x1000
31009+#define  SDHCI_CTRL_ADDRESSING_64BIT	0x2000
31010+#define  SDHCI_CTRL_ASYNC_INT_ENABLE	0x4000
31011 #define  SDHCI_CMD23_ENABLE		0x0800
31012 #define  SDHCI_CTRL_V4_MODE		0x1000
31013 #define  SDHCI_CTRL_64BIT_ADDR		0x2000
31014@@ -217,6 +223,7 @@
31015 #define  SDHCI_CAN_VDD_180	0x04000000
31016 #define  SDHCI_CAN_64BIT_V4	0x08000000
31017 #define  SDHCI_CAN_64BIT	0x10000000
31018+#define  SDHCI_CAN_ASYNC_INT	0x20000000
31019
31020 #define SDHCI_CAPABILITIES_1	0x44
31021 #define  SDHCI_SUPPORT_SDR50	0x00000001
31022@@ -264,6 +271,9 @@
31023 #define SDHCI_PRESET_CLKGEN_SEL		BIT(10)
31024 #define SDHCI_PRESET_SDCLK_FREQ_MASK	GENMASK(9, 0)
31025
31026+#define SDHCI_ADMA3_ID_ADDR_LOW	0x78
31027+#define SDHCI_ADMA3_ID_ADDR_HI	0x7C
31028+
31029 #define SDHCI_SLOT_INT_STATUS	0xFC
31030
31031 #define SDHCI_HOST_VERSION	0xFE
31032@@ -290,6 +300,7 @@
31033  */
31034 #define SDHCI_DEFAULT_BOUNDARY_SIZE  (512 * 1024)
31035 #define SDHCI_DEFAULT_BOUNDARY_ARG   (ilog2(SDHCI_DEFAULT_BOUNDARY_SIZE) - 12)
31036+#define SDHCI_DMA_BOUNDARY_SIZE	     (0x1 << 27)
31037
31038 /* ADMA2 32-bit DMA descriptor size */
31039 #define SDHCI_ADMA2_32_DESC_SZ	8
31040@@ -321,6 +332,12 @@ struct sdhci_adma2_32_desc {
31041  */
31042 #define SDHCI_ADMA2_64_DESC_SZ(host)	((host)->v4_mode ? 16 : 12)
31043
31044+/* ADMA3 32-bit DMA descriptor size */
31045+#define SDHCI_ADMA3_32_DESC_SZ	8
31046+
31047+/* ADMA3 64-bit DMA descriptor size */
31048+#define SDHCI_ADMA3_64_DESC_SZ	16
31049+
31050 /*
31051  * ADMA2 64-bit descriptor. Note 12-byte descriptor can't always be 8-byte
31052  * aligned.
31053@@ -335,6 +352,9 @@ struct sdhci_adma2_64_desc {
31054 #define ADMA2_TRAN_VALID	0x21
31055 #define ADMA2_NOP_END_VALID	0x3
31056 #define ADMA2_END		0x2
31057+#define ADMA2_LINK_VALID	0x31
31058+#define ADMA3_CMD_VALID		0x9
31059+#define ADMA3_END		0x3b
31060
31061 /*
31062  * Maximum segments assuming a 512KiB maximum requisition size and a minimum
31063@@ -359,6 +379,19 @@ enum sdhci_cookie {
31064 	COOKIE_MAPPED,		/* mapped by sdhci_prepare_data() */
31065 };
31066
31067+struct card_info {
31068+	unsigned int     card_type;
31069+	unsigned char    timing;
31070+	bool enhanced_strobe;
31071+	unsigned char    card_connect;
31072+#define CARD_CONNECT    1
31073+#define CARD_DISCONNECT 0
31074+	unsigned int     card_support_clock; /* clock rate */
31075+	unsigned int     card_state;      /* (our) card state */
31076+	unsigned int     sd_bus_speed;
31077+	unsigned int     ssr[16];
31078+};
31079+
31080 struct sdhci_host {
31081 	/* Data set by hardware interface driver */
31082 	const char *hw_name;	/* Hardware bus name */
31083@@ -460,6 +493,7 @@ struct sdhci_host {
31084 #define SDHCI_QUIRK2_ACMD23_BROKEN			(1<<14)
31085 /* Broken Clock divider zero in controller */
31086 #define SDHCI_QUIRK2_CLOCK_DIV_ZERO_BROKEN		(1<<15)
31087+#define SDHCI_QUIRK2_BROKEN_ADMA3			(1<<16)
31088 /* Controller has CRC in 136 bit Command Response */
31089 #define SDHCI_QUIRK2_RSP_136_HAS_CRC			(1<<16)
31090 /*
31091@@ -510,6 +544,8 @@ struct sdhci_host {
31092 #define SDHCI_SIGNALING_330	(1<<14)	/* Host is capable of 3.3V signaling */
31093 #define SDHCI_SIGNALING_180	(1<<15)	/* Host is capable of 1.8V signaling */
31094 #define SDHCI_SIGNALING_120	(1<<16)	/* Host is capable of 1.2V signaling */
31095+#define SDHCI_USE_ADMA3		(1<<17)	/* Host is ADMA3 capable */
31096+#define SDHCI_HOST_VER4_ENABLE	(1<<18) /* Host version 4 enable */
31097
31098 	unsigned int version;	/* SDHCI spec. version */
31099
31100@@ -543,14 +579,21 @@ struct sdhci_host {
31101
31102 	void *adma_table;	/* ADMA descriptor table */
31103 	void *align_buffer;	/* Bounce buffer */
31104+	void *adma3_table;	/* ADMA3 integrated descriptor table */
31105+	void *cmd_table;	/* ADMA3 command descriptor table */
31106
31107 	size_t adma_table_sz;	/* ADMA descriptor table size */
31108 	size_t align_buffer_sz;	/* Bounce buffer size */
31109+	size_t adma3_table_sz;	/* ADMA3 integrated descriptor table size */
31110+	size_t cmd_table_sz;	/* ADMA3 command descriptor table size */
31111
31112 	dma_addr_t adma_addr;	/* Mapped ADMA descr. table */
31113 	dma_addr_t align_addr;	/* Mapped bounce buffer */
31114+	dma_addr_t adma3_addr;	/* Mapped ADMA3 integrated descr. table */
31115+	dma_addr_t cmd_addr;	/* Mapped ADMA3 command descr. table */
31116
31117 	unsigned int desc_sz;	/* ADMA current descriptor size */
31118+	unsigned int adma3_desc_sz;	/* ADMA3 integrated descriptor size */
31119 	unsigned int alloc_desc_sz;	/* ADMA descr. max size host supports */
31120
31121 	struct workqueue_struct *complete_wq;	/* Request completion wq */
31122@@ -606,6 +649,10 @@ struct sdhci_host {
31123
31124 	u64			data_timeout;
31125
31126+	u32			is_tuning;
31127+	unsigned int		error_count;
31128+	struct card_info 	c_info;
31129+
31130 	unsigned long private[] ____cacheline_aligned;
31131 };
31132
31133@@ -645,6 +692,9 @@ struct sdhci_ops {
31134 	void    (*adma_workaround)(struct sdhci_host *host, u32 intmask);
31135 	void    (*card_event)(struct sdhci_host *host);
31136 	void	(*voltage_switch)(struct sdhci_host *host);
31137+	void	(*init)(struct sdhci_host *host);
31138+	int	(*start_signal_voltage_switch)(struct sdhci_host *host,
31139+					       struct mmc_ios *ios);
31140 	void	(*adma_write_desc)(struct sdhci_host *host, void **desc,
31141 				   dma_addr_t addr, int len, unsigned int cmd);
31142 	void	(*copy_to_bounce_buffer)(struct sdhci_host *host,
31143diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile
31144index 593d0593a..cdf3ff323 100644
31145--- a/drivers/mtd/Makefile
31146+++ b/drivers/mtd/Makefile
31147@@ -26,8 +26,9 @@ obj-$(CONFIG_MTD_SWAP)		+= mtdswap.o
31148 nftl-objs		:= nftlcore.o nftlmount.o
31149 inftl-objs		:= inftlcore.o inftlmount.o
31150
31151-obj-y		+= chips/ lpddr/ maps/ devices/ nand/ tests/
31152
31153 obj-$(CONFIG_MTD_SPI_NOR)	+= spi-nor/
31154+obj-y		+= chips/ lpddr/ maps/ devices/ nand/ tests/
31155+
31156 obj-$(CONFIG_MTD_UBI)		+= ubi/
31157 obj-$(CONFIG_MTD_HYPERBUS)	+= hyperbus/
31158diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
31159index 4a9aed4f0..5c3e95668 100644
31160--- a/drivers/mtd/nand/Kconfig
31161+++ b/drivers/mtd/nand/Kconfig
31162@@ -6,7 +6,32 @@ config MTD_NAND_CORE
31163 	tristate
31164
31165 source "drivers/mtd/nand/onenand/Kconfig"
31166+
31167+config MTD_SPI_NAND_HISI_BVT
31168+    tristate "Support for SPI NAND controller on Hisilicon SoCs"
31169+    depends on MTD_NAND
31170+    help
31171+      Enables support for the SPI NAND device drivers.
31172+
31173+config HISI_NAND_ECC_STATUS_REPORT
31174+	tristate "Report the ecc status to MTD for HiSilicon Nand Driver"
31175+	depends on MTD_NAND && ARCH_HISI_BVT
31176+	default n
31177+	help
31178+	  Flash Memory Controller reports the ecc status include ECC error
31179+	  and ECC corrected to MTD to monitor the aging of devices.
31180+
31181+config HISI_NAND_FS_MAY_NO_YAFFS2
31182+    bool "Remove the restraintion of 16bit ecc type on yaffs2 to HiSilicon"
31183+	depends on MFD_HISI_FMC
31184+    default n
31185+    help
31186+      The ecc type: 16bit is limited by the HiSilicon flash memory controller,
31187+      as the yaffs2 tag of hisi rootfs limits the min size of CTRL len is 28.
31188+
31189 source "drivers/mtd/nand/raw/Kconfig"
31190+source "drivers/mtd/nand/hifmc100/Kconfig"
31191+source "drivers/mtd/nand/hifmc100_nand/Kconfig"
31192 source "drivers/mtd/nand/spi/Kconfig"
31193
31194 menu "ECC engine support"
31195diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
31196index 981372953..4fb87a5c3 100644
31197--- a/drivers/mtd/nand/Makefile
31198+++ b/drivers/mtd/nand/Makefile
31199@@ -1,6 +1,8 @@
31200 # SPDX-License-Identifier: GPL-2.0
31201
31202 nandcore-objs := core.o bbt.o
31203+obj-$(CONFIG_MTD_NAND_HIFMC100)		+= hifmc100_nand/
31204+obj-$(CONFIG_MTD_SPI_NAND_HIFMC100)	+= hifmc100/
31205 obj-$(CONFIG_MTD_NAND_CORE) += nandcore.o
31206
31207 obj-y	+= onenand/
31208diff --git a/drivers/mtd/nand/hifmc100/Kconfig b/drivers/mtd/nand/hifmc100/Kconfig
31209new file mode 100644
31210index 000000000..5b15bc8b9
31211--- /dev/null
31212+++ b/drivers/mtd/nand/hifmc100/Kconfig
31213@@ -0,0 +1,17 @@
31214+#
31215+# hisilicon flash memory controller SPI nand device driver version 100
31216+# drivers/mtd/nand/hifmc100/Kconfig
31217+# add by hisilicon 2017.8.7
31218+#
31219+
31220+config MTD_SPI_NAND_HIFMC100
31221+	bool "Hisilicon Flash Memory Controller v100 SPI Nand devices support"
31222+	depends on MFD_HISI_FMC && MTD_SPI_NAND_HISI_BVT
31223+	select MISC_FILESYSTEMS
31224+	select MTD_BLOCK
31225+	select YAFFS_FS
31226+	select YAFFS_YAFFS2
31227+	help
31228+	  Hisilicon Flash Memory Controller version 100 is called hifmc100 for
31229+	  short. The controller driver support registers and DMA transfers
31230+	  while reading or writing the SPI nand flash.
31231diff --git a/drivers/mtd/nand/hifmc100/Makefile b/drivers/mtd/nand/hifmc100/Makefile
31232new file mode 100644
31233index 000000000..b1fda5de8
31234--- /dev/null
31235+++ b/drivers/mtd/nand/hifmc100/Makefile
31236@@ -0,0 +1,26 @@
31237+#
31238+# The Flash Memory Controller v100 Device Driver for hisilicon
31239+#
31240+# Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
31241+#
31242+# This program is free software; you can redistribute  it and/or modify it
31243+# under  the terms of  the GNU General  Public License as published by the
31244+# Free Software Foundation;  either version 2 of the  License, or (at your
31245+# option) any later version.
31246+#
31247+# This program is distributed in the hope that it will be useful,
31248+# but WITHOUT ANY WARRANTY; without even the implied warranty of
31249+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31250+# GNU General Public License for more details.
31251+#
31252+# You should have received a copy of the GNU General Public License
31253+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
31254+#
31255+#
31256+
31257+#
31258+# drivers/mtd/nand/hifmc100/Makefile
31259+#
31260+
31261+obj-y	+= hifmc_spi_nand_ids.o
31262+obj-y	+= hifmc100.o hifmc100_os.o
31263diff --git a/drivers/mtd/nand/hifmc100/hifmc100.c b/drivers/mtd/nand/hifmc100/hifmc100.c
31264new file mode 100644
31265index 000000000..6cb12d3b6
31266--- /dev/null
31267+++ b/drivers/mtd/nand/hifmc100/hifmc100.c
31268@@ -0,0 +1,1218 @@
31269+/*
31270+ * The Flash Memory Controller v100 Device Driver for hisilicon
31271+ *
31272+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
31273+ *
31274+ * This program is free software; you can redistribute  it and/or modify it
31275+ * under  the terms of  the GNU General  Public License as published by the
31276+ * Free Software Foundation;  either version 2 of the  License, or (at your
31277+ * option) any later version.
31278+ *
31279+ * This program is distributed in the hope that it will be useful,
31280+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
31281+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31282+ * GNU General Public License for more details.
31283+ *
31284+ * You should have received a copy of the GNU General Public License
31285+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
31286+ *
31287+ */
31288+
31289+#include <linux/kernel.h>
31290+#include <linux/module.h>
31291+#include <linux/clk.h>
31292+#include <linux/io.h>
31293+#include <linux/errno.h>
31294+#include <linux/slab.h>
31295+#include <linux/mtd/rawnand.h>
31296+#include <linux/delay.h>
31297+#include <linux/sched.h>
31298+#include <asm/setup.h>
31299+
31300+#include "../raw/hinfc_gen.h"
31301+#include "hifmc100.h"
31302+#include <linux/mfd/hisi_fmc.h>
31303+
31304+static void hifmc100_switch_to_spi_nand(struct hifmc_host *host)
31305+{
31306+	u32 reg;
31307+
31308+	reg = hifmc_readl(host, FMC_CFG);
31309+	reg &= ~FLASH_TYPE_SEL_MASK;
31310+	reg |= FMC_CFG_FLASH_SEL(FLASH_TYPE_SPI_NAND);
31311+	hifmc_writel(host, FMC_CFG, reg);
31312+}
31313+
31314+static void hifmc100_set_str_mode(const struct hifmc_host *host)
31315+{
31316+	u32 reg;
31317+
31318+	reg = hifmc_readl(host, FMC_GLOBAL_CFG);
31319+	reg &= (~FMC_GLOBAL_CFG_DTR_MODE);
31320+	hifmc_writel(host, FMC_GLOBAL_CFG, reg);
31321+}
31322+
31323+static void hifmc100_operation_config(struct hifmc_host *host, int op)
31324+{
31325+	int ret;
31326+	unsigned long clkrate = 0;
31327+	struct hifmc_spi *spi = host->spi;
31328+
31329+	hifmc100_switch_to_spi_nand(host);
31330+	clk_prepare_enable(host->clk);
31331+	switch (op) {
31332+	case OP_STYPE_WRITE:
31333+		clkrate = min((u_long)host->clkrate,
31334+			      (u_long)CLK_FMC_TO_CRG_MHZ(spi->write->clock));
31335+		break;
31336+	case OP_STYPE_READ:
31337+		clkrate = min((u_long)host->clkrate,
31338+			      (u_long)CLK_FMC_TO_CRG_MHZ(spi->read->clock));
31339+		break;
31340+	case OP_STYPE_ERASE:
31341+		clkrate = min((u_long)host->clkrate,
31342+			      (u_long)CLK_FMC_TO_CRG_MHZ(spi->erase->clock));
31343+		break;
31344+	default:
31345+		break;
31346+	}
31347+
31348+	ret = clk_set_rate(host->clk, clkrate);
31349+	if (WARN_ON(ret)) {
31350+		pr_err("clk_set_rate failed: %d\n", ret);
31351+	}
31352+}
31353+
31354+static void hifmc100_send_cmd_write(struct hifmc_host *host)
31355+{
31356+	unsigned char pages_per_block_shift;
31357+	unsigned int reg, block_num, block_num_h, page_num;
31358+	int ret;
31359+	struct hifmc_spi *spi = host->spi;
31360+	struct nand_chip *chip = host->chip;
31361+#ifdef HIFMC100_SPI_NAND_SUPPORT_REG_WRITE
31362+	const char *op = "Reg";
31363+#else
31364+	const char *op = "Dma";
31365+#endif
31366+
31367+	if (WR_DBG) {
31368+		pr_info("\n");
31369+	}
31370+	FMC_PR(WR_DBG, "*-Start send %s page write command\n", op);
31371+
31372+	mutex_lock(host->lock);
31373+	hifmc100_operation_config(host, OP_STYPE_WRITE);
31374+
31375+	ret = spi->driver->wait_ready(spi);
31376+	if (ret) {
31377+		DB_MSG("Error: %s program wait ready failed! status: %#x\n",
31378+		       op, ret);
31379+		goto end;
31380+	}
31381+
31382+	ret = spi->driver->write_enable(spi);
31383+	if (ret) {
31384+		DB_MSG("Error: %s program write enable failed! ret: %#x\n",
31385+		       op, ret);
31386+		goto end;
31387+	}
31388+
31389+	reg = FMC_INT_CLR_ALL;
31390+	hifmc_writel(host, FMC_INT_CLR, reg);
31391+	FMC_PR(WR_DBG, "|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg);
31392+
31393+	reg = OP_CFG_FM_CS(host->cmd_op.cs)
31394+	      | OP_CFG_MEM_IF_TYPE(spi->write->iftype)
31395+	      | OP_CFG_OEN_EN;
31396+	hifmc_writel(host, FMC_OP_CFG, reg);
31397+	FMC_PR(WR_DBG, "|-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg);
31398+
31399+	pages_per_block_shift = chip->phys_erase_shift - chip->page_shift;
31400+	block_num = host->addr_value[1] >> pages_per_block_shift;
31401+	block_num_h = block_num >> REG_CNT_HIGH_BLOCK_NUM_SHIFT;
31402+	reg = FMC_ADDRH_SET(block_num_h);
31403+	hifmc_writel(host, FMC_ADDRH, reg);
31404+	FMC_PR(WR_DBG, "|-Set ADDRH[%#x]%#x\n", FMC_ADDRH, reg);
31405+
31406+	page_num = host->addr_value[1] - (block_num << pages_per_block_shift);
31407+	reg = ((block_num & REG_CNT_BLOCK_NUM_MASK) << REG_CNT_BLOCK_NUM_SHIFT)
31408+	      | ((page_num & REG_CNT_PAGE_NUM_MASK) << REG_CNT_PAGE_NUM_SHIFT);
31409+	hifmc_writel(host, FMC_ADDRL, reg);
31410+	FMC_PR(WR_DBG, "|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg);
31411+
31412+	*host->epm = 0x0000;
31413+
31414+#ifndef HIFMC100_SPI_NAND_SUPPORT_REG_WRITE
31415+	reg = host->dma_buffer;
31416+	hifmc_writel(host, FMC_DMA_SADDR_D0, reg);
31417+	FMC_PR(WR_DBG, "|-Set DMA_SADDR_D[0x40]%#x\n", reg);
31418+
31419+#ifdef CONFIG_64BIT
31420+	reg = (host->dma_buffer & FMC_DMA_SADDRH_MASK) >> 32;
31421+	hifmc_writel(host, FMC_DMA_SADDRH_D0, reg);
31422+	FMC_PR(WR_DBG, "\t|-Set DMA_SADDRH_D0[%#x]%#x\n", FMC_DMA_SADDRH_D0, reg);
31423+#endif
31424+
31425+	reg = host->dma_oob;
31426+	hifmc_writel(host, FMC_DMA_SADDR_OOB, reg);
31427+	FMC_PR(WR_DBG, "|-Set DMA_SADDR_OOB[%#x]%#x\n", FMC_DMA_SADDR_OOB, reg);
31428+#ifdef CONFIG_64BIT
31429+	reg = (host->dma_oob & FMC_DMA_SADDRH_MASK) >> 32;
31430+	hifmc_writel(host, FMC_DMA_SADDRH_OOB, reg);
31431+	FMC_PR(WR_DBG, "\t|-Set DMA_SADDRH_OOB[%#x]%#x\n", FMC_DMA_SADDRH_OOB,
31432+	       reg);
31433+#endif
31434+#endif
31435+
31436+	reg = OP_CTRL_WR_OPCODE(spi->write->cmd)
31437+#ifdef HIFMC100_SPI_NAND_SUPPORT_REG_WRITE
31438+	      | OP_CTRL_DMA_OP(OP_TYPE_REG)
31439+#else
31440+	      | OP_CTRL_DMA_OP(OP_TYPE_DMA)
31441+#endif
31442+	      | OP_CTRL_RW_OP(RW_OP_WRITE)
31443+	      | OP_CTRL_DMA_OP_READY;
31444+	hifmc_writel(host, FMC_OP_CTRL, reg);
31445+	FMC_PR(WR_DBG, "|-Set OP_CTRL[%#x]%#x\n", FMC_OP_CTRL, reg);
31446+
31447+	FMC_DMA_WAIT_INT_FINISH(host);
31448+
31449+end:
31450+	mutex_unlock(host->lock);
31451+	FMC_PR(WR_DBG, "*-End %s page program!\n", op);
31452+}
31453+
31454+static void hifmc100_send_cmd_status(struct hifmc_host *host)
31455+{
31456+	u_char status;
31457+	int ret;
31458+	unsigned char addr = STATUS_ADDR;
31459+	struct hifmc_spi *spi = NULL;
31460+
31461+	if(host == NULL || host->spi == NULL) {
31462+		DB_MSG("Error: host or host->spi is NULL!\n");
31463+		return;
31464+	}
31465+	spi = host->spi;
31466+	if (host->cmd_op.l_cmd == NAND_CMD_GET_FEATURES) {
31467+		addr = PROTECT_ADDR;
31468+	}
31469+
31470+	ret = spi_nand_feature_op(spi, GET_OP, addr, &status);
31471+	if (ret)
31472+		return;
31473+	FMC_PR((ER_DBG || WR_DBG), "\t*-Get status[%#x]: %#x\n", addr, status);
31474+}
31475+
31476+static void hifmc100_send_cmd_read(struct hifmc_host *host)
31477+{
31478+	unsigned char pages_per_block_shift;
31479+	unsigned int reg, block_num, block_num_h, page_num;
31480+	struct hifmc_spi *spi = host->spi;
31481+	struct nand_chip *chip = host->chip;
31482+	int ret;
31483+#ifdef HIFMC100_SPI_NAND_SUPPORT_REG_READ
31484+	char *op = "Reg";
31485+#else
31486+	char *op = "Dma";
31487+#endif
31488+
31489+	if (RD_DBG) {
31490+		pr_info("\n");
31491+	}
31492+	FMC_PR(RD_DBG, "\t*-Start %s page read\n", op);
31493+
31494+	if ((host->addr_value[0] == host->cache_addr_value[0])
31495+			&& (host->addr_value[1] == host->cache_addr_value[1])) {
31496+		FMC_PR(RD_DBG, "\t*-%s read cache hit, addr[%#x %#x]\n",
31497+		       op, host->addr_value[1], host->addr_value[0]);
31498+		return;
31499+	}
31500+
31501+	mutex_lock(host->lock);
31502+	hifmc100_operation_config(host, OP_STYPE_READ);
31503+
31504+	FMC_PR(RD_DBG, "\t|-Wait ready before %s page read\n", op);
31505+	ret = spi->driver->wait_ready(spi);
31506+	if (ret) {
31507+		DB_MSG("Error: %s read wait ready fail! ret: %#x\n", op, ret);
31508+		goto end;
31509+	}
31510+
31511+	reg = FMC_INT_CLR_ALL;
31512+	hifmc_writel(host, FMC_INT_CLR, reg);
31513+	FMC_PR(RD_DBG, "\t|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg);
31514+
31515+	if (host->cmd_op.l_cmd == NAND_CMD_READOOB)
31516+		host->cmd_op.op_cfg = OP_CTRL_RD_OP_SEL(RD_OP_READ_OOB);
31517+	else
31518+		host->cmd_op.op_cfg = OP_CTRL_RD_OP_SEL(RD_OP_READ_ALL_PAGE);
31519+
31520+	reg = OP_CFG_FM_CS(host->cmd_op.cs)
31521+	      | OP_CFG_MEM_IF_TYPE(spi->read->iftype)
31522+	      | OP_CFG_DUMMY_NUM(spi->read->dummy)
31523+	      | OP_CFG_OEN_EN;
31524+	hifmc_writel(host, FMC_OP_CFG, reg);
31525+	FMC_PR(RD_DBG, "\t|-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg);
31526+
31527+	pages_per_block_shift = chip->phys_erase_shift - chip->page_shift;
31528+	block_num = host->addr_value[1] >> pages_per_block_shift;
31529+	block_num_h = block_num >> REG_CNT_HIGH_BLOCK_NUM_SHIFT;
31530+
31531+	reg = FMC_ADDRH_SET(block_num_h);
31532+	hifmc_writel(host, FMC_ADDRH, reg);
31533+	FMC_PR(RD_DBG, "\t|-Set ADDRH[%#x]%#x\n", FMC_ADDRH, reg);
31534+
31535+	page_num = host->addr_value[1] - (block_num << pages_per_block_shift);
31536+	reg = ((block_num & REG_CNT_BLOCK_NUM_MASK) << REG_CNT_BLOCK_NUM_SHIFT)
31537+	      | ((page_num & REG_CNT_PAGE_NUM_MASK) << REG_CNT_PAGE_NUM_SHIFT);
31538+	hifmc_writel(host, FMC_ADDRL, reg);
31539+	FMC_PR(RD_DBG, "\t|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg);
31540+
31541+#ifndef HIFMC100_SPI_NAND_SUPPORT_REG_READ
31542+	reg = host->dma_buffer;
31543+	hifmc_writel(host, FMC_DMA_SADDR_D0, reg);
31544+	FMC_PR(RD_DBG, "\t|-Set DMA_SADDR_D0[%#x]%#x\n", FMC_DMA_SADDR_D0, reg);
31545+
31546+#ifdef CONFIG_64BIT
31547+	reg = (host->dma_buffer & FMC_DMA_SADDRH_MASK) >> 32;
31548+	hifmc_writel(host, FMC_DMA_SADDRH_D0, reg);
31549+	FMC_PR(RD_DBG, "\t|-Set DMA_SADDRH_D0[%#x]%#x\n", FMC_DMA_SADDRH_D0, reg);
31550+#endif
31551+
31552+	reg = host->dma_oob;
31553+	hifmc_writel(host, FMC_DMA_SADDR_OOB, reg);
31554+	FMC_PR(RD_DBG, "\t|-Set DMA_SADDR_OOB[%#x]%#x\n", FMC_DMA_SADDR_OOB,
31555+	       reg);
31556+
31557+#ifdef CONFIG_64BIT
31558+	reg = (host->dma_oob & FMC_DMA_SADDRH_MASK) >> 32;
31559+	hifmc_writel(host, FMC_DMA_SADDRH_OOB, reg);
31560+	FMC_PR(RD_DBG, "\t|-Set DMA_SADDRH_OOB[%#x]%#x\n", FMC_DMA_SADDRH_OOB,
31561+	       reg);
31562+#endif
31563+#endif
31564+
31565+	reg = OP_CTRL_RD_OPCODE(spi->read->cmd) | host->cmd_op.op_cfg
31566+#ifdef HIFMC100_SPI_NAND_SUPPORT_REG_READ
31567+	      | OP_CTRL_DMA_OP(OP_TYPE_REG)
31568+#else
31569+	      | OP_CTRL_DMA_OP(OP_TYPE_DMA)
31570+#endif
31571+	      | OP_CTRL_RW_OP(RW_OP_READ) | OP_CTRL_DMA_OP_READY;
31572+	hifmc_writel(host, FMC_OP_CTRL, reg);
31573+	FMC_PR(RD_DBG, "\t|-Set OP_CTRL[%#x]%#x\n", FMC_OP_CTRL, reg);
31574+
31575+	FMC_DMA_WAIT_INT_FINISH(host);
31576+
31577+	host->cache_addr_value[0] = host->addr_value[0];
31578+	host->cache_addr_value[1] = host->addr_value[1];
31579+
31580+end:
31581+	mutex_unlock(host->lock);
31582+	FMC_PR(RD_DBG, "\t*-End %s page read\n", op);
31583+}
31584+
31585+static void hifmc100_send_cmd_erase(struct hifmc_host *host)
31586+{
31587+	unsigned int reg;
31588+	struct hifmc_spi *spi = host->spi;
31589+	int ret;
31590+
31591+	if (ER_DBG) {
31592+		pr_info("\n");
31593+	}
31594+	FMC_PR(ER_DBG, "\t*-Start send cmd erase!\n");
31595+
31596+	mutex_lock(host->lock);
31597+	hifmc100_operation_config(host, OP_STYPE_ERASE);
31598+
31599+	ret = spi->driver->wait_ready(spi);
31600+	FMC_PR(ER_DBG, "\t|-Erase wait ready, ret: %#x\n", ret);
31601+	if (ret) {
31602+		DB_MSG("Error: Erase wait ready fail! status: %#x\n", ret);
31603+		goto end;
31604+	}
31605+
31606+	ret = spi->driver->write_enable(spi);
31607+	if (ret) {
31608+		DB_MSG("Error: Erase write enable failed! ret: %#x\n", ret);
31609+		goto end;
31610+	}
31611+
31612+	reg = FMC_INT_CLR_ALL;
31613+	hifmc_writel(host, FMC_INT_CLR, reg);
31614+	FMC_PR(ER_DBG, "\t|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg);
31615+
31616+	reg = spi->erase->cmd;
31617+	hifmc_writel(host, FMC_CMD, FMC_CMD_CMD1(reg));
31618+	FMC_PR(ER_DBG, "\t|-Set CMD[%#x]%#x\n", FMC_CMD, reg);
31619+
31620+	reg = FMC_ADDRL_BLOCK_H_MASK(host->addr_value[1])
31621+	      | FMC_ADDRL_BLOCK_L_MASK(host->addr_value[0]);
31622+	hifmc_writel(host, FMC_ADDRL, reg);
31623+	FMC_PR(ER_DBG, "\t|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg);
31624+
31625+	reg = OP_CFG_FM_CS(host->cmd_op.cs)
31626+	      | OP_CFG_MEM_IF_TYPE(spi->erase->iftype)
31627+	      | OP_CFG_ADDR_NUM(STD_OP_ADDR_NUM)
31628+	      | OP_CFG_DUMMY_NUM(spi->erase->dummy)
31629+	      | OP_CFG_OEN_EN;
31630+	hifmc_writel(host, FMC_OP_CFG, reg);
31631+	FMC_PR(ER_DBG, "\t|-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg);
31632+
31633+	reg = FMC_OP_CMD1_EN
31634+	      | FMC_OP_ADDR_EN
31635+	      | FMC_OP_REG_OP_START;
31636+	hifmc_writel(host, FMC_OP, reg);
31637+	FMC_PR(ER_DBG, "\t|-Set OP[%#x]%#x\n", FMC_OP, reg);
31638+
31639+	FMC_CMD_WAIT_CPU_FINISH(host);
31640+
31641+end:
31642+	mutex_unlock(host->lock);
31643+	FMC_PR(ER_DBG, "\t*-End send cmd erase!\n");
31644+}
31645+
31646+void hifmc100_ecc0_switch(struct hifmc_host *host, unsigned char op)
31647+{
31648+	unsigned int config;
31649+#if EC_DBG
31650+	unsigned int cmp_cfg;
31651+
31652+	if(host == NULL) {
31653+		DB_MSG("Error: host is NULL!\n");
31654+		return;
31655+	}
31656+	config = hifmc_readl(host, FMC_CFG);
31657+	FMC_PR(EC_DBG, "\t *-Get CFG[%#x]%#x\n", FMC_CFG, config);
31658+
31659+	if (op) {
31660+		cmp_cfg = host->fmc_cfg;
31661+	} else {
31662+		cmp_cfg = host->fmc_cfg_ecc0;
31663+	}
31664+
31665+	if (cmp_cfg != config)
31666+		DB_MSG("Warning: FMC config[%#x] is different.\n",
31667+		       cmp_cfg);
31668+#endif
31669+	if(host == NULL) {
31670+		DB_MSG("Error: host is NULL!\n");
31671+		return;
31672+	}
31673+	if (op == ENABLE) {
31674+		config = host->fmc_cfg_ecc0;
31675+	} else if (op == DISABLE) {
31676+		config = host->fmc_cfg;
31677+	} else {
31678+		DB_MSG("Error: Invalid opcode: %d\n", op);
31679+		return;
31680+	}
31681+
31682+	hifmc_writel(host, FMC_CFG, config);
31683+	FMC_PR(EC_DBG, "\t *-Set CFG[%#x]%#x\n", FMC_CFG, config);
31684+}
31685+
31686+static void hifmc100_send_cmd_readid(struct hifmc_host *host)
31687+{
31688+	unsigned int reg;
31689+
31690+	FMC_PR(BT_DBG, "\t|*-Start send cmd read ID\n");
31691+
31692+	hifmc100_ecc0_switch(host, ENABLE);
31693+
31694+	reg = FMC_CMD_CMD1(SPI_CMD_RDID);
31695+	hifmc_writel(host, FMC_CMD, reg);
31696+	FMC_PR(BT_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, reg);
31697+
31698+	reg = READ_ID_ADDR;
31699+	hifmc_writel(host, FMC_ADDRL, reg);
31700+	FMC_PR(BT_DBG, "\t||-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg);
31701+
31702+	reg = OP_CFG_FM_CS(host->cmd_op.cs)
31703+	      | OP_CFG_ADDR_NUM(READ_ID_ADDR_NUM)
31704+	      | OP_CFG_OEN_EN;
31705+	hifmc_writel(host, FMC_OP_CFG, reg);
31706+	FMC_PR(BT_DBG, "\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg);
31707+
31708+	reg = FMC_DATA_NUM_CNT(MAX_SPI_NAND_ID_LEN);
31709+	hifmc_writel(host, FMC_DATA_NUM, reg);
31710+	FMC_PR(BT_DBG, "\t||-Set DATA_NUM[%#x]%#x\n", FMC_DATA_NUM, reg);
31711+
31712+	reg = FMC_OP_CMD1_EN
31713+	      | FMC_OP_ADDR_EN
31714+	      | FMC_OP_READ_DATA_EN
31715+	      | FMC_OP_REG_OP_START;
31716+	hifmc_writel(host, FMC_OP, reg);
31717+	FMC_PR(BT_DBG, "\t||-Set OP[%#x]%#x\n", FMC_OP, reg);
31718+
31719+	host->addr_cycle = 0x0;
31720+
31721+	FMC_CMD_WAIT_CPU_FINISH(host);
31722+
31723+	hifmc100_ecc0_switch(host, DISABLE);
31724+
31725+	FMC_PR(BT_DBG, "\t|*-End read flash ID\n");
31726+}
31727+
31728+static void hifmc100_send_cmd_reset(struct hifmc_host *host)
31729+{
31730+	unsigned int reg;
31731+
31732+	FMC_PR(BT_DBG, "\t|*-Start send cmd reset\n");
31733+
31734+	reg = FMC_CMD_CMD1(SPI_CMD_RESET);
31735+	hifmc_writel(host, FMC_CMD, reg);
31736+	FMC_PR(BT_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, reg);
31737+
31738+	reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN;
31739+	hifmc_writel(host, FMC_OP_CFG, reg);
31740+	FMC_PR(BT_DBG, "\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg);
31741+
31742+	reg = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START;
31743+	hifmc_writel(host, FMC_OP, reg);
31744+	FMC_PR(BT_DBG, "\t||-Set OP[%#x]%#x\n", FMC_OP, reg);
31745+
31746+	FMC_CMD_WAIT_CPU_FINISH(host);
31747+
31748+	FMC_PR(BT_DBG, "\t|*-End send cmd reset\n");
31749+}
31750+
31751+static void hifmc100_host_init(struct hifmc_host *host)
31752+{
31753+	unsigned int reg;
31754+
31755+	FMC_PR(BT_DBG, "\t||*-Start SPI Nand host init\n");
31756+
31757+	reg = hifmc_readl(host, FMC_CFG);
31758+	if ((reg & FMC_CFG_OP_MODE_MASK) == FMC_CFG_OP_MODE_BOOT) {
31759+		reg |= FMC_CFG_OP_MODE(FMC_CFG_OP_MODE_NORMAL);
31760+		hifmc_writel(host, FMC_CFG, reg);
31761+		FMC_PR(BT_DBG, "\t|||-Set CFG[%#x]%#x\n", FMC_CFG, reg);
31762+	}
31763+
31764+	host->fmc_cfg = reg;
31765+	host->fmc_cfg_ecc0 = (reg & ~ECC_TYPE_MASK) | ECC_TYPE_0BIT;
31766+
31767+	reg = hifmc_readl(host, FMC_GLOBAL_CFG);
31768+	if (reg & FMC_GLOBAL_CFG_WP_ENABLE) {
31769+		reg &= ~FMC_GLOBAL_CFG_WP_ENABLE;
31770+		hifmc_writel(host, FMC_GLOBAL_CFG, reg);
31771+	}
31772+
31773+	host->addr_cycle = 0;
31774+	host->addr_value[0] = 0;
31775+	host->addr_value[1] = 0;
31776+	host->cache_addr_value[0] = ~0;
31777+	host->cache_addr_value[1] = ~0;
31778+
31779+	host->send_cmd_write = hifmc100_send_cmd_write;
31780+	host->send_cmd_status = hifmc100_send_cmd_status;
31781+	host->send_cmd_read = hifmc100_send_cmd_read;
31782+	host->send_cmd_erase = hifmc100_send_cmd_erase;
31783+	host->send_cmd_readid = hifmc100_send_cmd_readid;
31784+	host->send_cmd_reset = hifmc100_send_cmd_reset;
31785+#ifdef CONFIG_PM
31786+	host->suspend = hifmc100_suspend;
31787+	host->resume  = hifmc100_resume;
31788+#endif
31789+
31790+	reg = TIMING_CFG_TCSH(CS_HOLD_TIME)
31791+	      | TIMING_CFG_TCSS(CS_SETUP_TIME)
31792+	      | TIMING_CFG_TSHSL(CS_DESELECT_TIME);
31793+	hifmc_writel(host, FMC_SPI_TIMING_CFG, reg);
31794+
31795+	reg = ALL_BURST_ENABLE;
31796+	hifmc_writel(host, FMC_DMA_AHB_CTRL, reg);
31797+
31798+	FMC_PR(BT_DBG, "\t||*-End SPI Nand host init\n");
31799+}
31800+
31801+static unsigned char hifmc100_read_byte(struct mtd_info *mtd)
31802+{
31803+	struct nand_chip *chip = mtd_to_nand(mtd);
31804+	struct hifmc_host *host = chip->priv;
31805+	unsigned char value;
31806+	unsigned char ret_val = 0;
31807+
31808+	if (host->cmd_op.l_cmd == NAND_CMD_READID) {
31809+		value = hifmc_readb(host->iobase + host->offset);
31810+		host->offset++;
31811+		if (host->cmd_op.data_no == host->offset) {
31812+			host->cmd_op.l_cmd = 0;
31813+		}
31814+		return value;
31815+	}
31816+
31817+	if (host->cmd_op.cmd == NAND_CMD_STATUS) {
31818+		value = hifmc_readl(host, FMC_STATUS);
31819+		if (host->cmd_op.l_cmd == NAND_CMD_GET_FEATURES) {
31820+			FMC_PR((ER_DBG || WR_DBG), "\t\tRead BP status:%#x\n",
31821+			       value);
31822+			if (ANY_BP_ENABLE(value)) {
31823+				ret_val |= NAND_STATUS_WP;
31824+			}
31825+
31826+			host->cmd_op.l_cmd = NAND_CMD_STATUS;
31827+		}
31828+
31829+		if (!(value & STATUS_OIP_MASK)) {
31830+			ret_val |= NAND_STATUS_READY;
31831+		}
31832+
31833+		if (value & STATUS_E_FAIL_MASK) {
31834+			FMC_PR(ER_DBG, "\t\tGet erase status: %#x\n", value);
31835+			ret_val |= NAND_STATUS_FAIL;
31836+		}
31837+
31838+		if (value & STATUS_P_FAIL_MASK) {
31839+			FMC_PR(WR_DBG, "\t\tGet write status: %#x\n", value);
31840+			ret_val |= NAND_STATUS_FAIL;
31841+		}
31842+
31843+		return ret_val;
31844+	}
31845+
31846+	if (host->cmd_op.l_cmd == NAND_CMD_READOOB) {
31847+		value  = hifmc_readb(host->buffer + host->pagesize + host->offset);
31848+		host->offset++;
31849+		return value;
31850+	}
31851+
31852+	host->offset++;
31853+
31854+	return hifmc_readb(host->buffer + host->column + host->offset - 1);
31855+}
31856+
31857+static unsigned short hifmc100_read_word(struct mtd_info *mtd)
31858+{
31859+	struct nand_chip *chip = mtd_to_nand(mtd);
31860+	struct hifmc_host *host = chip->priv;
31861+
31862+	host->offset += 2;
31863+	return hifmc_readw(host->buffer + host->column + host->offset - 2);
31864+}
31865+
31866+static void hifmc100_write_buf(struct mtd_info *mtd,
31867+			       const u_char *buf, int len)
31868+{
31869+	struct nand_chip *chip = mtd_to_nand(mtd);
31870+	struct hifmc_host *host = chip->priv;
31871+
31872+#ifdef HIFMC100_SPI_NAND_SUPPORT_REG_WRITE
31873+	if (buf == chip->oob_poi) {
31874+		memcpy((char *)host->iobase + host->pagesize, buf, len);
31875+	} else {
31876+		memcpy((char *)host->iobase, buf, len);
31877+	}
31878+#else
31879+	if (buf == chip->oob_poi) {
31880+		memcpy((char *)(host->buffer + host->pagesize), buf, len);
31881+	} else {
31882+		memcpy((char *)host->buffer, buf, len);
31883+	}
31884+#endif
31885+	return;
31886+}
31887+
31888+static void hifmc100_read_buf(struct mtd_info *mtd, u_char *buf, int len)
31889+{
31890+	struct nand_chip *chip = mtd_to_nand(mtd);
31891+	struct hifmc_host *host = chip->priv;
31892+
31893+#ifdef HIFMC100_SPI_NAND_SUPPORT_REG_READ
31894+	if (buf == chip->oob_poi) {
31895+		memcpy(buf, (char *)host->iobase + host->pagesize, len);
31896+	} else {
31897+		memcpy(buf, (char *)host->iobase, len);
31898+	}
31899+#else
31900+	if (buf == chip->oob_poi) {
31901+		memcpy(buf, (char *)host->buffer + host->pagesize, len);
31902+	} else {
31903+		memcpy(buf, (char *)host->buffer, len);
31904+	}
31905+#endif
31906+
31907+#ifdef CONFIG_HISI_NAND_ECC_STATUS_REPORT
31908+	if (buf != chip->oob_poi) {
31909+		u_int reg;
31910+		u_int ecc_step = host->pagesize >> 10;
31911+
31912+		reg = hifmc_readl(host, HIFMC100_ECC_ERR_NUM0_BUF0);
31913+		while (ecc_step) {
31914+			u_char err_num;
31915+
31916+			err_num = GET_ECC_ERR_NUM(--ecc_step, reg);
31917+			if (err_num == 0xff) {
31918+				mtd->ecc_stats.failed++;
31919+			} else {
31920+				mtd->ecc_stats.corrected += err_num;
31921+			}
31922+		}
31923+	}
31924+#endif
31925+
31926+	return;
31927+}
31928+
31929+static void hifmc100_select_chip(struct mtd_info *mtd, int chipselect)
31930+{
31931+	struct nand_chip *chip = mtd_to_nand(mtd);
31932+	struct hifmc_host *host = chip->priv;
31933+
31934+	if (chipselect < 0) {
31935+		mutex_unlock(&fmc_switch_mutex);
31936+		return;
31937+	}
31938+
31939+	mutex_lock(&fmc_switch_mutex);
31940+
31941+	if (chipselect > CONFIG_SPI_NAND_MAX_CHIP_NUM) {
31942+		DB_BUG("Error: Invalid chipselect: %d\n", chipselect);
31943+	}
31944+
31945+	if (host->mtd != mtd) {
31946+		host->mtd = mtd;
31947+		host->cmd_op.cs = chipselect;
31948+	}
31949+
31950+	if (!(chip->options & NAND_BROKEN_XD)) {
31951+		if ((chip->state == FL_ERASING) || (chip->state == FL_WRITING)) {
31952+			host->cmd_op.l_cmd = NAND_CMD_GET_FEATURES;
31953+		}
31954+	}
31955+}
31956+
31957+static void hifmc100_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned ctrl)
31958+{
31959+	unsigned char cmd;
31960+	int is_cache_invalid = 1;
31961+	struct nand_chip *chip = mtd_to_nand(mtd);
31962+	struct hifmc_host *host = chip->priv;
31963+	unsigned int udat = (unsigned int)dat;
31964+
31965+	if (ctrl & NAND_ALE) {
31966+		unsigned int addr_value = 0;
31967+		unsigned int addr_offset = 0;
31968+
31969+		if (ctrl & NAND_CTRL_CHANGE) {
31970+			host->addr_cycle = 0x0;
31971+			host->addr_value[0] = 0x0;
31972+			host->addr_value[1] = 0x0;
31973+		}
31974+		addr_offset = host->addr_cycle << 3;
31975+
31976+		if (host->addr_cycle >= HIFMC100_ADDR_CYCLE_MASK) {
31977+			addr_offset = (host->addr_cycle -
31978+				       HIFMC100_ADDR_CYCLE_MASK) << 3;
31979+			addr_value = 1;
31980+		}
31981+		host->addr_value[addr_value] |=
31982+			((udat & 0xff) << addr_offset);
31983+
31984+		host->addr_cycle++;
31985+	}
31986+
31987+	if ((ctrl & NAND_CLE) && (ctrl & NAND_CTRL_CHANGE)) {
31988+		cmd = udat & 0xff;
31989+		host->cmd_op.cmd = cmd;
31990+		switch (cmd) {
31991+		case NAND_CMD_PAGEPROG:
31992+			host->offset = 0;
31993+			host->send_cmd_write(host);
31994+			break;
31995+
31996+		case NAND_CMD_READSTART:
31997+			is_cache_invalid = 0;
31998+			if (host->addr_value[0] == host->pagesize) {
31999+				host->cmd_op.l_cmd = NAND_CMD_READOOB;
32000+			}
32001+			host->send_cmd_read(host);
32002+			break;
32003+
32004+		case NAND_CMD_ERASE2:
32005+			host->send_cmd_erase(host);
32006+			break;
32007+
32008+		case NAND_CMD_READID:
32009+			memset((u_char *)(host->iobase), 0,
32010+			       MAX_SPI_NAND_ID_LEN);
32011+			host->cmd_op.l_cmd = cmd;
32012+			host->cmd_op.data_no = MAX_SPI_NAND_ID_LEN;
32013+			host->send_cmd_readid(host);
32014+			break;
32015+
32016+		case NAND_CMD_STATUS:
32017+			host->send_cmd_status(host);
32018+			break;
32019+
32020+		case NAND_CMD_READ0:
32021+			host->cmd_op.l_cmd = cmd;
32022+			break;
32023+
32024+		case NAND_CMD_RESET:
32025+			host->send_cmd_reset(host);
32026+			break;
32027+
32028+		case NAND_CMD_SEQIN:
32029+		case NAND_CMD_ERASE1:
32030+		default:
32031+			break;
32032+		}
32033+	}
32034+
32035+	if ((dat == NAND_CMD_NONE) && host->addr_cycle) {
32036+		if (host->cmd_op.cmd == NAND_CMD_SEQIN
32037+				|| host->cmd_op.cmd == NAND_CMD_READ0
32038+				|| host->cmd_op.cmd == NAND_CMD_READID) {
32039+			host->offset = 0x0;
32040+			host->column = (host->addr_value[0] & 0xffff);
32041+		}
32042+	}
32043+
32044+	if (is_cache_invalid) {
32045+		host->cache_addr_value[0] = ~0;
32046+		host->cache_addr_value[1] = ~0;
32047+	}
32048+}
32049+
32050+static int hifmc100_dev_ready(struct mtd_info *mtd)
32051+{
32052+	unsigned int reg;
32053+	unsigned long deadline = jiffies + FMC_MAX_READY_WAIT_JIFFIES;
32054+	struct nand_chip *chip = mtd_to_nand(mtd);
32055+	struct hifmc_host *host = chip->priv;
32056+
32057+	do {
32058+		reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN;
32059+		hifmc_writel(host, FMC_OP_CFG, reg);
32060+
32061+		reg = FMC_OP_READ_STATUS_EN | FMC_OP_REG_OP_START;
32062+		hifmc_writel(host, FMC_OP, reg);
32063+
32064+		FMC_CMD_WAIT_CPU_FINISH(host);
32065+
32066+		reg = hifmc_readl(host, FMC_STATUS);
32067+
32068+		if (!(reg & STATUS_OIP_MASK)) {
32069+			return NAND_STATUS_READY;
32070+		}
32071+
32072+		cond_resched();
32073+	} while (!time_after_eq(jiffies, deadline));
32074+
32075+	if (!(chip->options & NAND_SCAN_SILENT_NODEV)) {
32076+		pr_warn("Wait SPI nand ready timeout, status: %#x\n", reg);
32077+	}
32078+
32079+	return 0;
32080+}
32081+
32082+/*
32083+ * 'host->epm' only use the first oobfree[0] field, it looks very simple, But...
32084+ */
32085+/* Default OOB area layout */
32086+static int hifmc_ooblayout_ecc_default(struct mtd_info *mtd, int section,
32087+				       struct mtd_oob_region *oobregion)
32088+{
32089+	if (section) {
32090+		return -ERANGE;
32091+	}
32092+
32093+	oobregion->length = 32;
32094+	oobregion->offset = 32;
32095+
32096+	return 0;
32097+}
32098+
32099+static int hifmc_ooblayout_free_default(struct mtd_info *mtd, int section,
32100+					struct mtd_oob_region *oobregion)
32101+{
32102+	if (section) {
32103+		return -ERANGE;
32104+	}
32105+
32106+	oobregion->length = 30;
32107+	oobregion->offset = 2;
32108+
32109+	return 0;
32110+}
32111+
32112+static struct mtd_ooblayout_ops hifmc_ooblayout_default_ops = {
32113+	.ecc = hifmc_ooblayout_ecc_default,
32114+	.free = hifmc_ooblayout_free_default,
32115+};
32116+
32117+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2
32118+static int hifmc_ooblayout_ecc_4k16bit(struct mtd_info *mtd, int section,
32119+				       struct mtd_oob_region *oobregion)
32120+{
32121+	if (section) {
32122+		return -ERANGE;
32123+	}
32124+
32125+	oobregion->length = 14;
32126+	oobregion->offset = 14;
32127+
32128+	return 0;
32129+}
32130+
32131+static int hifmc_ooblayout_free_4k16bit(struct mtd_info *mtd, int section,
32132+					struct mtd_oob_region *oobregion)
32133+{
32134+	if (section) {
32135+		return -ERANGE;
32136+	}
32137+
32138+	oobregion->length = 14;
32139+	oobregion->offset = 2;
32140+
32141+	return 0;
32142+}
32143+
32144+static struct mtd_ooblayout_ops hifmc_ooblayout_4k16bit_ops = {
32145+	.ecc = hifmc_ooblayout_ecc_4k16bit,
32146+	.free = hifmc_ooblayout_free_4k16bit,
32147+};
32148+
32149+static int hifmc_ooblayout_ecc_2k16bit(struct mtd_info *mtd, int section,
32150+				       struct mtd_oob_region *oobregion)
32151+{
32152+	if (section) {
32153+		return -ERANGE;
32154+	}
32155+
32156+	oobregion->length = 6;
32157+	oobregion->offset = 6;
32158+
32159+	return 0;
32160+}
32161+
32162+static int hifmc_ooblayout_free_2k16bit(struct mtd_info *mtd, int section,
32163+					struct mtd_oob_region *oobregion)
32164+{
32165+	if (section) {
32166+		return -ERANGE;
32167+	}
32168+
32169+	oobregion->length = 6;
32170+	oobregion->offset = 2;
32171+
32172+	return 0;
32173+}
32174+
32175+static struct mtd_ooblayout_ops hifmc_ooblayout_2k16bit_ops = {
32176+	.ecc = hifmc_ooblayout_ecc_2k16bit,
32177+	.free = hifmc_ooblayout_free_2k16bit,
32178+};
32179+#endif
32180+
32181+static struct nand_config_info hifmc_spi_nand_config_table[] = {
32182+	{NAND_PAGE_4K,  NAND_ECC_24BIT, 24, 200,    &hifmc_ooblayout_default_ops},
32183+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2
32184+	{NAND_PAGE_4K,  NAND_ECC_16BIT, 16, 128,    &hifmc_ooblayout_4k16bit_ops},
32185+#endif
32186+	{NAND_PAGE_4K,  NAND_ECC_8BIT,  8, 128,     &hifmc_ooblayout_default_ops},
32187+	{NAND_PAGE_4K,  NAND_ECC_0BIT,  0, 32,      &hifmc_ooblayout_default_ops},
32188+	{NAND_PAGE_2K,  NAND_ECC_24BIT, 24, 128,    &hifmc_ooblayout_default_ops},
32189+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2
32190+	{NAND_PAGE_2K,  NAND_ECC_16BIT, 16, 64,     &hifmc_ooblayout_2k16bit_ops},
32191+#endif
32192+	{NAND_PAGE_2K,  NAND_ECC_8BIT,  8, 64,      &hifmc_ooblayout_default_ops},
32193+	{NAND_PAGE_2K,  NAND_ECC_0BIT,  0, 32,      &hifmc_ooblayout_default_ops},
32194+	{0, 0, 0, 0, NULL},
32195+};
32196+
32197+/*
32198+ * Auto-sensed the page size and ecc type value. driver will try each of page
32199+ * size and ecc type one by one till flash can be read and wrote accurately.
32200+ * so the page size and ecc type is match adaptively without switch on the board
32201+ */
32202+static struct nand_config_info *hifmc100_get_config_type_info(
32203+	struct mtd_info *mtd, struct nand_dev_t *nand_dev)
32204+{
32205+	struct nand_config_info *best = NULL;
32206+	struct nand_chip *chip = mtd_to_nand(mtd);
32207+	struct nand_config_info *info = hifmc_spi_nand_config_table;
32208+
32209+	nand_dev->start_type = "Auto";
32210+
32211+	for (; info->ooblayout_ops; info++) {
32212+		if (match_page_type_to_size(info->pagetype) != mtd->writesize) {
32213+			continue;
32214+		}
32215+
32216+		if (mtd->oobsize < info->oobsize) {
32217+			continue;
32218+		}
32219+
32220+		if (!best || (best->ecctype < info->ecctype)) {
32221+			best = info;
32222+		}
32223+	}
32224+
32225+	/* All SPI NAND are small-page, SLC */
32226+	chip->bits_per_cell = 1;
32227+
32228+	return best;
32229+}
32230+
32231+static void hifmc100_chip_init(struct nand_chip *chip)
32232+{
32233+	chip->read_byte = hifmc100_read_byte;
32234+	chip->read_word = hifmc100_read_word;
32235+	chip->write_buf = hifmc100_write_buf;
32236+	chip->read_buf = hifmc100_read_buf;
32237+
32238+	chip->select_chip = hifmc100_select_chip;
32239+
32240+	chip->cmd_ctrl = hifmc100_cmd_ctrl;
32241+	chip->dev_ready = hifmc100_dev_ready;
32242+
32243+	chip->chip_delay = FMC_CHIP_DELAY;
32244+
32245+	chip->options = NAND_SKIP_BBTSCAN | NAND_BROKEN_XD
32246+			| NAND_SCAN_SILENT_NODEV;
32247+
32248+	chip->ecc.mode = NAND_ECC_NONE;
32249+}
32250+
32251+static void hifmc100_set_oob_info(struct mtd_info *mtd,
32252+				  struct nand_config_info *info, struct nand_dev_t *nand_dev)
32253+{
32254+	struct nand_chip *chip = mtd_to_nand(mtd);
32255+	struct hifmc_host *host = chip->priv;
32256+	struct mtd_oob_region hifmc_oobregion = {0, 0};
32257+	if (info == NULL || mtd == NULL || nand_dev == NULL) {
32258+		DB_MSG("set oob info err!!!\n");
32259+		return;
32260+	}
32261+
32262+	if (info->ecctype != NAND_ECC_0BIT) {
32263+		mtd->oobsize = info->oobsize;
32264+	}
32265+
32266+	host->oobsize = mtd->oobsize;
32267+	nand_dev->oobsize = host->oobsize;
32268+
32269+	host->dma_oob = host->dma_buffer + host->pagesize;
32270+	host->bbm = (u_char *)(host->buffer + host->pagesize
32271+			       + HIFMC_BAD_BLOCK_POS);
32272+	if(info->ooblayout_ops == NULL) {
32273+		DB_MSG("Error: info->ooblayout_ops or is NULL!\n");
32274+		return;
32275+	}
32276+	info->ooblayout_ops->free(mtd, 0, &hifmc_oobregion);
32277+
32278+	mtd_set_ooblayout(mtd, info->ooblayout_ops);
32279+
32280+	/* EB bits locate in the bottom two of CTRL(30) */
32281+	host->epm = (u_short *)(host->buffer + host->pagesize
32282+				+ hifmc_oobregion.offset + 28);
32283+
32284+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2
32285+	if (best->ecctype == NAND_ECC_16BIT) {
32286+		if (host->pagesize == _2K) {
32287+			/* EB bits locate in the bottom two of CTRL(4) */
32288+			host->epm = (u_short *)(host->buffer + host->pagesize
32289+						+ hifmc_oobregion.offset + 4);
32290+		} else if (host->pagesize == _4K) {
32291+			/* EB bit locate in the bottom two of CTRL(14) */
32292+			host->epm = (u_short *)(host->buffer + host->pagesize
32293+						+ hifmc_oobregion.offset + 12);
32294+		}
32295+	}
32296+#endif
32297+}
32298+
32299+static unsigned int hifmc100_get_ecc_reg(struct hifmc_host *host,
32300+		const struct nand_config_info *info, struct nand_dev_t *nand_dev)
32301+{
32302+	if (info == NULL || host == NULL || nand_dev == NULL) {
32303+		DB_MSG("get ecc reg err!!!\n");
32304+		return 0;
32305+	}
32306+	host->ecctype = info->ecctype;
32307+	nand_dev->ecctype = host->ecctype;
32308+
32309+	return FMC_CFG_ECC_TYPE(match_ecc_type_to_reg(info->ecctype));
32310+}
32311+
32312+static unsigned int hifmc100_get_page_reg(struct hifmc_host *host,
32313+		const struct nand_config_info *info)
32314+{
32315+	if (info == NULL || host == NULL) {
32316+		DB_MSG("get page reg err!!!\n");
32317+		return 0;
32318+	}
32319+	host->pagesize = match_page_type_to_size(info->pagetype);
32320+
32321+	return FMC_CFG_PAGE_SIZE(match_page_type_to_reg(info->pagetype));
32322+}
32323+
32324+static unsigned int hifmc100_get_block_reg(struct hifmc_host *host,
32325+		const struct nand_config_info *info)
32326+{
32327+	unsigned int block_reg = 0;
32328+	unsigned int page_per_block = 0;
32329+	struct mtd_info *mtd = NULL;
32330+
32331+	if (info == NULL || host == NULL) {
32332+		DB_MSG("get block reg err!!!\n");
32333+		return 0;
32334+	}
32335+
32336+	mtd = host->mtd;
32337+	if(mtd == NULL) {
32338+		DB_MSG("err:mtd is NULL!!!\n");
32339+		return 0;
32340+	}
32341+	host->block_page_mask = ((mtd->erasesize / mtd->writesize) - 1);
32342+	page_per_block = mtd->erasesize / match_page_type_to_size(info->pagetype);
32343+	switch (page_per_block) {
32344+	case 64:
32345+		block_reg = BLOCK_SIZE_64_PAGE;
32346+		break;
32347+	case 128:
32348+		block_reg = BLOCK_SIZE_128_PAGE;
32349+		break;
32350+	case 256:
32351+		block_reg = BLOCK_SIZE_256_PAGE;
32352+		break;
32353+	case 512:
32354+		block_reg = BLOCK_SIZE_512_PAGE;
32355+		break;
32356+	default:
32357+		DB_MSG("Can't support block %#x and page %#x size\n",
32358+		       mtd->erasesize, mtd->writesize);
32359+	}
32360+
32361+	return FMC_CFG_BLOCK_SIZE(block_reg);
32362+}
32363+
32364+static void hifmc100_set_fmc_cfg_reg(struct hifmc_host *host,
32365+	const struct nand_config_info *type_info, struct nand_dev_t *nand_dev)
32366+{
32367+	unsigned int page_reg, ecc_reg, block_reg, reg_fmc_cfg;
32368+
32369+	ecc_reg = hifmc100_get_ecc_reg(host, type_info, nand_dev);
32370+	page_reg = hifmc100_get_page_reg(host, type_info);
32371+	block_reg = hifmc100_get_block_reg(host, type_info);
32372+
32373+	reg_fmc_cfg = hifmc_readl(host, FMC_CFG);
32374+	reg_fmc_cfg &= ~(PAGE_SIZE_MASK | ECC_TYPE_MASK | BLOCK_SIZE_MASK);
32375+	reg_fmc_cfg |= ecc_reg | page_reg | block_reg;
32376+	hifmc_writel(host, FMC_CFG, reg_fmc_cfg);
32377+
32378+	/* Save value of FMC_CFG and FMC_CFG_ECC0 to turn on/off ECC */
32379+	host->fmc_cfg = reg_fmc_cfg;
32380+	host->fmc_cfg_ecc0 = (host->fmc_cfg & ~ECC_TYPE_MASK) | ECC_TYPE_0BIT;
32381+	FMC_PR(BT_DBG, "\t|-Save FMC_CFG[%#x]: %#x and FMC_CFG_ECC0: %#x\n",
32382+	       FMC_CFG, host->fmc_cfg, host->fmc_cfg_ecc0);
32383+}
32384+
32385+static int hifmc100_set_config_info(struct mtd_info *mtd,
32386+				    struct nand_chip *chip, struct nand_dev_t *nand_dev)
32387+{
32388+	struct hifmc_host *host = chip->priv;
32389+	struct nand_config_info *type_info = NULL;
32390+
32391+	FMC_PR(BT_DBG, "\t*-Start config Block Page OOB and Ecc\n");
32392+
32393+	type_info = hifmc100_get_config_type_info(mtd, nand_dev);
32394+	WARN_ON(!type_info);
32395+	if (type_info == NULL) {
32396+		DB_MSG("set config info err!!!\n");
32397+		return 0;
32398+	}
32399+
32400+	FMC_PR(BT_DBG, "\t|-%s Config, PageSize %s EccType %s OOBSize %d\n",
32401+	       nand_dev->start_type, nand_page_name(type_info->pagetype),
32402+	       nand_ecc_name(type_info->ecctype), type_info->oobsize);
32403+
32404+	/* Set the page_size, ecc_type, block_size of FMC_CFG[0x0] register */
32405+	hifmc100_set_fmc_cfg_reg(host, type_info, nand_dev);
32406+
32407+	hifmc100_set_oob_info(mtd, type_info, nand_dev);
32408+
32409+	FMC_PR(BT_DBG, "\t*-End config Block Page Oob and Ecc\n");
32410+
32411+	return 0;
32412+}
32413+
32414+void hifmc100_spi_nand_init(struct nand_chip *chip)
32415+{
32416+	struct hifmc_host *host = NULL;
32417+
32418+	if((chip == NULL) || (chip->priv == NULL)) {
32419+		DB_MSG("Error: chip or chip->priv is NULL!\n");
32420+		return;
32421+	}
32422+	host = chip->priv;
32423+	FMC_PR(BT_DBG, "\t|*-Start hifmc100 SPI Nand init\n");
32424+
32425+	/* Switch SPI type to SPI nand */
32426+	hifmc100_switch_to_spi_nand(host);
32427+
32428+	/* hold on STR mode */
32429+	hifmc100_set_str_mode(host);
32430+
32431+	/* Hifmc host init */
32432+	hifmc100_host_init(host);
32433+	host->chip = chip;
32434+
32435+	/* Hifmc nand_chip struct init */
32436+	hifmc100_chip_init(chip);
32437+
32438+	hifmc_spi_nand_ids_register();
32439+	hinfc_param_adjust = hifmc100_set_config_info;
32440+
32441+	FMC_PR(BT_DBG, "\t|*-End hifmc100 SPI Nand init\n");
32442+}
32443+#ifdef CONFIG_PM
32444+int hifmc100_suspend(struct platform_device *pltdev, pm_message_t state)
32445+{
32446+	int ret;
32447+	struct hifmc_host *host = platform_get_drvdata(pltdev);
32448+	struct hifmc_spi *spi = host->spi;
32449+
32450+	mutex_lock(host->lock);
32451+	hifmc100_switch_to_spi_nand(host);
32452+
32453+	ret = spi->driver->wait_ready(spi);
32454+	if (ret) {
32455+		DB_MSG("Error: wait ready failed!");
32456+		clk_disable_unprepare(host->clk);
32457+		mutex_unlock(host->lock);
32458+		return 0;
32459+	}
32460+
32461+	clk_disable_unprepare(host->clk);
32462+	mutex_unlock(host->lock);
32463+
32464+	return 0;
32465+}
32466+
32467+int hifmc100_resume(struct platform_device *pltdev)
32468+{
32469+	int cs;
32470+	struct hifmc_host *host = platform_get_drvdata(pltdev);
32471+	struct nand_chip *chip = host->chip;
32472+
32473+	mutex_lock(host->lock);
32474+	hifmc100_switch_to_spi_nand(host);
32475+	clk_prepare_enable(host->clk);
32476+
32477+	for (cs = 0; cs < chip->numchips; cs++) {
32478+		host->send_cmd_reset(host);
32479+	}
32480+
32481+	hifmc100_spi_nand_config(host);
32482+
32483+	mutex_unlock(host->lock);
32484+	return 0;
32485+}
32486+#endif
32487diff --git a/drivers/mtd/nand/hifmc100/hifmc100.h b/drivers/mtd/nand/hifmc100/hifmc100.h
32488new file mode 100644
32489index 000000000..9f169f3d5
32490--- /dev/null
32491+++ b/drivers/mtd/nand/hifmc100/hifmc100.h
32492@@ -0,0 +1,354 @@
32493+/*
32494+ * The Flash Memory Controller v100 Device Driver for hisilicon
32495+ *
32496+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
32497+ *
32498+ * This program is free software; you can redistribute  it and/or modify it
32499+ * under  the terms of  the GNU General  Public License as published by the
32500+ * Free Software Foundation;  either version 2 of the  License, or (at your
32501+ * option) any later version.
32502+ *
32503+ * This program is distributed in the hope that it will be useful,
32504+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32505+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32506+ * GNU General Public License for more details.
32507+ *
32508+ * You should have received a copy of the GNU General Public License
32509+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
32510+ *
32511+ */
32512+
32513+#ifndef __HIFMC100_H__
32514+#define __HIFMC100_H__
32515+
32516+#include <linux/platform_device.h>
32517+#include <linux/mfd/hisi_fmc.h>
32518+
32519+#define INFINITE            (0xFFFFFFFF)
32520+
32521+#define SPI_IF_READ_STD         (0x01)
32522+#define SPI_IF_READ_FAST        (0x02)
32523+#define SPI_IF_READ_DUAL        (0x04)
32524+#define SPI_IF_READ_DUAL_ADDR       (0x08)
32525+#define SPI_IF_READ_QUAD        (0x10)
32526+#define SPI_IF_READ_QUAD_ADDR       (0x20)
32527+
32528+#define SPI_IF_WRITE_STD        (0x01)
32529+#define SPI_IF_WRITE_DUAL       (0x02)
32530+#define SPI_IF_WRITE_DUAL_ADDR      (0x04)
32531+#define SPI_IF_WRITE_QUAD       (0x08)
32532+#define SPI_IF_WRITE_QUAD_ADDR      (0x10)
32533+
32534+#define SPI_IF_ERASE_SECTOR_4K      (0x01)
32535+#define SPI_IF_ERASE_SECTOR_32K     (0x02)
32536+#define SPI_IF_ERASE_SECTOR_64K     (0x04)
32537+#define SPI_IF_ERASE_SECTOR_128K    (0x08)
32538+#define SPI_IF_ERASE_SECTOR_256K    (0x10)
32539+
32540+#define HIFMC_SPI_NAND_SUPPORT_READ (SPI_IF_READ_STD \
32541+                    | SPI_IF_READ_FAST \
32542+                    | SPI_IF_READ_DUAL \
32543+                    | SPI_IF_READ_DUAL_ADDR \
32544+                    | SPI_IF_READ_QUAD \
32545+                    | SPI_IF_READ_QUAD_ADDR)
32546+
32547+#define HIFMC_SPI_NAND_SUPPORT_WRITE    (SPI_IF_WRITE_STD | SPI_IF_WRITE_QUAD)
32548+
32549+#define HIFMC_SPI_NAND_SUPPORT_MAX_DUMMY    8
32550+
32551+#define SPI_CMD_READ_STD        0x03    /* Standard read cache */
32552+#define SPI_CMD_READ_FAST       0x0B    /* Higher speed read cache */
32553+#define SPI_CMD_READ_DUAL       0x3B    /* 2 IO read cache only date */
32554+#define SPI_CMD_READ_DUAL_ADDR      0xBB    /* 2 IO read cache date&addr */
32555+#define SPI_CMD_READ_QUAD       0x6B    /* 4 IO read cache only date */
32556+#define SPI_CMD_READ_QUAD_ADDR      0xEB    /* 4 IO read cache date&addr */
32557+
32558+#define SPI_CMD_WRITE_STD       0x02    /* Standard page program */
32559+#define SPI_CMD_WRITE_DUAL      0xA2    /* 2 IO program only date */
32560+#define SPI_CMD_WRITE_DUAL_ADDR     0xD2    /* 2 IO program date&addr */
32561+#define SPI_CMD_WRITE_QUAD      0x32    /* 4 IO program only date */
32562+#define SPI_CMD_WRITE_QUAD_ADDR     0x12    /* 4 IO program date&addr */
32563+
32564+#define SPI_CMD_SE_4K           0x20    /* 4KB sector Erase */
32565+#define SPI_CMD_SE_32K          0x52    /* 32KB sector Erase */
32566+#define SPI_CMD_SE_64K          0xD8    /* 64KB sector Erase */
32567+#define SPI_CMD_SE_128K         0xD8    /* 128KB sector Erase */
32568+#define SPI_CMD_SE_256K         0xD8    /* 256KB sector Erase */
32569+
32570+#define SET_READ_STD(_dummy_, _size_, _clk_) \
32571+    static struct spi_op read_std_##_dummy_##_size_##_clk_ = { \
32572+    SPI_IF_READ_STD, SPI_CMD_READ_STD, _dummy_, _size_, _clk_ }
32573+
32574+#define SET_READ_FAST(_dummy_, _size_, _clk_) \
32575+    static struct spi_op read_fast_##_dummy_##_size_##_clk_ = { \
32576+    SPI_IF_READ_FAST, SPI_CMD_READ_FAST, _dummy_, _size_, _clk_ }
32577+
32578+#define SET_READ_DUAL(_dummy_, _size_, _clk_) \
32579+    static struct spi_op read_dual_##_dummy_##_size_##_clk_ = { \
32580+    SPI_IF_READ_DUAL, SPI_CMD_READ_DUAL, _dummy_, _size_, _clk_ }
32581+
32582+#define SET_READ_DUAL_ADDR(_dummy_, _size_, _clk_) \
32583+    static struct spi_op read_dual_addr_##_dummy_##_size_##_clk_ = { \
32584+    SPI_IF_READ_DUAL_ADDR, SPI_CMD_READ_DUAL_ADDR, _dummy_, _size_, _clk_ }
32585+
32586+#define SET_READ_QUAD(_dummy_, _size_, _clk_) \
32587+    static struct spi_op read_quad_##_dummy_##_size_##_clk_ = { \
32588+    SPI_IF_READ_QUAD, SPI_CMD_READ_QUAD, _dummy_, _size_, _clk_ }
32589+
32590+#define SET_READ_QUAD_ADDR(_dummy_, _size_, _clk_) \
32591+    static struct spi_op read_quad_addr_##_dummy_##_size_##_clk_ = { \
32592+    SPI_IF_READ_QUAD_ADDR, SPI_CMD_READ_QUAD_ADDR, _dummy_, _size_, _clk_ }
32593+
32594+#define SET_WRITE_STD(_dummy_, _size_, _clk_) \
32595+    static struct spi_op write_std_##_dummy_##_size_##_clk_ = { \
32596+    SPI_IF_WRITE_STD, SPI_CMD_WRITE_STD, _dummy_, _size_, _clk_ }
32597+
32598+#define SET_WRITE_DUAL(_dummy_, _size_, _clk_) \
32599+    static struct spi_op write_dual_##_dummy_##_size_##_clk_ = { \
32600+    SPI_IF_WRITE_DUAL, SPI_CMD_WRITE_DUAL, _dummy_, _size_, _clk_ }
32601+
32602+#define SET_WRITE_DUAL_ADDR(_dummy_, _size_, _clk_) \
32603+    static struct spi_op write_dual_addr_##_dummy_##_size_##_clk_ = { \
32604+SPI_IF_WRITE_DUAL_ADDR, SPI_CMD_WRITE_DUAL_ADDR, _dummy_, _size_, _clk_ }
32605+
32606+#define SET_WRITE_QUAD(_dummy_, _size_, _clk_) \
32607+    static struct spi_op write_quad_##_dummy_##_size_##_clk_ = { \
32608+    SPI_IF_WRITE_QUAD, SPI_CMD_WRITE_QUAD, _dummy_, _size_, _clk_ }
32609+
32610+#define SET_WRITE_QUAD_ADDR(_dummy_, _size_, _clk_) \
32611+    static struct spi_op write_quad_addr_##_dummy_##_size_##_clk_ = { \
32612+SPI_IF_WRITE_QUAD_ADDR, SPI_CMD_WRITE_QUAD_ADDR, _dummy_, _size_, _clk_ }
32613+
32614+#define SET_ERASE_SECTOR_4K(_dummy_, _size_, _clk_) \
32615+    static struct spi_op erase_sector_4k_##_dummy_##_size_##_clk_ = { \
32616+    SPI_IF_ERASE_SECTOR_4K, SPI_CMD_SE_4K, _dummy_, _size_, _clk_ }
32617+
32618+#define SET_ERASE_SECTOR_32K(_dummy_, _size_, _clk_) \
32619+    static struct spi_op erase_sector_32k_##_dummy_##_size_##_clk_ = { \
32620+    SPI_IF_ERASE_SECTOR_32K, SPI_CMD_SE_32K, _dummy_, _size_, _clk_ }
32621+
32622+#define SET_ERASE_SECTOR_64K(_dummy_, _size_, _clk_) \
32623+    static struct spi_op erase_sector_64k_##_dummy_##_size_##_clk_ = { \
32624+    SPI_IF_ERASE_SECTOR_64K, SPI_CMD_SE_64K, _dummy_, _size_, _clk_ }
32625+
32626+#define SET_ERASE_SECTOR_128K(_dummy_, _size_, _clk_) \
32627+    static struct spi_op erase_sector_128k_##_dummy_##_size_##_clk_ = { \
32628+    SPI_IF_ERASE_SECTOR_128K, SPI_CMD_SE_128K, _dummy_, _size_, _clk_ }
32629+
32630+#define SET_ERASE_SECTOR_256K(_dummy_, _size_, _clk_) \
32631+    static struct spi_op erase_sector_256k_##_dummy_##_size_##_clk_ = { \
32632+    SPI_IF_ERASE_SECTOR_256K, SPI_CMD_SE_256K, _dummy_, _size_, _clk_ }
32633+
32634+#define READ_STD(_dummy_, _size_, _clk_) read_std_##_dummy_##_size_##_clk_
32635+#define READ_FAST(_dummy_, _size_, _clk_) read_fast_##_dummy_##_size_##_clk_
32636+#define READ_DUAL(_dummy_, _size_, _clk_) read_dual_##_dummy_##_size_##_clk_
32637+#define READ_DUAL_ADDR(_dummy_, _size_, _clk_) \
32638+        read_dual_addr_##_dummy_##_size_##_clk_
32639+#define READ_QUAD(_dummy_, _size_, _clk_) read_quad_##_dummy_##_size_##_clk_
32640+#define READ_QUAD_ADDR(_dummy_, _size_, _clk_) \
32641+        read_quad_addr_##_dummy_##_size_##_clk_
32642+
32643+#define WRITE_STD(_dummy_, _size_, _clk_) write_std_##_dummy_##_size_##_clk_
32644+#define WRITE_DUAL(_dummy_, _size_, _clk_) write_dual_##_dummy_##_size_##_clk_
32645+#define WRITE_DUAL_ADDR(_dummy_, _size_, _clk_) \
32646+        write_dual_addr_##_dummy_##_size_##_clk_
32647+#define WRITE_QUAD(_dummy_, _size_, _clk_) write_quad_##_dummy_##_size_##_clk_
32648+#define WRITE_QUAD_ADDR(_dummy_, _size_, _clk_) \
32649+        write_quad_addr_##_dummy_##_size_##_clk_
32650+
32651+#define ERASE_SECTOR_4K(_dummy_, _size_, _clk_) \
32652+        erase_sector_4k_##_dummy_##_size_##_clk_
32653+#define ERASE_SECTOR_32K(_dummy_, _size_, _clk_) \
32654+        erase_sector_32k_##_dummy_##_size_##_clk_
32655+#define ERASE_SECTOR_64K(_dummy_, _size_, _clk_) \
32656+        erase_sector_64k_##_dummy_##_size_##_clk_
32657+#define ERASE_SECTOR_128K(_dummy_, _size_, _clk_) \
32658+        erase_sector_128k_##_dummy_##_size_##_clk_
32659+#define ERASE_SECTOR_256K(_dummy_, _size_, _clk_) \
32660+        erase_sector_256k_##_dummy_##_size_##_clk_
32661+
32662+#define SPI_CMD_WREN            0x06    /* Write Enable */
32663+#define SPI_CMD_WRDI            0x04    /* Write Disable */
32664+
32665+#define SPI_CMD_RDID            0x9F    /* Read Identification */
32666+
32667+#define SPI_CMD_GET_FEATURES        0x0F    /* Get Features */
32668+#define SPI_CMD_SET_FEATURE     0x1F    /* Set Feature */
32669+
32670+#define SPI_CMD_PAGE_READ       0x13    /* Page Read to Cache */
32671+
32672+#define SPI_CMD_RESET           0xff    /* Reset the device */
32673+
32674+/* These macroes are for debug only, reg option is slower then dma option */
32675+#undef HIFMC100_SPI_NAND_SUPPORT_REG_READ
32676+/* #define HIFMC100_SPI_NAND_SUPPORT_REG_READ */
32677+
32678+#undef HIFMC100_SPI_NAND_SUPPORT_REG_WRITE
32679+/* #define HIFMC100_SPI_NAND_SUPPORT_REG_WRITE */
32680+
32681+#ifdef CONFIG_HISI_NAND_ECC_STATUS_REPORT
32682+#define HIFMC100_ECC_ERR_NUM0_BUF0      0xc0
32683+
32684+#define GET_ECC_ERR_NUM(_i, _reg)       (((_reg) >> ((_i) * 8)) & 0xff)
32685+#endif
32686+#define REG_CNT_HIGH_BLOCK_NUM_SHIFT        10
32687+
32688+#define REG_CNT_BLOCK_NUM_MASK          0x3ff
32689+#define REG_CNT_BLOCK_NUM_SHIFT         22
32690+
32691+#define REG_CNT_PAGE_NUM_MASK           0x3f
32692+#define REG_CNT_PAGE_NUM_SHIFT          16
32693+
32694+#define ERR_STR_DRIVER "Driver does not support this configure "
32695+#define ERR_STR_CHECK "Please make sure the hardware configuration is correct"
32696+#define HIFMC100_ADDR_CYCLE_MASK        0x2
32697+#define OP_STYPE_NONE           0x0
32698+#define OP_STYPE_READ           0x01
32699+#define OP_STYPE_WRITE          0x02
32700+#define OP_STYPE_ERASE          0x04
32701+#define CLK_FMC_TO_CRG_MHZ(_clk)    ((_clk) * 2000000)
32702+#define MAX_SPI_OP          8
32703+/* SPI general operation parameter */
32704+struct spi_op {
32705+	unsigned char iftype;
32706+	unsigned char cmd;
32707+	unsigned char dummy;
32708+	unsigned int size;
32709+	unsigned int clock;
32710+};
32711+
32712+struct spi_drv;
32713+
32714+/* SPI interface all operation */
32715+struct hifmc_spi {
32716+	char *name;
32717+	int chipselect;
32718+	unsigned long long chipsize;
32719+	unsigned int erasesize;
32720+#define SPI_NOR_3BYTE_ADDR_LEN  3   /* address len 3Bytes */
32721+#define SPI_NOR_4BYTE_ADDR_LEN  4   /* address len 4Bytes for 32MB */
32722+	unsigned int addrcycle;
32723+
32724+	struct spi_op read[1];
32725+	struct spi_op write[1];
32726+	struct spi_op erase[MAX_SPI_OP];
32727+
32728+	void *host;
32729+
32730+	struct spi_drv *driver;
32731+};
32732+
32733+/* SPI interface special operation function hook */
32734+struct spi_drv {
32735+	int (*wait_ready)(struct hifmc_spi *spi);
32736+	int (*write_enable)(struct hifmc_spi *spi);
32737+	int (*qe_enable)(struct hifmc_spi *spi);
32738+	int (*bus_prepare)(struct hifmc_spi *spi, int op);
32739+	int (*entry_4addr)(struct hifmc_spi *spi, int en);
32740+};
32741+
32742+struct spi_nand_info {
32743+	char *name;
32744+	unsigned char id[MAX_SPI_NAND_ID_LEN];
32745+	unsigned char id_len;
32746+	unsigned long long chipsize;
32747+	unsigned int erasesize;
32748+	unsigned int pagesize;
32749+	unsigned int oobsize;
32750+#define BBP_LAST_PAGE       0x01
32751+#define BBP_FIRST_PAGE      0x02
32752+	unsigned int badblock_pos;
32753+	struct spi_op *read[MAX_SPI_OP];
32754+	struct spi_op *write[MAX_SPI_OP];
32755+	struct spi_op *erase[MAX_SPI_OP];
32756+	struct spi_drv *driver;
32757+};
32758+
32759+extern char spi_nand_feature_op(struct hifmc_spi *spi, u_char op, u_char addr,
32760+				  u_char *val);
32761+
32762+struct hifmc_host {
32763+	struct mtd_info *mtd;
32764+	struct nand_chip *chip;
32765+	struct hifmc_spi spi[CONFIG_SPI_NAND_MAX_CHIP_NUM];
32766+	struct hifmc_cmd_op cmd_op;
32767+
32768+	void __iomem *iobase;
32769+	void __iomem *regbase;
32770+	struct clk *clk;
32771+	u32 clkrate;
32772+
32773+	unsigned int fmc_cfg;
32774+	unsigned int fmc_cfg_ecc0;
32775+
32776+	unsigned int offset;
32777+
32778+	struct device *dev;
32779+	struct mutex *lock;
32780+
32781+	/* This is maybe an un-aligment address, only for malloc or free */
32782+	char *buforg;
32783+	char *buffer;
32784+
32785+#ifdef CONFIG_64BIT
32786+	unsigned long long dma_buffer;
32787+	unsigned long long dma_oob;
32788+#else
32789+	unsigned int dma_buffer;
32790+	unsigned int dma_oob;
32791+#endif
32792+
32793+	unsigned int addr_cycle;
32794+	unsigned int addr_value[2];
32795+	unsigned int cache_addr_value[2];
32796+
32797+	unsigned int column;
32798+	unsigned int block_page_mask;
32799+
32800+	unsigned int ecctype;
32801+	unsigned int pagesize;
32802+	unsigned int oobsize;
32803+
32804+	int add_partition;
32805+
32806+	int  need_rr_data;
32807+#define HIFMC100_READ_RETRY_DATA_LEN         128
32808+	char rr_data[HIFMC100_READ_RETRY_DATA_LEN];
32809+	struct read_retry_t *read_retry;
32810+
32811+	int version;
32812+
32813+	/* BOOTROM read two bytes to detect the bad block flag */
32814+#define HIFMC_BAD_BLOCK_POS     0
32815+	unsigned char *bbm; /* nand bad block mark */
32816+	unsigned short *epm;    /* nand empty page mark */
32817+
32818+	unsigned int uc_er;
32819+
32820+	void (*send_cmd_write)(struct hifmc_host *host);
32821+	void (*send_cmd_status)(struct hifmc_host *host);
32822+	void (*send_cmd_read)(struct hifmc_host *host);
32823+	void (*send_cmd_erase)(struct hifmc_host *host);
32824+	void (*send_cmd_readid)(struct hifmc_host *host);
32825+	void (*send_cmd_reset)(struct hifmc_host *host);
32826+#ifdef CONFIG_PM
32827+	int (*suspend)(struct platform_device *pltdev, pm_message_t state);
32828+	int (*resume)(struct platform_device *pltdev);
32829+#endif
32830+};
32831+
32832+void hifmc100_ecc0_switch(struct hifmc_host *host, unsigned char op);
32833+
32834+void hifmc100_spi_nand_init(struct nand_chip *chip);
32835+
32836+extern void hifmc_spi_nand_ids_register(void);
32837+
32838+extern void hifmc_set_nand_system_clock(struct spi_op *op, int clk_en);
32839+
32840+#ifdef CONFIG_PM
32841+int hifmc100_suspend(struct platform_device *pltdev, pm_message_t state);
32842+int hifmc100_resume(struct platform_device *pltdev);
32843+void hifmc100_spi_nand_config(struct hifmc_host *host);
32844+#endif
32845+
32846+#endif /* End of __HIFMC100_H__ */
32847diff --git a/drivers/mtd/nand/hifmc100/hifmc100_os.c b/drivers/mtd/nand/hifmc100/hifmc100_os.c
32848new file mode 100644
32849index 000000000..980bfb8f6
32850--- /dev/null
32851+++ b/drivers/mtd/nand/hifmc100/hifmc100_os.c
32852@@ -0,0 +1,247 @@
32853+/*
32854+ * The Flash Memory Controller v100 Device Driver for hisilicon
32855+ *
32856+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
32857+ *
32858+ * This program is free software; you can redistribute  it and/or modify it
32859+ * under  the terms of  the GNU General  Public License as published by the
32860+ * Free Software Foundation;  either version 2 of the  License, or (at your
32861+ * option) any later version.
32862+ *
32863+ * This program is distributed in the hope that it will be useful,
32864+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
32865+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32866+ * GNU General Public License for more details.
32867+ *
32868+ * You should have received a copy of the GNU General Public License
32869+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
32870+ *
32871+ */
32872+
32873+#include <linux/kernel.h>
32874+#include <linux/slab.h>
32875+#include <linux/delay.h>
32876+#include <linux/module.h>
32877+#include <linux/platform_device.h>
32878+#include <linux/dma-mapping.h>
32879+#include <linux/mtd/rawnand.h>
32880+#include <linux/mtd/partitions.h>
32881+#include <linux/of_platform.h>
32882+#include <linux/mfd/hisi_fmc.h>
32883+
32884+#include <asm/setup.h>
32885+
32886+#include "../../mtdcore.h"
32887+#include "hifmc100.h"
32888+
32889+static int hifmc100_spi_nand_pre_probe(struct nand_chip *chip)
32890+{
32891+	uint8_t nand_maf_id;
32892+	struct hifmc_host *host = chip->priv;
32893+
32894+	/* Reset the chip first */
32895+	host->send_cmd_reset(host);
32896+	udelay(1000);
32897+
32898+	/* Check the ID */
32899+	host->offset = 0;
32900+	memset((unsigned char *)(chip->IO_ADDR_R), 0, 0x10);
32901+	host->send_cmd_readid(host);
32902+	nand_maf_id = hifmc_readb(chip->IO_ADDR_R);
32903+
32904+	if (nand_maf_id == 0x00 || nand_maf_id == 0xff) {
32905+		printk("Cannot found a valid SPI Nand Device\n");
32906+		return 1;
32907+	}
32908+
32909+	return 0;
32910+}
32911+
32912+static int hifmc_nand_scan(struct mtd_info *mtd)
32913+{
32914+	int result = 0;
32915+	unsigned char cs;
32916+	unsigned char chip_num = CONFIG_SPI_NAND_MAX_CHIP_NUM;
32917+	struct nand_chip *chip = mtd_to_nand(mtd);
32918+	struct hifmc_host *host = chip->priv;
32919+
32920+	for (cs = 0; chip_num && (cs < HIFMC_MAX_CHIP_NUM); cs++) {
32921+		if (hifmc_cs_user[cs]) {
32922+			FMC_PR(BT_DBG, "\t\t*-Current CS(%d) is occupied.\n",
32923+			       cs);
32924+			continue;
32925+		}
32926+
32927+		host->cmd_op.cs = cs;
32928+
32929+		if (hifmc100_spi_nand_pre_probe(chip)) {
32930+			return -ENODEV;
32931+		}
32932+
32933+		FMC_PR(BT_DBG, "\t\t*-Scan SPI nand flash on CS: %d\n", cs);
32934+		if (nand_scan_with_ids(mtd, chip_num, NULL)) {
32935+			continue;
32936+		}
32937+		chip_num--;
32938+	}
32939+
32940+	if (chip_num == CONFIG_SPI_NAND_MAX_CHIP_NUM) {
32941+		result = -ENXIO;
32942+	} else {
32943+		result = 0;
32944+	}
32945+
32946+	return result;
32947+}
32948+
32949+static int hisi_spi_nand_probe(struct platform_device *pltdev)
32950+{
32951+	int len;
32952+	int result = 0;
32953+	struct hifmc_host *host = NULL;
32954+	struct nand_chip *chip = NULL;
32955+	struct mtd_info *mtd = NULL;
32956+	struct device *dev = &pltdev->dev;
32957+	struct device_node *np = NULL;
32958+	struct hisi_fmc *fmc = dev_get_drvdata(dev->parent);
32959+
32960+	FMC_PR(BT_DBG, "\t*-Start SPI Nand flash driver probe\n");
32961+
32962+	if (!fmc) {
32963+		dev_err(dev, "get mfd fmc devices failed\n");
32964+		return -ENXIO;
32965+	}
32966+
32967+	len = sizeof(struct hifmc_host) + sizeof(struct nand_chip) +
32968+	      sizeof(struct mtd_info);
32969+	host = devm_kzalloc(dev, len, GFP_KERNEL);
32970+	if (!host) {
32971+		return -ENOMEM;
32972+	}
32973+	memset((char *)host, 0, len);
32974+
32975+	platform_set_drvdata(pltdev, host);
32976+	host->dev = &pltdev->dev;
32977+
32978+	host->chip = chip = (struct nand_chip *)&host[1];
32979+	host->mtd  = mtd  = nand_to_mtd(chip);
32980+
32981+	host->regbase = fmc->regbase;
32982+	host->iobase = fmc->iobase;
32983+	host->clk = fmc->clk;
32984+	host->lock = &fmc->lock;
32985+	host->buffer = fmc->buffer;
32986+	host->dma_buffer = fmc->dma_buffer;
32987+
32988+	memset((char *)host->iobase, 0xff, fmc->dma_len);
32989+	chip->IO_ADDR_R = chip->IO_ADDR_W = host->iobase;
32990+
32991+	chip->priv = host;
32992+
32993+	/* Set system clock */
32994+	result = clk_prepare_enable(host->clk);
32995+	if (result) {
32996+		printk("\nclk prepare enable failed!");
32997+		goto fail;
32998+	}
32999+
33000+	hifmc100_spi_nand_init(chip);
33001+
33002+	np = of_get_next_available_child(dev->of_node, NULL);
33003+	if (np == NULL) {
33004+		printk("\nof_get_next_available_child failed!");
33005+		goto fail;
33006+	}
33007+	mtd->name = np->name;
33008+	mtd->type = MTD_NANDFLASH;
33009+	mtd->priv = chip;
33010+	mtd->owner = THIS_MODULE;
33011+
33012+	result = of_property_read_u32(np, "spi-max-frequency", &host->clkrate);
33013+	if (result) {
33014+		printk("\nget fmc clkrate failed");
33015+		goto fail;
33016+	}
33017+
33018+	result = hifmc_nand_scan(mtd);
33019+	if (result) {
33020+		FMC_PR(BT_DBG, "\t|-Scan SPI Nand failed.\n");
33021+		goto fail;
33022+	}
33023+
33024+	result = mtd_device_register(mtd, NULL, 0);
33025+	if (!result) {
33026+		FMC_PR(BT_DBG, "\t*-End driver probe !!\n");
33027+		return 0;
33028+	}
33029+
33030+	result = -ENODEV;
33031+	nand_release(mtd);
33032+fail:
33033+	clk_disable_unprepare(host->clk);
33034+	DB_MSG("Error: driver probe, result: %d\n", result);
33035+	return result;
33036+}
33037+
33038+static int hisi_spi_nand_remove(struct platform_device *pltdev)
33039+{
33040+	struct hifmc_host *host = platform_get_drvdata(pltdev);
33041+
33042+	if (host) {
33043+		if (host->clk)
33044+			clk_disable_unprepare(host->clk);
33045+		if (host->mtd)
33046+			nand_release(host->mtd);
33047+	}
33048+
33049+	return 0;
33050+}
33051+
33052+#ifdef CONFIG_PM
33053+static int hifmc100_os_suspend(struct platform_device *pltdev,
33054+			       pm_message_t state)
33055+{
33056+	struct hifmc_host *host = platform_get_drvdata(pltdev);
33057+
33058+	if (host && host->suspend) {
33059+		return (host->suspend)(pltdev, state);
33060+	}
33061+
33062+	return 0;
33063+}
33064+
33065+static int hifmc100_os_resume(struct platform_device *pltdev)
33066+{
33067+	struct hifmc_host *host = platform_get_drvdata(pltdev);
33068+
33069+	if (host && host->resume) {
33070+		return (host->resume)(pltdev);
33071+	}
33072+
33073+	return 0;
33074+}
33075+#endif /* End of CONFIG_PM */
33076+
33077+static const struct of_device_id hisi_spi_nand_dt_ids[] = {
33078+	{ .compatible = "hisilicon,hisi-spi-nand" },
33079+	{ } /* sentinel */
33080+};
33081+MODULE_DEVICE_TABLE(of, hisi_spi_nand_dt_ids);
33082+
33083+static struct platform_driver hisi_spi_nand_driver = {
33084+	.driver = {
33085+		.name   = "hisi_spi_nand",
33086+		.of_match_table = hisi_spi_nand_dt_ids,
33087+	},
33088+	.probe  = hisi_spi_nand_probe,
33089+	.remove = hisi_spi_nand_remove,
33090+#ifdef CONFIG_PM
33091+	.suspend    = hifmc100_os_suspend,
33092+	.resume     = hifmc100_os_resume,
33093+#endif
33094+};
33095+module_platform_driver(hisi_spi_nand_driver);
33096+
33097+MODULE_LICENSE("GPL");
33098+MODULE_AUTHOR("BVT_BSP");
33099+MODULE_DESCRIPTION("Hisilicon Flash Memory Controller V100 SPI Nand Driver");
33100diff --git a/drivers/mtd/nand/hifmc100/hifmc100_spi_general.c b/drivers/mtd/nand/hifmc100/hifmc100_spi_general.c
33101new file mode 100644
33102index 000000000..3b46205f3
33103--- /dev/null
33104+++ b/drivers/mtd/nand/hifmc100/hifmc100_spi_general.c
33105@@ -0,0 +1,313 @@
33106+/*
33107+ * The Flash Memory Controller v100 Device Driver for hisilicon
33108+ *
33109+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
33110+ *
33111+ * This program is free software; you can redistribute  it and/or modify it
33112+ * under  the terms of  the GNU General  Public License as published by the
33113+ * Free Software Foundation;  either version 2 of the  License, or (at your
33114+ * option) any later version.
33115+ *
33116+ * This program is distributed in the hope that it will be useful,
33117+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33118+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33119+ * GNU General Public License for more details.
33120+ *
33121+ * You should have received a copy of the GNU General Public License
33122+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
33123+ *
33124+ */
33125+
33126+/*
33127+    Send set/get features command to SPI Nand flash
33128+*/
33129+char spi_nand_feature_op(struct hifmc_spi *spi, u_char op, u_char addr,
33130+			   u_char *val)
33131+{
33132+	unsigned int reg;
33133+	const char *str[] = {"Get", "Set"};
33134+	struct hifmc_host *host = NULL;
33135+
33136+	if (!spi) {
33137+		DB_MSG("Error: spi is NULL !\n");
33138+		return -1;
33139+	}
33140+	host = (struct hifmc_host *)spi->host;
33141+	if (!host) {
33142+		DB_MSG("Error: host is NULL !\n");
33143+		return -1;
33144+	}
33145+
33146+	if ((op == GET_OP) && (STATUS_ADDR == addr)) {
33147+		if (!val) {
33148+			DB_MSG("Error: val is NULL !\n");
33149+			return -1;
33150+		}
33151+		if (SR_DBG) {
33152+			pr_info("\n");
33153+		}
33154+		FMC_PR(SR_DBG, "\t\t|*-Start Get Status\n");
33155+
33156+		reg = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN;
33157+		hifmc_writel(host, FMC_OP_CFG, reg);
33158+		FMC_PR(SR_DBG, "\t\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg);
33159+
33160+		reg = FMC_OP_READ_STATUS_EN | FMC_OP_REG_OP_START;
33161+		hifmc_writel(host, FMC_OP, reg);
33162+		FMC_PR(SR_DBG, "\t\t||-Set OP[%#x]%#x\n", FMC_OP, reg);
33163+
33164+		FMC_CMD_WAIT_CPU_FINISH(host);
33165+
33166+		*val = hifmc_readl(host, FMC_STATUS);
33167+		FMC_PR(SR_DBG, "\t\t|*-End Get Status, result: %#x\n", *val);
33168+
33169+		return 0;
33170+	}
33171+
33172+	FMC_PR(FT_DBG, "\t|||*-Start %s feature, addr[%#x]\n", str[op], addr);
33173+
33174+	hifmc100_ecc0_switch(host, ENABLE);
33175+
33176+	reg = FMC_CMD_CMD1(op ? SPI_CMD_SET_FEATURE : SPI_CMD_GET_FEATURES);
33177+	hifmc_writel(host, FMC_CMD, reg);
33178+	FMC_PR(FT_DBG, "\t||||-Set CMD[%#x]%#x\n", FMC_CMD, reg);
33179+
33180+	hifmc_writel(host, FMC_ADDRL, addr);
33181+	FMC_PR(FT_DBG, "\t||||-Set ADDRL[%#x]%#x\n", FMC_ADDRL, addr);
33182+
33183+	reg = OP_CFG_FM_CS(host->cmd_op.cs)
33184+	      | OP_CFG_ADDR_NUM(FEATURES_OP_ADDR_NUM)
33185+	      | OP_CFG_OEN_EN;
33186+	hifmc_writel(host, FMC_OP_CFG, reg);
33187+	FMC_PR(FT_DBG, "\t||||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg);
33188+
33189+	reg = FMC_DATA_NUM_CNT(FEATURES_DATA_LEN);
33190+	hifmc_writel(host, FMC_DATA_NUM, reg);
33191+	FMC_PR(FT_DBG, "\t||||-Set DATA_NUM[%#x]%#x\n", FMC_DATA_NUM, reg);
33192+
33193+	reg = FMC_OP_CMD1_EN
33194+	      | FMC_OP_ADDR_EN
33195+	      | FMC_OP_REG_OP_START;
33196+
33197+	if (op == SET_OP) {
33198+		if (!val || !host->iobase) {
33199+			DB_MSG("Error: host->iobase is NULL !\n");
33200+			return -1;
33201+		}
33202+		reg |= FMC_OP_WRITE_DATA_EN;
33203+		hifmc_writeb(*val, host->iobase);
33204+		FMC_PR(FT_DBG, "\t||||-Write IO[%#lx]%#x\n", (long)host->iobase,
33205+		       *(u_char *)host->iobase);
33206+	} else {
33207+		reg |= FMC_OP_READ_DATA_EN;
33208+	}
33209+
33210+	hifmc_writel(host, FMC_OP, reg);
33211+	FMC_PR(FT_DBG, "\t||||-Set OP[%#x]%#x\n", FMC_OP, reg);
33212+
33213+	FMC_CMD_WAIT_CPU_FINISH(host);
33214+
33215+	if (op == GET_OP) {
33216+		if (!val || !host->iobase) {
33217+			DB_MSG("Error: val or host->iobase is NULL !\n");
33218+			return -1;
33219+		}
33220+		*val = hifmc_readb(host->iobase);
33221+		FMC_PR(FT_DBG, "\t||||-Read IO[%#lx]%#x\n", (long)host->iobase,
33222+		       *(u_char *)host->iobase);
33223+	}
33224+
33225+	hifmc100_ecc0_switch(host, DISABLE);
33226+
33227+	FMC_PR(FT_DBG, "\t|||*-End %s Feature[%#x]:%#x\n", str[op], addr, *val);
33228+
33229+	return 0;
33230+}
33231+
33232+/*
33233+    Read status[C0H]:[0]bit OIP, judge whether the device is busy or not
33234+*/
33235+static int spi_general_wait_ready(struct hifmc_spi *spi)
33236+{
33237+	unsigned char status;
33238+	int ret;
33239+	unsigned long deadline = jiffies + FMC_MAX_READY_WAIT_JIFFIES;
33240+	struct hifmc_host *host = NULL;
33241+
33242+	if(spi == NULL || spi->host == NULL) {
33243+		DB_MSG("Error: host or host->spi is NULL!\n");
33244+		return -1;
33245+	}
33246+	host = (struct hifmc_host *)spi->host;
33247+
33248+	do {
33249+		ret = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, &status);
33250+		if (ret)
33251+		    return -1;
33252+		if (!(status & STATUS_OIP_MASK)) {
33253+			if ((host->cmd_op.l_cmd == NAND_CMD_ERASE2)
33254+					&& (status & STATUS_E_FAIL_MASK)) {
33255+				return status;
33256+			}
33257+			if ((host->cmd_op.l_cmd == NAND_CMD_PAGEPROG)
33258+					&& (status & STATUS_P_FAIL_MASK)) {
33259+				return status;
33260+			}
33261+			return 0;
33262+		}
33263+
33264+		cond_resched();
33265+	} while (!time_after_eq(jiffies, deadline));
33266+
33267+	DB_MSG("Error: SPI Nand wait ready timeout, status: %#x\n", status);
33268+
33269+	return 1;
33270+}
33271+
33272+/*
33273+    Send write enable cmd to SPI Nand, status[C0H]:[2]bit WEL must be set 1
33274+*/
33275+static int spi_general_write_enable(struct hifmc_spi *spi)
33276+{
33277+	u_char reg;
33278+	int ret;
33279+	unsigned int regl;
33280+	struct hifmc_host *host = NULL;
33281+	if(spi == NULL || spi->host == NULL) {
33282+		DB_MSG("Error: host or host->spi is NULL!\n");
33283+		return -1;
33284+	}
33285+	host = spi->host;
33286+	if (WE_DBG) {
33287+		pr_info("\n");
33288+	}
33289+	FMC_PR(WE_DBG, "\t|*-Start Write Enable\n");
33290+
33291+	ret = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, &reg);
33292+	if (ret)
33293+		return -1;
33294+	if (reg & STATUS_WEL_MASK) {
33295+		FMC_PR(WE_DBG, "\t||-Write Enable was opened! reg: %#x\n",
33296+		       reg);
33297+		return 0;
33298+	}
33299+
33300+	regl = hifmc_readl(host, FMC_GLOBAL_CFG);
33301+	FMC_PR(WE_DBG, "\t||-Get GLOBAL_CFG[%#x]%#x\n", FMC_GLOBAL_CFG, regl);
33302+	if (regl & FMC_GLOBAL_CFG_WP_ENABLE) {
33303+		regl &= ~FMC_GLOBAL_CFG_WP_ENABLE;
33304+		hifmc_writel(host, FMC_GLOBAL_CFG, regl);
33305+		FMC_PR(WE_DBG, "\t||-Set GLOBAL_CFG[%#x]%#x\n",
33306+		       FMC_GLOBAL_CFG, regl);
33307+	}
33308+
33309+	regl = FMC_CMD_CMD1(SPI_CMD_WREN);
33310+	hifmc_writel(host, FMC_CMD, regl);
33311+	FMC_PR(WE_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, regl);
33312+
33313+	regl = OP_CFG_FM_CS(host->cmd_op.cs) | OP_CFG_OEN_EN;
33314+	hifmc_writel(host, FMC_OP_CFG, regl);
33315+	FMC_PR(WE_DBG, "\t||-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, regl);
33316+
33317+	regl = FMC_OP_CMD1_EN | FMC_OP_REG_OP_START;
33318+	hifmc_writel(host, FMC_OP, regl);
33319+	FMC_PR(WE_DBG, "\t||-Set OP[%#x]%#x\n", FMC_OP, regl);
33320+
33321+	FMC_CMD_WAIT_CPU_FINISH(host);
33322+
33323+#if WE_DBG
33324+	if(!spi->driver) {
33325+		DB_MSG("Error: spi->driver is NULL!\n");
33326+		return -1;
33327+	}
33328+	spi->driver->wait_ready(spi);
33329+
33330+	ret = spi_nand_feature_op(spi, GET_OP, STATUS_ADDR, &reg);
33331+	if (ret)
33332+		return -1;
33333+	if (reg & STATUS_WEL_MASK) {
33334+		FMC_PR(WE_DBG, "\t||-Write Enable success. reg: %#x\n", reg);
33335+	} else {
33336+		DB_MSG("Error: Write Enable failed! reg: %#x\n", reg);
33337+		return reg;
33338+	}
33339+#endif
33340+
33341+	FMC_PR(WE_DBG, "\t|*-End Write Enable\n");
33342+	return 0;
33343+}
33344+
33345+/*
33346+    judge whether SPI Nand support QUAD read/write or not
33347+*/
33348+static int spi_is_quad(struct hifmc_spi *spi)
33349+{
33350+	const char *if_str[] = {"STD", "DUAL", "DIO", "QUAD", "QIO"};
33351+	FMC_PR(QE_DBG, "\t\t|||*-SPI read iftype: %s write iftype: %s\n",
33352+	       if_str[spi->read->iftype], if_str[spi->write->iftype]);
33353+
33354+	if ((spi->read->iftype == IF_TYPE_QUAD)
33355+			|| (spi->read->iftype == IF_TYPE_QIO)
33356+			|| (spi->write->iftype == IF_TYPE_QUAD)
33357+			|| (spi->write->iftype == IF_TYPE_QIO)) {
33358+		return 1;
33359+	}
33360+
33361+	return 0;
33362+}
33363+
33364+/*
33365+    Send set features cmd to SPI Nand, feature[B0H]:[0]bit QE would be set
33366+*/
33367+static int spi_general_qe_enable(struct hifmc_spi *spi)
33368+{
33369+	int op;
33370+	u_char reg;
33371+	int ret;
33372+	const char *str[] = {"Disable", "Enable"};
33373+
33374+	if(!spi || !spi->host || !spi->driver) {
33375+		DB_MSG("Error: host or spi->host or spi->driver is NULL!\n");
33376+		return -1;
33377+	}
33378+	FMC_PR(QE_DBG, "\t||*-Start SPI Nand flash QE\n");
33379+
33380+	op = spi_is_quad(spi);
33381+
33382+	FMC_PR(QE_DBG, "\t|||*-End Quad check, SPI Nand %s Quad.\n", str[op]);
33383+
33384+	ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, &reg);
33385+	if (ret)
33386+		return -1;
33387+	FMC_PR(QE_DBG, "\t|||-Get [%#x]feature: %#x\n", FEATURE_ADDR, reg);
33388+	if ((reg & FEATURE_QE_ENABLE) == op) {
33389+		FMC_PR(QE_DBG, "\t||*-SPI Nand quad was %sd!\n", str[op]);
33390+		return op;
33391+	}
33392+
33393+	if (op == ENABLE) {
33394+		reg |= FEATURE_QE_ENABLE;
33395+	} else {
33396+		reg &= ~FEATURE_QE_ENABLE;
33397+	}
33398+
33399+	ret = spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, &reg);
33400+	if (ret)
33401+		return -1;
33402+	FMC_PR(QE_DBG, "\t|||-SPI Nand %s Quad\n", str[op]);
33403+
33404+	spi->driver->wait_ready(spi);
33405+
33406+	ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, &reg);
33407+	if (ret)
33408+		return -1;
33409+	if ((reg & FEATURE_QE_ENABLE) == op) {
33410+		FMC_PR(QE_DBG, "\t|||-SPI Nand %s Quad succeed!\n", str[op]);
33411+	} else {
33412+		DB_MSG("Error: %s Quad failed! reg: %#x\n", str[op], reg);
33413+	}
33414+
33415+	FMC_PR(QE_DBG, "\t||*-End SPI Nand %s Quad.\n", str[op]);
33416+
33417+	return op;
33418+}
33419diff --git a/drivers/mtd/nand/hifmc100/hifmc_spi_nand_ids.c b/drivers/mtd/nand/hifmc100/hifmc_spi_nand_ids.c
33420new file mode 100644
33421index 000000000..bf963d146
33422--- /dev/null
33423+++ b/drivers/mtd/nand/hifmc100/hifmc_spi_nand_ids.c
33424@@ -0,0 +1,2457 @@
33425+/*
33426+ * The Flash Memory Controller v100 Device Driver for hisilicon
33427+ *
33428+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
33429+ *
33430+ * This program is free software; you can redistribute  it and/or modify it
33431+ * under  the terms of  the GNU General  Public License as published by the
33432+ * Free Software Foundation;  either version 2 of the  License, or (at your
33433+ * option) any later version.
33434+ *
33435+ * This program is distributed in the hope that it will be useful,
33436+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
33437+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
33438+ * GNU General Public License for more details.
33439+ *
33440+ * You should have received a copy of the GNU General Public License
33441+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
33442+ *
33443+ */
33444+
33445+#include <asm/setup.h>
33446+#include <linux/types.h>
33447+#include <linux/io.h>
33448+#include <linux/sched.h>
33449+#include <linux/printk.h>
33450+#include <linux/platform_device.h>
33451+#include <linux/mtd/rawnand.h>
33452+#include <linux/mtd/partitions.h>
33453+#include <linux/mfd/hisi_fmc.h>
33454+#include <linux/uaccess.h>
33455+
33456+#include "../raw/hinfc_gen.h"
33457+#include "hifmc100.h"
33458+
33459+SET_READ_STD(1, INFINITE, 24);
33460+
33461+SET_READ_FAST(1, INFINITE, 80);
33462+SET_READ_FAST(1, INFINITE, 100);
33463+SET_READ_FAST(1, INFINITE, 104);
33464+SET_READ_FAST(1, INFINITE, 108);
33465+SET_READ_FAST(1, INFINITE, 120);
33466+SET_READ_FAST(1, INFINITE, 133);
33467+
33468+SET_READ_DUAL(1, INFINITE, 80);
33469+SET_READ_DUAL(1, INFINITE, 100);
33470+SET_READ_DUAL(1, INFINITE, 104);
33471+SET_READ_DUAL(1, INFINITE, 108);
33472+SET_READ_DUAL(1, INFINITE, 120);
33473+SET_READ_DUAL(1, INFINITE, 133);
33474+
33475+SET_READ_DUAL_ADDR(1, INFINITE, 40);
33476+SET_READ_DUAL_ADDR(1, INFINITE, 80);
33477+SET_READ_DUAL_ADDR(2, INFINITE, 80);
33478+SET_READ_DUAL_ADDR(1, INFINITE, 100);
33479+SET_READ_DUAL_ADDR(1, INFINITE, 104);
33480+SET_READ_DUAL_ADDR(1, INFINITE, 108);
33481+SET_READ_DUAL_ADDR(1, INFINITE, 120);
33482+SET_READ_DUAL_ADDR(2, INFINITE, 104);
33483+
33484+SET_READ_QUAD(1, INFINITE, 80);
33485+SET_READ_QUAD(1, INFINITE, 100);
33486+SET_READ_QUAD(1, INFINITE, 104);
33487+SET_READ_QUAD(1, INFINITE, 108);
33488+SET_READ_QUAD(1, INFINITE, 120);
33489+SET_READ_QUAD(1, INFINITE, 133);
33490+
33491+SET_READ_QUAD_ADDR(2, INFINITE, 40);
33492+SET_READ_QUAD_ADDR(1, INFINITE, 80);
33493+SET_READ_QUAD_ADDR(2, INFINITE, 80);
33494+SET_READ_QUAD_ADDR(4, INFINITE, 80);
33495+SET_READ_QUAD_ADDR(1, INFINITE, 100);
33496+SET_READ_QUAD_ADDR(1, INFINITE, 104);
33497+SET_READ_QUAD_ADDR(2, INFINITE, 104);
33498+SET_READ_QUAD_ADDR(1, INFINITE, 108);
33499+SET_READ_QUAD_ADDR(1, INFINITE, 120);
33500+SET_READ_QUAD_ADDR(4, INFINITE, 104);
33501+
33502+SET_WRITE_STD(0, 256, 24);
33503+SET_WRITE_STD(0, 256, 75);
33504+SET_WRITE_STD(0, 256, 80);
33505+SET_WRITE_STD(0, 256, 100);
33506+SET_WRITE_STD(0, 256, 104);
33507+SET_WRITE_STD(0, 256, 133);
33508+
33509+SET_WRITE_QUAD(0, 256, 80);
33510+SET_WRITE_QUAD(0, 256, 100);
33511+SET_WRITE_QUAD(0, 256, 104);
33512+SET_WRITE_QUAD(0, 256, 108);
33513+SET_WRITE_QUAD(0, 256, 120);
33514+SET_WRITE_QUAD(0, 256, 133);
33515+
33516+SET_ERASE_SECTOR_128K(0, _128K, 24);
33517+SET_ERASE_SECTOR_128K(0, _128K, 75);
33518+SET_ERASE_SECTOR_128K(0, _128K, 80);
33519+SET_ERASE_SECTOR_128K(0, _128K, 104);
33520+SET_ERASE_SECTOR_128K(0, _128K, 133);
33521+
33522+SET_ERASE_SECTOR_256K(0, _256K, 24);
33523+SET_ERASE_SECTOR_256K(0, _256K, 75);
33524+SET_ERASE_SECTOR_256K(0, _256K, 80);
33525+SET_ERASE_SECTOR_256K(0, _256K, 100);
33526+SET_ERASE_SECTOR_256K(0, _256K, 104);
33527+SET_ERASE_SECTOR_256K(0, _256K, 133);
33528+
33529+#include "hifmc100_spi_general.c"
33530+static struct spi_drv spi_driver_general = {
33531+	.wait_ready = spi_general_wait_ready,
33532+	.write_enable = spi_general_write_enable,
33533+	.qe_enable = spi_general_qe_enable,
33534+};
33535+
33536+/* some spi nand flash default QUAD enable, needn't to set qe enable */
33537+static struct spi_drv spi_driver_no_qe = {
33538+	.wait_ready = spi_general_wait_ready,
33539+	.write_enable = spi_general_write_enable,
33540+};
33541+
33542+#define SPI_NAND_ID_TAB_VER     "2.7"
33543+
33544+/******* SPI Nand ID Table ***************************************************
33545+ * Version  Manufacturer    Chip Name   Size        Operation
33546+ * 1.0  ESMT        F50L512M41A     64MB        Add 5 chip
33547+ *      GD          5F1GQ4UAYIG     128MB
33548+ *      GD          5F2GQ4UAYIG     256MB
33549+ *	GD	    GD5F2GQ5UEYIG   256MB
33550+ *      GD          5F4GQ4UAYIG     512MB
33551+ *      GD          5F4GQ4UBYIG     512MB
33552+ *      GD          5F1GQ4RB9IG     128MB
33553+ *      GD          5F1GQ4UEYIHY    128MB
33554+ * 1.1  ESMT        F50L1G41A       128MB       Add 2 chip
33555+ *      Winbond     W25N01GV        128MB
33556+ *      Winbond     W25N02JWZEIF    256MB
33557+ * 1.2  GD          5F1GQ4UBYIG     128MB       Add 2 chip
33558+ *      GD      5F2GQ4U9IGR/BYIG    256MB
33559+ *      GD   1.8V   5F4GQ6RE9IG     512MB
33560+ * 1.3  ATO         ATO25D1GA       128MB       Add 1 chip
33561+ * 1.4  MXIC        MX35LF1GE4AB    128MB       Add 2 chip
33562+ *      MXIC        MX35LF2GE4AB    256MB       (SOP-16Pin)
33563+ * 1.5  Paragon     PN26G01A        128MB       Add 1 chip
33564+ * 1.6  All-flash   AFS1GQ4UAC      128MB       Add 1 chip
33565+ * 1.7  TOSHIBA     TC58CVG0S3H     128MB       Add 2 chip
33566+ *      TOSHIBA     TC58CVG2S0H     512MB
33567+ * 1.8  ALL-flash   AFS2GQ4UAD      256MB       Add 2 chip
33568+ *      Paragon     PN26G02A        256MB
33569+ * 1.9  TOSHIBA     TC58CVG1S3H     256MB       Add 1 chip
33570+ * 2.0  HeYangTek   HYF1GQ4UAACAE   128MB       Add 3 chip
33571+ *      HeYangTek   HYF2GQ4UAACAE   256MB
33572+ *      HeYangTek   HYF4GQ4UAACBE   512MB
33573+ * 2.1  Micron      MT29F1G01ABA    128MB       Add 5 chip
33574+ *	TOSHIBA 1.8V TC58CYG0S3H   128MB
33575+ *	TOSHIBA 1.8V TC58CYG1S3H   256MB
33576+ *	TOSHIBA 1.8V TC58CYG2S0H   512MB
33577+ *	Winbond 1.8V W25N01GWZEIG  128MB
33578+ * 2.2  Micron      MT29F2G01ABA    256MB       Add 1 chip
33579+ * 2.3  MXIC        MX35LF2G14AC    256MB       Add 1 chip
33580+ * 2.4  GD 1.8V     5F4GQ4RAYIG     512MB       Add 1 chip
33581+ * 2.5  GD 1.8V     5F2GQ4RB9IGR    256MB       Add 1 chip
33582+ * 2.6  MXIC 1.8V   MX35UF1G14AC    128MB       Add 4 chip
33583+ *      MXIC 1.8V   MX35UF2G14AC    256MB
33584+ *      Micron 1.8V MT29F1G01ABB    128MB
33585+ *      Micron 1.8V MT29F2G01ABB    256MB
33586+ * 2.7  Dosilicon   DS35Q1GA-IB     128MB       Add 2 chip
33587+ *      Dosilicon   DS35Q2GA-IB     256MB
33588+ *      GD          5F1GQ4RB9IGR    128MB
33589+ *      Micron      MT29F4G01ADAG   512MB   3.3V    Add 1 chip
33590+ *      GD 1.8V     5F4GQ4RBYIG     512MB       Add 1 chip
33591+ *      Etron 1.8V  EM78D044VCF-H   256MB
33592+ *      Etron 3.3V  EM73C044VCC-H   128MB
33593+ *      XTX 3.3V    XT26G01B 1Gbit  128MB
33594+ *      Micron      MT29F4G01ABBFDW 512MB 	1.8V
33595+ *	FM	    FM25S01-DND-A-G 128MB  	3.3V
33596+ *	FM	    FM25S01A	    128MB	3.3V
33597+ ******************************************************************************/
33598+struct spi_nand_info hifmc_spi_nand_flash_table[] = {
33599+	/* Micron MT29F1G01ABA 1GBit */
33600+	{
33601+		.name      = "MT29F1G01ABA",
33602+		.id        = {0x2C, 0x14},
33603+		.id_len    = 2,
33604+		.chipsize  = _128M,
33605+		.erasesize = _128K,
33606+		.pagesize  = _2K,
33607+		.oobsize   = 128,
33608+		.badblock_pos = BBP_FIRST_PAGE,
33609+		.read      = {
33610+			&READ_STD(1, INFINITE, 24),
33611+			&READ_FAST(1, INFINITE, 80),
33612+			&READ_DUAL(1, INFINITE, 80),
33613+			&READ_DUAL_ADDR(1, INFINITE, 80),
33614+			&READ_QUAD(1, INFINITE, 80),
33615+			&READ_QUAD_ADDR(2, INFINITE, 80),
33616+			0
33617+		},
33618+		.write     = {
33619+			&WRITE_STD(0, 256, 80),
33620+			&WRITE_QUAD(0, 256, 80),
33621+			0
33622+		},
33623+		.erase     = {
33624+			&ERASE_SECTOR_128K(0, _128K, 80),
33625+			0
33626+		},
33627+		.driver    = &spi_driver_no_qe,
33628+	},
33629+
33630+	/* Micron MT29F1G01ABB 1GBit 1.8V */
33631+	{
33632+		.name      = "MT29F1G01ABB",
33633+		.id        = {0x2C, 0x15},
33634+		.id_len    = 2,
33635+		.chipsize  = _128M,
33636+		.erasesize = _128K,
33637+		.pagesize  = _2K,
33638+		.oobsize   = 128,
33639+		.badblock_pos = BBP_FIRST_PAGE,
33640+		.read      = {
33641+			&READ_STD(1, INFINITE, 24),
33642+			&READ_FAST(1, INFINITE, 80),
33643+			&READ_DUAL(1, INFINITE, 80),
33644+			&READ_DUAL_ADDR(1, INFINITE, 80),
33645+			&READ_QUAD(1, INFINITE, 80),
33646+			&READ_QUAD_ADDR(2, INFINITE, 80),
33647+			0
33648+		},
33649+		.write     = {
33650+			&WRITE_STD(0, 256, 80),
33651+			&WRITE_QUAD(0, 256, 80),
33652+			0
33653+		},
33654+		.erase     = {
33655+			&ERASE_SECTOR_128K(0, _128K, 80),
33656+			0
33657+		},
33658+		.driver    = &spi_driver_no_qe,
33659+	},
33660+
33661+	/* Micron MT29F2G01ABA 2GBit */
33662+	{
33663+		.name      = "MT29F2G01ABA",
33664+		.id        = {0x2C, 0x24},
33665+		.id_len    = 2,
33666+		.chipsize  = _256M,
33667+		.erasesize = _128K,
33668+		.pagesize  = _2K,
33669+		.oobsize   = 128,
33670+		.badblock_pos = BBP_FIRST_PAGE,
33671+		.read      = {
33672+			&READ_STD(1, INFINITE, 24),
33673+			&READ_FAST(1, INFINITE, 108),
33674+			&READ_DUAL(1, INFINITE, 108),
33675+			&READ_DUAL_ADDR(1, INFINITE, 108),
33676+			&READ_QUAD(1, INFINITE, 108),
33677+			&READ_QUAD_ADDR(2, INFINITE, 104),
33678+			0
33679+		},
33680+		.write     = {
33681+			&WRITE_STD(0, 256, 80),
33682+			&WRITE_QUAD(0, 256, 108),
33683+			0
33684+		},
33685+		.erase     = {
33686+			&ERASE_SECTOR_128K(0, _128K, 80),
33687+			0
33688+		},
33689+		.driver    = &spi_driver_no_qe,
33690+	},
33691+
33692+	/* Micron MT29F2G01ABB 2GBit 1.8V */
33693+	{
33694+		.name      = "MT29F2G01ABB",
33695+		.id        = {0x2C, 0x25},
33696+		.id_len    = 2,
33697+		.chipsize  = _256M,
33698+		.erasesize = _128K,
33699+		.pagesize  = _2K,
33700+		.oobsize   = 128,
33701+		.badblock_pos = BBP_FIRST_PAGE,
33702+		.read      = {
33703+			&READ_STD(1, INFINITE, 24),
33704+			&READ_FAST(1, INFINITE, 80),
33705+			&READ_DUAL(1, INFINITE, 80),
33706+			&READ_DUAL_ADDR(1, INFINITE, 80),
33707+			&READ_QUAD(1, INFINITE, 80),
33708+			&READ_QUAD_ADDR(2, INFINITE, 80),
33709+			0
33710+		},
33711+		.write     = {
33712+			&WRITE_STD(0, 256, 80),
33713+			&WRITE_QUAD(0, 256, 80),
33714+			0
33715+		},
33716+		.erase     = {
33717+			&ERASE_SECTOR_128K(0, _128K, 80),
33718+			0
33719+		},
33720+		.driver    = &spi_driver_no_qe,
33721+	},
33722+
33723+	/* Micron MT29F4G01ADAG 4GBit 3.3V */
33724+	{
33725+		.name      = "MT29F4G01ADAG",
33726+		.id        = {0x2C, 0x36},
33727+		.id_len    = 2,
33728+		.chipsize  = _512M,
33729+		.erasesize = _128K,
33730+		.pagesize  = _2K,
33731+		.oobsize   = 128,
33732+		.badblock_pos = BBP_FIRST_PAGE,
33733+		.read      = {
33734+			&READ_STD(1, INFINITE, 24),
33735+			&READ_FAST(1, INFINITE, 108),
33736+			&READ_DUAL(1, INFINITE, 108),
33737+			&READ_DUAL_ADDR(1, INFINITE, 108),
33738+			&READ_QUAD(1, INFINITE, 108),
33739+			&READ_QUAD_ADDR(2, INFINITE, 104),
33740+			0
33741+		},
33742+		.write     = {
33743+			&WRITE_STD(0, 256, 80),
33744+			&WRITE_QUAD(0, 256, 108),
33745+			0
33746+		},
33747+		.erase     = {
33748+			&ERASE_SECTOR_128K(0, _128K, 80),
33749+			0
33750+		},
33751+		.driver    = &spi_driver_no_qe,
33752+	},
33753+
33754+	/* ESMT F50L512M41A 512Mbit */
33755+	{
33756+		.name      = "F50L512M41A",
33757+		.id        = {0xC8, 0x20},
33758+		.id_len    = 2,
33759+		.chipsize  = _64M,
33760+		.erasesize = _128K,
33761+		.pagesize  = _2K,
33762+		.oobsize   = 64,
33763+		.badblock_pos = BBP_FIRST_PAGE,
33764+		.read      = {
33765+			&READ_STD(1, INFINITE, 24),
33766+			&READ_FAST(1, INFINITE, 104),
33767+			&READ_DUAL(1, INFINITE, 104),
33768+			&READ_QUAD(1, INFINITE, 104),
33769+			0
33770+		},
33771+		.write     = {
33772+			&WRITE_STD(0, 256, 24),
33773+			&WRITE_QUAD(0, 256, 104),
33774+			0
33775+		},
33776+		.erase     = {
33777+			&ERASE_SECTOR_128K(0, _128K, 24),
33778+			0
33779+		},
33780+		.driver    = &spi_driver_no_qe,
33781+	},
33782+
33783+	/* ESMT F50L1G41A 1Gbit */
33784+	{
33785+		.name      = "F50L1G41A",
33786+		.id        = {0xC8, 0x21},
33787+		.id_len    = 2,
33788+		.chipsize  = _128M,
33789+		.erasesize = _128K,
33790+		.pagesize  = _2K,
33791+		.oobsize   = 64,
33792+		.badblock_pos = BBP_FIRST_PAGE,
33793+		.read      = {
33794+			&READ_STD(1, INFINITE, 24),
33795+			&READ_FAST(1, INFINITE, 104),
33796+			&READ_DUAL(1, INFINITE, 104),
33797+			&READ_QUAD(1, INFINITE, 104),
33798+			0
33799+		},
33800+		.write     = {
33801+			&WRITE_STD(0, 256, 24),
33802+			&WRITE_QUAD(0, 256, 104),
33803+			0
33804+		},
33805+		.erase     = {
33806+			&ERASE_SECTOR_128K(0, _128K, 24),
33807+			0
33808+		},
33809+		.driver    = &spi_driver_no_qe,
33810+	},
33811+
33812+	/* GD 3.3v GD5F1GQ5UEYIGY/GD5F1GQ5UEYIGR 1Gbit */
33813+	{
33814+		.name      = "GD5F1GQ5UEYIGY",
33815+		.id        = {0xc8, 0x51},
33816+		.id_len    = 2,
33817+		.chipsize  = _128M,
33818+		.erasesize = _128K,
33819+		.pagesize  = _2K,
33820+		.oobsize   = 128,
33821+		.badblock_pos = BBP_FIRST_PAGE,
33822+		.read      = {
33823+			&READ_STD(1, INFINITE, 24),
33824+			&READ_FAST(1, INFINITE, 133),
33825+			&READ_DUAL(1, INFINITE, 133),
33826+			&READ_QUAD(1, INFINITE, 133),
33827+			0
33828+		},
33829+		.write     = {
33830+			&WRITE_STD(0, 256, 133),
33831+			&WRITE_QUAD(0, 256, 133),
33832+			0
33833+		},
33834+		.erase     = {
33835+			&ERASE_SECTOR_128K(0, _128K, 133),
33836+			0
33837+		},
33838+		.driver    = &spi_driver_general,
33839+	},
33840+
33841+	/* ESMT F50L1G41LB-104YG2ME 1Gbit */
33842+	{
33843+		.name      = "F50L1G41LB-104YG2ME",
33844+		.id        = {0xC8, 0x01, 0X7F},
33845+		.id_len    = 3,
33846+		.chipsize  = _128M,
33847+		.erasesize = _128K,
33848+		.pagesize  = _2K,
33849+		.oobsize   = 64,
33850+		.badblock_pos = BBP_FIRST_PAGE,
33851+		.read      = {
33852+			&READ_STD(1, INFINITE, 24),
33853+			&READ_FAST(1, INFINITE, 104),
33854+			&READ_DUAL(1, INFINITE, 104),
33855+			&READ_QUAD(1, INFINITE, 104),
33856+			0
33857+		},
33858+		.write     = {
33859+			&WRITE_STD(0, 256, 104),
33860+			&WRITE_QUAD(0, 256, 104),
33861+			0
33862+		},
33863+		.erase     = {
33864+			&ERASE_SECTOR_128K(0, _128K, 104),
33865+			0
33866+		},
33867+		.driver    = &spi_driver_no_qe,
33868+	},
33869+
33870+	/* GD 3.3v GD5F1GQ4UAYIG 1Gbit */
33871+	{
33872+		.name      = "GD5F1GQ4UAYIG",
33873+		.id        = {0xc8, 0xf1},
33874+		.id_len    = 2,
33875+		.chipsize  = _128M,
33876+		.erasesize = _128K,
33877+		.pagesize  = _2K,
33878+		.oobsize   = 64,
33879+		.badblock_pos = BBP_FIRST_PAGE,
33880+		.read      = {
33881+			&READ_STD(1, INFINITE, 24),
33882+			&READ_FAST(1, INFINITE, 120),
33883+			&READ_DUAL(1, INFINITE, 120),
33884+			&READ_DUAL_ADDR(1, INFINITE, 120),
33885+			&READ_QUAD(1, INFINITE, 120),
33886+			&READ_QUAD_ADDR(1, INFINITE, 120),
33887+			0
33888+		},
33889+		.write     = {
33890+			&WRITE_STD(0, 256, 24),
33891+			&WRITE_QUAD(0, 256, 120),
33892+			0
33893+		},
33894+		.erase     = {
33895+			&ERASE_SECTOR_128K(0, _128K, 24),
33896+			0
33897+		},
33898+		.driver    = &spi_driver_general,
33899+	},
33900+
33901+	/* GD 1.8v GD5F1GQ5REYIG 1Gbit */
33902+	{
33903+		.name      = "GD5F1GQ5REYIG",
33904+		.id        = {0xc8, 0x41},
33905+		.id_len    = 2,
33906+		.chipsize  = _128M,
33907+		.erasesize = _128K,
33908+		.pagesize  = _2K,
33909+		.oobsize   = 128,
33910+		.badblock_pos = BBP_FIRST_PAGE,
33911+		.read      = {
33912+			&READ_STD(1, INFINITE, 24),
33913+			&READ_FAST(1, INFINITE, 104),
33914+			&READ_DUAL(1, INFINITE, 104),
33915+			&READ_QUAD(1, INFINITE, 104),
33916+			0
33917+		},
33918+		.write     = {
33919+			&WRITE_STD(0, 256, 24),
33920+			&WRITE_QUAD(0, 256, 104),
33921+			0
33922+		},
33923+		.erase     = {
33924+			&ERASE_SECTOR_128K(0, _128K, 104),
33925+			0
33926+		},
33927+		.driver    = &spi_driver_general,
33928+	},
33929+
33930+	/* GD 3.3v GD5F1GQ4UEYIHY 1Gbit */
33931+	{
33932+		.name      = "GD5F1GQ4UEYIHY",
33933+		.id        = {0xc8, 0xd9},
33934+		.id_len    = 2,
33935+		.chipsize  = _128M,
33936+		.erasesize = _128K,
33937+		.pagesize  = _2K,
33938+		.oobsize   = 64,
33939+		.badblock_pos = BBP_FIRST_PAGE,
33940+		.read      = {
33941+			&READ_STD(1, INFINITE, 24),
33942+			&READ_FAST(1, INFINITE, 120),
33943+			&READ_DUAL(1, INFINITE, 120),
33944+			&READ_DUAL_ADDR(1, INFINITE, 120),
33945+			&READ_QUAD(1, INFINITE, 120),
33946+			&READ_QUAD_ADDR(1, INFINITE, 120),
33947+			0
33948+		},
33949+		.write     = {
33950+			&WRITE_STD(0, 256, 104),
33951+			&WRITE_QUAD(0, 256, 120),
33952+			0
33953+		},
33954+		.erase     = {
33955+			&ERASE_SECTOR_128K(0, _128K, 104),
33956+			0
33957+		},
33958+		.driver    = &spi_driver_general,
33959+	},
33960+
33961+	/* GD 1.8v GD5F1GQ4RB9IG 1Gbit */
33962+	{
33963+		.name      = "GD5F1GQ4RB9IG",
33964+		.id        = {0xc8, 0xc1},
33965+		.id_len    = 2,
33966+		.chipsize  = _128M,
33967+		.erasesize = _128K,
33968+		.pagesize  = _2K,
33969+		.oobsize   = 128,
33970+		.badblock_pos = BBP_FIRST_PAGE,
33971+		.read      = {
33972+			&READ_STD(1, INFINITE, 24),
33973+			&READ_FAST(1, INFINITE, 120),
33974+			&READ_DUAL(1, INFINITE, 120),
33975+			&READ_DUAL_ADDR(1, INFINITE, 120),
33976+			&READ_QUAD(1, INFINITE, 120),
33977+			&READ_QUAD_ADDR(1, INFINITE, 120),
33978+			0
33979+		},
33980+		.write     = {
33981+			&WRITE_STD(0, 256, 24),
33982+			&WRITE_QUAD(0, 256, 120),
33983+			0
33984+		},
33985+		.erase     = {
33986+			&ERASE_SECTOR_128K(0, _128K, 24),
33987+			0
33988+		},
33989+		.driver    = &spi_driver_general,
33990+	},
33991+
33992+	/* GD 3.3v GD5F1GQ4UBYIG 1Gbit */
33993+	{
33994+		.name      = "GD5F1GQ4UBYIG",
33995+		.id        = {0xc8, 0xd1},
33996+		.id_len    = 2,
33997+		.chipsize  = _128M,
33998+		.erasesize = _128K,
33999+		.pagesize  = _2K,
34000+		.oobsize   = 128,
34001+		.badblock_pos = BBP_FIRST_PAGE,
34002+		.read      = {
34003+			&READ_STD(1, INFINITE, 24),
34004+			&READ_FAST(1, INFINITE, 120),
34005+			&READ_DUAL(1, INFINITE, 120),
34006+			&READ_DUAL_ADDR(1, INFINITE, 120),
34007+			&READ_QUAD(1, INFINITE, 120),
34008+			&READ_QUAD_ADDR(1, INFINITE, 120),
34009+			0
34010+		},
34011+		.write     = {
34012+			&WRITE_STD(0, 256, 24),
34013+			&WRITE_QUAD(0, 256, 120),
34014+			0
34015+		},
34016+		.erase     = {
34017+			&ERASE_SECTOR_128K(0, _128K, 24),
34018+			0
34019+		},
34020+		.driver    = &spi_driver_general,
34021+	},
34022+
34023+	/* GD 3.3v GD5F2GQ4UAYIG 2Gbit */
34024+	{
34025+		.name      = "GD5F2GQ4UAYIG",
34026+		.id        = {0xc8, 0xf2},
34027+		.id_len    = 2,
34028+		.chipsize  = _256M,
34029+		.erasesize = _128K,
34030+		.pagesize  = _2K,
34031+		.oobsize   = 64,
34032+		.badblock_pos = BBP_FIRST_PAGE,
34033+		.read      = {
34034+			&READ_STD(1, INFINITE, 24),
34035+			&READ_FAST(1, INFINITE, 120),
34036+			&READ_DUAL(1, INFINITE, 120),
34037+			&READ_DUAL_ADDR(1, INFINITE, 120),
34038+			&READ_QUAD(1, INFINITE, 120),
34039+			&READ_QUAD_ADDR(1, INFINITE, 120),
34040+			0
34041+		},
34042+		.write     = {
34043+			&WRITE_STD(0, 256, 24),
34044+			&WRITE_QUAD(0, 256, 120),
34045+			0
34046+		},
34047+		.erase     = {
34048+			&ERASE_SECTOR_128K(0, _128K, 24),
34049+			0
34050+		},
34051+		.driver    = &spi_driver_general,
34052+	},
34053+
34054+	/* GD 3.3v GD5F2GQ4U9IGR/BYIG 2Gbit */
34055+	{
34056+		.name      = "GD5F2GQ4U9IGR/BYIG",
34057+		.id        = {0xc8, 0xd2},
34058+		.id_len    = 2,
34059+		.chipsize  = _256M,
34060+		.erasesize = _128K,
34061+		.pagesize  = _2K,
34062+		.oobsize   = 128,
34063+		.badblock_pos = BBP_FIRST_PAGE,
34064+		.read      = {
34065+			&READ_STD(1, INFINITE, 24),
34066+			&READ_FAST(1, INFINITE, 120),
34067+			&READ_DUAL(1, INFINITE, 120),
34068+			&READ_DUAL_ADDR(1, INFINITE, 120),
34069+			&READ_QUAD(1, INFINITE, 120),
34070+			&READ_QUAD_ADDR(1, INFINITE, 120),
34071+			0
34072+		},
34073+		.write     = {
34074+			&WRITE_STD(0, 256, 24),
34075+			&WRITE_QUAD(0, 256, 120),
34076+			0
34077+		},
34078+		.erase     = {
34079+			&ERASE_SECTOR_128K(0, _128K, 24),
34080+			0
34081+		},
34082+		.driver    = &spi_driver_general,
34083+	},
34084+
34085+	/* GD 3.3v GD5F2GQ5UEYIG 2Gbit */
34086+	{
34087+		.name      = "GD5F2GQ5UEYIG",
34088+		.id        = {0xc8, 0x52},
34089+		.id_len    = 2,
34090+		.chipsize  = _256M,
34091+		.erasesize = _128K,
34092+		.pagesize  = _2K,
34093+		.oobsize   = 128,
34094+		.badblock_pos = BBP_FIRST_PAGE,
34095+		.read      = {
34096+			&READ_STD(1, INFINITE, 24),
34097+			&READ_FAST(1, INFINITE, 104),
34098+			&READ_DUAL(1, INFINITE, 104),
34099+			&READ_DUAL_ADDR(2, INFINITE, 104),
34100+			&READ_QUAD(1, INFINITE, 104),
34101+			&READ_QUAD_ADDR(4, INFINITE, 104),
34102+			0
34103+		},
34104+		.write     = {
34105+			&WRITE_STD(0, 256, 104),
34106+			&WRITE_QUAD(0, 256, 120),
34107+			0
34108+		},
34109+		.erase     = {
34110+			&ERASE_SECTOR_128K(0, _128K, 104),
34111+			0
34112+		},
34113+		.driver    = &spi_driver_general,
34114+	},
34115+
34116+	/* GD 1.8v GD5F2GQ5REYIG 2Gbit */
34117+	{
34118+        .name      = "GD5F2GQ5REYIG",
34119+        .id        = {0xc8, 0x42},
34120+        .id_len    = 2,
34121+        .chipsize  = _256M,
34122+        .erasesize = _128K,
34123+        .pagesize  = _2K,
34124+        .oobsize   = 128,
34125+        .badblock_pos = BBP_FIRST_PAGE,
34126+        .read      = {
34127+            &READ_STD(1, INFINITE, 24),
34128+            &READ_FAST(1, INFINITE, 104),
34129+            &READ_DUAL(1, INFINITE, 104),
34130+            &READ_DUAL_ADDR(2, INFINITE, 104),
34131+            &READ_QUAD(1, INFINITE, 104),
34132+            &READ_QUAD_ADDR(4, INFINITE, 104),
34133+            0
34134+        },
34135+        .write     = {
34136+            &WRITE_STD(0, 256, 104),
34137+            &WRITE_QUAD(0, 256, 104),
34138+            0
34139+        },
34140+        .erase     = {
34141+            &ERASE_SECTOR_128K(0, _128K, 104),
34142+            0
34143+        },
34144+        .driver    = &spi_driver_general,
34145+    },
34146+
34147+	/* GD 3.3v GD5F4GQ4UAYIG 4Gbit */
34148+	{
34149+		.name      = "GD5F4GQ4UAYIG",
34150+		.id        = {0xc8, 0xf4},
34151+		.id_len    = 2,
34152+		.chipsize  = _512M,
34153+		.erasesize = _128K,
34154+		.pagesize  = _2K,
34155+		.oobsize   = 64,
34156+		.badblock_pos = BBP_FIRST_PAGE,
34157+		.read      = {
34158+			&READ_STD(1, INFINITE, 24),
34159+			&READ_FAST(1, INFINITE, 120),
34160+			&READ_DUAL(1, INFINITE, 120),
34161+			&READ_DUAL_ADDR(1, INFINITE, 120),
34162+			&READ_QUAD(1, INFINITE, 120),
34163+			&READ_QUAD_ADDR(1, INFINITE, 120),
34164+			0
34165+		},
34166+		.write     = {
34167+			&WRITE_STD(0, 256, 24),
34168+			&WRITE_QUAD(0, 256, 120),
34169+			0
34170+		},
34171+		.erase     = {
34172+			&ERASE_SECTOR_128K(0, _128K, 24),
34173+			0
34174+		},
34175+		.driver    = &spi_driver_general,
34176+	},
34177+
34178+	/* GD 3.3v GD5F4GQ4UBYIG 4Gbit */
34179+	{
34180+		.name      = "GD5F4GQ4UBYIG",
34181+		.id        = {0xc8, 0xd4},
34182+		.id_len    = 2,
34183+		.chipsize  = _512M,
34184+		.erasesize = _256K,
34185+		.pagesize  = _4K,
34186+		.oobsize   = 256,
34187+		.badblock_pos = BBP_FIRST_PAGE,
34188+		.read      = {
34189+			&READ_STD(1, INFINITE, 24),
34190+			&READ_FAST(1, INFINITE, 120),
34191+			&READ_DUAL(1, INFINITE, 120),
34192+			&READ_DUAL_ADDR(1, INFINITE, 120),
34193+			&READ_QUAD(1, INFINITE, 120),
34194+			&READ_QUAD_ADDR(1, INFINITE, 120),
34195+			0
34196+		},
34197+		.write     = {
34198+			&WRITE_STD(0, 256, 24),
34199+			&WRITE_QUAD(0, 256, 120),
34200+			0
34201+		},
34202+		.erase     = {
34203+			&ERASE_SECTOR_256K(0, _256K, 24),
34204+			0
34205+		},
34206+		.driver    = &spi_driver_general,
34207+	},
34208+
34209+	/* GD 3.3v GD5F4GQ6UEYIG 4Gbit */
34210+	{
34211+		.name      = "GD5F4GQ6UEYIG",
34212+		.id        = {0xc8, 0x55},
34213+		.id_len    = 2,
34214+		.chipsize  = _512M,
34215+		.erasesize = _128K,
34216+		.pagesize  = _2K,
34217+		.oobsize   = 128,
34218+		.badblock_pos = BBP_FIRST_PAGE,
34219+		.read      = {
34220+			&READ_STD(1, INFINITE, 24), /* 24MHz */
34221+			&READ_FAST(1, INFINITE, 104),  /* 104MHz */
34222+			&READ_DUAL(1, INFINITE, 104),  /* 104MHz */
34223+			&READ_DUAL_ADDR(2, INFINITE, 104),  /* 104MHz */
34224+			&READ_QUAD(1, INFINITE, 104),  /* 104MHz */
34225+			&READ_QUAD_ADDR(4, INFINITE, 104),  /* 104MHz */
34226+			0
34227+		},
34228+		.write     = {
34229+			&WRITE_STD(0, 256, 24),  /* 24MHz */
34230+			&WRITE_QUAD(0, 256, 104),  /* 104MHz */
34231+			0
34232+		},
34233+		.erase     = {
34234+			&ERASE_SECTOR_128K(0, _128K, 104),  /* 104MHz */
34235+			0
34236+		},
34237+		.driver    = &spi_driver_general,
34238+	},
34239+
34240+	/* GD 1.8V GD5F1GQ4RB9IGR 1Gbit */
34241+	{
34242+		.name      = "GD5F1GQ4RB9IGR",
34243+		.id        = {0xc8, 0xc1},
34244+		.id_len    = 2,
34245+		.chipsize  = _128M,
34246+		.erasesize = _128K,
34247+		.pagesize  = _2K,
34248+		.oobsize   = 128,
34249+		.badblock_pos = BBP_FIRST_PAGE,
34250+		.read      = {
34251+			&READ_STD(1, INFINITE, 24),
34252+			&READ_FAST(1, INFINITE, 104),
34253+			&READ_DUAL(1, INFINITE, 104),
34254+			&READ_DUAL_ADDR(1, INFINITE, 104),
34255+			&READ_QUAD(1, INFINITE, 104),
34256+			&READ_QUAD_ADDR(1, INFINITE, 104),
34257+			0
34258+		},
34259+		.write     = {
34260+			&WRITE_STD(0, 256, 24),
34261+			&WRITE_QUAD(0, 256, 104),
34262+			0
34263+		},
34264+		.erase     = {
34265+			&ERASE_SECTOR_128K(0, _128K, 24),
34266+			0
34267+		},
34268+		.driver    = &spi_driver_general,
34269+	},
34270+
34271+	/* GD 1.8V GD5F2GQ4RB9IGR 2Gbit */
34272+	{
34273+		.name      = "GD5F2GQ4RB9IGR",
34274+		.id        = {0xc8, 0xc2},
34275+		.id_len    = 2,
34276+		.chipsize  = _256M,
34277+		.erasesize = _128K,
34278+		.pagesize  = _2K,
34279+		.oobsize   = 128,
34280+		.badblock_pos = BBP_FIRST_PAGE,
34281+		.read      = {
34282+			&READ_STD(1, INFINITE, 24),
34283+			&READ_FAST(1, INFINITE, 104),
34284+			&READ_DUAL(1, INFINITE, 104),
34285+			&READ_DUAL_ADDR(1, INFINITE, 104),
34286+			&READ_QUAD(1, INFINITE, 104),
34287+			&READ_QUAD_ADDR(1, INFINITE, 104),
34288+			0
34289+		},
34290+		.write     = {
34291+			&WRITE_STD(0, 256, 24),
34292+			&WRITE_QUAD(0, 256, 104),
34293+			0
34294+		},
34295+		.erase     = {
34296+			&ERASE_SECTOR_128K(0, _128K, 24),
34297+			0
34298+		},
34299+		.driver    = &spi_driver_general,
34300+	},
34301+	/* GD 1.8V 5F4GQ6RE9IG 4Gbit */
34302+	{
34303+		.name      = "GD5F4GQ6RE9IG",
34304+		.id        = {0xc8, 0x45},
34305+		.id_len    = 2,
34306+		.chipsize  = _512M,
34307+		.erasesize = _128K,
34308+		.pagesize  = _2K,
34309+		.oobsize   = 128,
34310+		.badblock_pos = BBP_FIRST_PAGE,
34311+		.read      = {
34312+			&READ_STD(1, INFINITE, 24),
34313+			&READ_FAST(1, INFINITE, 80),
34314+			&READ_DUAL(1, INFINITE, 80),
34315+			&READ_DUAL_ADDR(2, INFINITE, 80),
34316+			&READ_QUAD(1, INFINITE, 80),
34317+			&READ_QUAD_ADDR(4, INFINITE, 80),
34318+			0
34319+		},
34320+		.write     = {
34321+			&WRITE_STD(0, 256, 80),
34322+			&WRITE_QUAD(0, 256, 80),
34323+			0
34324+		},
34325+		.erase     = {
34326+			&ERASE_SECTOR_128K(0, _128K, 80),
34327+			0
34328+		},
34329+		.driver    = &spi_driver_general,
34330+	},
34331+	/* GD 1.8V GD5F4GQ4RAYIG 4Gbit */
34332+	{
34333+		.name      = "GD5F4GQ4RAYIG",
34334+		.id        = {0xc8, 0xe4},
34335+		.id_len    = 2,
34336+		.chipsize  = _512M,
34337+		.erasesize = _256K,
34338+		.pagesize  = _4K,
34339+		.oobsize   = 256,
34340+		.badblock_pos = BBP_FIRST_PAGE,
34341+		.read      = {
34342+			&READ_STD(1, INFINITE, 24),
34343+			&READ_FAST(1, INFINITE, 104),
34344+			&READ_DUAL(1, INFINITE, 104),
34345+			&READ_DUAL_ADDR(1, INFINITE, 104),
34346+			&READ_QUAD(1, INFINITE, 104),
34347+			&READ_QUAD_ADDR(1, INFINITE, 104),
34348+			0
34349+		},
34350+		.write     = {
34351+			&WRITE_STD(0, 256, 24),
34352+			&WRITE_QUAD(0, 256, 104),
34353+			0
34354+		},
34355+		.erase     = {
34356+			&ERASE_SECTOR_256K(0, _256K, 24),
34357+			0
34358+		},
34359+		.driver    = &spi_driver_general,
34360+	},
34361+
34362+	/* Winbond 1.8V W25N02JWZEIF 2Gbit */
34363+	{
34364+		.name      = "W25N02JWZEIF",
34365+		.id        = {0xef, 0xbf, 0x22},
34366+		.id_len    = 3,
34367+		.chipsize  = _256M,
34368+		.erasesize = _128K,
34369+		.pagesize  = _2K,
34370+		.oobsize   = 64,
34371+		.badblock_pos = BBP_FIRST_PAGE,
34372+		.read      = {
34373+			&READ_STD(1, INFINITE, 24),
34374+			&READ_FAST(1, INFINITE, 120),
34375+			&READ_DUAL(1, INFINITE, 120),
34376+			&READ_DUAL_ADDR(1, INFINITE, 120),
34377+			&READ_QUAD(1, INFINITE, 120),
34378+			&READ_QUAD_ADDR(2, INFINITE, 104),
34379+			0
34380+		},
34381+		.write     = {
34382+			&WRITE_STD(0, 256, 104),
34383+			&WRITE_QUAD(0, 256, 104),
34384+			0
34385+		},
34386+		.erase     = {
34387+			&ERASE_SECTOR_128K(0, _128K, 104),
34388+			0
34389+		},
34390+		.driver  = &spi_driver_general,
34391+	},
34392+
34393+	/* GD 1.8V 5F4GQ4RBYIG 4Gbit */
34394+	{
34395+		.name      = "5F4GQ4RBYIG",
34396+		.id        = {0xc8, 0xc4},
34397+		.id_len    = 2,
34398+		.chipsize  = _512M,
34399+		.erasesize = _256K,
34400+		.pagesize  = _4K,
34401+		.oobsize   = 256,
34402+		.badblock_pos = BBP_FIRST_PAGE,
34403+		.read      = {
34404+			&READ_STD(1, INFINITE, 24),
34405+			&READ_FAST(1, INFINITE, 120),
34406+			&READ_DUAL(1, INFINITE, 120),
34407+			&READ_DUAL_ADDR(1, INFINITE, 120),
34408+			&READ_QUAD(1, INFINITE, 120),
34409+			&READ_QUAD_ADDR(1, INFINITE, 120),
34410+			0
34411+		},
34412+		.write     = {
34413+			&WRITE_STD(0, 256, 24),
34414+			&WRITE_QUAD(0, 256, 120),
34415+			0
34416+		},
34417+		.erase     = {
34418+			&ERASE_SECTOR_256K(0, _256K, 24),
34419+			0
34420+		},
34421+		.driver    = &spi_driver_general,
34422+	},
34423+
34424+	/* Winbond W25N01GV 1Gbit 3.3V */
34425+	{
34426+		.name      = "W25N01GV",
34427+		.id        = {0xef, 0xaa, 0x21},
34428+		.id_len    = 3,
34429+		.chipsize  = _128M,
34430+		.erasesize = _128K,
34431+		.pagesize  = _2K,
34432+		.oobsize   = 64,
34433+		.badblock_pos = BBP_FIRST_PAGE,
34434+		.read      = {
34435+			&READ_STD(1, INFINITE, 24),
34436+			&READ_FAST(1, INFINITE, 104),
34437+			&READ_DUAL(1, INFINITE, 104),
34438+			&READ_DUAL_ADDR(1, INFINITE, 104),
34439+			&READ_QUAD(1, INFINITE, 104),
34440+			&READ_QUAD_ADDR(2, INFINITE, 104),
34441+			0
34442+		},
34443+		.write     = {
34444+			&WRITE_STD(0, 256, 24),
34445+			&WRITE_QUAD(0, 256, 104),
34446+			0
34447+		},
34448+		.erase     = {
34449+			&ERASE_SECTOR_128K(0, _128K, 24),
34450+			0
34451+		},
34452+		.driver    = &spi_driver_no_qe,
34453+	},
34454+
34455+	/* Winbond W25N01GWZEIG 1Gbit 1.8V */
34456+	{
34457+		.name      = "W25N01GWZEIG",
34458+		.id        = {0xef, 0xba, 0x21},
34459+		.id_len    = 3,
34460+		.chipsize  = _128M,
34461+		.erasesize = _128K,
34462+		.pagesize  = _2K,
34463+		.oobsize   = 64,
34464+		.badblock_pos = BBP_FIRST_PAGE,
34465+		.read      = {
34466+			&READ_STD(1, INFINITE, 24),
34467+			&READ_FAST(1, INFINITE, 104),
34468+			&READ_DUAL(1, INFINITE, 104),
34469+			&READ_DUAL_ADDR(1, INFINITE, 104),
34470+			&READ_QUAD(1, INFINITE, 104),
34471+			&READ_QUAD_ADDR(2, INFINITE, 104),
34472+			0
34473+		},
34474+		.write     = {
34475+			&WRITE_STD(0, 256, 24),
34476+			&WRITE_QUAD(0, 256, 80),
34477+			0
34478+		},
34479+		.erase     = {
34480+			&ERASE_SECTOR_128K(0, _128K, 24),
34481+			0
34482+		},
34483+		.driver    = &spi_driver_no_qe,
34484+	},
34485+
34486+	/* ATO ATO25D1GA 1Gbit */
34487+	{
34488+		.name      = "ATO25D1GA",
34489+		.id        = {0x9b, 0x12},
34490+		.id_len    = 2,
34491+		.chipsize  = _128M,
34492+		.erasesize = _128K,
34493+		.pagesize  = _2K,
34494+		.oobsize   = 64,
34495+		.badblock_pos = BBP_FIRST_PAGE,
34496+		.read      = {
34497+			&READ_STD(1, INFINITE, 24),
34498+			&READ_FAST(1, INFINITE, 104),
34499+			&READ_QUAD(1, INFINITE, 104),
34500+			0
34501+		},
34502+		.write     = {
34503+			&WRITE_STD(0, 256, 24),
34504+			&WRITE_QUAD(0, 256, 104),
34505+			0
34506+		},
34507+		.erase     = {
34508+			&ERASE_SECTOR_128K(0, _128K, 24),
34509+			0
34510+		},
34511+		.driver    = &spi_driver_general,
34512+	},
34513+
34514+	/* MXIC MX35LF1GE4AB 1Gbit */
34515+	{
34516+		.name      = "MX35LF1GE4AB",
34517+		.id        = {0xc2, 0x12},
34518+		.id_len    = 2,
34519+		.chipsize  = _128M,
34520+		.erasesize = _128K,
34521+		.pagesize  = _2K,
34522+		.oobsize   = 64,
34523+		.badblock_pos = BBP_FIRST_PAGE,
34524+		.read      = {
34525+			&READ_STD(1, INFINITE, 24),
34526+			&READ_FAST(1, INFINITE, 104),
34527+			&READ_QUAD(1, INFINITE, 104),
34528+			0
34529+		},
34530+		.write     = {
34531+			&WRITE_STD(0, 256, 24),
34532+			&WRITE_QUAD(0, 256, 104),
34533+			0
34534+		},
34535+		.erase     = {
34536+			&ERASE_SECTOR_128K(0, _128K, 24),
34537+			0
34538+		},
34539+		.driver    = &spi_driver_general,
34540+	},
34541+
34542+	/* MXIC MX35UF1G14AC 1Gbit 1.8V */
34543+	{
34544+		.name      = "MX35UF1G14AC",
34545+		.id        = {0xc2, 0x90},
34546+		.id_len    = 2,
34547+		.chipsize  = _128M,
34548+		.erasesize = _128K,
34549+		.pagesize  = _2K,
34550+		.oobsize   = 64,
34551+		.badblock_pos = BBP_FIRST_PAGE,
34552+		.read      = {
34553+			&READ_STD(1, INFINITE, 24),
34554+			&READ_FAST(1, INFINITE, 104),
34555+			&READ_QUAD(1, INFINITE, 104),
34556+			0
34557+		},
34558+		.write     = {
34559+			&WRITE_STD(0, 256, 24),
34560+			&WRITE_QUAD(0, 256, 104),
34561+			0
34562+		},
34563+		.erase     = {
34564+			&ERASE_SECTOR_128K(0, _128K, 104),
34565+			0
34566+		},
34567+		.driver    = &spi_driver_general,
34568+	},
34569+
34570+	/* MXIC MX35LF2GE4AB 2Gbit SOP-16Pin */
34571+	{
34572+		.name      = "MX35LF2GE4AB",
34573+		.id        = {0xc2, 0x22},
34574+		.id_len    = 2,
34575+		.chipsize  = _256M,
34576+		.erasesize = _128K,
34577+		.pagesize  = _2K,
34578+		.oobsize   = 64,
34579+		.badblock_pos = BBP_FIRST_PAGE,
34580+		.read      = {
34581+			&READ_STD(1, INFINITE, 24),
34582+			&READ_FAST(1, INFINITE, 104),
34583+			&READ_QUAD(1, INFINITE, 104),
34584+			0
34585+		},
34586+		.write     = {
34587+			&WRITE_STD(0, 256, 24),
34588+			&WRITE_QUAD(0, 256, 104),
34589+			0
34590+		},
34591+		.erase     = {
34592+			&ERASE_SECTOR_128K(0, _128K, 24),
34593+			0
34594+		},
34595+		.driver    = &spi_driver_general,
34596+	},
34597+
34598+	/* MXIC MX35LF2G14AC 2GBit */
34599+	{
34600+		.name      = "MX35LF2G14AC",
34601+		.id        = {0xc2, 0x20},
34602+		.id_len    = 2,
34603+		.chipsize  = _256M,
34604+		.erasesize = _128K,
34605+		.pagesize  = _2K,
34606+		.oobsize   = 64,
34607+		.badblock_pos = BBP_FIRST_PAGE,
34608+		.read      = {
34609+			&READ_STD(1, INFINITE, 24),
34610+			&READ_FAST(1, INFINITE, 104),
34611+			&READ_QUAD(1, INFINITE, 104),
34612+			0
34613+		},
34614+		.write     = {
34615+			&WRITE_STD(0, 256, 24),
34616+			&WRITE_QUAD(0, 256, 104),
34617+			0
34618+		},
34619+		.erase     = {
34620+			&ERASE_SECTOR_128K(0, _128K, 24),
34621+			0
34622+		},
34623+		.driver    = &spi_driver_general,
34624+	},
34625+
34626+	/* MXIC MX35UF2G14AC 2Gbit 1.8V */
34627+	{
34628+		.name      = "MX35UF2G14AC",
34629+		.id        = {0xc2, 0xa0},
34630+		.id_len    = 2,
34631+		.chipsize  = _256M,
34632+		.erasesize = _128K,
34633+		.pagesize  = _2K,
34634+		.oobsize   = 64,
34635+		.badblock_pos = BBP_FIRST_PAGE,
34636+		.read      = {
34637+			&READ_STD(1, INFINITE, 24),
34638+			&READ_FAST(1, INFINITE, 104),
34639+			&READ_QUAD(1, INFINITE, 104),
34640+			0
34641+		},
34642+		.write     = {
34643+			&WRITE_STD(0, 256, 24),
34644+			&WRITE_QUAD(0, 256, 104),
34645+			0
34646+		},
34647+		.erase     = {
34648+			&ERASE_SECTOR_128K(0, _128K, 104),
34649+			0
34650+		},
34651+		.driver    = &spi_driver_general,
34652+	},
34653+
34654+	/* Paragon PN26G01A 1Gbit */
34655+	{
34656+		.name      = "PN26G01A",
34657+		.id        = {0xa1, 0xe1},
34658+		.id_len    = 2,
34659+		.chipsize  = _128M,
34660+		.erasesize = _128K,
34661+		.pagesize  = _2K,
34662+		.oobsize   = 128,
34663+		.badblock_pos = BBP_FIRST_PAGE,
34664+		.read      = {
34665+			&READ_STD(1, INFINITE, 24),
34666+			&READ_FAST(1, INFINITE, 108),
34667+			&READ_DUAL(1, INFINITE, 108),
34668+			&READ_DUAL_ADDR(1, INFINITE, 108),
34669+			&READ_QUAD(1, INFINITE, 108),
34670+			&READ_QUAD_ADDR(1, INFINITE, 108),
34671+			0
34672+		},
34673+		.write     = {
34674+			&WRITE_STD(0, 256, 24),
34675+			&WRITE_QUAD(0, 256, 108),
34676+			0
34677+		},
34678+		.erase     = {
34679+			&ERASE_SECTOR_128K(0, _128K, 24),
34680+			0
34681+		},
34682+		.driver    = &spi_driver_general,
34683+	},
34684+
34685+	/* Paragon PN26G02A 2Gbit */
34686+	{
34687+		.name      = "PN26G02A",
34688+		.id        = {0xa1, 0xe2},
34689+		.id_len    = 2,
34690+		.chipsize  = _256M,
34691+		.erasesize = _128K,
34692+		.pagesize  = _2K,
34693+		.oobsize   = 128,
34694+		.badblock_pos = BBP_FIRST_PAGE,
34695+		.read      = {
34696+			&READ_STD(1, INFINITE, 24),
34697+			&READ_FAST(1, INFINITE, 108),
34698+			&READ_DUAL(1, INFINITE, 108),
34699+			&READ_DUAL_ADDR(1, INFINITE, 108),
34700+			&READ_QUAD(1, INFINITE, 108),
34701+			&READ_QUAD_ADDR(1, INFINITE, 108),
34702+			0
34703+		},
34704+		.write     = {
34705+			&WRITE_STD(0, 256, 24),
34706+			&WRITE_QUAD(0, 256, 108),
34707+			0
34708+		},
34709+		.erase     = {
34710+			&ERASE_SECTOR_128K(0, _128K, 24),
34711+			0
34712+		},
34713+		.driver    = &spi_driver_general,
34714+	},
34715+
34716+	/* All-flash AFS1GQ4UAC 1Gbit */
34717+	{
34718+		.name      = "AFS1GQ4UAC",
34719+		.id        = {0xc1, 0x51},
34720+		.id_len    = 2,
34721+		.chipsize  = _128M,
34722+		.erasesize = _128K,
34723+		.pagesize  = _2K,
34724+		.oobsize   = 128,
34725+		.badblock_pos = BBP_FIRST_PAGE,
34726+		.read      = {
34727+			&READ_STD(1, INFINITE, 24),
34728+			&READ_FAST(1, INFINITE, 80),
34729+			&READ_DUAL(1, INFINITE, 80),
34730+			&READ_DUAL_ADDR(1, INFINITE, 80),
34731+			&READ_QUAD(1, INFINITE, 80),
34732+			&READ_QUAD_ADDR(1, INFINITE, 80),
34733+			0
34734+		},
34735+		.write     = {
34736+			&WRITE_STD(0, 256, 24),
34737+			&WRITE_QUAD(0, 256, 80),
34738+			0
34739+		},
34740+		.erase     = {
34741+			&ERASE_SECTOR_128K(0, _128K, 24),
34742+			0
34743+		},
34744+		.driver    = &spi_driver_general,
34745+	},
34746+
34747+	/* All-flash AFS2GQ4UAD 2Gbit */
34748+	{
34749+		.name      = "AFS2GQ4UAD",
34750+		.id        = {0xc1, 0x52},
34751+		.id_len    = 2,
34752+		.chipsize  = _256M,
34753+		.erasesize = _128K,
34754+		.pagesize  = _2K,
34755+		.oobsize   = 128,
34756+		.badblock_pos = BBP_FIRST_PAGE,
34757+		.read      = {
34758+			&READ_STD(1, INFINITE, 24),
34759+			&READ_FAST(1, INFINITE, 80),
34760+			&READ_DUAL(1, INFINITE, 80),
34761+			&READ_DUAL_ADDR(1, INFINITE, 80),
34762+			&READ_QUAD(1, INFINITE, 80),
34763+			&READ_QUAD_ADDR(1, INFINITE, 80),
34764+			0
34765+		},
34766+		.write     = {
34767+			&WRITE_STD(0, 256, 24),
34768+			&WRITE_QUAD(0, 256, 80),
34769+			0
34770+		},
34771+		.erase     = {
34772+			&ERASE_SECTOR_128K(0, _128K, 24),
34773+			0
34774+		},
34775+		.driver    = &spi_driver_general,
34776+	},
34777+
34778+	/* TOSHIBA TC58CVG0S3H 1Gbit */
34779+	{
34780+		.name      = "TC58CVG0S3H",
34781+		.id        = {0x98, 0xc2},
34782+		.id_len    = 2,
34783+		.chipsize  = _128M,
34784+		.erasesize = _128K,
34785+		.pagesize  = _2K,
34786+		.oobsize   = 128,
34787+		.badblock_pos = BBP_FIRST_PAGE,
34788+		.read      = {
34789+			&READ_STD(1, INFINITE, 24),
34790+			&READ_FAST(1, INFINITE, 104),
34791+			&READ_DUAL(1, INFINITE, 104),
34792+			&READ_QUAD(1, INFINITE, 104),
34793+			0
34794+		},
34795+		.write     = {
34796+			&WRITE_STD(0, 256, 104),
34797+			0
34798+		},
34799+		.erase     = {
34800+			&ERASE_SECTOR_128K(0, _128K, 104),
34801+			0
34802+		},
34803+		.driver    = &spi_driver_no_qe,
34804+	},
34805+
34806+	{
34807+		.name      = "TC58CVG0S3HRAIJ",
34808+		.id        = {0x98, 0xe2, 0x40},
34809+		.id_len    = 3,
34810+		.chipsize  = _128M,
34811+		.erasesize = _128K,
34812+		.pagesize  = _2K,
34813+		.oobsize   = 128,
34814+		.badblock_pos = BBP_FIRST_PAGE,
34815+		.read      = {
34816+			&READ_STD(1, INFINITE, 24),
34817+			&READ_FAST(1, INFINITE, 133),
34818+			&READ_DUAL(1, INFINITE, 133),
34819+			&READ_QUAD(1, INFINITE, 133),
34820+			0
34821+		},
34822+		.write     = {
34823+			&WRITE_STD(0, 256, 133),
34824+			&WRITE_QUAD(0, 256, 133),
34825+			0
34826+		},
34827+		.erase     = {
34828+			&ERASE_SECTOR_128K(0, _128K, 133),
34829+			0
34830+		},
34831+		.driver    = &spi_driver_no_qe,
34832+	},
34833+	/* TOSHIBA TC58CYG0S3H 1.8V 1Gbit */
34834+	{
34835+		.name      = "TC58CYG0S3H",
34836+		.id        = {0x98, 0xb2},
34837+		.id_len    = 2,
34838+		.chipsize  = _128M,
34839+		.erasesize = _128K,
34840+		.pagesize  = _2K,
34841+		.oobsize   = 128,
34842+		.badblock_pos = BBP_FIRST_PAGE,
34843+		.read      = {
34844+			&READ_STD(1, INFINITE, 24),
34845+			&READ_FAST(1, INFINITE, 104),
34846+			&READ_DUAL(1, INFINITE, 104),
34847+			&READ_QUAD(1, INFINITE, 104),
34848+			0
34849+		},
34850+		.write     = {
34851+			&WRITE_STD(0, 256, 104),
34852+			0
34853+		},
34854+		.erase     = {
34855+			&ERASE_SECTOR_128K(0, _128K, 104),
34856+			0
34857+		},
34858+		.driver    = &spi_driver_no_qe,
34859+	},
34860+
34861+	/* TOSHIBA TC58CYG0S3HRAIJ 1.8V 1Gbit */
34862+	{
34863+		.name      = "TC58CYG0S3HRAIJ",
34864+		.id        = {0x98, 0xD2, 0x40},
34865+		.id_len    = 3,
34866+		.chipsize  = _128M,
34867+		.erasesize = _128K,
34868+		.pagesize  = _2K,
34869+		.oobsize   = 128,
34870+		.badblock_pos = BBP_FIRST_PAGE,
34871+		.read      = {
34872+			&READ_STD(1, INFINITE, 24),
34873+			&READ_FAST(1, INFINITE, 133),
34874+			&READ_DUAL(1, INFINITE, 133),
34875+			&READ_QUAD(1, INFINITE, 133),
34876+			0
34877+		},
34878+		.write     = {
34879+			&WRITE_STD(0, 256, 133),
34880+			&WRITE_QUAD(0, 256, 133),
34881+			0
34882+		},
34883+		.erase     = {
34884+			&ERASE_SECTOR_128K(0, _128K, 133),
34885+			0
34886+		},
34887+		.driver    = &spi_driver_no_qe,
34888+	},
34889+
34890+	/* TOSHIBA TC58CVG1S3H 2Gbit */
34891+	{
34892+		.name      = "TC58CVG1S3H",
34893+		.id        = {0x98, 0xcb},
34894+		.id_len    = 2,
34895+		.chipsize  = _256M,
34896+		.erasesize = _128K,
34897+		.pagesize  = _2K,
34898+		.oobsize   = 128,
34899+		.badblock_pos = BBP_FIRST_PAGE,
34900+		.read      = {
34901+			&READ_STD(1, INFINITE, 24),
34902+			&READ_FAST(1, INFINITE, 104),
34903+			&READ_DUAL(1, INFINITE, 104),
34904+			&READ_QUAD(1, INFINITE, 104),
34905+			0
34906+		},
34907+		.write     = {
34908+			&WRITE_STD(0, 256, 104),
34909+			0
34910+		},
34911+		.erase     = {
34912+			&ERASE_SECTOR_128K(0, _128K, 104),
34913+			0
34914+		},
34915+		.driver    = &spi_driver_no_qe,
34916+	},
34917+
34918+	/* TOSHIBA TC58CVG1S3HRAIJ 2Gbit */
34919+	{
34920+		.name      = "TC58CVG1S3HRAIJ",
34921+		.id        = {0x98, 0xeb, 0x40},
34922+		.id_len    = 3,
34923+		.chipsize  = _256M,
34924+		.erasesize = _128K,
34925+		.pagesize  = _2K,
34926+		.oobsize   = 128,
34927+		.badblock_pos = BBP_FIRST_PAGE,
34928+		.read      = {
34929+			&READ_STD(1, INFINITE, 24),
34930+			&READ_FAST(1, INFINITE, 133),
34931+			&READ_DUAL(1, INFINITE, 133),
34932+			&READ_QUAD(1, INFINITE, 133),
34933+			0
34934+		},
34935+		.write     = {
34936+			&WRITE_STD(0, 256, 133),
34937+			&WRITE_QUAD(0, 256, 133),
34938+			0
34939+		},
34940+		.erase     = {
34941+			&ERASE_SECTOR_128K(0, _128K, 133),
34942+			0
34943+		},
34944+		.driver    = &spi_driver_no_qe,
34945+	},
34946+
34947+	/* TOSHIBA TC58CYG1S3H 1.8V 2Gbit */
34948+	{
34949+		.name      = "TC58CYG1S3H",
34950+		.id        = {0x98, 0xbb},
34951+		.id_len    = 2,
34952+		.chipsize  = _256M,
34953+		.erasesize = _128K,
34954+		.pagesize  = _2K,
34955+		.oobsize   = 128,
34956+		.badblock_pos = BBP_FIRST_PAGE,
34957+		.read      = {
34958+			&READ_STD(1, INFINITE, 24),
34959+			&READ_FAST(1, INFINITE, 104),
34960+			&READ_DUAL(1, INFINITE, 104),
34961+			&READ_QUAD(1, INFINITE, 104),
34962+			0
34963+		},
34964+		.write     = {
34965+			&WRITE_STD(0, 256, 75),
34966+			0
34967+		},
34968+		.erase     = {
34969+			&ERASE_SECTOR_128K(0, _128K, 75),
34970+			0
34971+		},
34972+		.driver    = &spi_driver_no_qe,
34973+	},
34974+
34975+	/* TOSHIBA TC58CYG1S3HRAIJ 1.8V 2Gbit */
34976+	{
34977+		.name      = "TC58CYG1S3HRAIJ",
34978+		.id        = {0x98, 0xdb, 0x40},
34979+		.id_len    = 3,
34980+		.chipsize  = _256M,
34981+		.erasesize = _128K,
34982+		.pagesize  = _2K,
34983+		.oobsize   = 128,
34984+		.badblock_pos = BBP_FIRST_PAGE,
34985+		.read      = {
34986+			&READ_STD(1, INFINITE, 24),
34987+			&READ_FAST(1, INFINITE, 133),
34988+			&READ_DUAL(1, INFINITE, 133),
34989+			&READ_QUAD(1, INFINITE, 133),
34990+			0
34991+		},
34992+		.write     = {
34993+			&WRITE_STD(0, 256, 133),
34994+			&WRITE_QUAD(0, 256, 133),
34995+			0
34996+		},
34997+		.erase     = {
34998+			&ERASE_SECTOR_128K(0, _128K, 133),
34999+			0
35000+		},
35001+		.driver    = &spi_driver_no_qe,
35002+	},
35003+
35004+	/* TOSHIBA TC58CVG2S0H 4Gbit */
35005+	{
35006+		.name      = "TC58CVG2S0H",
35007+		.id        = {0x98, 0xcd},
35008+		.id_len    = 2,
35009+		.chipsize  = _512M,
35010+		.erasesize = _256K,
35011+		.pagesize  = _4K,
35012+		.oobsize   = 256,
35013+		.badblock_pos = BBP_FIRST_PAGE,
35014+		.read      = {
35015+			&READ_STD(1, INFINITE, 24),
35016+			&READ_FAST(1, INFINITE, 104),
35017+			&READ_DUAL(1, INFINITE, 104),
35018+			&READ_QUAD(1, INFINITE, 104),
35019+			0
35020+		},
35021+		.write     = {
35022+			&WRITE_STD(0, 256, 104),
35023+			0
35024+		},
35025+		.erase     = {
35026+			&ERASE_SECTOR_256K(0, _256K, 104),
35027+			0
35028+		},
35029+		.driver    = &spi_driver_no_qe,
35030+	},
35031+
35032+	/* TOSHIBA TC58CVG2S0HRAIJ 4Gbit */
35033+	{
35034+		.name      = "TC58CVG2S0HRAIJ",
35035+		.id        = {0x98, 0xed, 0x51},
35036+		.id_len    = 3,
35037+		.chipsize  = _512M,
35038+		.erasesize = _256K,
35039+		.pagesize  = _4K,
35040+		.oobsize   = 256,
35041+		.badblock_pos = BBP_FIRST_PAGE,
35042+		.read      = {
35043+			&READ_STD(1, INFINITE, 24),
35044+			&READ_FAST(1, INFINITE, 133),
35045+			&READ_DUAL(1, INFINITE, 133),
35046+			&READ_QUAD(1, INFINITE, 133),
35047+			0
35048+		},
35049+		.write     = {
35050+			&WRITE_STD(0, 256, 133),
35051+			&WRITE_QUAD(0, 256, 133),
35052+			0
35053+		},
35054+		.erase     = {
35055+			&ERASE_SECTOR_256K(0, _256K, 133),
35056+			0
35057+		},
35058+		.driver    = &spi_driver_no_qe,
35059+	},
35060+
35061+	/* TOSHIBA TC58CYG2S0H 1.8V 4Gbit */
35062+	{
35063+		.name      = "TC58CYG2S0H",
35064+		.id        = {0x98, 0xbd},
35065+		.id_len    = 2,
35066+		.chipsize  = _512M,
35067+		.erasesize = _256K,
35068+		.pagesize  = _4K,
35069+		.oobsize   = 256,
35070+		.badblock_pos = BBP_FIRST_PAGE,
35071+		.read      = {
35072+			&READ_STD(1, INFINITE, 24),
35073+			&READ_FAST(1, INFINITE, 104),
35074+			&READ_DUAL(1, INFINITE, 104),
35075+			&READ_QUAD(1, INFINITE, 104),
35076+			0
35077+		},
35078+		.write     = {
35079+			&WRITE_STD(0, 256, 75),
35080+			0
35081+		},
35082+		.erase     = {
35083+			&ERASE_SECTOR_256K(0, _256K, 75),
35084+			0
35085+		},
35086+		.driver    = &spi_driver_no_qe,
35087+	},
35088+
35089+	/* KIOXIA TH58CYG2S0HRAIJ 1.8V 4Gbit */
35090+	{
35091+		.name      = "TH58CYG2S0HRAIJ",
35092+		.id        = {0x98, 0xdd, 0x51},
35093+		.id_len    = 3,
35094+		.chipsize  = _512M,
35095+		.erasesize = _256K,
35096+		.pagesize  = _4K,
35097+		.oobsize   = 256,
35098+		.badblock_pos = BBP_FIRST_PAGE,
35099+		.read      = {
35100+			&READ_STD(1, INFINITE, 24), /* 24MHz */
35101+			&READ_FAST(1, INFINITE, 133), /* 133MHz */
35102+			&READ_DUAL(1, INFINITE, 133), /* 133MHz */
35103+			&READ_QUAD(1, INFINITE, 133), /* 133MHz */
35104+			0
35105+		},
35106+		.write     = {
35107+			&WRITE_STD(0, 256, 133), /* 133MHz */
35108+			&WRITE_QUAD(0, 256, 133), /* 133MHz */
35109+			0
35110+		},
35111+		.erase     = {
35112+			&ERASE_SECTOR_256K(0, _256K, 133), /* 133MHz */
35113+			0
35114+		},
35115+		.driver    = &spi_driver_no_qe,
35116+	},
35117+
35118+	/* KIOXIA TH58CYG3S0H 1.8V 8Gbit */
35119+	{
35120+		.name      = "TH58CYG3S0H",
35121+		.id        = {0x98, 0xd4, 0x51},
35122+		.id_len    = 3,
35123+		.chipsize  = _1G,
35124+		.erasesize = _256K,
35125+		.pagesize  = _4K,
35126+		.oobsize   = 256,
35127+		.badblock_pos = BBP_FIRST_PAGE,
35128+		.read      = {
35129+			&READ_STD(1, INFINITE, 24), /* 24MHz */
35130+			&READ_FAST(1, INFINITE, 133), /* 133MHz */
35131+			&READ_DUAL(1, INFINITE, 133), /* 133MHz */
35132+			&READ_QUAD(1, INFINITE, 133), /* 133MHz */
35133+			0
35134+		},
35135+		.write     = {
35136+			&WRITE_STD(0, 256, 133), /* 133MHz */
35137+			&WRITE_QUAD(0, 256, 133), /* 133MHz */
35138+			0
35139+		},
35140+		.erase     = {
35141+			&ERASE_SECTOR_256K(0, _256K, 133), /* 133MHz */
35142+			0
35143+		},
35144+		.driver    = &spi_driver_no_qe,
35145+	},
35146+
35147+	/* HeYangTek HYF1GQ4UAACAE 1Gbit */
35148+	{
35149+		.name      = "HYF1GQ4UAACAE",
35150+		.id        = {0xc9, 0x51},
35151+		.id_len    = 2,
35152+		.chipsize  = _128M,
35153+		.erasesize = _128K,
35154+		.pagesize  = _2K,
35155+		.oobsize   = 128,
35156+		.badblock_pos = BBP_FIRST_PAGE,
35157+		.read      = {
35158+			&READ_STD(1, INFINITE, 24),
35159+			&READ_FAST(1, INFINITE, 80),
35160+			&READ_DUAL(1, INFINITE, 80),
35161+			&READ_DUAL_ADDR(1, INFINITE, 80),
35162+			&READ_QUAD(1, INFINITE, 80),
35163+			&READ_QUAD_ADDR(1, INFINITE, 80),
35164+			0
35165+		},
35166+		.write     = {
35167+			&WRITE_STD(0, 256, 80),
35168+			&WRITE_QUAD(0, 256, 80),
35169+			0
35170+		},
35171+		.erase     = {
35172+			&ERASE_SECTOR_128K(0, _128K, 80),
35173+			0
35174+		},
35175+		.driver    = &spi_driver_general,
35176+	},
35177+
35178+	/* HeYangTek HYF2GQ4UAACAE 2Gbit */
35179+	{
35180+		.name      = "HYF2GQ4UAACAE",
35181+		.id        = {0xc9, 0x52},
35182+		.id_len    = 2,
35183+		.chipsize  = _256M,
35184+		.erasesize = _128K,
35185+		.pagesize  = _2K,
35186+		.oobsize   = 128,
35187+		.badblock_pos = BBP_FIRST_PAGE,
35188+		.read      = {
35189+			&READ_STD(1, INFINITE, 24),
35190+			&READ_FAST(1, INFINITE, 80),
35191+			&READ_DUAL(1, INFINITE, 80),
35192+			&READ_DUAL_ADDR(1, INFINITE, 80),
35193+			&READ_QUAD(1, INFINITE, 80),
35194+			&READ_QUAD_ADDR(1, INFINITE, 80),
35195+			0
35196+		},
35197+		.write     = {
35198+			&WRITE_STD(0, 256, 80),
35199+			&WRITE_QUAD(0, 256, 80),
35200+			0
35201+		},
35202+		.erase     = {
35203+			&ERASE_SECTOR_128K(0, _128K, 80),
35204+			0
35205+		},
35206+		.driver    = &spi_driver_general,
35207+	},
35208+
35209+	/* HeYangTek HYF4GQ4UAACBE 4Gbit */
35210+	{
35211+		.name      = "HYF4GQ4UAACBE",
35212+		.id        = {0xc9, 0xd4},
35213+		.id_len    = 2,
35214+		.chipsize  = _512M,
35215+		.erasesize = _256K,
35216+		.pagesize  = _4K,
35217+		.oobsize   = 256,
35218+		.badblock_pos = BBP_FIRST_PAGE,
35219+		.read      = {
35220+			&READ_STD(1, INFINITE, 24),
35221+			&READ_FAST(1, INFINITE, 80),
35222+			&READ_DUAL(1, INFINITE, 80),
35223+			&READ_DUAL_ADDR(1, INFINITE, 80),
35224+			&READ_QUAD(1, INFINITE, 80),
35225+			&READ_QUAD_ADDR(1, INFINITE, 80),
35226+			0
35227+		},
35228+		.write     = {
35229+			&WRITE_STD(0, 256, 80),
35230+			&WRITE_QUAD(0, 256, 80),
35231+			0
35232+		},
35233+		.erase     = {
35234+			&ERASE_SECTOR_256K(0, _256K, 80),
35235+			0
35236+		},
35237+		.driver    = &spi_driver_general,
35238+	},
35239+
35240+	/* Dosilicon 3.3V DS35Q1GA-IB 1Gbit */
35241+	{
35242+		.name      = "DS35Q1GA-IB",
35243+		.id        = {0xe5, 0x71},
35244+		.id_len    = 2,
35245+		.chipsize  = _128M,
35246+		.erasesize = _128K,
35247+		.pagesize  = _2K,
35248+		.oobsize   = 64,
35249+		.badblock_pos = BBP_FIRST_PAGE,
35250+		.read      = {
35251+			&READ_STD(1, INFINITE, 24),
35252+			&READ_FAST(1, INFINITE, 104),
35253+			&READ_DUAL(1, INFINITE, 104),
35254+			&READ_QUAD(1, INFINITE, 104),
35255+			0
35256+		},
35257+		.write     = {
35258+			&WRITE_STD(0, 256, 80),
35259+			&WRITE_QUAD(0, 256, 104),
35260+			0
35261+		},
35262+		.erase     = {
35263+			&ERASE_SECTOR_128K(0, _128K, 104),
35264+			0
35265+		},
35266+		.driver    = &spi_driver_general,
35267+	},
35268+
35269+	/* XTX 3.3V XT26G01B 1Gbit */
35270+	{
35271+		.name      = "XT26G01B",
35272+		.id        = {0x0B, 0xF1},
35273+		.id_len    = 2,
35274+		.chipsize  = _128M,
35275+		.erasesize = _128K,
35276+		.pagesize  = _2K,
35277+		.oobsize   = 64,
35278+		.badblock_pos = BBP_FIRST_PAGE,
35279+		.read      = {
35280+			&READ_STD(1, INFINITE, 24),
35281+			&READ_FAST(1, INFINITE, 80),
35282+			&READ_DUAL(1, INFINITE, 80),
35283+			&READ_DUAL_ADDR(1, INFINITE, 80),
35284+			&READ_QUAD(1, INFINITE, 80),
35285+			&READ_QUAD_ADDR(1, INFINITE, 80),
35286+			0
35287+		},
35288+		.write     = {
35289+			&WRITE_STD(0, 256, 80),
35290+			&WRITE_QUAD(0, 256, 80),
35291+			0
35292+		},
35293+		.erase     = {
35294+			&ERASE_SECTOR_128K(0, _128K, 80),
35295+			0
35296+		},
35297+		.driver    = &spi_driver_general,
35298+	},
35299+
35300+	/* Etron 1.8V EM78F044VCA-H 8Gbit */
35301+	{
35302+		.name      = "EM78F044VCA-H",
35303+		.id        = {0xD5, 0x8D},
35304+		.id_len    = 2,
35305+		.chipsize  = _512M * 2,
35306+		.erasesize = _256K,
35307+		.pagesize  = _4K,
35308+		.oobsize   = 256,
35309+		.badblock_pos = BBP_FIRST_PAGE,
35310+		.read      = {
35311+			&READ_STD(1, INFINITE, 24),
35312+			&READ_FAST(1, INFINITE, 100),
35313+			&READ_DUAL(1, INFINITE, 100),
35314+			&READ_DUAL_ADDR(1, INFINITE, 100),
35315+			&READ_QUAD(1, INFINITE, 100),
35316+			&READ_QUAD_ADDR(1, INFINITE, 100),
35317+			0
35318+		},
35319+		.write     = {
35320+			&WRITE_STD(0, 256, 100),
35321+			&WRITE_QUAD(0, 256, 100),
35322+			0
35323+		},
35324+		.erase     = {
35325+			&ERASE_SECTOR_256K(0, _256K, 100),
35326+			0
35327+		},
35328+		.driver    = &spi_driver_general,
35329+	},
35330+
35331+	/* Etron 1.8V EM78E044VCA-H 4Gbit */
35332+	{
35333+		.name      = "EM78E044VCA-H",
35334+		.id        = {0xD5, 0x8C},
35335+		.id_len    = 2,
35336+		.chipsize  = _512M,
35337+		.erasesize = _256K,
35338+		.pagesize  = _4K,
35339+		.oobsize   = 256,
35340+		.badblock_pos = BBP_FIRST_PAGE,
35341+		.read      = {
35342+			&READ_STD(1, INFINITE, 24),
35343+			&READ_FAST(1, INFINITE, 100),
35344+			&READ_DUAL(1, INFINITE, 100),
35345+			&READ_DUAL_ADDR(1, INFINITE, 100),
35346+			&READ_QUAD(1, INFINITE, 100),
35347+			&READ_QUAD_ADDR(1, INFINITE, 100),
35348+			0
35349+		},
35350+		.write     = {
35351+			&WRITE_STD(0, 256, 100),
35352+			&WRITE_QUAD(0, 256, 100),
35353+			0
35354+		},
35355+		.erase     = {
35356+			&ERASE_SECTOR_256K(0, _256K, 100),
35357+			0
35358+		},
35359+		.driver    = &spi_driver_general,
35360+	},
35361+
35362+	/* Etron 1.8V EM78D044VCF-H 2Gbit */
35363+	{
35364+		.name      = "EM78D044VCF-H",
35365+		.id        = {0xd5, 0x81},
35366+		.id_len    = 2,
35367+		.chipsize  = _256M,
35368+		.erasesize = _128K,
35369+		.pagesize  = _2K,
35370+		.oobsize   = 64,
35371+		.badblock_pos = BBP_FIRST_PAGE,
35372+		.read      = {
35373+			&READ_STD(1, INFINITE, 24),
35374+			&READ_FAST(1, INFINITE, 104),
35375+			&READ_DUAL(1, INFINITE, 104),
35376+			&READ_DUAL_ADDR(1, INFINITE, 104),
35377+			&READ_QUAD(1, INFINITE, 104),
35378+			&READ_QUAD_ADDR(1, INFINITE, 104),
35379+			0
35380+		},
35381+		.write     = {
35382+			&WRITE_STD(0, 256, 80),
35383+			&WRITE_QUAD(0, 256, 104),
35384+			0
35385+		},
35386+		.erase     = {
35387+			&ERASE_SECTOR_128K(0, _128K, 104),
35388+			0
35389+		},
35390+		.driver    = &spi_driver_general,
35391+	},
35392+
35393+	/* Etron 3.3V EM73C044VCC-H 1Gbit */
35394+	{
35395+		.name      = "EM73C044VCC-H",
35396+		.id        = {0xd5, 0x22},
35397+		.id_len    = 2,
35398+		.chipsize  = _128M,
35399+		.erasesize = _128K,
35400+		.pagesize  = _2K,
35401+		.oobsize   = 64,
35402+		.badblock_pos = BBP_FIRST_PAGE,
35403+		.read      = {
35404+			&READ_STD(1, INFINITE, 24),
35405+			&READ_FAST(1, INFINITE, 120),
35406+			&READ_DUAL(1, INFINITE, 120),
35407+			&READ_DUAL_ADDR(1, INFINITE, 120),
35408+			&READ_QUAD(1, INFINITE, 120),
35409+			&READ_QUAD_ADDR(1, INFINITE, 120),
35410+			0
35411+		},
35412+		.write     = {
35413+			&WRITE_STD(0, 256, 104),
35414+			&WRITE_QUAD(0, 256, 120),
35415+			0
35416+		},
35417+		.erase     = {
35418+			&ERASE_SECTOR_128K(0, _128K, 104),
35419+			0
35420+		},
35421+		.driver    = &spi_driver_general,
35422+	},
35423+
35424+	/* Micron MT29F4G01ABBFDWB 4GBit 1.8V */
35425+	{
35426+		.name      = "MT29F4G01ABBFDWB",
35427+		.id        = {0x2C, 0x35},
35428+		.id_len    = 2,
35429+		.chipsize  = _512M,
35430+		.erasesize = _256K,
35431+		.pagesize  = _4K,
35432+		.oobsize   = 256,
35433+		.badblock_pos = BBP_FIRST_PAGE,
35434+		.read      = {
35435+			&READ_STD(1, INFINITE, 24),
35436+			&READ_FAST(1, INFINITE, 80),
35437+			&READ_DUAL(1, INFINITE, 80),
35438+			&READ_QUAD(1, INFINITE, 80),
35439+			0
35440+		},
35441+		.write     = {
35442+			&WRITE_STD(0, 256, 80),
35443+			&WRITE_QUAD(0, 256, 80),
35444+			0
35445+		},
35446+		.erase     = {
35447+			&ERASE_SECTOR_256K(0, _256K, 80),
35448+			0
35449+		},
35450+		.driver    = &spi_driver_no_qe,
35451+	},
35452+
35453+	/* Dosilicon 3.3V DS35Q2GA-IB 1Gb */
35454+	{
35455+		.name      = "DS35Q2GA-IB",
35456+		.id        = {0xe5, 0x72},
35457+		.id_len    = 2,
35458+		.chipsize  = _256M,
35459+		.erasesize = _128K,
35460+		.pagesize  = _2K,
35461+		.oobsize   = 64,
35462+		.badblock_pos = BBP_FIRST_PAGE,
35463+		.read      = {
35464+			&READ_STD(1, INFINITE, 24),
35465+			&READ_FAST(1, INFINITE, 104),
35466+			&READ_DUAL(1, INFINITE, 104),
35467+			&READ_QUAD(1, INFINITE, 104),
35468+			0
35469+		},
35470+		.write     = {
35471+			&WRITE_STD(0, 256, 80),
35472+			&WRITE_QUAD(0, 256, 104),
35473+			0
35474+		},
35475+		.erase     = {
35476+			&ERASE_SECTOR_128K(0, _128K, 104),
35477+			0
35478+		},
35479+		.driver    = &spi_driver_general,
35480+	},
35481+
35482+	/* FM 3.3v FM25S01-DND-A-G  1Gbit */
35483+	{
35484+		.name      = "FM25S01-DND-A-G",
35485+		.id        = {0xa1, 0xa1},
35486+		.id_len    = 2,
35487+		.chipsize  = _128M,
35488+		.erasesize = _128K,
35489+		.pagesize  = _2K,
35490+		.oobsize   = 128,
35491+		.badblock_pos = BBP_FIRST_PAGE,
35492+		.read      = {
35493+			&READ_STD(1, INFINITE, 24), /* 24MHz */
35494+			&READ_FAST(1, INFINITE, 104), /* 104MHz */
35495+			&READ_DUAL(1, INFINITE, 104), /* 104MHz */
35496+			&READ_DUAL_ADDR(1, INFINITE, 40), /* 40MHz */
35497+			&READ_QUAD(1, INFINITE, 104), /* 104MHz */
35498+			&READ_QUAD_ADDR(2, INFINITE, 40), /* 40MHz */
35499+			0
35500+		},
35501+		.write     = {
35502+			&WRITE_STD(0, 256, 104), /* 104MHz */
35503+			&WRITE_QUAD(0, 256, 104),  /* 104MHz */
35504+			0
35505+		},
35506+		.erase     = {
35507+			&ERASE_SECTOR_128K(0, _128K, 104), /* 104MHz */
35508+			0
35509+		},
35510+		.driver    = &spi_driver_no_qe,
35511+	},
35512+
35513+	/* FM 3.3v FM25S01A 1Gbit */
35514+	{
35515+		.name      = "FM25S01A",
35516+		.id        = {0xa1, 0xe4},
35517+		.id_len    = 2,
35518+		.chipsize  = _128M,
35519+		.erasesize = _128K,
35520+		.pagesize  = _2K,
35521+		.oobsize   = 64,
35522+		.badblock_pos = BBP_FIRST_PAGE,
35523+		.read      = {
35524+			&READ_STD(1, INFINITE, 24), /* 104MHz */
35525+			&READ_FAST(1, INFINITE, 104), /* 104MHz */
35526+			&READ_DUAL(1, INFINITE, 104), /* 104MHz */
35527+			&READ_DUAL_ADDR(1, INFINITE, 40), /* 40MHz */
35528+			&READ_QUAD(1, INFINITE, 104), /* 104MHz */
35529+			&READ_QUAD_ADDR(2, INFINITE, 40), /* 40MHz */
35530+			0
35531+		},
35532+		.write     = {
35533+			&WRITE_STD(0, 256, 104), /* 104MHz */
35534+			&WRITE_QUAD(0, 256, 104),  /* 104MHz */
35535+			0
35536+		},
35537+		.erase     = {
35538+			&ERASE_SECTOR_128K(0, _128K, 104), /* 104MHz */
35539+			0
35540+		},
35541+		.driver    = &spi_driver_no_qe,
35542+	},
35543+
35544+	{   .id_len    = 0, },
35545+};
35546+
35547+
35548+static void hifmc100_spi_nand_search_rw(struct spi_nand_info *spiinfo,
35549+					struct spi_op *spiop_rw, u_int iftype, u_int max_dummy, int rw_type)
35550+{
35551+	int ix = 0;
35552+	struct spi_op **spiop, **fitspiop;
35553+
35554+	for (fitspiop = spiop = (rw_type ? spiinfo->write : spiinfo->read);
35555+			(*spiop) && ix < MAX_SPI_OP; spiop++, ix++) {
35556+		if (((*spiop)->iftype & iftype)
35557+				&& ((*spiop)->dummy <= max_dummy)
35558+				&& (*fitspiop)->iftype < (*spiop)->iftype) {
35559+			fitspiop = spiop;
35560+		}
35561+	}
35562+	memcpy(spiop_rw, (*fitspiop), sizeof(struct spi_op));
35563+}
35564+
35565+
35566+static void hifmc100_spi_nand_get_erase(const struct spi_nand_info *spiinfo,
35567+					struct spi_op *spiop_erase)
35568+{
35569+	int ix;
35570+
35571+	spiop_erase->size = 0;
35572+	for (ix = 0; ix < MAX_SPI_OP; ix++) {
35573+		if (spiinfo->erase[ix] == NULL) {
35574+			break;
35575+		}
35576+		if (spiinfo->erasesize == spiinfo->erase[ix]->size) {
35577+			memcpy(&spiop_erase[ix], spiinfo->erase[ix],
35578+			       sizeof(struct spi_op));
35579+			break;
35580+		}
35581+	}
35582+}
35583+
35584+
35585+static void hifmc100_map_spi_op(struct hifmc_spi *spi)
35586+{
35587+	unsigned char ix;
35588+	const int iftype_read[] = {
35589+		SPI_IF_READ_STD,    IF_TYPE_STD,
35590+		SPI_IF_READ_FAST,   IF_TYPE_STD,
35591+		SPI_IF_READ_DUAL,   IF_TYPE_DUAL,
35592+		SPI_IF_READ_DUAL_ADDR,  IF_TYPE_DIO,
35593+		SPI_IF_READ_QUAD,   IF_TYPE_QUAD,
35594+		SPI_IF_READ_QUAD_ADDR,  IF_TYPE_QIO,
35595+		0,          0,
35596+	};
35597+	const int iftype_write[] = {
35598+		SPI_IF_WRITE_STD,   IF_TYPE_STD,
35599+		SPI_IF_WRITE_QUAD,  IF_TYPE_QUAD,
35600+		0,          0,
35601+	};
35602+	const char *if_str[] = {"STD", "DUAL", "DIO", "QUAD", "QIO"};
35603+
35604+	FMC_PR(BT_DBG, "\t||*-Start Get SPI operation iftype\n");
35605+
35606+	for (ix = 0; iftype_write[ix]; ix += 2) {
35607+		if (spi->write->iftype == iftype_write[ix]) {
35608+			spi->write->iftype = iftype_write[ix + 1];
35609+			break;
35610+		}
35611+	}
35612+	FMC_PR(BT_DBG, "\t|||-Get best write iftype: %s \n",
35613+	       if_str[spi->write->iftype]);
35614+
35615+	for (ix = 0; iftype_read[ix]; ix += 2) {
35616+		if (spi->read->iftype == iftype_read[ix]) {
35617+			spi->read->iftype = iftype_read[ix + 1];
35618+			break;
35619+		}
35620+	}
35621+	FMC_PR(BT_DBG, "\t|||-Get best read iftype: %s \n",
35622+	       if_str[spi->read->iftype]);
35623+
35624+	spi->erase->iftype = IF_TYPE_STD;
35625+	FMC_PR(BT_DBG, "\t|||-Get best erase iftype: %s \n",
35626+	       if_str[spi->erase->iftype]);
35627+
35628+	FMC_PR(BT_DBG, "\t||*-End Get SPI operation iftype \n");
35629+}
35630+
35631+
35632+static void hifmc100_spi_ids_probe(struct mtd_info *mtd,
35633+				   struct spi_nand_info *spi_dev)
35634+{
35635+	u_char reg;
35636+	int ret;
35637+	struct nand_chip *chip = NULL;
35638+	struct hifmc_host *host = NULL;
35639+	struct hifmc_spi *spi = NULL;
35640+
35641+	if(mtd == NULL || spi_dev == NULL) {
35642+		DB_MSG("Error: mtd or spi_dev is NULL!\n");
35643+		return;
35644+	}
35645+	chip = mtd_to_nand(mtd);
35646+	if (chip == NULL || chip->priv == NULL) {
35647+		DB_MSG("Error: chip is NULL!\n");
35648+		return;
35649+	}
35650+	host = chip->priv;
35651+	if (host->spi == NULL) {
35652+		DB_MSG("Error: host->spi is NULL!\n");
35653+		return;
35654+	}
35655+	spi = host->spi;
35656+	FMC_PR(BT_DBG, "\t|*-Start match SPI operation & chip init\n");
35657+
35658+	spi->host = host;
35659+	spi->name = spi_dev->name;
35660+	spi->driver = spi_dev->driver;
35661+	if(!spi->driver) {
35662+		 DB_MSG("Error: host->driver is NULL!\n");
35663+		 return;
35664+	}
35665+
35666+	hifmc100_spi_nand_search_rw(spi_dev, spi->read,
35667+				    HIFMC_SPI_NAND_SUPPORT_READ,
35668+				    HIFMC_SPI_NAND_SUPPORT_MAX_DUMMY, RW_OP_READ);
35669+	FMC_PR(BT_DBG, "\t||-Save spi->read op cmd:%#x\n", spi->read->cmd);
35670+
35671+	hifmc100_spi_nand_search_rw(spi_dev, spi->write,
35672+				    HIFMC_SPI_NAND_SUPPORT_WRITE,
35673+				    HIFMC_SPI_NAND_SUPPORT_MAX_DUMMY, RW_OP_WRITE);
35674+	FMC_PR(BT_DBG, "\t||-Save spi->write op cmd:%#x\n", spi->write->cmd);
35675+
35676+	hifmc100_spi_nand_get_erase(spi_dev, spi->erase);
35677+	FMC_PR(BT_DBG, "\t||-Save spi->erase op cmd:%#x\n", spi->erase->cmd);
35678+
35679+	hifmc100_map_spi_op(spi);
35680+
35681+	if (spi->driver->qe_enable) {
35682+		spi->driver->qe_enable(spi);
35683+	}
35684+
35685+	/* Disable write protection */
35686+	ret = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, &reg);
35687+	if (ret)
35688+		return;
35689+	FMC_PR(BT_DBG, "\t||-Get protect status[%#x]: %#x\n", PROTECT_ADDR,
35690+	       reg);
35691+	if (ANY_BP_ENABLE(reg)) {
35692+		reg &= ~ALL_BP_MASK;
35693+		ret = spi_nand_feature_op(spi, SET_OP, PROTECT_ADDR, &reg);
35694+		if (ret)
35695+		    return;
35696+		FMC_PR(BT_DBG, "\t||-Set [%#x]FT %#x\n", PROTECT_ADDR, reg);
35697+
35698+		spi->driver->wait_ready(spi);
35699+
35700+		ret = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, &reg);
35701+		if (ret)
35702+		    return;
35703+		FMC_PR(BT_DBG, "\t||-Check BP disable result: %#x\n", reg);
35704+		if (ANY_BP_ENABLE(reg)) {
35705+			DB_MSG("Error: Write protection disable failed!\n");
35706+		}
35707+	}
35708+
35709+	/* Disable chip internal ECC */
35710+	ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, &reg);
35711+	if (ret)
35712+	    return;
35713+	FMC_PR(BT_DBG, "\t||-Get feature status[%#x]: %#x\n", FEATURE_ADDR,
35714+	       reg);
35715+	if (reg & FEATURE_ECC_ENABLE) {
35716+		reg &= ~FEATURE_ECC_ENABLE;
35717+		ret = spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, &reg);
35718+		if (ret)
35719+		    return;
35720+		FMC_PR(BT_DBG, "\t||-Set [%#x]FT: %#x\n", FEATURE_ADDR, reg);
35721+
35722+		spi->driver->wait_ready(spi);
35723+
35724+		ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, &reg);
35725+		if (ret)
35726+		    return;
35727+		FMC_PR(BT_DBG, "\t||-Check internal ECC disable result: %#x\n",
35728+		       reg);
35729+		if (reg & FEATURE_ECC_ENABLE) {
35730+			DB_MSG("Error: Chip internal ECC disable failed!\n");
35731+		}
35732+	}
35733+
35734+	hifmc_cs_user[host->cmd_op.cs]++;
35735+
35736+	FMC_PR(BT_DBG, "\t|*-End match SPI operation & chip init\n");
35737+}
35738+
35739+static struct nand_flash_dev spi_nand_dev;
35740+
35741+static struct nand_flash_dev *spi_nand_get_flash_info(struct mtd_info *mtd,
35742+		unsigned char *id)
35743+{
35744+	unsigned char ix;
35745+	int len = 0;
35746+	char buffer[100];
35747+	struct nand_chip *chip = mtd_to_nand(mtd);
35748+	struct hifmc_host *host = chip->priv;
35749+	struct spi_nand_info *spi_dev = hifmc_spi_nand_flash_table;
35750+	struct nand_flash_dev *type = &spi_nand_dev;
35751+
35752+	FMC_PR(BT_DBG, "\t*-Start find SPI Nand flash\n");
35753+
35754+	len = sprintf(buffer, "SPI Nand(cs %d) ID: %#x %#x",
35755+		      host->cmd_op.cs, id[0], id[1]);
35756+
35757+	for (; spi_dev->id_len; spi_dev++) {
35758+		if (!access_ok(VERIFY_READ, id, spi_dev->id_len)) {
35759+			DB_MSG("err:spi_nand_get_flash_info access_ok fail\n");
35760+			return NULL;
35761+		}
35762+		if (memcmp(id, spi_dev->id, spi_dev->id_len)) {
35763+			continue;
35764+		}
35765+
35766+		for (ix = 2; ix < spi_dev->id_len; ix++) {
35767+			if((spi_dev->id_len <= MAX_SPI_NAND_ID_LEN)) {
35768+				len += sprintf(buffer + len, " %#x", id[ix]);
35769+			}
35770+		}
35771+		pr_info("%s\n", buffer);
35772+
35773+		FMC_PR(BT_DBG, "\t||-CS(%d) found SPI Nand: %s\n",
35774+		       host->cmd_op.cs, spi_dev->name);
35775+
35776+		type->name = spi_dev->name;
35777+		memcpy(type->id, spi_dev->id, spi_dev->id_len);
35778+		type->pagesize = spi_dev->pagesize;
35779+		type->chipsize = (unsigned int)(spi_dev->chipsize >> 20);
35780+		type->erasesize = spi_dev->erasesize;
35781+		type->id_len = spi_dev->id_len;
35782+		type->oobsize = spi_dev->oobsize;
35783+		FMC_PR(BT_DBG, "\t|-Save struct nand_flash_dev info\n");
35784+
35785+		mtd->oobsize = spi_dev->oobsize;
35786+		mtd->erasesize = spi_dev->erasesize;
35787+		mtd->writesize = spi_dev->pagesize;
35788+		chip->chipsize = spi_dev->chipsize;
35789+
35790+		hifmc100_spi_ids_probe(mtd, spi_dev);
35791+
35792+		FMC_PR(BT_DBG, "\t*-Found SPI nand: %s\n", spi_dev->name);
35793+
35794+		return type;
35795+	}
35796+
35797+	FMC_PR(BT_DBG, "\t*-Not found SPI nand flash, %s\n", buffer);
35798+
35799+	return NULL;
35800+}
35801+
35802+
35803+void hifmc_spi_nand_ids_register(void)
35804+{
35805+	pr_info("SPI Nand ID Table Version %s\n", SPI_NAND_ID_TAB_VER);
35806+	get_spi_nand_flash_type_hook = spi_nand_get_flash_info;
35807+}
35808+
35809+#ifdef CONFIG_PM
35810+
35811+void hifmc100_spi_nand_config(struct hifmc_host *host)
35812+{
35813+	u_char reg;
35814+	int ret;
35815+	struct hifmc_spi *spi = NULL;
35816+	static const char *str[] = {"STD", "DUAL", "DIO", "QUAD", "QIO"};
35817+
35818+	if((host == NULL) || (host->spi == NULL)) {
35819+		DB_MSG("Error: host or host->spi is NULL!\n");
35820+		return;
35821+	}
35822+	spi = host->spi;
35823+	/* judge whether support QUAD read/write or not, set it if yes */
35824+	FMC_PR(PM_DBG, "\t|-SPI read iftype: %s write iftype: %s\n",
35825+	       str[spi->read->iftype], str[spi->write->iftype]);
35826+
35827+	if (spi->driver->qe_enable) {
35828+		spi->driver->qe_enable(spi);
35829+	}
35830+
35831+	/* Disable write protection */
35832+	ret = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, &reg);
35833+	if (ret)
35834+	    return;
35835+	FMC_PR(PM_DBG, "\t|-Get protect status[%#x]: %#x\n", PROTECT_ADDR,
35836+	       reg);
35837+	if (ANY_BP_ENABLE(reg)) {
35838+		reg &= ~ALL_BP_MASK;
35839+		ret = spi_nand_feature_op(spi, SET_OP, PROTECT_ADDR, &reg);
35840+		if (ret)
35841+		    return;
35842+		FMC_PR(PM_DBG, "\t|-Set [%#x]FT %#x\n", PROTECT_ADDR, reg);
35843+
35844+		spi->driver->wait_ready(spi);
35845+
35846+		ret = spi_nand_feature_op(spi, GET_OP, PROTECT_ADDR, &reg);
35847+		if (ret)
35848+		    return;
35849+		FMC_PR(PM_DBG, "\t|-Check BP disable result: %#x\n", reg);
35850+		if (ANY_BP_ENABLE(reg)) {
35851+			DB_MSG("Error: Write protection disable failed!\n");
35852+		}
35853+	}
35854+
35855+	/* Disable chip internal ECC */
35856+	ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, &reg);
35857+	if (ret)
35858+	    return;
35859+	FMC_PR(PM_DBG, "\t|-Get feature status[%#x]: %#x\n", FEATURE_ADDR,
35860+	       reg);
35861+	if (reg & FEATURE_ECC_ENABLE) {
35862+		reg &= ~FEATURE_ECC_ENABLE;
35863+		ret = spi_nand_feature_op(spi, SET_OP, FEATURE_ADDR, &reg);
35864+		if (ret)
35865+		    return;
35866+		FMC_PR(PM_DBG, "\t|-Set [%#x]FT: %#x\n", FEATURE_ADDR, reg);
35867+
35868+		spi->driver->wait_ready(spi);
35869+
35870+		ret = spi_nand_feature_op(spi, GET_OP, FEATURE_ADDR, &reg);
35871+		if (ret)
35872+		    return;
35873+		FMC_PR(PM_DBG, "\t|-Check internal ECC disable result: %#x\n",
35874+		       reg);
35875+		if (reg & FEATURE_ECC_ENABLE) {
35876+			DB_MSG("Error: Chip internal ECC disable failed!\n");
35877+		}
35878+	}
35879+}
35880+
35881+#endif /* CONFIG_PM */
35882diff --git a/drivers/mtd/nand/hifmc100_nand/Kconfig b/drivers/mtd/nand/hifmc100_nand/Kconfig
35883new file mode 100644
35884index 000000000..188c9a77a
35885--- /dev/null
35886+++ b/drivers/mtd/nand/hifmc100_nand/Kconfig
35887@@ -0,0 +1,50 @@
35888+#
35889+# drivers/mtd/nand/hifmc100_nand/Kconfig
35890+# add by hisilicon 2017.10.26
35891+#
35892+
35893+menuconfig MTD_NAND_HIFMC100
35894+	bool "Hisilicon Flash Memory Controller v100 Nand devices support"
35895+	depends on MFD_HISI_FMC && !MTD_SPI_NAND_HISI_BVT
35896+	select MISC_FILESYSTEMS
35897+	select MTD_BLOCK
35898+	select YAFFS_FS
35899+	select YAFFS_YAFFS2
35900+	help
35901+	  Hisilicon Flash Memory Controller version 100 is called hifmc100 for
35902+	  short. The controller support DMA transfers while reading or writing
35903+	  the Nand flash.
35904+
35905+if MTD_NAND_HIFMC100
35906+
35907+config HIFMC100_NAND_EDO_MODE
35908+	bool "the Extended Data Out(EDO) mode"
35909+	help
35910+	  In Extended data out (EDO), a new data cycle is started while the data
35911+	  output of the previous cycle is still active. This process of cycle
35912+	  overlapping, called pipelining, increases processing speed by about
35913+	  10 nanoseconds per cycle,increasing computer performance by about 5
35914+	  percent compared to performance using FMP.
35915+
35916+config RW_H_WIDTH
35917+	int "the width of Read/Write HIGH Hold Time (0 to 15)"
35918+	range 0 15
35919+	default 10 if (ARCH_HI3559AV100 || ARCH_HI3569V100)
35920+	help
35921+	  the Read/Write HIGH Hold Time of nand flash
35922+
35923+config R_L_WIDTH
35924+	int "the Read pulse width (0 to 15)"
35925+	range 0 15
35926+	default 10 if (ARCH_HI3559AV100 || ARCH_HI3569V100)
35927+	help
35928+	  the Read/Write LOW Hold Time of nand flash
35929+
35930+config W_L_WIDTH
35931+	int "the Write pulse width (0 to 15)"
35932+	range 0 15
35933+	default 10 if (ARCH_HI3559AV100 || ARCH_HI3569V100)
35934+	help
35935+	  the Read/Write LOW Hold Time of nand flash
35936+
35937+endif # End of MTD_NAND_HIFMC100
35938diff --git a/drivers/mtd/nand/hifmc100_nand/Makefile b/drivers/mtd/nand/hifmc100_nand/Makefile
35939new file mode 100644
35940index 000000000..623363cfc
35941--- /dev/null
35942+++ b/drivers/mtd/nand/hifmc100_nand/Makefile
35943@@ -0,0 +1,26 @@
35944+#
35945+# The Flash Memory Controller v100 Device Driver for hisilicon
35946+#
35947+# Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
35948+#
35949+# This program is free software; you can redistribute  it and/or modify it
35950+# under  the terms of  the GNU General  Public License as published by the
35951+# Free Software Foundation;  either version 2 of the  License, or (at your
35952+# option) any later version.
35953+#
35954+# This program is distributed in the hope that it will be useful,
35955+# but WITHOUT ANY WARRANTY; without even the implied warranty of
35956+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35957+# GNU General Public License for more details.
35958+#
35959+# You should have received a copy of the GNU General Public License
35960+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
35961+#
35962+#
35963+
35964+#
35965+# drivers/mtd/nand/hifmc100_nand/Makefile
35966+#
35967+
35968+obj-y	+= hifmc_nand_spl_ids.o
35969+obj-y	+= hifmc100_nand.o hifmc100_nand_os.o
35970diff --git a/drivers/mtd/nand/hifmc100_nand/hifmc100_nand.c b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand.c
35971new file mode 100644
35972index 000000000..5c08d4beb
35973--- /dev/null
35974+++ b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand.c
35975@@ -0,0 +1,1170 @@
35976+/*
35977+ * The Flash Memory Controller v100 Device Driver for hisilicon
35978+ *
35979+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
35980+ *
35981+ * This program is free software; you can redistribute  it and/or modify it
35982+ * under  the terms of  the GNU General  Public License as published by the
35983+ * Free Software Foundation;  either version 2 of the  License, or (at your
35984+ * option) any later version.
35985+ *
35986+ * This program is distributed in the hope that it will be useful,
35987+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
35988+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
35989+ * GNU General Public License for more details.
35990+ *
35991+ * You should have received a copy of the GNU General Public License
35992+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
35993+ *
35994+ */
35995+
35996+#include <linux/io.h>
35997+#include <linux/compiler.h>
35998+#include <linux/delay.h>
35999+#include <linux/printk.h>
36000+#include <linux/clk.h>
36001+#include <linux/mfd/hisi_fmc.h>
36002+
36003+#include "../raw/hinfc_gen.h"
36004+#include "hifmc100_nand_os.h"
36005+#include "hifmc100_nand.h"
36006+
36007+#include <mach/platform.h>
36008+
36009+static void hifmc100_dma_transfer(struct hifmc_host *host, unsigned int todev)
36010+{
36011+	unsigned int reg = (unsigned int)host->dma_buffer;
36012+	char *op = todev ? "write" : "read";
36013+
36014+	FMC_PR(DMA_DB, "\t\t *-Start %s page dma transfer\n", op);
36015+
36016+	hifmc_writel(host, FMC_DMA_SADDR_D0, reg);
36017+	FMC_PR(DMA_DB, "\t\t |-Set ADDR0[%#x]%#x\n", FMC_DMA_SADDR_D0, reg);
36018+
36019+#ifdef CONFIG_64BIT
36020+	reg = (unsigned int)((host->dma_buffer & FMC_DMA_SADDRH_MASK) >> 32);
36021+	hifmc_writel(host, FMC_DMA_SADDRH_D0, reg);
36022+	FMC_PR(DMA_DB, "\t\t |-Set ADDRH0[%#x]%#x\n", FMC_DMA_SADDRH_D0, reg);
36023+#endif
36024+
36025+	reg += FMC_DMA_ADDR_OFFSET;
36026+	hifmc_writel(host, FMC_DMA_SADDR_D1, reg);
36027+	FMC_PR(DMA_DB, "\t\t |-Set ADDR1[%#x]%#x\n", FMC_DMA_SADDR_D1, reg);
36028+
36029+	reg += FMC_DMA_ADDR_OFFSET;
36030+	hifmc_writel(host, FMC_DMA_SADDR_D2, reg);
36031+	FMC_PR(DMA_DB, "\t\t |-Set ADDR2[%#x]%#x\n", FMC_DMA_SADDR_D2, reg);
36032+
36033+	reg += FMC_DMA_ADDR_OFFSET;
36034+	hifmc_writel(host, FMC_DMA_SADDR_D3, reg);
36035+	FMC_PR(DMA_DB, "\t\t |-Set ADDR3[%#x]%#x\n", FMC_DMA_SADDR_D3, reg);
36036+
36037+	reg = host->dma_oob;
36038+	hifmc_writel(host, FMC_DMA_SADDR_OOB, reg);
36039+	FMC_PR(DMA_DB, "\t\t |-Set OOB[%#x]%#x\n", FMC_DMA_SADDR_OOB, reg);
36040+
36041+#ifdef CONFIG_64BIT
36042+	reg = (unsigned int)((host->dma_oob & FMC_DMA_SADDRH_MASK) >> 32);
36043+	hifmc_writel(host, FMC_DMA_SADDRH_OOB, reg);
36044+	FMC_PR(DMA_DB, "\t\t |-Set ADDRH0[%#x]%#x\n", FMC_DMA_SADDRH_OOB, reg);
36045+#endif
36046+
36047+	if (host->ecctype == NAND_ECC_0BIT) {
36048+		hifmc_writel(host, FMC_DMA_LEN, FMC_DMA_LEN_SET(host->oobsize));
36049+		FMC_PR(DMA_DB, "\t\t |-Set LEN[%#x]%#x\n", FMC_DMA_LEN, reg);
36050+	}
36051+	reg = FMC_OP_READ_DATA_EN | FMC_OP_WRITE_DATA_EN;
36052+	hifmc_writel(host, FMC_OP, reg);
36053+	FMC_PR(DMA_DB, "\t\t |-Set OP[%#x]%#x\n", FMC_OP, reg);
36054+
36055+	reg = FMC_DMA_AHB_CTRL_DMA_PP_EN |
36056+	      FMC_DMA_AHB_CTRL_BURST16_EN |
36057+	      FMC_DMA_AHB_CTRL_BURST8_EN |
36058+	      FMC_DMA_AHB_CTRL_BURST4_EN;
36059+	hifmc_writel(host, FMC_DMA_AHB_CTRL, reg);
36060+	FMC_PR(DMA_DB, "\t\t |-Set AHBCTRL[%#x]%#x\n", FMC_DMA_AHB_CTRL, reg);
36061+
36062+	reg = OP_CFG_FM_CS(host->cmd_op.cs) |
36063+	      OP_CFG_ADDR_NUM(host->addr_cycle);
36064+	hifmc_writel(host, FMC_OP_CFG, reg);
36065+	FMC_PR(DMA_DB, "\t\t |-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg);
36066+
36067+	reg = OP_CTRL_DMA_OP_READY;
36068+	if (todev) {
36069+		reg |= OP_CTRL_RW_OP(todev);
36070+	}
36071+	hifmc_writel(host, FMC_OP_CTRL, reg);
36072+	FMC_PR(DMA_DB, "\t\t |-Set OP_CTRL[%#x]%#x\n", FMC_OP_CTRL, reg);
36073+
36074+	FMC_DMA_WAIT_CPU_FINISH(host);
36075+
36076+	FMC_PR(DMA_DB, "\t\t *-End %s page dma transfer\n", op);
36077+
36078+	return;
36079+}
36080+
36081+
36082+static void hifmc100_send_cmd_write(struct hifmc_host *host)
36083+{
36084+	unsigned int reg;
36085+
36086+	FMC_PR(WR_DBG, "\t|*-Start send page programme cmd\n");
36087+
36088+	if (*host->bbm != 0xFF && *host->bbm != 0x00) {
36089+		pr_info("WARNING: attempt to write an invalid bbm. " \
36090+			"page: 0x%08x, mark: 0x%02x,\n",
36091+			GET_PAGE_INDEX(host), *host->bbm);
36092+	}
36093+
36094+	host->enable_ecc_randomizer(host, ENABLE, ENABLE);
36095+
36096+	reg = host->addr_value[1];
36097+	hifmc_writel(host, FMC_ADDRH, reg);
36098+	FMC_PR(WR_DBG, "\t||-Set ADDRH[%#x]%#x\n", FMC_ADDRH, reg);
36099+
36100+	reg = host->addr_value[0] & 0xffff0000;
36101+	hifmc_writel(host, FMC_ADDRL, reg);
36102+	FMC_PR(WR_DBG, "\t||-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg);
36103+
36104+	reg = FMC_CMD_CMD2(NAND_CMD_PAGEPROG) | FMC_CMD_CMD1(NAND_CMD_SEQIN);
36105+	hifmc_writel(host, FMC_CMD, reg);
36106+	FMC_PR(WR_DBG, "\t||-Set CMD[%#x]%#x\n", FMC_CMD, reg);
36107+
36108+	*host->epm = 0x0000;
36109+
36110+	hifmc100_dma_transfer(host, RW_OP_WRITE);
36111+
36112+	FMC_PR(WR_DBG, "\t|*-End send page read cmd\n");
36113+}
36114+
36115+
36116+static void hifmc100_send_cmd_read(struct hifmc_host *host)
36117+{
36118+	unsigned int reg;
36119+
36120+	FMC_PR(RD_DBG, "\t*-Start send page read cmd\n");
36121+
36122+	if ((host->addr_value[0] == host->cache_addr_value[0]) &&
36123+			(host->addr_value[1] == host->cache_addr_value[1])) {
36124+		FMC_PR(RD_DBG, "\t*-Cache hit! addr1[%#x], addr0[%#x]\n",
36125+		       host->addr_value[1], host->addr_value[0]);
36126+		return;
36127+	}
36128+
36129+	host->page_status = 0;
36130+
36131+	host->enable_ecc_randomizer(host, ENABLE, ENABLE);
36132+
36133+	reg = FMC_INT_CLR_ALL;
36134+	hifmc_writel(host, FMC_INT_CLR, reg);
36135+	FMC_PR(RD_DBG, "\t|-Set INT_CLR[%#x]%#x\n", FMC_INT_CLR, reg);
36136+
36137+	reg = host->nand_cfg;
36138+	hifmc_writel(host, FMC_CFG, reg);
36139+	FMC_PR(RD_DBG, "\t|-Set CFG[%#x]%#x\n", FMC_CFG, reg);
36140+
36141+	reg = host->addr_value[1];
36142+	hifmc_writel(host, FMC_ADDRH, reg);
36143+	FMC_PR(RD_DBG, "\t|-Set ADDRH[%#x]%#x\n", FMC_ADDRH, reg);
36144+
36145+	reg = host->addr_value[0] & 0xffff0000;
36146+	hifmc_writel(host, FMC_ADDRL, reg);
36147+	FMC_PR(RD_DBG, "\t|-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg);
36148+
36149+	reg = FMC_CMD_CMD2(NAND_CMD_READSTART) | FMC_CMD_CMD1(NAND_CMD_READ0);
36150+	hifmc_writel(host, FMC_CMD, reg);
36151+	FMC_PR(RD_DBG, "\t|-Set CMD[%#x]%#x\n", FMC_CMD, reg);
36152+
36153+	hifmc100_dma_transfer(host, RW_OP_READ);
36154+
36155+	if (hifmc_readl(host, FMC_INT) & FMC_INT_ERR_INVALID) {
36156+		host->page_status |= HIFMC100_PS_UC_ECC;
36157+	}
36158+
36159+	host->cache_addr_value[0] = host->addr_value[0];
36160+	host->cache_addr_value[1] = host->addr_value[1];
36161+
36162+	FMC_PR(RD_DBG, "\t*-End send page read cmd\n");
36163+}
36164+
36165+
36166+static void hifmc100_send_cmd_erase(struct hifmc_host *host)
36167+{
36168+	unsigned int reg;
36169+
36170+	FMC_PR(ER_DBG, "\t *-Start send cmd erase\n");
36171+
36172+	/* Don't case the read retry config */
36173+	host->enable_ecc_randomizer(host, DISABLE, DISABLE);
36174+
36175+	reg = host->addr_value[0];
36176+	hifmc_writel(host, FMC_ADDRL, reg);
36177+	FMC_PR(ER_DBG, "\t |-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg);
36178+
36179+	reg = FMC_CMD_CMD2(NAND_CMD_ERASE2) | FMC_CMD_CMD1(NAND_CMD_ERASE1);
36180+	hifmc_writel(host, FMC_CMD, reg);
36181+	FMC_PR(ER_DBG, "\t |-Set CMD[%#x]%#x\n", FMC_CMD, reg);
36182+
36183+	reg = OP_CFG_FM_CS(host->cmd_op.cs) |
36184+	      OP_CFG_ADDR_NUM(host->addr_cycle);
36185+	hifmc_writel(host, FMC_OP_CFG, reg);
36186+	FMC_PR(ER_DBG, "\t |-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg);
36187+
36188+	/* need to config WAIT_READY_EN */
36189+	reg = FMC_OP_WAIT_READY_EN |
36190+	      FMC_OP_CMD1_EN |
36191+	      FMC_OP_CMD2_EN |
36192+	      FMC_OP_ADDR_EN |
36193+	      FMC_OP_REG_OP_START;
36194+	hifmc_writel(host, FMC_OP, reg);
36195+	FMC_PR(ER_DBG, "\t |-Set OP[%#x]%#x\n", FMC_OP, reg);
36196+
36197+	FMC_CMD_WAIT_CPU_FINISH(host);
36198+
36199+	FMC_PR(ER_DBG, "\t |*-End send cmd erase\n");
36200+}
36201+
36202+
36203+static void hifmc100_ecc_randomizer(struct hifmc_host *host, int ecc_en,
36204+				    int randomizer_en)
36205+{
36206+	unsigned int old_reg, reg;
36207+	unsigned int  change = 0;
36208+	char *ecc_op = ecc_en ? "Quit" : "Enter";
36209+	char *rand_op = randomizer_en ? "Enable" : "Disable";
36210+
36211+	if (IS_NAND_RANDOM(host)) {
36212+		reg = old_reg = hifmc_readl(host, FMC_GLOBAL_CFG);
36213+		if (randomizer_en) {
36214+			reg |= FMC_GLOBAL_CFG_RANDOMIZER_EN;
36215+		} else {
36216+			reg &= ~FMC_GLOBAL_CFG_RANDOMIZER_EN;
36217+		}
36218+
36219+		if (old_reg != reg) {
36220+			FMC_PR(EC_DBG, "\t |*-Start %s randomizer\n", rand_op);
36221+			FMC_PR(EC_DBG, "\t ||-Get global CFG[%#x]%#x\n",
36222+			       FMC_GLOBAL_CFG, old_reg);
36223+			hifmc_writel(host, FMC_GLOBAL_CFG, reg);
36224+			FMC_PR(EC_DBG, "\t ||-Set global CFG[%#x]%#x\n",
36225+			       FMC_GLOBAL_CFG, reg);
36226+			change++;
36227+		}
36228+	}
36229+
36230+	old_reg = hifmc_readl(host, FMC_CFG);
36231+	reg = (ecc_en ? host->nand_cfg : host->nand_cfg_ecc0);
36232+
36233+	if (old_reg != reg) {
36234+		FMC_PR(EC_DBG, "\t |%s-Start %s ECC0 mode\n", change ? "|" : "*",
36235+		       ecc_op);
36236+		FMC_PR(EC_DBG, "\t ||-Get CFG[%#x]%#x\n", FMC_CFG, old_reg);
36237+		hifmc_writel(host, FMC_CFG, reg);
36238+		FMC_PR(EC_DBG, "\t ||-Set CFG[%#x]%#x\n", FMC_CFG, reg);
36239+		change++;
36240+	}
36241+
36242+	if (EC_DBG && change) {
36243+		FMC_PR(EC_DBG, "\t |*-End randomizer and ECC0 mode config\n");
36244+	}
36245+}
36246+
36247+
36248+static void hifmc100_send_cmd_status(struct hifmc_host *host)
36249+{
36250+	unsigned int regval;
36251+
36252+	host->enable_ecc_randomizer(host, DISABLE, DISABLE);
36253+
36254+	regval = OP_CFG_FM_CS(host->cmd_op.cs);
36255+	hifmc_writel(host, FMC_OP_CFG, regval);
36256+
36257+	regval = FMC_OP_READ_STATUS_EN | FMC_OP_REG_OP_START;
36258+	hifmc_writel(host, FMC_OP, regval);
36259+
36260+	FMC_CMD_WAIT_CPU_FINISH(host);
36261+}
36262+
36263+
36264+static void hifmc100_send_cmd_readid(struct hifmc_host *host)
36265+{
36266+	unsigned int reg;
36267+
36268+	FMC_PR(BT_DBG, "\t *-Start read nand flash ID\n");
36269+
36270+	host->enable_ecc_randomizer(host, DISABLE, DISABLE);
36271+
36272+	reg = FMC_DATA_NUM_CNT(host->cmd_op.data_no);
36273+	hifmc_writel(host, FMC_DATA_NUM, reg);
36274+	FMC_PR(BT_DBG, "\t |-Set DATA_NUM[%#x]%#x\n", FMC_DATA_NUM, reg);
36275+
36276+	reg = FMC_CMD_CMD1(NAND_CMD_READID);
36277+	hifmc_writel(host, FMC_CMD, reg);
36278+	FMC_PR(BT_DBG, "\t |-Set CMD[%#x]%#x\n", FMC_CMD, reg);
36279+
36280+	reg = 0;
36281+	hifmc_writel(host, FMC_ADDRL, reg);
36282+	FMC_PR(BT_DBG, "\t |-Set ADDRL[%#x]%#x\n", FMC_ADDRL, reg);
36283+
36284+	reg = OP_CFG_FM_CS(host->cmd_op.cs) |
36285+	      OP_CFG_ADDR_NUM(READ_ID_ADDR_NUM);
36286+	hifmc_writel(host, FMC_OP_CFG, reg);
36287+	FMC_PR(BT_DBG, "\t |-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg);
36288+
36289+	reg = FMC_OP_CMD1_EN |
36290+	      FMC_OP_ADDR_EN |
36291+	      FMC_OP_READ_DATA_EN |
36292+	      FMC_OP_REG_OP_START;
36293+	hifmc_writel(host, FMC_OP, reg);
36294+	FMC_PR(BT_DBG, "\t |-Set OP[%#x]%#x\n", FMC_OP, reg);
36295+
36296+	host->addr_cycle = 0x0;
36297+
36298+	FMC_CMD_WAIT_CPU_FINISH(host);
36299+
36300+	FMC_PR(BT_DBG, "\t *-End read nand flash ID\n");
36301+}
36302+
36303+
36304+static void hifmc100_send_cmd_reset(struct hifmc_host *host)
36305+{
36306+	unsigned int reg;
36307+
36308+	FMC_PR(BT_DBG, "\t *-Start reset nand flash\n");
36309+
36310+	reg = FMC_CMD_CMD1(NAND_CMD_RESET);
36311+	hifmc_writel(host, FMC_CMD, reg);
36312+	FMC_PR(BT_DBG, "\t |-Set CMD[%#x]%#x\n", FMC_CMD, reg);
36313+
36314+	reg = OP_CFG_FM_CS(host->cmd_op.cs);
36315+	hifmc_writel(host, FMC_OP_CFG, reg);
36316+	FMC_PR(BT_DBG, "\t |-Set OP_CFG[%#x]%#x\n", FMC_OP_CFG, reg);
36317+
36318+	reg = FMC_OP_CMD1_EN |
36319+	      FMC_OP_WAIT_READY_EN |
36320+	      FMC_OP_REG_OP_START;
36321+	hifmc_writel(host, FMC_OP, reg);
36322+	FMC_PR(BT_DBG, "\t |-Set OP[%#x]%#x\n", FMC_OP, reg);
36323+
36324+	FMC_CMD_WAIT_CPU_FINISH(host);
36325+
36326+	FMC_PR(BT_DBG, "\t *-End reset nand flash\n");
36327+}
36328+
36329+
36330+static unsigned char hifmc100_read_byte(struct mtd_info *mtd)
36331+{
36332+	unsigned char value = 0;
36333+	struct nand_chip *chip = mtd_to_nand(mtd);
36334+	struct hifmc_host *host = chip->priv;
36335+
36336+	if (host->cmd_op.l_cmd == NAND_CMD_READID) {
36337+		value = hifmc_readb((void __iomem *)(chip->IO_ADDR_R + host->offset));
36338+		host->offset++;
36339+		if (host->cmd_op.data_no == host->offset) {
36340+			host->cmd_op.l_cmd = 0;
36341+		}
36342+		return value;
36343+	}
36344+
36345+	if (host->cmd_op.cmd == NAND_CMD_STATUS) {
36346+		value = hifmc_readl(host, FMC_STATUS);
36347+		if (host->cmd_op.l_cmd == NAND_CMD_ERASE1) {
36348+			FMC_PR(ER_DBG, "\t*-Erase WP status: %#x\n", value);
36349+		}
36350+		if (host->cmd_op.l_cmd == NAND_CMD_PAGEPROG) {
36351+			FMC_PR(WR_DBG, "\t*-Write WP status: %#x\n", value);
36352+		}
36353+		return value;
36354+	}
36355+
36356+	if (host->cmd_op.l_cmd == NAND_CMD_READOOB) {
36357+		value = hifmc_readb((void __iomem *)(host->buffer +
36358+					host->pagesize + host->offset));
36359+		host->offset++;
36360+		return value;
36361+	}
36362+
36363+	host->offset++;
36364+
36365+	return hifmc_readb((void __iomem *)(host->buffer + host->column +
36366+				host->offset - 1));
36367+}
36368+
36369+
36370+static unsigned short hifmc100_read_word(struct mtd_info *mtd)
36371+{
36372+	struct nand_chip *chip = mtd_to_nand(mtd);
36373+	struct hifmc_host *host = chip->priv;
36374+
36375+	host->offset += 2;
36376+	return hifmc_readw(host->buffer + host->column + host->offset - 2);
36377+}
36378+
36379+
36380+static void hifmc100_write_buf(struct mtd_info *mtd,
36381+			       const u_char *buf, int len)
36382+{
36383+	struct nand_chip *chip = mtd_to_nand(mtd);
36384+	struct hifmc_host *host = chip->priv;
36385+
36386+#ifdef HIFMC100_NAND_SUPPORT_REG_WRITE
36387+	if (buf == chip->oob_poi) {
36388+		memcpy((char *)host->iobase + host->pagesize, buf, len);
36389+	} else {
36390+		memcpy((char *)host->iobase, buf, len);
36391+	}
36392+#else
36393+	if (buf == chip->oob_poi) {
36394+		memcpy((char *)host->buffer + host->pagesize, buf, len);
36395+	} else {
36396+		memcpy((char *)host->buffer, buf, len);
36397+	}
36398+#endif
36399+	return;
36400+}
36401+
36402+#ifdef CONFIG_HISI_NAND_ECC_STATUS_REPORT
36403+
36404+static void hifmc100_ecc_err_num_count(struct mtd_info *mtd,
36405+				       u_int ecc_st, u_int reg)
36406+{
36407+	u_char err_num;
36408+
36409+	if (ecc_st > 4) {
36410+		ecc_st = 4;
36411+	}
36412+
36413+	while (ecc_st) {
36414+		err_num = GET_ECC_ERR_NUM(--ecc_st, reg);
36415+		if (err_num == 0xff) {
36416+			mtd->ecc_stats.failed++;
36417+		} else {
36418+			mtd->ecc_stats.corrected += err_num;
36419+		}
36420+	}
36421+}
36422+#endif
36423+
36424+
36425+static void hifmc100_read_buf(struct mtd_info *mtd, u_char *buf, int len)
36426+{
36427+	struct nand_chip *chip = mtd_to_nand(mtd);
36428+	struct hifmc_host *host = chip->priv;
36429+
36430+#ifdef HIFMC100_NAND_SUPPORT_REG_READ
36431+	if (buf == chip->oob_poi) {
36432+		memcpy(buf, (char *)host->iobase + host->pagesize, len);
36433+	} else {
36434+		memcpy(buf, (char *)host->iobase, len);
36435+	}
36436+#else
36437+	if (buf == chip->oob_poi) {
36438+		memcpy(buf, (char *)host->buffer + host->pagesize, len);
36439+	} else {
36440+		memcpy(buf, (char *)host->buffer, len);
36441+	}
36442+#endif
36443+
36444+#ifdef CONFIG_HISI_NAND_ECC_STATUS_REPORT
36445+	if (buf != chip->oob_poi) {
36446+		u_int reg;
36447+		u_int ecc_step = host->pagesize >> 10;
36448+
36449+		/* 2K or 4K or 8K(1) or 16K(1-1) pagesize */
36450+		reg = hifmc_readl(host, HIFMC100_ECC_ERR_NUM0_BUF0);
36451+		hifmc100_ecc_err_num_count(mtd, ecc_step, reg);
36452+
36453+		if (ecc_step > 4) {
36454+			/* 8K(2) or 16K(1-2) pagesize */
36455+			reg = hifmc_readl(host, HIFMC100_ECC_ERR_NUM1_BUF0);
36456+			hifmc100_ecc_err_num_count(mtd, ecc_step, reg);
36457+			if (ecc_step > 8) {
36458+				/* 16K(2-1) pagesize */
36459+				reg = hifmc_readl(host,
36460+						  HIFMC100_ECC_ERR_NUM0_BUF1);
36461+				hifmc100_ecc_err_num_count(mtd, ecc_step, reg);
36462+				/* 16K(2-2) pagesize */
36463+				reg = hifmc_readl(host,
36464+						  HIFMC100_ECC_ERR_NUM1_BUF1);
36465+				hifmc100_ecc_err_num_count(mtd, ecc_step, reg);
36466+			}
36467+		}
36468+	}
36469+#endif
36470+
36471+	return;
36472+}
36473+
36474+
36475+static void hifmc100_select_chip(struct mtd_info *mtd, int chipselect)
36476+{
36477+	struct nand_chip *chip = mtd_to_nand(mtd);
36478+	struct hifmc_host *host = chip->priv;
36479+
36480+	if (chipselect < 0) {
36481+		mutex_unlock(&fmc_switch_mutex);
36482+		return;
36483+	}
36484+
36485+	mutex_lock(&fmc_switch_mutex);
36486+
36487+	if (chipselect > CONFIG_HIFMC100_MAX_NAND_CHIP) {
36488+		DB_BUG("Error: Invalid chip select: %d\n", chipselect);
36489+	}
36490+
36491+	host->cmd_op.cs = chipselect;
36492+	if (host->mtd != mtd) {
36493+		host->mtd = mtd;
36494+	}
36495+
36496+	switch (chip->state) {
36497+	case FL_ERASING:
36498+		host->cmd_op.l_cmd = NAND_CMD_ERASE1;
36499+		if (ER_DBG) {
36500+			pr_info("\n");
36501+		}
36502+		FMC_PR(ER_DBG, "\t*-Erase chip: %d\n", chipselect);
36503+		break;
36504+	case FL_WRITING:
36505+		host->cmd_op.l_cmd = NAND_CMD_PAGEPROG;
36506+		if (WR_DBG) {
36507+			pr_info("\n");
36508+		}
36509+		FMC_PR(WR_DBG, "\t*-Write chip: %d\n", chipselect);
36510+		break;
36511+	case FL_READING:
36512+		host->cmd_op.l_cmd = NAND_CMD_READ0;
36513+		if (RD_DBG) {
36514+			pr_info("\n");
36515+		}
36516+		FMC_PR(RD_DBG, "\t*-Read chip: %d\n", chipselect);
36517+		break;
36518+	default:
36519+		break;
36520+	}
36521+}
36522+
36523+
36524+static void hifmc100_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned ctrl)
36525+{
36526+	unsigned char cmd;
36527+	int is_cache_invalid = 1;
36528+	struct nand_chip *chip = mtd_to_nand(mtd);
36529+	struct hifmc_host *host = chip->priv;
36530+
36531+	if (ctrl & NAND_ALE) {
36532+		unsigned int addr_value = 0;
36533+		unsigned int addr_offset = 0;
36534+
36535+		if (ctrl & NAND_CTRL_CHANGE) {
36536+			host->addr_cycle = 0x0;
36537+			host->addr_value[0] = 0x0;
36538+			host->addr_value[1] = 0x0;
36539+		}
36540+		addr_offset = host->addr_cycle << 3;
36541+
36542+		if (host->addr_cycle >= HIFMC100_ADDR_CYCLE_MASK) {
36543+			addr_offset = (host->addr_cycle -
36544+				       HIFMC100_ADDR_CYCLE_MASK) << 3;
36545+			addr_value = 1;
36546+		}
36547+
36548+		host->addr_value[addr_value] |=
36549+			(((unsigned int)dat & 0xff) << addr_offset);
36550+
36551+		host->addr_cycle++;
36552+	}
36553+
36554+	if ((ctrl & NAND_CLE) && (ctrl & NAND_CTRL_CHANGE)) {
36555+		cmd = (unsigned int)dat & 0xff;
36556+		host->cmd_op.cmd = cmd;
36557+		switch (cmd) {
36558+		case NAND_CMD_PAGEPROG:
36559+			host->offset = 0;
36560+			host->send_cmd_pageprog(host);
36561+			break;
36562+
36563+		case NAND_CMD_READSTART:
36564+			is_cache_invalid = 0;
36565+			if (host->addr_value[0] == host->pagesize) {
36566+				host->cmd_op.l_cmd = NAND_CMD_READOOB;
36567+			}
36568+			host->send_cmd_readstart(host);
36569+			break;
36570+
36571+		case NAND_CMD_ERASE2:
36572+			host->cmd_op.l_cmd = cmd;
36573+			host->send_cmd_erase(host);
36574+			break;
36575+
36576+		case NAND_CMD_READID:
36577+			memset((u_char *)(chip->IO_ADDR_R), 0, MAX_NAND_ID_LEN);
36578+			host->cmd_op.l_cmd = cmd;
36579+			host->cmd_op.data_no = MAX_NAND_ID_LEN;
36580+			host->send_cmd_readid(host);
36581+			break;
36582+
36583+		case NAND_CMD_STATUS:
36584+			host->send_cmd_status(host);
36585+			break;
36586+
36587+		case NAND_CMD_READ0:
36588+			host->cmd_op.l_cmd = cmd;
36589+			break;
36590+
36591+		case NAND_CMD_RESET:
36592+			host->send_cmd_reset(host);
36593+			break;
36594+
36595+		case NAND_CMD_SEQIN:
36596+		case NAND_CMD_ERASE1:
36597+		default:
36598+			break;
36599+		}
36600+	}
36601+
36602+	/* pass pagesize and ecctype to kernel when startup. */
36603+	host->enable_ecc_randomizer(host, ENABLE, ENABLE);
36604+
36605+	if ((dat == NAND_CMD_NONE) && host->addr_cycle) {
36606+		if (host->cmd_op.cmd == NAND_CMD_SEQIN ||
36607+		    host->cmd_op.cmd == NAND_CMD_READ0 ||
36608+		    host->cmd_op.cmd == NAND_CMD_READID) {
36609+			host->offset = 0x0;
36610+			host->column = (host->addr_value[0] & 0xffff);
36611+		}
36612+	}
36613+
36614+	if (is_cache_invalid) {
36615+		host->cache_addr_value[0] = ~0;
36616+		host->cache_addr_value[1] = ~0;
36617+	}
36618+}
36619+
36620+
36621+static int hifmc100_dev_ready(struct mtd_info *mtd)
36622+{
36623+	return 0x1;
36624+}
36625+
36626+
36627+/*
36628+ * 'host->epm' only use the first oobfree[0] field, it looks very simple, But...
36629+ */
36630+static int hifmc_ooblayout_ecc_default(struct mtd_info *mtd, int section,
36631+				       struct mtd_oob_region *oobregion)
36632+{
36633+	if (section) {
36634+		return -ERANGE;
36635+	}
36636+
36637+	oobregion->length = 32;
36638+	oobregion->offset = 32;
36639+
36640+	return 0;
36641+}
36642+
36643+static int hifmc_ooblayout_free_default(struct mtd_info *mtd, int section,
36644+					struct mtd_oob_region *oobregion)
36645+{
36646+	if (section) {
36647+		return -ERANGE;
36648+	}
36649+
36650+	oobregion->length = 30;
36651+	oobregion->offset = 2;
36652+
36653+	return 0;
36654+}
36655+
36656+static struct mtd_ooblayout_ops hifmc_ooblayout_default_ops = {
36657+	.ecc = hifmc_ooblayout_ecc_default,
36658+	.free = hifmc_ooblayout_free_default,
36659+};
36660+
36661+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2
36662+static int hifmc_ooblayout_ecc_4k16bit(struct mtd_info *mtd, int section,
36663+				       struct mtd_oob_region *oobregion)
36664+{
36665+	if (section) {
36666+		return -ERANGE;
36667+	}
36668+
36669+	oobregion->length = 14;
36670+	oobregion->offset = 14;
36671+
36672+	return 0;
36673+}
36674+
36675+static int hifmc_ooblayout_free_4k16bit(struct mtd_info *mtd, int section,
36676+					struct mtd_oob_region *oobregion)
36677+{
36678+	if (section) {
36679+		return -ERANGE;
36680+	}
36681+
36682+	oobregion->length = 14;
36683+	oobregion->offset = 2;
36684+
36685+	return 0;
36686+}
36687+tatic struct mtd_ooblayout_ops hifmc_ooblayout_4k16bit_ops = {
36688+	.ecc = hifmc_ooblayout_ecc_4k16bit,
36689+	.free = hifmc_ooblayout_free_4k16bit,
36690+};
36691+
36692+static int hifmc_ooblayout_ecc_2k16bit(struct mtd_info *mtd, int section,
36693+				       struct mtd_oob_region *oobregion)
36694+{
36695+	if (section) {
36696+		return -ERANGE;
36697+	}
36698+
36699+	oobregion->length = 6;
36700+	oobregion->offset = 6;
36701+
36702+	return 0;
36703+}
36704+
36705+static int hifmc_ooblayout_free_2k16bit(struct mtd_info *mtd, int section,
36706+					struct mtd_oob_region *oobregion)
36707+{
36708+	if (section) {
36709+		return -ERANGE;
36710+	}
36711+
36712+	oobregion->length = 6;
36713+	oobregion->offset = 2;
36714+
36715+	return 0;
36716+}
36717+
36718+static struct mtd_ooblayout_ops hifmc_ooblayout_2k16bit_ops = {
36719+	.ecc = hifmc_ooblayout_ecc_2k16bit,
36720+	.free = hifmc_ooblayout_free_2k16bit,
36721+};
36722+#endif
36723+
36724+/* ecc/pagesize get from NAND controller */
36725+static struct nand_config_info hifmc100_nand_hw_auto_config_table[] = {
36726+	{NAND_PAGE_16K, NAND_ECC_64BIT, 64, 1824, &hifmc_ooblayout_default_ops}, /* 1824 */
36727+	{NAND_PAGE_16K, NAND_ECC_40BIT, 40, 1200, &hifmc_ooblayout_default_ops}, /* 1152 */
36728+	{NAND_PAGE_16K, NAND_ECC_0BIT,  0, 32,          &hifmc_ooblayout_default_ops},
36729+
36730+	{NAND_PAGE_8K, NAND_ECC_64BIT, 64, 928, &hifmc_ooblayout_default_ops}, /* 928 */
36731+	{NAND_PAGE_8K, NAND_ECC_40BIT, 40, 600, &hifmc_ooblayout_default_ops}, /* 592 */
36732+	{NAND_PAGE_8K, NAND_ECC_24BIT, 24, 368, &hifmc_ooblayout_default_ops}, /* 368 */
36733+	{NAND_PAGE_8K, NAND_ECC_0BIT,  0, 32, &hifmc_ooblayout_default_ops},
36734+
36735+	{NAND_PAGE_4K, NAND_ECC_24BIT, 24, 200, &hifmc_ooblayout_default_ops}, /* 200 */
36736+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2
36737+	{NAND_PAGE_4K, NAND_ECC_16BIT, 16, 128, &hifmc_ooblayout_4k16bit_ops}, /* 128 */
36738+#endif
36739+	{NAND_PAGE_4K, NAND_ECC_8BIT, 8, 128, &hifmc_ooblayout_default_ops}, /* 88 */
36740+	{NAND_PAGE_4K, NAND_ECC_0BIT, 0, 32, &hifmc_ooblayout_default_ops},
36741+
36742+	{NAND_PAGE_2K, NAND_ECC_24BIT, 24, 128, &hifmc_ooblayout_default_ops}, /* 116 */
36743+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2
36744+	{NAND_PAGE_2K, NAND_ECC_16BIT, 16, 64, &hifmc_ooblayout_2k16bit_ops}, /* 64 */
36745+#endif
36746+	{NAND_PAGE_2K, NAND_ECC_8BIT,  8, 64, &hifmc_ooblayout_default_ops}, /* 60 */
36747+	{NAND_PAGE_2K, NAND_ECC_0BIT,  0, 32, &hifmc_ooblayout_default_ops},
36748+
36749+	{0,     0,      0,      0,      NULL},
36750+};
36751+
36752+
36753+/*
36754+ *  0 - This NAND NOT support randomizer
36755+ *  1 - This NAND support randomizer.
36756+ */
36757+static int hifmc100_nand_support_randomizer(u_int pageisze, u_int ecctype)
36758+{
36759+	switch (pageisze) {
36760+	case _8K:
36761+		return (ecctype >= NAND_ECC_24BIT && ecctype <= NAND_ECC_80BIT);
36762+	case _16K:
36763+		return (ecctype >= NAND_ECC_40BIT && ecctype <= NAND_ECC_80BIT);
36764+	case _32K:
36765+		return (ecctype >= NAND_ECC_40BIT && ecctype <= NAND_ECC_80BIT);
36766+	default:
36767+		return 0;
36768+	}
36769+}
36770+
36771+
36772+/* used the best correct arithmetic. */
36773+static struct nand_config_info *hifmc100_get_config_type_info(
36774+	struct mtd_info *mtd, struct nand_dev_t *nand_dev)
36775+{
36776+	struct nand_config_info *best = NULL;
36777+	struct nand_chip *chip = mtd_to_nand(mtd);
36778+	struct hifmc_host *host = chip->priv;
36779+	struct nand_config_info *info = hifmc100_nand_hw_auto_config_table;
36780+
36781+	nand_dev->start_type = "Auto";
36782+	nand_dev->flags |= (IS_NANDC_HW_AUTO(host) | IS_NANDC_CONFIG_DONE(host));
36783+
36784+	for (; info->ooblayout_ops; info++) {
36785+		if (match_page_type_to_size(info->pagetype) != mtd->writesize) {
36786+			continue;
36787+		}
36788+
36789+		if (mtd->oobsize < info->oobsize) {
36790+			continue;
36791+		}
36792+
36793+		if (!best || (best->ecctype < info->ecctype)) {
36794+			best = info;
36795+		}
36796+	}
36797+
36798+	return best;
36799+}
36800+
36801+
36802+static unsigned int hifmc100_get_ecc_reg(struct hifmc_host *host,
36803+		const struct nand_config_info *info, struct nand_dev_t *nand_dev)
36804+{
36805+	host->ecctype = info->ecctype;
36806+	FMC_PR(BT_DBG, "\t |-Save best EccType %d(%s)\n", host->ecctype,
36807+	       match_ecc_type_to_str(info->ecctype));
36808+
36809+	nand_dev->ecctype = host->ecctype;
36810+
36811+	return FMC_CFG_ECC_TYPE(match_ecc_type_to_reg(info->ecctype));
36812+}
36813+
36814+
36815+static unsigned int hifmc100_get_page_reg(struct hifmc_host *host,
36816+		const struct nand_config_info *info)
36817+{
36818+	host->pagesize = match_page_type_to_size(info->pagetype);
36819+	FMC_PR(BT_DBG, "\t |-Save best PageSize %d(%s)\n", host->pagesize,
36820+	       match_page_type_to_str(info->pagetype));
36821+
36822+	return FMC_CFG_PAGE_SIZE(match_page_type_to_reg(info->pagetype));
36823+}
36824+
36825+
36826+static unsigned int hifmc100_get_block_reg(struct hifmc_host *host,
36827+		const struct nand_config_info *info)
36828+{
36829+	unsigned int block_reg = 0;
36830+	unsigned int page_per_block;
36831+	struct mtd_info *mtd = host->mtd;
36832+
36833+	host->block_page_mask = ((mtd->erasesize / mtd->writesize) - 1);
36834+	page_per_block = mtd->erasesize / match_page_type_to_size(info->pagetype);
36835+	switch (page_per_block) {
36836+	case 64:
36837+		block_reg = BLOCK_SIZE_64_PAGE;
36838+		break;
36839+	case 128:
36840+		block_reg = BLOCK_SIZE_128_PAGE;
36841+		break;
36842+	case 256:
36843+		block_reg = BLOCK_SIZE_256_PAGE;
36844+		break;
36845+	case 512:
36846+		block_reg = BLOCK_SIZE_512_PAGE;
36847+		break;
36848+	default:
36849+		DB_MSG("Can't support block %#x and page %#x size\n",
36850+		       mtd->erasesize, mtd->writesize);
36851+	}
36852+
36853+	return FMC_CFG_BLOCK_SIZE(block_reg);
36854+}
36855+
36856+
36857+static void hifmc100_set_fmc_cfg_reg(struct hifmc_host *host,
36858+				    const struct nand_config_info *type_info, struct nand_dev_t *nand_dev)
36859+{
36860+	unsigned int page_reg, ecc_reg, block_reg, reg_fmc_cfg;
36861+
36862+	ecc_reg = hifmc100_get_ecc_reg(host, type_info, nand_dev);
36863+	page_reg = hifmc100_get_page_reg(host, type_info);
36864+	block_reg = hifmc100_get_block_reg(host, type_info);
36865+
36866+	if (hifmc100_nand_support_randomizer(host->pagesize, host->ecctype)) {
36867+		host->flags |= IS_NAND_RANDOM(nand_dev);
36868+	}
36869+
36870+	/*
36871+	 * Check if hardware enable randomizer PIN, But NAND does not need
36872+	 * randomizer. We will notice user.
36873+	 */
36874+	if (IS_NAND_RANDOM(host) &&
36875+			!hifmc100_nand_support_randomizer(host->pagesize,
36876+							  host->ecctype)) {
36877+		DB_BUG(ERSTR_HARDWARE
36878+		       "This NAND flash does not support `randomizer`, "
36879+		       "Please don't configure hardware randomizer PIN.");
36880+	}
36881+	/* Save value of FMC_CFG and FMC_CFG_ECC0 to turn on/off ECC */
36882+	reg_fmc_cfg = hifmc_readl(host, FMC_CFG);
36883+	reg_fmc_cfg &= ~(PAGE_SIZE_MASK | ECC_TYPE_MASK | BLOCK_SIZE_MASK);
36884+	reg_fmc_cfg |= ecc_reg | page_reg | block_reg;
36885+	host->nand_cfg = reg_fmc_cfg;
36886+	host->nand_cfg_ecc0 = (host->nand_cfg & ~ECC_TYPE_MASK) | ECC_TYPE_0BIT;
36887+	FMC_PR(BT_DBG, "\t|-Save FMC_CFG[%#x]: %#x and FMC_CFG_ECC0: %#x\n",
36888+	       FMC_CFG, host->nand_cfg, host->nand_cfg_ecc0);
36889+
36890+	/* pass pagesize and ecctype to kernel when spiflash startup. */
36891+	host->enable_ecc_randomizer(host, ENABLE, ENABLE);
36892+
36893+	/*
36894+	 * If it want to support the 'read retry' feature, the 'randomizer'
36895+	 * feature must be support first.
36896+	 */
36897+	host->read_retry = NULL;
36898+
36899+	if (host->read_retry && !IS_NAND_RANDOM(host)) {
36900+		DB_BUG(ERSTR_HARDWARE
36901+		       "This Nand flash need to enable 'randomizer' feature. "
36902+		       "Please configure hardware randomizer PIN.");
36903+	}
36904+}
36905+
36906+
36907+static void hifmc100_set_oob_info(struct mtd_info *mtd,
36908+				  struct nand_config_info *info, struct nand_dev_t *nand_dev)
36909+{
36910+	int buffer_len;
36911+	struct nand_chip *chip = mtd_to_nand(mtd);
36912+	struct hifmc_host *host = chip->priv;
36913+	struct mtd_oob_region hifmc_oobregion = {0, 0};
36914+
36915+	if (info->ecctype != NAND_ECC_0BIT) {
36916+		mtd->oobsize = info->oobsize;
36917+	}
36918+	mtd->oobavail = HIFMC100_NAND_OOBSIZE_FOR_YAFFS;
36919+
36920+	host->oobsize = mtd->oobsize;
36921+
36922+	buffer_len = host->pagesize + host->oobsize;
36923+
36924+	memset(host->buffer, 0xff, buffer_len);
36925+	host->dma_oob = host->dma_buffer + host->pagesize;
36926+
36927+	host->bbm = (unsigned char *)(host->buffer + host->pagesize +
36928+				      HIFMC100_BAD_BLOCK_POS);
36929+
36930+	info->ooblayout_ops->free(mtd, 0, &hifmc_oobregion);
36931+
36932+	mtd_set_ooblayout(mtd, info->ooblayout_ops);
36933+
36934+	/* EB bits locate in the bottom two of CTRL(30) */
36935+	host->epm = (u_short *)(host->buffer + host->pagesize +
36936+				hifmc_oobregion.offset + 28);
36937+
36938+#ifdef CONFIG_HISI_NAND_FS_MAY_NO_YAFFS2
36939+	if (best->ecctype == NAND_ECC_16BIT) {
36940+		if (host->pagesize == _2K) {
36941+			/* EB bits locate in the bottom two of CTRL(4) */
36942+			host->epm = (u_short *)(host->buffer + host->pagesize +
36943+						hifmc_oobregion.offset + 4);
36944+		} else if (host->pagesize == _4K) {
36945+			/* EB bit locate in the bottom two of CTRL(14) */
36946+			host->epm = (u_short *)(host->buffer + host->pagesize +
36947+						hifmc_oobregion.offset + 12);
36948+		}
36949+	}
36950+#endif
36951+}
36952+
36953+static int hifmc100_set_config_info(struct mtd_info *mtd,
36954+				    struct nand_chip *chip, struct nand_dev_t *dev)
36955+{
36956+	struct hifmc_host *host = chip->priv;
36957+	struct nand_dev_t *nand_dev = dev;
36958+	struct nand_config_info *type_info = NULL;
36959+
36960+	FMC_PR(BT_DBG, "\t*-Start config Block Page OOB and Ecc\n");
36961+
36962+	type_info = hifmc100_get_config_type_info(mtd, nand_dev);
36963+	WARN_ON(!type_info);
36964+
36965+	FMC_PR(BT_DBG, "\t|-%s Config, PageSize %s EccType %s OobSize %d\n",
36966+	       nand_dev->start_type, nand_page_name(type_info->pagetype),
36967+	       nand_ecc_name(type_info->ecctype), type_info->oobsize);
36968+
36969+	/* Set the page_size, ecc_type, block_size of FMC_CFG[0x0] register */
36970+	hifmc100_set_fmc_cfg_reg(host, type_info, nand_dev);
36971+
36972+	hifmc100_set_oob_info(mtd, type_info, nand_dev);
36973+
36974+	if (mtd->writesize > NAND_MAX_PAGESIZE ||
36975+	    mtd->oobsize > NAND_MAX_OOBSIZE) {
36976+		DB_BUG(ERSTR_DRIVER
36977+		       "Driver does not support this Nand Flash. Please " \
36978+		       "increase NAND_MAX_PAGESIZE and NAND_MAX_OOBSIZE.\n");
36979+	}
36980+
36981+	/* Some Nand Flash devices have subpage structure */
36982+	if (mtd->writesize != host->pagesize) {
36983+		unsigned int shift = 0;
36984+		unsigned int writesize = mtd->writesize;
36985+
36986+		while (writesize > host->pagesize) {
36987+			writesize >>= 1;
36988+			shift++;
36989+		}
36990+		chip->chipsize = chip->chipsize >> shift;
36991+		mtd->erasesize = mtd->erasesize >> shift;
36992+		mtd->writesize = host->pagesize;
36993+		pr_info("Nand divide into 1/%u\n", (1 << shift));
36994+	}
36995+
36996+	FMC_PR(BT_DBG, "\t*-End config Block Page Oob and Ecc\n");
36997+
36998+	return 0;
36999+}
37000+
37001+
37002+static void hifmc100_chip_init(struct nand_chip *chip)
37003+{
37004+	struct hifmc_host *host = chip->priv;
37005+
37006+	memset((char *)chip->IO_ADDR_R, 0xff, host->dma_len);
37007+
37008+	chip->read_byte = hifmc100_read_byte;
37009+	chip->read_word = hifmc100_read_word;
37010+	chip->write_buf = hifmc100_write_buf;
37011+	chip->read_buf = hifmc100_read_buf;
37012+
37013+	chip->select_chip = hifmc100_select_chip;
37014+
37015+	chip->cmd_ctrl = hifmc100_cmd_ctrl;
37016+	chip->dev_ready = hifmc100_dev_ready;
37017+
37018+	chip->chip_delay = FMC_CHIP_DELAY;
37019+
37020+	chip->options = NAND_NEED_READRDY | NAND_BROKEN_XD |
37021+			NAND_SKIP_BBTSCAN;
37022+
37023+	chip->ecc.mode = NAND_ECC_NONE;
37024+}
37025+
37026+
37027+static int hifmc100_host_init(struct hifmc_host *host)
37028+{
37029+	unsigned int reg, flash_type;
37030+
37031+	FMC_PR(BT_DBG, "\t *-Start nand host init\n");
37032+
37033+	reg = hifmc_readl(host, FMC_CFG);
37034+	FMC_PR(BT_DBG, "\t |-Read FMC CFG[%#x]%#x\n", FMC_CFG, reg);
37035+	flash_type = GET_SPI_FLASH_TYPE(reg);
37036+	if (flash_type != FLASH_TYPE_NAND) {
37037+		DB_MSG("Error: Flash type isn't Nand flash. reg[%#x]\n", reg);
37038+		reg |= FMC_CFG_FLASH_SEL(FLASH_TYPE_NAND);
37039+		FMC_PR(BT_DBG, "\t |-Change flash type to Nand flash\n");
37040+	}
37041+
37042+	if ((reg & FMC_CFG_OP_MODE_MASK) == FMC_CFG_OP_MODE_BOOT) {
37043+		reg |= FMC_CFG_OP_MODE(FMC_CFG_OP_MODE_NORMAL);
37044+		FMC_PR(BT_DBG, "\t |-Controller enter normal mode\n");
37045+	}
37046+	hifmc_writel(host, FMC_CFG, reg);
37047+	FMC_PR(BT_DBG, "\t |-Set CFG[%#x]%#x\n", FMC_CFG, reg);
37048+
37049+	host->nand_cfg = reg;
37050+	host->nand_cfg_ecc0 = (reg & ~ECC_TYPE_MASK) | ECC_TYPE_0BIT;
37051+
37052+	reg = hifmc_readl(host, FMC_GLOBAL_CFG);
37053+	FMC_PR(BT_DBG, "\t |-Read global CFG[%#x]%#x\n", FMC_GLOBAL_CFG, reg);
37054+	if (reg & FMC_GLOBAL_CFG_RANDOMIZER_EN) {
37055+		host->flags &= ~NAND_RANDOMIZER;
37056+		FMC_PR(BT_DBG, "\t |-Default disable randomizer\n");
37057+		reg &= ~FMC_GLOBAL_CFG_RANDOMIZER_EN;
37058+		hifmc_writel(host, FMC_GLOBAL_CFG, reg);
37059+		FMC_PR(BT_DBG, "\t |-Set global CFG[%#x]%#x\n", FMC_GLOBAL_CFG, reg);
37060+	}
37061+
37062+#ifdef CONFIG_HIFMC100_NAND_EDO_MODE
37063+	/* enable EDO node */
37064+	reg = hifmc_readl(host, FMC_GLOBAL_CFG);
37065+	hifmc_writel(host, FMC_GLOBAL_CFG, SET_NAND_EDO_MODE_EN(reg));
37066+#endif
37067+
37068+	host->addr_cycle = 0;
37069+	host->addr_value[0] = 0;
37070+	host->addr_value[1] = 0;
37071+	host->cache_addr_value[0] = ~0;
37072+	host->cache_addr_value[1] = ~0;
37073+
37074+	host->send_cmd_pageprog = hifmc100_send_cmd_write;
37075+	host->send_cmd_status = hifmc100_send_cmd_status;
37076+	host->send_cmd_readstart = hifmc100_send_cmd_read;
37077+	host->send_cmd_erase = hifmc100_send_cmd_erase;
37078+	host->send_cmd_readid = hifmc100_send_cmd_readid;
37079+	host->send_cmd_reset = hifmc100_send_cmd_reset;
37080+
37081+	/*
37082+	 * check if start from nand.
37083+	 * This register REG_SYSSTAT is set in start.S
37084+	 * When start in NAND (Auto), the ECC/PAGESIZE driver don't detect.
37085+	 */
37086+	host->flags |= NANDC_HW_AUTO;
37087+
37088+	if (GET_SYS_BOOT_MODE(reg) == BOOT_FROM_NAND) {
37089+		host->flags |= NANDC_CONFIG_DONE;
37090+		FMC_PR(BT_DBG, "\t |-Auto config pagesize and ecctype\n");
37091+	}
37092+
37093+	host->enable_ecc_randomizer = hifmc100_ecc_randomizer;
37094+
37095+	FMC_PR(BT_DBG, "\t *-End nand host init\n");
37096+
37097+	return 0;
37098+}
37099+
37100+
37101+int hifmc100_nand_init(struct nand_chip *chip)
37102+{
37103+	struct hifmc_host *host = chip->priv;
37104+
37105+	/* enable and set system clock */
37106+	clk_prepare_enable(host->clk);
37107+
37108+	/* fmc ip version check */
37109+	host->version = hifmc_readl(host, FMC_VERSION);
37110+	if (host->version != HIFMC_VER_100) {
37111+		return -EFAULT;
37112+	}
37113+	pr_info("Found Flash Memory Controller v100 Nand Driver\n");
37114+
37115+	/* hifmc host init */
37116+	if (hifmc100_host_init(host)) {
37117+		DB_MSG("Error: Nand host init failed!\n");
37118+		return -EFAULT;
37119+	}
37120+	host->chip = chip;
37121+
37122+	hifmc_writel(host,
37123+		     FMC_PND_PWIDTH_CFG,
37124+		     PWIDTH_CFG_RW_HCNT(CONFIG_RW_H_WIDTH) |
37125+		     PWIDTH_CFG_R_LCNT(CONFIG_R_L_WIDTH) |
37126+		     PWIDTH_CFG_W_LCNT(CONFIG_W_L_WIDTH));
37127+
37128+	/* hifmc nand_chip struct init */
37129+	hifmc100_chip_init(chip);
37130+
37131+	hifmc_spl_ids_register();
37132+	hinfc_param_adjust = hifmc100_set_config_info;
37133+
37134+	return 0;
37135+}
37136+
37137+#ifdef CONFIG_PM
37138+
37139+void hifmc100_nand_config(const struct hifmc_host *host)
37140+{
37141+	/* enable system clock */
37142+	clk_prepare_enable(host->clk);
37143+	FMC_PR(PM_DBG, "\t |-enable system clock\n");
37144+}
37145+#endif  /* CONFIG_PM */
37146diff --git a/drivers/mtd/nand/hifmc100_nand/hifmc100_nand.h b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand.h
37147new file mode 100644
37148index 000000000..fba2f43ba
37149--- /dev/null
37150+++ b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand.h
37151@@ -0,0 +1,151 @@
37152+/*
37153+ * The Flash Memory Controller v100 Device Driver for hisilicon
37154+ *
37155+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
37156+ *
37157+ * This program is free software; you can redistribute  it and/or modify it
37158+ * under  the terms of  the GNU General  Public License as published by the
37159+ * Free Software Foundation;  either version 2 of the  License, or (at your
37160+ * option) any later version.
37161+ *
37162+ * This program is distributed in the hope that it will be useful,
37163+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
37164+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37165+ * GNU General Public License for more details.
37166+ *
37167+ * You should have received a copy of the GNU General Public License
37168+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
37169+ *
37170+ */
37171+
37172+#ifndef __HIFMC100_NAND_H__
37173+#define __HIFMC100_NAND_H__
37174+
37175+#include <linux/mfd/hisi_fmc.h>
37176+
37177+/******************************************************************************/
37178+/* These macroes are for debug only, reg option is slower then dma option */
37179+#undef HIFMC100_NAND_SUPPORT_REG_READ
37180+/* #define HIFMC100_NAND_SUPPORT_REG_READ */
37181+
37182+#undef HIFMC100_NAND_SUPPORT_REG_WRITE
37183+/* #define HIFMC100_NAND_SUPPORT_REG_WRITE */
37184+
37185+/*****************************************************************************/
37186+#define HIFMC100_ECC_ERR_NUM0_BUF0      0xc0
37187+#define HIFMC100_ECC_ERR_NUM1_BUF0      0xc4
37188+#define HIFMC100_ECC_ERR_NUM0_BUF1      0xc8
37189+#define HIFMC100_ECC_ERR_NUM1_BUF1      0xcc
37190+
37191+#define GET_ECC_ERR_NUM(_i, _reg)       (((_reg) >> ((_i) * 8)) & 0xff)
37192+
37193+/*****************************************************************************/
37194+#define NAND_MAX_PAGESIZE           32768
37195+#define NAND_MAX_OOBSIZE            4800
37196+
37197+#define CONFIG_SUPPORT_YAFFS
37198+#define HIFMC100_NAND_OOBSIZE_FOR_YAFFS     32
37199+
37200+/*****************************************************************************/
37201+#define REG_CNT_HIGH_BLOCK_NUM_SHIFT        10
37202+
37203+#define REG_CNT_BLOCK_NUM_MASK          0x3ff
37204+#define REG_CNT_BLOCK_NUM_SHIFT         22
37205+
37206+#define REG_CNT_PAGE_NUM_MASK           0x3f
37207+#define REG_CNT_PAGE_NUM_SHIFT          16
37208+
37209+/*****************************************************************************/
37210+#define HIFMC100_ADDR_CYCLE_MASK        0x4
37211+#define NAND_EDO_MODE_SHIFT            9
37212+#define NAND_EDO_MODE_MASK             (1<<NAND_EDO_MODE_SHIFT)
37213+#define SET_NAND_EDO_MODE_EN(reg)      ((reg) | NAND_EDO_MODE_MASK)
37214+/*****************************************************************************/
37215+struct hifmc_host {
37216+	struct nand_chip *chip;
37217+	struct mtd_info  *mtd;
37218+
37219+	struct hifmc_cmd_op cmd_op;
37220+	void __iomem *regbase;
37221+	void __iomem *iobase;
37222+
37223+	/* Controller config option nand flash */
37224+	unsigned int nand_cfg;
37225+	unsigned int nand_cfg_ecc0;
37226+
37227+	unsigned int offset;
37228+
37229+	struct device *dev;
37230+
37231+	/* This is maybe an un-aligment address, only for malloc or free */
37232+	char *buforg;
37233+	char *buffer;
37234+
37235+#ifdef CONFIG_64BIT
37236+	unsigned long long dma_buffer;
37237+	unsigned long long dma_oob;
37238+#else
37239+	unsigned int dma_buffer;
37240+	unsigned int dma_oob;
37241+#endif
37242+	unsigned int dma_len;
37243+
37244+	unsigned int addr_cycle;
37245+	unsigned int addr_value[2];
37246+	unsigned int cache_addr_value[2];
37247+
37248+	unsigned int column;
37249+	unsigned int block_page_mask;
37250+
37251+	unsigned int ecctype;
37252+	unsigned int pagesize;
37253+	unsigned int oobsize;
37254+
37255+	int  need_rr_data;
37256+#define HIFMC100_READ_RETRY_DATA_LEN         128
37257+	char rr_data[HIFMC100_READ_RETRY_DATA_LEN];
37258+	int  version;
37259+	int   add_partition;
37260+
37261+	/* BOOTROM read two bytes to detect the bad block flag */
37262+#define HIFMC100_BAD_BLOCK_POS              0
37263+	unsigned char *bbm;  /* nand bad block mark */
37264+	unsigned short *epm;  /* nand empty page mark */
37265+	unsigned int flags;
37266+
37267+#define HIFMC100_PS_UC_ECC        0x01 /* page has ecc error */
37268+#define HIFMC100_PS_BAD_BLOCK     0x02 /* bad block */
37269+#define HIFMC100_PS_EMPTY_PAGE    0x04 /* page is empty */
37270+#define HIFMC100_PS_EPM_ERROR     0x0100 /* empty page mark word has error. */
37271+#define HIFMC100_PS_BBM_ERROR     0x0200 /* bad block mark word has error. */
37272+	unsigned int page_status;
37273+
37274+	struct clk *clk;
37275+
37276+	void (*send_cmd_pageprog)(struct hifmc_host *host);
37277+	void (*send_cmd_status)(struct hifmc_host *host);
37278+	void (*send_cmd_readstart)(struct hifmc_host *host);
37279+	void (*send_cmd_erase)(struct hifmc_host *host);
37280+	void (*send_cmd_readid)(struct hifmc_host *host);
37281+	void (*send_cmd_reset)(struct hifmc_host *host);
37282+	void (*enable)(int enable);
37283+
37284+	void (*enable_ecc_randomizer)(struct hifmc_host *host,
37285+				      int ecc_en, int randomizer_en);
37286+
37287+	void (*detect_ecc)(struct hifmc_host *host);
37288+
37289+	struct read_retry_t *read_retry;
37290+};
37291+
37292+extern struct nand_dev_t g_nand_dev;
37293+
37294+int hifmc100_nand_init(struct nand_chip *chip);
37295+
37296+extern void hifmc_spl_ids_register(void);
37297+
37298+#ifdef CONFIG_PM
37299+void hifmc100_nand_config(const struct hifmc_host *host);
37300+#endif
37301+
37302+#endif /* End of __HIFMC100_NAND_H__ */
37303diff --git a/drivers/mtd/nand/hifmc100_nand/hifmc100_nand_os.c b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand_os.c
37304new file mode 100644
37305index 000000000..0849cd3cb
37306--- /dev/null
37307+++ b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand_os.c
37308@@ -0,0 +1,180 @@
37309+/*
37310+ * The Flash Memory Controller v100 Device Driver for hisilicon
37311+ *
37312+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
37313+ *
37314+ * This program is free software; you can redistribute  it and/or modify it
37315+ * under  the terms of  the GNU General  Public License as published by the
37316+ * Free Software Foundation;  either version 2 of the  License, or (at your
37317+ * option) any later version.
37318+ *
37319+ * This program is distributed in the hope that it will be useful,
37320+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
37321+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37322+ * GNU General Public License for more details.
37323+ *
37324+ * You should have received a copy of the GNU General Public License
37325+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
37326+ *
37327+ */
37328+
37329+#include <linux/of_platform.h>
37330+
37331+#include "hifmc100_nand_os.h"
37332+#include "hifmc100_nand.h"
37333+#include <linux/mfd/hisi_fmc.h>
37334+
37335+static inline int mtd_has_partitions(void)
37336+{
37337+	return 1;
37338+}
37339+
37340+static int hisi_nand_os_probe(struct platform_device *pltdev)
37341+{
37342+	int len;
37343+	int result = 0;
37344+	struct hifmc_host *host = NULL;
37345+	struct nand_chip *chip = NULL;
37346+	struct mtd_info *mtd = NULL;
37347+	int nr_parts = 0;
37348+	struct mtd_partition *parts = NULL;
37349+	struct device *dev = &pltdev->dev;
37350+	struct device_node *np = NULL;
37351+	struct hisi_fmc *fmc = dev_get_drvdata(dev->parent);
37352+
37353+	if (!fmc) {
37354+		dev_err(dev, "get mfd fmc devices failed\n");
37355+		return -ENXIO;
37356+	}
37357+
37358+	len = sizeof(struct hifmc_host) + sizeof(struct nand_chip)
37359+	      + sizeof(struct mtd_info);
37360+	host = devm_kzalloc(dev, len, GFP_KERNEL);
37361+	if (!host) {
37362+		return -ENOMEM;
37363+	}
37364+	memset((char *)host, 0, len);
37365+	platform_set_drvdata(pltdev, host);
37366+
37367+	host->dev = &pltdev->dev;
37368+	host->chip = chip = (struct nand_chip *)&host[1];
37369+	host->mtd = mtd = nand_to_mtd(chip);
37370+	host->regbase = fmc->regbase;
37371+	host->iobase = fmc->iobase;
37372+	host->clk = fmc->clk;
37373+	chip->IO_ADDR_R = chip->IO_ADDR_W = host->iobase;
37374+	host->buffer = fmc->buffer;
37375+	host->dma_buffer = fmc->dma_buffer;
37376+	host->dma_len = fmc->dma_len;
37377+
37378+	/* hifmc Nand host init */
37379+	chip->priv = host;
37380+	result = hifmc100_nand_init(chip);
37381+	if (result) {
37382+		DB_MSG("Error: host init failed! result: %d\n", result);
37383+		goto fail;
37384+	}
37385+
37386+	np = of_get_next_available_child(dev->of_node, NULL);
37387+	mtd->name = np->name;
37388+	mtd->type = MTD_NANDFLASH;
37389+	mtd->priv = chip;
37390+	mtd->flags = MTD_CAP_NANDFLASH;
37391+	mtd->owner = THIS_MODULE;
37392+
37393+	if (nand_scan(mtd, CONFIG_HIFMC100_MAX_NAND_CHIP)) {
37394+		result = -ENXIO;
37395+		goto fail;
37396+	}
37397+
37398+	result = mtd_device_register(host->mtd, parts, nr_parts);
37399+	if (result) {
37400+		kfree(parts);
37401+		parts = NULL;
37402+	}
37403+
37404+	return (result == 1) ? -ENODEV : 0;
37405+
37406+fail:
37407+	clk_disable_unprepare(host->clk);
37408+	nand_release(mtd);
37409+	return result;
37410+}
37411+
37412+static int hisi_nand_os_remove(struct platform_device *pltdev)
37413+{
37414+	struct hifmc_host *host = platform_get_drvdata(pltdev);
37415+
37416+	clk_disable_unprepare(host->clk);
37417+	nand_release(host->mtd);
37418+
37419+	return 0;
37420+}
37421+
37422+#ifdef CONFIG_PM
37423+static int hifmc100_nand_os_suspend(struct platform_device *pltdev,
37424+				    pm_message_t state)
37425+{
37426+	struct hifmc_host *host = platform_get_drvdata(pltdev);
37427+	struct device *dev = &pltdev->dev;
37428+	if (!host || !host->clk) {
37429+		dev_err(dev,"host or host->clk is null err\n");
37430+		return 0;
37431+	}
37432+
37433+	while ((hifmc_readl(host, FMC_OP) & FMC_OP_REG_OP_START)) {
37434+		_cond_resched();
37435+	}
37436+
37437+	while ((hifmc_readl(host, FMC_OP_CTRL) & OP_CTRL_DMA_OP_READY)) {
37438+		_cond_resched();
37439+	}
37440+
37441+	clk_disable_unprepare(host->clk);
37442+	FMC_PR(PM_DBG, "\t|-disable system clock\n");
37443+	return 0;
37444+}
37445+
37446+static int hifmc100_nand_os_resume(struct platform_device *pltdev)
37447+{
37448+	int cs;
37449+	struct hifmc_host *host = platform_get_drvdata(pltdev);
37450+	struct nand_chip *chip = NULL;
37451+
37452+	if (!host) {
37453+		return 0;
37454+	}
37455+	chip = host->chip;
37456+
37457+	for (cs = 0; cs < chip->numchips; cs++) {
37458+		host->send_cmd_reset(host);
37459+	}
37460+
37461+	hifmc100_nand_config(host);
37462+	return 0;
37463+}
37464+#endif /* CONFIG_PM */
37465+
37466+static const struct of_device_id hisi_nand_dt_ids[] = {
37467+	{ .compatible = "hisilicon,hisi_nand" },
37468+	{ } /* sentinel */
37469+};
37470+MODULE_DEVICE_TABLE(of, hisi_nand_dt_ids);
37471+
37472+static struct platform_driver hisi_nand_driver = {
37473+	.driver = {
37474+		.name   = "hisi_nand",
37475+		.of_match_table = hisi_nand_dt_ids,
37476+	},
37477+	.probe  = hisi_nand_os_probe,
37478+	.remove = hisi_nand_os_remove,
37479+#ifdef CONFIG_PM
37480+	.suspend    = hifmc100_nand_os_suspend,
37481+	.resume     = hifmc100_nand_os_resume,
37482+#endif
37483+};
37484+module_platform_driver(hisi_nand_driver);
37485+
37486+MODULE_LICENSE("GPL");
37487+MODULE_AUTHOR("BVT_BSP");
37488+MODULE_DESCRIPTION("Hisilicon Flash Memory Controller V100 Nand Driver");
37489diff --git a/drivers/mtd/nand/hifmc100_nand/hifmc100_nand_os.h b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand_os.h
37490new file mode 100644
37491index 000000000..a27813530
37492--- /dev/null
37493+++ b/drivers/mtd/nand/hifmc100_nand/hifmc100_nand_os.h
37494@@ -0,0 +1,72 @@
37495+/*
37496+ * The Flash Memory Controller v100 Device Driver for hisilicon
37497+ *
37498+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
37499+ *
37500+ * This program is free software; you can redistribute  it and/or modify it
37501+ * under  the terms of  the GNU General  Public License as published by the
37502+ * Free Software Foundation;  either version 2 of the  License, or (at your
37503+ * option) any later version.
37504+ *
37505+ * This program is distributed in the hope that it will be useful,
37506+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
37507+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37508+ * GNU General Public License for more details.
37509+ *
37510+ * You should have received a copy of the GNU General Public License
37511+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
37512+ *
37513+ */
37514+
37515+#ifndef __HIFMC100_NAND_OS_H__
37516+#define __HIFMC100_NAND_OS_H__
37517+
37518+#include <linux/init.h>
37519+#include <linux/module.h>
37520+#include <linux/mtd/mtd.h>
37521+#include <linux/mtd/nand.h>
37522+#include <linux/mtd/rawnand.h>
37523+#include <linux/mtd/partitions.h>
37524+#include <linux/delay.h>
37525+#include <linux/dma-mapping.h>
37526+#include <linux/sched.h>
37527+#include <asm/errno.h>
37528+#include <asm/setup.h>
37529+#include <linux/io.h>
37530+#include <linux/version.h>
37531+#include <linux/kernel.h>
37532+#include <linux/platform_device.h>
37533+
37534+#include <linux/resource.h>
37535+#include <linux/clk.h>
37536+#include <linux/clkdev.h>
37537+
37538+#if (KERNEL_VERSION(3, 4, 5) <= LINUX_VERSION_CODE)
37539+#include "../../mtdcore.h"
37540+#endif
37541+
37542+
37543+#define DEFAULT_NAND_PAGESIZE   2048
37544+#define DEFAULT_NAND_OOBSIZE    64
37545+
37546+#define NAND_BUFFER_LEN     (DEFAULT_NAND_PAGESIZE + DEFAULT_NAND_OOBSIZE)
37547+
37548+
37549+#ifndef CONFIG_RW_H_WIDTH
37550+#define CONFIG_RW_H_WIDTH   (10)
37551+#warning NOT config CONFIG_RW_H_WIDTH, used default value, maybe invalid.
37552+#endif
37553+
37554+#ifndef CONFIG_R_L_WIDTH
37555+#define CONFIG_R_L_WIDTH    (10)
37556+#warning NOT config CONFIG_R_L_WIDTH, used default value, maybe invalid.
37557+#endif
37558+
37559+#ifndef CONFIG_W_L_WIDTH
37560+#define CONFIG_W_L_WIDTH    (10)
37561+#warning NOT config CONFIG_W_L_WIDTH, used default value, maybe invalid.
37562+#endif
37563+
37564+extern void hifmc100_nand_controller_enable(int enable);
37565+
37566+#endif /* End of __HIFMC100_NAND_OS_H__ */
37567diff --git a/drivers/mtd/nand/hifmc100_nand/hifmc_nand_spl_ids.c b/drivers/mtd/nand/hifmc100_nand/hifmc_nand_spl_ids.c
37568new file mode 100644
37569index 000000000..b03510a44
37570--- /dev/null
37571+++ b/drivers/mtd/nand/hifmc100_nand/hifmc_nand_spl_ids.c
37572@@ -0,0 +1,982 @@
37573+/*
37574+ * The Flash Memory Controller v100 Device Driver for hisilicon
37575+ *
37576+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
37577+ *
37578+ * This program is free software; you can redistribute  it and/or modify it
37579+ * under  the terms of  the GNU General  Public License as published by the
37580+ * Free Software Foundation;  either version 2 of the  License, or (at your
37581+ * option) any later version.
37582+ *
37583+ * This program is distributed in the hope that it will be useful,
37584+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
37585+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37586+ * GNU General Public License for more details.
37587+ *
37588+ * You should have received a copy of the GNU General Public License
37589+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
37590+ *
37591+ */
37592+
37593+#include <asm/setup.h>
37594+#include <linux/mtd/nand.h>
37595+#include <linux/mfd/hisi_fmc.h>
37596+#include <linux/uaccess.h>
37597+
37598+#include "../raw/hinfc_gen.h"
37599+#include "hifmc100_nand.h"
37600+
37601+
37602+#define _768K           (_256K + _512K)
37603+
37604+
37605+struct nand_flash_special_dev {
37606+	unsigned char id[8];
37607+	int length;             /* length of id. */
37608+	unsigned long long chipsize;
37609+	struct nand_flash_dev *(*probe)(unsigned char *id);
37610+	char *name;
37611+
37612+	unsigned long pagesize;
37613+	unsigned long erasesize;
37614+	unsigned long oobsize;
37615+	unsigned long options;
37616+	unsigned int read_retry_type;
37617+
37618+#define BBP_LAST_PAGE                    0x01
37619+#define BBP_FIRST_PAGE                   0x02
37620+	unsigned int badblock_pos;
37621+	int flags;
37622+};
37623+
37624+
37625+/*                    this is nand probe function.                           */
37626+
37627+
37628+static struct nand_flash_dev *hynix_probe_v02(unsigned char *id)
37629+{
37630+	struct nand_flash_dev *type = &g_nand_dev.flash_dev;
37631+
37632+	int pagesizes[]   = {_2K, _4K, _8K, 0};
37633+	int oobsizes[]    = {128, 224, 448, 0, 0, 0, 0, 0};
37634+	int blocksizes[]  = {_128K, _256K, _512K, _768K, _1M, _2M, 0, 0};
37635+
37636+	int blocktype = (((id[3] >> 5) & 0x04) | ((id[3] >> 4) & 0x03));
37637+	int oobtype   = (((id[3] >> 2) & 0x03) | ((id[3] >> 4) & 0x04));
37638+
37639+	type->options   = 0;
37640+	type->pagesize  = pagesizes[(id[3] & 0x03)];
37641+	type->erasesize = blocksizes[blocktype];
37642+	type->oobsize = oobsizes[oobtype];
37643+
37644+	return type;
37645+}
37646+
37647+
37648+static struct nand_flash_dev *samsung_probe_v02(unsigned char *id)
37649+{
37650+	struct nand_flash_dev *type = &g_nand_dev.flash_dev;
37651+
37652+	int pagesizes[]   = {_2K, _4K, _8K, 0};
37653+	int oobsizes[]    = {0, 128, 218, 400, 436, 0, 0, 0};
37654+	int blocksizes[]  = {_128K, _256K, _512K, _1M, 0, 0, 0, 0};
37655+
37656+	int blocktype = (((id[3] >> 5) & 0x04) | ((id[3] >> 4) & 0x03));
37657+	int oobtype   = (((id[3] >> 4) & 0x04) | ((id[3] >> 2) & 0x03));
37658+
37659+	type->options   = 0;
37660+	type->pagesize  = pagesizes[(id[3] & 0x03)];
37661+	type->erasesize = blocksizes[blocktype];
37662+	type->oobsize = oobsizes[oobtype];
37663+
37664+	return type;
37665+}
37666+
37667+#define DRV_VERSION     "1.40"
37668+
37669+/*
37670+ * samsung:  27nm need randomizer, 21nm need read retry;
37671+ * micron:   25nm need read retry, datasheet will explain read retry.
37672+ * toshaba   32nm need randomizer, 24nm need read retry.
37673+ * hynix:    2xnm need read retry.
37674+ *
37675+ *      The special nand flash ID table version 1.39
37676+ *
37677+ * manufactory  |  type  |       name        |   ecc_type  | version_tag
37678+ * Micron       |  MLC   |  MT29F64G08CBABA  |   40bit/1k  |  1.36
37679+ * Micron       |  MLC   |  MT29F32G08CBADA  |   40bit/1k  |
37680+ * Micron       |  SLC   |  MT29F8G08ABxBA   |   4bit/512  |
37681+ * Micron       |  MLC   |  MT29F16G08CBABx  |   12bit/512 |
37682+ * Micron       |  MLC   |  MT29F16G08CBACA  |   24bit/1k  |
37683+ * Micron       |  MLC   |  MT29F32G08CBACA  |   24bit/1k  |
37684+ * Micron       |  MLC   |  MT29F64G08CxxAA  |   24bit/1k  |
37685+ * Micron       |  MLC   |  MT29F256G08CJAAA |   24bit/1k  |   2CE
37686+ * Micron       |  MLC   |  MT29F256G08CMCBB |   24bit/1k  |
37687+ * Micron       |  SLC   |  MT29F8G08ABACA   |   8bit/512  |
37688+ * Micron       |  SLC   |  MT29F4G08ABAEA   |   8bit/512  |
37689+ * Micron       |  SLC   |  MT29F2G08ABAFA   |   8bit/512  |
37690+ * Micron       |  SLC   |  MT29F16G08ABACA  |   8bit/512  |
37691+ * Toshiba      |  MLC   |  TC58NVG4D2FTA00  |   24bit/1k  |
37692+ * Toshiba      |  MLC   |  TH58NVG6D2FTA20  |   24bit/1k  |   2CE
37693+ * Toshiba      |  MLC   |  TC58NVG5D2HTA00  |   40bit/1k  |
37694+ * Toshiba      |  MLC   |  TC58NVG6D2GTA00  |   40bit/1k  |
37695+ * Toshiba      |  MLC   |  TC58NVG6DCJTA00  |             |
37696+ * Toshiba      |  MLC   |  TC58TEG5DCJTA00  |             |
37697+ * Toshiba      |  SLC   |  TC58NVG0S3HTA00  |   8bit/512  |
37698+ * Toshiba      |  SLC   |  TC58NVG1S3HTA00  |   8bit/512  |
37699+ * Toshiba      |  SLC   |  TC58NVG1S3ETA00  |   4bit/512  |
37700+ * Toshiba      |  SLC   |  TC58NVG3S0FTA00  |   4bit/512  |
37701+ * Toshiba      |  SLC   |  TC58NVG2S0FTA00  |   4bit/512  |
37702+ * Toshiba      |  SLC   |  TH58NVG2S3HTA00  |   4bit/512  |
37703+ * Toshiba      |  TLC   |  TC58NVG5T2JTA00  |   60bit/1k  |
37704+ * Toshiba      |  TLC   |  TC58TEG5DCKTAx0  |   60bit/1k  |
37705+ * Toshiba      |  MLC   |  Tx58TEGxDDKTAx0  |             |
37706+ * Samsung      |  MLC   |  K9LB(HC/PD/MD)G08U0(1)D  |   8bit/512B  |
37707+ * Samsung      |  MLC   |  K9GAG08U0E       |   24bit/1KB |
37708+ * Samsung      |  MLC   |  K9LBG08U0E       |   24bit/1KB |
37709+ * Samsung      |  MLC   |  K9G8G08U0C       |   24bit/1KB |
37710+ * Samsung      |  MLC   |  K9GAG08U0F       |   24bit/1KB |
37711+ * Samsung      |  MLC   |  K9LBG08U0M       |             |
37712+ * Samsung      |  MLC   |  K9GBG08U0A       |   24bit/1KB |
37713+ * Samsung      |  MLC   |  K9GBG08U0B       |   40bit/1KB |
37714+ * Hynix        |  MLC   |  H27UAG8T2A       |             |
37715+ * Hynix        |  MLC   |  H27UAG8T2B       |             |
37716+ * Hynix        |  MLC   |  H27UBG8T2A       |             |
37717+ * Hynix        |  MLC   |  H27UBG8T2BTR     |   24bit/1KB |
37718+ * Hynix        |  MLC   |  H27UCG8T2A       |   40bit/1KB |
37719+ * Hynix        |  MLC   |  H27UBG8T2C       |   40bit/1KB |
37720+ * MISC         |  MLC   |  P1UAGA30AT-GCA   |   8bit/512  |
37721+ * MISC         |  MLC   |  PSU8GA30AT-GIA/ASU8GA30IT-G30CA  |   4bit/512  |
37722+ * MISC         |  SLC   |  PSU2GA30AT       |   1bit/512  |   1.36
37723+ * Toshiba      |  SLC   |  TC58NVG2S0HTA00  |   24bit/1K  |   1.37
37724+ * Toshiba      |  SLC   |  TC58NVG3S0HTA00  |   24bit/1K  |   1.37
37725+ * Micron       |  SLC   |  MT29F2G08ABAEA   |   4bit/512 |
37726+ * Spansion     |  SLC   | S34ML02G200TFI000     | 24bit/1K |
37727+ * Spansion     |  SLC   | S34ML04G200TFI000     | 24bit/1K |  1.38
37728+ * MXIC Macronix|  SLC   | MX30UF2G18AC 1.8V | 4bit/512 |  1.39
37729+ * Spansion     |  SLC   | S34MS01G200TFI00 1.8V | 4bit/512 |  1.40
37730+ * Spansion     |  SLC   | S34MS02G200TFI00 1.8V | 24bit/1K |  1.40
37731+ * Spansion     |  SLC   | S34MS04G200TFI00 1.8V | 24bit/1K |  1.40
37732+ *
37733+ */
37734+static struct nand_flash_special_dev nand_flash_special_table[] = {
37735+
37736+	/************************* 1.8V MXIC Macronix **************************/
37737+	{       /* SLC 4bit/512 1.8V */
37738+		.name      = "MX30UF2G18AC",
37739+		.id        = {0xC2, 0xAA, 0x90, 0x15, 0x06},
37740+		.length    = 5,
37741+		.chipsize  = _256M,
37742+		.probe     = NULL,
37743+		.pagesize  = _2K,
37744+		.erasesize = _128K,
37745+		.oobsize   = 64,
37746+		.options   = 0,
37747+		.read_retry_type = NAND_RR_NONE,
37748+		.badblock_pos    = BBP_FIRST_PAGE,
37749+		.flags = 0,
37750+	},
37751+
37752+	/****************************** Spansion *******************************/
37753+
37754+	{      /* SLC S34ML02G200TFI000 */
37755+		.name      = "S34ML02G200TFI000",
37756+		.id        = {0x01, 0xDA, 0x90, 0x95, 0x46, 0x00, 0x00, 0x00},
37757+		.length    = 5,
37758+		.chipsize  = _256M,
37759+		.probe     = NULL,
37760+		.pagesize  = _2K,
37761+		.erasesize = _128K,
37762+		.oobsize   = 128,
37763+		.options   = 0,
37764+		.read_retry_type = NAND_RR_NONE,
37765+		.badblock_pos    = BBP_FIRST_PAGE,
37766+		.flags = 0,
37767+	},
37768+
37769+	{      /* SLC S34ML04G200TFI000 */
37770+		.name      = "S34ML04G200TFI000",
37771+		.id        = {0x01, 0xDC, 0x90, 0x95, 0x56, 0x00, 0x00, 0x00},
37772+		.length    = 5,
37773+		.chipsize  = _512M,
37774+		.probe     = NULL,
37775+		.pagesize  = _2K,
37776+		.erasesize = _128K,
37777+		.oobsize   = 128,
37778+		.options   = 0,
37779+		.read_retry_type = NAND_RR_NONE,
37780+		.badblock_pos    = BBP_FIRST_PAGE,
37781+		.flags = 0,
37782+	},
37783+
37784+	{      /* SLC S34MS02G200TFI00 1.8V */
37785+		.name      = "S34MS02G200TFI00",
37786+		.id        = {0x01, 0xAA, 0x90, 0x15, 0x46, 0x00, 0x00, 0x00},
37787+		.length    = 5,
37788+		.chipsize  = _256M,
37789+		.probe     = NULL,
37790+		.pagesize  = _2K,
37791+		.erasesize = _128K,
37792+		.oobsize   = 128,
37793+		.options   = 0,
37794+		.read_retry_type = NAND_RR_NONE,
37795+		.badblock_pos    = BBP_FIRST_PAGE,
37796+		.flags = 0,
37797+	},
37798+
37799+	{      /* SLC S34MS04G200TFI00 1.8V */
37800+		.name      = "S34MS04G200TFI00",
37801+		.id        = {0x01, 0xAC, 0x90, 0x15, 0x56, 0x00, 0x00, 0x00},
37802+		.length    = 5,
37803+		.chipsize  = _512M,
37804+		.probe     = NULL,
37805+		.pagesize  = _2K,
37806+		.erasesize = _128K,
37807+		.oobsize   = 128,
37808+		.options   = 0,
37809+		.read_retry_type = NAND_RR_NONE,
37810+		.badblock_pos    = BBP_FIRST_PAGE,
37811+		.flags = 0,
37812+	},
37813+
37814+	/****************************** Micron *******************************/
37815+
37816+	{        /* MLC 40bit/1k */
37817+		.name      = "MT29F64G08CBABA",
37818+		.id        = {0x2C, 0x64, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00},
37819+		.length    = 8,
37820+		.chipsize  = _8G,
37821+		.probe     = NULL,
37822+		.pagesize  = _8K,
37823+		.erasesize = _2M,
37824+		.oobsize   = 744,
37825+		.options   = 0,
37826+		.read_retry_type = NAND_RR_MICRON,
37827+		.badblock_pos    = BBP_FIRST_PAGE,
37828+		.flags = NAND_RANDOMIZER | NAND_CHIP_MICRON,
37829+	},
37830+	{        /* MLC 40bit/1k */
37831+		.name      = "MT29F32G08CBADA",
37832+		.id        = {0x2C, 0x44, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00},
37833+		.length    = 8,
37834+		.chipsize  = _4G,
37835+		.probe     = NULL,
37836+		.pagesize  = _8K,
37837+		.erasesize = _2M,
37838+		.oobsize   = 744,
37839+		.options   = 0,
37840+		.read_retry_type = NAND_RR_MICRON,
37841+		.badblock_pos    = BBP_FIRST_PAGE,
37842+		.flags = NAND_RANDOMIZER,
37843+	},
37844+	{        /* SLC 4bit/512 */
37845+		.name      = "MT29F8G08ABxBA",
37846+		.id        = {0x2C, 0x38, 0x00, 0x26, 0x85, 0x00, 0x00, 0x00},
37847+		.length    = 8,
37848+		.chipsize  = _1G,
37849+		.probe     = NULL,
37850+		.pagesize  = _4K,
37851+		.erasesize = _512K,
37852+		.oobsize   = 224,
37853+		.options   = 0,
37854+		.read_retry_type = NAND_RR_NONE,
37855+		.badblock_pos    = BBP_FIRST_PAGE,
37856+		.flags = 0,
37857+	},
37858+	{        /* MLC 12bit/512 */
37859+		.name      = "MT29F16G08CBABx",
37860+		.id        = {0x2C, 0x48, 0x04, 0x46, 0x85, 0x00, 0x00, 0x00},
37861+		.length    = 8,
37862+		.chipsize  = _2G,
37863+		.probe     = NULL,
37864+		.pagesize  = _4K,
37865+		.erasesize = _1M,
37866+		.oobsize   = 224,
37867+		.options   = 0,
37868+		.read_retry_type = NAND_RR_NONE,
37869+		.badblock_pos    = BBP_FIRST_PAGE,
37870+		.flags = 0,
37871+	},
37872+	{        /* MLC 24bit/1k */
37873+		.name      = "MT29F16G08CBACA",
37874+		.id        = {0x2C, 0x48, 0x04, 0x4A, 0xA5, 0x00, 0x00, 0x00},
37875+		.length    = 8,
37876+		.chipsize  = _2G,
37877+		.probe     = NULL,
37878+		.pagesize  = _4K,
37879+		.erasesize = _1M,
37880+		.oobsize   = 224,
37881+		.options   = 0,
37882+		.read_retry_type = NAND_RR_NONE,
37883+		.badblock_pos    = BBP_FIRST_PAGE,
37884+		.flags = 0,
37885+	},
37886+	{        /* MLC 24bit/1k */
37887+		.name      = "MT29F32G08CBACA",
37888+		.id        = {0x2C, 0x68, 0x04, 0x4A, 0xA9, 0x00, 0x00, 0x00},
37889+		.length    = 8,
37890+		.chipsize  = _4G,
37891+		.probe     = NULL,
37892+		.pagesize  = _4K,
37893+		.erasesize = _1M,
37894+		.oobsize   = 224,
37895+		.options   = 0,
37896+		.read_retry_type = NAND_RR_NONE,
37897+		.badblock_pos    = BBP_FIRST_PAGE,
37898+		.flags = 0,
37899+	},
37900+	{        /* MLC 24bit/1k */
37901+		.name      = "MT29F64G08CxxAA",
37902+		.id        = {0x2C, 0x88, 0x04, 0x4B, 0xA9, 0x00, 0x00, 0x00},
37903+		.length    = 8,
37904+		.chipsize  = _8G,
37905+		.probe     = NULL,
37906+		.pagesize  = _8K,
37907+		.erasesize = _2M,
37908+		.oobsize   = 448,
37909+		.options   = 0,
37910+		.read_retry_type = NAND_RR_NONE,
37911+		.badblock_pos    = BBP_FIRST_PAGE,
37912+		.flags = NAND_RANDOMIZER,
37913+	},
37914+	{        /* MLC 24bit/1k 2CE */
37915+		.name      = "MT29F256G08CJAAA",
37916+		.id        = {0x2C, 0xA8, 0x05, 0xCB, 0xA9, 0x00, 0x00, 0x00},
37917+		.length    = 8,
37918+		.chipsize  = _16G,
37919+		.probe     = NULL,
37920+		.pagesize  = _8K,
37921+		.erasesize = _2M,
37922+		.oobsize   = 448,
37923+		.options   = 0,
37924+		.read_retry_type = NAND_RR_NONE,
37925+		.badblock_pos    = BBP_FIRST_PAGE,
37926+		.flags = NAND_RANDOMIZER,
37927+	},
37928+	{        /* MLC 40bit/1k */
37929+		.name      = "MT29F256G08CMCBB",
37930+		.id        = {0x2C, 0x64, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00},
37931+		.length    = 8,
37932+		.chipsize  = _8G,
37933+		.probe     = NULL,
37934+		.pagesize  = _8K,
37935+		.erasesize = _2M,
37936+		.oobsize   = 744,
37937+		.options   = 0,
37938+		.read_retry_type = NAND_RR_NONE,
37939+		.badblock_pos    = BBP_FIRST_PAGE,
37940+		.flags = 0,
37941+	},
37942+	{        /* SLC 8bit/512 */
37943+		.name      = "MT29F8G08ABACA",
37944+		.id        = {0x2C, 0xD3, 0x90, 0xA6, 0x64, 0x00, 0x00, 0x00},
37945+		.length    = 5,
37946+		.chipsize  = _1G,
37947+		.probe     = NULL,
37948+		.pagesize  = _4K,
37949+		.erasesize = _256K,
37950+		.oobsize   = 224,
37951+		.options   = 0,
37952+		.read_retry_type = NAND_RR_NONE,
37953+		.badblock_pos    = BBP_FIRST_PAGE,
37954+		.flags = 0,
37955+	},
37956+	{        /* SLC 8bit/512 */
37957+		.name      = "MT29F4G08ABAEA",
37958+		.id        = {0x2C, 0xDC, 0x90, 0xA6, 0x54, 0x00, 0x00, 0x00},
37959+		.length    = 5,
37960+		.chipsize  = _512M,
37961+		.probe     = NULL,
37962+		.pagesize  = _4K,
37963+		.erasesize = _256K,
37964+		.oobsize   = 224,
37965+		.options   = 0,
37966+		.read_retry_type = NAND_RR_NONE,
37967+		.badblock_pos    = BBP_FIRST_PAGE,
37968+		.flags = 0,
37969+	},
37970+	{        /* SLC 8bit/512 */
37971+		.name      = "MT29F2G08ABAFA",
37972+		.id        = {0x2C, 0xDA, 0x90, 0x95, 0x04, 0x00, 0x00, 0x00},
37973+		.length    = 5,
37974+		.chipsize  = _256M,
37975+		.probe     = NULL,
37976+		.pagesize  = _2K,
37977+		.erasesize = _128K,
37978+		.oobsize   = 224,
37979+		.options   = 0,
37980+		.read_retry_type = NAND_RR_NONE,
37981+		.badblock_pos    = BBP_FIRST_PAGE,
37982+		.flags = 0,
37983+	},
37984+	{      /* SLC MT29F2G08ABAEA */
37985+		.name      = "MT29F2G08ABAEA",
37986+		.id        = {0x2C, 0xDA, 0x90, 0x95, 0x06, 0x00, 0x00, 0x00},
37987+		.length    = 5,
37988+		.chipsize  = _256M,
37989+		.probe     = NULL,
37990+		.pagesize  = _2K,
37991+		.erasesize = _128K,
37992+		.oobsize   = 64,
37993+		.options   = 0,
37994+		.read_retry_type = NAND_RR_NONE,
37995+		.badblock_pos    = BBP_FIRST_PAGE,
37996+		.flags = 0,
37997+	},
37998+	{        /* SLC 8bit/512 */
37999+		.name      = "MT29F16G08ABACA",
38000+		.id        = {0x2C, 0x48, 0x00, 0x26, 0xA9, 0x00, 0x00, 0x00},
38001+		.length    = 5,
38002+		.chipsize  = _2G,
38003+		.probe     = NULL,
38004+		.pagesize  = _4K,
38005+		.erasesize = _512K,
38006+		.oobsize   = 224,
38007+		.options   = 0,
38008+		.read_retry_type = NAND_RR_NONE,
38009+		.badblock_pos    = BBP_FIRST_PAGE,
38010+		.flags = 0,
38011+	},
38012+
38013+	/****************************** Toshaba *******************************/
38014+
38015+	{       /* MLC 24bit/1k 32nm */
38016+		.name      = "TC58NVG4D2FTA00",
38017+		.id        = {0x98, 0xD5, 0x94, 0x32, 0x76, 0x55, 0x00, 0x00},
38018+		.length    = 6,
38019+		.chipsize  = _2G,
38020+		.probe     = NULL,
38021+		.pagesize  = _8K,
38022+		.erasesize = _1M,
38023+		.oobsize   = 448,
38024+		.options   = 0,
38025+		.read_retry_type = NAND_RR_NONE,
38026+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38027+		.flags = 0,
38028+	},
38029+	{       /* MLC 24bit/1k 32nm 2CE */
38030+		.name      = "TH58NVG6D2FTA20",
38031+		.id        = {0x98, 0xD7, 0x94, 0x32, 0x76, 0x55, 0x00, 0x00},
38032+		.length    = 6,
38033+		.chipsize  = _4G,
38034+		.probe     = NULL,
38035+		.pagesize  = _8K,
38036+		.erasesize = _1M,
38037+		.oobsize   = 448,
38038+		.options   = 0,
38039+		.read_retry_type = NAND_RR_NONE,
38040+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38041+		.flags = 0,
38042+	},
38043+	{       /* MLC 40bit/1k 24nm */
38044+		.name      = "TC58NVG5D2HTA00 24nm",
38045+		.id        = {0x98, 0xD7, 0x94, 0x32, 0x76, 0x56, 0x08, 0x00},
38046+		.length    = 6,
38047+		.chipsize  = _4G,
38048+		.probe     = NULL,
38049+		.pagesize  = _8K,
38050+		.erasesize = _1M,
38051+		.oobsize   = 640,
38052+		.options   = 0,
38053+		.read_retry_type = NAND_RR_TOSHIBA_24nm,
38054+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38055+		.flags = NAND_RANDOMIZER,
38056+	},
38057+	{       /* MLC 40bit/1k */
38058+		.name      = "TC58NVG6D2GTA00",
38059+		.id        = {0x98, 0xDE, 0x94, 0x82, 0x76, 0x00, 0x00, 0x00},
38060+		.length    = 5,
38061+		.chipsize  = _8G,
38062+		.probe     = NULL,
38063+		.pagesize  = _8K,
38064+		.erasesize = _2M,
38065+		.oobsize   = 640,
38066+		.options   = 0,
38067+		.read_retry_type = NAND_RR_NONE,
38068+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38069+		.flags = 0,
38070+	},
38071+	{       /* MLC 19nm */
38072+		.name      = "TC58NVG6DCJTA00 19nm",
38073+		.id        = {0x98, 0xDE, 0x84, 0x93, 0x72, 0x57, 0x08, 0x04},
38074+		.length    = 8,
38075+		.chipsize  = _8G,
38076+		.probe     = NULL,
38077+		.pagesize  = _16K,
38078+		.erasesize = _4M,
38079+		.oobsize   = 1280,
38080+		.options   = 0,
38081+		.read_retry_type = NAND_RR_TOSHIBA_24nm,
38082+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38083+		.flags = NAND_RANDOMIZER,
38084+	},
38085+	{       /* MLC 19nm */
38086+		.name      = "TC58TEG5DCJTA00 19nm",
38087+		.id        = {0x98, 0xD7, 0x84, 0x93, 0x72, 0x57, 0x08, 0x04},
38088+		.length    = 6,
38089+		.chipsize  = _4G,
38090+		.probe     = NULL,
38091+		.pagesize  = _16K,
38092+		.erasesize = _4M,
38093+		.oobsize   = 1280,
38094+		.options   = 0,
38095+		.read_retry_type = NAND_RR_TOSHIBA_24nm,
38096+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38097+		.flags = NAND_RANDOMIZER | NAND_CHIP_TOSHIBA_TOGGLE_10,
38098+	},
38099+	{       /* SLC 8bit/512 */
38100+		.name      = "TC58NVG0S3HTA00",
38101+		.id        = {0x98, 0xF1, 0x80, 0x15, 0x72, 0x00, 0x00, 0x00},
38102+		.length    = 5,
38103+		.chipsize  = _128M,
38104+		.probe     = NULL,
38105+		.pagesize  = _2K,
38106+		.erasesize = _128K,
38107+		.oobsize   = 128,
38108+		.options   = 0,
38109+		.read_retry_type = NAND_RR_NONE,
38110+		/*
38111+		 * Datasheet: read one column of any page in each block. If the
38112+		 * data of the column is 00 (Hex), define the block as a bad
38113+		 * block.
38114+		 */
38115+		.badblock_pos    = BBP_FIRST_PAGE,
38116+		.flags = 0,
38117+	},
38118+	{       /* SLC 8bit/512 */
38119+		.name      = "TC58NVG1S3HTA00",
38120+		.id        = {0x98, 0xDA, 0x90, 0x15, 0x76, 0x16, 0x08, 0x00},
38121+		.length    = 7,
38122+		.chipsize  = _256M,
38123+		.probe     = NULL,
38124+		.pagesize  = _2K,
38125+		.erasesize = _128K,
38126+		.oobsize   = 128,
38127+		.options   = 0,
38128+		.read_retry_type = NAND_RR_NONE,
38129+		.badblock_pos    = BBP_FIRST_PAGE,
38130+		.flags = 0,
38131+	},
38132+	{       /* SLC 4bit/512 */
38133+		.name      = "TC58NVG1S3ETA00",
38134+		.id        = {0x98, 0xDA, 0x90, 0x15, 0x76, 0x14, 0x03, 0x00},
38135+		.length    = 7,
38136+		.chipsize  = _256M,
38137+		.probe     = NULL,
38138+		.pagesize  = _2K,
38139+		.erasesize = _128K,
38140+		.oobsize   = 64,
38141+		.options   = 0,
38142+		.read_retry_type = NAND_RR_NONE,
38143+		.badblock_pos    = BBP_FIRST_PAGE,
38144+		.flags = 0,
38145+	},
38146+	{       /* SLC 4bit/512 */
38147+		.name      = "TC58NVG3S0FTA00",
38148+		.id        = {0x98, 0xD3, 0x90, 0x26, 0x76, 0x15, 0x02, 0x08},
38149+		.length    = 8,
38150+		.chipsize  = _1G,
38151+		.probe     = NULL,
38152+		.pagesize  = _4K,
38153+		.erasesize = _256K,
38154+		.oobsize   = 232,
38155+		.options   = 0,
38156+		.read_retry_type = NAND_RR_NONE,
38157+		.badblock_pos    = BBP_FIRST_PAGE,
38158+		.flags = 0,
38159+	},
38160+	{       /* SLC 24bit/1k */
38161+		.name      = "TC58NVG3S0HTA00",
38162+		.id        = {0x98, 0xD3, 0x91, 0x26, 0x76, 0x16, 0x08, 0x00},
38163+		.length    = 8,
38164+		.chipsize  = _1G,
38165+		.probe     = NULL,
38166+		.pagesize  = _4K,
38167+		.erasesize = _256K,
38168+		.oobsize   = 256,
38169+		.options   = 0,
38170+		.read_retry_type = NAND_RR_NONE,
38171+		.badblock_pos    = BBP_FIRST_PAGE,
38172+		.flags = 0,
38173+	},
38174+	{       /* SLC 24bit/1k */
38175+		.name      = "TC58NVG2S0HTA00",
38176+		.id        = {0x98, 0xDC, 0x90, 0x26, 0x76, 0x16, 0x08, 0x00},
38177+		.length    = 8,
38178+		.chipsize  = _512M,
38179+		.probe     = NULL,
38180+		.pagesize  = _4K,
38181+		.erasesize = _256K,
38182+		.oobsize   = 256,
38183+		.options   = 0,
38184+		.read_retry_type = NAND_RR_NONE,
38185+		.badblock_pos    = BBP_FIRST_PAGE,
38186+		.flags = 0,
38187+	},
38188+	{       /* SLC 4bit/512 */
38189+		.name      = "TC58NVG2S0FTA00",
38190+		.id        = {0x98, 0xDC, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08},
38191+		.length    = 8,
38192+		.chipsize  = _512M,
38193+		.probe     = NULL,
38194+		.pagesize  = _4K,
38195+		.erasesize = _256K,
38196+		.oobsize   = 224,
38197+		.options   = 0,
38198+		.read_retry_type = NAND_RR_NONE,
38199+		.badblock_pos    = BBP_FIRST_PAGE,
38200+		.flags = 0,
38201+	},
38202+	{       /* SLC 4bit/512 */
38203+		.name      = "TH58NVG2S3HTA00",
38204+		.id        = {0x98, 0xDC, 0x91, 0x15, 0x76},
38205+		.length    = 5,
38206+		.chipsize  = _512M,
38207+		.probe     = NULL,
38208+		.pagesize  = _2K,
38209+		.erasesize = _128K,
38210+		.oobsize   = 128,
38211+		.options   = 0,
38212+		.read_retry_type = NAND_RR_NONE,
38213+		.badblock_pos    = BBP_FIRST_PAGE,
38214+		.flags = 0,
38215+	},
38216+	{       /* TLC 60bit/1k 19nm */
38217+		.name      = "TC58NVG5T2JTA00 19nm TLC",
38218+		/* datasheet says 6 ids id data, but really has 8 ids. */
38219+		.id        = {0x98, 0xD7, 0x98, 0x92, 0x72, 0x57, 0x08, 0x10},
38220+		.length    = 6,
38221+		.chipsize  = _4G,
38222+		.probe     = NULL,
38223+		.pagesize  = _8K,
38224+		.erasesize = _4M,
38225+		.oobsize   = 1024,
38226+		.options   = 0,
38227+		.read_retry_type = NAND_RR_TOSHIBA_24nm,
38228+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38229+		.flags = NAND_RANDOMIZER,
38230+	},
38231+	{ /* TLC 60bit/1k 19nm */
38232+		.name      = "TC58TEG5DCKTAx0 19nm MLC",
38233+		/* datasheet says 6 ids id data, but really has 8 ids. */
38234+		.id    = {0x98, 0xD7, 0x84, 0x93, 0x72, 0x50, 0x08, 0x04},
38235+		.length    = 6,
38236+		.chipsize  = _4G,
38237+		.probe     = NULL,
38238+		.pagesize  = _16K,
38239+		.erasesize = _4M,
38240+		.oobsize   = 1280,
38241+		.options   = 0,
38242+		.read_retry_type = NAND_RR_TOSHIBA_19nm,
38243+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38244+		.flags = NAND_RANDOMIZER,
38245+	},
38246+	{
38247+		.name      = "Tx58TEGxDDKTAx0 19nm MLC",
38248+		.id    = {0x98, 0xDE, 0x94, 0x93, 0x76, 0x50},
38249+		.length    = 6,
38250+		.chipsize  = _4G,
38251+		.probe     = NULL,
38252+		.pagesize  = _16K,
38253+		.erasesize = _4M,
38254+		.oobsize   = 1280,
38255+		.options   = 0,
38256+		.read_retry_type = NAND_RR_TOSHIBA_19nm,
38257+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38258+		.flags = NAND_RANDOMIZER,
38259+	},
38260+	/******************************* Samsung ******************************/
38261+	{       /* MLC 8bit/512B */
38262+		.name     = "K9LB(HC/PD/MD)G08U0(1)D",
38263+		.id       = {0xEC, 0xD7, 0xD5, 0x29, 0x38, 0x41, 0x00, 0x00},
38264+		.length   = 6,
38265+		.chipsize = _4G,
38266+		.probe    = samsung_probe_v02,
38267+		.read_retry_type = NAND_RR_NONE,
38268+		.badblock_pos    = BBP_LAST_PAGE,
38269+		.flags = 0,
38270+	},
38271+	{       /* MLC 24bit/1KB */
38272+		.name      = "K9GAG08U0E",
38273+		.id        = {0xEC, 0xD5, 0x84, 0x72, 0x50, 0x42, 0x00, 0x00},
38274+		.length    = 6,
38275+		.chipsize  = _2G,
38276+		.probe     = samsung_probe_v02,
38277+		.read_retry_type = NAND_RR_NONE,
38278+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38279+		.flags = 0,
38280+	},
38281+	{       /* MLC 24bit/1KB */
38282+		.name     = "K9LBG08U0E",
38283+		.id       = {0xEC, 0xD7, 0xC5, 0x72, 0x54, 0x42, 0x00, 0x00},
38284+		.length   = 6,
38285+		.chipsize = _4G,
38286+		.probe    = samsung_probe_v02,
38287+		.read_retry_type = NAND_RR_NONE,
38288+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38289+		.flags = 0,
38290+	},
38291+	{       /* MLC 24bit/1KB */
38292+		.name     = "K9G8G08U0C",
38293+		.id       = {0xEC, 0xD3, 0x84, 0x72, 0x50, 0x42, 0x00, 0x00},
38294+		.length   = 6,
38295+		.chipsize = _1G,
38296+		.probe    = samsung_probe_v02,
38297+		.read_retry_type = NAND_RR_NONE,
38298+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38299+		.flags = 0,
38300+	},
38301+	{        /* MLC 24bit/1k */
38302+		.name      = "K9GAG08U0F",
38303+		.id        = {0xEC, 0xD5, 0x94, 0x76, 0x54, 0x43, 0x00, 0x00},
38304+		.length    = 6,
38305+		.chipsize  = _2G,
38306+		.probe     = NULL,
38307+		.pagesize  = _8K,
38308+		.erasesize = _1M,
38309+		.oobsize   = 512,
38310+		.options   = 0,
38311+		.read_retry_type = NAND_RR_NONE,
38312+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38313+		.flags = 0,
38314+	},
38315+	{        /* MLC */
38316+		.name      = "K9LBG08U0M",
38317+		.id        = {0xEC, 0xD7, 0x55, 0xB6, 0x78, 0x00, 0x00, 0x00},
38318+		.length    = 5,
38319+		.chipsize  = _4G,
38320+		.probe     = NULL,
38321+		.pagesize  = _4K,
38322+		.erasesize = _512K,
38323+		.oobsize   = 128,
38324+		.options   = 0,
38325+		.read_retry_type = NAND_RR_NONE,
38326+		.badblock_pos    = BBP_LAST_PAGE,
38327+		.flags = 0,
38328+	},
38329+	{        /* MLC 24bit/1k */
38330+		.name      = "K9GBG08U0A 20nm",
38331+		.id        = {0xEC, 0xD7, 0x94, 0x7A, 0x54, 0x43, 0x00, 0x00},
38332+		.length    = 6,
38333+		.chipsize  = _4G,
38334+		.probe     = NULL,
38335+		.pagesize  = _8K,
38336+		.erasesize = _1M,
38337+		.oobsize   = 640,
38338+		.options   = 0,
38339+		.read_retry_type = NAND_RR_SAMSUNG,
38340+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38341+		.flags = NAND_RANDOMIZER,
38342+	},
38343+	{        /* MLC 40bit/1k */
38344+		.name      = "K9GBG08U0B",
38345+		.id        = {0xEC, 0xD7, 0x94, 0x7E, 0x64, 0x44, 0x00, 0x00},
38346+		.length    = 6,
38347+		.chipsize  = _4G,
38348+		.probe     = NULL,
38349+		.pagesize  = _8K,
38350+		.erasesize = _1M,
38351+		.oobsize   = 1024,
38352+		.options   = 0,
38353+		.read_retry_type = NAND_RR_SAMSUNG,
38354+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38355+		.flags = NAND_RANDOMIZER,
38356+	},
38357+
38358+	/*********************************** Hynix ****************************/
38359+	{       /* MLC */
38360+		.name     = "H27UAG8T2A",
38361+		.id       = { 0xAD, 0xD5, 0x94, 0x25, 0x44, 0x41, },
38362+		.length   = 6,
38363+		.chipsize = _2G,
38364+		.probe    = hynix_probe_v02,
38365+		.read_retry_type = NAND_RR_NONE,
38366+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38367+		.flags = 0,
38368+	},
38369+	{       /* MLC */
38370+		.name     = "H27UAG8T2B",
38371+		.id       = { 0xAD, 0xD5, 0x94, 0x9A, 0x74, 0x42, },
38372+		.length   = 6,
38373+		.chipsize = _2G,
38374+		.probe    = hynix_probe_v02,
38375+		.read_retry_type = NAND_RR_NONE,
38376+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38377+		.flags = 0,
38378+	},
38379+	{       /* MLC */
38380+		.name     = "H27UBG8T2A",
38381+		.id       = { 0xAD, 0xD7, 0x94, 0x9A, 0x74, 0x42, },
38382+		.length   = 6,
38383+		.chipsize = _4G,
38384+		.probe    = hynix_probe_v02,
38385+		.read_retry_type = NAND_RR_NONE,
38386+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38387+		.flags = 0,
38388+	},
38389+	{
38390+		.name      = "H27UBG8T2BTR 26nm",
38391+		.id        = { 0xAD, 0xD7, 0x94, 0xDA, 0x74, 0xC3, },
38392+		.length    = 6,
38393+		.chipsize  = _4G,
38394+		.probe     = NULL,
38395+		.pagesize  = _8K,
38396+		.erasesize = _2M,
38397+		.oobsize   = 640,
38398+		.options   = 0,
38399+		.read_retry_type = NAND_RR_HYNIX_BG_BDIE,
38400+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38401+		.flags = NAND_RANDOMIZER,
38402+	},
38403+	{        /* MLC 40bit/1k */
38404+		.name      = "H27UCG8T2A",
38405+		.id        = { 0xAD, 0xDE, 0x94, 0xDA, 0x74, 0xC4, },
38406+		.length    = 6,
38407+		.chipsize  = _8G,
38408+		.probe     = NULL,
38409+		.pagesize  = _8K,
38410+		.erasesize = _2M,
38411+		.oobsize   = 640,
38412+		.options   = 0,
38413+		.read_retry_type = NAND_RR_HYNIX_CG_ADIE,
38414+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38415+		.flags = NAND_RANDOMIZER,
38416+	},
38417+	{        /* MLC 40bit/1k */
38418+		.name      = "H27UBG8T2C",
38419+		.id        = { 0xAD, 0xD7, 0x94, 0x91, 0x60, 0x44, },
38420+		.length    = 6,
38421+		.chipsize  = _4G,
38422+		.probe     = NULL,
38423+		.pagesize  = _8K,
38424+		.erasesize = _2M,
38425+		.oobsize   = 640,
38426+		.options   = 0,
38427+		.read_retry_type = NAND_RR_HYNIX_BG_CDIE,
38428+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38429+		.flags = NAND_RANDOMIZER,
38430+	},
38431+
38432+	/********************** MISC ******************************************/
38433+	{        /* MLC 8bit/512 */
38434+		.name      = "P1UAGA30AT-GCA",
38435+		.id        = { 0xC8, 0xD5, 0x14, 0x29, 0x34, 0x01, },
38436+		.length    = 6,
38437+		.chipsize  = _2G,
38438+		.probe     = NULL,
38439+		.pagesize  = _4K,
38440+		.erasesize = _512K,
38441+		.oobsize   = 218,
38442+		.options   = 0,
38443+		.read_retry_type = NAND_RR_NONE,
38444+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38445+		.flags = 0,
38446+	},
38447+	{       /* MLC 4bit/512 */
38448+		/*
38449+		 * PowerFlash ASU8GA30IT-G30CA ID and MIRA PSU8GA30AT-GIA ID are
38450+		 * the same ID
38451+		 */
38452+		.name      = "PSU8GA30AT-GIA/ASU8GA30IT-G30CA",
38453+		.id        = { 0xC8, 0xD3, 0x90, 0x19, 0x34, 0x01, },
38454+		.length    = 6,
38455+		.chipsize  = _1G,
38456+		.probe     = NULL,
38457+		.pagesize  = _4K,
38458+		.erasesize = _256K,
38459+		.oobsize   = 218,
38460+		.options   = 0,
38461+		.read_retry_type = NAND_RR_NONE,
38462+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38463+		.flags = 0,
38464+	},
38465+	{        /* SLC 1bit/512 */
38466+		.name      = "PSU2GA30AT",
38467+		.id        = { 0x7F, 0x7F, 0x7F, 0x7F, 0xC8, 0xDA, 0x00, 0x15, },
38468+		.length    = 8,
38469+		.chipsize  = _256M,
38470+		.probe     = NULL,
38471+		.pagesize  = _2K,
38472+		.erasesize = _128K,
38473+		.oobsize   = 64,
38474+		.options   = 0,
38475+		.read_retry_type = NAND_RR_NONE,
38476+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
38477+		.flags = 0,
38478+	},
38479+	{{0}, 0, 0, 0, 0, 0, 0, 0, 0},
38480+};
38481+
38482+struct nand_dev_t g_nand_dev;
38483+
38484+struct nand_flash_dev *hifmc_get_spl_flash_type(struct mtd_info *mtd,
38485+		unsigned char *id)
38486+{
38487+	struct nand_chip *chip = mtd_to_nand(mtd);
38488+	struct nand_flash_special_dev *spl_dev = nand_flash_special_table;
38489+	struct nand_flash_dev *type = &g_nand_dev.flash_dev;
38490+	struct nand_dev_t *nand_dev = &g_nand_dev;
38491+
38492+	FMC_PR(BT_DBG, "\t *-Start find special nand flash\n");
38493+
38494+	pr_info("Nand ID: %#X %#X %#X %#X %#X %#X %#X %#X\n", id[0], id[1],
38495+		id[2], id[3], id[4], id[5], id[6], id[7]);
38496+
38497+	for (; spl_dev->length; spl_dev++) {
38498+		if (!access_ok(VERIFY_READ, id, spl_dev->length)) {
38499+			pr_info("err: access_ok verify fail\n");
38500+			return NULL;
38501+		}
38502+		if (memcmp(id, spl_dev->id, spl_dev->length)) {
38503+			continue;
38504+		}
38505+
38506+		FMC_PR(BT_DBG, "\t |-Found special Nand flash: %s\n",
38507+		       spl_dev->name);
38508+
38509+		if (spl_dev->probe) {
38510+			type = spl_dev->probe(id);
38511+		} else {
38512+			type->options   = spl_dev->options;
38513+			type->pagesize  = spl_dev->pagesize;
38514+			type->erasesize = spl_dev->erasesize;
38515+			type->oobsize = spl_dev->oobsize;
38516+		}
38517+
38518+		type->name = spl_dev->name;
38519+		type->id_len = spl_dev->length;
38520+		memcpy(type->id, id, type->id_len);
38521+		type->chipsize = (unsigned int)(spl_dev->chipsize >> 20);
38522+		FMC_PR(BT_DBG, "\t |-Save struct nand_flash_dev info\n");
38523+
38524+		memcpy(nand_dev->ids, id, MAX_NAND_ID_LEN);
38525+		nand_dev->oobsize = type->oobsize;
38526+		nand_dev->flags = spl_dev->flags;
38527+		nand_dev->read_retry_type = spl_dev->read_retry_type;
38528+		FMC_PR(BT_DBG, "\t |-Save struct nand_dev_t information\n");
38529+
38530+		mtd->oobsize = spl_dev->oobsize;
38531+		mtd->erasesize = spl_dev->erasesize;
38532+		mtd->writesize = spl_dev->pagesize;
38533+		chip->chipsize = spl_dev->chipsize;
38534+		mtd->size = spl_dev->chipsize;
38535+
38536+		return type;
38537+	}
38538+	nand_dev->read_retry_type = NAND_RR_NONE;
38539+
38540+	chip->cmdfunc(mtd, NAND_CMD_READID, 0x00, -1);
38541+	chip->read_byte(mtd);
38542+	chip->read_byte(mtd);
38543+
38544+	FMC_PR(BT_DBG, "\t *-Not found special nand flash\n");
38545+
38546+	return NULL;
38547+}
38548+
38549+
38550+void hifmc_spl_ids_register(void)
38551+{
38552+	pr_info("Special NAND id table Version %s\n", DRV_VERSION);
38553+	get_spi_nand_flash_type_hook = hifmc_get_spl_flash_type;
38554+}
38555diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile
38556index 2930f5b90..7817ec61d 100644
38557--- a/drivers/mtd/nand/raw/Makefile
38558+++ b/drivers/mtd/nand/raw/Makefile
38559@@ -59,7 +59,7 @@ obj-$(CONFIG_MTD_NAND_MESON)		+= meson_nand.o
38560 obj-$(CONFIG_MTD_NAND_CADENCE)		+= cadence-nand-controller.o
38561 obj-$(CONFIG_MTD_NAND_ARASAN)		+= arasan-nand-controller.o
38562
38563-nand-objs := nand_base.o nand_legacy.o nand_bbt.o nand_timings.o nand_ids.o
38564+nand-objs := nand_base.o nand_bbt.o nand_timings.o nand_ids.o hinfc_gen.o hinfc_spl_ids.o match_table.o
38565 nand-objs += nand_onfi.o
38566 nand-objs += nand_jedec.o
38567 nand-objs += nand_amd.o
38568diff --git a/drivers/mtd/nand/raw/hinfc_gen.c b/drivers/mtd/nand/raw/hinfc_gen.c
38569new file mode 100644
38570index 000000000..127edd6b4
38571--- /dev/null
38572+++ b/drivers/mtd/nand/raw/hinfc_gen.c
38573@@ -0,0 +1,237 @@
38574+/*
38575+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
38576+ *
38577+ * This program is free software; you can redistribute  it and/or modify it
38578+ * under  the terms of  the GNU General  Public License as published by the
38579+ * Free Software Foundation;  either version 2 of the  License, or (at your
38580+ * option) any later version.
38581+ *
38582+ * This program is distributed in the hope that it will be useful,
38583+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
38584+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38585+ * GNU General Public License for more details.
38586+ *
38587+ * You should have received a copy of the GNU General Public License
38588+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
38589+ *
38590+ */
38591+
38592+#include <linux/mfd/hisi_fmc.h>
38593+#include "match_table.h"
38594+#include "hinfc_gen.h"
38595+
38596+struct nand_flash_dev *(*get_spi_nand_flash_type_hook)(struct mtd_info *mtd,
38597+		unsigned char *id) = NULL;
38598+
38599+static struct match_t match_ecc[] = {
38600+	MATCH_SET_TYPE_DATA(NAND_ECC_NONE, "none"),
38601+	MATCH_SET_TYPE_DATA(NAND_ECC_0BIT, "none"),
38602+	MATCH_SET_TYPE_DATA(NAND_ECC_1BIT_512, "1bit/512"),
38603+	MATCH_SET_TYPE_DATA(NAND_ECC_4BIT, "4bit/512"),
38604+	MATCH_SET_TYPE_DATA(NAND_ECC_4BIT_512, "4bit/512"),
38605+	MATCH_SET_TYPE_DATA(NAND_ECC_4BYTE, "4byte/1k"),
38606+	MATCH_SET_TYPE_DATA(NAND_ECC_8BIT, "4bit/512"),
38607+	MATCH_SET_TYPE_DATA(NAND_ECC_8BIT_512, "8bit/512"),
38608+	MATCH_SET_TYPE_DATA(NAND_ECC_8BYTE, "8byte/1k"),
38609+	MATCH_SET_TYPE_DATA(NAND_ECC_13BIT, "13bit/1k"),
38610+	MATCH_SET_TYPE_DATA(NAND_ECC_16BIT, "8bit/512"),
38611+	MATCH_SET_TYPE_DATA(NAND_ECC_18BIT, "18bit/1k"),
38612+	MATCH_SET_TYPE_DATA(NAND_ECC_24BIT, "24bit/1k"),
38613+	MATCH_SET_TYPE_DATA(NAND_ECC_27BIT, "27bit/1k"),
38614+	MATCH_SET_TYPE_DATA(NAND_ECC_32BIT, "32bit/1k"),
38615+	MATCH_SET_TYPE_DATA(NAND_ECC_40BIT, "40bit/1k"),
38616+	MATCH_SET_TYPE_DATA(NAND_ECC_41BIT, "41bit/1k"),
38617+	MATCH_SET_TYPE_DATA(NAND_ECC_48BIT, "48bit/1k"),
38618+	MATCH_SET_TYPE_DATA(NAND_ECC_60BIT, "60bit/1k"),
38619+	MATCH_SET_TYPE_DATA(NAND_ECC_72BIT, "72bit/1k"),
38620+	MATCH_SET_TYPE_DATA(NAND_ECC_80BIT, "80bit/1k"),
38621+};
38622+
38623+const char *nand_ecc_name(int type)
38624+{
38625+	return (char *)match_type_to_data(match_ecc, ARRAY_SIZE(match_ecc),
38626+					  type, "unknown");
38627+}
38628+
38629+char *get_ecctype_str(enum ecc_type ecctype)
38630+{
38631+	static char *ecctype_string[] = {
38632+		"None", "1bit/512Byte", "4bits/512Byte", "8bits/512Byte",
38633+		"24bits/1K", "40bits/1K", "unknown", "unknown"
38634+	};
38635+	return ecctype_string[(ecctype & 0x07)];
38636+}
38637+
38638+static struct match_type_str page2name[] = {
38639+	{ NAND_PAGE_512B, "512" },
38640+	{ NAND_PAGE_2K,   "2K" },
38641+	{ NAND_PAGE_4K,   "4K" },
38642+	{ NAND_PAGE_8K,   "8K" },
38643+	{ NAND_PAGE_16K,  "16K" },
38644+	{ NAND_PAGE_32K,  "32K" },
38645+};
38646+
38647+const char *nand_page_name(int type)
38648+{
38649+	return type2str(page2name, ARRAY_SIZE(page2name), type, "unknown");
38650+}
38651+
38652+char *get_pagesize_str(enum page_type pagetype)
38653+{
38654+	static char *pagesize_str[] = {
38655+		"512", "2K", "4K", "8K", "16K", "unknown",
38656+		"unknown", "unknown"
38657+	};
38658+	return pagesize_str[(pagetype & 0x07)];
38659+}
38660+
38661+static struct match_reg_type page2size[] = {
38662+	{ _512B, NAND_PAGE_512B },
38663+	{ _2K, NAND_PAGE_2K },
38664+	{ _4K, NAND_PAGE_4K },
38665+	{ _8K, NAND_PAGE_8K },
38666+	{ _16K, NAND_PAGE_16K },
38667+	{ _32K, NAND_PAGE_32K },
38668+};
38669+
38670+unsigned int get_pagesize(enum page_type pagetype)
38671+{
38672+	unsigned int pagesize[] = {
38673+		_512B, _2K, _4K, _8K, _16K, 0, 0, 0
38674+	};
38675+	return pagesize[(pagetype & 0x07)];
38676+}
38677+
38678+int nandpage_size2type(int size)
38679+{
38680+	return reg2type(page2size, ARRAY_SIZE(page2size), size, NAND_PAGE_2K);
38681+}
38682+
38683+int nandpage_type2size(int size)
38684+{
38685+	return type2reg(page2size, ARRAY_SIZE(page2size), size, NAND_PAGE_2K);
38686+}
38687+
38688+char *nand_dbgfs_options;
38689+
38690+static int __init dbgfs_options_setup(char *s)
38691+{
38692+	nand_dbgfs_options = s;
38693+	return 1;
38694+}
38695+__setup("nanddbgfs=", dbgfs_options_setup);
38696+
38697+int get_bits(unsigned int n)
38698+{
38699+	int loop;
38700+	int ret = 0;
38701+
38702+	if (!n)
38703+		return 0;
38704+
38705+	if (n > 0xFFFF)
38706+		loop = n > 0xFFFFFF ? 32 : 24;
38707+	else
38708+		loop = n > 0xFF ? 16 : 8;
38709+
38710+	while (loop-- > 0 && n) {
38711+		if (n & 1)
38712+			ret++;
38713+		n >>= 1;
38714+	}
38715+	return ret;
38716+}
38717+
38718+#define et_ecc_none	0x00
38719+#define et_ecc_4bit	0x02
38720+#define et_ecc_8bit	0x03
38721+#define et_ecc_24bit1k	0x04
38722+#define et_ecc_40bit1k	0x05
38723+#define et_ecc_64bit1k	0x06
38724+
38725+static struct match_reg_type ecc_yaffs_type_t[] = {
38726+	{et_ecc_none,		NAND_ECC_0BIT},
38727+	{et_ecc_4bit,		NAND_ECC_8BIT},
38728+	{et_ecc_8bit,		NAND_ECC_16BIT},
38729+	{et_ecc_24bit1k,	NAND_ECC_24BIT},
38730+	{et_ecc_40bit1k,	NAND_ECC_40BIT},
38731+	{et_ecc_64bit1k,	NAND_ECC_64BIT}
38732+};
38733+
38734+unsigned char match_ecc_type_to_yaffs(unsigned char type)
38735+{
38736+	return type2reg(ecc_yaffs_type_t, ARRAY_SIZE(ecc_yaffs_type_t), type,
38737+			et_ecc_4bit);
38738+}
38739+
38740+static struct match_t page_table[] = {
38741+	{NAND_PAGE_2K,	PAGE_SIZE_2KB,	"2K"},
38742+	{NAND_PAGE_4K,	PAGE_SIZE_4KB,	"4K"},
38743+	{NAND_PAGE_8K,	PAGE_SIZE_8KB,	"8K"},
38744+	{NAND_PAGE_16K,	PAGE_SIZE_16KB,	"16K"},
38745+};
38746+
38747+unsigned char match_page_reg_to_type(unsigned char reg)
38748+{
38749+	return match_reg_to_type(page_table, ARRAY_SIZE(page_table), reg,
38750+				 NAND_PAGE_2K);
38751+}
38752+
38753+unsigned char match_page_type_to_reg(unsigned char type)
38754+{
38755+	return match_type_to_reg(page_table, ARRAY_SIZE(page_table), type,
38756+				 PAGE_SIZE_2KB);
38757+}
38758+
38759+const char *match_page_type_to_str(unsigned char type)
38760+{
38761+	return match_type_to_data(page_table, ARRAY_SIZE(page_table), type,
38762+				  "unknown");
38763+}
38764+
38765+static struct match_t ecc_table[] = {
38766+	{NAND_ECC_0BIT,		ECC_TYPE_0BIT,	"none"},
38767+	{NAND_ECC_8BIT,		ECC_TYPE_8BIT,	"4bit/512"},
38768+	{NAND_ECC_16BIT,	ECC_TYPE_16BIT,	"8bit/512"},
38769+	{NAND_ECC_24BIT,	ECC_TYPE_24BIT,	"24bit/1K"},
38770+	{NAND_ECC_28BIT,	ECC_TYPE_28BIT,	"28bit/1K"},
38771+	{NAND_ECC_40BIT,	ECC_TYPE_40BIT,	"40bit/1K"},
38772+	{NAND_ECC_64BIT,	ECC_TYPE_64BIT,	"64bit/1K"},
38773+};
38774+
38775+unsigned char match_ecc_reg_to_type(unsigned char reg)
38776+{
38777+	return match_reg_to_type(ecc_table, ARRAY_SIZE(ecc_table), reg,
38778+				 NAND_ECC_8BIT);
38779+}
38780+
38781+unsigned char match_ecc_type_to_reg(unsigned char type)
38782+{
38783+	return match_type_to_reg(ecc_table, ARRAY_SIZE(ecc_table), type,
38784+				 ECC_TYPE_8BIT);
38785+}
38786+
38787+const char *match_ecc_type_to_str(unsigned char type)
38788+{
38789+	return match_type_to_data(ecc_table, ARRAY_SIZE(ecc_table), type,
38790+				  "unknown");
38791+}
38792+
38793+static struct match_t page_type_size_table[] = {
38794+	{NAND_PAGE_2K,	_2K,	NULL},
38795+	{NAND_PAGE_4K,	_4K,	NULL},
38796+	{NAND_PAGE_8K,	_8K,	NULL},
38797+	{NAND_PAGE_16K,	_16K,	NULL},
38798+};
38799+
38800+unsigned char match_page_size_to_type(unsigned int size)
38801+{
38802+	return match_reg_to_type(page_type_size_table,
38803+				 ARRAY_SIZE(page_type_size_table), size, NAND_PAGE_2K);
38804+}
38805+
38806+unsigned int match_page_type_to_size(unsigned char type)
38807+{
38808+	return match_type_to_reg(page_type_size_table,
38809+				 ARRAY_SIZE(page_type_size_table), type, _2K);
38810+}
38811\ No newline at end of file
38812diff --git a/drivers/mtd/nand/raw/hinfc_gen.h b/drivers/mtd/nand/raw/hinfc_gen.h
38813new file mode 100644
38814index 000000000..673ab8361
38815--- /dev/null
38816+++ b/drivers/mtd/nand/raw/hinfc_gen.h
38817@@ -0,0 +1,281 @@
38818+/*
38819+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
38820+ *
38821+ * This program is free software; you can redistribute  it and/or modify it
38822+ * under  the terms of  the GNU General  Public License as published by the
38823+ * Free Software Foundation;  either version 2 of the  License, or (at your
38824+ * option) any later version.
38825+ *
38826+ * This program is distributed in the hope that it will be useful,
38827+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
38828+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
38829+ * GNU General Public License for more details.
38830+ *
38831+ * You should have received a copy of the GNU General Public License
38832+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
38833+ *
38834+ */
38835+
38836+#ifndef __HINFC_GEN_H__
38837+#define __HINFC_GEN_H__
38838+
38839+#include <linux/mtd/mtd.h>
38840+#include <linux/mtd/rawnand.h>
38841+#include <linux/string_helpers.h>
38842+#include <asm/setup.h>
38843+#include <linux/module.h>
38844+
38845+#define HINFC_VER_300                   (0x300)
38846+#define HINFC_VER_301                   (0x301)
38847+#define HINFC_VER_310                   (0x310)
38848+#define HINFC_VER_504                   (0x504)
38849+#define HINFC_VER_505                   (0x505)
38850+#define HINFC_VER_600                   (0x600)
38851+#define HINFC_VER_610                   (0x610)
38852+#define HINFC_VER_620                   (0x620)
38853+
38854+#define HISNFC_VER_100                  (0x400)
38855+
38856+#define NAND_PAGE_512B                   0
38857+#define NAND_PAGE_1K                     1
38858+#define NAND_PAGE_2K                     2
38859+#define NAND_PAGE_4K                     3
38860+#define NAND_PAGE_8K                     4
38861+#define NAND_PAGE_16K                    5
38862+#define NAND_PAGE_32K                    6
38863+
38864+#define NAND_ECC_NONE                    0
38865+#define NAND_ECC_0BIT                    0
38866+#define NAND_ECC_1BIT                    1
38867+#define NAND_ECC_1BIT_512                1
38868+#define NAND_ECC_4BIT                    2
38869+#define NAND_ECC_4BIT_512                2
38870+#define NAND_ECC_4BYTE                   2
38871+#define NAND_ECC_8BIT                    2
38872+#define NAND_ECC_8BIT_512                3
38873+#define NAND_ECC_8BYTE                   3
38874+#define NAND_ECC_13BIT                   4
38875+#define NAND_ECC_16BIT                   5
38876+#define NAND_ECC_18BIT                   6
38877+#define NAND_ECC_24BIT                   7
38878+#define NAND_ECC_27BIT                   8
38879+#define NAND_ECC_28BIT                   9
38880+#define NAND_ECC_32BIT                   10
38881+#define NAND_ECC_40BIT                   11
38882+#define NAND_ECC_41BIT                   12
38883+#define NAND_ECC_42BIT                   13
38884+#define NAND_ECC_48BIT                   14
38885+#define NAND_ECC_60BIT                   15
38886+#define NAND_ECC_64BIT                   16
38887+#define NAND_ECC_72BIT                   17
38888+#define NAND_ECC_80BIT                   18
38889+
38890+enum ecc_type {
38891+	et_ecc_none    = 0x00,
38892+	et_ecc_1bit    = 0x01,
38893+	et_ecc_4bit    = 0x02,
38894+	et_ecc_8bit    = 0x03,
38895+	et_ecc_24bit1k = 0x04,
38896+	et_ecc_40bit1k = 0x05,
38897+	et_ecc_64bit1k = 0x06,
38898+};
38899+
38900+enum page_type {
38901+	pt_pagesize_512   = 0x00,
38902+	pt_pagesize_2K    = 0x01,
38903+	pt_pagesize_4K    = 0x02,
38904+	pt_pagesize_8K    = 0x03,
38905+	pt_pagesize_16K   = 0x04,
38906+};
38907+
38908+struct nand_config_info {
38909+	unsigned int pagetype;
38910+	unsigned int ecctype;
38911+	unsigned int ecc_strength;
38912+	unsigned int oobsize;
38913+	struct mtd_ooblayout_ops *ooblayout_ops;
38914+};
38915+
38916+struct hinfc_host;
38917+
38918+struct nand_sync {
38919+#define SET_NAND_SYNC_TYPE(_mfr, _onfi, _version) \
38920+	((((_mfr) & 0xFF) << 16) | (((_version) & 0xFF) << 8) \
38921+	 | ((_onfi) & 0xFF))
38922+
38923+#define GET_NAND_SYNC_TYPE_MFR(_type) (((_type) >> 16) & 0xFF)
38924+#define GET_NAND_SYNC_TYPE_VER(_type) (((_type) >> 8) & 0xFF)
38925+#define GET_NAND_SYNC_TYPE_INF(_type) ((_type) & 0xFF)
38926+
38927+#define NAND_TYPE_ONFI_23_MICRON    \
38928+	SET_NAND_SYNC_TYPE(NAND_MFR_MICRON, NAND_IS_ONFI, 0x23)
38929+#define NAND_TYPE_ONFI_30_MICRON    \
38930+	SET_NAND_SYNC_TYPE(NAND_MFR_MICRON, NAND_IS_ONFI, 0x30)
38931+#define NAND_TYPE_TOGGLE_TOSHIBA    \
38932+	SET_NAND_SYNC_TYPE(NAND_MFR_TOSHIBA, 0, 0)
38933+#define NAND_TYPE_TOGGLE_SAMSUNG    \
38934+	SET_NAND_SYNC_TYPE(NAND_MFR_SAMSUNG, 0, 0)
38935+
38936+#define NAND_TYPE_TOGGLE_10         SET_NAND_SYNC_TYPE(0, 0, 0x10)
38937+#define NAND_TYPE_ONFI_30           SET_NAND_SYNC_TYPE(0, NAND_IS_ONFI, 0x30)
38938+#define NAND_TYPE_ONFI_23           SET_NAND_SYNC_TYPE(0, NAND_IS_ONFI, 0x23)
38939+
38940+	int type;
38941+	int (*enable)(struct nand_chip *chip);
38942+	int (*disable)(struct nand_chip *chip);
38943+};
38944+
38945+struct read_retry_t {
38946+	int type;
38947+	int count;
38948+	int (*set_rr_param)(struct hinfc_host *host, int param);
38949+	int (*get_rr_param)(struct hinfc_host *host);
38950+	int (*reset_rr_param)(struct hinfc_host *host);
38951+};
38952+
38953+struct ecc_info_t {
38954+	int pagesize;
38955+	int ecctype;
38956+	int threshold;
38957+	int section;
38958+	void (*dump)(struct hinfc_host *host, unsigned char ecc[],
38959+		     int *max_bitsflag);
38960+};
38961+
38962+struct nand_dev_t {
38963+	struct nand_flash_dev flash_dev;
38964+
38965+	char *start_type;
38966+	unsigned char ids[8];
38967+	int oobsize;
38968+	int ecctype;
38969+
38970+	/* (Controller) support ecc/page detect, driver don't need detect */
38971+#define NANDC_HW_AUTO                         0x01
38972+	/* (Controller) support ecc/page detect,
38973+	 * and current ecc/page config finish */
38974+#define NANDC_CONFIG_DONE                     0x02
38975+	/* (Controller) is sync, default is async */
38976+#define NANDC_IS_SYNC_BOOT                    0x04
38977+
38978+/* (NAND) need randomizer */
38979+#define NAND_RANDOMIZER                       0x10
38980+/* (NAND) is ONFI interface, combine with sync/async symble */
38981+#define NAND_IS_ONFI                          0x20
38982+/* (NAND) support async and sync, such micron onfi, toshiba toggle 1.0 */
38983+#define NAND_MODE_SYNC_ASYNC                  0x40
38984+/* (NAND) support only sync, such samsung sync. */
38985+#define NAND_MODE_ONLY_SYNC                   0x80
38986+
38987+#define NAND_CHIP_MICRON   (NAND_MODE_SYNC_ASYNC | NAND_IS_ONFI)
38988+/* This NAND is async, or sync/async, default is async mode,
38989+ * toggle1.0 interface */
38990+#define NAND_CHIP_TOSHIBA_TOGGLE_10  (NAND_MODE_SYNC_ASYNC)
38991+/* This NAND is only sync mode, toggle2.0 interface */
38992+#define NAND_CHIP_TOSHIBA_TOGGLE_20   (NAND_MODE_ONLY_SYNC)
38993+/* This NAND is only sync mode */
38994+#define NAND_CHIP_SAMSUNG  (NAND_MODE_ONLY_SYNC)
38995+
38996+	unsigned int flags;
38997+
38998+#define NAND_RR_NONE                   0x00
38999+#define NAND_RR_HYNIX_BG_BDIE          0x10
39000+#define NAND_RR_HYNIX_BG_CDIE          0x11
39001+#define NAND_RR_HYNIX_CG_ADIE          0x12
39002+#define NAND_RR_MICRON                 0x20
39003+#define NAND_RR_SAMSUNG                0x30
39004+#define NAND_RR_TOSHIBA_24nm           0x40
39005+#define NAND_RR_TOSHIBA_19nm           0x41
39006+	int read_retry_type;
39007+};
39008+
39009+
39010+#define IS_NANDC_HW_AUTO(_host)         ((_host)->flags & NANDC_HW_AUTO)
39011+#define IS_NANDC_CONFIG_DONE(_host)     ((_host)->flags & NANDC_CONFIG_DONE)
39012+#define IS_NANDC_SYNC_BOOT(_host)       ((_host)->flags & NANDC_IS_SYNC_BOOT)
39013+
39014+#define IS_NAND_RANDOM(_dev)         ((_dev)->flags & NAND_RANDOMIZER)
39015+#define IS_NAND_ONLY_SYNC(_dev)      ((_dev)->flags & NAND_MODE_ONLY_SYNC)
39016+#define IS_NAND_SYNC_ASYNC(_dev)     ((_dev)->flags & NAND_MODE_SYNC_ASYNC)
39017+#define IS_NAND_ONFI(_dev)           ((_dev)->flags & NAND_IS_ONFI)
39018+
39019+#define ERSTR_HARDWARE  "Hardware configuration error. "
39020+#define ERSTR_DRIVER    "Driver does not support. "
39021+
39022+#define ENABLE                    1
39023+#define DISABLE                   0
39024+
39025+char *get_ecctype_str(enum ecc_type ecctype);
39026+
39027+char *get_pagesize_str(enum page_type pagetype);
39028+
39029+unsigned int get_pagesize(enum page_type pagetype);
39030+
39031+const char *nand_ecc_name(int type);
39032+
39033+const char *nand_page_name(int type);
39034+
39035+int nandpage_size2type(int size);
39036+
39037+int nandpage_type2size(int size);
39038+
39039+extern int (*hinfc_param_adjust)(struct mtd_info *mtd, struct nand_chip *chip,
39040+				 struct nand_dev_t *nand_dev);
39041+
39042+extern struct nand_flash_dev *(*nand_get_flash_type_func)(struct mtd_info *mtd,
39043+							  struct nand_chip *chip,
39044+							  struct nand_dev_t *spinand_dev_t);
39045+
39046+extern struct nand_flash_dev *(*get_spi_nand_flash_type_hook)
39047+(struct mtd_info *mtd, unsigned char *id);
39048+
39049+extern int (*hinfc_param_adjust)(struct mtd_info *,
39050+				 struct nand_chip *, struct nand_dev_t *);
39051+
39052+struct nand_flash_dev *hinfc_get_flash_type(struct mtd_info *mtd,
39053+					    struct nand_chip *chip,
39054+					    u8 *id_data, int *busw);
39055+
39056+extern struct nand_flash_dev *(*get_spi_nand_flash_type_hook)
39057+(struct mtd_info *mtd, unsigned char *id);
39058+
39059+void hinfc_nand_param_adjust(struct mtd_info *mtd, struct nand_chip *chip);
39060+
39061+void hinfc_show_info(struct mtd_info *mtd, const char *vendor, char *chipname);
39062+
39063+void hinfc_show_chipsize(struct nand_chip *chip);
39064+
39065+int get_bits(unsigned int n);
39066+
39067+#define hinfc_pr_msg(_fmt, arg...) printk(_fmt, ##arg)
39068+
39069+#define hinfc_pr_bug(fmt, args...) do { \
39070+	printk("%s(%d): bug " fmt, __FILE__, __LINE__, ##args); \
39071+	while (1) \
39072+		; \
39073+} while (0)
39074+
39075+#define PR_MSG(_fmt, arg...) \
39076+	    printk(_fmt, ##arg)
39077+
39078+extern char *nand_dbgfs_options;
39079+
39080+extern unsigned char match_page_reg_to_type(unsigned char reg);
39081+
39082+extern unsigned char match_page_type_to_reg(unsigned char type);
39083+
39084+extern const char *match_page_type_to_str(unsigned char type);
39085+
39086+extern unsigned char match_ecc_reg_to_type(unsigned char reg);
39087+
39088+extern unsigned char match_ecc_type_to_reg(unsigned char type);
39089+
39090+extern const char *match_ecc_type_to_str(unsigned char type);
39091+
39092+extern unsigned char match_page_size_to_type(unsigned int size);
39093+
39094+extern unsigned int match_page_type_to_size(unsigned char type);
39095+
39096+const char *nand_ecc_name(int type);
39097+
39098+#endif /* End of __HINFC_GEN_H__ */
39099\ No newline at end of file
39100diff --git a/drivers/mtd/nand/raw/hinfc_spl_ids.c b/drivers/mtd/nand/raw/hinfc_spl_ids.c
39101new file mode 100644
39102index 000000000..0fd7db974
39103--- /dev/null
39104+++ b/drivers/mtd/nand/raw/hinfc_spl_ids.c
39105@@ -0,0 +1,970 @@
39106+/*
39107+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
39108+ *
39109+ * This program is free software; you can redistribute  it and/or modify it
39110+ * under  the terms of  the GNU General  Public License as published by the
39111+ * Free Software Foundation;  either version 2 of the  License, or (at your
39112+ * option) any later version.
39113+ *
39114+ * This program is distributed in the hope that it will be useful,
39115+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
39116+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
39117+ * GNU General Public License for more details.
39118+ *
39119+ * You should have received a copy of the GNU General Public License
39120+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
39121+ *
39122+ */
39123+
39124+#include <linux/mtd/mtd.h>
39125+#include <linux/mfd/hisi_fmc.h>
39126+#include "hinfc_gen.h"
39127+
39128+struct nand_flash_special_dev {
39129+	unsigned char id[8];
39130+	int length;             /* length of id. */
39131+	unsigned long long chipsize;
39132+	struct nand_flash_dev *(*probe)(struct nand_dev_t *nand_dev);
39133+	char *name;
39134+
39135+	unsigned long pagesize;
39136+	unsigned long erasesize;
39137+	unsigned long oobsize;
39138+	unsigned long options;
39139+	unsigned int read_retry_type;
39140+
39141+#define BBP_LAST_PAGE                    0x01
39142+#define BBP_FIRST_PAGE                   0x02
39143+	unsigned int badblock_pos;
39144+	unsigned int flags;
39145+};
39146+
39147+
39148+/*                    this is nand probe function.                           */
39149+
39150+
39151+static struct nand_flash_dev *hynix_probe_v02(
39152+	struct nand_dev_t *nand_dev)
39153+{
39154+	unsigned char *id = nand_dev->ids;
39155+	struct nand_flash_dev *type = &nand_dev->flash_dev;
39156+
39157+	int pagesizes[]   = {SZ_2K, SZ_4K, SZ_8K, 0};
39158+	int oobsizes[]    = {128, 224, 448, 0, 0, 0, 0, 0};
39159+	int blocksizes[]  = {SZ_128K, SZ_256K, SZ_512K,
39160+			     (SZ_256K + SZ_512K), SZ_1M, SZ_2M, 0, 0
39161+			    };
39162+
39163+	int blocktype = (((id[3] >> 5) & 0x04) | ((id[3] >> 4) & 0x03));
39164+	int oobtype   = (((id[3] >> 2) & 0x03) | ((id[3] >> 4) & 0x04));
39165+
39166+	type->options   = 0;
39167+	type->pagesize  = pagesizes[(id[3] & 0x03)];
39168+	type->erasesize = blocksizes[blocktype];
39169+	nand_dev->oobsize = oobsizes[oobtype];
39170+
39171+	return type;
39172+}
39173+
39174+
39175+static struct nand_flash_dev *samsung_probe_v02(
39176+	struct nand_dev_t *nand_dev)
39177+{
39178+	unsigned char *id = nand_dev->ids;
39179+	struct nand_flash_dev *type = &nand_dev->flash_dev;
39180+
39181+	int pagesizes[]   = {SZ_2K, SZ_4K, SZ_8K, 0};
39182+	int oobsizes[]    = {0, 128, 218, 400, 436, 0, 0, 0};
39183+	int blocksizes[]  = {SZ_128K, SZ_256K, SZ_512K, SZ_1M, 0, 0, 0, 0};
39184+
39185+	int blocktype = (((id[3] >> 5) & 0x04) | ((id[3] >> 4) & 0x03));
39186+	int oobtype   = (((id[3] >> 4) & 0x04) | ((id[3] >> 2) & 0x03));
39187+
39188+	type->options   = 0;
39189+	type->pagesize  = pagesizes[(id[3] & 0x03)];
39190+	type->erasesize = blocksizes[blocktype];
39191+	nand_dev->oobsize = oobsizes[oobtype];
39192+
39193+	return type;
39194+}
39195+
39196+
39197+#define DRV_VERSION     "1.38"
39198+
39199+
39200+/*
39201+ * samsung:  27nm need randomizer, 21nm need read retry;
39202+ * micron:   25nm need read retry, datasheet will explain read retry.
39203+ * toshaba   32nm need randomizer, 24nm need read retry.
39204+ * hynix:    2xnm need read retry.
39205+ *
39206+ *		The special nand flash ID table version 1.37
39207+ *
39208+ * manufactory  |  type  |       name 	     |   ecc_type  | version_tag
39209+ * Micron		|  MLC	 |  MT29F64G08CBABA  |   40bit/1k  |  1.36
39210+ * Micron		|  MLC	 |  MT29F32G08CBADA  |   40bit/1k  |
39211+ * Micron		|  SLC	 |  MT29F8G08ABxBA   |   4bit/512  |
39212+ * Micron		|  MLC	 |  MT29F16G08CBABx  |   12bit/512 |
39213+ * Micron		|  MLC	 |  MT29F16G08CBACA  |   24bit/1k  |
39214+ * Micron		|  MLC	 |  MT29F32G08CBACA  |   24bit/1k  |
39215+ * Micron		|  MLC	 |  MT29F64G08CxxAA  |   24bit/1k  |
39216+ * Micron		|  MLC	 |  MT29F256G08CJAAA |   24bit/1k  |   2CE
39217+ * Micron		|  MLC	 |  MT29F256G08CMCBB |   24bit/1k  |
39218+ * Micron		|  SLC	 |  MT29F8G08ABACA   |   8bit/512  |
39219+ * Micron		|  SLC	 |  MT29F4G08ABAEA   |   8bit/512  |
39220+ * Micron		|  SLC	 |  MT29F2G08ABAFA   |   8bit/512  |
39221+ * Micron		|  SLC	 |  MT29F16G08ABACA  |   8bit/512  |
39222+ * Toshiba		|  MLC   |  TC58NVG4D2FTA00  |   24bit/1k  |
39223+ * Toshiba		|  MLC   |  TH58NVG6D2FTA20  |   24bit/1k  |   2CE
39224+ * Toshiba		|  MLC   |  TC58NVG5D2HTA00  |   40bit/1k  |
39225+ * Toshiba		|  MLC   |  TC58NVG6D2GTA00  |   40bit/1k  |
39226+ * Toshiba		|  MLC   |  TC58NVG6DCJTA00  |			   |
39227+ * Toshiba		|  MLC   |  TC58TEG5DCJTA00  |			   |
39228+ * Toshiba		|  SLC   |  TC58NVG0S3HTA00  |   8bit/512  |
39229+ * Toshiba		|  SLC   |  TC58NVG1S3HTA00  |   8bit/512  |
39230+ * Toshiba		|  SLC   |  TC58NVG1S3ETA00  |   4bit/512  |
39231+ * Toshiba		|  SLC   |  TC58NVG3S0FTA00  |   4bit/512  |
39232+ * Toshiba		|  SLC   |  TC58NVG2S0FTA00  |   4bit/512  |
39233+ * Toshiba		|  SLC   |  TH58NVG2S3HTA00  |   4bit/512  |
39234+ * Toshiba		|  TLC   |  TC58NVG5T2JTA00  |   60bit/1k  |
39235+ * Toshiba		|  TLC   |  TC58TEG5DCKTAx0  |   60bit/1k  |
39236+ * Toshiba		|  MLC   |  Tx58TEGxDDKTAx0  |			   |
39237+ * Samsung		|  MLC   |  K9LB(HC/PD/MD)G08U0(1)D  |   8bit/512B  |
39238+ * Samsung		|  MLC   |  K9GAG08U0E	     |   24bit/1KB |
39239+ * Samsung		|  MLC   |  K9LBG08U0E	     |   24bit/1KB |
39240+ * Samsung		|  MLC   |  K9G8G08U0C	     |   24bit/1KB |
39241+ * Samsung		|  MLC   |  K9GAG08U0F	     |   24bit/1KB |
39242+ * Samsung		|  MLC   |  K9LBG08U0M	     |             |
39243+ * Samsung		|  MLC   |  K9GBG08U0A	     |   24bit/1KB |
39244+ * Samsung		|  MLC   |  K9GBG08U0B	     |   40bit/1KB |
39245+ * Hynix		|  MLC   |  H27UAG8T2A	     |			   |
39246+ * Hynix		|  MLC   |  H27UAG8T2B	     |			   |
39247+ * Hynix		|  MLC   |  H27UBG8T2A	     |			   |
39248+ * Hynix		|  MLC   |  H27UBG8T2BTR	 |	 24bit/1KB |
39249+ * Hynix		|  MLC   |  H27UCG8T2A		 |	 40bit/1KB |
39250+ * Hynix		|  MLC   |  H27UBG8T2C		 |	 40bit/1KB |
39251+ * MISC			|  MLC   |  P1UAGA30AT-GCA	 |	 8bit/512  |
39252+ * MISC			|  MLC   |  PSU8GA30AT-GIA/ASU8GA30IT-G30CA	 |	 4bit/512  |
39253+ * MISC			|  SLC   |  PSU2GA30AT   	 |	 1bit/512  |   1.36
39254+ * Toshiba		|  SLC   |  TC58NVG2S0HTA00  |	 24bit/1K  |   1.37
39255+ * Toshiba		|  SLC   |  TC58NVG3S0HTA00  |   24bit/1K  |   1.37
39256+ * Micron		|  SLC	 |  MT29F2G08ABAEA   |   4bit/512 |
39257+ * Spansion		|  SLC	 | S34ML02G200TFI000	 | 24bit/1K |
39258+ * Spansion		|  SLC	 | S34ML04G200TFI000	 | 24bit/1K |  1.38
39259+ *
39260+ */
39261+
39262+static struct nand_flash_special_dev nand_flash_special_dev[] = {
39263+
39264+/****************************** Spansion *******************************/
39265+
39266+	{ /* SLC S34ML02G200TFI000 */
39267+		.name      = "S34ML02G200TFI000",
39268+		.id        = {0x01, 0xDA, 0x90, 0x95, 0x46, 0x00, 0x00, 0x00},
39269+		.length    = 5,
39270+		.chipsize  = _256M,
39271+		.probe     = NULL,
39272+		.pagesize  = SZ_2K,
39273+		.erasesize = SZ_128K,
39274+		.oobsize   = 128,
39275+		.options   = 0,
39276+		.read_retry_type = NAND_RR_NONE,
39277+		.badblock_pos    = BBP_FIRST_PAGE,
39278+		.flags = 0,
39279+	},
39280+
39281+	{ /* SLC S34ML04G200TFI000 */
39282+		.name      = "S34ML04G200TFI000",
39283+		.id        = {0x01, 0xDC, 0x90, 0x95, 0x56, 0x00, 0x00, 0x00},
39284+		.length    = 5,
39285+		.chipsize  = _512M,
39286+		.probe     = NULL,
39287+		.pagesize  = SZ_2K,
39288+		.erasesize = SZ_128K,
39289+		.oobsize   = 128,
39290+		.options   = 0,
39291+		.read_retry_type = NAND_RR_NONE,
39292+		.badblock_pos    = BBP_FIRST_PAGE,
39293+		.flags = 0,
39294+	},
39295+
39296+	/****************************** Micron *******************************/
39297+	{        /* MLC 40bit/1k */
39298+		.name      = "MT29F64G08CBABA",
39299+		.id        = {0x2C, 0x64, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00},
39300+		.length    = 8,
39301+		.chipsize  = _8G,
39302+		.probe     = NULL,
39303+		.pagesize  = SZ_8K,
39304+		.erasesize = SZ_2M,
39305+		.oobsize   = 744,
39306+		.options   = 0,
39307+		.read_retry_type = NAND_RR_MICRON,
39308+		.badblock_pos    = BBP_FIRST_PAGE,
39309+		.flags = NAND_RANDOMIZER | NAND_CHIP_MICRON,
39310+	},
39311+	{        /* MLC 40bit/1k */
39312+		.name      = "MT29F32G08CBADA",
39313+		.id        = {0x2C, 0x44, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00},
39314+		.length    = 8,
39315+		.chipsize  = _4G,
39316+		.probe     = NULL,
39317+		.pagesize  = SZ_8K,
39318+		.erasesize = SZ_2M,
39319+		.oobsize   = 744,
39320+		.options   = 0,
39321+		.read_retry_type = NAND_RR_MICRON,
39322+		.badblock_pos    = BBP_FIRST_PAGE,
39323+		.flags = NAND_RANDOMIZER,
39324+	},
39325+	{        /* SLC 4bit/512 */
39326+		.name      = "MT29F8G08ABxBA",
39327+		.id        = {0x2C, 0x38, 0x00, 0x26, 0x85, 0x00, 0x00, 0x00},
39328+		.length    = 8,
39329+		.chipsize  = SZ_1G,
39330+		.probe     = NULL,
39331+		.pagesize  = SZ_4K,
39332+		.erasesize = SZ_512K,
39333+		.oobsize   = 224,
39334+		.options   = 0,
39335+		.read_retry_type = NAND_RR_NONE,
39336+		.badblock_pos    = BBP_FIRST_PAGE,
39337+		.flags = 0,
39338+	},
39339+	{        /* MLC 12bit/512 */
39340+		.name      = "MT29F16G08CBABx",
39341+		.id        = {0x2C, 0x48, 0x04, 0x46, 0x85, 0x00, 0x00, 0x00},
39342+		.length    = 8,
39343+		.chipsize  = SZ_2G,
39344+		.probe     = NULL,
39345+		.pagesize  = SZ_4K,
39346+		.erasesize = SZ_1M,
39347+		.oobsize   = 224,
39348+		.options   = 0,
39349+		.read_retry_type = NAND_RR_NONE,
39350+		.badblock_pos    = BBP_FIRST_PAGE,
39351+		.flags = 0,
39352+	},
39353+	{        /* MLC 24bit/1k */
39354+		.name      = "MT29F16G08CBACA",
39355+		.id        = {0x2C, 0x48, 0x04, 0x4A, 0xA5, 0x00, 0x00, 0x00},
39356+		.length    = 8,
39357+		.chipsize  = SZ_2G,
39358+		.probe     = NULL,
39359+		.pagesize  = SZ_4K,
39360+		.erasesize = SZ_1M,
39361+		.oobsize   = 224,
39362+		.options   = 0,
39363+		.read_retry_type = NAND_RR_NONE,
39364+		.badblock_pos    = BBP_FIRST_PAGE,
39365+		.flags = 0,
39366+	},
39367+	{        /* MLC 24bit/1k */
39368+		.name      = "MT29F32G08CBACA",
39369+		.id        = {0x2C, 0x68, 0x04, 0x4A, 0xA9, 0x00, 0x00, 0x00},
39370+		.length    = 8,
39371+		.chipsize  = _4G,
39372+		.probe     = NULL,
39373+		.pagesize  = SZ_4K,
39374+		.erasesize = SZ_1M,
39375+		.oobsize   = 224,
39376+		.options   = 0,
39377+		.read_retry_type = NAND_RR_NONE,
39378+		.badblock_pos    = BBP_FIRST_PAGE,
39379+		.flags = 0,
39380+	},
39381+	{        /* MLC 24bit/1k */
39382+		.name      = "MT29F64G08CxxAA",
39383+		.id        = {0x2C, 0x88, 0x04, 0x4B, 0xA9, 0x00, 0x00, 0x00},
39384+		.length    = 8,
39385+		.chipsize  = _8G,
39386+		.probe     = NULL,
39387+		.pagesize  = SZ_8K,
39388+		.erasesize = SZ_2M,
39389+		.oobsize   = 448,
39390+		.options   = 0,
39391+		.read_retry_type = NAND_RR_NONE,
39392+		.badblock_pos    = BBP_FIRST_PAGE,
39393+		.flags = 0,
39394+	},
39395+	{        /* MLC 24bit/1k 2CE */
39396+		.name      = "MT29F256G08CJAAA",
39397+		.id        = {0x2C, 0xA8, 0x05, 0xCB, 0xA9, 0x00, 0x00, 0x00},
39398+		.length    = 8,
39399+		.chipsize  = _16G,
39400+		.probe     = NULL,
39401+		.pagesize  = SZ_8K,
39402+		.erasesize = SZ_2M,
39403+		.oobsize   = 448,
39404+		.options   = 0,
39405+		.read_retry_type = NAND_RR_NONE,
39406+		.badblock_pos    = BBP_FIRST_PAGE,
39407+		.flags = 0,
39408+	},
39409+	{        /* MLC 40bit/1k */
39410+		.name      = "MT29F256G08CMCBB",
39411+		.id        = {0x2C, 0x64, 0x44, 0x4B, 0xA9, 0x00, 0x00, 0x00},
39412+		.length    = 8,
39413+		.chipsize  = _8G,
39414+		.probe     = NULL,
39415+		.pagesize  = SZ_8K,
39416+		.erasesize = SZ_2M,
39417+		.oobsize   = 744,
39418+		.options   = 0,
39419+		.read_retry_type = NAND_RR_NONE,
39420+		.badblock_pos    = BBP_FIRST_PAGE,
39421+		.flags = 0,
39422+	},
39423+	{        /* SLC 8bit/512 */
39424+		.name      = "MT29F8G08ABACA",
39425+		.id        = {0x2C, 0xD3, 0x90, 0xA6, 0x64, 0x00, 0x00, 0x00},
39426+		.length    = 5,
39427+		.chipsize  = SZ_1G,
39428+		.probe     = NULL,
39429+		.pagesize  = SZ_4K,
39430+		.erasesize = SZ_256K,
39431+		.oobsize   = 224,
39432+		.options   = 0,
39433+		.read_retry_type = NAND_RR_NONE,
39434+		.badblock_pos    = BBP_FIRST_PAGE,
39435+		.flags = 0,
39436+	},
39437+	{        /* SLC 8bit/512 */
39438+		.name      = "MT29F4G08ABAEA",
39439+		.id        = {0x2C, 0xDC, 0x90, 0xA6, 0x54, 0x00, 0x00, 0x00},
39440+		.length    = 5,
39441+		.chipsize  = SZ_512M,
39442+		.probe     = NULL,
39443+		.pagesize  = SZ_4K,
39444+		.erasesize = SZ_256K,
39445+		.oobsize   = 224,
39446+		.options   = 0,
39447+		.read_retry_type = NAND_RR_NONE,
39448+		.badblock_pos    = BBP_FIRST_PAGE,
39449+		.flags = 0,
39450+	},
39451+	{        /* SLC 8bit/512 */
39452+		.name      = "MT29F2G08ABAFA",
39453+		.id        = {0x2C, 0xDA, 0x90, 0x95, 0x04, 0x00, 0x00, 0x00},
39454+		.length    = 5,
39455+		.chipsize  = SZ_256M,
39456+		.probe     = NULL,
39457+		.pagesize  = SZ_2K,
39458+		.erasesize = SZ_128K,
39459+		.oobsize   = 224,
39460+		.options   = 0,
39461+		.read_retry_type = NAND_RR_NONE,
39462+		.badblock_pos    = BBP_FIRST_PAGE,
39463+		.flags = 0,
39464+	},
39465+	{ /* SLC MT29F2G08ABAEA */
39466+		.name      = "MT29F2G08ABAEA",
39467+		.id        = {0x2C, 0xDA, 0x90, 0x95, 0x06, 0x00, 0x00, 0x00},
39468+		.length    = 5,
39469+		.chipsize  = _256M,
39470+		.probe     = NULL,
39471+		.pagesize  = SZ_2K,
39472+		.erasesize = SZ_128K,
39473+		.oobsize   = 64,
39474+		.options   = 0,
39475+		.read_retry_type = NAND_RR_NONE,
39476+		.badblock_pos    = BBP_FIRST_PAGE,
39477+		.flags = 0,
39478+	},
39479+	{        /* SLC 8bit/512 */
39480+		.name      = "MT29F16G08ABACA",
39481+		.id        = {0x2C, 0x48, 0x00, 0x26, 0xA9, 0x00, 0x00, 0x00},
39482+		.length    = 5,
39483+		.chipsize  = SZ_2G,
39484+		.probe     = NULL,
39485+		.pagesize  = SZ_4K,
39486+		.erasesize = SZ_512K,
39487+		.oobsize   = 224,
39488+		.options   = 0,
39489+		.read_retry_type = NAND_RR_NONE,
39490+		.badblock_pos    = BBP_FIRST_PAGE,
39491+		.flags = 0,
39492+	},
39493+
39494+/****************************** Toshaba *******************************/
39495+
39496+	{       /* MLC 24bit/1k 32nm */
39497+		.name      = "TC58NVG4D2FTA00",
39498+		.id        = {0x98, 0xD5, 0x94, 0x32, 0x76, 0x55, 0x00, 0x00},
39499+		.length    = 6,
39500+		.chipsize  = SZ_2G,
39501+		.probe     = NULL,
39502+		.pagesize  = SZ_8K,
39503+		.erasesize = SZ_1M,
39504+		.oobsize   = 448,
39505+		.options   = 0,
39506+		.read_retry_type = NAND_RR_NONE,
39507+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39508+		.flags = 0,
39509+	},
39510+	{       /* MLC 24bit/1k 32nm 2CE */
39511+		.name      = "TH58NVG6D2FTA20",
39512+		.id        = {0x98, 0xD7, 0x94, 0x32, 0x76, 0x55, 0x00, 0x00},
39513+		.length    = 6,
39514+		.chipsize  = _4G,
39515+		.probe     = NULL,
39516+		.pagesize  = SZ_8K,
39517+		.erasesize = SZ_1M,
39518+		.oobsize   = 448,
39519+		.options   = 0,
39520+		.read_retry_type = NAND_RR_NONE,
39521+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39522+		.flags = 0,
39523+	},
39524+	{       /* MLC 40bit/1k 24nm */
39525+		.name      = "TC58NVG5D2HTA00 24nm",
39526+		.id        = {0x98, 0xD7, 0x94, 0x32, 0x76, 0x56, 0x08, 0x00},
39527+		.length    = 6,
39528+		.chipsize  = _4G,
39529+		.probe     = NULL,
39530+		.pagesize  = SZ_8K,
39531+		.erasesize = SZ_1M,
39532+		.oobsize   = 640,
39533+		.options   = 0,
39534+		.read_retry_type = NAND_RR_TOSHIBA_24nm,
39535+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39536+		.flags = NAND_RANDOMIZER,
39537+	},
39538+	{       /* MLC 40bit/1k */
39539+		.name      = "TC58NVG6D2GTA00",
39540+		.id        = {0x98, 0xDE, 0x94, 0x82, 0x76, 0x00, 0x00, 0x00},
39541+		.length    = 5,
39542+		.chipsize  = _8G,
39543+		.probe     = NULL,
39544+		.pagesize  = SZ_8K,
39545+		.erasesize = SZ_2M,
39546+		.oobsize   = 640,
39547+		.options   = 0,
39548+		.read_retry_type = NAND_RR_NONE,
39549+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39550+		.flags = 0,
39551+	},
39552+	{       /* MLC 19nm */
39553+		.name      = "TC58NVG6DCJTA00 19nm",
39554+		.id        = {0x98, 0xDE, 0x84, 0x93, 0x72, 0x57, 0x08, 0x04},
39555+		.length    = 8,
39556+		.chipsize  = _8G,
39557+		.probe     = NULL,
39558+		.pagesize  = SZ_16K,
39559+		.erasesize = SZ_4M,
39560+		.oobsize   = 1280,
39561+		.options   = 0,
39562+		.read_retry_type = NAND_RR_TOSHIBA_24nm,
39563+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39564+		.flags = NAND_RANDOMIZER,
39565+	},
39566+	{       /* MLC 19nm */
39567+		.name      = "TC58TEG5DCJTA00 19nm",
39568+		.id        = {0x98, 0xD7, 0x84, 0x93, 0x72, 0x57, 0x08, 0x04},
39569+		.length    = 6,
39570+		.chipsize  = _4G,
39571+		.probe     = NULL,
39572+		.pagesize  = SZ_16K,
39573+		.erasesize = SZ_4M,
39574+		.oobsize   = 1280,
39575+		.options   = 0,
39576+		.read_retry_type = NAND_RR_TOSHIBA_24nm,
39577+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39578+		.flags = NAND_RANDOMIZER | NAND_CHIP_TOSHIBA_TOGGLE_10,
39579+	},
39580+	{       /* SLC 8bit/512 */
39581+		.name      = "TC58NVG0S3HTA00",
39582+		.id        = {0x98, 0xF1, 0x80, 0x15, 0x72, 0x00, 0x00, 0x00},
39583+		.length    = 5,
39584+		.chipsize  = SZ_128M,
39585+		.probe     = NULL,
39586+		.pagesize  = SZ_2K,
39587+		.erasesize = SZ_128K,
39588+		.oobsize   = 128,
39589+		.options   = 0,
39590+		.read_retry_type = NAND_RR_NONE,
39591+		/*
39592+		 * Datasheet: read one column of any page in each block. If the
39593+		 * data of the column is 00 (Hex), define the block as a bad
39594+		 * block.
39595+		 */
39596+		.badblock_pos    = BBP_FIRST_PAGE,
39597+		.flags = 0,
39598+	},
39599+	{       /* SLC 8bit/512 */
39600+		.name      = "TC58NVG1S3HTA00",
39601+		.id        = {0x98, 0xDA, 0x90, 0x15, 0x76, 0x16, 0x08, 0x00},
39602+		.length    = 7,
39603+		.chipsize  = SZ_256M,
39604+		.probe     = NULL,
39605+		.pagesize  = SZ_2K,
39606+		.erasesize = SZ_128K,
39607+		.oobsize   = 128,
39608+		.options   = 0,
39609+		.read_retry_type = NAND_RR_NONE,
39610+		.badblock_pos    = BBP_FIRST_PAGE,
39611+		.flags = 0,
39612+	},
39613+	{       /* SLC 4bit/512 */
39614+		.name      = "TC58NVG1S3ETA00",
39615+		.id        = {0x98, 0xDA, 0x90, 0x15, 0x76, 0x14, 0x03, 0x00},
39616+		.length    = 7,
39617+		.chipsize  = SZ_256M,
39618+		.probe     = NULL,
39619+		.pagesize  = SZ_2K,
39620+		.erasesize = SZ_128K,
39621+		.oobsize   = 64,
39622+		.options   = 0,
39623+		.read_retry_type = NAND_RR_NONE,
39624+		.badblock_pos    = BBP_FIRST_PAGE,
39625+		.flags = 0,
39626+	},
39627+	{       /* SLC 4bit/512 */
39628+		.name      = "TC58NVG3S0FTA00",
39629+		.id        = {0x98, 0xD3, 0x90, 0x26, 0x76, 0x15, 0x02, 0x08},
39630+		.length    = 8,
39631+		.chipsize  = SZ_1G,
39632+		.probe     = NULL,
39633+		.pagesize  = SZ_4K,
39634+		.erasesize = SZ_256K,
39635+		.oobsize   = 232,
39636+		.options   = 0,
39637+		.read_retry_type = NAND_RR_NONE,
39638+		.badblock_pos    = BBP_FIRST_PAGE,
39639+		.flags = 0,
39640+	},
39641+	{       /* SLC 4bit/512 */
39642+		.name      = "TC58NVG3S0HTA00",
39643+		.id        = {0x98, 0xD3, 0x91, 0x26, 0x76, 0x16, 0x08, 0x00},
39644+		.length    = 8,
39645+		.chipsize  = SZ_1G,
39646+		.probe     = NULL,
39647+		.pagesize  = SZ_4K,
39648+		.erasesize = SZ_256K,
39649+		.oobsize   = 256,
39650+		.options   = 0,
39651+		.read_retry_type = NAND_RR_NONE,
39652+		.badblock_pos    = BBP_FIRST_PAGE,
39653+		.flags = 0,
39654+	},
39655+	{       /* SLC 24bit/1k */
39656+		.name      = "TC58NVG2S0HTA00",
39657+		.id        = {0x98, 0xDC, 0x90, 0x26, 0x76, 0x16, 0x08, 0x00},
39658+		.length    = 8,
39659+		.chipsize  = SZ_512M,
39660+		.probe     = NULL,
39661+		.pagesize  = SZ_4K,
39662+		.erasesize = SZ_256K,
39663+		.oobsize   = 256,
39664+		.options   = 0,
39665+		.read_retry_type = NAND_RR_NONE,
39666+		.badblock_pos    = BBP_FIRST_PAGE,
39667+		.flags = 0,
39668+	},
39669+	{       /* SLC 4bit/512 */
39670+		.name      = "TC58NVG2S0FTA00",
39671+		.id        = {0x98, 0xDC, 0x90, 0x26, 0x76, 0x15, 0x01, 0x08},
39672+		.length    = 8,
39673+		.chipsize  = SZ_512M,
39674+		.probe     = NULL,
39675+		.pagesize  = SZ_4K,
39676+		.erasesize = SZ_256K,
39677+		.oobsize   = 224,
39678+		.options   = 0,
39679+		.read_retry_type = NAND_RR_NONE,
39680+		.badblock_pos    = BBP_FIRST_PAGE,
39681+		.flags = 0,
39682+	},
39683+	{       /* SLC 4bit/512 */
39684+		.name      = "TH58NVG2S3HTA00",
39685+		.id        = {0x98, 0xDC, 0x91, 0x15, 0x76},
39686+		.length    = 5,
39687+		.chipsize  = SZ_512M,
39688+		.probe     = NULL,
39689+		.pagesize  = SZ_2K,
39690+		.erasesize = SZ_128K,
39691+		.oobsize   = 128,
39692+		.options   = 0,
39693+		.read_retry_type = NAND_RR_NONE,
39694+		.badblock_pos    = BBP_FIRST_PAGE,
39695+		.flags = 0,
39696+	},
39697+	{       /* TLC 60bit/1k 19nm */
39698+		.name      = "TC58NVG5T2JTA00 19nm TLC",
39699+		.id        = {0x98, 0xD7, 0x98, 0x92, 0x72, 0x57, 0x08, 0x10},
39700+		.length    = 6,
39701+		.chipsize  = _4G,
39702+		.probe     = NULL,
39703+		.pagesize  = SZ_8K,
39704+		.erasesize = SZ_4M,
39705+		.oobsize   = 1024,
39706+		.options   = 0,
39707+		.read_retry_type = NAND_RR_TOSHIBA_24nm,
39708+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39709+		.flags = NAND_RANDOMIZER,
39710+	},
39711+	{ /* TLC 60bit/1k 19nm */
39712+		.name	   = "TC58TEG5DCKTAx0 19nm MLC",
39713+		/* datasheet says 6 ids id data, but really has 8 ids. */
39714+		.id	   = {0x98, 0xD7, 0x84, 0x93, 0x72, 0x50, 0x08, 0x04},
39715+		.length    = 6,
39716+		.chipsize  = _4G,
39717+		.probe	   = NULL,
39718+		.pagesize  = SZ_16K,
39719+		.erasesize = SZ_4M,
39720+		.oobsize   = 1280,
39721+		.options   = 0,
39722+		.read_retry_type = NAND_RR_TOSHIBA_19nm,
39723+		.badblock_pos	 = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39724+		.flags = NAND_RANDOMIZER,
39725+	},
39726+	{
39727+		.name	   = "Tx58TEGxDDKTAx0 19nm MLC",
39728+		.id	   = {0x98, 0xDE, 0x94, 0x93, 0x76, 0x50},
39729+		.length    = 6,
39730+		.chipsize  = _4G,
39731+		.probe	   = NULL,
39732+		.pagesize  = SZ_16K,
39733+		.erasesize = SZ_4M,
39734+		.oobsize   = 1280,
39735+		.options   = 0,
39736+		.read_retry_type = NAND_RR_TOSHIBA_19nm,
39737+		.badblock_pos	 = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39738+		.flags = NAND_RANDOMIZER,
39739+	},
39740+/******************************* Samsung ******************************/
39741+	{       /* MLC 8bit/512B */
39742+		.name     = "K9LB(HC/PD/MD)G08U0(1)D",
39743+		.id       = {0xEC, 0xD7, 0xD5, 0x29, 0x38, 0x41, 0x00, 0x00},
39744+		.length   = 6,
39745+		.chipsize = _4G,
39746+		.probe    = samsung_probe_v02,
39747+		.read_retry_type = NAND_RR_NONE,
39748+		.badblock_pos    = BBP_LAST_PAGE,
39749+		.flags = 0,
39750+	},
39751+	{       /* MLC 24bit/1KB */
39752+		.name      = "K9GAG08U0E",
39753+		.id        = {0xEC, 0xD5, 0x84, 0x72, 0x50, 0x42, 0x00, 0x00},
39754+		.length    = 6,
39755+		.chipsize  = SZ_2G,
39756+		.probe     = samsung_probe_v02,
39757+		.read_retry_type = NAND_RR_NONE,
39758+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39759+		.flags = 0,
39760+	},
39761+	{       /* MLC 24bit/1KB */
39762+		.name     = "K9LBG08U0E",
39763+		.id       = {0xEC, 0xD7, 0xC5, 0x72, 0x54, 0x42, 0x00, 0x00},
39764+		.length   = 6,
39765+		.chipsize = _4G,
39766+		.probe    = samsung_probe_v02,
39767+		.read_retry_type = NAND_RR_NONE,
39768+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39769+		.flags = 0,
39770+	},
39771+	{       /* MLC 24bit/1KB */
39772+		.name     = "K9G8G08U0C",
39773+		.id       = {0xEC, 0xD3, 0x84, 0x72, 0x50, 0x42, 0x00, 0x00},
39774+		.length   = 6,
39775+		.chipsize = SZ_1G,
39776+		.probe    = samsung_probe_v02,
39777+		.read_retry_type = NAND_RR_NONE,
39778+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39779+		.flags = 0,
39780+	},
39781+	{        /* MLC 24bit/1k */
39782+		.name      = "K9GAG08U0F",
39783+		.id        = {0xEC, 0xD5, 0x94, 0x76, 0x54, 0x43, 0x00, 0x00},
39784+		.length    = 6,
39785+		.chipsize  = SZ_2G,
39786+		.probe     = NULL,
39787+		.pagesize  = SZ_8K,
39788+		.erasesize = SZ_1M,
39789+		.oobsize   = 512,
39790+		.options   = 0,
39791+		.read_retry_type = NAND_RR_NONE,
39792+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39793+		.flags = 0,
39794+	},
39795+	{        /* MLC */
39796+		.name      = "K9LBG08U0M",
39797+		.id        = {0xEC, 0xD7, 0x55, 0xB6, 0x78, 0x00, 0x00, 0x00},
39798+		.length    = 5,
39799+		.chipsize  = _4G,
39800+		.probe     = NULL,
39801+		.pagesize  = SZ_4K,
39802+		.erasesize = SZ_512K,
39803+		.oobsize   = 128,
39804+		.options   = 0,
39805+		.read_retry_type = NAND_RR_NONE,
39806+		.badblock_pos    = BBP_LAST_PAGE,
39807+		.flags = 0,
39808+	},
39809+	{        /* MLC 24bit/1k */
39810+		.name      = "K9GBG08U0A 20nm",
39811+		.id        = {0xEC, 0xD7, 0x94, 0x7A, 0x54, 0x43, 0x00, 0x00},
39812+		.length    = 6,
39813+		.chipsize  = _4G,
39814+		.probe     = NULL,
39815+		.pagesize  = SZ_8K,
39816+		.erasesize = SZ_1M,
39817+		.oobsize   = 640,
39818+		.options   = 0,
39819+		.read_retry_type = NAND_RR_SAMSUNG,
39820+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39821+		.flags = NAND_RANDOMIZER,
39822+	},
39823+	{        /* MLC 40bit/1k */
39824+		.name      = "K9GBG08U0B",
39825+		.id        = {0xEC, 0xD7, 0x94, 0x7E, 0x64, 0x44, 0x00, 0x00},
39826+		.length    = 6,
39827+		.chipsize  = _4G,
39828+		.probe     = NULL,
39829+		.pagesize  = SZ_8K,
39830+		.erasesize = SZ_1M,
39831+		.oobsize   = 1024,
39832+		.options   = 0,
39833+		.read_retry_type = NAND_RR_SAMSUNG,
39834+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39835+		.flags = NAND_RANDOMIZER,
39836+	},
39837+
39838+/*********************************** Hynix ****************************/
39839+	{       /* MLC */
39840+		.name     = "H27UAG8T2A",
39841+		.id       = { 0xAD, 0xD5, 0x94, 0x25, 0x44, 0x41, },
39842+		.length   = 6,
39843+		.chipsize = SZ_2G,
39844+		.probe    = hynix_probe_v02,
39845+		.read_retry_type = NAND_RR_NONE,
39846+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39847+		.flags = 0,
39848+	},
39849+	{       /* MLC */
39850+		.name     = "H27UAG8T2B",
39851+		.id       = { 0xAD, 0xD5, 0x94, 0x9A, 0x74, 0x42, },
39852+		.length   = 6,
39853+		.chipsize = SZ_2G,
39854+		.probe    = hynix_probe_v02,
39855+		.read_retry_type = NAND_RR_NONE,
39856+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39857+		.flags = 0,
39858+	},
39859+	{       /* MLC */
39860+		.name     = "H27UBG8T2A",
39861+		.id       = { 0xAD, 0xD7, 0x94, 0x9A, 0x74, 0x42, },
39862+		.length   = 6,
39863+		.chipsize = _4G,
39864+		.probe    = hynix_probe_v02,
39865+		.read_retry_type = NAND_RR_NONE,
39866+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39867+		.flags = 0,
39868+	},
39869+	{
39870+		.name      = "H27UBG8T2BTR 26nm",
39871+		.id        = { 0xAD, 0xD7, 0x94, 0xDA, 0x74, 0xC3, },
39872+		.length    = 6,
39873+		.chipsize  = _4G,
39874+		.probe     = NULL,
39875+		.pagesize  = SZ_8K,
39876+		.erasesize = SZ_2M,
39877+		.oobsize   = 640,
39878+		.options   = 0,
39879+		.read_retry_type = NAND_RR_HYNIX_BG_BDIE,
39880+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39881+		.flags = NAND_RANDOMIZER,
39882+	},
39883+	{        /* MLC 40bit/1k */
39884+		.name      = "H27UCG8T2A",
39885+		.id        = { 0xAD, 0xDE, 0x94, 0xDA, 0x74, 0xC4, },
39886+		.length    = 6,
39887+		.chipsize  = _8G,
39888+		.probe     = NULL,
39889+		.pagesize  = SZ_8K,
39890+		.erasesize = SZ_2M,
39891+		.oobsize   = 640,
39892+		.options   = 0,
39893+		.read_retry_type = NAND_RR_HYNIX_CG_ADIE,
39894+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39895+		.flags = NAND_RANDOMIZER,
39896+	},
39897+	{        /* MLC 40bit/1k */
39898+		.name      = "H27UBG8T2C",
39899+		.id        = { 0xAD, 0xD7, 0x94, 0x91, 0x60, 0x44, },
39900+		.length    = 6,
39901+		.chipsize  = _4G,
39902+		.probe     = NULL,
39903+		.pagesize  = SZ_8K,
39904+		.erasesize = SZ_2M,
39905+		.oobsize   = 640,
39906+		.options   = 0,
39907+		.read_retry_type = NAND_RR_HYNIX_BG_CDIE,
39908+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39909+		.flags = NAND_RANDOMIZER,
39910+	},
39911+
39912+/********************** MISC ******************************************/
39913+	{        /* MLC 8bit/512 */
39914+		.name      = "P1UAGA30AT-GCA",
39915+		.id        = { 0xC8, 0xD5, 0x14, 0x29, 0x34, 0x01, },
39916+		.length    = 6,
39917+		.chipsize  = SZ_2G,
39918+		.probe     = NULL,
39919+		.pagesize  = SZ_4K,
39920+		.erasesize = SZ_512K,
39921+		.oobsize   = 218,
39922+		.options   = 0,
39923+		.read_retry_type = NAND_RR_NONE,
39924+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39925+		.flags = 0,
39926+	},
39927+	{       /* MLC 4bit/512 */
39928+		/*
39929+		 * PowerFlash ASU8GA30IT-G30CA ID and MIRA PSU8GA30AT-GIA ID are
39930+		 * the same ID
39931+		 */
39932+		.name      = "PSU8GA30AT-GIA/ASU8GA30IT-G30CA",
39933+		.id        = { 0xC8, 0xD3, 0x90, 0x19, 0x34, 0x01, },
39934+		.length    = 6,
39935+		.chipsize  = SZ_1G,
39936+		.probe     = NULL,
39937+		.pagesize  = SZ_4K,
39938+		.erasesize = SZ_256K,
39939+		.oobsize   = 218,
39940+		.options   = 0,
39941+		.read_retry_type = NAND_RR_NONE,
39942+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39943+		.flags = 0,
39944+	},
39945+	{        /* SLC 1bit/512 */
39946+		.name      = "PSU2GA30AT",
39947+		.id        = { 0x7F, 0x7F, 0x7F, 0x7F, 0xC8, 0xDA, 0x00, 0x15, },
39948+		.length    = 8,
39949+		.chipsize  = SZ_256M,
39950+		.probe     = NULL,
39951+		.pagesize  = SZ_2K,
39952+		.erasesize = SZ_128K,
39953+		.oobsize   = 64,
39954+		.options   = 0,
39955+		.read_retry_type = NAND_RR_NONE,
39956+		.badblock_pos    = BBP_FIRST_PAGE | BBP_LAST_PAGE,
39957+		.flags = 0,
39958+	},
39959+	{{0}, 0, 0, 0, 0, 0, 0, 0, 0},
39960+};
39961+
39962+#define NUM_OF_SPECIAL_DEVICE  \
39963+	(sizeof(nand_flash_special_dev) / sizeof(struct nand_flash_special_dev))
39964+
39965+int (*hinfc_param_adjust)(struct mtd_info *, struct nand_chip *,
39966+			  struct nand_dev_t *) = NULL;
39967+
39968+static struct nand_dev_t __nand_dev;
39969+
39970+
39971+static struct nand_flash_dev *hinfc_nand_probe(struct mtd_info *mtd,
39972+					       struct nand_chip *chip,
39973+					       struct nand_dev_t *nand_dev)
39974+{
39975+	struct nand_flash_special_dev *spl_dev = NULL;
39976+	unsigned char *byte = nand_dev->ids;
39977+	struct nand_flash_dev *type = &nand_dev->flash_dev;
39978+
39979+	hinfc_pr_msg("Nand ID: 0x%02X 0x%02X 0x%02X 0x%02X",
39980+		     byte[0], byte[1], byte[2], byte[3]);
39981+	hinfc_pr_msg(" 0x%02X 0x%02X 0x%02X 0x%02X\n",
39982+		     byte[4], byte[5], byte[6], byte[7]);
39983+
39984+	for (spl_dev = nand_flash_special_dev; spl_dev->length; spl_dev++) {
39985+		if (memcmp(byte, spl_dev->id, spl_dev->length))
39986+			continue;
39987+
39988+		hinfc_pr_msg("The Special NAND id table Version: %s\n", DRV_VERSION);
39989+
39990+		if (spl_dev->probe) {
39991+			type = spl_dev->probe(nand_dev);
39992+		} else {
39993+			type->options   = spl_dev->options;
39994+			type->pagesize  = spl_dev->pagesize;
39995+			type->erasesize = spl_dev->erasesize;
39996+			nand_dev->oobsize = spl_dev->oobsize;
39997+		}
39998+
39999+		nand_dev->read_retry_type = spl_dev->read_retry_type;
40000+		nand_dev->flags = spl_dev->flags;
40001+
40002+		type->id[1] = byte[1];
40003+		type->chipsize = (unsigned long)(spl_dev->chipsize >> 20);
40004+		type->name = spl_dev->name;
40005+		return type;
40006+	}
40007+	nand_dev->read_retry_type = NAND_RR_NONE;
40008+
40009+	return NULL;
40010+}
40011+
40012+
40013+struct nand_flash_dev *hinfc_get_flash_type(struct mtd_info *mtd,
40014+					    struct nand_chip *chip,
40015+					    u8 *id_data, int *busw)
40016+{
40017+	struct nand_flash_dev *type = NULL;
40018+	struct nand_dev_t *nand_dev = &__nand_dev;
40019+
40020+	memset(nand_dev, 0, sizeof(struct nand_dev_t));
40021+	memcpy(nand_dev->ids, id_data, 8);
40022+
40023+	if (!hinfc_nand_probe(mtd, chip, nand_dev))
40024+		return NULL;
40025+
40026+	type = &nand_dev->flash_dev;
40027+
40028+	if (!mtd->name)
40029+		mtd->name = type->name;
40030+
40031+	chip->chipsize = (uint64_t)type->chipsize << 20;
40032+	mtd->erasesize = type->erasesize;
40033+	mtd->writesize = type->pagesize;
40034+	mtd->oobsize   = nand_dev->oobsize;
40035+	*busw = (type->options & NAND_BUSWIDTH_16);
40036+
40037+	return type;
40038+}
40039+
40040+
40041+void hinfc_nand_param_adjust(struct mtd_info *mtd, struct nand_chip *chip)
40042+{
40043+	struct nand_dev_t *nand_dev = &__nand_dev;
40044+
40045+	if (!nand_dev->oobsize)
40046+		nand_dev->oobsize = mtd->oobsize;
40047+
40048+	if (hinfc_param_adjust)
40049+		hinfc_param_adjust(mtd, chip, nand_dev);
40050+}
40051+
40052+
40053+void hinfc_show_info(struct mtd_info *mtd, const char *vendor, char *chipname)
40054+{
40055+	struct nand_dev_t *nand_dev = &__nand_dev;
40056+
40057+	if (IS_NAND_RANDOM(nand_dev))
40058+		hinfc_pr_msg("Randomizer \n");
40059+
40060+	if (nand_dev->read_retry_type != NAND_RR_NONE)
40061+		hinfc_pr_msg("Read-Retry \n");
40062+
40063+	if (nand_dev->start_type)
40064+		hinfc_pr_msg("Nand(%s): ", nand_dev->start_type);
40065+	else
40066+		hinfc_pr_msg("Nand: ");
40067+
40068+	hinfc_pr_msg("OOB:%dB ", nand_dev->oobsize);
40069+	hinfc_pr_msg("ECC:%s ", nand_ecc_name(nand_dev->ecctype));
40070+}
40071+
40072+
40073+void hinfc_show_chipsize(struct nand_chip *chip)
40074+{
40075+}
40076diff --git a/drivers/mtd/nand/raw/internals.h b/drivers/mtd/nand/raw/internals.h
40077index 012876e14..be6bb9c30 100644
40078--- a/drivers/mtd/nand/raw/internals.h
40079+++ b/drivers/mtd/nand/raw/internals.h
40080@@ -17,8 +17,12 @@
40081  * NAND Flash Manufacturer ID Codes
40082  */
40083 #define NAND_MFR_AMD		0x01
40084-#define NAND_MFR_ATO		0x9b
40085 #define NAND_MFR_EON		0x92
40086+#define NAND_MFR_WINBOND	0xef
40087+#define NAND_MFR_ATO		0x9b
40088+#define NAND_MFR_MXIC		0xc2
40089+#define NAND_MFR_ALL_FLASH	0xc1
40090+#define NAND_MFR_PARAGON	0xa1
40091 #define NAND_MFR_ESMT		0xc8
40092 #define NAND_MFR_FUJITSU	0x04
40093 #define NAND_MFR_HYNIX		0xad
40094@@ -32,7 +36,10 @@
40095 #define NAND_MFR_STMICRO	0x20
40096 /* Kioxia is new name of Toshiba memory. */
40097 #define NAND_MFR_TOSHIBA	0x98
40098-#define NAND_MFR_WINBOND	0xef
40099+#define NAND_MFR_GD_ESMT	0xc8
40100+#define NAND_MFR_HEYANGTEK	0xc9
40101+#define NAND_MFR_DOSILICON	0xe5
40102+#define NAND_MFR_FIDELIX	0xf8
40103
40104 /**
40105  * struct nand_manufacturer_ops - NAND Manufacturer operations
40106diff --git a/drivers/mtd/nand/raw/match_table.c b/drivers/mtd/nand/raw/match_table.c
40107new file mode 100644
40108index 000000000..6bad75f97
40109--- /dev/null
40110+++ b/drivers/mtd/nand/raw/match_table.c
40111@@ -0,0 +1,102 @@
40112+/******************************************************************************
40113+ *    COPYRIGHT (C) Hisilicon.2013
40114+ *    All rights reserved.
40115+ * ***
40116+ *    Create by Hisilicon 2013-08-15
40117+ *
40118+ *****************************************************************************/
40119+
40120+#include <linux/string.h>
40121+#include "match_table.h"
40122+
40123+int reg2type(struct match_reg_type *table, int length, int reg, int def)
40124+{
40125+	while (length-- > 0) {
40126+		if (table->reg == reg) {
40127+			return table->type;
40128+		}
40129+		table++;
40130+	}
40131+	return def;
40132+}
40133+
40134+int type2reg(struct match_reg_type *table, int length, int type, int def)
40135+{
40136+	while (length-- > 0) {
40137+		if (table->type == type) {
40138+			return table->reg;
40139+		}
40140+		table++;
40141+	}
40142+	return def;
40143+}
40144+
40145+int str2type(struct match_type_str *table, int length, const char *str,
40146+	     int size, int def)
40147+{
40148+	while (length-- > 0) {
40149+		if (!strncmp(table->str, str, size)) {
40150+			return table->type;
40151+		}
40152+		table++;
40153+	}
40154+	return def;
40155+}
40156+
40157+const char *type2str(struct match_type_str *table, int length, int type,
40158+		     const char *def)
40159+{
40160+	while (length-- > 0) {
40161+		if (table->type == type) {
40162+			return table->str;
40163+		}
40164+		table++;
40165+	}
40166+	return def;
40167+}
40168+
40169+int match_reg_to_type(struct match_t *table, int nr_table, int reg, int def)
40170+{
40171+	while (nr_table-- > 0) {
40172+		if (table->reg == reg) {
40173+			return table->type;
40174+		}
40175+		table++;
40176+	}
40177+	return def;
40178+}
40179+
40180+int match_type_to_reg(struct match_t *table, int nr_table, int type, int def)
40181+{
40182+	while (nr_table-- > 0) {
40183+		if (table->type == type) {
40184+			return table->reg;
40185+		}
40186+		table++;
40187+	}
40188+	return def;
40189+}
40190+
40191+int match_data_to_type(struct match_t *table, int nr_table, const char *data,
40192+		       int size, int def)
40193+{
40194+	while (nr_table-- > 0) {
40195+		if (!memcmp(table->data, data, size)) {
40196+			return table->type;
40197+		}
40198+		table++;
40199+	}
40200+	return def;
40201+}
40202+
40203+void *match_type_to_data(struct match_t *table, int nr_table, int type,
40204+			 void *def)
40205+{
40206+	while (nr_table-- > 0) {
40207+		if (table->type == type) {
40208+			return table->data;
40209+		}
40210+		table++;
40211+	}
40212+	return def;
40213+}
40214diff --git a/drivers/mtd/nand/raw/match_table.h b/drivers/mtd/nand/raw/match_table.h
40215new file mode 100644
40216index 000000000..9c5f0af09
40217--- /dev/null
40218+++ b/drivers/mtd/nand/raw/match_table.h
40219@@ -0,0 +1,51 @@
40220+/******************************************************************************
40221+ *    COPYRIGHT (C) Hisilicon 2013
40222+ *    All rights reserved.
40223+ * ***
40224+ *    Create by Hisilicon 2013-08-15
40225+ *
40226+ *****************************************************************************/
40227+#ifndef __MATCH_TABLE_H__
40228+#define __MATCH_TABLE_H__
40229+
40230+struct match_reg_type {
40231+	int reg;
40232+	int type;
40233+};
40234+
40235+struct match_type_str {
40236+	int type;
40237+	const char *str;
40238+};
40239+
40240+struct match_t {
40241+	int type;
40242+	int reg;
40243+	void *data;
40244+};
40245+
40246+#define MATCH_SET_TYPE_REG(_type, _reg)   {(_type), (_reg), (void *)0}
40247+#define MATCH_SET_TYPE_DATA(_type, _data) {(_type), 0, (void *)(_data)}
40248+#define MATCH_SET(_type, _reg, _data)     {(_type), (_reg), (void *)(_data)}
40249+
40250+int reg2type(struct match_reg_type *table, int length, int reg, int def);
40251+
40252+int type2reg(struct match_reg_type *table, int length, int type, int def);
40253+
40254+int str2type(struct match_type_str *table, int length, const char *str,
40255+	     int size, int def);
40256+
40257+const char *type2str(struct match_type_str *table, int length, int type,
40258+		     const char *def);
40259+
40260+int match_reg_to_type(struct match_t *table, int nr_table, int reg, int def);
40261+
40262+int match_type_to_reg(struct match_t *table, int nr_table, int type, int def);
40263+
40264+int match_data_to_type(struct match_t *table, int nr_table, const char *data,
40265+		       int size, int def);
40266+
40267+void *match_type_to_data(struct match_t *table, int nr_table, int type,
40268+			 void *def);
40269+
40270+#endif /* End of __MATCH_TABLE_H__ */
40271diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c
40272index 1f0d542d5..e2f2d86e3 100644
40273--- a/drivers/mtd/nand/raw/nand_base.c
40274+++ b/drivers/mtd/nand/raw/nand_base.c
40275@@ -44,6 +44,7 @@
40276 #include <linux/of.h>
40277 #include <linux/gpio/consumer.h>
40278
40279+#include "hinfc_gen.h"
40280 #include "internals.h"
40281
40282 static int nand_pairing_dist3_get_info(struct mtd_info *mtd, int page,
40283@@ -3968,6 +3969,10 @@ static int nand_do_write_ops(struct nand_chip *chip, loff_t to,
40284 	int ret;
40285 	int oob_required = oob ? 1 : 0;
40286
40287+#ifdef CONFIG_ARCH_HISI_BVT
40288+    oob_required = 1;
40289+#endif
40290+
40291 	ops->retlen = 0;
40292 	if (!writelen)
40293 		return 0;
40294@@ -4695,7 +4700,8 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
40295 	const struct nand_manufacturer_desc *manufacturer_desc;
40296 	struct mtd_info *mtd = nand_to_mtd(chip);
40297 	struct nand_memory_organization *memorg;
40298-	int busw, ret;
40299+	int busw = 0;
40300+	int ret = 0;
40301 	u8 *id_data = chip->id.data;
40302 	u8 maf_id, dev_id;
40303 	u64 targetsize;
40304@@ -4752,6 +4758,30 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
40305 	manufacturer_desc = nand_get_manufacturer_desc(maf_id);
40306 	chip->manufacturer.desc = manufacturer_desc;
40307
40308+#ifdef CONFIG_ARCH_HISI_BVT
40309+
40310+#ifndef CONFIG_MTD_SPI_NAND_HISI_BVT
40311+	/* Parallel Nand Flash */
40312+
40313+	/* The 3rd id byte holds MLC / multichip data */
40314+	chip->bits_per_cell = nand_get_bits_per_cell(id_data[2]);
40315+#endif
40316+
40317+	if (get_spi_nand_flash_type_hook)
40318+	    type = get_spi_nand_flash_type_hook(mtd, id_data);
40319+
40320+	if (type)
40321+	    goto ident_done;
40322+#ifdef CONFIG_MTD_SPI_NAND_HISI_BVT
40323+	else {
40324+	    pr_info("This device[%02x,%02x] cannot found in spi nand id table!!\n",
40325+		    maf_id, dev_id);
40326+	    return -ENODEV;
40327+	}
40328+#endif
40329+
40330+#endif /* endif CONFIG_ARCH_HISI_BVT */
40331+
40332 	if (!type)
40333 		type = nand_flash_ids;
40334
40335@@ -4816,12 +4846,16 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
40336 					   memorg->pages_per_eraseblock);
40337
40338 ident_done:
40339+#ifdef CONFIG_ARCH_HISI_BVT
40340+	hinfc_nand_param_adjust(mtd, chip);
40341+#endif
40342 	if (!mtd->name)
40343 		mtd->name = chip->parameters.model;
40344
40345 	if (chip->options & NAND_BUSWIDTH_AUTO) {
40346 		WARN_ON(busw & NAND_BUSWIDTH_16);
40347 		nand_set_defaults(chip);
40348+		printk("NAND_BUSWIDTH_AUTO,line:%d",__LINE__);
40349 	} else if (busw != (chip->options & NAND_BUSWIDTH_16)) {
40350 		/*
40351 		 * Check, if buswidth is correct. Hardware drivers should set
40352@@ -4869,6 +4903,10 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
40353 	pr_info("%d MiB, %s, erase size: %d KiB, page size: %d, OOB size: %d\n",
40354 		(int)(targetsize >> 20), nand_is_slc(chip) ? "SLC" : "MLC",
40355 		mtd->erasesize >> 10, mtd->writesize, mtd->oobsize);
40356+
40357+	/* Print ecc type and ecc mode about hisilicon flash controller */
40358+	hinfc_show_info(mtd, nand_manufacturer_name(manufacturer_desc), type->name);
40359+
40360 	return 0;
40361
40362 free_detect_allocation:
40363diff --git a/drivers/mtd/nand/raw/nand_ids.c b/drivers/mtd/nand/raw/nand_ids.c
40364index b9945791a..e59b4f017 100644
40365--- a/drivers/mtd/nand/raw/nand_ids.c
40366+++ b/drivers/mtd/nand/raw/nand_ids.c
40367@@ -172,6 +172,11 @@ static const struct nand_manufacturer_desc nand_manufacturer_descs[] = {
40368 	{NAND_MFR_AMD, "AMD/Spansion", &amd_nand_manuf_ops},
40369 	{NAND_MFR_ATO, "ATO"},
40370 	{NAND_MFR_EON, "Eon"},
40371+	{NAND_MFR_WINBOND,	"Winbond"},
40372+	{NAND_MFR_ATO,		"ATO"},
40373+	{NAND_MFR_MXIC,		"MXIC"},
40374+	{NAND_MFR_ALL_FLASH,	"All-flash"},
40375+	{NAND_MFR_PARAGON,	"Paragon"},
40376 	{NAND_MFR_ESMT, "ESMT", &esmt_nand_manuf_ops},
40377 	{NAND_MFR_FUJITSU, "Fujitsu"},
40378 	{NAND_MFR_HYNIX, "Hynix", &hynix_nand_manuf_ops},
40379@@ -184,7 +189,10 @@ static const struct nand_manufacturer_desc nand_manufacturer_descs[] = {
40380 	{NAND_MFR_SANDISK, "SanDisk"},
40381 	{NAND_MFR_STMICRO, "ST Micro"},
40382 	{NAND_MFR_TOSHIBA, "Toshiba", &toshiba_nand_manuf_ops},
40383-	{NAND_MFR_WINBOND, "Winbond"},
40384+	{NAND_MFR_HEYANGTEK, "HeYangTek"},
40385+	{NAND_MFR_DOSILICON, "Dosilicon"},
40386+	{NAND_MFR_FIDELIX, "Fidelix/Dosi"}, /* Fidelix was purchased by Dosilicon */
40387+	{0x0, "Unknown"}
40388 };
40389
40390 /**
40391diff --git a/drivers/mtd/spi-nor/controllers/Kconfig b/drivers/mtd/spi-nor/controllers/Kconfig
40392index 5c0e0ec2e..bffa9c1a6 100644
40393--- a/drivers/mtd/spi-nor/controllers/Kconfig
40394+++ b/drivers/mtd/spi-nor/controllers/Kconfig
40395@@ -10,11 +10,12 @@ config SPI_ASPEED_SMC
40396 	  the host firmware. The implementation only supports SPI NOR.
40397
40398 config SPI_HISI_SFC
40399-	tristate "Hisilicon FMC SPI NOR Flash Controller(SFC)"
40400-	depends on ARCH_HISI || COMPILE_TEST
40401-	depends on HAS_IOMEM
40402+	tristate "Hisilicon FMCV100 SPI-NOR Flash Controller(SFC)"
40403+	depends on ARCH_HISI || ARCH_HISI_BVT || COMPILE_TEST
40404+	depends on HAS_IOMEM && HAS_DMA
40405 	help
40406-	  This enables support for HiSilicon FMC SPI NOR flash controller.
40407+	  This enables support for hisilicon flash memory contrller ver100
40408+	  (FMCV100)- SPI-NOR flash controller.
40409
40410 config SPI_NXP_SPIFI
40411 	tristate "NXP SPI Flash Interface (SPIFI)"
40412@@ -62,3 +63,31 @@ config SPI_INTEL_SPI_PLATFORM
40413
40414 	  To compile this driver as a module, choose M here: the module
40415 	  will be called intel-spi-platform.
40416+
40417+config MTD_SPI_IDS
40418+    bool "SPI Flash Timing Cycles Probe Function"
40419+    default n
40420+    help
40421+      This option enables hisfc300/hisfc350 used spi flash timing cylces
40422+      probe function.
40423+      If your use hisfc300 and hisfc350, this function should be select.
40424+
40425+config CLOSE_SPI_8PIN_4IO
40426+	bool "Close SPI device Quad SPI mode for some 8PIN chip"
40427+	default y if ARCH_HISI_BVT
40428+	help
40429+	Hifmcv100 and Hisfcv350 support Quad SPI mode and Quad&addr SPI mode.
40430+	But some 8PIN chip does not support this mode when HOLD/IO3 PIN
40431+	was used by reset operation.
40432+	Usually, your should not config this option.
40433+
40434+config HISI_SPI_BLOCK_PROTECT
40435+	bool "Hisilicon Spi Nor Device BP(Block Protect) Support"
40436+	depends on SPI_HISI_SFC
40437+	default y if SPI_HISI_SFC
40438+	help
40439+	  HISI SFC supports BP(Block Protect) feature to preestablish a series
40440+	  area to avoid writing and erasing, except to reading. With this macro
40441+	  definition we can get the BP info which was setted before. The
40442+	  BOTTOM/TOP bit is setted to BOTTOM, it means the lock area starts
40443+	  from 0 address.
40444diff --git a/drivers/net/ethernet/hisilicon/Kconfig b/drivers/net/ethernet/hisilicon/Kconfig
40445index 44f9279cd..cf0b370d0 100644
40446--- a/drivers/net/ethernet/hisilicon/Kconfig
40447+++ b/drivers/net/ethernet/hisilicon/Kconfig
40448@@ -137,4 +137,6 @@ config HNS3_ENET
40449
40450 endif #HNS3
40451
40452+source "drivers/net/ethernet/hisilicon/higmac/Kconfig"
40453+
40454 endif # NET_VENDOR_HISILICON
40455diff --git a/drivers/net/ethernet/hisilicon/Makefile b/drivers/net/ethernet/hisilicon/Makefile
40456index 7f76d4120..95598fffc 100644
40457--- a/drivers/net/ethernet/hisilicon/Makefile
40458+++ b/drivers/net/ethernet/hisilicon/Makefile
40459@@ -8,4 +8,5 @@ obj-$(CONFIG_HIP04_ETH) += hip04_eth.o
40460 obj-$(CONFIG_HNS_MDIO) += hns_mdio.o
40461 obj-$(CONFIG_HNS) += hns/
40462 obj-$(CONFIG_HNS3) += hns3/
40463-obj-$(CONFIG_HISI_FEMAC) += hisi_femac.o
40464+obj-$(CONFIG_HISI_FEMAC) += hisi-femac/
40465+obj-$(CONFIG_HIETH_GMAC) += higmac/
40466diff --git a/drivers/net/ethernet/hisilicon/higmac/Kconfig b/drivers/net/ethernet/hisilicon/higmac/Kconfig
40467new file mode 100644
40468index 000000000..97b173e00
40469--- /dev/null
40470+++ b/drivers/net/ethernet/hisilicon/higmac/Kconfig
40471@@ -0,0 +1,106 @@
40472+#
40473+# higmac family network device configuration
40474+#
40475+
40476+menuconfig HIETH_GMAC
40477+	tristate "hieth gmac family network device support"
40478+	select PHYLIB
40479+	select RESET_CONTROLLER
40480+	help
40481+	  This selects the hieth gmac family network device.
40482+	  The gigabit switch fabric (GSF) receives and transmits data over Ethernet
40483+	  ports at 10/100/1000 Mbit/s in full-duplex or half-duplex mode.
40484+	  The Ethernet port exchanges data with the CPU port, and supports
40485+	  the energy efficient Ethernet (EEE) and wake on LAN (WoL) functions.
40486+
40487+if HIETH_GMAC
40488+
40489+config HIGMAC_DDR_64BIT
40490+	bool "higmac ddr width 64 bit"
40491+	depends on ARM64
40492+	default n
40493+	help
40494+	  This define the higmac supports DDR width 64 bit.
40495+	  In the newest version, the DDR size may be 8G.
40496+	  But in old version, the higmac only supports DDR width 32 bit.
40497+	  The default value is false.
40498+
40499+config HIGMAC_DESC_4WORD
40500+        bool "higmac descriptor size is 4 words"
40501+        default y
40502+        help
40503+	  This define the size of higmac descriptor structure.
40504+	  In the newest version, descriptor size is 4 words.
40505+	  But in some old version, the size is 8 words.
40506+	  The default value is true.
40507+
40508+config HIGMAC_RXCSUM
40509+        bool "higmac Receive checksumming offload supported"
40510+        default y
40511+        help
40512+	  This indicate MAC support Receive checksumming offload.
40513+	  Support IPv4 and IPv6, tcp and udp.
40514+	  The default value is enabled.
40515+	  If old version MAC does not support, disable this option please.
40516+
40517+config RX_FLOW_CTRL_SUPPORT
40518+	bool "rx flow ctrl supported"
40519+	default y
40520+	help
40521+	  Rx flow ctrl supported, default is enabled.
40522+	  When we received pause frame,
40523+	  we will stop transmiting data frame for some time.
40524+	  The stopping time is the time filled in pause frame.
40525+
40526+config TX_FLOW_CTRL_SUPPORT
40527+	bool "tx flow ctrl supported"
40528+	default y
40529+	help
40530+	  Tx flow ctrl supported, default is enabled.
40531+	  When we has no buffer to receive packet,
40532+	  we will send pause frame.
40533+	  When buffer is available, we will send zero-quanta pause frame.
40534+
40535+config TX_FLOW_CTRL_PAUSE_TIME
40536+	hex "tx flow ctrl pause time"
40537+	default "0xFFFF"
40538+	help
40539+	  The pause time filled in the sending pause frame.
40540+	  The unit is the time for transmiting 512 bit data.
40541+	  This value is 16 bit, so its value is 0x0000~0xFFFF.
40542+	  The default value is 0xFFFF.
40543+
40544+config TX_FLOW_CTRL_PAUSE_INTERVAL
40545+	hex "tx flow ctrl pause interval"
40546+	default "0xFFFF"
40547+	help
40548+	  The interval time for sending pause frame.
40549+	  When the remainint amount of receive queue is below tx flow ctrl active threshold,
40550+	  we will wait this time to transmiting pause frame.
40551+	  The unit is the time for transmiting 512 bit data.
40552+	  This value is 16 bit, so its value is 0x0000~0xFFFF.
40553+	  The default value is 0xFFFF.
40554+
40555+config TX_FLOW_CTRL_ACTIVE_THRESHOLD
40556+	int "tx flow ctrl active threshold"
40557+	default "16"
40558+	range 1 127
40559+	help
40560+	  The threshold for activing tx flow ctrl.
40561+	  When the left amount of receive queue descriptors is below this threshold,
40562+	  hardware will send pause frame immediately.
40563+	  We advise this value is set smaller than 64. Too bigger is not a good choice.
40564+	  This value must be smaller than tx flow ctrl deactive threshold.
40565+
40566+config TX_FLOW_CTRL_DEACTIVE_THRESHOLD
40567+	int "tx flow ctrl deactive threshold"
40568+	default "32"
40569+	range 1 127
40570+	help
40571+	  The threshold for deactiving tx flow ctrl.
40572+	  When the left amount of receive queue descriptors is above or equal with this threshold,
40573+	  hardware will exit flow control state.
40574+	  We advise this value is set smaller than 64. Too bigger is not a good choice.
40575+	  This value must be larger than tx flow ctrl active threshold.
40576+
40577+endif # HIETH_GMAC
40578diff --git a/drivers/net/ethernet/hisilicon/higmac/Makefile b/drivers/net/ethernet/hisilicon/higmac/Makefile
40579new file mode 100644
40580index 000000000..b19e27d42
40581--- /dev/null
40582+++ b/drivers/net/ethernet/hisilicon/higmac/Makefile
40583@@ -0,0 +1,2 @@
40584+obj-$(CONFIG_HIETH_GMAC) += hieth-gmac.o
40585+hieth-gmac-objs := board.o higmac.o pm.o util.o autoeee/autoeee.o autoeee/phy_id_table.o
40586diff --git a/drivers/net/ethernet/hisilicon/higmac/autoeee/autoeee.c b/drivers/net/ethernet/hisilicon/higmac/autoeee/autoeee.c
40587new file mode 100644
40588index 000000000..05c2b6205
40589--- /dev/null
40590+++ b/drivers/net/ethernet/hisilicon/higmac/autoeee/autoeee.c
40591@@ -0,0 +1,162 @@
40592+/*
40593+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
40594+ * Description: Higmac driver autoeee process
40595+ * Author: KTP_BSP
40596+ * Create: 2018-10-08
40597+ */
40598+
40599+#include "autoeee.h"
40600+#include "../higmac.h"
40601+#include <linux/phy.h>
40602+#include <linux/micrel_phy.h>
40603+
40604+static u32 set_link_stat(struct higmac_netdev_local const *ld)
40605+{
40606+	u32 link_stat = 0;
40607+
40608+	switch (ld->phy->speed) {
40609+	case SPEED_10:
40610+		link_stat |= HIGMAC_SPD_10M;
40611+		break;
40612+	case SPEED_100:
40613+		link_stat |= HIGMAC_SPD_100M;
40614+		break;
40615+	case SPEED_1000:
40616+		link_stat |= HIGMAC_SPD_1000M;
40617+		break;
40618+	default:
40619+		break;
40620+	}
40621+	return link_stat;
40622+}
40623+
40624+static void set_eee_clk(struct higmac_netdev_local const *ld, u32 phy_id)
40625+{
40626+	u32 v;
40627+
40628+	if ((phy_id & REALTEK_PHY_MASK) == REALTEK_PHY_ID_8211E) {
40629+		v = readl(ld->gmac_iobase + EEE_CLK);
40630+		v &= ~MASK_EEE_CLK;
40631+		v |= BIT_DISABLE_TX_CLK;
40632+		writel(v, ld->gmac_iobase + EEE_CLK);
40633+	} else if ((phy_id & MICREL_PHY_ID_MASK) == PHY_ID_KSZ9031) {
40634+		v = readl(ld->gmac_iobase + EEE_CLK);
40635+		v &= ~MASK_EEE_CLK;
40636+		v |= (BIT_DISABLE_TX_CLK | BIT_PHY_KSZ9031);
40637+		writel(v, ld->gmac_iobase + EEE_CLK);
40638+	}
40639+}
40640+
40641+static void enable_eee(struct higmac_netdev_local const *ld)
40642+{
40643+	u32 v;
40644+
40645+	/* EEE_1us: 0x7c for 125M */
40646+	writel(0x7c, ld->gmac_iobase +
40647+	       EEE_TIME_CLK_CNT);
40648+	writel(0x1e0400, ld->gmac_iobase + EEE_TIMER);
40649+
40650+	v = readl(ld->gmac_iobase + EEE_LINK_STATUS);
40651+	v |= 0x3 << 1; /* auto EEE and ... */
40652+	v |= BIT_PHY_LINK_STATUS; /* phy linkup */
40653+	writel(v, ld->gmac_iobase + EEE_LINK_STATUS);
40654+
40655+	v = readl(ld->gmac_iobase + EEE_ENABLE);
40656+	v |= BIT_EEE_ENABLE; /* enable EEE */
40657+	writel(v, ld->gmac_iobase + EEE_ENABLE);
40658+}
40659+
40660+static void set_phy_eee_mode(struct higmac_netdev_local const *ld)
40661+{
40662+	u32 v;
40663+	if (netif_msg_wol(ld))
40664+		pr_info("enter phy-EEE mode\n");
40665+
40666+	v = readl(ld->gmac_iobase + EEE_ENABLE);
40667+	v &= ~BIT_EEE_ENABLE; /* disable auto-EEE */
40668+	writel(v, ld->gmac_iobase + EEE_ENABLE);
40669+}
40670+
40671+void init_autoeee(struct higmac_netdev_local *ld)
40672+{
40673+	int phy_id;
40674+	int eee_available, lp_eee_capable;
40675+	u32 v, link_stat;
40676+	struct phy_info *phy_info = NULL;
40677+	if (ld == NULL || ld->eee_init == NULL || ld->phy == NULL)
40678+		return;
40679+	phy_id = ld->phy->phy_id;
40680+	if (ld->eee_init != NULL)
40681+		goto eee_init;
40682+
40683+	phy_info = phy_search_ids(phy_id);
40684+	if (phy_info == NULL)
40685+		goto not_support;
40686+
40687+	eee_available = phy_info->eee_available;
40688+	if (netif_msg_wol(ld) && phy_info->name != NULL)
40689+		pr_info("fit phy_id:0x%x, phy_name:%s, eee:%d\n",
40690+			phy_info->phy_id, phy_info->name, eee_available);
40691+
40692+	if (!eee_available)
40693+		goto not_support;
40694+
40695+	if (eee_available == PHY_EEE) {
40696+		set_phy_eee_mode(ld);
40697+		return;
40698+	}
40699+
40700+	ld->eee_init = phy_info->eee_init;
40701+eee_init:
40702+	link_stat = set_link_stat(ld);
40703+
40704+	lp_eee_capable = ld->eee_init(ld->phy);
40705+	if (lp_eee_capable < 0)
40706+		return;
40707+
40708+	if (ld->phy->link) {
40709+		if (((u32)lp_eee_capable) & link_stat) {
40710+			set_eee_clk(ld, phy_id);
40711+			enable_eee(ld);
40712+
40713+			if (netif_msg_wol(ld))
40714+				pr_info("enter auto-EEE mode\n");
40715+		} else {
40716+			if (netif_msg_wol(ld))
40717+				pr_info("link partner not support EEE\n");
40718+		}
40719+	} else {
40720+		v = readl(ld->gmac_iobase + EEE_LINK_STATUS);
40721+		v &= ~(BIT_PHY_LINK_STATUS); /* phy linkdown */
40722+		writel(v, ld->gmac_iobase + EEE_LINK_STATUS);
40723+	}
40724+
40725+	return;
40726+
40727+not_support:
40728+	ld->eee_init = NULL;
40729+	if (netif_msg_wol(ld))
40730+		pr_info("non-EEE mode\n");
40731+}
40732+
40733+void eee_phy_linkdown(struct higmac_netdev_local const *ld)
40734+{
40735+	u32 v;
40736+	if (ld == NULL)
40737+		return;
40738+	v = readl(ld->gmac_iobase + EEE_LINK_STATUS);
40739+	/* update phy link state */
40740+	v &= ~BIT_PHY_LINK_STATUS;
40741+	writel(v, ld->gmac_iobase + EEE_LINK_STATUS);
40742+}
40743+
40744+void eee_phy_linkup(struct higmac_netdev_local const *ld)
40745+{
40746+	u32 v;
40747+	if (ld == NULL)
40748+		return;
40749+	v = readl(ld->gmac_iobase + EEE_LINK_STATUS);
40750+	/* update phy link state */
40751+	v |= BIT_PHY_LINK_STATUS;
40752+	writel(v, ld->gmac_iobase + EEE_LINK_STATUS);
40753+}
40754diff --git a/drivers/net/ethernet/hisilicon/higmac/autoeee/autoeee.h b/drivers/net/ethernet/hisilicon/higmac/autoeee/autoeee.h
40755new file mode 100644
40756index 000000000..30cbb9799
40757--- /dev/null
40758+++ b/drivers/net/ethernet/hisilicon/higmac/autoeee/autoeee.h
40759@@ -0,0 +1,52 @@
40760+/*
40761+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
40762+ * Description: autoeee head file
40763+ * Author: KTP_BSP
40764+ * Create: 2018-10-08
40765+ */
40766+
40767+#ifndef	_AUTO_EEE_H
40768+#define	_AUTO_EEE_H
40769+
40770+#include "../higmac.h"
40771+
40772+#define NO_EEE          0
40773+#define MAC_EEE         1
40774+#define PHY_EEE         2
40775+#define PARTNER_EEE     2
40776+
40777+struct phy_info {
40778+	char *name;
40779+	int phy_id;
40780+	char eee_available; /* eee support by this phy */
40781+	int (*eee_init)(struct phy_device *phy_dev);
40782+};
40783+
40784+/* GMAC register definition */
40785+#define EEE_CLK			0x800
40786+#define MASK_EEE_CLK		(0x3 << 20)
40787+#define BIT_DISABLE_TX_CLK	BIT(21)
40788+#define BIT_PHY_KSZ9031		BIT(20)
40789+#define EEE_ENABLE		0x808
40790+#define BIT_EEE_ENABLE		BIT(0)
40791+#define EEE_TIMER		0x80C
40792+#define EEE_LINK_STATUS		0x810
40793+#define BIT_PHY_LINK_STATUS	BIT(0)
40794+#define EEE_TIME_CLK_CNT	0x814
40795+
40796+/* ----------------------------phy register-------------------------------*/
40797+/* MMD: MDIO Manageable Device */
40798+#define MACR		0x0D
40799+#define MAADR		0x0E
40800+#define EEE_DEV		0x3
40801+#define EEE_CAPABILITY	0x14
40802+#define	EEELPAR_DEV	0x7
40803+#define EEELPAR		0x3D /* EEE link partner ability register */
40804+#define EEE_ADVERTISE	0x3c
40805+#define LP_1000BASE_EEE	BIT(2)
40806+#define LP_100BASE_EEE	BIT(1)
40807+
40808+struct phy_info *phy_search_ids(int phy_id);
40809+void init_autoeee(struct higmac_netdev_local *ld);
40810+
40811+#endif
40812diff --git a/drivers/net/ethernet/hisilicon/higmac/autoeee/phy_id_table.c b/drivers/net/ethernet/hisilicon/higmac/autoeee/phy_id_table.c
40813new file mode 100644
40814index 000000000..d98bbf1f0
40815--- /dev/null
40816+++ b/drivers/net/ethernet/hisilicon/higmac/autoeee/phy_id_table.c
40817@@ -0,0 +1,184 @@
40818+/*
40819+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
40820+ * Description: Higmac phy id table
40821+ * Author: KTP_BSP
40822+ * Create: 2018-10-08
40823+ */
40824+
40825+#include "../higmac.h"
40826+#include "autoeee.h"
40827+#include <linux/delay.h>
40828+#include <linux/kernel.h>
40829+#include <linux/phy.h>
40830+
40831+struct phy_info phy_info_table[];
40832+
40833+struct phy_info *phy_search_ids(int phy_id)
40834+{
40835+	int i;
40836+	struct phy_info *fit_info = NULL;
40837+
40838+	for (i = 0; phy_info_table[i].name; i++) {
40839+		if (phy_id == phy_info_table[i].phy_id) {
40840+			fit_info = &phy_info_table[i];
40841+			break;
40842+		}
40843+	}
40844+
40845+	return fit_info;
40846+}
40847+
40848+static inline int phy_mmd_read(struct phy_device *phy_dev,
40849+			       u32 mmd_device, u32 regnum)
40850+{
40851+	phy_write(phy_dev, MACR, mmd_device); /* function = 00 address */
40852+	phy_write(phy_dev, MAADR, regnum);
40853+	phy_write(phy_dev, MACR, 0x4000 | mmd_device); /* function = 01 data */
40854+
40855+	return phy_read(phy_dev, MAADR);
40856+}
40857+
40858+static inline int phy_mmd_write(struct phy_device *phy_dev, u32 mmd_device,
40859+				u32 regnum, u16 val)
40860+{
40861+	phy_write(phy_dev, MACR, mmd_device); /* function = 00 address */
40862+	phy_write(phy_dev, MAADR, regnum);
40863+	phy_write(phy_dev, MACR, 0x4000 | mmd_device); /* function = 01 data */
40864+
40865+	return phy_write(phy_dev, MAADR, val);
40866+}
40867+
40868+static int smsc_lan8740_init(struct phy_device *phy_dev)
40869+{
40870+	static int first_time = 0;
40871+	int v;
40872+	u32 eee_type = 0;
40873+
40874+	if (!first_time) {
40875+		/* Realtek LAN 8740 start to enable eee */
40876+		int eee_lan;
40877+
40878+		eee_lan = phy_read(phy_dev, 0x10);
40879+		if (eee_lan < 0)
40880+			return eee_lan;
40881+		eee_lan = (u32)eee_lan | 0x4;
40882+		phy_write(phy_dev, 0x10, eee_lan);
40883+		eee_lan = phy_read(phy_dev, 0x10);
40884+		if (eee_lan < 0)
40885+			return eee_lan;
40886+		/* auto negotiate after enable eee */
40887+		eee_lan = phy_read(phy_dev, 0x0);
40888+		if (eee_lan < 0)
40889+			return eee_lan;
40890+		eee_lan = (u32)eee_lan | 0x200;
40891+		phy_write(phy_dev, 0x0, eee_lan);
40892+		first_time = 1;
40893+	}
40894+
40895+	v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR);
40896+	if ((u32)v & LP_1000BASE_EEE)
40897+		eee_type |= HIGMAC_SPD_1000M;
40898+	if ((u32)v & LP_100BASE_EEE)
40899+		eee_type |= HIGMAC_SPD_100M;
40900+
40901+	return (int)eee_type;
40902+}
40903+
40904+#define RTL8211EG_MAC	0
40905+#if RTL8211EG_MAC
40906+static int rtl8211eg_mac_init(struct phy_device *phy_dev)
40907+{
40908+	static int first_time = 0;
40909+	/* Realtek 8211EG start reset to change eee to mac */
40910+	int v;
40911+	u32 eee_type = 0;
40912+
40913+	if (!first_time) {
40914+		int tmp;
40915+
40916+		phy_write(phy_dev, 0x1f, 0x0);
40917+		phy_write(phy_dev, MII_BMCR, BMCR_RESET); /* reset phy */
40918+		do { /* wait phy restart over */
40919+			udelay(1);
40920+			tmp = phy_read(phy_dev, MII_BMSR);
40921+			/* no need to wait AN finished */
40922+			tmp &= (BMSR_ANEGCOMPLETE | BMSR_ANEGCAPABLE);
40923+		} while (!tmp);
40924+
40925+		phy_write(phy_dev, 0x1f, 0x7);
40926+		phy_write(phy_dev, 0x1e, 0x20);
40927+		phy_write(phy_dev, 0x1b, 0xa03a);
40928+		phy_write(phy_dev, 0x1f, 0x0);
40929+
40930+		first_time = 1;
40931+	}
40932+
40933+	v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR);
40934+	if ((u32)v & LP_1000BASE_EEE)
40935+		eee_type |= HIGMAC_SPD_1000M;
40936+	if ((u32)v & LP_100BASE_EEE)
40937+		eee_type |= HIGMAC_SPD_100M;
40938+
40939+	return (int)eee_type;
40940+}
40941+#else
40942+static int rtl8211eg_init(struct phy_device *phy_dev)
40943+{
40944+	u32 eee_type = 0;
40945+	u32 v;
40946+
40947+	v = (u32)phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR);
40948+	if (v & LP_1000BASE_EEE)
40949+		eee_type |= HIGMAC_SPD_1000M;
40950+	if (v & LP_100BASE_EEE)
40951+		eee_type |= HIGMAC_SPD_100M;
40952+
40953+	return (int)eee_type;
40954+}
40955+#endif
40956+
40957+static int festa_v200_init(struct phy_device *phy_dev)
40958+{
40959+	static int first_time_init = 0;
40960+	int v;
40961+	u32 eee_type = 0;
40962+
40963+	if (!first_time_init) {
40964+		/* EEE_CAPABILITY register: support 100M-BaseT */
40965+		v = phy_mmd_read(phy_dev, EEE_DEV, EEE_CAPABILITY);
40966+		phy_mmd_write(phy_dev, EEE_DEV, EEE_CAPABILITY,
40967+			      ((u32)v) | BIT(1));
40968+
40969+		/* EEE_ADVERTISEMENT register: advertising 100M-BaseT */
40970+		v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEE_ADVERTISE);
40971+		phy_mmd_write(phy_dev, EEELPAR_DEV, EEE_ADVERTISE,
40972+			      ((u32)v) | BIT(1));
40973+
40974+		v = phy_read(phy_dev, MII_BMCR);
40975+		if (v < 0)
40976+			return v;
40977+		v = (u32)v | (BMCR_ANENABLE | BMCR_ANRESTART);
40978+		phy_write(phy_dev, MII_BMCR, v); /* auto-neg restart */
40979+
40980+		first_time_init = 1;
40981+	}
40982+
40983+	v = phy_mmd_read(phy_dev, EEELPAR_DEV, EEELPAR);
40984+	if ((u32)v & LP_1000BASE_EEE)
40985+		eee_type |= HIGMAC_SPD_1000M;
40986+	if ((u32)v & LP_100BASE_EEE)
40987+		eee_type |= HIGMAC_SPD_100M;
40988+
40989+	return (int)eee_type;
40990+}
40991+
40992+struct phy_info phy_info_table[] = {
40993+	/* phy_name      phy_id      eee_available  phy_driver */
40994+	{"SMSC LAN8740", 0x0007c110, MAC_EEE, &smsc_lan8740_init},
40995+#if RTL8211EG_MAC
40996+	{"Realtek 8211EG", 0x001cc915, MAC_EEE, &rtl8211eg_mac_init},
40997+#else
40998+	{"Realtek 8211EG", 0x001cc915, PHY_EEE, &rtl8211eg_init},
40999+#endif
41000+	{"Festa V200", HISILICON_PHY_ID_FESTAV200, MAC_EEE, &festa_v200_init},
41001+};
41002diff --git a/drivers/net/ethernet/hisilicon/higmac/board.c b/drivers/net/ethernet/hisilicon/higmac/board.c
41003new file mode 100644
41004index 000000000..b7a1d879d
41005--- /dev/null
41006+++ b/drivers/net/ethernet/hisilicon/higmac/board.c
41007@@ -0,0 +1,118 @@
41008+/*
41009+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
41010+ * Description: Higmac driver board file
41011+ * Author: KTP_BSP
41012+ * Create: 2018-10-08
41013+ */
41014+
41015+#include <linux/clk.h>
41016+#include <linux/kernel.h>
41017+#include <linux/reset.h>
41018+#include "higmac.h"
41019+
41020+void higmac_mac_core_reset(struct higmac_netdev_local *priv)
41021+{
41022+	/* undo reset */
41023+	if (priv == NULL || priv->port_rst == NULL)
41024+		return;
41025+	reset_control_deassert(priv->port_rst);
41026+	usleep_range(50, 60); /* wait 50~60us */
41027+
41028+	/* soft reset mac port */
41029+	reset_control_assert(priv->port_rst);
41030+	usleep_range(50, 60); /* wait 50~60us */
41031+	/* undo reset */
41032+	reset_control_deassert(priv->port_rst);
41033+}
41034+
41035+void higmac_hw_internal_phy_reset(struct higmac_netdev_local *priv)
41036+{
41037+}
41038+
41039+void higmac_hw_phy_reset(struct higmac_netdev_local *priv)
41040+{
41041+	if (priv == NULL)
41042+		return;
41043+	if (priv->internal_phy)
41044+		higmac_hw_internal_phy_reset(priv);
41045+	else
41046+		higmac_hw_external_phy_reset(priv);
41047+}
41048+
41049+void higmac_hw_external_phy_reset(struct higmac_netdev_local *priv)
41050+{
41051+	if (priv == NULL)
41052+		return;
41053+	if (priv->phy_rst != NULL) {
41054+		/* write 0 to cancel reset */
41055+		reset_control_deassert(priv->phy_rst);
41056+		msleep(50); /* wait 50ms */
41057+
41058+		/* HIFONE or 98cv200 use CRG register to reset phy */
41059+		/* RST_BIT, write 0 to reset phy, write 1 to cancel reset */
41060+		reset_control_assert(priv->phy_rst);
41061+
41062+		/*
41063+		 * delay some time to ensure reset ok,
41064+		 * this depends on PHY hardware feature
41065+		 */
41066+		msleep(50); /* wait 50ms */
41067+
41068+		/* write 0 to cancel reset */
41069+		reset_control_deassert(priv->phy_rst);
41070+		/* delay some time to ensure later MDIO access */
41071+		msleep(50); /* wait 50ms */
41072+	}
41073+}
41074+
41075+void higmac_internal_phy_clk_disable(struct higmac_netdev_local const *priv)
41076+{
41077+}
41078+
41079+void higmac_internal_phy_clk_enable(struct higmac_netdev_local const *priv)
41080+{
41081+}
41082+
41083+void higmac_hw_all_clk_disable(struct higmac_netdev_local *priv)
41084+{
41085+	/*
41086+	 * If macif clock is enabled when suspend, we should
41087+	 * disable it here.
41088+	 * Because when resume, PHY will link up again and
41089+	 * macif clock will be enabled too. If we don't disable
41090+	 * macif clock in suspend, macif clock will be enabled twice.
41091+	 */
41092+	if (priv == NULL || priv->clk == NULL || priv->netdev == NULL || priv->macif_clk == NULL)
41093+		return;
41094+
41095+	if (priv->netdev->flags & IFF_UP)
41096+		clk_disable_unprepare(priv->macif_clk);
41097+
41098+	/*
41099+	 * This is called in suspend, when net device is down,
41100+	 * MAC clk is disabled.
41101+	 * So we need to judge whether MAC clk is enabled,
41102+	 * otherwise kernel will WARNING if clk disable twice.
41103+	 */
41104+	if (priv->netdev->flags & IFF_UP)
41105+		clk_disable_unprepare(priv->clk);
41106+
41107+	if (priv->internal_phy)
41108+		higmac_internal_phy_clk_disable(priv);
41109+}
41110+
41111+void higmac_hw_all_clk_enable(struct higmac_netdev_local *priv)
41112+{
41113+	if (priv == NULL || priv->netdev == NULL || priv->clk == NULL)
41114+		return;
41115+
41116+	if (priv->internal_phy)
41117+		higmac_internal_phy_clk_enable(priv);
41118+
41119+	if (priv->netdev->flags & IFF_UP)
41120+		clk_prepare_enable(priv->macif_clk);
41121+
41122+	/* If net device is down when suspend, we should not enable MAC clk. */
41123+	if (priv->netdev->flags & IFF_UP)
41124+		clk_prepare_enable(priv->clk);
41125+}
41126diff --git a/drivers/net/ethernet/hisilicon/higmac/higmac.c b/drivers/net/ethernet/hisilicon/higmac/higmac.c
41127new file mode 100644
41128index 000000000..e77712344
41129--- /dev/null
41130+++ b/drivers/net/ethernet/hisilicon/higmac/higmac.c
41131@@ -0,0 +1,2645 @@
41132+/*
41133+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
41134+ * Description: Higmac driver main process
41135+ * Author: KTP_BSP
41136+ * Create: 2018-10-08
41137+ */
41138+
41139+#include "higmac.h"
41140+#include "util.h"
41141+#include "autoeee/autoeee.h"
41142+#include "sockioctl.h"
41143+#include "pm.h"
41144+
41145+#include <linux/kernel.h>
41146+#include <linux/errno.h>
41147+#include <linux/unistd.h>
41148+#include <linux/interrupt.h>
41149+#include <linux/delay.h>
41150+#include <linux/netdevice.h>
41151+#include <linux/etherdevice.h>
41152+#include <linux/skbuff.h>
41153+#include <linux/spinlock.h>
41154+#include <linux/mm.h>
41155+#include <linux/mii.h>
41156+#include <linux/ethtool.h>
41157+#include <linux/phy.h>
41158+#include <linux/dma-mapping.h>
41159+#include <linux/workqueue.h>
41160+#include <linux/device.h>
41161+#include <linux/atomic.h>
41162+#include <linux/platform_device.h>
41163+#include <linux/capability.h>
41164+#include <linux/time.h>
41165+#include <asm/setup.h>
41166+#include <linux/proc_fs.h>
41167+#include <linux/module.h>
41168+
41169+#include <linux/circ_buf.h>
41170+#include <linux/of_net.h>
41171+#include <linux/of_mdio.h>
41172+#include <linux/clk.h>
41173+#include <linux/reset.h>
41174+
41175+#define has_tso_cap(hw_cap)		((((hw_cap) >> 28) & 0x3) == VER_TSO)
41176+#define has_rxhash_cap(hw_cap)		((hw_cap) & BIT(30))
41177+#define has_rss_cap(hw_cap)		((hw_cap) & BIT(31))
41178+
41179+#define DEFAULT_MSG_ENABLE (NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK)
41180+static int debug = -1;
41181+module_param(debug, int, 0000);
41182+MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)");
41183+
41184+static void higmac_set_desc_depth(struct higmac_netdev_local const *priv,
41185+		  u32 rx, u32 tx)
41186+{
41187+	u32 reg, val;
41188+	int i;
41189+
41190+	writel(BITS_RX_FQ_DEPTH_EN, priv->gmac_iobase + RX_FQ_REG_EN);
41191+	val = readl(priv->gmac_iobase + RX_FQ_DEPTH);
41192+	val &= ~Q_ADDR_HI8_MASK;
41193+	val |= rx << DESC_WORD_SHIFT;
41194+	writel(val, priv->gmac_iobase + RX_FQ_DEPTH);
41195+	writel(0, priv->gmac_iobase + RX_FQ_REG_EN);
41196+
41197+	writel(BITS_RX_BQ_DEPTH_EN, priv->gmac_iobase + RX_BQ_REG_EN);
41198+	val = readl(priv->gmac_iobase + RX_BQ_DEPTH);
41199+	val &= ~Q_ADDR_HI8_MASK;
41200+	val |= rx << DESC_WORD_SHIFT;
41201+	writel(val, priv->gmac_iobase + RX_BQ_DEPTH);
41202+	for (i = 1; i < priv->num_rxqs; i++) {
41203+		reg = rx_bq_depth_queue(i);
41204+		val = readl(priv->gmac_iobase + reg);
41205+		val &= ~Q_ADDR_HI8_MASK;
41206+		val |= rx << DESC_WORD_SHIFT;
41207+		writel(val, priv->gmac_iobase + reg);
41208+	}
41209+	writel(0, priv->gmac_iobase + RX_BQ_REG_EN);
41210+
41211+	writel(BITS_TX_BQ_DEPTH_EN, priv->gmac_iobase + TX_BQ_REG_EN);
41212+	val = readl(priv->gmac_iobase + TX_BQ_DEPTH);
41213+	val &= ~Q_ADDR_HI8_MASK;
41214+	val |= tx << DESC_WORD_SHIFT;
41215+	writel(val, priv->gmac_iobase + TX_BQ_DEPTH);
41216+	writel(0, priv->gmac_iobase + TX_BQ_REG_EN);
41217+
41218+	writel(BITS_TX_RQ_DEPTH_EN, priv->gmac_iobase + TX_RQ_REG_EN);
41219+	val = readl(priv->gmac_iobase + TX_RQ_DEPTH);
41220+	val &= ~Q_ADDR_HI8_MASK;
41221+	val |= tx << DESC_WORD_SHIFT;
41222+	writel(val, priv->gmac_iobase + TX_RQ_DEPTH);
41223+	writel(0, priv->gmac_iobase + TX_RQ_REG_EN);
41224+}
41225+
41226+static void higmac_set_rx_fq(struct higmac_netdev_local const *priv,
41227+		  dma_addr_t phy_addr)
41228+{
41229+#if defined(CONFIG_HIGMAC_DDR_64BIT)
41230+	u32 val;
41231+#endif
41232+	writel(BITS_RX_FQ_START_ADDR_EN, priv->gmac_iobase + RX_FQ_REG_EN);
41233+#if defined(CONFIG_HIGMAC_DDR_64BIT)
41234+	val = readl(priv->gmac_iobase + RX_FQ_DEPTH);
41235+	val &= Q_ADDR_HI8_MASK;
41236+	val |= (phy_addr >> REG_BIT_WIDTH) << Q_ADDR_HI8_OFFSET;
41237+	writel(val, priv->gmac_iobase + RX_FQ_DEPTH);
41238+#endif
41239+	writel((u32)phy_addr, priv->gmac_iobase + RX_FQ_START_ADDR);
41240+	writel(0, priv->gmac_iobase + RX_FQ_REG_EN);
41241+}
41242+
41243+static void higmac_set_rx_bq(struct higmac_netdev_local const *priv,
41244+		  dma_addr_t phy_addr)
41245+{
41246+#if defined(CONFIG_HIGMAC_DDR_64BIT)
41247+	u32 val;
41248+#endif
41249+	writel(BITS_RX_BQ_START_ADDR_EN, priv->gmac_iobase + RX_BQ_REG_EN);
41250+#if defined(CONFIG_HIGMAC_DDR_64BIT)
41251+	val = readl(priv->gmac_iobase + RX_BQ_DEPTH);
41252+	val &= Q_ADDR_HI8_MASK;
41253+	val |= (phy_addr >> REG_BIT_WIDTH) << Q_ADDR_HI8_OFFSET;
41254+	writel(val, priv->gmac_iobase + RX_BQ_DEPTH);
41255+#endif
41256+	writel((u32)phy_addr, priv->gmac_iobase + RX_BQ_START_ADDR);
41257+	writel(0, priv->gmac_iobase + RX_BQ_REG_EN);
41258+}
41259+
41260+static void higmac_set_tx_bq(struct higmac_netdev_local const *priv,
41261+		  dma_addr_t phy_addr)
41262+{
41263+#if defined(CONFIG_HIGMAC_DDR_64BIT)
41264+	u32 val;
41265+#endif
41266+	writel(BITS_TX_BQ_START_ADDR_EN, priv->gmac_iobase + TX_BQ_REG_EN);
41267+#if defined(CONFIG_HIGMAC_DDR_64BIT)
41268+	val = readl(priv->gmac_iobase + TX_BQ_DEPTH);
41269+	val &= Q_ADDR_HI8_MASK;
41270+	val |= (phy_addr >> REG_BIT_WIDTH) << Q_ADDR_HI8_OFFSET;
41271+	writel(val, priv->gmac_iobase + TX_BQ_DEPTH);
41272+#endif
41273+	writel((u32)phy_addr, priv->gmac_iobase + TX_BQ_START_ADDR);
41274+	writel(0, priv->gmac_iobase + TX_BQ_REG_EN);
41275+}
41276+
41277+static void higmac_set_tx_rq(struct higmac_netdev_local const *priv,
41278+		  dma_addr_t phy_addr)
41279+{
41280+#if defined(CONFIG_HIGMAC_DDR_64BIT)
41281+	u32 val;
41282+#endif
41283+	writel(BITS_TX_RQ_START_ADDR_EN, priv->gmac_iobase + TX_RQ_REG_EN);
41284+#if defined(CONFIG_HIGMAC_DDR_64BIT)
41285+	val = readl(priv->gmac_iobase + TX_RQ_DEPTH);
41286+	val &= Q_ADDR_HI8_MASK;
41287+	val |= (phy_addr >> REG_BIT_WIDTH) << Q_ADDR_HI8_OFFSET;
41288+	writel(val, priv->gmac_iobase + TX_RQ_DEPTH);
41289+#endif
41290+	writel((u32)phy_addr, priv->gmac_iobase + TX_RQ_START_ADDR);
41291+	writel(0, priv->gmac_iobase + TX_RQ_REG_EN);
41292+}
41293+
41294+static void higmac_hw_set_desc_addr(struct higmac_netdev_local const *priv)
41295+{
41296+	u32 reg;
41297+	int i;
41298+#if defined(CONFIG_HIGMAC_DDR_64BIT)
41299+	u32 val;
41300+#endif
41301+
41302+	higmac_set_rx_fq(priv, priv->RX_FQ.phys_addr);
41303+	higmac_set_rx_bq(priv, priv->RX_BQ.phys_addr);
41304+	higmac_set_tx_rq(priv, priv->TX_RQ.phys_addr);
41305+	higmac_set_tx_bq(priv, priv->TX_BQ.phys_addr);
41306+
41307+	for (i = 1; i < priv->num_rxqs; i++) {
41308+		reg = rx_bq_start_addr_queue(i);
41309+		writel(BITS_RX_BQ_START_ADDR_EN,
41310+		       priv->gmac_iobase + RX_BQ_REG_EN);
41311+#if defined(CONFIG_HIGMAC_DDR_64BIT)
41312+		val = readl(priv->gmac_iobase + reg);
41313+		val &= Q_ADDR_HI8_MASK;
41314+		val |= ((priv->pool[BASE_QUEUE_NUMS + i].phys_addr) >> REG_BIT_WIDTH) <<
41315+		       Q_ADDR_HI8_OFFSET;
41316+		writel(val, priv->gmac_iobase + reg);
41317+#endif
41318+		/* pool 3 add i */
41319+		writel((u32)(priv->pool[BASE_QUEUE_NUMS + i].phys_addr),
41320+		       priv->gmac_iobase + reg);
41321+		writel(0, priv->gmac_iobase + RX_BQ_REG_EN);
41322+	}
41323+}
41324+
41325+static void higmac_set_rss_cap(struct higmac_netdev_local const *priv)
41326+{
41327+	u32 val = 0;
41328+
41329+	if (priv->has_rxhash_cap)
41330+		val |= BIT_RXHASH_CAP;
41331+	if (priv->has_rss_cap)
41332+		val |= BIT_RSS_CAP;
41333+	writel(val, priv->gmac_iobase + HW_CAP_EN);
41334+}
41335+
41336+/* config AXI bus burst and outstanding for better performance */
41337+static void higmac_axi_bus_cfg(struct higmac_netdev_local *priv)
41338+{
41339+	if (!priv->axi_bus_cfg_base)
41340+		return;
41341+
41342+#if defined(CONFIG_ARCH_HI3519) || defined(CONFIG_ARCH_HI3519V101) || \
41343+	defined(CONFIG_ARCH_HI3559) || defined(CONFIG_ARCH_HI3556) || \
41344+	defined(CONFIG_ARCH_HI3516AV200)
41345+	if (!(readl(priv->axi_bus_cfg_base) >> BURST_OUTSTANDING_OFFSET))
41346+		writel(BURST4_OUTSTANDING1, priv->axi_bus_cfg_base);
41347+#elif defined(CONFIG_ARCH_HI3521A) || defined(CONFIG_ARCH_HI3531A)
41348+	writel(BURST4_OUTSTANDING1, priv->axi_bus_cfg_base);
41349+#endif
41350+}
41351+
41352+static void higmac_hw_init(struct higmac_netdev_local *priv)
41353+{
41354+	u32 val;
41355+	u32 reg;
41356+	int i;
41357+
41358+	higmac_axi_bus_cfg(priv);
41359+
41360+	/* disable and clear all interrupts */
41361+	writel(0, priv->gmac_iobase + ENA_PMU_INT);
41362+	writel(~0, priv->gmac_iobase + RAW_PMU_INT);
41363+
41364+	for (i = 1; i < priv->num_rxqs; i++) {
41365+		reg = rss_ena_int_queue(i);
41366+		writel(0, priv->gmac_iobase + reg);
41367+	}
41368+	writel(~0, priv->gmac_iobase + RSS_RAW_PMU_INT);
41369+
41370+	/* enable CRC erro packets filter */
41371+	val = readl(priv->gmac_iobase + REC_FILT_CONTROL);
41372+	val |= BIT_CRC_ERR_PASS;
41373+	writel(val, priv->gmac_iobase + REC_FILT_CONTROL);
41374+
41375+	/* set tx min packet length */
41376+	val = readl(priv->gmac_iobase + CRF_MIN_PACKET);
41377+	val &= ~BIT_MASK_TX_MIN_LEN;
41378+	val |= ETH_HLEN << BIT_OFFSET_TX_MIN_LEN;
41379+	writel(val, priv->gmac_iobase + CRF_MIN_PACKET);
41380+
41381+	/* fix bug for udp and ip error check */
41382+	writel(CONTROL_WORD_CONFIG, priv->gmac_iobase + CONTROL_WORD);
41383+
41384+	writel(0, priv->gmac_iobase + COL_SLOT_TIME);
41385+
41386+	writel(DUPLEX_HALF, priv->gmac_iobase + MAC_DUPLEX_HALF_CTRL);
41387+
41388+	/* interrupt when rcv packets >= RX_BQ_INT_THRESHOLD */
41389+	val = RX_BQ_INT_THRESHOLD |
41390+		(TX_RQ_INT_THRESHOLD << BITS_OFFSET_TX_RQ_IN_TH);
41391+	writel(val, priv->gmac_iobase + IN_QUEUE_TH);
41392+
41393+	/* RX_BQ/TX_RQ in timeout threshold */
41394+	writel(0x10000, priv->gmac_iobase + RX_BQ_IN_TIMEOUT_TH);
41395+
41396+	writel(0x18000, priv->gmac_iobase + TX_RQ_IN_TIMEOUT_TH);
41397+
41398+	higmac_set_desc_depth(priv, RX_DESC_NUM, TX_DESC_NUM);
41399+}
41400+
41401+static inline void higmac_irq_enable(struct higmac_netdev_local *ld)
41402+{
41403+	if (ld == NULL)
41404+		return;
41405+	writel(RX_BQ_IN_INT | RX_BQ_IN_TIMEOUT_INT
41406+		| TX_RQ_IN_INT | TX_RQ_IN_TIMEOUT_INT,
41407+		ld->gmac_iobase + ENA_PMU_INT);
41408+}
41409+
41410+static void higmac_irq_enable_queue(struct higmac_netdev_local *ld,
41411+				    int rxq_id)
41412+{
41413+	if (rxq_id) {
41414+		u32 reg;
41415+
41416+		reg = rss_ena_int_queue(rxq_id);
41417+		writel(~0, ld->gmac_iobase + reg);
41418+	} else {
41419+		higmac_irq_enable(ld);
41420+	}
41421+}
41422+
41423+static inline void higmac_irq_enable_all_queue(struct higmac_netdev_local *ld)
41424+{
41425+	int i;
41426+	if (ld == NULL)
41427+		return;
41428+	for (i = 0; i < ld->num_rxqs; i++)
41429+		higmac_irq_enable_queue(ld, i);
41430+}
41431+
41432+static inline void higmac_irq_disable(struct higmac_netdev_local const *ld)
41433+{
41434+	if (ld == NULL)
41435+		return;
41436+	writel(0, ld->gmac_iobase + ENA_PMU_INT);
41437+}
41438+
41439+static void higmac_irq_disable_queue(struct higmac_netdev_local const *ld,
41440+		  int rxq_id)
41441+{
41442+	if (rxq_id) {
41443+		u32 reg;
41444+
41445+		reg = rss_ena_int_queue(rxq_id);
41446+		writel(0, ld->gmac_iobase + reg);
41447+	} else {
41448+		higmac_irq_disable(ld);
41449+	}
41450+}
41451+
41452+static inline void higmac_irq_disable_all_queue(struct higmac_netdev_local const *ld)
41453+{
41454+	int i;
41455+	if (ld == NULL)
41456+		return;
41457+	for (i = 0; i < ld->num_rxqs; i++)
41458+		higmac_irq_disable_queue(ld, i);
41459+}
41460+
41461+static bool higmac_queue_irq_disabled(struct higmac_netdev_local *ld,
41462+				      int rxq_id)
41463+{
41464+	u32 reg, val;
41465+
41466+	if (rxq_id)
41467+		reg = rss_ena_int_queue(rxq_id);
41468+	else
41469+		reg = ENA_PMU_INT;
41470+	val = readl(ld->gmac_iobase + reg);
41471+
41472+	return !val;
41473+}
41474+
41475+static inline void higmac_hw_desc_enable(struct higmac_netdev_local const *ld)
41476+{
41477+	if (ld == NULL)
41478+		return;
41479+	writel(0xF, ld->gmac_iobase + DESC_WR_RD_ENA);
41480+}
41481+
41482+static inline void higmac_hw_desc_disable(struct higmac_netdev_local const *ld)
41483+{
41484+	if (ld == NULL)
41485+		return;
41486+	writel(0, ld->gmac_iobase + DESC_WR_RD_ENA);
41487+}
41488+
41489+static inline void higmac_port_enable(struct higmac_netdev_local const *ld)
41490+{
41491+	if (ld == NULL)
41492+		return;
41493+	writel(BITS_TX_EN | BITS_RX_EN, ld->gmac_iobase + PORT_EN);
41494+}
41495+
41496+static inline void higmac_port_disable(struct higmac_netdev_local const *ld)
41497+{
41498+	if (ld != NULL) {
41499+		writel(0, ld->gmac_iobase + PORT_EN);
41500+	}
41501+}
41502+
41503+/* set gmac's multicast list, here we setup gmac's mc filter */
41504+static void higmac_gmac_multicast_list(struct net_device const *dev)
41505+{
41506+	struct higmac_netdev_local *ld = netdev_priv(dev);
41507+	unsigned int rec_filter;
41508+
41509+	rec_filter = readl(ld->gmac_iobase + REC_FILT_CONTROL);
41510+	/*
41511+	 * when set gmac in promisc mode
41512+	 * a. dev in IFF_PROMISC mode
41513+	 */
41514+	if ((dev->flags & IFF_PROMISC)) {
41515+		/* promisc mode.received all pkgs. */
41516+		rec_filter &= ~(BIT_BC_DROP_EN | BIT_MC_MATCH_EN |
41517+				BIT_UC_MATCH_EN);
41518+	} else {
41519+		/* drop uc pkgs with field 'DA' not match our's */
41520+		rec_filter |= BIT_UC_MATCH_EN;
41521+
41522+		if (dev->flags & IFF_BROADCAST) /* no broadcast */
41523+			rec_filter &= ~BIT_BC_DROP_EN;
41524+		else
41525+			rec_filter |= BIT_BC_DROP_EN;
41526+
41527+		if (netdev_mc_empty(dev) || !(dev->flags & IFF_MULTICAST)) {
41528+			/* haven't join any mc group */
41529+			writel(0, ld->gmac_iobase + PORT_MC_ADDR_LOW);
41530+			writel(0, ld->gmac_iobase + PORT_MC_ADDR_HIGH);
41531+			rec_filter |= BIT_MC_MATCH_EN;
41532+		} else if (netdev_mc_count(dev) == 1 &&
41533+				(dev->flags & IFF_MULTICAST)) {
41534+			struct netdev_hw_addr *ha = NULL;
41535+			unsigned int d;
41536+
41537+			netdev_for_each_mc_addr(ha, dev) {
41538+				d = (ha->addr[0] << 8) | (ha->addr[1]); /* shift left 8bits */
41539+				writel(d, ld->gmac_iobase + PORT_MC_ADDR_HIGH);
41540+				/* addr2 3 shift left 24 16 bits */
41541+				d = (ha->addr[2] << 24) | (ha->addr[3] << 16) |
41542+				     (ha->addr[4] << 8) | (ha->addr[5]); /* a4 << 8 | a5 */
41543+				writel(d, ld->gmac_iobase + PORT_MC_ADDR_LOW);
41544+			}
41545+			rec_filter |= BIT_MC_MATCH_EN;
41546+		} else {
41547+			rec_filter &= ~BIT_MC_MATCH_EN;
41548+		}
41549+	}
41550+	writel(rec_filter, ld->gmac_iobase + REC_FILT_CONTROL);
41551+}
41552+
41553+/*
41554+ * the func stop the hw desc and relaim the software skb resource
41555+ * before reusing the gmac, you'd better reset the gmac
41556+ */
41557+void higmac_reclaim_rx_tx_resource(struct higmac_netdev_local *ld)
41558+{
41559+	unsigned long rxflags, txflags;
41560+	int rd_offset, wr_offset;
41561+	int i;
41562+	if (ld == NULL)
41563+		return;
41564+	higmac_irq_disable_all_queue(ld);
41565+	higmac_hw_desc_disable(ld);
41566+	writel(STOP_RX_TX, ld->gmac_iobase + STOP_CMD);
41567+
41568+	spin_lock_irqsave(&ld->rxlock, rxflags);
41569+	/* RX_BQ: logic write pointer */
41570+	wr_offset = readl(ld->gmac_iobase + RX_BQ_WR_ADDR);
41571+	/* RX_BQ: software read pointer */
41572+	rd_offset = readl(ld->gmac_iobase + RX_BQ_RD_ADDR);
41573+	/* prevent to reclaim skb in rx bottom half */
41574+	writel(wr_offset, ld->gmac_iobase + RX_BQ_RD_ADDR);
41575+
41576+	for (i = 1; i < ld->num_rxqs; i++) {
41577+		u32 rx_bq_wr_reg, rx_bq_rd_reg;
41578+
41579+		rx_bq_wr_reg = rx_bq_wr_addr_queue(i);
41580+		rx_bq_rd_reg = rx_bq_rd_addr_queue(i);
41581+
41582+		wr_offset = readl(ld->gmac_iobase + rx_bq_wr_reg);
41583+		writel(wr_offset, ld->gmac_iobase + rx_bq_rd_reg);
41584+	}
41585+
41586+	/* RX_FQ: software write pointer */
41587+	wr_offset = readl(ld->gmac_iobase + RX_FQ_WR_ADDR);
41588+	/* RX_FQ: logic read pointer */
41589+	rd_offset = readl(ld->gmac_iobase + RX_FQ_RD_ADDR);
41590+	if (!rd_offset)
41591+		rd_offset = (RX_DESC_NUM - 1) << DESC_BYTE_SHIFT;
41592+	else
41593+		rd_offset -= DESC_SIZE;
41594+	/* stop to feed hw desc */
41595+	writel(rd_offset, ld->gmac_iobase + RX_FQ_WR_ADDR);
41596+
41597+	for (i = 0; i < ld->RX_FQ.count; i++) {
41598+		if (!ld->RX_FQ.skb[i])
41599+			ld->RX_FQ.skb[i] = SKB_MAGIC;
41600+	}
41601+	spin_unlock_irqrestore(&ld->rxlock, rxflags);
41602+
41603+	/*
41604+	 * no need to wait pkts in TX_RQ finish to free all skb,
41605+	 * because higmac_xmit_reclaim is in the tx_lock,
41606+	 */
41607+	spin_lock_irqsave(&ld->txlock, txflags);
41608+	/* TX_RQ: logic write */
41609+	wr_offset = readl(ld->gmac_iobase + TX_RQ_WR_ADDR);
41610+	/* TX_RQ: software read */
41611+	rd_offset = readl(ld->gmac_iobase + TX_RQ_RD_ADDR);
41612+	/* stop to reclaim tx skb */
41613+	writel(wr_offset, ld->gmac_iobase + TX_RQ_RD_ADDR);
41614+
41615+	/* TX_BQ: logic read */
41616+	rd_offset = readl(ld->gmac_iobase + TX_BQ_RD_ADDR);
41617+	if (!rd_offset)
41618+		rd_offset = (TX_DESC_NUM - 1) << DESC_BYTE_SHIFT;
41619+	else
41620+		rd_offset -= DESC_SIZE;
41621+	/* stop software tx skb */
41622+	writel(rd_offset, ld->gmac_iobase + TX_BQ_WR_ADDR);
41623+
41624+	for (i = 0; i < ld->TX_BQ.count; i++) {
41625+		if (!ld->TX_BQ.skb[i])
41626+			ld->TX_BQ.skb[i] = SKB_MAGIC;
41627+	}
41628+	spin_unlock_irqrestore(&ld->txlock, txflags);
41629+}
41630+
41631+static void higmac_monitor_func(struct timer_list *t);
41632+static void higmac_set_multicast_list(struct net_device *dev);
41633+
41634+static void higmac_hw_set_mac_addr(struct net_device *dev)
41635+{
41636+	struct higmac_netdev_local *priv = netdev_priv(dev);
41637+	unsigned char *mac = dev->dev_addr;
41638+	u32 val;
41639+
41640+	val = mac[1] | (mac[0] << 8); /* shift left 8 bits */
41641+	writel(val, priv->gmac_iobase + STATION_ADDR_HIGH);
41642+	/* mac 2 3 4 5 shift left 24 16 8 0 bits */
41643+	val = mac[5] | (mac[4] << 8) | (mac[3] << 16) | (mac[2] << 24);
41644+	writel(val, priv->gmac_iobase + STATION_ADDR_LOW);
41645+}
41646+
41647+static u32 higmac_rx_refill(struct higmac_netdev_local *priv);
41648+
41649+static void higmac_free_rx_skb(struct higmac_netdev_local *ld)
41650+{
41651+	struct sk_buff *skb = NULL;
41652+	int i;
41653+
41654+	for (i = 0; i < ld->RX_FQ.count; i++) {
41655+		skb = ld->RX_FQ.skb[i];
41656+		if (skb != NULL) {
41657+			ld->rx_skb[i] = NULL;
41658+			ld->RX_FQ.skb[i] = NULL;
41659+			if (skb == SKB_MAGIC)
41660+				continue;
41661+			dev_kfree_skb_any(skb);
41662+			/*
41663+			 * need to unmap the skb here
41664+			 * but there is no way to get the dma_addr here,
41665+			 * and unmap(TO_DEVICE) ops do nothing in fact,
41666+			 * so we ignore to call
41667+			 * dma_unmap_single(dev, dma_addr, skb->len,
41668+			 *      DMA_TO_DEVICE)
41669+			 */
41670+		}
41671+	}
41672+}
41673+
41674+static void higmac_free_tx_skb(struct higmac_netdev_local *ld)
41675+{
41676+	struct sk_buff *skb = NULL;
41677+	int i;
41678+
41679+	for (i = 0; i < ld->TX_BQ.count; i++) {
41680+		skb = ld->TX_BQ.skb[i];
41681+		if (skb != NULL) {
41682+			ld->tx_skb[i] = NULL;
41683+			ld->TX_BQ.skb[i] = NULL;
41684+			if (skb == SKB_MAGIC)
41685+				continue;
41686+			dev_kfree_skb_any(skb);
41687+			/* unmap the skb */
41688+		}
41689+	}
41690+}
41691+
41692+/* reset and re-config gmac */
41693+void higmac_restart(struct higmac_netdev_local *ld)
41694+{
41695+	unsigned long rxflags, txflags;
41696+	if (ld == NULL || ld->netdev == NULL)
41697+		return;
41698+	/* restart hw engine now */
41699+	higmac_mac_core_reset(ld);
41700+
41701+	spin_lock_irqsave(&ld->rxlock, rxflags);
41702+	spin_lock_irqsave(&ld->txlock, txflags);
41703+
41704+	higmac_free_rx_skb(ld);
41705+	higmac_free_tx_skb(ld);
41706+
41707+	pmt_reg_restore(ld);
41708+	higmac_hw_init(ld);
41709+	higmac_hw_set_mac_addr(ld->netdev);
41710+	higmac_hw_set_desc_addr(ld);
41711+
41712+	/* we don't set macif here, it will be set in adjust_link */
41713+	if (ld->netdev->flags & IFF_UP) {
41714+		/*
41715+		 * when resume, only do the following operations
41716+		 * when dev is up before suspend.
41717+		 */
41718+		higmac_rx_refill(ld);
41719+		higmac_set_multicast_list(ld->netdev);
41720+
41721+		higmac_hw_desc_enable(ld);
41722+		higmac_port_enable(ld);
41723+		higmac_irq_enable_all_queue(ld);
41724+	}
41725+	spin_unlock_irqrestore(&ld->txlock, txflags);
41726+	spin_unlock_irqrestore(&ld->rxlock, rxflags);
41727+}
41728+
41729+static int higmac_net_set_mac_address(struct net_device *dev, void *p)
41730+{
41731+	int ret;
41732+
41733+	ret = eth_mac_addr(dev, p);
41734+	if (!ret)
41735+		higmac_hw_set_mac_addr(dev);
41736+
41737+	return ret;
41738+}
41739+
41740+#define HIGMAC_LINK_CHANGE_PROTECT
41741+#define HIGMAC_MAC_TX_RESET_IN_LINKUP
41742+
41743+#ifdef HIGMAC_LINK_CHANGE_PROTECT
41744+#define HIGMAC_MS_TO_NS 1000000ULL
41745+#define HIGMAC_FLUSH_WAIT_TIME (100*HIGMAC_MS_TO_NS)
41746+/* protect code */
41747+static void higmac_linkup_flush(struct higmac_netdev_local *ld)
41748+{
41749+	int tx_bq_wr_offset, tx_bq_rd_offset;
41750+	unsigned long long time_limit, time_now;
41751+
41752+	time_now = sched_clock();
41753+	time_limit = time_now + HIGMAC_FLUSH_WAIT_TIME;
41754+
41755+	do {
41756+		tx_bq_wr_offset = readl(ld->gmac_iobase + TX_BQ_WR_ADDR);
41757+		tx_bq_rd_offset = readl(ld->gmac_iobase + TX_BQ_RD_ADDR);
41758+
41759+		time_now = sched_clock();
41760+		if (unlikely((long long)time_now -
41761+				(long long)time_limit >= 0))
41762+			break;
41763+	} while (tx_bq_rd_offset != tx_bq_wr_offset);
41764+
41765+	mdelay(1);
41766+}
41767+#endif
41768+
41769+#ifdef HIGMAC_MAC_TX_RESET_IN_LINKUP
41770+static void higmac_mac_tx_state_engine_reset(struct higmac_netdev_local *priv)
41771+{
41772+	u32 val;
41773+
41774+	val = readl(priv->gmac_iobase + MAC_CLEAR);
41775+	val |= BIT_TX_SOFT_RESET;
41776+	writel(val, priv->gmac_iobase + MAC_CLEAR);
41777+
41778+	mdelay(5); /* wait 5ms */
41779+
41780+	val = readl(priv->gmac_iobase + MAC_CLEAR);
41781+	val &= ~BIT_TX_SOFT_RESET;
41782+	writel(val, priv->gmac_iobase + MAC_CLEAR);
41783+}
41784+#endif
41785+
41786+static void higmac_adjust_link(struct net_device *dev)
41787+{
41788+	struct higmac_netdev_local *priv = NULL;
41789+	struct phy_device *phy = NULL;
41790+	bool link_status_changed = false;
41791+	if (dev == NULL)
41792+		return;
41793+	priv = netdev_priv(dev);
41794+	if (priv == NULL || priv->phy == NULL)
41795+		return;
41796+	phy = priv->phy;
41797+	if (phy->link) {
41798+		if ((priv->old_speed != phy->speed) ||
41799+				(priv->old_duplex != phy->duplex)) {
41800+#ifdef HIGMAC_LINK_CHANGE_PROTECT
41801+			unsigned long txflags;
41802+
41803+			spin_lock_irqsave(&priv->txlock, txflags);
41804+
41805+			higmac_linkup_flush(priv);
41806+#endif
41807+			higmac_config_port(dev, phy->speed, phy->duplex);
41808+#ifdef HIGMAC_MAC_TX_RESET_IN_LINKUP
41809+			higmac_mac_tx_state_engine_reset(priv);
41810+#endif
41811+#ifdef HIGMAC_LINK_CHANGE_PROTECT
41812+			spin_unlock_irqrestore(&priv->txlock, txflags);
41813+#endif
41814+			higmac_set_flow_ctrl_state(priv, phy->pause);
41815+
41816+			if (priv->autoeee)
41817+				init_autoeee(priv);
41818+
41819+			link_status_changed = true;
41820+			priv->old_link = 1;
41821+			priv->old_speed = phy->speed;
41822+			priv->old_duplex = phy->duplex;
41823+		}
41824+	} else if (priv->old_link) {
41825+		link_status_changed = true;
41826+		priv->old_link = 0;
41827+		priv->old_speed = SPEED_UNKNOWN;
41828+		priv->old_duplex = DUPLEX_UNKNOWN;
41829+	}
41830+
41831+	if (link_status_changed && netif_msg_link(priv))
41832+		phy_print_status(phy);
41833+}
41834+
41835+int higmac_tx_avail(struct higmac_netdev_local const *ld)
41836+{
41837+	unsigned int tx_bq_wr_offset, tx_bq_rd_offset;
41838+	if (ld == NULL)
41839+		return -ENOMEM;
41840+	tx_bq_wr_offset = readl(ld->gmac_iobase + TX_BQ_WR_ADDR);
41841+	tx_bq_rd_offset = readl(ld->gmac_iobase + TX_BQ_RD_ADDR);
41842+
41843+	return (tx_bq_rd_offset >> DESC_BYTE_SHIFT) + TX_DESC_NUM -
41844+		(tx_bq_wr_offset >> DESC_BYTE_SHIFT) - 1;
41845+}
41846+
41847+static int higmac_init_sg_desc_queue(struct higmac_netdev_local *ld)
41848+{
41849+	ld->sg_count = ld->TX_BQ.count + HIGMAC_SG_DESC_ADD;
41850+	if (has_cap_cci(ld->hw_cap)) {
41851+		ld->dma_sg_desc = kmalloc_array(ld->sg_count,
41852+						sizeof(struct sg_desc),
41853+						GFP_KERNEL);
41854+		if (ld->dma_sg_desc)
41855+			ld->dma_sg_phy = virt_to_phys(ld->dma_sg_desc);
41856+	} else {
41857+		ld->dma_sg_desc = (struct sg_desc *)dma_alloc_coherent(ld->dev,
41858+				  ld->sg_count * sizeof(struct sg_desc),
41859+				  &ld->dma_sg_phy, GFP_KERNEL);
41860+	}
41861+
41862+	if (!ld->dma_sg_desc) {
41863+		pr_err("alloc sg desc dma error!\n");
41864+		return -ENOMEM;
41865+	}
41866+#ifdef HIGMAC_TSO_DEBUG
41867+	pr_info("Higmac dma_sg_phy: 0x%pK\n", (void *)(uintptr_t)ld->dma_sg_phy);
41868+#endif
41869+
41870+	ld->sg_head = 0;
41871+	ld->sg_tail = 0;
41872+
41873+	return 0;
41874+}
41875+
41876+static void higmac_destroy_sg_desc_queue(struct higmac_netdev_local *ld)
41877+{
41878+	if (ld->dma_sg_desc) {
41879+		if (has_cap_cci(ld->hw_cap))
41880+			kfree(ld->dma_sg_desc);
41881+		else
41882+			dma_free_coherent(ld->dev,
41883+					  ld->sg_count * sizeof(struct sg_desc),
41884+					  ld->dma_sg_desc, ld->dma_sg_phy);
41885+		ld->dma_sg_desc = NULL;
41886+	}
41887+}
41888+
41889+static bool higmac_rx_fq_empty(struct higmac_netdev_local const *priv)
41890+{
41891+	u32 start, end;
41892+
41893+	start = readl(priv->gmac_iobase + RX_FQ_WR_ADDR);
41894+	end = readl(priv->gmac_iobase + RX_FQ_RD_ADDR);
41895+	if (start == end)
41896+		return true;
41897+	else
41898+		return false;
41899+}
41900+
41901+static bool higmac_rxq_has_packets(struct higmac_netdev_local const *priv, int rxq_id)
41902+{
41903+	u32 rx_bq_rd_reg, rx_bq_wr_reg;
41904+	u32 start, end;
41905+
41906+	rx_bq_rd_reg = rx_bq_rd_addr_queue(rxq_id);
41907+	rx_bq_wr_reg = rx_bq_wr_addr_queue(rxq_id);
41908+
41909+	start = readl(priv->gmac_iobase + rx_bq_rd_reg);
41910+	end = readl(priv->gmac_iobase + rx_bq_wr_reg);
41911+	if (start == end)
41912+		return false;
41913+	else
41914+		return true;
41915+}
41916+
41917+static void higmac_monitor_func(struct timer_list *t)
41918+{
41919+	struct higmac_netdev_local *ld = from_timer(ld, t, monitor);
41920+	struct net_device *dev = NULL;
41921+	u32 refill_cnt;
41922+
41923+	if (ld == NULL) {
41924+		higmac_trace(HIGMAC_NORMAL_LEVEL, "ld is null");
41925+		return;
41926+	}
41927+
41928+	if (ld->netdev == NULL) {
41929+		higmac_trace(HIGMAC_NORMAL_LEVEL, "ld->netdev is null");
41930+		return;
41931+	}
41932+	dev_hold(ld->netdev);
41933+	dev = ld->netdev;
41934+	if (!netif_running(dev)) {
41935+		dev_put(dev);
41936+		higmac_trace(HIGMAC_NORMAL_LEVEL, "network driver is stopped");
41937+		return;
41938+	}
41939+	dev_put(dev);
41940+
41941+	spin_lock(&ld->rxlock);
41942+	refill_cnt = higmac_rx_refill(ld);
41943+	if (!refill_cnt && higmac_rx_fq_empty(ld)) {
41944+		int rxq_id;
41945+
41946+		for (rxq_id = 0; rxq_id < ld->num_rxqs; rxq_id++) {
41947+			if (higmac_rxq_has_packets(ld, rxq_id))
41948+				napi_schedule(&ld->q_napi[rxq_id].napi);
41949+		}
41950+	}
41951+	spin_unlock(&ld->rxlock);
41952+
41953+	ld->monitor.expires = jiffies + HIGMAC_MONITOR_TIMER;
41954+	mod_timer(&ld->monitor, ld->monitor.expires);
41955+}
41956+
41957+static u32 higmac_rx_refill(struct higmac_netdev_local *priv)
41958+{
41959+	struct higmac_desc *desc = NULL;
41960+	struct sk_buff *skb = NULL;
41961+	struct cyclic_queue_info dma_info;
41962+	u32 len = HIETH_MAX_FRAME_SIZE;
41963+	dma_addr_t addr;
41964+	u32 refill_cnt = 0;
41965+	u32 i;
41966+	/* software write pointer */
41967+	dma_info.start = dma_cnt(readl(priv->gmac_iobase + RX_FQ_WR_ADDR));
41968+	/* logic read pointer */
41969+	dma_info.end = dma_cnt(readl(priv->gmac_iobase + RX_FQ_RD_ADDR));
41970+	dma_info.num = CIRC_SPACE(dma_info.start, dma_info.end, RX_DESC_NUM);
41971+
41972+	for (i = 0, dma_info.pos = dma_info.start; i < dma_info.num; i++) {
41973+		if (priv->RX_FQ.skb[dma_info.pos] || priv->rx_skb[dma_info.pos])
41974+			break;
41975+
41976+		skb = netdev_alloc_skb_ip_align(priv->netdev, len);
41977+		if (unlikely(skb == NULL))
41978+			break;
41979+
41980+		if (!has_cap_cci(priv->hw_cap)) {
41981+			addr = dma_map_single(priv->dev, skb->data, len,
41982+					      DMA_FROM_DEVICE);
41983+			if (dma_mapping_error(priv->dev, addr)) {
41984+				dev_kfree_skb_any(skb);
41985+				break;
41986+			}
41987+		} else {
41988+			addr = virt_to_phys(skb->data);
41989+		}
41990+
41991+		desc = priv->RX_FQ.desc + dma_info.pos;
41992+		desc->data_buff_addr = (u32)addr;
41993+#if defined(CONFIG_HIGMAC_DDR_64BIT)
41994+		desc->reserve31 = addr >> REG_BIT_WIDTH;
41995+#endif
41996+		priv->RX_FQ.skb[dma_info.pos] = skb;
41997+		priv->rx_skb[dma_info.pos] = skb;
41998+
41999+		desc->buffer_len = len - 1;
42000+		desc->data_len = 0;
42001+		desc->fl = 0;
42002+		desc->descvid = DESC_VLD_FREE;
42003+		desc->skb_id = dma_info.pos;
42004+
42005+		refill_cnt++;
42006+		dma_info.pos = dma_ring_incr(dma_info.pos, RX_DESC_NUM);
42007+	}
42008+
42009+	/*
42010+	 * This barrier is important here.  It is required to ensure
42011+	 * the ARM CPU flushes it's DMA write buffers before proceeding
42012+	 * to the next instruction, to ensure that GMAC will see
42013+	 * our descriptor changes in memory
42014+	 */
42015+	higmac_sync_barrier();
42016+
42017+	if (dma_info.pos != dma_info.start)
42018+		writel(dma_byte(dma_info.pos), priv->gmac_iobase + RX_FQ_WR_ADDR);
42019+
42020+	return refill_cnt;
42021+}
42022+
42023+static void higmac_rx_skbput(struct net_device *dev, struct sk_buff *skb,
42024+			     struct higmac_desc *desc, int rxq_id)
42025+{
42026+	struct higmac_netdev_local *ld = netdev_priv(dev);
42027+	dma_addr_t addr;
42028+	u32 len;
42029+	int ret;
42030+
42031+	len = desc->data_len;
42032+
42033+	if (!has_cap_cci(ld->hw_cap)) {
42034+		addr = desc->data_buff_addr;
42035+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42036+		addr |= (dma_addr_t)(desc->reserve31) << REG_BIT_WIDTH;
42037+#endif
42038+		dma_unmap_single(ld->dev, addr, HIETH_MAX_FRAME_SIZE,
42039+				 DMA_FROM_DEVICE);
42040+	}
42041+
42042+	skb_put(skb, len);
42043+	if (skb->len > HIETH_MAX_FRAME_SIZE) {
42044+		netdev_err(dev, "rcv len err, len = %d\n", skb->len);
42045+		dev->stats.rx_errors++;
42046+		dev->stats.rx_length_errors++;
42047+		dev_kfree_skb_any(skb);
42048+		return;
42049+	}
42050+
42051+	skb->protocol = eth_type_trans(skb, dev);
42052+	skb->ip_summed = CHECKSUM_NONE;
42053+
42054+#if defined(CONFIG_HIGMAC_RXCSUM)
42055+	ret = higmac_rx_checksum(dev, skb, desc);
42056+	if (unlikely(ret)) {
42057+		return;
42058+	}
42059+#endif
42060+	if ((dev->features & NETIF_F_RXHASH) && desc->has_hash)
42061+		skb_set_hash(skb, desc->rxhash, desc->l3_hash ?
42062+			     PKT_HASH_TYPE_L3 : PKT_HASH_TYPE_L4);
42063+
42064+	skb_record_rx_queue(skb, rxq_id);
42065+
42066+	napi_gro_receive(&ld->q_napi[rxq_id].napi, skb);
42067+	dev->stats.rx_packets++;
42068+	dev->stats.rx_bytes += len;
42069+}
42070+
42071+static int higmac_rx_skb(struct net_device *dev, struct higmac_desc *desc,
42072+			 u16 skb_id, int rxq_id)
42073+{
42074+	struct higmac_netdev_local *ld = netdev_priv(dev);
42075+	struct sk_buff *skb = NULL;
42076+
42077+	spin_lock(&ld->rxlock);
42078+	skb = ld->rx_skb[skb_id];
42079+	if (unlikely(skb == NULL)) {
42080+		spin_unlock(&ld->rxlock);
42081+		netdev_err(dev, "inconsistent rx_skb\n");
42082+		return -1;
42083+	}
42084+
42085+	/* data consistent check */
42086+	if (unlikely(skb != ld->RX_FQ.skb[skb_id])) {
42087+		netdev_err(dev, "desc->skb(0x%p),RX_FQ.skb[%d](0x%p)\n",
42088+			   skb, skb_id, ld->RX_FQ.skb[skb_id]);
42089+		if (ld->RX_FQ.skb[skb_id] == SKB_MAGIC) {
42090+			spin_unlock(&ld->rxlock);
42091+			return 0;
42092+		}
42093+		WARN_ON(1);
42094+	} else {
42095+		ld->RX_FQ.skb[skb_id] = NULL;
42096+	}
42097+	spin_unlock(&ld->rxlock);
42098+
42099+	higmac_rx_skbput(dev, skb, desc, rxq_id);
42100+	return 0;
42101+}
42102+
42103+static int higmac_rx(struct net_device *dev, int limit, int rxq_id)
42104+{
42105+	struct higmac_netdev_local *ld = netdev_priv(dev);
42106+	struct higmac_desc *desc = NULL;
42107+	struct cyclic_queue_info dma_info;
42108+	u32 rx_bq_rd_reg, rx_bq_wr_reg;
42109+	u16 skb_id;
42110+	u32 i;
42111+
42112+	rx_bq_rd_reg = rx_bq_rd_addr_queue(rxq_id);
42113+	rx_bq_wr_reg = rx_bq_wr_addr_queue(rxq_id);
42114+
42115+	/* software read pointer */
42116+	dma_info.start = dma_cnt(readl(ld->gmac_iobase + rx_bq_rd_reg));
42117+	/* logic write pointer */
42118+	dma_info.end = dma_cnt(readl(ld->gmac_iobase + rx_bq_wr_reg));
42119+	dma_info.num = CIRC_CNT(dma_info.end, dma_info.start, RX_DESC_NUM);
42120+	if (dma_info.num > limit)
42121+		dma_info.num = limit;
42122+
42123+	/* ensure get updated desc */
42124+	rmb();
42125+	for (i = 0, dma_info.pos = dma_info.start; i < dma_info.num; i++) {
42126+		if (rxq_id)
42127+			desc = ld->pool[BASE_QUEUE_NUMS + rxq_id].desc + dma_info.pos;
42128+		else
42129+			desc = ld->RX_BQ.desc + dma_info.pos;
42130+		skb_id = desc->skb_id;
42131+
42132+		if (unlikely(higmac_rx_skb(dev, desc, skb_id, rxq_id)))
42133+			break;
42134+
42135+		spin_lock(&ld->rxlock);
42136+		ld->rx_skb[skb_id] = NULL;
42137+		spin_unlock(&ld->rxlock);
42138+		dma_info.pos = dma_ring_incr(dma_info.pos, RX_DESC_NUM);
42139+	}
42140+
42141+	if (dma_info.pos != dma_info.start)
42142+		writel(dma_byte(dma_info.pos), ld->gmac_iobase + rx_bq_rd_reg);
42143+
42144+	spin_lock(&ld->rxlock);
42145+	higmac_rx_refill(ld);
42146+	spin_unlock(&ld->rxlock);
42147+
42148+	return dma_info.num;
42149+}
42150+
42151+#ifdef HIGMAC_TSO_DEBUG
42152+unsigned int id_send;
42153+unsigned int id_free;
42154+struct send_pkt_info pkt_rec[MAX_RECORD];
42155+#endif
42156+
42157+static int higmac_check_tx_err(struct higmac_netdev_local *ld,
42158+			       struct higmac_tso_desc *tx_bq_desc, unsigned int desc_pos)
42159+{
42160+	unsigned int tx_err = tx_bq_desc->tx_err;
42161+
42162+	if (unlikely(tx_err & ERR_ALL)) {
42163+		struct sg_desc *desc_cur = NULL;
42164+		int *sg_word = NULL;
42165+		int i;
42166+
42167+		WARN((tx_err & ERR_ALL),
42168+		     "TX ERR: desc1=0x%x, desc2=0x%x, desc5=0x%x\n",
42169+		     tx_bq_desc->data_buff_addr,
42170+		     tx_bq_desc->desc1.val, tx_bq_desc->tx_err);
42171+
42172+		desc_cur = ld->dma_sg_desc + ld->TX_BQ.sg_desc_offset[desc_pos];
42173+		sg_word = (int *)desc_cur;
42174+		for (i = 0; i < sizeof(struct sg_desc) / sizeof(int); i++)
42175+			pr_err("%s,%d: sg_desc word[%d]=0x%x\n",
42176+			       __func__, __LINE__, i, sg_word[i]);
42177+
42178+		return -1;
42179+	}
42180+
42181+	return 0;
42182+}
42183+
42184+static void higmac_xmit_release_gso_sg(struct higmac_netdev_local *ld,
42185+				       struct higmac_tso_desc *tx_rq_desc, unsigned int desc_pos)
42186+{
42187+	struct sg_desc *desc_cur = NULL;
42188+	int nfrags = tx_rq_desc->desc1.tx.nfrags_num;
42189+	unsigned int desc_offset;
42190+	dma_addr_t addr;
42191+	size_t len;
42192+	int i;
42193+
42194+	desc_offset = ld->TX_BQ.sg_desc_offset[desc_pos];
42195+	WARN_ON(desc_offset != ld->sg_tail);
42196+	desc_cur = ld->dma_sg_desc + desc_offset;
42197+
42198+	addr = desc_cur->linear_addr;
42199+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42200+	addr |= (dma_addr_t)(desc_cur->reserv3 >>
42201+			     SG_DESC_HI8_OFFSET) <<
42202+		REG_BIT_WIDTH;
42203+#endif
42204+	len = desc_cur->linear_len;
42205+	dma_unmap_single(ld->dev, addr, len, DMA_TO_DEVICE);
42206+	for (i = 0; i < nfrags; i++) {
42207+		addr = desc_cur->frags[i].addr;
42208+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42209+		addr |= (dma_addr_t)
42210+			(desc_cur->frags[i].reserved >>
42211+			 SG_DESC_HI8_OFFSET) <<
42212+			REG_BIT_WIDTH;
42213+#endif
42214+		len = desc_cur->frags[i].size;
42215+		dma_unmap_page(ld->dev, addr, len,
42216+			       DMA_TO_DEVICE);
42217+	}
42218+}
42219+
42220+static int higmac_xmit_release_gso(struct higmac_netdev_local *ld,
42221+				   struct higmac_tso_desc *tx_rq_desc, unsigned int desc_pos)
42222+{
42223+	int pkt_type;
42224+	int nfrags = tx_rq_desc->desc1.tx.nfrags_num;
42225+	dma_addr_t addr;
42226+	size_t len;
42227+
42228+	if (unlikely(higmac_check_tx_err(ld, tx_rq_desc, desc_pos) < 0)) {
42229+		/* dev_close */
42230+		higmac_irq_disable_all_queue(ld);
42231+		higmac_hw_desc_disable(ld);
42232+
42233+		netif_carrier_off(ld->netdev);
42234+		netif_stop_queue(ld->netdev);
42235+
42236+		phy_stop(ld->phy);
42237+		del_timer_sync(&ld->monitor);
42238+		return -1;
42239+	}
42240+
42241+	if (tx_rq_desc->desc1.tx.tso_flag || nfrags)
42242+		pkt_type = PKT_SG;
42243+	else
42244+		pkt_type = PKT_NORMAL;
42245+
42246+	if (pkt_type == PKT_NORMAL) {
42247+		if (!has_cap_cci(ld->hw_cap)) {
42248+			addr = tx_rq_desc->data_buff_addr;
42249+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42250+			addr |= (dma_addr_t)(tx_rq_desc->reserve_desc2 &
42251+					     TX_DESC_HI8_MASK) <<
42252+				REG_BIT_WIDTH;
42253+#endif
42254+			len = tx_rq_desc->desc1.tx.data_len;
42255+			dma_unmap_single(ld->dev, addr, len, DMA_TO_DEVICE);
42256+		}
42257+	} else {
42258+		if (!has_cap_cci(ld->hw_cap))
42259+			higmac_xmit_release_gso_sg(ld, tx_rq_desc, desc_pos);
42260+
42261+		ld->sg_tail = (ld->sg_tail + 1) % ld->sg_count;
42262+	}
42263+
42264+#ifdef HIGMAC_TSO_DEBUG
42265+	if (id_free >= MAX_RECORD)
42266+		id_free = 0;
42267+	pkt_rec[id_free].status = 0;
42268+	id_free++;
42269+#endif
42270+
42271+	return 0;
42272+}
42273+
42274+static int higmac_xmit_reclaim_release(struct net_device *dev,
42275+				       struct sk_buff *skb, struct higmac_desc *desc, u32 pos)
42276+{
42277+	struct higmac_netdev_local *priv = netdev_priv(dev);
42278+	struct higmac_tso_desc *tso_desc = NULL;
42279+	dma_addr_t addr;
42280+
42281+	if (priv->tso_supported) {
42282+		tso_desc = (struct higmac_tso_desc *)desc;
42283+		return higmac_xmit_release_gso(priv, tso_desc, pos);
42284+	} else if (!has_cap_cci(priv->hw_cap)) {
42285+		addr = desc->data_buff_addr;
42286+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42287+		addr |= (dma_addr_t)(desc->rxhash & TX_DESC_HI8_MASK) <<
42288+			REG_BIT_WIDTH;
42289+#endif
42290+		dma_unmap_single(priv->dev, addr, skb->len, DMA_TO_DEVICE);
42291+	}
42292+	return 0;
42293+}
42294+
42295+static void higmac_xmit_reclaim(struct net_device *dev)
42296+{
42297+	struct sk_buff *skb = NULL;
42298+	struct higmac_desc *desc = NULL;
42299+	struct higmac_netdev_local *priv = netdev_priv(dev);
42300+	unsigned int bytes_compl = 0;
42301+	unsigned int pkts_compl = 0;
42302+	struct cyclic_queue_info dma_info;
42303+	u32 i;
42304+
42305+	spin_lock(&priv->txlock);
42306+
42307+	/* software read */
42308+	dma_info.start = dma_cnt(readl(priv->gmac_iobase + TX_RQ_RD_ADDR));
42309+	/* logic write */
42310+	dma_info.end = dma_cnt(readl(priv->gmac_iobase + TX_RQ_WR_ADDR));
42311+	dma_info.num = CIRC_CNT(dma_info.end, dma_info.start, TX_DESC_NUM);
42312+
42313+	for (i = 0, dma_info.pos = dma_info.start; i < dma_info.num; i++) {
42314+		skb = priv->tx_skb[dma_info.pos];
42315+		if (unlikely(skb == NULL)) {
42316+			netdev_err(dev, "inconsistent tx_skb\n");
42317+			break;
42318+		}
42319+
42320+		if (skb != priv->TX_BQ.skb[dma_info.pos]) {
42321+			netdev_err(dev, "wired, tx skb[%d](%p) != skb(%p)\n",
42322+				   dma_info.pos, priv->TX_BQ.skb[dma_info.pos], skb);
42323+			if (priv->TX_BQ.skb[dma_info.pos] == SKB_MAGIC)
42324+				goto next;
42325+		}
42326+
42327+		pkts_compl++;
42328+		bytes_compl += skb->len;
42329+		desc = priv->TX_RQ.desc + dma_info.pos;
42330+		if (higmac_xmit_reclaim_release(dev, skb, desc, dma_info.pos) < 0)
42331+			break;
42332+
42333+		priv->TX_BQ.skb[dma_info.pos] = NULL;
42334+next:
42335+		priv->tx_skb[dma_info.pos] = NULL;
42336+		dev_consume_skb_any(skb);
42337+		dma_info.pos = dma_ring_incr(dma_info.pos, TX_DESC_NUM);
42338+	}
42339+
42340+	if (dma_info.pos != dma_info.start)
42341+		writel(dma_byte(dma_info.pos), priv->gmac_iobase + TX_RQ_RD_ADDR);
42342+
42343+	if (pkts_compl || bytes_compl)
42344+		netdev_completed_queue(dev, pkts_compl, bytes_compl);
42345+
42346+	if (unlikely(netif_queue_stopped(priv->netdev)) && pkts_compl)
42347+		netif_wake_queue(priv->netdev);
42348+
42349+	spin_unlock(&priv->txlock);
42350+}
42351+
42352+static int higmac_poll(struct napi_struct *napi, int budget)
42353+{
42354+	struct higmac_napi *q_napi = container_of(napi,
42355+						  struct higmac_napi, napi);
42356+	struct higmac_netdev_local *priv = q_napi->ndev_priv;
42357+	int work_done = 0;
42358+	int num;
42359+	u32 ints;
42360+	u32 raw_int_reg, raw_int_mask;
42361+
42362+	dev_hold(priv->netdev);
42363+	if (q_napi->rxq_id) {
42364+		raw_int_reg = RSS_RAW_PMU_INT;
42365+		raw_int_mask = def_int_mask_queue((u32)q_napi->rxq_id);
42366+	} else {
42367+		raw_int_reg = RAW_PMU_INT;
42368+		raw_int_mask = DEF_INT_MASK;
42369+	}
42370+
42371+	do {
42372+		if (!q_napi->rxq_id)
42373+			higmac_xmit_reclaim(priv->netdev);
42374+		num = higmac_rx(priv->netdev, budget - work_done, q_napi->rxq_id);
42375+		work_done += num;
42376+		if (work_done >= budget)
42377+			break;
42378+
42379+		ints = readl(priv->gmac_iobase + raw_int_reg);
42380+		ints &= raw_int_mask;
42381+		writel(ints, priv->gmac_iobase + raw_int_reg);
42382+	} while (ints || higmac_rxq_has_packets(priv, q_napi->rxq_id));
42383+
42384+	if (work_done < budget) {
42385+		napi_complete(napi);
42386+		higmac_irq_enable_queue(priv, q_napi->rxq_id);
42387+	}
42388+
42389+	dev_put(priv->netdev);
42390+	return work_done;
42391+}
42392+
42393+static irqreturn_t higmac_interrupt(int irq, void *dev_id)
42394+{
42395+	struct higmac_napi *q_napi = (struct higmac_napi *)dev_id;
42396+	struct higmac_netdev_local *ld = q_napi->ndev_priv;
42397+	u32 ints;
42398+	u32 raw_int_reg, raw_int_mask;
42399+
42400+	if (higmac_queue_irq_disabled(ld, q_napi->rxq_id))
42401+		return IRQ_NONE;
42402+
42403+	if (q_napi->rxq_id) {
42404+		raw_int_reg = RSS_RAW_PMU_INT;
42405+		raw_int_mask = def_int_mask_queue((u32)q_napi->rxq_id);
42406+	} else {
42407+		raw_int_reg = RAW_PMU_INT;
42408+		raw_int_mask = DEF_INT_MASK;
42409+	}
42410+
42411+	ints = readl(ld->gmac_iobase + raw_int_reg);
42412+	ints &= raw_int_mask;
42413+	writel(ints, ld->gmac_iobase + raw_int_reg);
42414+
42415+	if (likely(ints || higmac_rxq_has_packets(ld, q_napi->rxq_id))) {
42416+		higmac_irq_disable_queue(ld, q_napi->rxq_id);
42417+		napi_schedule(&q_napi->napi);
42418+	}
42419+
42420+	return IRQ_HANDLED;
42421+}
42422+
42423+static int higmac_xmit_gso_sg_frag(struct higmac_netdev_local *ld,
42424+				   struct sk_buff *skb, struct sg_desc *desc_cur,
42425+				   struct higmac_tso_desc *tx_bq_desc, unsigned int desc_pos)
42426+{
42427+	int nfrags = skb_shinfo(skb)->nr_frags;
42428+	dma_addr_t addr;
42429+	dma_addr_t dma_addr;
42430+	phys_addr_t phys_addr;
42431+	int i, ret;
42432+
42433+	for (i = 0; i < nfrags; i++) {
42434+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
42435+		int len = frag->size;
42436+
42437+		if (!has_cap_cci(ld->hw_cap)) {
42438+			dma_addr = skb_frag_dma_map(ld->dev, frag, 0,
42439+						    len, DMA_TO_DEVICE);
42440+			ret = dma_mapping_error(ld->dev, dma_addr);
42441+			if (unlikely(ret)) {
42442+				pr_err("skb frag DMA Mapping fail");
42443+				return -EFAULT;
42444+			}
42445+			desc_cur->frags[i].addr = (u32)dma_addr;
42446+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42447+			desc_cur->frags[i].reserved =
42448+				(dma_addr >> REG_BIT_WIDTH) <<
42449+				SG_DESC_HI8_OFFSET;
42450+#endif
42451+		} else {
42452+			phys_addr =
42453+				page_to_phys(skb_frag_page(frag)) + frag->page_offset;
42454+			desc_cur->frags[i].addr = (u32)phys_addr;
42455+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42456+			desc_cur->frags[i].reserved =
42457+				(phys_addr >> REG_BIT_WIDTH) <<
42458+				SG_DESC_HI8_OFFSET;
42459+#endif
42460+		}
42461+		desc_cur->frags[i].size = len;
42462+	}
42463+
42464+	addr = ld->dma_sg_phy + ld->sg_head * sizeof(struct sg_desc);
42465+	tx_bq_desc->data_buff_addr = (u32)addr;
42466+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42467+	tx_bq_desc->reserve_desc2 = (addr >> REG_BIT_WIDTH) &
42468+				    TX_DESC_HI8_MASK;
42469+#endif
42470+	ld->TX_BQ.sg_desc_offset[desc_pos] = ld->sg_head;
42471+
42472+	ld->sg_head = (ld->sg_head + 1) % ld->sg_count;
42473+
42474+	return 0;
42475+}
42476+
42477+static int higmac_xmit_gso_sg(struct higmac_netdev_local *ld,
42478+			      struct sk_buff *skb,
42479+			      struct higmac_tso_desc *tx_bq_desc, unsigned int desc_pos)
42480+{
42481+	struct sg_desc *desc_cur = NULL;
42482+	dma_addr_t dma_addr;
42483+	phys_addr_t phys_addr;
42484+	int ret;
42485+
42486+	if (unlikely(((ld->sg_head + 1) % ld->sg_count) == ld->sg_tail)) {
42487+		/* SG pkt, but sg desc all used */
42488+		pr_err("WARNING: sg desc all used.\n");
42489+		return -EBUSY;
42490+	}
42491+
42492+	desc_cur = ld->dma_sg_desc + ld->sg_head;
42493+
42494+	/* deal with ipv6_id */
42495+	if (tx_bq_desc->desc1.tx.tso_flag &&
42496+			tx_bq_desc->desc1.tx.ip_ver == PKT_IPV6 &&
42497+			tx_bq_desc->desc1.tx.prot_type == PKT_UDP)
42498+		desc_cur->ipv6_id = ntohl(skb_shinfo(skb)->ip6_frag_id);
42499+
42500+	desc_cur->total_len = skb->len;
42501+	desc_cur->linear_len = skb_headlen(skb);
42502+	if (!has_cap_cci(ld->hw_cap)) {
42503+		dma_addr = dma_map_single(ld->dev, skb->data,
42504+					  desc_cur->linear_len,
42505+					  DMA_TO_DEVICE);
42506+		ret = dma_mapping_error(ld->dev, dma_addr);
42507+		if (unlikely(ret)) {
42508+			pr_err("DMA Mapping fail");
42509+			return -EFAULT;
42510+		}
42511+		desc_cur->linear_addr = (u32)dma_addr;
42512+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42513+		desc_cur->reserv3 = (dma_addr >> REG_BIT_WIDTH) <<
42514+				    SG_DESC_HI8_OFFSET;
42515+#endif
42516+	} else {
42517+		phys_addr = virt_to_phys(skb->data);
42518+		desc_cur->linear_addr = (u32)phys_addr;
42519+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42520+		desc_cur->reserv3 = (phys_addr >> REG_BIT_WIDTH) <<
42521+				    SG_DESC_HI8_OFFSET;
42522+#endif
42523+	}
42524+
42525+	ret = higmac_xmit_gso_sg_frag(ld, skb, desc_cur, tx_bq_desc, desc_pos);
42526+	if (unlikely(ret))
42527+		return ret;
42528+
42529+	return 0;
42530+}
42531+
42532+static int higmac_xmit_gso(struct higmac_netdev_local *ld, struct sk_buff *skb,
42533+			   struct higmac_tso_desc *tx_bq_desc, unsigned int desc_pos)
42534+{
42535+	int pkt_type = PKT_NORMAL;
42536+	int nfrags = skb_shinfo(skb)->nr_frags;
42537+	dma_addr_t addr;
42538+	int ret;
42539+
42540+	if (skb_is_gso(skb) || nfrags)
42541+		pkt_type = PKT_SG; /* TSO pkt or SG pkt */
42542+
42543+	ret = higmac_check_hw_capability(skb);
42544+	if (unlikely(ret))
42545+		return ret;
42546+
42547+	ret = higmac_get_pkt_info(ld, skb, tx_bq_desc);
42548+	if (unlikely(ret))
42549+		return ret;
42550+
42551+	if (pkt_type == PKT_NORMAL) {
42552+		if (!has_cap_cci(ld->hw_cap)) {
42553+			addr = dma_map_single(ld->dev, skb->data, skb->len, DMA_TO_DEVICE);
42554+			ret = dma_mapping_error(ld->dev, addr);
42555+			if (unlikely(ret)) {
42556+				pr_err("Normal Packet DMA Mapping fail.\n");
42557+				return -EFAULT;
42558+			}
42559+			tx_bq_desc->data_buff_addr = (u32)addr;
42560+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42561+			tx_bq_desc->reserve_desc2 = (addr >> REG_BIT_WIDTH) &
42562+						    TX_DESC_HI8_MASK;
42563+#endif
42564+		} else {
42565+			addr = virt_to_phys(skb->data);
42566+			tx_bq_desc->data_buff_addr = (u32)addr;
42567+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42568+			tx_bq_desc->reserve_desc2 = (addr >> REG_BIT_WIDTH) &
42569+						    TX_DESC_HI8_MASK;
42570+#endif
42571+		}
42572+	} else {
42573+		ret = higmac_xmit_gso_sg(ld, skb, tx_bq_desc, desc_pos);
42574+		if (unlikely(ret))
42575+			return ret;
42576+	}
42577+
42578+#ifdef HIGMAC_TSO_DEBUG
42579+	if (id_send >= MAX_RECORD)
42580+		id_send = 0;
42581+	memcpy(&pkt_rec[id_send].desc, tx_bq_desc, sizeof(struct higmac_tso_desc));
42582+	pkt_rec[id_send].status = 1;
42583+	id_send++;
42584+#endif
42585+	return 0;
42586+}
42587+
42588+static netdev_tx_t higmac_net_xmit(struct sk_buff *skb, struct net_device *dev);
42589+
42590+static netdev_tx_t higmac_sw_gso(struct higmac_netdev_local *ld,
42591+				 struct sk_buff *skb)
42592+{
42593+	struct sk_buff *segs = NULL;
42594+	struct sk_buff *curr_skb = NULL;
42595+	int ret;
42596+	int gso_segs = skb_shinfo(skb)->gso_segs;
42597+	if (gso_segs == 0 && skb_shinfo(skb)->gso_size != 0)
42598+		gso_segs = DIV_ROUND_UP(skb->len, skb_shinfo(skb)->gso_size);
42599+
42600+	/* Estimate the number of fragments in the worst case */
42601+	if (unlikely(higmac_tx_avail(ld) < gso_segs)) {
42602+		netif_stop_queue(ld->netdev);
42603+		if (higmac_tx_avail(ld) < gso_segs) {
42604+			ld->netdev->stats.tx_dropped++;
42605+			ld->netdev->stats.tx_fifo_errors++;
42606+			return NETDEV_TX_BUSY;
42607+		}
42608+		netif_wake_queue(ld->netdev);
42609+	}
42610+
42611+	segs = skb_gso_segment(skb, ld->netdev->features & ~(NETIF_F_CSUM_MASK |
42612+			       NETIF_F_SG | NETIF_F_GSO_SOFTWARE));
42613+	if (IS_ERR_OR_NULL(segs))
42614+		goto drop;
42615+
42616+	do {
42617+		curr_skb = segs;
42618+		segs = segs->next;
42619+		curr_skb->next = NULL;
42620+		ret = higmac_net_xmit(curr_skb, ld->netdev);
42621+		if (unlikely(ret != NETDEV_TX_OK))
42622+			pr_err_once("higmac_net_xmit error ret=%d\n", ret);
42623+	} while (segs != NULL);
42624+
42625+	dev_kfree_skb_any(skb);
42626+	return NETDEV_TX_OK;
42627+
42628+drop:
42629+	dev_kfree_skb_any(skb);
42630+	ld->netdev->stats.tx_dropped++;
42631+	return NETDEV_TX_OK;
42632+}
42633+
42634+static int higmac_net_xmit_normal(struct sk_buff *skb, struct net_device *dev,
42635+				  struct higmac_desc *desc, u32 pos)
42636+{
42637+	struct higmac_netdev_local *ld = netdev_priv(dev);
42638+	dma_addr_t addr;
42639+
42640+	if (!has_cap_cci(ld->hw_cap)) {
42641+		addr = dma_map_single(ld->dev, skb->data, skb->len, DMA_TO_DEVICE);
42642+		if (unlikely(dma_mapping_error(ld->dev, addr))) {
42643+			dev_kfree_skb_any(skb);
42644+			dev->stats.tx_dropped++;
42645+			ld->tx_skb[pos] = NULL;
42646+			ld->TX_BQ.skb[pos] = NULL;
42647+			return -1;
42648+		}
42649+		desc->data_buff_addr = (u32)addr;
42650+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42651+		desc->rxhash = (addr >> REG_BIT_WIDTH) & TX_DESC_HI8_MASK;
42652+#endif
42653+	} else {
42654+		addr = virt_to_phys(skb->data);
42655+		desc->data_buff_addr = (u32)addr;
42656+#if defined(CONFIG_HIGMAC_DDR_64BIT)
42657+		desc->rxhash = (addr >> REG_BIT_WIDTH) & TX_DESC_HI8_MASK;
42658+#endif
42659+	}
42660+	desc->buffer_len = HIETH_MAX_FRAME_SIZE - 1;
42661+	desc->data_len = skb->len;
42662+	desc->fl = DESC_FL_FULL;
42663+	desc->descvid = DESC_VLD_BUSY;
42664+
42665+	return 0;
42666+}
42667+
42668+static int higmac_check_skb_len(struct sk_buff *skb, struct net_device *dev)
42669+{
42670+	if (skb->len < ETH_HLEN) {
42671+		dev_kfree_skb_any(skb);
42672+		dev->stats.tx_errors++;
42673+		dev->stats.tx_dropped++;
42674+		return -1;
42675+	}
42676+	return 0;
42677+}
42678+
42679+static netdev_tx_t higmac_net_xmit(struct sk_buff *skb, struct net_device *dev)
42680+{
42681+	struct higmac_netdev_local *ld = netdev_priv(dev);
42682+	struct higmac_desc *desc = NULL;
42683+	unsigned long txflags;
42684+	int ret;
42685+	u32 pos;
42686+
42687+	if (unlikely(higmac_check_skb_len(skb, dev) < 0))
42688+		return NETDEV_TX_OK;
42689+
42690+	/*
42691+	 * if adding higmac_xmit_reclaim here, iperf tcp client
42692+	 * performance will be affected, from 550M(avg) to 513M~300M
42693+	 */
42694+
42695+	/* software write pointer */
42696+	pos = dma_cnt(readl(ld->gmac_iobase + TX_BQ_WR_ADDR));
42697+
42698+	spin_lock_irqsave(&ld->txlock, txflags);
42699+
42700+	if (unlikely(ld->tx_skb[pos] || ld->TX_BQ.skb[pos])) {
42701+		dev->stats.tx_dropped++;
42702+		dev->stats.tx_fifo_errors++;
42703+		netif_stop_queue(dev);
42704+		spin_unlock_irqrestore(&ld->txlock, txflags);
42705+
42706+		return NETDEV_TX_BUSY;
42707+	}
42708+
42709+	ld->TX_BQ.skb[pos] = skb;
42710+	ld->tx_skb[pos] = skb;
42711+
42712+	desc = ld->TX_BQ.desc + pos;
42713+
42714+	if (ld->tso_supported) {
42715+		ret = higmac_xmit_gso(ld, skb, (struct higmac_tso_desc *)desc, pos);
42716+		if (unlikely(ret < 0)) {
42717+			ld->tx_skb[pos] = NULL;
42718+			ld->TX_BQ.skb[pos] = NULL;
42719+			spin_unlock_irqrestore(&ld->txlock, txflags);
42720+
42721+			if (ret == -ENOTSUPP)
42722+				return higmac_sw_gso(ld, skb);
42723+
42724+			dev_kfree_skb_any(skb);
42725+			dev->stats.tx_dropped++;
42726+			return NETDEV_TX_OK;
42727+		}
42728+	} else {
42729+		ret = higmac_net_xmit_normal(skb, dev, desc, pos);
42730+		if (unlikely(ret < 0)) {
42731+			spin_unlock_irqrestore(&ld->txlock, txflags);
42732+			return NETDEV_TX_OK;
42733+		}
42734+	}
42735+
42736+	/*
42737+	 * This barrier is important here.  It is required to ensure
42738+	 * the ARM CPU flushes it's DMA write buffers before proceeding
42739+	 * to the next instruction, to ensure that GMAC will see
42740+	 * our descriptor changes in memory
42741+	 */
42742+	higmac_sync_barrier();
42743+	pos = dma_ring_incr(pos, TX_DESC_NUM);
42744+	writel(dma_byte(pos), ld->gmac_iobase + TX_BQ_WR_ADDR);
42745+
42746+	netif_trans_update(dev);
42747+	dev->stats.tx_packets++;
42748+	dev->stats.tx_bytes += skb->len;
42749+	netdev_sent_queue(dev, skb->len);
42750+
42751+	spin_unlock_irqrestore(&ld->txlock, txflags);
42752+
42753+	return NETDEV_TX_OK;
42754+}
42755+
42756+void higmac_enable_napi(struct higmac_netdev_local *priv)
42757+{
42758+	struct higmac_napi *q_napi = NULL;
42759+	int i;
42760+	if (priv == NULL)
42761+		return;
42762+	for (i = 0; i < priv->num_rxqs; i++) {
42763+		q_napi = &priv->q_napi[i];
42764+		napi_enable(&q_napi->napi);
42765+	}
42766+}
42767+
42768+void higmac_disable_napi(struct higmac_netdev_local *priv)
42769+{
42770+	struct higmac_napi *q_napi = NULL;
42771+	int i;
42772+	if (priv == NULL)
42773+		return;
42774+	for (i = 0; i < priv->num_rxqs; i++) {
42775+		q_napi = &priv->q_napi[i];
42776+		napi_disable(&q_napi->napi);
42777+	}
42778+}
42779+
42780+static int higmac_net_open(struct net_device *dev)
42781+{
42782+	struct higmac_netdev_local *ld = netdev_priv(dev);
42783+	unsigned long flags;
42784+
42785+	clk_prepare_enable(ld->macif_clk);
42786+	clk_prepare_enable(ld->clk);
42787+
42788+	/*
42789+	 * If we configure mac address by
42790+	 * "ifconfig ethX hw ether XX:XX:XX:XX:XX:XX",
42791+	 * the ethX must be down state and mac core clock is disabled
42792+	 * which results the mac address has not been configured
42793+	 * in mac core register.
42794+	 * So we must set mac address again here,
42795+	 * because mac core clock is enabled at this time
42796+	 * and we can configure mac address to mac core register.
42797+	 */
42798+	higmac_hw_set_mac_addr(dev);
42799+
42800+	/*
42801+	 * We should use netif_carrier_off() here,
42802+	 * because the default state should be off.
42803+	 * And this call should before phy_start().
42804+	 */
42805+	netif_carrier_off(dev);
42806+	higmac_enable_napi(ld);
42807+	phy_start(ld->phy);
42808+
42809+	higmac_hw_desc_enable(ld);
42810+	higmac_port_enable(ld);
42811+	higmac_irq_enable_all_queue(ld);
42812+
42813+	spin_lock_irqsave(&ld->rxlock, flags);
42814+	higmac_rx_refill(ld);
42815+	spin_unlock_irqrestore(&ld->rxlock, flags);
42816+
42817+	ld->monitor.expires = jiffies + HIGMAC_MONITOR_TIMER;
42818+	mod_timer(&ld->monitor, ld->monitor.expires);
42819+
42820+	netif_start_queue(dev);
42821+
42822+	return 0;
42823+}
42824+
42825+static int higmac_net_close(struct net_device *dev)
42826+{
42827+	struct higmac_netdev_local *ld = netdev_priv(dev);
42828+
42829+	higmac_irq_disable_all_queue(ld);
42830+	higmac_hw_desc_disable(ld);
42831+
42832+	higmac_disable_napi(ld);
42833+
42834+	netif_carrier_off(dev);
42835+	netif_stop_queue(dev);
42836+
42837+	phy_stop(ld->phy);
42838+	del_timer_sync(&ld->monitor);
42839+
42840+	clk_disable_unprepare(ld->clk);
42841+	clk_disable_unprepare(ld->macif_clk);
42842+
42843+	return 0;
42844+}
42845+
42846+static void higmac_net_timeout(struct net_device *dev)
42847+{
42848+	dev->stats.tx_errors++;
42849+
42850+	pr_err("tx timeout!\n");
42851+}
42852+
42853+static void higmac_set_multicast_list(struct net_device *dev)
42854+{
42855+	higmac_gmac_multicast_list(dev);
42856+}
42857+
42858+static void higmac_enable_rxcsum_drop(struct higmac_netdev_local const *ld,
42859+		  bool drop)
42860+{
42861+	unsigned int v;
42862+
42863+	v = readl(ld->gmac_iobase + TSO_COE_CTRL);
42864+	if (drop)
42865+		v |= COE_ERR_DROP;
42866+	else
42867+		v &= ~COE_ERR_DROP;
42868+	writel(v, ld->gmac_iobase + TSO_COE_CTRL);
42869+}
42870+
42871+static int higmac_set_features(struct net_device *dev,
42872+			       netdev_features_t features)
42873+{
42874+	struct higmac_netdev_local *ld = netdev_priv(dev);
42875+	netdev_features_t changed = dev->features ^ features;
42876+
42877+	if (changed & NETIF_F_RXCSUM) {
42878+		if (features & NETIF_F_RXCSUM)
42879+			higmac_enable_rxcsum_drop(ld, true);
42880+		else
42881+			higmac_enable_rxcsum_drop(ld, false);
42882+	}
42883+
42884+	return 0;
42885+}
42886+
42887+static struct net_device_stats *higmac_net_get_stats(struct net_device *dev)
42888+{
42889+	return &dev->stats;
42890+}
42891+
42892+static const struct ethtool_ops hieth_ethtools_ops = {
42893+	.get_drvinfo = higmac_get_drvinfo,
42894+	.get_link = higmac_get_link,
42895+	.get_settings = higmac_get_settings,
42896+	.set_settings = higmac_set_settings,
42897+	.get_pauseparam = higmac_get_pauseparam,
42898+	.set_pauseparam = higmac_set_pauseparam,
42899+	.get_msglevel = higmac_ethtool_getmsglevel,
42900+	.set_msglevel = higmac_ethtool_setmsglevel,
42901+	.get_rxfh_key_size = higmac_get_rxfh_key_size,
42902+	.get_rxfh_indir_size = higmac_get_rxfh_indir_size,
42903+	.get_rxfh = higmac_get_rxfh,
42904+	.set_rxfh = higmac_set_rxfh,
42905+	.get_rxnfc = higmac_get_rxnfc,
42906+	.set_rxnfc = higmac_set_rxnfc,
42907+};
42908+
42909+static const struct net_device_ops hieth_netdev_ops = {
42910+	.ndo_open = higmac_net_open,
42911+	.ndo_stop = higmac_net_close,
42912+	.ndo_start_xmit = higmac_net_xmit,
42913+	.ndo_tx_timeout = higmac_net_timeout,
42914+	.ndo_set_rx_mode = higmac_set_multicast_list,
42915+	.ndo_set_features = higmac_set_features,
42916+	.ndo_do_ioctl = higmac_ioctl,
42917+	.ndo_set_mac_address = higmac_net_set_mac_address,
42918+	.ndo_change_mtu = eth_change_mtu,
42919+	.ndo_get_stats = higmac_net_get_stats,
42920+};
42921+
42922+static int higmac_of_get_param(struct higmac_netdev_local *ld,
42923+			       struct device_node const *node)
42924+{
42925+	/* get auto eee */
42926+	ld->autoeee = of_property_read_bool(node, "autoeee");
42927+	/* get internal flag */
42928+	ld->internal_phy =
42929+		of_property_read_bool(node, "internal-phy");
42930+
42931+	return 0;
42932+}
42933+
42934+static void higmac_destroy_hw_desc_queue(struct higmac_netdev_local *priv)
42935+{
42936+	int i;
42937+
42938+	for (i = 0; i < QUEUE_NUMS + RSS_NUM_RXQS - 1; i++) {
42939+		if (priv->pool[i].desc) {
42940+			if (has_cap_cci(priv->hw_cap))
42941+				kfree(priv->pool[i].desc);
42942+			else
42943+				dma_free_coherent(priv->dev, priv->pool[i].size,
42944+						  priv->pool[i].desc,
42945+						  priv->pool[i].phys_addr);
42946+			priv->pool[i].desc = NULL;
42947+		}
42948+	}
42949+
42950+	kfree(priv->RX_FQ.skb);
42951+	kfree(priv->TX_BQ.skb);
42952+	priv->RX_FQ.skb = NULL;
42953+	priv->TX_BQ.skb = NULL;
42954+
42955+	if (priv->tso_supported) {
42956+		kfree(priv->TX_BQ.sg_desc_offset);
42957+		priv->TX_BQ.sg_desc_offset = NULL;
42958+	}
42959+
42960+	kfree(priv->tx_skb);
42961+	priv->tx_skb = NULL;
42962+
42963+	kfree(priv->rx_skb);
42964+	priv->rx_skb = NULL;
42965+}
42966+
42967+static int higmac_init_desc_queue_mem(struct higmac_netdev_local *priv)
42968+{
42969+	priv->RX_FQ.skb = kzalloc(priv->RX_FQ.count
42970+				  * sizeof(struct sk_buff *), GFP_KERNEL);
42971+	if (!priv->RX_FQ.skb)
42972+		return -ENOMEM;
42973+
42974+	priv->rx_skb = kzalloc(priv->RX_FQ.count
42975+			       * sizeof(struct sk_buff *), GFP_KERNEL);
42976+	if (priv->rx_skb == NULL)
42977+		return -ENOMEM;
42978+
42979+	priv->TX_BQ.skb = kzalloc(priv->TX_BQ.count
42980+				  * sizeof(struct sk_buff *), GFP_KERNEL);
42981+	if (!priv->TX_BQ.skb)
42982+		return -ENOMEM;
42983+
42984+	priv->tx_skb = kzalloc(priv->TX_BQ.count
42985+			       * sizeof(struct sk_buff *), GFP_KERNEL);
42986+	if (priv->tx_skb == NULL)
42987+		return -ENOMEM;
42988+
42989+	if (priv->tso_supported) {
42990+		priv->TX_BQ.sg_desc_offset = kzalloc(priv->TX_BQ.count
42991+						     * sizeof(int), GFP_KERNEL);
42992+		if (!priv->TX_BQ.sg_desc_offset)
42993+			return -ENOMEM;
42994+	}
42995+
42996+	return 0;
42997+}
42998+
42999+static int higmac_init_hw_desc_queue(struct higmac_netdev_local *priv)
43000+{
43001+	struct device *dev = NULL;
43002+	struct higmac_desc *virt_addr = NULL;
43003+	dma_addr_t phys_addr = 0;
43004+	int size, i;
43005+	if (priv == NULL || priv->dev == NULL)
43006+		return -EINVAL;
43007+	dev = priv->dev;
43008+	if (dev == NULL)
43009+		return -EINVAL;
43010+	priv->RX_FQ.count = RX_DESC_NUM;
43011+	priv->RX_BQ.count = RX_DESC_NUM;
43012+	priv->TX_BQ.count = TX_DESC_NUM;
43013+	priv->TX_RQ.count = TX_DESC_NUM;
43014+
43015+	for (i = 1; i < RSS_NUM_RXQS; i++)
43016+		priv->pool[BASE_QUEUE_NUMS + i].count = RX_DESC_NUM;
43017+
43018+	for (i = 0; i < (QUEUE_NUMS + RSS_NUM_RXQS - 1); i++) {
43019+		size = priv->pool[i].count * sizeof(struct higmac_desc);
43020+		if (has_cap_cci(priv->hw_cap)) {
43021+			virt_addr = kmalloc(size, GFP_KERNEL);
43022+			if (virt_addr != NULL) {
43023+				memset(virt_addr, 0, size);
43024+				phys_addr = virt_to_phys(virt_addr);
43025+			}
43026+		} else {
43027+			virt_addr = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL);
43028+			if (virt_addr != NULL)
43029+				memset(virt_addr, 0, size);
43030+		}
43031+		if (virt_addr == NULL)
43032+			goto error_free_pool;
43033+
43034+		priv->pool[i].size = size;
43035+		priv->pool[i].desc = virt_addr;
43036+		priv->pool[i].phys_addr = phys_addr;
43037+	}
43038+
43039+	if (higmac_init_desc_queue_mem(priv) == -ENOMEM)
43040+		goto error_free_pool;
43041+
43042+	higmac_hw_set_desc_addr(priv);
43043+	if (has_cap_cci(priv->hw_cap))
43044+		pr_info("higmac: ETH MAC supporte CCI.\n");
43045+
43046+	return 0;
43047+
43048+error_free_pool:
43049+	higmac_destroy_hw_desc_queue(priv);
43050+
43051+	return -ENOMEM;
43052+}
43053+
43054+void higmac_init_napi(struct higmac_netdev_local *priv)
43055+{
43056+	struct higmac_napi *q_napi = NULL;
43057+	int i;
43058+	if (priv == NULL || priv->netdev == NULL)
43059+		return;
43060+	for (i = 0; i < priv->num_rxqs; i++) {
43061+		q_napi = &priv->q_napi[i];
43062+		q_napi->rxq_id = i;
43063+		q_napi->ndev_priv = priv;
43064+		netif_napi_add(priv->netdev, &q_napi->napi, higmac_poll,
43065+			       NAPI_POLL_WEIGHT);
43066+	}
43067+}
43068+
43069+void higmac_destroy_napi(struct higmac_netdev_local *priv)
43070+{
43071+	struct higmac_napi *q_napi = NULL;
43072+	int i;
43073+	if (priv == NULL)
43074+		return;
43075+	for (i = 0; i < priv->num_rxqs; i++) {
43076+		q_napi = &priv->q_napi[i];
43077+		netif_napi_del(&q_napi->napi);
43078+	}
43079+}
43080+
43081+int higmac_request_irqs(struct platform_device *pdev,
43082+			struct higmac_netdev_local *priv)
43083+{
43084+	struct device *dev = NULL;
43085+	int ret;
43086+	int i;
43087+	if (pdev == NULL || priv == NULL || priv->dev == NULL || pdev->name == NULL)
43088+		return -ENOMEM;
43089+
43090+	dev = priv->dev;
43091+	for (i = 0; i < priv->num_rxqs; i++) {
43092+		ret = platform_get_irq(pdev, i);
43093+		if (ret < 0) {
43094+			dev_err(dev, "No irq[%d] resource, ret=%d\n", i, ret);
43095+			return ret;
43096+		}
43097+		priv->irq[i] = ret;
43098+
43099+		ret = devm_request_irq(dev, priv->irq[i], higmac_interrupt,
43100+				       IRQF_SHARED, pdev->name,
43101+				       &priv->q_napi[i]);
43102+		if (ret) {
43103+			dev_err(dev, "devm_request_irq failed, ret=%d\n", ret);
43104+			return ret;
43105+		}
43106+	}
43107+
43108+	return 0;
43109+}
43110+
43111+static int higmac_dev_probe_res(struct platform_device *pdev,
43112+				struct higmac_netdev_local *priv)
43113+{
43114+	struct device *dev = &pdev->dev;
43115+	struct net_device *ndev = priv->netdev;
43116+	struct resource *res = NULL;
43117+	int ret;
43118+
43119+	res = platform_get_resource(pdev, IORESOURCE_MEM, MEM_GMAC_IOBASE);
43120+	priv->gmac_iobase = devm_ioremap_resource(dev, res);
43121+	if (IS_ERR(priv->gmac_iobase)) {
43122+		ret = PTR_ERR(priv->gmac_iobase);
43123+		return ret;
43124+	}
43125+
43126+	res = platform_get_resource(pdev, IORESOURCE_MEM, MEM_MACIF_IOBASE);
43127+	priv->macif_base = devm_ioremap_resource(dev, res);
43128+	if (IS_ERR(priv->macif_base)) {
43129+		ret = PTR_ERR(priv->macif_base);
43130+		return ret;
43131+	}
43132+
43133+	/* only for some chip to fix AXI bus burst and outstanding config */
43134+	res = platform_get_resource(pdev, IORESOURCE_MEM, MEM_AXI_BUS_CFG_IOBASE);
43135+	priv->axi_bus_cfg_base = devm_ioremap_resource(dev, res);
43136+	if (IS_ERR(priv->axi_bus_cfg_base))
43137+		priv->axi_bus_cfg_base = NULL;
43138+
43139+	priv->port_rst = devm_reset_control_get(dev, HIGMAC_PORT_RST_NAME);
43140+	if (IS_ERR(priv->port_rst)) {
43141+		ret = PTR_ERR(priv->port_rst);
43142+		return ret;
43143+	}
43144+
43145+	priv->macif_rst = devm_reset_control_get(dev, HIGMAC_MACIF_RST_NAME);
43146+	if (IS_ERR(priv->macif_rst)) {
43147+		ret = PTR_ERR(priv->macif_rst);
43148+		return ret;
43149+	}
43150+
43151+	priv->phy_rst = devm_reset_control_get(dev, HIGMAC_PHY_RST_NAME);
43152+	if (IS_ERR(priv->phy_rst))
43153+		priv->phy_rst = NULL;
43154+
43155+	priv->clk = devm_clk_get(&pdev->dev, HIGMAC_MAC_CLK_NAME);
43156+	if (IS_ERR(priv->clk)) {
43157+		netdev_err(ndev, "failed to get clk\n");
43158+		ret = -ENODEV;
43159+		return ret;
43160+	}
43161+
43162+	ret = clk_prepare_enable(priv->clk);
43163+	if (ret < 0) {
43164+		netdev_err(ndev, "failed to enable clk %d\n", ret);
43165+		return ret;
43166+	}
43167+	return 0;
43168+}
43169+
43170+static int higmac_dev_macif_clk(struct platform_device *pdev,
43171+				struct higmac_netdev_local *priv, struct net_device *ndev)
43172+{
43173+	int ret;
43174+
43175+	priv->macif_clk = devm_clk_get(&pdev->dev, HIGMAC_MACIF_CLK_NAME);
43176+	if (IS_ERR(priv->macif_clk))
43177+		priv->macif_clk = NULL;
43178+
43179+	if (priv->macif_clk != NULL) {
43180+		ret = clk_prepare_enable(priv->macif_clk);
43181+		if (ret < 0) {
43182+			netdev_err(ndev, "failed enable macif_clk %d\n", ret);
43183+			return ret;
43184+		}
43185+	}
43186+	return 0;
43187+}
43188+
43189+static int higmac_dev_probe_init(struct platform_device *pdev,
43190+				 struct higmac_netdev_local *priv, struct net_device *ndev)
43191+{
43192+	int ret;
43193+
43194+	higmac_init_napi(priv);
43195+	spin_lock_init(&priv->rxlock);
43196+	spin_lock_init(&priv->txlock);
43197+	spin_lock_init(&priv->pmtlock);
43198+
43199+	/* init netdevice */
43200+	ndev->irq = priv->irq[0];
43201+	ndev->watchdog_timeo = 3 * HZ; /* 3HZ */
43202+	ndev->netdev_ops = &hieth_netdev_ops;
43203+	ndev->ethtool_ops = &hieth_ethtools_ops;
43204+
43205+	if (priv->has_rxhash_cap)
43206+		ndev->hw_features |= NETIF_F_RXHASH;
43207+	if (priv->has_rss_cap)
43208+		ndev->hw_features |= NETIF_F_NTUPLE;
43209+	if (priv->tso_supported)
43210+		ndev->hw_features |= NETIF_F_SG |
43211+				     NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
43212+				     NETIF_F_TSO | NETIF_F_TSO6;
43213+
43214+#if defined(CONFIG_HIGMAC_RXCSUM)
43215+	ndev->hw_features |= NETIF_F_RXCSUM;
43216+	higmac_enable_rxcsum_drop(priv, true);
43217+#endif
43218+
43219+	ndev->features |= ndev->hw_features;
43220+	ndev->features |= NETIF_F_HIGHDMA | NETIF_F_GSO;
43221+	ndev->vlan_features |= ndev->features;
43222+
43223+	timer_setup(&priv->monitor, higmac_monitor_func, 0);
43224+
43225+	device_set_wakeup_capable(priv->dev, 1);
43226+	/*
43227+	 * when we can let phy powerdown?
43228+	 * In some mode, we don't want phy powerdown,
43229+	 * so I set wakeup enable all the time
43230+	 */
43231+	device_set_wakeup_enable(priv->dev, 1);
43232+
43233+	priv->wol_enable = false;
43234+
43235+	priv->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE);
43236+
43237+#if defined(CONFIG_HIGMAC_DDR_64BIT)
43238+	if (!has_cap_cci(priv->hw_cap)) {
43239+		struct device *dev = &pdev->dev;
43240+		ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); /* 64bit */
43241+		if (ret) {
43242+			pr_err("dma set mask 64 failed! ret=%d", ret);
43243+			return ret;
43244+		}
43245+	}
43246+#endif
43247+
43248+	/* init hw desc queue */
43249+	ret = higmac_init_hw_desc_queue(priv);
43250+	if (ret)
43251+		return ret;
43252+
43253+	return 0;
43254+}
43255+
43256+static int higmac_dev_probe_phy(struct platform_device *pdev,
43257+				struct higmac_netdev_local *priv, struct net_device *ndev,
43258+				bool fixed_link)
43259+{
43260+	int ret;
43261+
43262+	/* phy fix here?? other way ??? */
43263+	higmac_phy_register_fixups();
43264+
43265+	priv->phy = of_phy_connect(ndev, priv->phy_node,
43266+				   &higmac_adjust_link, 0, priv->phy_mode);
43267+	if (priv->phy == NULL || priv->phy->drv == NULL) {
43268+		ret = -ENODEV;
43269+		return ret;
43270+	}
43271+
43272+	/* If the phy_id is all zero and not fixed link, there is no device there */
43273+	if ((priv->phy->phy_id == 0) && !fixed_link) {
43274+		pr_info("phy %d not found\n", priv->phy->mdio.addr);
43275+		ret = -ENODEV;
43276+		return ret;
43277+	}
43278+
43279+	pr_info("attached PHY %d to driver %s, PHY_ID=0x%x\n",
43280+		priv->phy->mdio.addr, priv->phy->drv->name, priv->phy->phy_id);
43281+
43282+	/* Stop Advertising 1000BASE Capability if interface is not RGMII */
43283+	if ((priv->phy_mode == PHY_INTERFACE_MODE_MII) ||
43284+			(priv->phy_mode == PHY_INTERFACE_MODE_RMII)) {
43285+		priv->phy->advertising &= ~(SUPPORTED_1000baseT_Half |
43286+					    SUPPORTED_1000baseT_Full);
43287+
43288+		/*
43289+		 * Internal FE phy's reg BMSR bit8 is wrong, make the kernel
43290+		 * believe it has the 1000base Capability, so fix it here
43291+		 */
43292+		if (priv->phy->phy_id == HISILICON_PHY_ID_FESTAV200)
43293+			priv->phy->supported &= ~(ADVERTISED_1000baseT_Full |
43294+						  ADVERTISED_1000baseT_Half);
43295+	}
43296+
43297+	higmac_set_flow_ctrl_args(priv);
43298+	higmac_set_flow_ctrl_params(priv);
43299+	priv->phy->supported |= SUPPORTED_Pause;
43300+	if (priv->flow_ctrl)
43301+		priv->phy->advertising |= SUPPORTED_Pause;
43302+
43303+	if (priv->autoeee)
43304+		init_autoeee(priv);
43305+
43306+	ret = higmac_request_irqs(pdev, priv);
43307+	if (ret)
43308+		return ret;
43309+
43310+	return 0;
43311+}
43312+
43313+static void higmac_set_hw_cap(struct platform_device *pdev,
43314+			      struct higmac_netdev_local *priv)
43315+{
43316+	unsigned int hw_cap;
43317+
43318+	hw_cap = readl(priv->gmac_iobase + CRF_MIN_PACKET);
43319+	priv->tso_supported = has_tso_cap(hw_cap);
43320+	priv->has_rxhash_cap = has_rxhash_cap(hw_cap);
43321+	priv->has_rss_cap = has_rss_cap(hw_cap);
43322+
43323+	higmac_set_rss_cap(priv);
43324+	higmac_get_rss_key(priv);
43325+	if (priv->has_rss_cap) {
43326+		priv->rss_info.ind_tbl_size = RSS_INDIRECTION_TABLE_SIZE;
43327+		higmac_get_rss(priv);
43328+	}
43329+
43330+	if (priv->has_rxhash_cap) {
43331+		priv->rss_info.hash_cfg = DEF_HASH_CFG;
43332+		higmac_config_hash_policy(priv);
43333+	}
43334+}
43335+
43336+static void higmac_set_mac_addr(struct net_device *ndev,
43337+				struct device_node *node)
43338+{
43339+	const char *mac_addr = NULL;
43340+
43341+	mac_addr = of_get_mac_address(node);
43342+	if (mac_addr != NULL)
43343+		ether_addr_copy(ndev->dev_addr, mac_addr);
43344+	if (!is_valid_ether_addr(ndev->dev_addr)) {
43345+		eth_hw_addr_random(ndev);
43346+		netdev_warn(ndev, "using random MAC address %pM\n",
43347+			    ndev->dev_addr);
43348+	}
43349+
43350+	higmac_hw_set_mac_addr(ndev);
43351+}
43352+
43353+static int higmac_phy_init(struct device *dev, struct net_device *ndev,
43354+			   struct higmac_netdev_local *priv, struct device_node *node, bool *fixed_link)
43355+{
43356+	int ret;
43357+
43358+	/*
43359+	 * phy reset, should be early than "of_mdiobus_register".
43360+	 * becausue "of_mdiobus_register" will read PHY register by MDIO.
43361+	 */
43362+	higmac_hw_phy_reset(priv);
43363+
43364+	higmac_of_get_param(priv, node);
43365+
43366+	ret = of_get_phy_mode(node);
43367+	if (ret < 0) {
43368+		netdev_err(ndev, "not find phy-mode\n");
43369+		return ret;
43370+	}
43371+	priv->phy_mode = ret;
43372+
43373+	priv->phy_node = of_parse_phandle(node, "phy-handle", 0);
43374+	if (priv->phy_node == NULL) {
43375+		/* check if a fixed-link is defined in device-tree */
43376+		if (of_phy_is_fixed_link(node)) {
43377+			ret = of_phy_register_fixed_link(node);
43378+			if (ret < 0) {
43379+				dev_err(dev, "cannot register fixed PHY %d\n", ret);
43380+				return ret;
43381+			}
43382+
43383+			/*
43384+			 * In the case of a fixed PHY, the DT node associated
43385+			 * to the PHY is the Ethernet MAC DT node.
43386+			 */
43387+			priv->phy_node = of_node_get(node);
43388+			*fixed_link = true;
43389+		} else {
43390+			netdev_err(ndev, "not find phy-handle\n");
43391+			ret = -EINVAL;
43392+			return ret;
43393+		}
43394+	}
43395+	return 0;
43396+}
43397+
43398+static int higmac_dev_probe_device(struct platform_device *pdev,
43399+				   struct net_device **p_ndev, struct higmac_netdev_local **p_priv)
43400+{
43401+	struct device *dev = &pdev->dev;
43402+	struct device_node *node = dev->of_node;
43403+	struct net_device *ndev = NULL;
43404+	struct higmac_netdev_local *priv = NULL;
43405+	int num_rxqs;
43406+
43407+	higmac_verify_flow_ctrl_args();
43408+
43409+	if (of_device_is_compatible(node, "hisilicon,higmac-v5"))
43410+		num_rxqs = RSS_NUM_RXQS;
43411+	else
43412+		num_rxqs = 1;
43413+
43414+	ndev = alloc_etherdev_mqs(sizeof(struct higmac_netdev_local), 1,
43415+				  num_rxqs);
43416+	if (ndev == NULL)
43417+		return -ENOMEM;
43418+
43419+	platform_set_drvdata(pdev, ndev);
43420+	SET_NETDEV_DEV(ndev, dev);
43421+
43422+	priv = netdev_priv(ndev);
43423+	priv->dev = dev;
43424+	dev_hold(ndev);
43425+	priv->netdev = ndev;
43426+	priv->num_rxqs = num_rxqs;
43427+
43428+	if (of_device_is_compatible(node, "hisilicon,higmac-v3"))
43429+		priv->hw_cap |= HW_CAP_CCI;
43430+
43431+	*p_ndev = ndev;
43432+	*p_priv = priv;
43433+	return 0;
43434+}
43435+
43436+static int higmac_dev_probe_queue(struct platform_device *pdev,
43437+				  struct higmac_netdev_local *priv, struct net_device *ndev, bool fixed_link)
43438+{
43439+	int ret;
43440+
43441+	ret = higmac_dev_probe_init(pdev, priv, ndev);
43442+	if (ret)
43443+		goto _error_hw_desc_queue;
43444+
43445+	if (priv->tso_supported) {
43446+		ret = higmac_init_sg_desc_queue(priv);
43447+		if (ret)
43448+			goto _error_sg_desc_queue;
43449+	}
43450+
43451+	/* register netdevice */
43452+	ret = register_netdev(priv->netdev);
43453+	if (ret) {
43454+		pr_err("register_ndev failed!");
43455+		goto _error_sg_desc_queue;
43456+	}
43457+
43458+	/*
43459+	 * reset queue here to make BQL only reset once.
43460+	 * if we put netdev_reset_queue() in higmac_net_open(),
43461+	 * the BQL will be reset when ifconfig eth0 down and up,
43462+	 * but the tx ring is not cleared before.
43463+	 * As a result, the NAPI poll will call netdev_completed_queue()
43464+	 * and BQL throw a bug.
43465+	 */
43466+	netdev_reset_queue(ndev);
43467+
43468+	clk_disable_unprepare(priv->clk);
43469+	if (priv->macif_clk != NULL)
43470+		clk_disable_unprepare(priv->macif_clk);
43471+
43472+	pr_info("ETH: %s, phy_addr=%d\n",
43473+		phy_modes(priv->phy_mode), priv->phy->mdio.addr);
43474+
43475+	dev_put(ndev);
43476+	return ret;
43477+
43478+_error_sg_desc_queue:
43479+	if (priv->tso_supported)
43480+		higmac_destroy_sg_desc_queue(priv);
43481+_error_hw_desc_queue:
43482+	higmac_destroy_hw_desc_queue(priv);
43483+	higmac_destroy_napi(priv);
43484+
43485+	return ret;
43486+}
43487+
43488+static int higmac_dev_probe(struct platform_device *pdev)
43489+{
43490+	struct device *dev = &pdev->dev;
43491+	struct device_node *node = dev->of_node;
43492+	struct net_device *ndev = NULL;
43493+	struct higmac_netdev_local *priv = NULL;
43494+	int ret;
43495+	bool fixed_link = false;
43496+
43497+	ret = higmac_dev_probe_device(pdev, &ndev, &priv);
43498+	if (ret)
43499+		return ret;
43500+
43501+	ret = higmac_dev_probe_res(pdev, priv);
43502+	if (ret)
43503+		goto out_free_netdev;
43504+
43505+	ret = higmac_dev_macif_clk(pdev, priv, ndev);
43506+	if (ret)
43507+		goto out_clk_disable;
43508+
43509+	higmac_mac_core_reset(priv);
43510+
43511+	ret = higmac_phy_init(dev, ndev, priv, node, &fixed_link);
43512+	if (ret)
43513+		goto out_macif_clk_disable;
43514+
43515+	higmac_set_mac_addr(ndev, node);
43516+	higmac_set_hw_cap(pdev, priv);
43517+
43518+	/* init hw controller */
43519+	higmac_hw_init(priv);
43520+
43521+	ret = higmac_dev_probe_phy(pdev, priv, ndev, fixed_link);
43522+	if (ret) {
43523+		if (priv->phy == NULL)
43524+			goto out_phy_node;
43525+		else
43526+			goto out_phy_disconnect;
43527+	}
43528+
43529+	ret = higmac_dev_probe_queue(pdev, priv, ndev, fixed_link);
43530+	if (ret)
43531+		goto out_phy_disconnect;
43532+
43533+	return ret;
43534+
43535+out_phy_disconnect:
43536+	phy_disconnect(priv->phy);
43537+out_phy_node:
43538+	of_node_put(priv->phy_node);
43539+out_macif_clk_disable:
43540+	if (priv->macif_clk != NULL)
43541+		clk_disable_unprepare(priv->macif_clk);
43542+out_clk_disable:
43543+	clk_disable_unprepare(priv->clk);
43544+out_free_netdev:
43545+	dev_put(ndev);
43546+	free_netdev(ndev);
43547+
43548+	return ret;
43549+}
43550+
43551+static int higmac_dev_remove(struct platform_device *pdev)
43552+{
43553+	struct net_device *ndev = platform_get_drvdata(pdev);
43554+	struct higmac_netdev_local *priv = netdev_priv(ndev);
43555+
43556+	/* stop the gmac and free all resource */
43557+	del_timer_sync(&priv->monitor);
43558+	higmac_destroy_napi(priv);
43559+
43560+	unregister_netdev(ndev);
43561+
43562+	higmac_reclaim_rx_tx_resource(priv);
43563+	higmac_free_rx_skb(priv);
43564+	higmac_free_tx_skb(priv);
43565+
43566+	if (priv->tso_supported)
43567+		higmac_destroy_sg_desc_queue(priv);
43568+	higmac_destroy_hw_desc_queue(priv);
43569+
43570+	phy_disconnect(priv->phy);
43571+	of_node_put(priv->phy_node);
43572+
43573+	free_netdev(ndev);
43574+
43575+	higmac_phy_unregister_fixups();
43576+
43577+	return 0;
43578+}
43579+
43580+#ifdef CONFIG_PM
43581+static void higmac_disable_irq(struct higmac_netdev_local *priv)
43582+{
43583+	int i;
43584+
43585+	for (i = 0; i < priv->num_rxqs; i++)
43586+		disable_irq(priv->irq[i]);
43587+}
43588+
43589+static void higmac_enable_irq(struct higmac_netdev_local *priv)
43590+{
43591+	int i;
43592+
43593+	for (i = 0; i < priv->num_rxqs; i++)
43594+		enable_irq(priv->irq[i]);
43595+}
43596+
43597+int higmac_dev_suspend(struct platform_device *pdev, pm_message_t state)
43598+{
43599+	struct net_device *ndev = platform_get_drvdata(pdev);
43600+	struct higmac_netdev_local *priv = netdev_priv(ndev);
43601+
43602+	higmac_disable_irq(priv);
43603+	/*
43604+	 * If support Wake on LAN, we should not disconnect phy
43605+	 * because it will call phy_suspend to power down phy.
43606+	 */
43607+	if (!priv->wol_enable)
43608+		phy_disconnect(priv->phy);
43609+	del_timer_sync(&priv->monitor);
43610+	/*
43611+	 * If suspend when netif is not up, the napi_disable will run into
43612+	 * dead loop and dpm_drv_timeout will give warning.
43613+	 */
43614+	if (netif_running(ndev))
43615+		higmac_disable_napi(priv);
43616+	netif_device_detach(ndev);
43617+
43618+	netif_carrier_off(ndev);
43619+
43620+	/*
43621+	 * If netdev is down, MAC clock is disabled.
43622+	 * So if we want to reclaim MAC rx and tx resource,
43623+	 * we must first enable MAC clock and then disable it.
43624+	 */
43625+	if (!(ndev->flags & IFF_UP))
43626+		clk_prepare_enable(priv->clk);
43627+
43628+	higmac_reclaim_rx_tx_resource(priv);
43629+
43630+	if (!(ndev->flags & IFF_UP))
43631+		clk_disable_unprepare(priv->clk);
43632+
43633+	pmt_enter(priv);
43634+
43635+	if (!priv->wol_enable) {
43636+		/*
43637+		 * if no WOL, then poweroff
43638+		 * no need to call genphy_resume() in resume,
43639+		 * because we reset everything
43640+		 */
43641+		genphy_suspend(priv->phy); /* power down phy */
43642+		msleep(20); /* wait 20ms */
43643+		higmac_hw_all_clk_disable(priv);
43644+	}
43645+
43646+	return 0;
43647+}
43648+EXPORT_SYMBOL(higmac_dev_suspend);
43649+
43650+int higmac_dev_resume(struct platform_device *pdev)
43651+{
43652+	struct net_device *ndev = platform_get_drvdata(pdev);
43653+	struct higmac_netdev_local *priv = netdev_priv(ndev);
43654+	int ret;
43655+
43656+	/*
43657+	 * If we support Wake on LAN, we doesn't call clk_disable.
43658+	 * But when we resume, the uboot may off mac clock and reset phy
43659+	 * by re-write the mac CRG register.
43660+	 * So we first call clk_disable, and then clk_enable.
43661+	 */
43662+	if (priv->wol_enable)
43663+		higmac_hw_all_clk_disable(priv);
43664+
43665+	higmac_hw_all_clk_enable(priv);
43666+	/* internal FE_PHY: enable clk and reset  */
43667+	higmac_hw_phy_reset(priv);
43668+
43669+	/*
43670+	 * If netdev is down, MAC clock is disabled.
43671+	 * So if we want to restart MAC and re-initialize it,
43672+	 * we must first enable MAC clock and then disable it.
43673+	 */
43674+	if (!(ndev->flags & IFF_UP))
43675+		clk_prepare_enable(priv->clk);
43676+
43677+	/* power on gmac */
43678+	higmac_restart(priv);
43679+
43680+	/*
43681+	 * If support WoL, we didn't disconnect phy.
43682+	 * But when we resume, we reset PHY, so we want to
43683+	 * call phy_connect to make phy_fixup excuted.
43684+	 * This is important for internal PHY fix.
43685+	 */
43686+	if (priv->wol_enable)
43687+		phy_disconnect(priv->phy);
43688+
43689+	ret = phy_connect_direct(ndev, priv->phy, higmac_adjust_link,
43690+				 priv->phy_mode);
43691+	if (ret)
43692+		return ret;
43693+
43694+	/*
43695+	 * If we suspend and resume when net device is down,
43696+	 * some operations are unnecessary.
43697+	 */
43698+	if (ndev->flags & IFF_UP) {
43699+		priv->monitor.expires = jiffies + HIGMAC_MONITOR_TIMER;
43700+		mod_timer(&priv->monitor, priv->monitor.expires);
43701+		priv->old_link = 0;
43702+		priv->old_speed = SPEED_UNKNOWN;
43703+		priv->old_duplex = DUPLEX_UNKNOWN;
43704+	}
43705+	if (netif_running(ndev))
43706+		higmac_enable_napi(priv);
43707+	netif_device_attach(ndev);
43708+	if (ndev->flags & IFF_UP)
43709+		phy_start(priv->phy);
43710+	higmac_enable_irq(priv);
43711+
43712+	pmt_exit(priv);
43713+
43714+	if (!(ndev->flags & IFF_UP))
43715+		clk_disable_unprepare(priv->clk);
43716+
43717+	return 0;
43718+}
43719+EXPORT_SYMBOL(higmac_dev_resume);
43720+#else
43721+#define higmac_dev_suspend	NULL
43722+#define higmac_dev_resume	NULL
43723+#endif
43724+
43725+static const struct of_device_id higmac_of_match[] = {
43726+	{ .compatible = "hisilicon,higmac", },
43727+	{ .compatible = "hisilicon,higmac-v1", },
43728+	{ .compatible = "hisilicon,higmac-v2", },
43729+	{ .compatible = "hisilicon,higmac-v3", },
43730+	{ .compatible = "hisilicon,higmac-v4", },
43731+	{ .compatible = "hisilicon,higmac-v5", },
43732+	{ },
43733+};
43734+
43735+MODULE_DEVICE_TABLE(of, higmac_of_match);
43736+
43737+static struct platform_driver higmac_dev_driver = {
43738+	.probe = higmac_dev_probe,
43739+	.remove = higmac_dev_remove,
43740+	.suspend = higmac_dev_suspend,
43741+	.resume = higmac_dev_resume,
43742+	.driver = {
43743+		.owner = THIS_MODULE,
43744+		.name = HIGMAC_DRIVER_NAME,
43745+		.of_match_table = higmac_of_match,
43746+	},
43747+};
43748+
43749+#include "proc_dev.c"
43750+
43751+static int __init higmac_init(void)
43752+{
43753+	int ret;
43754+
43755+	ret = platform_driver_register(&higmac_dev_driver);
43756+	if (ret)
43757+		return ret;
43758+
43759+	higmac_proc_create();
43760+
43761+	return 0;
43762+}
43763+
43764+static void __exit higmac_exit(void)
43765+{
43766+	platform_driver_unregister(&higmac_dev_driver);
43767+
43768+	higmac_proc_destroy();
43769+}
43770+
43771+module_init(higmac_init);
43772+module_exit(higmac_exit);
43773+
43774+MODULE_AUTHOR("Hisilicon");
43775+MODULE_DESCRIPTION("Hisilicon double GMAC driver, base on driver higmacv200");
43776+MODULE_LICENSE("GPL v2");
43777diff --git a/drivers/net/ethernet/hisilicon/higmac/higmac.h b/drivers/net/ethernet/hisilicon/higmac/higmac.h
43778new file mode 100644
43779index 000000000..2e26d8064
43780--- /dev/null
43781+++ b/drivers/net/ethernet/hisilicon/higmac/higmac.h
43782@@ -0,0 +1,603 @@
43783+/*
43784+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
43785+ * Description: Higmac driver main process head file
43786+ * Author: KTP_BSP
43787+ * Create: 2018-10-08
43788+ */
43789+
43790+#ifndef __HIGMAC_HIGMAC_H__
43791+#define __HIGMAC_HIGMAC_H__
43792+
43793+#include <linux/kernel.h>
43794+#include <linux/delay.h>
43795+#include <linux/netdevice.h>
43796+#include <linux/list.h>
43797+#include <linux/phy.h>
43798+#include <linux/io.h>
43799+#include <linux/interrupt.h>
43800+
43801+#define STATION_ADDR_LOW		0x0000
43802+#define STATION_ADDR_HIGH		0x0004
43803+#define MAC_DUPLEX_HALF_CTRL		0x0008
43804+
43805+#define PORT_MODE			0x0040
43806+
43807+#define PORT_EN				0x0044
43808+#define BITS_TX_EN			BIT(2)
43809+#define BITS_RX_EN			BIT(1)
43810+
43811+#define FC_TX_TIMER			0x001C
43812+
43813+#define PAUSE_THR			0x0038
43814+
43815+#define PAUSE_EN			0x0048
43816+#define BIT_RX_FDFC			BIT(0)
43817+#define BIT_TX_FDFC			BIT(1)
43818+
43819+#define RX_PAUSE_EN			0x02A4
43820+#define BIT_RX_FQ_PAUSE_EN		BIT(0)
43821+#define BIT_RX_BQ_PAUSE_EN		BIT(1)
43822+
43823+#define CRF_TX_PAUSE			0x0340
43824+
43825+#define BITS_Q_PAUSE_TH_OFFSET		16
43826+#define BITS_Q_PAUSE_TH_MASK		0xFFFF
43827+
43828+#define REC_FILT_CONTROL		0x0064
43829+#define BIT_CRC_ERR_PASS		BIT(5)
43830+#define BIT_PAUSE_FRM_PASS		BIT(4)
43831+#define BIT_VLAN_DROP_EN		BIT(3)
43832+#define BIT_BC_DROP_EN			BIT(2)
43833+#define BIT_MC_MATCH_EN			BIT(1)
43834+#define BIT_UC_MATCH_EN			BIT(0)
43835+
43836+#define	PORT_MC_ADDR_LOW		0x0068
43837+#define	PORT_MC_ADDR_HIGH		0x006C
43838+#define MAC_CLEAR			0x0070
43839+#define BIT_TX_SOFT_RESET		BIT(0)
43840+
43841+#define MODE_CHANGE_EN			0x01b4
43842+#define BIT_MODE_CHANGE_EN		BIT(0)
43843+
43844+#define COL_SLOT_TIME			0x01c0
43845+
43846+#define CRF_MIN_PACKET			0x0210
43847+#define BIT_OFFSET_TX_MIN_LEN		8
43848+#define BIT_MASK_TX_MIN_LEN		GENMASK(13, 8)
43849+
43850+#define CONTROL_WORD			0x0214
43851+#define CONTROL_WORD_CONFIG		0x640
43852+
43853+#define TSO_COE_CTRL			0x02e8
43854+#define BIT_COE_IPHDR_DROP		BIT(4)
43855+#define BIT_COE_PAYLOAD_DROP		BIT(5)
43856+#define BIT_COE_IPV6_UDP_ZERO_DROP	BIT(6)
43857+#define COE_ERR_DROP			(BIT_COE_IPHDR_DROP | \
43858+					BIT_COE_PAYLOAD_DROP | \
43859+					BIT_COE_IPV6_UDP_ZERO_DROP)
43860+
43861+#define RX_FQ_START_ADDR		0x0500
43862+#define RX_FQ_DEPTH			0x0504
43863+#define REG_BIT_WIDTH			32
43864+#define Q_ADDR_HI8_OFFSET		24
43865+#define Q_ADDR_HI8_MASK			(BIT(Q_ADDR_HI8_OFFSET) - 1)
43866+#define TX_DESC_HI8_MASK		0xff
43867+#define SG_DESC_HI8_OFFSET		8
43868+#define RX_FQ_WR_ADDR			0x0508
43869+#define BITS_RX_FQ_WR_ADDR		mk_bits(0, 21)
43870+#define RX_FQ_RD_ADDR			0x050c
43871+#define BITS_RX_FQ_RD_ADDR		mk_bits(0, 21)
43872+#define RX_FQ_VLDDESC_CNT		0x0510
43873+#define BITS_RX_FQ_VLDDESC_CNT		mk_bits(0, 16)
43874+#define RX_FQ_ALEMPTY_TH		0x0514
43875+#define BITS_RX_FQ_ALEMPTY_TH		mk_bits(0, 16)
43876+#define RX_FQ_REG_EN			0x0518
43877+#define BITS_RX_FQ_START_ADDR_EN	BIT(2)
43878+#define BITS_RX_FQ_DEPTH_EN		BIT(1)
43879+#define BITS_RX_FQ_RD_ADDR_EN		mk_bits(0, 1)
43880+#define RX_FQ_ALFULL_TH			0x051c
43881+#define BITS_RX_FQ_ALFULL_TH		mk_bits(0, 16)
43882+
43883+#define RX_BQ_START_ADDR		0x0520
43884+#define RX_BQ_DEPTH			0x0524
43885+#define RX_BQ_WR_ADDR			0x0528
43886+#define RX_BQ_RD_ADDR			0x052c
43887+#define RX_BQ_FREE_DESC_CNT		0x0530
43888+#define BITS_RX_BQ_FREE_DESC_CNT	mk_bits(0, 16)
43889+#define RX_BQ_ALEMPTY_TH		0x0534
43890+#define BITS_RX_BQ_ALEMPTY_TH		mk_bits(0, 16)
43891+#define RX_BQ_REG_EN			0x0538
43892+#define BITS_RX_BQ_START_ADDR_EN	BIT(2)
43893+#define BITS_RX_BQ_DEPTH_EN		BIT(1)
43894+#define BITS_RX_BQ_WR_ADDR_EN		mk_bits(0, 1)
43895+#define RX_BQ_ALFULL_TH			0x053c
43896+#define BITS_RX_BQ_ALFULL_TH		mk_bits(0, 16)
43897+
43898+#define TX_BQ_START_ADDR		0x0580
43899+#define TX_BQ_DEPTH			0x0584
43900+#define TX_BQ_WR_ADDR			0x0588
43901+#define BITS_TX_BQ_WR_ADDR		mk_bits(0, 21)
43902+#define TX_BQ_RD_ADDR			0x058c
43903+#define BITS_TX_BQ_RD_ADDR		mk_bits(0, 21)
43904+#define TX_BQ_VLDDESC_CNT		0x0590
43905+#define BITS_TX_BQ_VLDDESC_CNT		mk_bits(0, 16)
43906+#define TX_BQ_ALEMPTY_TH		0x0594
43907+#define BITS_TX_BQ_ALEMPTY_TH		mk_bits(0, 16)
43908+#define TX_BQ_REG_EN			0x0598
43909+#define BITS_TX_BQ_START_ADDR_EN	BIT(2)
43910+#define BITS_TX_BQ_DEPTH_EN		BIT(1)
43911+#define BITS_TX_BQ_RD_ADDR_EN		mk_bits(0, 1)
43912+#define TX_BQ_ALFULL_TH			0x059c
43913+#define BITS_TX_BQ_ALFULL_TH		mk_bits(0, 16)
43914+
43915+#define TX_RQ_START_ADDR		0x05a0
43916+#define TX_RQ_DEPTH			0x05a4
43917+#define TX_RQ_WR_ADDR			0x05a8
43918+#define BITS_TX_RQ_WR_ADDR		mk_bits(0, 21)
43919+#define TX_RQ_RD_ADDR			0x05ac
43920+#define BITS_TX_RQ_RD_ADDR		mk_bits(0, 21)
43921+#define TX_RQ_FREE_DESC_CNT		0x05b0
43922+#define BITS_TX_RQ_FREE_DESC_CNT	mk_bits(0, 16)
43923+#define TX_RQ_ALEMPTY_TH		0x05b4
43924+#define BITS_TX_RQ_ALEMPTY_TH		mk_bits(0, 16)
43925+#define TX_RQ_REG_EN			0x05b8
43926+#define BITS_TX_RQ_START_ADDR_EN	BIT(2)
43927+#define BITS_TX_RQ_DEPTH_EN		BIT(1)
43928+#define BITS_TX_RQ_WR_ADDR_EN		mk_bits(0, 1)
43929+#define TX_RQ_ALFULL_TH			0x05bc
43930+#define BITS_TX_RQ_ALFULL_TH		mk_bits(0, 16)
43931+
43932+#define RAW_PMU_INT			0x05c0
43933+#define ENA_PMU_INT			0x05c4
43934+
43935+#define DESC_WR_RD_ENA				0x05CC
43936+
43937+#define IN_QUEUE_TH					0x05d8
43938+#define BITS_OFFSET_TX_RQ_IN_TH			16
43939+
43940+#define RX_BQ_IN_TIMEOUT_TH			0x05E0
43941+
43942+#define TX_RQ_IN_TIMEOUT_TH			0x05e4
43943+
43944+#define STOP_CMD			0x05e8
43945+#define BITS_TX_STOP_EN			BIT(1)
43946+#define BITS_RX_STOP_EN			BIT(0)
43947+#define	STOP_RX_TX			(BITS_TX_STOP_EN | BITS_RX_STOP_EN)
43948+
43949+#define RSS_IND_TBL			0x0c0c
43950+#define BIT_IND_TBL_READY		BIT(13)
43951+#define BIT_IND_TLB_WR			BIT(12)
43952+#define RSS_RAW_PMU_INT			0x0c10
43953+#define RSS_QUEUE1_START_ADDR		0x0c20
43954+#define rx_bq_start_addr_queue(i)	(RSS_QUEUE1_START_ADDR + \
43955+					((i) - 1) * 0x10)
43956+#define RSS_QUEUE1_DEPTH		0x0c24
43957+#define RX_BQ_WR_ADDR_QUEUE1		0x0c28
43958+#define RX_BQ_RD_ADDR_QUEUE1		0x0c2c
43959+#define RSS_QUEUE1_ENA_INT		0x0c90
43960+#define rss_ena_int_queue(i)		(RSS_QUEUE1_ENA_INT + ((i) - 1) * 0x4)
43961+#define rx_bq_depth_queue(i)		(RSS_QUEUE1_DEPTH + ((i) - 1) * 0x10)
43962+#define rx_bq_wr_addr_queue(i)		((i) ? (RX_BQ_WR_ADDR_QUEUE1 + \
43963+					((i) - 1) * 0x10) : RX_BQ_WR_ADDR)
43964+#define rx_bq_rd_addr_queue(i)		((i) ? (RX_BQ_RD_ADDR_QUEUE1 + \
43965+					((i) - 1) * 0x10) : RX_BQ_RD_ADDR)
43966+
43967+#define def_int_mask_queue(i)		(0x3 << (2 * ((i) - 1)))
43968+
43969+/* AXI burst and outstanding config */
43970+#define BURST_OUTSTANDING_REG		0x3014
43971+#define BURST4_OUTSTANDING1		0x81ff
43972+#define BURST_OUTSTANDING_OFFSET	16
43973+
43974+#define GMAC_SPEED_1000			0x05
43975+#define GMAC_SPEED_100			0x01
43976+#define GMAC_SPEED_10			0x00
43977+
43978+#define IPV4_HEAD_LENGTH		0x5
43979+
43980+enum higmac_tx_err {
43981+	ERR_NONE = 0,
43982+	ERR_DESC_CFG = (1 << 0),
43983+	ERR_DATA_LEN = (1 << 1),
43984+	ERR_DESC_NFRAG_NUM = (1 << 2), /* bit2 */
43985+	ERR_DESC_IP_HDR_LEN = (1 << 3), /* bit3 */
43986+	ERR_DESC_PROT_HDR_LEN = (1 << 4), /* bit4 */
43987+	ERR_DESC_MTU = (1 << 5), /* bit5 */
43988+	ERR_LINK_SGPKT_LEN = (1 << 8), /* bit8 */
43989+	ERR_LINK_TSOPKT_LINEAR = (1 << 9), /* bit9 */
43990+	ERR_LINK_NFRAG_LEN = (1 << 10), /* bit10 */
43991+	ERR_LINK_TOTAL_LEN = (1 << 11), /* bit11 */
43992+	ERR_HDR_TCP_BCMC = (1 << 12), /* bit12 */
43993+	ERR_HDR_UDP_BC = (1 << 13), /* bit13 */
43994+	ERR_HDR_VLAN_IP_TYPE = (1 << 14), /* bit14 */
43995+	ERR_HDR_IP_TYPE = (1 << 15), /* bit15 */
43996+	ERR_HDR_IP_VERSION = (1 << 16), /* bit16 */
43997+	ERR_HDR_IP_HDR_LEN = (1 << 17), /* bit17 */
43998+	ERR_HDR_IP_TOTAL_LEN = (1 << 18), /* bit18 */
43999+	ERR_HDR_IPV6_TTL_PROT = (1 << 19), /* bit19 */
44000+	ERR_HDR_IPV4_OFFSET = (1 << 20), /* bit20 */
44001+	ERR_HDR_IPV4_TTL_PROT = (1 << 21), /* bit21 */
44002+	ERR_HDR_UDP_LEN = (1 << 22), /* bit22 */
44003+	ERR_HDR_TCP_LEN = (1 << 23), /* bit23 */
44004+	ERR_DESC = (ERR_DESC_CFG | ERR_DATA_LEN |
44005+		    ERR_DESC_NFRAG_NUM | ERR_DESC_IP_HDR_LEN |
44006+		    ERR_DESC_PROT_HDR_LEN | ERR_DESC_MTU),
44007+	ERR_LINK = (ERR_LINK_SGPKT_LEN | ERR_LINK_TSOPKT_LINEAR |
44008+		    ERR_LINK_NFRAG_LEN | ERR_LINK_TOTAL_LEN),
44009+	ERR_HDR = (ERR_HDR_TCP_BCMC | ERR_HDR_UDP_BC |
44010+		   ERR_HDR_VLAN_IP_TYPE | ERR_HDR_IP_TYPE |
44011+		   ERR_HDR_IP_VERSION | ERR_HDR_IP_HDR_LEN |
44012+		   ERR_HDR_IP_TOTAL_LEN | ERR_HDR_IPV6_TTL_PROT |
44013+		   ERR_HDR_IPV4_OFFSET | ERR_HDR_IPV4_TTL_PROT |
44014+		   ERR_HDR_UDP_LEN | ERR_HDR_TCP_LEN),
44015+	ERR_ALL = (ERR_DESC | ERR_LINK | ERR_HDR),
44016+};
44017+
44018+#define HIGMAC_DRIVER_NAME	"hi_gmac_v200"
44019+
44020+#define HIGMAC_MAC_CLK_NAME	"higmac_clk"
44021+#define HIGMAC_MACIF_CLK_NAME	"macif_clk"
44022+
44023+#define HIGMAC_PORT_RST_NAME	"port_reset"
44024+#define HIGMAC_MACIF_RST_NAME	"macif_reset"
44025+#define HIGMAC_PHY_RST_NAME	"phy_reset"
44026+
44027+#define HIGMAC_TSO_DEBUG
44028+
44029+#include "tso.h"
44030+
44031+#if defined(CONFIG_ARCH_HI3519) || defined(CONFIG_ARCH_HI3519V101) || \
44032+	defined(CONFIG_ARCH_HI3516AV200)
44033+#ifdef readl
44034+#undef readl
44035+#undef readl_relaxed
44036+#undef writel
44037+#undef writel_relaxed
44038+#define readl		hi_readl
44039+#define readl_relaxed	hi_readl_relaxed
44040+#define writel		hi_writel
44041+#define writel_relaxed	hi_writel_relaxed
44042+#endif /* readl */
44043+#endif /* defined(CONFIG_ARCH_HI3519) || defined(CONFIG_HI3519V101) */
44044+
44045+#define HIGMAC_IOSIZE			0x1000
44046+#define HIGMAC_OFFSET			(HIGMAC_IOSIZE)
44047+
44048+#define RX_BQ_IN_INT			BIT(17)
44049+#define TX_RQ_IN_INT			BIT(19)
44050+#define RX_BQ_IN_TIMEOUT_INT		BIT(28)
44051+#define TX_RQ_IN_TIMEOUT_INT		BIT(29)
44052+
44053+#define DEF_INT_MASK			(RX_BQ_IN_INT | RX_BQ_IN_TIMEOUT_INT | \
44054+					TX_RQ_IN_INT | TX_RQ_IN_TIMEOUT_INT)
44055+
44056+/* write or read descriptor need memory barrier */
44057+#define higmac_sync_barrier() do { isb(); smp_mb(); } while (0)
44058+
44059+#define HISILICON_PHY_ID_FESTAV200      0x20669823
44060+#define PHY_ID_KSZ8051MNL               0x00221550
44061+#define PHY_ID_KSZ8081RNB               0x00221560
44062+#define PHY_ID_UNKNOWN                  0x00221513
44063+#define DEFAULT_PHY_MASK                0xfffffff0
44064+#define REALTEK_PHY_ID_8211E            0x001cc915
44065+#define REALTEK_PHY_MASK                0x001fffff
44066+
44067+enum {
44068+	GMAC_PORT0,
44069+	GMAC_PORT1,
44070+	GMAC_MAX_PORT,
44071+};
44072+
44073+enum {
44074+	MEM_GMAC_IOBASE,
44075+	MEM_MACIF_IOBASE,
44076+	MEM_AXI_BUS_CFG_IOBASE,
44077+	MEM_FWD_IOBASE,
44078+	MEM_CTRL_IOBASE,
44079+};
44080+
44081+#define HIGMAC_LINKED		BIT(0)
44082+#define HIGMAC_DUP_FULL		BIT(1)
44083+#define HIGMAC_SPD_10M		BIT(2)
44084+#define HIGMAC_SPD_100M		BIT(3)
44085+#define HIGMAC_SPD_1000M	BIT(4)
44086+/* Flow Control defines */
44087+#define FLOW_OFF        0
44088+#define FLOW_RX         1
44089+#define FLOW_TX         2
44090+#define FLOW_AUTO       (FLOW_TX | FLOW_RX)
44091+
44092+#define RX_BQ_INT_THRESHOLD	0x40
44093+#define TX_RQ_INT_THRESHOLD	0x20
44094+
44095+#define HIGMAC_MONITOR_TIMER	(msecs_to_jiffies(200))
44096+
44097+#define HIETH_MAX_FRAME_SIZE	(1600 + 128)
44098+#define SKB_SIZE		(HIETH_MAX_FRAME_SIZE)
44099+
44100+#define DESC_VLD_FREE		0
44101+#define DESC_VLD_BUSY		1
44102+
44103+#define DESC_FL_FIRST		2
44104+#define DESC_FL_MID		0
44105+#define DESC_FL_LAST		1
44106+#define DESC_FL_FULL		3
44107+
44108+#if defined(CONFIG_HIGMAC_DESC_4WORD)
44109+#define DESC_WORD_SHIFT		2
44110+#else
44111+#define DESC_WORD_SHIFT		3
44112+#endif
44113+#define DESC_BYTE_SHIFT		(DESC_WORD_SHIFT + 2)
44114+#define DESC_WORD_CNT		(1 << DESC_WORD_SHIFT)
44115+#define DESC_SIZE		(1 << DESC_BYTE_SHIFT)
44116+
44117+#define RX_DESC_NUM			1024
44118+#define TX_DESC_NUM			1024
44119+
44120+/* DMA descriptor ring helpers */
44121+#define dma_ring_incr(n, s)		(((n) + 1) & ((s) - 1))
44122+#define dma_cnt(n)			((n) >> DESC_BYTE_SHIFT)
44123+#define dma_byte(n)			((n) << DESC_BYTE_SHIFT)
44124+
44125+#define RSS_HASH_KEY_SIZE		4
44126+#define RSS_INDIRECTION_TABLE_SIZE	128
44127+#define RSS_NUM_RXQS		4
44128+
44129+#define HW_CAP_TSO			BIT(0)
44130+#define HW_CAP_RXCSUM			BIT(1)
44131+#define HW_CAP_CCI			BIT(2)
44132+#define has_cap_tso(hw_cap)		((hw_cap) & HW_CAP_TSO)
44133+#define has_cap_rxcsum(hw_cap)		((hw_cap) & HW_CAP_RXCSUM)
44134+#define has_cap_cci(hw_cap)		((hw_cap) & HW_CAP_CCI)
44135+
44136+#if defined(CONFIG_HIGMAC_DESC_4WORD)
44137+struct higmac_desc {
44138+	unsigned int data_buff_addr;
44139+
44140+	unsigned int buffer_len : 11;
44141+#if defined(CONFIG_HIGMAC_RXCSUM)
44142+	unsigned int reserve2 : 1;
44143+	unsigned int payload_csum_err : 1;
44144+	unsigned int header_csum_err : 1;
44145+	unsigned int payload_csum_done : 1;
44146+	unsigned int header_csum_done : 1;
44147+#else
44148+	unsigned int reserve2 : 5;
44149+#endif
44150+	unsigned int data_len : 11;
44151+	unsigned int reserve1 : 2;
44152+	unsigned int fl : 2;
44153+	unsigned int descvid : 1;
44154+
44155+	unsigned int rxhash;
44156+	unsigned int reserve3 : 8;
44157+	unsigned int l3_hash : 1;
44158+	unsigned int has_hash : 1;
44159+	unsigned int skb_id : 14;
44160+	unsigned int reserve31 : 8;
44161+};
44162+
44163+struct higmac_tso_desc {
44164+	unsigned int data_buff_addr;
44165+	union {
44166+		struct {
44167+			unsigned int prot_hdr_len : 4;
44168+			unsigned int ip_hdr_len : 4;
44169+			unsigned int prot_type : 1;
44170+			unsigned int ip_ver : 1;
44171+			unsigned int vlan_flag : 1;
44172+			unsigned int nfrags_num : 5;
44173+			unsigned int data_len : 11;
44174+			unsigned int reservel : 1;
44175+			unsigned int tso_flag : 1;
44176+			unsigned int coe_flag : 1;
44177+			unsigned int sg_flag : 1;
44178+			unsigned int hw_own : 1;
44179+		} tx;
44180+		unsigned int val;
44181+	} desc1;
44182+	unsigned int reserve_desc2;
44183+	unsigned int tx_err;
44184+};
44185+#else
44186+struct higmac_desc {
44187+	unsigned int data_buff_addr;
44188+
44189+	unsigned int buffer_len : 11;
44190+#if defined(CONFIG_HIGMAC_RXCSUM)
44191+	unsigned int reserve2 : 1;
44192+	unsigned int payload_csum_err : 1;
44193+	unsigned int header_csum_err : 1;
44194+	unsigned int payload_csum_done : 1;
44195+#else
44196+	unsigned int reserve2 : 5;
44197+#endif
44198+	unsigned int data_len : 11;
44199+	unsigned int reserve1 : 2;
44200+	unsigned int fl : 2;
44201+	unsigned int descvid : 1;
44202+
44203+	unsigned int rxhash;
44204+	unsigned int reserve3 : 8;
44205+	unsigned int l3_hash : 1;
44206+	unsigned int has_hash : 1;
44207+	unsigned int skb_id : 14;
44208+	unsigned int reserve31 : 8;
44209+
44210+	unsigned int reserve4;
44211+	unsigned int reserve5;
44212+	unsigned int reserve6;
44213+	unsigned int reserve7;
44214+};
44215+
44216+struct higmac_tso_desc {
44217+	unsigned int data_buff_addr;
44218+	union {
44219+		struct {
44220+			unsigned int prot_hdr_len : 4;
44221+			unsigned int ip_hdr_len : 4;
44222+			unsigned int prot_type : 1;
44223+			unsigned int ip_ver : 1;
44224+			unsigned int vlan_flag : 1;
44225+			unsigned int nfrags_num : 5;
44226+			unsigned int data_len : 11;
44227+			unsigned int reservel : 1;
44228+			unsigned int tso_flag : 1;
44229+			unsigned int coe_flag : 1;
44230+			unsigned int sg_flag : 1;
44231+			unsigned int hw_own : 1;
44232+		} tx;
44233+		unsigned int val;
44234+	} desc1;
44235+	unsigned int reserve_desc2;
44236+	unsigned int reserve3;
44237+
44238+	unsigned int tx_err;
44239+	unsigned int reserve5;
44240+	unsigned int reserve6;
44241+	unsigned int reserve7;
44242+};
44243+#endif
44244+
44245+#define SKB_MAGIC	((struct sk_buff *)0x5a)
44246+
44247+struct higmac_napi {
44248+	struct napi_struct napi;
44249+	struct higmac_netdev_local *ndev_priv;
44250+	int rxq_id;
44251+};
44252+
44253+struct higmac_rss_info {
44254+	u32 hash_cfg;
44255+	u32 ind_tbl_size;
44256+	u8 ind_tbl[RSS_INDIRECTION_TABLE_SIZE];
44257+	u8 key[RSS_HASH_KEY_SIZE];
44258+};
44259+
44260+#define QUEUE_NUMS	4
44261+#define BASE_QUEUE_NUMS 3
44262+
44263+struct higmac_netdev_local {
44264+#define HIGMAC_SG_DESC_ADD	64U
44265+	struct sg_desc *dma_sg_desc ____cacheline_aligned;
44266+	dma_addr_t dma_sg_phy;
44267+	unsigned int sg_head;
44268+	unsigned int sg_tail;
44269+	unsigned int sg_count;
44270+
44271+	void __iomem *gmac_iobase;
44272+	void __iomem *macif_base;
44273+	void __iomem *axi_bus_cfg_base;
44274+	int index; /* 0 -- mac0, 1 -- mac1 */
44275+
44276+	u32 hw_cap;
44277+	bool tso_supported;
44278+	bool has_rxhash_cap;
44279+	bool has_rss_cap;
44280+	int num_rxqs;
44281+	struct higmac_napi q_napi[RSS_NUM_RXQS];
44282+	int irq[RSS_NUM_RXQS];
44283+	struct higmac_rss_info rss_info;
44284+
44285+	struct reset_control *port_rst;
44286+	struct reset_control *macif_rst;
44287+	struct reset_control *phy_rst;
44288+
44289+	struct {
44290+		struct higmac_desc *desc;
44291+		dma_addr_t phys_addr;
44292+		int *sg_desc_offset;
44293+		/* how many desc in the desc pool */
44294+		unsigned int count;
44295+		struct sk_buff **skb;
44296+		unsigned int size;
44297+	} pool[QUEUE_NUMS + RSS_NUM_RXQS - 1];
44298+#define RX_FQ		pool[0]
44299+#define RX_BQ		pool[1]
44300+#define TX_BQ		pool[2]
44301+#define TX_RQ		pool[3]
44302+
44303+	struct sk_buff **tx_skb;
44304+	struct sk_buff **rx_skb;
44305+
44306+	struct device *dev;
44307+	struct net_device *netdev;
44308+	struct clk *clk;
44309+	struct clk *macif_clk;
44310+
44311+	struct higmac_adapter *adapter;
44312+
44313+	struct timer_list monitor;
44314+
44315+	char phy_name[MII_BUS_ID_SIZE];
44316+	struct phy_device *phy;
44317+	struct device_node *phy_node;
44318+	phy_interface_t phy_mode;
44319+	bool autoeee;
44320+	bool internal_phy;
44321+	int (*eee_init)(struct phy_device *phy_dev);
44322+
44323+	unsigned int flow_ctrl;
44324+	unsigned int pause;
44325+	unsigned int pause_interval;
44326+	unsigned int flow_ctrl_active_threshold;
44327+	unsigned int flow_ctrl_deactive_threshold;
44328+
44329+	int old_link;
44330+	int old_speed;
44331+	int old_duplex;
44332+
44333+	/* receive packet lock */
44334+	spinlock_t rxlock;
44335+	/* transmit packet lock */
44336+	spinlock_t txlock;
44337+	/* power management lock */
44338+	spinlock_t pmtlock;
44339+
44340+	int dev_state; /* INIT/OPEN/CLOSE */
44341+	char pm_state;
44342+	bool wol_enable;
44343+	u32 msg_enable;
44344+#define INIT			0 /* init gmac */
44345+#define OPEN			1 /* power on gmac */
44346+#define CLOSE			2 /* power off gmac */
44347+};
44348+
44349+enum tso_version {
44350+	VER_NO_TSO = 0x0,
44351+	VER_BYTE_SPLICE = 0x1,
44352+	VER_SG_COE = 0x2,
44353+	VER_TSO = 0x3,
44354+};
44355+
44356+#ifdef HIGMAC_TSO_DEBUG
44357+#define MAX_RECORD	100
44358+struct send_pkt_info {
44359+	struct higmac_tso_desc desc;
44360+	int status;
44361+};
44362+#endif
44363+
44364+struct cyclic_queue_info {
44365+	u32 start;
44366+	u32 end;
44367+	u32 num;
44368+	u32 pos;
44369+};
44370+
44371+int higmac_tx_avail(struct higmac_netdev_local const *ld);
44372+
44373+/* board related func */
44374+void higmac_mac_core_reset(struct higmac_netdev_local *priv);
44375+void higmac_hw_internal_phy_reset(struct higmac_netdev_local *priv);
44376+void higmac_hw_external_phy_reset(struct higmac_netdev_local *priv);
44377+void higmac_internal_phy_clk_disable(struct higmac_netdev_local const *priv);
44378+void higmac_internal_phy_clk_enable(struct higmac_netdev_local const *priv);
44379+void higmac_hw_all_clk_disable(struct higmac_netdev_local *priv);
44380+void higmac_hw_all_clk_enable(struct higmac_netdev_local *priv);
44381+
44382+/* board independent func */
44383+void higmac_hw_phy_reset(struct higmac_netdev_local *priv);
44384+
44385+#endif
44386diff --git a/drivers/net/ethernet/hisilicon/higmac/pm.c b/drivers/net/ethernet/hisilicon/higmac/pm.c
44387new file mode 100644
44388index 000000000..4ad8e7c0c
44389--- /dev/null
44390+++ b/drivers/net/ethernet/hisilicon/higmac/pm.c
44391@@ -0,0 +1,341 @@
44392+/*
44393+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
44394+ * Description: Higmac driver pm process
44395+ * Author: KTP_BSP
44396+ * Create: 2018-10-08
44397+ */
44398+
44399+#include <linux/crc16.h>
44400+#include "pm.h"
44401+
44402+struct pm_reg_config pm_reg_config_backup;
44403+
44404+static void init_crc_table(void);
44405+static unsigned short compute_crc(const char *message, int nbytes);
44406+static unsigned short calculate_crc16(const char *buf, unsigned int mask)
44407+{
44408+	char data[N];
44409+	int i;
44410+	int len = 0;
44411+
44412+	memset(data, 0, sizeof(data));
44413+
44414+	for (i = 0; i < N; i++) {
44415+		if (mask & 0x1)
44416+			data[len++] = buf[i];
44417+
44418+		mask >>= 1;
44419+	}
44420+
44421+	return compute_crc(data, len);
44422+}
44423+
44424+/* use this func in config pm func */
44425+void _pmt_reg_backup(struct higmac_netdev_local const *ld)
44426+{
44427+	if (ld == NULL)
44428+		return;
44429+	pm_reg_config_backup.pmt_ctrl = readl(ld->gmac_iobase + PMT_CTRL);
44430+	pm_reg_config_backup.pmt_mask0 = readl(ld->gmac_iobase + PMT_MASK0);
44431+	pm_reg_config_backup.pmt_mask1 = readl(ld->gmac_iobase + PMT_MASK1);
44432+	pm_reg_config_backup.pmt_mask2 = readl(ld->gmac_iobase + PMT_MASK2);
44433+	pm_reg_config_backup.pmt_mask3 = readl(ld->gmac_iobase + PMT_MASK3);
44434+	pm_reg_config_backup.pmt_cmd = readl(ld->gmac_iobase + PMT_CMD);
44435+	pm_reg_config_backup.pmt_offset = readl(ld->gmac_iobase + PMT_OFFSET);
44436+	pm_reg_config_backup.pmt_crc1_0 = readl(ld->gmac_iobase + PMT_CRC1_0);
44437+	pm_reg_config_backup.pmt_crc3_2 = readl(ld->gmac_iobase + PMT_CRC3_2);
44438+}
44439+
44440+#define	PM_SET			1
44441+#define PM_CLEAR		0
44442+
44443+static void pmt_config_filter(struct pm_config const *config,
44444+			      struct higmac_netdev_local const *ld)
44445+{
44446+	unsigned int v;
44447+	unsigned int cmd = 0;
44448+	unsigned int offset = 0;
44449+	unsigned short crc[FILTERS] = { 0 };
44450+	int reg_mask;
44451+	unsigned int i;
44452+
44453+	/*
44454+	 * filter.valid		mask.valid	mask_bytes	effect
44455+	 *	0		*		*		no use the filter
44456+	 *	1		0		*	all pkts can wake-up(non-exist)
44457+	 *	1		1		0		all pkts can wake-up
44458+	 *	1		1		!0		normal filter
44459+	 */
44460+	/* setup filter */
44461+	for (i = 0; i < FILTERS; i++) {
44462+		if (config->filter[i].valid) {
44463+			if (config->filter[i].offset < PM_FILTER_OFFSET_MIN)
44464+				continue;
44465+			/* high 8 bits offset and low 8 bits valid bit */
44466+			offset |= config->filter[i].offset << (i * 8);
44467+			cmd |= BIT(i * 8); /* valid bit8 */
44468+			/* mask offset 4i */
44469+			reg_mask = PMT_MASK0 + (i * 4);
44470+
44471+			/*
44472+			 * for logic, mask valid bit(bit31) must set to 0,
44473+			 * 0 is enable
44474+			 */
44475+			v = config->filter[i].mask_bytes;
44476+			v &= ~BIT(31); /* bit31 */
44477+			writel(v, ld->gmac_iobase + reg_mask);
44478+
44479+			/* crc */
44480+			crc[i] = calculate_crc16(config->filter[i].value, v);
44481+			if (i <= 1) { /* for filter0 and filter 1 */
44482+				v = readl(ld->gmac_iobase + PMT_CRC1_0);
44483+				v &= ~(0xFFFF << (16 * i)); /* 16 bits mask */
44484+				v |= crc[i] << (16 * i); /* 16 bits mask */
44485+				writel(v, ld->gmac_iobase + PMT_CRC1_0);
44486+			} else { /* filter2 and filter3 */
44487+				v = readl(ld->gmac_iobase + PMT_CRC3_2);
44488+				v &= ~(0xFFFF << (16 * (i - 2))); /* filer 2 3, 16 bits mask */
44489+				v |= crc[i] << (16 * (i - 2)); /* filer 2 3, 16 bits mask */
44490+				writel(v, ld->gmac_iobase + PMT_CRC3_2);
44491+			}
44492+		}
44493+	}
44494+
44495+	if (cmd) {
44496+		writel(offset, ld->gmac_iobase + PMT_OFFSET);
44497+		writel(cmd, ld->gmac_iobase + PMT_CMD);
44498+	}
44499+}
44500+
44501+int pmt_config_gmac(struct pm_config const *config, struct higmac_netdev_local *ld)
44502+{
44503+	unsigned int v;
44504+	unsigned long flags;
44505+
44506+	if (ld == NULL || config == NULL)
44507+		return -EINVAL;
44508+
44509+	spin_lock_irqsave(&ld->pmtlock, flags);
44510+	if (config->wakeup_pkts_enable) {
44511+		/* disable wakeup_pkts_enable before reconfig? */
44512+		v = readl(ld->gmac_iobase + PMT_CTRL);
44513+		v &= ~BIT(2); /* bit2 */
44514+		writel(v, ld->gmac_iobase + PMT_CTRL); /* any side effect? */
44515+	} else {
44516+		goto config_ctrl;
44517+	}
44518+
44519+	pmt_config_filter(config, ld);
44520+
44521+config_ctrl:
44522+	v = 0;
44523+	if (config->uc_pkts_enable)
44524+		v |= BIT(9); /* bit9 uc pkts wakeup */
44525+	if (config->wakeup_pkts_enable)
44526+		v |= BIT(2); /* bit2 use filter framework */
44527+	if (config->magic_pkts_enable)
44528+		v |= BIT(1); /* magic pkts wakeup */
44529+
44530+	v |= 0x3 << 5; /* set bit5 bit6, clear irq status */
44531+	writel(v, ld->gmac_iobase + PMT_CTRL);
44532+
44533+	_pmt_reg_backup(ld);
44534+
44535+	spin_unlock_irqrestore(&ld->pmtlock, flags);
44536+
44537+	return 0;
44538+}
44539+
44540+/* pmt_config will overwrite pre-config */
44541+int pmt_config(struct net_device const *ndev, struct pm_config const *config)
44542+{
44543+	static int init;
44544+	int ret;
44545+	struct higmac_netdev_local *priv = netdev_priv(ndev);
44546+
44547+	if (!init)
44548+		init_crc_table();
44549+
44550+	ret = pmt_config_gmac(config, priv);
44551+	if (ret)
44552+		return ret;
44553+
44554+	priv->pm_state = PM_SET;
44555+	priv->wol_enable = true;
44556+	device_set_wakeup_enable(priv->dev, 1);
44557+
44558+	return 0;
44559+}
44560+
44561+bool pmt_enter(struct higmac_netdev_local *ld)
44562+{
44563+	int pm = false;
44564+	unsigned long flags;
44565+	if (ld == NULL)
44566+		return -EINVAL;
44567+	spin_lock_irqsave(&ld->pmtlock, flags);
44568+	if (ld->pm_state == PM_SET) {
44569+		unsigned int v;
44570+
44571+		v = readl(ld->gmac_iobase + PMT_CTRL);
44572+		v |= BIT(0); /* enter power down */
44573+		v |= BIT(3); /* bit3, enable wakeup irq */
44574+		v |= 0x3 << 5; /* set bit5 bit6, clear irq status */
44575+		writel(v, ld->gmac_iobase + PMT_CTRL);
44576+
44577+		ld->pm_state = PM_CLEAR;
44578+		pm = true;
44579+	}
44580+	spin_unlock_irqrestore(&ld->pmtlock, flags);
44581+	return pm;
44582+}
44583+
44584+void pmt_exit(struct higmac_netdev_local *ld)
44585+{
44586+	unsigned int v;
44587+	unsigned long flags;
44588+	if (ld == NULL)
44589+		return;
44590+	/* logic auto exit power down mode */
44591+	spin_lock_irqsave(&ld->pmtlock, flags);
44592+
44593+	v = readl(ld->gmac_iobase + PMT_CTRL);
44594+	v &= ~BIT(0); /* enter power down */
44595+	v &= ~BIT(3); /* bit3, enable wakeup irq */
44596+
44597+	v |= 0x3 << 5; /* set bit5 bit6, clear irq status */
44598+	writel(v, ld->gmac_iobase + PMT_CTRL);
44599+
44600+	spin_unlock_irqrestore(&ld->pmtlock, flags);
44601+
44602+	ld->wol_enable = false;
44603+}
44604+
44605+void pmt_reg_restore(struct higmac_netdev_local *ld)
44606+{
44607+	unsigned int v;
44608+	unsigned long flags;
44609+	if (ld == NULL)
44610+		return;
44611+	spin_lock_irqsave(&ld->pmtlock, flags);
44612+	v = pm_reg_config_backup.pmt_mask0;
44613+	writel(v, ld->gmac_iobase + PMT_MASK0);
44614+
44615+	v = pm_reg_config_backup.pmt_mask1;
44616+	writel(v, ld->gmac_iobase + PMT_MASK1);
44617+
44618+	v = pm_reg_config_backup.pmt_mask2;
44619+	writel(v, ld->gmac_iobase + PMT_MASK2);
44620+
44621+	v = pm_reg_config_backup.pmt_mask3;
44622+	writel(v, ld->gmac_iobase + PMT_MASK3);
44623+
44624+	v = pm_reg_config_backup.pmt_cmd;
44625+	writel(v, ld->gmac_iobase + PMT_CMD);
44626+
44627+	v = pm_reg_config_backup.pmt_offset;
44628+	writel(v, ld->gmac_iobase + PMT_OFFSET);
44629+
44630+	v = pm_reg_config_backup.pmt_crc1_0;
44631+	writel(v, ld->gmac_iobase + PMT_CRC1_0);
44632+
44633+	v = pm_reg_config_backup.pmt_crc3_2;
44634+	writel(v, ld->gmac_iobase + PMT_CRC3_2);
44635+
44636+	v = pm_reg_config_backup.pmt_ctrl;
44637+	writel(v, ld->gmac_iobase + PMT_CTRL);
44638+	spin_unlock_irqrestore(&ld->pmtlock, flags);
44639+}
44640+
44641+/* ========the following code copy from Synopsys DWC_gmac_crc_example.c====== */
44642+#define CRC16 /* Change it to CRC16 for CRC16 Computation */
44643+
44644+#if defined(CRC16)
44645+#define CRC_NAME		"CRC-16"
44646+#define POLYNOMIAL		0x8005
44647+#define INITIAL_REMAINDER	0xFFFF
44648+#define FINAL_XOR_VALUE		0x0000
44649+#define REVERSE_DATA
44650+#undef REVERSE_REMAINDER
44651+#endif
44652+
44653+#define WIDTH    (8 * sizeof(unsigned short))
44654+#define TOPBIT   BIT(WIDTH - 1)
44655+
44656+#ifdef REVERSE_DATA
44657+#undef  REVERSE_DATA
44658+#define reverse_data(X)		((unsigned char)reverse((X), 8))
44659+#else
44660+#undef  REVERSE_DATA
44661+#define reverse_data(X)		(X)
44662+#endif
44663+
44664+#ifdef REVERSE_REMAINDER
44665+#undef  REVERSE_REMAINDER
44666+#define reverse_remainder(X)	((unsigned short)reverse((X), WIDTH))
44667+#else
44668+#undef  REVERSE_REMAINDER
44669+#define reverse_remainder(X)	(X)
44670+#endif
44671+
44672+#define CRC_TABLE_LEN	256
44673+static unsigned short crc_table[CRC_TABLE_LEN];
44674+
44675+static unsigned int reverse(unsigned int data, unsigned char nbits)
44676+{
44677+	unsigned int reversed = 0x00000000;
44678+	unsigned char bit;
44679+
44680+	/* Reverse the data about the center bit. */
44681+	for (bit = 0; bit < nbits; ++bit) {
44682+		/* If the LSB bit is set, set the reflection of it. */
44683+		if (data & 0x01)
44684+			reversed |= BIT((nbits - 1) - bit);
44685+
44686+		data = (data >> 1);
44687+	}
44688+	return reversed;
44689+}
44690+
44691+/* This Initializes the partial CRC look up table */
44692+static void init_crc_table(void)
44693+{
44694+	unsigned short remainder;
44695+	unsigned int dividend;
44696+	unsigned char bit;
44697+
44698+	/* Compute the remainder of each possible dividend. */
44699+	for (dividend = 0; dividend < CRC_TABLE_LEN; ++dividend) {
44700+		/* Start with the dividend followed by zeros, WIDTH - 8. */
44701+		remainder = (unsigned short)(dividend << (WIDTH - 8));
44702+
44703+		/* Perform modulo-2 division, a bit at a time for 8 times. */
44704+		for (bit = 8; bit > 0; --bit) {
44705+			/* Try to divide the current data bit. */
44706+			if (remainder & TOPBIT)
44707+				remainder = (remainder << 1) ^ POLYNOMIAL;
44708+			else
44709+				remainder = (remainder << 1);
44710+		}
44711+
44712+		/* Store the result into the table. */
44713+		crc_table[dividend] = remainder;
44714+	}
44715+}
44716+
44717+static unsigned short compute_crc(const char *message, int nbytes)
44718+{
44719+	unsigned short remainder = INITIAL_REMAINDER;
44720+	int byte;
44721+	unsigned char data;
44722+
44723+	/* Divide the message by the polynomial, a byte at a time. */
44724+	for (byte = 0; byte < nbytes; ++byte) {
44725+		/* high 8 bits */
44726+		data = reverse_data(message[byte]) ^ (remainder >> (WIDTH - 8));
44727+		remainder = crc_table[data] ^ (remainder << 8); /* shift left 8 bits */
44728+	}
44729+
44730+	/* The final remainder is the CRC. */
44731+	return (reverse_remainder(remainder) ^ FINAL_XOR_VALUE);
44732+}
44733diff --git a/drivers/net/ethernet/hisilicon/higmac/pm.h b/drivers/net/ethernet/hisilicon/higmac/pm.h
44734new file mode 100644
44735index 000000000..e54ced46c
44736--- /dev/null
44737+++ b/drivers/net/ethernet/hisilicon/higmac/pm.h
44738@@ -0,0 +1,59 @@
44739+/*
44740+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
44741+ * Description: Higmac driver pm head file
44742+ * Author: KTP_BSP
44743+ * Create: 2020-05-19
44744+ */
44745+
44746+#ifndef __HIGMAC_PM_H__
44747+#define __HIGMAC_PM_H__
44748+
44749+#include "higmac.h"
44750+
44751+#define N			31
44752+#define FILTERS			4
44753+#define PM_FILTER_OFFSET_MIN	12
44754+struct pm_config {
44755+	unsigned char index; /* bit0--eth0 bit1--eth1 */
44756+	unsigned char uc_pkts_enable;
44757+	unsigned char magic_pkts_enable;
44758+	unsigned char wakeup_pkts_enable;
44759+	struct {
44760+		unsigned int mask_bytes : N;
44761+		unsigned int reserved : 1; /* userspace ignore this bit */
44762+		unsigned char offset; /* >= 12 */
44763+		unsigned char value[N]; /* byte string */
44764+		unsigned char valid; /* valid filter */
44765+	} filter[FILTERS];
44766+};
44767+
44768+struct pm_reg_config {
44769+	unsigned int pmt_ctrl;
44770+	unsigned int pmt_mask0;
44771+	unsigned int pmt_mask1;
44772+	unsigned int pmt_mask2;
44773+	unsigned int pmt_mask3;
44774+	unsigned int pmt_cmd;
44775+	unsigned int pmt_offset;
44776+	unsigned int pmt_crc1_0;
44777+	unsigned int pmt_crc3_2;
44778+};
44779+
44780+#define PMT_CTRL		0xa00
44781+#define PMT_MASK0		0xa04
44782+#define PMT_MASK1		0xa08
44783+#define PMT_MASK2		0xa0c
44784+#define PMT_MASK3		0xa10
44785+#define PMT_CMD			0xa14
44786+#define PMT_OFFSET		0xa18
44787+#define PMT_CRC1_0		0xa1c
44788+#define PMT_CRC3_2		0xa20
44789+#define MASK_INVALID_BIT	BIT(31)
44790+
44791+
44792+int pmt_config(struct net_device const *ndev, struct pm_config const *config);
44793+bool pmt_enter(struct higmac_netdev_local *ld);
44794+void pmt_exit(struct higmac_netdev_local *ld);
44795+void pmt_reg_restore(struct higmac_netdev_local *ld);
44796+
44797+#endif
44798\ No newline at end of file
44799diff --git a/drivers/net/ethernet/hisilicon/higmac/proc_dev.c b/drivers/net/ethernet/hisilicon/higmac/proc_dev.c
44800new file mode 100644
44801index 000000000..efb654fb4
44802--- /dev/null
44803+++ b/drivers/net/ethernet/hisilicon/higmac/proc_dev.c
44804@@ -0,0 +1,119 @@
44805+/*
44806+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
44807+ * Description: Higmac driver proc dev process
44808+ * Author: KTP_BSP
44809+ * Create: 2018-10-08
44810+ */
44811+
44812+#include "sockioctl.h"
44813+#include "pm.h"
44814+
44815+/* debug code */
44816+static int set_suspend(int eth_n)
44817+{
44818+	return 0;
44819+}
44820+
44821+/* debug code */
44822+static int set_resume(int eth_n)
44823+{
44824+	return 0;
44825+}
44826+
44827+static int hw_states_read(struct seq_file *m, void *v)
44828+{
44829+	return 0;
44830+}
44831+
44832+static struct proc_dir_entry *higmac_proc_root;
44833+
44834+static int proc_open_hw_states_read(struct inode *inode, struct file *file)
44835+{
44836+	return single_open(file, hw_states_read, PDE_DATA(inode));
44837+}
44838+
44839+static struct proc_file {
44840+	char *name;
44841+	const struct file_operations ops;
44842+
44843+} proc_file[] = {
44844+	{
44845+		.name = "hw_stats",
44846+		.ops = {
44847+			.open           = proc_open_hw_states_read,
44848+			.read           = seq_read,
44849+			.llseek         = seq_lseek,
44850+			.release        = single_release,
44851+		},
44852+	}
44853+};
44854+
44855+/*
44856+ * /proc/higmac/
44857+ *	|---hw_stats
44858+ *	|---skb_pools
44859+ */
44860+void higmac_proc_create(void)
44861+{
44862+	int i;
44863+
44864+	higmac_proc_root = proc_mkdir("higmac", NULL);
44865+	if (higmac_proc_root == NULL)
44866+		return;
44867+
44868+	for (i = 0; i < ARRAY_SIZE(proc_file); i++) {
44869+		struct proc_dir_entry *entry;
44870+
44871+		entry = proc_create(proc_file[i].name, 0, higmac_proc_root,
44872+				    &proc_file[i].ops);
44873+		if (entry == NULL)
44874+			pr_err("failed to create %s\n", proc_file[i].name);
44875+	}
44876+}
44877+
44878+void higmac_proc_destroy(void)
44879+{
44880+	int i;
44881+
44882+	for (i = 0; i < ARRAY_SIZE(proc_file); i++)
44883+		remove_proc_entry(proc_file[i].name, higmac_proc_root);
44884+
44885+	remove_proc_entry("higmac", NULL);
44886+}
44887+
44888+int higmac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
44889+{
44890+	struct higmac_netdev_local *priv = NULL;
44891+	struct pm_config config;
44892+	int val = 0;
44893+	if (ndev == NULL || rq == NULL)
44894+		return -EINVAL;
44895+	priv = netdev_priv(ndev);
44896+	switch (cmd) {
44897+	case SIOCSETPM:
44898+		if (rq->ifr_data == NULL ||
44899+				copy_from_user(&config, rq->ifr_data, sizeof(config)))
44900+			return -EFAULT;
44901+		return pmt_config(ndev, &config);
44902+
44903+	case SIOCSETSUSPEND:
44904+		if (rq->ifr_data == NULL || copy_from_user(&val, rq->ifr_data, sizeof(val)))
44905+			return -EFAULT;
44906+		return set_suspend(val);
44907+
44908+	case SIOCSETRESUME:
44909+		if (rq->ifr_data == NULL || copy_from_user(&val, rq->ifr_data, sizeof(val)))
44910+			return -EFAULT;
44911+		return set_resume(val);
44912+
44913+	default:
44914+		if (!netif_running(ndev))
44915+			return -EINVAL;
44916+
44917+		if (priv->phy == NULL)
44918+			return -EINVAL;
44919+
44920+		return phy_mii_ioctl(priv->phy, rq, cmd);
44921+	}
44922+	return 0;
44923+}
44924diff --git a/drivers/net/ethernet/hisilicon/higmac/sockioctl.h b/drivers/net/ethernet/hisilicon/higmac/sockioctl.h
44925new file mode 100644
44926index 000000000..349f0f215
44927--- /dev/null
44928+++ b/drivers/net/ethernet/hisilicon/higmac/sockioctl.h
44929@@ -0,0 +1,19 @@
44930+/*
44931+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
44932+ * Description: Higmac driver sockioctl head file
44933+ * Author: KTP_BSP
44934+ * Create: 2018-10-08
44935+ */
44936+
44937+#ifndef __HIGMAC_SOCKIOCTL_H__
44938+#define __HIGMAC_SOCKIOCTL_H__
44939+
44940+#include <linux/sockios.h>
44941+
44942+#define SIOCSETPM	(SIOCDEVPRIVATE + 4) /* set pmt wake up config */
44943+#define SIOCSETSUSPEND	(SIOCDEVPRIVATE + 5) /* call dev->suspend, debug */
44944+#define SIOCSETRESUME	(SIOCDEVPRIVATE + 6) /* call dev->resume, debug */
44945+
44946+int higmac_ioctl(struct net_device *net_dev, struct ifreq *rq, int cmd);
44947+
44948+#endif
44949diff --git a/drivers/net/ethernet/hisilicon/higmac/tso.h b/drivers/net/ethernet/hisilicon/higmac/tso.h
44950new file mode 100644
44951index 000000000..6c78d1d45
44952--- /dev/null
44953+++ b/drivers/net/ethernet/hisilicon/higmac/tso.h
44954@@ -0,0 +1,59 @@
44955+/*
44956+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
44957+ * Description: Higmac driver tso head file
44958+ * Author: KTP_BSP
44959+ * Create: 2018-10-08
44960+ */
44961+
44962+#ifndef __HIGMAC_TSO_H__
44963+#define __HIGMAC_TSO_H__
44964+
44965+#define SG_FLAG		BIT(30)
44966+#define COE_FLAG	BIT(29)
44967+#define TSO_FLAG	BIT(28)
44968+#define VLAN_FLAG	BIT(10)
44969+#define IPV6_FLAG	BIT(9)
44970+#define UDP_FLAG	BIT(8)
44971+
44972+#define PKT_IPV6_HDR_LEN	10
44973+#define PKT_UDP_HDR_LEN		2
44974+#define WORD_TO_BYTE		4
44975+enum {
44976+	PKT_NORMAL,
44977+	PKT_SG
44978+};
44979+
44980+enum {
44981+	PKT_IPV4,
44982+	PKT_IPV6
44983+};
44984+
44985+enum {
44986+	PKT_TCP,
44987+	PKT_UDP
44988+};
44989+
44990+struct frags_info {
44991+	/* Word(2*i+2) */
44992+	u32 addr;
44993+	/* Word(2*i+3) */
44994+	u32 size : 16;
44995+	u32 reserved : 16;
44996+};
44997+
44998+struct sg_desc {
44999+	/* Word0 */
45000+	u32 total_len : 17;
45001+	u32 reserv : 15;
45002+	/* Word1 */
45003+	u32 ipv6_id;
45004+	/* Word2 */
45005+	u32 linear_addr;
45006+	/* Word3 */
45007+	u32 linear_len : 16;
45008+	u32 reserv3 : 16;
45009+	/* MAX_SKB_FRAGS is 18 */
45010+	struct frags_info frags[18];
45011+};
45012+
45013+#endif
45014diff --git a/drivers/net/ethernet/hisilicon/higmac/util.c b/drivers/net/ethernet/hisilicon/higmac/util.c
45015new file mode 100644
45016index 000000000..eae79af52
45017--- /dev/null
45018+++ b/drivers/net/ethernet/hisilicon/higmac/util.c
45019@@ -0,0 +1,975 @@
45020+/*
45021+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
45022+ * Description: Higmac driver util file
45023+ * Author: KTP_BSP
45024+ * Create: 2020-05-19
45025+ */
45026+
45027+#include <linux/kernel.h>
45028+#include <linux/if_vlan.h>
45029+#include <linux/ip.h>
45030+#include <net/ipv6.h>
45031+#include <linux/reset.h>
45032+#include "util.h"
45033+
45034+static unsigned int flow_ctrl_en = FLOW_OFF;
45035+static int tx_flow_ctrl_pause_time = CONFIG_TX_FLOW_CTRL_PAUSE_TIME;
45036+static int tx_flow_ctrl_pause_interval = CONFIG_TX_FLOW_CTRL_PAUSE_INTERVAL;
45037+static int tx_flow_ctrl_active_threshold = CONFIG_TX_FLOW_CTRL_ACTIVE_THRESHOLD;
45038+static int tx_flow_ctrl_deactive_threshold =
45039+				CONFIG_TX_FLOW_CTRL_DEACTIVE_THRESHOLD;
45040+
45041+void higmac_trace(int level, const char *fmt, ...)
45042+{
45043+	if (level >= HIGMAC_TRACE_LEVEL) {
45044+		va_list args;
45045+		va_start(args, fmt);
45046+		printk("higmac_trace:");
45047+		printk(fmt, args);
45048+		printk("\n");
45049+		va_end(args);
45050+	}
45051+}
45052+
45053+void higmac_config_port(struct net_device const *dev, u32 speed, u32 duplex)
45054+{
45055+	struct higmac_netdev_local *priv = netdev_priv(dev);
45056+	u32 val;
45057+
45058+	switch (priv->phy_mode) {
45059+	case PHY_INTERFACE_MODE_RGMII:
45060+		if (speed == SPEED_1000)
45061+			val = RGMII_SPEED_1000;
45062+		else if (speed == SPEED_100)
45063+			val = RGMII_SPEED_100;
45064+		else
45065+			val = RGMII_SPEED_10;
45066+		break;
45067+	case PHY_INTERFACE_MODE_MII:
45068+		if (speed == SPEED_100)
45069+			val = MII_SPEED_100;
45070+		else
45071+			val = MII_SPEED_10;
45072+		break;
45073+	case PHY_INTERFACE_MODE_RMII:
45074+		if (speed == SPEED_100)
45075+			val = RMII_SPEED_100;
45076+		else
45077+			val = RMII_SPEED_10;
45078+		break;
45079+	default:
45080+		netdev_warn(dev, "not supported mode\n");
45081+		val = MII_SPEED_10;
45082+		break;
45083+	}
45084+
45085+	if (duplex)
45086+		val |= GMAC_FULL_DUPLEX;
45087+
45088+	reset_control_assert(priv->macif_rst);
45089+	writel_relaxed(val, priv->macif_base);
45090+	reset_control_deassert(priv->macif_rst);
45091+
45092+	writel_relaxed(BIT_MODE_CHANGE_EN, priv->gmac_iobase + MODE_CHANGE_EN);
45093+	if (speed == SPEED_1000)
45094+		val = GMAC_SPEED_1000;
45095+	else if (speed == SPEED_100)
45096+		val = GMAC_SPEED_100;
45097+	else
45098+		val = GMAC_SPEED_10;
45099+	writel_relaxed(val, priv->gmac_iobase + PORT_MODE);
45100+	writel_relaxed(0, priv->gmac_iobase + MODE_CHANGE_EN);
45101+	writel_relaxed(duplex, priv->gmac_iobase + MAC_DUPLEX_HALF_CTRL);
45102+}
45103+
45104+int higmac_rx_checksum(struct net_device *dev, struct sk_buff *skb,
45105+		  struct higmac_desc const *desc)
45106+{
45107+	int hdr_csum_done, payload_csum_done;
45108+	int hdr_csum_err, payload_csum_err;
45109+	if (skb == NULL || desc == NULL || dev == NULL)
45110+		return -EINVAL;
45111+	if (dev->features & NETIF_F_RXCSUM) {
45112+		hdr_csum_done =	desc->header_csum_done;
45113+		payload_csum_done =	desc->payload_csum_done;
45114+		hdr_csum_err = desc->header_csum_err;
45115+		payload_csum_err = desc->payload_csum_err;
45116+
45117+		if (hdr_csum_done && payload_csum_done) {
45118+			if (unlikely(hdr_csum_err || payload_csum_err)) {
45119+				dev->stats.rx_errors++;
45120+				dev->stats.rx_crc_errors++;
45121+				dev_kfree_skb_any(skb);
45122+				return -1;
45123+			} else {
45124+				skb->ip_summed = CHECKSUM_UNNECESSARY;
45125+			}
45126+		}
45127+	}
45128+	return 0;
45129+}
45130+
45131+void higmac_verify_flow_ctrl_args(void)
45132+{
45133+#if defined(CONFIG_TX_FLOW_CTRL_SUPPORT)
45134+	flow_ctrl_en |= FLOW_TX;
45135+#endif
45136+#if defined(CONFIG_RX_FLOW_CTRL_SUPPORT)
45137+	flow_ctrl_en |= FLOW_RX;
45138+#endif
45139+	if (tx_flow_ctrl_active_threshold < FC_ACTIVE_MIN ||
45140+		tx_flow_ctrl_active_threshold > FC_ACTIVE_MAX)
45141+		tx_flow_ctrl_active_threshold = FC_ACTIVE_DEFAULT;
45142+
45143+	if (tx_flow_ctrl_deactive_threshold < FC_DEACTIVE_MIN ||
45144+		tx_flow_ctrl_deactive_threshold > FC_DEACTIVE_MAX)
45145+		tx_flow_ctrl_deactive_threshold = FC_DEACTIVE_DEFAULT;
45146+
45147+	if (tx_flow_ctrl_active_threshold >= tx_flow_ctrl_deactive_threshold) {
45148+		tx_flow_ctrl_active_threshold = FC_ACTIVE_DEFAULT;
45149+		tx_flow_ctrl_deactive_threshold = FC_DEACTIVE_DEFAULT;
45150+	}
45151+
45152+	if (tx_flow_ctrl_pause_time < 0 ||
45153+		tx_flow_ctrl_pause_time > FC_PAUSE_TIME_MAX)
45154+		tx_flow_ctrl_pause_time = FC_PAUSE_TIME_DEFAULT;
45155+
45156+	if (tx_flow_ctrl_pause_interval < 0 ||
45157+		tx_flow_ctrl_pause_interval > FC_PAUSE_TIME_MAX)
45158+		tx_flow_ctrl_pause_interval = FC_PAUSE_INTERVAL_DEFAULT;
45159+
45160+	/*
45161+	 * pause interval should not bigger than pause time,
45162+	 * but should not too smaller to avoid sending too many pause frame.
45163+	 */
45164+	if ((tx_flow_ctrl_pause_interval > tx_flow_ctrl_pause_time) ||
45165+		(tx_flow_ctrl_pause_interval < ((unsigned int)tx_flow_ctrl_pause_time >> 1)))
45166+		tx_flow_ctrl_pause_interval = tx_flow_ctrl_pause_time;
45167+}
45168+
45169+void higmac_set_flow_ctrl_args(struct higmac_netdev_local *ld)
45170+{
45171+	if (ld == NULL)
45172+		return;
45173+	ld->flow_ctrl = flow_ctrl_en;
45174+	ld->pause = tx_flow_ctrl_pause_time;
45175+	ld->pause_interval = tx_flow_ctrl_pause_interval;
45176+	ld->flow_ctrl_active_threshold = tx_flow_ctrl_active_threshold;
45177+	ld->flow_ctrl_deactive_threshold = tx_flow_ctrl_deactive_threshold;
45178+}
45179+
45180+void higmac_set_flow_ctrl_params(struct higmac_netdev_local const *ld)
45181+{
45182+	unsigned int rx_fq_empty_th;
45183+	unsigned int rx_fq_full_th;
45184+	unsigned int rx_bq_empty_th;
45185+	unsigned int rx_bq_full_th;
45186+	unsigned int rec_filter;
45187+	if (ld == NULL)
45188+		return;
45189+	writel(ld->pause, ld->gmac_iobase + FC_TX_TIMER);
45190+	writel(ld->pause_interval, ld->gmac_iobase + PAUSE_THR);
45191+
45192+	rx_fq_empty_th = readl(ld->gmac_iobase + RX_FQ_ALEMPTY_TH);
45193+	rx_fq_empty_th &= ~(BITS_Q_PAUSE_TH_MASK << BITS_Q_PAUSE_TH_OFFSET);
45194+	rx_fq_empty_th |= (ld->flow_ctrl_active_threshold <<
45195+			BITS_Q_PAUSE_TH_OFFSET);
45196+	writel(rx_fq_empty_th, ld->gmac_iobase + RX_FQ_ALEMPTY_TH);
45197+
45198+	rx_fq_full_th = readl(ld->gmac_iobase + RX_FQ_ALFULL_TH);
45199+	rx_fq_full_th &= ~(BITS_Q_PAUSE_TH_MASK << BITS_Q_PAUSE_TH_OFFSET);
45200+	rx_fq_full_th |= (ld->flow_ctrl_deactive_threshold <<
45201+			BITS_Q_PAUSE_TH_OFFSET);
45202+	writel(rx_fq_full_th, ld->gmac_iobase + RX_FQ_ALFULL_TH);
45203+
45204+	rx_bq_empty_th = readl(ld->gmac_iobase + RX_BQ_ALEMPTY_TH);
45205+	rx_bq_empty_th &= ~(BITS_Q_PAUSE_TH_MASK << BITS_Q_PAUSE_TH_OFFSET);
45206+	rx_bq_empty_th |= (ld->flow_ctrl_active_threshold <<
45207+			BITS_Q_PAUSE_TH_OFFSET);
45208+	writel(rx_bq_empty_th, ld->gmac_iobase + RX_BQ_ALEMPTY_TH);
45209+
45210+	rx_bq_full_th = readl(ld->gmac_iobase + RX_BQ_ALFULL_TH);
45211+	rx_bq_full_th &= ~(BITS_Q_PAUSE_TH_MASK << BITS_Q_PAUSE_TH_OFFSET);
45212+	rx_bq_full_th |= (ld->flow_ctrl_deactive_threshold <<
45213+			BITS_Q_PAUSE_TH_OFFSET);
45214+	writel(rx_bq_full_th, ld->gmac_iobase + RX_BQ_ALFULL_TH);
45215+
45216+	writel(0, ld->gmac_iobase + CRF_TX_PAUSE);
45217+
45218+	rec_filter = readl(ld->gmac_iobase + REC_FILT_CONTROL);
45219+	rec_filter |= BIT_PAUSE_FRM_PASS;
45220+	writel(rec_filter, ld->gmac_iobase + REC_FILT_CONTROL);
45221+}
45222+
45223+void higmac_set_flow_ctrl_state(struct higmac_netdev_local const *ld, int pause)
45224+{
45225+	unsigned int flow_rx_q_en;
45226+	unsigned int flow;
45227+	if (ld == NULL)
45228+		return;
45229+	flow_rx_q_en = readl(ld->gmac_iobase + RX_PAUSE_EN);
45230+	flow_rx_q_en &= ~(BIT_RX_FQ_PAUSE_EN | BIT_RX_BQ_PAUSE_EN);
45231+	if (pause && (ld->flow_ctrl & FLOW_TX))
45232+		flow_rx_q_en |= (BIT_RX_FQ_PAUSE_EN | BIT_RX_BQ_PAUSE_EN);
45233+	writel(flow_rx_q_en, ld->gmac_iobase + RX_PAUSE_EN);
45234+
45235+	flow = readl(ld->gmac_iobase + PAUSE_EN);
45236+	flow &= ~(BIT_RX_FDFC | BIT_TX_FDFC);
45237+	if (pause) {
45238+		if (ld->flow_ctrl & FLOW_RX)
45239+			flow |= BIT_RX_FDFC;
45240+		if (ld->flow_ctrl & FLOW_TX)
45241+			flow |= BIT_TX_FDFC;
45242+	}
45243+	writel(flow, ld->gmac_iobase + PAUSE_EN);
45244+}
45245+
45246+static __be16 higmac_get_l3_proto(struct sk_buff *skb)
45247+{
45248+	__be16 l3_proto;
45249+
45250+	l3_proto = skb->protocol;
45251+	if (skb->protocol == htons(ETH_P_8021Q))
45252+		l3_proto = vlan_get_protocol(skb);
45253+
45254+	return l3_proto;
45255+}
45256+
45257+static unsigned int higmac_get_l4_proto(struct sk_buff *skb)
45258+{
45259+	__be16 l3_proto;
45260+	unsigned int l4_proto = IPPROTO_MAX;
45261+
45262+	l3_proto = higmac_get_l3_proto(skb);
45263+	if (l3_proto == htons(ETH_P_IP))
45264+		l4_proto = ip_hdr(skb)->protocol;
45265+	else if (l3_proto == htons(ETH_P_IPV6))
45266+		l4_proto = ipv6_hdr(skb)->nexthdr;
45267+
45268+	return l4_proto;
45269+}
45270+
45271+static inline bool higmac_skb_is_ipv6(struct sk_buff *skb)
45272+{
45273+	return (higmac_get_l3_proto(skb) == htons(ETH_P_IPV6));
45274+}
45275+
45276+static inline bool higmac_skb_is_udp(struct sk_buff *skb)
45277+{
45278+	return (higmac_get_l4_proto(skb) == IPPROTO_UDP);
45279+}
45280+
45281+static int higmac_check_hw_capability_for_udp(struct sk_buff const *skb)
45282+{
45283+	struct ethhdr *eth;
45284+
45285+	/* hardware can't dea with UFO broadcast packet */
45286+	eth = (struct ethhdr *)(skb->data);
45287+	if (skb_is_gso(skb) && is_broadcast_ether_addr(eth->h_dest))
45288+		return -ENOTSUPP;
45289+
45290+	return 0;
45291+}
45292+
45293+static int higmac_check_hw_capability_for_ipv6(struct sk_buff *skb)
45294+{
45295+	unsigned int l4_proto;
45296+
45297+	l4_proto = ipv6_hdr(skb)->nexthdr;
45298+	if ((l4_proto != IPPROTO_TCP) && (l4_proto != IPPROTO_UDP)) {
45299+		/*
45300+		 * when IPv6 next header is not tcp or udp,
45301+		 * it means that IPv6 next header is extension header.
45302+		 * Hardware can't deal with this case,
45303+		 * so do checksumming by software or do GSO by software.
45304+		 */
45305+		if (skb_is_gso(skb))
45306+			return -ENOTSUPP;
45307+
45308+		if (skb->ip_summed == CHECKSUM_PARTIAL &&
45309+		    skb_checksum_help(skb))
45310+			return -EFAULT;
45311+	}
45312+
45313+	return 0;
45314+}
45315+
45316+static inline bool higmac_skb_is_ipv4_with_options(struct sk_buff *skb)
45317+{
45318+	return ((higmac_get_l3_proto(skb) == htons(ETH_P_IP)) &&
45319+		(ip_hdr(skb)->ihl > IPV4_HEAD_LENGTH));
45320+}
45321+
45322+int higmac_check_hw_capability(struct sk_buff *skb)
45323+{
45324+	int ret;
45325+
45326+	/*
45327+	 * if tcp_mtu_probe() use (2 * tp->mss_cache) as probe_size,
45328+	 * the linear data length will be larger than 2048,
45329+	 * the MAC can't handle it, so let the software do it.
45330+	 */
45331+	 if (skb == NULL)
45332+		return -EINVAL;
45333+	if (skb_is_gso(skb) && (skb_headlen(skb) > 2048)) /* 2048(2k) */
45334+		return -ENOTSUPP;
45335+
45336+	if (higmac_skb_is_ipv6(skb)) {
45337+		ret = higmac_check_hw_capability_for_ipv6(skb);
45338+		if (ret)
45339+			return ret;
45340+	}
45341+
45342+	if (higmac_skb_is_udp(skb)) {
45343+		ret = higmac_check_hw_capability_for_udp(skb);
45344+		if (ret)
45345+			return ret;
45346+	}
45347+
45348+	if (((skb->ip_summed == CHECKSUM_PARTIAL) || skb_is_gso(skb)) &&
45349+	    higmac_skb_is_ipv4_with_options(skb))
45350+		return -ENOTSUPP;
45351+
45352+	return 0;
45353+}
45354+
45355+static void higmac_do_udp_checksum(struct sk_buff *skb)
45356+{
45357+	int offset;
45358+	__wsum csum;
45359+	__sum16 udp_csum;
45360+
45361+	offset = skb_checksum_start_offset(skb);
45362+	WARN_ON(offset >= skb_headlen(skb));
45363+	csum = skb_checksum(skb, offset, skb->len - offset, 0);
45364+
45365+	offset += skb->csum_offset;
45366+	WARN_ON(offset + sizeof(__sum16) > skb_headlen(skb));
45367+	udp_csum = csum_fold(csum);
45368+	if (udp_csum == 0)
45369+		udp_csum = CSUM_MANGLED_0;
45370+
45371+	*(__sum16 *)(skb->data + offset) = udp_csum;
45372+
45373+	skb->ip_summed = CHECKSUM_NONE;
45374+}
45375+
45376+static int higmac_get_pkt_info_l3l4(struct higmac_tso_desc *tx_bq_desc,
45377+		  struct sk_buff *skb, unsigned int *l4_proto, unsigned int *max_mss,
45378+		  unsigned char *coe_enable)
45379+{
45380+	__be16 l3_proto; /* level 3 protocol */
45381+	int max_data_len = skb->len - ETH_HLEN;
45382+
45383+	l3_proto = skb->protocol;
45384+	if (skb->protocol == htons(ETH_P_8021Q)) {
45385+		l3_proto = vlan_get_protocol(skb);
45386+		tx_bq_desc->desc1.tx.vlan_flag = 1;
45387+		max_data_len -= VLAN_HLEN;
45388+	}
45389+
45390+	if (l3_proto == htons(ETH_P_IP)) {
45391+		struct iphdr *iph;
45392+
45393+		iph = ip_hdr(skb);
45394+		tx_bq_desc->desc1.tx.ip_ver = PKT_IPV4;
45395+		tx_bq_desc->desc1.tx.ip_hdr_len = iph->ihl;
45396+
45397+		if ((max_data_len >= GSO_MAX_SIZE) &&
45398+			(ntohs(iph->tot_len) <= (iph->ihl << 2))) /* shift left 2 */
45399+			iph->tot_len = htons(GSO_MAX_SIZE - 1);
45400+
45401+		*max_mss -= iph->ihl * WORD_TO_BYTE;
45402+		*l4_proto = iph->protocol;
45403+	} else if (l3_proto == htons(ETH_P_IPV6)) {
45404+		tx_bq_desc->desc1.tx.ip_ver = PKT_IPV6;
45405+		tx_bq_desc->desc1.tx.ip_hdr_len = PKT_IPV6_HDR_LEN;
45406+		*max_mss -= PKT_IPV6_HDR_LEN * WORD_TO_BYTE;
45407+		*l4_proto = ipv6_hdr(skb)->nexthdr;
45408+	} else {
45409+		*coe_enable = 0;
45410+	}
45411+
45412+	if (*l4_proto == IPPROTO_TCP) {
45413+		tx_bq_desc->desc1.tx.prot_type = PKT_TCP;
45414+		if (tcp_hdr(skb)->doff < sizeof(struct tcphdr) / WORD_TO_BYTE)
45415+			return -EFAULT;
45416+		tx_bq_desc->desc1.tx.prot_hdr_len = tcp_hdr(skb)->doff;
45417+		*max_mss -= tcp_hdr(skb)->doff * WORD_TO_BYTE;
45418+	} else if (*l4_proto == IPPROTO_UDP) {
45419+		tx_bq_desc->desc1.tx.prot_type = PKT_UDP;
45420+		tx_bq_desc->desc1.tx.prot_hdr_len = PKT_UDP_HDR_LEN;
45421+		if (l3_proto == htons(ETH_P_IPV6))
45422+			*max_mss -= sizeof(struct frag_hdr);
45423+	} else {
45424+		*coe_enable = 0;
45425+	}
45426+
45427+	return 0;
45428+}
45429+
45430+int higmac_get_pkt_info(struct higmac_netdev_local *ld,
45431+		  struct sk_buff *skb, struct higmac_tso_desc *tx_bq_desc)
45432+{
45433+	int nfrags;
45434+	unsigned int l4_proto = IPPROTO_MAX;
45435+	unsigned int max_mss = ETH_DATA_LEN;
45436+	unsigned char coe_enable = 0;
45437+	int ret;
45438+	if (skb == NULL || tx_bq_desc == NULL)
45439+		return -EINVAL;
45440+
45441+	nfrags = skb_shinfo(skb)->nr_frags;
45442+	if (likely(skb->ip_summed == CHECKSUM_PARTIAL))
45443+		coe_enable = 1;
45444+
45445+	tx_bq_desc->desc1.val = 0;
45446+
45447+	if (skb_is_gso(skb)) {
45448+		tx_bq_desc->desc1.tx.tso_flag = 1;
45449+		tx_bq_desc->desc1.tx.sg_flag = 1;
45450+	} else if (nfrags) {
45451+		tx_bq_desc->desc1.tx.sg_flag = 1;
45452+	}
45453+
45454+	ret = higmac_get_pkt_info_l3l4(tx_bq_desc, skb, &l4_proto, &max_mss,
45455+	    &coe_enable);
45456+	if (ret < 0)
45457+		return ret;
45458+
45459+	if (skb_is_gso(skb))
45460+		tx_bq_desc->desc1.tx.data_len =
45461+			(skb_shinfo(skb)->gso_size > max_mss) ? max_mss :
45462+					skb_shinfo(skb)->gso_size;
45463+	else
45464+		tx_bq_desc->desc1.tx.data_len = skb->len;
45465+
45466+	if (coe_enable && skb_is_gso(skb) && (l4_proto == IPPROTO_UDP))
45467+		higmac_do_udp_checksum(skb);
45468+
45469+	if (coe_enable)
45470+		tx_bq_desc->desc1.tx.coe_flag = 1;
45471+
45472+	tx_bq_desc->desc1.tx.nfrags_num = nfrags;
45473+
45474+	tx_bq_desc->desc1.tx.hw_own = DESC_VLD_BUSY;
45475+	return 0;
45476+}
45477+
45478+void higmac_get_drvinfo(struct net_device *net_dev,
45479+		  struct ethtool_drvinfo *info)
45480+{
45481+	if (info == NULL)
45482+		return;
45483+	strncpy(info->driver, "higmac driver", sizeof(info->driver));
45484+	strncpy(info->version, "higmac v200", sizeof(info->version));
45485+	strncpy(info->bus_info, "platform", sizeof(info->bus_info));
45486+}
45487+
45488+unsigned int higmac_get_link(struct net_device *net_dev)
45489+{
45490+	struct higmac_netdev_local *ld = netdev_priv(net_dev);
45491+
45492+	return ld->phy->link ? HIGMAC_LINKED : 0;
45493+}
45494+
45495+int higmac_get_settings(struct net_device *net_dev,
45496+		  struct ethtool_cmd *cmd)
45497+{
45498+	struct higmac_netdev_local *ld = netdev_priv(net_dev);
45499+
45500+	if (ld->phy != NULL)
45501+		return phy_ethtool_gset(ld->phy, cmd);
45502+
45503+	return -EINVAL;
45504+}
45505+
45506+int higmac_set_settings(struct net_device *net_dev,
45507+		  struct ethtool_cmd *cmd)
45508+{
45509+	struct higmac_netdev_local *ld = netdev_priv(net_dev);
45510+
45511+	if (!capable(CAP_NET_ADMIN))
45512+		return -EPERM;
45513+
45514+	if (ld->phy != NULL)
45515+		return phy_ethtool_sset(ld->phy, cmd);
45516+
45517+	return -EINVAL;
45518+}
45519+
45520+void higmac_get_pauseparam(struct net_device *net_dev,
45521+		  struct ethtool_pauseparam *pause)
45522+{
45523+	struct higmac_netdev_local *ld = NULL;
45524+	if (net_dev == NULL || pause == NULL)
45525+		return;
45526+	ld = netdev_priv(net_dev);
45527+
45528+	pause->rx_pause = 0;
45529+	pause->tx_pause = 0;
45530+	pause->autoneg = ld->phy->autoneg;
45531+
45532+	if (ld->flow_ctrl & FLOW_RX)
45533+		pause->rx_pause = 1;
45534+	if (ld->flow_ctrl & FLOW_TX)
45535+		pause->tx_pause = 1;
45536+}
45537+
45538+int higmac_set_pauseparam(struct net_device *net_dev,
45539+		  struct ethtool_pauseparam *pause)
45540+{
45541+	struct higmac_netdev_local *ld = netdev_priv(net_dev);
45542+	struct phy_device *phy = ld->phy;
45543+	unsigned int new_pause = FLOW_OFF;
45544+
45545+	if (pause == NULL)
45546+		return -ENOMEM;
45547+
45548+	if (pause->rx_pause)
45549+		new_pause |= FLOW_RX;
45550+	if (pause->tx_pause)
45551+		new_pause |= FLOW_TX;
45552+
45553+	if (new_pause != ld->flow_ctrl)
45554+		ld->flow_ctrl = new_pause;
45555+
45556+	higmac_set_flow_ctrl_state(ld, phy->pause);
45557+	phy->advertising &= ~SUPPORTED_Pause;
45558+	if (ld->flow_ctrl)
45559+		phy->advertising |= SUPPORTED_Pause;
45560+
45561+	if (phy->autoneg) {
45562+		if (netif_running(net_dev))
45563+			return phy_start_aneg(phy);
45564+	}
45565+
45566+	return 0;
45567+}
45568+
45569+u32 higmac_ethtool_getmsglevel(struct net_device *ndev)
45570+{
45571+	struct higmac_netdev_local *priv = netdev_priv(ndev);
45572+
45573+	return priv->msg_enable;
45574+}
45575+
45576+void higmac_ethtool_setmsglevel(struct net_device *ndev, u32 level)
45577+{
45578+	struct higmac_netdev_local *priv = netdev_priv(ndev);
45579+
45580+	priv->msg_enable = level;
45581+}
45582+
45583+u32 higmac_get_rxfh_key_size(struct net_device *ndev)
45584+{
45585+	return RSS_HASH_KEY_SIZE;
45586+}
45587+
45588+u32 higmac_get_rxfh_indir_size(struct net_device *ndev)
45589+{
45590+	struct higmac_netdev_local *priv = netdev_priv(ndev);
45591+
45592+	return priv->rss_info.ind_tbl_size;
45593+}
45594+
45595+int higmac_get_rxfh(struct net_device *ndev, u32 *indir, u8 *hkey,
45596+		  u8 *hfunc)
45597+{
45598+	struct higmac_netdev_local *priv = netdev_priv(ndev);
45599+	struct higmac_rss_info *rss = &priv->rss_info;
45600+
45601+	if (hfunc != NULL)
45602+		*hfunc = ETH_RSS_HASH_TOP;
45603+
45604+	if (hkey != NULL)
45605+		memcpy(hkey, rss->key, RSS_HASH_KEY_SIZE);
45606+
45607+	if (indir != NULL) {
45608+		int i;
45609+
45610+		for (i = 0; i < rss->ind_tbl_size; i++)
45611+			indir[i] = rss->ind_tbl[i];
45612+	}
45613+
45614+	return 0;
45615+}
45616+
45617+void higmac_get_rss_key(struct higmac_netdev_local *priv)
45618+{
45619+	struct higmac_rss_info *rss = NULL;
45620+	u32 hkey;
45621+	if (priv == NULL)
45622+		return;
45623+	rss = &priv->rss_info;
45624+	hkey = readl(priv->gmac_iobase + RSS_HASH_KEY);
45625+	*((u32 *)rss->key) = hkey;
45626+}
45627+
45628+static void higmac_set_rss_key(struct higmac_netdev_local *priv)
45629+{
45630+	struct higmac_rss_info *rss = &priv->rss_info;
45631+
45632+	writel(*((u32 *)rss->key), priv->gmac_iobase + RSS_HASH_KEY);
45633+}
45634+
45635+static int higmac_wait_rss_ready(struct higmac_netdev_local const *priv)
45636+{
45637+	void __iomem *base = priv->gmac_iobase;
45638+	int i;
45639+	const int timeout = 10000;
45640+
45641+	for (i = 0; !(readl(base + RSS_IND_TBL) & BIT_IND_TBL_READY); i++) {
45642+		if (i == timeout) {
45643+			netdev_err(priv->netdev, "wait rss ready timeout!\n");
45644+			return -ETIMEDOUT;
45645+		}
45646+		usleep_range(10, 20); /* wait 10~20us */
45647+	}
45648+
45649+	return 0;
45650+}
45651+
45652+static void higmac_config_rss(struct higmac_netdev_local *priv)
45653+{
45654+	struct higmac_rss_info *rss = NULL;
45655+	u32 rss_val;
45656+	unsigned int i;
45657+	if (priv == NULL)
45658+		return;
45659+	rss = &priv->rss_info;
45660+	for (i = 0; i < rss->ind_tbl_size; i++) {
45661+		if (higmac_wait_rss_ready(priv) != 0)
45662+			break;
45663+		rss_val = BIT_IND_TLB_WR | (rss->ind_tbl[i] << 8) | i; /* shift 8 */
45664+		writel(rss_val, priv->gmac_iobase + RSS_IND_TBL);
45665+	}
45666+}
45667+
45668+void higmac_get_rss(struct higmac_netdev_local *priv)
45669+{
45670+	struct higmac_rss_info *rss = NULL;
45671+	u32 rss_val;
45672+	int i;
45673+	if (priv == NULL)
45674+		return;
45675+	rss = &priv->rss_info;
45676+	for (i = 0; i < rss->ind_tbl_size; i++) {
45677+		if (higmac_wait_rss_ready(priv) != 0)
45678+			break;
45679+		writel(i, priv->gmac_iobase + RSS_IND_TBL);
45680+		if (higmac_wait_rss_ready(priv) != 0)
45681+			break;
45682+		rss_val = readl(priv->gmac_iobase + RSS_IND_TBL);
45683+		rss->ind_tbl[i] = (rss_val >> 10) & 0x3; /* right shift 10 */
45684+	}
45685+}
45686+
45687+int higmac_set_rxfh(struct net_device *ndev, const u32 *indir,
45688+		  const u8 *hkey, const u8 hfunc)
45689+{
45690+	struct higmac_netdev_local *priv = netdev_priv(ndev);
45691+	struct higmac_rss_info *rss = &priv->rss_info;
45692+
45693+	if (hfunc != ETH_RSS_HASH_NO_CHANGE && hfunc != ETH_RSS_HASH_TOP)
45694+		return -EOPNOTSUPP;
45695+
45696+	if (indir != NULL) {
45697+		int i;
45698+
45699+		for (i = 0; i < rss->ind_tbl_size; i++)
45700+			rss->ind_tbl[i] = indir[i];
45701+	}
45702+
45703+	if (hkey != NULL) {
45704+		memcpy(rss->key, hkey, RSS_HASH_KEY_SIZE);
45705+		higmac_set_rss_key(priv);
45706+	}
45707+
45708+	higmac_config_rss(priv);
45709+
45710+	return 0;
45711+}
45712+
45713+static void higmac_get_rss_hash(struct ethtool_rxnfc *info, u32 hash_cfg,
45714+		  u32 l3_hash_en, u32 l4_hash_en, u32 vlan_hash_en)
45715+{
45716+	if (hash_cfg & l3_hash_en)
45717+		info->data |= RXH_IP_SRC | RXH_IP_DST;
45718+	if (hash_cfg & l4_hash_en)
45719+		info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
45720+	if (hash_cfg & vlan_hash_en)
45721+		info->data |= RXH_VLAN;
45722+}
45723+
45724+static int higmac_get_rss_hash_opts(struct higmac_netdev_local const *priv,
45725+		  struct ethtool_rxnfc *info)
45726+{
45727+	u32 hash_cfg = priv->rss_info.hash_cfg;
45728+
45729+	info->data = 0;
45730+
45731+	switch (info->flow_type) {
45732+	case TCP_V4_FLOW:
45733+		higmac_get_rss_hash(info, hash_cfg, TCPV4_L3_HASH_EN, TCPV4_L4_HASH_EN,
45734+			TCPV4_VLAN_HASH_EN);
45735+		break;
45736+	case TCP_V6_FLOW:
45737+		higmac_get_rss_hash(info, hash_cfg, TCPV6_L3_HASH_EN, TCPV6_L4_HASH_EN,
45738+			TCPV6_VLAN_HASH_EN);
45739+		break;
45740+	case UDP_V4_FLOW:
45741+		higmac_get_rss_hash(info, hash_cfg, UDPV4_L3_HASH_EN, UDPV4_L4_HASH_EN,
45742+			UDPV4_VLAN_HASH_EN);
45743+		break;
45744+	case UDP_V6_FLOW:
45745+		higmac_get_rss_hash(info, hash_cfg, UDPV6_L3_HASH_EN, UDPV6_L4_HASH_EN,
45746+			UDPV6_VLAN_HASH_EN);
45747+		break;
45748+	case IPV4_FLOW:
45749+		higmac_get_rss_hash(info, hash_cfg, IPV4_L3_HASH_EN, 0,
45750+			IPV4_VLAN_HASH_EN);
45751+		break;
45752+	case IPV6_FLOW:
45753+		higmac_get_rss_hash(info, hash_cfg, IPV6_L3_HASH_EN, 0,
45754+			IPV6_VLAN_HASH_EN);
45755+		break;
45756+	default:
45757+		return -EINVAL;
45758+	}
45759+
45760+	return 0;
45761+}
45762+
45763+int higmac_get_rxnfc(struct net_device *ndev,
45764+		  struct ethtool_rxnfc *info, u32 *rules)
45765+{
45766+	struct higmac_netdev_local *priv = netdev_priv(ndev);
45767+	int ret = -EOPNOTSUPP;
45768+	if (info == NULL)
45769+		return -EINVAL;
45770+	switch (info->cmd) {
45771+	case ETHTOOL_GRXRINGS:
45772+		info->data = priv->num_rxqs;
45773+		ret = 0;
45774+		break;
45775+	case ETHTOOL_GRXFH:
45776+		return higmac_get_rss_hash_opts(priv, info);
45777+	default:
45778+		break;
45779+	}
45780+	return ret;
45781+}
45782+
45783+void higmac_config_hash_policy(struct higmac_netdev_local const *priv)
45784+{
45785+	if (priv == NULL)
45786+		return;
45787+	writel(priv->rss_info.hash_cfg, priv->gmac_iobase + RSS_HASH_CONFIG);
45788+}
45789+
45790+static int higmac_set_tcp_udp_hash_cfg(struct ethtool_rxnfc const *info,
45791+		  u32 *hash_cfg, u32 l4_mask, u32 vlan_mask)
45792+{
45793+	switch (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
45794+	case 0: // all bits is 0
45795+		*hash_cfg &= ~l4_mask;
45796+		break;
45797+	case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
45798+		*hash_cfg |= l4_mask;
45799+		break;
45800+	default:
45801+		return -EINVAL;
45802+	}
45803+	if (info->data & RXH_VLAN)
45804+		*hash_cfg |= vlan_mask;
45805+	else
45806+		*hash_cfg &= ~vlan_mask;
45807+	return 0;
45808+}
45809+
45810+static int higmac_ip_hash_cfg(struct ethtool_rxnfc const *info,
45811+		  u32 *hash_cfg, u32 vlan_mask)
45812+{
45813+	if (info->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3))
45814+		return -EINVAL;
45815+	if (info->data & RXH_VLAN)
45816+		*hash_cfg |= vlan_mask;
45817+	else
45818+		*hash_cfg &= ~vlan_mask;
45819+	return 0;
45820+}
45821+
45822+static int higmac_set_rss_hash_opts(struct higmac_netdev_local *priv,
45823+		  struct ethtool_rxnfc const *info)
45824+{
45825+	u32 hash_cfg;
45826+	if (priv == NULL || priv->netdev == NULL)
45827+		return -EINVAL;
45828+	hash_cfg = priv->rss_info.hash_cfg;
45829+	netdev_info(priv->netdev, "Set RSS flow type = %d, data = %lld\n",
45830+		    info->flow_type, info->data);
45831+
45832+	if (!(info->data & RXH_IP_SRC) || !(info->data & RXH_IP_DST))
45833+		return -EINVAL;
45834+
45835+	switch (info->flow_type) {
45836+	case TCP_V4_FLOW:
45837+		if (higmac_set_tcp_udp_hash_cfg(info, &hash_cfg,
45838+			TCPV4_L4_HASH_EN, TCPV4_VLAN_HASH_EN) == -EINVAL)
45839+			return -EINVAL;
45840+		break;
45841+	case TCP_V6_FLOW:
45842+		if (higmac_set_tcp_udp_hash_cfg(info, &hash_cfg,
45843+			TCPV6_L4_HASH_EN, TCPV6_VLAN_HASH_EN) == -EINVAL)
45844+			return -EINVAL;
45845+		break;
45846+	case UDP_V4_FLOW:
45847+		if (higmac_set_tcp_udp_hash_cfg(info, &hash_cfg,
45848+			UDPV4_L4_HASH_EN, UDPV4_L4_HASH_EN) == -EINVAL)
45849+			return -EINVAL;
45850+		break;
45851+	case UDP_V6_FLOW:
45852+		if (higmac_set_tcp_udp_hash_cfg(info, &hash_cfg,
45853+			UDPV6_L4_HASH_EN, UDPV6_L4_HASH_EN) == -EINVAL)
45854+			return -EINVAL;
45855+		break;
45856+	case IPV4_FLOW:
45857+		if (higmac_ip_hash_cfg(info, &hash_cfg,
45858+			IPV4_VLAN_HASH_EN) == -EINVAL)
45859+			return -EINVAL;
45860+		break;
45861+		break;
45862+	case IPV6_FLOW:
45863+		if (higmac_ip_hash_cfg(info, &hash_cfg,
45864+			IPV6_VLAN_HASH_EN) == -EINVAL)
45865+			return -EINVAL;
45866+		break;
45867+	default:
45868+		return -EINVAL;
45869+	}
45870+
45871+	priv->rss_info.hash_cfg = hash_cfg;
45872+	higmac_config_hash_policy(priv);
45873+
45874+	return 0;
45875+}
45876+
45877+int higmac_set_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *info)
45878+{
45879+	struct higmac_netdev_local *priv = netdev_priv(ndev);
45880+	if (info == NULL)
45881+		return -EINVAL;
45882+	switch (info->cmd) {
45883+	case ETHTOOL_SRXFH:
45884+		return higmac_set_rss_hash_opts(priv, info);
45885+	default:
45886+		break;
45887+	}
45888+	return -EOPNOTSUPP;
45889+}
45890+
45891+static int ksz8051mnl_phy_fix(struct phy_device *phy_dev)
45892+{
45893+	u32 v;
45894+	int ret;
45895+
45896+	if (phy_dev->interface != PHY_INTERFACE_MODE_RMII)
45897+		return 0;
45898+
45899+	ret = phy_read(phy_dev, 0x1F);
45900+	if (ret < 0)
45901+		return ret;
45902+	v = ret;
45903+	v |= (1 << 7); /* set bit 7, phy RMII 50MHz clk; */
45904+	phy_write(phy_dev, 0x1F, v);
45905+
45906+	ret = phy_read(phy_dev, 0x16);
45907+	if (ret < 0)
45908+		return ret;
45909+	v = ret;
45910+	v |= (1 << 1); /* set phy RMII override; */
45911+	phy_write(phy_dev, 0x16, v);
45912+
45913+	return 0;
45914+}
45915+
45916+static int ksz8081rnb_phy_fix(struct phy_device *phy_dev)
45917+{
45918+	u32 v;
45919+	int ret;
45920+
45921+	if (phy_dev->interface != PHY_INTERFACE_MODE_RMII)
45922+		return 0;
45923+
45924+	ret = phy_read(phy_dev, 0x1F);
45925+	if (ret < 0)
45926+		return ret;
45927+	v = ret;
45928+	v |= (1 << 7); /* set bit 7, phy RMII 50MHz clk; */
45929+	phy_write(phy_dev, 0x1F, v);
45930+
45931+	return 0;
45932+}
45933+
45934+static int unknown_phy_fix(struct phy_device *phy_dev)
45935+{
45936+	u32 v;
45937+	int ret;
45938+
45939+	if (phy_dev->interface != PHY_INTERFACE_MODE_RMII)
45940+		return 0;
45941+
45942+	ret = phy_read(phy_dev, 0x1F);
45943+	if (ret < 0)
45944+		return ret;
45945+	v = ret;
45946+	v |= (1 << 7); /* set bit 7, phy RMII 50MHz clk; */
45947+	phy_write(phy_dev, 0x1F, v);
45948+
45949+	return 0;
45950+}
45951+
45952+static int rtl8211e_phy_fix(struct phy_device *phy_dev)
45953+{
45954+	u32 v;
45955+	int ret;
45956+
45957+	/* select Extension page */
45958+	phy_write(phy_dev, 0x1f, 0x7);
45959+	/* switch ExtPage 164 */
45960+	phy_write(phy_dev, 0x1e, 0xa4);
45961+
45962+	/* config RGMII rx pin io driver max */
45963+	ret = phy_read(phy_dev, 0x1c);
45964+	if (ret < 0)
45965+		return ret;
45966+	v = ret;
45967+	v = (v & 0xff03) | 0xfc;
45968+	phy_write(phy_dev, 0x1c, v);
45969+
45970+	/* select to page 0 */
45971+	phy_write(phy_dev, 0x1f, 0);
45972+
45973+	return 0;
45974+}
45975+
45976+void higmac_phy_register_fixups(void)
45977+{
45978+	phy_register_fixup_for_uid(PHY_ID_UNKNOWN, DEFAULT_PHY_MASK,
45979+				   unknown_phy_fix);
45980+	phy_register_fixup_for_uid(PHY_ID_KSZ8051MNL, DEFAULT_PHY_MASK,
45981+				   ksz8051mnl_phy_fix);
45982+	phy_register_fixup_for_uid(PHY_ID_KSZ8081RNB, DEFAULT_PHY_MASK,
45983+				   ksz8081rnb_phy_fix);
45984+	phy_register_fixup_for_uid(REALTEK_PHY_ID_8211E, REALTEK_PHY_MASK,
45985+				   rtl8211e_phy_fix);
45986+}
45987+
45988+void higmac_phy_unregister_fixups(void)
45989+{
45990+	phy_unregister_fixup_for_uid(PHY_ID_UNKNOWN, DEFAULT_PHY_MASK);
45991+	phy_unregister_fixup_for_uid(PHY_ID_KSZ8051MNL, DEFAULT_PHY_MASK);
45992+	phy_unregister_fixup_for_uid(PHY_ID_KSZ8081RNB, DEFAULT_PHY_MASK);
45993+	phy_unregister_fixup_for_uid(REALTEK_PHY_ID_8211E, REALTEK_PHY_MASK);
45994+}
45995diff --git a/drivers/net/ethernet/hisilicon/higmac/util.h b/drivers/net/ethernet/hisilicon/higmac/util.h
45996new file mode 100644
45997index 000000000..ca1c99bb5
45998--- /dev/null
45999+++ b/drivers/net/ethernet/hisilicon/higmac/util.h
46000@@ -0,0 +1,102 @@
46001+/*
46002+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
46003+ * Description: Higmac driver util head file
46004+ * Author: KTP_BSP
46005+ * Create: 2018-10-08
46006+ */
46007+
46008+#ifndef __HIGMAC_UTIL_H__
46009+#define __HIGMAC_UTIL_H__
46010+
46011+#include "higmac.h"
46012+
46013+#define HIGMAC_TRACE_LEVEL 10
46014+#define HIGMAC_NORMAL_LEVEL 7
46015+
46016+#define mk_bits(shift, nbits) ((((shift) & 0x1F) << 16) | ((nbits) & 0x3F))
46017+
46018+#define FC_ACTIVE_MIN		1
46019+#define FC_ACTIVE_DEFAULT	16
46020+#define FC_ACTIVE_MAX		127
46021+#define FC_DEACTIVE_MIN		1
46022+#define FC_DEACTIVE_DEFAULT	32
46023+#define FC_DEACTIVE_MAX		127
46024+
46025+#define FC_PAUSE_TIME_DEFAULT		0xFFFF
46026+#define FC_PAUSE_INTERVAL_DEFAULT	0xFFFF
46027+#define FC_PAUSE_TIME_MAX		0xFFFF
46028+
46029+#define HW_CAP_EN			0x0c00
46030+#define BIT_RSS_CAP			BIT(0)
46031+#define BIT_RXHASH_CAP			BIT(1)
46032+#define RSS_HASH_KEY			0x0c04
46033+#define RSS_HASH_CONFIG			0x0c08
46034+#define TCPV4_L3_HASH_EN		BIT(0)
46035+#define TCPV4_L4_HASH_EN		BIT(1)
46036+#define TCPV4_VLAN_HASH_EN		BIT(2)
46037+#define UDPV4_L3_HASH_EN		BIT(4)
46038+#define UDPV4_L4_HASH_EN		BIT(5)
46039+#define UDPV4_VLAN_HASH_EN		BIT(6)
46040+#define IPV4_L3_HASH_EN			BIT(8)
46041+#define IPV4_VLAN_HASH_EN		BIT(9)
46042+#define TCPV6_L3_HASH_EN		BIT(12)
46043+#define TCPV6_L4_HASH_EN		BIT(13)
46044+#define TCPV6_VLAN_HASH_EN		BIT(14)
46045+#define UDPV6_L3_HASH_EN		BIT(16)
46046+#define UDPV6_L4_HASH_EN		BIT(17)
46047+#define UDPV6_VLAN_HASH_EN		BIT(18)
46048+#define IPV6_L3_HASH_EN			BIT(20)
46049+#define IPV6_VLAN_HASH_EN		BIT(21)
46050+#define DEF_HASH_CFG			0x377377
46051+
46052+#define RGMII_SPEED_1000		0x2c
46053+#define RGMII_SPEED_100			0x2f
46054+#define RGMII_SPEED_10			0x2d
46055+#define MII_SPEED_100			0x0f
46056+#define MII_SPEED_10			0x0d
46057+#define RMII_SPEED_100			0x8f
46058+#define RMII_SPEED_10			0x8d
46059+#define GMAC_FULL_DUPLEX		BIT(4)
46060+
46061+void higmac_trace(int level, const char *fmt, ...);
46062+
46063+void higmac_config_port(struct net_device const *dev, u32 speed, u32 duplex);
46064+int higmac_rx_checksum(struct net_device *dev, struct sk_buff *skb,
46065+		  struct higmac_desc const *desc);
46066+void higmac_verify_flow_ctrl_args(void);
46067+void higmac_set_flow_ctrl_args(struct higmac_netdev_local *ld);
46068+
46069+int higmac_check_hw_capability(struct sk_buff *skb);
46070+int higmac_get_pkt_info(struct higmac_netdev_local *ld,
46071+			struct sk_buff *skb, struct higmac_tso_desc *tx_bq_desc);
46072+
46073+void higmac_get_drvinfo(struct net_device *net_dev,
46074+			struct ethtool_drvinfo *info);
46075+unsigned int higmac_get_link(struct net_device *net_dev);
46076+int higmac_get_settings(struct net_device *net_dev, struct ethtool_cmd *cmd);
46077+int higmac_set_settings(struct net_device *net_dev, struct ethtool_cmd *cmd);
46078+void higmac_get_pauseparam(struct net_device *net_dev,
46079+			   struct ethtool_pauseparam *pause);
46080+int higmac_set_pauseparam(struct net_device *net_dev,
46081+			  struct ethtool_pauseparam *pause);
46082+u32 higmac_ethtool_getmsglevel(struct net_device *ndev);
46083+void higmac_ethtool_setmsglevel(struct net_device *ndev, u32 level);
46084+u32 higmac_get_rxfh_key_size(struct net_device *ndev);
46085+u32 higmac_get_rxfh_indir_size(struct net_device *ndev);
46086+int higmac_get_rxfh(struct net_device *ndev, u32 *indir, u8 *hkey, u8 *hfunc);
46087+int higmac_set_rxfh(struct net_device *ndev, const u32 *indir,
46088+		    const u8 *hkey, const u8 hfunc);
46089+int higmac_get_rxnfc(struct net_device *ndev,
46090+		     struct ethtool_rxnfc *info, u32 *rules);
46091+int higmac_set_rxnfc(struct net_device *ndev, struct ethtool_rxnfc *info);
46092+
46093+void higmac_get_rss_key(struct higmac_netdev_local *priv);
46094+void higmac_get_rss(struct higmac_netdev_local *priv);
46095+void higmac_config_hash_policy(struct higmac_netdev_local const *priv);
46096+
46097+void higmac_set_flow_ctrl_state(struct higmac_netdev_local const *ld, int pause);
46098+void higmac_set_flow_ctrl_params(struct higmac_netdev_local const *ld);
46099+
46100+void higmac_phy_register_fixups(void);
46101+void higmac_phy_unregister_fixups(void);
46102+#endif
46103diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/Makefile b/drivers/net/ethernet/hisilicon/hisi-femac/Makefile
46104new file mode 100644
46105index 000000000..bfad94751
46106--- /dev/null
46107+++ b/drivers/net/ethernet/hisilicon/hisi-femac/Makefile
46108@@ -0,0 +1,6 @@
46109+#
46110+# Makefile for the HISILICON Fast Ethernet network device drivers.
46111+#
46112+
46113+obj-$(CONFIG_HISI_FEMAC) += hisi-femac.o
46114+hisi-femac-objs := hisi_femac.o phy_fix.o util.o
46115diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/festa_s28v115_2c02.h b/drivers/net/ethernet/hisilicon/hisi-femac/festa_s28v115_2c02.h
46116new file mode 100644
46117index 000000000..6c00c71a0
46118--- /dev/null
46119+++ b/drivers/net/ethernet/hisilicon/hisi-femac/festa_s28v115_2c02.h
46120@@ -0,0 +1,191 @@
46121+/*
46122+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
46123+ * Description: Hieth driver festa_s28v115_2c02 phy fixup paramters
46124+ * Author: KTP_BSP
46125+ * Create: 2018-10-08
46126+ */
46127+
46128+#ifndef __HIETH_FESTA_S28V115_2C02_H__
46129+#define __HIETH_FESTA_S28V115_2C02_H__
46130+	0x33f9, 0xbd, 0x33fa, 0x34, 0x33fb, 0x00,
46131+	0x33fc, 0x39, 0x3400, 0x39, 0x3401, 0xCC,
46132+	0x3402, 0x2C, 0x3403, 0x02, 0x3404, 0xFD,
46133+	0x3405, 0xFF, 0x3406, 0xF0, 0x3407, 0xF6,
46134+	0x3408, 0x36, 0x3409, 0x18, 0x340A, 0x26,
46135+	0x340B, 0x05, 0x340C, 0xC6, 0x340D, 0x01,
46136+	0x340E, 0xF7, 0x340F, 0x36, 0x3410, 0x18,
46137+	0x3411, 0xCC, 0x3412, 0x35, 0x3413, 0x9F,
46138+	0x3414, 0x1A, 0x3415, 0xB3, 0x3416, 0x00,
46139+	0x3417, 0xD2, 0x3418, 0x27, 0x3419, 0x09,
46140+	0x341A, 0xFD, 0x341B, 0x00, 0x341C, 0xD2,
46141+	0x341D, 0x7F, 0x341E, 0x01, 0x341F, 0xBF,
46142+	0x3420, 0x7F, 0x3421, 0x01, 0x3422, 0xB1,
46143+	0x3423, 0x39, 0x3424, 0x3C, 0x3425, 0x3C,
46144+	0x3426, 0x30, 0x3427, 0xF6, 0x3428, 0x30,
46145+	0x3429, 0x55, 0x342A, 0xC0, 0x342B, 0x07,
46146+	0x342C, 0x18, 0x342D, 0xFE, 0x342E, 0x30,
46147+	0x342F, 0x4C, 0x3430, 0x18, 0x3431, 0x3A,
46148+	0x3432, 0x18, 0x3433, 0xE6, 0x3434, 0x00,
46149+	0x3435, 0x5C, 0x3436, 0xE7, 0x3437, 0x01,
46150+	0x3438, 0xC1, 0x3439, 0x07, 0x343A, 0x23,
46151+	0x343B, 0x04, 0x343C, 0xC6, 0x343D, 0x07,
46152+	0x343E, 0xE7, 0x343F, 0x01, 0x3440, 0x58,
46153+	0x3441, 0x58, 0x3442, 0x58, 0x3443, 0x58,
46154+	0x3444, 0x58, 0x3445, 0xE7, 0x3446, 0x00,
46155+	0x3447, 0xF6, 0x3448, 0x20, 0x3449, 0x04,
46156+	0x344A, 0xC4, 0x344B, 0x1F, 0x344C, 0xEA,
46157+	0x344D, 0x00, 0x344E, 0xF7, 0x344F, 0x20,
46158+	0x3450, 0x04, 0x3451, 0x38, 0x3452, 0x38,
46159+	0x3453, 0x39, 0x3454, 0x3C, 0x3455, 0x37,
46160+	0x3456, 0x36, 0x3457, 0x30, 0x3458, 0x1A,
46161+	0x3459, 0xEE, 0x345A, 0x00, 0x345B, 0x18,
46162+	0x345C, 0xE6, 0x345D, 0x00, 0x345E, 0x26,
46163+	0x345F, 0x1C, 0x3460, 0xF6, 0x3461, 0x00,
46164+	0x3462, 0x5C, 0x3463, 0xC5, 0x3464, 0x04,
46165+	0x3465, 0x27, 0x3466, 0x06, 0x3467, 0xCC,
46166+	0x3468, 0x36, 0x3469, 0x12, 0x346A, 0xBD,
46167+	0x346B, 0xF0, 0x346C, 0xA5, 0x346D, 0xF6,
46168+	0x346E, 0x00, 0x346F, 0x47, 0x3470, 0xC4,
46169+	0x3471, 0xF3, 0x3472, 0xF7, 0x3473, 0x00,
46170+	0x3474, 0x47, 0x3475, 0xC6, 0x3476, 0x01,
46171+	0x3477, 0x1A, 0x3478, 0xEE, 0x3479, 0x00,
46172+	0x347A, 0x20, 0x347B, 0x10, 0x347C, 0x5A,
46173+	0x347D, 0x26, 0x347E, 0x14, 0x347F, 0xF6,
46174+	0x3480, 0x00, 0x3481, 0x46, 0x3482, 0x4F,
46175+	0x3483, 0xC4, 0x3484, 0x0C, 0x3485, 0x83,
46176+	0x3486, 0x00, 0x3487, 0x08, 0x3488, 0x26,
46177+	0x3489, 0x05, 0x348A, 0xC6, 0x348B, 0x02,
46178+	0x348C, 0x18, 0x348D, 0xE7, 0x348E, 0x00,
46179+	0x348F, 0x5F, 0x3490, 0x38, 0x3491, 0x38,
46180+	0x3492, 0x39, 0x3493, 0xF6, 0x3494, 0x00,
46181+	0x3495, 0x5C, 0x3496, 0xC5, 0x3497, 0x04,
46182+	0x3498, 0x27, 0x3499, 0x06, 0x349A, 0xCC,
46183+	0x349B, 0x36, 0x349C, 0x08, 0x349D, 0xBD,
46184+	0x349E, 0xF0, 0x349F, 0xA5, 0x34A0, 0xF6,
46185+	0x34A1, 0x00, 0x34A2, 0x47, 0x34A3, 0xC4,
46186+	0x34A4, 0xF3, 0x34A5, 0xCA, 0x34A6, 0x08,
46187+	0x34A7, 0xF7, 0x34A8, 0x00, 0x34A9, 0x47,
46188+	0x34AA, 0x18, 0x34AB, 0xFE, 0x34AC, 0x00,
46189+	0x34AD, 0xB6, 0x34AE, 0x18, 0x34AF, 0xAD,
46190+	0x34B0, 0x00, 0x34B1, 0xBD, 0x34B2, 0x34,
46191+	0x34B3, 0x24, 0x34B4, 0xF6, 0x34B5, 0x1E,
46192+	0x34B6, 0x05, 0x34B7, 0xC5, 0x34B8, 0x02,
46193+	0x34B9, 0x27, 0x34BA, 0x0A, 0x34BB, 0xF6,
46194+	0x34BC, 0x1E, 0x34BD, 0x07, 0x34BE, 0xC5,
46195+	0x34BF, 0x02, 0x34C0, 0x27, 0x34C1, 0x03,
46196+	0x34C2, 0xBD, 0x34C3, 0xC0, 0x34C4, 0x33,
46197+	0x34C5, 0xF6, 0x34C6, 0x31, 0x34C7, 0x1F,
46198+	0x34C8, 0x37, 0x34C9, 0xC6, 0x34CA, 0x52,
46199+	0x34CB, 0xBD, 0x34CC, 0xDC, 0x34CD, 0x53,
46200+	0x34CE, 0x31, 0x34CF, 0xF6, 0x34D0, 0x00,
46201+	0x34D1, 0x41, 0x34D2, 0xC5, 0x34D3, 0x10,
46202+	0x34D4, 0x26, 0x34D5, 0x04, 0x34D6, 0x13,
46203+	0x34D7, 0x23, 0x34D8, 0x40, 0x34D9, 0x0D,
46204+	0x34DA, 0xBD, 0x34DB, 0x93, 0x34DC, 0xCE,
46205+	0x34DD, 0x1A, 0x34DE, 0xEE, 0x34DF, 0x00,
46206+	0x34E0, 0x18, 0x34E1, 0x6F, 0x34E2, 0x00,
46207+	0x34E3, 0xC6, 0x34E4, 0x04, 0x34E5, 0x20,
46208+	0x34E6, 0xA9, 0x34E7, 0x1A, 0x34E8, 0xEE,
46209+	0x34E9, 0x00, 0x34EA, 0x18, 0x34EB, 0x6F,
46210+	0x34EC, 0x00, 0x34ED, 0xC6, 0x34EE, 0x01,
46211+	0x34EF, 0x20, 0x34F0, 0x9F, 0x34F1, 0x3C,
46212+	0x34F2, 0x37, 0x34F3, 0x36, 0x34F4, 0x30,
46213+	0x34F5, 0x1A, 0x34F6, 0xEE, 0x34F7, 0x00,
46214+	0x34F8, 0x18, 0x34F9, 0xE6, 0x34FA, 0x00,
46215+	0x34FB, 0x26, 0x34FC, 0x49, 0x34FD, 0xF6,
46216+	0x34FE, 0x00, 0x34FF, 0x5C, 0x3500, 0xC5,
46217+	0x3501, 0x04, 0x3502, 0x27, 0x3503, 0x06,
46218+	0x3504, 0xCC, 0x3505, 0x35, 0x3506, 0xFC,
46219+	0x3507, 0xBD, 0x3508, 0xF0, 0x3509, 0xA5,
46220+	0x350A, 0xC6, 0x350B, 0x52, 0x350C, 0xBD,
46221+	0x350D, 0xDC, 0x350E, 0xF3, 0x350F, 0x5D,
46222+	0x3510, 0x27, 0x3511, 0x03, 0x3512, 0xBD,
46223+	0x3513, 0xC0, 0x3514, 0x22, 0x3515, 0xF6,
46224+	0x3516, 0x00, 0x3517, 0x46, 0x3518, 0xC5,
46225+	0x3519, 0x0C, 0x351A, 0x26, 0x351B, 0x0A,
46226+	0x351C, 0x1A, 0x351D, 0xEE, 0x351E, 0x00,
46227+	0x351F, 0x18, 0x3520, 0x6F, 0x3521, 0x00,
46228+	0x3522, 0xC6, 0x3523, 0x07, 0x3524, 0x20,
46229+	0x3525, 0x1D, 0x3526, 0xFC, 0x3527, 0x30,
46230+	0x3528, 0x0C, 0x3529, 0xBD, 0x352A, 0x93,
46231+	0x352B, 0x19, 0x352C, 0xBD, 0x352D, 0x9F,
46232+	0x352E, 0x0B, 0x352F, 0xC6, 0x3530, 0x02,
46233+	0x3531, 0x37, 0x3532, 0xC6, 0x3533, 0x51,
46234+	0x3534, 0xBD, 0x3535, 0xDC, 0x3536, 0x53,
46235+	0x3537, 0x31, 0x3538, 0x7F, 0x3539, 0x02,
46236+	0x353A, 0x07, 0x353B, 0xC6, 0x353C, 0x02,
46237+	0x353D, 0x1A, 0x353E, 0xEE, 0x353F, 0x00,
46238+	0x3540, 0x18, 0x3541, 0xE7, 0x3542, 0x00,
46239+	0x3543, 0x38, 0x3544, 0x38, 0x3545, 0x39,
46240+	0x3546, 0xC6, 0x3547, 0x52, 0x3548, 0xBD,
46241+	0x3549, 0xDC, 0x354A, 0xF3, 0x354B, 0x5D,
46242+	0x354C, 0x27, 0x354D, 0x03, 0x354E, 0xBD,
46243+	0x354F, 0xC0, 0x3550, 0x22, 0x3551, 0xF6,
46244+	0x3552, 0x00, 0x3553, 0x46, 0x3554, 0xC5,
46245+	0x3555, 0x0C, 0x3556, 0x26, 0x3557, 0x0A,
46246+	0x3558, 0x1A, 0x3559, 0xEE, 0x355A, 0x00,
46247+	0x355B, 0x18, 0x355C, 0x6F, 0x355D, 0x00,
46248+	0x355E, 0xC6, 0x355F, 0x07, 0x3560, 0x20,
46249+	0x3561, 0xE1, 0x3562, 0xC6, 0x3563, 0x51,
46250+	0x3564, 0xBD, 0x3565, 0xDC, 0x3566, 0xF3,
46251+	0x3567, 0x5D, 0x3568, 0x26, 0x3569, 0x04,
46252+	0x356A, 0xC6, 0x356B, 0x02, 0x356C, 0x20,
46253+	0x356D, 0xD5, 0x356E, 0xF6, 0x356F, 0x00,
46254+	0x3570, 0x41, 0x3571, 0xC5, 0x3572, 0x10,
46255+	0x3573, 0x26, 0x3574, 0x20, 0x3575, 0xF6,
46256+	0x3576, 0x02, 0x3577, 0x07, 0x3578, 0xC1,
46257+	0x3579, 0x02, 0x357A, 0x24, 0x357B, 0x19,
46258+	0x357C, 0x18, 0x357D, 0xFE, 0x357E, 0x02,
46259+	0x357F, 0x08, 0x3580, 0x18, 0x3581, 0xAD,
46260+	0x3582, 0x00, 0x3583, 0xF6, 0x3584, 0x02,
46261+	0x3585, 0x06, 0x3586, 0x27, 0x3587, 0x0D,
46262+	0x3588, 0xC6, 0x3589, 0x02, 0x358A, 0x37,
46263+	0x358B, 0xC6, 0x358C, 0x51, 0x358D, 0xBD,
46264+	0x358E, 0xDC, 0x358F, 0x53, 0x3590, 0x31,
46265+	0x3591, 0xC6, 0x3592, 0x02, 0x3593, 0x20,
46266+	0x3594, 0xAE, 0x3595, 0x1A, 0x3596, 0xEE,
46267+	0x3597, 0x00, 0x3598, 0x18, 0x3599, 0x6F,
46268+	0x359A, 0x00, 0x359B, 0xC6, 0x359C, 0x03,
46269+	0x359D, 0x20, 0x359E, 0xA4, 0x359F, 0xF6,
46270+	0x35A0, 0x01, 0x35A1, 0xBF, 0x35A2, 0xC1,
46271+	0x35A3, 0x08, 0x35A4, 0x24, 0x35A5, 0x55,
46272+	0x35A6, 0xBD, 0x35A7, 0xF6, 0x35A8, 0xD3,
46273+	0x35A9, 0x35, 0x35AA, 0xBA, 0x35AB, 0x35,
46274+	0x35AC, 0xC2, 0x35AD, 0x35, 0x35AE, 0xCA,
46275+	0x35AF, 0x35, 0x35B0, 0xD2, 0x35B1, 0x35,
46276+	0x35B2, 0xDA, 0x35B3, 0x35, 0x35B4, 0xE2,
46277+	0x35B5, 0x35, 0x35B6, 0xEA, 0x35B7, 0x35,
46278+	0x35B8, 0xF2, 0x35B9, 0x39, 0x35BA, 0xCC,
46279+	0x35BB, 0x01, 0x35BC, 0xB1, 0x35BD, 0xBD,
46280+	0x35BE, 0x34, 0x35BF, 0x54, 0x35C0, 0x20,
46281+	0x35C1, 0x36, 0x35C2, 0xCC, 0x35C3, 0x01,
46282+	0x35C4, 0xB1, 0x35C5, 0xBD, 0x35C6, 0xC1,
46283+	0x35C7, 0x52, 0x35C8, 0x20, 0x35C9, 0x2E,
46284+	0x35CA, 0xCC, 0x35CB, 0x01, 0x35CC, 0xB1,
46285+	0x35CD, 0xBD, 0x35CE, 0x34, 0x35CF, 0xF1,
46286+	0x35D0, 0x20, 0x35D1, 0x26, 0x35D2, 0xCC,
46287+	0x35D3, 0x01, 0x35D4, 0xB1, 0x35D5, 0xBD,
46288+	0x35D6, 0xC3, 0x35D7, 0x9A, 0x35D8, 0x20,
46289+	0x35D9, 0x1E, 0x35DA, 0xCC, 0x35DB, 0x01,
46290+	0x35DC, 0xB1, 0x35DD, 0xBD, 0x35DE, 0xC4,
46291+	0x35DF, 0x39, 0x35E0, 0x20, 0x35E1, 0x16,
46292+	0x35E2, 0xCC, 0x35E3, 0x01, 0x35E4, 0xB1,
46293+	0x35E5, 0xBD, 0x35E6, 0xC5, 0x35E7, 0x0B,
46294+	0x35E8, 0x20, 0x35E9, 0x0E, 0x35EA, 0xCC,
46295+	0x35EB, 0x01, 0x35EC, 0xB1, 0x35ED, 0xBD,
46296+	0x35EE, 0xC6, 0x35EF, 0x3A, 0x35F0, 0x20,
46297+	0x35F1, 0x06, 0x35F2, 0xCC, 0x35F3, 0x01,
46298+	0x35F4, 0xB1, 0x35F5, 0xBD, 0x35F6, 0xC7,
46299+	0x35F7, 0xC2, 0x35F8, 0xF7, 0x35F9, 0x01,
46300+	0x35FA, 0xBF, 0x35FB, 0x39, 0x35FC, 0x43,
46301+	0x35FD, 0x3A, 0x35FE, 0x41, 0x35FF, 0x44,
46302+	0x3600, 0x54, 0x3601, 0x5F, 0x3602, 0x41,
46303+	0x3603, 0x54, 0x3604, 0x4E, 0x3605, 0x0A,
46304+	0x3606, 0x0D, 0x3607, 0x00, 0x3608, 0x43,
46305+	0x3609, 0x3A, 0x360A, 0x45, 0x360B, 0x6E,
46306+	0x360C, 0x5F, 0x360D, 0x53, 0x360E, 0x74,
46307+	0x360F, 0x0A, 0x3610, 0x0D, 0x3611, 0x00,
46308+	0x3612, 0x43, 0x3613, 0x3A, 0x3614, 0x49,
46309+	0x3615, 0x0A, 0x3616, 0x0D, 0x3617, 0x00,
46310+	0x3618, 0x00, 0x3400, 0x01, 0x33f8, 0x01
46311+#endif
46312\ No newline at end of file
46313diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/festa_s28v202_2e01.h b/drivers/net/ethernet/hisilicon/hisi-femac/festa_s28v202_2e01.h
46314new file mode 100644
46315index 000000000..758d79688
46316--- /dev/null
46317+++ b/drivers/net/ethernet/hisilicon/hisi-femac/festa_s28v202_2e01.h
46318@@ -0,0 +1,84 @@
46319+/*
46320+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
46321+ * Description: Hieth driver festa_s28v202_2e01 phy fixup paramters
46322+ * Author: KTP_BSP
46323+ * Create: 2020-05-11
46324+ */
46325+
46326+#ifndef __HIETH_FESTA_S28V202_2E01_H__
46327+#define __HIETH_FESTA_S28V202_2E01_H__
46328+	0x33f9, 0xbd, 0x33fa, 0x34, 0x33fb, 0x00,
46329+	0x33fc, 0x39, 0x3400, 0x39, 0x3401, 0xCC,
46330+	0x3402, 0x2E, 0x3403, 0x01, 0x3404, 0xFD,
46331+	0x3405, 0xFF, 0x3406, 0xF2, 0x3407, 0x4F,
46332+	0x3408, 0xFD, 0x3409, 0xFF, 0x340A, 0xF0,
46333+	0x340B, 0xF6, 0x340C, 0x34, 0x340D, 0xD7,
46334+	0x340E, 0x26, 0x340F, 0x05, 0x3410, 0xC6,
46335+	0x3411, 0x01, 0x3412, 0xF7, 0x3413, 0x34,
46336+	0x3414, 0xD7, 0x3415, 0xF6, 0x3416, 0x08,
46337+	0x3417, 0x00, 0x3418, 0xF7, 0x3419, 0x34,
46338+	0x341A, 0xD8, 0x341B, 0xC6, 0x341C, 0x01,
46339+	0x341D, 0xF7, 0x341E, 0x08, 0x341F, 0x00,
46340+	0x3420, 0x20, 0x3421, 0x0F, 0x3422, 0xCC,
46341+	0x3423, 0x34, 0x3424, 0x3F, 0x3425, 0x1A,
46342+	0x3426, 0xB3, 0x3427, 0x00, 0x3428, 0xCC,
46343+	0x3429, 0x27, 0x342A, 0x03, 0x342B, 0xFD,
46344+	0x342C, 0x00, 0x342D, 0xCC, 0x342E, 0x78,
46345+	0x342F, 0x08, 0x3430, 0x00, 0x3431, 0xF6,
46346+	0x3432, 0x08, 0x3433, 0x00, 0x3434, 0xC1,
46347+	0x3435, 0x02, 0x3436, 0x26, 0x3437, 0xEA,
46348+	0x3438, 0xF6, 0x3439, 0x34, 0x343A, 0xD8,
46349+	0x343B, 0xF7, 0x343C, 0x08, 0x343D, 0x00,
46350+	0x343E, 0x39, 0x343F, 0xBD, 0x3440, 0xF7,
46351+	0x3441, 0xFA, 0x3442, 0x08, 0x3443, 0xCC,
46352+	0x3444, 0x20, 0x3445, 0xA1, 0x3446, 0xED,
46353+	0x3447, 0x05, 0x3448, 0xC6, 0x3449, 0xA4,
46354+	0x344A, 0xED, 0x344B, 0x03, 0x344C, 0xBD,
46355+	0x344D, 0x8B, 0x344E, 0x82, 0x344F, 0xE7,
46356+	0x3450, 0x07, 0x3451, 0xC0, 0x3452, 0x02,
46357+	0x3453, 0x27, 0x3454, 0x11, 0x3455, 0x5A,
46358+	0x3456, 0x27, 0x3457, 0x0E, 0x3458, 0x5A,
46359+	0x3459, 0x27, 0x345A, 0x39, 0x345B, 0x5A,
46360+	0x345C, 0x27, 0x345D, 0x36, 0x345E, 0x5A,
46361+	0x345F, 0x27, 0x3460, 0x51, 0x3461, 0x5A,
46362+	0x3462, 0x27, 0x3463, 0x4E, 0x3464, 0x20,
46363+	0x3465, 0x6D, 0x3466, 0x18, 0x3467, 0xFE,
46364+	0x3468, 0x30, 0x3469, 0x1E, 0x346A, 0xF6,
46365+	0x346B, 0x30, 0x346C, 0x22, 0x346D, 0x18,
46366+	0x346E, 0x3A, 0x346F, 0x18, 0x3470, 0xE6,
46367+	0x3471, 0x00, 0x3472, 0x58, 0x3473, 0x58,
46368+	0x3474, 0xE7, 0x3475, 0x02, 0x3476, 0x1A,
46369+	0x3477, 0xEE, 0x3478, 0x05, 0x3479, 0x18,
46370+	0x347A, 0xE6, 0x347B, 0x00, 0x347C, 0xC4,
46371+	0x347D, 0x03, 0x347E, 0xEA, 0x347F, 0x02,
46372+	0x3480, 0x18, 0x3481, 0xE7, 0x3482, 0x00,
46373+	0x3483, 0x1A, 0x3484, 0xEE, 0x3485, 0x03,
46374+	0x3486, 0x18, 0x3487, 0xE6, 0x3488, 0x00,
46375+	0x3489, 0xC4, 0x348A, 0x1F, 0x348B, 0xCA,
46376+	0x348C, 0xC0, 0x348D, 0x18, 0x348E, 0xE7,
46377+	0x348F, 0x00, 0x3490, 0xC6, 0x3491, 0x09,
46378+	0x3492, 0x20, 0x3493, 0x3A, 0x3494, 0x1A,
46379+	0x3495, 0xEE, 0x3496, 0x05, 0x3497, 0x18,
46380+	0x3498, 0xE6, 0x3499, 0x00, 0x349A, 0xC4,
46381+	0x349B, 0x03, 0x349C, 0xCA, 0x349D, 0x54,
46382+	0x349E, 0x18, 0x349F, 0xE7, 0x34A0, 0x00,
46383+	0x34A1, 0x1A, 0x34A2, 0xEE, 0x34A3, 0x03,
46384+	0x34A4, 0x18, 0x34A5, 0xE6, 0x34A6, 0x00,
46385+	0x34A7, 0xC4, 0x34A8, 0x1F, 0x34A9, 0xCA,
46386+	0x34AA, 0x20, 0x34AB, 0x18, 0x34AC, 0xE7,
46387+	0x34AD, 0x00, 0x34AE, 0xC6, 0x34AF, 0x74,
46388+	0x34B0, 0x20, 0x34B1, 0x1C, 0x34B2, 0x1A,
46389+	0x34B3, 0xEE, 0x34B4, 0x05, 0x34B5, 0x18,
46390+	0x34B6, 0xE6, 0x34B7, 0x00, 0x34B8, 0xC4,
46391+	0x34B9, 0x03, 0x34BA, 0xCA, 0x34BB, 0x48,
46392+	0x34BC, 0x18, 0x34BD, 0xE7, 0x34BE, 0x00,
46393+	0x34BF, 0x1A, 0x34C0, 0xEE, 0x34C1, 0x03,
46394+	0x34C2, 0x18, 0x34C3, 0xE6, 0x34C4, 0x00,
46395+	0x34C5, 0xC4, 0x34C6, 0x1F, 0x34C7, 0xCA,
46396+	0x34C8, 0x20, 0x34C9, 0x18, 0x34CA, 0xE7,
46397+	0x34CB, 0x00, 0x34CC, 0xC6, 0x34CD, 0x52,
46398+	0x34CE, 0x18, 0x34CF, 0x08, 0x34D0, 0x18,
46399+	0x34D1, 0xE7, 0x34D2, 0x00, 0x34D3, 0xAE,
46400+	0x34D4, 0x00, 0x34D5, 0x38, 0x34D6, 0x39,
46401+	0x34D7, 0x00, 0x3400, 0x01, 0x33f8, 0x01
46402+#endif
46403diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/festa_v272_2723.h b/drivers/net/ethernet/hisilicon/hisi-femac/festa_v272_2723.h
46404new file mode 100644
46405index 000000000..edb9d53bb
46406--- /dev/null
46407+++ b/drivers/net/ethernet/hisilicon/hisi-femac/festa_v272_2723.h
46408@@ -0,0 +1,44 @@
46409+/*
46410+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
46411+ * Description: Hieth driver festa_v272_2723 phy fixup paramters
46412+ * Author: KTP_BSP
46413+ * Create: 2018-10-08
46414+ */
46415+
46416+#ifndef __HIETH_FESTA_V272_2723_H__
46417+#define __HIETH_FESTA_V272_2723_H__
46418+	0x33f9, 0xbd, 0x33fa, 0x34, 0x33fb, 0x00,
46419+	0x33fc, 0x39, 0x3400, 0x39, 0x3401, 0xCC,
46420+	0x3402, 0x27, 0x3403, 0x23, 0x3404, 0xFD,
46421+	0x3405, 0xFF, 0x3406, 0xF0, 0x3407, 0x20,
46422+	0x3408, 0x00, 0x3409, 0x3C, 0x340A, 0x3C,
46423+	0x340B, 0x30, 0x340C, 0xF6, 0x340D, 0x00,
46424+	0x340E, 0x4A, 0x340F, 0xC4, 0x3410, 0x7F,
46425+	0x3411, 0xE7, 0x3412, 0x01, 0x3413, 0xF6,
46426+	0x3414, 0x01, 0x3415, 0xBE, 0x3416, 0xC1,
46427+	0x3417, 0x02, 0x3418, 0x27, 0x3419, 0x0E,
46428+	0x341A, 0xE6, 0x341B, 0x01, 0x341C, 0xC1,
46429+	0x341D, 0x14, 0x341E, 0x27, 0x341F, 0x08,
46430+	0x3420, 0xC1, 0x3421, 0x18, 0x3422, 0x25,
46431+	0x3423, 0x09, 0x3424, 0xC1, 0x3425, 0x1B,
46432+	0x3426, 0x22, 0x3427, 0x05, 0x3428, 0xC6,
46433+	0x3429, 0x5C, 0x342A, 0xF7, 0x342B, 0x20,
46434+	0x342C, 0xA1, 0x342D, 0xF6, 0x342E, 0x01,
46435+	0x342F, 0xBF, 0x3430, 0xC1, 0x3431, 0x01,
46436+	0x3432, 0x26, 0x3433, 0x29, 0x3434, 0xF6,
46437+	0x3435, 0x30, 0x3436, 0x55, 0x3437, 0xC0,
46438+	0x3438, 0x05, 0x3439, 0xE7, 0x343A, 0x01,
46439+	0x343B, 0xC1, 0x343C, 0x13, 0x343D, 0x23,
46440+	0x343E, 0x04, 0x343F, 0xC6, 0x3440, 0x13,
46441+	0x3441, 0xE7, 0x3442, 0x01, 0x3443, 0x18,
46442+	0x3444, 0xFE, 0x3445, 0x30, 0x3446, 0x4C,
46443+	0x3447, 0x18, 0x3448, 0x3A, 0x3449, 0x18,
46444+	0x344A, 0xE6, 0x344B, 0x00, 0x344C, 0x58,
46445+	0x344D, 0x58, 0x344E, 0x58, 0x344F, 0x58,
46446+	0x3450, 0x58, 0x3451, 0xE7, 0x3452, 0x00,
46447+	0x3453, 0xF6, 0x3454, 0x20, 0x3455, 0x04,
46448+	0x3456, 0xC4, 0x3457, 0x1F, 0x3458, 0xEA,
46449+	0x3459, 0x00, 0x345A, 0xF7, 0x345B, 0x20,
46450+	0x345C, 0x04, 0x345D, 0x38, 0x345E, 0x38,
46451+	0x345F, 0x39, 0x3400, 0x01, 0x33f8, 0x01
46452+#endif
46453\ No newline at end of file
46454diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/hisi_femac.c b/drivers/net/ethernet/hisilicon/hisi-femac/hisi_femac.c
46455new file mode 100644
46456index 000000000..48815a2d6
46457--- /dev/null
46458+++ b/drivers/net/ethernet/hisilicon/hisi-femac/hisi_femac.c
46459@@ -0,0 +1,1588 @@
46460+/*
46461+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
46462+ * Description: Hieth driver main process file
46463+ * Author: KTP_BSP
46464+ * Create: 2018-10-08
46465+ */
46466+
46467+#include <linux/circ_buf.h>
46468+#include <linux/clk.h>
46469+#include <linux/etherdevice.h>
46470+#include <linux/if_ether.h>
46471+#include <linux/interrupt.h>
46472+#include <linux/module.h>
46473+#include <linux/of_mdio.h>
46474+#include <linux/of_net.h>
46475+#include <linux/platform_device.h>
46476+#include <linux/reset.h>
46477+#include <linux/tcp.h>
46478+#include <net/protocol.h>
46479+
46480+#include "phy_fix.h"
46481+#include "hisi_femac.h"
46482+#include "util.h"
46483+
46484+static void hisi_femac_irq_enable(const struct hisi_femac_priv *priv, u32 irqs)
46485+{
46486+	u32 val;
46487+
46488+	val = readl(priv->glb_base + GLB_IRQ_ENA);
46489+	writel(val | irqs, priv->glb_base + GLB_IRQ_ENA);
46490+}
46491+
46492+static void hisi_femac_irq_disable(const struct hisi_femac_priv *priv, u32 irqs)
46493+{
46494+	u32 val;
46495+
46496+	val = readl(priv->glb_base + GLB_IRQ_ENA);
46497+	writel(val & (~irqs), priv->glb_base + GLB_IRQ_ENA);
46498+}
46499+
46500+#ifdef CONFIG_FEPHY_OPT
46501+static u32 highflag = 0;
46502+static u32 lowflag = 0;
46503+static void hisi_femac_trim_phy(struct phy_device *phy_dev, u32 val)
46504+{
46505+	u32 val1;
46506+	/* 32 pieces of data */
46507+	int table[32] = {0x11, 0x10, 0x10, 0xf, 0xe, 0xd, 0xd, 0xc,
46508+			 0xb, 0xa, 0xa, 0x9, 0x8, 0x7, 0x7, 0x6,
46509+			 0x5, 0x5, 0x4, 0x3, 0x2, 0x2, 0x1, 0x0,
46510+			 0x3f, 0x3f, 0x3e, 0x3d, 0x3c, 0x3b, 0x3a
46511+			};
46512+
46513+	phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_CACHE);
46514+	phy_write(phy_dev, MII_EXPMD, val);
46515+	val &= 0x1f;
46516+	val1 = table[val];
46517+	phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_VALUE);
46518+	val = (u32)phy_read(phy_dev, MII_EXPMD);
46519+	val = (val1 << 2) | (val & 0x3); /* shift left 2 bits */
46520+	phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_VALUE);
46521+	phy_write(phy_dev, MII_EXPMD, val);
46522+}
46523+
46524+static void hisi_femac_trim(const struct net_device *dev)
46525+{
46526+	struct phy_device *phy_dev = NULL;
46527+	int temp;
46528+	u32 val;
46529+
46530+	phy_dev = dev->phydev;
46531+	if (phy_dev == NULL) {
46532+		pr_err("get phy device failed \n");
46533+		return;
46534+	}
46535+
46536+	phy_write(phy_dev, MII_EXPMA, FEPHY_TRIM_CACHE);
46537+	val = (u32)phy_read(phy_dev, MII_EXPMD);
46538+	temp = regval_to_temp(val);
46539+	if ((temp > HIGH_TEMP) && (highflag == 0)) {
46540+		highflag = 1;
46541+		if ((val & 0x1f) > 1)
46542+			val = (val & 0xe0) | ((val & 0x1f) - 1);
46543+		else
46544+			return;
46545+		hisi_femac_trim_phy(phy_dev, val);
46546+	}
46547+	if ((temp < NORMAL_TEMP1) && (highflag == 1)) {
46548+		highflag = 0;
46549+		if ((val & 0x1f) < 0x1f)
46550+			val = (val & 0xe0) | ((val & 0x1f) + 1);
46551+		else
46552+			return;
46553+		hisi_femac_trim_phy(phy_dev, val);
46554+	}
46555+	if ((temp > NORMAL_TEMP2) && (lowflag == 0)) {
46556+		lowflag = 1;
46557+		if ((val & 0x1f) > 1)
46558+			val = (val & 0xe0) | ((val & 0x1f) - 1);
46559+		else
46560+			return;
46561+		hisi_femac_trim_phy(phy_dev, val);
46562+	}
46563+	if ((temp < LOW_TEMP) && (lowflag == 1)) {
46564+		lowflag = 0;
46565+		if ((val & 0x1f) < 0x1f)
46566+			val = (val & 0xe0) | ((val & 0x1f) + 1);
46567+		else
46568+			return;
46569+		hisi_femac_trim_phy(phy_dev, val);
46570+	}
46571+}
46572+
46573+static void hisi_femac_watchdog(struct work_struct *work)
46574+{
46575+	struct delayed_work *dwork = to_delayed_work(work);
46576+	struct hisi_femac_priv *priv = container_of(dwork, struct hisi_femac_priv,
46577+				       watchdog_queue);
46578+	void __iomem *sys_reg_addr;
46579+	struct net_device *dev = NULL;
46580+	u32 val;
46581+
46582+	dev = priv->ndev;
46583+	if (dev == NULL) {
46584+		pr_err("get net device failed \n");
46585+		return;
46586+	}
46587+
46588+	sys_reg_addr = (void __iomem *)ioremap_nocache(SYS_REG_ADDR, 0x100);
46589+	if (!sys_reg_addr) {
46590+		pr_err("iomap failed \n");
46591+		return;
46592+	}
46593+	val = readl(sys_reg_addr + MISC_CTRL45);
46594+	if ((val >> 30) != 0x3) { /* bit[30 31] */
46595+		val |= TSENSOR_EN;
46596+		writel(val, sys_reg_addr + MISC_CTRL45);
46597+		mdelay(10); /* wait 10ms */
46598+	}
46599+	val = readl(sys_reg_addr + MISC_CTRL47) & TSENSOR_RESULT0;
46600+	/* high 16bit */
46601+	val += (readl(sys_reg_addr + MISC_CTRL47) & TSENSOR_RESULT1) >> 16;
46602+	val += readl(sys_reg_addr + MISC_CTRL48) & TSENSOR_RESULT2;
46603+	/* high 16bit */
46604+	val += (readl(sys_reg_addr + MISC_CTRL48) & TSENSOR_RESULT3) >> 16;
46605+	val = val / 4; /* average value of the 4 values */
46606+	if (val < LOW_TEM_VALUE || val > HIGH_TEM_VALUE) {
46607+		goto out;
46608+	}
46609+	hisi_femac_trim(dev);
46610+out:
46611+	iounmap(sys_reg_addr);
46612+	schedule_delayed_work(&priv->watchdog_queue, FEPHY_OPT_TIMER);
46613+}
46614+#endif
46615+
46616+static void hisi_femac_tx_sg_dma_unmap(const struct hisi_femac_priv *priv,
46617+				       const struct sk_buff *skb, unsigned int pos)
46618+{
46619+	struct tx_desc *desc_cur;
46620+	dma_addr_t addr;
46621+	u32 len;
46622+	int i;
46623+
46624+	desc_cur = priv->tx_ring.desc + pos;
46625+
46626+	addr = desc_cur->linear_addr;
46627+	len = desc_cur->linear_len;
46628+	dma_unmap_single(priv->dev, addr, len, DMA_TO_DEVICE);
46629+
46630+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
46631+		addr = desc_cur->frags[i].addr;
46632+		len = desc_cur->frags[i].size;
46633+		dma_unmap_page(priv->dev, addr, len, DMA_TO_DEVICE);
46634+	}
46635+}
46636+
46637+static void hisi_femac_tx_dma_unmap(const struct hisi_femac_priv *priv,
46638+				    const struct sk_buff *skb, unsigned int pos)
46639+{
46640+	if (!(skb_is_gso(skb) || skb_shinfo(skb)->nr_frags)) {
46641+		dma_addr_t dma_addr;
46642+
46643+		dma_addr = priv->txq.dma_phys[pos];
46644+		dma_unmap_single(priv->dev, dma_addr, skb->len, DMA_TO_DEVICE);
46645+	} else {
46646+		hisi_femac_tx_sg_dma_unmap(priv, skb, pos);
46647+	}
46648+}
46649+
46650+static void hisi_femac_xmit_reclaim(struct net_device *dev)
46651+{
46652+	struct sk_buff *skb = NULL;
46653+	struct hisi_femac_priv *priv = netdev_priv(dev);
46654+	struct hisi_femac_queue *txq = &priv->txq;
46655+	unsigned int bytes_compl = 0;
46656+	unsigned int pkts_compl = 0;
46657+	u32 val;
46658+
46659+	netif_tx_lock(dev);
46660+
46661+	val = readl(priv->port_base + ADDRQ_STAT) & TX_CNT_INUSE_MASK;
46662+	while (val < priv->tx_fifo_used_cnt) {
46663+		skb = txq->skb[txq->tail];
46664+		if (unlikely(skb == NULL)) {
46665+			netdev_err(dev, "xmitq_cnt_inuse=%d, tx_fifo_used=%d\n",
46666+				   val, priv->tx_fifo_used_cnt);
46667+			break;
46668+		}
46669+		hisi_femac_tx_dma_unmap(priv, skb, txq->tail);
46670+		pkts_compl++;
46671+		bytes_compl += skb->len;
46672+		dev_kfree_skb_any(skb);
46673+
46674+		priv->tx_fifo_used_cnt--;
46675+
46676+		val = readl(priv->port_base + ADDRQ_STAT) & TX_CNT_INUSE_MASK;
46677+		txq->skb[txq->tail] = NULL;
46678+		txq->tail = (txq->tail + 1) % txq->num;
46679+	}
46680+
46681+	netdev_completed_queue(dev, pkts_compl, bytes_compl);
46682+
46683+	if (unlikely(netif_queue_stopped(dev)) && pkts_compl)
46684+		netif_wake_queue(dev);
46685+
46686+	netif_tx_unlock(dev);
46687+}
46688+
46689+static void hisi_femac_get_tso_err_info(const struct hisi_femac_priv *priv)
46690+{
46691+	unsigned int reg_addr, reg_tx_info, reg_tx_err;
46692+	unsigned int sg_index;
46693+	struct tx_desc *sg_desc = NULL;
46694+	int *sg_word = NULL;
46695+	int i;
46696+
46697+	reg_addr = readl(priv->port_base + TSO_DBG_ADDR);
46698+	reg_tx_info = readl(priv->port_base + TSO_DBG_TX_INFO);
46699+	reg_tx_err = readl(priv->port_base + TSO_DBG_TX_ERR);
46700+
46701+	WARN(1, "tx err=0x%x, tx_info=0x%x, addr=0x%x\n",
46702+	     reg_tx_err, reg_tx_info, reg_addr);
46703+
46704+	sg_index = (reg_addr - priv->tx_ring.dma_phys) / sizeof(struct tx_desc);
46705+	sg_desc = priv->tx_ring.desc + sg_index;
46706+	sg_word = (int *)sg_desc;
46707+	for (i = 0; i < sizeof(struct tx_desc) / sizeof(int); i++)
46708+		pr_err("%s,%d: sg_desc word[%d]=0x%x\n",
46709+		       __func__, __LINE__, i, sg_word[i]);
46710+
46711+	/* restart MAC to transmit next packet */
46712+	hisi_femac_irq_disable(priv, INT_TX_ERR);
46713+	/*
46714+	 * If we need allow netcard transmit packet again.
46715+	 * we should readl TSO_DBG_STATE and enable irq.
46716+	 */
46717+}
46718+
46719+static netdev_tx_t hisi_femac_net_xmit(struct sk_buff *skb,
46720+				       struct net_device *dev);
46721+
46722+static netdev_tx_t hisi_femac_sw_gso(struct sk_buff *skb,
46723+				     struct net_device *dev)
46724+{
46725+	struct sk_buff *segs = NULL;
46726+	struct sk_buff *curr_skb = NULL;
46727+	netdev_features_t features = dev->features;
46728+
46729+	features &= ~(NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
46730+		      NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO);
46731+	segs = skb_gso_segment(skb, features);
46732+	if (IS_ERR_OR_NULL(segs)) {
46733+		goto drop;
46734+	}
46735+
46736+	do {
46737+		curr_skb = segs;
46738+		segs = segs->next;
46739+		curr_skb->next = NULL;
46740+		if (hisi_femac_net_xmit(curr_skb, dev)) {
46741+			dev_kfree_skb(curr_skb);
46742+			while (segs != NULL) {
46743+				curr_skb = segs;
46744+				segs = segs->next;
46745+				curr_skb->next = NULL;
46746+				dev_kfree_skb_any(curr_skb);
46747+			}
46748+			goto drop;
46749+		}
46750+	} while (segs != NULL);
46751+
46752+	dev_kfree_skb_any(skb);
46753+	return NETDEV_TX_OK;
46754+
46755+drop:
46756+	dev_kfree_skb_any(skb);
46757+	dev->stats.tx_dropped++;
46758+	return NETDEV_TX_OK;
46759+}
46760+
46761+static int hisi_femac_fill_sg_desc(const struct hisi_femac_priv *priv,
46762+				   const struct sk_buff *skb, unsigned int pos)
46763+{
46764+	struct tx_desc *desc_cur;
46765+	dma_addr_t addr;
46766+	int ret;
46767+	int i;
46768+
46769+	desc_cur = priv->tx_ring.desc + pos;
46770+
46771+	desc_cur->ipv6_id = ntohl(skb_shinfo(skb)->ip6_frag_id);
46772+
46773+	desc_cur->total_len = skb->len;
46774+	addr = dma_map_single(priv->dev, skb->data, skb_headlen(skb),
46775+			      DMA_TO_DEVICE);
46776+	if (unlikely(dma_mapping_error(priv->dev, addr))) {
46777+		return -EINVAL;
46778+	}
46779+	desc_cur->linear_addr = addr;
46780+	desc_cur->linear_len = skb_headlen(skb);
46781+
46782+	for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
46783+		skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
46784+		int len = frag->bv_len;
46785+
46786+		addr = skb_frag_dma_map(priv->dev, frag, 0, len, DMA_TO_DEVICE);
46787+		ret = dma_mapping_error(priv->dev, addr);
46788+		if (unlikely(ret)) {
46789+			return -EINVAL;
46790+		}
46791+		desc_cur->frags[i].addr = addr;
46792+		desc_cur->frags[i].size = len;
46793+	}
46794+
46795+	return 0;
46796+}
46797+
46798+static void hisi_femac_adjust_link(struct net_device *dev)
46799+{
46800+	struct hisi_femac_priv *priv = netdev_priv(dev);
46801+	struct phy_device *phy = dev->phydev;
46802+	u32 status = 0;
46803+
46804+	if (phy->link)
46805+		status |= MAC_PORTSET_LINKED;
46806+	if (phy->duplex == DUPLEX_FULL)
46807+		status |= MAC_PORTSET_DUPLEX_FULL;
46808+	if (phy->speed == SPEED_100)
46809+		status |= MAC_PORTSET_SPEED_100M;
46810+
46811+	if ((status != priv->link_status) &&
46812+			((status | priv->link_status) & MAC_PORTSET_LINKED)) {
46813+		writel(status, priv->port_base + MAC_PORTSET);
46814+		priv->link_status = status;
46815+		phy_print_status(phy);
46816+
46817+		priv->tx_pause_en = phy->pause;
46818+		hisi_femac_set_flow_ctrl(priv);
46819+	}
46820+}
46821+
46822+static void hisi_femac_rx_refill(struct hisi_femac_priv *priv)
46823+{
46824+	struct hisi_femac_queue *rxq = &priv->rxq;
46825+	struct sk_buff *skb = NULL;
46826+	u32 pos;
46827+	u32 len;
46828+	dma_addr_t addr;
46829+	u32 alloc_rxbuf_align;
46830+	int reserve_room;
46831+
46832+	pos = rxq->head;
46833+	while (readl(priv->port_base + ADDRQ_STAT) & BIT_RX_READY) {
46834+		if (!CIRC_SPACE(pos, rxq->tail, rxq->num)) {
46835+			break;
46836+		}
46837+		if (unlikely(rxq->skb[pos])) {
46838+			netdev_err(priv->ndev, "err skb[%d]=%p\n",
46839+				   pos, rxq->skb[pos]);
46840+			break;
46841+		}
46842+		len = MAX_FRAME_SIZE + RXBUF_ADDR_ALIGN_SIZE;
46843+		skb = netdev_alloc_skb_ip_align(priv->ndev, len);
46844+		if (unlikely(skb == NULL)) {
46845+			break;
46846+		}
46847+
46848+		alloc_rxbuf_align = ((uintptr_t)skb->data - NET_IP_ALIGN) &
46849+				    (RXBUF_ADDR_ALIGN_SIZE - 1);
46850+		if (alloc_rxbuf_align) {
46851+			reserve_room = RXBUF_ADDR_ALIGN_SIZE -
46852+				       alloc_rxbuf_align;
46853+			len -= reserve_room;
46854+			skb_reserve(skb, reserve_room);
46855+		}
46856+
46857+		addr = dma_map_single(priv->dev, skb->data, len,
46858+				      DMA_FROM_DEVICE);
46859+		if (dma_mapping_error(priv->dev, addr)) {
46860+			dev_kfree_skb_any(skb);
46861+			break;
46862+		}
46863+		rxq->dma_phys[pos] = addr;
46864+		rxq->skb[pos] = skb;
46865+		writel(addr, priv->port_base + IQ_ADDR);
46866+		pos = (pos + 1) % rxq->num;
46867+	}
46868+	rxq->head = pos;
46869+}
46870+
46871+#ifdef FEMAC_RX_REFILL_IN_IRQ
46872+static void hisi_femac_recv_queue(struct net_device *dev, struct sk_buff *skb,
46873+				  u32 rx_pkt_info)
46874+{
46875+	struct hisi_femac_priv *priv = netdev_priv(dev);
46876+	int hdr_csum_done, hdr_csum_err;
46877+	int payload_csum_done, payload_csum_err;
46878+
46879+	skb->ip_summed = CHECKSUM_NONE;
46880+	if (dev->features & NETIF_F_RXCSUM) {
46881+		hdr_csum_done =
46882+			(rx_pkt_info >> BITS_HEADER_DONE_OFFSET) &
46883+			BITS_HEADER_DONE_MASK;
46884+		payload_csum_done =
46885+			(rx_pkt_info >> BITS_PAYLOAD_DONE_OFFSET) &
46886+			BITS_PAYLOAD_DONE_MASK;
46887+		hdr_csum_err =
46888+			(rx_pkt_info >> BITS_HEADER_ERR_OFFSET) &
46889+			BITS_HEADER_ERR_MASK;
46890+		payload_csum_err =
46891+			(rx_pkt_info >> BITS_PAYLOAD_ERR_OFFSET) &
46892+			BITS_PAYLOAD_ERR_MASK;
46893+
46894+		if (hdr_csum_done && payload_csum_done) {
46895+			if (unlikely(hdr_csum_err)) {
46896+				dev->stats.rx_errors++;
46897+				dev->stats.rx_crc_errors++;
46898+				dev_kfree_skb_any(skb);
46899+				return;
46900+			} else if (!payload_csum_err) {
46901+				skb->ip_summed = CHECKSUM_UNNECESSARY;
46902+			}
46903+		}
46904+	}
46905+	skb_queue_tail(&priv->rx_head, skb);
46906+}
46907+
46908+static void hisi_femac_pre_receive(struct net_device *dev)
46909+{
46910+	struct hisi_femac_priv *priv = netdev_priv(dev);
46911+	struct hisi_femac_queue *rxq = &priv->rxq;
46912+	struct sk_buff *skb = NULL;
46913+	u32 rx_pkt_info, pos, len;
46914+	unsigned long rxflags;
46915+
46916+	spin_lock_irqsave(&priv->rxlock, rxflags);
46917+	pos = rxq->tail;
46918+	while (readl(priv->glb_base + GLB_IRQ_RAW) & IRQ_INT_RX_RDY) {
46919+		rx_pkt_info = readl(priv->port_base + IQFRM_DES);
46920+		len = rx_pkt_info & RX_FRAME_LEN_MASK;
46921+		len -= ETH_FCS_LEN;
46922+
46923+		/* tell hardware we will deal with this packet */
46924+		writel(IRQ_INT_RX_RDY, priv->glb_base + GLB_IRQ_RAW);
46925+
46926+		skb = rxq->skb[pos];
46927+		if (unlikely(skb == NULL)) {
46928+			netdev_err(dev, "rx skb NULL. pos=%d\n", pos);
46929+			break;
46930+		}
46931+		rxq->skb[pos] = NULL;
46932+
46933+		dma_unmap_single(priv->dev, rxq->dma_phys[pos], MAX_FRAME_SIZE,
46934+				 DMA_FROM_DEVICE);
46935+		skb_put(skb, len);
46936+		if (unlikely(skb->len > MAX_FRAME_SIZE)) {
46937+			netdev_err(dev, "rcv len err, len = %d\n", skb->len);
46938+			dev->stats.rx_errors++;
46939+			dev->stats.rx_length_errors++;
46940+			dev_kfree_skb_any(skb);
46941+			goto next;
46942+		}
46943+
46944+		hisi_femac_recv_queue(dev, skb, rx_pkt_info);
46945+next:
46946+		pos = (pos + 1) % rxq->num;
46947+	}
46948+	rxq->tail = pos;
46949+
46950+	hisi_femac_rx_refill(priv);
46951+	spin_unlock_irqrestore(&priv->rxlock, rxflags);
46952+}
46953+
46954+static u32 hisi_femac_rx(struct net_device *dev, int limit)
46955+{
46956+	struct hisi_femac_priv *priv = netdev_priv(dev);
46957+	struct sk_buff *skb = skb_dequeue(&priv->rx_head);
46958+	u32 rx_pkts_num = 0;
46959+
46960+	while (skb != NULL) {
46961+		skb->protocol = eth_type_trans(skb, dev);
46962+		napi_gro_receive(&priv->napi, skb);
46963+		dev->stats.rx_packets++;
46964+		dev->stats.rx_bytes += skb->len;
46965+		rx_pkts_num++;
46966+
46967+		if (rx_pkts_num >= limit) {
46968+			break;
46969+		}
46970+		skb = skb_dequeue(&priv->rx_head);
46971+	}
46972+
46973+	return rx_pkts_num;
46974+}
46975+#else
46976+static int hisi_femac_recv_queue(struct net_device *dev, struct sk_buff *skb,
46977+				 u32 rx_pkt_info)
46978+{
46979+	struct hisi_femac_priv *priv = netdev_priv(dev);
46980+	int hdr_csum_done, hdr_csum_err;
46981+	int payload_csum_done, payload_csum_err;
46982+
46983+	skb->ip_summed = CHECKSUM_NONE;
46984+	if (dev->features & NETIF_F_RXCSUM) {
46985+		hdr_csum_done =
46986+			(rx_pkt_info >> BITS_HEADER_DONE_OFFSET) &
46987+			BITS_HEADER_DONE_MASK;
46988+		payload_csum_done =
46989+			(rx_pkt_info >> BITS_PAYLOAD_DONE_OFFSET) &
46990+			BITS_PAYLOAD_DONE_MASK;
46991+		hdr_csum_err =
46992+			(rx_pkt_info >> BITS_HEADER_ERR_OFFSET) &
46993+			BITS_HEADER_ERR_MASK;
46994+		payload_csum_err =
46995+			(rx_pkt_info >> BITS_PAYLOAD_ERR_OFFSET) &
46996+			BITS_PAYLOAD_ERR_MASK;
46997+
46998+		if (hdr_csum_done && payload_csum_done) {
46999+			if (unlikely(hdr_csum_err)) {
47000+				dev->stats.rx_errors++;
47001+				dev->stats.rx_crc_errors++;
47002+				dev_kfree_skb_any(skb);
47003+				return -1;
47004+			} else if (!payload_csum_err) {
47005+				skb->ip_summed = CHECKSUM_UNNECESSARY;
47006+			}
47007+		}
47008+	}
47009+	return 0;
47010+}
47011+
47012+static u32 hisi_femac_rx(struct net_device *dev, int limit)
47013+{
47014+	struct hisi_femac_priv *priv = netdev_priv(dev);
47015+	struct hisi_femac_queue *rxq = &priv->rxq;
47016+	struct sk_buff *skb;
47017+	u32 rx_pkt_info, pos, len;
47018+	u32 rx_pkts_num = 0;
47019+
47020+	pos = rxq->tail;
47021+	while (readl(priv->glb_base + GLB_IRQ_RAW) & IRQ_INT_RX_RDY) {
47022+		rx_pkt_info = readl(priv->port_base + IQFRM_DES);
47023+		len = rx_pkt_info & RX_FRAME_LEN_MASK;
47024+		len -= ETH_FCS_LEN;
47025+
47026+		/* tell hardware we will deal with this packet */
47027+		writel(IRQ_INT_RX_RDY, priv->glb_base + GLB_IRQ_RAW);
47028+
47029+		rx_pkts_num++;
47030+
47031+		skb = rxq->skb[pos];
47032+		if (unlikely(!skb)) {
47033+			netdev_err(dev, "rx skb NULL. pos=%d\n", pos);
47034+			break;
47035+		}
47036+		rxq->skb[pos] = NULL;
47037+
47038+		dma_unmap_single(priv->dev, rxq->dma_phys[pos], MAX_FRAME_SIZE,
47039+				 DMA_FROM_DEVICE);
47040+		skb_put(skb, len);
47041+		if (unlikely(skb->len > MAX_FRAME_SIZE)) {
47042+			netdev_err(dev, "rcv len err, len = %d\n", skb->len);
47043+			dev->stats.rx_errors++;
47044+			dev->stats.rx_length_errors++;
47045+			dev_kfree_skb_any(skb);
47046+			goto next;
47047+		}
47048+
47049+		if (hisi_femac_recv_queue(dev, skb, rx_pkt_info) < 0)
47050+			goto next;
47051+
47052+		skb->protocol = eth_type_trans(skb, dev);
47053+		napi_gro_receive(&priv->napi, skb);
47054+		dev->stats.rx_packets++;
47055+		dev->stats.rx_bytes += len;
47056+next:
47057+		pos = (pos + 1) % rxq->num;
47058+		if (rx_pkts_num >= limit) {
47059+			break;
47060+		}
47061+	}
47062+	rxq->tail = pos;
47063+
47064+	hisi_femac_rx_refill(priv);
47065+
47066+	return rx_pkts_num;
47067+}
47068+#endif
47069+
47070+static int hisi_femac_poll(struct napi_struct *napi, int budget)
47071+{
47072+	struct hisi_femac_priv *priv = container_of(napi,
47073+				       struct hisi_femac_priv, napi);
47074+	struct net_device *dev = priv->ndev;
47075+	int work_done = 0;
47076+	int task = budget;
47077+	u32 ints, num;
47078+
47079+	do {
47080+#ifdef FEMAC_RX_REFILL_IN_IRQ
47081+		hisi_femac_pre_receive(dev);
47082+#endif
47083+		hisi_femac_xmit_reclaim(dev);
47084+		num = hisi_femac_rx(dev, task);
47085+		work_done += num;
47086+		task -= num;
47087+		if (work_done >= budget) {
47088+			break;
47089+		}
47090+
47091+		ints = readl(priv->glb_base + GLB_IRQ_RAW);
47092+		writel(ints & DEF_INT_MASK,
47093+		       priv->glb_base + GLB_IRQ_RAW);
47094+	} while (ints & DEF_INT_MASK);
47095+
47096+	if (work_done < budget) {
47097+		napi_complete(napi);
47098+		hisi_femac_irq_enable(priv, DEF_INT_MASK &
47099+				      (~IRQ_INT_TX_PER_PACKET));
47100+	}
47101+
47102+	return work_done;
47103+}
47104+
47105+static irqreturn_t hisi_femac_interrupt(int irq, void *dev_id)
47106+{
47107+	u32 ints;
47108+	struct net_device *dev = (struct net_device *)dev_id;
47109+	struct hisi_femac_priv *priv = netdev_priv(dev);
47110+
47111+	ints = readl(priv->glb_base + GLB_IRQ_RAW);
47112+	if (likely(ints & DEF_INT_MASK)) {
47113+#ifdef FEMAC_RX_REFILL_IN_IRQ
47114+		hisi_femac_pre_receive(dev);
47115+#endif
47116+		writel(ints & DEF_INT_MASK,
47117+		       priv->glb_base + GLB_IRQ_RAW);
47118+		hisi_femac_irq_disable(priv, DEF_INT_MASK);
47119+		napi_schedule(&priv->napi);
47120+	}
47121+
47122+	if (has_tso_cap(priv->hw_cap) && unlikely(ints & INT_TX_ERR))
47123+		hisi_femac_get_tso_err_info(priv);
47124+
47125+	return IRQ_HANDLED;
47126+}
47127+
47128+static int hisi_femac_init_tx_descriptor_ring(struct hisi_femac_priv *priv)
47129+{
47130+	priv->tx_ring.desc = (struct tx_desc *)dma_alloc_coherent(priv->dev,
47131+			     TXQ_NUM * sizeof(struct tx_desc), &priv->tx_ring.dma_phys, GFP_KERNEL);
47132+	if (!priv->tx_ring.desc) {
47133+		return -ENOMEM;
47134+	}
47135+
47136+	return 0;
47137+}
47138+
47139+static void hisi_femac_destroy_tx_descriptor_ring(struct hisi_femac_priv *priv)
47140+{
47141+	if (priv->tx_ring.desc)
47142+		dma_free_coherent(priv->dev, TXQ_NUM * sizeof(struct tx_desc),
47143+				  priv->tx_ring.desc, priv->tx_ring.dma_phys);
47144+	priv->tx_ring.desc = NULL;
47145+}
47146+
47147+static int hisi_femac_init_queue(struct device *dev,
47148+				 struct hisi_femac_queue *queue, unsigned int num)
47149+{
47150+	queue->skb = devm_kcalloc(dev, num, sizeof(struct sk_buff *), GFP_KERNEL);
47151+	if (queue->skb == NULL) {
47152+		return -ENOMEM;
47153+	}
47154+
47155+	queue->dma_phys = devm_kcalloc(dev, num, sizeof(dma_addr_t), GFP_KERNEL);
47156+	if (queue->dma_phys == NULL) {
47157+		return -ENOMEM;
47158+	}
47159+
47160+	queue->num = num;
47161+	queue->head = 0;
47162+	queue->tail = 0;
47163+
47164+	return 0;
47165+}
47166+
47167+static int hisi_femac_init_tx_and_rx_queues(struct hisi_femac_priv *priv)
47168+{
47169+	int ret;
47170+
47171+	ret = hisi_femac_init_queue(priv->dev, &priv->txq, TXQ_NUM);
47172+	if (ret) {
47173+		return ret;
47174+	}
47175+
47176+	ret = hisi_femac_init_queue(priv->dev, &priv->rxq, RXQ_NUM);
47177+	if (ret) {
47178+		return ret;
47179+	}
47180+
47181+	priv->tx_fifo_used_cnt = 0;
47182+
47183+	return 0;
47184+}
47185+
47186+static void hisi_femac_free_skb_rings(struct hisi_femac_priv *priv)
47187+{
47188+	struct hisi_femac_queue *txq = &priv->txq;
47189+	struct hisi_femac_queue *rxq = &priv->rxq;
47190+	struct sk_buff *skb = NULL;
47191+	dma_addr_t dma_addr;
47192+	u32 pos;
47193+
47194+	pos = rxq->tail;
47195+	while (pos != rxq->head) {
47196+		skb = rxq->skb[pos];
47197+		if (unlikely(skb == NULL)) {
47198+			netdev_err(priv->ndev, "NULL rx skb. pos=%d, head=%d\n",
47199+				   pos, rxq->head);
47200+			pos = (pos + 1) % rxq->num;
47201+			continue;
47202+		}
47203+
47204+		dma_addr = rxq->dma_phys[pos];
47205+		dma_unmap_single(priv->dev, dma_addr, MAX_FRAME_SIZE, DMA_FROM_DEVICE);
47206+
47207+		dev_kfree_skb_any(skb);
47208+		rxq->skb[pos] = NULL;
47209+		pos = (pos + 1) % rxq->num;
47210+	}
47211+	rxq->tail = pos;
47212+
47213+	pos = txq->tail;
47214+	while (pos != txq->head) {
47215+		skb = txq->skb[pos];
47216+		if (unlikely(skb == NULL)) {
47217+			netdev_err(priv->ndev, "NULL tx skb. pos=%d, head=%d\n",
47218+				   pos, txq->head);
47219+			pos = (pos + 1) % txq->num;
47220+			continue;
47221+		}
47222+		hisi_femac_tx_dma_unmap(priv, skb, pos);
47223+		dev_kfree_skb_any(skb);
47224+		txq->skb[pos] = NULL;
47225+		pos = (pos + 1) % txq->num;
47226+	}
47227+	txq->tail = pos;
47228+	priv->tx_fifo_used_cnt = 0;
47229+}
47230+
47231+static int hisi_femac_set_hw_mac_addr(const struct hisi_femac_priv *priv,
47232+				      const unsigned char *mac)
47233+{
47234+	u32 reg;
47235+
47236+	reg = mac[1] | (mac[0] << 8);  /* mac0 is high 8 bits */
47237+	writel(reg, priv->glb_base + GLB_HOSTMAC_H16);
47238+	/* addr2 [24 31] addr3 [16 23] addr4 [8 15]  addr5 [0 7] */
47239+	reg = mac[5] | (mac[4] << 8) | (mac[3] << 16) | (mac[2] << 24);
47240+	writel(reg, priv->glb_base + GLB_HOSTMAC_L32);
47241+
47242+	return 0;
47243+}
47244+
47245+static int hisi_femac_port_reset(const struct hisi_femac_priv *priv)
47246+{
47247+	u32 val;
47248+
47249+	val = readl(priv->glb_base + GLB_SOFT_RESET);
47250+	val |= SOFT_RESET_ALL;
47251+	writel(val, priv->glb_base + GLB_SOFT_RESET);
47252+
47253+	usleep_range(500, 800); /* wait 500-800us */
47254+
47255+	val &= ~SOFT_RESET_ALL;
47256+	writel(val, priv->glb_base + GLB_SOFT_RESET);
47257+
47258+	return 0;
47259+}
47260+
47261+static int hisi_femac_net_open(struct net_device *dev)
47262+{
47263+	struct hisi_femac_priv *priv = netdev_priv(dev);
47264+
47265+	hisi_femac_set_hw_mac_addr(priv, dev->dev_addr);
47266+	/*
47267+	 * clear interrupts will drop the first packet MAC have received,
47268+	 * so do it before refill the rx free skbs.
47269+	 */
47270+	writel(IRQ_ENA_PORT0_MASK, priv->glb_base + GLB_IRQ_RAW);
47271+	hisi_femac_rx_refill(priv);
47272+
47273+	netif_carrier_off(dev);
47274+	netdev_reset_queue(dev);
47275+	netif_start_queue(dev);
47276+	napi_enable(&priv->napi);
47277+
47278+	priv->link_status = 0;
47279+	if (dev->phydev)
47280+		phy_start(dev->phydev);
47281+
47282+	hisi_femac_irq_enable(priv, IRQ_ENA_ALL | IRQ_ENA_PORT0 | DEF_INT_MASK);
47283+	if (has_tso_cap(priv->hw_cap))
47284+		hisi_femac_irq_enable(priv, INT_TX_ERR);
47285+
47286+	return 0;
47287+}
47288+
47289+static void hisi_femac_port_init(struct hisi_femac_priv *priv);
47290+
47291+static int hisi_femac_net_close(struct net_device *dev)
47292+{
47293+	struct hisi_femac_priv *priv = netdev_priv(dev);
47294+
47295+	hisi_femac_irq_disable(priv, IRQ_ENA_PORT0);
47296+
47297+	if (dev->phydev)
47298+		phy_stop(dev->phydev);
47299+
47300+	netif_stop_queue(dev);
47301+	napi_disable(&priv->napi);
47302+
47303+	/*
47304+	 * reset MAC port first before free skb rings
47305+	 * to prevent potential risk of use-after-free.
47306+	 */
47307+	hisi_femac_port_reset(priv);
47308+	hisi_femac_port_init(priv);
47309+
47310+	priv->tx_pause_en = false;
47311+	hisi_femac_set_flow_ctrl(priv);
47312+	hisi_femac_free_skb_rings(priv);
47313+#ifdef FEMAC_RX_REFILL_IN_IRQ
47314+	skb_queue_purge(&priv->rx_head);
47315+#endif
47316+
47317+	return 0;
47318+}
47319+
47320+static bool hisi_femac_net_isready(struct net_device *dev)
47321+{
47322+	struct hisi_femac_priv *priv = netdev_priv(dev);
47323+	struct hisi_femac_queue *txq = &priv->txq;
47324+	u32 val;
47325+
47326+	val = readl(priv->port_base + ADDRQ_STAT);
47327+	val &= BIT_TX_READY;
47328+	if (!val) {
47329+		hisi_femac_irq_enable(priv, IRQ_INT_TX_PER_PACKET);
47330+		dev->stats.tx_dropped++;
47331+		dev->stats.tx_fifo_errors++;
47332+		netif_stop_queue(dev);
47333+		return false;
47334+	}
47335+
47336+	if (unlikely(!CIRC_SPACE(txq->head, txq->tail,
47337+				 txq->num))) {
47338+		hisi_femac_irq_enable(priv, IRQ_INT_TX_PER_PACKET);
47339+		dev->stats.tx_dropped++;
47340+		dev->stats.tx_fifo_errors++;
47341+		netif_stop_queue(dev);
47342+		return false;
47343+	}
47344+
47345+	return true;
47346+}
47347+
47348+static netdev_tx_t hisi_femac_net_xmit(struct sk_buff *skb,
47349+				       struct net_device *dev)
47350+{
47351+	struct hisi_femac_priv *priv = netdev_priv(dev);
47352+	struct hisi_femac_queue *txq = &priv->txq;
47353+	dma_addr_t addr;
47354+	int ret;
47355+	u32 pkt_info;
47356+
47357+	if (!hisi_femac_net_isready(dev))
47358+		return NETDEV_TX_BUSY;
47359+
47360+	ret = hisi_femac_check_hw_capability(skb);
47361+	if (unlikely(ret)) {
47362+		if (ret == -ENOTSUPP)
47363+			return hisi_femac_sw_gso(skb, dev);
47364+
47365+		dev_kfree_skb_any(skb);
47366+		dev->stats.tx_dropped++;
47367+		return NETDEV_TX_OK;
47368+	}
47369+
47370+	pkt_info = hisi_femac_get_pkt_info(skb);
47371+
47372+	if (!(skb_is_gso(skb) || skb_shinfo(skb)->nr_frags)) {
47373+		addr = dma_map_single(priv->dev, skb->data,
47374+				      skb->len, DMA_TO_DEVICE);
47375+		if (unlikely(dma_mapping_error(priv->dev, addr))) {
47376+			dev_kfree_skb_any(skb);
47377+			dev->stats.tx_dropped++;
47378+			return NETDEV_TX_OK;
47379+		}
47380+	} else {
47381+		ret = hisi_femac_fill_sg_desc(priv, skb, txq->head);
47382+		if (unlikely(ret)) {
47383+			dev_kfree_skb_any(skb);
47384+			dev->stats.tx_dropped++;
47385+			return NETDEV_TX_OK;
47386+		}
47387+
47388+		addr = priv->tx_ring.dma_phys +
47389+		       txq->head * sizeof(struct tx_desc);
47390+
47391+		/* Ensure desc info writen to memory before config hardware */
47392+		wmb();
47393+	}
47394+	txq->dma_phys[txq->head] = addr;
47395+
47396+	skb_tx_timestamp(skb);
47397+
47398+	txq->skb[txq->head] = skb;
47399+	txq->head = (txq->head + 1) % txq->num;
47400+
47401+	writel(addr, priv->port_base + EQ_ADDR);
47402+	writel(pkt_info, priv->port_base + EQFRM_LEN);
47403+
47404+	priv->tx_fifo_used_cnt++;
47405+
47406+	dev->stats.tx_packets++;
47407+	dev->stats.tx_bytes += skb->len;
47408+	netdev_sent_queue(dev, skb->len);
47409+
47410+	return NETDEV_TX_OK;
47411+}
47412+
47413+static int hisi_femac_set_mac_address(struct net_device *dev, void *p)
47414+{
47415+	struct hisi_femac_priv *priv = netdev_priv(dev);
47416+	struct sockaddr *skaddr = p;
47417+
47418+	if (!is_valid_ether_addr(skaddr->sa_data)) {
47419+		return -EADDRNOTAVAIL;
47420+	}
47421+
47422+	memcpy(dev->dev_addr, skaddr->sa_data, dev->addr_len);
47423+	dev->addr_assign_type &= ~NET_ADDR_RANDOM;
47424+
47425+	hisi_femac_set_hw_mac_addr(priv, dev->dev_addr);
47426+
47427+	return 0;
47428+}
47429+
47430+static void hisi_femac_enable_hw_addr_filter(const struct hisi_femac_priv *priv,
47431+		unsigned int reg_n, bool enable)
47432+{
47433+	u32 val;
47434+
47435+	val = readl(priv->glb_base + glb_mac_h16(reg_n));
47436+	if (enable) {
47437+		val |= BIT_MACFLT_ENA;
47438+	} else {
47439+		val &= ~BIT_MACFLT_ENA;
47440+	}
47441+	writel(val, priv->glb_base + glb_mac_h16(reg_n));
47442+}
47443+
47444+static void hisi_femac_set_hw_addr_filter(const struct hisi_femac_priv *priv,
47445+		const unsigned char *addr, unsigned int reg_n)
47446+{
47447+	unsigned int high, low;
47448+	u32 val;
47449+
47450+	high = glb_mac_h16(reg_n);
47451+	low = glb_mac_l32(reg_n);
47452+	/* addr2 [24 31] addr3 [16 23] addr4 [8 15]  addr5 [0 7] */
47453+	val = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];
47454+	writel(val, priv->glb_base + low);
47455+
47456+	val = readl(priv->glb_base + high);
47457+	val &= ~MACFLT_HI16_MASK;
47458+	val |= ((addr[0] << 8) | addr[1]); /* addr0 is high 8 bits */
47459+	val |= (BIT_MACFLT_ENA | BIT_MACFLT_FW2CPU);
47460+	writel(val, priv->glb_base + high);
47461+}
47462+
47463+static void hisi_femac_set_promisc_mode(const struct hisi_femac_priv *priv,
47464+					bool promisc_mode)
47465+{
47466+	u32 val;
47467+
47468+	val = readl(priv->glb_base + GLB_FWCTRL);
47469+	if (promisc_mode) {
47470+		val |= FWCTRL_FWALL2CPU;
47471+	} else {
47472+		val &= ~FWCTRL_FWALL2CPU;
47473+	}
47474+	writel(val, priv->glb_base + GLB_FWCTRL);
47475+}
47476+
47477+/* Handle multiple multicast addresses (perfect filtering) */
47478+static void hisi_femac_set_mc_addr_filter(const struct hisi_femac_priv *priv)
47479+{
47480+	struct net_device *dev = priv->ndev;
47481+	u32 val;
47482+
47483+	val = readl(priv->glb_base + GLB_MACTCTRL);
47484+	if ((netdev_mc_count(dev) > MAX_MULTICAST_ADDRESSES) ||
47485+			(dev->flags & IFF_ALLMULTI)) {
47486+		val |= MACTCTRL_MULTI2CPU;
47487+	} else {
47488+		int reg = MAX_UNICAST_ADDRESSES;
47489+		int i;
47490+		struct netdev_hw_addr *ha = NULL;
47491+
47492+		for (i = reg; i < MAX_MAC_FILTER_NUM; i++)
47493+			hisi_femac_enable_hw_addr_filter(priv, i, false);
47494+
47495+		netdev_for_each_mc_addr(ha, dev) {
47496+			hisi_femac_set_hw_addr_filter(priv, ha->addr, reg);
47497+			reg++;
47498+		}
47499+		val &= ~MACTCTRL_MULTI2CPU;
47500+	}
47501+	writel(val, priv->glb_base + GLB_MACTCTRL);
47502+}
47503+
47504+/* Handle multiple unicast addresses (perfect filtering) */
47505+static void hisi_femac_set_uc_addr_filter(const struct hisi_femac_priv *priv)
47506+{
47507+	struct net_device *dev = priv->ndev;
47508+	u32 val;
47509+
47510+	val = readl(priv->glb_base + GLB_MACTCTRL);
47511+	if (netdev_uc_count(dev) > MAX_UNICAST_ADDRESSES) {
47512+		val |= MACTCTRL_UNI2CPU;
47513+	} else {
47514+		int reg = 0;
47515+		int i;
47516+		struct netdev_hw_addr *ha = NULL;
47517+
47518+		for (i = reg; i < MAX_UNICAST_ADDRESSES; i++)
47519+			hisi_femac_enable_hw_addr_filter(priv, i, false);
47520+
47521+		netdev_for_each_uc_addr(ha, dev) {
47522+			hisi_femac_set_hw_addr_filter(priv, ha->addr, reg);
47523+			reg++;
47524+		}
47525+		val &= ~MACTCTRL_UNI2CPU;
47526+	}
47527+	writel(val, priv->glb_base + GLB_MACTCTRL);
47528+}
47529+
47530+static void hisi_femac_net_set_rx_mode(struct net_device *dev)
47531+{
47532+	struct hisi_femac_priv *priv = netdev_priv(dev);
47533+
47534+	if (dev->flags & IFF_PROMISC) {
47535+		hisi_femac_set_promisc_mode(priv, true);
47536+	} else {
47537+		hisi_femac_set_promisc_mode(priv, false);
47538+		hisi_femac_set_mc_addr_filter(priv);
47539+		hisi_femac_set_uc_addr_filter(priv);
47540+	}
47541+}
47542+
47543+static int hisi_femac_net_ioctl(struct net_device *dev,
47544+				struct ifreq *ifreq, int cmd)
47545+{
47546+	if (!netif_running(dev)) {
47547+		return -EINVAL;
47548+	}
47549+
47550+	if (!dev->phydev) {
47551+		return -EINVAL;
47552+	}
47553+
47554+	return phy_mii_ioctl(dev->phydev, ifreq, cmd);
47555+}
47556+
47557+static const struct ethtool_ops hisi_femac_ethtools_ops = {
47558+	.get_link = ethtool_op_get_link,
47559+	.get_link_ksettings = phy_ethtool_get_link_ksettings,
47560+	.set_link_ksettings = phy_ethtool_set_link_ksettings,
47561+	.get_pauseparam = hisi_femac_get_pauseparam,
47562+	.set_pauseparam = hisi_femac_set_pauseparam,
47563+	.get_ts_info = ethtool_op_get_ts_info,
47564+};
47565+
47566+static const struct net_device_ops hisi_femac_netdev_ops = {
47567+	.ndo_open = hisi_femac_net_open,
47568+	.ndo_stop = hisi_femac_net_close,
47569+	.ndo_start_xmit = hisi_femac_net_xmit,
47570+	.ndo_do_ioctl = hisi_femac_net_ioctl,
47571+	.ndo_set_mac_address = hisi_femac_set_mac_address,
47572+	.ndo_set_rx_mode = hisi_femac_net_set_rx_mode,
47573+	.ndo_set_features = hisi_femac_set_features,
47574+};
47575+
47576+static void hisi_femac_verify_flow_ctrl_args(struct hisi_femac_priv *priv)
47577+{
47578+	if (priv->tx_pause_active_thresh < FC_ACTIVE_MIN ||
47579+		priv->tx_pause_active_thresh > FC_ACTIVE_MAX)
47580+		priv->tx_pause_active_thresh = FC_ACTIVE_DEFAULT;
47581+
47582+	if (priv->tx_pause_deactive_thresh < FC_DEACTIVE_MIN ||
47583+		priv->tx_pause_deactive_thresh > FC_DEACTIVE_MAX)
47584+		priv->tx_pause_deactive_thresh = FC_DEACTIVE_DEFAULT;
47585+
47586+	if (priv->tx_pause_active_thresh >= priv->tx_pause_deactive_thresh) {
47587+		priv->tx_pause_active_thresh = FC_ACTIVE_DEFAULT;
47588+		priv->tx_pause_deactive_thresh = FC_DEACTIVE_DEFAULT;
47589+	}
47590+}
47591+
47592+static void hisi_femac_core_reset(const struct hisi_femac_priv *priv)
47593+{
47594+	reset_control_assert(priv->mac_rst);
47595+	reset_control_deassert(priv->mac_rst);
47596+}
47597+
47598+static void hisi_femac_phy_reset(const struct hisi_femac_priv *priv)
47599+{
47600+	/*
47601+	 * To make sure PHY hardware reset success,
47602+	 * we must keep PHY in deassert state first and
47603+	 * then complete the hardware reset operation
47604+	 */
47605+	reset_control_deassert(priv->phy_rst);
47606+	hisi_femac_sleep_us(priv->phy_reset_delays[PRE_DELAY]);
47607+
47608+	reset_control_assert(priv->phy_rst);
47609+	/*
47610+	 * delay some time to ensure reset ok,
47611+	 * this depends on PHY hardware feature
47612+	 */
47613+	hisi_femac_sleep_us(priv->phy_reset_delays[PULSE]);
47614+	reset_control_deassert(priv->phy_rst);
47615+	/* delay some time to ensure later MDIO access */
47616+	hisi_femac_sleep_us(priv->phy_reset_delays[POST_DELAY]);
47617+}
47618+
47619+static void hisi_femac_port_init(struct hisi_femac_priv *priv)
47620+{
47621+	u32 val;
47622+
47623+	/* MAC gets link status info and phy mode by software config */
47624+	val = MAC_PORTSEL_STAT_CPU;
47625+	if (priv->ndev->phydev->interface == PHY_INTERFACE_MODE_RMII)
47626+		val |= MAC_PORTSEL_RMII;
47627+	writel(val, priv->port_base + MAC_PORTSEL);
47628+
47629+	/* clear all interrupt status */
47630+	writel(IRQ_ENA_PORT0_MASK, priv->glb_base + GLB_IRQ_RAW);
47631+	hisi_femac_irq_disable(priv, IRQ_ENA_PORT0_MASK | IRQ_ENA_PORT0);
47632+
47633+	if (has_tso_cap(priv->hw_cap)) {
47634+		/* enable TSO debug for error handle */
47635+		val = readl(priv->port_base + TSO_DBG_EN);
47636+		val |= BITS_TSO_DBG_EN;
47637+		writel(val, priv->port_base + TSO_DBG_EN);
47638+	}
47639+
47640+	val = readl(priv->glb_base + GLB_FWCTRL);
47641+	val &= ~(FWCTRL_VLAN_ENABLE | FWCTRL_FWALL2CPU);
47642+	val |= FWCTRL_FW2CPU_ENA;
47643+	writel(val, priv->glb_base + GLB_FWCTRL);
47644+
47645+	val = readl(priv->glb_base + GLB_MACTCTRL);
47646+	val |= (MACTCTRL_BROAD2CPU | MACTCTRL_MACT_ENA);
47647+	writel(val, priv->glb_base + GLB_MACTCTRL);
47648+
47649+	val = readl(priv->port_base + MAC_SET);
47650+	val &= ~MAX_FRAME_SIZE_MASK;
47651+	val |= MAX_FRAME_SIZE;
47652+	writel(val, priv->port_base + MAC_SET);
47653+
47654+	val = RX_COALESCED_TIMER |
47655+	      (RX_COALESCED_FRAMES << RX_COALESCED_FRAME_OFFSET);
47656+	writel(val, priv->port_base + RX_COALESCE_SET);
47657+
47658+	val = (HW_RX_FIFO_DEPTH << RX_DEPTH_OFFSET) | HW_TX_FIFO_DEPTH;
47659+	writel(val, priv->port_base + QLEN_SET);
47660+
47661+	hisi_femac_set_flow_ctrl(priv);
47662+}
47663+
47664+static int hisi_femac_drv_res(struct platform_device *pdev,
47665+			      struct hisi_femac_priv *priv)
47666+{
47667+	struct resource *res = NULL;
47668+	struct device *dev = &pdev->dev;
47669+	struct device_node *node = dev->of_node;
47670+	int ret;
47671+
47672+	if (of_device_is_compatible(node, "hisilicon,hisi-femac-v2"))
47673+		priv->hw_cap |= HW_CAP_TSO | HW_CAP_RXCSUM;
47674+
47675+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
47676+	priv->port_base = devm_ioremap_resource(dev, res);
47677+	if (IS_ERR(priv->port_base)) {
47678+		ret = PTR_ERR(priv->port_base);
47679+		return ret;
47680+	}
47681+
47682+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
47683+	priv->glb_base = devm_ioremap_resource(dev, res);
47684+	if (IS_ERR(priv->glb_base)) {
47685+		ret = PTR_ERR(priv->glb_base);
47686+		return ret;
47687+	}
47688+
47689+	priv->clk = devm_clk_get(&pdev->dev, NULL);
47690+	if (IS_ERR(priv->clk)) {
47691+		dev_err(dev, "failed to get clk\n");
47692+		ret = -ENODEV;
47693+		return ret;
47694+	}
47695+
47696+	ret = clk_prepare_enable(priv->clk);
47697+	if (ret) {
47698+		dev_err(dev, "failed to enable clk %d\n", ret);
47699+		return ret;
47700+	}
47701+	return 0;
47702+}
47703+
47704+static int hisi_femac_drv_mac(struct platform_device *pdev,
47705+			      struct hisi_femac_priv *priv)
47706+{
47707+	struct device *dev = &pdev->dev;
47708+	struct device_node *node = dev->of_node;
47709+	const char *mac_addr = NULL;
47710+	struct net_device *ndev = priv->ndev;
47711+
47712+	priv->mac_rst = devm_reset_control_get(dev, "mac");
47713+	if (IS_ERR(priv->mac_rst))
47714+		return PTR_ERR(priv->mac_rst);
47715+
47716+	hisi_femac_core_reset(priv);
47717+
47718+	mac_addr = of_get_mac_address(node);
47719+	if (!IS_ERR(mac_addr))
47720+		ether_addr_copy(ndev->dev_addr, mac_addr);
47721+	if (!is_valid_ether_addr(ndev->dev_addr)) {
47722+		eth_hw_addr_random(ndev);
47723+		dev_warn(dev, "using random MAC address %pM\n",
47724+			 ndev->dev_addr);
47725+	}
47726+	return 0;
47727+}
47728+
47729+static struct phy_device *hisi_femac_drv_phy(struct platform_device *pdev,
47730+		struct hisi_femac_priv *priv, int *ret)
47731+{
47732+	__ETHTOOL_DECLARE_LINK_MODE_MASK(mask) = { 0, };
47733+	__ETHTOOL_DECLARE_LINK_MODE_MASK(supported) = { 0, };
47734+	__ETHTOOL_DECLARE_LINK_MODE_MASK(advertising) = { 0, };
47735+	struct device *dev = &pdev->dev;
47736+	struct device_node *node = dev->of_node;
47737+	struct phy_device *phy = NULL;
47738+
47739+	priv->phy_rst = devm_reset_control_get(dev, "phy");
47740+	if (IS_ERR(priv->phy_rst)) {
47741+		priv->phy_rst = NULL;
47742+	} else {
47743+		*ret = of_property_read_u32_array(node, PHY_RESET_DELAYS_PROPERTY,
47744+						  priv->phy_reset_delays, DELAYS_NUM);
47745+		if (*ret)
47746+			return phy;
47747+		hisi_femac_phy_reset(priv);
47748+	}
47749+
47750+	phy_register_fixups();
47751+
47752+	phy = of_phy_get_and_connect(priv->ndev, node, hisi_femac_adjust_link);
47753+	if (phy == NULL) {
47754+		/* check if a fixed-link is defined in device-tree */
47755+		if (of_phy_is_fixed_link(node)) {
47756+			*ret = of_phy_register_fixed_link(node);
47757+			if (*ret < 0) {
47758+				dev_err(dev, "cannot regitster fixed link phy %d \n", *ret);
47759+				return phy;
47760+			}
47761+			/*
47762+			 * In case of a fixed link phy, the DT node associated
47763+			 * to the phy is the Ethernet MAC DT node.
47764+			 */
47765+			phy_interface_t iface = PHY_INTERFACE_MODE_NA;
47766+			of_get_phy_mode(node, &iface);
47767+			phy = of_phy_connect(priv->ndev, of_node_get(node), &hisi_femac_adjust_link, 0,
47768+					     iface);
47769+			if (phy == NULL) {
47770+				dev_err(dev, "fixed_link didnot connect successfully.\n");
47771+				return phy;
47772+			}
47773+		} else {
47774+			dev_err(dev, "connect to PHY failed!\n");
47775+			*ret = -ENODEV;
47776+			return phy;
47777+		}
47778+	}
47779+
47780+	linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, advertising);
47781+	linkmode_or(phy->advertising, phy->advertising, advertising);
47782+	linkmode_set_bit(ETHTOOL_LINK_MODE_Pause_BIT, supported);
47783+	linkmode_or(phy->supported, phy->supported, supported);
47784+	linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Full_BIT, mask);
47785+	linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseT_Half_BIT, mask);
47786+	linkmode_andnot(phy->advertising, phy->advertising, mask);
47787+
47788+	phy_attached_print(phy, "phy_id=0x%.8lx, phy_mode=%s\n",
47789+			   (unsigned long)phy->phy_id, phy_modes(phy->interface));
47790+
47791+	return phy;
47792+}
47793+
47794+static void hisi_femac_drv_napi(struct platform_device *pdev,
47795+				struct hisi_femac_priv *priv)
47796+{
47797+	struct net_device *ndev = priv->ndev;
47798+
47799+	ndev->watchdog_timeo = 6 * HZ; /* 6HZ */
47800+	ndev->priv_flags |= IFF_UNICAST_FLT;
47801+	ndev->netdev_ops = &hisi_femac_netdev_ops;
47802+	ndev->ethtool_ops = &hisi_femac_ethtools_ops;
47803+	netif_napi_add(ndev, &priv->napi, hisi_femac_poll, FEMAC_POLL_WEIGHT);
47804+
47805+#ifdef CONFIG_FEPHY_OPT
47806+	INIT_DELAYED_WORK(&priv->watchdog_queue, hisi_femac_watchdog);
47807+	schedule_delayed_work(&priv->watchdog_queue, FEPHY_OPT_TIMER);
47808+#endif
47809+
47810+	if (has_tso_cap(priv->hw_cap))
47811+		ndev->hw_features |= NETIF_F_SG |
47812+						NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
47813+						NETIF_F_TSO | NETIF_F_TSO6 | NETIF_F_UFO;
47814+
47815+	if (has_rxcsum_cap(priv->hw_cap))
47816+		ndev->hw_features |= NETIF_F_RXCSUM;
47817+	ndev->features |= ndev->hw_features;
47818+	ndev->vlan_features |= ndev->features;
47819+
47820+	device_set_wakeup_capable(priv->dev, true);
47821+	device_set_wakeup_enable(priv->dev, true);
47822+
47823+	priv->tx_pause_en = true;
47824+	priv->tx_pause_active_thresh = TX_FLOW_CTRL_ACTIVE_THRESHOLD;
47825+	priv->tx_pause_deactive_thresh = TX_FLOW_CTRL_DEACTIVE_THRESHOLD;
47826+
47827+	hisi_femac_verify_flow_ctrl_args(priv);
47828+
47829+	hisi_femac_port_init(priv);
47830+
47831+	if (has_rxcsum_cap(priv->hw_cap))
47832+		hisi_femac_enable_rxcsum_drop(priv, true);
47833+}
47834+
47835+static int hisi_femac_drv_queues(struct platform_device *pdev,
47836+				 struct hisi_femac_priv *priv)
47837+{
47838+	int ret;
47839+
47840+#ifdef FEMAC_RX_REFILL_IN_IRQ
47841+	skb_queue_head_init(&priv->rx_head);
47842+	spin_lock_init(&priv->rxlock);
47843+#endif
47844+	ret = hisi_femac_init_tx_and_rx_queues(priv);
47845+	if (ret)
47846+		return ret;
47847+
47848+	if (has_tso_cap(priv->hw_cap)) {
47849+		ret = hisi_femac_init_tx_descriptor_ring(priv);
47850+		if (ret)
47851+			return ret;
47852+	}
47853+	return 0;
47854+}
47855+
47856+static int hisi_femac_drv_register(struct platform_device *pdev,
47857+				   struct hisi_femac_priv *priv)
47858+{
47859+	struct device *dev = &pdev->dev;
47860+	struct net_device *ndev = priv->ndev;
47861+	int ret;
47862+
47863+	ndev->irq = platform_get_irq(pdev, 0);
47864+	if (ndev->irq <= 0) {
47865+		dev_err(dev, "No irq resource\n");
47866+		ret = -ENODEV;
47867+		return ret;
47868+	}
47869+
47870+	ret = devm_request_irq(dev, ndev->irq, hisi_femac_interrupt,
47871+			       IRQF_SHARED, pdev->name, ndev);
47872+	if (ret) {
47873+		dev_err(dev, "devm_request_irq %d failed!\n", ndev->irq);
47874+		return ret;
47875+	}
47876+
47877+	ret = register_netdev(ndev);
47878+	if (ret) {
47879+		dev_err(dev, "register_netdev failed!\n");
47880+		return ret;
47881+	}
47882+	return 0;
47883+}
47884+
47885+static int hisi_femac_drv_probe(struct platform_device *pdev)
47886+{
47887+	struct device *dev = &pdev->dev;
47888+	struct net_device *ndev = NULL;
47889+	struct hisi_femac_priv *priv = NULL;
47890+	struct phy_device *phy = NULL;
47891+	int ret;
47892+
47893+	ndev = alloc_etherdev(sizeof(*priv));
47894+	if (ndev == NULL)
47895+		return -ENOMEM;
47896+
47897+	platform_set_drvdata(pdev, ndev);
47898+	SET_NETDEV_DEV(ndev, &pdev->dev);
47899+
47900+	priv = netdev_priv(ndev);
47901+	priv->dev = dev;
47902+	priv->ndev = ndev;
47903+
47904+	ret = hisi_femac_drv_res(pdev, priv);
47905+	if (ret)
47906+		goto out_free_netdev;
47907+
47908+	ret = hisi_femac_drv_mac(pdev, priv);
47909+	if (ret)
47910+		goto out_disable_clk;
47911+
47912+	phy = hisi_femac_drv_phy(pdev, priv, &ret);
47913+	if (phy == NULL)
47914+		goto out_disable_clk;
47915+
47916+	hisi_femac_drv_napi(pdev, priv);
47917+
47918+	ret = hisi_femac_drv_queues(pdev, priv);
47919+	if (ret)
47920+		goto out_disconnect_phy;
47921+
47922+	ret = hisi_femac_drv_register(pdev, priv);
47923+	if (ret)
47924+		goto out_destroy_descriptor;
47925+
47926+	return ret;
47927+
47928+out_destroy_descriptor:
47929+	if (has_tso_cap(priv->hw_cap))
47930+		hisi_femac_destroy_tx_descriptor_ring(priv);
47931+out_disconnect_phy:
47932+	netif_napi_del(&priv->napi);
47933+	phy_disconnect(phy);
47934+out_disable_clk:
47935+	clk_disable_unprepare(priv->clk);
47936+out_free_netdev:
47937+	free_netdev(ndev);
47938+
47939+	return ret;
47940+}
47941+
47942+static int hisi_femac_drv_remove(struct platform_device *pdev)
47943+{
47944+	struct net_device *ndev = platform_get_drvdata(pdev);
47945+	struct hisi_femac_priv *priv = netdev_priv(ndev);
47946+
47947+	netif_napi_del(&priv->napi);
47948+	unregister_netdev(ndev);
47949+	if (has_tso_cap(priv->hw_cap))
47950+		hisi_femac_destroy_tx_descriptor_ring(priv);
47951+
47952+	phy_disconnect(ndev->phydev);
47953+#ifdef CONFIG_FEPHY_OPT
47954+	cancel_delayed_work_sync(&priv->watchdog_queue);
47955+#endif
47956+	clk_disable_unprepare(priv->clk);
47957+	free_netdev(ndev);
47958+
47959+	phy_unregister_fixups();
47960+
47961+	return 0;
47962+}
47963+
47964+#ifdef CONFIG_PM
47965+static int hisi_femac_drv_suspend(struct platform_device *pdev,
47966+				  pm_message_t state)
47967+{
47968+	struct net_device *ndev = platform_get_drvdata(pdev);
47969+	struct hisi_femac_priv *priv = netdev_priv(ndev);
47970+
47971+	disable_irq(ndev->irq);
47972+	if (netif_running(ndev)) {
47973+		hisi_femac_net_close(ndev);
47974+		netif_device_detach(ndev);
47975+	}
47976+
47977+	clk_disable_unprepare(priv->clk);
47978+
47979+	return 0;
47980+}
47981+
47982+static int hisi_femac_drv_resume(struct platform_device *pdev)
47983+{
47984+	struct net_device *ndev = platform_get_drvdata(pdev);
47985+	struct hisi_femac_priv *priv = netdev_priv(ndev);
47986+
47987+	clk_prepare_enable(priv->clk);
47988+	if (priv->phy_rst != NULL)
47989+		hisi_femac_phy_reset(priv);
47990+
47991+	if (netif_running(ndev)) {
47992+		hisi_femac_port_init(priv);
47993+		hisi_femac_net_open(ndev);
47994+		netif_device_attach(ndev);
47995+	}
47996+	enable_irq(ndev->irq);
47997+
47998+	return 0;
47999+}
48000+#endif
48001+
48002+static const struct of_device_id hisi_femac_match[] = {
48003+	{
48004+		.compatible = "hisilicon,hisi-femac-v1",
48005+	},
48006+	{
48007+		.compatible = "hisilicon,hisi-femac-v2",
48008+	},
48009+	{
48010+		.compatible = "hisilicon,hi3516cv500-femac",
48011+	},
48012+	{
48013+		.compatible = "hisilicon,hi3516cv300-femac",
48014+	},
48015+	{
48016+		.compatible = "hisilicon,hi3536dv100-femac",
48017+	},
48018+	{
48019+		.compatible = "hisilicon,hi3556v200-femac",
48020+	},
48021+	{
48022+		.compatible = "hisilicon,hi3559v200-femac",
48023+	},
48024+	{},
48025+};
48026+
48027+MODULE_DEVICE_TABLE(of, hisi_femac_match);
48028+
48029+static struct platform_driver hisi_femac_driver = {
48030+	.driver = {
48031+		.name = "hisi-femac",
48032+		.of_match_table = hisi_femac_match,
48033+	},
48034+	.probe = hisi_femac_drv_probe,
48035+	.remove = hisi_femac_drv_remove,
48036+#ifdef CONFIG_PM
48037+	.suspend = hisi_femac_drv_suspend,
48038+	.resume = hisi_femac_drv_resume,
48039+#endif
48040+};
48041+
48042+module_platform_driver(hisi_femac_driver);
48043+
48044+MODULE_DESCRIPTION("Hisilicon Fast Ethernet MAC driver");
48045+MODULE_AUTHOR("Hisilicon");
48046+MODULE_LICENSE("GPL v2");
48047+MODULE_ALIAS("platform:hisi-femac");
48048diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/hisi_femac.h b/drivers/net/ethernet/hisilicon/hisi-femac/hisi_femac.h
48049new file mode 100644
48050index 000000000..5e260ad18
48051--- /dev/null
48052+++ b/drivers/net/ethernet/hisilicon/hisi-femac/hisi_femac.h
48053@@ -0,0 +1,269 @@
48054+/*
48055+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
48056+ * Description: Hieth driver femac head file
48057+ * Author: KTP_BSP
48058+ * Create: 2020-05-19
48059+ */
48060+
48061+#ifndef __HIETH_HISI_FEMAC_H__
48062+#define __HIETH_HISI_FEMAC_H__
48063+
48064+/* MAC control register list */
48065+#define MAC_PORTSEL                0x0200
48066+#define MAC_PORTSEL_STAT_CPU       BIT(0)
48067+#define MAC_PORTSEL_RMII           BIT(1)
48068+#define MAC_PORTSET                0x0208
48069+#define MAC_PORTSET_DUPLEX_FULL    BIT(0)
48070+#define MAC_PORTSET_LINKED         BIT(1)
48071+#define MAC_PORTSET_SPEED_100M     BIT(2)
48072+#define MAC_SET                    0x0210
48073+#define MAX_FRAME_SIZE             1600
48074+#define MAX_FRAME_SIZE_MASK        GENMASK(10, 0)
48075+#define BIT_PAUSE_EN               BIT(18)
48076+#define RX_COALESCE_SET            0x0340
48077+#define RX_COALESCED_FRAME_OFFSET  24
48078+#define RX_COALESCED_FRAMES        8
48079+#define RX_COALESCED_TIMER         0x74
48080+#define QLEN_SET                   0x0344
48081+#define RX_DEPTH_OFFSET            8
48082+#define MAX_HW_FIFO_DEPTH          64
48083+#define HW_TX_FIFO_DEPTH           12
48084+#define HW_RX_FIFO_DEPTH           (MAX_HW_FIFO_DEPTH - HW_TX_FIFO_DEPTH)
48085+#define FC_LEVEL                   0x0348
48086+#define BITS_FC_ACTIVE_THR_OFFSET  8
48087+#define FC_DEACTIVE_THR_MASK       GENMASK(5, 0)
48088+#define FC_ACTIVE_THR_MASK         GENMASK(13, 8)
48089+#define BIT_FC_EN                  BIT(14)
48090+#define IQFRM_DES                  0x0354
48091+#define RX_FRAME_LEN_MASK          GENMASK(11, 0)
48092+#define BITS_PAYLOAD_ERR_OFFSET    28
48093+#define BITS_PAYLOAD_ERR_MASK      0x1
48094+#define BITS_HEADER_ERR_OFFSET     29
48095+#define BITS_HEADER_ERR_MASK       0x1
48096+#define BITS_PAYLOAD_DONE_OFFSET   30
48097+#define BITS_PAYLOAD_DONE_MASK     0x1
48098+#define BITS_HEADER_DONE_OFFSET    31
48099+#define BITS_HEADER_DONE_MASK      0x1
48100+#define IQ_ADDR                    0x0358
48101+#define EQ_ADDR                    0x0360
48102+#define EQFRM_LEN                  0x0364
48103+#define ADDRQ_STAT                 0x036C
48104+#define TX_CNT_INUSE_MASK          GENMASK(5, 0)
48105+#define BIT_TX_READY               BIT(24)
48106+#define BIT_RX_READY               BIT(25)
48107+#define RX_COE_CTRL                0x0380
48108+#define BIT_COE_IPV6_UDP_ZERO_DROP BIT(13)
48109+#define BIT_COE_PAYLOAD_DROP       BIT(14)
48110+#define BIT_COE_IPHDR_DROP         BIT(15)
48111+#define COE_ERR_DROP               (BIT_COE_IPHDR_DROP |  \
48112+									BIT_COE_PAYLOAD_DROP |  \
48113+									BIT_COE_IPV6_UDP_ZERO_DROP)
48114+#define TSO_DBG_EN      0x03A4
48115+#define BITS_TSO_DBG_EN BIT(31)
48116+#define TSO_DBG_STATE   0x03A8
48117+#define TSO_DBG_ADDR    0x03AC
48118+#define TSO_DBG_TX_INFO 0x03B0
48119+#define TSO_DBG_TX_ERR  0x03B4
48120+/* global control register list */
48121+#define GLB_HOSTMAC_L32       0x0000
48122+#define GLB_HOSTMAC_H16       0x0004
48123+#define GLB_SOFT_RESET        0x0008
48124+#define SOFT_RESET_ALL        BIT(0)
48125+#define GLB_FWCTRL            0x0010
48126+#define FWCTRL_VLAN_ENABLE    BIT(0)
48127+#define FWCTRL_FW2CPU_ENA     BIT(5)
48128+#define FWCTRL_FWALL2CPU      BIT(7)
48129+#define GLB_MACTCTRL          0x0014
48130+#define MACTCTRL_UNI2CPU      BIT(1)
48131+#define MACTCTRL_MULTI2CPU    BIT(3)
48132+#define MACTCTRL_BROAD2CPU    BIT(5)
48133+#define MACTCTRL_MACT_ENA     BIT(7)
48134+#define GLB_IRQ_STAT          0x0030
48135+#define GLB_IRQ_ENA           0x0034
48136+#define IRQ_ENA_PORT0_MASK    GENMASK(7, 0)
48137+#define IRQ_ENA_PORT0         BIT(18)
48138+#define IRQ_ENA_ALL           BIT(19)
48139+#define GLB_IRQ_RAW           0x0038
48140+#define IRQ_INT_RX_RDY        BIT(0)
48141+#define IRQ_INT_TX_PER_PACKET BIT(1)
48142+#define IRQ_INT_TX_FIFO_EMPTY BIT(6)
48143+#define IRQ_INT_MULTI_RXRDY   BIT(7)
48144+#define INT_TX_ERR            BIT(8)
48145+#define DEF_INT_MASK          (IRQ_INT_MULTI_RXRDY |  \
48146+							   IRQ_INT_TX_PER_PACKET |  \
48147+							   IRQ_INT_TX_FIFO_EMPTY)
48148+#define GLB_MAC_L32_BASE        0x0100
48149+#define GLB_MAC_H16_BASE        0x0104
48150+#define MACFLT_HI16_MASK        GENMASK(15, 0)
48151+#define BIT_MACFLT_ENA          BIT(17)
48152+#define BIT_MACFLT_FW2CPU       BIT(21)
48153+#define glb_mac_h16(reg)        (GLB_MAC_H16_BASE + ((reg) * 0x8))
48154+#define glb_mac_l32(reg)        (GLB_MAC_L32_BASE + ((reg) * 0x8))
48155+#define MAX_MAC_FILTER_NUM      8
48156+#define MAX_UNICAST_ADDRESSES   2
48157+#define MAX_MULTICAST_ADDRESSES (MAX_MAC_FILTER_NUM - MAX_UNICAST_ADDRESSES)
48158+/* software tx and rx queue number, should be power of 2 */
48159+#define TXQ_NUM                64
48160+#define RXQ_NUM                128
48161+#define FEMAC_POLL_WEIGHT      64
48162+#define HW_CAP_TSO             BIT(0)
48163+#define HW_CAP_RXCSUM          BIT(1)
48164+#define has_tso_cap(hw_cap)    ((hw_cap) & HW_CAP_TSO)
48165+#define has_rxcsum_cap(hw_cap) ((hw_cap) & HW_CAP_RXCSUM)
48166+#define RXBUF_ADDR_ALIGN_SIZE  64UL
48167+/* UDP header len is 2 word */
48168+#define UDP_HDR_LEN 2
48169+/* IPv6 header len is 10 word */
48170+#define IPV6_HDR_LEN 10
48171+#define WORD_TO_BYTE 4
48172+
48173+#define BIT_OFFSET_NFRAGS_NUM      11
48174+#define BIT_OFFSET_PROT_HEADER_LEN 16
48175+#define BIT_OFFSET_IP_HEADER_LEN   20
48176+#define BIT_FLAG_SG                BIT(26)
48177+#define BIT_FLAG_TXCSUM            BIT(27)
48178+#define BIT_FLAG_UDP               BIT(28)
48179+#define BIT_FLAG_IPV6              BIT(29)
48180+#define BIT_FLAG_VLAN              BIT(30)
48181+#define BIT_FLAG_TSO               BIT(31)
48182+
48183+#define PHY_RESET_DELAYS_PROPERTY "hisilicon,phy-reset-delays-us"
48184+
48185+/*
48186+ * The threshold for activing tx flow ctrl.
48187+ * When the left amount of receive queue descriptors is below this threshold,
48188+ * hardware will send pause frame immediately.
48189+ * We advise this value is set between 1 and 10.
48190+ * Too bigger is not a good choice.
48191+ * This value must be smaller than tx flow ctrl deactive threshold.
48192+ */
48193+#define TX_FLOW_CTRL_ACTIVE_THRESHOLD 3
48194+/*
48195+ * The threshold for deactiving tx flow ctrl.
48196+ * When the left amount of receive queue descriptors is
48197+ * above or equal with this threshold,
48198+ * hardware will exit flow control state.
48199+ * We advise this value is set between 1 and 10.
48200+ * Too bigger is not a good choice.
48201+ * This value must be larger than tx flow ctrl active threshold.
48202+ */
48203+#define TX_FLOW_CTRL_DEACTIVE_THRESHOLD 5
48204+#define FC_ACTIVE_MIN                   1
48205+#define FC_ACTIVE_DEFAULT               3
48206+#define FC_ACTIVE_MAX                   31
48207+#define FC_DEACTIVE_MIN                 1
48208+#define FC_DEACTIVE_DEFAULT             5
48209+#define FC_DEACTIVE_MAX                 31
48210+
48211+#if (defined(CONFIG_ARCH_HI3516EV200) || defined(CONFIG_ARCH_HI3516EV300) || defined(CONFIG_ARCH_HI3516DV200))
48212+#define CONFIG_FEPHY_OPT
48213+#endif
48214+
48215+#ifdef CONFIG_FEPHY_OPT
48216+/* FEPHY register list */
48217+
48218+#define  SYS_REG_ADDR                   0x12028000
48219+#define  FEPHY_TRIM_CACHE               0x3022
48220+#define  FEPHY_TRIM_VALUE               0x20a1
48221+#define  LOW_TEM_VALUE                  117
48222+#define  HIGH_TEM_VALUE                 915
48223+#define  LINK_STATUS                    0x4
48224+#define  IS_LINK                        0X4
48225+#define  SPEED_STATUS                   0x18
48226+#define  SPEED_100M                     0x8
48227+#define  LINK_AN_SR                     0x11
48228+#define  MISC_CTRL45                    0x00B4
48229+#define  MISC_CTRL47                    0x00BC
48230+#define  MISC_CTRL48                    0x00C0
48231+#define  TSENSOR_RESULT0                0x3ff
48232+#define  TSENSOR_RESULT1                0x3ff0000
48233+#define  TSENSOR_RESULT2                0x3ff
48234+#define  TSENSOR_RESULT3                0x3ff0000
48235+#define  TSENSOR_EN                     0xc3200000
48236+#define  HIGH_TEMP                      100
48237+#define  NORMAL_TEMP1                   90
48238+#define  NORMAL_TEMP2                   20
48239+#define  LOW_TEMP                       10
48240+#define  TSENSOR_LIMIT                  0xfffff
48241+#define  regval_to_temp(val)            ((val - 117) * 165 / 798 - 40)
48242+#define  FEPHY_OPT_TIMER                (30 * HZ)
48243+#endif
48244+
48245+enum phy_reset_delays {
48246+	PRE_DELAY,
48247+	PULSE,
48248+	POST_DELAY,
48249+	DELAYS_NUM,
48250+};
48251+
48252+struct hisi_femac_queue {
48253+	struct sk_buff **skb;
48254+	dma_addr_t *dma_phys;
48255+	unsigned int num;
48256+	unsigned int head;
48257+	unsigned int tail;
48258+};
48259+
48260+struct hisi_femac_tx_desc_ring {
48261+	struct tx_desc *desc;
48262+	dma_addr_t dma_phys;
48263+};
48264+
48265+#define FEMAC_RX_REFILL_IN_IRQ
48266+
48267+struct hisi_femac_priv {
48268+	void __iomem *port_base;
48269+	void __iomem *glb_base;
48270+	struct clk *clk;
48271+	struct reset_control *mac_rst;
48272+	struct reset_control *phy_rst;
48273+	u32 phy_reset_delays[DELAYS_NUM];
48274+	u32 link_status;
48275+
48276+#ifdef CONFIG_FEPHY_OPT
48277+	struct delayed_work watchdog_queue;
48278+#endif
48279+	struct device *dev;
48280+	struct net_device *ndev;
48281+
48282+	u32 hw_cap;
48283+	struct hisi_femac_queue txq;
48284+	struct hisi_femac_queue rxq;
48285+#ifdef FEMAC_RX_REFILL_IN_IRQ
48286+	struct sk_buff_head rx_head;
48287+	spinlock_t rxlock;
48288+#endif
48289+	struct hisi_femac_tx_desc_ring tx_ring;
48290+	u32 tx_fifo_used_cnt;
48291+	struct napi_struct napi;
48292+
48293+	/* 802.3x flow control */
48294+	bool tx_pause_en;
48295+	u32 tx_pause_active_thresh;
48296+	u32 tx_pause_deactive_thresh;
48297+};
48298+
48299+struct frags_info {
48300+	/* Word(2*i+2) */
48301+	u32 addr;
48302+	/* Word(2*i+3) */
48303+	u32 size : 16;
48304+	u32 reserved : 16;
48305+};
48306+
48307+struct tx_desc {
48308+	/* Word0 */
48309+	u32 total_len : 17;
48310+	u32 reserv : 15;
48311+	/* Word1 */
48312+	u32 ipv6_id;
48313+	/* Word2 */
48314+	u32 linear_addr;
48315+	/* Word3 */
48316+	u32 linear_len : 16;
48317+	u32 reserv3 : 16;
48318+	/* MAX_SKB_FRAGS is 30 */
48319+	struct frags_info frags[30];
48320+};
48321+
48322+#endif
48323diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/phy_fix.c b/drivers/net/ethernet/hisilicon/hisi-femac/phy_fix.c
48324new file mode 100644
48325index 000000000..e7a3989b8
48326--- /dev/null
48327+++ b/drivers/net/ethernet/hisilicon/hisi-femac/phy_fix.c
48328@@ -0,0 +1,109 @@
48329+/*
48330+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
48331+ * Description: Hieth driver phy_fix process
48332+ * Author: KTP_BSP
48333+ * Create: 2018-10-08
48334+ */
48335+
48336+#include <linux/phy.h>
48337+#include "phy_fix.h"
48338+
48339+static const u32 phy_v272_fix_param[] = {
48340+#include "festa_v272_2723.h"
48341+};
48342+
48343+static const u32 phy_v115_fix_param[] = {
48344+#include "festa_s28v115_2c02.h"
48345+};
48346+
48347+static const u32 phy_v202_fix_param[] = {
48348+#include "festa_s28v202_2e01.h"
48349+};
48350+
48351+static int phy_expanded_write_bulk(struct phy_device *phy_dev,
48352+				   const u32 reg_and_val[], int count)
48353+{
48354+	int i, v;
48355+	u32 reg_addr;
48356+	u16 val;
48357+
48358+	v = phy_read(phy_dev, MII_BMCR);
48359+	v = (u32)v | BMCR_PDOWN;
48360+	phy_write(phy_dev, MII_BMCR, v);
48361+
48362+	for (i = 0; i < count; i += 2) { /* Process 2 data at a time. */
48363+		reg_addr = reg_and_val[i];
48364+		val = (u16)reg_and_val[i + 1];
48365+		phy_write(phy_dev, MII_EXPMA, reg_addr);
48366+		phy_write(phy_dev, MII_EXPMD, val);
48367+	}
48368+
48369+	v = phy_read(phy_dev, MII_BMCR);
48370+	v = (u32)v & (~BMCR_PDOWN);
48371+	phy_write(phy_dev, MII_BMCR, v);
48372+
48373+	return 0;
48374+}
48375+
48376+static int hisilicon_fephy_v272_fix(struct phy_device *phy_dev)
48377+{
48378+	int count;
48379+
48380+	count = ARRAY_SIZE(phy_v272_fix_param);
48381+	if (count % 2) /* must be an even number, mod 2 */
48382+		pr_warn("internal FEPHY fix register count is not right.\n");
48383+	phy_expanded_write_bulk(phy_dev, phy_v272_fix_param, count);
48384+
48385+	return 0;
48386+}
48387+
48388+static int hisilicon_fephy_v115_fix(struct phy_device *phy_dev)
48389+{
48390+	int count;
48391+
48392+	count = ARRAY_SIZE(phy_v115_fix_param);
48393+	if (count % 2) /* must be an even number, mod 2 */
48394+		pr_warn("internal FEPHY fix register count is not right.\n");
48395+	phy_expanded_write_bulk(phy_dev, phy_v115_fix_param, count);
48396+
48397+	return 0;
48398+}
48399+
48400+static int hisilicon_fephy_v202_fix(struct phy_device *phy_dev)
48401+{
48402+	int count;
48403+
48404+	count = ARRAY_SIZE(phy_v202_fix_param);
48405+	if (count % 2) /* must be an even number, mod 2 */
48406+		pr_warn("internal FEPHY fix register count is not right.\n");
48407+	phy_expanded_write_bulk(phy_dev, phy_v202_fix_param, count);
48408+
48409+	return 0;
48410+}
48411+
48412+void phy_register_fixups(void)
48413+{
48414+	phy_register_fixup_for_uid(HISILICON_PHY_ID_FESTAV272,
48415+				   HISILICON_PHY_MASK,
48416+				   hisilicon_fephy_v272_fix);
48417+
48418+	phy_register_fixup_for_uid(HISILICON_PHY_ID_FESTAV115,
48419+				   HISILICON_PHY_MASK,
48420+				   hisilicon_fephy_v115_fix);
48421+
48422+	phy_register_fixup_for_uid(HISILICON_PHY_ID_FESTAV202,
48423+				   HISILICON_PHY_MASK,
48424+				   hisilicon_fephy_v202_fix);
48425+}
48426+
48427+void phy_unregister_fixups(void)
48428+{
48429+	phy_unregister_fixup_for_uid(HISILICON_PHY_ID_FESTAV272,
48430+				     HISILICON_PHY_MASK);
48431+
48432+	phy_unregister_fixup_for_uid(HISILICON_PHY_ID_FESTAV115,
48433+				     HISILICON_PHY_MASK);
48434+
48435+	phy_unregister_fixup_for_uid(HISILICON_PHY_ID_FESTAV202,
48436+				     HISILICON_PHY_MASK);
48437+}
48438diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/phy_fix.h b/drivers/net/ethernet/hisilicon/hisi-femac/phy_fix.h
48439new file mode 100644
48440index 000000000..b7a725090
48441--- /dev/null
48442+++ b/drivers/net/ethernet/hisilicon/hisi-femac/phy_fix.h
48443@@ -0,0 +1,22 @@
48444+/*
48445+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2018-2020. All rights reserved.
48446+ * Description: Hieth driver phy fixup head file
48447+ * Author: KTP_BSP
48448+ * Create: 2018-10-08
48449+ */
48450+
48451+#ifndef __HIETH_PHY_FIX_H__
48452+#define __HIETH_PHY_FIX_H__
48453+
48454+#define HISILICON_PHY_ID_FESTAV272     0x20669901
48455+#define HISILICON_PHY_ID_FESTAV115     0x20669903
48456+#define HISILICON_PHY_ID_FESTAV202     0x20669906
48457+#define HISILICON_PHY_MASK             0xffffffff
48458+
48459+#define MII_EXPMD 0x1d
48460+#define MII_EXPMA 0x1e
48461+
48462+void phy_register_fixups(void);
48463+void phy_unregister_fixups(void);
48464+
48465+#endif
48466diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/util.c b/drivers/net/ethernet/hisilicon/hisi-femac/util.c
48467new file mode 100644
48468index 000000000..4f803784e
48469--- /dev/null
48470+++ b/drivers/net/ethernet/hisilicon/hisi-femac/util.c
48471@@ -0,0 +1,318 @@
48472+/*
48473+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
48474+ * Description: Hieth driver util file
48475+ * Author: KTP_BSP
48476+ * Create: 2020-05-19
48477+ */
48478+
48479+#include <linux/if_vlan.h>
48480+#include <linux/ip.h>
48481+#include <net/ipv6.h>
48482+#include <linux/phy.h>
48483+
48484+#include "util.h"
48485+
48486+static void hisi_femac_do_udp_checksum(struct sk_buff *skb)
48487+{
48488+	int offset;
48489+	__wsum csum;
48490+	__sum16 udp_csum;
48491+
48492+	offset = skb_checksum_start_offset(skb);
48493+	WARN_ON(offset >= skb_headlen(skb));
48494+	csum = skb_checksum(skb, offset, skb->len - offset, 0);
48495+
48496+	offset += skb->csum_offset;
48497+	WARN_ON(offset + sizeof(__sum16) > skb_headlen(skb));
48498+
48499+	udp_csum = csum_fold(csum);
48500+	if (udp_csum == 0)
48501+		udp_csum = CSUM_MANGLED_0;
48502+
48503+	*(__sum16 *)(skb->data + offset) = udp_csum;
48504+
48505+	skb->ip_summed = CHECKSUM_NONE;
48506+}
48507+
48508+static __be16 hisi_femac_get_l3_proto(struct sk_buff *skb)
48509+{
48510+	__be16 l3_proto;
48511+
48512+	l3_proto = skb->protocol;
48513+	if (skb->protocol == htons(ETH_P_8021Q))
48514+		l3_proto = vlan_get_protocol(skb);
48515+
48516+	return l3_proto;
48517+}
48518+
48519+static inline bool hisi_femac_skb_is_ipv6(struct sk_buff *skb)
48520+{
48521+	return (hisi_femac_get_l3_proto(skb) == htons(ETH_P_IPV6));
48522+}
48523+
48524+static int hisi_femac_check_hw_capability_for_ipv6(struct sk_buff *skb)
48525+{
48526+	unsigned int l4_proto;
48527+
48528+	l4_proto = ipv6_hdr(skb)->nexthdr;
48529+	if ((l4_proto != IPPROTO_TCP) && (l4_proto != IPPROTO_UDP)) {
48530+		/*
48531+		 * when IPv6 next header is not tcp or udp,
48532+		 * it means that IPv6 next header is extension header.
48533+		 * Hardware can't deal with this case,
48534+		 * so do checksumming by software or do GSO by software.
48535+		 */
48536+		if (skb_is_gso(skb)) {
48537+			return -ENOTSUPP;
48538+		}
48539+
48540+		if (skb->ip_summed == CHECKSUM_PARTIAL &&
48541+				skb_checksum_help(skb)) {
48542+			return -EINVAL;
48543+		}
48544+	}
48545+
48546+	return 0;
48547+}
48548+
48549+int hisi_femac_check_hw_capability(struct sk_buff *skb)
48550+{
48551+	/*
48552+	 * if tcp_mtu_probe() use (2 * tp->mss_cache) as probe_size,
48553+	 * the linear data length will be larger than 2048,
48554+	 * the MAC can't handle it, so let the software do it.
48555+	 */
48556+	if (skb_is_gso(skb) && (skb_headlen(skb) > 2048)) { /* max is 2048 */
48557+		return -ENOTSUPP;
48558+	}
48559+
48560+	if (hisi_femac_skb_is_ipv6(skb)) {
48561+		return hisi_femac_check_hw_capability_for_ipv6(skb);
48562+	}
48563+
48564+	return 0;
48565+}
48566+
48567+static unsigned int hisi_femac_get_pkt_info_gso(struct sk_buff *skb,
48568+		bool txcsum, unsigned int max_mss, unsigned int l4_proto)
48569+{
48570+	u32 pkt_info = 0;
48571+	bool do_txcsum = txcsum;
48572+
48573+	/*
48574+	 * Although netcard support UFO feature, it can't deal with
48575+	 * UDP header checksum.
48576+	 * So the driver will do UDP header checksum and netcard will just
48577+	 * fragment the packet.
48578+	 */
48579+	if (do_txcsum && skb_is_gso(skb) && (l4_proto == IPPROTO_UDP)) {
48580+		hisi_femac_do_udp_checksum(skb);
48581+		do_txcsum = false;
48582+	}
48583+
48584+	if (do_txcsum)
48585+		pkt_info |= BIT_FLAG_TXCSUM;
48586+
48587+	if (skb_is_gso(skb)) {
48588+		pkt_info |= (BIT_FLAG_SG | BIT_FLAG_TSO);
48589+	} else if (skb_shinfo(skb)->nr_frags) {
48590+		pkt_info |= BIT_FLAG_SG;
48591+	}
48592+
48593+	pkt_info |= (skb_shinfo(skb)->nr_frags << BIT_OFFSET_NFRAGS_NUM);
48594+	pkt_info |= (skb_is_gso(skb) ? ((skb_shinfo(skb)->gso_size > max_mss) ?
48595+					max_mss : skb_shinfo(skb)->gso_size) :
48596+					(skb->len + ETH_FCS_LEN));
48597+	return pkt_info;
48598+}
48599+
48600+u32 hisi_femac_get_pkt_info(struct sk_buff *skb)
48601+{
48602+	__be16 l3_proto;
48603+	unsigned int l4_proto = IPPROTO_MAX;
48604+	bool do_txcsum = false;
48605+	int max_data_len;
48606+	unsigned int max_mss = ETH_DATA_LEN;
48607+	u32 pkt_info = 0;
48608+
48609+	if (skb == NULL)
48610+		return 0;
48611+
48612+	max_data_len = skb->len - ETH_HLEN;
48613+
48614+	if (skb->ip_summed == CHECKSUM_PARTIAL)
48615+		do_txcsum = true;
48616+
48617+	l3_proto = skb->protocol;
48618+	if (skb->protocol == htons(ETH_P_8021Q)) {
48619+		l3_proto = vlan_get_protocol(skb);
48620+		max_data_len -= VLAN_HLEN;
48621+		pkt_info |= BIT_FLAG_VLAN;
48622+	}
48623+
48624+	if (l3_proto == htons(ETH_P_IP)) {
48625+		struct iphdr *iph = ip_hdr(skb);
48626+
48627+		if ((max_data_len >= GSO_MAX_SIZE) &&
48628+			(ntohs(iph->tot_len) <= (iph->ihl << 2))) /* trans 2 bytes */
48629+			iph->tot_len = htons(GSO_MAX_SIZE - 1);
48630+
48631+		max_mss -= iph->ihl * WORD_TO_BYTE;
48632+		pkt_info |= (iph->ihl << BIT_OFFSET_IP_HEADER_LEN);
48633+		l4_proto = iph->protocol;
48634+	} else if (l3_proto == htons(ETH_P_IPV6)) {
48635+		max_mss -= IPV6_HDR_LEN * WORD_TO_BYTE;
48636+		pkt_info |= BIT_FLAG_IPV6;
48637+		pkt_info |= (IPV6_HDR_LEN << BIT_OFFSET_IP_HEADER_LEN);
48638+		l4_proto = ipv6_hdr(skb)->nexthdr;
48639+	} else {
48640+		do_txcsum = false;
48641+	}
48642+
48643+	if (l4_proto == IPPROTO_TCP) {
48644+		max_mss -= tcp_hdr(skb)->doff * WORD_TO_BYTE;
48645+		pkt_info |= (tcp_hdr(skb)->doff << BIT_OFFSET_PROT_HEADER_LEN);
48646+	} else if (l4_proto == IPPROTO_UDP) {
48647+		if (l3_proto == htons(ETH_P_IPV6))
48648+			max_mss -= sizeof(struct frag_hdr);
48649+		pkt_info |= (BIT_FLAG_UDP |
48650+			     (UDP_HDR_LEN << BIT_OFFSET_PROT_HEADER_LEN));
48651+	} else {
48652+		do_txcsum = false;
48653+	}
48654+
48655+	pkt_info |= hisi_femac_get_pkt_info_gso(skb, do_txcsum, max_mss, l4_proto);
48656+
48657+	return pkt_info;
48658+}
48659+
48660+void hisi_femac_sleep_us(u32 time_us)
48661+{
48662+	u32 time_ms;
48663+
48664+	if (!time_us) {
48665+		return;
48666+	}
48667+
48668+	time_ms = DIV_ROUND_UP(time_us, 1000); /* add 1000us, round up */
48669+	if (time_ms < 20) { /* less than 20 ms */
48670+		usleep_range(time_us, time_us + 500); /* add maximum 500us */
48671+	} else {
48672+		msleep(time_ms);
48673+	}
48674+}
48675+
48676+void hisi_femac_set_flow_ctrl(const struct hisi_femac_priv *priv)
48677+{
48678+	unsigned int pause_en;
48679+	unsigned int tx_flow_ctrl;
48680+
48681+	if (priv == NULL)
48682+		return;
48683+
48684+	tx_flow_ctrl = readl(priv->port_base + FC_LEVEL);
48685+	tx_flow_ctrl &= ~FC_DEACTIVE_THR_MASK;
48686+	tx_flow_ctrl |= priv->tx_pause_deactive_thresh;
48687+	tx_flow_ctrl &= ~FC_ACTIVE_THR_MASK;
48688+	tx_flow_ctrl |= priv->tx_pause_active_thresh << BITS_FC_ACTIVE_THR_OFFSET;
48689+
48690+	pause_en = readl(priv->port_base + MAC_SET);
48691+
48692+	if (priv->tx_pause_en) {
48693+		tx_flow_ctrl |= BIT_FC_EN;
48694+		pause_en |= BIT_PAUSE_EN;
48695+	} else {
48696+		tx_flow_ctrl &= ~BIT_FC_EN;
48697+		pause_en &= ~BIT_PAUSE_EN;
48698+	}
48699+
48700+	writel(tx_flow_ctrl, priv->port_base + FC_LEVEL);
48701+
48702+	writel(pause_en, priv->port_base + MAC_SET);
48703+}
48704+
48705+void hisi_femac_get_pauseparam(struct net_device *dev,
48706+			       struct ethtool_pauseparam *pause)
48707+{
48708+	struct hisi_femac_priv *priv = netdev_priv(dev);
48709+
48710+	if (dev == NULL || dev->phydev == NULL || pause == NULL)
48711+		return;
48712+
48713+	pause->autoneg = dev->phydev->autoneg;
48714+	pause->rx_pause = 1;
48715+	if (priv->tx_pause_en)
48716+		pause->tx_pause = 1;
48717+}
48718+
48719+int hisi_femac_set_pauseparam(struct net_device *dev,
48720+			      struct ethtool_pauseparam *pause)
48721+{
48722+	struct hisi_femac_priv *priv = netdev_priv(dev);
48723+	struct phy_device *phy = NULL;
48724+	int ret = 0;
48725+
48726+	if (dev == NULL || pause == NULL || pause->rx_pause == 0) {
48727+		return -EINVAL;
48728+	}
48729+
48730+	phy = dev->phydev;
48731+
48732+	if (pause->tx_pause != priv->tx_pause_en) {
48733+		priv->tx_pause_en = pause->tx_pause;
48734+		hisi_femac_set_flow_ctrl(priv);
48735+	}
48736+
48737+	if (phy != NULL && phy->autoneg) {
48738+		if (netif_running(dev)) {
48739+			struct ethtool_cmd cmd;
48740+			/* auto-negotiation automatically restarted */
48741+			cmd.cmd = ETHTOOL_NWAY_RST;
48742+			cmd.supported = phy->supported;
48743+			cmd.advertising = phy->advertising;
48744+			cmd.autoneg = phy->autoneg;
48745+			cmd.speed = phy->speed;
48746+			cmd.duplex = phy->duplex;
48747+			cmd.phy_address = phy->mdio.addr;
48748+//			ret = phy_ethtool_sset(phy, &cmd);
48749+		}
48750+	}
48751+
48752+	return ret;
48753+}
48754+
48755+void hisi_femac_enable_rxcsum_drop(const struct hisi_femac_priv *priv,
48756+				   bool drop)
48757+{
48758+	unsigned int val;
48759+	if (priv == NULL)
48760+		return;
48761+
48762+	val = readl(priv->port_base + RX_COE_CTRL);
48763+	val &= ~COE_ERR_DROP;
48764+	if (drop)
48765+		val |= (BIT_COE_IPHDR_DROP | BIT_COE_IPV6_UDP_ZERO_DROP);
48766+	writel(val, priv->port_base + RX_COE_CTRL);
48767+}
48768+
48769+int hisi_femac_set_features(struct net_device *dev, netdev_features_t features)
48770+{
48771+	struct hisi_femac_priv *priv = NULL;
48772+	netdev_features_t changed;
48773+
48774+	if (dev == NULL)
48775+		return -1;
48776+
48777+	priv = netdev_priv(dev);
48778+	changed = dev->features ^ features;
48779+
48780+	if (changed & NETIF_F_RXCSUM) {
48781+		if (features & NETIF_F_RXCSUM) {
48782+			hisi_femac_enable_rxcsum_drop(priv, true);
48783+		} else {
48784+			hisi_femac_enable_rxcsum_drop(priv, false);
48785+		}
48786+	}
48787+
48788+	return 0;
48789+}
48790diff --git a/drivers/net/ethernet/hisilicon/hisi-femac/util.h b/drivers/net/ethernet/hisilicon/hisi-femac/util.h
48791new file mode 100644
48792index 000000000..009424857
48793--- /dev/null
48794+++ b/drivers/net/ethernet/hisilicon/hisi-femac/util.h
48795@@ -0,0 +1,25 @@
48796+/*
48797+ * Copyright (c) Hisilicon Technologies Co., Ltd. 2020-2020. All rights reserved.
48798+ * Description: Hieth driver util head file
48799+ * Author: KTP_BSP
48800+ * Create: 2020-05-19
48801+ */
48802+
48803+#ifndef __HIETH_UTIL_H__
48804+#define __HIETH_UTIL_H__
48805+
48806+#include "hisi_femac.h"
48807+
48808+int hisi_femac_check_hw_capability(struct sk_buff *skb);
48809+u32 hisi_femac_get_pkt_info(struct sk_buff *skb);
48810+void hisi_femac_sleep_us(u32 time_us);
48811+void hisi_femac_set_flow_ctrl(const struct hisi_femac_priv *priv);
48812+void hisi_femac_get_pauseparam(struct net_device *dev,
48813+			       struct ethtool_pauseparam *pause);
48814+int hisi_femac_set_pauseparam(struct net_device *dev,
48815+			      struct ethtool_pauseparam *pause);
48816+void hisi_femac_enable_rxcsum_drop(const struct hisi_femac_priv *priv,
48817+				   bool drop);
48818+int hisi_femac_set_features(struct net_device *dev, netdev_features_t features);
48819+
48820+#endif
48821\ No newline at end of file
48822diff --git a/drivers/net/ethernet/hisilicon/hisi_femac.c b/drivers/net/ethernet/hisilicon/hisi_femac.c
48823index 57c3bc4f7..180805656 100644
48824--- a/drivers/net/ethernet/hisilicon/hisi_femac.c
48825+++ b/drivers/net/ethernet/hisilicon/hisi_femac.c
48826@@ -86,7 +86,7 @@
48827 /* software tx and rx queue number, should be power of 2 */
48828 #define TXQ_NUM				64
48829 #define RXQ_NUM				128
48830-#define FEMAC_POLL_WEIGHT		16
48831+#define FEMAC_POLL_WEIGHT		64
48832
48833 #define PHY_RESET_DELAYS_PROPERTY	"hisilicon,phy-reset-delays-us"
48834
48835@@ -973,6 +973,6 @@ static struct platform_driver hisi_femac_driver = {
48836 module_platform_driver(hisi_femac_driver);
48837
48838 MODULE_DESCRIPTION("Hisilicon Fast Ethernet MAC driver");
48839-MODULE_AUTHOR("Dongpo Li <lidongpo@hisilicon.com>");
48840+MODULE_AUTHOR("Hisilicon");
48841 MODULE_LICENSE("GPL v2");
48842 MODULE_ALIAS("platform:hisi-femac");
48843diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
48844index 7fb7a4196..1a357516b 100644
48845--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
48846+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_gmac.c
48847@@ -702,7 +702,7 @@ static void hns_gmac_get_strings(u32 stringset, u8 *data)
48848
48849 static int hns_gmac_get_sset_count(int stringset)
48850 {
48851-	if (stringset == ETH_SS_STATS)
48852+	if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
48853 		return ARRAY_SIZE(g_gmac_stats_string);
48854
48855 	return 0;
48856diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
48857index d0f8b1fff..c5176565f 100644
48858--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
48859+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_ppe.c
48860@@ -444,7 +444,7 @@ void hns_ppe_update_stats(struct hns_ppe_cb *ppe_cb)
48861
48862 int hns_ppe_get_sset_count(int stringset)
48863 {
48864-	if (stringset == ETH_SS_STATS)
48865+	if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
48866 		return ETH_PPE_STATIC_NUM;
48867 	return 0;
48868 }
48869diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
48870index b6c8910cf..4cda44494 100644
48871--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
48872+++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_rcb.c
48873@@ -897,7 +897,7 @@ void hns_rcb_get_stats(struct hnae_queue *queue, u64 *data)
48874  */
48875 int hns_rcb_get_ring_sset_count(int stringset)
48876 {
48877-	if (stringset == ETH_SS_STATS)
48878+	if (stringset == ETH_SS_STATS || stringset == ETH_SS_PRIV_FLAGS)
48879 		return HNS_RING_STATIC_REG_NUM;
48880
48881 	return 0;
48882diff --git a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
48883index 3616b77ca..883c5f5db 100644
48884--- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
48885+++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
48886@@ -2092,8 +2092,11 @@ static int mlx4_en_get_module_eeprom(struct net_device *dev,
48887 		ret = mlx4_get_module_info(mdev->dev, priv->port,
48888 					   offset, ee->len - i, data + i);
48889
48890-		if (!ret) /* Done reading */
48891+		if (!ret) {
48892+			/* DOM was not readable after all */
48893+			memset(data + i, 0, ee->len - i);
48894 			return 0;
48895+		}
48896
48897 		if (ret < 0) {
48898 			en_err(priv,
48899diff --git a/drivers/net/mdio/Kconfig b/drivers/net/mdio/Kconfig
48900index a10cc460d..42603264a 100644
48901--- a/drivers/net/mdio/Kconfig
48902+++ b/drivers/net/mdio/Kconfig
48903@@ -107,6 +107,13 @@ config MDIO_HISI_FEMAC
48904 	  This module provides a driver for the MDIO busses found in the
48905 	  Hisilicon SoC that have an Fast Ethernet MAC.
48906
48907+config MDIO_HISI_GEMAC
48908+	tristate "Hisilicon GEMAC MDIO bus controller"
48909+	depends on HAS_IOMEM && OF_MDIO
48910+	help
48911+	  This module provides a driver for the MDIO busses found in the
48912+	  Hisilicon SoC that have an Gigabit Ethernet MAC.
48913+
48914 config MDIO_I2C
48915 	tristate
48916 	depends on I2C
48917diff --git a/drivers/net/mdio/Makefile b/drivers/net/mdio/Makefile
48918index 5c498dde4..67b74ed9d 100644
48919--- a/drivers/net/mdio/Makefile
48920+++ b/drivers/net/mdio/Makefile
48921@@ -9,7 +9,10 @@ obj-$(CONFIG_MDIO_BCM_UNIMAC)		+= mdio-bcm-unimac.o
48922 obj-$(CONFIG_MDIO_BITBANG)		+= mdio-bitbang.o
48923 obj-$(CONFIG_MDIO_CAVIUM)		+= mdio-cavium.o
48924 obj-$(CONFIG_MDIO_GPIO)			+= mdio-gpio.o
48925+obj-$(CONFIG_ARCH_HI3531DV200)		+= mdio_hi3531dv200_gemac.o
48926+obj-$(CONFIG_ARCH_HI3535AV100)		+= mdio_hi3535av100_gemac.o
48927 obj-$(CONFIG_MDIO_HISI_FEMAC)		+= mdio-hisi-femac.o
48928+obj-$(CONFIG_MDIO_HISI_GEMAC)		+= mdio-hisi-gemac.o
48929 obj-$(CONFIG_MDIO_I2C)			+= mdio-i2c.o
48930 obj-$(CONFIG_MDIO_IPQ4019)		+= mdio-ipq4019.o
48931 obj-$(CONFIG_MDIO_IPQ8064)		+= mdio-ipq8064.o
48932diff --git a/drivers/net/phy/mdio_hisi_femac.c b/drivers/net/phy/mdio_hisi_femac.c
48933new file mode 100644
48934index 000000000..25f187574
48935--- /dev/null
48936+++ b/drivers/net/phy/mdio_hisi_femac.c
48937@@ -0,0 +1,489 @@
48938+/*
48939+ * Hisilicon Fast Ethernet MDIO Bus Driver
48940+ *
48941+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
48942+ *
48943+ * This program is free software; you can redistribute it and/or modify
48944+ * it under the terms of the GNU General Public License as published by
48945+ * the Free Software Foundation; either version 2 of the License, or
48946+ * (at your option) any later version.
48947+ *
48948+ * This program is distributed in the hope that it will be useful,
48949+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
48950+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48951+ * GNU General Public License for more details.
48952+ *
48953+ * You should have received a copy of the GNU General Public License
48954+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
48955+ */
48956+
48957+#include <linux/clk.h>
48958+#include <linux/iopoll.h>
48959+#include <linux/kernel.h>
48960+#include <linux/module.h>
48961+#include <linux/of_address.h>
48962+#include <linux/of_mdio.h>
48963+#include <linux/platform_device.h>
48964+#include <linux/reset.h>
48965+
48966+#define MDIO_RWCTRL		0x00
48967+#define MDIO_RO_DATA		0x04
48968+#define MDIO_WRITE		BIT(13)
48969+#define MDIO_RW_FINISH		BIT(15)
48970+#define BIT_PHY_ADDR_OFFSET	8
48971+#define BIT_WR_DATA_OFFSET	16
48972+
48973+#define BIT_MASK_FEPHY_ADDR	GENMASK(4, 0)
48974+#define BIT_FEPHY_SEL		BIT(5)
48975+
48976+#if defined(CONFIG_ARCH_HI3536DV100)
48977+#define BIT_OFFSET_LD_SET	0
48978+#define BIT_OFFSET_LDO_SET	5
48979+#define BIT_OFFSET_R_TUNING	8
48980+#elif defined(CONFIG_ARCH_HI3521DV200) || defined(CONFIG_ARCH_HI3520DV500)
48981+#define BIT_OFFSET_LD_SET   6
48982+#define BIT_OFFSET_LDO_SET  12
48983+#define BIT_OFFSET_R_TUNING 0
48984+#define DEF_LD_AM              0x9
48985+#define DEF_LDO_AM             0x3
48986+#define DEF_R_TUNING           0x16
48987+#else
48988+#define BIT_OFFSET_LD_SET	25
48989+#define BIT_OFFSET_LDO_SET	22
48990+#define BIT_OFFSET_R_TUNING	16
48991+#endif
48992+#define MII_EXPMD		0x1d
48993+#define MII_EXPMA		0x1e
48994+
48995+#define REG_LD_AM		0x3050
48996+#define BIT_MASK_LD_SET		GENMASK(4, 0)
48997+#define REG_LDO_AM		0x3051
48998+#define BIT_MASK_LDO_SET	GENMASK(2, 0)
48999+#define REG_R_TUNING		0x3052
49000+#define BIT_MASK_R_TUNING	GENMASK(5, 0)
49001+#define REG_WR_DONE		0x3053
49002+#define BIT_CFG_DONE		BIT(0)
49003+#define BIT_CFG_ACK		BIT(1)
49004+#define REG_DEF_ATE		0x3057
49005+#define BIT_AUTOTRIM_DONE	BIT(0)
49006+
49007+#define PHY_RESET_DELAYS_PROPERTY	"hisilicon,phy-reset-delays-us"
49008+
49009+enum phy_reset_delays {
49010+	PRE_DELAY,
49011+	PULSE,
49012+	POST_DELAY,
49013+	DELAYS_NUM,
49014+};
49015+
49016+struct hisi_femac_mdio_data {
49017+	struct clk *clk;
49018+	struct clk *fephy_clk;
49019+	struct reset_control *phy_rst;
49020+	struct reset_control *fephy_rst;
49021+	u32 phy_reset_delays[DELAYS_NUM];
49022+	void __iomem *membase;
49023+	void __iomem *fephy_iobase;
49024+	void __iomem *fephy_trim_iobase;
49025+	struct mii_bus *bus;
49026+	u32 phy_addr;
49027+};
49028+
49029+static int hisi_femac_mdio_wait_ready(struct hisi_femac_mdio_data *data)
49030+{
49031+	u32 val;
49032+
49033+	return readl_poll_timeout_atomic(data->membase + MDIO_RWCTRL,
49034+				  val, val & MDIO_RW_FINISH, 20, 10000);
49035+}
49036+
49037+static int hisi_femac_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
49038+{
49039+	struct hisi_femac_mdio_data *data = bus->priv;
49040+	int ret;
49041+
49042+	ret = hisi_femac_mdio_wait_ready(data);
49043+	if (ret)
49044+		return ret;
49045+
49046+	writel(((u32)mii_id << BIT_PHY_ADDR_OFFSET) | ((u32)regnum),
49047+		  data->membase + MDIO_RWCTRL);
49048+
49049+	ret = hisi_femac_mdio_wait_ready(data);
49050+	if (ret)
49051+		return ret;
49052+
49053+	return readl(data->membase + MDIO_RO_DATA) & 0xFFFF;
49054+}
49055+
49056+static int hisi_femac_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
49057+				 u16 value)
49058+{
49059+	struct hisi_femac_mdio_data *data = bus->priv;
49060+	int ret;
49061+
49062+	ret = hisi_femac_mdio_wait_ready(data);
49063+	if (ret)
49064+		return ret;
49065+
49066+	writel(MDIO_WRITE | (value << BIT_WR_DATA_OFFSET) |
49067+	       ((u32)mii_id << BIT_PHY_ADDR_OFFSET) | ((u32)regnum),
49068+	       data->membase + MDIO_RWCTRL);
49069+
49070+	return hisi_femac_mdio_wait_ready(data);
49071+}
49072+
49073+static void hisi_femac_sleep_us(u32 time_us)
49074+{
49075+	u32 time_ms;
49076+
49077+	if (!time_us)
49078+		return;
49079+
49080+	time_ms = DIV_ROUND_UP(time_us, 1000);
49081+	if (time_ms < 20)
49082+		usleep_range(time_us, time_us + 500);
49083+	else
49084+		msleep(time_ms);
49085+}
49086+
49087+static void hisi_femac_phy_reset(const struct hisi_femac_mdio_data *data)
49088+{
49089+	/* To make sure PHY hardware reset success,
49090+	 * we must keep PHY in deassert state first and
49091+	 * then complete the hardware reset operation
49092+	 */
49093+	reset_control_deassert(data->phy_rst);
49094+	hisi_femac_sleep_us(data->phy_reset_delays[PRE_DELAY]);
49095+
49096+	reset_control_assert(data->phy_rst);
49097+	/* delay some time to ensure reset ok,
49098+	 * this depends on PHY hardware feature
49099+	 */
49100+	hisi_femac_sleep_us(data->phy_reset_delays[PULSE]);
49101+	reset_control_deassert(data->phy_rst);
49102+	/* delay some time to ensure later MDIO access */
49103+	hisi_femac_sleep_us(data->phy_reset_delays[POST_DELAY]);
49104+}
49105+
49106+static void hisi_femac_get_phy_addr(struct hisi_femac_mdio_data *data,
49107+				    struct device_node *np)
49108+{
49109+	struct device_node *child = NULL;
49110+	int addr;
49111+
49112+	child = of_get_next_available_child(np, NULL);
49113+	if (!child) {
49114+		pr_err("%s: No valid PHY device node!\n", __func__);
49115+		return;
49116+	}
49117+
49118+	addr = of_mdio_parse_addr(&data->bus->dev, child);
49119+	if (addr < 0) {
49120+		pr_err("%s: get PHY address failed!\n", __func__);
49121+		return;
49122+	}
49123+
49124+	data->phy_addr = addr;
49125+}
49126+
49127+static inline bool hisi_femac_use_fephy(struct hisi_femac_mdio_data *data)
49128+{
49129+	/*return false;*/
49130+	return (data->fephy_iobase ?
49131+			!(readl(data->fephy_iobase) & BIT_FEPHY_SEL) : false);
49132+}
49133+
49134+static void hisi_femac_fephy_reset(struct hisi_femac_mdio_data *data)
49135+{
49136+	u32 val;
49137+
49138+	/* disable MDCK clock to make sure FEPHY reset success */
49139+	clk_disable_unprepare(data->clk);
49140+
49141+	val = readl(data->fephy_iobase);
49142+	val &= ~BIT_MASK_FEPHY_ADDR;
49143+	val |= data->phy_addr;
49144+	writel(val, data->fephy_iobase);
49145+
49146+	clk_prepare_enable(data->fephy_clk);
49147+	udelay(10); /* 10:delay */
49148+
49149+	reset_control_assert(data->fephy_rst);
49150+	udelay(10);
49151+	reset_control_deassert(data->fephy_rst);
49152+	/* delay at least 15ms for MDIO operation */
49153+	msleep(20);
49154+
49155+	clk_prepare_enable(data->clk);
49156+	/* delay 5ms after enable MDCK to make sure FEPHY trim safe */
49157+	mdelay(5);
49158+}
49159+
49160+static inline int fephy_expanded_read(struct mii_bus *bus, int phy_addr,
49161+				      u32 reg_addr)
49162+{
49163+	int ret;
49164+
49165+	hisi_femac_mdio_write(bus, phy_addr, MII_EXPMA, reg_addr);
49166+	ret = hisi_femac_mdio_read(bus, phy_addr, MII_EXPMD);
49167+
49168+	return ret;
49169+}
49170+
49171+static inline int fephy_expanded_write(struct mii_bus *bus, int phy_addr,
49172+				       u32 reg_addr, u16 val)
49173+{
49174+	int ret;
49175+
49176+	hisi_femac_mdio_write(bus, phy_addr, MII_EXPMA, reg_addr);
49177+	ret = hisi_femac_mdio_write(bus, phy_addr, MII_EXPMD, val);
49178+
49179+	return ret;
49180+}
49181+
49182+void hisi_femac_fephy_use_default_trim(struct hisi_femac_mdio_data *data)
49183+{
49184+	unsigned short val;
49185+	int timeout = 3;
49186+
49187+	pr_info("No OTP data, festa PHY use default ATE parameters!\n");
49188+
49189+	do {
49190+		msleep(250);
49191+		val = fephy_expanded_read(data->bus, data->phy_addr,
49192+					  REG_DEF_ATE);
49193+		val &= BIT_AUTOTRIM_DONE;
49194+	} while (!val && --timeout);
49195+
49196+	if (!timeout)
49197+		pr_err("festa PHY wait autotrim done timeout!\n");
49198+
49199+	mdelay(5);
49200+}
49201+
49202+static void hisi_femac_fephy_trim(struct hisi_femac_mdio_data *data)
49203+{
49204+	struct mii_bus *bus = data->bus;
49205+	u32 phy_addr = data->phy_addr;
49206+	int timeout = 3000;
49207+	u32 val;
49208+	u8 ld_set;
49209+	u8 ldo_set;
49210+	u8 r_tuning;
49211+
49212+	/* FEPHY get OTP trim data from special reg not fephy control reg1 */
49213+#if defined(CONFIG_ARCH_HI3536DV100) || \
49214+	defined(CONFIG_ARCH_HI3521DV200) || \
49215+	defined(CONFIG_ARCH_HI3520DV500)
49216+	val = readl(data->fephy_trim_iobase);
49217+#else
49218+	val = readl(data->fephy_iobase);
49219+#endif
49220+	ld_set = (val >> BIT_OFFSET_LD_SET) & BIT_MASK_LD_SET;
49221+	ldo_set = (val >> BIT_OFFSET_LDO_SET) & BIT_MASK_LDO_SET;
49222+	r_tuning = (val >> BIT_OFFSET_R_TUNING) & BIT_MASK_R_TUNING;
49223+
49224+#if defined(CONFIG_ARCH_HI3521DV200) || \
49225+	defined(CONFIG_ARCH_HI3520DV500)
49226+	if (!ld_set && !ldo_set && !r_tuning) {
49227+		ld_set = DEF_LD_AM;
49228+		ldo_set = DEF_LDO_AM;
49229+		r_tuning = DEF_R_TUNING;
49230+	}
49231+#endif
49232+
49233+	if (!ld_set && !ldo_set && !r_tuning) {
49234+		hisi_femac_fephy_use_default_trim(data);
49235+		return;
49236+	}
49237+
49238+	val = fephy_expanded_read(bus, phy_addr, REG_LD_AM);
49239+	val = (val & ~BIT_MASK_LD_SET) | (ld_set & BIT_MASK_LD_SET);
49240+	fephy_expanded_write(bus, phy_addr, REG_LD_AM, val);
49241+
49242+	val = fephy_expanded_read(bus, phy_addr, REG_LDO_AM);
49243+	val = (val & ~BIT_MASK_LDO_SET) | (ldo_set & BIT_MASK_LDO_SET);
49244+	fephy_expanded_write(bus, phy_addr, REG_LDO_AM, val);
49245+
49246+	val = fephy_expanded_read(bus, phy_addr, REG_R_TUNING);
49247+	val = (val & ~BIT_MASK_R_TUNING) | (r_tuning & BIT_MASK_R_TUNING);
49248+	fephy_expanded_write(bus, phy_addr, REG_R_TUNING, val);
49249+
49250+	val = fephy_expanded_read(bus, phy_addr, REG_WR_DONE);
49251+	if (val & BIT_CFG_ACK)
49252+		pr_err("festa PHY 0x3053 bit CFG_ACK value: 1\n");
49253+	val = val | BIT_CFG_DONE;
49254+	fephy_expanded_write(bus, phy_addr, REG_WR_DONE, val);
49255+
49256+	do {
49257+		usleep_range(100, 150);
49258+		val = fephy_expanded_read(bus, phy_addr, REG_WR_DONE);
49259+		val &= BIT_CFG_ACK;
49260+	} while (!val && --timeout);
49261+	if (!timeout)
49262+		pr_err("festa PHY 0x3053 wait bit CFG_ACK timeout!\n");
49263+
49264+	mdelay(5);
49265+
49266+	pr_info("FEPHY:addr=%d, la_am=0x%x, ldo_am=0x%x, r_tuning=0x%x\n",
49267+		phy_addr,
49268+		fephy_expanded_read(bus, phy_addr, REG_LD_AM),
49269+		fephy_expanded_read(bus, phy_addr, REG_LDO_AM),
49270+		fephy_expanded_read(bus, phy_addr, REG_R_TUNING));
49271+}
49272+
49273+static void hisi_femac_fephy_reset_and_trim(struct hisi_femac_mdio_data *data)
49274+{
49275+	hisi_femac_fephy_reset(data);
49276+	hisi_femac_fephy_trim(data);
49277+}
49278+
49279+static void hisi_femac_fephy_set_phy_addr(struct hisi_femac_mdio_data *data)
49280+{
49281+	u32 val;
49282+
49283+	if (!data->fephy_iobase)
49284+		return;
49285+
49286+	val = readl(data->fephy_iobase);
49287+	val &= ~BIT_MASK_FEPHY_ADDR;
49288+	val |= (data->phy_addr + 1);
49289+	writel(val, data->fephy_iobase);
49290+}
49291+
49292+static int hisi_femac_mdio_probe(struct platform_device *pdev)
49293+{
49294+	struct device_node *np = pdev->dev.of_node;
49295+	struct mii_bus *bus = NULL;
49296+	struct hisi_femac_mdio_data *data = NULL;
49297+	struct resource *res = NULL;
49298+	int ret;
49299+
49300+	bus = mdiobus_alloc_size(sizeof(*data));
49301+	if (!bus)
49302+		return -ENOMEM;
49303+
49304+	bus->name = "hisi_femac_mii_bus";
49305+	bus->read = &hisi_femac_mdio_read;
49306+	bus->write = &hisi_femac_mdio_write;
49307+	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", pdev->name);
49308+	bus->parent = &pdev->dev;
49309+
49310+	data = bus->priv;
49311+	data->bus = bus;
49312+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
49313+	data->membase = devm_ioremap_resource(&pdev->dev, res);
49314+	if (IS_ERR(data->membase)) {
49315+		ret = PTR_ERR(data->membase);
49316+		goto err_out_free_mdiobus;
49317+	}
49318+
49319+	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
49320+	if (res) {
49321+		data->fephy_iobase = devm_ioremap_resource(&pdev->dev, res);
49322+		if (IS_ERR(data->fephy_iobase)) {
49323+			ret = PTR_ERR(data->fephy_iobase);
49324+			goto err_out_free_mdiobus;
49325+		}
49326+	} else {
49327+		data->fephy_iobase = NULL;
49328+	}
49329+
49330+	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
49331+	if (res) {
49332+		data->fephy_trim_iobase = devm_ioremap_resource(&pdev->dev,
49333+								res);
49334+		if (IS_ERR(data->fephy_trim_iobase)) {
49335+			ret = PTR_ERR(data->fephy_trim_iobase);
49336+			goto err_out_free_mdiobus;
49337+		}
49338+	} else {
49339+		data->fephy_trim_iobase = NULL;
49340+	}
49341+
49342+	data->clk = devm_clk_get(&pdev->dev, "mdio");
49343+	if (IS_ERR(data->clk)) {
49344+		ret = PTR_ERR(data->clk);
49345+		goto err_out_free_mdiobus;
49346+	}
49347+
49348+	data->fephy_clk = devm_clk_get(&pdev->dev, "phy");
49349+	if (IS_ERR(data->fephy_clk))
49350+		data->fephy_clk = NULL;
49351+
49352+	ret = clk_prepare_enable(data->clk);
49353+	if (ret)
49354+		goto err_out_free_mdiobus;
49355+
49356+	data->phy_rst = devm_reset_control_get(&pdev->dev, "external-phy");
49357+	if (IS_ERR(data->phy_rst)) {
49358+		data->phy_rst = NULL;
49359+	} else {
49360+		ret = of_property_read_u32_array(np,
49361+						 PHY_RESET_DELAYS_PROPERTY,
49362+						 data->phy_reset_delays,
49363+						 DELAYS_NUM);
49364+		if (ret)
49365+			goto err_out_disable_clk;
49366+		hisi_femac_phy_reset(data);
49367+	}
49368+
49369+	data->fephy_rst = devm_reset_control_get(&pdev->dev, "internal-phy");
49370+	if (IS_ERR(data->fephy_rst))
49371+		data->fephy_rst = NULL;
49372+
49373+	hisi_femac_get_phy_addr(data, np);
49374+	if (hisi_femac_use_fephy(data))
49375+		hisi_femac_fephy_reset_and_trim(data);
49376+	else
49377+		hisi_femac_fephy_set_phy_addr(data);
49378+
49379+	ret = of_mdiobus_register(bus, np);
49380+	if (ret)
49381+		goto err_out_disable_clk;
49382+
49383+	platform_set_drvdata(pdev, bus);
49384+
49385+	return 0;
49386+
49387+err_out_disable_clk:
49388+	clk_disable_unprepare(data->fephy_clk);
49389+	clk_disable_unprepare(data->clk);
49390+err_out_free_mdiobus:
49391+	mdiobus_free(bus);
49392+	return ret;
49393+}
49394+
49395+static int hisi_femac_mdio_remove(struct platform_device *pdev)
49396+{
49397+	struct mii_bus *bus = platform_get_drvdata(pdev);
49398+	struct hisi_femac_mdio_data *data = bus->priv;
49399+
49400+	mdiobus_unregister(bus);
49401+	clk_disable_unprepare(data->clk);
49402+	mdiobus_free(bus);
49403+
49404+	return 0;
49405+}
49406+
49407+static const struct of_device_id hisi_femac_mdio_dt_ids[] = {
49408+	{ .compatible = "hisilicon,hisi-femac-mdio" },
49409+	{ }
49410+};
49411+MODULE_DEVICE_TABLE(of, hisi_femac_mdio_dt_ids);
49412+
49413+static struct platform_driver hisi_femac_mdio_driver = {
49414+	.probe = hisi_femac_mdio_probe,
49415+	.remove = hisi_femac_mdio_remove,
49416+	.driver = {
49417+		.name = "hisi-femac-mdio",
49418+		.of_match_table = hisi_femac_mdio_dt_ids,
49419+	},
49420+};
49421+
49422+module_platform_driver(hisi_femac_mdio_driver);
49423+
49424+MODULE_DESCRIPTION("Hisilicon Fast Ethernet MAC MDIO interface driver");
49425+MODULE_AUTHOR("Hisilicon>");
49426+MODULE_LICENSE("GPL v2");
49427diff --git a/drivers/net/phy/mdio_hisi_gemac.c b/drivers/net/phy/mdio_hisi_gemac.c
49428new file mode 100644
49429index 000000000..79ebfa400
49430--- /dev/null
49431+++ b/drivers/net/phy/mdio_hisi_gemac.c
49432@@ -0,0 +1,256 @@
49433+/*
49434+ * Hisilicon Gigabit Ethernet MDIO Bus Driver
49435+ *
49436+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
49437+ *
49438+ * This program is free software; you can redistribute it and/or modify
49439+ * it under the terms of the GNU General Public License as published by
49440+ * the Free Software Foundation; either version 2 of the License, or
49441+ * (at your option) any later version.
49442+ *
49443+ * This program is distributed in the hope that it will be useful,
49444+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
49445+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
49446+ * GNU General Public License for more details.
49447+ *
49448+ * You should have received a copy of the GNU General Public License
49449+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
49450+ */
49451+
49452+#include <linux/clk.h>
49453+#include <linux/iopoll.h>
49454+#include <linux/kernel.h>
49455+#include <linux/module.h>
49456+#include <linux/of_address.h>
49457+#include <linux/of_mdio.h>
49458+#include <linux/platform_device.h>
49459+#include <linux/reset.h>
49460+#include "mdio_hisi_gemac.h"
49461+
49462+#if defined(CONFIG_ARCH_HI3519) || defined(CONFIG_ARCH_HI3519V101) || \
49463+	defined(CONFIG_ARCH_HI3516AV200)
49464+#ifdef readl
49465+#undef readl
49466+#undef writel
49467+#define readl		hi_readl
49468+#define writel		hi_writel
49469+#endif
49470+#endif
49471+
49472+#define MDIO_SINGLE_CMD		0x00
49473+#define MDIO_SINGLE_DATA	0x04
49474+#define MDIO_RDATA_STATUS	0x10
49475+#define BIT_PHY_ADDR_OFFSET	8
49476+#define MDIO_WRITE		BIT(16)
49477+#define MDIO_READ		BIT(17)
49478+#define MDIO_START		BIT(20)
49479+#define MDIO_START_READ		(MDIO_START | MDIO_READ)
49480+#define MDIO_START_WRITE	(MDIO_START | MDIO_WRITE)
49481+
49482+struct hisi_gemac_mdio_data {
49483+	struct clk *clk;
49484+	struct reset_control *phy_rst;
49485+	void __iomem *membase;
49486+};
49487+
49488+static int hisi_gemac_mdio_wait_ready(struct hisi_gemac_mdio_data *data)
49489+{
49490+	u32 val;
49491+
49492+	return readl_poll_timeout(data->membase + MDIO_SINGLE_CMD,
49493+				  val, !(val & MDIO_START), 20, 10000);
49494+}
49495+
49496+static int hisi_gemac_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
49497+{
49498+	struct hisi_gemac_mdio_data *data = bus->priv;
49499+	int ret;
49500+
49501+	ret = hisi_gemac_mdio_wait_ready(data);
49502+	if (ret)
49503+		return ret;
49504+
49505+	writel(MDIO_START_READ | ((u32)mii_id << BIT_PHY_ADDR_OFFSET) |
49506+	       ((u32)regnum),
49507+	       data->membase + MDIO_SINGLE_CMD);
49508+
49509+	ret = hisi_gemac_mdio_wait_ready(data);
49510+	if (ret)
49511+		return ret;
49512+
49513+	/* if read data is invalid, we just return 0 instead of -EAGAIN.
49514+	 * This can make MDIO more robust when reading PHY status.
49515+	 */
49516+	if (readl(data->membase + MDIO_RDATA_STATUS))
49517+		return 0;
49518+
49519+	return readl(data->membase + MDIO_SINGLE_DATA) >> 16;
49520+}
49521+
49522+static int hisi_gemac_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
49523+				 u16 value)
49524+{
49525+	struct hisi_gemac_mdio_data *data = bus->priv;
49526+	int ret;
49527+
49528+	ret = hisi_gemac_mdio_wait_ready(data);
49529+	if (ret)
49530+		return ret;
49531+
49532+	writel(value, data->membase + MDIO_SINGLE_DATA);
49533+	writel(MDIO_START_WRITE | ((u32)mii_id << BIT_PHY_ADDR_OFFSET) |
49534+	       ((u32)regnum),
49535+	       data->membase + MDIO_SINGLE_CMD);
49536+
49537+	return hisi_gemac_mdio_wait_ready(data);
49538+}
49539+
49540+static void hisi_gemac_external_phy_reset(struct hisi_gemac_mdio_data const *data)
49541+{
49542+	if (data->phy_rst) {
49543+		/* write 0 to cancel reset */
49544+		reset_control_deassert(data->phy_rst);
49545+		msleep(50);
49546+
49547+		/* HIFONE or 98cv200 use CRG register to reset phy */
49548+		/* RST_BIT, write 0 to reset phy, write 1 to cancel reset */
49549+		reset_control_assert(data->phy_rst);
49550+
49551+		/* delay some time to ensure reset ok,
49552+		 * this depends on PHY hardware feature
49553+		 */
49554+		msleep(50);
49555+
49556+		/* write 0 to cancel reset */
49557+		reset_control_deassert(data->phy_rst);
49558+		/* delay some time to ensure later MDIO access */
49559+		msleep(50);
49560+	} else {
49561+#if defined(CONFIG_ARCH_HI3516A)
49562+#include <mach/hi3516a_io.h>
49563+#define GPIO_BASE_ETH_PHY_RESET		0x20140000
49564+#define GPIO_BIT_ETH_PHY_RESET		1
49565+		void __iomem *gpio_base;
49566+		u32 val;
49567+
49568+		gpio_base = (void __iomem *)IO_ADDRESS(GPIO_BASE_ETH_PHY_RESET);
49569+		/* use GPIO to do hardware PHY reset */
49570+		/* set direction */
49571+		val = readl(gpio_base + 0x400);
49572+		val |= (1 << GPIO_BIT_ETH_PHY_RESET);
49573+		writel(val, gpio_base + 0x400);
49574+
49575+		/* Firstly, set to 1 regardless of the value of this pin */
49576+		writel(0xFF, gpio_base + (4 << GPIO_BIT_ETH_PHY_RESET));
49577+		msleep(20);
49578+
49579+		/* Set to 0 to reset, then sleep 200ms */
49580+		writel(0x0, gpio_base + (4 << GPIO_BIT_ETH_PHY_RESET));
49581+		msleep(20);
49582+
49583+		/* then, cancel reset, and should sleep 50ms */
49584+		writel(0xFF, gpio_base + (4 << GPIO_BIT_ETH_PHY_RESET));
49585+		msleep(200);
49586+#endif
49587+	}
49588+}
49589+
49590+static int hisi_gemac_mdio_probe(struct platform_device *pdev)
49591+{
49592+	struct device_node *np = pdev->dev.of_node;
49593+	struct mii_bus *bus = NULL;
49594+	struct hisi_gemac_mdio_data *data = NULL;
49595+	struct resource *res = NULL;
49596+	int ret;
49597+
49598+	ret = hisi_gemac_pinctrl_config(pdev);
49599+	if (ret) {
49600+		pr_err("higmac pinctrl config error=%d.\n", ret);
49601+		return ret;
49602+	}
49603+
49604+	bus = mdiobus_alloc_size(sizeof(*data));
49605+	if (!bus)
49606+		return -ENOMEM;
49607+
49608+	bus->name = "hisi_gemac_mii_bus";
49609+	bus->read = &hisi_gemac_mdio_read;
49610+	bus->write = &hisi_gemac_mdio_write;
49611+	snprintf(bus->id, MII_BUS_ID_SIZE, "%s", pdev->name);
49612+	bus->parent = &pdev->dev;
49613+
49614+	data = bus->priv;
49615+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
49616+	if (res == NULL || data == NULL) {
49617+		ret = -ENXIO;
49618+		goto err_out_free_mdiobus;
49619+	}
49620+	data->membase = devm_ioremap(&pdev->dev, res->start,
49621+				     resource_size(res));
49622+	if (!data->membase) {
49623+		ret = -ENOMEM;
49624+		goto err_out_free_mdiobus;
49625+	}
49626+
49627+	data->clk = devm_clk_get(&pdev->dev, NULL);
49628+	if (IS_ERR(data->clk)) {
49629+		ret = PTR_ERR(data->clk);
49630+		goto err_out_free_mdiobus;
49631+	}
49632+
49633+	ret = clk_prepare_enable(data->clk);
49634+	if (ret)
49635+		goto err_out_free_mdiobus;
49636+
49637+	data->phy_rst = devm_reset_control_get(&pdev->dev, "phy_reset");
49638+	if (IS_ERR(data->phy_rst))
49639+		data->phy_rst = NULL;
49640+	hisi_gemac_external_phy_reset(data);
49641+
49642+	ret = of_mdiobus_register(bus, np);
49643+	if (ret)
49644+		goto err_out_disable_clk;
49645+
49646+	platform_set_drvdata(pdev, bus);
49647+
49648+	return 0;
49649+
49650+err_out_disable_clk:
49651+	clk_disable_unprepare(data->clk);
49652+err_out_free_mdiobus:
49653+	mdiobus_free(bus);
49654+	return ret;
49655+}
49656+
49657+static int hisi_gemac_mdio_remove(struct platform_device *pdev)
49658+{
49659+	struct mii_bus *bus = platform_get_drvdata(pdev);
49660+	struct hisi_gemac_mdio_data *data = bus->priv;
49661+
49662+	mdiobus_unregister(bus);
49663+	clk_disable_unprepare(data->clk);
49664+	mdiobus_free(bus);
49665+
49666+	return 0;
49667+}
49668+
49669+static const struct of_device_id hisi_gemac_mdio_dt_ids[] = {
49670+	{ .compatible = "hisilicon,hisi-gemac-mdio" },
49671+	{ }
49672+};
49673+MODULE_DEVICE_TABLE(of, hisi_gemac_mdio_dt_ids);
49674+
49675+static struct platform_driver hisi_gemac_mdio_driver = {
49676+	.probe = hisi_gemac_mdio_probe,
49677+	.remove = hisi_gemac_mdio_remove,
49678+	.driver = {
49679+		.name = "hisi-gemac-mdio",
49680+		.of_match_table = hisi_gemac_mdio_dt_ids,
49681+	},
49682+};
49683+
49684+module_platform_driver(hisi_gemac_mdio_driver);
49685+
49686+MODULE_DESCRIPTION("Hisilicon Gigabit Ethernet MAC MDIO interface driver");
49687+MODULE_AUTHOR("Hisilicon>");
49688+MODULE_LICENSE("GPL v2");
49689diff --git a/drivers/net/phy/mdio_hisi_gemac.h b/drivers/net/phy/mdio_hisi_gemac.h
49690new file mode 100644
49691index 000000000..5eefc01e5
49692--- /dev/null
49693+++ b/drivers/net/phy/mdio_hisi_gemac.h
49694@@ -0,0 +1,32 @@
49695+/*
49696+ * Hisilicon gemac pinout config headerfile.
49697+ *
49698+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2019. All rights reserved.
49699+ *
49700+ * This program is free software; you can redistribute it and/or modify
49701+ * it under the terms of the GNU General Public License as published by
49702+ * the Free Software Foundation; either version 2 of the License, or
49703+ * (at your option) any later version.
49704+ *
49705+ * This program is distributed in the hope that it will be useful,
49706+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
49707+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
49708+ * GNU General Public License for more details.
49709+ *
49710+ * You should have received a copy of the GNU General Public License
49711+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
49712+ */
49713+
49714+#ifndef __MDIO_HISI_GEMAC_H__
49715+#define  __MDIO_HISI_GEMAC_H__
49716+
49717+#if defined(CONFIG_ARCH_HI3531DV200) || defined(CONFIG_ARCH_HI3535AV100)
49718+int hisi_gemac_pinctrl_config(struct platform_device *pdev);
49719+#else
49720+static inline int hisi_gemac_pinctrl_config(struct platform_device *pdev)
49721+{
49722+	return 0;
49723+}
49724+#endif
49725+
49726+#endif /* __MDIO_HISI_GEMAC_H__ */
49727diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
49728index db7866b6f..413159372 100644
49729--- a/drivers/net/phy/phy.c
49730+++ b/drivers/net/phy/phy.c
49731@@ -260,6 +260,28 @@ static void phy_sanitize_settings(struct phy_device *phydev)
49732 	}
49733 }
49734
49735+int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd)
49736+{
49737+	cmd->supported = phydev->supported;
49738+
49739+	cmd->advertising = phydev->advertising;
49740+	cmd->lp_advertising = phydev->lp_advertising;
49741+
49742+	ethtool_cmd_speed_set(cmd, phydev->speed);
49743+	cmd->duplex = phydev->duplex;
49744+	if (phydev->interface == PHY_INTERFACE_MODE_MOCA)
49745+		cmd->port = PORT_BNC;
49746+	else
49747+		cmd->port = PORT_MII;
49748+	cmd->phy_address = phydev->mdio.addr;
49749+	cmd->transceiver = phy_is_internal(phydev) ?
49750+		XCVR_INTERNAL : XCVR_EXTERNAL;
49751+	cmd->autoneg = phydev->autoneg;
49752+	cmd->eth_tp_mdix_ctrl = phydev->mdix;
49753+
49754+	return 0;
49755+}
49756+EXPORT_SYMBOL(phy_ethtool_gset);
49757 void phy_ethtool_ksettings_get(struct phy_device *phydev,
49758 			       struct ethtool_link_ksettings *cmd)
49759 {
49760diff --git a/drivers/net/phy/realtek.c b/drivers/net/phy/realtek.c
49761index b4879306b..cb7b1635c 100644
49762--- a/drivers/net/phy/realtek.c
49763+++ b/drivers/net/phy/realtek.c
49764@@ -29,6 +29,12 @@
49765 #define RTL8211F_PHYCR1				0x18
49766 #define RTL8211F_INSR				0x1d
49767
49768+/* RTL8211F RGMII requires special TX delays depending
49769+   on the actual hardware circuit/wiring.
49770+   TXDLY register does not need to be set
49771+   when pin No.25 via 4.7k-ohm to DVDD-RG.
49772+*/
49773+#define RTL8211F_RGMII_TX_DELAY_ENABLE  1
49774 #define RTL8211F_TX_DELAY			BIT(8)
49775 #define RTL8211F_RX_DELAY			BIT(3)
49776
49777@@ -185,6 +191,10 @@ static int rtl8211f_config_init(struct phy_device *phydev)
49778 	u16 val;
49779 	int ret;
49780
49781+#if RTL8211F_RGMII_TX_DELAY_ENABLE
49782+	if (phydev->interface == PHY_INTERFACE_MODE_RGMII)
49783+		return ret;
49784+#endif
49785 	val = RTL8211F_ALDPS_ENABLE | RTL8211F_ALDPS_PLL_OFF | RTL8211F_ALDPS_XTAL_OFF;
49786 	phy_modify_paged_changed(phydev, 0xa43, RTL8211F_PHYCR1, val, val);
49787
49788diff --git a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
49789index 0d374a294..9f2151377 100644
49790--- a/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
49791+++ b/drivers/net/wireless/realtek/rtl8xxxu/rtl8xxxu_core.c
49792@@ -5806,6 +5806,7 @@ static int rtl8xxxu_submit_int_urb(struct ieee80211_hw *hw)
49793 	ret = usb_submit_urb(urb, GFP_KERNEL);
49794 	if (ret) {
49795 		usb_unanchor_urb(urb);
49796+		usb_free_urb(urb);
49797 		goto error;
49798 	}
49799
49800diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
49801index 0c473d75e..cb9f492fd 100644
49802--- a/drivers/pci/Kconfig
49803+++ b/drivers/pci/Kconfig
49804@@ -256,5 +256,6 @@ source "drivers/pci/hotplug/Kconfig"
49805 source "drivers/pci/controller/Kconfig"
49806 source "drivers/pci/endpoint/Kconfig"
49807 source "drivers/pci/switch/Kconfig"
49808+source "drivers/pci/hipcie/Kconfig"
49809
49810 endif
49811diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
49812index 522d2b974..2b9167379 100644
49813--- a/drivers/pci/Makefile
49814+++ b/drivers/pci/Makefile
49815@@ -36,5 +36,6 @@ obj-$(CONFIG_PCI_ENDPOINT)	+= endpoint/
49816
49817 obj-y				+= controller/
49818 obj-y				+= switch/
49819+obj-$(CONFIG_HIPCIE) += hipcie/
49820
49821 ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG
49822diff --git a/drivers/pci/hipcie/Kconfig b/drivers/pci/hipcie/Kconfig
49823new file mode 100644
49824index 000000000..c8d88ef66
49825--- /dev/null
49826+++ b/drivers/pci/hipcie/Kconfig
49827@@ -0,0 +1,27 @@
49828+menuconfig HIPCIE
49829+	bool "Hisilicon PCI Express support"
49830+	depends on PCI && (ARCH_HI3531DV200 || ARCH_HI3535AV100 || ARCH_HI3559AV100 || ARCH_HI3531A || ARCH_HI3519AV100 || ARCH_HI3568V100 || ARCH_HI3569V100)
49831+	default y if PCI
49832+	default n if ! PCI
49833+	help
49834+	 Hisilicon PCI Express support
49835+	 Choose this selection to support PCI Express uses.
49836+
49837+if HIPCIE
49838+
49839+menu "PCI Express configs"
49840+
49841+
49842+config LIMIT_MAX_RD_REQ_SIZE
49843+	bool "limit pcie max read request size"
49844+	depends on PCI && (ARCH_HI3531DV200 || ARCH_HI3535AV100 || ARCH_HI3559AV100 || ARCH_HI3531A || ARCH_HI3519AV100 || ARCH_HI3568V100 || ARCH_HI3569V100)
49845+	help
49846+	 The default max read request size of pcie device is 512 Byte. When pcie use
49847+	 the card of pcie-to-sata to connect to the sata disk, with the default max read
49848+	 request size value of 512 byte, would cause the low bandwidth of VDP. If you enable
49849+	 the LIMIT_MAX_RD_REQ_SIZE config, the max read request size of pcie device would be
49850+	 set to 128 byte, and the problem of VDP low band width also be avoided.
49851+
49852+endmenu
49853+
49854+endif
49855diff --git a/drivers/pci/hipcie/Makefile b/drivers/pci/hipcie/Makefile
49856new file mode 100644
49857index 000000000..04554201e
49858--- /dev/null
49859+++ b/drivers/pci/hipcie/Makefile
49860@@ -0,0 +1,8 @@
49861+
49862+obj-$(CONFIG_HIPCIE) += hipcie.o
49863+
49864+hipcie-objs	:= pcie.o
49865+
49866+ifeq ($(CONFIG_PCI_DEBUG),y)
49867+	        EXTRA_CFLAGS += -DPCIE_DEBUG
49868+endif
49869diff --git a/drivers/pci/hipcie/pci.h b/drivers/pci/hipcie/pci.h
49870new file mode 100644
49871index 000000000..daefc0faf
49872--- /dev/null
49873+++ b/drivers/pci/hipcie/pci.h
49874@@ -0,0 +1,96 @@
49875+/*
49876+ *  arch/arm/include/asm/mach/pci.h
49877+ *
49878+ *  Copyright (C) 2000 Russell King
49879+ *
49880+ * This program is free software; you can redistribute it and/or modify
49881+ * it under the terms of the GNU General Public License version 2 as
49882+ * published by the Free Software Foundation.
49883+ */
49884+
49885+#ifndef __ASM_MACH_PCI_H
49886+#define __ASM_MACH_PCI_H
49887+
49888+#include <linux/ioport.h>
49889+
49890+struct pci_sys_data;
49891+struct pci_ops;
49892+struct pci_bus;
49893+struct device;
49894+
49895+#ifdef CONFIG_PCI_MSI
49896+#define HISI_PCI_MSI_NR (8 * 32)
49897+struct hisi_msi {
49898+	struct msi_controller chip;
49899+	DECLARE_BITMAP(used, HISI_PCI_MSI_NR);
49900+	struct irq_domain *domain;
49901+	unsigned long pages;
49902+	struct mutex lock;
49903+	int irq;
49904+};
49905+#endif
49906+
49907+struct hw_pci {
49908+#ifdef CONFIG_PCI_DOMAINS
49909+	int domain;
49910+#endif
49911+#ifdef CONFIG_PCI_MSI
49912+	struct hisi_msi msi;
49913+#endif
49914+	struct device *dev;
49915+	struct pci_ops *ops;
49916+	int nr_controllers;
49917+	void **private_data;
49918+	int (*setup)(int nr, struct pci_sys_data *);
49919+	struct pci_bus *(*scan)(int nr, struct pci_sys_data *);
49920+	void (*preinit)(void);
49921+	void (*postinit)(void);
49922+	u8 (*swizzle)(struct pci_dev *dev, u8 *pin);
49923+	int (*map_irq)(const struct pci_dev *dev, u8 slot, u8 pin);
49924+	resource_size_t (*align_resource)(struct pci_dev *dev,
49925+					  const struct resource *res,
49926+					  resource_size_t start,
49927+					  resource_size_t size,
49928+					  resource_size_t align);
49929+	void (*add_bus)(struct pci_bus *bus);
49930+	void (*remove_bus)(struct pci_bus *bus);
49931+};
49932+
49933+/*
49934+ * Per-controller structure
49935+ */
49936+struct pci_sys_data {
49937+#ifdef CONFIG_PCI_DOMAINS
49938+	int domain;
49939+#endif
49940+	struct list_head node;
49941+	int busnr; /* primary bus number			*/
49942+	u64 mem_offset; /* bus->cpu memory mapping offset	*/
49943+	unsigned long io_offset; /* bus->cpu IO mapping offset		*/
49944+	struct pci_bus *bus; /* PCI bus				*/
49945+	struct list_head resources; /* root bus resources (apertures)       */
49946+	struct resource io_res;
49947+	char io_res_name[12];
49948+	/* Bridge swizzling */
49949+	u8 (*swizzle)(struct pci_dev *, u8 *);
49950+	/* IRQ mapping */
49951+	int (*map_irq)(const struct pci_dev *, u8, u8);
49952+	/* Resource alignement requirements	*/
49953+	resource_size_t (*align_resource)(struct pci_dev *dev,
49954+					  const struct resource *res,
49955+					  resource_size_t start,
49956+					  resource_size_t size,
49957+					  resource_size_t align);
49958+	void (*add_bus)(struct pci_bus *bus);
49959+	void (*remove_bus)(struct pci_bus *bus);
49960+	void *private_data; /* platform controller private data	*/
49961+};
49962+
49963+void __weak pcibios_update_irq(struct pci_dev *dev, int irq)
49964+{
49965+	dev_dbg(&dev->dev, "assigning IRQ %02d\n", irq);
49966+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq);
49967+}
49968+
49969+
49970+#endif /* __ASM_MACH_PCI_H */
49971diff --git a/drivers/pci/hipcie/pcie.c b/drivers/pci/hipcie/pcie.c
49972new file mode 100644
49973index 000000000..4c44b6b44
49974--- /dev/null
49975+++ b/drivers/pci/hipcie/pcie.c
49976@@ -0,0 +1,985 @@
49977+/*
49978+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
49979+ *
49980+ * This program is free software; you can redistribute it and/or modify
49981+ * it under the terms of the GNU General Public License as published by
49982+ * the Free Software Foundation; either version 2 of the License, or
49983+ * (at your option) any later version.
49984+ *
49985+ * This program is distributed in the hope that it will be useful,
49986+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
49987+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
49988+ * GNU General Public License for more details.
49989+ *
49990+ * You should have received a copy of the GNU General Public License
49991+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
49992+ */
49993+
49994+#include <linux/module.h>
49995+#include <linux/kernel.h>
49996+#include <linux/pci.h>
49997+#include <linux/mbus.h>
49998+#include <asm/irq.h>
49999+#include <linux/of.h>
50000+#include <linux/of_pci.h>
50001+#include <linux/platform_device.h>
50002+#include <linux/delay.h>
50003+#include <linux/spinlock.h>
50004+#include <linux/version.h>
50005+#include <asm/siginfo.h>
50006+#include <linux/interrupt.h>
50007+#include <linux/irq.h>
50008+#include <linux/irqdomain.h>
50009+#include <linux/msi.h>
50010+#include <linux/of_irq.h>
50011+#include "../pci.h"
50012+#ifdef CONFIG_ARM64
50013+#include "pci.h"
50014+#endif
50015+
50016+#define PCIE_DBG_REG		1
50017+#define PCIE_DBG_FUNC		2
50018+#define PCIE_DBG_MODULE		3
50019+
50020+#define PCIE_DEBUG_LEVEL PCIE_DBG_MODULE
50021+
50022+/* #define PCIE_DEBUG */
50023+#ifdef PCIE_DEBUG
50024+#define pcie_debug(level, str, arg...) \
50025+	do { \
50026+		if ((level) <= PCIE_DEBUG_LEVEL) { \
50027+			pr_debug("%s->%d," str "\n", \
50028+				__func__, __LINE__, ##arg); \
50029+		} \
50030+	} while (0)
50031+#else
50032+#define pcie_debug(level, str, arg...)
50033+#endif
50034+
50035+#define pcie_assert(con) \
50036+	do { \
50037+		if (!(con)) { \
50038+			pr_err("%s->%d,assert fail!\n", \
50039+				__func__, __LINE__); \
50040+		} \
50041+	} while (0)
50042+
50043+#define pcie_error(str, arg...) \
50044+	pr_err("%s->%d" str "\n", __func__, __LINE__, ##arg)
50045+
50046+#define __256MB__ 0x10000000
50047+#define __128MB__ 0x8000000
50048+#define __4KB__ 0x1000
50049+#define __8KB__ 0x2000
50050+#define __16KB__ 0x4000
50051+
50052+enum pcie_sel {
50053+	/*
50054+	 * No controller selected.
50055+	 */
50056+	pcie_sel_none,
50057+	/*
50058+	 * PCIE0 selected.
50059+	 */
50060+	pcie0_x1_sel,
50061+	/*
50062+	 * PCIE1 selected.
50063+	 */
50064+	pcie1_x1_sel
50065+};
50066+
50067+enum pcie_rc_sel {
50068+	pcie_controller_unselected,
50069+	pcie_controller_selected
50070+};
50071+
50072+enum pcie_controller {
50073+	pcie_controller_none = -1,
50074+	pcie_controller_0 = 0,
50075+	pcie_controller_1 = 1
50076+};
50077+
50078+struct pcie_iatu {
50079+	unsigned int viewport;          /* iATU Viewport Register        */
50080+	unsigned int region_ctrl_1;     /* Region Control 1 Register     */
50081+	unsigned int region_ctrl_2;     /* Region Control 2 Register     */
50082+	unsigned int lbar;              /* Lower Base Address Register   */
50083+	unsigned int ubar;              /* Upper Base Address Register   */
50084+	unsigned int lar;               /* Limit Address Register        */
50085+	unsigned int ltar; /* Lower Target Address Register */
50086+	unsigned int utar;              /* Upper Target Address Register */
50087+};
50088+
50089+#define MAX_IATU_PER_CTRLLER	(6)
50090+
50091+struct pcie_info {
50092+	/*
50093+	 * Root bus number
50094+	 */
50095+	int		root_bus_nr;
50096+	enum		pcie_controller controller;
50097+
50098+	/*
50099+	 * Devices configuration space base
50100+	 */
50101+	unsigned long	base_addr;
50102+
50103+	/*
50104+	 * RC configuration space base
50105+	 */
50106+	unsigned long	conf_base_addr;
50107+};
50108+
50109+#define MAX_PCIE_CONTROLLER_NUM  2
50110+static struct pcie_info pcie_info[MAX_PCIE_CONTROLLER_NUM] = {
50111+	{ .root_bus_nr = -1, },
50112+	{ .root_bus_nr = -1, }
50113+};
50114+
50115+static int pcie_controllers_nr;
50116+
50117+static unsigned int pcie_errorvalue;
50118+
50119+struct device_node *g_of_node = NULL;
50120+
50121+static DEFINE_SPINLOCK(cw_lock);
50122+
50123+#define msi_contrl_interrupt 0x830
50124+#define MSI_CTRL_UPPER_ADDR_OFF 0x824
50125+#define MSI_CTRL_ADDR_OFF 0x820
50126+#define MSI_CTRL_INT_EN_OFF0 0x828
50127+#define MSI_CTRL_INT_EN_OFF1 0x834
50128+#define MSI_CTRL_INT_EN_OFF2 0x840
50129+#define MSI_CTRL_INT_EN_OFF3 0x84c
50130+#define MSI_CTRL_INT_EN_OFF4 0x858
50131+#define MSI_CTRL_INT_EN_OFF5 0x864
50132+#define MSI_CTRL_INT_EN_OFF6 0x870
50133+#define MSI_CTRL_INT_EN_OFF7 0x87c
50134+
50135+#define PCIE0_MODE_SEL  (1 << 0)
50136+#define PCIE1_MODE_SEL  (1 << 1)
50137+
50138+#if defined(CONFIG_ARCH_HI3531DV200)
50139+#include "pcie_hi3531dv200.c"
50140+#elif defined(CONFIG_ARCH_HI3535AV100)
50141+#include "pcie_hi3535av100.c"
50142+#elif defined(CONFIG_ARCH_HI3519AV100)
50143+#include "pcie_hi3519av100.c"
50144+#elif defined(CONFIG_ARCH_HI3559AV100)
50145+#include "pcie_hi3559av100.c"
50146+#else
50147+#error You must have defined CONFIG_ARCH_HI35xx...
50148+#endif
50149+
50150+static struct pcie_info *bus_to_info(int busnr)
50151+{
50152+	int i = pcie_controllers_nr;
50153+	for (; i >= 0; i--) {
50154+		if (pcie_info[i].controller != pcie_controller_none
50155+				&& pcie_info[i].root_bus_nr <= busnr
50156+				&& pcie_info[i].root_bus_nr != -1)
50157+			return &pcie_info[i];
50158+	}
50159+
50160+	return NULL;
50161+}
50162+
50163+#define PCIE_CFG_BUS(busnr) ((busnr & 0xff) << 20)
50164+#define PCIE_CFG_DEV(devfn) ((devfn & 0xff) << 12)
50165+#define PCIE_CFG_REG(reg) (reg & 0xffc) /* set dword align */
50166+
50167+static inline unsigned long to_pcie_address(struct pci_bus *bus,
50168+		unsigned int devfn, int where)
50169+{
50170+	struct pcie_info *info = bus_to_info(bus->number);
50171+	unsigned long address = 0;
50172+
50173+	if (unlikely(!info)) {
50174+		pcie_error(
50175+			"%s:Cannot find corresponding controller for appointed device!", __func__);
50176+		BUG();
50177+	}
50178+
50179+	address = info->base_addr + (PCIE_CFG_BUS(bus->number)
50180+				     | PCIE_CFG_DEV(devfn) | PCIE_CFG_REG((unsigned int)where));
50181+
50182+	return address;
50183+}
50184+
50185+static inline int is_pcie_link_up(struct pcie_info *info)
50186+{
50187+	int i;
50188+
50189+	for (i = 0; i < 10000; i++) {
50190+		if (__arch_check_pcie_link(info))
50191+			break;
50192+		udelay(100);
50193+	}
50194+
50195+	return (i < 10000);
50196+}
50197+
50198+static int pcie_read_from_device(struct pci_bus *bus, unsigned int devfn,
50199+				 int where, int size, u32 *value)
50200+{
50201+	struct pcie_info *info = bus_to_info(bus->number);
50202+	unsigned int val;
50203+	void __iomem *addr;
50204+	int i = 0;
50205+
50206+	if (unlikely(!info)) {
50207+		pcie_error(
50208+			"%s:Cannot find corresponding controller for appointed device!", __func__);
50209+		BUG();
50210+	}
50211+	if (!is_pcie_link_up(info)) {
50212+		pcie_debug(PCIE_DBG_MODULE, "pcie %d not link up!",
50213+			   info->controller);
50214+		return -1;
50215+	}
50216+
50217+	addr = (void __iomem *)(uintptr_t)to_pcie_address(bus, devfn, where);
50218+
50219+	val = readl(addr);
50220+
50221+	i = 0;
50222+	while (i < 2000) {
50223+		__asm__ __volatile__("nop\n");
50224+		i++;
50225+	}
50226+
50227+	if (pcie_errorvalue == 1) {
50228+		pcie_errorvalue = 0;
50229+		val = 0xffffffff;
50230+	}
50231+
50232+	if (size == 1)
50233+		*value = ((val >> (((unsigned int)where & 0x3) << 3)) & 0xff);
50234+	else if (size == 2)
50235+		*value = ((val >> (((unsigned int)where & 0x3) << 3)) & 0xffff);
50236+	else if (size == 4)
50237+		*value = val;
50238+	else {
50239+		pcie_error("Unknown size(%d) for read ops", size);
50240+		BUG();
50241+	}
50242+
50243+	return PCIBIOS_SUCCESSFUL;
50244+}
50245+
50246+static int pcie_read_from_dbi(struct pcie_info *info, unsigned int devfn,
50247+			      int where, int size, u32 *value)
50248+{
50249+	unsigned int val;
50250+
50251+	/*
50252+	 * For host-side config space read, ignore device func nr.
50253+	 */
50254+	if (devfn > 0)
50255+		return -EIO;
50256+
50257+	val = (u32)readl((void *)(uintptr_t)(info->conf_base_addr +
50258+					     ((unsigned int)where & (~0x3))));
50259+
50260+	if (1 == size)
50261+		*value = (val >> (((unsigned int)where & 0x3) << 3)) & 0xff;
50262+	else if (2 == size)
50263+		*value = (val >> (((unsigned int)where & 0x3) << 3)) & 0xffff;
50264+	else if (4 == size)
50265+		*value = val;
50266+	else {
50267+		pcie_error("Unknown size for config read operation!");
50268+		BUG();
50269+	}
50270+
50271+	return PCIBIOS_SUCCESSFUL;
50272+}
50273+
50274+static int pcie_read_conf(struct pci_bus *bus, unsigned int devfn,
50275+			  int where, int size, u32 *value)
50276+{
50277+	struct pcie_info *info = bus_to_info(bus->number);
50278+	int ret;
50279+
50280+	if (unlikely(!info)) {
50281+		pcie_error(
50282+			"%s:Cannot find corresponding controller for appointed device!", __func__);
50283+		BUG();
50284+	}
50285+
50286+	if (bus->number == info->root_bus_nr)
50287+		ret =  pcie_read_from_dbi(info, devfn, where, size, value);
50288+	else
50289+		ret =  pcie_read_from_device(bus, devfn, where, size, value);
50290+
50291+	pcie_debug(PCIE_DBG_REG,
50292+		   "bus %d, devfn %d, where 0x%x, size 0x%x, value 0x%x",
50293+		   bus->number & 0xff, devfn, where, size, *value);
50294+
50295+	return ret;
50296+}
50297+
50298+static int pcie_write_to_device(struct pci_bus *bus, unsigned int devfn,
50299+				int where, int size, u32 value)
50300+{
50301+	struct pcie_info *info = bus_to_info(bus->number);
50302+	void __iomem *addr;
50303+	unsigned int org;
50304+	unsigned long flag;
50305+
50306+	if (unlikely(!info)) {
50307+		pcie_error(
50308+			"%s:Cannot find corresponding controller for appointed device!", __func__);
50309+		BUG();
50310+	}
50311+
50312+	if (!is_pcie_link_up(info)) {
50313+		pcie_debug(PCIE_DBG_MODULE, "pcie %d not link up!",
50314+			   info->controller);
50315+		return -1;
50316+	}
50317+
50318+	spin_lock_irqsave(&cw_lock, flag);
50319+
50320+	pcie_read_from_device(bus, devfn, where, 4, &org);
50321+
50322+	addr = (void __iomem *)(uintptr_t)to_pcie_address(bus, devfn, where);
50323+
50324+	if (size == 1) {
50325+		org &= (~(0xff << (((unsigned int)where & 0x3) << 3)));
50326+		org |= (value << (((unsigned int)where & 0x3) << 3));
50327+	} else if (size == 2) {
50328+		org &= (~(0xffff << (((unsigned int)where & 0x3) << 3)));
50329+		org |= (value << (((unsigned int)where & 0x3) << 3));
50330+	} else if (size == 4) {
50331+		org = value;
50332+	} else {
50333+		pcie_error("Unknown size(%d) for read ops", size);
50334+		BUG();
50335+	}
50336+
50337+	writel(org, addr);
50338+
50339+	spin_unlock_irqrestore(&cw_lock, flag);
50340+
50341+	return PCIBIOS_SUCCESSFUL;
50342+}
50343+
50344+static int pcie_write_to_dbi(struct pcie_info *info, unsigned int devfn,
50345+			     int where, int size, u32 value)
50346+{
50347+	unsigned long flag;
50348+	unsigned int org;
50349+
50350+	spin_lock_irqsave(&cw_lock, flag);
50351+
50352+	if (pcie_read_from_dbi(info, devfn, (unsigned int)where, 4, &org)) {
50353+		pcie_error("Cannot read from dbi! 0x%x:0x%x:0x%x!",
50354+			   0, devfn, (unsigned int)where);
50355+		spin_unlock_irqrestore(&cw_lock, flag);
50356+		return -EIO;
50357+	}
50358+	if (size == 1) {
50359+		org &= (~(0xff << (((unsigned int)where & 0x3) << 3)));
50360+		org |= (value << (((unsigned int)where & 0x3) << 3));
50361+	} else if (size == 2) {
50362+		org &= (~(0xffff << (((unsigned int)where & 0x3) << 3)));
50363+		org |= (value << (((unsigned int)where & 0x3) << 3));
50364+	} else if (size == 4) {
50365+		org = value;
50366+	} else {
50367+		pcie_error("Unknown size(%d) for read ops", size);
50368+		BUG();
50369+	}
50370+	writel(org, ((void __iomem *)(uintptr_t)info->conf_base_addr +
50371+		     ((unsigned int)where & (~0x3))));
50372+
50373+	spin_unlock_irqrestore(&cw_lock, flag);
50374+
50375+	return PCIBIOS_SUCCESSFUL;
50376+}
50377+
50378+static int pcie_write_conf(struct pci_bus *bus, unsigned int devfn,
50379+			   int where, int size, u32 value)
50380+{
50381+	struct pcie_info *info = bus_to_info(bus->number);
50382+
50383+	pcie_debug(PCIE_DBG_REG,
50384+		   "bus %d, devfn %d, where 0x%x, size 0x%x, value 0x%x",
50385+		   bus->number & 0xff, devfn, where, size, value);
50386+
50387+	if (unlikely(!info)) {
50388+		pcie_error(
50389+			"%s:Cannot find corresponding controller for appointed device!", __func__);
50390+		BUG();
50391+	}
50392+
50393+	if (bus->number == info->root_bus_nr)
50394+		return pcie_write_to_dbi(info, devfn, where, size, value);
50395+	else
50396+		return pcie_write_to_device(bus, devfn, where, size, value);
50397+}
50398+
50399+static struct pci_ops pcie_ops = {
50400+	.read = pcie_read_conf,
50401+	.write = pcie_write_conf,
50402+};
50403+
50404+void pci_set_max_rd_req_size(const struct pci_bus *bus)
50405+{
50406+	struct pci_dev *dev = NULL;
50407+	struct pci_bus *child = NULL;
50408+	int pos;
50409+	unsigned short dev_contrl_reg_val = 0;
50410+	unsigned int max_rd_req_size = 0;
50411+
50412+	list_for_each_entry(dev, &bus->devices, bus_list) {
50413+		/* set device max read requset size */
50414+		pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
50415+		if (pos) {
50416+			pci_read_config_word(dev, pos + PCI_EXP_DEVCTL,
50417+					     &dev_contrl_reg_val);
50418+			max_rd_req_size = (dev_contrl_reg_val >> 12) & 0x7;
50419+			if (max_rd_req_size > 0x0) {
50420+				dev_contrl_reg_val &= ~(max_rd_req_size << 12);
50421+				pci_write_config_word(dev, pos + PCI_EXP_DEVCTL,
50422+						      dev_contrl_reg_val);
50423+			}
50424+		}
50425+	}
50426+
50427+	list_for_each_entry(dev, &bus->devices, bus_list) {
50428+		BUG_ON(!dev->is_probed);
50429+		child = dev->subordinate;
50430+		if (child)
50431+			pci_set_max_rd_req_size(child);
50432+	}
50433+}
50434+
50435+#ifdef CONFIG_PCI_MSI
50436+int pci_msi_is_enable(struct platform_device *pdev)
50437+{
50438+	int msi_irq;
50439+
50440+	msi_irq = platform_get_irq_byname(pdev, "msi");
50441+	if (msi_irq < 0) {
50442+		return false;
50443+	}
50444+
50445+	return true;
50446+}
50447+#endif
50448+
50449+#ifdef CONFIG_ARM64
50450+
50451+static int pci_common_init(struct platform_device *pdev, struct hw_pci *hipcie)
50452+{
50453+	struct device_node *dn = pdev->dev.of_node;
50454+	struct pcie_info *info = NULL;
50455+	struct pci_bus *bus = NULL;
50456+	resource_size_t io_addr;
50457+	int ret;
50458+	int pcie_contrl = -1;
50459+	int bus_start;
50460+
50461+	LIST_HEAD(res);
50462+
50463+	ret = of_property_read_u32(dn, "pcie_controller", &pcie_contrl);
50464+	if (ret) {
50465+		pr_err("%s:No pcie_controller found!\n", __func__);
50466+		return -EINVAL;
50467+	}
50468+
50469+	if (pcie_contrl == 0)
50470+		bus_start = 0;
50471+	else
50472+		bus_start = 0x2;
50473+
50474+	ret = devm_of_pci_get_host_bridge_resources(&pdev->dev, bus_start, 0xff, &res,
50475+						    &io_addr);
50476+	if (ret)
50477+		return ret;
50478+	bus = pci_create_root_bus(&pdev->dev, bus_start, &pcie_ops, hipcie, &res);
50479+	if (!bus)
50480+		return -ENOMEM;
50481+
50482+#ifdef CONFIG_PCI_MSI
50483+	if (pci_msi_is_enable(pdev)) {
50484+		bus->msi = &hipcie->msi.chip;
50485+	}
50486+#endif
50487+
50488+#ifdef CONFIG_LIMIT_MAX_RD_REQ_SIZE
50489+	pci_set_max_rd_req_size(bus);
50490+#endif
50491+
50492+	pcie_info[pcie_contrl].root_bus_nr = bus->number;
50493+	info = bus_to_info(bus->number);
50494+	if (info != NULL)
50495+		__arch_config_iatu_tbl(info, NULL);
50496+
50497+	pci_scan_child_bus(bus);
50498+	pci_assign_unassigned_bus_resources(bus);
50499+	pci_bus_add_devices(bus);
50500+
50501+	platform_set_drvdata(pdev, hipcie);
50502+
50503+	return 0;
50504+}
50505+#else
50506+static int pci_common_init_bvt(struct platform_device *pdev,
50507+			       struct hw_pci *hipcie)
50508+{
50509+	struct device_node *dn = pdev->dev.of_node;
50510+	struct pcie_info *info = NULL;
50511+	struct pci_bus *bus = NULL;
50512+	resource_size_t io_addr;
50513+	int ret;
50514+	int pcie_contrl;
50515+	int bus_start;
50516+
50517+	LIST_HEAD(res);
50518+
50519+	ret = of_property_read_u32(dn, "pcie_controller", &pcie_contrl);
50520+	if (ret) {
50521+		pr_err("%s:No pcie_controller found!\n", __func__);
50522+		return -EINVAL;
50523+	}
50524+
50525+	if (pcie_contrl == 0)
50526+		bus_start = 0;
50527+	else
50528+		bus_start = 2;
50529+
50530+	ret = devm_of_pci_get_host_bridge_resources(&pdev->dev, bus_start, 0xff, &res, &io_addr);
50531+	if (ret)
50532+		return ret;
50533+
50534+	bus = pci_create_root_bus(&pdev->dev, bus_start, &pcie_ops, hipcie, &res);
50535+	if (!bus)
50536+		return -ENOMEM;
50537+
50538+#ifdef CONFIG_PCI_MSI
50539+	if (pci_msi_is_enable(pdev)) {
50540+		bus->msi = &hipcie->msi.chip;
50541+	}
50542+#endif
50543+
50544+#ifdef CONFIG_LIMIT_MAX_RD_REQ_SIZE
50545+	pci_set_max_rd_req_size(bus);
50546+#endif
50547+
50548+	pcie_info[pcie_contrl].root_bus_nr = bus->number;
50549+	info = bus_to_info(bus->number);
50550+	if (info != NULL) {
50551+		__arch_config_iatu_tbl(info, NULL);
50552+	}
50553+
50554+	pci_scan_child_bus(bus);
50555+	pci_assign_unassigned_bus_resources(bus);
50556+	pci_bus_add_devices(bus);
50557+
50558+	platform_set_drvdata(pdev, hipcie);
50559+
50560+	return 0;
50561+}
50562+#endif
50563+
50564+#ifdef CONFIG_PCI_MSI
50565+static inline struct hisi_msi *to_hisi_msi(struct msi_controller *chip)
50566+{
50567+	return container_of(chip, struct hisi_msi, chip);
50568+}
50569+
50570+static int hisi_msi_alloc(struct hisi_msi *chip)
50571+{
50572+	int msi;
50573+
50574+	mutex_lock(&chip->lock);
50575+
50576+	msi = find_first_zero_bit(chip->used, HISI_PCI_MSI_NR);
50577+	if (msi < HISI_PCI_MSI_NR)
50578+		set_bit(msi, chip->used);
50579+	else
50580+		msi = -ENOSPC;
50581+
50582+	mutex_unlock(&chip->lock);
50583+
50584+	return msi;
50585+}
50586+
50587+static void hisi_msi_free(struct hisi_msi *chip, unsigned long irq)
50588+{
50589+	struct device *dev = chip->chip.dev;
50590+
50591+	mutex_lock(&chip->lock);
50592+
50593+	if (!test_bit(irq, chip->used))
50594+		dev_err(dev, "trying to free unused MSI#%lu\n", irq);
50595+	else
50596+		clear_bit(irq, chip->used);
50597+
50598+	mutex_unlock(&chip->lock);
50599+}
50600+
50601+static irqreturn_t hisi_pcie_msi_irq(int irq, void *data)
50602+{
50603+	struct hw_pci *hi_pcie = data;
50604+	struct device *dev = hi_pcie->dev;
50605+	struct hisi_msi *msi = &hi_pcie->msi;
50606+	unsigned int i;
50607+	unsigned int processed = 0;
50608+	void *dbi_base = (void *)(uintptr_t)
50609+			 pcie_info[hi_pcie->nr_controllers].conf_base_addr;
50610+
50611+	for (i = 0; i < 8; i++) {
50612+		unsigned long reg = readl(dbi_base + 0x830 + i * 0xc);
50613+
50614+		while (reg) {
50615+			unsigned int offset = find_first_bit(&reg, 32);
50616+			unsigned int index = i * 32 + offset;
50617+			unsigned int irq;
50618+
50619+			/* clear the interrupt */
50620+			writel(1 << offset, dbi_base + msi_contrl_interrupt + i * 0xc);
50621+
50622+			irq = irq_find_mapping(msi->domain, index);
50623+			if (irq) {
50624+				if (test_bit(index, msi->used)) {
50625+					generic_handle_irq(irq);
50626+				} else
50627+					dev_info(dev, "unhandled MSI\n");
50628+			} else {
50629+				/*
50630+				 * * that's weird who triggered this?
50631+				 * * just clear it
50632+				 *  */
50633+				dev_info(dev, "unexpected MSI\n");
50634+			}
50635+
50636+			/* see if there's any more pending in this vector */
50637+			reg = readl(dbi_base +  msi_contrl_interrupt + i * 0xc);
50638+			processed++;
50639+		}
50640+	}
50641+	return processed > 0 ? IRQ_HANDLED : IRQ_NONE;
50642+}
50643+
50644+static int hisi_msi_setup_irq(struct msi_controller *chip,
50645+			      struct pci_dev *pdev, struct msi_desc *desc)
50646+{
50647+	struct hisi_msi *msi = to_hisi_msi(chip);
50648+	struct msi_msg msg;
50649+	unsigned int irq;
50650+	int hwirq;
50651+
50652+	if (pdev->bus->number == pcie_info[0].root_bus_nr ||
50653+			pdev->bus->number == pcie_info[1].root_bus_nr)
50654+		return 0;
50655+
50656+	hwirq = hisi_msi_alloc(msi);
50657+	if (hwirq < 0)
50658+		return hwirq;
50659+
50660+	irq = irq_create_mapping(msi->domain, hwirq);
50661+	if (!irq) {
50662+		hisi_msi_free(msi, hwirq);
50663+		return -EINVAL;
50664+	}
50665+
50666+	irq_set_msi_desc(irq, desc);
50667+
50668+	desc->msi_attrib.multiple = 0x5;
50669+
50670+	msg.address_lo = virt_to_phys((void *)(uintptr_t)msi->pages);
50671+	msg.address_hi = (virt_to_phys((void *)(uintptr_t)msi->pages) >> 32);
50672+	msg.data = hwirq;
50673+
50674+	pci_write_msi_msg(irq, &msg);
50675+
50676+	return 0;
50677+}
50678+
50679+static void hisi_msi_teardown_irq(struct msi_controller *chip,
50680+				  unsigned int irq)
50681+{
50682+	struct hisi_msi *msi = to_hisi_msi(chip);
50683+	struct irq_data *d = irq_get_irq_data(irq);
50684+	irq_hw_number_t hwirq = 0;
50685+
50686+	if (d != NULL)
50687+		hwirq = irqd_to_hwirq(d);
50688+
50689+	irq_dispose_mapping(irq);
50690+	hisi_msi_free(msi, hwirq);
50691+}
50692+
50693+static struct irq_chip hisi_msi_irq_chip = {
50694+	.name = "HISI PCIe MSI",
50695+	.irq_enable = pci_msi_unmask_irq,
50696+	.irq_disable = pci_msi_mask_irq,
50697+	.irq_mask = pci_msi_mask_irq,
50698+	.irq_unmask = pci_msi_unmask_irq,
50699+};
50700+
50701+static int hisi_msi_map(struct irq_domain *domain, unsigned int irq,
50702+			irq_hw_number_t hwirq)
50703+{
50704+	irq_set_chip_and_handler(irq, &hisi_msi_irq_chip, handle_simple_irq);
50705+	irq_set_chip_data(irq, domain->host_data);
50706+
50707+	return 0;
50708+}
50709+
50710+static const struct irq_domain_ops msi_domain_ops = {
50711+	.map = hisi_msi_map,
50712+};
50713+
50714+static int hisi_pcie_enable_msi(struct hw_pci *pcie)
50715+{
50716+	struct device *dev = pcie->dev;
50717+	struct platform_device *pdev = to_platform_device(dev);
50718+	struct hisi_msi *msi = &pcie->msi;
50719+	unsigned long base;
50720+	int err;
50721+
50722+	void *dbi_base = (void *)(uintptr_t)
50723+			 pcie_info[pcie->nr_controllers].conf_base_addr;
50724+
50725+	if (!msi) {
50726+		dev_err(dev, "msi is null, error.\n");
50727+		return -EINVAL;
50728+	}
50729+
50730+	mutex_init(&msi->lock);
50731+
50732+	msi->chip.dev = dev;
50733+	msi->chip.setup_irq = hisi_msi_setup_irq;
50734+	msi->chip.teardown_irq = hisi_msi_teardown_irq;
50735+
50736+	msi->domain = irq_domain_add_linear(dev->of_node, HISI_PCI_MSI_NR,
50737+					    &msi_domain_ops, &msi->chip);
50738+	if (!msi->domain) {
50739+		dev_err(dev, "failed to create IRQ domain\n");
50740+		return -ENOMEM;
50741+	}
50742+
50743+	err = platform_get_irq_byname(pdev, "msi");
50744+	if (err < 0) {
50745+		dev_err(dev, "failed to get IRQ: %d\n", err);
50746+		goto err;
50747+	}
50748+
50749+	msi->irq = err;
50750+
50751+	err = request_irq(msi->irq, hisi_pcie_msi_irq, IRQF_NO_THREAD,
50752+			  hisi_msi_irq_chip.name, pcie);
50753+	if (err < 0) {
50754+		dev_err(dev, "failed to request IRQ: %d\n", err);
50755+		goto err;
50756+	}
50757+
50758+	/* setup AFI/FPCI range */
50759+	msi->pages = __get_free_pages(GFP_KERNEL, 0);
50760+	base = virt_to_phys((void *)(uintptr_t)msi->pages);
50761+
50762+	writel(base >> 32, dbi_base + MSI_CTRL_UPPER_ADDR_OFF);
50763+	writel(base, dbi_base + MSI_CTRL_ADDR_OFF);
50764+
50765+	/* enable all MSI vectors */
50766+	writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF0);
50767+	writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF1);
50768+	writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF2);
50769+	writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF3);
50770+	writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF4);
50771+	writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF5);
50772+	writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF6);
50773+	writel(0xffffffff, dbi_base + MSI_CTRL_INT_EN_OFF7);
50774+
50775+	return 0;
50776+
50777+err:
50778+	irq_domain_remove(msi->domain);
50779+	return err;
50780+}
50781+
50782+static int hisi_pcie_disable_msi(struct hw_pci *pcie)
50783+{
50784+	struct hisi_msi *msi = &pcie->msi;
50785+	unsigned int i, irq;
50786+	void *dbi_base = (void *)(uintptr_t)
50787+			 pcie_info[pcie->nr_controllers].conf_base_addr;
50788+
50789+	/* disable all MSI vectors */
50790+	writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF0);
50791+	writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF1);
50792+	writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF2);
50793+	writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF3);
50794+	writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF4);
50795+	writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF5);
50796+	writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF6);
50797+	writel(0x0, dbi_base + MSI_CTRL_INT_EN_OFF7);
50798+
50799+	free_pages(msi->pages, 0);
50800+
50801+	if (msi->irq > 0)
50802+		free_irq(msi->irq, pcie);
50803+
50804+	for (i = 0; i < HISI_PCI_MSI_NR; i++) {
50805+		irq = irq_find_mapping(msi->domain, i);
50806+		if (irq > 0)
50807+			irq_dispose_mapping(irq);
50808+	}
50809+
50810+	irq_domain_remove(msi->domain);
50811+
50812+	return 0;
50813+}
50814+#endif
50815+
50816+static int __init pcie_init(struct platform_device *pdev)
50817+{
50818+	int err;
50819+	struct hw_pci *hipcie = NULL;
50820+
50821+	if (!pdev) {
50822+		pr_err("pdev is null!\n");
50823+		return -ENOMEM;
50824+	}
50825+
50826+	hipcie = kzalloc(sizeof(struct hw_pci), GFP_KERNEL);
50827+	if (!hipcie) {
50828+		pr_err("kzalloc hw_pci space failed!\n");
50829+		return -ENOMEM;
50830+	}
50831+
50832+	hipcie->dev = &pdev->dev;
50833+
50834+	g_of_node = pdev->dev.of_node;
50835+	if (!g_of_node) {
50836+		pr_err("get node from dts failed! controller:%d\n", pcie_controllers_nr);
50837+		kfree(hipcie);
50838+		return -EIO;
50839+	}
50840+
50841+	err = of_property_read_u32(g_of_node, "pcie_controller", &pcie_controllers_nr);
50842+	if (err) {
50843+		pr_err("%s:No pcie_controller found!\n", __func__);
50844+		kfree(hipcie);
50845+		return -EINVAL;
50846+	}
50847+
50848+	if (__arch_pcie_info_setup(pcie_info, &pcie_controllers_nr)) {
50849+		kfree(hipcie);
50850+		return -EIO;
50851+	}
50852+
50853+	if (pcie_controllers_nr >= MAX_PCIE_CONTROLLER_NUM) {
50854+		pr_err("pcie_controllers_nr is Invalid, pcie_controllers_nr: %d\n",
50855+		       pcie_controllers_nr);
50856+		kfree(hipcie);
50857+		return -EINVAL;
50858+	}
50859+
50860+	if (__arch_pcie_sys_init(&pcie_info[pcie_controllers_nr]))
50861+		goto pcie_init_err;
50862+
50863+	hipcie->nr_controllers = pcie_controllers_nr;
50864+	pr_err("Number of PCIe controllers: %d\n",
50865+	       hipcie->nr_controllers);
50866+
50867+#ifdef CONFIG_PCI_MSI
50868+	if (pci_msi_is_enable(pdev)) {
50869+		err = hisi_pcie_enable_msi(hipcie);
50870+		if (err < 0) {
50871+			pr_err("failed to enable MSI support: %d\n", err);
50872+			goto pcie_init_err;
50873+		}
50874+	}
50875+#endif
50876+
50877+#ifdef CONFIG_ARM64
50878+	err = pci_common_init(pdev, hipcie);
50879+#else
50880+	err = pci_common_init_bvt(pdev, hipcie);
50881+#endif
50882+
50883+	if (err)
50884+		goto disable_msi;
50885+
50886+	return 0;
50887+
50888+disable_msi:
50889+#ifdef CONFIG_PCI_MSI
50890+	if (pci_msi_is_enable(pdev))
50891+		hisi_pcie_disable_msi(hipcie);
50892+#endif
50893+pcie_init_err:
50894+	__arch_pcie_info_release(&pcie_info[pcie_controllers_nr]);
50895+
50896+	kfree(hipcie);
50897+
50898+	return -EIO;
50899+}
50900+
50901+static int __exit pcie_uinit(struct platform_device *pdev)
50902+{
50903+	__arch_pcie_info_release(pcie_info);
50904+	return 0;
50905+}
50906+
50907+#include <linux/platform_device.h>
50908+#include <linux/pm.h>
50909+
50910+int  hisi_pcie_plat_driver_probe(struct platform_device *pdev)
50911+{
50912+	return 0;
50913+}
50914+int  hisi_pcie_plat_driver_remove(struct platform_device *pdev)
50915+{
50916+	return 0;
50917+}
50918+
50919+#ifdef CONFIG_PM
50920+int hisi_pcie_plat_driver_suspend(struct device *dev)
50921+{
50922+	__arch_pcie_sys_exit();
50923+	return 0;
50924+}
50925+
50926+int hisi_pcie_plat_driver_resume(struct device *dev)
50927+{
50928+	return __arch_pcie_sys_init(pcie_info);
50929+}
50930+
50931+const struct dev_pm_ops hisi_pcie_pm_ops = {
50932+	.suspend = NULL,
50933+	.suspend_noirq = hisi_pcie_plat_driver_suspend,
50934+	.resume = NULL,
50935+	.resume_noirq = hisi_pcie_plat_driver_resume
50936+};
50937+
50938+#define HISI_PCIE_PM_OPS (&hisi_pcie_pm_ops)
50939+#else
50940+#define HISI_PCIE_PM_OPS NULL
50941+#endif
50942+
50943+#define PCIE_RC_DRV_NAME "hisi pcie root complex"
50944+
50945+static const struct of_device_id hisi_pcie_match_table[] = {
50946+	{ .compatible = "hisilicon,hisi-pcie", },
50947+	{},
50948+};
50949+
50950+static struct platform_driver hisi_pcie_driver = {
50951+	.driver = {
50952+		.name = "hisi-pcie",
50953+		.owner = THIS_MODULE,
50954+		.of_match_table = of_match_ptr(hisi_pcie_match_table),
50955+	},
50956+	.probe = pcie_init,
50957+};
50958+module_platform_driver(hisi_pcie_driver);
50959+
50960+MODULE_DESCRIPTION("Hisilicon PCI-Express Root Complex driver");
50961+MODULE_LICENSE("GPL");
50962diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
50963index 8b587fc97..07482a509 100644
50964--- a/drivers/pci/pci-driver.c
50965+++ b/drivers/pci/pci-driver.c
50966@@ -19,6 +19,7 @@
50967 #include <linux/kexec.h>
50968 #include <linux/of_device.h>
50969 #include <linux/acpi.h>
50970+#include <linux/of_pci.h>
50971 #include <linux/dma-map-ops.h>
50972 #include "pci.h"
50973 #include "pcie/portdrv.h"
50974@@ -394,6 +395,9 @@ static int __pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
50975
50976 int __weak pcibios_alloc_irq(struct pci_dev *dev)
50977 {
50978+#ifdef CONFIG_SATA_AHCI
50979+	dev->irq = of_irq_parse_and_map_pci(dev, 0, 0);
50980+#endif
50981 	return 0;
50982 }
50983
50984diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
50985index 9ed5f167a..533d43e77 100644
50986--- a/drivers/phy/Kconfig
50987+++ b/drivers/phy/Kconfig
50988@@ -83,5 +83,6 @@ source "drivers/phy/tegra/Kconfig"
50989 source "drivers/phy/ti/Kconfig"
50990 source "drivers/phy/intel/Kconfig"
50991 source "drivers/phy/xilinx/Kconfig"
50992+source "drivers/phy/hibvt/Kconfig"
50993
50994 endmenu
50995diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
50996index 6eb291677..38a096b29 100644
50997--- a/drivers/phy/Makefile
50998+++ b/drivers/phy/Makefile
50999@@ -9,6 +9,7 @@ obj-$(CONFIG_PHY_LPC18XX_USB_OTG)	+= phy-lpc18xx-usb-otg.o
51000 obj-$(CONFIG_PHY_XGENE)			+= phy-xgene.o
51001 obj-$(CONFIG_PHY_PISTACHIO_USB)		+= phy-pistachio-usb.o
51002 obj-$(CONFIG_USB_LGM_PHY)		+= phy-lgm-usb.o
51003+obj-$(CONFIG_ARCH_HISI_BVT)		+= hibvt/
51004 obj-y					+= allwinner/	\
51005 					   amlogic/	\
51006 					   broadcom/	\
51007diff --git a/drivers/phy/hibvt/Kconfig b/drivers/phy/hibvt/Kconfig
51008new file mode 100644
51009index 000000000..9fcb56c1c
51010--- /dev/null
51011+++ b/drivers/phy/hibvt/Kconfig
51012@@ -0,0 +1,23 @@
51013+config PHY_HISI_SATA
51014+	tristate "Hisilicon sata phy support"
51015+	depends on (ARCH_HI3531DV200 || ARCH_HI3535AV100 || ARCH_HI3521DV200 || ARCH_HI3520DV500) && OF && HAS_IOMEM
51016+	default n
51017+	select GENERIC_PHY
51018+	help
51019+	  Enable this to support the sata phy that is part of
51020+	  sata driver for hisilicon
51021+
51022+config HISI_SATA_MODE
51023+	int "Hisi sata interworking speed mode(1.5G:0/3G:1/6G:2)"
51024+	depends on PHY_HISI_SATA
51025+	help
51026+	  Hisilicon sata interworking speed mode
51027+
51028+menuconfig HI_USB_PHY
51029+	tristate "HiSilicon USB support"
51030+
51031+if HI_USB_PHY
51032+
51033+source "drivers/phy/hibvt/usb/Kconfig"
51034+
51035+endif # HI_USB_PHY
51036diff --git a/drivers/phy/hibvt/Makefile b/drivers/phy/hibvt/Makefile
51037new file mode 100644
51038index 000000000..7b038f48e
51039--- /dev/null
51040+++ b/drivers/phy/hibvt/Makefile
51041@@ -0,0 +1,5 @@
51042+#
51043+# Makefile for the phy drivers.
51044+#
51045+obj-$(CONFIG_PHY_HISI_SATA)			+= phy-hisi-sata.o
51046+obj-y	+= usb/
51047diff --git a/drivers/phy/hibvt/phy-hisi-sata.c b/drivers/phy/hibvt/phy-hisi-sata.c
51048new file mode 100644
51049index 000000000..d7384fec3
51050--- /dev/null
51051+++ b/drivers/phy/hibvt/phy-hisi-sata.c
51052@@ -0,0 +1,175 @@
51053+/*
51054+ * Copyright (c) 2016-2019 HiSilicon Technologies Co., Ltd.
51055+ *
51056+ * This program is free software; you can redistribute  it and/or modify it
51057+ * under  the terms of  the GNU General  Public License as published by the
51058+ * Free Software Foundation;  either version 2 of the  License, or (at your
51059+ * option) any later version.
51060+ *
51061+ * This program is distributed in the hope that it will be useful,
51062+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
51063+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51064+ * GNU General Public License for more details.
51065+ *
51066+ * You should have received a copy of the GNU General Public License
51067+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
51068+ *
51069+ */
51070+
51071+#include <linux/delay.h>
51072+#include <linux/io.h>
51073+#include <linux/module.h>
51074+#include <linux/phy/phy.h>
51075+#include <linux/platform_device.h>
51076+#include <linux/io.h>
51077+
51078+static unsigned int phy_mode = CONFIG_HISI_SATA_MODE;
51079+static unsigned int ports_num;
51080+unsigned int sata_port_map;
51081+
51082+#ifdef MODULE
51083+module_param(mode_3g, uint, 0600);
51084+MODULE_PARM_DESC(phy_mode, "sata phy mode (0:1.5G;1:3G(default);2:6G)");
51085+#endif
51086+
51087+#ifdef CONFIG_ARCH_HI3531DV200
51088+#include "phy-hi3531dv200-sata.c"
51089+#endif
51090+
51091+#ifdef CONFIG_ARCH_HI3535AV100
51092+#include "phy-hi3535av100-sata.c"
51093+#endif
51094+
51095+#ifdef CONFIG_ARCH_HI3521DV200
51096+#include "phy-hi3521dv200-sata.c"
51097+#endif
51098+
51099+#ifdef CONFIG_ARCH_HI3520DV500
51100+#include "phy-hi3521dv200-sata.c"
51101+#endif
51102+
51103+static int hisi_sata_phy_init(struct phy *phy)
51104+{
51105+	unsigned int sata_port_num = 0;
51106+	void __iomem *mmio = phy_get_drvdata(phy);
51107+
51108+	sata_port_num = hisi_sata_get_port_info();
51109+	if ((sata_port_num < 1)) {
51110+		pr_err("sata ports number:%d WRONG!!!\n", sata_port_num);
51111+		return -EINVAL;
51112+	}
51113+	ports_num = sata_port_num;
51114+
51115+	hisi_sata_poweron();
51116+	hisi_sata_reset();
51117+	hisi_sata_phy_reset();
51118+	hisi_sata_phy_clk_sel();
51119+	hisi_sata_clk_enable();
51120+	msleep(20);
51121+	hisi_sata_phy_unreset();
51122+	msleep(20);
51123+	hisi_sata_unreset();
51124+	msleep(20);
51125+	hisi_sata_phy_config(mmio, phy_mode);
51126+
51127+	return 0;
51128+}
51129+
51130+static int hisi_sata_phy_exit(struct phy *phy)
51131+{
51132+	hisi_sata_phy_reset();
51133+	msleep(20);
51134+	hisi_sata_reset();
51135+	msleep(20);
51136+	hisi_sata_clk_reset();
51137+	msleep(20);
51138+	hisi_sata_clk_disable();
51139+	hisi_sata_poweroff();
51140+	msleep(20);
51141+
51142+	return 0;
51143+}
51144+
51145+static struct phy_ops hisi_sata_phy_ops = {
51146+	.init		= hisi_sata_phy_init,
51147+	.exit		= hisi_sata_phy_exit,
51148+	.owner		= THIS_MODULE,
51149+};
51150+
51151+static int hisi_sata_phy_probe(struct platform_device *pdev)
51152+{
51153+	struct phy_provider *phy_provider = NULL;
51154+	struct device *dev = &pdev->dev;
51155+	struct resource *res = NULL;
51156+	struct phy *phy = NULL;
51157+	void __iomem *mmio = NULL;
51158+
51159+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
51160+	if (!res) {
51161+		dev_err(dev, "failed to get reg base\n");
51162+		return -ENOENT;
51163+	}
51164+
51165+	mmio = devm_ioremap(dev, res->start, resource_size(res));
51166+	if (!mmio)
51167+		return -ENOMEM;
51168+
51169+	phy = devm_phy_create(dev, NULL, &hisi_sata_phy_ops);
51170+	if (IS_ERR(phy)) {
51171+		dev_err(dev, "failed to create PHY\n");
51172+		return PTR_ERR(phy);
51173+	}
51174+
51175+	of_property_read_u32(dev->of_node, "ports_num_max", &ports_num);
51176+
51177+	phy_set_drvdata(phy, mmio);
51178+
51179+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
51180+	if (IS_ERR(phy_provider))
51181+		return PTR_ERR(phy_provider);
51182+
51183+	return 0;
51184+}
51185+
51186+static int hisi_sata_phy_suspend(struct platform_device *pdev,
51187+				 pm_message_t state)
51188+{
51189+	struct device *dev = &pdev->dev;
51190+	struct phy *phy = to_phy(dev);
51191+
51192+	hisi_sata_phy_exit(phy);
51193+
51194+	return 0;
51195+}
51196+
51197+static int hisi_sata_phy_resume(struct platform_device *pdev)
51198+{
51199+	struct device *dev = &pdev->dev;
51200+	struct phy *phy = to_phy(dev);
51201+
51202+	hisi_sata_phy_init(phy);
51203+
51204+	return 0;
51205+}
51206+
51207+static const struct of_device_id hisi_sata_phy_of_match[] = {
51208+	{ .compatible = "hisilicon,hisi-sata-phy", },
51209+	{ },
51210+};
51211+MODULE_DEVICE_TABLE(of, hisi_sata_phy_of_match);
51212+
51213+static struct platform_driver hisi_sata_phy_driver = {
51214+	.probe	= hisi_sata_phy_probe,
51215+	.suspend = hisi_sata_phy_suspend,
51216+	.resume  = hisi_sata_phy_resume,
51217+	.driver = {
51218+		.name	= "hisi-sata-phy",
51219+		.of_match_table	= hisi_sata_phy_of_match,
51220+	}
51221+};
51222+module_platform_driver(hisi_sata_phy_driver);
51223+
51224+MODULE_AUTHOR("HiSilicon BVT");
51225+MODULE_DESCRIPTION("HISILICON SATA PHY driver");
51226+MODULE_ALIAS("platform:hisi-sata-phy");
51227+MODULE_LICENSE("GPL v2");
51228diff --git a/drivers/phy/hibvt/phy-hisi-sata.h b/drivers/phy/hibvt/phy-hisi-sata.h
51229new file mode 100644
51230index 000000000..44730c519
51231--- /dev/null
51232+++ b/drivers/phy/hibvt/phy-hisi-sata.h
51233@@ -0,0 +1,39 @@
51234+/*
51235+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
51236+ *
51237+ * This program is free software; you can redistribute  it and/or modify it
51238+ * under  the terms of  the GNU General  Public License as published by the
51239+ * Free Software Foundation;  either version 2 of the  License, or (at your
51240+ * option) any later version.
51241+ *
51242+ * This program is distributed in the hope that it will be useful,
51243+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
51244+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51245+ * GNU General Public License for more details.
51246+ *
51247+ * You should have received a copy of the GNU General Public License
51248+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
51249+ *
51250+ */
51251+
51252+enum {
51253+	/* hisi extended global controller registers */
51254+	PHY_CTL0    = 0xA0,
51255+	PHY_CTL1    = 0xA4,
51256+	PHY_RST_BACK_MASK	= 0xAC,
51257+	PHY_CTL2	= 0xB0,
51258+
51259+#define PHY_DATA_INVERT     (0x1 << 3)
51260+#define PHY0_RST_MASK		(0x1 << 4)
51261+#define PHY_RST_MASK_ALL	(0xF << 4)
51262+
51263+	/* hisi extended registers for each SATA port */
51264+	PORT_FIFOTH		= 0x44,
51265+	PORT_FIFOTH2	= 0x7C,
51266+	PORT_PHYCTL1    = 0x48,
51267+	PORT_PHYCTL     = 0x74,
51268+
51269+#define PHY_MODE_1_5G   0
51270+#define PHY_MODE_3G     1
51271+#define PHY_MODE_6G     2
51272+};
51273diff --git a/drivers/phy/hibvt/usb/Kconfig b/drivers/phy/hibvt/usb/Kconfig
51274new file mode 100644
51275index 000000000..c7b5ab6e7
51276--- /dev/null
51277+++ b/drivers/phy/hibvt/usb/Kconfig
51278@@ -0,0 +1,85 @@
51279+#
51280+# Phy drivers for Hisilicon platforms
51281+#
51282+config PHY_HISI_USB2
51283+	bool
51284+	depends on (!ARCH_HI3559AV100 && !ARCH_HI3569V100 && !ARCH_HI3516EV200 && \
51285+		!ARCH_HI3516EV300 && !ARCH_HI3518EV300 && !ARCH_HI3516DV200)
51286+	default y
51287+	help
51288+	  Support for PHY on Hisilicon Socs. This Phy supports
51289+	  USB 1.5Mb/s, USB 12Mb/s, USB 480Mb/s speeds. It suppots one
51290+	  USB host port to accept one USB device. Support init the phy
51291+	  and adjust phy Eye Diagram.
51292+
51293+config PHY_HISI_USB3
51294+	bool
51295+	depends on (ARCH_HI3519AV100 || ARCH_HI3556AV100 || ARCH_HI3559AV100 || \
51296+		ARCH_HI3569V100 || ARCH_HI3568V100 || ARCH_HI3531DV200 || \
51297+		ARCH_HI3535AV100)
51298+	default y
51299+	help
51300+	  Support for PHY on Hisilicon Socs. This Phy supports
51301+	  USB3.0 and Compatible with USB2.0. It suppots one
51302+	  USB host port to accept one USB device. Support init the phy
51303+	  and adjust phy Eye Diagram.
51304+
51305+config HIBVT_USB_PHY
51306+	bool "Hisilicon USB PHY driver"
51307+	depends on (!ARCH_HI3516EV200 && !ARCH_HI3516EV300 && !ARCH_HI3518EV300 && \
51308+		!ARCH_HI3516DV200)
51309+	default y
51310+	help
51311+	  Support for PHY on Hisilicon Socs. This Phy supports
51312+	  USB 1.5Mb/s, USB 12Mb/s, USB 480Mb/s speeds. It suppots one
51313+	  USB host port to accept one USB device. Support init the phy
51314+	  and adjust phy Eye Diagram.
51315+
51316+config PHY_HISI_XVP_USB2
51317+	tristate "Hisilicon XVP USB2 PHY Driver"
51318+	depends on (ARCH_HI3516EV200 || ARCH_HI3516EV300 || ARCH_HI3518EV300 || \
51319+		ARCH_HI3516DV200)
51320+	select GENERIC_PHY
51321+	default y
51322+	help
51323+	  Support for PHY on Hisilicon Socs. This Phy supports
51324+	  USB 1.5Mb/s, USB 12Mb/s, USB 480Mb/s speeds. It suppots one
51325+	  USB host port to accept one USB device. Support init the phy
51326+	  and adjust phy Eye Diagram.
51327+
51328+menuconfig USB_MODE_OPTION
51329+	bool "Hisilicon USB related configuration"
51330+	depends on (!ARCH_HI3516EV200 && !ARCH_HI3516EV300 && !ARCH_HI3518EV300 && \
51331+		!ARCH_HI3516DV200 && !ARCH_HI3531DV200 && !ARCH_HI3535AV100 &&	\
51332+		!ARCH_HI3521DV200 && !ARCH_HI3520DV500)
51333+
51334+if USB_MODE_OPTION
51335+
51336+config USB_DRD0_IN_HOST
51337+	bool "USB DRD0 Mode Select HOST"
51338+	help
51339+	  Select whether the USB drd0 is working in host mode.
51340+
51341+config USB_DRD0_IN_DEVICE
51342+	bool "USB DRD0 Mode Select DEVICE"
51343+	depends on (!ARCH_HI3531DV200 && !ARCH_HI3535AV100 && !ARCH_HI3521DV200 && \
51344+		!ARCH_HI3520DV500)
51345+	help
51346+	  Select whether the USB drd0 is working in device mode.
51347+
51348+config USB_DRD1_IN_HOST
51349+	bool "USB DRD1 Mode Select HOST"
51350+	depends on (ARCH_HI3519AV100 || ARCH_HI3556AV100 || ARCH_HI3559AV100 ||	\
51351+		ARCH_HI3569V100 || ARCH_HI3568V100)
51352+	help
51353+	  Select whether the USB drd1 is working in host mode.
51354+
51355+config USB_DRD1_IN_DEVICE
51356+	bool "USB DRD1 Mode Select DEVICE"
51357+	depends on (!USB_DRD1_IN_HOST && !USB_DRD0_IN_DEVICE)
51358+	depends on (ARCH_HI3519AV100 || ARCH_HI3556AV100 || ARCH_HI3559AV100 || \
51359+		ARCH_HI3569V100 || ARCH_HI3568V100)
51360+	help
51361+	  Select whether the USB drd1 is working in device mode.
51362+
51363+endif # USB_MODE_OPTION
51364diff --git a/drivers/phy/hibvt/usb/Makefile b/drivers/phy/hibvt/usb/Makefile
51365new file mode 100644
51366index 000000000..dc9e8d71f
51367--- /dev/null
51368+++ b/drivers/phy/hibvt/usb/Makefile
51369@@ -0,0 +1,17 @@
51370+obj-$(CONFIG_HIBVT_USB_PHY)		    += phy-hisi-usb.o
51371+obj-$(CONFIG_ARCH_HI3531DV200)		+= phy-hi3531dv200-usb.o
51372+obj-$(CONFIG_ARCH_HI3535AV100)		+= phy-hi3531dv200-usb.o
51373+obj-$(CONFIG_ARCH_HI3521DV200)		+= phy-hi3521dv200-usb.o
51374+obj-$(CONFIG_ARCH_HI3520DV500)		+= phy-hi3521dv200-usb.o
51375+obj-$(CONFIG_ARCH_HI3559AV100)			+= phy-hi3559av100-usb.o
51376+obj-$(CONFIG_ARCH_HI3569V100)			+= phy-hi3559av100-usb.o
51377+obj-$(CONFIG_ARCH_HI3556AV100)			+= phy-hi3556av100-usb.o
51378+obj-$(CONFIG_ARCH_HI3519AV100)			+= phy-hi3519av100-usb.o
51379+obj-$(CONFIG_ARCH_HI3568V100)			+= phy-hi3519av100-usb.o
51380+obj-$(CONFIG_ARCH_HI3516CV500)			+= phy-hi3516cv500-usb.o
51381+obj-$(CONFIG_ARCH_HI3516DV300)			+= phy-hi3516dv300-usb.o
51382+obj-$(CONFIG_ARCH_HI3559V200)			+= phy-hi3559v200-usb.o
51383+obj-$(CONFIG_ARCH_HI3562V100)			+= phy-hi3559v200-usb.o
51384+obj-$(CONFIG_ARCH_HI3566V100)			+= phy-hi3559v200-usb.o
51385+obj-$(CONFIG_ARCH_HI3556V200)			+= phy-hi3556v200-usb.o
51386+obj-$(CONFIG_PHY_HISI_XVP_USB2)		+= phy-hixvp-hisi-usb.o
51387diff --git a/drivers/phy/hibvt/usb/phy-hi3516dv300-usb.c b/drivers/phy/hibvt/usb/phy-hi3516dv300-usb.c
51388new file mode 100644
51389index 000000000..ba232b259
51390--- /dev/null
51391+++ b/drivers/phy/hibvt/usb/phy-hi3516dv300-usb.c
51392@@ -0,0 +1,310 @@
51393+/*
51394+ * phy-hi3516dv300-usb.c
51395+ *
51396+ * USB phy driver.
51397+ *
51398+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2018-2019. All rights reserved.
51399+ *
51400+ * This program is free software; you can redistribute it and/or modify
51401+ * it under the terms of the GNU General Public License as published by
51402+ * the Free Software Foundation; either version 2 of the License, or
51403+ *  (at your option) any later version.
51404+ *
51405+ * This program is distributed in the hope that it will be useful,
51406+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
51407+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
51408+ * GNU General Public License for more details.
51409+ *
51410+ * You should have received a copy of the GNU General Public License
51411+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
51412+ */
51413+
51414+#include <linux/delay.h>
51415+#include <linux/of_address.h>
51416+#include <linux/phy/phy.h>
51417+#include <linux/usb/ch9.h>
51418+
51419+#include "phy-hisi-usb.h"
51420+
51421+#define CRG_BASE_REG           0x140
51422+#define USB2_UTMI_PCTRL        (0x1 << 15)
51423+#define USB2_PHY_TEST_SRST_REQ (0x1 << 14)
51424+#define USB2_UTMI_CKSEL        (0x1 << 13)
51425+#define USB2_UTMI_CKEN         (0x1 << 12)
51426+#define USB2_REF_CKEN          (0x1 << 9)
51427+#define USB2_BUS_CKEN          (0x1 << 8)
51428+#define USB2_VCC_SRST_REQ      (0x1 << 3)
51429+#define USB2_PHY_CKEN          (0x1 << 2)
51430+#define USB2_PHY_PORT_TREQ     (0x1 << 1)
51431+#define USB2_PHY_REQ           (0x1 << 0)
51432+
51433+#define CTRL_BASE_REG 0x100e0000
51434+
51435+#define REG_GUSB3PIPECTL0    0xc2c0
51436+#define PCS_SSP_SOFT_RESET   (0x1 << 31)
51437+#define PORT_DISABLE_SUSPEND (0x1 << 17)
51438+
51439+#define REG_GCTL      0xc110
51440+#define PORT_CAP_DIR  (0x3 << 12)
51441+#define PORT_SET_HOST (0x1 << 12)
51442+
51443+#define GTXTHRCFG       0xc108
51444+#define USB2_G_TXTHRCFG 0x23100000
51445+
51446+#define GRXTHRCFG       0xc10c
51447+#define USB2_G_RXTHRCFG 0x23100000
51448+
51449+#define REG_GUCTL1            0xc11c
51450+#define PARKMODE_DISABLE_FSLS (0x1 << 15)
51451+#define PARKMODE_DISABLE_HS   (0x1 << 16)
51452+#define PARKMODE_DISABLE_SS   (0x1 << 17)
51453+
51454+#define USB2_INNO_PHY_BASE_REG  0x10110000
51455+#define USB2_PHY_CLK_OUTPUT_REG 0x18
51456+#define USB2_PHY_CLK_OUTPUT_VAL 0x0c
51457+#define USB2_INNO_TRIM_OFFSET   0x0c
51458+
51459+#define USB2_VBUS_IO_BASE_REG 0x10ff0000
51460+#define USB2_VBUS_IO_OFFSET   0x40
51461+#define USB2_VBUS_IO_VAL      0x431
51462+
51463+#define USB_TRIM_BASE_REG    0x100a0000
51464+#define USB_TRIM_OFFSET      0x38
51465+#define USB_INNO_TRIM_MASK   0x7c
51466+#define USB_INNO_TRIM_VAL(a) (((a) << 2) & USB_INNO_TRIM_MASK)
51467+#define USB_TRIM_VAL_MASK    0x1f
51468+#define USB_TRIM_VAL_MIN     0xf
51469+#define USB_TRIM_VAL_MAX     0x1c
51470+
51471+#define HS_HIGH_HEIGHT_TUNING_OFFSET 0x8
51472+#define HS_HIGH_HEIGHT_TUNING_MASK   (0x7 << 4)
51473+#define HS_HIGH_HEIGHT_TUNING_VAL    0x5 << 4
51474+
51475+#define PRE_EMPHASIS_TUNING_OFFSET 0x0
51476+#define PRE_EMPHASIS_TUNING_MASK   (0x7 << 0)
51477+#define PRE_EMPHASIS_TUNING_VAL    0x7 << 0
51478+
51479+#define PRE_EMPHASIS_STRENGTH_OFFSET 0x14
51480+#define PRE_EMPHASIS_STRENGTH_MASK   (0x7 << 2)
51481+#define PRE_EMPHASIS_STRENGTH_VAL    0x3 << 2
51482+
51483+#define HS_SLEW_RATE_TUNING_OFFSET 0x74
51484+#define HS_SLEW_RATE_TUNING_MASK   (0x7 << 1)
51485+#define HS_SLEW_RATE_TUNING_VAL    0x7 << 1
51486+
51487+#define DISCONNECT_TRIGGER_OFFSET 0x10
51488+#define DISCONNECT_TRIGGER_MASK   (0xf << 4)
51489+#define DISCONNECT_TRIGGER_VAL    0xd << 4
51490+
51491+static void usb_vbus_multi_gpio(void)
51492+{
51493+	void __iomem *vbus = ioremap(USB2_VBUS_IO_BASE_REG, __1K__);
51494+	if (vbus == NULL)
51495+		return;
51496+
51497+	writel(USB2_VBUS_IO_VAL, vbus + USB2_VBUS_IO_OFFSET);
51498+	udelay(U_LEVEL2);
51499+
51500+	iounmap(vbus);
51501+}
51502+
51503+static void usb_trim_c(void)
51504+{
51505+	unsigned int reg;
51506+	unsigned int trim_val;
51507+	void __iomem *inno_clk_output = NULL;
51508+	void __iomem *usb_trim = NULL;
51509+
51510+	inno_clk_output = ioremap(USB2_INNO_PHY_BASE_REG, __1K__);
51511+	if (inno_clk_output == NULL)
51512+		return;
51513+
51514+	usb_trim = ioremap(USB_TRIM_BASE_REG, __1K__);
51515+	if (usb_trim == NULL)
51516+		goto free;
51517+
51518+	/* set inno phy output clock */
51519+	writel(USB2_PHY_CLK_OUTPUT_VAL, inno_clk_output + USB2_PHY_CLK_OUTPUT_REG);
51520+	udelay(U_LEVEL2);
51521+
51522+	/*
51523+	 * USB Trim config:45ohm HS ODT value tuning & FS/LS
51524+	 * driver strength tuning, adapt it to usb trim val.
51525+	 */
51526+	trim_val = readl(usb_trim + USB_TRIM_OFFSET);
51527+	trim_val &= USB_TRIM_VAL_MASK;
51528+	if ((trim_val >= USB_TRIM_VAL_MIN) && (trim_val <= USB_TRIM_VAL_MAX)) {
51529+		reg = readl(inno_clk_output + USB2_INNO_TRIM_OFFSET);
51530+		udelay(U_LEVEL2);
51531+		reg &= ~USB_INNO_TRIM_MASK;
51532+		reg |= USB_INNO_TRIM_VAL(trim_val);
51533+		writel(reg, inno_clk_output + USB2_INNO_TRIM_OFFSET);
51534+		udelay(U_LEVEL2);
51535+	}
51536+
51537+	iounmap(usb_trim);
51538+free:
51539+	iounmap(inno_clk_output);
51540+	return;
51541+}
51542+
51543+static void usb_crg_c(struct phy *phy)
51544+{
51545+	unsigned int reg;
51546+	struct hisi_priv *priv = phy_get_drvdata(phy);
51547+
51548+	/* usb phy reset */
51549+	reg = readl(priv->peri_crg + CRG_BASE_REG);
51550+	reg |= USB2_PHY_TEST_SRST_REQ;
51551+	writel(reg, priv->peri_crg + CRG_BASE_REG);
51552+	udelay(U_LEVEL5);
51553+
51554+	/* cancel usb phy srst */
51555+	reg = readl(priv->peri_crg + CRG_BASE_REG);
51556+	reg &= ~USB2_PHY_TEST_SRST_REQ;
51557+	writel(reg, priv->peri_crg + CRG_BASE_REG);
51558+	udelay(U_LEVEL2);
51559+
51560+	/* usb2 vcc reset */
51561+	reg = readl(priv->peri_crg + CRG_BASE_REG);
51562+	reg |= USB2_VCC_SRST_REQ;
51563+	writel(reg, priv->peri_crg + CRG_BASE_REG);
51564+	udelay(U_LEVEL6);
51565+
51566+	usb_trim_c();
51567+
51568+	/* open phy ref cken, utmi pctrl and utmi cksel */
51569+	reg = readl(priv->peri_crg + CRG_BASE_REG);
51570+	reg |= USB2_PHY_CKEN;
51571+	reg &= ~USB2_UTMI_PCTRL;
51572+	reg &= ~USB2_UTMI_CKSEL;
51573+	writel(reg, priv->peri_crg + CRG_BASE_REG);
51574+	udelay(U_LEVEL1);
51575+
51576+	/* open utmi cken and controller ref cken */
51577+	reg = readl(priv->peri_crg + CRG_BASE_REG);
51578+	reg |= USB2_UTMI_CKEN;
51579+	reg |= USB2_REF_CKEN;
51580+	writel(reg, priv->peri_crg + CRG_BASE_REG);
51581+	udelay(U_LEVEL1);
51582+
51583+	/* open bus cken */
51584+	reg = readl(priv->peri_crg + CRG_BASE_REG);
51585+	reg |= USB2_BUS_CKEN;
51586+	writel(reg, priv->peri_crg + CRG_BASE_REG);
51587+	udelay(U_LEVEL6);
51588+
51589+	/* cancel POR reset, TPOR reset and vcc reset */
51590+	reg = readl(priv->peri_crg + CRG_BASE_REG);
51591+	reg &= ~USB2_PHY_REQ;
51592+	reg &= ~USB2_PHY_PORT_TREQ;
51593+	reg &= ~USB2_VCC_SRST_REQ;
51594+	writel(reg, priv->peri_crg + CRG_BASE_REG);
51595+	udelay(U_LEVEL6);
51596+}
51597+
51598+static void usb_ctrl_c(struct phy *phy)
51599+{
51600+	unsigned int reg;
51601+	struct hisi_priv *priv = phy_get_drvdata(phy);
51602+
51603+	priv->ctrl_base = ioremap(CTRL_BASE_REG, __64K__);
51604+	if (priv->ctrl_base == NULL)
51605+		return;
51606+
51607+	reg = readl(priv->ctrl_base + REG_GUCTL1);
51608+	reg |= PARKMODE_DISABLE_FSLS;
51609+	reg |= PARKMODE_DISABLE_HS;
51610+	reg |= PARKMODE_DISABLE_SS;
51611+	writel(reg, priv->ctrl_base + REG_GUCTL1);
51612+	udelay(U_LEVEL2);
51613+
51614+	reg = readl(priv->ctrl_base + REG_GUSB3PIPECTL0);
51615+	reg |= PCS_SSP_SOFT_RESET;
51616+	writel(reg, priv->ctrl_base + REG_GUSB3PIPECTL0);
51617+	udelay(U_LEVEL2);
51618+
51619+	reg = readl(priv->ctrl_base + REG_GCTL);
51620+	reg &= ~PORT_CAP_DIR;
51621+	reg |= PORT_SET_HOST; /* [13:12] 01: Host; 10: Device; 11: OTG */
51622+	writel(reg, priv->ctrl_base + REG_GCTL);
51623+	udelay(U_LEVEL2);
51624+
51625+	reg = readl(priv->ctrl_base + REG_GUSB3PIPECTL0);
51626+	reg &= ~PCS_SSP_SOFT_RESET;
51627+	reg &= ~PORT_DISABLE_SUSPEND;  /* disable suspend */
51628+	writel(reg, priv->ctrl_base + REG_GUSB3PIPECTL0);
51629+	udelay(U_LEVEL2);
51630+
51631+	writel(USB2_G_TXTHRCFG, priv->ctrl_base + GTXTHRCFG);
51632+	writel(USB2_G_RXTHRCFG, priv->ctrl_base + GRXTHRCFG);
51633+	udelay(U_LEVEL2);
51634+
51635+	iounmap(priv->ctrl_base);
51636+}
51637+
51638+static void usb_eye_c(struct phy *phy)
51639+{
51640+	unsigned int reg;
51641+	void __iomem *inno_base = NULL;
51642+
51643+	inno_base = ioremap(USB2_INNO_PHY_BASE_REG, __1K__);
51644+	if (inno_base == NULL)
51645+		return;
51646+
51647+	/* HS eye height tuning */
51648+	reg = readl(inno_base + HS_HIGH_HEIGHT_TUNING_OFFSET);
51649+	reg &= ~HS_HIGH_HEIGHT_TUNING_MASK;
51650+	reg |= HS_HIGH_HEIGHT_TUNING_VAL;
51651+	writel(reg, inno_base + HS_HIGH_HEIGHT_TUNING_OFFSET);
51652+
51653+	/* Pre-emphasis tuning */
51654+	reg = readl(inno_base + PRE_EMPHASIS_TUNING_OFFSET);
51655+	reg &= ~PRE_EMPHASIS_TUNING_MASK;
51656+	reg |= PRE_EMPHASIS_TUNING_VAL;
51657+	writel(reg, inno_base + PRE_EMPHASIS_TUNING_OFFSET);
51658+
51659+	/* Pre-emphasis strength */
51660+	reg = readl(inno_base + PRE_EMPHASIS_STRENGTH_OFFSET);
51661+	reg &= ~PRE_EMPHASIS_STRENGTH_MASK;
51662+	reg |= PRE_EMPHASIS_STRENGTH_VAL;
51663+	writel(reg, inno_base + PRE_EMPHASIS_STRENGTH_OFFSET);
51664+
51665+	/* HS driver slew rate tunning */
51666+	reg = readl(inno_base + HS_SLEW_RATE_TUNING_OFFSET);
51667+	reg &= ~HS_SLEW_RATE_TUNING_MASK;
51668+	reg |= HS_SLEW_RATE_TUNING_VAL;
51669+	writel(reg, inno_base + HS_SLEW_RATE_TUNING_OFFSET);
51670+
51671+	/* HOST disconnects detection trigger point */
51672+	reg = readl(inno_base + DISCONNECT_TRIGGER_OFFSET);
51673+	reg &= ~DISCONNECT_TRIGGER_MASK;
51674+	reg |= DISCONNECT_TRIGGER_VAL;
51675+	writel(reg, inno_base + DISCONNECT_TRIGGER_OFFSET);
51676+	iounmap(inno_base);
51677+}
51678+
51679+void hisi_usb_phy_on(struct phy *phy)
51680+{
51681+	usb_crg_c(phy);
51682+
51683+	usb_vbus_multi_gpio();
51684+
51685+	usb_eye_c(phy);
51686+
51687+	usb_ctrl_c(phy);
51688+}
51689+EXPORT_SYMBOL(hisi_usb_phy_on);
51690+
51691+void hisi_usb_phy_off(struct phy *phy)
51692+{
51693+	unsigned int reg;
51694+	struct hisi_priv *priv = phy_get_drvdata(phy);
51695+
51696+	/* usb2 vcc reset */
51697+	reg = readl(priv->peri_crg + CRG_BASE_REG);
51698+	reg |= USB2_VCC_SRST_REQ;
51699+	writel(reg, priv->peri_crg + CRG_BASE_REG);
51700+	udelay(U_LEVEL6);
51701+}
51702+EXPORT_SYMBOL(hisi_usb_phy_off);
51703diff --git a/drivers/phy/hibvt/usb/phy-hisi-usb.c b/drivers/phy/hibvt/usb/phy-hisi-usb.c
51704new file mode 100644
51705index 000000000..da83abdf9
51706--- /dev/null
51707+++ b/drivers/phy/hibvt/usb/phy-hisi-usb.c
51708@@ -0,0 +1,149 @@
51709+/*
51710+ * phy-hisi-usb.c
51711+ *
51712+ * USB phy driver.
51713+ *
51714+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2019. All rights reserved.
51715+ *
51716+ * This program is free software; you can redistribute it and/or modify
51717+ * it under the terms of the GNU General Public License as published by
51718+ * the Free Software Foundation; either version 2 of the License, or
51719+ * (at your option) any later version.
51720+ *
51721+ * This program is distributed in the hope that it will be useful,
51722+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
51723+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
51724+ * GNU General Public License for more details.
51725+ *
51726+ * You should have received a copy of the GNU General Public License
51727+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
51728+ */
51729+
51730+#include <linux/module.h>
51731+#include <linux/phy/phy.h>
51732+#include <linux/platform_device.h>
51733+#include <linux/of_address.h>
51734+
51735+#include "phy-hisi-usb.h"
51736+
51737+static int hisi_usb_phy_probe(struct platform_device *pdev)
51738+{
51739+	struct device *dev = &pdev->dev;
51740+	struct phy *phy = NULL;
51741+	struct hisi_priv *priv = NULL;
51742+	struct device_node *np = pdev->dev.of_node;
51743+
51744+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
51745+	if (priv == NULL)
51746+		return -ENOMEM;
51747+
51748+	phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL);
51749+	if (phy == NULL) {
51750+		devm_kfree(dev, priv);
51751+		return -ENOMEM;
51752+	}
51753+
51754+	priv->peri_crg = of_iomap(np, CRG_NODE_IDX);
51755+	if (IS_ERR(priv->peri_crg))
51756+		priv->peri_crg = NULL;
51757+
51758+	priv->misc_ctrl = of_iomap(np, MISC_NODE_IDX);
51759+	if (IS_ERR(priv->misc_ctrl))
51760+		priv->misc_ctrl = NULL;
51761+
51762+	priv->sys_ctrl = of_iomap(np, SYS_NODE_IDX);
51763+	if (IS_ERR(priv->sys_ctrl))
51764+		priv->sys_ctrl = NULL;
51765+
51766+	priv->ctrl_base = of_iomap(np, CTRL_NODE_IDX);
51767+	if (IS_ERR(priv->ctrl_base))
51768+		priv->ctrl_base = NULL;
51769+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100)
51770+	if (of_property_read_u32(np, "phyid", &priv->phyid))
51771+		return -EINVAL;
51772+#endif
51773+	platform_set_drvdata(pdev, phy);
51774+	phy_set_drvdata(phy, priv);
51775+
51776+#ifdef CONFIG_PHY_HISI_USB2
51777+	hisi_usb_phy_on(phy);
51778+#endif
51779+#ifdef CONFIG_PHY_HISI_USB3
51780+	hisi_usb3_phy_on(phy);
51781+#endif
51782+	iounmap(priv->peri_crg);
51783+	iounmap(priv->misc_ctrl);
51784+	iounmap(priv->sys_ctrl);
51785+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100)
51786+	iounmap(priv->ctrl_base);
51787+#endif
51788+
51789+	return 0;
51790+}
51791+
51792+static int hisi_usb_phy_remove(struct platform_device *pdev)
51793+{
51794+	struct device *dev = &pdev->dev;
51795+	struct phy *phy = dev_get_drvdata(&pdev->dev);
51796+	struct hisi_priv *priv = phy_get_drvdata(phy);
51797+
51798+#ifdef CONFIG_PHY_HISI_USB2
51799+	hisi_usb_phy_off(phy);
51800+#endif
51801+#ifdef CONFIG_PHY_HISI_USB3
51802+	hisi_usb3_phy_off(phy);
51803+#endif
51804+	devm_kfree(dev, priv);
51805+	devm_kfree(dev, phy);
51806+
51807+	return 0;
51808+}
51809+
51810+static const struct of_device_id hisi_usb_phy_of_match[] = {
51811+	{ .compatible = "hisilicon,hisi-usb-phy", },
51812+	{ .compatible = "hisilicon,hisi-usb3-phy_0", },
51813+	{ .compatible = "hisilicon,hisi-usb3-phy_1", },
51814+	{ },
51815+};
51816+MODULE_DEVICE_TABLE(of, hisi_usb_phy_of_match);
51817+
51818+#ifdef CONFIG_PM_SLEEP
51819+static int hisi_usb_phy_suspend(struct device *dev)
51820+{
51821+	struct phy *phy = dev_get_drvdata(dev);
51822+#ifdef CONFIG_PHY_HISI_USB2
51823+	hisi_usb_phy_off(phy);
51824+#endif
51825+#ifdef CONFIG_PHY_HISI_USB3
51826+	hisi_usb3_phy_off(phy);
51827+#endif
51828+	return 0;
51829+}
51830+
51831+static int hisi_usb_phy_resume(struct device *dev)
51832+{
51833+	struct phy *phy = dev_get_drvdata(dev);
51834+#ifdef CONFIG_PHY_HISI_USB2
51835+	hisi_usb_phy_on(phy);
51836+#endif
51837+#ifdef CONFIG_PHY_HISI_USB3
51838+	hisi_usb3_phy_on(phy);
51839+#endif
51840+	return 0;
51841+}
51842+#endif /* CONFIG_PM_SLEEP */
51843+
51844+static SIMPLE_DEV_PM_OPS(hisi_usb_pm_ops, hisi_usb_phy_suspend,
51845+			 hisi_usb_phy_resume);
51846+
51847+static struct platform_driver hisi_usb_phy_driver = {
51848+	.probe	= hisi_usb_phy_probe,
51849+	.remove = hisi_usb_phy_remove,
51850+	.driver = {
51851+		.name	= "hisi-usb-phy",
51852+		.pm	= &hisi_usb_pm_ops,
51853+		.of_match_table	= hisi_usb_phy_of_match,
51854+	}
51855+};
51856+module_platform_driver(hisi_usb_phy_driver);
51857+MODULE_LICENSE("GPL v2");
51858diff --git a/drivers/phy/hibvt/usb/phy-hisi-usb.h b/drivers/phy/hibvt/usb/phy-hisi-usb.h
51859new file mode 100644
51860index 000000000..5e20e6e4a
51861--- /dev/null
51862+++ b/drivers/phy/hibvt/usb/phy-hisi-usb.h
51863@@ -0,0 +1,72 @@
51864+/*
51865+ * phy-hisi-usb.h
51866+ *
51867+ * USB phy driver headerfile.
51868+ *
51869+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2019. All rights reserved.
51870+ *
51871+ * This program is free software; you can redistribute it and/or modify
51872+ * it under the terms of the GNU General Public License as published by
51873+ * the Free Software Foundation; either version 2 of the License, or
51874+ * (at your option) any later version.
51875+ *
51876+ * This program is distributed in the hope that it will be useful,
51877+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
51878+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
51879+ * GNU General Public License for more details.
51880+ *
51881+ * You should have received a copy of the GNU General Public License
51882+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
51883+ */
51884+
51885+#ifndef USB2_INCLUDE_PHY_H
51886+#define USB2_INCLUDE_PHY_H
51887+
51888+extern void hisi_usb_phy_on(struct phy *phy);
51889+extern void hisi_usb_phy_off(struct phy *phy);
51890+extern void hisi_usb3_phy_on(struct phy *phy);
51891+extern void hisi_usb3_phy_off(struct phy *phy);
51892+
51893+struct hisi_priv {
51894+	void __iomem    *peri_crg;
51895+	void __iomem	*misc_ctrl;
51896+	void __iomem	*sys_ctrl;
51897+	void __iomem	*ctrl_base;
51898+	unsigned int	phyid;
51899+};
51900+
51901+typedef enum mode {
51902+	PCIE_X2 = 0,
51903+	PCIE_X1,
51904+	USB3
51905+} combphy_mode;
51906+
51907+#define U_LEVEL1 10
51908+#define U_LEVEL2 20
51909+#define U_LEVEL3 30
51910+#define U_LEVEL4 50
51911+#define U_LEVEL5 100
51912+#define U_LEVEL6 200
51913+#define U_LEVEL7 300
51914+#define U_LEVEL8 500
51915+
51916+#define M_LEVEL1 2
51917+#define M_LEVEL2 5
51918+#define M_LEVEL3 10
51919+#define M_LEVEL4 20
51920+#define M_LEVEL5 50
51921+#define M_LEVEL6 100
51922+#define M_LEVEL7 200
51923+
51924+#define __1K__  0x400
51925+#define __2K__  0x800
51926+#define __4K__  0x1000
51927+#define __8K__  0x2000
51928+#define __64K__ 0x10000
51929+
51930+#define CRG_NODE_IDX    0
51931+#define MISC_NODE_IDX   1
51932+#define SYS_NODE_IDX    2
51933+#define CTRL_NODE_IDX   3
51934+
51935+#endif /* USB2_INCLUDE_PHY_H */
51936diff --git a/drivers/phy/hibvt/usb/phy-hixvp-hisi-usb.c b/drivers/phy/hibvt/usb/phy-hixvp-hisi-usb.c
51937new file mode 100644
51938index 000000000..be6831947
51939--- /dev/null
51940+++ b/drivers/phy/hibvt/usb/phy-hixvp-hisi-usb.c
51941@@ -0,0 +1,803 @@
51942+/*
51943+ * phy-hixvp-hisi-usb.c
51944+ *
51945+ * USB phy driver.
51946+ *
51947+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2019. All rights reserved.
51948+ *
51949+ * This program is free software; you can redistribute  it and/or modify it
51950+ * under  the terms of  the GNU General Public License as published by the
51951+ * Free Software Foundation;  either version 2 of the  License, or (at your
51952+ * option) any later version.
51953+ *
51954+ * This program is distributed in the hope that it will be useful,
51955+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
51956+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51957+ * GNU General Public License for more details.
51958+ *
51959+ * You should have received a copy of the GNU General Public License
51960+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
51961+ *
51962+ */
51963+#include <linux/clk-provider.h>
51964+#include <linux/clk.h>
51965+#include <linux/delay.h>
51966+#include <linux/module.h>
51967+#include <linux/of_address.h>
51968+#include <linux/phy/phy.h>
51969+#include <linux/platform_device.h>
51970+#include <linux/reset.h>
51971+#include <linux/usb/ch9.h>
51972+
51973+#include "phy-hisi-usb.h"
51974+
51975+#define HIXVP_PHY_TRIM_OFFSET 0x0008
51976+#define HIXVP_PHY_TRIM_MASK   0x1f00
51977+#define HIXVP_PHY_TRIM_VAL(a) (((a) << 8) & HIXVP_PHY_TRIM_MASK)
51978+
51979+#define HIXVP_PHY_SVB_OFFSET 0x0000
51980+#define HIXVP_PHY_SVB_MASK   0x0f000000
51981+#define HIXVP_PHY_SVB_VAL(a) (((a) << 24) & HIXVP_PHY_SVB_MASK)
51982+
51983+struct hisi_hixvp_priv {
51984+	void __iomem *crg_base;
51985+	void __iomem *phy_base;
51986+	void __iomem *pin_base;
51987+	struct phy *phy;
51988+	struct device *dev;
51989+	struct clk **clks;
51990+	int num_clocks;
51991+	u32 phy_pll_offset;
51992+	u32 phy_pll_mask;
51993+	u32 phy_pll_val;
51994+	u32 crg_offset;
51995+	u32 crg_defal_mask;
51996+	u32 crg_defal_val;
51997+	u32 vbus_offset;
51998+	u32 vbus_val;
51999+	int vbus_flag;
52000+	u32 pwren_offset;
52001+	u32 pwren_val;
52002+	int pwren_flag;
52003+	u32 ana_cfg_0_eye_val;
52004+	u32 ana_cfg_0_offset;
52005+	int ana_cfg_0_flag;
52006+	u32 ana_cfg_2_eye_val;
52007+	u32 ana_cfg_2_offset;
52008+	int ana_cfg_2_flag;
52009+	u32 ana_cfg_4_eye_val;
52010+	u32 ana_cfg_4_offset;
52011+	int ana_cfg_4_flag;
52012+	struct reset_control *usb_phy_tpor_rst;
52013+	struct reset_control *usb_phy_por_rst;
52014+	u32 trim_otp_addr;
52015+	u32 trim_otp_mask;
52016+	u32 trim_otp_bit_offset;
52017+	u32 trim_otp_min;
52018+	u32 trim_otp_max;
52019+	int trim_flag;
52020+	u32 svb_otp_addr;
52021+	u32 svb_otp_predev5_min;
52022+	u32 svb_otp_predev5_max;
52023+	u32 svb_phy_predev5_val;
52024+	int svb_predev5_flag;
52025+	u32 svb_otp_predev4_min;
52026+	u32 svb_otp_predev4_max;
52027+	u32 svb_phy_predev4_val;
52028+	int svb_predev4_flag;
52029+	u32 svb_otp_predev3_min;
52030+	u32 svb_otp_predev3_max;
52031+	u32 svb_phy_predev3_val;
52032+	int svb_predev3_flag;
52033+	u32 svb_otp_predev2_min;
52034+	u32 svb_otp_predev2_max;
52035+	u32 svb_phy_predev2_val;
52036+	int svb_predev2_flag;
52037+	int svb_flag;
52038+};
52039+
52040+void hisi_usb_hixvp_def_all_exist(struct hisi_hixvp_priv *priv)
52041+{
52042+	if (priv == NULL)
52043+		return;
52044+
52045+	/* All parameters exist by default */
52046+	priv->vbus_flag = 1;
52047+
52048+	priv->pwren_flag = 1;
52049+
52050+	priv->ana_cfg_0_flag = 1;
52051+
52052+	priv->ana_cfg_2_flag = 1;
52053+
52054+	priv->ana_cfg_4_flag = 1;
52055+
52056+	priv->trim_flag = 1;
52057+
52058+	priv->svb_predev5_flag = 1;
52059+
52060+	priv->svb_predev4_flag = 1;
52061+
52062+	priv->svb_predev3_flag = 1;
52063+
52064+	priv->svb_predev2_flag = 1;
52065+
52066+	priv->svb_flag = 1;
52067+}
52068+
52069+void hisi_usb_hixvp_get_eye_para(const struct device *dev,
52070+    struct hisi_hixvp_priv *priv)
52071+{
52072+	int ret;
52073+
52074+	if ((dev == NULL) || (priv == NULL))
52075+		return;
52076+
52077+	if (dev->of_node == NULL)
52078+		return;
52079+
52080+	/*
52081+	 * Get phy eye parameters,if you want to change them,please open
52082+	 * dtsi file and modify parameters at phy node.
52083+	 */
52084+	ret = of_property_read_u32(dev->of_node, "ana_cfg_0_eye_val",
52085+				   &(priv->ana_cfg_0_eye_val));
52086+	if (ret)
52087+		priv->ana_cfg_0_flag = 0;
52088+
52089+	ret = of_property_read_u32(dev->of_node, "ana_cfg_0_offset",
52090+				   &(priv->ana_cfg_0_offset));
52091+	if (ret)
52092+		priv->ana_cfg_0_flag = 0;
52093+
52094+	ret = of_property_read_u32(dev->of_node, "ana_cfg_2_eye_val",
52095+				   &(priv->ana_cfg_2_eye_val));
52096+	if (ret)
52097+		priv->ana_cfg_2_flag = 0;
52098+
52099+	ret = of_property_read_u32(dev->of_node, "ana_cfg_2_offset",
52100+				   &(priv->ana_cfg_2_offset));
52101+	if (ret)
52102+		priv->ana_cfg_2_flag = 0;
52103+
52104+	ret = of_property_read_u32(dev->of_node, "ana_cfg_4_eye_val",
52105+				   &(priv->ana_cfg_4_eye_val));
52106+	if (ret)
52107+		priv->ana_cfg_4_flag = 0;
52108+
52109+	ret = of_property_read_u32(dev->of_node, "ana_cfg_4_offset",
52110+				   &(priv->ana_cfg_4_offset));
52111+	if (ret)
52112+		priv->ana_cfg_4_flag = 0;
52113+}
52114+
52115+void hisi_usb_hixvp_phy_eye_config(const struct hisi_hixvp_priv *priv)
52116+{
52117+	if (priv == NULL)
52118+		return;
52119+
52120+	if (priv->ana_cfg_0_flag)
52121+		writel(priv->ana_cfg_0_eye_val, priv->phy_base + priv->ana_cfg_0_offset);
52122+
52123+	if (priv->ana_cfg_2_flag)
52124+		writel(priv->ana_cfg_2_eye_val, priv->phy_base + priv->ana_cfg_2_offset);
52125+
52126+	if (priv->ana_cfg_4_flag)
52127+		writel(priv->ana_cfg_4_eye_val, priv->phy_base + priv->ana_cfg_4_offset);
52128+}
52129+
52130+void hisi_usb_hixvp_get_trim_para(const struct device *dev,
52131+    struct hisi_hixvp_priv *priv)
52132+{
52133+	int ret;
52134+
52135+	if ((dev == NULL) || (priv == NULL))
52136+		return;
52137+
52138+	if (dev->of_node == NULL)
52139+		return;
52140+
52141+	/* get phy trim parameters */
52142+	ret = of_property_read_u32(dev->of_node, "trim_otp_addr",
52143+				   &(priv->trim_otp_addr));
52144+	if (ret)
52145+		priv->trim_flag = 0;
52146+
52147+	ret = of_property_read_u32(dev->of_node, "trim_otp_mask",
52148+				   &(priv->trim_otp_mask));
52149+	if (ret)
52150+		priv->trim_flag = 0;
52151+
52152+	ret = of_property_read_u32(dev->of_node, "trim_otp_bit_offset",
52153+				   &(priv->trim_otp_bit_offset));
52154+	if (ret)
52155+		priv->trim_flag = 0;
52156+
52157+	ret = of_property_read_u32(dev->of_node, "trim_otp_min", &(priv->trim_otp_min));
52158+	if (ret)
52159+		priv->trim_flag = 0;
52160+
52161+	ret = of_property_read_u32(dev->of_node, "trim_otp_max", &(priv->trim_otp_max));
52162+	if (ret)
52163+		priv->trim_flag = 0;
52164+}
52165+
52166+void hisi_usb_hixvp_phy_trim_config(const struct hisi_hixvp_priv *priv)
52167+{
52168+	unsigned int trim_otp_val;
52169+	unsigned int reg;
52170+	void __iomem *phy_trim = NULL;
52171+
52172+	if (priv == NULL)
52173+		return;
52174+
52175+	if (priv->trim_flag) {
52176+		phy_trim = ioremap_nocache(priv->trim_otp_addr, __1K__);
52177+		if (phy_trim == NULL)
52178+			return;
52179+
52180+		reg = readl(phy_trim);
52181+		trim_otp_val = (reg & priv->trim_otp_mask);
52182+		if ((trim_otp_val >= priv->trim_otp_min) &&
52183+				(trim_otp_val <= priv->trim_otp_max)) {
52184+			/* set trim value to HiXVPV100 phy */
52185+			reg = readl(priv->phy_base + HIXVP_PHY_TRIM_OFFSET);
52186+			reg &= ~HIXVP_PHY_TRIM_MASK;
52187+			reg |= HIXVP_PHY_TRIM_VAL(trim_otp_val >> priv->trim_otp_bit_offset);
52188+			writel(reg, priv->phy_base + HIXVP_PHY_TRIM_OFFSET);
52189+		}
52190+		iounmap(phy_trim);
52191+	}
52192+}
52193+
52194+void hisi_usb_hixvp_get_svb_para_1(const struct device *dev,
52195+    struct hisi_hixvp_priv *priv)
52196+{
52197+	int ret;
52198+
52199+	if ((dev == NULL) || (priv == NULL))
52200+		return;
52201+
52202+	if (dev->of_node == NULL)
52203+		return;
52204+
52205+	/* get phy svb parmteters */
52206+	ret = of_property_read_u32(dev->of_node, "svb_otp_addr", &
52207+				   (priv->svb_otp_addr));
52208+	if (ret)
52209+		priv->svb_flag = 0;
52210+
52211+	ret = of_property_read_u32(dev->of_node, "svb_otp_predev5_min",
52212+				   &(priv->svb_otp_predev5_min));
52213+	if (ret)
52214+		priv->svb_predev5_flag = 0;
52215+
52216+	ret = of_property_read_u32(dev->of_node, "svb_otp_predev5_max",
52217+				   &(priv->svb_otp_predev5_max));
52218+	if (ret)
52219+		priv->svb_predev5_flag = 0;
52220+
52221+	ret = of_property_read_u32(dev->of_node, "svb_phy_predev5_val",
52222+				   &(priv->svb_phy_predev5_val));
52223+	if (ret)
52224+		priv->svb_predev5_flag = 0;
52225+
52226+	ret = of_property_read_u32(dev->of_node, "svb_otp_predev4_min",
52227+				   &(priv->svb_otp_predev4_min));
52228+	if (ret)
52229+		priv->svb_predev4_flag = 0;
52230+
52231+	ret = of_property_read_u32(dev->of_node, "svb_otp_predev4_max",
52232+				   &(priv->svb_otp_predev4_max));
52233+	if (ret)
52234+		priv->svb_predev4_flag = 0;
52235+
52236+	ret = of_property_read_u32(dev->of_node, "svb_phy_predev4_val",
52237+				   &(priv->svb_phy_predev4_val));
52238+	if (ret)
52239+		priv->svb_predev4_flag = 0;
52240+}
52241+
52242+void hisi_usb_hixvp_get_svb_para_2(const struct device *dev,
52243+    struct hisi_hixvp_priv *priv)
52244+{
52245+	int ret;
52246+
52247+	if ((dev == NULL) || (priv == NULL))
52248+		return;
52249+
52250+	if (dev->of_node == NULL)
52251+		return;
52252+
52253+	ret = of_property_read_u32(dev->of_node, "svb_otp_predev3_min",
52254+				   &(priv->svb_otp_predev3_min));
52255+	if (ret)
52256+		priv->svb_predev3_flag = 0;
52257+
52258+	ret = of_property_read_u32(dev->of_node, "svb_otp_predev3_max",
52259+				   &(priv->svb_otp_predev3_max));
52260+	if (ret)
52261+		priv->svb_predev3_flag = 0;
52262+
52263+	ret = of_property_read_u32(dev->of_node, "svb_phy_predev3_val",
52264+				   &(priv->svb_phy_predev3_val));
52265+	if (ret)
52266+		priv->svb_predev3_flag = 0;
52267+
52268+	ret = of_property_read_u32(dev->of_node, "svb_otp_predev2_min",
52269+				   &(priv->svb_otp_predev2_min));
52270+	if (ret)
52271+		priv->svb_predev2_flag = 0;
52272+
52273+	ret = of_property_read_u32(dev->of_node, "svb_otp_predev2_max",
52274+				   &(priv->svb_otp_predev2_max));
52275+	if (ret)
52276+		priv->svb_predev2_flag = 0;
52277+
52278+	ret = of_property_read_u32(dev->of_node, "svb_phy_predev2_val",
52279+				   &(priv->svb_phy_predev2_val));
52280+	if (ret)
52281+		priv->svb_predev2_flag = 0;
52282+}
52283+
52284+void hisi_usb_hixvp_phy_svb_config(const struct hisi_hixvp_priv *priv)
52285+{
52286+	unsigned int reg;
52287+	unsigned int ret;
52288+	void __iomem *phy_svb = NULL;
52289+
52290+	if (priv == NULL)
52291+		return;
52292+
52293+	if (priv->svb_flag) {
52294+		phy_svb = ioremap_nocache(priv->svb_otp_addr, __1K__);
52295+		if (phy_svb == NULL)
52296+			return;
52297+
52298+		ret = readl(phy_svb);
52299+		reg = readl(priv->phy_base + HIXVP_PHY_SVB_OFFSET);
52300+		reg &= ~HIXVP_PHY_SVB_MASK;
52301+		if ((ret >= priv->svb_otp_predev5_min) &&
52302+				(ret < priv->svb_otp_predev5_max) && (priv->svb_predev5_flag))
52303+			reg |= HIXVP_PHY_SVB_VAL(priv->svb_phy_predev5_val);
52304+		else if ((ret >= priv->svb_otp_predev4_min) &&
52305+				(ret < priv->svb_otp_predev4_max) && (priv->svb_predev4_flag))
52306+			reg |= HIXVP_PHY_SVB_VAL(priv->svb_phy_predev4_val);
52307+		else if ((ret >= priv->svb_otp_predev3_min) &&
52308+				(ret <= priv->svb_otp_predev3_max) && (priv->svb_predev3_flag))
52309+			reg |= HIXVP_PHY_SVB_VAL(priv->svb_phy_predev3_val);
52310+		else if ((ret > priv->svb_otp_predev2_min) &&
52311+				(ret <= priv->svb_otp_predev2_max) && (priv->svb_predev2_flag))
52312+			reg |= HIXVP_PHY_SVB_VAL(priv->svb_phy_predev2_val);
52313+		else
52314+			reg |= HIXVP_PHY_SVB_VAL(priv->svb_phy_predev4_val);
52315+
52316+		writel(reg, priv->phy_base + HIXVP_PHY_SVB_OFFSET);
52317+		iounmap(phy_svb);
52318+	}
52319+}
52320+
52321+static void hisi_usb_vbus_and_pwren_config(const struct device *dev,
52322+    struct hisi_hixvp_priv *priv)
52323+{
52324+	int ret;
52325+
52326+	if ((dev == NULL) || (priv == NULL))
52327+		return;
52328+
52329+	if (dev->of_node == NULL)
52330+		return;
52331+
52332+	/* Some chips do not have VBUS encapsulation and need to be configured */
52333+	ret = of_property_read_u32(dev->of_node, "vbus_offset", &(priv->vbus_offset));
52334+	if (ret)
52335+		priv->vbus_flag = 0;
52336+
52337+	ret = of_property_read_u32(dev->of_node, "vbus_val", &(priv->vbus_val));
52338+	if (ret)
52339+		priv->vbus_flag = 0;
52340+
52341+	/* Some chips do not have PWREN encapsulation and need to be configured */
52342+	ret = of_property_read_u32(dev->of_node, "pwren_offset", &(priv->pwren_offset));
52343+	if (ret)
52344+		priv->pwren_flag = 0;
52345+
52346+	ret = of_property_read_u32(dev->of_node, "pwren_val", &(priv->pwren_val));
52347+	if (ret)
52348+		priv->pwren_flag = 0;
52349+
52350+	if (priv->vbus_flag)
52351+		writel(priv->vbus_val, priv->pin_base + priv->vbus_offset);
52352+
52353+	udelay(U_LEVEL2);
52354+
52355+	if (priv->pwren_flag)
52356+		writel(priv->pwren_val, priv->pin_base + priv->pwren_offset);
52357+
52358+	udelay(U_LEVEL2);
52359+}
52360+
52361+static int hisi_usb_hixvp_get_pll_clk(const struct device *dev,
52362+    struct hisi_hixvp_priv *priv)
52363+{
52364+	int ret;
52365+
52366+	if ((dev == NULL) || (priv == NULL))
52367+		return -EINVAL;
52368+
52369+	if (dev->of_node == NULL)
52370+		return -EINVAL;
52371+
52372+	/* Get phy pll clk config parameters from the phy node of the dtsi file */
52373+	ret = of_property_read_u32(dev->of_node, "phy_pll_offset",
52374+				   &(priv->phy_pll_offset));
52375+	if (ret) {
52376+		dev_err(dev, "get phy_pll_offset failed: %d\n", ret);
52377+		return ret;
52378+	}
52379+
52380+	ret = of_property_read_u32(dev->of_node, "phy_pll_mask", &(priv->phy_pll_mask));
52381+	if (ret) {
52382+		dev_err(dev, "get phy_pll_mask failed: %d\n", ret);
52383+		return ret;
52384+	}
52385+
52386+	ret = of_property_read_u32(dev->of_node, "phy_pll_val", &(priv->phy_pll_val));
52387+	if (ret) {
52388+		dev_err(dev, "get phy_pll_val failed: %d\n", ret);
52389+		return ret;
52390+	}
52391+
52392+	return 0;
52393+}
52394+
52395+static int hisi_usb_hixvp_set_crg_val(const struct device *dev,
52396+    struct hisi_hixvp_priv *priv)
52397+{
52398+	int ret;
52399+	unsigned int reg;
52400+
52401+	if ((dev == NULL) || (priv == NULL))
52402+		return -EINVAL;
52403+
52404+	if (dev->of_node == NULL)
52405+		return -EINVAL;
52406+
52407+	/* Get CRG default value from the phy node of the dtsi file */
52408+	ret = of_property_read_u32(dev->of_node, "crg_offset", &(priv->crg_offset));
52409+	if (ret) {
52410+		dev_err(dev, "get crg_offset failed: %d\n", ret);
52411+		return ret;
52412+	}
52413+
52414+	ret = of_property_read_u32(dev->of_node, "crg_defal_mask",
52415+				   &(priv->crg_defal_mask));
52416+	if (ret) {
52417+		dev_err(dev, "get crg_defal_mask failed: %d\n", ret);
52418+		return ret;
52419+	}
52420+
52421+	ret = of_property_read_u32(dev->of_node, "crg_defal_val",
52422+				   &(priv->crg_defal_val));
52423+	if (ret) {
52424+		dev_err(dev, "get crg_defal_val failed: %d\n", ret);
52425+		return ret;
52426+	}
52427+
52428+	/* write phy crg default value */
52429+	reg = readl(priv->crg_base + priv->crg_offset);
52430+	reg &= ~priv->crg_defal_mask;
52431+	reg |= priv->crg_defal_val;
52432+	writel(reg, priv->crg_base + priv->crg_offset);
52433+
52434+	return 0;
52435+}
52436+
52437+static int hisi_usb_hixvp_phy_get_para(struct device *dev,
52438+    struct hisi_hixvp_priv *priv)
52439+{
52440+	int ret;
52441+
52442+	if ((dev == NULL) || (priv == NULL))
52443+		return -EINVAL;
52444+
52445+	hisi_usb_hixvp_def_all_exist(priv);
52446+
52447+	ret = hisi_usb_hixvp_get_pll_clk(dev, priv);
52448+	if (ret) {
52449+		dev_err(dev, "get pll clk failed: %d\n", ret);
52450+		return ret;
52451+	}
52452+
52453+	hisi_usb_hixvp_get_trim_para(dev, priv);
52454+	hisi_usb_hixvp_get_eye_para(dev, priv);
52455+	hisi_usb_hixvp_get_svb_para_1(dev, priv);
52456+	hisi_usb_hixvp_get_svb_para_2(dev, priv);
52457+
52458+	return 0;
52459+}
52460+
52461+static int hisi_usb_hixvp_phy_get_clks(struct hisi_hixvp_priv *priv, int count)
52462+{
52463+	struct device *dev = priv->dev;
52464+	struct device_node *np = dev->of_node;
52465+	int i;
52466+
52467+	priv->num_clocks = count;
52468+
52469+	if (!count)
52470+		return 0;
52471+
52472+	priv->clks =
52473+		devm_kcalloc(dev, priv->num_clocks, sizeof(struct clk *), GFP_KERNEL);
52474+	if (priv->clks == NULL)
52475+		return -ENOMEM;
52476+
52477+	for (i = 0; i < priv->num_clocks; i++) {
52478+		struct clk *clk;
52479+
52480+		clk = of_clk_get(np, i);
52481+		if (IS_ERR(clk)) {
52482+			while (--i >= 0)
52483+				clk_put(priv->clks[i]);
52484+
52485+			devm_kfree(dev, priv->clks);
52486+			priv->clks = NULL;
52487+			return PTR_ERR(clk);
52488+		}
52489+
52490+		priv->clks[i] = clk;
52491+	}
52492+	return 0;
52493+}
52494+
52495+static int hisi_usb_hixvp_clk_rst_config(struct platform_device *pdev,
52496+    struct hisi_hixvp_priv *priv)
52497+{
52498+	struct device *dev = &pdev->dev;
52499+	struct device_node *np = pdev->dev.of_node;
52500+	int ret;
52501+
52502+	ret = hisi_usb_hixvp_phy_get_clks(priv, of_clk_get_parent_count(np));
52503+	if (ret) {
52504+		dev_err(dev, "get hixvp phy clk failed\n");
52505+		return ret;
52506+	}
52507+
52508+	priv->usb_phy_tpor_rst = devm_reset_control_get(dev, "phy_tpor_reset");
52509+	if (IS_ERR_OR_NULL(priv->usb_phy_tpor_rst)) {
52510+		dev_err(dev, "get phy_tpor_reset failed: %d\n", ret);
52511+		return PTR_ERR(priv->usb_phy_tpor_rst);
52512+	}
52513+
52514+	priv->usb_phy_por_rst = devm_reset_control_get(dev, "phy_por_reset");
52515+	if (IS_ERR_OR_NULL(priv->usb_phy_por_rst)) {
52516+		dev_err(dev, "get phy_por_reset failed: %d\n", ret);
52517+		return PTR_ERR(priv->usb_phy_por_rst);
52518+	}
52519+
52520+	return 0;
52521+}
52522+
52523+static int hisi_usb_hixvp_iomap(struct device_node *np,
52524+				struct hisi_hixvp_priv *priv)
52525+{
52526+	if ((np == NULL) || (priv == NULL))
52527+		return -EINVAL;
52528+
52529+	priv->phy_base = of_iomap(np, 0);
52530+	if (IS_ERR(priv->phy_base))
52531+		return -ENOMEM;
52532+
52533+	priv->crg_base = of_iomap(np, 1);
52534+	if (IS_ERR(priv->crg_base)) {
52535+		iounmap(priv->phy_base);
52536+		return -ENOMEM;
52537+	}
52538+
52539+	priv->pin_base = of_iomap(np, 2);
52540+	if (IS_ERR(priv->pin_base)) {
52541+		iounmap(priv->phy_base);
52542+		iounmap(priv->crg_base);
52543+		return -ENOMEM;
52544+	}
52545+
52546+	return 0;
52547+}
52548+
52549+static int hisi_usb_hixvp_phy_init(struct phy *phy)
52550+{
52551+	struct hisi_hixvp_priv *priv = phy_get_drvdata(phy);
52552+	int i, ret;
52553+	unsigned int reg;
52554+
52555+	for (i = 0; i < priv->num_clocks; i++) {
52556+		ret = clk_prepare_enable(priv->clks[i]);
52557+		if (ret < 0) {
52558+			while (--i >= 0) {
52559+				clk_disable_unprepare(priv->clks[i]);
52560+				clk_put(priv->clks[i]);
52561+			}
52562+		}
52563+	}
52564+
52565+	udelay(U_LEVEL5);
52566+
52567+	/* undo por reset */
52568+	ret = reset_control_deassert(priv->usb_phy_por_rst);
52569+	if (ret)
52570+		return ret;
52571+
52572+	/* pll out clk */
52573+	reg = readl(priv->phy_base + priv->phy_pll_offset);
52574+	reg &= ~priv->phy_pll_mask;
52575+	reg |= priv->phy_pll_val;
52576+	writel(reg, priv->phy_base + priv->phy_pll_offset);
52577+
52578+	mdelay(M_LEVEL1);
52579+
52580+	/* undo tpor reset */
52581+	ret = reset_control_deassert(priv->usb_phy_tpor_rst);
52582+	if (ret)
52583+		return ret;
52584+
52585+	udelay(U_LEVEL6);
52586+
52587+	hisi_usb_hixvp_phy_eye_config(priv);
52588+
52589+	hisi_usb_hixvp_phy_trim_config(priv);
52590+
52591+	hisi_usb_hixvp_phy_svb_config(priv);
52592+	return 0;
52593+}
52594+
52595+static int hisi_usb_hixvp_phy_exit(struct phy *phy)
52596+{
52597+	struct hisi_hixvp_priv *priv = phy_get_drvdata(phy);
52598+	int i, ret;
52599+
52600+	for (i = 0; i < priv->num_clocks; i++)
52601+		clk_disable_unprepare(priv->clks[i]);
52602+
52603+	ret = reset_control_assert(priv->usb_phy_por_rst);
52604+	if (ret)
52605+		return ret;
52606+
52607+	ret = reset_control_assert(priv->usb_phy_tpor_rst);
52608+	if (ret)
52609+		return ret;
52610+
52611+	return 0;
52612+}
52613+
52614+static const struct phy_ops hisi_usb_hixvp_phy_ops = {
52615+	.init = hisi_usb_hixvp_phy_init,
52616+	.exit = hisi_usb_hixvp_phy_exit,
52617+	.owner = THIS_MODULE,
52618+};
52619+
52620+static int hisi_usb_hixvp_phy_probe(struct platform_device *pdev)
52621+{
52622+	struct device *dev = &pdev->dev;
52623+	struct phy *phy = NULL;
52624+	struct hisi_hixvp_priv *priv = NULL;
52625+	struct device_node *np = pdev->dev.of_node;
52626+	struct phy_provider *phy_provider = NULL;
52627+	int ret;
52628+
52629+	phy = devm_phy_create(dev, dev->of_node, &hisi_usb_hixvp_phy_ops);
52630+	if (IS_ERR(phy))
52631+		return PTR_ERR(phy);
52632+
52633+	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
52634+	if (priv == NULL)
52635+		return -ENOMEM;
52636+
52637+	ret = hisi_usb_hixvp_iomap(np, priv);
52638+	if (ret) {
52639+		devm_kfree(dev, priv);
52640+		priv = NULL;
52641+
52642+		return -ENOMEM;
52643+	}
52644+
52645+	platform_set_drvdata(pdev, priv);
52646+	priv->dev = dev;
52647+
52648+	ret = hisi_usb_hixvp_clk_rst_config(pdev, priv);
52649+	if (ret)
52650+		goto xvp_unmap;
52651+
52652+	ret = hisi_usb_hixvp_phy_get_para(dev, priv);
52653+	if (ret)
52654+		goto xvp_unmap;
52655+
52656+	hisi_usb_vbus_and_pwren_config(dev, priv);
52657+
52658+	ret = hisi_usb_hixvp_set_crg_val(dev, priv);
52659+	if (ret)
52660+		goto xvp_unmap;
52661+
52662+	platform_set_drvdata(pdev, priv);
52663+	phy_set_drvdata(phy, priv);
52664+
52665+	phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
52666+	if (IS_ERR(phy_provider)) {
52667+		ret = PTR_ERR(phy_provider);
52668+		goto xvp_unmap;
52669+	}
52670+
52671+	return 0;
52672+xvp_unmap:
52673+	iounmap(priv->phy_base);
52674+	iounmap(priv->crg_base);
52675+	iounmap(priv->pin_base);
52676+
52677+	devm_kfree(dev, priv);
52678+	priv = NULL;
52679+
52680+	return ret;
52681+}
52682+
52683+static int hisi_usb_hixvp_phy_remove(struct platform_device *pdev)
52684+{
52685+	struct device *dev = &pdev->dev;
52686+	struct hisi_hixvp_priv *priv = platform_get_drvdata(pdev);
52687+	int i;
52688+
52689+	for (i = 0; i < priv->num_clocks; i++)
52690+		clk_put(priv->clks[i]);
52691+
52692+	iounmap(priv->phy_base);
52693+	iounmap(priv->crg_base);
52694+	iounmap(priv->pin_base);
52695+
52696+	devm_kfree(dev, priv);
52697+	priv = NULL;
52698+
52699+	return 0;
52700+}
52701+
52702+#ifdef CONFIG_PM_SLEEP
52703+static int hisi_usb_hixvp_phy_suspend(struct device *dev)
52704+{
52705+	struct phy *phy = dev_get_drvdata(dev);
52706+
52707+	if (hisi_usb_hixvp_phy_exit(phy))
52708+		return -1;
52709+
52710+	return 0;
52711+}
52712+
52713+static int hisi_usb_hixvp_phy_resume(struct device *dev)
52714+{
52715+	struct phy *phy = dev_get_drvdata(dev);
52716+
52717+	if (hisi_usb_hixvp_phy_init(phy))
52718+		return -1;
52719+
52720+	return 0;
52721+}
52722+#endif /* CONFIG_PM_SLEEP */
52723+
52724+static SIMPLE_DEV_PM_OPS(hisi_usb_pm_ops, hisi_usb_hixvp_phy_suspend,
52725+			 hisi_usb_hixvp_phy_resume);
52726+
52727+static const struct of_device_id hisi_usb_hixvp_phy_of_match[] = {
52728+	{ .compatible = "hisilicon,hixvp-usb2-phy" },
52729+	{},
52730+};
52731+
52732+static struct platform_driver hisi_usb_hixvp_phy_driver = {
52733+	.probe = hisi_usb_hixvp_phy_probe,
52734+	.remove = hisi_usb_hixvp_phy_remove,
52735+	.driver = {
52736+		.name = "hisi-usb-hixvp-phy",
52737+		.pm = &hisi_usb_pm_ops,
52738+		.of_match_table = hisi_usb_hixvp_phy_of_match,
52739+	}
52740+};
52741+module_platform_driver(hisi_usb_hixvp_phy_driver);
52742+MODULE_DESCRIPTION("HISILICON USB HIXVP PHY driver");
52743+MODULE_ALIAS("platform:hisi-usb-hixvp-phy");
52744+MODULE_LICENSE("GPL v2");
52745diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig
52746index d55b3727e..6d73fab25 100644
52747--- a/drivers/power/reset/Kconfig
52748+++ b/drivers/power/reset/Kconfig
52749@@ -95,7 +95,7 @@ config POWER_RESET_GPIO_RESTART
52750
52751 config POWER_RESET_HISI
52752 	bool "Hisilicon power-off driver"
52753-	depends on ARCH_HISI
52754+	depends on ARCH_HISI || ARCH_HISI_BVT
52755 	help
52756 	  Reboot support for Hisilicon boards.
52757
52758diff --git a/drivers/ras/Kconfig b/drivers/ras/Kconfig
52759index c2a236f2e..fa3951a03 100644
52760--- a/drivers/ras/Kconfig
52761+++ b/drivers/ras/Kconfig
52762@@ -29,8 +29,8 @@ menuconfig RAS
52763 	  so have ideal availability, but may be unreliable, with frequent
52764 	  data corruption.
52765
52766-if RAS
52767+#if RAS
52768
52769-source "arch/x86/ras/Kconfig"
52770+#source "arch/x86/ras/Kconfig"
52771
52772-endif
52773+#endif
52774diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
52775index 54cf5ec8f..a1de70bd3 100644
52776--- a/drivers/rtc/Kconfig
52777+++ b/drivers/rtc/Kconfig
52778@@ -944,6 +944,14 @@ comment "Platform RTC drivers"
52779 # <asm/mc146818rtc.h> defining CMOS_READ/CMOS_WRITE, and a
52780 # global rtc_lock ... it's not yet just another platform_device.
52781
52782+config RTC_DRV_HIBVT
52783+	tristate "HiSilicon BVT RTC support"
52784+	help
52785+	  Generic RTC framework driver for HiSilicon BVT SoCs.
52786+
52787+	  To compile this driver as a module, choose M here: the module
52788+	  will be called rtc-hibvt.
52789+
52790 config RTC_DRV_CMOS
52791 	tristate "PC-style 'CMOS'"
52792 	depends on X86 || ARM || PPC || MIPS || SPARC64
52793diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
52794index bfb574641..41f5ad4f9 100644
52795--- a/drivers/rtc/Makefile
52796+++ b/drivers/rtc/Makefile
52797@@ -18,6 +18,7 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS)	+= sysfs.o
52798
52799 # Keep the list ordered.
52800
52801+obj-$(CONFIG_RTC_DRV_HIBVT)	+= rtc-hibvt.o
52802 obj-$(CONFIG_RTC_DRV_88PM80X)	+= rtc-88pm80x.o
52803 obj-$(CONFIG_RTC_DRV_88PM860X)	+= rtc-88pm860x.o
52804 obj-$(CONFIG_RTC_DRV_AB3100)	+= rtc-ab3100.o
52805diff --git a/drivers/rtc/rtc-hibvt.c b/drivers/rtc/rtc-hibvt.c
52806new file mode 100644
52807index 000000000..2ad9e970e
52808--- /dev/null
52809+++ b/drivers/rtc/rtc-hibvt.c
52810@@ -0,0 +1,663 @@
52811+/*
52812+ * rtc-hibvt.c
52813+ *
52814+ * RTC driver for Hisilicon BVT
52815+ *
52816+ * Copyright (C) 2016 HiSilicon Technologies Co., Ltd.
52817+ *
52818+ * This program is free software; you can redistribute it and/or modify
52819+ * it under the terms of the GNU General Public License as published by
52820+ * the Free Software Foundation; either version 2 of the License, or
52821+ * (at your option) any later version.
52822+ *
52823+ * This program is distributed in the hope that it will be useful,
52824+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
52825+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
52826+ * GNU General Public License for more details.
52827+ */
52828+
52829+#include <linux/bcd.h>
52830+#include <linux/bitops.h>
52831+#include <linux/log2.h>
52832+#include <linux/interrupt.h>
52833+#include <linux/kernel.h>
52834+#include <linux/module.h>
52835+#include <linux/rtc.h>
52836+#include <linux/version.h>
52837+#include <linux/io.h>
52838+#include <linux/delay.h>
52839+
52840+#include <linux/of.h>
52841+#include <linux/of_device.h>
52842+#include <linux/platform_device.h>
52843+
52844+union u_spi_rw {
52845+	struct {
52846+		unsigned int spi_wdata : 8; /* [7:0] */
52847+		unsigned int spi_rdata : 8; /* [15:8] */
52848+		unsigned int spi_addr : 7; /* [22:16] */
52849+		unsigned int spi_rw : 1; /* [23] */
52850+		unsigned int spi_start : 1; /* [24] */
52851+		unsigned int reserved : 6; /* [30:25] */
52852+		unsigned int spi_busy : 1; /* [31] */
52853+	} bits;
52854+	unsigned int u32;
52855+};
52856+
52857+struct hibvt_time_str {
52858+	unsigned char dayl;
52859+	unsigned char dayh;
52860+	unsigned char second;
52861+	unsigned char minute;
52862+	unsigned char hour;
52863+};
52864+
52865+#define SPI_CLK_DIV 0x000
52866+#define SPI_RW 0x004
52867+
52868+#define SPI_WRITE		0
52869+#define SPI_READ		1
52870+
52871+#if defined(CONFIG_ARCH_HI3531DV200) || defined(CONFIG_ARCH_HI3535AV100) || \
52872+	defined(CONFIG_ARCH_HI3521DV200) || defined(CONFIG_ARCH_HI3520DV500)
52873+
52874+/* RTC REG */
52875+#define RTC_10MS_COUN		0x00
52876+#define RTC_S_COUNT		0x04
52877+#define RTC_M_COUNT		0x08
52878+#define RTC_H_COUNT		0x0C
52879+#define RTC_D_COUNT_L		0x10
52880+#define RTC_D_COUNT_H		0x14
52881+
52882+#define RTC_MR_10MS		0x18
52883+#define RTC_MR_S		0x1C
52884+#define RTC_MR_M		0x20
52885+#define RTC_MR_H		0x24
52886+#define RTC_MR_D_L		0x28
52887+#define RTC_MR_D_H		0x2C
52888+
52889+#define RTC_LR_10MS		0x30
52890+#define RTC_LR_S		0x34
52891+#define RTC_LR_M		0x38
52892+#define RTC_LR_H		0x3C
52893+#define RTC_LR_D_L		0x40
52894+#define RTC_LR_D_H		0x44
52895+
52896+#define RTC_LORD		0x48
52897+
52898+#define RTC_IMSC		0x4C
52899+#define RTC_INT_CLR		0x50
52900+#define RTC_INT			0x54
52901+#define RTC_INT_RAW		0x58
52902+
52903+#define RTC_CLK			0x5C
52904+#define RTC_POR_N		0x60
52905+#define RTC_SAR_CTRL		0x68
52906+#define RTC_CLK_CFG		0x6C
52907+
52908+#define RTC_FREQ_H		0x144
52909+#define RTC_FREQ_L		0x148
52910+
52911+#define RTC_REG_LOCK1	0x190
52912+#define RTC_REG_LOCK2	0x194
52913+#define RTC_REG_LOCK3	0x198
52914+#define RTC_REG_LOCK4	0x19C
52915+#endif
52916+
52917+#if defined(CONFIG_ARCH_HI3556AV100) || defined(CONFIG_ARCH_HI3519AV100) || \
52918+    defined(CONFIG_ARCH_HI3556V200)  || defined(CONFIG_ARCH_HI3559V200)  || \
52919+    defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) || \
52920+    defined(CONFIG_ARCH_HI3516EV200) || defined(CONFIG_ARCH_HI3516EV300) || \
52921+    defined(CONFIG_ARCH_HI3518EV300) || defined(CONFIG_ARCH_HI3516DV200) || \
52922+    defined(CONFIG_ARCH_HI3562V100)  || defined(CONFIG_ARCH_HI3566V100)  || \
52923+    defined(CONFIG_ARCH_HI3568V100)  || defined(CONFIG_ARCH_HI3559AV100) || \
52924+	defined(CONFIG_ARCH_HI3559CV100) || defined(CONFIG_ARCH_HI3569V100)
52925+
52926+#define SPI_RTC_TYPE
52927+
52928+/* RTC REG */
52929+#define RTC_10MS_COUN	0x00
52930+#define RTC_S_COUNT		0x01
52931+#define RTC_M_COUNT		0x02
52932+#define RTC_H_COUNT		0x03
52933+#define RTC_D_COUNT_L	0x04
52934+#define RTC_D_COUNT_H	0x05
52935+
52936+#define RTC_MR_10MS		0x06
52937+#define RTC_MR_S		0x07
52938+#define RTC_MR_M		0x08
52939+#define RTC_MR_H		0x09
52940+#define RTC_MR_D_L		0x0A
52941+#define RTC_MR_D_H		0x0B
52942+
52943+#define RTC_LR_10MS		0x0C
52944+#define RTC_LR_S		0x0D
52945+#define RTC_LR_M		0x0E
52946+#define RTC_LR_H		0x0F
52947+#define RTC_LR_D_L		0x10
52948+#define RTC_LR_D_H		0x11
52949+
52950+#define RTC_LORD		0x12
52951+
52952+#define RTC_IMSC		0x13
52953+#define RTC_INT_CLR		0x14
52954+#define RTC_INT			0x15
52955+#define RTC_INT_RAW		0x16
52956+
52957+#define RTC_CLK			0x17
52958+#define RTC_POR_N		0x18
52959+#define RTC_SAR_CTRL	0x1A
52960+#define RTC_CLK_CFG	    0x1B
52961+
52962+#define RTC_FREQ_H		0x51
52963+#define RTC_FREQ_L		0x52
52964+
52965+#define RTC_REG_LOCK1	0x64
52966+#define RTC_REG_LOCK2	0x65
52967+#define RTC_REG_LOCK3	0x66
52968+#define RTC_REG_LOCK4	0x67
52969+#endif
52970+
52971+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3559CV100) || \
52972+    defined(CONFIG_ARCH_HI3569V100)
52973+#define PWR_REG_ADDR	0x180C0000
52974+#define PWR_REG_LENGTH	0x100
52975+#endif
52976+#define FREQ_H_DEFAULT  0x8
52977+#define FREQ_L_DEFAULT  0x1B
52978+
52979+#define LV_CTL_DEFAULT  0x20
52980+#define CLK_DIV_DEFAULT 0x4
52981+#define INT_RST_DEFAULT 0x0
52982+#define INT_MSK_DEFAULT 0x4
52983+
52984+#define AIE_INT_MASK       BIT(0)
52985+#define LV_INT_MASK        BIT(1)
52986+#define REG_LOAD_STAT      BIT(0)
52987+#define REG_LOCK_STAT      BIT(1)
52988+#define REG_LOCK_BYPASS    BIT(2)
52989+
52990+#define RTC_RW_RETRY_CNT    5
52991+#define SPI_RW_RETRY_CNT    500
52992+#define RTC_SLEEP_TIME_MS   20
52993+
52994+#define date_to_sec(d, h, m, s)     ((s) + (m) * 60 + (h) * 60 * 60 + (d) * 24 * 60 * 60)
52995+#define sec_to_day(s)            ((s) / (60 * 60 * 24))
52996+
52997+struct hibvt_rtc {
52998+	struct rtc_device *rtc_dev;
52999+	void __iomem *regs;
53000+	int                  rtc_irq;
53001+};
53002+#define hibvt_rtc_readl(x) (*((volatile unsigned char *)(x)))
53003+#define hibvt_rtc_writel(v, x) (*((volatile unsigned char *)(x)) = (v))
53004+
53005+#if defined(SPI_RTC_TYPE)
53006+static int hibvt_spi_write(void *spi_reg, unsigned char reg,
53007+			   unsigned char val)
53008+{
53009+	union u_spi_rw w_data, r_data;
53010+	int cnt = SPI_RW_RETRY_CNT;
53011+
53012+	r_data.u32 = 0;
53013+	w_data.u32 = 0;
53014+
53015+	w_data.bits.spi_wdata = val;
53016+	w_data.bits.spi_addr = reg;
53017+	w_data.bits.spi_rw = SPI_WRITE;
53018+	w_data.bits.spi_start = 0x1;
53019+
53020+	writel(w_data.u32, (spi_reg+SPI_RW));
53021+
53022+	do
53023+		r_data.u32 = readl(spi_reg+SPI_RW);
53024+	while (r_data.bits.spi_busy && (--cnt));
53025+
53026+	if (r_data.bits.spi_busy)
53027+		return -EIO;
53028+
53029+	return 0;
53030+}
53031+
53032+static int hibvt_spi_read(void *spi_reg, unsigned char reg,
53033+			  unsigned char *val)
53034+{
53035+	union u_spi_rw w_data, r_data;
53036+	int cnt = SPI_RW_RETRY_CNT;
53037+
53038+	r_data.u32 = 0;
53039+	w_data.u32 = 0;
53040+	w_data.bits.spi_addr = reg;
53041+	w_data.bits.spi_rw = SPI_READ;
53042+	w_data.bits.spi_start = 0x1;
53043+
53044+	writel(w_data.u32, (spi_reg+SPI_RW));
53045+
53046+	do
53047+		r_data.u32 = readl(spi_reg+SPI_RW);
53048+	while (r_data.bits.spi_busy && (--cnt));
53049+
53050+	if (r_data.bits.spi_busy)
53051+		return -EIO;
53052+
53053+	*val = r_data.bits.spi_rdata;
53054+
53055+	return 0;
53056+}
53057+#else
53058+static unsigned int hibvt_write_reg(void *spi_reg, unsigned long offset,
53059+				    unsigned char val)
53060+{
53061+	hibvt_rtc_writel(val, (spi_reg + offset));
53062+	return 0;
53063+}
53064+
53065+static unsigned int hibvt_read_reg(void *spi_reg, unsigned long offset,
53066+				   unsigned char *val)
53067+{
53068+	*val = hibvt_rtc_readl(spi_reg + offset);
53069+	return 0;
53070+}
53071+#endif
53072+
53073+
53074+static unsigned int hibvt_rtc_write(void *spi_reg, unsigned long offset,
53075+				    unsigned char val)
53076+{
53077+#if defined(SPI_RTC_TYPE)
53078+	return hibvt_spi_write(spi_reg, offset, val);
53079+#else
53080+	return hibvt_write_reg(spi_reg, offset, val);
53081+#endif
53082+}
53083+
53084+static unsigned int hibvt_rtc_read(void *spi_reg, unsigned long offset,
53085+				   unsigned char *val)
53086+{
53087+#if defined(SPI_RTC_TYPE)
53088+	return hibvt_spi_read(spi_reg, offset, val);
53089+#else
53090+	return hibvt_read_reg(spi_reg, offset, val);
53091+#endif
53092+}
53093+
53094+static int hibvt_rtc_read_time(struct device *dev, struct rtc_time *time)
53095+{
53096+	struct hibvt_rtc *rtc = dev_get_drvdata(dev);
53097+	struct hibvt_time_str time_str = {0};
53098+	unsigned long seconds = 0;
53099+	unsigned int day;
53100+	unsigned char raw_value = 0;
53101+	int cnt = RTC_RW_RETRY_CNT;
53102+
53103+	hibvt_rtc_read(rtc->regs, RTC_INT_RAW, &raw_value);
53104+
53105+	if (raw_value & LV_INT_MASK)
53106+		/* low voltage detected, date/time is not reliable. */
53107+		hibvt_rtc_write(rtc->regs, RTC_INT_CLR, 1);
53108+
53109+	hibvt_rtc_read(rtc->regs, RTC_LORD, &raw_value);
53110+	if (raw_value & REG_LOCK_BYPASS)
53111+		hibvt_rtc_write(rtc->regs, RTC_LORD,
53112+				(~(REG_LOCK_BYPASS)) & raw_value);
53113+
53114+	hibvt_rtc_read(rtc->regs, RTC_LORD, &raw_value);
53115+	/* lock the time */
53116+	hibvt_rtc_write(rtc->regs, RTC_LORD, (REG_LOCK_STAT) | raw_value);
53117+	/* wait rtc load flag */
53118+	do {
53119+		hibvt_rtc_read(rtc->regs, RTC_LORD, &raw_value);
53120+		msleep(RTC_SLEEP_TIME_MS);
53121+	} while ((raw_value & REG_LOCK_STAT) && (--cnt));
53122+
53123+	if (raw_value & REG_LOCK_STAT)
53124+		return -EBUSY;
53125+
53126+	hibvt_rtc_read(rtc->regs, RTC_S_COUNT, &time_str.second);
53127+	hibvt_rtc_read(rtc->regs, RTC_M_COUNT, &time_str.minute);
53128+	hibvt_rtc_read(rtc->regs, RTC_H_COUNT, &time_str.hour);
53129+	hibvt_rtc_read(rtc->regs, RTC_D_COUNT_L, &time_str.dayl);
53130+	hibvt_rtc_read(rtc->regs, RTC_D_COUNT_H, &time_str.dayh);
53131+
53132+	day = (time_str.dayl | (time_str.dayh << 8)); /* Move to a high 8 bit. */
53133+	seconds = date_to_sec(day, time_str.hour, time_str.minute, time_str.second);
53134+
53135+	rtc_time64_to_tm(seconds, time);
53136+
53137+	return rtc_valid_tm(time);
53138+}
53139+
53140+static int hibvt_rtc_set_time(struct device *dev, struct rtc_time *time)
53141+{
53142+	struct hibvt_rtc *rtc = dev_get_drvdata(dev);
53143+	unsigned int days;
53144+	unsigned long seconds = 0;
53145+	unsigned int cnt = RTC_RW_RETRY_CNT;
53146+	unsigned char raw_value = 0;
53147+
53148+	seconds = rtc_tm_to_time64(time);
53149+
53150+	days = sec_to_day(seconds);
53151+
53152+	hibvt_rtc_write(rtc->regs, RTC_LR_10MS, 0);
53153+	hibvt_rtc_write(rtc->regs, RTC_LR_S, time->tm_sec);
53154+	hibvt_rtc_write(rtc->regs, RTC_LR_M, time->tm_min);
53155+	hibvt_rtc_write(rtc->regs, RTC_LR_H, time->tm_hour);
53156+	hibvt_rtc_write(rtc->regs, RTC_LR_D_L, (days & 0xFF));
53157+	hibvt_rtc_write(rtc->regs, RTC_LR_D_H, (days >> 8));  /* Move to a Low 8 bit. */
53158+
53159+	hibvt_rtc_write(rtc->regs, RTC_LORD,
53160+			(raw_value | REG_LOAD_STAT));
53161+	/* wait rtc load flag */
53162+	do {
53163+		hibvt_rtc_read(rtc->regs, RTC_LORD, &raw_value);
53164+		msleep(RTC_SLEEP_TIME_MS);
53165+	} while ((raw_value & REG_LOAD_STAT) && (--cnt));
53166+
53167+	if (raw_value & REG_LOAD_STAT)
53168+		return -EBUSY;
53169+
53170+	return 0;
53171+}
53172+
53173+static int hibvt_rtc_read_alarm(struct device *dev,
53174+				struct rtc_wkalrm *alrm)
53175+{
53176+	struct hibvt_rtc *rtc = dev_get_drvdata(dev);
53177+	struct hibvt_time_str time_str = {0};
53178+	unsigned long seconds = 0;
53179+	unsigned int day;
53180+	unsigned char int_state = 0;
53181+
53182+	memset(alrm, 0, sizeof(struct rtc_wkalrm));
53183+
53184+	hibvt_rtc_read(rtc->regs, RTC_MR_S, &time_str.second);
53185+	hibvt_rtc_read(rtc->regs, RTC_MR_M, &time_str.minute);
53186+	hibvt_rtc_read(rtc->regs, RTC_MR_H, &time_str.hour);
53187+	hibvt_rtc_read(rtc->regs, RTC_MR_D_L, &time_str.dayl);
53188+	hibvt_rtc_read(rtc->regs, RTC_MR_D_H, &time_str.dayh);
53189+
53190+	day = (unsigned int)(time_str.dayl | (time_str.dayh << 8)); /* Move to a high 8 bit. */
53191+	seconds = date_to_sec(day, time_str.hour, time_str.minute, time_str.second);
53192+
53193+	rtc_time64_to_tm(seconds, &alrm->time);
53194+
53195+	hibvt_rtc_read(rtc->regs, RTC_IMSC, &int_state);
53196+
53197+	alrm->enabled = !!(int_state & AIE_INT_MASK);
53198+	alrm->pending = alrm->enabled;
53199+
53200+	return 0;
53201+}
53202+
53203+static int hibvt_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
53204+{
53205+	struct hibvt_rtc *rtc = dev_get_drvdata(dev);
53206+	unsigned int days;
53207+	unsigned long seconds = 0;
53208+	unsigned char val = 0;
53209+
53210+	seconds = rtc_tm_to_time64(&alrm->time);
53211+
53212+	days = sec_to_day(seconds);
53213+
53214+	hibvt_rtc_write(rtc->regs, RTC_MR_10MS, 0);
53215+	hibvt_rtc_write(rtc->regs, RTC_MR_S, alrm->time.tm_sec);
53216+	hibvt_rtc_write(rtc->regs, RTC_MR_M, alrm->time.tm_min);
53217+	hibvt_rtc_write(rtc->regs, RTC_MR_H, alrm->time.tm_hour);
53218+	hibvt_rtc_write(rtc->regs, RTC_MR_D_L, (days & 0xFF));
53219+	hibvt_rtc_write(rtc->regs, RTC_MR_D_H, (days >> 8)); /* Move to a Low 8 bit. */
53220+
53221+	hibvt_rtc_read(rtc->regs, RTC_IMSC, &val);
53222+	if (alrm->enabled)
53223+		hibvt_rtc_write(rtc->regs, RTC_IMSC, val | AIE_INT_MASK);
53224+	else
53225+		hibvt_rtc_write(rtc->regs, RTC_IMSC, val & ~AIE_INT_MASK);
53226+
53227+	return 0;
53228+}
53229+
53230+static int hibvt_rtc_alarm_irq_enable(struct device *dev,
53231+				      unsigned int enabled)
53232+{
53233+	struct hibvt_rtc *rtc = dev_get_drvdata(dev);
53234+	unsigned char val = 0;
53235+
53236+	hibvt_rtc_read(rtc->regs, RTC_IMSC, &val);
53237+	if (enabled)
53238+		hibvt_rtc_write(rtc->regs, RTC_IMSC, val | AIE_INT_MASK);
53239+	else
53240+		hibvt_rtc_write(rtc->regs, RTC_IMSC, val & ~AIE_INT_MASK);
53241+
53242+	return 0;
53243+}
53244+
53245+/*
53246+ * interrupt function
53247+ * do nothing. left for future
53248+ */
53249+static irqreturn_t hibvt_rtc_alm_interrupt(int irq, void *data)
53250+{
53251+	struct hibvt_rtc *rtc = (struct hibvt_rtc *)data;
53252+	unsigned char val = 0;
53253+
53254+	hibvt_rtc_read(rtc->regs, RTC_INT, &val);
53255+	hibvt_rtc_write(rtc->regs, RTC_INT_CLR, AIE_INT_MASK);
53256+
53257+	if (val & AIE_INT_MASK)
53258+		rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
53259+
53260+	return IRQ_HANDLED;
53261+}
53262+
53263+#define FREQ_MAX_VAL	    3277000
53264+#define FREQ_MIN_VAL	    3276000
53265+
53266+static int hibvt_rtc_ioctl(struct device *dev,
53267+			   unsigned int cmd, unsigned long arg)
53268+{
53269+	struct hibvt_rtc *rtc = dev_get_drvdata(dev);
53270+
53271+	switch (cmd) {
53272+	case RTC_PLL_SET: {
53273+		char freq_l, freq_h;
53274+		struct rtc_pll_info pll_info = {0};
53275+
53276+		if (copy_from_user(&pll_info, (struct rtc_pll_info *)(uintptr_t)arg,
53277+				   sizeof(struct rtc_pll_info)))
53278+			return -EFAULT;
53279+
53280+		/* freq = 32700 + (freq /3052)*100 */
53281+		if (pll_info.pll_value > FREQ_MAX_VAL ||
53282+			pll_info.pll_value < FREQ_MIN_VAL)
53283+			return -EINVAL;
53284+
53285+		/* freq convert: (freq-3270000) * 3052 / 10000 */
53286+		pll_info.pll_value = (pll_info.pll_value - 3270000) *
53287+				     3052 / 10000;
53288+
53289+		/* & 0xff Obtains the lower eight bits of data. */
53290+		freq_l = (char)(pll_info.pll_value & 0xff);
53291+		/* pll_info.pll_value >> 8 & 0xf  Obtains the last four bits of the higher eight bits. */
53292+		freq_h = (char)((pll_info.pll_value >> 8) & 0xf);
53293+
53294+		hibvt_rtc_write(rtc->regs, RTC_FREQ_H, freq_h);
53295+		hibvt_rtc_write(rtc->regs, RTC_FREQ_L, freq_l);
53296+
53297+		return 0;
53298+	}
53299+	case RTC_PLL_GET: {
53300+		char freq_l = 0;
53301+		char freq_h = 0;
53302+		struct rtc_pll_info pll_info = {0};
53303+
53304+		hibvt_rtc_read(rtc->regs, RTC_FREQ_H, &freq_h);
53305+		hibvt_rtc_read(rtc->regs, RTC_FREQ_L, &freq_l);
53306+
53307+		if ((void __user *)(uintptr_t)arg == NULL) {
53308+			dev_err(dev, "IO err or user buf is NULL..\n");
53309+			return -1;
53310+		}
53311+
53312+		/* freq_h & 0xf << 8 :Shifts leftwards by 8 bits and obtains the lower 4 bits. */
53313+		pll_info.pll_value = (((unsigned)freq_h & 0xf) << 8) + freq_l;
53314+
53315+		/* freq convert: 3270000 + (freq * 10000) / 3052 */
53316+		pll_info.pll_value = 3270000 + ((unsigned int)pll_info.pll_value * 10000) / 3052;
53317+
53318+		pll_info.pll_max = FREQ_MAX_VAL;
53319+		pll_info.pll_min = FREQ_MIN_VAL;
53320+		if (copy_to_user((void __user *)(uintptr_t)arg,
53321+				 &pll_info, sizeof(struct rtc_pll_info)))
53322+			return -EFAULT;
53323+
53324+		return 0;
53325+	}
53326+	default:
53327+		return -ENOIOCTLCMD;
53328+	}
53329+}
53330+
53331+static const struct rtc_class_ops hibvt_rtc_ops = {
53332+	.read_time = hibvt_rtc_read_time,
53333+	.set_time = hibvt_rtc_set_time,
53334+	.read_alarm = hibvt_rtc_read_alarm,
53335+	.set_alarm = hibvt_rtc_set_alarm,
53336+	.alarm_irq_enable = hibvt_rtc_alarm_irq_enable,
53337+	.ioctl = hibvt_rtc_ioctl,
53338+};
53339+
53340+static int hibvt_rtc_init(struct hibvt_rtc *rtc)
53341+{
53342+	void *spi_reg = rtc->regs;
53343+	unsigned char val = 0;
53344+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3559CV100) || \
53345+    defined(CONFIG_ARCH_HI3569V100)
53346+	void *pwr_reg = NULL;
53347+#endif
53348+	/*
53349+	 * clk div value = (apb_clk/spi_clk)/2-1,
53350+	 *  apb clk = 100MHz, spi_clk = 10MHz,so value= 0x4
53351+	 */
53352+	writel(CLK_DIV_DEFAULT, (spi_reg + SPI_CLK_DIV));
53353+
53354+	hibvt_rtc_write(spi_reg, RTC_IMSC, INT_MSK_DEFAULT);
53355+	hibvt_rtc_write(spi_reg, RTC_SAR_CTRL, LV_CTL_DEFAULT);
53356+
53357+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3559CV100) || \
53358+    defined(CONFIG_ARCH_HI3569V100)
53359+	pwr_reg = ioremap(PWR_REG_ADDR, PWR_REG_LENGTH);
53360+	if(pwr_reg == NULL)	{
53361+		return -1;
53362+	}
53363+	writel(0x5A5AABCD, pwr_reg+0x58);
53364+	iounmap(pwr_reg);
53365+#else
53366+	/* default driver capability */
53367+	hibvt_rtc_write(spi_reg, RTC_REG_LOCK4, 0x5A); /* 0x5A:ctl order */
53368+	hibvt_rtc_write(spi_reg, RTC_REG_LOCK3, 0x5A); /* 0x5A:ctl order */
53369+	hibvt_rtc_write(spi_reg, RTC_REG_LOCK2, 0xAB); /* 0xAB:ctl order */
53370+	hibvt_rtc_write(spi_reg, RTC_REG_LOCK1, 0xCD); /* 0xCD:ctl order */
53371+#endif
53372+
53373+#if defined(CONFIG_ARCH_HI3516CV500) || defined(CONFIG_ARCH_HI3516DV300) ||\
53374+	defined(CONFIG_ARCH_HI3556V200)  || defined(CONFIG_ARCH_HI3559V200)  ||\
53375+	defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3559CV100) ||\
53376+	defined(CONFIG_ARCH_HI3519AV100) || defined(CONFIG_ARCH_HI3556AV100) ||\
53377+	defined(CONFIG_ARCH_HI3536DV100) || defined(CONFIG_ARCH_HI3562V100)  ||\
53378+	defined(CONFIG_ARCH_HI3566V100)  || defined(CONFIG_ARCH_HI3569V100)  || \
53379+	defined(CONFIG_ARCH_HI3568V100)
53380+	hibvt_rtc_write(spi_reg, RTC_CLK_CFG, 0x02);
53381+#elif defined(CONFIG_ARCH_HI3516EV200) || defined(CONFIG_ARCH_HI3516EV300) ||\
53382+	defined(CONFIG_ARCH_HI3518EV300) || defined(CONFIG_ARCH_HI3516DV200) ||\
53383+	defined(CONFIG_ARCH_HI3531DV200) || defined(CONFIG_ARCH_HI3535AV100) || \
53384+    defined(CONFIG_ARCH_HI3521DV200) || defined(CONFIG_ARCH_HI3520DV500)
53385+	hibvt_rtc_write(spi_reg, RTC_CLK_CFG, 0x03);
53386+#else
53387+	/* HI3536CV100 */
53388+	hibvt_rtc_write(spi_reg, RTC_CLK_CFG, 0x01);
53389+#endif
53390+
53391+	/* default FREQ COEF */
53392+	hibvt_rtc_write(spi_reg, RTC_FREQ_H, FREQ_H_DEFAULT);
53393+	hibvt_rtc_write(spi_reg, RTC_FREQ_L, FREQ_L_DEFAULT);
53394+
53395+	hibvt_rtc_read(spi_reg, RTC_INT_RAW, &val);
53396+
53397+	if (val & LV_INT_MASK)
53398+		/* low voltage detected, date/time is not reliable. */
53399+		hibvt_rtc_write(rtc->regs, RTC_INT_CLR, 1);
53400+
53401+	return 0;
53402+}
53403+
53404+static int hibvt_rtc_probe(struct platform_device *pdev)
53405+{
53406+	struct resource  *mem = NULL;
53407+	struct hibvt_rtc *rtc = NULL;
53408+	int    ret;
53409+
53410+	rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL);
53411+	if (!rtc)
53412+		return -ENOMEM;
53413+
53414+	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
53415+	rtc->regs = devm_ioremap_resource(&pdev->dev, mem);
53416+	if (IS_ERR((const void *)rtc->regs)) {
53417+		dev_err(&pdev->dev, "could not map I/O memory\n");
53418+		return PTR_ERR((const void *)rtc->regs);
53419+	}
53420+
53421+	rtc->rtc_irq = platform_get_irq(pdev, 0);
53422+	ret = devm_request_irq(&pdev->dev, rtc->rtc_irq,
53423+			       hibvt_rtc_alm_interrupt, 0, pdev->name, rtc);
53424+	if (ret) {
53425+		dev_err(&pdev->dev, "could not request irq %d\n", rtc->rtc_irq);
53426+		return ret;
53427+	}
53428+
53429+	platform_set_drvdata(pdev, rtc);
53430+	rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name,
53431+						&hibvt_rtc_ops, THIS_MODULE);
53432+	if (IS_ERR(rtc->rtc_dev)) {
53433+		dev_err(&pdev->dev, "could not register rtc device\n");
53434+		return PTR_ERR(rtc->rtc_dev);
53435+	}
53436+
53437+	if (hibvt_rtc_init(rtc)) {
53438+		dev_err(&pdev->dev, "hibvt_rtc_init failed.\n");
53439+		return -EIO;
53440+	}
53441+
53442+	dev_info(&pdev->dev, "RTC driver for hibvt enabled\n");
53443+
53444+	return 0;
53445+}
53446+
53447+static int hibvt_rtc_remove(struct platform_device *pdev)
53448+{
53449+	return 0;
53450+}
53451+
53452+static const struct of_device_id hibvt_rtc_match[] = {
53453+	{ .compatible = "hisilicon,hi35xx-rtc" },
53454+	{},
53455+};
53456+
53457+static struct platform_driver hibvt_rtc_driver = {
53458+	.probe  = hibvt_rtc_probe,
53459+	.remove = hibvt_rtc_remove,
53460+	.driver =  {
53461+		.name = "hibvt_rtc",
53462+		.of_match_table = hibvt_rtc_match,
53463+	},
53464+};
53465+
53466+module_platform_driver(hibvt_rtc_driver);
53467+
53468+#define OSDRV_MODULE_VERSION_STRING "HISI_rtc @HiMPP"
53469+
53470+MODULE_AUTHOR("Hisilicon");
53471+MODULE_DESCRIPTION("Hisilicon RTC driver");
53472+MODULE_LICENSE("GPL v2");
53473+MODULE_VERSION("HI_VERSION=" OSDRV_MODULE_VERSION_STRING);
53474diff --git a/drivers/scsi/ufs/Kconfig b/drivers/scsi/ufs/Kconfig
53475index c339517b7..4ff8f3de5 100644
53476--- a/drivers/scsi/ufs/Kconfig
53477+++ b/drivers/scsi/ufs/Kconfig
53478@@ -182,3 +182,12 @@ config SCSI_UFS_CRYPTO
53479 	  Enabling this makes it possible for the kernel to use the crypto
53480 	  capabilities of the UFS device (if present) to perform crypto
53481 	  operations on data being transferred to/from the device.
53482+
53483+config SCSI_UFS_HI3559AV100
53484+	tristate "Hi3559av100 specific hooks to UFS controller platform driver"
53485+	depends on SCSI_UFSHCD_PLATFORM
53486+	help
53487+	  This selects the UFS support for Hi3559av100 SoC.
53488+
53489+	  Select this if you have UFS controller on Hi3751v810 chipset.
53490+	  If unsure, say N.
53491diff --git a/drivers/scsi/ufs/Makefile b/drivers/scsi/ufs/Makefile
53492index 4679af1b5..8042bf7c6 100644
53493--- a/drivers/scsi/ufs/Makefile
53494+++ b/drivers/scsi/ufs/Makefile
53495@@ -16,3 +16,4 @@ obj-$(CONFIG_SCSI_UFSHCD_PLATFORM) += ufshcd-pltfrm.o
53496 obj-$(CONFIG_SCSI_UFS_HISI) += ufs-hisi.o
53497 obj-$(CONFIG_SCSI_UFS_MEDIATEK) += ufs-mediatek.o
53498 obj-$(CONFIG_SCSI_UFS_TI_J721E) += ti-j721e-ufs.o
53499+obj-$(CONFIG_SCSI_UFS_HI3559AV100) += hi3559av100.o
53500diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c
53501index 24927cf48..ccf04e4f1 100644
53502--- a/drivers/scsi/ufs/ufshcd-pltfrm.c
53503+++ b/drivers/scsi/ufs/ufshcd-pltfrm.c
53504@@ -17,6 +17,9 @@
53505 #include "unipro.h"
53506
53507 #define UFSHCD_DEFAULT_LANES_PER_DIRECTION		2
53508+#define UFSHCD_DEFAULT_PWM		FAST_MODE
53509+#define UFSHCD_DEFAULT_GEAR		UFS_HS_G1
53510+#define UFSHCD_DEFAULT_RATE		PA_HS_MODE_B
53511
53512 static int ufshcd_parse_clock_info(struct ufs_hba *hba)
53513 {
53514@@ -172,6 +175,9 @@ static int ufshcd_parse_regulator_info(struct ufs_hba *hba)
53515 	struct device *dev = hba->dev;
53516 	struct ufs_vreg_info *info = &hba->vreg_info;
53517
53518+	if (hba->info_skip)
53519+		return 0;
53520+
53521 	err = ufshcd_populate_vreg(dev, "vdd-hba", &info->vdd_hba);
53522 	if (err)
53523 		goto out;
53524@@ -189,6 +195,18 @@ static int ufshcd_parse_regulator_info(struct ufs_hba *hba)
53525 	return err;
53526 }
53527
53528+static void ufshcd_parse_cd_pin(struct ufs_hba *hba)
53529+{
53530+#ifdef CONFIG_SCSI_UFS_CARD
53531+	struct device *dev = hba->dev;
53532+	struct device_node *np = dev->of_node;
53533+	if (of_get_property(np, "cd-gpio", NULL))
53534+		hba->cd_gpio = of_get_named_gpio(np, "cd-gpio", 0);
53535+	else
53536+		hba->cd_gpio = -1;
53537+#endif
53538+}
53539+
53540 #ifdef CONFIG_PM
53541 /**
53542  * ufshcd_pltfrm_suspend - suspend power management function
53543@@ -242,6 +260,34 @@ void ufshcd_pltfrm_shutdown(struct platform_device *pdev)
53544 }
53545 EXPORT_SYMBOL_GPL(ufshcd_pltfrm_shutdown);
53546
53547+static void ufshcd_init_skip_info(struct ufs_hba *hba)
53548+{
53549+	struct device *dev = hba->dev;
53550+	int ret;
53551+
53552+	ret = of_property_read_u32(dev->of_node, "skip-info", &hba->info_skip);
53553+	if (ret)
53554+		hba->info_skip = 0;
53555+}
53556+
53557+static void ufshcd_init_powermode(struct ufs_hba *hba)
53558+{
53559+	struct device *dev = hba->dev;
53560+	int ret;
53561+
53562+	ret = of_property_read_u32(dev->of_node, "power-mode", &hba->hc_pwm);
53563+	if (ret)
53564+		hba->hc_pwm = UFSHCD_DEFAULT_PWM;
53565+
53566+	ret = of_property_read_u32(dev->of_node, "gear", &hba->hc_gear);
53567+	if (ret)
53568+		hba->hc_gear = UFSHCD_DEFAULT_GEAR;
53569+
53570+	ret = of_property_read_u32(dev->of_node, "rate", &hba->hc_rate);
53571+	if (ret)
53572+		hba->hc_rate = UFSHCD_DEFAULT_RATE;
53573+}
53574+
53575 static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba)
53576 {
53577 	struct device *dev = hba->dev;
53578@@ -388,6 +434,7 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
53579 	}
53580
53581 	hba->vops = vops;
53582+	ufshcd_init_skip_info(hba);
53583
53584 	err = ufshcd_parse_clock_info(hba);
53585 	if (err) {
53586@@ -402,6 +449,8 @@ int ufshcd_pltfrm_init(struct platform_device *pdev,
53587 		goto dealloc_host;
53588 	}
53589
53590+	ufshcd_parse_cd_pin(hba);
53591+	ufshcd_init_powermode(hba);
53592 	ufshcd_init_lanes_per_dir(hba);
53593
53594 	err = ufshcd_init(hba, mmio_base, irq);
53595diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
53596index 3139d9df6..fc0b43268 100644
53597--- a/drivers/scsi/ufs/ufshcd.c
53598+++ b/drivers/scsi/ufs/ufshcd.c
53599@@ -6231,6 +6231,40 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba)
53600 	return retval;
53601 }
53602
53603+#ifdef CONFIG_SCSI_UFS_CARD
53604+static int ufshcd_check_card_detect(struct ufs_hba *hba)
53605+{
53606+	int ret = D_IGNORED;
53607+
53608+	if (gpio_is_valid(hba->cd_gpio))
53609+		ret = gpio_get_value(hba->cd_gpio) ?  D_NO_DETECT : D_DETECT;
53610+
53611+	return ret;
53612+}
53613+
53614+static irqreturn_t ufshcd_intr_card_detect(int irq, void *__hba)
53615+{
53616+	struct ufs_hba *hba = __hba;
53617+	unsigned long flags;
53618+
53619+	spin_lock_irqsave(hba->host->host_lock, flags);
53620+	hba->card_status_changed = true;
53621+	hba->ufshcd_state = UFSHCD_STATE_OFFLINE;
53622+	spin_unlock_irqrestore(hba->host->host_lock, flags);
53623+
53624+	/*
53625+	 * This handler would not work during UFS driver's sleep mode.
53626+	 * That makes pending tasks failed when UFS driver enters
53627+	 * into suspend mode and interface re-establishment be permitted
53628+	 * only after UFS driver exit from suspend mode.
53629+	 */
53630+	if (!(work_pending(&hba->cd_work))) {
53631+		queue_work(hba->cd_wq, &hba->cd_work);
53632+	}
53633+	return IRQ_HANDLED;
53634+}
53635+#endif
53636+
53637 static int ufshcd_clear_tm_cmd(struct ufs_hba *hba, int tag)
53638 {
53639 	int err = 0;
53640@@ -6829,6 +6863,10 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba)
53641 	int err;
53642 	unsigned long flags;
53643
53644+#ifdef CONFIG_SCSI_UFS_CARD
53645+	if (ufshcd_check_card_detect(hba) == D_NO_DETECT)
53646+		return 0;
53647+#endif
53648 	/*
53649 	 * Stop the host controller and complete the requests
53650 	 * cleared by h/w
53651@@ -6844,6 +6882,8 @@ static int ufshcd_host_reset_and_restore(struct ufs_hba *hba)
53652 	/* scale up clocks to max frequency before full reinitialization */
53653 	ufshcd_set_clk_freq(hba, true);
53654
53655+	ufshcd_vops_clk_hareware_init_notify(hba);
53656+
53657 	err = ufshcd_hba_enable(hba);
53658 	if (err)
53659 		goto out;
53660@@ -7268,6 +7308,7 @@ static int ufs_get_device_desc(struct ufs_hba *hba)
53661 	dev_info->wspecversion = desc_buf[DEVICE_DESC_PARAM_SPEC_VER] << 8 |
53662 				      desc_buf[DEVICE_DESC_PARAM_SPEC_VER + 1];
53663
53664+	hba->manufacturer_id = dev_desc->wmanufacturerid;
53665 	model_index = desc_buf[DEVICE_DESC_PARAM_PRDCT_NAME];
53666
53667 	err = ufshcd_read_string_desc(hba, model_index,
53668@@ -7831,6 +7872,138 @@ static const struct attribute_group *ufshcd_driver_groups[] = {
53669 	NULL,
53670 };
53671
53672+#ifdef CONFIG_SCSI_UFS_CARD
53673+static int ufshcd_select_next_job(struct ufs_hba *hba, bool current_status)
53674+{
53675+	bool is_card_detected;
53676+
53677+	/*
53678+	 * We assume scenarios for 4 cases and decribe them
53679+	 * with following conventions
53680+	 *
53681+	 * Physical card Status (A) / Device file status (B)
53682+	 * Insertion (I) / Removal (R)
53683+	 *
53684+	 * 1) A = I
53685+	 * 	1-1) B = I : (I) -> R
53686+	 *	This might means bad card insertion that can cause
53687+	 *	something wrong for opertions.
53688+	 *
53689+	 *	1-2) B = R : (R) -> I
53690+	 *	Normal insertion
53691+	 *
53692+	 * 2) A = R
53693+	 * 	2-1) B = I : (I) -> R
53694+	 *	Normal removal
53695+	 *
53696+	 *	2-2) B = R : (R)
53697+	 *	Return because old status is 'removal'
53698+	 *	and any care isn't required.
53699+	 *
53700+	 *
53701+	 */
53702+	is_card_detected = (D_DETECT == ufshcd_check_card_detect(hba));
53703+	if (hba->latest_card_status == H_INSERT) {
53704+		return H_REMOVE;
53705+	} else {
53706+		if (is_card_detected)
53707+			return H_INSERT;
53708+		else
53709+			return H_BREAK;
53710+	}
53711+}
53712+
53713+static void ufshcd_card_detect_handler(struct work_struct *work)
53714+{
53715+	struct ufs_hba *hba;
53716+	unsigned long flags;
53717+	int tag;
53718+	unsigned long outstanding_reqs;
53719+	int current_status;
53720+	struct scsi_target *starget;
53721+	struct uic_command uic_cmd = {0};
53722+
53723+	hba = container_of(work, struct ufs_hba, cd_work);
53724+	msleep(50);
53725+	current_status = hba->latest_card_status;
53726+	while (1) {
53727+		pm_runtime_get_sync(hba->dev);
53728+
53729+		/*
53730+		 * There is a requirement of whether card detection interrupt
53731+		 * happens before terminating here not to miss the interrupt.
53732+		 * The hint should be wrapped by spin lock.
53733+		 */
53734+		spin_lock_irqsave(hba->host->host_lock, flags);
53735+		if (unlikely(!hba->card_status_changed)) {
53736+			spin_unlock_irqrestore(hba->host->host_lock, flags);
53737+			return;
53738+		}
53739+		hba->card_status_changed = false;
53740+		spin_unlock_irqrestore(hba->host->host_lock, flags);
53741+
53742+		current_status = ufshcd_select_next_job(hba, current_status);
53743+
53744+		if (current_status == H_INSERT) {
53745+			/*
53746+			 * On insertion, a total sequence to initialize
53747+			 * UFS interface is required.
53748+			 */
53749+
53750+			ufshcd_hba_enable(hba);
53751+			ufshcd_probe_hba(hba);
53752+
53753+			dev_err(hba->dev, "card inserted\n");
53754+			hba->latest_card_status = current_status;
53755+			hba->error_count = 0;
53756+			break;
53757+		} else if (current_status == H_REMOVE) {
53758+			/*
53759+			 * On removal, clearing slots and I/O completion
53760+			 * of pending tasks, if any, are required.
53761+			 */
53762+
53763+			spin_lock_irqsave(hba->host->host_lock, flags);
53764+			outstanding_reqs = hba->outstanding_reqs;
53765+			spin_unlock_irqrestore(hba->host->host_lock, flags);
53766+			if (outstanding_reqs) {
53767+				for_each_set_bit(tag, &outstanding_reqs, hba->nutrs)
53768+					ufshcd_clear_cmd(hba, tag);
53769+				__ufshcd_transfer_req_compl(hba, DID_NO_CONNECT);
53770+			}
53771+
53772+			uic_cmd.command = UIC_CMD_DME_RESET;
53773+			ufshcd_send_uic_cmd(hba, &uic_cmd);
53774+
53775+			spin_lock_irqsave(hba->host->host_lock, flags);
53776+			ufshcd_hba_stop(hba, true);
53777+			hba->ufshcd_state = UFSHCD_STATE_OFFLINE;
53778+			spin_unlock_irqrestore(hba->host->host_lock, flags);
53779+
53780+			/*
53781+			 * A device file removal is required on card removal
53782+			 */
53783+			if (!list_empty(&hba->host->__targets)) {
53784+				starget = list_first_entry(&hba->host->__targets,
53785+						struct scsi_target, siblings);
53786+				scsi_remove_device(hba->sdev_rpmb);
53787+				scsi_remove_device(hba->sdev_boot);
53788+				scsi_remove_device(hba->sdev_ufs_device);
53789+				scsi_remove_target(&starget->dev);
53790+			}
53791+
53792+			dev_err(hba->dev, "card removed\n");
53793+			hba->latest_card_status = current_status;
53794+			return;
53795+		} else {
53796+			dev_err(hba->dev, "returned\n");
53797+			break;
53798+		}
53799+	}
53800+	pm_runtime_put_sync(hba->dev);
53801+}
53802+#endif
53803+
53804 static struct ufs_hba_variant_params ufs_hba_vps = {
53805 	.hba_enable_delay_us		= 1000,
53806 	.wb_flush_threshold		= UFS_WB_BUF_REMAIN_PERCENT(40),
53807@@ -8540,6 +8713,10 @@ static int ufshcd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
53808 	enum ufs_dev_pwr_mode req_dev_pwr_mode;
53809 	enum uic_link_state req_link_state;
53810
53811+#ifdef CONFIG_SCSI_UFS_CARD
53812+	if (hba->ufshcd_state == UFSHCD_STATE_OFFLINE)
53813+		return 0;
53814+#endif
53815 	hba->pm_op_in_progress = 1;
53816 	if (!ufshcd_is_shutdown_pm(pm_op)) {
53817 		pm_lvl = ufshcd_is_runtime_pm(pm_op) ?
53818@@ -9017,6 +9194,9 @@ void ufshcd_remove(struct ufs_hba *hba)
53819 	ufshcd_exit_clk_gating(hba);
53820 	if (ufshcd_is_clkscaling_supported(hba))
53821 		device_remove_file(hba->dev, &hba->clk_scaling.enable_attr);
53822+#ifdef CONFIG_SCSI_UFS_CARD
53823+	destroy_workqueue(hba->cd_wq);
53824+#endif
53825 	ufshcd_hba_exit(hba);
53826 }
53827 EXPORT_SYMBOL_GPL(ufshcd_remove);
53828@@ -9185,6 +9365,14 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
53829 	INIT_WORK(&hba->eh_work, ufshcd_err_handler);
53830 	INIT_WORK(&hba->eeh_work, ufshcd_exception_event_handler);
53831
53832+#ifdef CONFIG_SCSI_UFS_CARD
53833+	INIT_WORK(&hba->cd_work, ufshcd_card_detect_handler);
53834+	hba->cd_wq = alloc_workqueue("ufshcd_cd_wq", WQ_FREEZABLE, 0);
53835+	if (!hba->cd_wq) {
53836+		err = -ENOMEM;
53837+		goto out_error;
53838+	}
53839+#endif
53840 	/* Initialize UIC command mutex */
53841 	mutex_init(&hba->uic_cmd_mutex);
53842
53843@@ -9293,7 +9481,37 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
53844 	 */
53845 	ufshcd_set_ufs_dev_active(hba);
53846
53847+#ifndef CONFIG_SCSI_UFS_CARD
53848 	async_schedule(ufshcd_async_scan, hba);
53849+#else
53850+	unsigned int cd_irq;
53851+	if (gpio_is_valid(hba->cd_gpio) &&
53852+			!gpio_request(hba->cd_gpio, "UFSCARD")) {
53853+		cd_irq = gpio_to_irq(hba->cd_gpio);
53854+		dev_err(hba->dev, "card detection interrupt number = %d\n", cd_irq);
53855+		if (cd_irq &&
53856+			devm_request_irq(hba->dev, cd_irq, ufshcd_intr_card_detect,
53857+				IRQF_TRIGGER_RISING |
53858+				IRQF_TRIGGER_FALLING |
53859+				IRQF_ONESHOT,
53860+				UFSCARDHCD, hba) == 0) {
53861+			dev_warn(hba->dev, "success to request irq for card detect.\n");
53862+			enable_irq_wake(cd_irq);
53863+			hba->is_cd_irq_enabled = true;
53864+			hba->cd_irq = cd_irq;
53865+		} else
53866+			dev_warn(hba->dev, "cannot request irq for card detect.\n");
53867+	}
53868+
53869+	if (D_DETECT == ufshcd_check_card_detect(hba)) {
53870+		hba->latest_card_status = true;
53871+		async_schedule(ufshcd_async_scan, hba);
53872+	} else {
53873+		hba->latest_card_status = false;
53874+		ufshcd_hba_stop(hba, true);
53875+		hba->ufshcd_state = UFSHCD_STATE_OFFLINE;
53876+	}
53877+#endif
53878 	ufs_sysfs_add_nodes(hba->dev);
53879
53880 	return 0;
53881diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
53882index 812aa3487..c2fe83d27 100644
53883--- a/drivers/scsi/ufs/ufshcd.h
53884+++ b/drivers/scsi/ufs/ufshcd.h
53885@@ -50,6 +50,7 @@
53886
53887 #define UFSHCD "ufshcd"
53888 #define UFSHCD_DRIVER_VERSION "0.2"
53889+#define UFSCARDHCD "ufscarddetect"
53890
53891 struct ufs_hba;
53892
53893@@ -324,6 +325,7 @@ struct ufs_hba_variant_ops {
53894 					void *data);
53895 	int	(*program_key)(struct ufs_hba *hba,
53896 			       const union ufs_crypto_cfg_entry *cfg, int slot);
53897+	void	(*clk_hareware_init_notify)(void);
53898 };
53899
53900 /* clock gating state  */
53901@@ -463,6 +465,20 @@ struct ufs_stats {
53902 	struct ufs_err_reg_hist task_abort;
53903 };
53904
53905+/* card status */
53906+enum ufs_card_status {
53907+	D_IGNORED = -1,
53908+	D_NO_DETECT = 0,
53909+	D_DETECT,
53910+};
53911+
53912+/* card detect handler action */
53913+enum {
53914+	H_BREAK = -1,
53915+	H_REMOVE = 0,
53916+	H_INSERT,
53917+};
53918+
53919 enum ufshcd_quirks {
53920 	/* Interrupt aggregation support is broken */
53921 	UFSHCD_QUIRK_BROKEN_INTR_AGGR			= 1 << 0,
53922@@ -747,6 +763,18 @@ struct ufs_hba {
53923 	struct work_struct eh_work;
53924 	struct work_struct eeh_work;
53925
53926+#ifdef CONFIG_SCSI_UFS_CARD
53927+	/* card irq */
53928+	unsigned int cd_irq;
53929+	bool is_cd_irq_enabled;
53930+
53931+	/* card detect & work queue */
53932+	int cd_gpio;
53933+	bool latest_card_status;
53934+	bool card_status_changed;
53935+	struct work_struct cd_work;
53936+	struct workqueue_struct *cd_wq;
53937+#endif
53938 	/* HBA Errors */
53939 	u32 errors;
53940 	u32 uic_error;
53941@@ -757,6 +785,7 @@ struct ufs_hba {
53942 	bool force_pmc;
53943 	bool silence_err_logs;
53944
53945+	uint16_t manufacturer_id;
53946 	/* Device management request data */
53947 	struct ufs_dev_cmd dev_cmd;
53948 	ktime_t last_dme_cmd_tstamp;
53949@@ -781,6 +810,11 @@ struct ufs_hba {
53950 	/* Control to enable/disable host capabilities */
53951 	u32 caps;
53952
53953+	u32 hc_pwm;
53954+	u32 hc_gear;
53955+	u32 hc_rate;
53956+	u32 info_skip;
53957+
53958 	struct devfreq *devfreq;
53959 	struct ufs_clk_scaling clk_scaling;
53960 	bool is_sys_suspended;
53961@@ -1234,4 +1268,9 @@ static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun)
53962 int ufshcd_dump_regs(struct ufs_hba *hba, size_t offset, size_t len,
53963 		     const char *prefix);
53964
53965+static inline void ufshcd_vops_clk_hareware_init_notify(struct ufs_hba *hba)
53966+{
53967+	if (hba->vops && hba->vops->clk_hareware_init_notify)
53968+		hba->vops->clk_hareware_init_notify();
53969+}
53970 #endif /* End of Header */
53971diff --git a/drivers/spi/spi-gpio.c b/drivers/spi/spi-gpio.c
53972index 0584f4d2f..d035d4995 100644
53973--- a/drivers/spi/spi-gpio.c
53974+++ b/drivers/spi/spi-gpio.c
53975@@ -367,8 +367,10 @@ static int spi_gpio_probe(struct platform_device *pdev)
53976 	else
53977 		status = spi_gpio_probe_pdata(pdev, master);
53978
53979-	if (status)
53980+	if (status) {
53981+		spi_master_put(master);
53982 		return status;
53983+	}
53984
53985 	spi_gpio = spi_master_get_devdata(master);
53986
53987diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c
53988index d1776fea2..3b280d713 100644
53989--- a/drivers/spi/spi-pl022.c
53990+++ b/drivers/spi/spi-pl022.c
53991@@ -34,6 +34,7 @@
53992 #include <linux/gpio.h>
53993 #include <linux/of_gpio.h>
53994 #include <linux/pinctrl/consumer.h>
53995+#include <linux/of_address.h>
53996
53997 /*
53998  * This macro is used to define some register default values.
53999@@ -127,6 +128,18 @@
54000 /* This one is only in the PL023 variant */
54001 #define SSP_CR1_MASK_FBCLKDEL_ST (0x7UL << 13)
54002
54003+#ifdef CONFIG_ARCH_HISI_BVT
54004+/*
54005+ * The Hisilicon version of this block adds some bits
54006+ * in SSP_CR1
54007+ */
54008+#define SSP_CR1_MASK_BIGEND_HISI	(0x1UL << 4)
54009+#define SSP_CR1_MASK_ALTASENS_HISI	(0x1UL << 6)
54010+
54011+#define SSP_TX_FIFO_CR(r)  (r + 0x28)
54012+#define SSP_RX_FIFO_CR(r)  (r + 0x2C)
54013+#endif
54014+
54015 /*
54016  * SSP Status Register - SSP_SR
54017  */
54018@@ -288,6 +301,10 @@
54019
54020 #define SPI_POLLING_TIMEOUT 1000
54021
54022+#ifdef CONFIG_ARCH_HISI_BVT
54023+#define PL022_IDS_INDEX_HISI		4
54024+#endif
54025+
54026 /*
54027  * The type of reading going on on this chip
54028  */
54029@@ -330,6 +347,15 @@ struct vendor_data {
54030 	bool internal_cs_ctrl;
54031 };
54032
54033+#ifdef CONFIG_ARCH_HISI_BVT
54034+struct cs_data {
54035+	struct resource		res;
54036+	void __iomem		*virt_addr;
54037+	unsigned int		cs_sb;
54038+	unsigned int		cs_mask_bit;
54039+};
54040+#endif
54041+
54042 /**
54043  * struct pl022 - This is the private SSP driver data structure
54044  * @adev: AMBA device model hookup
54045@@ -399,6 +425,9 @@ struct pl022 {
54046 #endif
54047 	int cur_cs;
54048 	int *chipselects;
54049+#ifdef CONFIG_ARCH_HISI_BVT
54050+	struct cs_data		*cs_data;
54051+#endif
54052 };
54053
54054 /**
54055@@ -455,13 +484,41 @@ static void null_cs_control(u32 command)
54056 static void internal_cs_control(struct pl022 *pl022, u32 command)
54057 {
54058 	u32 tmp;
54059+#ifdef CONFIG_ARCH_HISI_BVT
54060+	struct amba_device *adev = pl022->adev;
54061+	struct amba_driver *adrv = container_of(adev->dev.driver,
54062+			struct amba_driver, drv);
54063+
54064+	if (pl022->vendor->extended_cr && (adev->periphid ==
54065+				adrv->id_table[PL022_IDS_INDEX_HISI].id)) {
54066+		if (pl022->cs_data) {
54067+			tmp = readl(pl022->cs_data->virt_addr);
54068+			tmp &= ~(pl022->cs_data->cs_mask_bit);
54069+			tmp |= ((u32)pl022->cur_cs) << pl022->cs_data->cs_sb;
54070+			writel(tmp, pl022->cs_data->virt_addr);
54071+		}
54072
54073-	tmp = readw(SSP_CSR(pl022->virtbase));
54074-	if (command == SSP_CHIP_SELECT)
54075-		tmp &= ~BIT(pl022->cur_cs);
54076-	else
54077-		tmp |= BIT(pl022->cur_cs);
54078-	writew(tmp, SSP_CSR(pl022->virtbase));
54079+		if (command == SSP_CHIP_SELECT)
54080+			/* Enable SSP */
54081+			writew((readw(SSP_CR1(pl022->virtbase)) |
54082+						SSP_CR1_MASK_SSE),
54083+					SSP_CR1(pl022->virtbase));
54084+		else
54085+			/* disable SSP */
54086+			writew((readw(SSP_CR1(pl022->virtbase)) &
54087+						(~SSP_CR1_MASK_SSE)),
54088+					SSP_CR1(pl022->virtbase));
54089+	} else {
54090+#endif
54091+		tmp = readw(SSP_CSR(pl022->virtbase));
54092+		if (command == SSP_CHIP_SELECT)
54093+			tmp &= ~BIT(pl022->cur_cs);
54094+		else
54095+			tmp |= BIT(pl022->cur_cs);
54096+		writew(tmp, SSP_CSR(pl022->virtbase));
54097+#ifdef CONFIG_ARCH_HISI_BVT
54098+	}
54099+#endif
54100 }
54101
54102 static void pl022_cs_control(struct pl022 *pl022, u32 command)
54103@@ -561,8 +618,16 @@ static int flush(struct pl022 *pl022)
54104 static void restore_state(struct pl022 *pl022)
54105 {
54106 	struct chip_data *chip = pl022->cur_chip;
54107+#ifdef CONFIG_ARCH_HISI_BVT
54108+	struct amba_device *adev = pl022->adev;
54109+	struct amba_driver *adrv = container_of(adev->dev.driver,
54110+			struct amba_driver, drv);
54111
54112+	if (pl022->vendor->extended_cr && (adev->periphid !=
54113+				adrv->id_table[PL022_IDS_INDEX_HISI].id))
54114+#else
54115 	if (pl022->vendor->extended_cr)
54116+#endif
54117 		writel(chip->cr0, SSP_CR0(pl022->virtbase));
54118 	else
54119 		writew(chip->cr0, SSP_CR0(pl022->virtbase));
54120@@ -635,6 +700,15 @@ static void restore_state(struct pl022 *pl022)
54121 	GEN_MASK_BITS(SSP_FEEDBACK_CLK_DELAY_NONE, SSP_CR1_MASK_FBCLKDEL_ST, 13) \
54122 )
54123
54124+#ifdef CONFIG_ARCH_HISI_BVT
54125+/* Hisilicon versions extend this register to use all 16 bits */
54126+#define DEFAULT_SSP_REG_CR1_HISI ( \
54127+	DEFAULT_SSP_REG_CR1 | \
54128+	GEN_MASK_BITS(SSP_RX_MSB, SSP_CR1_MASK_BIGEND_HISI, 4) | \
54129+	GEN_MASK_BITS(0x1, SSP_CR1_MASK_ALTASENS_HISI, 6) \
54130+)
54131+#endif
54132+
54133 #define DEFAULT_SSP_REG_CPSR ( \
54134 	GEN_MASK_BITS(SSP_DEFAULT_PRESCALE, SSP_CPSR_MASK_CPSDVSR, 0) \
54135 )
54136@@ -654,8 +728,22 @@ static void load_ssp_default_config(struct pl022 *pl022)
54137 		writel(DEFAULT_SSP_REG_CR0_ST_PL023, SSP_CR0(pl022->virtbase));
54138 		writew(DEFAULT_SSP_REG_CR1_ST_PL023, SSP_CR1(pl022->virtbase));
54139 	} else if (pl022->vendor->extended_cr) {
54140+#ifdef CONFIG_ARCH_HISI_BVT
54141+		struct amba_device *adev = pl022->adev;
54142+		struct amba_driver *adrv = container_of(adev->dev.driver,
54143+				struct amba_driver, drv);
54144+
54145+		if (adev->periphid == adrv->id_table[PL022_IDS_INDEX_HISI].id) {
54146+			writew(DEFAULT_SSP_REG_CR0, SSP_CR0(pl022->virtbase));
54147+			writew(DEFAULT_SSP_REG_CR1_HISI,
54148+					SSP_CR1(pl022->virtbase));
54149+		} else {
54150+#endif
54151 		writel(DEFAULT_SSP_REG_CR0_ST, SSP_CR0(pl022->virtbase));
54152 		writew(DEFAULT_SSP_REG_CR1_ST, SSP_CR1(pl022->virtbase));
54153+#ifdef CONFIG_ARCH_HISI_BVT
54154+		}
54155+#endif
54156 	} else {
54157 		writew(DEFAULT_SSP_REG_CR0, SSP_CR0(pl022->virtbase));
54158 		writew(DEFAULT_SSP_REG_CR1, SSP_CR1(pl022->virtbase));
54159@@ -1138,7 +1226,7 @@ static int pl022_dma_probe(struct pl022 *pl022)
54160 	if (!pl022->dummypage)
54161 		goto err_no_dummypage;
54162
54163-	dev_info(&pl022->adev->dev, "setup for DMA on RX %s, TX %s\n",
54164+	dev_dbg(&pl022->adev->dev, "setup for DMA on RX %s, TX %s\n",
54165 		 dma_chan_name(pl022->dma_rx_channel),
54166 		 dma_chan_name(pl022->dma_tx_channel));
54167
54168@@ -1563,11 +1651,10 @@ static void do_polling_transfer(struct pl022 *pl022)
54169
54170 		/* Update total byte transferred */
54171 		message->actual_length += pl022->cur_transfer->len;
54172+		if (pl022->cur_transfer->cs_change)
54173+			pl022_cs_control(pl022, SSP_CHIP_DESELECT);
54174 		/* Move to next transfer */
54175 		message->state = next_transfer(pl022);
54176-		if (message->state != STATE_DONE
54177-		    && pl022->cur_transfer->cs_change)
54178-			pl022_cs_control(pl022, SSP_CHIP_DESELECT);
54179 	}
54180 out:
54181 	/* Handle end of message */
54182@@ -1855,6 +1942,13 @@ static int pl022_setup(struct spi_device *spi)
54183 	unsigned int bits = spi->bits_per_word;
54184 	u32 tmp;
54185 	struct device_node *np = spi->dev.of_node;
54186+#ifdef CONFIG_ARCH_HISI_BVT
54187+	struct amba_device *adev = pl022->adev;
54188+	struct amba_driver *adrv = container_of(adev->dev.driver,
54189+			struct amba_driver, drv);
54190+	writel(0, SSP_TX_FIFO_CR(pl022->virtbase));
54191+	writel(0, SSP_RX_FIFO_CR(pl022->virtbase));
54192+#endif
54193
54194 	if (!spi->max_speed_hz)
54195 		return -EINVAL;
54196@@ -1997,7 +2091,12 @@ static int pl022_setup(struct spi_device *spi)
54197 	chip->cpsr = clk_freq.cpsdvsr;
54198
54199 	/* Special setup for the ST micro extended control registers */
54200+#ifdef CONFIG_ARCH_HISI_BVT
54201+	if (pl022->vendor->extended_cr && (adev->periphid !=
54202+				adrv->id_table[PL022_IDS_INDEX_HISI].id)) {
54203+#else
54204 	if (pl022->vendor->extended_cr) {
54205+#endif
54206 		u32 etx;
54207
54208 		if (pl022->vendor->pl023) {
54209@@ -2031,6 +2130,22 @@ static int pl022_setup(struct spi_device *spi)
54210 			       SSP_CR1_MASK_RXIFLSEL_ST, 7);
54211 		SSP_WRITE_BITS(chip->cr1, chip_info->tx_lev_trig,
54212 			       SSP_CR1_MASK_TXIFLSEL_ST, 10);
54213+#ifdef CONFIG_ARCH_HISI_BVT
54214+	} else if (pl022->vendor->extended_cr && (adev->periphid ==
54215+				adrv->id_table[PL022_IDS_INDEX_HISI].id)) {
54216+		SSP_WRITE_BITS(chip->cr0, bits - 1,
54217+			       SSP_CR0_MASK_DSS, 0);
54218+		SSP_WRITE_BITS(chip->cr0, chip_info->iface,
54219+			       SSP_CR0_MASK_FRF, 4);
54220+
54221+		if (spi->mode & SPI_LSB_FIRST)
54222+			tmp = !!SPI_LSB_FIRST;
54223+		else
54224+			tmp = !SPI_LSB_FIRST;
54225+
54226+		SSP_WRITE_BITS(chip->cr1, tmp, SSP_CR1_MASK_BIGEND_HISI, 4);
54227+		SSP_WRITE_BITS(chip->cr1, 0x1, SSP_CR1_MASK_ALTASENS_HISI, 6);
54228+#endif
54229 	} else {
54230 		SSP_WRITE_BITS(chip->cr0, bits - 1,
54231 			       SSP_CR0_MASK_DSS, 0);
54232@@ -2119,6 +2234,8 @@ pl022_platform_data_dt_get(struct device *dev)
54233 static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
54234 {
54235 	struct device *dev = &adev->dev;
54236+	struct amba_driver *adrv = container_of(adev->dev.driver,
54237+			struct amba_driver, drv);
54238 	struct pl022_ssp_controller *platform_info =
54239 			dev_get_platdata(&adev->dev);
54240 	struct spi_master *master;
54241@@ -2126,7 +2243,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
54242 	struct device_node *np = adev->dev.of_node;
54243 	int status = 0, i, num_cs;
54244
54245-	dev_info(&adev->dev,
54246+	dev_dbg(&adev->dev,
54247 		 "ARM PL022 driver, device ID: 0x%08x\n", adev->periphid);
54248 	if (!platform_info && IS_ENABLED(CONFIG_OF))
54249 		platform_info = pl022_platform_data_dt_get(dev);
54250@@ -2182,6 +2299,43 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
54251 	} else if (pl022->vendor->internal_cs_ctrl) {
54252 		for (i = 0; i < num_cs; i++)
54253 			pl022->chipselects[i] = i;
54254+
54255+#ifdef CONFIG_ARCH_HISI_BVT
54256+		if ((adev->periphid == adrv->id_table[PL022_IDS_INDEX_HISI].id)
54257+				&& pl022->vendor->extended_cr
54258+				&& (num_cs > 1)) {
54259+			pl022->cs_data = devm_kzalloc(dev,
54260+					sizeof(struct cs_data),
54261+					GFP_KERNEL);
54262+			if (!pl022->cs_data) {
54263+				status = -ENOMEM;
54264+				goto err_no_mem;
54265+			}
54266+
54267+			if (of_address_to_resource(np, 1,
54268+						&pl022->cs_data->res)) {
54269+				status = -EPROBE_DEFER;
54270+				goto err_no_gpio;
54271+			}
54272+
54273+			if (of_property_read_u32(np, "hisi,spi_cs_sb",
54274+						&pl022->cs_data->cs_sb)) {
54275+				status = -EPROBE_DEFER;
54276+				goto err_no_gpio;
54277+			}
54278+
54279+			if (of_property_read_u32(np, "hisi,spi_cs_mask_bit",
54280+						&pl022->cs_data->cs_mask_bit)) {
54281+				status = -EPROBE_DEFER;
54282+				goto err_no_gpio;
54283+			}
54284+
54285+			pl022->cs_data->virt_addr = devm_ioremap(dev,
54286+					pl022->cs_data->res.start,
54287+					resource_size(&pl022->cs_data->res));
54288+		} else
54289+				pl022->cs_data = NULL;
54290+#endif
54291 	} else if (IS_ENABLED(CONFIG_OF)) {
54292 		for (i = 0; i < num_cs; i++) {
54293 			int cs_gpio = of_get_named_gpio(np, "cs-gpios", i);
54294@@ -2227,7 +2381,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
54295 		status = -ENOMEM;
54296 		goto err_no_ioremap;
54297 	}
54298-	dev_info(&adev->dev, "mapped registers from %pa to %p\n",
54299+	dev_dbg(&adev->dev, "mapped registers from %pa to %p\n",
54300 		&adev->res.start, pl022->virtbase);
54301
54302 	pl022->clk = devm_clk_get(&adev->dev, NULL);
54303@@ -2287,7 +2441,7 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
54304
54305 	/* let runtime pm put suspend */
54306 	if (platform_info->autosuspend_delay > 0) {
54307-		dev_info(&adev->dev,
54308+		dev_dbg(&adev->dev,
54309 			"will use autosuspend for runtime pm, delay %dms\n",
54310 			platform_info->autosuspend_delay);
54311 		pm_runtime_set_autosuspend_delay(dev,
54312@@ -2308,6 +2462,10 @@ static int pl022_probe(struct amba_device *adev, const struct amba_id *id)
54313  err_no_ioremap:
54314 	amba_release_regions(adev);
54315  err_no_ioregion:
54316+#ifdef CONFIG_ARCH_HISI_BVT
54317+	if (pl022->cs_data)
54318+		devm_iounmap(&adev->dev, pl022->cs_data->virt_addr);
54319+#endif
54320  err_no_gpio:
54321  err_no_mem:
54322 	spi_master_put(master);
54323@@ -2334,6 +2492,10 @@ pl022_remove(struct amba_device *adev)
54324
54325 	clk_disable_unprepare(pl022->clk);
54326 	amba_release_regions(adev);
54327+#ifdef CONFIG_ARCH_HISI_BVT
54328+	if (pl022->cs_data)
54329+		devm_iounmap(&adev->dev, pl022->cs_data->virt_addr);
54330+#endif
54331 	tasklet_disable(&pl022->pump_transfers);
54332 	return 0;
54333 }
54334@@ -2445,6 +2607,17 @@ static struct vendor_data vendor_lsi = {
54335 	.internal_cs_ctrl = true,
54336 };
54337
54338+#ifdef CONFIG_ARCH_HISI_BVT
54339+static struct vendor_data vendor_hisi = {
54340+	.fifodepth = 256,
54341+	.max_bpw = 16,
54342+	.unidir = false,
54343+	.extended_cr = true,
54344+	.pl023 = false,
54345+	.loopback = true,
54346+	.internal_cs_ctrl = true,
54347+};
54348+#endif
54349 static const struct amba_id pl022_ids[] = {
54350 	{
54351 		/*
54352@@ -2485,6 +2658,17 @@ static const struct amba_id pl022_ids[] = {
54353 		.mask	= 0x000fffff,
54354 		.data	= &vendor_lsi,
54355 	},
54356+#ifdef CONFIG_ARCH_HISI_BVT
54357+	{
54358+		/*
54359+		 * Hisilicon derivative, this has a 16bit wide
54360+		 * and 256 locations deep TX/RX FIFO
54361+		 */
54362+		.id	= 0x00800022,
54363+		.mask	= 0xffffffff,
54364+		.data	= &vendor_hisi,
54365+	},
54366+#endif
54367 	{ 0, 0 },
54368 };
54369
54370diff --git a/drivers/tty/vt/vc_screen.c b/drivers/tty/vt/vc_screen.c
54371index 1850bacdb..d3934eb8f 100644
54372--- a/drivers/tty/vt/vc_screen.c
54373+++ b/drivers/tty/vt/vc_screen.c
54374@@ -373,6 +373,9 @@ vcs_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
54375 	loff_t pos;
54376 	bool viewed, attr, uni_mode;
54377
54378+	if (use_unicode(inode))
54379+		return -EOPNOTSUPP;
54380+
54381 	con_buf = (char *) __get_free_page(GFP_KERNEL);
54382 	if (!con_buf)
54383 		return -ENOMEM;
54384diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
54385index 95a9bae72..ad951a1a1 100644
54386--- a/drivers/usb/core/hub.c
54387+++ b/drivers/usb/core/hub.c
54388@@ -1419,6 +1419,10 @@ static int hub_configure(struct usb_hub *hub,
54389 		ret = -ENODEV;
54390 		goto fail;
54391 	} else if (hub->descriptor->bNbrPorts == 0) {
54392+		if (!hdev->parent) {
54393+			dev_info(hub_dev, "hub can't support USB3.0\n");
54394+			return -ENODEV;
54395+		}
54396 		message = "hub doesn't have any ports!";
54397 		ret = -ENODEV;
54398 		goto fail;
54399diff --git a/drivers/usb/core/notify.c b/drivers/usb/core/notify.c
54400index e61436637..b507a25ce 100644
54401--- a/drivers/usb/core/notify.c
54402+++ b/drivers/usb/core/notify.c
54403@@ -66,3 +66,11 @@ void usb_notify_remove_bus(struct usb_bus *ubus)
54404 {
54405 	blocking_notifier_call_chain(&usb_notifier_list, USB_BUS_REMOVE, ubus);
54406 }
54407+void usb_notify_online_status(bool online)
54408+{
54409+	if (online) {
54410+		blocking_notifier_call_chain(&usb_notifier_list, USB_GADGET_ADD, NULL);
54411+	} else {
54412+		blocking_notifier_call_chain(&usb_notifier_list, USB_GADGET_REMOVE, NULL);
54413+	}
54414+}
54415diff --git a/drivers/usb/dwc3/Makefile b/drivers/usb/dwc3/Makefile
54416index ae86da0dc..9abca9a8a 100644
54417--- a/drivers/usb/dwc3/Makefile
54418+++ b/drivers/usb/dwc3/Makefile
54419@@ -2,10 +2,9 @@
54420 # define_trace.h needs to know how to find our header
54421 CFLAGS_trace.o				:= -I$(src)
54422
54423-obj-$(CONFIG_USB_DWC3)			+= dwc3.o
54424-
54425-dwc3-y					:= core.o
54426+obj-$(CONFIG_USB_DWC3)			+= dwc3.o dwc3-hisi.o
54427
54428+dwc3-y					:= core.o proc.o
54429 ifneq ($(CONFIG_TRACING),)
54430 	dwc3-y				+= trace.o
54431 endif
54432diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c
54433index 1580d51ae..1219a6487 100644
54434--- a/drivers/usb/dwc3/core.c
54435+++ b/drivers/usb/dwc3/core.c
54436@@ -37,9 +37,25 @@
54437 #include "io.h"
54438
54439 #include "debug.h"
54440+#include "dwc3-hisi.h"
54441
54442 #define DWC3_DEFAULT_AUTOSUSPEND_DELAY	5000 /* ms */
54443
54444+
54445+/*
54446+ * Default to the number of outstanding pipelined transfer
54447+ * requests is 0x3[11:8], modify the field change to 0x7.
54448+ */
54449+static void dwc3_outstanding_pipe_choose(struct dwc3 *dwc)
54450+{
54451+	u32	reg;
54452+
54453+	reg = dwc3_readl(dwc->regs, DWC3_GSBUSCFG1);
54454+	reg &= ~DWC3_PIPE_TRANS_LIMIT_MASK;
54455+	reg |= DWC3_PIPE_TRANS_LIMIT;
54456+	dwc3_writel(dwc->regs, DWC3_GSBUSCFG1, reg);
54457+}
54458+
54459 /**
54460  * dwc3_get_dr_mode - Validates and sets dr_mode
54461  * @dwc: pointer to our context structure
54462@@ -1294,7 +1310,8 @@ static void dwc3_get_properties(struct dwc3 *dwc)
54463 	 */
54464 	hird_threshold = 12;
54465
54466-	dwc->maximum_speed = usb_get_maximum_speed(dev);
54467+	dwc->maximum_speed = usb_get_max_speed(dev);
54468+
54469 	dwc->dr_mode = usb_get_dr_mode(dev);
54470 	dwc->hsphy_mode = of_usb_get_phy_mode(dev->of_node);
54471
54472@@ -1330,6 +1347,9 @@ static void dwc3_get_properties(struct dwc3 *dwc)
54473 	device_property_read_u8(dev, "snps,tx-max-burst-prd",
54474 				&tx_max_burst_prd);
54475
54476+	dwc->usb2_lpm_disable = device_property_read_bool(dev,
54477+				"snps,usb2-lpm-disable");
54478+
54479 	dwc->disable_scramble_quirk = device_property_read_bool(dev,
54480 				"snps,disable_scramble_quirk");
54481 	dwc->u2exit_lfps_quirk = device_property_read_bool(dev,
54482@@ -1367,6 +1387,16 @@ static void dwc3_get_properties(struct dwc3 *dwc)
54483 	dwc->parkmode_disable_ss_quirk = device_property_read_bool(dev,
54484 				"snps,parkmode-disable-ss-quirk");
54485
54486+	dwc->dis_initiate_u1 = device_property_read_bool(dev,
54487+				"snps,dis_initiate_u1");
54488+	dwc->dis_initiate_u2 = device_property_read_bool(dev,
54489+				"snps,dis_initiate_u2");
54490+
54491+	dwc->eps_new_init = device_property_read_bool(dev,
54492+				"snps,eps_new_init");
54493+	device_property_read_u32(dev, "eps_directions",
54494+				 &dwc->eps_directions);
54495+
54496 	dwc->tx_de_emphasis_quirk = device_property_read_bool(dev,
54497 				"snps,tx_de_emphasis_quirk");
54498 	device_property_read_u8(dev, "snps,tx_de_emphasis",
54499@@ -1550,6 +1580,10 @@ static int dwc3_probe(struct platform_device *pdev)
54500 	platform_set_drvdata(pdev, dwc);
54501 	dwc3_cache_hwparams(dwc);
54502
54503+	device_property_read_u32_array(dev, "eps_map",
54504+					dwc->dwceps_map_to_usbeps,
54505+					DWC3_NUM_EPS(&dwc->hwparams));
54506+
54507 	spin_lock_init(&dwc->lock);
54508 	mutex_init(&dwc->mutex);
54509
54510@@ -1585,6 +1619,8 @@ static int dwc3_probe(struct platform_device *pdev)
54511 		goto err4;
54512 	}
54513
54514+	dwc3_outstanding_pipe_choose(dwc);
54515+
54516 	dwc3_check_params(dwc);
54517 	dwc3_debugfs_init(dwc);
54518
54519@@ -1652,6 +1688,10 @@ static int dwc3_remove(struct platform_device *pdev)
54520 	dwc3_free_event_buffers(dwc);
54521 	dwc3_free_scratch_buffers(dwc);
54522
54523+	hisi_dwc3_exited();
54524+
54525+	dwc3_set_mode(dwc, DWC3_GCTL_PRTCAP_HOST);
54526+
54527 	return 0;
54528 }
54529
54530diff --git a/drivers/usb/dwc3/core.h b/drivers/usb/dwc3/core.h
54531index 79e1b82e5..ace408a7e 100644
54532--- a/drivers/usb/dwc3/core.h
54533+++ b/drivers/usb/dwc3/core.h
54534@@ -32,6 +32,8 @@
54535 #include <linux/phy/phy.h>
54536
54537 #define DWC3_MSG_MAX	500
54538+#define DWC3_PIPE_TRANS_LIMIT_MASK	(0xf << 8)
54539+#define DWC3_PIPE_TRANS_LIMIT		(0x7 << 8)
54540
54541 /* Global constants */
54542 #define DWC3_PULL_UP_TIMEOUT	500	/* ms */
54543@@ -478,6 +480,9 @@
54544
54545 #define DWC3_DSTS_RXFIFOEMPTY		BIT(17)
54546
54547+#define DWC3_EVENT_PRAM_MAX_SOFFN	0x3fff
54548+#define DWC3_EVENT_PRAM_SOFFN_MASK  0x3fff
54549+
54550 #define DWC3_DSTS_SOFFN_MASK		(0x3fff << 3)
54551 #define DWC3_DSTS_SOFFN(n)		(((n) & DWC3_DSTS_SOFFN_MASK) >> 3)
54552
54553@@ -658,7 +663,7 @@ struct dwc3_event_buffer {
54554 #define DWC3_EP_DIRECTION_TX	true
54555 #define DWC3_EP_DIRECTION_RX	false
54556
54557-#define DWC3_TRB_NUM		256
54558+#define DWC3_TRB_NUM		4096
54559
54560 /**
54561  * struct dwc3_ep - device side endpoint representation
54562@@ -726,8 +731,8 @@ struct dwc3_ep {
54563 	 * By using u8 types we ensure that our % operator when incrementing
54564 	 * enqueue and dequeue get optimized away by the compiler.
54565 	 */
54566-	u8			trb_enqueue;
54567-	u8			trb_dequeue;
54568+	u32			trb_enqueue;
54569+	u32			trb_dequeue;
54570
54571 	u8			number;
54572 	u8			type;
54573@@ -1092,6 +1097,8 @@ struct dwc3 {
54574 	struct dwc3_event_buffer *ev_buf;
54575 	struct dwc3_ep		*eps[DWC3_ENDPOINTS_NUM];
54576
54577+	u32			dwceps_map_to_usbeps[DWC3_ENDPOINTS_NUM];
54578+
54579 	struct usb_gadget	*gadget;
54580 	struct usb_gadget_driver *gadget_driver;
54581
54582@@ -1199,6 +1206,12 @@ struct dwc3 {
54583 	u8			speed;
54584
54585 	u8			num_eps;
54586+/*
54587+ * NOTICE: eps_directions bitmap[0~31] 0: out ep, 1: in ep
54588+ * and used with total ep numbers(num_out_eps + num_in_eps)
54589+ */
54590+#define DWC3_EPS_DEFAULT_DIRECTIONS 0xaaaaaaaa
54591+	u32			eps_directions;
54592
54593 	struct dwc3_hwparams	hwparams;
54594 	struct dentry		*root;
54595@@ -1215,6 +1228,13 @@ struct dwc3 {
54596 	u8			tx_thr_num_pkt_prd;
54597 	u8			tx_max_burst_prd;
54598
54599+	struct proc_dir_entry* parent_entry;
54600+	struct proc_dir_entry* csts_entry;
54601+	u8			udc_connect_status;
54602+#define UDC_DISCONNECTED 	0
54603+#define UDC_CONNECT_HOST 	1
54604+#define UDC_CONNECT_CHARGER	2
54605+
54606 	const char		*hsphy_interface;
54607
54608 	unsigned		connected:1;
54609@@ -1253,6 +1273,10 @@ struct dwc3 {
54610 	unsigned		dis_del_phy_power_chg_quirk:1;
54611 	unsigned		dis_tx_ipgap_linecheck_quirk:1;
54612 	unsigned		parkmode_disable_ss_quirk:1;
54613+	unsigned		dis_initiate_u1:1;
54614+	unsigned		dis_initiate_u2:1;
54615+
54616+	unsigned		eps_new_init:1;
54617
54618 	unsigned		tx_de_emphasis_quirk:1;
54619 	unsigned		tx_de_emphasis:2;
54620@@ -1519,6 +1543,9 @@ static inline void dwc3_otg_host_init(struct dwc3 *dwc)
54621 { }
54622 #endif
54623
54624+int dwc3_proc_init(struct dwc3 *dwc);
54625+int dwc3_proc_shutdown(struct dwc3 *dwc);
54626+
54627 /* power management interface */
54628 #if !IS_ENABLED(CONFIG_USB_DWC3_HOST)
54629 int dwc3_gadget_suspend(struct dwc3 *dwc);
54630diff --git a/drivers/usb/dwc3/dwc3-hisi.c b/drivers/usb/dwc3/dwc3-hisi.c
54631new file mode 100644
54632index 000000000..d8d3e8377
54633--- /dev/null
54634+++ b/drivers/usb/dwc3/dwc3-hisi.c
54635@@ -0,0 +1,446 @@
54636+/*
54637+ * dwc3-hisi.c
54638+ *
54639+ * Dwc3 private driver for Hisilicon.
54640+ *
54641+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2018-2019. All rights reserved.
54642+ *
54643+ * This program is free software; you can redistribute  it and/or modify it
54644+ * under  the terms of  the GNU General Public License as published by the
54645+ * Free Software Foundation;  either version 2 of the  License, or (at your
54646+ * option) any later version.
54647+ *
54648+ * This program is distributed in the hope that it will be useful,
54649+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
54650+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54651+ * GNU General Public License for more details.
54652+ *
54653+ * You should have received a copy of the GNU General Public License
54654+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
54655+ *
54656+ */
54657+
54658+#include <linux/clk-provider.h>
54659+#include <linux/clk.h>
54660+#include <linux/delay.h>
54661+#include <linux/dma-mapping.h>
54662+#include <linux/kernel.h>
54663+#include <linux/module.h>
54664+#include <linux/of.h>
54665+#include <linux/of_address.h>
54666+#include <linux/of_irq.h>
54667+#include <linux/of_platform.h>
54668+#include <linux/phy/phy.h>
54669+#include <linux/platform_device.h>
54670+#include <linux/pm_runtime.h>
54671+#include <linux/reset.h>
54672+#include <linux/slab.h>
54673+#include <linux/usb/ch9.h>
54674+
54675+#include "dwc3-hisi.h"
54676+
54677+#define USB3_CTRL           0x190
54678+#define REG_SYS_STAT        0x8c
54679+#define PCIE_USB3_MODE_MASK (0x3 << 12)
54680+#define USB3_PCLK_OCC_SEL   (0x1 << 30)
54681+
54682+#define PERI_USB3_GTXTHRCFG 0x2310000
54683+
54684+#define REG_GUSB3PIPECTL0 0xc2c0
54685+#define GTXTHRCFG         0xc108
54686+
54687+#define PCS_SSP_SOFT_RESET  (0x1 << 31)
54688+#define SUSPEND_USB3_SS_PHY (0x1 << 17)
54689+
54690+#define GUSB2PHYCFG_OFFSET 0xc200
54691+#define GCTL_OFFSET        0xc110
54692+#define GUCTL_OFFSET       0xc12C
54693+#define GFLADJ_OFFSET      0xc630
54694+
54695+#define U2_FREECLK_EXISTS (0x1 << 30)
54696+#define SOFITPSYNC        (0x1 << 10)
54697+#define REFCLKPER_MASK    0xffc00000
54698+#define REFCLKPER_VAL	0x29
54699+#define set_refclkper(a)  (((a) << 22) & REFCLKPER_MASK)
54700+
54701+#define PLS1        (0x1 << 31)
54702+#define DECR_MASK   0x7f000000
54703+#define DECR_VAL	0xa
54704+#define set_decr(a) (((a) << 24) & DECR_MASK)
54705+
54706+#define LPM_SEL      (0x1 << 23)
54707+#define FLADJ_MASK   0x003fff00
54708+#define FLADJ_VAL	0x7f0
54709+#define set_fladj(a) (((a) << 8) & FLADJ_MASK)
54710+
54711+/* hi3559a */
54712+#define DOUBLE_PCIE_MODE    0x0
54713+#define P0_PCIE_ADD_P1_USB3 (0x1 << 12)
54714+#define DOUBLE_USB3         (0x2 << 12)
54715+
54716+/* hi3556a,hi3519a */
54717+#define PCIE_X1_MODE (0x0 << 12)
54718+#define USB3_MODE    (0x1 << 12)
54719+
54720+static struct hi_priv *usb_priv = NULL;
54721+
54722+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100)
54723+static int speed_adapt_for_hi3559a(struct device_node *np)
54724+{
54725+	unsigned int ret;
54726+	unsigned int reg;
54727+
54728+	if (np == NULL)
54729+		return -EINVAL;
54730+
54731+	usb_priv->speed_id = -1;
54732+
54733+	reg = readl(usb_priv->sys_ctrl + REG_SYS_STAT);
54734+	reg &= PCIE_USB3_MODE_MASK;
54735+
54736+	switch (reg) {
54737+	case DOUBLE_PCIE_MODE:
54738+		ret = USB_SPEED_HIGH;
54739+		break;
54740+	case P0_PCIE_ADD_P1_USB3:
54741+		if (of_property_read_u32(np, "port_speed", &usb_priv->speed_id))
54742+			usb_priv->speed_id = -1;
54743+
54744+		if (usb_priv->speed_id == 0)
54745+			ret = USB_SPEED_HIGH;
54746+		else if (usb_priv->speed_id == 1)
54747+			ret = USB_SPEED_SUPER;
54748+		else
54749+			ret = USB_SPEED_UNKNOWN;
54750+
54751+		break;
54752+	case DOUBLE_USB3:
54753+		ret = USB_SPEED_SUPER;
54754+		break;
54755+	default:
54756+		ret = USB_SPEED_UNKNOWN;
54757+	}
54758+
54759+	return ret;
54760+}
54761+#endif
54762+
54763+#if defined(CONFIG_ARCH_HI3556AV100) || defined(CONFIG_ARCH_HI3519AV100)
54764+static int speed_adapt_for_hi3556a(struct device *dev)
54765+{
54766+	unsigned int ret;
54767+	unsigned int reg;
54768+
54769+	if (dev == NULL)
54770+		return -EINVAL;
54771+
54772+	reg = readl(usb_priv->sys_ctrl + REG_SYS_STAT);
54773+	reg &= PCIE_USB3_MODE_MASK;
54774+
54775+	if (reg == PCIE_X1_MODE)
54776+		ret = USB_SPEED_HIGH;
54777+	else
54778+		ret = usb_get_maximum_speed(dev);
54779+
54780+	return ret;
54781+}
54782+#endif
54783+
54784+int usb_get_max_speed(struct device *dev)
54785+{
54786+	unsigned int ret;
54787+	struct device_node *np = dev->of_node;
54788+
54789+	if (np == NULL)
54790+		return -EINVAL;
54791+
54792+	usb_priv = kzalloc(sizeof(*usb_priv), GFP_KERNEL);
54793+	if (usb_priv == NULL)
54794+		return -ENOMEM;
54795+
54796+	usb_priv->peri_crg = of_iomap(np, DEV_NODE_FLAG1);
54797+	if (IS_ERR(usb_priv->peri_crg)) {
54798+		kfree(usb_priv);
54799+		usb_priv = NULL;
54800+		return -ENOMEM;
54801+	}
54802+
54803+	usb_priv->sys_ctrl = of_iomap(np, DEV_NODE_FLAG2);
54804+	if (IS_ERR(usb_priv->sys_ctrl)) {
54805+		iounmap(usb_priv->peri_crg);
54806+
54807+		kfree(usb_priv);
54808+		usb_priv = NULL;
54809+		return -ENOMEM;
54810+	}
54811+
54812+#if defined(CONFIG_ARCH_HI3559AV100) || defined(CONFIG_ARCH_HI3569V100)
54813+	ret = speed_adapt_for_hi3559a(np);
54814+#elif defined(CONFIG_ARCH_HI3556AV100) || defined(CONFIG_ARCH_HI3519AV100)
54815+	ret = speed_adapt_for_hi3556a(dev);
54816+#else
54817+	ret = usb_get_maximum_speed(dev);
54818+#endif
54819+
54820+	iounmap(usb_priv->sys_ctrl);
54821+	iounmap(usb_priv->peri_crg);
54822+
54823+	return ret;
54824+}
54825+EXPORT_SYMBOL(usb_get_max_speed);
54826+
54827+void hisi_dwc3_exited(void)
54828+{
54829+	kfree(usb_priv);
54830+	usb_priv = NULL;
54831+}
54832+EXPORT_SYMBOL(hisi_dwc3_exited);
54833+
54834+static int set_ctrl_crg_val(struct device_node *np, struct dwc3_hisi *hisi)
54835+{
54836+	unsigned int ret;
54837+	unsigned int reg;
54838+
54839+	if ((np == NULL) || (hisi == NULL))
54840+		return -EINVAL;
54841+
54842+	/* get usb ctrl crg para */
54843+	ret = of_property_read_u32(np, "crg_offset", &hisi->crg_offset);
54844+	if (ret)
54845+		return ret;
54846+
54847+	ret = of_property_read_u32(np, "crg_ctrl_def_mask", &hisi->crg_ctrl_def_mask);
54848+	if (ret)
54849+		return ret;
54850+
54851+	ret = of_property_read_u32(np, "crg_ctrl_def_val", &hisi->crg_ctrl_def_val);
54852+	if (ret)
54853+		return ret;
54854+
54855+	/* write usb ctrl crg default value */
54856+	reg = readl(hisi->crg_base + hisi->crg_offset);
54857+	reg &= ~hisi->crg_ctrl_def_mask;
54858+	reg |= hisi->crg_ctrl_def_val;
54859+	writel(reg, hisi->crg_base + hisi->crg_offset);
54860+
54861+	return 0;
54862+}
54863+
54864+static int dwc3_hisi_clk_init(struct dwc3_hisi *hisi, int count)
54865+{
54866+	struct device *dev = hisi->dev;
54867+	struct device_node *np = dev->of_node;
54868+	int i, ret;
54869+
54870+	if (!count)
54871+		return -EINVAL;
54872+
54873+	if (np == NULL)
54874+		return -EINVAL;
54875+
54876+	hisi->num_clocks = count;
54877+
54878+	hisi->clks = devm_kcalloc(dev, hisi->num_clocks, sizeof(struct clk *),
54879+				  GFP_KERNEL);
54880+	if (hisi->clks == NULL)
54881+		return -ENOMEM;
54882+
54883+	for (i = 0; i < hisi->num_clocks; i++) {
54884+		struct clk *clk;
54885+
54886+		clk = of_clk_get(np, i);
54887+		if (IS_ERR(clk)) {
54888+			while (--i >= 0)
54889+				clk_put(hisi->clks[i]);
54890+
54891+			ret = PTR_ERR(clk);
54892+			goto clk_free;
54893+		}
54894+
54895+		ret = clk_prepare_enable(clk);
54896+		if (ret < 0) {
54897+			while (--i >= 0) {
54898+				clk_disable_unprepare(hisi->clks[i]);
54899+				clk_put(hisi->clks[i]);
54900+			}
54901+			clk_put(clk);
54902+
54903+			goto clk_free;
54904+		}
54905+
54906+		hisi->clks[i] = clk;
54907+	}
54908+
54909+	return 0;
54910+clk_free:
54911+	devm_kfree(dev, hisi->clks);
54912+	hisi->clks = NULL;
54913+
54914+	return ret;
54915+}
54916+
54917+static void control_free_clk_config(struct dwc3_hisi *hisi)
54918+{
54919+	unsigned int reg;
54920+
54921+	if (hisi == NULL)
54922+		return;
54923+
54924+	reg = readl(hisi->ctrl_base + GUSB2PHYCFG_OFFSET);
54925+	reg &= ~U2_FREECLK_EXISTS;
54926+	writel(reg, hisi->ctrl_base + GUSB2PHYCFG_OFFSET);
54927+
54928+	reg = readl(hisi->ctrl_base + GCTL_OFFSET);
54929+	reg &= ~SOFITPSYNC;
54930+	writel(reg, hisi->ctrl_base + GCTL_OFFSET);
54931+
54932+	reg = readl(hisi->ctrl_base + GUCTL_OFFSET);
54933+	reg &= ~REFCLKPER_MASK;
54934+	reg |= set_refclkper(REFCLKPER_VAL);
54935+	writel(reg, hisi->ctrl_base + GUCTL_OFFSET);
54936+
54937+	reg = readl(hisi->ctrl_base + GFLADJ_OFFSET);
54938+	reg &= ~PLS1;
54939+	writel(reg, hisi->ctrl_base + GFLADJ_OFFSET);
54940+
54941+	reg = readl(hisi->ctrl_base + GFLADJ_OFFSET);
54942+	reg &= ~DECR_MASK;
54943+	reg |= set_decr(DECR_VAL);
54944+	writel(reg, hisi->ctrl_base + GFLADJ_OFFSET);
54945+
54946+	reg = readl(hisi->ctrl_base + GFLADJ_OFFSET);
54947+	reg |= LPM_SEL;
54948+	writel(reg, hisi->ctrl_base + GFLADJ_OFFSET);
54949+
54950+	reg = readl(hisi->ctrl_base + GFLADJ_OFFSET);
54951+	reg &= ~FLADJ_MASK;
54952+	reg |= set_fladj(FLADJ_VAL);
54953+	writel(reg, hisi->ctrl_base + GFLADJ_OFFSET);
54954+}
54955+
54956+static int dwc3_hisi_iomap(struct device_node *np, struct dwc3_hisi *hisi)
54957+{
54958+	if ((np == NULL) || (hisi == NULL))
54959+		return -EINVAL;
54960+
54961+	hisi->ctrl_base = of_iomap(np, DEV_NODE_FLAG0);
54962+	if (IS_ERR(hisi->ctrl_base))
54963+		return -ENOMEM;
54964+
54965+	hisi->crg_base = of_iomap(np, DEV_NODE_FLAG1);
54966+	if (IS_ERR(hisi->crg_base)) {
54967+		iounmap(hisi->ctrl_base);
54968+		return -ENOMEM;
54969+	}
54970+
54971+	return 0;
54972+}
54973+
54974+static int dwc3_hisi_probe(struct platform_device *pdev)
54975+{
54976+	struct dwc3_hisi *hisi = NULL;
54977+	struct device *dev = &pdev->dev;
54978+	struct device_node *np = dev->of_node;
54979+	int ret, i;
54980+
54981+	hisi = devm_kzalloc(dev, sizeof(*hisi), GFP_KERNEL);
54982+	if (hisi == NULL)
54983+		return -ENOMEM;
54984+
54985+	platform_set_drvdata(pdev, hisi);
54986+	hisi->dev = dev;
54987+
54988+	ret = dwc3_hisi_iomap(np, hisi);
54989+	if (ret) {
54990+		devm_kfree(dev, hisi);
54991+		hisi = NULL;
54992+
54993+		return -ENOMEM;
54994+	}
54995+
54996+	hisi->port_rst = devm_reset_control_get(dev, "vcc_reset");
54997+	if (IS_ERR_OR_NULL(hisi->port_rst)) {
54998+		ret = PTR_ERR(hisi->port_rst);
54999+		goto hidwc3_unmap;
55000+	}
55001+
55002+	ret = set_ctrl_crg_val(np, hisi);
55003+	if (ret)
55004+		goto hidwc3_unmap;
55005+
55006+	reset_control_assert(hisi->port_rst);
55007+
55008+	ret = dwc3_hisi_clk_init(hisi, of_clk_get_parent_count(np));
55009+	if (ret)
55010+		goto hidwc3_unmap;
55011+
55012+	reset_control_deassert(hisi->port_rst);
55013+
55014+	control_free_clk_config(hisi);
55015+
55016+	udelay(U_LEVEL2);
55017+
55018+	ret = of_platform_populate(np, NULL, NULL, dev);
55019+	if (ret) {
55020+		for (i = 0; i < hisi->num_clocks; i++) {
55021+			clk_disable_unprepare(hisi->clks[i]);
55022+			clk_put(hisi->clks[i]);
55023+		}
55024+		goto hidwc3_unmap;
55025+	}
55026+
55027+	return 0;
55028+hidwc3_unmap:
55029+	iounmap(hisi->ctrl_base);
55030+	iounmap(hisi->crg_base);
55031+
55032+	devm_kfree(dev, hisi);
55033+	hisi = NULL;
55034+
55035+	return ret;
55036+}
55037+
55038+static int dwc3_hisi_remove(struct platform_device *pdev)
55039+{
55040+	struct dwc3_hisi *hisi = platform_get_drvdata(pdev);
55041+	struct device *dev = &pdev->dev;
55042+	int i;
55043+
55044+	for (i = 0; i < hisi->num_clocks; i++) {
55045+		clk_disable_unprepare(hisi->clks[i]);
55046+		clk_put(hisi->clks[i]);
55047+	}
55048+
55049+	reset_control_assert(hisi->port_rst);
55050+
55051+	of_platform_depopulate(dev);
55052+
55053+	iounmap(hisi->ctrl_base);
55054+	iounmap(hisi->crg_base);
55055+
55056+	devm_kfree(dev, hisi);
55057+	hisi = NULL;
55058+
55059+	return 0;
55060+}
55061+
55062+static const struct of_device_id hisi_dwc3_match[] = {
55063+	{ .compatible = "hisi,dwusb2" },
55064+	{ .compatible = "hisi,dwusb3" },
55065+	{},
55066+};
55067+MODULE_DEVICE_TABLE(of, hisi_dwc3_match);
55068+
55069+static struct platform_driver dwc3_hisi_driver = {
55070+	.probe = dwc3_hisi_probe,
55071+	.remove = dwc3_hisi_remove,
55072+	.driver = {
55073+		.name = "hisi-dwc3",
55074+		.of_match_table = hisi_dwc3_match,
55075+	},
55076+};
55077+module_platform_driver(dwc3_hisi_driver);
55078+
55079+MODULE_LICENSE("GPL v2");
55080+MODULE_DESCRIPTION("DesignWare USB3 of Hisilicon");
55081+MODULE_AUTHOR("Hisilicon Technologies Co., Ltd..>");
55082diff --git a/drivers/usb/dwc3/dwc3-hisi.h b/drivers/usb/dwc3/dwc3-hisi.h
55083new file mode 100644
55084index 000000000..606cf0507
55085--- /dev/null
55086+++ b/drivers/usb/dwc3/dwc3-hisi.h
55087@@ -0,0 +1,54 @@
55088+/*
55089+ * dwc3-hisi.h
55090+ *
55091+ * Dwc3 private headerfile for Hisilicon.
55092+ *
55093+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2018-2019. All rights reserved.
55094+ *
55095+ * This program is free software; you can redistribute  it and/or modify it
55096+ * under  the terms of  the GNU General Public License as published by the
55097+ * Free Software Foundation;  either version 2 of the  License, or (at your
55098+ * option) any later version.
55099+ *
55100+ * This program is distributed in the hope that it will be useful,
55101+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
55102+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55103+ * GNU General Public License for more details.
55104+ *
55105+ * You should have received a copy of the GNU General Public License
55106+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
55107+ *
55108+ */
55109+
55110+#ifndef USB_INCLUDE_DWC3_HISI_H
55111+#define USB_INCLUDE_DWC3_HISI_H
55112+
55113+struct hi_priv {
55114+	void __iomem *peri_crg;
55115+	void __iomem *sys_ctrl;
55116+	void __iomem *misc_ctrl;
55117+	unsigned int speed_id;
55118+};
55119+
55120+struct dwc3_hisi {
55121+	struct device *dev;
55122+	struct clk **clks;
55123+	int num_clocks;
55124+	void __iomem *ctrl_base;
55125+	void __iomem *crg_base;
55126+	struct reset_control *port_rst;
55127+	u32 crg_offset;
55128+	u32 crg_ctrl_def_mask;
55129+	u32 crg_ctrl_def_val;
55130+};
55131+
55132+extern int usb_get_max_speed(struct device *dev);
55133+extern void hisi_dwc3_exited(void);
55134+
55135+#define DEV_NODE_FLAG0	0
55136+#define DEV_NODE_FLAG1	1
55137+#define DEV_NODE_FLAG2	2
55138+
55139+#define U_LEVEL2	200
55140+
55141+#endif
55142diff --git a/drivers/usb/dwc3/ep0.c b/drivers/usb/dwc3/ep0.c
55143index 3cd294264..edf3f9b59 100644
55144--- a/drivers/usb/dwc3/ep0.c
55145+++ b/drivers/usb/dwc3/ep0.c
55146@@ -281,6 +281,24 @@ void dwc3_ep0_out_start(struct dwc3 *dwc)
55147 	WARN_ON(ret < 0);
55148 }
55149
55150+static u32 dwc3_usbep_to_dwc3ep(struct dwc3 *dwc, u32 num)
55151+{
55152+	u32 res = 0;
55153+	int i;
55154+
55155+	if (!dwc)
55156+		return 0;
55157+
55158+	for (i = 0; i < dwc->num_eps; i++) {
55159+		if (dwc->dwceps_map_to_usbeps[i] == num) {
55160+			res = i;
55161+			break;
55162+		}
55163+	}
55164+
55165+	return res;
55166+}
55167+
55168 static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le)
55169 {
55170 	struct dwc3_ep		*dep;
55171@@ -291,6 +309,9 @@ static struct dwc3_ep *dwc3_wIndex_to_dep(struct dwc3 *dwc, __le16 wIndex_le)
55172 	if ((windex & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
55173 		epnum |= 1;
55174
55175+	if (dwc->eps_new_init)
55176+		epnum = dwc3_usbep_to_dwc3ep(dwc, epnum);
55177+
55178 	dep = dwc->eps[epnum];
55179 	if (dep == NULL)
55180 		return NULL;
55181@@ -385,6 +406,9 @@ static int dwc3_ep0_handle_u1(struct dwc3 *dwc, enum usb_device_state state,
55182 	if (set && dwc->dis_u1_entry_quirk)
55183 		return -EINVAL;
55184
55185+	if (dwc->dis_initiate_u1)
55186+		return -EINVAL;
55187+
55188 	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
55189 	if (set)
55190 		reg |= DWC3_DCTL_INITU1ENA;
55191@@ -409,6 +433,9 @@ static int dwc3_ep0_handle_u2(struct dwc3 *dwc, enum usb_device_state state,
55192 	if (set && dwc->dis_u2_entry_quirk)
55193 		return -EINVAL;
55194
55195+	if (dwc->dis_initiate_u2)
55196+		return -EINVAL;
55197+
55198 	reg = dwc3_readl(dwc->regs, DWC3_DCTL);
55199 	if (set)
55200 		reg |= DWC3_DCTL_INITU2ENA;
55201@@ -638,9 +665,14 @@ static int dwc3_ep0_set_config(struct dwc3 *dwc, struct usb_ctrlrequest *ctrl)
55202 			 * nothing is pending from application.
55203 			 */
55204 			reg = dwc3_readl(dwc->regs, DWC3_DCTL);
55205-			if (!dwc->dis_u1_entry_quirk)
55206+			if (dwc->dis_initiate_u1)
55207+				reg &= (~DWC3_DCTL_ACCEPTU1ENA);
55208+			else
55209 				reg |= DWC3_DCTL_ACCEPTU1ENA;
55210-			if (!dwc->dis_u2_entry_quirk)
55211+
55212+			if (dwc->dis_initiate_u2)
55213+				reg &= (~DWC3_DCTL_ACCEPTU2ENA);
55214+			else
55215 				reg |= DWC3_DCTL_ACCEPTU2ENA;
55216 			dwc3_writel(dwc->regs, DWC3_DCTL, reg);
55217 		}
55218diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c
55219old mode 100644
55220new mode 100755
55221index b75fe5680..bec11c742
55222--- a/drivers/usb/dwc3/gadget.c
55223+++ b/drivers/usb/dwc3/gadget.c
55224@@ -27,6 +27,8 @@
55225 #include "gadget.h"
55226 #include "io.h"
55227
55228+static bool __dwc3_gadget_target_frame_elapsed(struct dwc3_ep *dep);
55229+
55230 #define DWC3_ALIGN_FRAME(d, n)	(((d)->frame_number + ((d)->interval * (n))) \
55231 					& ~((d)->interval - 1))
55232
55233@@ -147,7 +149,7 @@ int dwc3_gadget_set_link_state(struct dwc3 *dwc, enum dwc3_link_state state)
55234  * if it is point to the link TRB, wrap around to the beginning. The
55235  * link TRB is always at the last TRB entry.
55236  */
55237-static void dwc3_ep_inc_trb(u8 *index)
55238+static void dwc3_ep_inc_trb(u32 *index)
55239 {
55240 	(*index)++;
55241 	if (*index == (DWC3_TRB_NUM - 1))
55242@@ -594,7 +596,11 @@ static int dwc3_gadget_set_ep_config(struct dwc3_ep *dep, unsigned int action)
55243 	 * so on. We consider the direction bit as part of the physical
55244 	 * endpoint number. So USB endpoint 0x81 is 0x03.
55245 	 */
55246-	params.param1 |= DWC3_DEPCFG_EP_NUMBER(dep->number);
55247+	if (dwc->eps_new_init)
55248+		params.param1 |=
55249+			DWC3_DEPCFG_EP_NUMBER(dwc->dwceps_map_to_usbeps[dep->number]);
55250+	else
55251+		params.param1 |= DWC3_DEPCFG_EP_NUMBER(dep->number);
55252
55253 	/*
55254 	 * We must use the lower 16 TX FIFOs even though
55255@@ -665,7 +671,12 @@ static int __dwc3_gadget_ep_enable(struct dwc3_ep *dep, unsigned int action)
55256 		dep->flags |= DWC3_EP_ENABLED;
55257
55258 		reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
55259-		reg |= DWC3_DALEPENA_EP(dep->number);
55260+
55261+		if (dwc->eps_new_init)
55262+			reg |= DWC3_DALEPENA_EP(dwc->dwceps_map_to_usbeps[dep->number]);
55263+		else
55264+			reg |= DWC3_DALEPENA_EP(dep->number);
55265+
55266 		dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
55267
55268 		if (usb_endpoint_xfer_control(desc))
55269@@ -789,7 +800,12 @@ static int __dwc3_gadget_ep_disable(struct dwc3_ep *dep)
55270 		__dwc3_gadget_ep_set_halt(dep, 0, false);
55271
55272 	reg = dwc3_readl(dwc->regs, DWC3_DALEPENA);
55273-	reg &= ~DWC3_DALEPENA_EP(dep->number);
55274+
55275+	if (dwc->eps_new_init)
55276+		reg &= ~DWC3_DALEPENA_EP(dwc->dwceps_map_to_usbeps[dep->number]);
55277+	else
55278+		reg &= ~DWC3_DALEPENA_EP(dep->number);
55279+
55280 	dwc3_writel(dwc->regs, DWC3_DALEPENA, reg);
55281
55282 	/* Clear out the ep descriptors for non-ep0 */
55283@@ -920,9 +936,9 @@ static void dwc3_gadget_ep_free_request(struct usb_ep *ep,
55284  * index is 0, we will wrap backwards, skip the link TRB, and return
55285  * the one just before that.
55286  */
55287-static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index)
55288+static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u32 index)
55289 {
55290-	u8 tmp = index;
55291+	u32 tmp = index;
55292
55293 	if (!tmp)
55294 		tmp = DWC3_TRB_NUM - 1;
55295@@ -932,7 +948,7 @@ static struct dwc3_trb *dwc3_ep_prev_trb(struct dwc3_ep *dep, u8 index)
55296
55297 static u32 dwc3_calc_trbs_left(struct dwc3_ep *dep)
55298 {
55299-	u8			trbs_left;
55300+	u32			trbs_left;
55301
55302 	/*
55303 	 * If the enqueue & dequeue are equal then the TRB ring is either full
55304@@ -968,6 +984,7 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
55305 	struct dwc3		*dwc = dep->dwc;
55306 	struct usb_gadget	*gadget = dwc->gadget;
55307 	enum usb_device_speed	speed = gadget->speed;
55308+	unsigned int chain_skip = 0;
55309
55310 	trb->size = DWC3_TRB_SIZE_LENGTH(length);
55311 	trb->bpl = lower_32_bits(dma);
55312@@ -1016,8 +1033,19 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
55313 					mult--;
55314
55315 				trb->size |= DWC3_TRB_SIZE_PCM1(mult);
55316+
55317+				/*
55318+				 * If there are three transactions per mframe,
55319+				 * and each transcation length = 1024B, no any
55320+				 * chain trb needed, so skip it.
55321+				 */
55322+				if (req->request.length == (3 * maxp))
55323+					chain_skip = 1;
55324 			}
55325+			if (speed == USB_SPEED_SUPER)
55326+				chain_skip = 1;
55327 		} else {
55328+			chain_skip = 1;
55329 			trb->ctrl = DWC3_TRBCTL_ISOCHRONOUS;
55330 		}
55331
55332@@ -1053,7 +1081,7 @@ static void __dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_trb *trb,
55333 	if ((!no_interrupt && !chain) || must_interrupt)
55334 		trb->ctrl |= DWC3_TRB_CTRL_IOC;
55335
55336-	if (chain)
55337+	if ((!chain_skip) && chain)
55338 		trb->ctrl |= DWC3_TRB_CTRL_CHN;
55339 	else if (dep->stream_capable && is_last)
55340 		trb->ctrl |= DWC3_TRB_CTRL_LST;
55341@@ -1167,6 +1195,9 @@ static int dwc3_prepare_last_sg(struct dwc3_ep *dep,
55342 static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
55343 		struct dwc3_request *req)
55344 {
55345+	struct dwc3             *dwc = dep->dwc;
55346+	struct usb_gadget       *gadget = dwc->gadget;
55347+	enum usb_device_speed   speed = gadget->speed;
55348 	struct scatterlist *sg = req->start_sg;
55349 	struct scatterlist *s;
55350 	int		i;
55351@@ -1220,9 +1251,13 @@ static int dwc3_prepare_trbs_sg(struct dwc3_ep *dep,
55352 					num_trbs_left <= 2 &&
55353 					sg_dma_len(sg_next(s)) >= length))
55354 				must_interrupt = true;
55355-
55356-			dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false,
55357-					must_interrupt);
55358+			if ((speed == USB_SPEED_HIGH) &&
55359+					usb_endpoint_xfer_isoc(dep->endpoint.desc))
55360+				dwc3_prepare_one_trb(dep, req, trb_length, 1, 0, false,
55361+	                    must_interrupt);
55362+			else
55363+				dwc3_prepare_one_trb(dep, req, trb_length, 1, i, false,
55364+						must_interrupt);
55365 		}
55366
55367 		/*
55368@@ -1382,6 +1417,13 @@ static int __dwc3_gadget_kick_transfer(struct dwc3_ep *dep)
55369 	if (starting) {
55370 		params.param0 = upper_32_bits(req->trb_dma);
55371 		params.param1 = lower_32_bits(req->trb_dma);
55372+		if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
55373+			while (__dwc3_gadget_target_frame_elapsed(dep))
55374+				dep->frame_number = DWC3_ALIGN_FRAME(dep, 1);
55375+
55376+			dep->frame_number = DWC3_ALIGN_FRAME(dep, 1);
55377+		}
55378+
55379 		cmd = DWC3_DEPCMD_STARTTRANSFER;
55380
55381 		if (dep->stream_capable)
55382@@ -1427,6 +1469,16 @@ static int __dwc3_gadget_get_frame(struct dwc3 *dwc)
55383 	return DWC3_DSTS_SOFFN(reg);
55384 }
55385
55386+static bool __dwc3_gadget_target_frame_elapsed(struct dwc3_ep *dep) {
55387+	u16 cframe =  __dwc3_gadget_get_frame(dep->dwc);
55388+	u16 eframe = dep->frame_number & DWC3_EVENT_PRAM_SOFFN_MASK;
55389+	if (eframe == cframe)
55390+		return true;
55391+
55392+	return (((eframe - cframe) & DWC3_EVENT_PRAM_SOFFN_MASK)
55393+		> DWC3_EVENT_PRAM_MAX_SOFFN / 2);
55394+}
55395+
55396 /**
55397  * dwc3_gadget_start_isoc_quirk - workaround invalid frame number
55398  * @dep: isoc endpoint
55399@@ -1584,6 +1636,9 @@ static int __dwc3_gadget_start_isoc(struct dwc3_ep *dep)
55400 	}
55401
55402 	for (i = 0; i < DWC3_ISOC_MAX_RETRIES; i++) {
55403+		while (__dwc3_gadget_target_frame_elapsed(dep))
55404+			dep->frame_number = DWC3_ALIGN_FRAME(dep, i + 1);
55405+
55406 		dep->frame_number = DWC3_ALIGN_FRAME(dep, i + 1);
55407
55408 		ret = __dwc3_gadget_kick_transfer(dep);
55409@@ -1668,8 +1723,10 @@ static int __dwc3_gadget_ep_queue(struct dwc3_ep *dep, struct dwc3_request *req)
55410 	 */
55411 	if (usb_endpoint_xfer_isoc(dep->endpoint.desc)) {
55412 		if (!(dep->flags & DWC3_EP_PENDING_REQUEST) &&
55413-				!(dep->flags & DWC3_EP_TRANSFER_STARTED))
55414+				list_empty(&dep->started_list)) {
55415+			dwc3_stop_active_transfer(dep, true, true);
55416 			return 0;
55417+		}
55418
55419 		if ((dep->flags & DWC3_EP_PENDING_REQUEST)) {
55420 			if (!(dep->flags & DWC3_EP_TRANSFER_STARTED))
55421@@ -1756,6 +1813,9 @@ static int dwc3_gadget_ep_dequeue(struct usb_ep *ep,
55422
55423 	spin_lock_irqsave(&dwc->lock, flags);
55424
55425+	if (list_empty(&dep->pending_list) && list_empty(&dep->started_list) )
55426+		goto out;
55427+
55428 	list_for_each_entry(r, &dep->cancelled_list, list) {
55429 		if (r == req)
55430 			goto out;
55431@@ -2679,12 +2739,77 @@ static int dwc3_gadget_init_endpoint(struct dwc3 *dwc, u8 epnum)
55432 	return 0;
55433 }
55434
55435+static int dwc3_gadget_init_hw_all_endpoints(struct dwc3 *dwc)
55436+{
55437+	struct dwc3_ep			*dep = NULL;
55438+	struct dwc3_hwparams    *parms = &dwc->hwparams;
55439+	u32 direction = dwc->eps_directions;
55440+	u8 num_eps = DWC3_NUM_EPS(parms);
55441+	u8 num_in_eps = 0;
55442+	u8 num_out_eps = 0;
55443+	u8 epnum = 0;
55444+	u8 i;
55445+	int ret;
55446+
55447+	if (!direction)
55448+		direction = DWC3_EPS_DEFAULT_DIRECTIONS;
55449+
55450+	for (i = 0; i < num_eps; i++) {
55451+		if (direction & 0x1)
55452+			epnum = (num_in_eps++ << 1) + 1;
55453+		else
55454+			epnum = (num_out_eps++ << 1);
55455+
55456+		dep = kzalloc(sizeof(*dep), GFP_KERNEL);
55457+		if (!dep)
55458+			return -ENOMEM;
55459+
55460+		dep->dwc = dwc;
55461+		dep->number = i;
55462+		dep->direction = !!(direction & 0x1);
55463+		dep->regs = dwc->regs + DWC3_DEP_BASE(i);
55464+		dwc->eps[i] = dep;
55465+
55466+		snprintf(dep->name, sizeof(dep->name), "ep%d%s", epnum >> 1,
55467+				(epnum & 1) ? "in" : "out");
55468+
55469+		dep->endpoint.name = dep->name;
55470+
55471+		if (epnum == 0 || epnum == 1) {
55472+			dep->endpoint.desc = &dwc3_gadget_ep0_desc;
55473+			dep->endpoint.comp_desc = NULL;
55474+			ret = dwc3_gadget_init_control_endpoint(dep);
55475+		} else if (dep->direction) {
55476+			ret = dwc3_gadget_init_in_endpoint(dep);
55477+		} else {
55478+			ret = dwc3_gadget_init_out_endpoint(dep);
55479+		}
55480+
55481+		if (ret)
55482+		return ret;
55483+
55484+		dep->endpoint.caps.dir_in = !!(direction & 0x1);
55485+		dep->endpoint.caps.dir_out = !(direction & 0x1);
55486+		direction = (direction >> 1);
55487+
55488+		INIT_LIST_HEAD(&dep->pending_list);
55489+		INIT_LIST_HEAD(&dep->started_list);
55490+		INIT_LIST_HEAD(&dep->cancelled_list);
55491+	}
55492+
55493+	return 0;
55494+}
55495+
55496 static int dwc3_gadget_init_endpoints(struct dwc3 *dwc, u8 total)
55497 {
55498 	u8				epnum;
55499
55500 	INIT_LIST_HEAD(&dwc->gadget->ep_list);
55501
55502+	if (dwc->eps_new_init) {
55503+		return dwc3_gadget_init_hw_all_endpoints(dwc);
55504+	}
55505+
55506 	for (epnum = 0; epnum < total; epnum++) {
55507 		int			ret;
55508
55509@@ -3640,6 +3765,7 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc,
55510 		break;
55511 	case DWC3_DEVICE_EVENT_CONNECT_DONE:
55512 		dwc3_gadget_conndone_interrupt(dwc);
55513+		usb_notify_online_status(true);
55514 		break;
55515 	case DWC3_DEVICE_EVENT_WAKEUP:
55516 		dwc3_gadget_wakeup_interrupt(dwc);
55517@@ -3661,9 +3787,11 @@ static void dwc3_gadget_interrupt(struct dwc3 *dwc,
55518 			 * Ignore suspend event until the gadget enters into
55519 			 * USB_STATE_CONFIGURED state.
55520 			 */
55521-			if (dwc->gadget->state >= USB_STATE_CONFIGURED)
55522+			if (dwc->gadget->state >= USB_STATE_CONFIGURED) {
55523 				dwc3_gadget_suspend_interrupt(dwc,
55524 						event->event_info);
55525+				usb_notify_online_status(false);
55526+			}
55527 		}
55528 		break;
55529 	case DWC3_DEVICE_EVENT_SOF:
55530@@ -3892,6 +4020,7 @@ int dwc3_gadget_init(struct dwc3 *dwc)
55531 		goto err3;
55532 	}
55533
55534+	dwc3_proc_init(dwc);
55535
55536 	usb_initialize_gadget(dwc->dev, dwc->gadget, dwc_gadget_release);
55537 	dev				= &dwc->gadget->dev;
55538diff --git a/drivers/usb/dwc3/proc.c b/drivers/usb/dwc3/proc.c
55539new file mode 100755
55540index 000000000..7425e0eb9
55541--- /dev/null
55542+++ b/drivers/usb/dwc3/proc.c
55543@@ -0,0 +1,138 @@
55544+/*
55545+ * proc.c
55546+ *
55547+ * Dwc3 private driver for Hisilicon.
55548+ *
55549+ * Copyright (C) Hisilicon Technologies Co., Ltd. 2018-2019. All rights reserved.
55550+ *
55551+ * This program is free software; you can redistribute  it and/or modify it
55552+ * under  the terms of  the GNU General Public License as published by the
55553+ * Free Software Foundation;  either version 2 of the  License, or (at your
55554+ * option) any later version.
55555+ *
55556+ * This program is distributed in the hope that it will be useful,
55557+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
55558+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
55559+ * GNU General Public License for more details.
55560+ *
55561+ * You should have received a copy of the GNU General Public License
55562+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
55563+ *
55564+ */
55565+
55566+#include <linux/proc_fs.h>
55567+#include <linux/seq_file.h>
55568+#include <linux/device.h>
55569+#include <linux/io.h>
55570+#include <linux/platform_device.h>
55571+
55572+#include "core.h"
55573+
55574+#define DWC3_PROC_ROOT "dwc3"
55575+#define DWC3_PROC_CONNECTED_STATUS "csts"
55576+
55577+static struct proc_dir_entry *proc_dwc3_dir = NULL;
55578+static int proc_dwc3_dir_cnt = 0;
55579+
55580+static void dwc3_stats_seq_printout(struct seq_file *s)
55581+{
55582+	struct dwc3 *dwc = s->private;
55583+
55584+	switch (dwc->udc_connect_status) {
55585+	case UDC_CONNECT_HOST:
55586+		seq_puts(s, "cnt2host\n");
55587+		break;
55588+	case UDC_CONNECT_CHARGER:
55589+		seq_puts(s, "cnt2charger\n");
55590+		break;
55591+	default:
55592+		seq_puts(s, "disconnected\n");
55593+		break;
55594+	}
55595+}
55596+
55597+/* define parameters where showed in proc file */
55598+static int dwc3_stats_seq_show(struct seq_file *s, void *v)
55599+{
55600+	if (s == NULL)
55601+		return -EINVAL;
55602+
55603+	dwc3_stats_seq_printout(s);
55604+	return 0;
55605+}
55606+
55607+/* proc file open */
55608+static int dwc3_stats_proc_open(struct inode *inode, struct file *file)
55609+{
55610+	if ((inode == NULL) || (file == NULL))
55611+		return -EINVAL;
55612+
55613+	return single_open(file, dwc3_stats_seq_show, PDE_DATA(inode));
55614+};
55615+
55616+/* proc file operation */
55617+static const struct proc_ops dwc3_stats_proc_ops = {
55618+	.proc_open = dwc3_stats_proc_open,
55619+	.proc_read = seq_read,
55620+	.proc_release = single_release,
55621+};
55622+
55623+int dwc3_proc_init(struct dwc3 *dwc)
55624+{
55625+	struct proc_dir_entry *proc_entry = NULL;
55626+
55627+	if (dwc == NULL)
55628+		return -EINVAL;
55629+
55630+	if (proc_dwc3_dir == NULL) {
55631+		proc_entry = proc_mkdir(DWC3_PROC_ROOT, NULL);
55632+		if (proc_entry == NULL) {
55633+			pr_err("%s: failed to create proc file %s\n",
55634+			       __func__, DWC3_PROC_ROOT);
55635+			return 1;
55636+		}
55637+		proc_dwc3_dir = proc_entry;
55638+	}
55639+	proc_dwc3_dir_cnt++;
55640+
55641+	proc_entry = proc_mkdir(to_platform_device(dwc->dev)->name, proc_dwc3_dir);
55642+	if (proc_entry == NULL) {
55643+		pr_err("%s: failed to create proc file %s\n",
55644+		       __func__, to_platform_device(dwc->dev)->name);
55645+		return -1;
55646+	}
55647+	dwc->parent_entry = proc_entry;
55648+
55649+	proc_entry = proc_create_data(DWC3_PROC_CONNECTED_STATUS,
55650+				      0, dwc->parent_entry,
55651+				      &dwc3_stats_proc_ops, dwc);
55652+	if (proc_entry == NULL) {
55653+		pr_err("%s: failed to create proc file %s\n",
55654+		       __func__, DWC3_PROC_CONNECTED_STATUS);
55655+		return -1;
55656+	}
55657+	dwc->csts_entry = proc_entry;
55658+
55659+	/*
55660+	 * add here if more proc information need.
55661+	 */
55662+	return 0;
55663+}
55664+
55665+int dwc3_proc_shutdown(struct dwc3 *dwc)
55666+{
55667+	if (proc_dwc3_dir != NULL) {
55668+		remove_proc_entry(DWC3_PROC_CONNECTED_STATUS, dwc->parent_entry);
55669+		remove_proc_entry(to_platform_device(dwc->dev)->name, proc_dwc3_dir);
55670+	}
55671+
55672+	if (proc_dwc3_dir_cnt)
55673+		proc_dwc3_dir_cnt--;
55674+
55675+	if (proc_dwc3_dir_cnt == 0) {
55676+		remove_proc_entry(DWC3_PROC_ROOT, NULL);
55677+		proc_dwc3_dir = NULL;
55678+	}
55679+
55680+	return 0;
55681+}
55682diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
55683index 8bec0cbf8..db79eab52 100644
55684--- a/drivers/usb/gadget/composite.c
55685+++ b/drivers/usb/gadget/composite.c
55686@@ -705,8 +705,7 @@ static int bos_desc(struct usb_composite_dev *cdev)
55687 	usb_ext->bLength = USB_DT_USB_EXT_CAP_SIZE;
55688 	usb_ext->bDescriptorType = USB_DT_DEVICE_CAPABILITY;
55689 	usb_ext->bDevCapabilityType = USB_CAP_TYPE_EXT;
55690-	usb_ext->bmAttributes = cpu_to_le32(USB_LPM_SUPPORT |
55691-					    USB_BESL_SUPPORT | besl);
55692+	usb_ext->bmAttributes = cpu_to_le32(0x0);
55693
55694 	/*
55695 	 * The Superspeed USB Capability descriptor shall be implemented by all
55696diff --git a/drivers/usb/gadget/epautoconf.c b/drivers/usb/gadget/epautoconf.c
55697old mode 100644
55698new mode 100755
55699index 1eb4fa2e6..02be1969b
55700--- a/drivers/usb/gadget/epautoconf.c
55701+++ b/drivers/usb/gadget/epautoconf.c
55702@@ -67,6 +67,9 @@ struct usb_ep *usb_ep_autoconfig_ss(
55703 )
55704 {
55705 	struct usb_ep	*ep;
55706+	u8 type;
55707+
55708+	type = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
55709
55710 	if (gadget->ops->match_ep) {
55711 		ep = gadget->ops->match_ep(gadget, desc, ep_comp);
55712@@ -75,9 +78,16 @@ struct usb_ep *usb_ep_autoconfig_ss(
55713 	}
55714
55715 	/* Second, look at endpoints until an unclaimed one looks usable */
55716-	list_for_each_entry (ep, &gadget->ep_list, ep_list) {
55717-		if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp))
55718-			goto found_ep;
55719+	if (type == USB_ENDPOINT_XFER_INT) {
55720+		list_for_each_entry_reverse(ep, &gadget->ep_list, ep_list) {
55721+			if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp))
55722+				goto found_ep;
55723+		}
55724+	} else {
55725+		list_for_each_entry(ep, &gadget->ep_list, ep_list) {
55726+			if (usb_gadget_ep_match_desc(gadget, ep, desc, ep_comp))
55727+				goto found_ep;
55728+		}
55729 	}
55730
55731 	/* Fail */
55732diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
55733index 950c9435b..a92694ff6 100644
55734--- a/drivers/usb/gadget/function/f_mass_storage.c
55735+++ b/drivers/usb/gadget/function/f_mass_storage.c
55736@@ -307,6 +307,7 @@ struct fsg_common {
55737 	unsigned int		bad_lun_okay:1;
55738 	unsigned int		running:1;
55739 	unsigned int		sysfs:1;
55740+	unsigned int		actived:1;
55741
55742 	struct completion	thread_notifier;
55743 	struct task_struct	*thread_task;
55744@@ -1338,7 +1339,7 @@ static int do_start_stop(struct fsg_common *common)
55745
55746 	up_read(&common->filesem);
55747 	down_write(&common->filesem);
55748-	fsg_lun_close(curlun);
55749+	common->actived = 0;
55750 	up_write(&common->filesem);
55751 	down_read(&common->filesem);
55752
55753@@ -1775,7 +1776,7 @@ static int check_command(struct fsg_common *common, int cmnd_size,
55754
55755 	/* If the medium isn't mounted and the command needs to access
55756 	 * it, return an error. */
55757-	if (curlun && !fsg_lun_is_open(curlun) && needs_medium) {
55758+	if (curlun && !common->actived && needs_medium) {
55759 		curlun->sense_data = SS_MEDIUM_NOT_PRESENT;
55760 		return -EINVAL;
55761 	}
55762@@ -2234,6 +2235,7 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg)
55763 	}
55764
55765 	common->running = 0;
55766+	common->actived = 0;
55767 	if (!new_fsg || rc)
55768 		return rc;
55769
55770@@ -2277,7 +2279,7 @@ static int do_set_interface(struct fsg_common *common, struct fsg_dev *new_fsg)
55771 		bh->inreq->complete = bulk_in_complete;
55772 		bh->outreq->complete = bulk_out_complete;
55773 	}
55774-
55775+	common->actived = 1;
55776 	common->running = 1;
55777 	for (i = 0; i < ARRAY_SIZE(common->luns); ++i)
55778 		if (common->luns[i])
55779diff --git a/drivers/usb/gadget/function/f_uac1.c b/drivers/usb/gadget/function/f_uac1.c
55780index e65f474ad..5bb7ce3eb 100644
55781--- a/drivers/usb/gadget/function/f_uac1.c
55782+++ b/drivers/usb/gadget/function/f_uac1.c
55783@@ -56,6 +56,16 @@ static inline struct f_uac1_opts *g_audio_to_uac1_opts(struct g_audio *audio)
55784 /* Number of streaming interfaces */
55785 #define F_AUDIO_NUM_INTERFACES		2
55786
55787+static struct usb_interface_assoc_descriptor uac_iad = {
55788+	.bLength = sizeof(uac_iad),
55789+	.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
55790+	.bFirstInterface = 0,
55791+	.bInterfaceCount = 3,
55792+	.bFunctionClass = USB_CLASS_AUDIO,
55793+	.bFunctionSubClass = 0,
55794+	.bFunctionProtocol = UAC_VERSION_1,
55795+};
55796+
55797 /* B.3.1  Standard AC Interface Descriptor */
55798 static struct usb_interface_descriptor ac_interface_desc = {
55799 	.bLength =		USB_DT_INTERFACE_SIZE,
55800@@ -254,7 +264,46 @@ static struct uac_iso_endpoint_descriptor as_iso_in_desc = {
55801 	.wLockDelay =		0,
55802 };
55803
55804+static struct usb_ss_ep_comp_descriptor as_ss_ep_comp = {
55805+	.bLength        = sizeof(as_ss_ep_comp),
55806+	.bDescriptorType    = USB_DT_SS_ENDPOINT_COMP,
55807+	.bMaxBurst =		0,
55808+	.bmAttributes =		0,
55809+	.wBytesPerInterval = cpu_to_le16(UAC1_OUT_EP_MAX_PACKET_SIZE),
55810+};
55811+
55812 static struct usb_descriptor_header *f_audio_desc[] = {
55813+	(struct usb_descriptor_header *)&uac_iad,
55814+	(struct usb_descriptor_header *)&ac_interface_desc,
55815+	(struct usb_descriptor_header *)&ac_header_desc,
55816+
55817+	(struct usb_descriptor_header *)&usb_out_it_desc,
55818+	(struct usb_descriptor_header *)&io_out_ot_desc,
55819+	(struct usb_descriptor_header *)&io_in_it_desc,
55820+	(struct usb_descriptor_header *)&usb_in_ot_desc,
55821+
55822+	(struct usb_descriptor_header *)&as_out_interface_alt_0_desc,
55823+	(struct usb_descriptor_header *)&as_out_interface_alt_1_desc,
55824+	(struct usb_descriptor_header *)&as_out_header_desc,
55825+
55826+	(struct usb_descriptor_header *)&as_out_type_i_desc,
55827+
55828+	(struct usb_descriptor_header *)&as_out_ep_desc,
55829+	(struct usb_descriptor_header *)&as_iso_out_desc,
55830+
55831+	(struct usb_descriptor_header *)&as_in_interface_alt_0_desc,
55832+	(struct usb_descriptor_header *)&as_in_interface_alt_1_desc,
55833+	(struct usb_descriptor_header *)&as_in_header_desc,
55834+
55835+	(struct usb_descriptor_header *)&as_in_type_i_desc,
55836+
55837+	(struct usb_descriptor_header *)&as_in_ep_desc,
55838+	(struct usb_descriptor_header *)&as_iso_in_desc,
55839+	NULL,
55840+};
55841+
55842+static struct usb_descriptor_header *f_audio_ss_desc[] = {
55843+	(struct usb_descriptor_header *)&uac_iad,
55844 	(struct usb_descriptor_header *)&ac_interface_desc,
55845 	(struct usb_descriptor_header *)&ac_header_desc,
55846
55847@@ -270,6 +319,7 @@ static struct usb_descriptor_header *f_audio_desc[] = {
55848 	(struct usb_descriptor_header *)&as_out_type_i_desc,
55849
55850 	(struct usb_descriptor_header *)&as_out_ep_desc,
55851+	(struct usb_descriptor_header *)&as_ss_ep_comp,
55852 	(struct usb_descriptor_header *)&as_iso_out_desc,
55853
55854 	(struct usb_descriptor_header *)&as_in_interface_alt_0_desc,
55855@@ -279,6 +329,7 @@ static struct usb_descriptor_header *f_audio_desc[] = {
55856 	(struct usb_descriptor_header *)&as_in_type_i_desc,
55857
55858 	(struct usb_descriptor_header *)&as_in_ep_desc,
55859+	(struct usb_descriptor_header *)&as_ss_ep_comp,
55860 	(struct usb_descriptor_header *)&as_iso_in_desc,
55861 	NULL,
55862 };
55863@@ -567,6 +618,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
55864 	us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1));
55865 	if (IS_ERR(us))
55866 		return PTR_ERR(us);
55867+	uac_iad.iFunction = us[STR_AC_IF].id;
55868 	ac_interface_desc.iInterface = us[STR_AC_IF].id;
55869 	usb_out_it_desc.iTerminal = us[STR_USB_OUT_IT].id;
55870 	usb_out_it_desc.iChannelNames = us[STR_USB_OUT_IT_CH_NAMES].id;
55871@@ -603,6 +655,7 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
55872 	status = usb_interface_id(c, f);
55873 	if (status < 0)
55874 		goto fail;
55875+	uac_iad.bFirstInterface = status;
55876 	ac_interface_desc.bInterfaceNumber = status;
55877 	uac1->ac_intf = status;
55878 	uac1->ac_alt = 0;
55879@@ -643,8 +696,8 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
55880 	audio->in_ep->desc = &as_in_ep_desc;
55881
55882 	/* copy descriptors, and track endpoint copies */
55883-	status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc, NULL,
55884-					NULL);
55885+	status = usb_assign_descriptors(f, f_audio_desc, f_audio_desc,
55886+				f_audio_ss_desc, NULL);
55887 	if (status)
55888 		goto fail;
55889
55890diff --git a/drivers/usb/gadget/function/f_uvc.c b/drivers/usb/gadget/function/f_uvc.c
55891index f48a00e49..b6b9a69c2 100644
55892--- a/drivers/usb/gadget/function/f_uvc.c
55893+++ b/drivers/usb/gadget/function/f_uvc.c
55894@@ -642,7 +642,7 @@ uvc_function_bind(struct usb_configuration *c, struct usb_function *f)
55895
55896 	uvc_ss_streaming_ep.wMaxPacketSize = cpu_to_le16(max_packet_size);
55897 	uvc_ss_streaming_ep.bInterval = opts->streaming_interval;
55898-	uvc_ss_streaming_comp.bmAttributes = max_packet_mult - 1;
55899+	uvc_ss_streaming_comp.bmAttributes = 1;
55900 	uvc_ss_streaming_comp.bMaxBurst = opts->streaming_maxburst;
55901 	uvc_ss_streaming_comp.wBytesPerInterval =
55902 		cpu_to_le16(max_packet_size * max_packet_mult *
55903@@ -789,6 +789,11 @@ static struct usb_function_instance *uvc_alloc_inst(void)
55904 	struct uvc_descriptor_header **ctl_cls;
55905 	int ret;
55906
55907+	struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) *ed;
55908+	/* GUID of the UVC H.264 extension unit */
55909+    static char extension_guid[] = {0x41, 0x76, 0x9E, 0xA2, 0x04, 0xDE, 0xE3, 0x47,
55910+		0x8B, 0x2B, 0xF4, 0x34, 0x1A, 0xFF, 0x00, 0x3B};
55911+
55912 	opts = kzalloc(sizeof(*opts), GFP_KERNEL);
55913 	if (!opts)
55914 		return ERR_PTR(-ENOMEM);
55915@@ -824,6 +829,20 @@ static struct usb_function_instance *uvc_alloc_inst(void)
55916 	pd->iProcessing			= 0;
55917 	pd->bmVideoStandards		= 0;
55918
55919+	ed = &opts->uvc_extension;
55920+	ed->bLength			= UVC_DT_EXTENSION_UNIT_SIZE(1, 2);
55921+	ed->bDescriptorType		= USB_DT_CS_INTERFACE;
55922+	ed->bDescriptorSubType		= UVC_VC_EXTENSION_UNIT;
55923+	ed->bUnitID			= 10;
55924+	memcpy(ed->guidExtensionCode, extension_guid, sizeof(extension_guid));
55925+	ed->bNrInPins			= 1;
55926+	ed->baSourceID[0]      	= 2;
55927+	ed->bNumControls		= 15;
55928+	ed->bControlSize		= 2;
55929+	ed->bmControls[0]		= 1;
55930+	ed->bmControls[1]		= 0;
55931+	ed->iExtension			= 0;
55932+
55933 	od = &opts->uvc_output_terminal;
55934 	od->bLength			= UVC_DT_OUTPUT_TERMINAL_SIZE;
55935 	od->bDescriptorType		= USB_DT_CS_INTERFACE;
55936@@ -847,8 +866,9 @@ static struct usb_function_instance *uvc_alloc_inst(void)
55937 	ctl_cls[0] = NULL;	/* assigned elsewhere by configfs */
55938 	ctl_cls[1] = (struct uvc_descriptor_header *)cd;
55939 	ctl_cls[2] = (struct uvc_descriptor_header *)pd;
55940-	ctl_cls[3] = (struct uvc_descriptor_header *)od;
55941-	ctl_cls[4] = NULL;	/* NULL-terminate */
55942+	ctl_cls[3] = (struct uvc_descriptor_header *)ed;
55943+	ctl_cls[4] = (struct uvc_descriptor_header *)od;
55944+	ctl_cls[5] = NULL;	/* NULL-terminate */
55945 	opts->fs_control =
55946 		(const struct uvc_descriptor_header * const *)ctl_cls;
55947
55948@@ -863,7 +883,8 @@ static struct usb_function_instance *uvc_alloc_inst(void)
55949 		(const struct uvc_descriptor_header * const *)ctl_cls;
55950
55951 	opts->streaming_interval = 1;
55952-	opts->streaming_maxpacket = 1024;
55953+	opts->streaming_maxpacket = 3072;
55954+	opts->streaming_maxburst = 15;
55955
55956 	ret = uvcg_attach_configfs(opts);
55957 	if (ret < 0) {
55958diff --git a/drivers/usb/gadget/function/u_uvc.h b/drivers/usb/gadget/function/u_uvc.h
55959index 9a01a7d4f..392ae14dc 100644
55960--- a/drivers/usb/gadget/function/u_uvc.h
55961+++ b/drivers/usb/gadget/function/u_uvc.h
55962@@ -52,6 +52,7 @@ struct f_uvc_opts {
55963 	struct uvc_processing_unit_descriptor		uvc_processing;
55964 	struct uvc_output_terminal_descriptor		uvc_output_terminal;
55965 	struct uvc_color_matching_descriptor		uvc_color_matching;
55966+	struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) 	uvc_extension;
55967
55968 	/*
55969 	 * Control descriptors pointers arrays for full-/high-speed and
55970@@ -60,8 +61,8 @@ struct f_uvc_opts {
55971 	 * descriptors. Used by configfs only, must not be touched by legacy
55972 	 * gadgets.
55973 	 */
55974-	struct uvc_descriptor_header			*uvc_fs_control_cls[5];
55975-	struct uvc_descriptor_header			*uvc_ss_control_cls[5];
55976+	struct uvc_descriptor_header			*uvc_fs_control_cls[6];
55977+	struct uvc_descriptor_header			*uvc_ss_control_cls[6];
55978
55979 	/*
55980 	 * Streaming descriptors for full-speed, high-speed and super-speed.
55981diff --git a/drivers/usb/gadget/function/uvc.h b/drivers/usb/gadget/function/uvc.h
55982index 23ee25383..f2936f637 100644
55983--- a/drivers/usb/gadget/function/uvc.h
55984+++ b/drivers/usb/gadget/function/uvc.h
55985@@ -64,8 +64,11 @@ extern unsigned int uvc_gadget_trace_param;
55986 /* ------------------------------------------------------------------------
55987  * Driver specific constants
55988  */
55989-
55990-#define UVC_NUM_REQUESTS			4
55991+#ifdef UVC_SG_REQ
55992+#define UVC_NUM_REQUESTS	1
55993+#else
55994+#define UVC_NUM_REQUESTS	32
55995+#endif
55996 #define UVC_MAX_REQUEST_SIZE			64
55997 #define UVC_MAX_EVENTS				4
55998
55999@@ -87,6 +90,9 @@ struct uvc_video {
56000 	unsigned int imagesize;
56001 	struct mutex mutex;	/* protects frame parameters */
56002
56003+	unsigned int num_sgs; /* record base */
56004+	__u8 *sg_buf;
56005+
56006 	/* Requests */
56007 	unsigned int req_size;
56008 	struct usb_request *req[UVC_NUM_REQUESTS];
56009diff --git a/drivers/usb/gadget/function/uvc_configfs.c b/drivers/usb/gadget/function/uvc_configfs.c
56010old mode 100644
56011new mode 100755
56012index 00fb58e50..604e87788
56013--- a/drivers/usb/gadget/function/uvc_configfs.c
56014+++ b/drivers/usb/gadget/function/uvc_configfs.c
56015@@ -319,7 +319,49 @@ static ssize_t uvcg_default_processing_bm_controls_show(
56016 	return result;
56017 }
56018
56019-UVC_ATTR_RO(uvcg_default_processing_, bm_controls, bmControls);
56020+static ssize_t uvcg_default_processing_bm_controls_store(
56021+	struct config_item *item, const char *page, size_t len)
56022+{
56023+	struct config_group *group = to_config_group(item);
56024+	struct f_uvc_opts *opts;
56025+	struct config_item *opts_item;
56026+	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
56027+	struct uvc_processing_unit_descriptor *pd;
56028+	int ret, i;
56029+	const char *pg = page;
56030+	/* sign, base 2 representation, newline, terminator */
56031+	char buf[1 + sizeof(u8) * 8 + 1 + 1];
56032+	int idx;
56033+
56034+	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
56035+
56036+	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
56037+	opts = to_f_uvc_opts(opts_item);
56038+	pd = &opts->uvc_processing;
56039+
56040+	idx = 0;
56041+	while (pg - page < len) {
56042+		i = 0;
56043+		while (i < sizeof(buf) && (pg - page < len) &&
56044+				*pg != '\0' && *pg != '\n')
56045+			buf[i++] = *pg++;
56046+		while ((pg - page < len) && (*pg == '\0' || *pg == '\n'))
56047+			++pg;
56048+		buf[i] = '\0';
56049+		ret = kstrtou8(buf, 0, &pd->bmControls[idx++]);
56050+		if (ret < 0)
56051+			goto end;
56052+		if (idx >= pd->bControlSize)
56053+			break;
56054+	}
56055+	ret = len;
56056+end:
56057+	mutex_unlock(&opts->lock);
56058+	mutex_unlock(su_mutex);
56059+	return ret;
56060+}
56061+
56062+UVC_ATTR(uvcg_default_processing_, bm_controls, bmControls);
56063
56064 static struct configfs_attribute *uvcg_default_processing_attrs[] = {
56065 	&uvcg_default_processing_attr_b_unit_id,
56066@@ -342,11 +384,10 @@ static const struct uvcg_config_group_type uvcg_default_processing_type = {
56067 /* -----------------------------------------------------------------------------
56068  * control/processing
56069  */
56070-
56071 static const struct uvcg_config_group_type uvcg_processing_grp_type = {
56072 	.type = {
56073-		.ct_item_ops	= &uvcg_config_item_ops,
56074-		.ct_owner	= THIS_MODULE,
56075+		.ct_item_ops    = &uvcg_config_item_ops,
56076+		.ct_owner   = THIS_MODULE,
56077 	},
56078 	.name = "processing",
56079 	.children = (const struct uvcg_config_group_type*[]) {
56080@@ -355,6 +396,115 @@ static const struct uvcg_config_group_type uvcg_processing_grp_type = {
56081 	},
56082 };
56083
56084+/* control/extension/default */
56085+static struct uvcg_default_extension {
56086+	struct config_group	group;
56087+} uvcg_default_extension;
56088+
56089+static inline struct uvcg_default_extension
56090+*to_uvcg_default_extension(struct config_item *item)
56091+{
56092+	return container_of(to_config_group(item),
56093+			    struct uvcg_default_extension, group);
56094+}
56095+
56096+#define UVCG_DEFAULT_EXTENSION_ATTR(cname, aname, conv)		\
56097+static ssize_t uvcg_default_extension_##cname##_show(			\
56098+	struct config_item *item, char *page)				\
56099+{									\
56100+	struct uvcg_default_extension *dp = to_uvcg_default_extension(item); \
56101+	struct f_uvc_opts *opts;					\
56102+	struct config_item *opts_item;					\
56103+	struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex;	\
56104+	struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) *ed;			\
56105+	int result;							\
56106+									\
56107+	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
56108+									\
56109+	opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent;	\
56110+	opts = to_f_uvc_opts(opts_item);				\
56111+	ed = &opts->uvc_extension;					\
56112+									\
56113+	mutex_lock(&opts->lock);					\
56114+	result = sprintf(page, "%d\n", conv(ed->aname));		\
56115+	mutex_unlock(&opts->lock);					\
56116+									\
56117+	mutex_unlock(su_mutex);						\
56118+	return result;							\
56119+}									\
56120+									\
56121+UVC_ATTR_RO(uvcg_default_extension_, cname, aname)
56122+
56123+#define identity_conv(x) (x)
56124+
56125+UVCG_DEFAULT_EXTENSION_ATTR(b_unit_id, bUnitID, identity_conv);
56126+UVCG_DEFAULT_EXTENSION_ATTR(b_num_input_pins, bNrInPins, identity_conv);
56127+UVCG_DEFAULT_EXTENSION_ATTR(i_extension, iExtension, identity_conv);
56128+
56129+#undef identity_conv
56130+
56131+#undef UVCG_DEFAULT_EXTENSION_ATTR
56132+
56133+static ssize_t uvcg_default_extension_bm_controls_show(
56134+	struct config_item *item, char *page)
56135+{
56136+	struct uvcg_default_extension *dp = to_uvcg_default_extension(item);
56137+	struct f_uvc_opts *opts;
56138+	struct config_item *opts_item;
56139+	struct mutex *su_mutex = &dp->group.cg_subsys->su_mutex;
56140+	struct UVC_EXTENSION_UNIT_DESCRIPTOR(1, 2) *ed;
56141+	int result, i;
56142+	char *pg = page;
56143+
56144+	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
56145+
56146+	opts_item = dp->group.cg_item.ci_parent->ci_parent->ci_parent;
56147+	opts = to_f_uvc_opts(opts_item);
56148+	ed = &opts->uvc_extension;
56149+
56150+	mutex_lock(&opts->lock);
56151+	for (result = 0, i = 0; i < ed->bControlSize; ++i) {
56152+		result += sprintf(pg, "%d\n", ed->bmControls[i]);
56153+		pg = page + result;
56154+	}
56155+	mutex_unlock(&opts->lock);
56156+
56157+	mutex_unlock(su_mutex);
56158+
56159+	return result;
56160+}
56161+
56162+UVC_ATTR_RO(uvcg_default_extension_, bm_controls, bmControls);
56163+
56164+static struct configfs_attribute *uvcg_default_extension_attrs[] = {
56165+	&uvcg_default_extension_attr_b_unit_id,
56166+	&uvcg_default_extension_attr_b_num_input_pins,
56167+	&uvcg_default_extension_attr_bm_controls,
56168+	&uvcg_default_extension_attr_i_extension,
56169+	NULL,
56170+};
56171+
56172+static struct config_item_type uvcg_default_extension_type = {
56173+	.ct_attrs	= uvcg_default_extension_attrs,
56174+	.ct_owner	= THIS_MODULE,
56175+};
56176+
56177+/* struct uvcg_extension {}; */
56178+
56179+/* control/extension */
56180+static struct uvcg_extension_grp {
56181+	struct config_group	group;
56182+} uvcg_extension_grp;
56183+
56184+static struct config_item_type uvcg_extension_grp_type = {
56185+ 	.ct_owner = THIS_MODULE,
56186+ };
56187+
56188+/* streaming/frame_based */
56189+static struct uvcg_frame_based_format_grp {
56190+	struct config_group	group;
56191+} uvcg_frame_based_format_grp;
56192+
56193 /* -----------------------------------------------------------------------------
56194  * control/terminal/camera/default
56195  */
56196@@ -430,7 +580,50 @@ static ssize_t uvcg_default_camera_bm_controls_show(
56197 	return result;
56198 }
56199
56200-UVC_ATTR_RO(uvcg_default_camera_, bm_controls, bmControls);
56201+static ssize_t uvcg_default_camera_bm_controls_store(
56202+	struct config_item *item, const char *page, size_t len)
56203+{
56204+	struct config_group *group = to_config_group(item);
56205+	struct f_uvc_opts *opts;
56206+	struct config_item *opts_item;
56207+	struct mutex *su_mutex = &group->cg_subsys->su_mutex;
56208+	struct uvc_camera_terminal_descriptor *cd;
56209+	int ret, i;
56210+	const char *pg = page;
56211+	/* sign, base 2 representation, newline, terminator */
56212+	char buf[1 + sizeof(u8) * 8 + 1 + 1];
56213+	int idx;
56214+
56215+	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
56216+
56217+	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent->
56218+			ci_parent;
56219+	opts = to_f_uvc_opts(opts_item);
56220+	cd = &opts->uvc_camera_terminal;
56221+
56222+	idx = 0;
56223+	while (pg - page < len) {
56224+		i = 0;
56225+		while (i < sizeof(buf) && (pg - page < len) &&
56226+				*pg != '\0' && *pg != '\n')
56227+			buf[i++] = *pg++;
56228+		while ((pg - page < len) && (*pg == '\0' || *pg == '\n'))
56229+			++pg;
56230+		buf[i] = '\0';
56231+		ret = kstrtou8(buf, 0, &cd->bmControls[idx++]);
56232+		if (ret < 0)
56233+			goto end;
56234+		if (idx >= cd->bControlSize)
56235+			break;
56236+	}
56237+	ret = len;
56238+end:
56239+	mutex_unlock(&opts->lock);
56240+	mutex_unlock(su_mutex);
56241+	return ret;
56242+}
56243+
56244+UVC_ATTR(uvcg_default_camera_, bm_controls, bmControls);
56245
56246 static struct configfs_attribute *uvcg_default_camera_attrs[] = {
56247 	&uvcg_default_camera_attr_b_terminal_id,
56248@@ -772,6 +965,7 @@ static const char * const uvcg_format_names[] = {
56249 enum uvcg_format_type {
56250 	UVCG_UNCOMPRESSED = 0,
56251 	UVCG_MJPEG,
56252+	UVCG_FRAME_FRAME_BASED,
56253 };
56254
56255 struct uvcg_format {
56256@@ -1381,6 +1575,7 @@ static struct config_item *uvcg_frame_make(struct config_group *group,
56257 		return ERR_PTR(-EINVAL);
56258 	}
56259 	++fmt->num_frames;
56260+	h->frame.b_frame_index	= fmt->num_frames;
56261 	mutex_unlock(&opts->lock);
56262
56263 	config_item_init_type_name(&h->item, name, &uvcg_frame_type);
56264@@ -1405,6 +1600,263 @@ static void uvcg_frame_drop(struct config_group *group, struct config_item *item
56265 	config_item_put(item);
56266 }
56267
56268+struct uvcg_frame_based_frame {
56269+	struct {
56270+		u8	b_length;
56271+		u8	b_descriptor_type;
56272+		u8	b_descriptor_subtype;
56273+		u8	b_frame_index;
56274+		u8	bm_capabilities;
56275+		u16	w_width;
56276+		u16	w_height;
56277+		u32	dw_min_bit_rate;
56278+		u32	dw_max_bit_rate;
56279+		u32	dw_default_frame_interval;
56280+		u8	b_frame_interval_type;
56281+		u32  dw_bytes_per_line;
56282+	} __attribute__((packed)) frame;
56283+	u32 *dw_frame_interval;
56284+	enum uvcg_format_type	fmt_type;
56285+	struct config_item	item;
56286+};
56287+
56288+static struct uvcg_frame_based_frame *to_uvcg_frame_based_frame(struct config_item *item)
56289+{
56290+	return container_of(item, struct uvcg_frame_based_frame, item);
56291+}
56292+
56293+#define UVCG_FRAME_BASED_FRAME_ATTR(cname, aname, to_cpu_endian, to_little_endian, bits) \
56294+static ssize_t uvcg_frame_based_frame_##cname##_show(struct config_item *item, char *page)\
56295+{									\
56296+	struct uvcg_frame_based_frame *f = to_uvcg_frame_based_frame(item);			\
56297+	struct f_uvc_opts *opts;					\
56298+	struct config_item *opts_item;					\
56299+	struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
56300+	int result;							\
56301+									\
56302+	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
56303+									\
56304+	opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent;	\
56305+	opts = to_f_uvc_opts(opts_item);				\
56306+									\
56307+	mutex_lock(&opts->lock);					\
56308+	result = sprintf(page, "%d\n", to_cpu_endian(f->frame.cname));	\
56309+	mutex_unlock(&opts->lock);					\
56310+									\
56311+	mutex_unlock(su_mutex);						\
56312+	return result;							\
56313+}									\
56314+									\
56315+static ssize_t  uvcg_frame_based_frame_##cname##_store(struct config_item *item,	\
56316+					   const char *page, size_t len)\
56317+{									\
56318+	struct uvcg_frame_based_frame *f = to_uvcg_frame_based_frame(item);			\
56319+	struct f_uvc_opts *opts;					\
56320+	struct config_item *opts_item;					\
56321+	struct uvcg_format *fmt;					\
56322+	struct mutex *su_mutex = &f->item.ci_group->cg_subsys->su_mutex;\
56323+	int ret;							\
56324+	u##bits num;							\
56325+									\
56326+	ret = kstrtou##bits(page, 0, &num);				\
56327+	if (ret)							\
56328+		return ret;						\
56329+									\
56330+	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
56331+									\
56332+	opts_item = f->item.ci_parent->ci_parent->ci_parent->ci_parent;	\
56333+	opts = to_f_uvc_opts(opts_item);				\
56334+	fmt = to_uvcg_format(f->item.ci_parent);			\
56335+									\
56336+	mutex_lock(&opts->lock);					\
56337+	if (fmt->linked || opts->refcnt) {				\
56338+		ret = -EBUSY;						\
56339+		goto end;						\
56340+	}								\
56341+									\
56342+	f->frame.cname = to_little_endian(num);				\
56343+	ret = len;							\
56344+end:									\
56345+	mutex_unlock(&opts->lock);					\
56346+	mutex_unlock(su_mutex);						\
56347+	return ret;							\
56348+}									\
56349+									\
56350+UVC_ATTR(uvcg_frame_based_frame_, cname, aname);
56351+
56352+#define noop_conversion(x) (x)
56353+
56354+UVCG_FRAME_BASED_FRAME_ATTR(bm_capabilities, bmCapabilities, noop_conversion,
56355+		noop_conversion, 8);
56356+UVCG_FRAME_BASED_FRAME_ATTR(w_width, wWidth, le16_to_cpu, cpu_to_le16, 16);
56357+UVCG_FRAME_BASED_FRAME_ATTR(w_height, wHeight, le16_to_cpu, cpu_to_le16, 16);
56358+UVCG_FRAME_BASED_FRAME_ATTR(dw_min_bit_rate, dwMinBitRate, le32_to_cpu, cpu_to_le32, 32);
56359+UVCG_FRAME_BASED_FRAME_ATTR(dw_max_bit_rate, dwMaxBitRate, le32_to_cpu, cpu_to_le32, 32);
56360+UVCG_FRAME_BASED_FRAME_ATTR(dw_default_frame_interval, dwDefaultFrameInterval,
56361+		le32_to_cpu, cpu_to_le32, 32);
56362+UVCG_FRAME_BASED_FRAME_ATTR(dw_bytes_per_line, dwBytesPerLine,
56363+		le32_to_cpu, cpu_to_le32, 32);
56364+
56365+#undef noop_conversion
56366+
56367+#undef UVCG_FRAME_BASED_FRAME_ATTR
56368+
56369+static ssize_t uvcg_frame_based_frame_dw_frame_interval_show(struct config_item *item,
56370+						 char *page)
56371+{
56372+	struct uvcg_frame_based_frame *frm = to_uvcg_frame_based_frame(item);
56373+	struct f_uvc_opts *opts;
56374+	struct config_item *opts_item;
56375+	struct mutex *su_mutex = &frm->item.ci_group->cg_subsys->su_mutex;
56376+	int result, i;
56377+	char *pg = page;
56378+
56379+	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
56380+
56381+	opts_item = frm->item.ci_parent->ci_parent->ci_parent->ci_parent;
56382+	opts = to_f_uvc_opts(opts_item);
56383+
56384+	mutex_lock(&opts->lock);
56385+	for (result = 0, i = 0; i < frm->frame.b_frame_interval_type; ++i) {
56386+		result += sprintf(pg, "%d\n",
56387+				  le32_to_cpu(frm->dw_frame_interval[i]));
56388+		pg = page + result;
56389+	}
56390+	mutex_unlock(&opts->lock);
56391+
56392+	mutex_unlock(su_mutex);
56393+	return result;
56394+}
56395+
56396+static ssize_t uvcg_frame_based_frame_dw_frame_interval_store(struct config_item *item,
56397+						  const char *page, size_t len)
56398+{
56399+	struct uvcg_frame_based_frame *ch = to_uvcg_frame_based_frame(item);
56400+	struct f_uvc_opts *opts;
56401+	struct config_item *opts_item;
56402+	struct uvcg_format *fmt;
56403+	struct mutex *su_mutex = &ch->item.ci_group->cg_subsys->su_mutex;
56404+	int ret = 0, n = 0;
56405+	u32 *frm_intrv, *tmp;
56406+
56407+	mutex_lock(su_mutex); /* for navigating configfs hierarchy */
56408+
56409+	opts_item = ch->item.ci_parent->ci_parent->ci_parent->ci_parent;
56410+	opts = to_f_uvc_opts(opts_item);
56411+	fmt = to_uvcg_format(ch->item.ci_parent);
56412+
56413+	mutex_lock(&opts->lock);
56414+	if (fmt->linked || opts->refcnt) {
56415+		ret = -EBUSY;
56416+		goto end;
56417+	}
56418+
56419+	ret = __uvcg_iter_frm_intrv(page, len, __uvcg_count_frm_intrv, &n);
56420+	if (ret)
56421+		goto end;
56422+
56423+	tmp = frm_intrv = kcalloc(n, sizeof(u32), GFP_KERNEL);
56424+	if (!frm_intrv) {
56425+		ret = -ENOMEM;
56426+		goto end;
56427+	}
56428+
56429+	ret = __uvcg_iter_frm_intrv(page, len, __uvcg_fill_frm_intrv, &tmp);
56430+	if (ret) {
56431+		kfree(frm_intrv);
56432+		goto end;
56433+	}
56434+
56435+	kfree(ch->dw_frame_interval);
56436+	ch->dw_frame_interval = frm_intrv;
56437+	ch->frame.b_frame_interval_type = n;
56438+	ret = len;
56439+
56440+end:
56441+	mutex_unlock(&opts->lock);
56442+	mutex_unlock(su_mutex);
56443+	return ret;
56444+}
56445+
56446+UVC_ATTR(uvcg_frame_based_frame_, dw_frame_interval, dwFrameInterval);
56447+
56448+static struct configfs_attribute *uvcg_frame_based_frame_attrs[] = {
56449+	&uvcg_frame_based_frame_attr_bm_capabilities,
56450+	&uvcg_frame_based_frame_attr_w_width,
56451+	&uvcg_frame_based_frame_attr_w_height,
56452+	&uvcg_frame_based_frame_attr_dw_min_bit_rate,
56453+	&uvcg_frame_based_frame_attr_dw_max_bit_rate,
56454+	&uvcg_frame_based_frame_attr_dw_default_frame_interval,
56455+	&uvcg_frame_based_frame_attr_dw_frame_interval,
56456+	&uvcg_frame_based_frame_attr_dw_bytes_per_line,
56457+	NULL,
56458+};
56459+
56460+static struct config_item_type uvcg_frame_based_frame_type = {
56461+	.ct_attrs	= uvcg_frame_based_frame_attrs,
56462+	.ct_owner	= THIS_MODULE,
56463+};
56464+
56465+static struct config_item *uvcg_frame_based_frame_make(struct config_group *group,
56466+					   const char *name)
56467+{
56468+	struct uvcg_frame_based_frame *h;
56469+	struct uvcg_format *fmt;
56470+	struct f_uvc_opts *opts;
56471+	struct config_item *opts_item;
56472+
56473+	h = kzalloc(sizeof(*h), GFP_KERNEL);
56474+	if (!h)
56475+		return ERR_PTR(-ENOMEM);
56476+
56477+	h->frame.b_descriptor_type		= USB_DT_CS_INTERFACE;
56478+	h->frame.b_frame_index			= 1;
56479+	h->frame.w_width			= cpu_to_le16(640);
56480+	h->frame.w_height			= cpu_to_le16(360);
56481+	h->frame.dw_min_bit_rate		= cpu_to_le32(18432000);
56482+	h->frame.dw_max_bit_rate		= cpu_to_le32(55296000);
56483+	h->frame.dw_default_frame_interval	= cpu_to_le32(333333);
56484+	h->frame.dw_bytes_per_line	= cpu_to_le32(0);
56485+
56486+	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
56487+	opts = to_f_uvc_opts(opts_item);
56488+
56489+	mutex_lock(&opts->lock);
56490+	fmt = to_uvcg_format(&group->cg_item);
56491+	if (fmt->type == UVCG_FRAME_FRAME_BASED) {
56492+		h->frame.b_descriptor_subtype = UVC_VS_FRAME_FRAME_BASED;
56493+		h->fmt_type = UVCG_FRAME_FRAME_BASED;
56494+	} else {
56495+		mutex_unlock(&opts->lock);
56496+		kfree(h);
56497+		return ERR_PTR(-EINVAL);
56498+	}
56499+	++fmt->num_frames;
56500+	h->frame.b_frame_index	= fmt->num_frames;
56501+	mutex_unlock(&opts->lock);
56502+
56503+	config_item_init_type_name(&h->item, name, &uvcg_frame_based_frame_type);
56504+
56505+	return &h->item;
56506+}
56507+
56508+static void uvcg_frame_based_frame_drop(struct config_group *group, struct config_item *item)
56509+{
56510+	struct uvcg_frame_based_frame *h = to_uvcg_frame_based_frame(item);
56511+	struct uvcg_format *fmt;
56512+	struct f_uvc_opts *opts;
56513+	struct config_item *opts_item;
56514+
56515+	opts_item = group->cg_item.ci_parent->ci_parent->ci_parent;
56516+	opts = to_f_uvc_opts(opts_item);
56517+
56518+	mutex_lock(&opts->lock);
56519+	fmt = to_uvcg_format(&group->cg_item);
56520+	--fmt->num_frames;
56521+	kfree(h);
56522+	mutex_unlock(&opts->lock);
56523+}
56524+
56525 static void uvcg_format_set_indices(struct config_group *fmt)
56526 {
56527 	struct config_item *ci;
56528@@ -1629,10 +2081,17 @@ static const struct config_item_type uvcg_uncompressed_type = {
56529 static struct config_group *uvcg_uncompressed_make(struct config_group *group,
56530 						   const char *name)
56531 {
56532+#ifndef CONFIG_HISI_MC
56533 	static char guid[] = {
56534 		'Y',  'U',  'Y',  '2', 0x00, 0x00, 0x10, 0x00,
56535 		 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
56536 	};
56537+#else
56538+	static char guid[] = {
56539+		'N',  'V',  '2',  '1', 0x00, 0x00, 0x10, 0x00,
56540+		 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
56541+	};
56542+#endif
56543 	struct uvcg_uncompressed *h;
56544
56545 	h = kzalloc(sizeof(*h), GFP_KERNEL);
56546@@ -1643,7 +2102,11 @@ static struct config_group *uvcg_uncompressed_make(struct config_group *group,
56547 	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
56548 	h->desc.bDescriptorSubType	= UVC_VS_FORMAT_UNCOMPRESSED;
56549 	memcpy(h->desc.guidFormat, guid, sizeof(guid));
56550+#ifndef CONFIG_HISI_MC
56551 	h->desc.bBitsPerPixel		= 16;
56552+#else
56553+	h->desc.bBitsPerPixel		= 12;
56554+#endif
56555 	h->desc.bDefaultFrameIndex	= 1;
56556 	h->desc.bAspectRatioX		= 0;
56557 	h->desc.bAspectRatioY		= 0;
56558@@ -1818,6 +2281,205 @@ static const struct config_item_type uvcg_mjpeg_type = {
56559 	.ct_owner	= THIS_MODULE,
56560 };
56561
56562+/* streaming/frame_based<NAME> */
56563+struct uvcg_frame_based_format {
56564+	struct uvcg_format		fmt;
56565+	struct uvc_frame_based_format_desc		desc;
56566+};
56567+
56568+static struct uvcg_frame_based_format *to_uvcg_frame_based_format(struct config_item *item)
56569+{
56570+	return container_of(
56571+		container_of(to_config_group(item), struct uvcg_format, group),
56572+		struct uvcg_frame_based_format, fmt);
56573+}
56574+
56575+static struct configfs_group_operations uvcg_frame_based_format_group_ops = {
56576+	.make_item		= uvcg_frame_based_frame_make,
56577+	.drop_item		= uvcg_frame_based_frame_drop,
56578+};
56579+
56580+#define UVCG_FRAME_BASED_FORMAT_ATTR_RO(cname, aname, conv)				\
56581+static ssize_t uvcg_frame_based_format_##cname##_show(struct config_item *item, char *page)\
56582+{									\
56583+	struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item);			\
56584+	struct f_uvc_opts *opts;					\
56585+	struct config_item *opts_item;					\
56586+	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
56587+	int result;							\
56588+									\
56589+	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
56590+									\
56591+	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
56592+	opts = to_f_uvc_opts(opts_item);				\
56593+									\
56594+	mutex_lock(&opts->lock);					\
56595+	result = sprintf(page, "%d\n", conv(u->desc.aname));		\
56596+	mutex_unlock(&opts->lock);					\
56597+									\
56598+	mutex_unlock(su_mutex);						\
56599+	return result;							\
56600+}									\
56601+									\
56602+UVC_ATTR_RO(uvcg_frame_based_format_, cname, aname)
56603+
56604+#define UVCG_FRAME_BASED_FORMAT_ATTR(cname, aname, conv)				\
56605+static ssize_t uvcg_frame_based_format_##cname##_show(struct config_item *item, char *page)\
56606+{									\
56607+	struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item);			\
56608+	struct f_uvc_opts *opts;					\
56609+	struct config_item *opts_item;					\
56610+	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
56611+	int result;							\
56612+									\
56613+	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
56614+									\
56615+	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
56616+	opts = to_f_uvc_opts(opts_item);				\
56617+									\
56618+	mutex_lock(&opts->lock);					\
56619+	result = sprintf(page, "%d\n", conv(u->desc.aname));		\
56620+	mutex_unlock(&opts->lock);					\
56621+									\
56622+	mutex_unlock(su_mutex);						\
56623+	return result;							\
56624+}									\
56625+									\
56626+static ssize_t								\
56627+uvcg_frame_based_format_##cname##_store(struct config_item *item,			\
56628+			   const char *page, size_t len)		\
56629+{									\
56630+	struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item);			\
56631+	struct f_uvc_opts *opts;					\
56632+	struct config_item *opts_item;					\
56633+	struct mutex *su_mutex = &u->fmt.group.cg_subsys->su_mutex;	\
56634+	int ret;							\
56635+	u8 num;								\
56636+									\
56637+	mutex_lock(su_mutex); /* for navigating configfs hierarchy */	\
56638+									\
56639+	opts_item = u->fmt.group.cg_item.ci_parent->ci_parent->ci_parent;\
56640+	opts = to_f_uvc_opts(opts_item);				\
56641+									\
56642+	mutex_lock(&opts->lock);					\
56643+	if (u->fmt.linked || opts->refcnt) {				\
56644+		ret = -EBUSY;						\
56645+		goto end;						\
56646+	}								\
56647+									\
56648+	ret = kstrtou8(page, 0, &num);					\
56649+	if (ret)							\
56650+		goto end;						\
56651+									\
56652+	if (num > 255) {						\
56653+		ret = -EINVAL;						\
56654+		goto end;						\
56655+	}								\
56656+	u->desc.aname = num;						\
56657+	ret = len;							\
56658+end:									\
56659+	mutex_unlock(&opts->lock);					\
56660+	mutex_unlock(su_mutex);						\
56661+	return ret;							\
56662+}									\
56663+									\
56664+UVC_ATTR(uvcg_frame_based_format_, cname, aname)
56665+
56666+#define identity_conv(x) (x)
56667+
56668+UVCG_FRAME_BASED_FORMAT_ATTR(b_default_frame_index, bDefaultFrameIndex,
56669+		       identity_conv);
56670+UVCG_FRAME_BASED_FORMAT_ATTR_RO(b_aspect_ratio_x, bAspectRatioX, identity_conv);
56671+UVCG_FRAME_BASED_FORMAT_ATTR_RO(b_aspect_ratio_y, bAspectRatioY, identity_conv);
56672+UVCG_FRAME_BASED_FORMAT_ATTR_RO(bm_interface_flags, bmInterfaceFlags, identity_conv);
56673+
56674+#undef identity_conv
56675+
56676+#undef UVCG_FRAME_BASED_FORMAT_ATTR
56677+#undef UVCG_FRAME_BASED_FORMAT_ATTR_RO
56678+
56679+static inline ssize_t
56680+uvcg_frame_based_format_bma_controls_show(struct config_item *item, char *page)
56681+{
56682+	struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item);
56683+	return uvcg_format_bma_controls_show(&u->fmt, page);
56684+}
56685+
56686+static inline ssize_t
56687+uvcg_frame_based_format_bma_controls_store(struct config_item *item,
56688+				     const char *page, size_t len)
56689+{
56690+	struct uvcg_frame_based_format *u = to_uvcg_frame_based_format(item);
56691+	return uvcg_format_bma_controls_store(&u->fmt, page, len);
56692+}
56693+
56694+UVC_ATTR(uvcg_frame_based_format_, bma_controls, bmaControls);
56695+
56696+static struct configfs_attribute *uvcg_frame_based_format_attrs[] = {
56697+	&uvcg_frame_based_format_attr_b_default_frame_index,
56698+	&uvcg_frame_based_format_attr_b_aspect_ratio_x,
56699+	&uvcg_frame_based_format_attr_b_aspect_ratio_y,
56700+	&uvcg_frame_based_format_attr_bm_interface_flags,
56701+	&uvcg_frame_based_format_attr_bma_controls,
56702+	NULL,
56703+};
56704+
56705+static struct config_item_type uvcg_frame_based_format_type = {
56706+	.ct_group_ops	= &uvcg_frame_based_format_group_ops,
56707+	.ct_attrs	= uvcg_frame_based_format_attrs,
56708+	.ct_owner	= THIS_MODULE,
56709+};
56710+
56711+static struct config_group *uvcg_frame_based_format_make(struct config_group *group,
56712+						   const char *name)
56713+{
56714+	static char guid[] = { /*Declear frame frame based as H264*/
56715+		'H',  '2',  '6',  '4', 0x00, 0x00, 0x10, 0x00,
56716+		 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71
56717+	};
56718+	struct uvcg_frame_based_format *h;
56719+
56720+	h = kzalloc(sizeof(*h), GFP_KERNEL);
56721+	if (!h)
56722+		return ERR_PTR(-ENOMEM);
56723+
56724+	h->desc.bLength			= UVC_DT_FRAME_BASED_FORMAT_SIZE;
56725+	h->desc.bDescriptorType		= USB_DT_CS_INTERFACE;
56726+	h->desc.bDescriptorSubType	= UVC_VS_FORMAT_FRAME_BASED;
56727+	memcpy(h->desc.guidFormat, guid, sizeof(guid));
56728+	h->desc.bBitsPerPixel		= 16;
56729+	h->desc.bDefaultFrameIndex	= 1;
56730+	h->desc.bAspectRatioX	= 0;
56731+	h->desc.bAspectRatioY	= 0;
56732+	h->desc.bmInterfaceFlags	= 0;
56733+	h->desc.bCopyProtect		= 0;
56734+	h->desc.bVariableSize		= 1;
56735+
56736+	h->fmt.type = UVCG_FRAME_FRAME_BASED;
56737+	config_group_init_type_name(&h->fmt.group, name,
56738+				    &uvcg_frame_based_format_type);
56739+
56740+	return &h->fmt.group;
56741+}
56742+
56743+static void uvcg_frame_based_format_drop(struct config_group *group,
56744+			    struct config_item *item)
56745+{
56746+	struct uvcg_frame_based_format *h = to_uvcg_frame_based_format(item);
56747+
56748+	kfree(h);
56749+}
56750+
56751+static struct configfs_group_operations uvcg_frame_based_format_grp_ops = {
56752+	.make_group		= uvcg_frame_based_format_make,
56753+	.drop_item		= uvcg_frame_based_format_drop,
56754+};
56755+
56756+static struct config_item_type uvcg_frame_based_format_grp_type = {
56757+	.ct_group_ops	= &uvcg_frame_based_format_grp_ops,
56758+	.ct_owner	= THIS_MODULE,
56759+};
56760+
56761 static struct config_group *uvcg_mjpeg_make(struct config_group *group,
56762 						   const char *name)
56763 {
56764@@ -2049,6 +2711,11 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
56765 				container_of(fmt, struct uvcg_mjpeg, fmt);
56766
56767 			*size += sizeof(m->desc);
56768+		} else if (fmt->type == UVCG_FRAME_FRAME_BASED) {
56769+			struct uvcg_frame_based_format *h =
56770+				container_of(fmt, struct uvcg_frame_based_format, fmt);
56771+
56772+			*size += sizeof(h->desc);
56773 		} else {
56774 			return -EINVAL;
56775 		}
56776@@ -2057,7 +2724,14 @@ static int __uvcg_cnt_strm(void *priv1, void *priv2, void *priv3, int n,
56777 	case UVCG_FRAME: {
56778 		struct uvcg_frame *frm = priv1;
56779 		int sz = sizeof(frm->dw_frame_interval);
56780+		if (frm->frame.b_descriptor_subtype == UVC_VS_FRAME_FRAME_BASED) {
56781+			struct uvcg_frame_based_frame *fb_frm = priv1;
56782+			*size += sizeof(fb_frm->frame);
56783+			*size += fb_frm->frame.b_frame_interval_type * sizeof(fb_frm->dw_frame_interval);
56784
56785+			++*count;
56786+			return 0;
56787+		}
56788 		*size += sizeof(frm->frame);
56789 		*size += frm->frame.b_frame_interval_type * sz;
56790 	}
56791@@ -2123,6 +2797,15 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
56792 			m->desc.bNumFrameDescriptors = fmt->num_frames;
56793 			memcpy(*dest, &m->desc, sizeof(m->desc));
56794 			*dest += sizeof(m->desc);
56795+		} else if (fmt->type == UVCG_FRAME_FRAME_BASED) {
56796+			struct uvc_frame_based_format_desc *ffb = *dest;
56797+			struct uvcg_frame_based_format *h =
56798+				container_of(fmt, struct uvcg_frame_based_format, fmt);
56799+
56800+			memcpy(*dest, &h->desc, sizeof(h->desc));
56801+			*dest += sizeof(h->desc);
56802+			ffb->bNumFrameDescriptors = fmt->num_frames;
56803+			ffb->bFormatIndex = n + 1;
56804 		} else {
56805 			return -EINVAL;
56806 		}
56807@@ -2132,6 +2815,19 @@ static int __uvcg_fill_strm(void *priv1, void *priv2, void *priv3, int n,
56808 		struct uvcg_frame *frm = priv1;
56809 		struct uvc_descriptor_header *h = *dest;
56810
56811+		if (frm->frame.b_descriptor_subtype == UVC_VS_FRAME_FRAME_BASED) {
56812+			struct uvcg_frame_based_frame *fb_frm = priv1;
56813+			sz = sizeof(fb_frm->frame);
56814+			memcpy(*dest, &fb_frm->frame, sz);
56815+			*dest += sz;
56816+			sz = fb_frm->frame.b_frame_interval_type *
56817+			sizeof(*fb_frm->dw_frame_interval);
56818+			memcpy(*dest, fb_frm->dw_frame_interval, sz);
56819+			*dest += sz;
56820+			h->bLength = UVC_DT_FRAME_BASED_FRAME_SIZE(
56821+				fb_frm->frame.b_frame_interval_type);
56822+			return 0;
56823+		}
56824 		sz = sizeof(frm->frame);
56825 		memcpy(*dest, &frm->frame, sz);
56826 		*dest += sz;
56827diff --git a/drivers/usb/gadget/function/uvc_v4l2.c b/drivers/usb/gadget/function/uvc_v4l2.c
56828index 4ca89eab6..1272038be 100644
56829--- a/drivers/usb/gadget/function/uvc_v4l2.c
56830+++ b/drivers/usb/gadget/function/uvc_v4l2.c
56831@@ -56,8 +56,13 @@ struct uvc_format {
56832 };
56833
56834 static struct uvc_format uvc_formats[] = {
56835+#ifndef CONFIG_HISI_MC
56836 	{ 16, V4L2_PIX_FMT_YUYV  },
56837+#else
56838+	{ 12, V4L2_PIX_FMT_NV21 },
56839+#endif
56840 	{ 0,  V4L2_PIX_FMT_MJPEG },
56841+	{ 0,  V4L2_PIX_FMT_H264 },
56842 };
56843
56844 static int
56845diff --git a/drivers/usb/gadget/function/uvc_video.c b/drivers/usb/gadget/function/uvc_video.c
56846index 633e23d58..835f5f048 100644
56847--- a/drivers/usb/gadget/function/uvc_video.c
56848+++ b/drivers/usb/gadget/function/uvc_video.c
56849@@ -12,13 +12,15 @@
56850 #include <linux/usb/ch9.h>
56851 #include <linux/usb/gadget.h>
56852 #include <linux/usb/video.h>
56853-
56854+#include <linux/usb/g_uvc.h>
56855 #include <media/v4l2-dev.h>
56856
56857 #include "uvc.h"
56858 #include "uvc_queue.h"
56859 #include "uvc_video.h"
56860
56861+#include <linux/scatterlist.h>
56862+#include <linux/io.h>
56863 /* --------------------------------------------------------------------------
56864  * Video codecs
56865  */
56866@@ -98,9 +100,45 @@ static void
56867 uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
56868 		struct uvc_buffer *buf)
56869 {
56870+	int ret;
56871+#ifdef UVC_SG_REQ
56872+	int len;
56873+	int ttllen = 0;
56874+	unsigned int sg_idx;
56875+	u8 *mem = NULL;
56876+
56877+	for (sg_idx = 0; sg_idx < video->num_sgs; sg_idx++) {
56878+		mem = sg_virt(&req->sg[sg_idx]);
56879+		len = video->req_size;
56880+
56881+		/* Add the header. */
56882+		ret = uvc_video_encode_header(video, buf, mem, len);
56883+		mem += ret;
56884+		len -= ret;
56885+
56886+		/* Process video data. */
56887+		ret = uvc_video_encode_data(video, buf, mem, len);
56888+		len -= ret;
56889+
56890+		/* Sync sg buffer len , default is 1024 or 3072 */
56891+		sg_set_buf(&req->sg[sg_idx], sg_virt(&req->sg[sg_idx]),
56892+				video->req_size - len);
56893+		ttllen += video->req_size - len;
56894+
56895+		if (buf->bytesused == video->queue.buf_used) {
56896+			video->queue.buf_used = 0;
56897+			buf->state = UVC_BUF_STATE_DONE;
56898+			uvcg_queue_next_buffer(&video->queue, buf);
56899+			video->fid ^= UVC_STREAM_FID;
56900+			break;
56901+		}
56902+	}
56903+	req->num_sgs = sg_idx + 1;
56904+	sg_mark_end(&req->sg[sg_idx]);
56905+	req->length = ttllen;
56906+#else
56907 	void *mem = req->buf;
56908 	int len = video->req_size;
56909-	int ret;
56910
56911 	/* Add the header. */
56912 	ret = uvc_video_encode_header(video, buf, mem, len);
56913@@ -119,6 +157,7 @@ uvc_video_encode_isoc(struct usb_request *req, struct uvc_video *video,
56914 		uvcg_queue_next_buffer(&video->queue, buf);
56915 		video->fid ^= UVC_STREAM_FID;
56916 	}
56917+#endif
56918 }
56919
56920 /* --------------------------------------------------------------------------
56921@@ -129,6 +168,15 @@ static int uvcg_video_ep_queue(struct uvc_video *video, struct usb_request *req)
56922 {
56923 	int ret;
56924
56925+	/*
56926+	 * Fixme, this is just to workaround the warning by udc core when the ep
56927+	 * is disabled, this may happens when the uvc application is still
56928+	 * streaming new data while the uvc gadget driver has already recieved
56929+	 * the streamoff but the streamoff event is not yet received by the app
56930+	 */
56931+	if (!video->ep->enabled)
56932+		return -EINVAL;
56933+
56934 	ret = usb_ep_queue(video->ep, req, GFP_ATOMIC);
56935 	if (ret < 0) {
56936 		uvcg_err(&video->uvc->func, "Failed to queue request (%d).\n",
56937@@ -176,9 +224,22 @@ static int
56938 uvc_video_free_requests(struct uvc_video *video)
56939 {
56940 	unsigned int i;
56941+#ifdef UVC_SG_REQ
56942+	unsigned int sg_idx;
56943+#endif
56944
56945 	for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
56946 		if (video->req[i]) {
56947+#ifdef UVC_SG_REQ
56948+			for (sg_idx = 0; sg_idx < video->num_sgs; sg_idx++)
56949+				if (sg_page(&video->req[i]->sg[sg_idx]))
56950+					kfree(sg_virt(&video->req[i]->sg[sg_idx]));
56951+
56952+			if (video->req[i]->sg) {
56953+				kfree(video->req[i]->sg);
56954+				video->req[i]->sg = NULL;
56955+			}
56956+#endif
56957 			usb_ep_free_request(video->ep, video->req[i]);
56958 			video->req[i] = NULL;
56959 		}
56960@@ -200,6 +261,11 @@ uvc_video_alloc_requests(struct uvc_video *video)
56961 	unsigned int req_size;
56962 	unsigned int i;
56963 	int ret = -ENOMEM;
56964+#ifdef UVC_SG_REQ
56965+	struct scatterlist  *sg;
56966+	unsigned int num_sgs;
56967+	unsigned int sg_idx;
56968+#endif
56969
56970 	BUG_ON(video->req_size);
56971
56972@@ -207,6 +273,35 @@ uvc_video_alloc_requests(struct uvc_video *video)
56973 		 * max_t(unsigned int, video->ep->maxburst, 1)
56974 		 * (video->ep->mult);
56975
56976+#ifdef UVC_SG_REQ
56977+	num_sgs = ((video->imagesize / (req_size - 2)) + 1);
56978+	video->num_sgs = num_sgs;
56979+
56980+	for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
56981+		sg = kmalloc(num_sgs * sizeof(struct scatterlist), GFP_ATOMIC);
56982+		if (sg == NULL)
56983+			goto error;
56984+		sg_init_table(sg, num_sgs);
56985+
56986+		video->req[i] = usb_ep_alloc_request(video->ep, GFP_KERNEL);
56987+		if (video->req[i] == NULL)
56988+			goto error;
56989+
56990+		for (sg_idx = 0 ; sg_idx < num_sgs ; sg_idx++) {
56991+			video->sg_buf = kmalloc(req_size, GFP_KERNEL);
56992+			if (video->sg_buf == NULL)
56993+				goto error;
56994+			sg_set_buf(&sg[sg_idx], video->sg_buf, req_size);
56995+		}
56996+		video->req[i]->sg = sg;
56997+		video->req[i]->num_sgs = num_sgs;
56998+		video->req[i]->length = 0;
56999+		video->req[i]->complete = uvc_video_complete;
57000+		video->req[i]->context = video;
57001+
57002+		list_add_tail(&video->req[i]->list, &video->req_free);
57003+	}
57004+#else
57005 	for (i = 0; i < UVC_NUM_REQUESTS; ++i) {
57006 		video->req_buffer[i] = kmalloc(req_size, GFP_KERNEL);
57007 		if (video->req_buffer[i] == NULL)
57008@@ -223,7 +318,7 @@ uvc_video_alloc_requests(struct uvc_video *video)
57009
57010 		list_add_tail(&video->req[i]->list, &video->req_free);
57011 	}
57012-
57013+#endif
57014 	video->req_size = req_size;
57015
57016 	return 0;
57017@@ -276,6 +371,9 @@ static void uvcg_video_pump(struct work_struct *work)
57018 			break;
57019 		}
57020
57021+#ifdef UVC_SG_REQ
57022+	sg_unmark_end(&req->sg[req->num_sgs - 1]);
57023+#endif
57024 		video->encode(req, video, buf);
57025
57026 		/* Queue the USB request */
57027@@ -289,6 +387,9 @@ static void uvcg_video_pump(struct work_struct *work)
57028 	}
57029
57030 	spin_lock_irqsave(&video->req_lock, flags);
57031+#ifdef UVC_SG_REQ
57032+	sg_unmark_end(&req->sg[req->num_sgs - 1]);
57033+#endif
57034 	list_add_tail(&req->list, &video->req_free);
57035 	spin_unlock_irqrestore(&video->req_lock, flags);
57036 	return;
57037@@ -348,11 +449,17 @@ int uvcg_video_init(struct uvc_video *video, struct uvc_device *uvc)
57038 	INIT_WORK(&video->pump, uvcg_video_pump);
57039
57040 	video->uvc = uvc;
57041+#ifndef CONFIG_HISI_MC
57042 	video->fcc = V4L2_PIX_FMT_YUYV;
57043+	video->imagesize = 320 * 240 * 2;
57044 	video->bpp = 16;
57045+#else
57046+	video->fcc = V4L2_PIX_FMT_NV21;
57047+	video->imagesize = 320 * 240 * 3 / 2;	/* YUV420: w*h*1.5 */
57048+	video->bpp = 12;
57049+#endif
57050 	video->width = 320;
57051 	video->height = 240;
57052-	video->imagesize = 320 * 240 * 2;
57053
57054 	/* Initialize the video buffers queue. */
57055 	uvcg_queue_init(&video->queue, V4L2_BUF_TYPE_VIDEO_OUTPUT,
57056diff --git a/drivers/vfio/pci/vfio_pci_intrs.c b/drivers/vfio/pci/vfio_pci_intrs.c
57057index 869dce5f1..3807bb163 100644
57058--- a/drivers/vfio/pci/vfio_pci_intrs.c
57059+++ b/drivers/vfio/pci/vfio_pci_intrs.c
57060@@ -642,6 +642,8 @@ int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags,
57061 	int (*func)(struct vfio_pci_device *vdev, unsigned index,
57062 		    unsigned start, unsigned count, uint32_t flags,
57063 		    void *data) = NULL;
57064+	int ret;
57065+	u16 cmd;
57066
57067 	switch (index) {
57068 	case VFIO_PCI_INTX_IRQ_INDEX:
57069@@ -689,5 +691,19 @@ int vfio_pci_set_irqs_ioctl(struct vfio_pci_device *vdev, uint32_t flags,
57070 	if (!func)
57071 		return -ENOTTY;
57072
57073-	return func(vdev, index, start, count, flags, data);
57074+	if (index == VFIO_PCI_MSIX_IRQ_INDEX) {
57075+		down_write(&vdev->memory_lock);
57076+		pci_read_config_word(vdev->pdev, PCI_COMMAND, &cmd);
57077+		pci_write_config_word(vdev->pdev, PCI_COMMAND,
57078+				      cmd | PCI_COMMAND_MEMORY);
57079+	}
57080+
57081+	ret = func(vdev, index, start, count, flags, data);
57082+
57083+	if (index == VFIO_PCI_MSIX_IRQ_INDEX) {
57084+		pci_write_config_word(vdev->pdev, PCI_COMMAND, cmd);
57085+		up_write(&vdev->memory_lock);
57086+	}
57087+
57088+	return ret;
57089 }
57090diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c
57091index fe888b5dc..5a0791e56 100644
57092--- a/drivers/vfio/vfio_iommu_spapr_tce.c
57093+++ b/drivers/vfio/vfio_iommu_spapr_tce.c
57094@@ -21,9 +21,9 @@
57095 #include <linux/sched/signal.h>
57096 #include <linux/mm.h>
57097
57098-#include <asm/iommu.h>
57099-#include <asm/tce.h>
57100-#include <asm/mmu_context.h>
57101+#include <linux/iommu.h>
57102+/* #include <linux/tce.h> */
57103+#include <linux/mmu_context.h>
57104
57105 #define DRIVER_VERSION  "0.1"
57106 #define DRIVER_AUTHOR   "aik@ozlabs.ru"
57107diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
57108index fbd438e9b..64431a1a9 100644
57109--- a/drivers/vfio/vfio_iommu_type1.c
57110+++ b/drivers/vfio/vfio_iommu_type1.c
57111@@ -28,6 +28,7 @@
57112 #include <linux/iommu.h>
57113 #include <linux/module.h>
57114 #include <linux/mm.h>
57115+#include <linux/ptrace.h>
57116 #include <linux/kthread.h>
57117 #include <linux/rbtree.h>
57118 #include <linux/sched/signal.h>
57119@@ -64,6 +65,7 @@ MODULE_PARM_DESC(dma_entry_limit,
57120
57121 struct vfio_iommu {
57122 	struct list_head	domain_list;
57123+	struct list_head	mm_list;
57124 	struct list_head	iova_list;
57125 	struct vfio_domain	*external_domain; /* domain for external user */
57126 	struct mutex		lock;
57127@@ -103,6 +105,14 @@ struct vfio_group {
57128 	struct list_head	next;
57129 	bool			mdev_group;	/* An mdev group */
57130 	bool			pinned_page_dirty_scope;
57131+	bool                    sva_enabled;
57132+};
57133+
57134+struct vfio_mm {
57135+#define VFIO_PASID_INVALID	(-1)
57136+	int			pasid;
57137+	struct mm_struct	*mm;
57138+	struct list_head	next;
57139 };
57140
57141 struct vfio_iova {
57142diff --git a/fs/9p/vfs_inode.c b/fs/9p/vfs_inode.c
57143index 0791480bf..5a195dd31 100644
57144--- a/fs/9p/vfs_inode.c
57145+++ b/fs/9p/vfs_inode.c
57146@@ -999,6 +999,7 @@ v9fs_vfs_getattr(const struct path *path, struct kstat *stat,
57147 		 u32 request_mask, unsigned int flags)
57148 {
57149 	struct dentry *dentry = path->dentry;
57150+	struct inode *inode = d_inode(dentry);
57151 	struct v9fs_session_info *v9ses;
57152 	struct p9_fid *fid;
57153 	struct p9_wstat *st;
57154@@ -1006,7 +1007,7 @@ v9fs_vfs_getattr(const struct path *path, struct kstat *stat,
57155 	p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
57156 	v9ses = v9fs_dentry2v9ses(dentry);
57157 	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
57158-		generic_fillattr(d_inode(dentry), stat);
57159+		generic_fillattr(inode, stat);
57160 		return 0;
57161 	}
57162 	fid = v9fs_fid_lookup(dentry);
57163@@ -1017,8 +1018,10 @@ v9fs_vfs_getattr(const struct path *path, struct kstat *stat,
57164 	if (IS_ERR(st))
57165 		return PTR_ERR(st);
57166
57167-	v9fs_stat2inode(st, d_inode(dentry), dentry->d_sb, 0);
57168-	generic_fillattr(d_inode(dentry), stat);
57169+	spin_lock(&inode->i_lock);
57170+	v9fs_stat2inode(st, inode, dentry->d_sb);
57171+	spin_unlock(&inode->i_lock);
57172+	generic_fillattr(inode, stat);
57173
57174 	p9stat_free(st);
57175 	kfree(st);
57176diff --git a/fs/9p/vfs_inode_dotl.c b/fs/9p/vfs_inode_dotl.c
57177index 72b67d810..74629e0a7 100644
57178--- a/fs/9p/vfs_inode_dotl.c
57179+++ b/fs/9p/vfs_inode_dotl.c
57180@@ -459,6 +459,7 @@ v9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat,
57181 		 u32 request_mask, unsigned int flags)
57182 {
57183 	struct dentry *dentry = path->dentry;
57184+	struct inode *inode = d_inode(dentry);
57185 	struct v9fs_session_info *v9ses;
57186 	struct p9_fid *fid;
57187 	struct p9_stat_dotl *st;
57188@@ -466,7 +467,7 @@ v9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat,
57189 	p9_debug(P9_DEBUG_VFS, "dentry: %p\n", dentry);
57190 	v9ses = v9fs_dentry2v9ses(dentry);
57191 	if (v9ses->cache == CACHE_LOOSE || v9ses->cache == CACHE_FSCACHE) {
57192-		generic_fillattr(d_inode(dentry), stat);
57193+		generic_fillattr(inode, stat);
57194 		return 0;
57195 	}
57196 	fid = v9fs_fid_lookup(dentry);
57197@@ -481,8 +482,10 @@ v9fs_vfs_getattr_dotl(const struct path *path, struct kstat *stat,
57198 	if (IS_ERR(st))
57199 		return PTR_ERR(st);
57200
57201-	v9fs_stat2inode_dotl(st, d_inode(dentry), 0);
57202-	generic_fillattr(d_inode(dentry), stat);
57203+	spin_lock(&inode->i_lock);
57204+	v9fs_stat2inode_dotl(st, inode);
57205+	spin_unlock(&inode->i_lock);
57206+	generic_fillattr(inode, stat);
57207 	/* Change block size to what the server returned */
57208 	stat->blksize = st->st_blksize;
57209
57210diff --git a/fs/aio.c b/fs/aio.c
57211index bd182bcca..425db15b5 100644
57212--- a/fs/aio.c
57213+++ b/fs/aio.c
57214@@ -1764,6 +1764,12 @@ static int aio_poll(struct aio_kiocb *aiocb, const struct iocb *iocb)
57215 	INIT_LIST_HEAD(&req->wait.entry);
57216 	init_waitqueue_func_entry(&req->wait, aio_poll_wake);
57217
57218+	/*
57219+	 * file may be released by aio_poll_wake() if an expected event
57220+	 * is triggered immediately after the return of vfs_poll(), so
57221+	 * an extra reference is needed here to prevent use-after-free.
57222+	 */
57223+	get_file(req->file);
57224 	mask = vfs_poll(req->file, &apt.pt) & req->events;
57225 	spin_lock_irq(&ctx->ctx_lock);
57226 	if (likely(req->head)) {
57227@@ -1791,6 +1797,8 @@ static int aio_poll(struct aio_kiocb *aiocb, const struct iocb *iocb)
57228 	spin_unlock_irq(&ctx->ctx_lock);
57229 	if (mask)
57230 		iocb_put(aiocb);
57231+	/* release the extra reference for vfs_poll() */
57232+	fput(req->file);
57233 	return apt.error;
57234 }
57235
57236diff --git a/fs/btrfs/block-group.c b/fs/btrfs/block-group.c
57237index c99e293b5..9a2861604 100644
57238--- a/fs/btrfs/block-group.c
57239+++ b/fs/btrfs/block-group.c
57240@@ -1824,6 +1824,41 @@ static struct btrfs_block_group *btrfs_create_block_group_cache(
57241 	return cache;
57242 }
57243
57244+static int check_exist_chunk(struct btrfs_fs_info *fs_info, u64 start, u64 len,
57245+			     u64 flags)
57246+{
57247+	struct btrfs_mapping_tree *map_tree = &fs_info->mapping_tree;
57248+	struct extent_map *em;
57249+	int ret;
57250+
57251+	read_lock(&map_tree->map_tree.lock);
57252+	em = lookup_extent_mapping(&map_tree->map_tree, start, len);
57253+	read_unlock(&map_tree->map_tree.lock);
57254+
57255+	if (!em) {
57256+		btrfs_err_rl(fs_info,
57257+	"block group start=%llu len=%llu doesn't have corresponding chunk",
57258+			     start, len);
57259+		ret = -ENOENT;
57260+		goto out;
57261+	}
57262+	if (em->start != start || em->len != len ||
57263+	    (em->map_lookup->type & BTRFS_BLOCK_GROUP_TYPE_MASK) !=
57264+	    (flags & BTRFS_BLOCK_GROUP_TYPE_MASK)) {
57265+		btrfs_err_rl(fs_info,
57266+"block group start=%llu len=%llu flags=0x%llx doesn't match with chunk start=%llu len=%llu flags=0x%llx",
57267+			     start, len , flags & BTRFS_BLOCK_GROUP_TYPE_MASK,
57268+			     em->start, em->len, em->map_lookup->type &
57269+			     BTRFS_BLOCK_GROUP_TYPE_MASK);
57270+		ret = -EUCLEAN;
57271+		goto out;
57272+	}
57273+	ret = 0;
57274+out:
57275+	free_extent_map(em);
57276+	return ret;
57277+}
57278+
57279 /*
57280  * Iterate all chunks and verify that each of them has the corresponding block
57281  * group
57282@@ -2021,6 +2056,9 @@ int btrfs_read_block_groups(struct btrfs_fs_info *info)
57283 		need_clear = 1;
57284
57285 	while (1) {
57286+		struct btrfs_block_group_item bg;
57287+		int slot;
57288+
57289 		ret = find_first_block_group(info, path, &key);
57290 		if (ret > 0)
57291 			break;
57292diff --git a/fs/fat/dir.c b/fs/fat/dir.c
57293index c4a274285..5972b82de 100644
57294--- a/fs/fat/dir.c
57295+++ b/fs/fat/dir.c
57296@@ -565,7 +565,8 @@ static int __fat_readdir(struct inode *inode, struct file *file,
57297 	const char *fill_name = NULL;
57298 	int fake_offset = 0;
57299 	loff_t cpos;
57300-	int short_len = 0, fill_len = 0;
57301+	int short_len;
57302+	int fill_len;
57303 	int ret = 0;
57304
57305 	mutex_lock(&sbi->s_lock);
57306@@ -614,12 +615,13 @@ static int __fat_readdir(struct inode *inode, struct file *file,
57307 			bh = NULL;
57308 			ret = status;
57309 			goto end_of_dir;
57310-		} else if (status == PARSE_INVALID)
57311+		} else if (status == PARSE_INVALID) {
57312 			goto record_end;
57313-		else if (status == PARSE_NOT_LONGNAME)
57314+		} else if (status == PARSE_NOT_LONGNAME) {
57315 			goto parse_record;
57316-		else if (status == PARSE_EOF)
57317+		} else if (status == PARSE_EOF) {
57318 			goto end_of_dir;
57319+		}
57320
57321 		if (nr_slots) {
57322 			void *longname = unicode + FAT_MAX_UNI_CHARS;
57323@@ -672,8 +674,9 @@ static int __fat_readdir(struct inode *inode, struct file *file,
57324 		if (tmp) {
57325 			inum = tmp->i_ino;
57326 			iput(tmp);
57327-		} else
57328+		} else {
57329 			inum = iunique(sb, MSDOS_ROOT_INO);
57330+		}
57331 		if (!dir_emit(ctx, fill_name, fill_len, inum,
57332 			    (de->attr & ATTR_DIR) ? DT_DIR : DT_REG))
57333 			goto fill_failed;
57334@@ -783,6 +786,388 @@ static int fat_ioctl_readdir(struct inode *inode, struct file *file,
57335 		ret = buf.result;
57336 	return ret;
57337 }
57338+#ifdef CONFIG_HISI_MC
57339+/*
57340+ * This is the "fatfilldirall_t" function type,
57341+ * used by fat_ioctl_filldirall to let
57342+ * the kernel specify what kind of dirent layout it wants to have.
57343+ * This allows the kernel to read directories into kernel space or
57344+ * to have different dirent layouts depending on the binary type.
57345+ */
57346+typedef int (*fatfilldirall_t)(void *__buf, const char *name,
57347+		int name_len, loff_t offset, u64 ino,
57348+		unsigned int d_type, struct msdos_dir_entry *de,
57349+		char *d_createtime);
57350+struct fatdirall_context {
57351+	const fatfilldirall_t actor;
57352+	loff_t pos;
57353+};
57354+
57355+struct fat_ioctl_filldirall_callback {
57356+	struct fatdirall_context ctx;
57357+	struct fat_direntall __user *current_dir;
57358+	struct fat_direntall __user *previous;
57359+	int count;
57360+	int usecount;
57361+	int error;
57362+	int result;
57363+	const char *longname;
57364+	int long_len;
57365+	const char *shortname;
57366+	int short_len;
57367+};
57368+
57369+static inline bool fat_dir_emit(struct fatdirall_context *ctx,
57370+		const char *name, int namelen,
57371+		u64 ino, unsigned type,
57372+		struct msdos_dir_entry *de,
57373+		char *d_createtime)
57374+{
57375+	return ctx->actor(ctx, name, namelen, ctx->pos, ino,
57376+			type, de, d_createtime) == 0;
57377+}
57378+static inline bool fat_dir_emit_dot(struct file *file,
57379+					struct fatdirall_context *ctx,
57380+					struct msdos_dir_entry *de,
57381+					char *d_createtime)
57382+{
57383+	return ctx->actor(ctx, ".", 1, ctx->pos,
57384+			file->f_path.dentry->d_inode->i_ino,
57385+			DT_DIR, de, d_createtime) == 0;
57386+}
57387+static inline bool fat_dir_emit_dotdot(struct file *file,
57388+					struct fatdirall_context *ctx,
57389+					struct msdos_dir_entry *de,
57390+					char *d_createtime)
57391+{
57392+	return ctx->actor(ctx, "..", 2, ctx->pos,
57393+			parent_ino(file->f_path.dentry),
57394+			DT_DIR, de, d_createtime) == 0;
57395+}
57396+
57397+static inline bool fat_dir_emit_dots(struct file *file,
57398+					struct fatdirall_context *ctx,
57399+					struct msdos_dir_entry *de,
57400+					char *d_createtime)
57401+{
57402+	if (ctx->pos == 0) {
57403+		if (!fat_dir_emit_dot(file, ctx, de, d_createtime))
57404+			return false;
57405+		ctx->pos = 1;
57406+	}
57407+	if (ctx->pos == 1) {
57408+		if (!fat_dir_emit_dotdot(file, ctx, de, d_createtime))
57409+			return false;
57410+		ctx->pos = 2;
57411+	}
57412+	return true;
57413+}
57414+
57415+
57416+static int __fat_readdirall(struct inode *inode, struct file *file,
57417+		struct fatdirall_context *ctx, int short_only,
57418+		struct fat_ioctl_filldirall_callback *both)
57419+{
57420+	struct super_block *sb = inode->i_sb;
57421+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
57422+	struct buffer_head *bh;
57423+	struct msdos_dir_entry *de;
57424+	unsigned char nr_slots;
57425+	wchar_t *unicode = NULL;
57426+	unsigned char bufname[FAT_MAX_SHORT_SIZE];
57427+	int isvfat = sbi->options.isvfat;
57428+	const char *fill_name = NULL;
57429+	int fake_offset = 0;
57430+	loff_t cpos;
57431+	int short_len = 0, fill_len = 0;
57432+	int ret = 0;
57433+	char d_createtime[8];
57434+
57435+	mutex_lock(&sbi->s_lock);
57436+
57437+	cpos = ctx->pos;
57438+	/* Fake . and .. for the root directory. */
57439+	if (inode->i_ino == MSDOS_ROOT_INO) {
57440+		if (!fat_dir_emit_dots(file, ctx, NULL, NULL))
57441+			goto out;
57442+		if (ctx->pos == 2) {
57443+			fake_offset = 1;
57444+			cpos = 0;
57445+		}
57446+	}
57447+	if (cpos & (sizeof(struct msdos_dir_entry) - 1)) {
57448+		ret = -ENOENT;
57449+		goto out;
57450+	}
57451+
57452+	bh = NULL;
57453+get_new:
57454+	if (fat_get_entry(inode, &cpos, &bh, &de) == -1)
57455+		goto end_of_dir;
57456+parse_record:
57457+	nr_slots = 0;
57458+	/*
57459+	 * Check for long filename entry, but if short_only, we don't
57460+	 * need to parse long filename.
57461+	 */
57462+	if (isvfat && !short_only) {
57463+		if (de->name[0] == DELETED_FLAG)
57464+			goto record_end;
57465+		if (de->attr != ATTR_EXT && (de->attr & ATTR_VOLUME))
57466+			goto record_end;
57467+		if (de->attr != ATTR_EXT && IS_FREE(de->name))
57468+			goto record_end;
57469+	} else {
57470+		if ((de->attr & ATTR_VOLUME) || IS_FREE(de->name))
57471+			goto record_end;
57472+	}
57473+
57474+	if (isvfat && de->attr == ATTR_EXT) {
57475+		int status = fat_parse_long(inode, &cpos, &bh, &de,
57476+				&unicode, &nr_slots);
57477+		if (status < 0) {
57478+			ctx->pos = cpos;
57479+			ret = status;
57480+			goto out;
57481+		} else if (status == PARSE_INVALID)
57482+			goto record_end;
57483+		else if (status == PARSE_NOT_LONGNAME)
57484+			goto parse_record;
57485+		else if (status == PARSE_EOF)
57486+			goto end_of_dir;
57487+
57488+		if (nr_slots) {
57489+			void *longname = unicode + FAT_MAX_UNI_CHARS;
57490+			int size = PATH_MAX - FAT_MAX_UNI_SIZE;
57491+			int len = fat_uni_to_x8(sb, unicode, longname, size);
57492+
57493+			fill_name = longname;
57494+			fill_len = len;
57495+
57496+			short_len = fat_parse_short(sb, de, bufname,
57497+					sbi->options.dotsOK);
57498+			if (short_len == 0)
57499+				goto record_end;
57500+
57501+			/* hack for fat_ioctl_filldir() */
57502+			both->longname = fill_name;
57503+			both->long_len = fill_len;
57504+			both->shortname = bufname;
57505+			both->short_len = short_len;
57506+			fill_name = NULL;
57507+			fill_len = 0;
57508+			goto start_filldir;
57509+		}
57510+	}
57511+
57512+	short_len = fat_parse_short(sb, de, bufname, sbi->options.dotsOK);
57513+	if (short_len == 0)
57514+		goto record_end;
57515+
57516+	fill_name = bufname;
57517+	fill_len = short_len;
57518+
57519+start_filldir:
57520+	if (!fake_offset)
57521+		ctx->pos = cpos - (nr_slots + 1)
57522+			* sizeof(struct msdos_dir_entry);
57523+
57524+	memset(d_createtime, 0, 8);
57525+	fat_time_fat2str(sbi, d_createtime, de->ctime,
57526+			de->cdate, de->ctime_cs);
57527+
57528+	if (!memcmp(de->name, MSDOS_DOT, MSDOS_NAME)) {
57529+		if (!fat_dir_emit_dot(file, ctx, de, d_createtime))
57530+			goto fill_failed;
57531+	} else if (!memcmp(de->name, MSDOS_DOTDOT, MSDOS_NAME)) {
57532+		if (!fat_dir_emit_dotdot(file, ctx, de, d_createtime))
57533+			goto fill_failed;
57534+	} else {
57535+		unsigned long inum;
57536+		loff_t i_pos = fat_make_i_pos(sb, bh, de);
57537+		struct inode *tmp = fat_iget(sb, i_pos);
57538+
57539+		if (tmp) {
57540+			inum = tmp->i_ino;
57541+			iput(tmp);
57542+		} else
57543+			inum = iunique(sb, MSDOS_ROOT_INO);
57544+		if (!fat_dir_emit(ctx, fill_name, fill_len, inum,
57545+					(de->attr & ATTR_DIR) ? DT_DIR : DT_REG,
57546+					de, d_createtime))
57547+			goto fill_failed;
57548+	}
57549+
57550+record_end:
57551+	fake_offset = 0;
57552+	ctx->pos = cpos;
57553+	goto get_new;
57554+end_of_dir:
57555+	ctx->pos = cpos;
57556+fill_failed:
57557+	brelse(bh);
57558+	if (unicode)
57559+		__putname(unicode);
57560+out:
57561+	mutex_unlock(&sbi->s_lock);
57562+	return ret;
57563+}
57564+
57565+static int fat_ioctl_filldirall(void *__buf, const char *name,
57566+				int name_len, loff_t offset,
57567+				u64 ino, unsigned int d_type,
57568+				struct msdos_dir_entry *de,
57569+				char *d_createtime)
57570+{
57571+	struct fat_direntall __user *dirent;
57572+	struct fat_ioctl_filldirall_callback *buf;
57573+	unsigned long d_ino;
57574+	int reclen = 0;
57575+	const char *longname = NULL;
57576+	int long_len = 0;
57577+	const char *shortname = NULL;
57578+	int short_len = 0;
57579+
57580+	buf = (struct fat_ioctl_filldirall_callback *) __buf;
57581+
57582+	if (name != NULL) {
57583+		reclen = ALIGN(offsetof(struct fat_direntall, d_name)
57584+				+ name_len + 2, sizeof(long));
57585+	} else {
57586+		longname = buf->longname;
57587+		long_len = buf->long_len;
57588+		shortname = buf->shortname;
57589+		short_len = buf->short_len;
57590+		reclen = ALIGN(offsetof(struct fat_direntall, d_name)
57591+				+ long_len + 2, sizeof(long));
57592+	}
57593+
57594+	buf->error = -EINVAL;   /* only used if we fail.. */
57595+
57596+	if (reclen >= buf->count)
57597+		return -EINVAL;
57598+
57599+	d_ino = ino;
57600+
57601+	if (sizeof(d_ino) < sizeof(ino) && d_ino != ino) {
57602+		buf->error = -EOVERFLOW;
57603+		return -EOVERFLOW;
57604+	}
57605+
57606+	dirent = buf->previous;
57607+
57608+	if (dirent) {
57609+		if (__put_user(offset, &dirent->d_off))
57610+			goto efault;
57611+	}
57612+
57613+	dirent = buf->current_dir;
57614+
57615+	if (__put_user(d_ino, &dirent->d_ino))
57616+		goto efault;
57617+
57618+	if (__put_user(reclen, &dirent->d_reclen))
57619+		goto efault;
57620+
57621+	if (name != NULL) {
57622+		if (copy_to_user(dirent->d_name, name, name_len))
57623+			goto efault;
57624+		if (__put_user(0, dirent->d_name + name_len))
57625+			goto efault;
57626+	} else {
57627+		if (copy_to_user(dirent->d_name, longname, long_len))
57628+			goto efault;
57629+		if (__put_user(0, dirent->d_name + long_len))
57630+			goto efault;
57631+	}
57632+
57633+	if (__put_user(d_type, &dirent->d_type))
57634+		goto efault;
57635+
57636+	if (de != NULL) {
57637+		u64 u_size = 0;
57638+		if (copy_to_user(&dirent->d_size, &u_size, sizeof(u64)))
57639+			goto efault;
57640+		if (copy_to_user(&dirent->d_size, &de->size, sizeof(u32)))
57641+			goto efault;
57642+	}
57643+
57644+	if (d_createtime != NULL) {
57645+		if (copy_to_user(dirent->d_createtime, d_createtime, 8))
57646+			goto efault;
57647+	}
57648+	buf->previous = dirent;
57649+	dirent = (void __user *)dirent + reclen;
57650+	buf->current_dir = dirent;
57651+	buf->count -= reclen;
57652+	buf->usecount += reclen;
57653+	return 0;
57654+efault:
57655+	buf->error = -EFAULT;
57656+	return -EFAULT;
57657+}
57658+
57659+
57660+static int fat_ioctl_readdirall(struct inode *inode, struct file *file,
57661+		void __user *dirent,
57662+		int short_only, int both)
57663+{
57664+	struct fat_ioctl_filldirall_callback buf = {
57665+		.ctx.actor = fat_ioctl_filldirall,
57666+	};
57667+
57668+	struct fat_direntall_buf __user *userbuf = dirent;
57669+	int ret;
57670+
57671+	buf.current_dir = &(userbuf->direntall);
57672+	buf.previous = NULL;
57673+	buf.error = 0;
57674+	buf.result = 0;
57675+	buf.usecount = 0;
57676+
57677+	if (get_user(buf.count, &(userbuf->d_count)))
57678+		return -EFAULT;
57679+
57680+	up_read(&inode->i_rwsem);
57681+	buf.ctx.pos = file->f_pos;
57682+	ret = -ENOENT;
57683+	if (!IS_DEADDIR(inode)) {
57684+		ret = __fat_readdirall(inode, file, &buf.ctx,
57685+				short_only, both ? &buf : NULL);
57686+		file->f_pos = buf.ctx.pos;
57687+	}
57688+	down_read(&inode->i_rwsem);
57689+
57690+	if (__put_user(buf.usecount, &(userbuf->d_usecount)))
57691+		return -EFAULT;
57692+	if (ret >= 0)
57693+		ret = buf.result;
57694+	return ret;
57695+}
57696+
57697+static int fat_dir_ioctl_readdirall(struct file *filp, unsigned int cmd,
57698+					unsigned long arg)
57699+{
57700+	struct inode *inode = filp->f_path.dentry->d_inode;
57701+	struct fat_direntall_buf __user *direntallbuf;
57702+	int short_only, both;
57703+
57704+	direntallbuf = (struct fat_direntall_buf __user *)arg;
57705+
57706+	if (!access_ok(VERIFY_WRITE, direntallbuf,
57707+			sizeof(struct fat_direntall_buf)))
57708+		return -EFAULT;
57709+	if (put_user(0, &(direntallbuf->direntall.d_reclen)))
57710+		return -EFAULT;
57711+	if (put_user(0, &(direntallbuf->d_usecount)))
57712+		return -EFAULT;
57713+	short_only = 0;
57714+	both = 1;
57715+	return fat_ioctl_readdirall(inode, filp, direntallbuf,
57716+			short_only, both);
57717+}
57718+#endif
57719+
57720
57721 static long fat_dir_ioctl(struct file *filp, unsigned int cmd,
57722 			  unsigned long arg)
57723@@ -790,7 +1175,10 @@ static long fat_dir_ioctl(struct file *filp, unsigned int cmd,
57724 	struct inode *inode = file_inode(filp);
57725 	struct __fat_dirent __user *d1 = (struct __fat_dirent __user *)arg;
57726 	int short_only, both;
57727-
57728+#ifdef CONFIG_HISI_MC
57729+	if (VFAT_IOCTL_READDIR_ALL == cmd)
57730+		return fat_dir_ioctl_readdirall(filp, cmd, arg);
57731+#endif
57732 	switch (cmd) {
57733 	case VFAT_IOCTL_READDIR_SHORT:
57734 		short_only = 1;
57735@@ -1094,11 +1482,15 @@ static int fat_zeroed_cluster(struct inode *dir, sector_t blknr, int nr_used,
57736 			err = -ENOMEM;
57737 			goto error;
57738 		}
57739+#ifndef CONFIG_ARCH_HISI_BVT
57740 		/* Avoid race with userspace read via bdev */
57741 		lock_buffer(bhs[n]);
57742+#endif
57743 		memset(bhs[n]->b_data, 0, sb->s_blocksize);
57744 		set_buffer_uptodate(bhs[n]);
57745+#ifndef CONFIG_ARCH_HISI_BVT
57746 		unlock_buffer(bhs[n]);
57747+#endif
57748 		mark_buffer_dirty_inode(bhs[n], dir);
57749
57750 		n++;
57751@@ -1155,8 +1547,10 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts)
57752 	fat_time_unix2fat(sbi, ts, &time, &date, &time_cs);
57753
57754 	de = (struct msdos_dir_entry *)bhs[0]->b_data;
57755+#ifndef CONFIG_ARCH_HISI_BVT
57756 	/* Avoid race with userspace read via bdev */
57757 	lock_buffer(bhs[0]);
57758+#endif
57759 	/* filling the new directory slots ("." and ".." entries) */
57760 	memcpy(de[0].name, MSDOS_DOT, MSDOS_NAME);
57761 	memcpy(de[1].name, MSDOS_DOTDOT, MSDOS_NAME);
57762@@ -1179,7 +1573,9 @@ int fat_alloc_new_dir(struct inode *dir, struct timespec64 *ts)
57763 	de[0].size = de[1].size = 0;
57764 	memset(de + 2, 0, sb->s_blocksize - 2 * sizeof(*de));
57765 	set_buffer_uptodate(bhs[0]);
57766+#ifndef CONFIG_ARCH_HISI_BVT
57767 	unlock_buffer(bhs[0]);
57768+#endif
57769 	mark_buffer_dirty_inode(bhs[0], dir);
57770
57771 	err = fat_zeroed_cluster(dir, blknr, 1, bhs, MAX_BUF_PER_PAGE);
57772@@ -1237,11 +1633,15 @@ static int fat_add_new_entries(struct inode *dir, void *slots, int nr_slots,
57773
57774 			/* fill the directory entry */
57775 			copy = min(size, sb->s_blocksize);
57776+#ifndef CONFIG_ARCH_HISI_BVT
57777 			/* Avoid race with userspace read via bdev */
57778 			lock_buffer(bhs[n]);
57779+#endif
57780 			memcpy(bhs[n]->b_data, slots, copy);
57781 			set_buffer_uptodate(bhs[n]);
57782+#ifndef CONFIG_ARCH_HISI_BVT
57783 			unlock_buffer(bhs[n]);
57784+#endif
57785 			mark_buffer_dirty_inode(bhs[n], dir);
57786 			slots += copy;
57787 			size -= copy;
57788diff --git a/fs/fat/fat.h b/fs/fat/fat.h
57789index 922a0c6ba..a84663246 100644
57790--- a/fs/fat/fat.h
57791+++ b/fs/fat/fat.h
57792@@ -444,6 +444,10 @@ extern void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts,
57793 			      __le16 __time, __le16 __date, u8 time_cs);
57794 extern void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts,
57795 			      __le16 *time, __le16 *date, u8 *time_cs);
57796+#ifdef CONFIG_HISI_MC
57797+extern void fat_time_fat2str(struct msdos_sb_info *sbi, char *d_createtime,
57798+		__le16 __time, __le16 __date, u8 time_cs);
57799+#endif
57800 extern int fat_truncate_time(struct inode *inode, struct timespec64 *now,
57801 			     int flags);
57802 extern int fat_update_time(struct inode *inode, struct timespec64 *now,
57803diff --git a/fs/fat/fatent.c b/fs/fat/fatent.c
57804index f7e3304b7..4351eaa8b 100644
57805--- a/fs/fat/fatent.c
57806+++ b/fs/fat/fatent.c
57807@@ -379,6 +379,9 @@ static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs,
57808 	int err, n, copy;
57809
57810 	err = 0;
57811+#ifdef CONFIG_HISI_MC
57812+	return 0;
57813+#endif
57814 	for (copy = 1; copy < sbi->fats; copy++) {
57815 		sector_t backup_fat = sbi->fat_length * copy;
57816
57817@@ -388,11 +391,15 @@ static int fat_mirror_bhs(struct super_block *sb, struct buffer_head **bhs,
57818 				err = -ENOMEM;
57819 				goto error;
57820 			}
57821+#ifndef CONFIG_ARCH_HISI_BVT
57822 			/* Avoid race with userspace read via bdev */
57823 			lock_buffer(c_bh);
57824+#endif
57825 			memcpy(c_bh->b_data, bhs[n]->b_data, sb->s_blocksize);
57826 			set_buffer_uptodate(c_bh);
57827+#ifndef CONFIG_ARCH_HISI_BVT
57828 			unlock_buffer(c_bh);
57829+#endif
57830 			mark_buffer_dirty_inode(c_bh, sbi->fat_inode);
57831 			if (sb->s_flags & SB_SYNCHRONOUS)
57832 				err = sync_dirty_buffer(c_bh);
57833diff --git a/fs/fat/file.c b/fs/fat/file.c
57834index f9ee27cf4..f424520d7 100644
57835--- a/fs/fat/file.c
57836+++ b/fs/fat/file.c
57837@@ -198,6 +198,17 @@ int fat_file_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
57838 	return blkdev_issue_flush(inode->i_sb->s_bdev, GFP_KERNEL);
57839 }
57840
57841+#ifdef CONFIG_HISI_MC
57842+int fat_file_flush(struct file *file, fl_owner_t id)
57843+{
57844+	struct address_space * mapping = file->f_mapping;
57845+	struct inode *inode = mapping->host;
57846+
57847+	inode->i_sb->s_op->write_inode(inode, NULL);
57848+
57849+	return 0;
57850+}
57851+#endif
57852
57853 const struct file_operations fat_file_operations = {
57854 	.llseek		= generic_file_llseek,
57855@@ -211,6 +222,9 @@ const struct file_operations fat_file_operations = {
57856 	.splice_read	= generic_file_splice_read,
57857 	.splice_write	= iter_file_splice_write,
57858 	.fallocate	= fat_fallocate,
57859+#ifdef CONFIG_HISI_MC
57860+	.flush		= fat_file_flush,
57861+#endif
57862 };
57863
57864 static int fat_cont_expand(struct inode *inode, loff_t size)
57865@@ -461,7 +475,13 @@ static int fat_allow_set_time(struct msdos_sb_info *sbi, struct inode *inode)
57866 	/* use a default check */
57867 	return 0;
57868 }
57869-
57870+#ifdef CONFIG_HISI_MC
57871+void reset_mmu_private(struct inode *inode, loff_t offset)
57872+{
57873+	MSDOS_I(inode)->mmu_private = offset;
57874+	inode->i_ctime = inode->i_mtime = ((struct timespec64) { get_seconds(), 0 });
57875+}
57876+#endif
57877 #define TIMES_SET_FLAGS	(ATTR_MTIME_SET | ATTR_ATIME_SET | ATTR_TIMES_SET)
57878 /* valid file mode bits */
57879 #define FAT_VALID_MODE	(S_IFREG | S_IFDIR | S_IRWXUGO)
57880@@ -494,6 +514,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
57881 	 * hole before it. XXX: this is no longer true with new truncate
57882 	 * sequence.
57883 	 */
57884+#ifndef CONFIG_HISI_MC
57885 	if (attr->ia_valid & ATTR_SIZE) {
57886 		inode_dio_wait(inode);
57887
57888@@ -504,7 +525,7 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
57889 			attr->ia_valid &= ~ATTR_SIZE;
57890 		}
57891 	}
57892-
57893+#endif
57894 	if (((attr->ia_valid & ATTR_UID) &&
57895 	     (!uid_eq(attr->ia_uid, sbi->options.fs_uid))) ||
57896 	    ((attr->ia_valid & ATTR_GID) &&
57897@@ -534,6 +555,9 @@ int fat_setattr(struct dentry *dentry, struct iattr *attr)
57898 			goto out;
57899 		down_write(&MSDOS_I(inode)->truncate_lock);
57900 		truncate_setsize(inode, attr->ia_size);
57901+#ifdef CONFIG_HISI_MC
57902+		reset_mmu_private(inode, attr->ia_size);
57903+#endif
57904 		fat_truncate_blocks(inode, attr->ia_size);
57905 		up_write(&MSDOS_I(inode)->truncate_lock);
57906 	}
57907diff --git a/fs/fat/inode.c b/fs/fat/inode.c
57908index bab9b202b..769444c64 100644
57909--- a/fs/fat/inode.c
57910+++ b/fs/fat/inode.c
57911@@ -628,8 +628,9 @@ static void fat_free_eofblocks(struct inode *inode)
57912 			round_up(MSDOS_I(inode)->mmu_private,
57913 				MSDOS_SB(inode->i_sb)->cluster_size)) {
57914 		int err;
57915-
57916+#ifndef CONFIG_HISI_MC
57917 		fat_truncate_blocks(inode, MSDOS_I(inode)->mmu_private);
57918+#endif
57919 		/* Fallocate results in updating the i_start/iogstart
57920 		 * for the zero byte file. So, make it return to
57921 		 * original state during evict and commit it to avoid
57922@@ -899,7 +900,70 @@ static int __fat_write_inode(struct inode *inode, int wait)
57923 	brelse(bh);
57924 	return err;
57925 }
57926+#ifdef CONFIG_HISI_MC
57927+static int __fat_write_inode_(struct inode *inode, int wait)
57928+{
57929+	struct super_block *sb = inode->i_sb;
57930+	struct msdos_sb_info *sbi = MSDOS_SB(sb);
57931+	struct buffer_head *bh;
57932+	struct msdos_dir_entry *raw_entry;
57933+	loff_t i_pos;
57934+	sector_t blocknr;
57935+	int err = 0;
57936+	int offset;
57937+
57938+	if (inode->i_ino == MSDOS_ROOT_INO)
57939+		return 0;
57940+
57941+retry:
57942+	i_pos = fat_i_pos_read(sbi, inode);
57943+	if (!i_pos)
57944+		return 0;
57945+
57946+	fat_get_blknr_offset(sbi, i_pos, &blocknr, &offset);
57947+	bh = sb_bread(sb, blocknr);
57948+	if (!bh) {
57949+		fat_msg(sb, KERN_ERR, "unable to read inode block "
57950+		       "for updating (i_pos %lld)", i_pos);
57951+		return -EIO;
57952+	}
57953+	spin_lock(&sbi->inode_hash_lock);
57954+	if (i_pos != MSDOS_I(inode)->i_pos) {
57955+		spin_unlock(&sbi->inode_hash_lock);
57956+		brelse(bh);
57957+		goto retry;
57958+	}
57959
57960+	raw_entry = &((struct msdos_dir_entry *) (bh->b_data))[offset];
57961+	if (S_ISDIR(inode->i_mode)) {
57962+		raw_entry->size = 0;
57963+	} else {
57964+		if ((raw_entry->start != 0) || (raw_entry->starthi != 0)) {
57965+			spin_unlock(&sbi->inode_hash_lock);
57966+			goto file_out;
57967+		}
57968+		raw_entry->size = cpu_to_le32(inode->i_size);
57969+	}
57970+	raw_entry->attr = fat_make_attrs(inode);
57971+	fat_set_start(raw_entry, MSDOS_I(inode)->i_logstart);
57972+	fat_time_unix2fat(sbi, &inode->i_mtime, &raw_entry->time,
57973+			  &raw_entry->date, NULL);
57974+	if (sbi->options.isvfat) {
57975+		__le16 atime;
57976+		fat_time_unix2fat(sbi, &inode->i_ctime, &raw_entry->ctime,
57977+				  &raw_entry->cdate, &raw_entry->ctime_cs);
57978+		fat_time_unix2fat(sbi, &inode->i_atime, &atime,
57979+				  &raw_entry->adate, NULL);
57980+	}
57981+	spin_unlock(&sbi->inode_hash_lock);
57982+	mark_buffer_dirty(bh);
57983+	if (wait)
57984+		err = sync_dirty_buffer(bh);
57985+file_out:
57986+	brelse(bh);
57987+	return err;
57988+}
57989+#endif
57990 static int fat_write_inode(struct inode *inode, struct writeback_control *wbc)
57991 {
57992 	int err;
57993@@ -910,8 +974,17 @@ static int fat_write_inode(struct inode *inode, struct writeback_control *wbc)
57994 		mutex_lock(&MSDOS_SB(sb)->s_lock);
57995 		err = fat_clusters_flush(sb);
57996 		mutex_unlock(&MSDOS_SB(sb)->s_lock);
57997-	} else
57998-		err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
57999+	} else {
58000+#ifdef CONFIG_HISI_MC
58001+		if (NULL == wbc) {
58002+			err = __fat_write_inode(inode, 1);
58003+		} else {
58004+			err = __fat_write_inode_(inode, wbc->sync_mode == WB_SYNC_ALL);
58005+		}
58006+#else
58007+			err = __fat_write_inode(inode, wbc->sync_mode == WB_SYNC_ALL);
58008+#endif
58009+	}
58010
58011 	return err;
58012 }
58013diff --git a/fs/fat/misc.c b/fs/fat/misc.c
58014index f1b2a1fc2..ddb5cf98a 100644
58015--- a/fs/fat/misc.c
58016+++ b/fs/fat/misc.c
58017@@ -198,7 +198,8 @@ static inline int fat_tz_offset(struct msdos_sb_info *sbi)
58018 void fat_time_fat2unix(struct msdos_sb_info *sbi, struct timespec64 *ts,
58019 		       __le16 __time, __le16 __date, u8 time_cs)
58020 {
58021-	u16 time = le16_to_cpu(__time), date = le16_to_cpu(__date);
58022+	u16 time = le16_to_cpu(__time);
58023+	u16 date = le16_to_cpu(__date);
58024 	time64_t second;
58025 	long day, leap_day, month, year;
58026
58027@@ -267,6 +268,35 @@ void fat_time_unix2fat(struct msdos_sb_info *sbi, struct timespec64 *ts,
58028 }
58029 EXPORT_SYMBOL_GPL(fat_time_unix2fat);
58030
58031+#ifdef CONFIG_HISI_MC
58032+void fat_time_fat2str(struct msdos_sb_info *sbi, char *d_createtime,
58033+		__le16 __time, __le16 __date, u8 time_cs)
58034+{
58035+	u16 time = le16_to_cpu(__time), date = le16_to_cpu(__date);
58036+	time_t day, month, year;
58037+
58038+	year  = date >> 9;
58039+	month = max(1, (date >> 5) & 0xf);
58040+	day   = max(1, date & 0x1f) - 1;
58041+
58042+	d_createtime[0] = year;
58043+	d_createtime[1] = month;
58044+	d_createtime[2] = day;
58045+	d_createtime[3] = (time >> 11);  /*hour*/
58046+	d_createtime[4] = ((time >> 5) & 0x3f);  /*min*/
58047+	d_createtime[5] = (time & 0x1f);  /*second 2s*/
58048+
58049+	if (!sbi->options.tz_set)
58050+		d_createtime[4] += sys_tz.tz_minuteswest;
58051+	else
58052+		d_createtime[4] -= sbi->options.time_offset;
58053+
58054+	if (time_cs)
58055+		d_createtime[5] += (time_cs / 100); /*second 1s*/
58056+}
58057+EXPORT_SYMBOL_GPL(fat_time_fat2str);
58058+#endif
58059+
58060 static inline struct timespec64 fat_timespec64_trunc_2secs(struct timespec64 ts)
58061 {
58062 	return (struct timespec64){ ts.tv_sec & ~1ULL, 0 };
58063diff --git a/fs/jffs2/compr.h b/fs/jffs2/compr.h
58064index 5e91d578f..01116b8ea 100644
58065--- a/fs/jffs2/compr.h
58066+++ b/fs/jffs2/compr.h
58067@@ -29,9 +29,15 @@
58068 #define JFFS2_DYNRUBIN_PRIORITY  20
58069 #define JFFS2_LZARI_PRIORITY     30
58070 #define JFFS2_RTIME_PRIORITY     50
58071+
58072+#ifdef CONFIG_HISI_MC
58073+#define JFFS2_LZMA_PRIORITY      70
58074+#define JFFS2_ZLIB_PRIORITY      80
58075+#define JFFS2_LZO_PRIORITY       90
58076+#else
58077 #define JFFS2_ZLIB_PRIORITY      60
58078 #define JFFS2_LZO_PRIORITY       80
58079-
58080+#endif
58081
58082 #define JFFS2_RUBINMIPS_DISABLED /* RUBINs will be used only */
58083 #define JFFS2_DYNRUBIN_DISABLED  /*	   for decompression */
58084diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
58085index df46f2d3f..b38ea130b 100644
58086--- a/fs/ubifs/file.c
58087+++ b/fs/ubifs/file.c
58088@@ -1493,6 +1493,9 @@ static int ubifs_releasepage(struct page *page, gfp_t unused_gfp_flags)
58089 	 */
58090 	if (PageWriteback(page))
58091 		return 0;
58092+#ifdef CONFIG_ARCH_HISI_BVT
58093+	return 0;
58094+#endif
58095 	ubifs_assert(c, PagePrivate(page));
58096 	ubifs_assert(c, 0);
58097 	detach_page_private(page);
58098diff --git a/include/dt-bindings/clock/hi3516dv300-clock.h b/include/dt-bindings/clock/hi3516dv300-clock.h
58099new file mode 100644
58100index 000000000..408c9b09d
58101--- /dev/null
58102+++ b/include/dt-bindings/clock/hi3516dv300-clock.h
58103@@ -0,0 +1,100 @@
58104+/*
58105+ * Copyright (c) 2016-2017 HiSilicon Technologies Co., Ltd.
58106+ *
58107+ * This program is free software; you can redistribute  it and/or modify it
58108+ * under  the terms of  the GNU General Public License as published by the
58109+ * Free Software Foundation;  either version 2 of the  License, or (at your
58110+ * option) any later version.
58111+ *
58112+ * This program is distributed in the hope that it will be useful,
58113+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58114+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
58115+ * GNU General Public License for more details.
58116+ *
58117+ * You should have received a copy of the GNU General Public License
58118+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
58119+ *
58120+ */
58121+
58122+#ifndef __DTS_HI3516DV300_CLOCK_H
58123+#define __DTS_HI3516DV300_CLOCK_H
58124+
58125+/* clk in Hi3516CV500 CRG */
58126+/* fixed rate clocks */
58127+#define HI3516DV300_FIXED_3M        1
58128+#define HI3516DV300_FIXED_6M        2
58129+#define HI3516DV300_FIXED_12M       3
58130+#define HI3516DV300_FIXED_24M       4
58131+#define HI3516DV300_FIXED_50M       5
58132+#define HI3516DV300_FIXED_83P3M     6
58133+#define HI3516DV300_FIXED_100M      7
58134+#define HI3516DV300_FIXED_125M      8
58135+#define HI3516DV300_FIXED_148P5M    9
58136+#define HI3516DV300_FIXED_150M      10
58137+#define HI3516DV300_FIXED_200M      11
58138+#define HI3516DV300_FIXED_250M      12
58139+#define HI3516DV300_FIXED_300M      13
58140+#define HI3516DV300_FIXED_324M      14
58141+#define HI3516DV300_FIXED_342M      15
58142+#define HI3516DV300_FIXED_375M      16
58143+#define HI3516DV300_FIXED_400M      17
58144+#define HI3516DV300_FIXED_448M      18
58145+#define HI3516DV300_FIXED_500M      19
58146+#define HI3516DV300_FIXED_540M      20
58147+#define HI3516DV300_FIXED_600M      21
58148+#define HI3516DV300_FIXED_750M      22
58149+#define HI3516DV300_FIXED_1000M     23
58150+#define HI3516DV300_FIXED_1500M     24
58151+#define HI3516DV300_FIXED_54M       25
58152+#define HI3516DV300_FIXED_25M       26
58153+#define HI3516DV300_FIXED_163M      27
58154+#define HI3516DV300_FIXED_257M      28
58155+#define HI3516DV300_FIXED_396M      29
58156+
58157+/* mux clocks */
58158+#define HI3516DV300_SYSAXI_CLK      30
58159+#define HI3516DV300_SYSAPB_CLK      31
58160+#define HI3516DV300_FMC_MUX         32
58161+#define HI3516DV300_UART_MUX        33
58162+#define HI3516DV300_MMC0_MUX        34
58163+#define HI3516DV300_MMC1_MUX        35
58164+#define HI3516DV300_MMC2_MUX        36
58165+#define HI3516DV300_UART1_MUX       33
58166+#define HI3516DV300_UART2_MUX       37
58167+#define HI3516DV300_UART4_MUX       38
58168+#define HI3516DV300_ETH_MUX     39
58169+
58170+/* gate clocks */
58171+#define HI3516DV300_UART0_CLK       40
58172+#define HI3516DV300_UART1_CLK       41
58173+#define HI3516DV300_UART2_CLK       42
58174+#define HI3516DV300_FMC_CLK         43
58175+#define HI3516DV300_ETH0_CLK        44
58176+#define HI3516DV300_USB2_BUS_CLK    45
58177+#define HI3516DV300_USB2_CLK        46
58178+#define HI3516DV300_DMAC_CLK        47
58179+#define HI3516DV300_SPI0_CLK        48
58180+#define HI3516DV300_SPI1_CLK        49
58181+#define HI3516DV300_MMC0_CLK        50
58182+#define HI3516DV300_MMC1_CLK        51
58183+#define HI3516DV300_MMC2_CLK        52
58184+#define HI3516DV300_UART4_CLK       53
58185+#define HI3516DV300_SPI2_CLK        54
58186+#define HI3516DV300_I2C0_CLK        55
58187+#define HI3516DV300_I2C1_CLK        56
58188+#define HI3516DV300_I2C2_CLK        57
58189+#define HI3516DV300_I2C3_CLK        58
58190+#define HI3516DV300_I2C4_CLK        59
58191+#define HI3516DV300_I2C5_CLK        60
58192+#define HI3516DV300_I2C6_CLK        61
58193+#define HI3516DV300_I2C7_CLK        62
58194+#define HI3516DV300_UART3_MUX       63
58195+#define HI3516DV300_UART3_CLK       64
58196+#define HI3516DV300_DMAC_AXICLK     70
58197+#define HI3516DV300_PWM_CLK         71
58198+#define HI3516DV300_PWM_MUX         72
58199+
58200+#define HI3516DV300_NR_CLKS     256
58201+#define HI3516DV300_NR_RSTS     256
58202+
58203+#endif  /* __DTS_HI3516DV300_CLOCK_H */
58204diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
58205index 31febd3e1..0fa3ac740 100644
58206--- a/include/linux/blkdev.h
58207+++ b/include/linux/blkdev.h
58208@@ -1384,7 +1384,11 @@ static inline bool bdev_is_partition(struct block_device *bdev)
58209 enum blk_default_limits {
58210 	BLK_MAX_SEGMENTS	= 128,
58211 	BLK_SAFE_MAX_SECTORS	= 255,
58212+#ifndef CONFIG_HISI_MC
58213 	BLK_DEF_MAX_SECTORS	= 2560,
58214+#else
58215+	BLK_DEF_MAX_SECTORS	= 8192,
58216+#endif
58217 	BLK_MAX_SEGMENT_SIZE	= 65536,
58218 	BLK_SEG_BOUNDARY_MASK	= 0xFFFFFFFFUL,
58219 };
58220diff --git a/include/linux/cpu.h b/include/linux/cpu.h
58221index d6428aaf6..a8d659c9a 100644
58222--- a/include/linux/cpu.h
58223+++ b/include/linux/cpu.h
58224@@ -41,6 +41,7 @@ extern bool arch_match_cpu_phys_id(int cpu, u64 phys_id);
58225 extern bool arch_find_n_match_cpu_physical_id(struct device_node *cpun,
58226 					      int cpu, unsigned int *thread);
58227
58228+extern int hi_register_cpu_notifier(struct notifier_block *nb);
58229 extern int cpu_add_dev_attr(struct device_attribute *attr);
58230 extern void cpu_remove_dev_attr(struct device_attribute *attr);
58231
58232diff --git a/include/linux/fb.h b/include/linux/fb.h
58233index ecfbcc055..b8567818b 100644
58234--- a/include/linux/fb.h
58235+++ b/include/linux/fb.h
58236@@ -293,6 +293,12 @@ struct fb_ops {
58237 	/* called at KDB enter and leave time to prepare the console */
58238 	int (*fb_debug_enter)(struct fb_info *info);
58239 	int (*fb_debug_leave)(struct fb_info *info);
58240+#ifdef CONFIG_ARCH_HISI_BVT
58241+#ifdef CONFIG_DMA_SHARED_BUFFER
58242+	/* Export the frame buffer as a dmabuf object */
58243+	struct dma_buf *(*fb_dmabuf_export)(struct fb_info *info);
58244+#endif
58245+#endif
58246 };
58247
58248 #ifdef CONFIG_FB_TILEBLITTING
58249diff --git a/include/linux/hi_cma.h b/include/linux/hi_cma.h
58250new file mode 100644
58251index 000000000..38444524f
58252--- /dev/null
58253+++ b/include/linux/hi_cma.h
58254@@ -0,0 +1,54 @@
58255+/*
58256+ * hi_cma.h
58257+ *
58258+ * Copyright (c) 2019 HiSilicon Technologies Co., Ltd.
58259+ *
58260+ * This program is free software; you can redistribute it and/or modify
58261+ * it under the terms of the GNU General Public License as published by
58262+ * the Free Software Foundation; either version 2 of the License, or
58263+ * (at your option) any later version.
58264+ *
58265+ * This program is distributed in the hope that it will be useful,
58266+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
58267+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
58268+ * GNU General Public License for more details.
58269+ *
58270+ * You should have received a copy of the GNU General Public License
58271+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
58272+ */
58273+#ifndef __HI_CMA_H__
58274+#define __HI_CMA_H__
58275+
58276+#include <linux/device.h>
58277+#include <linux/dma-mapping.h>
58278+#include <linux/dma-map-ops.h>
58279+#include <linux/module.h>
58280+#include <linux/string.h>
58281+#include <linux/cma.h>
58282+#include <linux/memblock.h>
58283+#include <linux/of.h>
58284+#include <linux/of_fdt.h>
58285+#include <linux/of_reserved_mem.h>
58286+
58287+#define NAME_LEN_MAX   64
58288+#define ZONE_MAX       64
58289+
58290+struct cma_zone {
58291+	struct device pdev;
58292+	char name[NAME_LEN_MAX];
58293+	gfp_t gfp;
58294+	phys_addr_t phys_start;
58295+	phys_addr_t nbytes;
58296+	u32 alloc_type;
58297+	u32 block_align;
58298+};
58299+
58300+#ifdef CONFIG_CMA
58301+int is_hicma_address(phys_addr_t phys, unsigned long size);
58302+phys_addr_t hisi_get_zones_start(void);
58303+struct cma_zone *hisi_get_cma_zone(const char *name);
58304+struct device *hisi_get_cma_device(const char *name);
58305+int __init hisi_declare_heap_memory(void);
58306+#endif /* CONFIG_CMA */
58307+
58308+#endif
58309diff --git a/include/linux/hiedmac.h b/include/linux/hiedmac.h
58310new file mode 100644
58311index 000000000..26157899a
58312--- /dev/null
58313+++ b/include/linux/hiedmac.h
58314@@ -0,0 +1,65 @@
58315+#ifndef __DMAC_H__
58316+#define __DMAC_H__
58317+
58318+#define DMAC_ERROR_BASE     0x64
58319+
58320+#define DMAC_CHN_SUCCESS            (DMAC_ERROR_BASE + 0x10)
58321+#define DMAC_CHN_ERROR              (DMAC_ERROR_BASE + 0x11)
58322+#define DMAC_CHN_TIMEOUT            (DMAC_ERROR_BASE + 0x12)
58323+#define DMAC_CHN_ALLOCAT            (DMAC_ERROR_BASE + 0x13)
58324+#define DMAC_CHN_VACANCY            (DMAC_ERROR_BASE + 0x14)
58325+#define DMAC_NOT_FINISHED           (DMAC_ERROR_BASE + 0xe)
58326+
58327+#ifdef CONFIG_HIEDMAC
58328+extern int dma_driver_init(void);
58329+extern int dmac_channelclose(unsigned int channel);
58330+extern int dmac_channelstart(unsigned int u32channel);
58331+extern int dmac_channel_allocate(void);
58332+
58333+extern int dmac_start_m2p(unsigned int channel, unsigned int pmemaddr,
58334+			  unsigned int uwperipheralid,
58335+			  unsigned int uwnumtransfers,
58336+			  unsigned int next_lli_addr);
58337+extern int dmac_m2p_transfer(unsigned long long memaddr, unsigned int uwperipheralid,
58338+			     unsigned int length);
58339+extern int dmac_channel_free(unsigned int channel);
58340+
58341+extern int do_dma_m2p(unsigned long long memaddr, unsigned int peripheral_addr,
58342+		      unsigned int length);
58343+extern int do_dma_p2m(unsigned long mem_addr, unsigned int peripheral_addr,
58344+		      unsigned int length);
58345+extern int dmac_wait(int channel);
58346+
58347+extern int dmac_start_m2m(unsigned int  channel, unsigned long psource,
58348+			  unsigned long pdest, unsigned int uwnumtransfers);
58349+extern int dmac_m2m_transfer(unsigned long source, unsigned long dest,
58350+			     unsigned int length);
58351+extern int dmac_register_isr(unsigned int channel, void *pisr);
58352+extern int free_dmalli_space(unsigned int *ppheadlli, unsigned int page_num);
58353+extern int dmac_start_llim2p(unsigned int channel, unsigned int *pfirst_lli,
58354+			     unsigned int uwperipheralid);
58355+extern int dmac_buildllim2m(unsigned long *ppheadlli,
58356+			    unsigned long psource,
58357+			    unsigned long pdest,
58358+			    unsigned int totaltransfersize,
58359+			    unsigned int uwnumtransfers);
58360+
58361+extern int dmac_start_llim2m(unsigned int channel, unsigned long *pfirst_lli);
58362+
58363+extern int allocate_dmalli_space(struct device *dev, unsigned long *ppheadlli,
58364+				 unsigned int page_num);
58365+#endif /* CONFIG_HIEDMAC*/
58366+
58367+
58368+/*structure for LLI*/
58369+typedef struct dmac_lli {
58370+	//must be 64Byte aligned
58371+	unsigned long next_lli;
58372+	unsigned int reserved[5];
58373+	unsigned int count;
58374+	unsigned long src_addr;
58375+	unsigned long dest_addr;
58376+	unsigned int config;
58377+	unsigned int pad[51];
58378+} dmac_lli;
58379+#endif
58380diff --git a/include/linux/i2c.h b/include/linux/i2c.h
58381index a670ae129..815f52046 100644
58382--- a/include/linux/i2c.h
58383+++ b/include/linux/i2c.h
58384@@ -124,6 +124,23 @@ static inline int i2c_master_send_dmasafe(const struct i2c_client *client,
58385 /* Transfer num messages.
58386  */
58387 int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);
58388+
58389+#ifdef CONFIG_ARCH_HISI_BVT
58390+
58391+extern int hi_i2c_master_send(const struct i2c_client *client, const char *buf,
58392+					int count);
58393+
58394+extern int hi_i2c_master_send_mul_reg(const struct i2c_client *client, const char *buf,
58395+					unsigned int count, unsigned int reg_data_width);
58396+
58397+extern int hi_i2c_master_recv(const struct i2c_client *client, char *buf,
58398+					int count);
58399+
58400+extern int hi_i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs,
58401+					int num);
58402+
58403+#endif
58404+
58405 /* Unlocked flavor */
58406 int __i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num);
58407
58408diff --git a/include/linux/mfd/hisi_fmc.h b/include/linux/mfd/hisi_fmc.h
58409new file mode 100644
58410index 000000000..28ce45908
58411--- /dev/null
58412+++ b/include/linux/mfd/hisi_fmc.h
58413@@ -0,0 +1,477 @@
58414+/*
58415+ * Header file for HiSilicon Flash Memory Controller Driver
58416+ *
58417+ * Copyright (c) 2016 HiSilicon Technologies Co., Ltd.
58418+ *
58419+ * This program is free software; you can redistribute it and/or modify
58420+ * it under the terms of the GNU General Public License version 2 as
58421+ * published by the Free Software Foundation.
58422+ */
58423+
58424+#ifndef __HISI_FMC_H
58425+#define __HISI_FMC_H
58426+
58427+#include <linux/compiler.h>
58428+#include <linux/clk.h>
58429+#include <linux/mutex.h>
58430+#include <linux/bitops.h>
58431+
58432+#define _512B					(512)
58433+#define _1K					(1024)
58434+#define _2K					(2048)
58435+#define _4K					(4096)
58436+#define _8K					(8192)
58437+#define _16K					(16384)
58438+#define _32K					(32768)
58439+#define _64K					(0x10000UL)
58440+#define _128K					(0x20000UL)
58441+#define _256K					(0x40000UL)
58442+#define _512K					(0x80000UL)
58443+#define _1M					(0x100000UL)
58444+#define _2M					(0x200000UL)
58445+#define _4M					(0x400000UL)
58446+#define _8M					(0x800000UL)
58447+#define _16M					(0x1000000UL)
58448+#define _32M					(0x2000000UL)
58449+#define _64M					(0x4000000UL)
58450+#define _128M					(0x8000000UL)
58451+#define _256M					(0x10000000UL)
58452+#define _512M					(0x20000000UL)
58453+#define _1G					(0x40000000ULL)
58454+#define _2G					(0x80000000ULL)
58455+#define _4G					(0x100000000ULL)
58456+#define _8G					(0x200000000ULL)
58457+#define _16G					(0x400000000ULL)
58458+#define _64G					(0x1000000000ULL)
58459+
58460+/* HIFMC REG MAP */
58461+#define FMC_CFG					0x00
58462+#define FMC_CFG_SPI_NAND_SEL(_type)		(((_size) & 0x3) << 11)
58463+#define SPI_NOR_ADDR_MODE			BIT(10)
58464+#define FMC_CFG_OP_MODE_MASK			BIT_MASK(0)
58465+#define FMC_CFG_OP_MODE_BOOT			0
58466+#define FMC_CFG_OP_MODE_NORMAL			1
58467+#define SPI_NOR_ADDR_MODE_3BYTES		(0x0 << 10)
58468+#define SPI_NOR_ADDR_MODE_4BYTES		(0x1 << 10)
58469+
58470+#define FMC_CFG_BLOCK_SIZE(_size)		(((_size) & 0x3) << 8)
58471+#define FMC_CFG_ECC_TYPE(_type)			(((_type) & 0x7) << 5)
58472+#define FMC_CFG_PAGE_SIZE(_size)		(((_size) & 0x3) << 3)
58473+#define FMC_CFG_FLASH_SEL(_type)		(((_type) & 0x3) << 1)
58474+#define FMC_CFG_OP_MODE(_mode)			((_mode) & 0x1)
58475+
58476+#define SPI_NAND_MFR_OTHER			0x0
58477+#define SPI_NAND_MFR_WINBOND			0x1
58478+#define SPI_NAND_MFR_ESMT			0x2
58479+#define SPI_NAND_MFR_MICRON			0x3
58480+
58481+#define SPI_NAND_SEL_SHIFT			11
58482+#define SPI_NAND_SEL_MASK			(0x3 << SPI_NAND_SEL_SHIFT)
58483+
58484+#define SPI_NOR_ADDR_MODE_3_BYTES		0x0
58485+#define SPI_NOR_ADDR_MODE_4_BYTES		0x1
58486+
58487+#define SPI_NOR_ADDR_MODE_SHIFT			10
58488+#define SPI_NOR_ADDR_MODE_MASK			(0x1 << SPI_NOR_ADDR_MODE_SHIFT)
58489+
58490+#define BLOCK_SIZE_64_PAGE			0x0
58491+#define BLOCK_SIZE_128_PAGE			0x1
58492+#define BLOCK_SIZE_256_PAGE			0x2
58493+#define BLOCK_SIZE_512_PAGE			0x3
58494+
58495+#define BLOCK_SIZE_MASK				(0x3 << 8)
58496+
58497+#define ECC_TYPE_0BIT				0x0
58498+#define ECC_TYPE_8BIT				0x1
58499+#define ECC_TYPE_16BIT				0x2
58500+#define ECC_TYPE_24BIT				0x3
58501+#define ECC_TYPE_28BIT				0x4
58502+#define ECC_TYPE_40BIT				0x5
58503+#define ECC_TYPE_64BIT				0x6
58504+
58505+#define ECC_TYPE_SHIFT				5
58506+#define ECC_TYPE_MASK				(0x7 << ECC_TYPE_SHIFT)
58507+
58508+#define PAGE_SIZE_2KB				0x0
58509+#define PAGE_SIZE_4KB				0x1
58510+#define PAGE_SIZE_8KB				0x2
58511+#define PAGE_SIZE_16KB				0x3
58512+
58513+#define PAGE_SIZE_SHIFT				3
58514+#define PAGE_SIZE_MASK				(0x3 << PAGE_SIZE_SHIFT)
58515+
58516+#define FLASH_TYPE_SPI_NOR			0x0
58517+#define FLASH_TYPE_SPI_NAND			0x1
58518+#define FLASH_TYPE_NAND				0x2
58519+#define FLASH_TYPE_UNKNOWN			0x3
58520+
58521+#define FLASH_TYPE_SEL_MASK			(0x3 << 1)
58522+#define GET_SPI_FLASH_TYPE(_reg)		(((_reg) >> 1) & 0x3)
58523+
58524+#define FMC_GLOBAL_CFG				0x04
58525+#define FMC_GLOBAL_CFG_WP_ENABLE		BIT(6)
58526+#define FMC_GLOBAL_CFG_RANDOMIZER_EN		(1 << 2)
58527+#define FLASH_TYPE_SEL_MASK			(0x3 << 1)
58528+#define FMC_CFG_FLASH_SEL(_type)		(((_type) & 0x3) << 1)
58529+
58530+#define FMC_GLOBAL_CFG_DTR_MODE		BIT(11)
58531+#define FMC_SPI_TIMING_CFG			0x08
58532+#define TIMING_CFG_TCSH(nr)			(((nr) & 0xf) << 8)
58533+#define TIMING_CFG_TCSS(nr)			(((nr) & 0xf) << 4)
58534+#define TIMING_CFG_TSHSL(nr)			((nr) & 0xf)
58535+
58536+#define CS_HOLD_TIME				0x6
58537+#define CS_SETUP_TIME				0x6
58538+#define CS_DESELECT_TIME			0xf
58539+
58540+#define FMC_PND_PWIDTH_CFG			0x0c
58541+#define PWIDTH_CFG_RW_HCNT(_n)			(((_n) & 0xf) << 8)
58542+#define PWIDTH_CFG_R_LCNT(_n)			(((_n) & 0xf) << 4)
58543+#define PWIDTH_CFG_W_LCNT(_n)			((_n) & 0xf)
58544+
58545+#define RW_H_WIDTH				(0xa)
58546+#define R_L_WIDTH				(0xa)
58547+#define W_L_WIDTH				(0xa)
58548+
58549+#define FMC_INT					0x18
58550+#define FMC_INT_AHB_OP				BIT(7)
58551+#define FMC_INT_WR_LOCK				BIT(6)
58552+#define FMC_INT_DMA_ERR				BIT(5)
58553+#define FMC_INT_ERR_ALARM			BIT(4)
58554+#define FMC_INT_ERR_INVALID			BIT(3)
58555+#define FMC_INT_ERR_INVALID_MASK		(0x8)
58556+#define FMC_INT_ERR_VALID			BIT(2)
58557+#define FMC_INT_ERR_VALID_MASK			(0x4)
58558+#define FMC_INT_OP_FAIL				BIT(1)
58559+#define FMC_INT_OP_DONE				BIT(0)
58560+
58561+#define FMC_INT_EN				0x1c
58562+#define FMC_INT_EN_AHB_OP			BIT(7)
58563+#define FMC_INT_EN_WR_LOCK			BIT(6)
58564+#define FMC_INT_EN_DMA_ERR			BIT(5)
58565+#define FMC_INT_EN_ERR_ALARM			BIT(4)
58566+#define FMC_INT_EN_ERR_INVALID			BIT(3)
58567+#define FMC_INT_EN_ERR_VALID			BIT(2)
58568+#define FMC_INT_EN_OP_FAIL			BIT(1)
58569+#define FMC_INT_EN_OP_DONE			BIT(0)
58570+
58571+#define FMC_INT_CLR				0x20
58572+#define FMC_INT_CLR_AHB_OP			BIT(7)
58573+#define FMC_INT_CLR_WR_LOCK			BIT(6)
58574+#define FMC_INT_CLR_DMA_ERR			BIT(5)
58575+#define FMC_INT_CLR_ERR_ALARM			BIT(4)
58576+#define FMC_INT_CLR_ERR_INVALID			BIT(3)
58577+#define FMC_INT_CLR_ERR_VALID			BIT(2)
58578+#define FMC_INT_CLR_OP_FAIL			BIT(1)
58579+#define FMC_INT_CLR_OP_DONE			BIT(0)
58580+
58581+#define FMC_INT_CLR_ALL				0xff
58582+
58583+#define FMC_CMD					0x24
58584+#define FMC_CMD_CMD2(_cmd)			(((_cmd) & 0xff) << 8)
58585+#define FMC_CMD_CMD1(_cmd)			((_cmd) & 0xff)
58586+
58587+#define FMC_ADDRH				0x28
58588+#define FMC_ADDRH_SET(_addr)			((_addr) & 0xff)
58589+
58590+#define FMC_ADDRL				0x2c
58591+#define FMC_ADDRL_BLOCK_MASK(_page)		((_page) & 0xffffffc0)
58592+#define FMC_ADDRL_BLOCK_H_MASK(_page)		(((_page) & 0xffff) << 16)
58593+#define FMC_ADDRL_BLOCK_L_MASK(_page)		((_page) & 0xffc0)
58594+
58595+#define READ_ID_ADDR				0x00
58596+#define PROTECT_ADDR				0xa0
58597+#define FEATURE_ADDR				0xb0
58598+#define STATUS_ADDR					0xc0
58599+#define FMC_OP_CFG				0x30
58600+#define OP_CFG_FM_CS(_cs)			((_cs) << 11)
58601+#define OP_CFG_FORCE_CS_EN(_en)			((_en) << 10)
58602+#define OP_CFG_MEM_IF_TYPE(_type)		(((_type) & 0x7) << 7)
58603+#define OP_CFG_ADDR_NUM(_addr)			(((_addr) & 0x7) << 4)
58604+#define OP_CFG_DUMMY_NUM(_dummy)		((_dummy) & 0xf)
58605+#define OP_CFG_OEN_EN               (0x1 << 13)
58606+
58607+#define IF_TYPE_SHIFT				7
58608+#define IF_TYPE_MASK				(0x7 << IF_TYPE_SHIFT)
58609+
58610+#define READ_ID_ADDR_NUM			1
58611+#define FEATURES_OP_ADDR_NUM			1
58612+#define STD_OP_ADDR_NUM				3
58613+
58614+#define FMC_SPI_OP_ADDR				0x34
58615+
58616+#define FMC_DATA_NUM				0x38
58617+#define FMC_DATA_NUM_CNT(_n)			((_n) & 0x3fff)
58618+
58619+#define SPI_NOR_SR_LEN				1 /* Status Register length */
58620+#define SPI_NOR_CR_LEN				1 /* Config Register length */
58621+#define FEATURES_DATA_LEN			1
58622+#define READ_OOB_BB_LEN				1
58623+
58624+#define PROTECT_BRWD_MASK			BIT(7)
58625+#define PROTECT_BP3_MASK			BIT(6)
58626+#define PROTECT_BP2_MASK			BIT(5)
58627+#define PROTECT_BP1_MASK			BIT(4)
58628+#define PROTECT_BP0_MASK			BIT(3)
58629+
58630+#define ANY_BP_ENABLE(_val)			((PROTECT_BP3_MASK & _val) \
58631+						|| (PROTECT_BP2_MASK & _val) \
58632+						|| (PROTECT_BP1_MASK & _val) \
58633+						|| (PROTECT_BP0_MASK & _val))
58634+
58635+#define ALL_BP_MASK				(PROTECT_BP3_MASK \
58636+						| PROTECT_BP2_MASK \
58637+						| PROTECT_BP1_MASK \
58638+						| PROTECT_BP0_MASK)
58639+
58640+#define FEATURE_ECC_ENABLE		        (1 << 4)
58641+#define FEATURE_QE_ENABLE			(1 << 0)
58642+
58643+#define FMC_OP					0x3c
58644+#define FMC_OP_DUMMY_EN				BIT(8)
58645+#define FMC_OP_CMD1_EN				BIT(7)
58646+#define FMC_OP_ADDR_EN				BIT(6)
58647+#define FMC_OP_WRITE_DATA_EN			BIT(5)
58648+#define FMC_OP_CMD2_EN				BIT(4)
58649+#define FMC_OP_WAIT_READY_EN			BIT(3)
58650+#define FMC_OP_READ_DATA_EN			BIT(2)
58651+#define FMC_OP_READ_STATUS_EN			BIT(1)
58652+#define FMC_OP_REG_OP_START			BIT(0)
58653+
58654+#define FMC_OP_DMA				0x68
58655+#define FMC_DMA_LEN				0x40
58656+#define FMC_DMA_LEN_SET(_len)			((_len) & 0x0fffffff)
58657+
58658+#define FMC_DMA_AHB_CTRL			0x48
58659+#define FMC_DMA_AHB_CTRL_DMA_PP_EN		BIT(3)
58660+#define FMC_DMA_AHB_CTRL_BURST16_EN		BIT(2)
58661+#define FMC_DMA_AHB_CTRL_BURST8_EN		BIT(1)
58662+#define FMC_DMA_AHB_CTRL_BURST4_EN		BIT(0)
58663+
58664+#define ALL_BURST_ENABLE			(FMC_DMA_AHB_CTRL_BURST16_EN \
58665+						| FMC_DMA_AHB_CTRL_BURST8_EN \
58666+						| FMC_DMA_AHB_CTRL_BURST4_EN)
58667+
58668+#define FMC_DMA_ADDR_OFFSET			4096
58669+
58670+#define FMC_DMA_SADDR_D0			0x4c
58671+
58672+#define FMC_DMA_SADDR_D1			0x50
58673+
58674+#define FMC_DMA_SADDR_D2			0x54
58675+
58676+#define FMC_DMA_SADDR_D3			0x58
58677+
58678+#define FMC_DMA_SADDR_OOB			0x5c
58679+
58680+#ifdef CONFIG_64BIT
58681+#define FMC_DMA_SADDRH_D0                       0x200
58682+#define FMC_DMA_SADDRH_SHIFT                    0x3LL
58683+#define FMC_DMA_SADDRH_MASK                     (FMC_DMA_SADDRH_SHIFT << 32)
58684+
58685+#define FMC_DMA_SADDRH_OOB                      0x210
58686+#endif
58687+
58688+#define FMC_DMA_BLK_SADDR			0x60
58689+#define FMC_DMA_BLK_SADDR_SET(_addr)		((_addr) & 0xffffff)
58690+
58691+#define FMC_DMA_BLK_LEN				0x64
58692+#define FMC_DMA_BLK_LEN_SET(_len)		((_len) & 0xffff)
58693+
58694+#define FMC_OP_CTRL				0x68
58695+#define OP_CTRL_RD_OPCODE(code)		(((code) & 0xff) << 16)
58696+#define OP_CTRL_WR_OPCODE(code)		(((code) & 0xff) << 8)
58697+#define OP_CTRL_RD_OP_SEL(_op)          	(((_op) & 0x3) << 4)
58698+#define OP_CTRL_DMA_OP(_type)			((_type) << 2)
58699+#define OP_CTRL_RW_OP(op)		((op) << 1)
58700+#define OP_CTRL_DMA_OP_READY		BIT(0)
58701+
58702+#define RD_OP_READ_ALL_PAGE			0x0
58703+#define RD_OP_READ_OOB				0x1
58704+#define RD_OP_BLOCK_READ			0x2
58705+
58706+#define RD_OP_SHIFT				4
58707+#define RD_OP_MASK				(0x3 << RD_OP_SHIFT)
58708+
58709+#define OP_TYPE_DMA				0x0
58710+#define OP_TYPE_REG				0x1
58711+
58712+#define FMC_OP_READ				0x0
58713+#define FMC_OP_WRITE				0x1
58714+#define RW_OP_READ				0x0
58715+#define RW_OP_WRITE				0x1
58716+
58717+#define FMC_OP_PARA				0x70
58718+#define FMC_OP_PARA_RD_OOB_ONLY			BIT(1)
58719+
58720+#define FMC_BOOT_SET				0x74
58721+#define FMC_BOOT_SET_DEVICE_ECC_EN		BIT(3)
58722+#define FMC_BOOT_SET_BOOT_QUAD_EN		BIT(1)
58723+
58724+#define FMC_STATUS				0xac
58725+
58726+#ifndef FMC_VERSION
58727+#define FMC_VERSION				0xbc
58728+#endif
58729+
58730+/* Hifmc IP version */
58731+#ifndef HIFMC_VER_100
58732+#define HIFMC_VER_100				(0x100)
58733+#endif
58734+
58735+/* DMA address align with 32 bytes. */
58736+#define FMC_DMA_ALIGN                           32
58737+
58738+#define FMC_CHIP_DELAY                          25
58739+#define HIFMC_ECC_ERR_NUM0_BUF0			0xc0
58740+#define GET_ECC_ERR_NUM(_i, _reg)		(((_reg) >> ((_i) * 8)) & 0xff)
58741+
58742+#define DISABLE               0
58743+#define ENABLE                1
58744+
58745+#define HIFMC_REG_ADDRESS_LEN			0x200
58746+
58747+#define FMC_MAX_READY_WAIT_JIFFIES		(HZ)
58748+
58749+#define MAX_SPI_NOR_ID_LEN			8
58750+#define MAX_NAND_ID_LEN				8
58751+#define MAX_SPI_NAND_ID_LEN			3
58752+
58753+#define GET_OP					0
58754+#define SET_OP					1
58755+
58756+#define STATUS_ECC_MASK				(0x3 << 4)
58757+#define STATUS_P_FAIL_MASK			(1 << 3)
58758+#define STATUS_E_FAIL_MASK			(1 << 2)
58759+#define STATUS_WEL_MASK				(1 << 1)
58760+#define STATUS_OIP_MASK				(1 << 0)
58761+
58762+#define FMC_VERSION				0xbc
58763+
58764+/* Hifmc IP version */
58765+#define HIFMC_VER_100				(0x100)
58766+
58767+#define CONFIG_SPI_NAND_MAX_CHIP_NUM		(1)
58768+
58769+#define CONFIG_HIFMC100_MAX_NAND_CHIP	(1)
58770+
58771+#define GET_PAGE_INDEX(host) \
58772+	                ((host->addr_value[0] >> 16) | (host->addr_value[1] << 16))
58773+#define HIFMC_MAX_CHIP_NUM		2
58774+
58775+extern unsigned char hifmc_cs_user[];
58776+
58777+#define hifmc_readl(_host, _reg) \
58778+	(readl((char *)_host->regbase + (_reg)))
58779+
58780+#define hifmc_readb( _addr) \
58781+	(readb((void __iomem *)(_addr)))
58782+
58783+#define hifmc_readw( _addr) \
58784+	(readw((void __iomem *)(_addr)))
58785+
58786+#define hifmc_writel(_host, _reg, _value) \
58787+	(writel((u_int)(_value), ((char *)_host->regbase + (_reg))))
58788+
58789+#define hifmc_writeb(_val, _addr) \
58790+	(writeb((u_int)(_val), ((char *)_addr)))
58791+
58792+#define FMC_WAIT_TIMEOUT 0x2000000
58793+
58794+#define FMC_CMD_WAIT_CPU_FINISH(_host) \
58795+	do { \
58796+		unsigned regval, timeout = FMC_WAIT_TIMEOUT * 2; \
58797+		do { \
58798+			regval = hifmc_readl((_host), FMC_OP); \
58799+			--timeout; \
58800+		} while ((regval & FMC_OP_REG_OP_START) && timeout); \
58801+		if (!timeout) \
58802+			pr_info("Error: Wait cmd cpu finish timeout!\n"); \
58803+	} while (0)
58804+
58805+#define FMC_DMA_WAIT_INT_FINISH(_host) \
58806+	do { \
58807+		unsigned regval, timeout = FMC_WAIT_TIMEOUT; \
58808+		do { \
58809+			regval = hifmc_readl((_host), FMC_INT); \
58810+			--timeout; \
58811+		} while ((!(regval & FMC_INT_OP_DONE) && timeout)); \
58812+		if (!timeout) \
58813+			pr_info("Error: Wait dma int finish timeout!\n"); \
58814+	} while (0)
58815+
58816+#define FMC_DMA_WAIT_CPU_FINISH(_host) \
58817+	do { \
58818+		unsigned regval, timeout = FMC_WAIT_TIMEOUT; \
58819+		do { \
58820+			regval = hifmc_readl((_host), FMC_OP_CTRL); \
58821+			--timeout; \
58822+		} while ((regval & OP_CTRL_DMA_OP_READY) && timeout); \
58823+		if (!timeout) \
58824+			pr_info("Error: Wait dma cpu finish timeout!\n"); \
58825+	} while (0)
58826+
58827+#define BT_DBG 0 /* Boot init debug print */
58828+#define ER_DBG 0 /* Erase debug print */
58829+#define WR_DBG 0 /* Write debug print */
58830+#define RD_DBG 0 /* Read debug print */
58831+#define QE_DBG 0 /* Quad Enable debug print */
58832+#define OP_DBG 0 /* OP command debug print */
58833+#define DMA_DB 0 /* DMA read or write debug print */
58834+#define AC_DBG 0 /* 3-4byte Address Cycle */
58835+#define SR_DBG 0 /* Status Register debug print */
58836+#define CR_DBG 0 /* Config Register debug print */
58837+#define FT_DBG 0 /* Features debug print */
58838+#define WE_DBG 0 /* Write Enable debug print */
58839+#define BP_DBG 0 /* Block Protection debug print */
58840+#define EC_DBG 0 /* enable/disable ecc0 and randomizer */
58841+#define PM_DBG 0 /* power management debug */
58842+
58843+#define FMC_PR(_type, _fmt, arg...) \
58844+	do { \
58845+		if (_type) \
58846+			DB_MSG(_fmt, ##arg) \
58847+	} while (0)
58848+
58849+#define DB_MSG(_fmt, arg...) \
58850+	pr_info("%s(%d): " _fmt, __func__, __LINE__, ##arg);
58851+
58852+#define DB_BUG(fmt, args...) \
58853+	do { \
58854+		pr_info("%s(%d): BUG: " fmt, __FILE__, __LINE__, ##args); \
58855+		while (1) \
58856+			; \
58857+	} while (0)
58858+
58859+enum hifmc_iftype {
58860+	IF_TYPE_STD,
58861+	IF_TYPE_DUAL,
58862+	IF_TYPE_DIO,
58863+	IF_TYPE_QUAD,
58864+	IF_TYPE_QIO,
58865+};
58866+
58867+struct hisi_fmc {
58868+	void __iomem *regbase;
58869+	void __iomem *iobase;
58870+	struct clk *clk;
58871+	struct mutex lock;
58872+	void *buffer;
58873+	dma_addr_t dma_buffer;
58874+	unsigned int dma_len;
58875+};
58876+
58877+struct hifmc_cmd_op {
58878+	unsigned char cs;
58879+	unsigned char cmd;
58880+	unsigned char l_cmd;
58881+	unsigned char addr_h;
58882+	unsigned int addr_l;
58883+	unsigned int data_no;
58884+	unsigned short option;
58885+	unsigned short op_cfg;
58886+};
58887+
58888+extern struct mutex fmc_switch_mutex;
58889+
58890+#endif /* __HISI_FMC_H */
58891diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h
58892index 40d7e98fc..5b77c8cda 100644
58893--- a/include/linux/mmc/host.h
58894+++ b/include/linux/mmc/host.h
58895@@ -173,6 +173,7 @@ struct mmc_host_ops {
58896 	 */
58897 	int	(*multi_io_quirk)(struct mmc_card *card,
58898 				  unsigned int direction, int blk_size);
58899+	int     (*card_info_save)(struct mmc_host *host);
58900 };
58901
58902 struct mmc_cqe_ops {
58903@@ -281,6 +282,12 @@ struct mmc_host {
58904 	unsigned int		f_min;
58905 	unsigned int		f_max;
58906 	unsigned int		f_init;
58907+	unsigned int		type;
58908+#define MMC_HOST_TYPE_MMC		0		/* MMC card */
58909+#define MMC_HOST_TYPE_SD		1		/* SD card */
58910+#define MMC_HOST_TYPE_SDIO		2		/* SDIO card */
58911+#define MMC_HOST_TYPE_SD_COMBO		3		/* SD combo (IO+mem) card */
58912+
58913 	u32			ocr_avail;
58914 	u32			ocr_avail_sdio;	/* SDIO-specific OCR */
58915 	u32			ocr_avail_sd;	/* SD-specific OCR */
58916@@ -425,6 +432,11 @@ struct mmc_host {
58917
58918 	struct delayed_work	detect;
58919 	int			detect_change;	/* card detect flag */
58920+	u32			card_status;
58921+#define MMC_CARD_UNINIT		0
58922+#define MMC_CARD_INIT		1
58923+#define MMC_CARD_INIT_FAIL	2
58924+
58925 	struct mmc_slot		slot;
58926
58927 	const struct mmc_bus_ops *bus_ops;	/* current bus driver */
58928diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
58929index 157357ec1..3588dc165 100644
58930--- a/include/linux/mtd/mtd.h
58931+++ b/include/linux/mtd/mtd.h
58932@@ -18,6 +18,12 @@
58933
58934 #include <asm/div64.h>
58935
58936+#define MTD_ERASE_PENDING	0x01
58937+#define MTD_ERASING		0x02
58938+#define MTD_ERASE_SUSPEND	0x04
58939+#define MTD_ERASE_DONE		0x08
58940+#define MTD_ERASE_FAILED	0x10
58941+
58942 #define MTD_FAIL_ADDR_UNKNOWN -1LL
58943
58944 struct mtd_info;
58945@@ -28,9 +34,18 @@ struct mtd_info;
58946  * or was not specific to any particular block.
58947  */
58948 struct erase_info {
58949+	struct mtd_info *mtd;
58950 	uint64_t addr;
58951 	uint64_t len;
58952 	uint64_t fail_addr;
58953+	u_long time;
58954+	u_long retries;
58955+	unsigned dev;
58956+	unsigned cell;
58957+	void (*callback) (struct erase_info *self);
58958+	u_long priv;
58959+	u_char state;
58960+	struct erase_info *next;
58961 };
58962
58963 struct mtd_erase_region_info {
58964@@ -55,11 +70,9 @@ struct mtd_erase_region_info {
58965  * @datbuf:	data buffer - if NULL only oob data are read/written
58966  * @oobbuf:	oob data buffer
58967  *
58968- * Note, some MTD drivers do not allow you to write more than one OOB area at
58969- * one go. If you try to do that on such an MTD device, -EINVAL will be
58970- * returned. If you want to make your implementation portable on all kind of MTD
58971- * devices you should split the write request into several sub-requests when the
58972- * request crosses a page boundary.
58973+ * Note, it is allowed to read more than one OOB area at one go, but not write.
58974+ * The interface assumes that the OOB write requests program only one page's
58975+ * OOB area.
58976  */
58977 struct mtd_oob_ops {
58978 	unsigned int	mode;
58979@@ -314,6 +327,10 @@ struct mtd_info {
58980 	int (*_point) (struct mtd_info *mtd, loff_t from, size_t len,
58981 		       size_t *retlen, void **virt, resource_size_t *phys);
58982 	int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len);
58983+	unsigned long (*_get_unmapped_area) (struct mtd_info *mtd,
58984+					     unsigned long len,
58985+					     unsigned long offset,
58986+					     unsigned long flags);
58987 	int (*_read) (struct mtd_info *mtd, loff_t from, size_t len,
58988 		      size_t *retlen, u_char *buf);
58989 	int (*_write) (struct mtd_info *mtd, loff_t to, size_t len,
58990@@ -356,6 +373,11 @@ struct mtd_info {
58991 	int (*_get_device) (struct mtd_info *mtd);
58992 	void (*_put_device) (struct mtd_info *mtd);
58993
58994+	/* Backing device capabilities for this device
58995+	 * - provides mmap capabilities
58996+	 */
58997+	struct backing_dev_info *backing_dev_info;
58998+
58999 	/*
59000 	 * flag indicates a panic write, low level drivers can take appropriate
59001 	 * action if required to ensure writes go through
59002@@ -456,13 +478,11 @@ static inline void mtd_set_of_node(struct mtd_info *mtd,
59003 				   struct device_node *np)
59004 {
59005 	mtd->dev.of_node = np;
59006-	if (!mtd->name)
59007-		of_property_read_string(np, "label", &mtd->name);
59008 }
59009
59010 static inline struct device_node *mtd_get_of_node(struct mtd_info *mtd)
59011 {
59012-	return dev_of_node(&mtd->dev);
59013+	return mtd->dev.of_node;
59014 }
59015
59016 static inline u32 mtd_oobavail(struct mtd_info *mtd, struct mtd_oob_ops *ops)
59017@@ -580,34 +600,6 @@ static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)
59018 	return do_div(sz, mtd->erasesize);
59019 }
59020
59021-/**
59022- * mtd_align_erase_req - Adjust an erase request to align things on eraseblock
59023- *			 boundaries.
59024- * @mtd: the MTD device this erase request applies on
59025- * @req: the erase request to adjust
59026- *
59027- * This function will adjust @req->addr and @req->len to align them on
59028- * @mtd->erasesize. Of course we expect @mtd->erasesize to be != 0.
59029- */
59030-static inline void mtd_align_erase_req(struct mtd_info *mtd,
59031-				       struct erase_info *req)
59032-{
59033-	u32 mod;
59034-
59035-	if (WARN_ON(!mtd->erasesize))
59036-		return;
59037-
59038-	mod = mtd_mod_by_eb(req->addr, mtd);
59039-	if (mod) {
59040-		req->addr -= mod;
59041-		req->len += mod;
59042-	}
59043-
59044-	mod = mtd_mod_by_eb(req->addr + req->len, mtd);
59045-	if (mod)
59046-		req->len += mtd->erasesize - mod;
59047-}
59048-
59049 static inline uint32_t mtd_div_by_ws(uint64_t sz, struct mtd_info *mtd)
59050 {
59051 	if (mtd->writesize_shift)
59052@@ -692,6 +684,8 @@ extern void register_mtd_user (struct mtd_notifier *new);
59053 extern int unregister_mtd_user (struct mtd_notifier *old);
59054 void *mtd_kmalloc_up_to(const struct mtd_info *mtd, size_t *size);
59055
59056+void mtd_erase_callback(struct erase_info *instr);
59057+
59058 static inline int mtd_is_bitflip(int err) {
59059 	return err == -EUCLEAN;
59060 }
59061diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h
59062index 60bac2c0e..04e292e88 100644
59063--- a/include/linux/mtd/spi-nor.h
59064+++ b/include/linux/mtd/spi-nor.h
59065@@ -11,6 +11,44 @@
59066 #include <linux/mtd/mtd.h>
59067 #include <linux/spi/spi-mem.h>
59068
59069+#ifdef CONFIG_ARCH_HISI_BVT
59070+#define SNOR_MFR_EON		CFI_MFR_EON
59071+#define SNOR_MFR_WINBOND	0xef
59072+#define SNOR_MFR_ESMT		0x8c
59073+#define SNOR_MFR_GD		0xc8
59074+#define SNOR_MFR_XTX		0x0b
59075+#define SNOR_MFR_PUYA		0x85
59076+
59077+/* Flash set the RESET# from */
59078+#define SPI_NOR_SR_RST_MASK	BIT(7)
59079+#define SPI_NOR_GET_RST(val)	(((val) & SPI_NOR_SR_RST_MASK) >> 7)
59080+#define SPI_NOR_SET_RST(val)    ((val) | SPI_NOR_SR_RST_MASK)
59081+
59082+/* Flash block protect */
59083+#ifdef CONFIG_HISI_SPI_BLOCK_PROTECT
59084+#define _2M				(0x200000UL)
59085+#define _4M				(0x400000UL)
59086+#define _8M				(0x800000UL)
59087+#define _16M				(0x1000000UL)
59088+#define _32M				(0x2000000UL)
59089+
59090+#define BP_NUM_3                        3
59091+#define BP_NUM_4                        4
59092+
59093+#define DEBUG_SPI_NOR_BP	0
59094+
59095+#define SPI_NOR_SR_BP0_SHIFT    2
59096+#define SPI_NOR_SR_BP_WIDTH_4   0xf
59097+#define SPI_NOR_SR_BP_MASK_4    (SPI_NOR_SR_BP_WIDTH_4 << SPI_NOR_SR_BP0_SHIFT)
59098+
59099+#define SPI_NOR_SR_BP_WIDTH_3   0x7
59100+#define SPI_NOR_SR_BP_MASK_3    (SPI_NOR_SR_BP_WIDTH_3 << SPI_NOR_SR_BP0_SHIFT)
59101+
59102+#define LOCK_LEVEL_MAX(bp_num)	(((0x01) << bp_num) - 1)
59103+
59104+#endif /* CONFIG_HISI_SPI_BLOCK_PROTECT */
59105+#endif /* CONFIG_ARCH_HISI_BVT */
59106+
59107 /*
59108  * Note on opcode nomenclature: some opcodes have a format like
59109  * SPINOR_OP_FUNCTION{4,}_x_y_z. The numbers x, y, and z stand for the number
59110@@ -98,6 +136,17 @@
59111
59112 /* Used for Spansion flashes only. */
59113 #define SPINOR_OP_BRWR		0x17	/* Bank register write */
59114+
59115+#ifdef CONFIG_ARCH_HISI_BVT
59116+#define SPINOR_OP_RDSR3		0x15    /* Read Status Register-3 */
59117+#define SPINOR_OP_WRSR3		0x11    /* Write Status Register-3 1 byte*/
59118+/* Used for GigaDevice flashes only. */
59119+#define SPINOR_OP_WRCR		0x31	/* Config register write */
59120+/* Software reset code */
59121+#define CR_DUMMY_CYCLE      (0x03 << 6) /* Macronix dummy cycle bits */
59122+#define SR_QUAD_EN_XTX      BIT(1)
59123+#endif
59124+
59125 #define SPINOR_OP_CLSR		0x30	/* Clear status register 1 */
59126
59127 /* Used for Micron flashes only. */
59128@@ -166,6 +215,23 @@
59129 	(SNOR_PROTO_IS_DTR |					\
59130 	 SNOR_PROTO_STR(_inst_nbits, _addr_nbits, _data_nbits))
59131
59132+#ifdef CONFIG_ARCH_HISI_BVT
59133+#define SNOR_OP_READ(_num_mode_clocks, _num_wait_states, _opcode, _proto) \
59134+	{							  \
59135+		.num_mode_clocks = _num_mode_clocks,		  \
59136+		.num_wait_states = _num_wait_states,		  \
59137+		.opcode = _opcode,				  \
59138+		.proto = _proto,				  \
59139+	}
59140+
59141+#define SNOR_OP_PROGRAMS(_opcode, _proto) \
59142+	{							  \
59143+		.opcode = _opcode,				  \
59144+		.proto = _proto,				  \
59145+	}
59146+
59147+#endif /* CONFIG_ARCH_HISI_BVT */
59148+
59149 enum spi_nor_protocol {
59150 	SNOR_PROTO_1_1_1 = SNOR_PROTO_STR(1, 1, 1),
59151 	SNOR_PROTO_1_1_2 = SNOR_PROTO_STR(1, 1, 2),
59152@@ -386,6 +452,15 @@ struct spi_nor {
59153 		struct spi_mem_dirmap_desc *wdesc;
59154 	} dirmap;
59155
59156+#ifdef CONFIG_ARCH_HISI_BVT
59157+#ifdef CONFIG_HISI_SPI_BLOCK_PROTECT
59158+	unsigned int end_addr;
59159+	unsigned int lock_level_max;
59160+	unsigned char level;
59161+#endif
59162+	struct device_node	*flash_node;
59163+	u32 clkrate;
59164+#endif
59165 	void *priv;
59166 };
59167
59168@@ -414,6 +489,13 @@ static inline struct device_node *spi_nor_get_flash_node(struct spi_nor *nor)
59169  *
59170  * Return: 0 for success, others for failure.
59171  */
59172+#ifdef CONFIG_ARCH_HISI_BVT
59173+void spi_nor_driver_shutdown(struct spi_nor *nor);
59174+#ifdef CONFIG_PM
59175+int spi_nor_suspend(struct spi_nor *nor, pm_message_t state);
59176+int hisi_spi_nor_resume(struct spi_nor *nor);
59177+#endif
59178+#endif /* CONFIG_ARCH_HISI_BVT */
59179 int spi_nor_scan(struct spi_nor *nor, const char *name,
59180 		 const struct spi_nor_hwcaps *hwcaps);
59181
59182diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
59183index f96b7f8d8..11911795d 100644
59184--- a/include/linux/netdev_features.h
59185+++ b/include/linux/netdev_features.h
59186@@ -30,6 +30,7 @@ enum {
59187 	NETIF_F_GRO_BIT,		/* Generic receive offload */
59188 	NETIF_F_LRO_BIT,		/* large receive offload */
59189
59190+	NETIF_F_UFO_BIT,		/* UDPv4 fragmentation */
59191 	/**/NETIF_F_GSO_SHIFT,		/* keep the order of SKB_GSO_* bits */
59192 	NETIF_F_TSO_BIT			/* ... TCPv4 segmentation */
59193 		= NETIF_F_GSO_SHIFT,
59194@@ -127,6 +128,7 @@ enum {
59195 #define NETIF_F_TSO6		__NETIF_F(TSO6)
59196 #define NETIF_F_TSO_ECN		__NETIF_F(TSO_ECN)
59197 #define NETIF_F_TSO		__NETIF_F(TSO)
59198+#define NETIF_F_UFO		__NETIF_F(UFO)
59199 #define NETIF_F_VLAN_CHALLENGED	__NETIF_F(VLAN_CHALLENGED)
59200 #define NETIF_F_RXFCS		__NETIF_F(RXFCS)
59201 #define NETIF_F_RXALL		__NETIF_F(RXALL)
59202@@ -207,7 +209,7 @@ static inline int find_next_netdev_feature(u64 feature, unsigned long start)
59203 				 NETIF_F_FSO)
59204
59205 /* List of features with software fallbacks. */
59206-#define NETIF_F_GSO_SOFTWARE	(NETIF_F_ALL_TSO | \
59207+#define NETIF_F_GSO_SOFTWARE	(NETIF_F_ALL_TSO | NETIF_F_UFO | \
59208 				 NETIF_F_GSO_SCTP)
59209
59210 /*
59211diff --git a/include/linux/phy.h b/include/linux/phy.h
59212index 08725a262..45c717bc1 100644
59213--- a/include/linux/phy.h
59214+++ b/include/linux/phy.h
59215@@ -1547,6 +1547,7 @@ void phy_queue_state_machine(struct phy_device *phydev, unsigned long jiffies);
59216 void phy_mac_interrupt(struct phy_device *phydev);
59217 void phy_start_machine(struct phy_device *phydev);
59218 void phy_stop_machine(struct phy_device *phydev);
59219+int phy_ethtool_gset(struct phy_device *phydev, struct ethtool_cmd *cmd);
59220 void phy_ethtool_ksettings_get(struct phy_device *phydev,
59221 			       struct ethtool_link_ksettings *cmd);
59222 int phy_ethtool_ksettings_set(struct phy_device *phydev,
59223diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
59224index acbf1875a..f4573b855 100644
59225--- a/include/linux/skbuff.h
59226+++ b/include/linux/skbuff.h
59227@@ -521,6 +521,7 @@ struct skb_shared_info {
59228 	struct skb_shared_hwtstamps hwtstamps;
59229 	unsigned int	gso_type;
59230 	u32		tskey;
59231+	__be32          ip6_frag_id;
59232
59233 	/*
59234 	 * Warning : all fields before dataref are cleared in __alloc_skb()
59235diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h
59236index e7b997d6f..8bec8c190 100644
59237--- a/include/linux/sunrpc/xprt.h
59238+++ b/include/linux/sunrpc/xprt.h
59239@@ -156,6 +156,7 @@ struct rpc_xprt_ops {
59240 	void		(*inject_disconnect)(struct rpc_xprt *xprt);
59241 	int		(*bc_setup)(struct rpc_xprt *xprt,
59242 				    unsigned int min_reqs);
59243+	struct svc_xprt*(*bc_get_xprt)(struct svc_serv *serv, struct net *net);
59244 	size_t		(*bc_maxpayload)(struct rpc_xprt *xprt);
59245 	unsigned int	(*bc_num_slots)(struct rpc_xprt *xprt);
59246 	void		(*bc_free_rqst)(struct rpc_rqst *rqst);
59247diff --git a/include/linux/types.h b/include/linux/types.h
59248index a14797760..2c35430e2 100644
59249--- a/include/linux/types.h
59250+++ b/include/linux/types.h
59251@@ -227,5 +227,8 @@ typedef void (*swap_func_t)(void *a, void *b, int size);
59252 typedef int (*cmp_r_func_t)(const void *a, const void *b, const void *priv);
59253 typedef int (*cmp_func_t)(const void *a, const void *b);
59254
59255+/* clocksource cycle base type */
59256+typedef u64 cycle_t;
59257+
59258 #endif /*  __ASSEMBLY__ */
59259 #endif /* _LINUX_TYPES_H */
59260diff --git a/include/linux/usb.h b/include/linux/usb.h
59261index d6a41841b..de3232ee5 100644
59262--- a/include/linux/usb.h
59263+++ b/include/linux/usb.h
59264@@ -2019,8 +2019,11 @@ static inline int usb_translate_errors(int error_code)
59265 #define USB_DEVICE_REMOVE	0x0002
59266 #define USB_BUS_ADD		0x0003
59267 #define USB_BUS_REMOVE		0x0004
59268+#define USB_GADGET_ADD		0x0005
59269+#define USB_GADGET_REMOVE	0x0006
59270 extern void usb_register_notify(struct notifier_block *nb);
59271 extern void usb_unregister_notify(struct notifier_block *nb);
59272+extern void usb_notify_online_status(bool online);
59273
59274 /* debugfs stuff */
59275 extern struct dentry *usb_debug_root;
59276diff --git a/include/uapi/linux/i2c-dev.h b/include/uapi/linux/i2c-dev.h
59277index 85f8047af..3f50287f3 100644
59278--- a/include/uapi/linux/i2c-dev.h
59279+++ b/include/uapi/linux/i2c-dev.h
59280@@ -52,6 +52,8 @@
59281 #define I2C_PEC		0x0708	/* != 0 to use PEC with SMBus */
59282 #define I2C_SMBUS	0x0720	/* SMBus transfer */
59283
59284+#define I2C_CONFIG_MUL_REG 0x070c
59285+#define I2C_CONFIG_FLAGS   0x070d
59286
59287 /* This is the structure as used in the I2C_SMBUS ioctl call */
59288 struct i2c_smbus_ioctl_data {
59289diff --git a/include/uapi/linux/i2c.h b/include/uapi/linux/i2c.h
59290index f71a1751c..f85deb485 100644
59291--- a/include/uapi/linux/i2c.h
59292+++ b/include/uapi/linux/i2c.h
59293@@ -22,7 +22,7 @@
59294     MA 02110-1301 USA.							     */
59295 /* ------------------------------------------------------------------------- */
59296
59297-/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
59298+/* With some changes from Kyosti Malkki <kmalkki@cc.hut.fi> and
59299    Frodo Looijaard <frodol@dds.nl> */
59300
59301 #ifndef _UAPI_LINUX_I2C_H
59302@@ -81,8 +81,14 @@ struct i2c_msg {
59303 #define I2C_M_REV_DIR_ADDR	0x2000	/* if I2C_FUNC_PROTOCOL_MANGLING */
59304 #define I2C_M_NOSTART		0x4000	/* if I2C_FUNC_NOSTART */
59305 #define I2C_M_STOP		0x8000	/* if I2C_FUNC_PROTOCOL_MANGLING */
59306+#define I2C_M_16BIT_REG		0x0002	/* indicate reg bit-width is 16bit */
59307+#define I2C_M_16BIT_DATA	0x0008	/* indicate data bit-width is 16bit */
59308+#define I2C_M_DMA		0x0004	/* indicate use dma mode */
59309 	__u16 len;		/* msg length				*/
59310 	__u8 *buf;		/* pointer to msg data			*/
59311+#if defined(CONFIG_HI_DMAC) || defined(CONFIG_HIEDMAC)
59312+	__u8 *highmem_buf;
59313+#endif
59314 };
59315
59316 /* To determine what functionality is present */
59317diff --git a/include/uapi/linux/msdos_fs.h b/include/uapi/linux/msdos_fs.h
59318index a5773899f..89a461a27 100644
59319--- a/include/uapi/linux/msdos_fs.h
59320+++ b/include/uapi/linux/msdos_fs.h
59321@@ -93,7 +93,23 @@ struct __fat_dirent {
59322 	unsigned short	d_reclen;
59323 	char		d_name[256]; /* We must not include limits.h! */
59324 };
59325+#ifdef CONFIG_HISI_MC
59326+struct fat_direntall {
59327+	unsigned long   d_ino;
59328+	unsigned long   d_off;
59329+	unsigned char   d_type;
59330+	u64     d_size;
59331+	char    d_createtime[8];
59332+	unsigned short  d_reclen;
59333+	char        d_name[1];
59334+};
59335
59336+struct fat_direntall_buf {
59337+	int d_count;
59338+	int d_usecount;
59339+	struct fat_direntall direntall;
59340+};
59341+#endif
59342 /*
59343  * ioctl commands
59344  */
59345@@ -104,7 +120,9 @@ struct __fat_dirent {
59346 #define FAT_IOCTL_SET_ATTRIBUTES	_IOW('r', 0x11, __u32)
59347 /*Android kernel has used 0x12, so we use 0x13*/
59348 #define FAT_IOCTL_GET_VOLUME_ID		_IOR('r', 0x13, __u32)
59349-
59350+#ifdef CONFIG_HISI_MC
59351+#define VFAT_IOCTL_READDIR_ALL    _IOR('r', 0x14, struct fat_direntall_buf)
59352+#endif
59353 struct fat_boot_sector {
59354 	__u8	ignored[3];	/* Boot strap short or near jump */
59355 	__u8	system_id[8];	/* Name - can be used to special case
59356diff --git a/include/uapi/linux/usb/g_uvc.h b/include/uapi/linux/usb/g_uvc.h
59357index 652f169a0..8addd4f94 100644
59358--- a/include/uapi/linux/usb/g_uvc.h
59359+++ b/include/uapi/linux/usb/g_uvc.h
59360@@ -12,6 +12,7 @@
59361 #include <linux/types.h>
59362 #include <linux/usb/ch9.h>
59363
59364+#define UVC_SG_REQ
59365 #define UVC_EVENT_FIRST			(V4L2_EVENT_PRIVATE_START + 0)
59366 #define UVC_EVENT_CONNECT		(V4L2_EVENT_PRIVATE_START + 0)
59367 #define UVC_EVENT_DISCONNECT		(V4L2_EVENT_PRIVATE_START + 1)
59368diff --git a/include/uapi/linux/usb/video.h b/include/uapi/linux/usb/video.h
59369index bfdae12cd..2d33002e9 100644
59370--- a/include/uapi/linux/usb/video.h
59371+++ b/include/uapi/linux/usb/video.h
59372@@ -342,6 +342,8 @@ struct UVC_EXTENSION_UNIT_DESCRIPTOR(p, n) {		\
59373 	__u8  iExtension;				\
59374 } __attribute__ ((packed))
59375
59376+DECLARE_UVC_EXTENSION_UNIT_DESCRIPTOR(1,2);
59377+
59378 /* 3.8.2.2. Video Control Interrupt Endpoint Descriptor */
59379 struct uvc_control_endpoint_descriptor {
59380 	__u8   bLength;
59381@@ -567,5 +569,63 @@ struct UVC_FRAME_MJPEG(n) {				\
59382 	__le32 dwFrameInterval[n];			\
59383 } __attribute__ ((packed))
59384
59385+/* 3.1.1  Frame Based Payload Video Format Descriptor */
59386+struct uvc_frame_based_format_desc {
59387+	__u8  bLength;
59388+	__u8  bDescriptorType;
59389+	__u8  bDescriptorSubType;
59390+	__u8  bFormatIndex;
59391+	__u8  bNumFrameDescriptors;
59392+	__u8  guidFormat[16];
59393+	__u8  bBitsPerPixel;
59394+	__u8  bDefaultFrameIndex;
59395+	__u8  bAspectRatioX;
59396+	__u8  bAspectRatioY;
59397+	__u8  bmInterfaceFlags;
59398+	__u8  bCopyProtect;
59399+	__u8  bVariableSize;
59400+} __attribute__((__packed__));
59401+
59402+#define UVC_DT_FRAME_BASED_FORMAT_SIZE		28
59403+
59404+/* 3.1.2  Frame Based Payload Frame Descriptor */
59405+struct uvc_frame_based_frame_desc {
59406+	__u8  bLength;
59407+	__u8  bDescriptorType;
59408+	__u8  bDescriptorSubType;
59409+	__u8  bFrameIndex;
59410+	__u8  bmCapabilities;
59411+	__u16 wWidth;
59412+	__u16 wHeight;
59413+	__u32 dwMinBitRate;
59414+	__u32 dwMaxBitRate;
59415+	__u32 dwDefaultFrameInterval;
59416+	__u8  bFrameIntervalType;
59417+	__u32 dwBytesPerLine;
59418+	__u32 dwFrameInterval[];
59419+} __attribute__((__packed__));
59420+
59421+#define UVC_DT_FRAME_BASED_FRAME_SIZE(n)			(26+4*(n))
59422+
59423+#define UVC_FRAME_BASED(n) \
59424+	uvc_frame_based_desc##n
59425+
59426+#define DECLARE_UVC_FRAME_BASED(n)			\
59427+struct UVC_FRAME_BASED(n) {				\
59428+	__u8  bLength;					\
59429+	__u8  bDescriptorType;				\
59430+	__u8  bDescriptorSubType;			\
59431+	__u8  bFrameIndex;				\
59432+	__u8  bmCapabilities;				\
59433+	__u16 wWidth;					\
59434+	__u16 wHeight;					\
59435+	__u32 dwMinBitRate;				\
59436+	__u32 dwMaxBitRate;				\
59437+	__u32 dwDefaultFrameInterval;			\
59438+	__u8  bFrameIntervalType;			\
59439+	__u32 dwBytesPerLine;			\
59440+	__u32 dwFrameInterval[n];			\
59441+} __attribute__ ((packed))
59442+
59443 #endif /* __LINUX_USB_VIDEO_H */
59444
59445diff --git a/init/main.c b/init/main.c
59446index 63cdf49f7..4263c0bb3 100644
59447--- a/init/main.c
59448+++ b/init/main.c
59449@@ -842,6 +842,34 @@ static void __init mm_init(void)
59450 	pti_init();
59451 }
59452
59453+#ifndef HISI_CHIP_OEM
59454+static char * __initdata hi3516_usb_mode;
59455+static int __init hi3516_usb_mode_setup(char *str)
59456+{
59457+	hi3516_usb_mode = str;
59458+	return 1;
59459+}
59460+__setup("Hi3516usbmode=", hi3516_usb_mode_setup);
59461+
59462+/*
59463+ * Set up device tree oem feature
59464+ */
59465+static void __init _dtb_hisi_oem(void)
59466+{
59467+	if (hi3516_usb_mode != NULL && strcmp(hi3516_usb_mode, "host") == 0) {
59468+		pr_notice("set usb mode to %s \n",hi3516_usb_mode);
59469+
59470+		struct device_node *root_node, *child_node;
59471+		root_node =  of_find_node_by_name(NULL, "soc");
59472+		if (root_node)
59473+			child_node = of_find_node_by_name(root_node, "xhci_0");
59474+		if (child_node)
59475+			child_node->sibling = child_node->sibling->sibling;
59476+	}
59477+
59478+}
59479+#endif
59480+
59481 void __init __weak arch_call_rest_init(void)
59482 {
59483 	rest_init();
59484@@ -895,6 +923,10 @@ asmlinkage __visible void __init __no_sanitize_address start_kernel(void)
59485 		parse_args("Setting extra init args", extra_init_args,
59486 			   NULL, 0, -1, -1, NULL, set_init_arg);
59487
59488+#ifndef HISI_CHIP_OEM
59489+	_dtb_hisi_oem();
59490+#endif
59491+
59492 	/*
59493 	 * These use large bootmem allocations and must precede
59494 	 * kmem_cache_init()
59495diff --git a/kernel/cpu.c b/kernel/cpu.c
59496index 67c22941b..dfbd3887e 100644
59497--- a/kernel/cpu.c
59498+++ b/kernel/cpu.c
59499@@ -331,6 +331,19 @@ void lockdep_assert_cpus_held(void)
59500 	percpu_rwsem_assert_held(&cpu_hotplug_lock);
59501 }
59502
59503+static RAW_NOTIFIER_HEAD(cpu_chain);
59504+
59505+/* Need to know about CPUs going up/down? */
59506+int hi_register_cpu_notifier(struct notifier_block *nb)
59507+{
59508+	int ret;
59509+	cpu_maps_update_begin();
59510+	ret = raw_notifier_chain_register(&cpu_chain, nb);
59511+	cpu_maps_update_done();
59512+	return ret;
59513+}
59514+EXPORT_SYMBOL(hi_register_cpu_notifier);
59515+
59516 static void lockdep_acquire_cpus_lock(void)
59517 {
59518 	rwsem_acquire(&cpu_hotplug_lock.dep_map, 0, 0, _THIS_IP_);
59519diff --git a/kernel/dma/contiguous.c b/kernel/dma/contiguous.c
59520index 16b95ff12..90f379978 100644
59521--- a/kernel/dma/contiguous.c
59522+++ b/kernel/dma/contiguous.c
59523@@ -164,6 +164,11 @@ void __init dma_pernuma_cma_reserve(void)
59524  * has been activated and all other subsystems have already allocated/reserved
59525  * memory.
59526  */
59527+#ifdef CONFIG_ARCH_HISI_BVT
59528+#ifdef CONFIG_64BIT
59529+extern __init int hisi_declare_heap_memory(void);
59530+#endif
59531+#endif
59532 void __init dma_contiguous_reserve(phys_addr_t limit)
59533 {
59534 	phys_addr_t selected_size = 0;
59535@@ -173,6 +178,11 @@ void __init dma_contiguous_reserve(phys_addr_t limit)
59536
59537 	pr_debug("%s(limit %08lx)\n", __func__, (unsigned long)limit);
59538
59539+#ifdef CONFIG_ARCH_HISI_BVT
59540+#ifdef CONFIG_64BIT
59541+	hisi_declare_heap_memory();
59542+#endif
59543+#endif
59544 	if (size_cmdline != -1) {
59545 		selected_size = size_cmdline;
59546 		selected_base = base_cmdline;
59547@@ -262,6 +272,7 @@ struct page *dma_alloc_from_contiguous(struct device *dev, size_t count,
59548
59549 	return cma_alloc(dev_get_cma_area(dev), count, align, no_warn);
59550 }
59551+EXPORT_SYMBOL(dma_alloc_from_contiguous);
59552
59553 /**
59554  * dma_release_from_contiguous() - release allocated pages
59555@@ -278,6 +289,12 @@ bool dma_release_from_contiguous(struct device *dev, struct page *pages,
59556 {
59557 	return cma_release(dev_get_cma_area(dev), pages, count);
59558 }
59559+EXPORT_SYMBOL(dma_release_from_contiguous);
59560+
59561+#ifdef CONFIG_ARM64
59562+#include <asm/cacheflush.h>
59563+EXPORT_SYMBOL(__flush_dcache_area);
59564+#endif
59565
59566 static struct page *cma_alloc_aligned(struct cma *cma, size_t size, gfp_t gfp)
59567 {
59568diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
59569index 85351a12c..e9e070a36 100644
59570--- a/kernel/printk/printk.c
59571+++ b/kernel/printk/printk.c
59572@@ -1475,7 +1475,7 @@ static int syslog_print(char __user *buf, int size)
59573 	char *text;
59574 	int len = 0;
59575
59576-	text = kmalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
59577+	text = kzalloc(LOG_LINE_MAX + PREFIX_MAX, GFP_KERNEL);
59578 	if (!text)
59579 		return -ENOMEM;
59580
59581diff --git a/kernel/relay.c b/kernel/relay.c
59582index b08d936d5..1a62975c6 100644
59583--- a/kernel/relay.c
59584+++ b/kernel/relay.c
59585@@ -581,7 +581,8 @@ struct rchan *relay_open(const char *base_filename,
59586 	if (!chan)
59587 		return NULL;
59588
59589-	chan->buf = alloc_percpu(struct rchan_buf *);
59590+	chan->buf = alloc_percpu_gfp(struct rchan_buf *,
59591+				GFP_KERNEL | __GFP_NOWARN);
59592 	if (!chan->buf) {
59593 		kfree(chan);
59594 		return NULL;
59595diff --git a/mm/init-mm.c b/mm/init-mm.c
59596index 153162669..6382b3b6b 100644
59597--- a/mm/init-mm.c
59598+++ b/mm/init-mm.c
59599@@ -40,3 +40,4 @@ struct mm_struct init_mm = {
59600 	.cpu_bitmap	= CPU_BITS_NONE,
59601 	INIT_MM_CONTEXT(init_mm)
59602 };
59603+EXPORT_SYMBOL(init_mm);
59604diff --git a/mm/madvise.c b/mm/madvise.c
59605index 23b48a004..2e09438d6 100644
59606--- a/mm/madvise.c
59607+++ b/mm/madvise.c
59608@@ -30,6 +30,7 @@
59609 #include <linux/swapops.h>
59610 #include <linux/shmem_fs.h>
59611 #include <linux/mmu_notifier.h>
59612+#include <linux/sched/mm.h>
59613
59614 #include <asm/tlb.h>
59615
59616diff --git a/mm/mincore.c b/mm/mincore.c
59617index 02db1a834..9a2c1208d 100644
59618--- a/mm/mincore.c
59619+++ b/mm/mincore.c
59620@@ -42,57 +42,15 @@ static int mincore_hugetlb(pte_t *pte, unsigned long hmask, unsigned long addr,
59621 	return 0;
59622 }
59623
59624-/*
59625- * Later we can get more picky about what "in core" means precisely.
59626- * For now, simply check to see if the page is in the page cache,
59627- * and is up to date; i.e. that no page-in operation would be required
59628- * at this time if an application were to map and access this page.
59629- */
59630-static unsigned char mincore_page(struct address_space *mapping, pgoff_t index)
59631-{
59632-	unsigned char present = 0;
59633-	struct page *page;
59634-
59635-	/*
59636-	 * When tmpfs swaps out a page from a file, any process mapping that
59637-	 * file will not get a swp_entry_t in its pte, but rather it is like
59638-	 * any other file mapping (ie. marked !present and faulted in with
59639-	 * tmpfs's .fault). So swapped out tmpfs mappings are tested here.
59640-	 */
59641-	page = find_get_incore_page(mapping, index);
59642-	if (page) {
59643-		present = PageUptodate(page);
59644-		put_page(page);
59645-	}
59646-
59647-	return present;
59648-}
59649-
59650-static int __mincore_unmapped_range(unsigned long addr, unsigned long end,
59651-				struct vm_area_struct *vma, unsigned char *vec)
59652-{
59653-	unsigned long nr = (end - addr) >> PAGE_SHIFT;
59654-	int i;
59655-
59656-	if (vma->vm_file) {
59657-		pgoff_t pgoff;
59658-
59659-		pgoff = linear_page_index(vma, addr);
59660-		for (i = 0; i < nr; i++, pgoff++)
59661-			vec[i] = mincore_page(vma->vm_file->f_mapping, pgoff);
59662-	} else {
59663-		for (i = 0; i < nr; i++)
59664-			vec[i] = 0;
59665-	}
59666-	return nr;
59667-}
59668-
59669 static int mincore_unmapped_range(unsigned long addr, unsigned long end,
59670 				   __always_unused int depth,
59671 				   struct mm_walk *walk)
59672 {
59673-	walk->private += __mincore_unmapped_range(addr, end,
59674-						  walk->vma, walk->private);
59675+	unsigned char *vec = walk->private;
59676+	unsigned long nr = (end - addr) >> PAGE_SHIFT;
59677+
59678+	memset(vec, 0, nr);
59679+	walk->private += nr;
59680 	return 0;
59681 }
59682
59683@@ -112,8 +70,9 @@ static int mincore_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
59684 		goto out;
59685 	}
59686
59687+	/* We'll consider a THP page under construction to be there */
59688 	if (pmd_trans_unstable(pmd)) {
59689-		__mincore_unmapped_range(addr, end, vma, vec);
59690+		memset(vec, 1, nr);
59691 		goto out;
59692 	}
59693
59694@@ -122,28 +81,17 @@ static int mincore_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end,
59695 		pte_t pte = *ptep;
59696
59697 		if (pte_none(pte))
59698-			__mincore_unmapped_range(addr, addr + PAGE_SIZE,
59699-						 vma, vec);
59700+			*vec = 0;
59701 		else if (pte_present(pte))
59702 			*vec = 1;
59703 		else { /* pte is a swap entry */
59704 			swp_entry_t entry = pte_to_swp_entry(pte);
59705
59706-			if (non_swap_entry(entry)) {
59707-				/*
59708-				 * migration or hwpoison entries are always
59709-				 * uptodate
59710-				 */
59711-				*vec = 1;
59712-			} else {
59713-#ifdef CONFIG_SWAP
59714-				*vec = mincore_page(swap_address_space(entry),
59715-						    swp_offset(entry));
59716-#else
59717-				WARN_ON(1);
59718-				*vec = 1;
59719-#endif
59720-			}
59721+			/*
59722+			 * migration or hwpoison entries are always
59723+			 * uptodate
59724+			 */
59725+			*vec = !!non_swap_entry(entry);
59726 		}
59727 		vec++;
59728 	}
59729diff --git a/mm/vmalloc.c b/mm/vmalloc.c
59730index f98801428..1a565eaad 100644
59731--- a/mm/vmalloc.c
59732+++ b/mm/vmalloc.c
59733@@ -326,6 +326,7 @@ int map_kernel_range(unsigned long start, unsigned long size, pgprot_t prot,
59734 	flush_cache_vmap(start, start + size);
59735 	return ret;
59736 }
59737+EXPORT_SYMBOL(map_kernel_range);
59738
59739 int is_vmalloc_or_module_addr(const void *x)
59740 {
59741@@ -2097,6 +2098,7 @@ struct vm_struct *__get_vm_area_caller(unsigned long size, unsigned long flags,
59742 	return __get_vm_area_node(size, 1, flags, start, end, NUMA_NO_NODE,
59743 				  GFP_KERNEL, caller);
59744 }
59745+EXPORT_SYMBOL(__get_vm_area_caller);
59746
59747 /**
59748  * get_vm_area - reserve a contiguous kernel virtual area
59749diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
59750index 9f52145bb..6baf1f429 100644
59751--- a/net/bluetooth/hci_event.c
59752+++ b/net/bluetooth/hci_event.c
59753@@ -5593,7 +5593,8 @@ static void process_adv_report(struct hci_dev *hdev, u8 type, bdaddr_t *bdaddr,
59754 		/* If the report will trigger a SCAN_REQ store it for
59755 		 * later merging.
59756 		 */
59757-		if (type == LE_ADV_IND || type == LE_ADV_SCAN_IND) {
59758+		if (!ext_adv && (type == LE_ADV_IND ||
59759+				 type == LE_ADV_SCAN_IND)) {
59760 			store_pending_adv_report(hdev, bdaddr, bdaddr_type,
59761 						 rssi, flags, data, len);
59762 			return;
59763diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
59764index 19ef4577b..bebc833f4 100644
59765--- a/net/ipv4/tcp_output.c
59766+++ b/net/ipv4/tcp_output.c
59767@@ -1561,6 +1561,11 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue,
59768 		return -ENOMEM;
59769 	}
59770
59771+	if (unlikely((sk->sk_wmem_queued >> 1) > sk->sk_sndbuf)) {
59772+		NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPWQUEUETOOBIG);
59773+		return -ENOMEM;
59774+	}
59775+
59776 	if (skb_unclone(skb, gfp))
59777 		return -ENOMEM;
59778
59779diff --git a/net/sunrpc/auth_gss/gss_mech_switch.c b/net/sunrpc/auth_gss/gss_mech_switch.c
59780index fae632da1..d6b8d6f61 100644
59781--- a/net/sunrpc/auth_gss/gss_mech_switch.c
59782+++ b/net/sunrpc/auth_gss/gss_mech_switch.c
59783@@ -34,11 +34,14 @@ gss_mech_free(struct gss_api_mech *gm)
59784 {
59785 	struct pf_desc *pf;
59786 	int i;
59787+	struct auth_domain *test;
59788
59789 	for (i = 0; i < gm->gm_pf_num; i++) {
59790 		pf = &gm->gm_pfs[i];
59791-		if (pf->domain)
59792-			auth_domain_put(pf->domain);
59793+		test = auth_domain_find(pf->auth_domain_name);
59794+		if (test != NULL) {
59795+			test->flavour->domain_release(test);
59796+		}
59797 		kfree(pf->auth_domain_name);
59798 		pf->auth_domain_name = NULL;
59799 	}
59800diff --git a/net/sunrpc/svc.c b/net/sunrpc/svc.c
59801index d38788cd9..f526b67d5 100644
59802--- a/net/sunrpc/svc.c
59803+++ b/net/sunrpc/svc.c
59804@@ -1539,15 +1539,22 @@ int
59805 bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
59806 	       struct svc_rqst *rqstp)
59807 {
59808+	struct net	*net = req->rq_xprt->xprt_net;
59809 	struct kvec	*argv = &rqstp->rq_arg.head[0];
59810 	struct kvec	*resv = &rqstp->rq_res.head[0];
59811 	struct rpc_task *task;
59812+	struct svc_xprt *s_xprt;
59813 	int proc_error;
59814 	int error;
59815
59816 	dprintk("svc: %s(%p)\n", __func__, req);
59817
59818+	s_xprt = req->rq_xprt->ops->bc_get_xprt(serv, net);
59819+	if (!s_xprt)
59820+		goto proc_error;
59821+
59822 	/* Build the svc_rqst used by the common processing routine */
59823+	rqstp->rq_xprt = s_xprt;
59824 	rqstp->rq_xid = req->rq_xid;
59825 	rqstp->rq_prot = req->rq_xprt->prot;
59826 	rqstp->rq_server = serv;
59827@@ -1606,6 +1613,12 @@ bc_svc_process(struct svc_serv *serv, struct rpc_rqst *req,
59828 out:
59829 	dprintk("svc: %s(), error=%d\n", __func__, error);
59830 	return error;
59831+
59832+proc_error:
59833+	/* Processing error: drop the request */
59834+	xprt_free_bc_request(req);
59835+	error = -EINVAL;
59836+	goto out;
59837 }
59838 EXPORT_SYMBOL_GPL(bc_svc_process);
59839 #endif /* CONFIG_SUNRPC_BACKCHANNEL */
59840diff --git a/net/sunrpc/xprtrdma/backchannel.c b/net/sunrpc/xprtrdma/backchannel.c
59841index c92c1aac2..9d1a966ba 100644
59842--- a/net/sunrpc/xprtrdma/backchannel.c
59843+++ b/net/sunrpc/xprtrdma/backchannel.c
59844@@ -35,6 +35,11 @@ int xprt_rdma_bc_setup(struct rpc_xprt *xprt, unsigned int reqs)
59845 	return 0;
59846 }
59847
59848+struct svc_xprt *xprt_rdma_bc_get_xprt(struct svc_serv *serv, struct net *net)
59849+{
59850+	return svc_find_xprt(serv, "rdma-bc", net, AF_UNSPEC, 0);
59851+}
59852+
59853 /**
59854  * xprt_rdma_bc_maxpayload - Return maximum backchannel message size
59855  * @xprt: transport
59856diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
59857index 8fb047888..5ea56bc2a 100644
59858--- a/net/wireless/nl80211.c
59859+++ b/net/wireless/nl80211.c
59860@@ -2121,7 +2121,7 @@ static int nl80211_send_wiphy(struct cfg80211_registered_device *rdev,
59861
59862 	hdr = nl80211hdr_put(msg, portid, seq, flags, cmd);
59863 	if (!hdr)
59864-		return -ENOBUFS;
59865+		goto nla_put_failure;
59866
59867 	if (WARN_ON(!state))
59868 		return -EINVAL;
59869diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
59870index 73df23570..9f959d7b5 100644
59871--- a/net/wireless/wext-sme.c
59872+++ b/net/wireless/wext-sme.c
59873@@ -201,8 +201,8 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev,
59874 			       struct iw_request_info *info,
59875 			       struct iw_point *data, char *ssid)
59876 {
59877-	struct wireless_dev *wdev = dev->ieee80211_ptr;
59878 	int ret = 0;
59879+	struct wireless_dev *wdev = dev->ieee80211_ptr;
59880
59881 	/* call only for station! */
59882 	if (WARN_ON(wdev->iftype != NL80211_IFTYPE_STATION))
59883diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
59884index 941337088..bbdfd6a1b 100644
59885--- a/scripts/Makefile.lib
59886+++ b/scripts/Makefile.lib
59887@@ -210,7 +210,9 @@ cpp_flags      = -Wp,-MMD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)     \
59888
59889 ld_flags       = $(KBUILD_LDFLAGS) $(ldflags-y) $(LDFLAGS_$(@F))
59890
59891-DTC_INCLUDE    := $(srctree)/scripts/dtc/include-prefixes
59892+DTC_INCLUDE    := $(srctree)/scripts/dtc/include-prefixes \
59893+		  $(objtree)/include/generated \
59894+		  $(srctree)/include/dt-bindings
59895
59896 dtc_cpp_flags  = -Wp,-MMD,$(depfile).pre.tmp -nostdinc                    \
59897 		 $(addprefix -I,$(DTC_INCLUDE))                          \
59898@@ -316,7 +318,7 @@ $(obj)/%.dtb.S: $(obj)/%.dtb FORCE
59899 	$(call if_changed,dt_S_dtb)
59900
59901 quiet_cmd_dtc = DTC     $@
59902-cmd_dtc = $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
59903+cmd_dtc = mkdir -p $(dir $(dtc-tmp)); $(HOSTCC) -E $(dtc_cpp_flags) -x assembler-with-cpp -o $(dtc-tmp) $< ; \
59904 	$(DTC) -O $(patsubst .%,%,$(suffix $@)) -o $@ -b 0 \
59905 		$(addprefix -i,$(dir $<) $(DTC_INCLUDE)) $(DTC_FLAGS) \
59906 		-d $(depfile).dtc.tmp $(dtc-tmp) ; \
59907diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
59908index 17cb6890d..af3392da3 100644
59909--- a/scripts/dtc/checks.c
59910+++ b/scripts/dtc/checks.c
59911@@ -819,8 +819,8 @@ static void check_pci_bridge(struct check *c, struct dt_info *dti, struct node *
59912
59913 	node->bus = &pci_bus;
59914
59915-	if (!strprefixeq(node->name, node->basenamelen, "pci") &&
59916-	    !strprefixeq(node->name, node->basenamelen, "pcie"))
59917+	if (!strprefixeq(node->name, 3, "pci") &&
59918+	    !strprefixeq(node->name, 4, "pcie"))
59919 		FAIL(c, dti, node, "node name is not \"pci\" or \"pcie\"");
59920
59921 	prop = get_property(node, "ranges");
59922diff --git a/sound/core/control.c b/sound/core/control.c
59923index 3b44378b9..b94592b46 100644
59924--- a/sound/core/control.c
59925+++ b/sound/core/control.c
59926@@ -1443,7 +1443,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
59927 		return -ENOMEM;
59928
59929 	/* Check the number of elements for this userspace control. */
59930-	count = info->owner;
59931+	count = info->count;
59932 	if (count == 0)
59933 		count = 1;
59934
59935diff --git a/tools/testing/selftests/net/fib_tests.sh b/tools/testing/selftests/net/fib_tests.sh
59936index 6fad54c7e..9d1302bb8 100755
59937--- a/tools/testing/selftests/net/fib_tests.sh
59938+++ b/tools/testing/selftests/net/fib_tests.sh
59939@@ -636,6 +636,20 @@ fib_suppress_test()
59940 	cleanup
59941 }
59942
59943+fib_suppress_test()
59944+{
59945+	$IP link add dummy1 type dummy
59946+	$IP link set dummy1 up
59947+	$IP -6 route add default dev dummy1
59948+	$IP -6 rule add table main suppress_prefixlength 0
59949+	ping -f -c 1000 -W 1 1234::1 || true
59950+	$IP -6 rule del table main suppress_prefixlength 0
59951+	$IP link del dummy1
59952+
59953+	# If we got here without crashing, we're good.
59954+	return 0
59955+}
59956+
59957 ################################################################################
59958 # Tests on route add and replace
59959
59960