diff options
author | Alexandre Oliva <lxoliva@fsfla.org> | 2014-08-10 13:32:46 +0000 |
---|---|---|
committer | Alexandre Oliva <lxoliva@fsfla.org> | 2014-08-10 13:32:46 +0000 |
commit | c328693e90efc83ee330f0344f2346feea6e3a80 (patch) | |
tree | 1c795ec93e72661e480699140074ac6d52aac91e | |
parent | a711ce44dfc016911368844322ad7d9eb7adfe4a (diff) | |
download | linux-libre-raptor-c328693e90efc83ee330f0344f2346feea6e3a80.tar.gz linux-libre-raptor-c328693e90efc83ee330f0344f2346feea6e3a80.zip |
3.16.0-1.fc22.gnu
56 files changed, 12306 insertions, 4928 deletions
diff --git a/freed-ora/current/master/.gitignore b/freed-ora/current/master/.gitignore index 07fc474de..d7bf1f79c 100644 --- a/freed-ora/current/master/.gitignore +++ b/freed-ora/current/master/.gitignore @@ -5,7 +5,4 @@ clog *.rpm *.orig kernel-[23].*/ -/perf-man.tar.gz -/perf-man-3.13.tar.gz -/perf-man-3.14.tar.gz -/perf-man-3.15.tar.gz +perf-man-*.tar.gz diff --git a/freed-ora/current/master/0001-ARM-sunxi-Add-driver-for-SD-MMC-hosts-found-on-Allwi.patch b/freed-ora/current/master/0001-ARM-sunxi-Add-driver-for-SD-MMC-hosts-found-on-Allwi.patch deleted file mode 100644 index de006062f..000000000 --- a/freed-ora/current/master/0001-ARM-sunxi-Add-driver-for-SD-MMC-hosts-found-on-Allwi.patch +++ /dev/null @@ -1,2201 +0,0 @@ -From 528a5cd576861f90f51398c707c602a79623492d Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Thu, 5 Sep 2013 19:52:41 -0300 -Subject: [PATCH] ARM: sunxi: Add driver for SD/MMC hosts found on Allwinner - sunxi SoCs -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The Allwinner sunxi mmc host uses dma in bus-master mode using a built-in -designware idmac controller, which is identical to the one found in the mmc-dw -hosts. However the rest of the host is not identical to mmc-dw, it deals with -sending stop commands in hardware which makes it significantly different -from the mmc-dw devices. - -Signed-off-by: David Lanzendörfer <david.lanzendoerfer@o2s.ch> -Signed-off-by: Emilio López <emilio@elopez.com.ar> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - .../devicetree/bindings/mmc/sunxi-mmc.txt | 43 + - arch/arm/boot/dts/Makefile | 1 + - arch/arm/boot/dts/sun4i-a10-a1000.dts | 9 + - arch/arm/boot/dts/sun4i-a10-cubieboard.dts | 9 + - arch/arm/boot/dts/sun4i-a10-hackberry.dts | 9 + - arch/arm/boot/dts/sun4i-a10-inet97fv2.dts | 9 + - arch/arm/boot/dts/sun4i-a10-mini-xplus.dts | 9 + - arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts | 9 + - arch/arm/boot/dts/sun4i-a10-pcduino.dts | 9 + - arch/arm/boot/dts/sun4i-a10.dtsi | 50 + - arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts | 32 + - arch/arm/boot/dts/sun5i-a10s.dtsi | 41 + - arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts | 16 + - arch/arm/boot/dts/sun5i-a13-olinuxino.dts | 16 + - arch/arm/boot/dts/sun5i-a13.dtsi | 25 + - arch/arm/boot/dts/sun6i-a31-m9.dts | 46 + - arch/arm/boot/dts/sun6i-a31.dtsi | 91 ++ - arch/arm/boot/dts/sun7i-a20-cubieboard2.dts | 9 + - arch/arm/boot/dts/sun7i-a20-cubietruck.dts | 40 + - arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts | 25 + - arch/arm/boot/dts/sun7i-a20.dtsi | 57 + - drivers/clk/sunxi/clk-factors.c | 36 + - drivers/clk/sunxi/clk-sunxi.c | 36 + - drivers/mmc/host/Kconfig | 7 + - drivers/mmc/host/Makefile | 2 + - drivers/mmc/host/sunxi-mmc.c | 1125 ++++++++++++++++++++ - include/linux/clk/sunxi.h | 22 + - 27 files changed, 1783 insertions(+) - create mode 100644 Documentation/devicetree/bindings/mmc/sunxi-mmc.txt - create mode 100644 arch/arm/boot/dts/sun6i-a31-m9.dts - create mode 100644 drivers/mmc/host/sunxi-mmc.c - create mode 100644 include/linux/clk/sunxi.h - -diff --git a/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt b/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt -new file mode 100644 -index 0000000..f0c06e7 ---- /dev/null -+++ b/Documentation/devicetree/bindings/mmc/sunxi-mmc.txt -@@ -0,0 +1,43 @@ -+* Allwinner sunxi MMC controller -+ -+The highspeed MMC host controller on Allwinner SoCs provides an interface -+for MMC, SD and SDIO types of memory cards. -+ -+Supported maximum speeds are the ones of the eMMC standard 4.5 as well -+as the speed of SD standard 3.0. -+Absolute maximum transfer rate is 200MB/s -+ -+Required properties: -+ - compatible : "allwinner,sun4i-a10-mmc" or "allwinner,sun5i-a13-mmc" -+ - reg : mmc controller base registers -+ - clocks : a list with 2 phandle + clock specifier pairs -+ - clock-names : must contain "ahb" and "mod" -+ - interrupts : mmc controller interrupt -+ -+Optional properties: -+ - resets : phandle + reset specifier pair -+ - reset-names : must contain "ahb" -+ - for cd, bus-width and additional generic mmc parameters -+ please refer to mmc.txt within this directory -+ -+Examples: -+ - Within .dtsi: -+ mmc0: mmc@01c0f000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c0f000 0x1000>; -+ clocks = <&ahb_gates 8>, <&mmc0_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <0 32 4>; -+ status = "disabled"; -+ }; -+ -+ - Within dts: -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default", "default"; -+ pinctrl-0 = <&mmc0_pins_a>; -+ pinctrl-1 = <&mmc0_cd_pin_reference_design>; -+ bus-width = <4>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ cd-inverted; -+ status = "okay"; -+ }; -diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile -index 35c146f..1cd137d 100644 ---- a/arch/arm/boot/dts/Makefile -+++ b/arch/arm/boot/dts/Makefile -@@ -351,6 +351,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += \ - sun5i-a13-olinuxino.dtb \ - sun5i-a13-olinuxino-micro.dtb \ - sun6i-a31-colombus.dtb \ -+ sun6i-a31-m9.dtb \ - sun7i-a20-cubieboard2.dtb \ - sun7i-a20-cubietruck.dtb \ - sun7i-a20-olinuxino-micro.dtb -diff --git a/arch/arm/boot/dts/sun4i-a10-a1000.dts b/arch/arm/boot/dts/sun4i-a10-a1000.dts -index fa746aea..3056db5 100644 ---- a/arch/arm/boot/dts/sun4i-a10-a1000.dts -+++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts -@@ -36,6 +36,15 @@ - }; - }; - -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_a>; -+ bus-width = <4>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; -diff --git a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts -index 4684cbe..ad9321b 100644 ---- a/arch/arm/boot/dts/sun4i-a10-cubieboard.dts -+++ b/arch/arm/boot/dts/sun4i-a10-cubieboard.dts -@@ -34,6 +34,15 @@ - }; - }; - -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_a>; -+ bus-width = <4>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; -diff --git a/arch/arm/boot/dts/sun4i-a10-hackberry.dts b/arch/arm/boot/dts/sun4i-a10-hackberry.dts -index d7c17e4..62defd5 100644 ---- a/arch/arm/boot/dts/sun4i-a10-hackberry.dts -+++ b/arch/arm/boot/dts/sun4i-a10-hackberry.dts -@@ -36,6 +36,15 @@ - }; - }; - -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_a>; -+ bus-width = <4>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; -diff --git a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts -index fe9272e..d1a9e34 100644 ---- a/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts -+++ b/arch/arm/boot/dts/sun4i-a10-inet97fv2.dts -@@ -24,6 +24,15 @@ - }; - - soc@01c00000 { -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_a>; -+ bus-width = <4>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ - uart0: serial@01c28000 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0_pins_a>; -diff --git a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts -index dd84a9e..07a598f 100644 ---- a/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts -+++ b/arch/arm/boot/dts/sun4i-a10-mini-xplus.dts -@@ -20,6 +20,15 @@ - compatible = "pineriver,mini-xplus", "allwinner,sun4i-a10"; - - soc@01c00000 { -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_a>; -+ bus-width = <4>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; -diff --git a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts -index 66cf0c7..8d5d321 100644 ---- a/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts -+++ b/arch/arm/boot/dts/sun4i-a10-olinuxino-lime.dts -@@ -33,6 +33,15 @@ - }; - }; - -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_a>; -+ bus-width = <4>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; -diff --git a/arch/arm/boot/dts/sun4i-a10-pcduino.dts b/arch/arm/boot/dts/sun4i-a10-pcduino.dts -index 255b47e..ce02086 100644 ---- a/arch/arm/boot/dts/sun4i-a10-pcduino.dts -+++ b/arch/arm/boot/dts/sun4i-a10-pcduino.dts -@@ -34,6 +34,15 @@ - }; - }; - -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_a>; -+ bus-width = <4>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; -diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi -index 9174724..29fd4f5 100644 ---- a/arch/arm/boot/dts/sun4i-a10.dtsi -+++ b/arch/arm/boot/dts/sun4i-a10.dtsi -@@ -377,6 +377,42 @@ - #size-cells = <0>; - }; - -+ mmc0: mmc@01c0f000 { -+ compatible = "allwinner,sun4i-a10-mmc"; -+ reg = <0x01c0f000 0x1000>; -+ clocks = <&ahb_gates 8>, <&mmc0_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <32>; -+ status = "disabled"; -+ }; -+ -+ mmc1: mmc@01c10000 { -+ compatible = "allwinner,sun4i-a10-mmc"; -+ reg = <0x01c10000 0x1000>; -+ clocks = <&ahb_gates 9>, <&mmc1_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <33>; -+ status = "disabled"; -+ }; -+ -+ mmc2: mmc@01c11000 { -+ compatible = "allwinner,sun4i-a10-mmc"; -+ reg = <0x01c11000 0x1000>; -+ clocks = <&ahb_gates 10>, <&mmc2_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <34>; -+ status = "disabled"; -+ }; -+ -+ mmc3: mmc@01c12000 { -+ compatible = "allwinner,sun4i-a10-mmc"; -+ reg = <0x01c12000 0x1000>; -+ clocks = <&ahb_gates 11>, <&mmc3_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <35>; -+ status = "disabled"; -+ }; -+ - usbphy: phy@01c13400 { - #phy-cells = <1>; - compatible = "allwinner,sun4i-a10-usb-phy"; -@@ -529,6 +565,20 @@ - allwinner,drive = <0>; - allwinner,pull = <0>; - }; -+ -+ mmc0_pins_a: mmc0@0 { -+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5"; -+ allwinner,function = "mmc0"; -+ allwinner,drive = <2>; -+ allwinner,pull = <0>; -+ }; -+ -+ mmc0_cd_pin_a: mmc0_cd_pin@0 { -+ allwinner,pins = "PH1"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; - }; - - timer@01c20c00 { -diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts -index 23611b7..de91308 100644 ---- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts -+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts -@@ -35,6 +35,24 @@ - }; - }; - -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_olinuxino_micro>; -+ bus-width = <4>; -+ cd-gpios = <&pio 6 1 0>; /* PG1 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ -+ mmc1: mmc@01c10000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc1_pins_a>, <&mmc1_cd_pin_olinuxino_micro>; -+ bus-width = <4>; -+ cd-gpios = <&pio 6 13 0>; /* PG13 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - status = "okay"; -@@ -49,6 +67,20 @@ - }; - - pinctrl@01c20800 { -+ mmc0_cd_pin_olinuxino_micro: mmc0_cd_pin@0 { -+ allwinner,pins = "PG1"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; -+ -+ mmc1_cd_pin_olinuxino_micro: mmc1_cd_pin@0 { -+ allwinner,pins = "PG13"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; -+ - led_pins_olinuxino: led_pins@0 { - allwinner,pins = "PE3"; - allwinner,function = "gpio_out"; -diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi -index 79989ed..fb345c2 100644 ---- a/arch/arm/boot/dts/sun5i-a10s.dtsi -+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi -@@ -338,6 +338,33 @@ - #size-cells = <0>; - }; - -+ mmc0: mmc@01c0f000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c0f000 0x1000>; -+ clocks = <&ahb_gates 8>, <&mmc0_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <32>; -+ status = "disabled"; -+ }; -+ -+ mmc1: mmc@01c10000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c10000 0x1000>; -+ clocks = <&ahb_gates 9>, <&mmc1_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <33>; -+ status = "disabled"; -+ }; -+ -+ mmc2: mmc@01c11000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c11000 0x1000>; -+ clocks = <&ahb_gates 10>, <&mmc2_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <34>; -+ status = "disabled"; -+ }; -+ - usbphy: phy@01c13400 { - #phy-cells = <1>; - compatible = "allwinner,sun5i-a13-usb-phy"; -@@ -451,6 +478,20 @@ - allwinner,drive = <0>; - allwinner,pull = <0>; - }; -+ -+ mmc0_pins_a: mmc0@0 { -+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5"; -+ allwinner,function = "mmc0"; -+ allwinner,drive = <2>; -+ allwinner,pull = <0>; -+ }; -+ -+ mmc1_pins_a: mmc1@0 { -+ allwinner,pins = "PG3","PG4","PG5","PG6","PG7","PG8"; -+ allwinner,function = "mmc1"; -+ allwinner,drive = <2>; -+ allwinner,pull = <0>; -+ }; - }; - - timer@01c20c00 { -diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts -index 11169d5..8515f19 100644 ---- a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts -+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts -@@ -21,6 +21,15 @@ - compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13"; - - soc@01c00000 { -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_olinuxinom>; -+ bus-width = <4>; -+ cd-gpios = <&pio 6 0 0>; /* PG0 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - status = "okay"; -@@ -35,6 +44,13 @@ - }; - - pinctrl@01c20800 { -+ mmc0_cd_pin_olinuxinom: mmc0_cd_pin@0 { -+ allwinner,pins = "PG0"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; -+ - led_pins_olinuxinom: led_pins@0 { - allwinner,pins = "PG9"; - allwinner,function = "gpio_out"; -diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts -index 7a9187b..51a9438 100644 ---- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts -+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts -@@ -20,6 +20,15 @@ - compatible = "olimex,a13-olinuxino", "allwinner,sun5i-a13"; - - soc@01c00000 { -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_olinuxino>; -+ bus-width = <4>; -+ cd-gpios = <&pio 6 0 0>; /* PG0 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - status = "okay"; -@@ -34,6 +43,13 @@ - }; - - pinctrl@01c20800 { -+ mmc0_cd_pin_olinuxino: mmc0_cd_pin@0 { -+ allwinner,pins = "PG0"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; -+ - led_pins_olinuxino: led_pins@0 { - allwinner,pins = "PG9"; - allwinner,function = "gpio_out"; -diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi -index f01c315..48ffa51 100644 ---- a/arch/arm/boot/dts/sun5i-a13.dtsi -+++ b/arch/arm/boot/dts/sun5i-a13.dtsi -@@ -320,6 +320,24 @@ - #size-cells = <0>; - }; - -+ mmc0: mmc@01c0f000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c0f000 0x1000>; -+ clocks = <&ahb_gates 8>, <&mmc0_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <32>; -+ status = "disabled"; -+ }; -+ -+ mmc2: mmc@01c11000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c11000 0x1000>; -+ clocks = <&ahb_gates 10>, <&mmc2_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <34>; -+ status = "disabled"; -+ }; -+ - usbphy: phy@01c13400 { - #phy-cells = <1>; - compatible = "allwinner,sun5i-a13-usb-phy"; -@@ -415,6 +433,13 @@ - allwinner,drive = <0>; - allwinner,pull = <0>; - }; -+ -+ mmc0_pins_a: mmc0@0 { -+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5"; -+ allwinner,function = "mmc0"; -+ allwinner,drive = <2>; -+ allwinner,pull = <0>; -+ }; - }; - - timer@01c20c00 { -diff --git a/arch/arm/boot/dts/sun6i-a31-m9.dts b/arch/arm/boot/dts/sun6i-a31-m9.dts -new file mode 100644 -index 0000000..a188721 ---- /dev/null -+++ b/arch/arm/boot/dts/sun6i-a31-m9.dts -@@ -0,0 +1,46 @@ -+/* -+ * Copyright 2014 Hans de Goede <hdegoede@redhat.com> -+ * -+ * The code contained herein is licensed under the GNU General Public -+ * License. You may obtain a copy of the GNU General Public License -+ * Version 2 or later at the following locations: -+ * -+ * http://www.opensource.org/licenses/gpl-license.html -+ * http://www.gnu.org/copyleft/gpl.html -+ */ -+ -+/dts-v1/; -+/include/ "sun6i-a31.dtsi" -+ -+/ { -+ model = "Mele M9 / A1000G Quad top set box"; -+ compatible = "mele,m9", "allwinner,sun6i-a31"; -+ -+ chosen { -+ bootargs = "earlyprintk console=ttyS0,115200"; -+ }; -+ -+ soc@01c00000 { -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_m9>; -+ cd-gpios = <&pio 7 22 0>; /* PH22 */ -+ status = "okay"; -+ }; -+ -+ pio: pinctrl@01c20800 { -+ mmc0_cd_pin_m9: mmc0_cd_pin@0 { -+ allwinner,pins = "PH22"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; -+ }; -+ -+ uart0: serial@01c28000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&uart0_pins_a>; -+ status = "okay"; -+ }; -+ }; -+}; -diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi -index d45efa7..0939fc1 100644 ---- a/arch/arm/boot/dts/sun6i-a31.dtsi -+++ b/arch/arm/boot/dts/sun6i-a31.dtsi -@@ -198,6 +198,38 @@ - "apb2_uart4", "apb2_uart5"; - }; - -+ mmc0_clk: clk@01c20088 { -+ #clock-cells = <0>; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; -+ reg = <0x01c20088 0x4>; -+ clocks = <&osc24M>, <&pll6>; -+ clock-output-names = "mmc0"; -+ }; -+ -+ mmc1_clk: clk@01c2008c { -+ #clock-cells = <0>; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; -+ reg = <0x01c2008c 0x4>; -+ clocks = <&osc24M>, <&pll6>; -+ clock-output-names = "mmc1"; -+ }; -+ -+ mmc2_clk: clk@01c20090 { -+ #clock-cells = <0>; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; -+ reg = <0x01c20090 0x4>; -+ clocks = <&osc24M>, <&pll6>; -+ clock-output-names = "mmc2"; -+ }; -+ -+ mmc3_clk: clk@01c20094 { -+ #clock-cells = <0>; -+ compatible = "allwinner,sun4i-a10-mod0-clk"; -+ reg = <0x01c20094 0x4>; -+ clocks = <&osc24M>, <&pll6>; -+ clock-output-names = "mmc3"; -+ }; -+ - spi0_clk: clk@01c200a0 { - #clock-cells = <0>; - compatible = "allwinner,sun4i-a10-mod0-clk"; -@@ -237,6 +269,58 @@ - #size-cells = <1>; - ranges; - -+ mmc0: mmc@01c0f000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c0f000 0x1000>; -+ clocks = <&ahb1_gates 8>, <&mmc0_clk>; -+ clock-names = "ahb", "mod"; -+ resets = <&ahb1_rst 8>; -+ reset-names = "ahb"; -+ interrupts = <0 60 4>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ -+ mmc1: mmc@01c10000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c10000 0x1000>; -+ clocks = <&ahb1_gates 9>, <&mmc1_clk>; -+ clock-names = "ahb", "mod"; -+ resets = <&ahb1_rst 9>; -+ reset-names = "reset"; -+ interrupts = <0 61 4>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ -+ mmc2: mmc@01c11000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c11000 0x1000>; -+ clocks = <&ahb1_gates 10>, <&mmc2_clk>; -+ clock-names = "ahb", "mod"; -+ resets = <&ahb1_rst 10>; -+ reset-names = "reset"; -+ interrupts = <0 62 4>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ -+ mmc3: mmc@01c12000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c12000 0x1000>; -+ clocks = <&ahb1_gates 11>, <&mmc3_clk>; -+ clock-names = "ahb", "mod"; -+ resets = <&ahb1_rst 11>; -+ reset-names = "reset"; -+ interrupts = <0 63 4>; -+ bus-width = <4>; -+ cd-inverted; -+ status = "disabled"; -+ }; -+ - nmi_intc: interrupt-controller@01f00c0c { - compatible = "allwinner,sun6i-a31-sc-nmi"; - interrupt-controller; -@@ -286,6 +370,13 @@ - allwinner,drive = <0>; - allwinner,pull = <0>; - }; -+ -+ mmc0_pins_a: mmc0@0 { -+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5"; -+ allwinner,function = "mmc0"; -+ allwinner,drive = <2>; -+ allwinner,pull = <0>; -+ }; - }; - - ahb1_rst: reset@01c202c0 { -diff --git a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -index 68de89f..b41aa99 100644 ---- a/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubieboard2.dts -@@ -20,6 +20,15 @@ - compatible = "cubietech,cubieboard2", "allwinner,sun7i-a20"; - - soc@01c00000 { -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_a>; -+ bus-width = <4>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; -diff --git a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -index cb25d3c..270bac0 100644 ---- a/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -+++ b/arch/arm/boot/dts/sun7i-a20-cubietruck.dts -@@ -20,6 +20,23 @@ - compatible = "cubietech,cubietruck", "allwinner,sun7i-a20"; - - soc@01c00000 { -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_a>; -+ bus-width = <4>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ -+ mmc3: mmc@01c12000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc3_pins_a>; -+ vmmc-supply = <®_vmmc3>; -+ non-removable; -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; -@@ -48,6 +65,18 @@ - }; - - pinctrl@01c20800 { -+ mmc3_pins_a: mmc3@0 { -+ /* AP6210 requires pull-up */ -+ allwinner,pull = <1>; -+ }; -+ -+ vmmc3_pin_cubietruck: vmmc3_pin@0 { -+ allwinner,pins = "PH9"; -+ allwinner,function = "gpio_out"; -+ allwinner,drive = <0>; -+ allwinner,pull = <0>; -+ }; -+ - ahci_pwr_pin_cubietruck: ahci_pwr_pin@1 { - allwinner,pins = "PH12"; - allwinner,function = "gpio_out"; -@@ -139,4 +168,15 @@ - reg_usb2_vbus: usb2-vbus { - status = "okay"; - }; -+ -+ reg_vmmc3: vmmc3 { -+ compatible = "regulator-fixed"; -+ pinctrl-names = "default"; -+ pinctrl-0 = <&vmmc3_pin_cubietruck>; -+ regulator-name = "vmmc3"; -+ regulator-min-microvolt = <3300000>; -+ regulator-max-microvolt = <3300000>; -+ enable-active-high; -+ gpio = <&pio 7 9 0>; -+ }; - }; -diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -index eeadf76..f989554 100644 ---- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts -@@ -31,6 +31,24 @@ - status = "okay"; - }; - -+ mmc0: mmc@01c0f000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc0_pins_a>, <&mmc0_cd_pin_a>; -+ bus-width = <4>; -+ cd-gpios = <&pio 7 1 0>; /* PH1 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ -+ mmc3: mmc@01c12000 { -+ pinctrl-names = "default"; -+ pinctrl-0 = <&mmc3_pins_a>, <&mmc3_cd_pin_olinuxinom>; -+ bus-width = <4>; -+ cd-gpios = <&pio 7 11 0>; /* PH11 */ -+ cd-inverted; -+ status = "okay"; -+ }; -+ - usbphy: phy@01c13400 { - usb1_vbus-supply = <®_usb1_vbus>; - usb2_vbus-supply = <®_usb2_vbus>; -@@ -65,6 +83,13 @@ - }; - - pinctrl@01c20800 { -+ mmc3_cd_pin_olinuxinom: mmc3_cd_pin@0 { -+ allwinner,pins = "PH11"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; -+ - led_pins_olinuxino: led_pins@0 { - allwinner,pins = "PH2"; - allwinner,function = "gpio_out"; -diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi -index 32efc10..99e8336 100644 ---- a/arch/arm/boot/dts/sun7i-a20.dtsi -+++ b/arch/arm/boot/dts/sun7i-a20.dtsi -@@ -447,6 +447,42 @@ - #size-cells = <0>; - }; - -+ mmc0: mmc@01c0f000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c0f000 0x1000>; -+ clocks = <&ahb_gates 8>, <&mmc0_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <0 32 4>; -+ status = "disabled"; -+ }; -+ -+ mmc1: mmc@01c10000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c10000 0x1000>; -+ clocks = <&ahb_gates 9>, <&mmc1_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <0 33 4>; -+ status = "disabled"; -+ }; -+ -+ mmc2: mmc@01c11000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c11000 0x1000>; -+ clocks = <&ahb_gates 10>, <&mmc2_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <0 34 4>; -+ status = "disabled"; -+ }; -+ -+ mmc3: mmc@01c12000 { -+ compatible = "allwinner,sun5i-a13-mmc"; -+ reg = <0x01c12000 0x1000>; -+ clocks = <&ahb_gates 11>, <&mmc3_clk>; -+ clock-names = "ahb", "mod"; -+ interrupts = <0 35 4>; -+ status = "disabled"; -+ }; -+ - usbphy: phy@01c13400 { - #phy-cells = <1>; - compatible = "allwinner,sun7i-a20-usb-phy"; -@@ -653,6 +689,27 @@ - allwinner,drive = <0>; - allwinner,pull = <0>; - }; -+ -+ mmc0_pins_a: mmc0@0 { -+ allwinner,pins = "PF0","PF1","PF2","PF3","PF4","PF5"; -+ allwinner,function = "mmc0"; -+ allwinner,drive = <2>; -+ allwinner,pull = <0>; -+ }; -+ -+ mmc0_cd_pin_a: mmc0_cd_pin@0 { -+ allwinner,pins = "PH1"; -+ allwinner,function = "gpio_in"; -+ allwinner,drive = <0>; -+ allwinner,pull = <1>; -+ }; -+ -+ mmc3_pins_a: mmc3@0 { -+ allwinner,pins = "PI4","PI5","PI6","PI7","PI8","PI9"; -+ allwinner,function = "mmc3"; -+ allwinner,drive = <2>; -+ allwinner,pull = <0>; -+ }; - }; - - timer@01c20c00 { -diff --git a/drivers/clk/sunxi/clk-factors.c b/drivers/clk/sunxi/clk-factors.c -index 9e23264..3806d97 100644 ---- a/drivers/clk/sunxi/clk-factors.c -+++ b/drivers/clk/sunxi/clk-factors.c -@@ -77,6 +77,41 @@ static long clk_factors_round_rate(struct clk_hw *hw, unsigned long rate, - return rate; - } - -+static long clk_factors_determine_rate(struct clk_hw *hw, unsigned long rate, -+ unsigned long *best_parent_rate, -+ struct clk **best_parent_p) -+{ -+ struct clk *clk = hw->clk, *parent, *best_parent = NULL; -+ int i, num_parents; -+ unsigned long parent_rate, best = 0, child_rate, best_child_rate = 0; -+ -+ /* find the parent that can help provide the fastest rate <= rate */ -+ num_parents = __clk_get_num_parents(clk); -+ for (i = 0; i < num_parents; i++) { -+ parent = clk_get_parent_by_index(clk, i); -+ if (!parent) -+ continue; -+ if (__clk_get_flags(clk) & CLK_SET_RATE_PARENT) -+ parent_rate = __clk_round_rate(parent, rate); -+ else -+ parent_rate = __clk_get_rate(parent); -+ -+ child_rate = clk_factors_round_rate(hw, rate, &parent_rate); -+ -+ if (child_rate <= rate && child_rate > best_child_rate) { -+ best_parent = parent; -+ best = parent_rate; -+ best_child_rate = child_rate; -+ } -+ } -+ -+ if (best_parent) -+ *best_parent_p = best_parent; -+ *best_parent_rate = best; -+ -+ return best_child_rate; -+} -+ - static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) - { -@@ -113,6 +148,7 @@ static int clk_factors_set_rate(struct clk_hw *hw, unsigned long rate, - } - - const struct clk_ops clk_factors_ops = { -+ .determine_rate = clk_factors_determine_rate, - .recalc_rate = clk_factors_recalc_rate, - .round_rate = clk_factors_round_rate, - .set_rate = clk_factors_set_rate, -diff --git a/drivers/clk/sunxi/clk-sunxi.c b/drivers/clk/sunxi/clk-sunxi.c -index bd7dc73..59f9040 100644 ---- a/drivers/clk/sunxi/clk-sunxi.c -+++ b/drivers/clk/sunxi/clk-sunxi.c -@@ -507,6 +507,42 @@ CLK_OF_DECLARE(sun7i_a20_gmac, "allwinner,sun7i-a20-gmac-clk", - - - /** -+ * clk_sunxi_mmc_phase_control() - configures MMC clock phase control -+ */ -+ -+void clk_sunxi_mmc_phase_control(struct clk_hw *hw, u8 sample, u8 output) -+{ -+ #define to_clk_composite(_hw) container_of(_hw, struct clk_composite, hw) -+ #define to_clk_factors(_hw) container_of(_hw, struct clk_factors, hw) -+ -+ struct clk_composite *composite = to_clk_composite(hw); -+ struct clk_hw *rate_hw = composite->rate_hw; -+ struct clk_factors *factors = to_clk_factors(rate_hw); -+ unsigned long flags = 0; -+ u32 reg; -+ -+ if (factors->lock) -+ spin_lock_irqsave(factors->lock, flags); -+ -+ reg = readl(factors->reg); -+ -+ /* set sample clock phase control */ -+ reg &= ~(0x7 << 20); -+ reg |= ((sample & 0x7) << 20); -+ -+ /* set output clock phase control */ -+ reg &= ~(0x7 << 8); -+ reg |= ((output & 0x7) << 8); -+ -+ writel(reg, factors->reg); -+ -+ if (factors->lock) -+ spin_unlock_irqrestore(factors->lock, flags); -+} -+EXPORT_SYMBOL(clk_sunxi_mmc_phase_control); -+ -+ -+/** - * sunxi_factors_clk_setup() - Setup function for factor clocks - */ - -diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig -index 8aaf8c1..d50ac1c 100644 ---- a/drivers/mmc/host/Kconfig -+++ b/drivers/mmc/host/Kconfig -@@ -694,3 +694,10 @@ config MMC_REALTEK_PCI - help - Say Y here to include driver code to support SD/MMC card interface - of Realtek PCI-E card reader -+ -+config MMC_SUNXI -+ tristate "Allwinner sunxi SD/MMC Host Controller support" -+ depends on ARCH_SUNXI -+ help -+ This selects support for the SD/MMC Host Controller on -+ Allwinner sunxi SoCs. -diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile -index 0c8aa5e..c706c0f 100644 ---- a/drivers/mmc/host/Makefile -+++ b/drivers/mmc/host/Makefile -@@ -53,6 +53,8 @@ obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o - - obj-$(CONFIG_MMC_REALTEK_PCI) += rtsx_pci_sdmmc.o - -+obj-$(CONFIG_MMC_SUNXI) += sunxi-mmc.o -+ - obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o - obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o - obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o -diff --git a/drivers/mmc/host/sunxi-mmc.c b/drivers/mmc/host/sunxi-mmc.c -new file mode 100644 -index 0000000..f1de52c ---- /dev/null -+++ b/drivers/mmc/host/sunxi-mmc.c -@@ -0,0 +1,1125 @@ -+/* -+ * Driver for sunxi SD/MMC host controllers -+ * (C) Copyright 2007-2011 Reuuimlla Technology Co., Ltd. -+ * (C) Copyright 2007-2011 Aaron Maoye <leafy.myeh@reuuimllatech.com> -+ * (C) Copyright 2013-2014 O2S GmbH <www.o2s.ch> -+ * (C) Copyright 2013-2014 David Lanzendörfer <david.lanzendoerfer@o2s.ch> -+ * (C) Copyright 2013-2014 Hans de Goede <hdegoede@redhat.com> -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License as -+ * published by the Free Software Foundation; either version 2 of -+ * the License, or (at your option) any later version. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/module.h> -+#include <linux/io.h> -+#include <linux/device.h> -+#include <linux/interrupt.h> -+#include <linux/delay.h> -+#include <linux/err.h> -+ -+#include <linux/clk.h> -+#include <linux/clk-private.h> -+#include <linux/clk/sunxi.h> -+ -+#include <linux/gpio.h> -+#include <linux/platform_device.h> -+#include <linux/spinlock.h> -+#include <linux/scatterlist.h> -+#include <linux/dma-mapping.h> -+#include <linux/slab.h> -+#include <linux/regulator/consumer.h> -+#include <linux/reset.h> -+ -+#include <linux/of_address.h> -+#include <linux/of_gpio.h> -+#include <linux/of_platform.h> -+ -+#include <linux/mmc/host.h> -+#include <linux/mmc/sd.h> -+#include <linux/mmc/sdio.h> -+#include <linux/mmc/mmc.h> -+#include <linux/mmc/core.h> -+#include <linux/mmc/card.h> -+#include <linux/mmc/slot-gpio.h> -+ -+/* register offset definitions */ -+#define SDXC_REG_GCTRL (0x00) /* SMC Global Control Register */ -+#define SDXC_REG_CLKCR (0x04) /* SMC Clock Control Register */ -+#define SDXC_REG_TMOUT (0x08) /* SMC Time Out Register */ -+#define SDXC_REG_WIDTH (0x0C) /* SMC Bus Width Register */ -+#define SDXC_REG_BLKSZ (0x10) /* SMC Block Size Register */ -+#define SDXC_REG_BCNTR (0x14) /* SMC Byte Count Register */ -+#define SDXC_REG_CMDR (0x18) /* SMC Command Register */ -+#define SDXC_REG_CARG (0x1C) /* SMC Argument Register */ -+#define SDXC_REG_RESP0 (0x20) /* SMC Response Register 0 */ -+#define SDXC_REG_RESP1 (0x24) /* SMC Response Register 1 */ -+#define SDXC_REG_RESP2 (0x28) /* SMC Response Register 2 */ -+#define SDXC_REG_RESP3 (0x2C) /* SMC Response Register 3 */ -+#define SDXC_REG_IMASK (0x30) /* SMC Interrupt Mask Register */ -+#define SDXC_REG_MISTA (0x34) /* SMC Masked Interrupt Status Register */ -+#define SDXC_REG_RINTR (0x38) /* SMC Raw Interrupt Status Register */ -+#define SDXC_REG_STAS (0x3C) /* SMC Status Register */ -+#define SDXC_REG_FTRGL (0x40) /* SMC FIFO Threshold Watermark Registe */ -+#define SDXC_REG_FUNS (0x44) /* SMC Function Select Register */ -+#define SDXC_REG_CBCR (0x48) /* SMC CIU Byte Count Register */ -+#define SDXC_REG_BBCR (0x4C) /* SMC BIU Byte Count Register */ -+#define SDXC_REG_DBGC (0x50) /* SMC Debug Enable Register */ -+#define SDXC_REG_HWRST (0x78) /* SMC Card Hardware Reset for Register */ -+#define SDXC_REG_DMAC (0x80) /* SMC IDMAC Control Register */ -+#define SDXC_REG_DLBA (0x84) /* SMC IDMAC Descriptor List Base Addre */ -+#define SDXC_REG_IDST (0x88) /* SMC IDMAC Status Register */ -+#define SDXC_REG_IDIE (0x8C) /* SMC IDMAC Interrupt Enable Register */ -+#define SDXC_REG_CHDA (0x90) -+#define SDXC_REG_CBDA (0x94) -+ -+#define mci_readl(host, reg) \ -+ readl((host)->reg_base + SDXC_##reg) -+#define mci_writel(host, reg, value) \ -+ writel((value), (host)->reg_base + SDXC_##reg) -+ -+/* global control register bits */ -+#define SDXC_SOFT_RESET BIT(0) -+#define SDXC_FIFO_RESET BIT(1) -+#define SDXC_DMA_RESET BIT(2) -+#define SDXC_INTERRUPT_ENABLE_BIT BIT(4) -+#define SDXC_DMA_ENABLE_BIT BIT(5) -+#define SDXC_DEBOUNCE_ENABLE_BIT BIT(8) -+#define SDXC_POSEDGE_LATCH_DATA BIT(9) -+#define SDXC_DDR_MODE BIT(10) -+#define SDXC_MEMORY_ACCESS_DONE BIT(29) -+#define SDXC_ACCESS_DONE_DIRECT BIT(30) -+#define SDXC_ACCESS_BY_AHB BIT(31) -+#define SDXC_ACCESS_BY_DMA (0 << 31) -+#define SDXC_HARDWARE_RESET \ -+ (SDXC_SOFT_RESET | SDXC_FIFO_RESET | SDXC_DMA_RESET) -+ -+/* clock control bits */ -+#define SDXC_CARD_CLOCK_ON BIT(16) -+#define SDXC_LOW_POWER_ON BIT(17) -+ -+/* bus width */ -+#define SDXC_WIDTH1 0 -+#define SDXC_WIDTH4 1 -+#define SDXC_WIDTH8 2 -+ -+/* smc command bits */ -+#define SDXC_RESP_EXPIRE BIT(6) -+#define SDXC_LONG_RESPONSE BIT(7) -+#define SDXC_CHECK_RESPONSE_CRC BIT(8) -+#define SDXC_DATA_EXPIRE BIT(9) -+#define SDXC_WRITE BIT(10) -+#define SDXC_SEQUENCE_MODE BIT(11) -+#define SDXC_SEND_AUTO_STOP BIT(12) -+#define SDXC_WAIT_PRE_OVER BIT(13) -+#define SDXC_STOP_ABORT_CMD BIT(14) -+#define SDXC_SEND_INIT_SEQUENCE BIT(15) -+#define SDXC_UPCLK_ONLY BIT(21) -+#define SDXC_READ_CEATA_DEV BIT(22) -+#define SDXC_CCS_EXPIRE BIT(23) -+#define SDXC_ENABLE_BIT_BOOT BIT(24) -+#define SDXC_ALT_BOOT_OPTIONS BIT(25) -+#define SDXC_BOOT_ACK_EXPIRE BIT(26) -+#define SDXC_BOOT_ABORT BIT(27) -+#define SDXC_VOLTAGE_SWITCH BIT(28) -+#define SDXC_USE_HOLD_REGISTER BIT(29) -+#define SDXC_START BIT(31) -+ -+/* interrupt bits */ -+#define SDXC_RESP_ERROR BIT(1) -+#define SDXC_COMMAND_DONE BIT(2) -+#define SDXC_DATA_OVER BIT(3) -+#define SDXC_TX_DATA_REQUEST BIT(4) -+#define SDXC_RX_DATA_REQUEST BIT(5) -+#define SDXC_RESP_CRC_ERROR BIT(6) -+#define SDXC_DATA_CRC_ERROR BIT(7) -+#define SDXC_RESP_TIMEOUT BIT(8) -+#define SDXC_DATA_TIMEOUT BIT(9) -+#define SDXC_VOLTAGE_CHANGE_DONE BIT(10) -+#define SDXC_FIFO_RUN_ERROR BIT(11) -+#define SDXC_HARD_WARE_LOCKED BIT(12) -+#define SDXC_START_BIT_ERROR BIT(13) -+#define SDXC_AUTO_COMMAND_DONE BIT(14) -+#define SDXC_END_BIT_ERROR BIT(15) -+#define SDXC_SDIO_INTERRUPT BIT(16) -+#define SDXC_CARD_INSERT BIT(30) -+#define SDXC_CARD_REMOVE BIT(31) -+#define SDXC_INTERRUPT_ERROR_BIT \ -+ (SDXC_RESP_ERROR | SDXC_RESP_CRC_ERROR | SDXC_DATA_CRC_ERROR | \ -+ SDXC_RESP_TIMEOUT | SDXC_DATA_TIMEOUT | SDXC_FIFO_RUN_ERROR | \ -+ SDXC_HARD_WARE_LOCKED | SDXC_START_BIT_ERROR | SDXC_END_BIT_ERROR) -+#define SDXC_INTERRUPT_DONE_BIT \ -+ (SDXC_AUTO_COMMAND_DONE | SDXC_DATA_OVER | \ -+ SDXC_COMMAND_DONE | SDXC_VOLTAGE_CHANGE_DONE) -+ -+/* status */ -+#define SDXC_RXWL_FLAG BIT(0) -+#define SDXC_TXWL_FLAG BIT(1) -+#define SDXC_FIFO_EMPTY BIT(2) -+#define SDXC_FIFO_FULL BIT(3) -+#define SDXC_CARD_PRESENT BIT(8) -+#define SDXC_CARD_DATA_BUSY BIT(9) -+#define SDXC_DATA_FSM_BUSY BIT(10) -+#define SDXC_DMA_REQUEST BIT(31) -+#define SDXC_FIFO_SIZE 16 -+ -+/* Function select */ -+#define SDXC_CEATA_ON (0xceaa << 16) -+#define SDXC_SEND_IRQ_RESPONSE BIT(0) -+#define SDXC_SDIO_READ_WAIT BIT(1) -+#define SDXC_ABORT_READ_DATA BIT(2) -+#define SDXC_SEND_CCSD BIT(8) -+#define SDXC_SEND_AUTO_STOPCCSD BIT(9) -+#define SDXC_CEATA_DEV_IRQ_ENABLE BIT(10) -+ -+/* IDMA controller bus mod bit field */ -+#define SDXC_IDMAC_SOFT_RESET BIT(0) -+#define SDXC_IDMAC_FIX_BURST BIT(1) -+#define SDXC_IDMAC_IDMA_ON BIT(7) -+#define SDXC_IDMAC_REFETCH_DES BIT(31) -+ -+/* IDMA status bit field */ -+#define SDXC_IDMAC_TRANSMIT_INTERRUPT BIT(0) -+#define SDXC_IDMAC_RECEIVE_INTERRUPT BIT(1) -+#define SDXC_IDMAC_FATAL_BUS_ERROR BIT(2) -+#define SDXC_IDMAC_DESTINATION_INVALID BIT(4) -+#define SDXC_IDMAC_CARD_ERROR_SUM BIT(5) -+#define SDXC_IDMAC_NORMAL_INTERRUPT_SUM BIT(8) -+#define SDXC_IDMAC_ABNORMAL_INTERRUPT_SUM BIT(9) -+#define SDXC_IDMAC_HOST_ABORT_INTERRUPT BIT(10) -+#define SDXC_IDMAC_IDLE (0 << 13) -+#define SDXC_IDMAC_SUSPEND (1 << 13) -+#define SDXC_IDMAC_DESC_READ (2 << 13) -+#define SDXC_IDMAC_DESC_CHECK (3 << 13) -+#define SDXC_IDMAC_READ_REQUEST_WAIT (4 << 13) -+#define SDXC_IDMAC_WRITE_REQUEST_WAIT (5 << 13) -+#define SDXC_IDMAC_READ (6 << 13) -+#define SDXC_IDMAC_WRITE (7 << 13) -+#define SDXC_IDMAC_DESC_CLOSE (8 << 13) -+ -+/* -+* If the idma-des-size-bits of property is ie 13, bufsize bits are: -+* Bits 0-12: buf1 size -+* Bits 13-25: buf2 size -+* Bits 26-31: not used -+* Since we only ever set buf1 size, we can simply store it directly. -+*/ -+#define SDXC_IDMAC_DES0_DIC BIT(1) /* disable interrupt on completion */ -+#define SDXC_IDMAC_DES0_LD BIT(2) /* last descriptor */ -+#define SDXC_IDMAC_DES0_FD BIT(3) /* first descriptor */ -+#define SDXC_IDMAC_DES0_CH BIT(4) /* chain mode */ -+#define SDXC_IDMAC_DES0_ER BIT(5) /* end of ring */ -+#define SDXC_IDMAC_DES0_CES BIT(30) /* card error summary */ -+#define SDXC_IDMAC_DES0_OWN BIT(31) /* 1-idma owns it, 0-host owns it */ -+ -+struct sunxi_idma_des { -+ u32 config; -+ u32 buf_size; -+ u32 buf_addr_ptr1; -+ u32 buf_addr_ptr2; -+}; -+ -+struct sunxi_mmc_host { -+ struct mmc_host *mmc; -+ struct regulator *vmmc; -+ struct reset_control *reset; -+ -+ /* IO mapping base */ -+ void __iomem *reg_base; -+ -+ spinlock_t lock; -+ struct tasklet_struct manual_stop_tasklet; -+ -+ /* clock management */ -+ struct clk *clk_ahb; -+ struct clk *clk_mod; -+ -+ /* ios information */ -+ u32 clk_mod_rate; -+ u32 bus_width; -+ u32 idma_des_size_bits; -+ u32 ddr; -+ u32 voltage_switching; -+ -+ /* irq */ -+ int irq; -+ u32 int_sum; -+ u32 sdio_imask; -+ -+ /* flags */ -+ bool wait_dma; -+ -+ dma_addr_t sg_dma; -+ void *sg_cpu; -+ -+ struct mmc_request *mrq; -+ struct mmc_request *manual_stop_mrq; -+ u32 ferror; -+}; -+ -+static int sunxi_mmc_init_host(struct mmc_host *mmc) -+{ -+ u32 rval; -+ struct sunxi_mmc_host *smc_host = mmc_priv(mmc); -+ int ret; -+ -+ ret = clk_prepare_enable(smc_host->clk_ahb); -+ if (ret) { -+ dev_err(mmc_dev(smc_host->mmc), "AHB clk err %d\n", ret); -+ return ret; -+ } -+ -+ ret = clk_prepare_enable(smc_host->clk_mod); -+ if (ret) { -+ dev_err(mmc_dev(smc_host->mmc), "MOD clk err %d\n", ret); -+ clk_disable_unprepare(smc_host->clk_ahb); -+ return ret; -+ } -+ -+ if (smc_host->reset) { -+ ret = reset_control_deassert(smc_host->reset); -+ if (ret) { -+ dev_err(mmc_dev(smc_host->mmc), "reset err %d\n", ret); -+ clk_disable_unprepare(smc_host->clk_ahb); -+ clk_disable_unprepare(smc_host->clk_mod); -+ return ret; -+ } -+ } -+ -+ /* reset controller */ -+ rval = mci_readl(smc_host, REG_GCTRL); -+ rval |= SDXC_HARDWARE_RESET; -+ mci_writel(smc_host, REG_GCTRL, rval); -+ -+ mci_writel(smc_host, REG_FTRGL, 0x20070008); -+ mci_writel(smc_host, REG_TMOUT, 0xffffffff); -+ mci_writel(smc_host, REG_IMASK, smc_host->sdio_imask); -+ mci_writel(smc_host, REG_RINTR, 0xffffffff); -+ mci_writel(smc_host, REG_DBGC, 0xdeb); -+ mci_writel(smc_host, REG_FUNS, SDXC_CEATA_ON); -+ mci_writel(smc_host, REG_DLBA, smc_host->sg_dma); -+ -+ rval = mci_readl(smc_host, REG_GCTRL); -+ rval |= SDXC_INTERRUPT_ENABLE_BIT; -+ rval &= ~SDXC_ACCESS_DONE_DIRECT; -+ mci_writel(smc_host, REG_GCTRL, rval); -+ -+ return 0; -+} -+ -+static void sunxi_mmc_exit_host(struct sunxi_mmc_host *smc_host) -+{ -+ mci_writel(smc_host, REG_GCTRL, SDXC_HARDWARE_RESET); -+ -+ if (smc_host->reset) -+ reset_control_assert(smc_host->reset); -+ -+ clk_disable_unprepare(smc_host->clk_ahb); -+ clk_disable_unprepare(smc_host->clk_mod); -+} -+ -+/* /\* UHS-I Operation Modes */ -+/* * DS 25MHz 12.5MB/s 3.3V */ -+/* * HS 50MHz 25MB/s 3.3V */ -+/* * SDR12 25MHz 12.5MB/s 1.8V */ -+/* * SDR25 50MHz 25MB/s 1.8V */ -+/* * SDR50 100MHz 50MB/s 1.8V */ -+/* * SDR104 208MHz 104MB/s 1.8V */ -+/* * DDR50 50MHz 50MB/s 1.8V */ -+/* * MMC Operation Modes */ -+/* * DS 26MHz 26MB/s 3/1.8/1.2V */ -+/* * HS 52MHz 52MB/s 3/1.8/1.2V */ -+/* * HSDDR 52MHz 104MB/s 3/1.8/1.2V */ -+/* * HS200 200MHz 200MB/s 1.8/1.2V */ -+/* * */ -+/* * Spec. Timing */ -+/* * SD3.0 */ -+/* * Fcclk Tcclk Fsclk Tsclk Tis Tih odly RTis RTih */ -+/* * 400K 2.5us 24M 41ns 5ns 5ns 1 2209ns 41ns */ -+/* * 25M 40ns 600M 1.67ns 5ns 5ns 3 14.99ns 5.01ns */ -+/* * 50M 20ns 600M 1.67ns 6ns 2ns 3 14.99ns 5.01ns */ -+/* * 50MDDR 20ns 600M 1.67ns 6ns 0.8ns 2 6.67ns 3.33ns */ -+/* * 104M 9.6ns 600M 1.67ns 3ns 0.8ns 1 7.93ns 1.67ns */ -+/* * 208M 4.8ns 600M 1.67ns 1.4ns 0.8ns 1 3.33ns 1.67ns */ -+ -+/* * 25M 40ns 300M 3.33ns 5ns 5ns 2 13.34ns 6.66ns */ -+/* * 50M 20ns 300M 3.33ns 6ns 2ns 2 13.34ns 6.66ns */ -+/* * 50MDDR 20ns 300M 3.33ns 6ns 0.8ns 1 6.67ns 3.33ns */ -+/* * 104M 9.6ns 300M 3.33ns 3ns 0.8ns 0 7.93ns 1.67ns */ -+/* * 208M 4.8ns 300M 3.33ns 1.4ns 0.8ns 0 3.13ns 1.67ns */ -+ -+/* * eMMC4.5 */ -+/* * 400K 2.5us 24M 41ns 3ns 3ns 1 2209ns 41ns */ -+/* * 25M 40ns 600M 1.67ns 3ns 3ns 3 14.99ns 5.01ns */ -+/* * 50M 20ns 600M 1.67ns 3ns 3ns 3 14.99ns 5.01ns */ -+/* * 50MDDR 20ns 600M 1.67ns 2.5ns 2.5ns 2 6.67ns 3.33ns */ -+/* * 200M 5ns 600M 1.67ns 1.4ns 0.8ns 1 3.33ns 1.67ns */ -+/* *\/ */ -+ -+static void sunxi_mmc_init_idma_des(struct sunxi_mmc_host *host, -+ struct mmc_data *data) -+{ -+ struct sunxi_idma_des *pdes = (struct sunxi_idma_des *)host->sg_cpu; -+ struct sunxi_idma_des *pdes_pa = (struct sunxi_idma_des *)host->sg_dma; -+ int i, max_len = (1 << host->idma_des_size_bits); -+ -+ for (i = 0; i < data->sg_len; i++) { -+ pdes[i].config = SDXC_IDMAC_DES0_CH | SDXC_IDMAC_DES0_OWN | -+ SDXC_IDMAC_DES0_DIC; -+ -+ if (data->sg[i].length == max_len) -+ pdes[i].buf_size = 0; /* 0 == max_len */ -+ else -+ pdes[i].buf_size = data->sg[i].length; -+ -+ pdes[i].buf_addr_ptr1 = sg_dma_address(&data->sg[i]); -+ pdes[i].buf_addr_ptr2 = (u32)&pdes_pa[i + 1]; -+ } -+ -+ pdes[0].config |= SDXC_IDMAC_DES0_FD; -+ pdes[i - 1].config = SDXC_IDMAC_DES0_OWN | SDXC_IDMAC_DES0_LD; -+ -+ /* -+ * Avoid the io-store starting the idmac hitting io-mem before the -+ * descriptors hit the main-mem. -+ */ -+ wmb(); -+} -+ -+static enum dma_data_direction sunxi_mmc_get_dma_dir(struct mmc_data *data) -+{ -+ if (data->flags & MMC_DATA_WRITE) -+ return DMA_TO_DEVICE; -+ else -+ return DMA_FROM_DEVICE; -+} -+ -+static int sunxi_mmc_map_dma(struct sunxi_mmc_host *smc_host, -+ struct mmc_data *data) -+{ -+ u32 i, dma_len; -+ struct scatterlist *sg; -+ -+ dma_len = dma_map_sg(mmc_dev(smc_host->mmc), data->sg, data->sg_len, -+ sunxi_mmc_get_dma_dir(data)); -+ if (dma_len == 0) { -+ dev_err(mmc_dev(smc_host->mmc), "dma_map_sg failed\n"); -+ return -ENOMEM; -+ } -+ -+ for_each_sg(data->sg, sg, data->sg_len, i) { -+ if (sg->offset & 3 || sg->length & 3) { -+ dev_err(mmc_dev(smc_host->mmc), -+ "unaligned scatterlist: os %x length %d\n", -+ sg->offset, sg->length); -+ return -EINVAL; -+ } -+ } -+ -+ return 0; -+} -+ -+static void sunxi_mmc_start_dma(struct sunxi_mmc_host *smc_host, -+ struct mmc_data *data) -+{ -+ u32 rval; -+ -+ sunxi_mmc_init_idma_des(smc_host, data); -+ -+ rval = mci_readl(smc_host, REG_GCTRL); -+ rval |= SDXC_DMA_ENABLE_BIT; -+ mci_writel(smc_host, REG_GCTRL, rval); -+ rval |= SDXC_DMA_RESET; -+ mci_writel(smc_host, REG_GCTRL, rval); -+ -+ mci_writel(smc_host, REG_DMAC, SDXC_IDMAC_SOFT_RESET); -+ -+ if (!(data->flags & MMC_DATA_WRITE)) -+ mci_writel(smc_host, REG_IDIE, SDXC_IDMAC_RECEIVE_INTERRUPT); -+ -+ mci_writel(smc_host, REG_DMAC, -+ SDXC_IDMAC_FIX_BURST | SDXC_IDMAC_IDMA_ON); -+} -+ -+static void sunxi_mmc_send_manual_stop(struct sunxi_mmc_host *host, -+ struct mmc_request *req) -+{ -+ u32 cmd_val = SDXC_START | SDXC_RESP_EXPIRE | SDXC_STOP_ABORT_CMD -+ | SDXC_CHECK_RESPONSE_CRC | MMC_STOP_TRANSMISSION; -+ u32 ri = 0; -+ unsigned long expire = jiffies + msecs_to_jiffies(1000); -+ -+ mci_writel(host, REG_CARG, 0); -+ mci_writel(host, REG_CMDR, cmd_val); -+ -+ do { -+ ri = mci_readl(host, REG_RINTR); -+ } while (!(ri & (SDXC_COMMAND_DONE | SDXC_INTERRUPT_ERROR_BIT)) && -+ time_before(jiffies, expire)); -+ -+ if (ri & SDXC_INTERRUPT_ERROR_BIT) { -+ dev_err(mmc_dev(host->mmc), "send stop command failed\n"); -+ if (req->stop) -+ req->stop->resp[0] = -ETIMEDOUT; -+ } else { -+ if (req->stop) -+ req->stop->resp[0] = mci_readl(host, REG_RESP0); -+ } -+ -+ mci_writel(host, REG_RINTR, 0xffff); -+} -+ -+static void sunxi_mmc_dump_errinfo(struct sunxi_mmc_host *smc_host) -+{ -+ struct mmc_command *cmd = smc_host->mrq->cmd; -+ struct mmc_data *data = smc_host->mrq->data; -+ -+ /* For some cmds timeout is normal with sd/mmc cards */ -+ if ((smc_host->int_sum & SDXC_INTERRUPT_ERROR_BIT) == -+ SDXC_RESP_TIMEOUT && (cmd->opcode == SD_IO_SEND_OP_COND || -+ cmd->opcode == SD_IO_RW_DIRECT)) -+ return; -+ -+ dev_err(mmc_dev(smc_host->mmc), -+ "smc %d err, cmd %d,%s%s%s%s%s%s%s%s%s%s !!\n", -+ smc_host->mmc->index, cmd->opcode, -+ data ? (data->flags & MMC_DATA_WRITE ? " WR" : " RD") : "", -+ smc_host->int_sum & SDXC_RESP_ERROR ? " RE" : "", -+ smc_host->int_sum & SDXC_RESP_CRC_ERROR ? " RCE" : "", -+ smc_host->int_sum & SDXC_DATA_CRC_ERROR ? " DCE" : "", -+ smc_host->int_sum & SDXC_RESP_TIMEOUT ? " RTO" : "", -+ smc_host->int_sum & SDXC_DATA_TIMEOUT ? " DTO" : "", -+ smc_host->int_sum & SDXC_FIFO_RUN_ERROR ? " FE" : "", -+ smc_host->int_sum & SDXC_HARD_WARE_LOCKED ? " HL" : "", -+ smc_host->int_sum & SDXC_START_BIT_ERROR ? " SBE" : "", -+ smc_host->int_sum & SDXC_END_BIT_ERROR ? " EBE" : "" -+ ); -+} -+ -+/* Called in interrupt context! */ -+static int sunxi_mmc_finalize_request(struct sunxi_mmc_host *host) -+{ -+ struct mmc_request *mrq = host->mrq; -+ -+ mci_writel(host, REG_IMASK, host->sdio_imask); -+ mci_writel(host, REG_IDIE, 0); -+ -+ if (host->int_sum & SDXC_INTERRUPT_ERROR_BIT) { -+ sunxi_mmc_dump_errinfo(host); -+ mrq->cmd->error = -ETIMEDOUT; -+ -+ if (mrq->data) -+ mrq->data->error = -ETIMEDOUT; -+ -+ if (mrq->stop) -+ mrq->stop->error = -ETIMEDOUT; -+ } else { -+ if (mrq->cmd->flags & MMC_RSP_136) { -+ mrq->cmd->resp[0] = mci_readl(host, REG_RESP3); -+ mrq->cmd->resp[1] = mci_readl(host, REG_RESP2); -+ mrq->cmd->resp[2] = mci_readl(host, REG_RESP1); -+ mrq->cmd->resp[3] = mci_readl(host, REG_RESP0); -+ } else { -+ mrq->cmd->resp[0] = mci_readl(host, REG_RESP0); -+ } -+ -+ if (mrq->data) -+ mrq->data->bytes_xfered = -+ mrq->data->blocks * mrq->data->blksz; -+ } -+ -+ if (mrq->data) { -+ struct mmc_data *data = mrq->data; -+ u32 rval; -+ -+ mci_writel(host, REG_IDST, 0x337); -+ mci_writel(host, REG_DMAC, 0); -+ rval = mci_readl(host, REG_GCTRL); -+ rval |= SDXC_DMA_RESET; -+ mci_writel(host, REG_GCTRL, rval); -+ rval &= ~SDXC_DMA_ENABLE_BIT; -+ mci_writel(host, REG_GCTRL, rval); -+ rval |= SDXC_FIFO_RESET; -+ mci_writel(host, REG_GCTRL, rval); -+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len, -+ sunxi_mmc_get_dma_dir(data)); -+ } -+ -+ mci_writel(host, REG_RINTR, 0xffff); -+ -+ dev_dbg(mmc_dev(host->mmc), "req done, resp %08x %08x %08x %08x\n", -+ mrq->cmd->resp[0], mrq->cmd->resp[1], -+ mrq->cmd->resp[2], mrq->cmd->resp[3]); -+ -+ host->mrq = NULL; -+ host->int_sum = 0; -+ host->wait_dma = false; -+ -+ if (mrq->data && mrq->data->error) { -+ host->manual_stop_mrq = mrq; -+ tasklet_schedule(&host->manual_stop_tasklet); -+ return -EBUSY; -+ } -+ -+ return 0; -+} -+ -+static irqreturn_t sunxi_mmc_irq(int irq, void *dev_id) -+{ -+ struct sunxi_mmc_host *host = dev_id; -+ struct mmc_request *mrq; -+ bool finalize = false; -+ bool complete = false; -+ bool sdio_int = false; -+ u32 msk_int; -+ u32 idma_int; -+ -+ spin_lock(&host->lock); -+ -+ idma_int = mci_readl(host, REG_IDST); -+ msk_int = mci_readl(host, REG_MISTA); -+ -+ dev_dbg(mmc_dev(host->mmc), "irq: rq %p mi %08x idi %08x\n", -+ host->mrq, msk_int, idma_int); -+ -+ mrq = host->mrq; -+ if (mrq) { -+ if (idma_int & SDXC_IDMAC_RECEIVE_INTERRUPT) -+ host->wait_dma = false; -+ -+ host->int_sum |= msk_int; -+ -+ /* Wait for COMMAND_DONE on RESPONSE_TIMEOUT before finalize */ -+ if ((host->int_sum & SDXC_RESP_TIMEOUT) && -+ !(host->int_sum & SDXC_COMMAND_DONE)) -+ mci_writel(host, REG_IMASK, -+ host->sdio_imask | SDXC_COMMAND_DONE); -+ /* Don't wait for dma on error */ -+ else if (host->int_sum & SDXC_INTERRUPT_ERROR_BIT) -+ finalize = true; -+ else if ((host->int_sum & SDXC_INTERRUPT_DONE_BIT) && -+ !host->wait_dma) -+ finalize = true; -+ } -+ -+ if (msk_int & SDXC_SDIO_INTERRUPT) -+ sdio_int = true; -+ -+ mci_writel(host, REG_RINTR, msk_int); -+ mci_writel(host, REG_IDST, idma_int); -+ -+ if (finalize) { -+ if (sunxi_mmc_finalize_request(host) == 0) -+ complete = true; -+ } -+ -+ spin_unlock(&host->lock); -+ -+ if (complete) -+ mmc_request_done(host->mmc, mrq); -+ -+ if (sdio_int) -+ mmc_signal_sdio_irq(host->mmc); -+ -+ return IRQ_HANDLED; -+} -+ -+static void sunxi_mmc_manual_stop_tasklet(unsigned long data) -+{ -+ struct sunxi_mmc_host *host = (struct sunxi_mmc_host *) data; -+ struct mmc_request *mrq; -+ unsigned long iflags; -+ -+ spin_lock_irqsave(&host->lock, iflags); -+ mrq = host->manual_stop_mrq; -+ spin_unlock_irqrestore(&host->lock, iflags); -+ -+ if (!mrq) { -+ dev_err(mmc_dev(host->mmc), "no request for manual stop\n"); -+ return; -+ } -+ -+ dev_err(mmc_dev(host->mmc), "data error, sending stop command\n"); -+ sunxi_mmc_send_manual_stop(host, mrq); -+ -+ spin_lock_irqsave(&host->lock, iflags); -+ host->manual_stop_mrq = NULL; -+ spin_unlock_irqrestore(&host->lock, iflags); -+ -+ mmc_request_done(host->mmc, mrq); -+} -+ -+static void sunxi_mmc_oclk_onoff(struct sunxi_mmc_host *host, u32 oclk_en) -+{ -+ unsigned long expire = jiffies + msecs_to_jiffies(2000); -+ u32 rval; -+ -+ rval = mci_readl(host, REG_CLKCR); -+ rval &= ~(SDXC_CARD_CLOCK_ON | SDXC_LOW_POWER_ON); -+ -+ if (oclk_en) -+ rval |= SDXC_CARD_CLOCK_ON; -+ -+ mci_writel(host, REG_CLKCR, rval); -+ -+ rval = SDXC_START | SDXC_UPCLK_ONLY | SDXC_WAIT_PRE_OVER; -+ if (host->voltage_switching) -+ rval |= SDXC_VOLTAGE_SWITCH; -+ mci_writel(host, REG_CMDR, rval); -+ -+ do { -+ rval = mci_readl(host, REG_CMDR); -+ } while (time_before(jiffies, expire) && (rval & SDXC_START)); -+ -+ if (rval & SDXC_START) { -+ dev_err(mmc_dev(host->mmc), "fatal err update clk timeout\n"); -+ host->ferror = 1; -+ } -+} -+ -+static void sunxi_mmc_clk_set_rate(struct sunxi_mmc_host *smc_host, -+ unsigned int rate) -+{ -+ u32 newrate, oclk_dly, rval, sclk_dly, src_clk; -+ struct clk_hw *hw = __clk_get_hw(smc_host->clk_mod); -+ -+ newrate = clk_round_rate(smc_host->clk_mod, rate); -+ if (smc_host->clk_mod_rate == newrate) { -+ dev_dbg(mmc_dev(smc_host->mmc), "clk already %d, rounded %d\n", -+ rate, newrate); -+ return; -+ } -+ -+ dev_dbg(mmc_dev(smc_host->mmc), "setting clk to %d, rounded %d\n", -+ rate, newrate); -+ -+ /* setting clock rate */ -+ clk_set_rate(smc_host->clk_mod, newrate); -+ smc_host->clk_mod_rate = clk_get_rate(smc_host->clk_mod); -+ dev_dbg(mmc_dev(smc_host->mmc), "clk is now %d\n", -+ smc_host->clk_mod_rate); -+ -+ sunxi_mmc_oclk_onoff(smc_host, 0); -+ /* clear internal divider */ -+ rval = mci_readl(smc_host, REG_CLKCR); -+ rval &= ~0xff; -+ mci_writel(smc_host, REG_CLKCR, rval); -+ -+ /* determine delays */ -+ if (rate <= 400000) { -+ oclk_dly = 0; -+ sclk_dly = 7; -+ } else if (rate <= 25000000) { -+ oclk_dly = 0; -+ sclk_dly = 5; -+ } else if (rate <= 50000000) { -+ if (smc_host->ddr) { -+ oclk_dly = 2; -+ sclk_dly = 4; -+ } else { -+ oclk_dly = 3; -+ sclk_dly = 5; -+ } -+ } else { -+ /* rate > 50000000 */ -+ oclk_dly = 2; -+ sclk_dly = 4; -+ } -+ -+ src_clk = clk_get_rate(clk_get_parent(smc_host->clk_mod)); -+ if (src_clk >= 300000000 && src_clk <= 400000000) { -+ if (oclk_dly) -+ oclk_dly--; -+ if (sclk_dly) -+ sclk_dly--; -+ } -+ -+ clk_sunxi_mmc_phase_control(hw, sclk_dly, oclk_dly); -+ sunxi_mmc_oclk_onoff(smc_host, 1); -+ -+ /* oclk_onoff sets various irq status bits, clear these */ -+ mci_writel(smc_host, REG_RINTR, -+ mci_readl(smc_host, REG_RINTR) & ~SDXC_SDIO_INTERRUPT); -+} -+ -+static void sunxi_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ struct sunxi_mmc_host *host = mmc_priv(mmc); -+ u32 rval; -+ s32 err; -+ -+ /* Set the power state */ -+ switch (ios->power_mode) { -+ case MMC_POWER_ON: -+ break; -+ -+ case MMC_POWER_UP: -+ if (!IS_ERR(host->vmmc)) { -+ mmc_regulator_set_ocr(host->mmc, host->vmmc, ios->vdd); -+ udelay(200); -+ } -+ -+ err = sunxi_mmc_init_host(mmc); -+ if (err) { -+ host->ferror = 1; -+ return; -+ } -+ -+ enable_irq(host->irq); -+ -+ dev_dbg(mmc_dev(host->mmc), "power on!\n"); -+ host->ferror = 0; -+ break; -+ -+ case MMC_POWER_OFF: -+ dev_dbg(mmc_dev(host->mmc), "power off!\n"); -+ disable_irq(host->irq); -+ sunxi_mmc_exit_host(host); -+ if (!IS_ERR(host->vmmc)) -+ mmc_regulator_set_ocr(host->mmc, host->vmmc, 0); -+ -+ host->ferror = 0; -+ break; -+ } -+ -+ /* set bus width */ -+ switch (ios->bus_width) { -+ case MMC_BUS_WIDTH_1: -+ mci_writel(host, REG_WIDTH, SDXC_WIDTH1); -+ host->bus_width = 1; -+ break; -+ case MMC_BUS_WIDTH_4: -+ mci_writel(host, REG_WIDTH, SDXC_WIDTH4); -+ host->bus_width = 4; -+ break; -+ case MMC_BUS_WIDTH_8: -+ mci_writel(host, REG_WIDTH, SDXC_WIDTH8); -+ host->bus_width = 8; -+ break; -+ } -+ -+ /* set ddr mode */ -+ rval = mci_readl(host, REG_GCTRL); -+ if (ios->timing == MMC_TIMING_UHS_DDR50) { -+ rval |= SDXC_DDR_MODE; -+ host->ddr = 1; -+ } else { -+ rval &= ~SDXC_DDR_MODE; -+ host->ddr = 0; -+ } -+ mci_writel(host, REG_GCTRL, rval); -+ -+ /* set up clock */ -+ if (ios->clock && ios->power_mode) { -+ dev_dbg(mmc_dev(host->mmc), "ios->clock: %d\n", ios->clock); -+ sunxi_mmc_clk_set_rate(host, ios->clock); -+ usleep_range(50000, 55000); -+ } -+} -+ -+static void sunxi_mmc_enable_sdio_irq(struct mmc_host *mmc, int enable) -+{ -+ struct sunxi_mmc_host *smc_host = mmc_priv(mmc); -+ unsigned long flags; -+ u32 imask; -+ -+ spin_lock_irqsave(&smc_host->lock, flags); -+ -+ imask = mci_readl(smc_host, REG_IMASK); -+ if (enable) { -+ smc_host->sdio_imask = SDXC_SDIO_INTERRUPT; -+ imask |= SDXC_SDIO_INTERRUPT; -+ } else { -+ smc_host->sdio_imask = 0; -+ imask &= ~SDXC_SDIO_INTERRUPT; -+ } -+ mci_writel(smc_host, REG_IMASK, imask); -+ spin_unlock_irqrestore(&smc_host->lock, flags); -+} -+ -+static void sunxi_mmc_hw_reset(struct mmc_host *mmc) -+{ -+ struct sunxi_mmc_host *smc_host = mmc_priv(mmc); -+ mci_writel(smc_host, REG_HWRST, 0); -+ udelay(10); -+ mci_writel(smc_host, REG_HWRST, 1); -+ udelay(300); -+} -+ -+static void sunxi_mmc_request(struct mmc_host *mmc, struct mmc_request *mrq) -+{ -+ struct sunxi_mmc_host *host = mmc_priv(mmc); -+ struct mmc_command *cmd = mrq->cmd; -+ struct mmc_data *data = mrq->data; -+ unsigned long iflags; -+ u32 imask = SDXC_INTERRUPT_ERROR_BIT; -+ u32 cmd_val = SDXC_START | (cmd->opcode & 0x3f); -+ int ret; -+ -+ if (!mmc_gpio_get_cd(mmc) || host->ferror) { -+ dev_dbg(mmc_dev(host->mmc), "no medium present\n"); -+ mrq->cmd->error = -ENOMEDIUM; -+ mmc_request_done(mmc, mrq); -+ return; -+ } -+ -+ if (data) { -+ ret = sunxi_mmc_map_dma(host, data); -+ if (ret < 0) { -+ dev_err(mmc_dev(host->mmc), "map DMA failed\n"); -+ cmd->error = ret; -+ cmd->data->error = ret; -+ mmc_request_done(host->mmc, mrq); -+ return; -+ } -+ } -+ -+ if (cmd->opcode == MMC_GO_IDLE_STATE) { -+ cmd_val |= SDXC_SEND_INIT_SEQUENCE; -+ imask |= SDXC_COMMAND_DONE; -+ } -+ -+ if (cmd->opcode == SD_SWITCH_VOLTAGE) { -+ cmd_val |= SDXC_VOLTAGE_SWITCH; -+ imask |= SDXC_VOLTAGE_CHANGE_DONE; -+ host->voltage_switching = 1; -+ sunxi_mmc_oclk_onoff(host, 1); -+ } -+ -+ if (cmd->flags & MMC_RSP_PRESENT) { -+ cmd_val |= SDXC_RESP_EXPIRE; -+ if (cmd->flags & MMC_RSP_136) -+ cmd_val |= SDXC_LONG_RESPONSE; -+ if (cmd->flags & MMC_RSP_CRC) -+ cmd_val |= SDXC_CHECK_RESPONSE_CRC; -+ -+ if ((cmd->flags & MMC_CMD_MASK) == MMC_CMD_ADTC) { -+ cmd_val |= SDXC_DATA_EXPIRE | SDXC_WAIT_PRE_OVER; -+ if (cmd->data->flags & MMC_DATA_STREAM) { -+ imask |= SDXC_AUTO_COMMAND_DONE; -+ cmd_val |= SDXC_SEQUENCE_MODE | -+ SDXC_SEND_AUTO_STOP; -+ } -+ -+ if (cmd->data->stop) { -+ imask |= SDXC_AUTO_COMMAND_DONE; -+ cmd_val |= SDXC_SEND_AUTO_STOP; -+ } else { -+ imask |= SDXC_DATA_OVER; -+ } -+ -+ if (cmd->data->flags & MMC_DATA_WRITE) -+ cmd_val |= SDXC_WRITE; -+ else -+ host->wait_dma = true; -+ } else { -+ imask |= SDXC_COMMAND_DONE; -+ } -+ } else { -+ imask |= SDXC_COMMAND_DONE; -+ } -+ -+ dev_dbg(mmc_dev(host->mmc), "cmd %d(%08x) arg %x ie 0x%08x len %d\n", -+ cmd_val & 0x3f, cmd_val, cmd->arg, imask, -+ mrq->data ? mrq->data->blksz * mrq->data->blocks : 0); -+ -+ spin_lock_irqsave(&host->lock, iflags); -+ -+ if (host->mrq || host->manual_stop_mrq) { -+ spin_unlock_irqrestore(&host->lock, iflags); -+ -+ if (data) -+ dma_unmap_sg(mmc_dev(host->mmc), data->sg, -+ data->sg_len, sunxi_mmc_get_dma_dir(data)); -+ -+ dev_err(mmc_dev(host->mmc), "request already pending\n"); -+ mrq->cmd->error = -EBUSY; -+ mmc_request_done(host->mmc, mrq); -+ return; -+ } -+ -+ if (data) { -+ mci_writel(host, REG_BLKSZ, data->blksz); -+ mci_writel(host, REG_BCNTR, data->blksz * data->blocks); -+ sunxi_mmc_start_dma(host, data); -+ } -+ -+ host->mrq = mrq; -+ mci_writel(host, REG_IMASK, host->sdio_imask | imask); -+ mci_writel(host, REG_CARG, cmd->arg); -+ mci_writel(host, REG_CMDR, cmd_val); -+ -+ spin_unlock_irqrestore(&host->lock, iflags); -+} -+ -+static const struct of_device_id sunxi_mmc_of_match[] = { -+ { .compatible = "allwinner,sun4i-a10-mmc", }, -+ { .compatible = "allwinner,sun5i-a13-mmc", }, -+ { /* sentinel */ } -+}; -+MODULE_DEVICE_TABLE(of, sunxi_mmc_of_match); -+ -+static struct mmc_host_ops sunxi_mmc_ops = { -+ .request = sunxi_mmc_request, -+ .set_ios = sunxi_mmc_set_ios, -+ .get_ro = mmc_gpio_get_ro, -+ .get_cd = mmc_gpio_get_cd, -+ .enable_sdio_irq = sunxi_mmc_enable_sdio_irq, -+ .hw_reset = sunxi_mmc_hw_reset, -+}; -+ -+static int sunxi_mmc_resource_request(struct sunxi_mmc_host *host, -+ struct platform_device *pdev) -+{ -+ struct device_node *np = pdev->dev.of_node; -+ int ret; -+ -+ if (of_device_is_compatible(np, "allwinner,sun4i-a10-mmc")) -+ host->idma_des_size_bits = 13; -+ else -+ host->idma_des_size_bits = 16; -+ -+ host->vmmc = devm_regulator_get_optional(&pdev->dev, "vmmc"); -+ if (IS_ERR(host->vmmc) && PTR_ERR(host->vmmc) == -EPROBE_DEFER) -+ return -EPROBE_DEFER; -+ -+ host->reg_base = devm_ioremap_resource(&pdev->dev, -+ platform_get_resource(pdev, IORESOURCE_MEM, 0)); -+ if (IS_ERR(host->reg_base)) -+ return PTR_ERR(host->reg_base); -+ -+ host->clk_ahb = devm_clk_get(&pdev->dev, "ahb"); -+ if (IS_ERR(host->clk_ahb)) { -+ dev_err(&pdev->dev, "Could not get ahb clock\n"); -+ return PTR_ERR(host->clk_ahb); -+ } -+ -+ host->clk_mod = devm_clk_get(&pdev->dev, "mod"); -+ if (IS_ERR(host->clk_mod)) { -+ dev_err(&pdev->dev, "Could not get mod clock\n"); -+ return PTR_ERR(host->clk_mod); -+ } -+ -+ host->reset = devm_reset_control_get(&pdev->dev, "ahb"); -+ if (IS_ERR(host->reset)) -+ host->reset = NULL; /* Having a reset controller is optional */ -+ -+ /* -+ * Sometimes the controller asserts the irq on boot for some reason, -+ * and since it is not clocked there is no way to clear it. So make -+ * sure the controller is in a sane state before enabling irqs. -+ */ -+ ret = sunxi_mmc_init_host(host->mmc); -+ if (ret) -+ return ret; -+ -+ host->irq = platform_get_irq(pdev, 0); -+ ret = devm_request_irq(&pdev->dev, host->irq, sunxi_mmc_irq, 0, -+ "sunxi-mmc", host); -+ if (ret == 0) -+ disable_irq(host->irq); -+ -+ /* And disable the controller again */ -+ sunxi_mmc_exit_host(host); -+ -+ return ret; -+} -+ -+static int sunxi_mmc_probe(struct platform_device *pdev) -+{ -+ struct sunxi_mmc_host *host; -+ struct mmc_host *mmc; -+ int ret; -+ -+ mmc = mmc_alloc_host(sizeof(struct sunxi_mmc_host), &pdev->dev); -+ if (!mmc) { -+ dev_err(&pdev->dev, "mmc alloc host failed\n"); -+ return -ENOMEM; -+ } -+ -+ host = mmc_priv(mmc); -+ host->mmc = mmc; -+ spin_lock_init(&host->lock); -+ tasklet_init(&host->manual_stop_tasklet, -+ sunxi_mmc_manual_stop_tasklet, (unsigned long)host); -+ -+ ret = sunxi_mmc_resource_request(host, pdev); -+ if (ret) -+ goto error_free_host; -+ -+ host->sg_cpu = dma_alloc_coherent(&pdev->dev, PAGE_SIZE, -+ &host->sg_dma, GFP_KERNEL); -+ if (!host->sg_cpu) { -+ dev_err(&pdev->dev, "Failed to allocate DMA descriptor mem\n"); -+ ret = -ENOMEM; -+ goto error_free_host; -+ } -+ -+ mmc->ops = &sunxi_mmc_ops; -+ mmc->max_blk_count = 8192; -+ mmc->max_blk_size = 4096; -+ mmc->max_segs = PAGE_SIZE / sizeof(struct sunxi_idma_des); -+ mmc->max_seg_size = (1 << host->idma_des_size_bits); -+ mmc->max_req_size = mmc->max_seg_size * mmc->max_segs; -+ /* 400kHz ~ 50MHz */ -+ mmc->f_min = 400000; -+ mmc->f_max = 50000000; -+ /* available voltages */ -+ if (!IS_ERR(host->vmmc)) -+ mmc->ocr_avail = mmc_regulator_get_ocrmask(host->vmmc); -+ else -+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; -+ -+ mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED; -+ mmc->caps2 |= MMC_CAP2_NO_PRESCAN_POWERUP; -+ -+ ret = mmc_of_parse(mmc); -+ if (ret) -+ goto error_free_dma; -+ -+ ret = mmc_add_host(mmc); -+ if (ret) -+ goto error_free_dma; -+ -+ dev_info(&pdev->dev, "base:0x%p irq:%u\n", host->reg_base, host->irq); -+ platform_set_drvdata(pdev, mmc); -+ return 0; -+ -+error_free_dma: -+ dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); -+error_free_host: -+ mmc_free_host(mmc); -+ return ret; -+} -+ -+static int sunxi_mmc_remove(struct platform_device *pdev) -+{ -+ struct mmc_host *mmc = platform_get_drvdata(pdev); -+ struct sunxi_mmc_host *host = mmc_priv(mmc); -+ -+ mmc_remove_host(mmc); -+ sunxi_mmc_exit_host(host); -+ tasklet_disable(&host->manual_stop_tasklet); -+ dma_free_coherent(&pdev->dev, PAGE_SIZE, host->sg_cpu, host->sg_dma); -+ mmc_free_host(mmc); -+ -+ return 0; -+} -+ -+static struct platform_driver sunxi_mmc_driver = { -+ .driver = { -+ .name = "sunxi-mmc", -+ .owner = THIS_MODULE, -+ .of_match_table = of_match_ptr(sunxi_mmc_of_match), -+ }, -+ .probe = sunxi_mmc_probe, -+ .remove = sunxi_mmc_remove, -+}; -+module_platform_driver(sunxi_mmc_driver); -+ -+MODULE_DESCRIPTION("Allwinner's SD/MMC Card Controller Driver"); -+MODULE_LICENSE("GPL v2"); -+MODULE_AUTHOR("David Lanzendörfer <david.lanzendoerfer@o2s.ch>"); -+MODULE_ALIAS("platform:sunxi-mmc"); -diff --git a/include/linux/clk/sunxi.h b/include/linux/clk/sunxi.h -new file mode 100644 -index 0000000..1ef5c89 ---- /dev/null -+++ b/include/linux/clk/sunxi.h -@@ -0,0 +1,22 @@ -+/* -+ * Copyright 2013 - Hans de Goede <hdegoede@redhat.com> -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ */ -+ -+#ifndef __LINUX_CLK_SUNXI_H_ -+#define __LINUX_CLK_SUNXI_H_ -+ -+#include <linux/clk.h> -+ -+void clk_sunxi_mmc_phase_control(struct clk_hw *hw, u8 sample, u8 output); -+ -+#endif --- -1.9.0 - diff --git a/freed-ora/current/master/0001-HID-rmi-do-not-handle-touchscreens-through-hid-rmi.patch b/freed-ora/current/master/0001-HID-rmi-do-not-handle-touchscreens-through-hid-rmi.patch deleted file mode 100644 index e9015c9ad..000000000 --- a/freed-ora/current/master/0001-HID-rmi-do-not-handle-touchscreens-through-hid-rmi.patch +++ /dev/null @@ -1,102 +0,0 @@ -Bugzilla: 1089583 -Upstream-status: Sent for 3.15 - -From 4cebb979af8d7bd1ec463406eaf57a44bd5b9f04 Mon Sep 17 00:00:00 2001 -From: Benjamin Tissoires <benjamin.tissoires@redhat.com> -Date: Tue, 22 Apr 2014 11:21:00 -0400 -Subject: [PATCH] HID: rmi: do not handle touchscreens through hid-rmi - -Currently, hid-rmi drives every Synaptics product, but the touchscreens -on the Windows tablets should be handled through hid-multitouch. - -Instead of providing a long list of PIDs, rely on the scan_report -capability to detect which should go to hid-multitouch, and which -should not go to hid-rmi. - -We introduce a generic HID_GROUP_HAVE_SPECIAL_DRIVER which can be reused -amoung other drivers if they want to have a catch rule but still -have multitouch devices handled through hid-multitouch. - -related bug: -https://bugzilla.kernel.org/show_bug.cgi?id=74241 -https://bugzilla.redhat.com/show_bug.cgi?id=1089583 - -Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> ---- - drivers/hid/hid-core.c | 10 ++++++++-- - drivers/hid/hid-rmi.c | 6 ++++-- - include/linux/hid.h | 13 +++++++++++++ - 3 files changed, 25 insertions(+), 4 deletions(-) - -diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c -index 6ba2fd0..ea18639 100644 ---- a/drivers/hid/hid-core.c -+++ b/drivers/hid/hid-core.c -@@ -776,6 +776,14 @@ static int hid_scan_report(struct hid_device *hid) - (hid->group == HID_GROUP_MULTITOUCH)) - hid->group = HID_GROUP_MULTITOUCH_WIN_8; - -+ /* -+ * Vendor specific handlings -+ */ -+ if ((hid->vendor == USB_VENDOR_ID_SYNAPTICS) && -+ (hid->group == HID_GROUP_GENERIC)) -+ /* hid-rmi should take care of them, not hid-generic */ -+ hid->group = HID_GROUP_HAVE_SPECIAL_DRIVER; -+ - vfree(parser); - return 0; - } -@@ -1840,8 +1848,6 @@ static const struct hid_device_id hid_have_special_driver[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) }, - { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, -- { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, -- { HID_I2C_DEVICE(USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, -diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c -index a4f04d4..a97a373 100644 ---- a/drivers/hid/hid-rmi.c -+++ b/drivers/hid/hid-rmi.c -@@ -863,8 +863,10 @@ static void rmi_remove(struct hid_device *hdev) - } - - static const struct hid_device_id rmi_id[] = { -- { HID_I2C_DEVICE(USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, -- { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, -+ { HID_DEVICE(BUS_I2C, HID_GROUP_HAVE_SPECIAL_DRIVER, -+ USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, -+ { HID_DEVICE(BUS_USB, HID_GROUP_HAVE_SPECIAL_DRIVER, -+ USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, - { } - }; - MODULE_DEVICE_TABLE(hid, rmi_id); -diff --git a/include/linux/hid.h b/include/linux/hid.h -index 1b5f1e9..2fdd612 100644 ---- a/include/linux/hid.h -+++ b/include/linux/hid.h -@@ -299,6 +299,19 @@ struct hid_item { - #define HID_GROUP_MULTITOUCH 0x0002 - #define HID_GROUP_SENSOR_HUB 0x0003 - #define HID_GROUP_MULTITOUCH_WIN_8 0x0004 -+#define HID_GROUP_HAVE_SPECIAL_DRIVER 0xffff -+/* -+ * HID_GROUP_HAVE_SPECIAL_DRIVER should be used when the device needs to be -+ * scanned in case it is handled by either hid-multitouch, hid-generic, -+ * hid-sensor-hub or any other generic hid driver. -+ * -+ * Devices declared in hid_have_special_driver[] in hid-core.c can use -+ * HID_GROUP_ANY instead because there will be not overlap between their -+ * specific driver and a generic one. -+ * -+ * Note: HID_GROUP_ANY is declared in linux/mod_devicetable.h -+ * and has a value of 0x0000 -+ */ - - /* - * This is the global environment of the parser. This information is --- -1.9.0 - diff --git a/freed-ora/current/master/0001-HID-rmi-introduce-RMI-driver-for-Synaptics-touchpads.patch b/freed-ora/current/master/0001-HID-rmi-introduce-RMI-driver-for-Synaptics-touchpads.patch deleted file mode 100644 index 632174608..000000000 --- a/freed-ora/current/master/0001-HID-rmi-introduce-RMI-driver-for-Synaptics-touchpads.patch +++ /dev/null @@ -1,1001 +0,0 @@ -Bugzilla: 1048314 -Upstream-status: Queued for 3.16 - -From 39141443c8ea2900af627d688a255e064e2b6e19 Mon Sep 17 00:00:00 2001 -From: Benjamin Tissoires <benjamin.tissoires@redhat.com> -Date: Wed, 9 Apr 2014 11:09:21 -0400 -Subject: [PATCH] HID: rmi: introduce RMI driver for Synaptics touchpads - -This driver add support for RMI4 over USB or I2C. -The current state is that it uses its own RMI4 implementation, but once -RMI4 is merged upstream, the driver will be a transport driver for the -RMI4 library. - -Part of this driver should be considered as temporary. Most of the RMI4 -processing and input handling will be deleted at some point. - -I based my work on Andrew's regarding its port of RMI4 over HID (see -https://github.com/mightybigcar/synaptics-rmi4/tree/rmihid ) -This repo presents how the driver may looks like at the end: -https://github.com/mightybigcar/synaptics-rmi4/blob/rmihid/drivers/input/rmi4/rmi_hid.c - -Without this temporary solution, the workaround we gave to users -is to disable i2c-hid, which leads to disabling the touchscreen on the -XPS 11 and 12 (Haswell generation). - -Related bugs: -https://bugzilla.redhat.com/show_bug.cgi?id=1048314 -https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1218973 - -Signed-off-by: Andrew Duggan <aduggan@synaptics.com> -Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> -Signed-off-by: Jiri Kosina <jkosina@suse.cz> - -- Removed obviously wrong hid_hw_stop() at the end of probe - -Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> ---- - drivers/hid/Kconfig | 8 + - drivers/hid/Makefile | 1 + - drivers/hid/hid-core.c | 2 + - drivers/hid/hid-rmi.c | 890 +++++++++++++++++++++++++++++++++++++++++++++++++ - include/linux/hid.h | 2 + - 6 files changed, 946 insertions(+) - create mode 100644 drivers/hid/hid-rmi.c - -diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig -index 34e2d39..b2d733b 100644 ---- a/drivers/hid/Kconfig -+++ b/drivers/hid/Kconfig -@@ -645,6 +645,14 @@ config HID_SUNPLUS - ---help--- - Support for Sunplus wireless desktop. - -+config HID_RMI -+ tristate "Synaptics RMI4 device support" -+ depends on HID -+ ---help--- -+ Support for Synaptics RMI4 touchpads. -+ Say Y here if you have a Synaptics RMI4 touchpads over i2c-hid or usbhid -+ and want support for its special functionalities. -+ - config HID_GREENASIA - tristate "GreenAsia (Product ID 0x12) game controller support" - depends on HID -diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile -index 30e4431..b326f79 100644 ---- a/drivers/hid/Makefile -+++ b/drivers/hid/Makefile -@@ -96,6 +96,7 @@ obj-$(CONFIG_HID_ROCCAT) += hid-roccat.o hid-roccat-common.o \ - hid-roccat-arvo.o hid-roccat-isku.o hid-roccat-kone.o \ - hid-roccat-koneplus.o hid-roccat-konepure.o hid-roccat-kovaplus.o \ - hid-roccat-lua.o hid-roccat-pyra.o hid-roccat-ryos.o hid-roccat-savu.o -+obj-$(CONFIG_HID_RMI) += hid-rmi.o - obj-$(CONFIG_HID_SAITEK) += hid-saitek.o - obj-$(CONFIG_HID_SAMSUNG) += hid-samsung.o - obj-$(CONFIG_HID_SMARTJOYPLUS) += hid-sjoy.o -diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c -index 253fe23..543dd1f 100644 ---- a/drivers/hid/hid-core.c -+++ b/drivers/hid/hid-core.c -@@ -1836,6 +1836,8 @@ static const struct hid_device_id hid_have_special_driver[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_VAIO_VGP_MOUSE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_STEELSERIES, USB_DEVICE_ID_STEELSERIES_SRWS1) }, - { HID_USB_DEVICE(USB_VENDOR_ID_SUNPLUS, USB_DEVICE_ID_SUNPLUS_WDESKTOP) }, -+ { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, -+ { HID_I2C_DEVICE(USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THINGM, USB_DEVICE_ID_BLINK1) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300) }, - { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304) }, -diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c -new file mode 100644 -index 0000000..a4f04d4 ---- /dev/null -+++ b/drivers/hid/hid-rmi.c -@@ -0,0 +1,890 @@ -+/* -+ * Copyright (c) 2013 Andrew Duggan <aduggan@synaptics.com> -+ * Copyright (c) 2013 Synaptics Incorporated -+ * Copyright (c) 2014 Benjamin Tissoires <benjamin.tissoires@gmail.com> -+ * Copyright (c) 2014 Red Hat, Inc -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the Free -+ * Software Foundation; either version 2 of the License, or (at your option) -+ * any later version. -+ */ -+ -+#include <linux/kernel.h> -+#include <linux/hid.h> -+#include <linux/input.h> -+#include <linux/input/mt.h> -+#include <linux/module.h> -+#include <linux/pm.h> -+#include <linux/slab.h> -+#include <linux/wait.h> -+#include <linux/sched.h> -+#include "hid-ids.h" -+ -+/* removed backported compat.h include */ -+ -+#define RMI_MOUSE_REPORT_ID 0x01 /* Mouse emulation Report */ -+#define RMI_WRITE_REPORT_ID 0x09 /* Output Report */ -+#define RMI_READ_ADDR_REPORT_ID 0x0a /* Output Report */ -+#define RMI_READ_DATA_REPORT_ID 0x0b /* Input Report */ -+#define RMI_ATTN_REPORT_ID 0x0c /* Input Report */ -+#define RMI_SET_RMI_MODE_REPORT_ID 0x0f /* Feature Report */ -+ -+/* flags */ -+#define RMI_READ_REQUEST_PENDING BIT(0) -+#define RMI_READ_DATA_PENDING BIT(1) -+#define RMI_STARTED BIT(2) -+ -+enum rmi_mode_type { -+ RMI_MODE_OFF = 0, -+ RMI_MODE_ATTN_REPORTS = 1, -+ RMI_MODE_NO_PACKED_ATTN_REPORTS = 2, -+}; -+ -+struct rmi_function { -+ unsigned page; /* page of the function */ -+ u16 query_base_addr; /* base address for queries */ -+ u16 command_base_addr; /* base address for commands */ -+ u16 control_base_addr; /* base address for controls */ -+ u16 data_base_addr; /* base address for datas */ -+ unsigned int interrupt_base; /* cross-function interrupt number -+ * (uniq in the device)*/ -+ unsigned int interrupt_count; /* number of interrupts */ -+ unsigned int report_size; /* size of a report */ -+ unsigned long irq_mask; /* mask of the interrupts -+ * (to be applied against ATTN IRQ) */ -+}; -+ -+/** -+ * struct rmi_data - stores information for hid communication -+ * -+ * @page_mutex: Locks current page to avoid changing pages in unexpected ways. -+ * @page: Keeps track of the current virtual page -+ * -+ * @wait: Used for waiting for read data -+ * -+ * @writeReport: output buffer when writing RMI registers -+ * @readReport: input buffer when reading RMI registers -+ * -+ * @input_report_size: size of an input report (advertised by HID) -+ * @output_report_size: size of an output report (advertised by HID) -+ * -+ * @flags: flags for the current device (started, reading, etc...) -+ * -+ * @f11: placeholder of internal RMI function F11 description -+ * @f30: placeholder of internal RMI function F30 description -+ * -+ * @max_fingers: maximum finger count reported by the device -+ * @max_x: maximum x value reported by the device -+ * @max_y: maximum y value reported by the device -+ * -+ * @gpio_led_count: count of GPIOs + LEDs reported by F30 -+ * @button_count: actual physical buttons count -+ * @button_mask: button mask used to decode GPIO ATTN reports -+ * @button_state_mask: pull state of the buttons -+ * -+ * @input: pointer to the kernel input device -+ * -+ * @reset_work: worker which will be called in case of a mouse report -+ * @hdev: pointer to the struct hid_device -+ */ -+struct rmi_data { -+ struct mutex page_mutex; -+ int page; -+ -+ wait_queue_head_t wait; -+ -+ u8 *writeReport; -+ u8 *readReport; -+ -+ int input_report_size; -+ int output_report_size; -+ -+ unsigned long flags; -+ -+ struct rmi_function f11; -+ struct rmi_function f30; -+ -+ unsigned int max_fingers; -+ unsigned int max_x; -+ unsigned int max_y; -+ unsigned int x_size_mm; -+ unsigned int y_size_mm; -+ -+ unsigned int gpio_led_count; -+ unsigned int button_count; -+ unsigned long button_mask; -+ unsigned long button_state_mask; -+ -+ struct input_dev *input; -+ -+ struct work_struct reset_work; -+ struct hid_device *hdev; -+}; -+ -+#define RMI_PAGE(addr) (((addr) >> 8) & 0xff) -+ -+static int rmi_write_report(struct hid_device *hdev, u8 *report, int len); -+ -+/** -+ * rmi_set_page - Set RMI page -+ * @hdev: The pointer to the hid_device struct -+ * @page: The new page address. -+ * -+ * RMI devices have 16-bit addressing, but some of the physical -+ * implementations (like SMBus) only have 8-bit addressing. So RMI implements -+ * a page address at 0xff of every page so we can reliable page addresses -+ * every 256 registers. -+ * -+ * The page_mutex lock must be held when this function is entered. -+ * -+ * Returns zero on success, non-zero on failure. -+ */ -+static int rmi_set_page(struct hid_device *hdev, u8 page) -+{ -+ struct rmi_data *data = hid_get_drvdata(hdev); -+ int retval; -+ -+ data->writeReport[0] = RMI_WRITE_REPORT_ID; -+ data->writeReport[1] = 1; -+ data->writeReport[2] = 0xFF; -+ data->writeReport[4] = page; -+ -+ retval = rmi_write_report(hdev, data->writeReport, -+ data->output_report_size); -+ if (retval != data->output_report_size) { -+ dev_err(&hdev->dev, -+ "%s: set page failed: %d.", __func__, retval); -+ return retval; -+ } -+ -+ data->page = page; -+ return 0; -+} -+ -+static int rmi_set_mode(struct hid_device *hdev, u8 mode) -+{ -+ int ret; -+ u8 txbuf[2] = {RMI_SET_RMI_MODE_REPORT_ID, mode}; -+ -+ ret = hid_hw_raw_request(hdev, RMI_SET_RMI_MODE_REPORT_ID, txbuf, -+ sizeof(txbuf), HID_FEATURE_REPORT, HID_REQ_SET_REPORT); -+ if (ret < 0) { -+ dev_err(&hdev->dev, "unable to set rmi mode to %d (%d)\n", mode, -+ ret); -+ return ret; -+ } -+ -+ return 0; -+} -+ -+static int rmi_write_report(struct hid_device *hdev, u8 *report, int len) -+{ -+ int ret; -+ -+ ret = hid_hw_output_report(hdev, (void *)report, len); -+ if (ret < 0) { -+ dev_err(&hdev->dev, "failed to write hid report (%d)\n", ret); -+ return ret; -+ } -+ -+ return ret; -+} -+ -+static int rmi_read_block(struct hid_device *hdev, u16 addr, void *buf, -+ const int len) -+{ -+ struct rmi_data *data = hid_get_drvdata(hdev); -+ int ret; -+ int bytes_read; -+ int bytes_needed; -+ int retries; -+ int read_input_count; -+ -+ mutex_lock(&data->page_mutex); -+ -+ if (RMI_PAGE(addr) != data->page) { -+ ret = rmi_set_page(hdev, RMI_PAGE(addr)); -+ if (ret < 0) -+ goto exit; -+ } -+ -+ for (retries = 5; retries > 0; retries--) { -+ data->writeReport[0] = RMI_READ_ADDR_REPORT_ID; -+ data->writeReport[1] = 0; /* old 1 byte read count */ -+ data->writeReport[2] = addr & 0xFF; -+ data->writeReport[3] = (addr >> 8) & 0xFF; -+ data->writeReport[4] = len & 0xFF; -+ data->writeReport[5] = (len >> 8) & 0xFF; -+ -+ set_bit(RMI_READ_REQUEST_PENDING, &data->flags); -+ -+ ret = rmi_write_report(hdev, data->writeReport, -+ data->output_report_size); -+ if (ret != data->output_report_size) { -+ clear_bit(RMI_READ_REQUEST_PENDING, &data->flags); -+ dev_err(&hdev->dev, -+ "failed to write request output report (%d)\n", -+ ret); -+ goto exit; -+ } -+ -+ bytes_read = 0; -+ bytes_needed = len; -+ while (bytes_read < len) { -+ if (!wait_event_timeout(data->wait, -+ test_bit(RMI_READ_DATA_PENDING, &data->flags), -+ msecs_to_jiffies(1000))) { -+ hid_warn(hdev, "%s: timeout elapsed\n", -+ __func__); -+ ret = -EAGAIN; -+ break; -+ } -+ -+ read_input_count = data->readReport[1]; -+ memcpy(buf + bytes_read, &data->readReport[2], -+ read_input_count < bytes_needed ? -+ read_input_count : bytes_needed); -+ -+ bytes_read += read_input_count; -+ bytes_needed -= read_input_count; -+ clear_bit(RMI_READ_DATA_PENDING, &data->flags); -+ } -+ -+ if (ret >= 0) { -+ ret = 0; -+ break; -+ } -+ } -+ -+exit: -+ clear_bit(RMI_READ_REQUEST_PENDING, &data->flags); -+ mutex_unlock(&data->page_mutex); -+ return ret; -+} -+ -+static inline int rmi_read(struct hid_device *hdev, u16 addr, void *buf) -+{ -+ return rmi_read_block(hdev, addr, buf, 1); -+} -+ -+static void rmi_f11_process_touch(struct rmi_data *hdata, int slot, -+ u8 finger_state, u8 *touch_data) -+{ -+ int x, y, wx, wy; -+ int wide, major, minor; -+ int z; -+ -+ input_mt_slot(hdata->input, slot); -+ input_mt_report_slot_state(hdata->input, MT_TOOL_FINGER, -+ finger_state == 0x01); -+ if (finger_state == 0x01) { -+ x = (touch_data[0] << 4) | (touch_data[2] & 0x07); -+ y = (touch_data[1] << 4) | (touch_data[2] >> 4); -+ wx = touch_data[3] & 0x07; -+ wy = touch_data[3] >> 4; -+ wide = (wx > wy); -+ major = max(wx, wy); -+ minor = min(wx, wy); -+ z = touch_data[4]; -+ -+ /* y is inverted */ -+ y = hdata->max_y - y; -+ -+ input_event(hdata->input, EV_ABS, ABS_MT_POSITION_X, x); -+ input_event(hdata->input, EV_ABS, ABS_MT_POSITION_Y, y); -+ input_event(hdata->input, EV_ABS, ABS_MT_ORIENTATION, wide); -+ input_event(hdata->input, EV_ABS, ABS_MT_PRESSURE, z); -+ input_event(hdata->input, EV_ABS, ABS_MT_TOUCH_MAJOR, major); -+ input_event(hdata->input, EV_ABS, ABS_MT_TOUCH_MINOR, minor); -+ } -+} -+ -+static void rmi_reset_work(struct work_struct *work) -+{ -+ struct rmi_data *hdata = container_of(work, struct rmi_data, -+ reset_work); -+ -+ /* switch the device to RMI if we receive a generic mouse report */ -+ rmi_set_mode(hdata->hdev, RMI_MODE_ATTN_REPORTS); -+} -+ -+static inline int rmi_schedule_reset(struct hid_device *hdev) -+{ -+ struct rmi_data *hdata = hid_get_drvdata(hdev); -+ return schedule_work(&hdata->reset_work); -+} -+ -+static int rmi_f11_input_event(struct hid_device *hdev, u8 irq, u8 *data, -+ int size) -+{ -+ struct rmi_data *hdata = hid_get_drvdata(hdev); -+ int offset; -+ int i; -+ -+ if (size < hdata->f11.report_size) -+ return 0; -+ -+ if (!(irq & hdata->f11.irq_mask)) -+ return 0; -+ -+ offset = (hdata->max_fingers >> 2) + 1; -+ for (i = 0; i < hdata->max_fingers; i++) { -+ int fs_byte_position = i >> 2; -+ int fs_bit_position = (i & 0x3) << 1; -+ int finger_state = (data[fs_byte_position] >> fs_bit_position) & -+ 0x03; -+ -+ rmi_f11_process_touch(hdata, i, finger_state, -+ &data[offset + 5 * i]); -+ } -+ input_mt_sync_frame(hdata->input); -+ input_sync(hdata->input); -+ return hdata->f11.report_size; -+} -+ -+static int rmi_f30_input_event(struct hid_device *hdev, u8 irq, u8 *data, -+ int size) -+{ -+ struct rmi_data *hdata = hid_get_drvdata(hdev); -+ int i; -+ int button = 0; -+ bool value; -+ -+ if (!(irq & hdata->f30.irq_mask)) -+ return 0; -+ -+ for (i = 0; i < hdata->gpio_led_count; i++) { -+ if (test_bit(i, &hdata->button_mask)) { -+ value = (data[i / 8] >> (i & 0x07)) & BIT(0); -+ if (test_bit(i, &hdata->button_state_mask)) -+ value = !value; -+ input_event(hdata->input, EV_KEY, BTN_LEFT + button++, -+ value); -+ } -+ } -+ return hdata->f30.report_size; -+} -+ -+static int rmi_input_event(struct hid_device *hdev, u8 *data, int size) -+{ -+ struct rmi_data *hdata = hid_get_drvdata(hdev); -+ unsigned long irq_mask = 0; -+ unsigned index = 2; -+ -+ if (!(test_bit(RMI_STARTED, &hdata->flags))) -+ return 0; -+ -+ irq_mask |= hdata->f11.irq_mask; -+ irq_mask |= hdata->f30.irq_mask; -+ -+ if (data[1] & ~irq_mask) -+ hid_warn(hdev, "unknown intr source:%02lx %s:%d\n", -+ data[1] & ~irq_mask, __FILE__, __LINE__); -+ -+ if (hdata->f11.interrupt_base < hdata->f30.interrupt_base) { -+ index += rmi_f11_input_event(hdev, data[1], &data[index], -+ size - index); -+ index += rmi_f30_input_event(hdev, data[1], &data[index], -+ size - index); -+ } else { -+ index += rmi_f30_input_event(hdev, data[1], &data[index], -+ size - index); -+ index += rmi_f11_input_event(hdev, data[1], &data[index], -+ size - index); -+ } -+ -+ return 1; -+} -+ -+static int rmi_read_data_event(struct hid_device *hdev, u8 *data, int size) -+{ -+ struct rmi_data *hdata = hid_get_drvdata(hdev); -+ -+ if (!test_bit(RMI_READ_REQUEST_PENDING, &hdata->flags)) { -+ hid_err(hdev, "no read request pending\n"); -+ return 0; -+ } -+ -+ memcpy(hdata->readReport, data, size < hdata->input_report_size ? -+ size : hdata->input_report_size); -+ set_bit(RMI_READ_DATA_PENDING, &hdata->flags); -+ wake_up(&hdata->wait); -+ -+ return 1; -+} -+ -+static int rmi_raw_event(struct hid_device *hdev, -+ struct hid_report *report, u8 *data, int size) -+{ -+ switch (data[0]) { -+ case RMI_READ_DATA_REPORT_ID: -+ return rmi_read_data_event(hdev, data, size); -+ case RMI_ATTN_REPORT_ID: -+ return rmi_input_event(hdev, data, size); -+ case RMI_MOUSE_REPORT_ID: -+ rmi_schedule_reset(hdev); -+ break; -+ } -+ -+ return 0; -+} -+ -+static int rmi_post_reset(struct hid_device *hdev) -+{ -+ return rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS); -+} -+ -+static int rmi_post_resume(struct hid_device *hdev) -+{ -+ return rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS); -+} -+ -+#define RMI4_MAX_PAGE 0xff -+#define RMI4_PAGE_SIZE 0x0100 -+ -+#define PDT_START_SCAN_LOCATION 0x00e9 -+#define PDT_END_SCAN_LOCATION 0x0005 -+#define RMI4_END_OF_PDT(id) ((id) == 0x00 || (id) == 0xff) -+ -+struct pdt_entry { -+ u8 query_base_addr:8; -+ u8 command_base_addr:8; -+ u8 control_base_addr:8; -+ u8 data_base_addr:8; -+ u8 interrupt_source_count:3; -+ u8 bits3and4:2; -+ u8 function_version:2; -+ u8 bit7:1; -+ u8 function_number:8; -+} __attribute__((__packed__)); -+ -+static inline unsigned long rmi_gen_mask(unsigned irq_base, unsigned irq_count) -+{ -+ return GENMASK(irq_count + irq_base - 1, irq_base); -+} -+ -+static void rmi_register_function(struct rmi_data *data, -+ struct pdt_entry *pdt_entry, int page, unsigned interrupt_count) -+{ -+ struct rmi_function *f = NULL; -+ u16 page_base = page << 8; -+ -+ switch (pdt_entry->function_number) { -+ case 0x11: -+ f = &data->f11; -+ break; -+ case 0x30: -+ f = &data->f30; -+ break; -+ } -+ -+ if (f) { -+ f->page = page; -+ f->query_base_addr = page_base | pdt_entry->query_base_addr; -+ f->command_base_addr = page_base | pdt_entry->command_base_addr; -+ f->control_base_addr = page_base | pdt_entry->control_base_addr; -+ f->data_base_addr = page_base | pdt_entry->data_base_addr; -+ f->interrupt_base = interrupt_count; -+ f->interrupt_count = pdt_entry->interrupt_source_count; -+ f->irq_mask = rmi_gen_mask(f->interrupt_base, -+ f->interrupt_count); -+ } -+} -+ -+static int rmi_scan_pdt(struct hid_device *hdev) -+{ -+ struct rmi_data *data = hid_get_drvdata(hdev); -+ struct pdt_entry entry; -+ int page; -+ bool page_has_function; -+ int i; -+ int retval; -+ int interrupt = 0; -+ u16 page_start, pdt_start , pdt_end; -+ -+ hid_info(hdev, "Scanning PDT...\n"); -+ -+ for (page = 0; (page <= RMI4_MAX_PAGE); page++) { -+ page_start = RMI4_PAGE_SIZE * page; -+ pdt_start = page_start + PDT_START_SCAN_LOCATION; -+ pdt_end = page_start + PDT_END_SCAN_LOCATION; -+ -+ page_has_function = false; -+ for (i = pdt_start; i >= pdt_end; i -= sizeof(entry)) { -+ retval = rmi_read_block(hdev, i, &entry, sizeof(entry)); -+ if (retval) { -+ hid_err(hdev, -+ "Read of PDT entry at %#06x failed.\n", -+ i); -+ goto error_exit; -+ } -+ -+ if (RMI4_END_OF_PDT(entry.function_number)) -+ break; -+ -+ page_has_function = true; -+ -+ hid_info(hdev, "Found F%02X on page %#04x\n", -+ entry.function_number, page); -+ -+ rmi_register_function(data, &entry, page, interrupt); -+ interrupt += entry.interrupt_source_count; -+ } -+ -+ if (!page_has_function) -+ break; -+ } -+ -+ hid_info(hdev, "%s: Done with PDT scan.\n", __func__); -+ retval = 0; -+ -+error_exit: -+ return retval; -+} -+ -+static int rmi_populate_f11(struct hid_device *hdev) -+{ -+ struct rmi_data *data = hid_get_drvdata(hdev); -+ u8 buf[20]; -+ int ret; -+ bool has_query12; -+ bool has_physical_props; -+ unsigned x_size, y_size; -+ -+ if (!data->f11.query_base_addr) { -+ hid_err(hdev, "No 2D sensor found, giving up.\n"); -+ return -ENODEV; -+ } -+ -+ /* query 0 contains some useful information */ -+ ret = rmi_read(hdev, data->f11.query_base_addr, buf); -+ if (ret) { -+ hid_err(hdev, "can not get query 0: %d.\n", ret); -+ return ret; -+ } -+ has_query12 = !!(buf[0] & BIT(5)); -+ -+ /* query 1 to get the max number of fingers */ -+ ret = rmi_read(hdev, data->f11.query_base_addr + 1, buf); -+ if (ret) { -+ hid_err(hdev, "can not get NumberOfFingers: %d.\n", ret); -+ return ret; -+ } -+ data->max_fingers = (buf[0] & 0x07) + 1; -+ if (data->max_fingers > 5) -+ data->max_fingers = 10; -+ -+ data->f11.report_size = data->max_fingers * 5 + -+ DIV_ROUND_UP(data->max_fingers, 4); -+ -+ if (!(buf[0] & BIT(4))) { -+ hid_err(hdev, "No absolute events, giving up.\n"); -+ return -ENODEV; -+ } -+ -+ /* -+ * query 12 to know if the physical properties are reported -+ * (query 12 is at offset 10 for HID devices) -+ */ -+ if (has_query12) { -+ ret = rmi_read(hdev, data->f11.query_base_addr + 10, buf); -+ if (ret) { -+ hid_err(hdev, "can not get query 12: %d.\n", ret); -+ return ret; -+ } -+ has_physical_props = !!(buf[0] & BIT(5)); -+ -+ if (has_physical_props) { -+ ret = rmi_read_block(hdev, -+ data->f11.query_base_addr + 11, buf, 4); -+ if (ret) { -+ hid_err(hdev, "can not read query 15-18: %d.\n", -+ ret); -+ return ret; -+ } -+ -+ x_size = buf[0] | (buf[1] << 8); -+ y_size = buf[2] | (buf[3] << 8); -+ -+ data->x_size_mm = DIV_ROUND_CLOSEST(x_size, 10); -+ data->y_size_mm = DIV_ROUND_CLOSEST(y_size, 10); -+ -+ hid_info(hdev, "%s: size in mm: %d x %d\n", -+ __func__, data->x_size_mm, data->y_size_mm); -+ } -+ } -+ -+ /* retrieve the ctrl registers */ -+ ret = rmi_read_block(hdev, data->f11.control_base_addr, buf, 20); -+ if (ret) { -+ hid_err(hdev, "can not read ctrl block of size 20: %d.\n", ret); -+ return ret; -+ } -+ -+ data->max_x = buf[6] | (buf[7] << 8); -+ data->max_y = buf[8] | (buf[9] << 8); -+ -+ return 0; -+} -+ -+static int rmi_populate_f30(struct hid_device *hdev) -+{ -+ struct rmi_data *data = hid_get_drvdata(hdev); -+ u8 buf[20]; -+ int ret; -+ bool has_gpio, has_led; -+ unsigned bytes_per_ctrl; -+ u8 ctrl2_addr; -+ int ctrl2_3_length; -+ int i; -+ -+ /* function F30 is for physical buttons */ -+ if (!data->f30.query_base_addr) { -+ hid_err(hdev, "No GPIO/LEDs found, giving up.\n"); -+ return -ENODEV; -+ } -+ -+ ret = rmi_read_block(hdev, data->f30.query_base_addr, buf, 2); -+ if (ret) { -+ hid_err(hdev, "can not get F30 query registers: %d.\n", ret); -+ return ret; -+ } -+ -+ has_gpio = !!(buf[0] & BIT(3)); -+ has_led = !!(buf[0] & BIT(2)); -+ data->gpio_led_count = buf[1] & 0x1f; -+ -+ /* retrieve ctrl 2 & 3 registers */ -+ bytes_per_ctrl = (data->gpio_led_count + 7) / 8; -+ /* Ctrl0 is present only if both has_gpio and has_led are set*/ -+ ctrl2_addr = (has_gpio && has_led) ? bytes_per_ctrl : 0; -+ /* Ctrl1 is always be present */ -+ ctrl2_addr += bytes_per_ctrl; -+ ctrl2_3_length = 2 * bytes_per_ctrl; -+ -+ data->f30.report_size = bytes_per_ctrl; -+ -+ ret = rmi_read_block(hdev, data->f30.control_base_addr + ctrl2_addr, -+ buf, ctrl2_3_length); -+ if (ret) { -+ hid_err(hdev, "can not read ctrl 2&3 block of size %d: %d.\n", -+ ctrl2_3_length, ret); -+ return ret; -+ } -+ -+ for (i = 0; i < data->gpio_led_count; i++) { -+ int byte_position = i >> 3; -+ int bit_position = i & 0x07; -+ u8 dir_byte = buf[byte_position]; -+ u8 data_byte = buf[byte_position + bytes_per_ctrl]; -+ bool dir = (dir_byte >> bit_position) & BIT(0); -+ bool dat = (data_byte >> bit_position) & BIT(0); -+ -+ if (dir == 0) { -+ /* input mode */ -+ if (dat) { -+ /* actual buttons have pull up resistor */ -+ data->button_count++; -+ set_bit(i, &data->button_mask); -+ set_bit(i, &data->button_state_mask); -+ } -+ } -+ -+ } -+ -+ return 0; -+} -+ -+static int rmi_populate(struct hid_device *hdev) -+{ -+ int ret; -+ -+ ret = rmi_scan_pdt(hdev); -+ if (ret) { -+ hid_err(hdev, "PDT scan failed with code %d.\n", ret); -+ return ret; -+ } -+ -+ ret = rmi_populate_f11(hdev); -+ if (ret) { -+ hid_err(hdev, "Error while initializing F11 (%d).\n", ret); -+ return ret; -+ } -+ -+ ret = rmi_populate_f30(hdev); -+ if (ret) -+ hid_warn(hdev, "Error while initializing F30 (%d).\n", ret); -+ -+ return 0; -+} -+ -+static void rmi_input_configured(struct hid_device *hdev, struct hid_input *hi) -+{ -+ struct rmi_data *data = hid_get_drvdata(hdev); -+ struct input_dev *input = hi->input; -+ int ret; -+ int res_x, res_y, i; -+ -+ data->input = input; -+ -+ hid_dbg(hdev, "Opening low level driver\n"); -+ ret = hid_hw_open(hdev); -+ if (ret) -+ return; -+ -+ /* Allow incoming hid reports */ -+ hid_device_io_start(hdev); -+ -+ ret = rmi_set_mode(hdev, RMI_MODE_ATTN_REPORTS); -+ if (ret < 0) { -+ dev_err(&hdev->dev, "failed to set rmi mode\n"); -+ goto exit; -+ } -+ -+ ret = rmi_set_page(hdev, 0); -+ if (ret < 0) { -+ dev_err(&hdev->dev, "failed to set page select to 0.\n"); -+ goto exit; -+ } -+ -+ ret = rmi_populate(hdev); -+ if (ret) -+ goto exit; -+ -+ __set_bit(EV_ABS, input->evbit); -+ input_set_abs_params(input, ABS_MT_POSITION_X, 1, data->max_x, 0, 0); -+ input_set_abs_params(input, ABS_MT_POSITION_Y, 1, data->max_y, 0, 0); -+ -+ if (data->x_size_mm && data->x_size_mm) { -+ res_x = (data->max_x - 1) / data->x_size_mm; -+ res_y = (data->max_y - 1) / data->x_size_mm; -+ -+ input_abs_set_res(input, ABS_MT_POSITION_X, res_x); -+ input_abs_set_res(input, ABS_MT_POSITION_Y, res_y); -+ } -+ -+ input_set_abs_params(input, ABS_MT_ORIENTATION, 0, 1, 0, 0); -+ input_set_abs_params(input, ABS_MT_PRESSURE, 0, 0xff, 0, 0); -+ input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 0x0f, 0, 0); -+ input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 0x0f, 0, 0); -+ -+ input_mt_init_slots(input, data->max_fingers, INPUT_MT_POINTER); -+ -+ if (data->button_count) { -+ __set_bit(EV_KEY, input->evbit); -+ for (i = 0; i < data->button_count; i++) -+ __set_bit(BTN_LEFT + i, input->keybit); -+ -+ if (data->button_count == 1) -+ __set_bit(INPUT_PROP_BUTTONPAD, input->propbit); -+ } -+ -+ set_bit(RMI_STARTED, &data->flags); -+ -+exit: -+ hid_device_io_stop(hdev); -+ hid_hw_close(hdev); -+} -+ -+static int rmi_input_mapping(struct hid_device *hdev, -+ struct hid_input *hi, struct hid_field *field, -+ struct hid_usage *usage, unsigned long **bit, int *max) -+{ -+ /* we want to make HID ignore the advertised HID collection */ -+ return -1; -+} -+ -+static int rmi_probe(struct hid_device *hdev, const struct hid_device_id *id) -+{ -+ struct rmi_data *data = NULL; -+ int ret; -+ size_t alloc_size; -+ -+ data = devm_kzalloc(&hdev->dev, sizeof(struct rmi_data), GFP_KERNEL); -+ if (!data) -+ return -ENOMEM; -+ -+ INIT_WORK(&data->reset_work, rmi_reset_work); -+ data->hdev = hdev; -+ -+ hid_set_drvdata(hdev, data); -+ -+ hdev->quirks |= HID_QUIRK_NO_INIT_REPORTS; -+ -+ ret = hid_parse(hdev); -+ if (ret) { -+ hid_err(hdev, "parse failed\n"); -+ return ret; -+ } -+ -+ data->input_report_size = (hdev->report_enum[HID_INPUT_REPORT] -+ .report_id_hash[RMI_ATTN_REPORT_ID]->size >> 3) -+ + 1 /* report id */; -+ data->output_report_size = (hdev->report_enum[HID_OUTPUT_REPORT] -+ .report_id_hash[RMI_WRITE_REPORT_ID]->size >> 3) -+ + 1 /* report id */; -+ -+ alloc_size = data->output_report_size + data->input_report_size; -+ -+ data->writeReport = devm_kzalloc(&hdev->dev, alloc_size, GFP_KERNEL); -+ if (!data->writeReport) { -+ ret = -ENOMEM; -+ return ret; -+ } -+ -+ data->readReport = data->writeReport + data->output_report_size; -+ -+ init_waitqueue_head(&data->wait); -+ -+ mutex_init(&data->page_mutex); -+ -+ ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); -+ if (ret) { -+ hid_err(hdev, "hw start failed\n"); -+ return ret; -+ } -+ -+ if (!test_bit(RMI_STARTED, &data->flags)) { -+ hid_hw_stop(hdev); -+ return -EIO; -+ } -+ -+ return 0; -+} -+ -+static void rmi_remove(struct hid_device *hdev) -+{ -+ struct rmi_data *hdata = hid_get_drvdata(hdev); -+ -+ clear_bit(RMI_STARTED, &hdata->flags); -+ -+ hid_hw_stop(hdev); -+} -+ -+static const struct hid_device_id rmi_id[] = { -+ { HID_I2C_DEVICE(USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, -+ { HID_USB_DEVICE(USB_VENDOR_ID_SYNAPTICS, HID_ANY_ID) }, -+ { } -+}; -+MODULE_DEVICE_TABLE(hid, rmi_id); -+ -+static struct hid_driver rmi_driver = { -+ .name = "hid-rmi", -+ .id_table = rmi_id, -+ .probe = rmi_probe, -+ .remove = rmi_remove, -+ .raw_event = rmi_raw_event, -+ .input_mapping = rmi_input_mapping, -+ .input_configured = rmi_input_configured, -+#ifdef CONFIG_PM -+ .resume = rmi_post_resume, -+ .reset_resume = rmi_post_reset, -+#endif -+}; -+ -+module_hid_driver(rmi_driver); -+ -+MODULE_AUTHOR("Andrew Duggan <aduggan@synaptics.com>"); -+MODULE_DESCRIPTION("RMI HID driver"); -+MODULE_LICENSE("GPL"); -diff --git a/include/linux/hid.h b/include/linux/hid.h -index 31b9d29..1b5f1e9 100644 ---- a/include/linux/hid.h -+++ b/include/linux/hid.h -@@ -571,6 +571,8 @@ struct hid_descriptor { - .bus = BUS_USB, .vendor = (ven), .product = (prod) - #define HID_BLUETOOTH_DEVICE(ven, prod) \ - .bus = BUS_BLUETOOTH, .vendor = (ven), .product = (prod) -+#define HID_I2C_DEVICE(ven, prod) \ -+ .bus = BUS_I2C, .vendor = (ven), .product = (prod) - - #define HID_REPORT_ID(rep) \ - .report_type = (rep) --- -1.8.3.1 - diff --git a/freed-ora/current/master/0001-ideapad-laptop-Change-Lenovo-Yoga-2-series-rfkill-ha.patch b/freed-ora/current/master/0001-ideapad-laptop-Change-Lenovo-Yoga-2-series-rfkill-ha.patch new file mode 100644 index 000000000..aab1c4e32 --- /dev/null +++ b/freed-ora/current/master/0001-ideapad-laptop-Change-Lenovo-Yoga-2-series-rfkill-ha.patch @@ -0,0 +1,138 @@ +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1021036 +Upstream-status: Send upstream for 3.17 + +From 0ad19912cb324f0a356a212433ec0b2a31f61acc Mon Sep 17 00:00:00 2001 +From: Hans de Goede <hdegoede@redhat.com> +Date: Fri, 20 Jun 2014 10:29:16 +0200 +Subject: [PATCH] ideapad-laptop: Change Lenovo Yoga 2 series rfkill handling + +It seems that the same problems which lead to adding an rfkill blacklist and +putting the Lenovo Yoga 2 11 on it are also present on the Lenovo Yoga 2 13 +and Lenovo Yoga 2 Pro too: +https://bugzilla.redhat.com/show_bug.cgi?id=1021036 +https://forums.lenovo.com/t5/Linux-Discussion/Yoga-2-13-not-Pro-Linux-Warning/m-p/1517612 + +Testing has shown that the firmware rfkill settings are persistent over +reboots. So blacklisting the driver is not good enough, if the wifi is blocked +at the firmware level the wifi needs to be explictly unblocked through the +ideapad-laptop interface. + +And at least on the Lenovo Yoga 2 13 the VPCCMD_RF register which on devices +with hardware kill switch reports the hardware switch state, needs to be +explictly set to 1 (radio enabled / not blocked). + +So this patch does 3 things to get proper rfkill handling on these models: + +1) Instead of blacklisting the rfkill functionality, which means that people +with a firmware blocked wifi get stuck in that situation, ignore the value +reported by the not present hardware rfkill switch, as this is what is causing +ideapad-laptop to wrongly report all radios as hardware blocks. But do register +the rfkill interfaces so that the user can soft [un]block them. + +2) On models without a hardware rfkill switch, explictly set VPCCMD_RF to 1 + +3) Drop the " 11" postfix from the dmi match string, as the entire Yoga 2 +series is affected. + +Yoga 2 11: +Reported-and-tested-by: Vincent Gerris <vgerris@gmail.com> + +Yoga 2 13: +Tested-by: madls05 <http://ubuntuforums.org/showthread.php?t=2215044> + +Yoga 2 Pro: +Reported-and-tested-by: Peter F. Patel-Schneider <pfpschneider@gmail.com> + +Signed-off-by: Hans de Goede <hdegoede@redhat.com> +--- + drivers/platform/x86/ideapad-laptop.c | 41 +++++++++++++++++++++++------------ + 1 file changed, 27 insertions(+), 14 deletions(-) + +diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c +index b4c495a..b0e3a2e 100644 +--- a/drivers/platform/x86/ideapad-laptop.c ++++ b/drivers/platform/x86/ideapad-laptop.c +@@ -87,6 +87,7 @@ struct ideapad_private { + struct backlight_device *blightdev; + struct dentry *debug; + unsigned long cfg; ++ bool has_hw_rfkill_switch; + }; + + static bool no_bt_rfkill; +@@ -473,12 +474,14 @@ static struct rfkill_ops ideapad_rfk_ops = { + + static void ideapad_sync_rfk_state(struct ideapad_private *priv) + { +- unsigned long hw_blocked; ++ unsigned long hw_blocked = 0; + int i; + +- if (read_ec_data(priv->adev->handle, VPCCMD_R_RF, &hw_blocked)) +- return; +- hw_blocked = !hw_blocked; ++ if (priv->has_hw_rfkill_switch) { ++ if (read_ec_data(priv->adev->handle, VPCCMD_R_RF, &hw_blocked)) ++ return; ++ hw_blocked = !hw_blocked; ++ } + + for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) + if (priv->rfk[i]) +@@ -821,14 +824,17 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) + } + } + +-/* Blacklist for devices where the ideapad rfkill interface does not work */ +-static struct dmi_system_id rfkill_blacklist[] = { +- /* The Lenovo Yoga 2 11 always reports everything as blocked */ ++/* ++ * Some ideapads don't have a hardware rfkill switch, reading VPCCMD_R_RF ++ * always results in 0 on these models, causing ideapad_laptop to wrongly ++ * report all radios as hardware-blocked. ++ */ ++static struct dmi_system_id no_hw_rfkill_list[] = { + { +- .ident = "Lenovo Yoga 2 11", ++ .ident = "Lenovo Yoga 2 11 / 13 / Pro", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), +- DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2 11"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2"), + }, + }, + {} +@@ -856,6 +862,7 @@ static int ideapad_acpi_add(struct platform_device *pdev) + priv->cfg = cfg; + priv->adev = adev; + priv->platform_device = pdev; ++ priv->has_hw_rfkill_switch = !dmi_check_system(no_hw_rfkill_list); + + ret = ideapad_sysfs_init(priv); + if (ret) +@@ -869,11 +876,17 @@ static int ideapad_acpi_add(struct platform_device *pdev) + if (ret) + goto input_failed; + +- if (!dmi_check_system(rfkill_blacklist)) { +- for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) +- if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) +- ideapad_register_rfkill(priv, i); +- } ++ /* ++ * On some models without a hw-switch (the yoga 2 13 at least) ++ * VPCCMD_W_RF must be explicitly set to 1 for the wifi to work. ++ */ ++ if (!priv->has_hw_rfkill_switch) ++ write_ec_cmd(priv->adev->handle, VPCCMD_W_RF, 1); ++ ++ for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) ++ if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) ++ ideapad_register_rfkill(priv, i); ++ + ideapad_sync_rfk_state(priv); + ideapad_sync_touchpad_state(priv); + +-- +2.0.0 + diff --git a/freed-ora/current/master/HID-rmi-do-not-fetch-more-than-16-bytes-in-a-query.patch b/freed-ora/current/master/HID-rmi-do-not-fetch-more-than-16-bytes-in-a-query.patch deleted file mode 100644 index 972a1b142..000000000 --- a/freed-ora/current/master/HID-rmi-do-not-fetch-more-than-16-bytes-in-a-query.patch +++ /dev/null @@ -1,60 +0,0 @@ -Bugzilla: 1090161 -Upstream-status: sent https://patchwork.kernel.org/patch/4055781/ - -From patchwork Thu Apr 24 22:26:38 2014 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -Subject: HID: rmi: do not fetch more than 16 bytes in a query -From: Benjamin Tissoires <benjamin.tissoires@redhat.com> -X-Patchwork-Id: 4055781 -Message-Id: <1398378398-24825-1-git-send-email-benjamin.tissoires@redhat.com> -To: Andrew Duggan <aduggan@synaptics.com>, - Christopher Heiny <cheiny@synaptics.com>, - Jiri Kosina <jkosina@suse.cz>, linux-input@vger.kernel.org, - linux-kernel@vger.kernel.org -Date: Thu, 24 Apr 2014 18:26:38 -0400 - -A firmware bug is present on the XPS Haswell edition which silently -split the request in two responses when the caller ask for a read of -more than 16 bytes. -The FW sends the first 16 then the 4 next, but it says that it answered -the 20 bytes in the first report. - -This occurs only on the retrieving of the min/max of X and Y of the F11 -function. -We only use the first 10 bytes of the Ctrl register, so we can get only -those 10 bytes to prevent the bug from happening. - -Resolves: -https://bugzilla.redhat.com/show_bug.cgi?id=1090161 - -Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com> - ---- -drivers/hid/hid-rmi.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/drivers/hid/hid-rmi.c b/drivers/hid/hid-rmi.c -index 7da9509..cee89c9 100644 ---- a/drivers/hid/hid-rmi.c -+++ b/drivers/hid/hid-rmi.c -@@ -613,10 +613,15 @@ static int rmi_populate_f11(struct hid_device *hdev) - } - } - -- /* retrieve the ctrl registers */ -- ret = rmi_read_block(hdev, data->f11.control_base_addr, buf, 20); -+ /* -+ * retrieve the ctrl registers -+ * the ctrl register has a size of 20 but a fw bug split it into 16 + 4, -+ * and there is no way to know if the first 20 bytes are here or not. -+ * We use only the first 10 bytes, so get only them. -+ */ -+ ret = rmi_read_block(hdev, data->f11.control_base_addr, buf, 10); - if (ret) { -- hid_err(hdev, "can not read ctrl block of size 20: %d.\n", ret); -+ hid_err(hdev, "can not read ctrl block of size 10: %d.\n", ret); - return ret; - } - diff --git a/freed-ora/current/master/Makefile b/freed-ora/current/master/Makefile index 386683b38..e63bbf299 100644 --- a/freed-ora/current/master/Makefile +++ b/freed-ora/current/master/Makefile @@ -47,6 +47,7 @@ debug: @perl -pi -e 's/# CONFIG_FAULT_INJECTION_DEBUG_FS is not set/CONFIG_FAULT_INJECTION_DEBUG_FS=y/' config-nodebug @perl -pi -e 's/# CONFIG_FAULT_INJECTION_STACKTRACE_FILTER is not set/CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y/' config-nodebug @perl -pi -e 's/# CONFIG_DEBUG_SG is not set/CONFIG_DEBUG_SG=y/' config-nodebug + @perl -pi -e 's/# CONFIG_DEBUG_PI_LIST is not set/CONFIG_DEBUG_PI_LIST=y/' config-nodebug @perl -pi -e 's/# CONFIG_DEBUG_WRITECOUNT is not set/CONFIG_DEBUG_WRITECOUNT=y/' config-nodebug @perl -pi -e 's/# CONFIG_DEBUG_OBJECTS is not set/CONFIG_DEBUG_OBJECTS=y/' config-nodebug @perl -pi -e 's/# CONFIG_DEBUG_OBJECTS_FREE is not set/CONFIG_DEBUG_OBJECTS_FREE=y/' config-nodebug diff --git a/freed-ora/current/master/Makefile.release b/freed-ora/current/master/Makefile.release index 6ee755ec4..58a011758 100644 --- a/freed-ora/current/master/Makefile.release +++ b/freed-ora/current/master/Makefile.release @@ -27,6 +27,7 @@ config-release: @perl -pi -e 's/CONFIG_FAULT_INJECTION_DEBUG_FS=y/# CONFIG_FAULT_INJECTION_DEBUG_FS is not set/' config-nodebug @perl -pi -e 's/CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y/# CONFIG_FAULT_INJECTION_STACKTRACE_FILTER is not set/' config-nodebug @perl -pi -e 's/CONFIG_DEBUG_SG=y/# CONFIG_DEBUG_SG is not set/' config-nodebug + @perl -pi -e 's/CONFIG_DEBUG_PI_LIST=y/# CONFIG_DEBUG_PI_LIST is not set/' config-nodebug @perl -pi -e 's/CONFIG_DEBUG_WRITECOUNT=y/# CONFIG_DEBUG_WRITECOUNT is not set/' config-nodebug @perl -pi -e 's/CONFIG_DEBUG_OBJECTS=y/# CONFIG_DEBUG_OBJECTS is not set/' config-nodebug @perl -pi -e 's/CONFIG_DEBUG_OBJECTS_FREE=y/# CONFIG_DEBUG_OBJECTS_FREE is not set/' config-nodebug diff --git a/freed-ora/current/master/Revert-Revert-ACPI-video-change-acpi-video-brightnes.patch b/freed-ora/current/master/Revert-Revert-ACPI-video-change-acpi-video-brightnes.patch new file mode 100644 index 000000000..2f44032c8 --- /dev/null +++ b/freed-ora/current/master/Revert-Revert-ACPI-video-change-acpi-video-brightnes.patch @@ -0,0 +1,44 @@ +Bugzilla: N/A +Upstream-status: Sigh. We almost got to drop this. + +From 20e3f1e1b9341d233a11734c07c076caac9936ef Mon Sep 17 00:00:00 2001 +From: Josh Boyer <jwboyer@fedoraproject.org> +Date: Mon, 28 Jul 2014 12:59:48 -0400 +Subject: [PATCH] Revert "Revert "ACPI / video: change acpi-video + brightness_switch_enabled default to 0"" + +This reverts commit 2843768b701971ab10e62c77d5c75ad7c306f1bd. +--- + Documentation/kernel-parameters.txt | 2 +- + drivers/acpi/video.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt +index b7fa2f599459..e8db409a7e3a 100644 +--- a/Documentation/kernel-parameters.txt ++++ b/Documentation/kernel-parameters.txt +@@ -3532,7 +3532,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted. + the allocated input device; If set to 0, video driver + will only send out the event without touching backlight + brightness level. +- default: 1 ++ default: 0 + + virtio_mmio.device= + [VMMIO] Memory mapped virtio (platform) device. +diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c +index 350d52a8f781..44c89f705018 100644 +--- a/drivers/acpi/video.c ++++ b/drivers/acpi/video.c +@@ -68,7 +68,7 @@ MODULE_AUTHOR("Bruno Ducrot"); + MODULE_DESCRIPTION("ACPI Video Driver"); + MODULE_LICENSE("GPL"); + +-static bool brightness_switch_enabled = 1; ++static bool brightness_switch_enabled; + module_param(brightness_switch_enabled, bool, 0644); + + /* +-- +1.9.3 + diff --git a/freed-ora/current/master/acer-wmi-Add-Aspire-5741-to-video_vendor_dmi_table.patch b/freed-ora/current/master/acer-wmi-Add-Aspire-5741-to-video_vendor_dmi_table.patch deleted file mode 100644 index 668fa0956..000000000 --- a/freed-ora/current/master/acer-wmi-Add-Aspire-5741-to-video_vendor_dmi_table.patch +++ /dev/null @@ -1,40 +0,0 @@ -Bugzilla: 1012674 -Upstream-status: Queued for 3.16 - -From a94de796cd769fc5c4a9c57ebe99c0ae74b9c8a1 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 2 Jun 2014 17:41:06 +0200 -Subject: [PATCH 09/14] acer-wmi: Add Aspire 5741 to video_vendor_dmi_table - -The Aspire 5741 has broken acpi-video backlight control, so add it to the -quirk table. - -https://bugzilla.redhat.com/show_bug.cgi?id=1012674 - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - drivers/platform/x86/acer-wmi.c | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c -index 3a746998f92a..bbf78b2d6d93 100644 ---- a/drivers/platform/x86/acer-wmi.c -+++ b/drivers/platform/x86/acer-wmi.c -@@ -570,6 +570,14 @@ static const struct dmi_system_id video_vendor_dmi_table[] = { - DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5750"), - }, - }, -+ { -+ .callback = video_set_backlight_video_vendor, -+ .ident = "Acer Aspire 5741", -+ .matches = { -+ DMI_MATCH(DMI_BOARD_VENDOR, "Acer"), -+ DMI_MATCH(DMI_PRODUCT_NAME, "Aspire 5741"), -+ }, -+ }, - {} - }; - --- -1.9.0 - diff --git a/freed-ora/current/master/acer-wmi-Switch-to-acpi_video_unregister_backlight.patch b/freed-ora/current/master/acer-wmi-Switch-to-acpi_video_unregister_backlight.patch deleted file mode 100644 index 310e8a299..000000000 --- a/freed-ora/current/master/acer-wmi-Switch-to-acpi_video_unregister_backlight.patch +++ /dev/null @@ -1,64 +0,0 @@ -Bugzilla: 1012674 -Upstream-status: Queued for 3.16 - -From d8aceabf18681a92e8031c43d3917f6826ac6691 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 2 Jun 2014 17:41:05 +0200 -Subject: [PATCH 08/14] acer-wmi: Switch to acpi_video_unregister_backlight - -Switch from acpi_video_unregister(), to acpi_video_unregister_backlight(), -so that the hotkeys handler registered by acpi-video stays in place. - -Since there are no mappings for the atkbd raw codes for the brightness -keys used by newer Acer models in /lib/udev/hwdb.d/60-keyboard.hwdb, and -since we map the wmi events with a code of KE_IGNORE, we rely on acpi-video -to do the hotkey handling for us. - -For laptops such as the Acer Aspire 5750 which uses intel gfx this works -despite us calling acpi_video_unregister() because the following happens: - -1) acpi-video module gets loaded (as it is a dependency of acer-wmi and i915) -2) acpi-video does NOT call acpi_video_register() -3) acer-wmi loads (assume it loads before i915), calls -acpi_video_dmi_promote_vendor(); which sets ACPI_VIDEO_BACKLIGHT_DMI_VENDOR -4) calls acpi_video_unregister -> not registered, nop -5) i915 loads, calls acpi_video_register -6) acpi_video_register registers the acpi_notifier for the hotkeys, - does NOT register a backlight device because of ACPI_VIDEO_BACKLIGHT_DMI_VENDOR - -But on the Acer Aspire 5750G, which uses nvidia graphics the following happens: -1) acpi-video module gets loaded (as it is a dependency of acer-wmi) -2) acpi-video calls acpi_video_register() -3) acpi_video_register registers the acpi_notifier for the hotkeys, - and a backlight device -4) acer-wmi loads, calls acpi_video_dmi_promote_vendor() -5) calls acpi_video_unregister, this unregisters BOTH the acpi_notifier for - the hotkeys AND the backlight device - -And we end up without any handler for the brightness hotkeys. This patch fixes -this by switching over to acpi_video_unregister_backlight() which keeps the -hotkey handler in place. - -https://bugzilla.kernel.org/show_bug.cgi?id=35622 - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - drivers/platform/x86/acer-wmi.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c -index c91f69b39db4..3a746998f92a 100644 ---- a/drivers/platform/x86/acer-wmi.c -+++ b/drivers/platform/x86/acer-wmi.c -@@ -2228,7 +2228,7 @@ static int __init acer_wmi_init(void) - pr_info("Brightness must be controlled by acpi video driver\n"); - } else { - pr_info("Disabling ACPI video driver\n"); -- acpi_video_unregister(); -+ acpi_video_unregister_backlight(); - } - - if (wmi_has_guid(WMID_GUID3)) { --- -1.9.0 - diff --git a/freed-ora/current/master/acpi-video-Add-an-acpi_video_unregister_backlight-fu.patch b/freed-ora/current/master/acpi-video-Add-an-acpi_video_unregister_backlight-fu.patch deleted file mode 100644 index c956ad0c2..000000000 --- a/freed-ora/current/master/acpi-video-Add-an-acpi_video_unregister_backlight-fu.patch +++ /dev/null @@ -1,112 +0,0 @@ -Bugzilla: 1012674 -Upstream-status: Queued for 3.16 - -From 4cf3eac89ed731d7cdb7d9d815a97109472af824 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 2 Jun 2014 17:41:04 +0200 -Subject: [PATCH 07/14] acpi-video: Add an acpi_video_unregister_backlight - function - -Add an acpi_video_unregister_backlight function, which only unregisters -the backlight device, and leaves the acpi_notifier in place. Some acpi_vendor -driver need this as they don't want the acpi_video# backlight device, but do -need the acpi-video driver for hotkey handling. - -Chances are that this new acpi_video_unregister_backlight() is actually -what existing acpi_vendor drivers have wanted all along. Currently acpi_vendor -drivers which want to disable the acpi_video# backlight device, make 2 calls: - -acpi_video_dmi_promote_vendor(); -acpi_video_unregister(); - -The intention here is to make things independent of when acpi_video_register() -gets called. As acpi_video_register() will get called on acpi-video load time -on non intel gfx machines, while it gets called on i915 load time on intel -gfx machines. - -This leads to the following 2 interesting scenarios: - -a) intel gfx: -1) acpi-video module gets loaded (as it is a dependency of acpi_vendor and i915) -2) acpi-video does NOT call acpi_video_register() -3) acpi_vendor loads (lets assume it loads before i915), calls -acpi_video_dmi_promote_vendor(); which sets ACPI_VIDEO_BACKLIGHT_DMI_VENDOR -4) calls acpi_video_unregister -> not registered, nop -5) i915 loads, calls acpi_video_register -6) acpi_video_register registers the acpi_notifier for the hotkeys, - does NOT register a backlight device because of ACPI_VIDEO_BACKLIGHT_DMI_VENDOR - -b) non intel gfx -1) acpi-video module gets loaded (as it is a dependency acpi_vendor) -2) acpi-video calls acpi_video_register() -3) acpi_video_register registers the acpi_notifier for the hotkeys, - and a backlight device -4) acpi_vendor loads, calls acpi_video_dmi_promote_vendor() -5) calls acpi_video_unregister, this unregisters BOTH the acpi_notifier for - the hotkeys AND the backlight device - -So here we have possibly the same acpi_vendor module, making the same calls, -but with different results, in one cases acpi-video does handle hotkeys, -in the other it does not. - -Note that the a) scenario turns into b) if we assume the i915 module loads -before the vendor_acpi module, so we also have different behavior depending -on module loading order! - -So as said I believe that quite a few existing acpi_vendor modules really -always want the behavior of a), hence this patch adds a new -acpi_video_unregister_backlight() which gives the behavior of a) independent -of module loading order. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - drivers/acpi/video.c | 14 ++++++++++++++ - include/acpi/video.h | 2 ++ - 2 files changed, 16 insertions(+) - -diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c -index a68313720c9c..d4d6ea3ac77a 100644 ---- a/drivers/acpi/video.c -+++ b/drivers/acpi/video.c -@@ -2070,6 +2070,20 @@ void acpi_video_unregister(void) - } - EXPORT_SYMBOL(acpi_video_unregister); - -+void acpi_video_unregister_backlight(void) -+{ -+ struct acpi_video_bus *video; -+ -+ if (!register_count) -+ return; -+ -+ mutex_lock(&video_list_lock); -+ list_for_each_entry(video, &video_bus_head, entry) -+ acpi_video_bus_unregister_backlight(video); -+ mutex_unlock(&video_list_lock); -+} -+EXPORT_SYMBOL(acpi_video_unregister_backlight); -+ - /* - * This is kind of nasty. Hardware using Intel chipsets may require - * the video opregion code to be run first in order to initialise -diff --git a/include/acpi/video.h b/include/acpi/video.h -index 61109f2609fc..ea4c7bbded4d 100644 ---- a/include/acpi/video.h -+++ b/include/acpi/video.h -@@ -19,11 +19,13 @@ struct acpi_device; - #if (defined CONFIG_ACPI_VIDEO || defined CONFIG_ACPI_VIDEO_MODULE) - extern int acpi_video_register(void); - extern void acpi_video_unregister(void); -+extern void acpi_video_unregister_backlight(void); - extern int acpi_video_get_edid(struct acpi_device *device, int type, - int device_id, void **edid); - #else - static inline int acpi_video_register(void) { return 0; } - static inline void acpi_video_unregister(void) { return; } -+static inline void acpi_video_unregister_backlight(void) { return; } - static inline int acpi_video_get_edid(struct acpi_device *device, int type, - int device_id, void **edid) - { --- -1.9.0 - diff --git a/freed-ora/current/master/acpi-video-Don-t-register-acpi_video_resume-notifier.patch b/freed-ora/current/master/acpi-video-Don-t-register-acpi_video_resume-notifier.patch deleted file mode 100644 index ac40462cd..000000000 --- a/freed-ora/current/master/acpi-video-Don-t-register-acpi_video_resume-notifier.patch +++ /dev/null @@ -1,214 +0,0 @@ -Bugzilla: 1012674 -Upstream-status: Queued for 3.16 - -From 5d9b5801af7cbeaab060fa07576ca6cd7dc3be89 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 2 Jun 2014 17:41:03 +0200 -Subject: [PATCH 06/14] acpi-video: Don't register acpi_video_resume notifier - without backlight devices - -If we're not going to be registering any backlight devices then -acpi_video_resume is always nop, so don't register it in that case. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> - --- - -Note to reviewers the changes to acpi_video_dev_register_backlight() only -remove the "if (!acpi_video_verify_backlight_support()) {" which surrounded -the entire body of the function, as that is checked earlier now. ---- - drivers/acpi/video.c | 139 +++++++++++++++++++++++++++------------------------ - 1 file changed, 74 insertions(+), 65 deletions(-) - -diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c -index f8bc5a755dda..a68313720c9c 100644 ---- a/drivers/acpi/video.c -+++ b/drivers/acpi/video.c -@@ -150,6 +150,7 @@ struct acpi_video_enumerated_device { - - struct acpi_video_bus { - struct acpi_device *device; -+ bool backlight_registered; - u8 dos_setting; - struct acpi_video_enumerated_device *attached_array; - u8 attached_count; -@@ -1658,88 +1659,89 @@ acpi_video_bus_match(acpi_handle handle, u32 level, void *context, - - static void acpi_video_dev_register_backlight(struct acpi_video_device *device) - { -- if (acpi_video_verify_backlight_support()) { -- struct backlight_properties props; -- struct pci_dev *pdev; -- acpi_handle acpi_parent; -- struct device *parent = NULL; -- int result; -- static int count; -- char *name; -- -- result = acpi_video_init_brightness(device); -- if (result) -- return; -- name = kasprintf(GFP_KERNEL, "acpi_video%d", count); -- if (!name) -- return; -- count++; -+ struct backlight_properties props; -+ struct pci_dev *pdev; -+ acpi_handle acpi_parent; -+ struct device *parent = NULL; -+ int result; -+ static int count; -+ char *name; - -- acpi_get_parent(device->dev->handle, &acpi_parent); -+ result = acpi_video_init_brightness(device); -+ if (result) -+ return; -+ name = kasprintf(GFP_KERNEL, "acpi_video%d", count); -+ if (!name) -+ return; -+ count++; - -- pdev = acpi_get_pci_dev(acpi_parent); -- if (pdev) { -- parent = &pdev->dev; -- pci_dev_put(pdev); -- } -+ acpi_get_parent(device->dev->handle, &acpi_parent); - -- memset(&props, 0, sizeof(struct backlight_properties)); -- props.type = BACKLIGHT_FIRMWARE; -- props.max_brightness = device->brightness->count - 3; -- device->backlight = backlight_device_register(name, -- parent, -- device, -- &acpi_backlight_ops, -- &props); -- kfree(name); -- if (IS_ERR(device->backlight)) -- return; -+ pdev = acpi_get_pci_dev(acpi_parent); -+ if (pdev) { -+ parent = &pdev->dev; -+ pci_dev_put(pdev); -+ } - -- /* -- * Save current brightness level in case we have to restore it -- * before acpi_video_device_lcd_set_level() is called next time. -- */ -- device->backlight->props.brightness = -- acpi_video_get_brightness(device->backlight); -+ memset(&props, 0, sizeof(struct backlight_properties)); -+ props.type = BACKLIGHT_FIRMWARE; -+ props.max_brightness = device->brightness->count - 3; -+ device->backlight = backlight_device_register(name, -+ parent, -+ device, -+ &acpi_backlight_ops, -+ &props); -+ kfree(name); -+ if (IS_ERR(device->backlight)) -+ return; - -- device->cooling_dev = thermal_cooling_device_register("LCD", -- device->dev, &video_cooling_ops); -- if (IS_ERR(device->cooling_dev)) { -- /* -- * Set cooling_dev to NULL so we don't crash trying to -- * free it. -- * Also, why the hell we are returning early and -- * not attempt to register video output if cooling -- * device registration failed? -- * -- dtor -- */ -- device->cooling_dev = NULL; -- return; -- } -+ /* -+ * Save current brightness level in case we have to restore it -+ * before acpi_video_device_lcd_set_level() is called next time. -+ */ -+ device->backlight->props.brightness = -+ acpi_video_get_brightness(device->backlight); - -- dev_info(&device->dev->dev, "registered as cooling_device%d\n", -- device->cooling_dev->id); -- result = sysfs_create_link(&device->dev->dev.kobj, -- &device->cooling_dev->device.kobj, -- "thermal_cooling"); -- if (result) -- printk(KERN_ERR PREFIX "Create sysfs link\n"); -- result = sysfs_create_link(&device->cooling_dev->device.kobj, -- &device->dev->dev.kobj, "device"); -- if (result) -- printk(KERN_ERR PREFIX "Create sysfs link\n"); -+ device->cooling_dev = thermal_cooling_device_register("LCD", -+ device->dev, &video_cooling_ops); -+ if (IS_ERR(device->cooling_dev)) { -+ /* -+ * Set cooling_dev to NULL so we don't crash trying to free it. -+ * Also, why the hell we are returning early and not attempt to -+ * register video output if cooling device registration failed? -+ * -- dtor -+ */ -+ device->cooling_dev = NULL; -+ return; - } -+ -+ dev_info(&device->dev->dev, "registered as cooling_device%d\n", -+ device->cooling_dev->id); -+ result = sysfs_create_link(&device->dev->dev.kobj, -+ &device->cooling_dev->device.kobj, -+ "thermal_cooling"); -+ if (result) -+ printk(KERN_ERR PREFIX "Create sysfs link\n"); -+ result = sysfs_create_link(&device->cooling_dev->device.kobj, -+ &device->dev->dev.kobj, "device"); -+ if (result) -+ printk(KERN_ERR PREFIX "Create sysfs link\n"); - } - - static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) - { - struct acpi_video_device *dev; - -+ if (!acpi_video_verify_backlight_support()) -+ return 0; -+ - mutex_lock(&video->device_list_lock); - list_for_each_entry(dev, &video->video_device_list, entry) - acpi_video_dev_register_backlight(dev); - mutex_unlock(&video->device_list_lock); - -+ video->backlight_registered = true; -+ - video->pm_nb.notifier_call = acpi_video_resume; - video->pm_nb.priority = 0; - return register_pm_notifier(&video->pm_nb); -@@ -1767,13 +1769,20 @@ static void acpi_video_dev_unregister_backlight(struct acpi_video_device *device - static int acpi_video_bus_unregister_backlight(struct acpi_video_bus *video) - { - struct acpi_video_device *dev; -- int error = unregister_pm_notifier(&video->pm_nb); -+ int error; -+ -+ if (!video->backlight_registered) -+ return 0; -+ -+ error = unregister_pm_notifier(&video->pm_nb); - - mutex_lock(&video->device_list_lock); - list_for_each_entry(dev, &video->video_device_list, entry) - acpi_video_dev_unregister_backlight(dev); - mutex_unlock(&video->device_list_lock); - -+ video->backlight_registered = false; -+ - return error; - } - --- -1.9.0 - diff --git a/freed-ora/current/master/acpi-video-Unregister-the-backlight-device-if-a-raw-.patch b/freed-ora/current/master/acpi-video-Unregister-the-backlight-device-if-a-raw-.patch deleted file mode 100644 index f922d4235..000000000 --- a/freed-ora/current/master/acpi-video-Unregister-the-backlight-device-if-a-raw-.patch +++ /dev/null @@ -1,130 +0,0 @@ -Bugzilla: 1093171 -Upstream-status: Queued for 3.16 - -From 7f5b3e9378c0adfdb1cf2ffde6c4f890e05517c7 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 2 Jun 2014 17:41:09 +0200 -Subject: [PATCH 12/14] acpi-video: Unregister the backlight device if a raw - one shows up later - -When video.use_native_backlight=1 and non intel gfx are in use, the raw -backlight device of the gfx driver will show up after acpi-video has done its -acpi_video_verify_backlight_support() check. - -This causes video.use_native_backlight=1 to not have the desired result. - -This patch fixes this by adding a backlight notifier and when a raw -backlight is registered or unregistered re-doing the -acpi_video_verify_backlight_support() check. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - drivers/acpi/video.c | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - 1 file changed, 57 insertions(+) - -diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c -index d4d6ea3ac77a..ab7cd65ce21e 100644 ---- a/drivers/acpi/video.c -+++ b/drivers/acpi/video.c -@@ -151,6 +151,7 @@ struct acpi_video_enumerated_device { - struct acpi_video_bus { - struct acpi_device *device; - bool backlight_registered; -+ bool backlight_notifier_registered; - u8 dos_setting; - struct acpi_video_enumerated_device *attached_array; - u8 attached_count; -@@ -162,6 +163,7 @@ struct acpi_video_bus { - struct input_dev *input; - char phys[32]; /* for input device */ - struct notifier_block pm_nb; -+ struct notifier_block backlight_nb; - }; - - struct acpi_video_device_flags { -@@ -1732,6 +1734,9 @@ static int acpi_video_bus_register_backlight(struct acpi_video_bus *video) - { - struct acpi_video_device *dev; - -+ if (video->backlight_registered) -+ return 0; -+ - if (!acpi_video_verify_backlight_support()) - return 0; - -@@ -1876,6 +1881,56 @@ static void acpi_video_bus_remove_notify_handler(struct acpi_video_bus *video) - video->input = NULL; - } - -+static int acpi_video_backlight_notify(struct notifier_block *nb, -+ unsigned long val, void *bd) -+{ -+ struct backlight_device *backlight = bd; -+ struct acpi_video_bus *video; -+ -+ /* acpi_video_verify_backlight_support only cares about raw devices */ -+ if (backlight->props.type != BACKLIGHT_RAW) -+ return NOTIFY_DONE; -+ -+ video = container_of(nb, struct acpi_video_bus, backlight_nb); -+ -+ switch (val) { -+ case BACKLIGHT_REGISTERED: -+ if (!acpi_video_verify_backlight_support()) -+ acpi_video_bus_unregister_backlight(video); -+ break; -+ case BACKLIGHT_UNREGISTERED: -+ acpi_video_bus_register_backlight(video); -+ break; -+ } -+ -+ return NOTIFY_OK; -+} -+ -+static int acpi_video_bus_add_backlight_notify_handler( -+ struct acpi_video_bus *video) -+{ -+ int error; -+ -+ video->backlight_nb.notifier_call = acpi_video_backlight_notify; -+ video->backlight_nb.priority = 0; -+ error = backlight_register_notifier(&video->backlight_nb); -+ if (error == 0) -+ video->backlight_notifier_registered = true; -+ -+ return error; -+} -+ -+static int acpi_video_bus_remove_backlight_notify_handler( -+ struct acpi_video_bus *video) -+{ -+ if (!video->backlight_notifier_registered) -+ return 0; -+ -+ video->backlight_notifier_registered = false; -+ -+ return backlight_unregister_notifier(&video->backlight_nb); -+} -+ - static int acpi_video_bus_put_devices(struct acpi_video_bus *video) - { - struct acpi_video_device *dev, *next; -@@ -1957,6 +2012,7 @@ static int acpi_video_bus_add(struct acpi_device *device) - - acpi_video_bus_register_backlight(video); - acpi_video_bus_add_notify_handler(video); -+ acpi_video_bus_add_backlight_notify_handler(video); - - return 0; - -@@ -1980,6 +2036,7 @@ static int acpi_video_bus_remove(struct acpi_device *device) - - video = acpi_driver_data(device); - -+ acpi_video_bus_remove_backlight_notify_handler(video); - acpi_video_bus_remove_notify_handler(video); - acpi_video_bus_unregister_backlight(video); - acpi_video_bus_put_devices(video); --- -1.9.0 - diff --git a/freed-ora/current/master/arm-beagle.patch b/freed-ora/current/master/arm-beagle.patch new file mode 100644 index 000000000..5e2d8abdc --- /dev/null +++ b/freed-ora/current/master/arm-beagle.patch @@ -0,0 +1,460 @@ +Bugzilla: 1012025 +Upstream-status: In beagle github repository https://github.com/beagleboard/kernel + +From b5a2528c89fc8049b2a6a750634c14983e33d00f Mon Sep 17 00:00:00 2001 +From: Robert Nelson <robertcnelson@gmail.com> +Date: Fri, 27 Dec 2013 13:05:09 -0600 +Subject: [PATCH] arm: dts: am335x-boneblack: lcdc add panel-info + +Signed-off-by: Robert Nelson <robertcnelson@gmail.com> +--- + arch/arm/boot/dts/am335x-boneblack.dts | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts +index 6b71ad9..09ffbd8 100644 +--- a/arch/arm/boot/dts/am335x-boneblack.dts ++++ b/arch/arm/boot/dts/am335x-boneblack.dts +@@ -74,5 +74,18 @@ + pinctrl-0 = <&nxp_hdmi_bonelt_pins>; + pinctrl-1 = <&nxp_hdmi_bonelt_off_pins>; + status = "okay"; ++ ++ panel-info { ++ bpp = <16>; ++ ac-bias = <255>; ++ ac-bias-intrpt = <0>; ++ dma-burst-sz = <16>; ++ fdd = <16>; ++ sync-edge = <1>; ++ sync-ctrl = <1>; ++ raster-order = <0>; ++ fifo-th = <0>; ++ invert-pxl-clk; ++ }; + }; + }; +-- +1.8.5.1 + +From 1da083a002581520dd358b8b8e097078000d12b9 Mon Sep 17 00:00:00 2001 +From: Robert Nelson <robertcnelson@gmail.com> +Date: Fri, 27 Dec 2013 13:14:19 -0600 +Subject: [PATCH 2/2] arm: dts: am335x-boneblack: add cpu0 opp points + +Signed-off-by: Robert Nelson <robertcnelson@gmail.com> +--- + arch/arm/boot/dts/am335x-boneblack.dts | 18 ++++++++++++++++++ + 1 file changed, 18 insertions(+) + +diff --git a/arch/arm/boot/dts/am335x-boneblack.dts b/arch/arm/boot/dts/am335x-boneblack.dts +index 09ffbd8..f213ccd 100644 +--- a/arch/arm/boot/dts/am335x-boneblack.dts ++++ b/arch/arm/boot/dts/am335x-boneblack.dts +@@ -67,6 +67,24 @@ + }; + + / { ++ cpus { ++ cpu@0 { ++ cpu0-supply = <&dcdc2_reg>; ++ /* ++ * To consider voltage drop between PMIC and SoC, ++ * tolerance value is reduced to 2% from 4% and ++ * voltage value is increased as a precaution. ++ */ ++ operating-points = < ++ /* kHz uV */ ++ 1000000 1325000 ++ 800000 1300000 ++ 600000 1112000 ++ 300000 969000 ++ >; ++ }; ++ }; ++ + hdmi { + compatible = "ti,tilcdc,slave"; + i2c = <&i2c0>; +-- +1.8.5.1 + +From 8551d8aa7d3e002da2097e7e902fb96fceb8694e Mon Sep 17 00:00:00 2001 +From: Robert Nelson <robertcnelson@gmail.com> +Date: Tue, 31 Dec 2013 11:17:45 -0600 +Subject: [PATCH 3/3] arm: dts: am335x-bone-common: enable and use i2c2 + +Signed-off-by: Robert Nelson <robertcnelson@gmail.com> +--- + arch/arm/boot/dts/am335x-bone-common.dtsi | 39 +++++++++++++++++++++++++++++++ + 1 file changed, 39 insertions(+) + +diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi +index e3f27ec..54366b6 100644 +--- a/arch/arm/boot/dts/am335x-bone-common.dtsi ++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi +@@ -84,6 +84,13 @@ + >; + }; + ++ i2c2_pins: pinmux_i2c2_pins { ++ pinctrl-single,pins = < ++ 0x178 0x73 /* (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3) uart1_ctsn.i2c2_sda */ ++ 0x17c 0x73 /* (SLEWCTRL_SLOW | PIN_INPUT_PULLUP | MUX_MODE3) uart1_rtsn.i2c2_scl */ ++ >; ++ }; ++ + uart0_pins: pinmux_uart0_pins { + pinctrl-single,pins = < + 0x170 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart0_rxd.uart0_rxd */ +@@ -220,6 +227,38 @@ + reg = <0x24>; + }; + ++ baseboard_eeprom: baseboard_eeprom@50 { ++ compatible = "at,24c256"; ++ reg = <0x50>; ++ }; ++}; ++ ++&i2c2 { ++ status = "okay"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&i2c2_pins>; ++ ++ clock-frequency = <100000>; ++ ++ cape_eeprom0: cape_eeprom0@54 { ++ compatible = "at,24c256"; ++ reg = <0x54>; ++ }; ++ ++ cape_eeprom1: cape_eeprom1@55 { ++ compatible = "at,24c256"; ++ reg = <0x55>; ++ }; ++ ++ cape_eeprom2: cape_eeprom2@56 { ++ compatible = "at,24c256"; ++ reg = <0x56>; ++ }; ++ ++ cape_eeprom3: cape_eeprom3@57 { ++ compatible = "at,24c256"; ++ reg = <0x57>; ++ }; + }; + + /include/ "tps65217.dtsi" +-- +1.8.5.2 + +From a3099dc53a47d1694a5b575580ec3406dc429bf8 Mon Sep 17 00:00:00 2001 +From: Robert Nelson <robertcnelson@gmail.com> +Date: Tue, 31 Dec 2013 14:18:00 -0600 +Subject: [PATCH 4/4] arm: dts: am335x-bone-common: setup default pinmux + http://elinux.org/Basic_Proto_Cape + +Signed-off-by: Robert Nelson <robertcnelson@gmail.com> +--- + arch/arm/boot/dts/am335x-bone-common.dtsi | 130 ++++++++++++++++++++++++++++++ + 1 file changed, 130 insertions(+) + +diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi +index e4571af..f85cabc 100644 +--- a/arch/arm/boot/dts/am335x-bone-common.dtsi ++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi +@@ -98,6 +98,13 @@ + >; + }; + ++ uart1_pins: pinmux_uart1_pins { ++ pinctrl-single,pins = < ++ 0x180 (PIN_INPUT_PULLUP | MUX_MODE0) /* uart1_rxd.uart1_rxd */ ++ 0x184 (PIN_OUTPUT_PULLDOWN | MUX_MODE0) /* uart1_txd.uart1_txd */ ++ >; ++ }; ++ + clkout2_pin: pinmux_clkout2_pin { + pinctrl-single,pins = < + 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */ +@@ -178,6 +185,33 @@ + 0x1c (PIN_INPUT_PULLUP | MUX_MODE1) /* gpmc_ad7.mmc1_dat7 */ + >; + }; ++ ++ spi0_pins: pinmux_spi0_pins { ++ pinctrl-single,pins = < ++ 0x150 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_sclk.spi0_sclk */ ++ 0x154 (PIN_INPUT_PULLUP | MUX_MODE0) /* spi0_d0.spi0_d0 */ ++ 0x158 (PIN_OUTPUT_PULLUP | MUX_MODE0) /* spi0_d1.spi0_d1 */ ++ 0x15c (PIN_OUTPUT_PULLUP | MUX_MODE0) /* spi0_cs0.spi0_cs0 */ ++ >; ++ }; ++ ++ ehrpwm1_pin_p9_14: pinmux_ehrpwm1_pin_p9_14 { ++ pinctrl-single,pins = < ++ 0x048 0x6 /* P9_14 (ZCZ ball U14) | MODE 6 */ ++ >; ++ }; ++ ++ ehrpwm1_pin_p9_16: pinmux_ehrpwm1_pin_p9_16 { ++ pinctrl-single,pins = < ++ 0x04c 0x6 /* P9_16 (ZCZ ball T14) | MODE 6 */ ++ >; ++ }; ++ ++ ecap0_pin_p9_42: pinmux_ecap0_pin_p9_42 { ++ pinctrl-single,pins = < ++ 0x164 0x0 /* P9_42 (ZCZ ball C18) | MODE 0 */ ++ >; ++ }; + }; + + &uart0 { +@@ -187,6 +221,13 @@ + status = "okay"; + }; + ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_pins>; ++ ++ status = "okay"; ++}; ++ + &usb { + status = "okay"; + +@@ -261,6 +302,56 @@ + }; + }; + ++&epwmss0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ecap0_pin_p9_42>; ++ status = "okay"; ++ ++ ecap@48300100 { ++ status = "okay"; ++ }; ++}; ++ ++&epwmss1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = < ++ &ehrpwm1_pin_p9_14 ++ &ehrpwm1_pin_p9_16 ++ >; ++ ++ status = "okay"; ++ ++ ehrpwm@48302200 { ++ status = "okay"; ++ }; ++}; ++ ++&spi0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&spi0_pins>; ++ status = "okay"; ++ ++ spidev0: spi@0 { ++ compatible = "spidev"; ++ reg = <0>; ++ spi-max-frequency = <16000000>; ++ spi-cpha; ++ }; ++ ++ spidev1: spi@1 { ++ compatible = "spidev"; ++ reg = <1>; ++ spi-max-frequency = <16000000>; ++ }; ++}; ++ ++&tscadc { ++ status = "okay"; ++ adc { ++ ti,adc-channels = <4 5 6>; ++ }; ++}; ++ + /include/ "tps65217.dtsi" + + &tps { +@@ -336,3 +427,42 @@ + cd-gpios = <&gpio0 6 GPIO_ACTIVE_HIGH>; + cd-inverted; + }; ++ ++/ { ++ ocp { ++ //FIXME: these pwm's still need work, this guild isn't working.. ++ //http://elinux.org/EBC_Exercise_13_Pulse_Width_Modulation ++ pwm_test_P9_14@0 { ++ compatible = "pwm_test"; ++ pwms = <&ehrpwm1 0 500000 1>; ++ pwm-names = "PWM_P9_14"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ehrpwm1_pin_p9_14>; ++ enabled = <1>; ++ duty = <0>; ++ status = "okay"; ++ }; ++ ++ pwm_test_P9_16@0 { ++ compatible = "pwm_test"; ++ pwms = <&ehrpwm1 0 500000 1>; ++ pwm-names = "PWM_P9_16"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ehrpwm1_pin_p9_16>; ++ enabled = <1>; ++ duty = <0>; ++ status = "okay"; ++ }; ++ ++ pwm_test_P9_42 { ++ compatible = "pwm_test"; ++ pwms = <&ecap0 0 500000 1>; ++ pwm-names = "PWM_P9_42"; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&ecap0_pin_p9_42>; ++ enabled = <1>; ++ duty = <0>; ++ status = "okay"; ++ }; ++ }; ++}; +-- +1.8.5.2 + +From b6e2c817edfc6d73874cf833daffe1be6c7ed8bb Mon Sep 17 00:00:00 2001 +From: Robert Nelson <robertcnelson@gmail.com> +Date: Thu, 13 Mar 2014 14:18:52 -0500 +Subject: [PATCH] arm: dts: am335x-bone-common: add + uart2_pins/uart4_pins/uart5_pins + +Signed-off-by: Robert Nelson <robertcnelson@gmail.com> +--- + arch/arm/boot/dts/am335x-bone-common.dtsi | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi +index f85cabc..5270d18 100644 +--- a/arch/arm/boot/dts/am335x-bone-common.dtsi ++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi +@@ -105,6 +105,27 @@ + >; + }; + ++ uart2_pins: pinmux_uart2_pins { ++ pinctrl-single,pins = < ++ 0x150 0x21 /* spi0_sclk.uart2_rxd | MODE1 */ ++ 0x154 0x01 /* spi0_d0.uart2_txd | MODE1 */ ++ >; ++ }; ++ ++ uart4_pins: pinmux_uart4_pins { ++ pinctrl-single,pins = < ++ 0x070 0x26 /* gpmc_wait0.uart4_rxd | MODE6 */ ++ 0x074 0x06 /* gpmc_wpn.uart4_txd | MODE6 */ ++ >; ++ }; ++ ++ uart5_pins: pinmux_uart5_pins { ++ pinctrl-single,pins = < ++ 0x0C4 0x24 /* lcd_data9.uart5_rxd | MODE4 */ ++ 0x0C0 0x04 /* lcd_data8.uart5_txd | MODE4 */ ++ >; ++ }; ++ + clkout2_pin: pinmux_clkout2_pin { + pinctrl-single,pins = < + 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */ +-- +1.9.0 + +From 72567452d5d6007010597158f6afd00e2bf07579 Mon Sep 17 00:00:00 2001 +From: Pantelis Antoniou <panto@antoniou-consulting.com> +Date: Sat, 15 Sep 2012 12:00:41 +0300 +Subject: [PATCH] pinctrl: pinctrl-single must be initialized early. + +When using pinctrl-single to handle i2c initialization, it has +to be done early. Whether this is the best way to do so, is an +exercise left to the reader. +--- + drivers/pinctrl/pinctrl-single.c | 12 +++++++++++- + 1 file changed, 11 insertions(+), 1 deletion(-) + +diff --git a/drivers/pinctrl/pinctrl-single.c b/drivers/pinctrl/pinctrl-single.c +index 829b98c..5107dcf 100644 +--- a/drivers/pinctrl/pinctrl-single.c ++++ b/drivers/pinctrl/pinctrl-single.c +@@ -2039,7 +2039,17 @@ static struct platform_driver pcs_driver = { + #endif + }; + +-module_platform_driver(pcs_driver); ++static int __init pcs_init(void) ++{ ++ return platform_driver_register(&pcs_driver); ++} ++postcore_initcall(pcs_init); ++ ++static void __exit pcs_exit(void) ++{ ++ platform_driver_unregister(&pcs_driver); ++} ++module_exit(pcs_exit); + + MODULE_AUTHOR("Tony Lindgren <tony@atomide.com>"); + MODULE_DESCRIPTION("One-register-per-pin type device tree based pinctrl driver"); +-- +1.8.5.2 + +From b6e2c817edfc6d73874cf833daffe1be6c7ed8bb Mon Sep 17 00:00:00 2001 +From: Robert Nelson <robertcnelson@gmail.com> +Date: Thu, 13 Mar 2014 14:18:52 -0500 +Subject: [PATCH] arm: dts: am335x-bone-common: add + uart2_pins/uart4_pins/uart5_pins + +Signed-off-by: Robert Nelson <robertcnelson@gmail.com> +--- + arch/arm/boot/dts/am335x-bone-common.dtsi | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/arch/arm/boot/dts/am335x-bone-common.dtsi b/arch/arm/boot/dts/am335x-bone-common.dtsi +index f85cabc..5270d18 100644 +--- a/arch/arm/boot/dts/am335x-bone-common.dtsi ++++ b/arch/arm/boot/dts/am335x-bone-common.dtsi +@@ -105,6 +105,27 @@ + >; + }; + ++ uart2_pins: pinmux_uart2_pins { ++ pinctrl-single,pins = < ++ 0x150 0x21 /* spi0_sclk.uart2_rxd | MODE1 */ ++ 0x154 0x01 /* spi0_d0.uart2_txd | MODE1 */ ++ >; ++ }; ++ ++ uart4_pins: pinmux_uart4_pins { ++ pinctrl-single,pins = < ++ 0x070 0x26 /* gpmc_wait0.uart4_rxd | MODE6 */ ++ 0x074 0x06 /* gpmc_wpn.uart4_txd | MODE6 */ ++ >; ++ }; ++ ++ uart5_pins: pinmux_uart5_pins { ++ pinctrl-single,pins = < ++ 0x0C4 0x24 /* lcd_data9.uart5_rxd | MODE4 */ ++ 0x0C0 0x04 /* lcd_data8.uart5_txd | MODE4 */ ++ >; ++ }; ++ + clkout2_pin: pinmux_clkout2_pin { + pinctrl-single,pins = < + 0x1b4 (PIN_OUTPUT_PULLDOWN | MUX_MODE3) /* xdma_event_intr1.clkout2 */ +-- +1.9.0 diff --git a/freed-ora/current/master/arm-imx6-utilite.patch b/freed-ora/current/master/arm-imx6-utilite.patch new file mode 100644 index 000000000..bb0747202 --- /dev/null +++ b/freed-ora/current/master/arm-imx6-utilite.patch @@ -0,0 +1,54 @@ +diff --git a/arch/arm/boot/dts/imx6q-cm-fx6.dts b/arch/arm/boot/dts/imx6q-cm-fx6.dts +index 99b46f8..8b6ddd1 100644 +--- a/arch/arm/boot/dts/imx6q-cm-fx6.dts ++++ b/arch/arm/boot/dts/imx6q-cm-fx6.dts +@@ -97,11 +97,49 @@ + MX6QDL_PAD_KEY_ROW0__UART4_RX_DATA 0x1b0b1 + >; + }; ++ ++ pinctrl_usdhc1: usdhc1grp { ++ fsl,pins = < ++ MX6QDL_PAD_SD1_CMD__SD1_CMD 0x17059 ++ MX6QDL_PAD_SD1_CLK__SD1_CLK 0x10059 ++ MX6QDL_PAD_SD1_DAT0__SD1_DATA0 0x17059 ++ MX6QDL_PAD_SD1_DAT1__SD1_DATA1 0x17059 ++ MX6QDL_PAD_SD1_DAT2__SD1_DATA2 0x17059 ++ MX6QDL_PAD_SD1_DAT3__SD1_DATA3 0x17059 ++ >; ++ }; ++ ++ pinctrl_usdhc3: usdhc3grp { ++ fsl,pins = < ++ MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17059 ++ MX6QDL_PAD_SD3_CLK__SD3_CLK 0x10059 ++ MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17059 ++ MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17059 ++ MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17059 ++ MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17059 ++ >; ++ }; + }; + }; + ++&sata { ++ status = "okay"; ++}; ++ + &uart4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; + status = "okay"; + }; ++ ++&usdhc1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_usdhc1>; ++ status = "okay"; ++}; ++ ++&usdhc3 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pinctrl_usdhc3>; ++ status = "okay"; ++}; diff --git a/freed-ora/current/master/arm-tegra-drmdetection.patch b/freed-ora/current/master/arm-tegra-drmdetection.patch new file mode 100644 index 000000000..d84040513 --- /dev/null +++ b/freed-ora/current/master/arm-tegra-drmdetection.patch @@ -0,0 +1,111 @@ +From: Stephen Warren <swarren@xxxxxxxxxx> + +When tegra-drm.ko is built as a module, these MODULE_DEVICE_TABLEs allow +the module to be auto-loaded since the module will match the devices +instantiated from device tree. + +(Notes for stable: in 3.14+, just git rm any conflicting file, since they +are added in later kernels. For 3.13 and below, manual merging will be +needed) + +Cc: <stable@xxxxxxxxxxxxxxx> +Signed-off-by: Stephen Warren <swarren@xxxxxxxxxx> +--- +v2: Remove change to drm.c, since the match table there isn't used for +probing. +--- + drivers/gpu/drm/tegra/dc.c | 1 + + drivers/gpu/drm/tegra/dpaux.c | 1 + + drivers/gpu/drm/tegra/dsi.c | 1 + + drivers/gpu/drm/tegra/gr2d.c | 1 + + drivers/gpu/drm/tegra/gr3d.c | 1 + + drivers/gpu/drm/tegra/hdmi.c | 1 + + drivers/gpu/drm/tegra/sor.c | 1 + + 7 files changed, 7 insertions(+) + +diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c +index ef40381f3909..48c3bc460eef 100644 +--- a/drivers/gpu/drm/tegra/dc.c ++++ b/drivers/gpu/drm/tegra/dc.c +@@ -1303,6 +1303,7 @@ static const struct of_device_id tegra_dc_of_match[] = { + /* sentinel */ + } + }; ++MODULE_DEVICE_TABLE(of, tegra_dc_of_match); + + static int tegra_dc_parse_dt(struct tegra_dc *dc) + { +diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c +index 3f132e356e9c..708f783ead47 100644 +--- a/drivers/gpu/drm/tegra/dpaux.c ++++ b/drivers/gpu/drm/tegra/dpaux.c +@@ -382,6 +382,7 @@ static const struct of_device_id tegra_dpaux_of_match[] = { + { .compatible = "nvidia,tegra124-dpaux", }, + { }, + }; ++MODULE_DEVICE_TABLE(of, tegra_dpaux_of_match); + + struct platform_driver tegra_dpaux_driver = { + .driver = { +diff --git a/drivers/gpu/drm/tegra/dsi.c b/drivers/gpu/drm/tegra/dsi.c +index bd56f2affa78..97c409f10456 100644 +--- a/drivers/gpu/drm/tegra/dsi.c ++++ b/drivers/gpu/drm/tegra/dsi.c +@@ -982,6 +982,7 @@ static const struct of_device_id tegra_dsi_of_match[] = { + { .compatible = "nvidia,tegra114-dsi", }, + { }, + }; ++MODULE_DEVICE_TABLE(of, tegra_dsi_of_match); + + struct platform_driver tegra_dsi_driver = { + .driver = { +diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c +index 7c53941f2a9e..02cd3e37a6ec 100644 +--- a/drivers/gpu/drm/tegra/gr2d.c ++++ b/drivers/gpu/drm/tegra/gr2d.c +@@ -121,6 +121,7 @@ static const struct of_device_id gr2d_match[] = { + { .compatible = "nvidia,tegra20-gr2d" }, + { }, + }; ++MODULE_DEVICE_TABLE(of, gr2d_match); + + static const u32 gr2d_addr_regs[] = { + GR2D_UA_BASE_ADDR, +diff --git a/drivers/gpu/drm/tegra/gr3d.c b/drivers/gpu/drm/tegra/gr3d.c +index 30f5ba9bd6d0..2bea2b2d204e 100644 +--- a/drivers/gpu/drm/tegra/gr3d.c ++++ b/drivers/gpu/drm/tegra/gr3d.c +@@ -130,6 +130,7 @@ static const struct of_device_id tegra_gr3d_match[] = { + { .compatible = "nvidia,tegra20-gr3d" }, + { } + }; ++MODULE_DEVICE_TABLE(of, tegra_gr3d_match); + + static const u32 gr3d_addr_regs[] = { + GR3D_IDX_ATTRIBUTE( 0), +diff --git a/drivers/gpu/drm/tegra/hdmi.c b/drivers/gpu/drm/tegra/hdmi.c +index a0b8d8539d07..84ea0c8b47f7 100644 +--- a/drivers/gpu/drm/tegra/hdmi.c ++++ b/drivers/gpu/drm/tegra/hdmi.c +@@ -1370,6 +1370,7 @@ static const struct of_device_id tegra_hdmi_of_match[] = { + { .compatible = "nvidia,tegra20-hdmi", .data = &tegra20_hdmi_config }, + { }, + }; ++MODULE_DEVICE_TABLE(of, tegra_hdmi_of_match); + + static int tegra_hdmi_probe(struct platform_device *pdev) + { +diff --git a/drivers/gpu/drm/tegra/sor.c b/drivers/gpu/drm/tegra/sor.c +index 27c979b50111..061a5c501124 100644 +--- a/drivers/gpu/drm/tegra/sor.c ++++ b/drivers/gpu/drm/tegra/sor.c +@@ -1455,6 +1455,7 @@ static const struct of_device_id tegra_sor_of_match[] = { + { .compatible = "nvidia,tegra124-sor", }, + { }, + }; ++MODULE_DEVICE_TABLE(of, tegra_sor_of_match); + + struct platform_driver tegra_sor_driver = { + .driver = { +-- +1.8.1.5 diff --git a/freed-ora/current/master/auditsc-audit_krule-mask-accesses-need-bounds-checking.patch b/freed-ora/current/master/auditsc-audit_krule-mask-accesses-need-bounds-checking.patch deleted file mode 100644 index 1a7763767..000000000 --- a/freed-ora/current/master/auditsc-audit_krule-mask-accesses-need-bounds-checking.patch +++ /dev/null @@ -1,128 +0,0 @@ -Bugzilla: 1102715 -Upstream-status: Submitted for 3.15 and CC'd to stable -Delivered-To: jwboyer@gmail.com -Received: by 10.76.6.212 with SMTP id d20csp285523oaa; - Wed, 28 May 2014 20:10:58 -0700 (PDT) -X-Received: by 10.66.250.166 with SMTP id zd6mr4872927pac.7.1401333057574; - Wed, 28 May 2014 20:10:57 -0700 (PDT) -Return-Path: <stable-owner@vger.kernel.org> -Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) - by mx.google.com with ESMTP id j1si26042371pbw.214.2014.05.28.20.10.31 - for <multiple recipients>; - Wed, 28 May 2014 20:10:57 -0700 (PDT) -Received-SPF: none (google.com: stable-owner@vger.kernel.org does not designate permitted sender hosts) client-ip=209.132.180.67; -Authentication-Results: mx.google.com; - spf=neutral (google.com: stable-owner@vger.kernel.org does not designate permitted sender hosts) smtp.mail=stable-owner@vger.kernel.org -Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand - id S1755059AbaE2DKa (ORCPT <rfc822;takashi.bg@gmail.com> - + 73 others); Wed, 28 May 2014 23:10:30 -0400 -Received: from mx1.redhat.com ([209.132.183.28]:34907 "EHLO mx1.redhat.com" - rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP - id S1753861AbaE2DK3 (ORCPT <rfc822;stable@vger.kernel.org>); - Wed, 28 May 2014 23:10:29 -0400 -Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) - by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id s4T3AQfK017267 - (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); - Wed, 28 May 2014 23:10:26 -0400 -Received: from paris.rdu.redhat.com (paris.rdu.redhat.com [10.13.136.28]) - by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id s4T3APd7019240; - Wed, 28 May 2014 23:10:26 -0400 -From: Eric Paris <eparis@redhat.com> -To: torvalds@linux-foundation.org -Cc: linux-audit@redhat.com, linux-kernel@vger.kernel.org, - Andy Lutomirski <luto@amacapital.net>, stable@vger.kernel.org, - Eric Paris <eparis@redhat.com> -Subject: [PATCH 1/2] auditsc: audit_krule mask accesses need bounds checking -Date: Wed, 28 May 2014 23:09:58 -0400 -Message-Id: <1401332999-15167-1-git-send-email-eparis@redhat.com> -X-Scanned-By: MIMEDefang 2.68 on 10.5.11.26 -Sender: stable-owner@vger.kernel.org -Precedence: bulk -List-ID: <stable.vger.kernel.org> -X-Mailing-List: stable@vger.kernel.org - -From: Andy Lutomirski <luto@amacapital.net> - -Fixes an easy DoS and possible information disclosure. - -This does nothing about the broken state of x32 auditing. - -eparis: If the admin has enabled auditd and has specifically loaded audit -rules. This bug has been around since before git. Wow... - -Cc: stable@vger.kernel.org -Signed-off-by: Andy Lutomirski <luto@amacapital.net> -Signed-off-by: Eric Paris <eparis@redhat.com> ---- - kernel/auditsc.c | 27 ++++++++++++++++++--------- - 1 file changed, 18 insertions(+), 9 deletions(-) - -diff --git a/kernel/auditsc.c b/kernel/auditsc.c -index 254ce20..842f58a 100644 ---- a/kernel/auditsc.c -+++ b/kernel/auditsc.c -@@ -728,6 +728,22 @@ static enum audit_state audit_filter_task(struct task_struct *tsk, char **key) - return AUDIT_BUILD_CONTEXT; - } - -+static int audit_in_mask(const struct audit_krule *rule, unsigned long val) -+{ -+ int word, bit; -+ -+ if (val > 0xffffffff) -+ return false; -+ -+ word = AUDIT_WORD(val); -+ if (word >= AUDIT_BITMASK_SIZE) -+ return false; -+ -+ bit = AUDIT_BIT(val); -+ -+ return rule->mask[word] & bit; -+} -+ - /* At syscall entry and exit time, this filter is called if the - * audit_state is not low enough that auditing cannot take place, but is - * also not high enough that we already know we have to write an audit -@@ -745,11 +761,8 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, - - rcu_read_lock(); - if (!list_empty(list)) { -- int word = AUDIT_WORD(ctx->major); -- int bit = AUDIT_BIT(ctx->major); -- - list_for_each_entry_rcu(e, list, list) { -- if ((e->rule.mask[word] & bit) == bit && -+ if (audit_in_mask(&e->rule, ctx->major) && - audit_filter_rules(tsk, &e->rule, ctx, NULL, - &state, false)) { - rcu_read_unlock(); -@@ -769,20 +782,16 @@ static enum audit_state audit_filter_syscall(struct task_struct *tsk, - static int audit_filter_inode_name(struct task_struct *tsk, - struct audit_names *n, - struct audit_context *ctx) { -- int word, bit; - int h = audit_hash_ino((u32)n->ino); - struct list_head *list = &audit_inode_hash[h]; - struct audit_entry *e; - enum audit_state state; - -- word = AUDIT_WORD(ctx->major); -- bit = AUDIT_BIT(ctx->major); -- - if (list_empty(list)) - return 0; - - list_for_each_entry_rcu(e, list, list) { -- if ((e->rule.mask[word] & bit) == bit && -+ if (audit_in_mask(&e->rule, ctx->major) && - audit_filter_rules(tsk, &e->rule, ctx, n, &state, false)) { - ctx->current_state = state; - return 1; --- -1.9.0 - --- -To unsubscribe from this list: send the line "unsubscribe stable" in -the body of a message to majordomo@vger.kernel.org -More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/freed-ora/current/master/backlight-Add-backlight-device-un-registration-notif.patch b/freed-ora/current/master/backlight-Add-backlight-device-un-registration-notif.patch deleted file mode 100644 index a411bb9cb..000000000 --- a/freed-ora/current/master/backlight-Add-backlight-device-un-registration-notif.patch +++ /dev/null @@ -1,132 +0,0 @@ -Bugzilla: 1093171 -Upstream-status: Queued for 3.16 - -From ee515e61a002b4d571407173ac8bbadadc114cf0 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 2 Jun 2014 17:41:08 +0200 -Subject: [PATCH 11/14] backlight: Add backlight device (un)registration - notification - -Some firmware drivers, ie acpi-video want to get themselves out of the -way (in some cases) when their also is a raw backlight device available. - -Due to module loading ordering being unknown, acpi-video cannot be certain -that the backlight_device_registered(BACKLIGHT_RAW) it does for this is -the final verdict wrt there being a BACKLIGHT_RAW device. - -By adding notification acpi-video can listen for backlight devices showing -up after it has loaded, and unregister its backlight device if desired. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - drivers/video/backlight/backlight.c | 40 +++++++++++++++++++++++++++++++++++++ - include/linux/backlight.h | 7 +++++++ - 2 files changed, 47 insertions(+) - -diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c -index bd2172c2d650..428089009cd5 100644 ---- a/drivers/video/backlight/backlight.c -+++ b/drivers/video/backlight/backlight.c -@@ -23,6 +23,7 @@ - - static struct list_head backlight_dev_list; - static struct mutex backlight_dev_list_mutex; -+static struct blocking_notifier_head backlight_notifier; - - static const char *const backlight_types[] = { - [BACKLIGHT_RAW] = "raw", -@@ -370,6 +371,9 @@ struct backlight_device *backlight_device_register(const char *name, - list_add(&new_bd->entry, &backlight_dev_list); - mutex_unlock(&backlight_dev_list_mutex); - -+ blocking_notifier_call_chain(&backlight_notifier, -+ BACKLIGHT_REGISTERED, new_bd); -+ - return new_bd; - } - EXPORT_SYMBOL(backlight_device_register); -@@ -413,6 +417,10 @@ void backlight_device_unregister(struct backlight_device *bd) - pmac_backlight = NULL; - mutex_unlock(&pmac_backlight_mutex); - #endif -+ -+ blocking_notifier_call_chain(&backlight_notifier, -+ BACKLIGHT_UNREGISTERED, bd); -+ - mutex_lock(&bd->ops_lock); - bd->ops = NULL; - mutex_unlock(&bd->ops_lock); -@@ -438,6 +446,36 @@ static int devm_backlight_device_match(struct device *dev, void *res, - } - - /** -+ * backlight_register_notifier - get notified of backlight (un)registration -+ * @nb: notifier block with the notifier to call on backlight (un)registration -+ * -+ * @return 0 on success, otherwise a negative error code -+ * -+ * Register a notifier to get notified when backlight devices get registered -+ * or unregistered. -+ */ -+int backlight_register_notifier(struct notifier_block *nb) -+{ -+ return blocking_notifier_chain_register(&backlight_notifier, nb); -+} -+EXPORT_SYMBOL(backlight_register_notifier); -+ -+/** -+ * backlight_unregister_notifier - unregister a backlight notifier -+ * @nb: notifier block to unregister -+ * -+ * @return 0 on success, otherwise a negative error code -+ * -+ * Register a notifier to get notified when backlight devices get registered -+ * or unregistered. -+ */ -+int backlight_unregister_notifier(struct notifier_block *nb) -+{ -+ return blocking_notifier_chain_unregister(&backlight_notifier, nb); -+} -+EXPORT_SYMBOL(backlight_unregister_notifier); -+ -+/** - * devm_backlight_device_register - resource managed backlight_device_register() - * @dev: the device to register - * @name: the name of the device -@@ -544,6 +582,8 @@ static int __init backlight_class_init(void) - backlight_class->pm = &backlight_class_dev_pm_ops; - INIT_LIST_HEAD(&backlight_dev_list); - mutex_init(&backlight_dev_list_mutex); -+ BLOCKING_INIT_NOTIFIER_HEAD(&backlight_notifier); -+ - return 0; - } - -diff --git a/include/linux/backlight.h b/include/linux/backlight.h -index 72647429adf6..adb14a8616df 100644 ---- a/include/linux/backlight.h -+++ b/include/linux/backlight.h -@@ -40,6 +40,11 @@ enum backlight_type { - BACKLIGHT_TYPE_MAX, - }; - -+enum backlight_notification { -+ BACKLIGHT_REGISTERED, -+ BACKLIGHT_UNREGISTERED, -+}; -+ - struct backlight_device; - struct fb_info; - -@@ -133,6 +138,8 @@ extern void devm_backlight_device_unregister(struct device *dev, - extern void backlight_force_update(struct backlight_device *bd, - enum backlight_update_reason reason); - extern bool backlight_device_registered(enum backlight_type type); -+extern int backlight_register_notifier(struct notifier_block *nb); -+extern int backlight_unregister_notifier(struct notifier_block *nb); - - #define to_backlight_device(obj) container_of(obj, struct backlight_device, dev) - --- -1.9.0 - diff --git a/freed-ora/current/master/config-arm-generic b/freed-ora/current/master/config-arm-generic index c1bc6534b..0c5242c69 100644 --- a/freed-ora/current/master/config-arm-generic +++ b/freed-ora/current/master/config-arm-generic @@ -2,6 +2,7 @@ CONFIG_KUSER_HELPERS=y # CONFIG_ASYMMETRIC_KEY_TYPE is not set CONFIG_COMMON_CLK=y CONFIG_EARLY_PRINTK=y +CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST=y CONFIG_FB_SSD1307=m CONFIG_HW_PERF_EVENTS=y CONFIG_NFS_FS=y @@ -29,7 +30,6 @@ CONFIG_INPUT_PWM_BEEPER=m CONFIG_ARM_SP805_WATCHDOG=m CONFIG_ARM_ARCH_TIMER=y CONFIG_ARM_ARCH_TIMER_EVTSTREAM=y -# CONFIG_ARM_DT_BL_CPUFREQ is not set CONFIG_NR_CPUS=8 CONFIG_SWIOTLB=y @@ -43,6 +43,7 @@ CONFIG_HAVE_PERF_USER_STACK_DUMP=y CONFIG_ARM_AMBA=y CONFIG_ARM_CCI=y CONFIG_ARM_DMA_USE_IOMMU=y +CONFIG_ARM_DMA_IOMMU_ALIGNMENT=8 CONFIG_ARM_GIC=y CONFIG_ARM_GLOBAL_TIMER=y CONFIG_ARM_SMMU=y @@ -55,12 +56,22 @@ CONFIG_FB_ARMCLCD=y # ARM VExpress CONFIG_ARCH_VEXPRESS=y -CONFIG_VEXPRESS_CONFIG=y +CONFIG_MFD_VEXPRESS_SYSREG=y +CONFIG_VEXPRESS_SYSCFG=y CONFIG_COMMON_CLK_VERSATILE=y +CONFIG_CLK_SP810=y +CONFIG_CLK_VEXPRESS_OSC=y CONFIG_I2C_VERSATILE=m CONFIG_POWER_RESET_VEXPRESS=y CONFIG_REGULATOR_VEXPRESS=m CONFIG_SENSORS_VEXPRESS=m +CONFIG_CLKSRC_VERSATILE=y +# CONFIG_ARM_CHARLCD is not set + +# Power/Thermal/Cpufreq +CONFIG_GENERIC_CPUFREQ_CPU0=m +# CONFIG_ARM_DT_BL_CPUFREQ is not set +# CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set # Device tree CONFIG_DTC=y @@ -106,6 +117,7 @@ CONFIG_MTD_OF_PARTS=m CONFIG_MTD_PHYSMAP=m CONFIG_MTD_PHYSMAP_OF=m # CONFIG_MTD_PHYSMAP_COMPAT is not set +# CONFIG_MTD_LPDDR2_NVM is not set # GPIO CONFIG_GPIO_DEVRES=y @@ -181,6 +193,7 @@ CONFIG_CMA_AREAS=7 # CONFIG_ARM_PTDUMP is not set # CONFIG_PATA_PLATFORM is not set +# CONFIG_USB_ULPI is not set ### turn off things which make no sense on embedded SoC @@ -237,5 +250,6 @@ CONFIG_CMA_AREAS=7 # drm # CONFIG_DRM_VMWGFX is not set +# CONFIG_IMX_IPUV3_CORE is not set # CONFIG_DEBUG_SET_MODULE_RONX is not set diff --git a/freed-ora/current/master/config-arm64 b/freed-ora/current/master/config-arm64 index ddd5bc4b9..082ceda8d 100644 --- a/freed-ora/current/master/config-arm64 +++ b/freed-ora/current/master/config-arm64 @@ -67,13 +67,37 @@ CONFIG_SPARSEMEM_VMEMMAP=y CONFIG_VIRTUALIZATION=y CONFIG_VM_EVENT_COUNTERS=y +CONFIG_EFI=y +CONFIG_EFI_VARS=y +CONFIG_EFIVAR_FS=y +CONFIG_EFI_VARS_PSTORE=y +CONFIG_EFI_VARS_PSTORE_DEFAULT_DISABLE=y + +CONFIG_ARM64_CRYPTO=y +CONFIG_CRYPTO_SHA1_ARM64_CE=m +CONFIG_CRYPTO_SHA2_ARM64_CE=m +CONFIG_CRYPTO_GHASH_ARM64_CE=m +CONFIG_CRYPTO_AES_ARM64_CE=m +CONFIG_CRYPTO_AES_ARM64_CE_CCM=m +CONFIG_CRYPTO_AES_ARM64_CE_BLK=m +CONFIG_CRYPTO_AES_ARM64_NEON_BLK=m + +# APM Xgene +CONFIG_POWER_RESET_XGENE=y +CONFIG_COMMON_CLK_XGENE=y + +CONFIG_AHCI_XGENE=y +CONFIG_PHY_XGENE=y +CONFIG_NET_XGENE=y +CONFIG_RTC_DRV_XGENE=m +CONFIG_RTC_DRV_EFI=y + # not arm64 # CONFIG_GPIO_ADNP is not set # CONFIG_GPIO_MCP23S08 is not set # CONFIG_MDIO_BUS_MUX_GPIO is not set # CONFIG_MDIO_BUS_MUX_MMIOREG is not set - # busted build for various reasons # uses pci_* for some reason to allocate DMA buffers # CONFIG_DVB_B2C2_FLEXCOP_USB is not set @@ -82,8 +106,8 @@ CONFIG_VM_EVENT_COUNTERS=y # dma issues in headers # CONFIG_PARPORT_PC is not set # CONFIG_VGA_CONSOLE is not set -CONFIG_POWER_RESET_XGENE=y -CONFIG_COMMON_CLK_XGENE=y -CONFIG_AHCI_XGENE=m -CONFIG_PHY_XGENE=m +CONFIG_PCI_XGENE=y +CONFIG_HOTPLUG_PCI=y +# CONFIG_HOTPLUG_PCI_CPCI is not set +# CONFIG_HOTPLUG_PCI_SHPC is not set diff --git a/freed-ora/current/master/config-armv7 b/freed-ora/current/master/config-armv7 index 4aaa913a6..03f43354f 100644 --- a/freed-ora/current/master/config-armv7 +++ b/freed-ora/current/master/config-armv7 @@ -8,6 +8,7 @@ CONFIG_ARCH_MXC=y CONFIG_ARCH_OMAP3=y CONFIG_ARCH_OMAP4=y CONFIG_ARCH_PICOXCELL=y +CONFIG_ARCH_QCOM=y CONFIG_ARCH_ROCKCHIP=y # CONFIG_ARCH_SOCFPGA is not set CONFIG_ARCH_TEGRA=y @@ -24,9 +25,9 @@ CONFIG_ARCH_ZYNQ=y # mvebu CONFIG_MACH_ARMADA_370_XP=y CONFIG_MACH_ARMADA_370=y +CONFIG_MACH_ARMADA_375=y +CONFIG_MACH_ARMADA_38X=y CONFIG_MACH_ARMADA_XP=y -# CONFIG_MACH_ARMADA_375 is not set -# CONFIG_MACH_ARMADA_38X is not set CONFIG_MACH_DOVE=y CONFIG_MVEBU_DEVBUS=y @@ -38,10 +39,12 @@ CONFIG_MV643XX_ETH=m CONFIG_PINCTRL_MVEBU=y CONFIG_PINCTRL_ARMADA_370=y CONFIG_PINCTRL_ARMADA_XP=y +# CONFIG_ARM_ARMADA_370_XP_CPUIDLE is not set CONFIG_PINCTRL_DOVE=y CONFIG_EDAC_MV64X60=m CONFIG_RTC_DRV_S35390A=m CONFIG_RTC_DRV_88PM80X=m +CONFIG_RTC_DRV_ISL12057=m CONFIG_RTC_DRV_MV=m CONFIG_MVNETA=m CONFIG_GPIO_MVEBU=y @@ -53,7 +56,9 @@ CONFIG_MMC_SDHCI_DOVE=m CONFIG_SPI_ORION=m CONFIG_USB_MV_UDC=m CONFIG_MVEBU_MBUS=y +CONFIG_USB_XHCI_MVEBU=m CONFIG_PHY_MVEBU_SATA=y +CONFIG_AHCI_MVEBU=m CONFIG_ARMADA_THERMAL=m CONFIG_DOVE_THERMAL=m CONFIG_DRM_ARMADA=m @@ -61,6 +66,7 @@ CONFIG_ORION_WATCHDOG=m CONFIG_SND_KIRKWOOD_SOC=m CONFIG_SND_KIRKWOOD_SOC_ARMADA370_DB=m CONFIG_USB_EHCI_HCD_ORION=m +CONFIG_MMC_SDHCI_PXAV3=m # CONFIG_CACHE_FEROCEON_L2 is not set # CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH is not set @@ -165,6 +171,8 @@ CONFIG_PINCTRL_PALMAS=y CONFIG_REGULATOR_PALMAS=y CONFIG_REGULATOR_PBIAS=m CONFIG_RTC_DRV_PALMAS=m +CONFIG_OMAP5_DSS_HDMI=y +CONFIG_OMAP5_DSS_HDMI_AUDIO=y CONFIG_WL_TI=y CONFIG_WLCORE_SDIO=m @@ -179,7 +187,6 @@ CONFIG_MTD_NAND_OMAP2=m CONFIG_MTD_NAND_OMAP_BCH=y CONFIG_SPI_OMAP24XX=m CONFIG_MFD_TI_SSP=m -CONFIG_SPI_TI_SSP=m CONFIG_SPI_TI_QSPI=m CONFIG_INPUT_TWL4030_PWRBUTTON=m @@ -309,7 +316,7 @@ CONFIG_OMAP_REMOTEPROC=m # CONFIG_OMAP_MUX_DEBUG is not set # CONFIG_VIDEO_OMAP3_DEBUG is not set -# AM33xx +# AM33xx/43xx CONFIG_SOC_AM33XX=y CONFIG_SOC_AM43XX=y CONFIG_AM335X_CONTROL_USB=m @@ -341,8 +348,31 @@ CONFIG_REGULATOR_TI_ABB=m CONFIG_TI_ADC081C=m CONFIG_TI_AM335X_ADC=m CONFIG_PWM_TIPWMSS=y -# CONFIG_GPIO_DAVINCI is not set -# CONFIG_DAVINCI_WATCHDOG is not set +CONFIG_MFD_TPS65218=m +CONFIG_REGULATOR_TPS65218=m + +# QCom +CONFIG_ARCH_MSM8X60=y +CONFIG_ARCH_MSM8960=y +CONFIG_ARCH_MSM8974=y +CONFIG_SERIAL_MSM=y +CONFIG_SERIAL_MSM_CONSOLE=y +CONFIG_PINCTRL_APQ8064=m +CONFIG_PINCTRL_IPQ8064=m +CONFIG_HW_RANDOM_MSM=m +CONFIG_I2C_QUP=m +CONFIG_SPI_QUP=m +CONFIG_GPIO_MSM_V2=m +CONFIG_POWER_RESET_MSM=y +CONFIG_USB_MSM_OTG=m +CONFIG_MMC_SDHCI_MSM=m +CONFIG_QCOM_BAM_DMA=m +CONFIG_QCOM_GSBI=m +CONFIG_MSM_IOMMU=y +CONFIG_DRM_MSM=m +CONFIG_DRM_MSM_FBDEV=y +CONFIG_USB_EHCI_MSM=m +# CONFIG_DRM_MSM_REGISTER_LOGGING is not set # i.MX CONFIG_MXC_IRQ_PRIOR=y @@ -351,10 +381,10 @@ CONFIG_SOC_IMX50=y CONFIG_SOC_IMX53=y CONFIG_SOC_IMX6Q=y CONFIG_SOC_IMX6SL=y +CONFIG_SOC_IMX6SX=y # CONFIG_SOC_VF610 is not set CONFIG_MACH_IMX51_DT=y # CONFIG_MACH_MX51_BABBAGE is not set -# CONFIG_MACH_EUKREA_CPUIMX51SD is not set CONFIG_ARM_IMX6Q_CPUFREQ=m CONFIG_IMX_THERMAL=m CONFIG_PATA_IMX=m @@ -390,6 +420,8 @@ CONFIG_RTC_DRV_SNVS=m # CONFIG_FB_IMX is not set CONFIG_SND_IMX_SOC=m +CONFIG_SND_SOC_FSL_ESAI=m +CONFIG_SND_SOC_FSL_SAI=m CONFIG_SND_SOC_FSL_SPDIF=m CONFIG_SND_SOC_FSL_SSI=m CONFIG_SND_SOC_FSL_UTILS=m @@ -402,6 +434,7 @@ CONFIG_SND_SOC_IMX_WM8962=m CONFIG_SND_SOC_IMX_MC13783=m CONFIG_SND_SOC_IMX_SPDIF=m CONFIG_SND_SOC_EUKREA_TLV320=m +CONFIG_SND_SOC_TVL320AIC32X4=m CONFIG_USB_IMX21_HCD=m CONFIG_USB_MXS_PHY=m @@ -421,7 +454,7 @@ CONFIG_PWM_IMX=m CONFIG_DRM_IMX=m CONFIG_DRM_IMX_FB_HELPER=m CONFIG_DRM_IMX_HDMI=m -CONFIG_DRM_IMX_IPUV3_CORE=m +CONFIG_IMX_IPUV3_CORE=m CONFIG_DRM_IMX_IPUV3=m CONFIG_DRM_IMX_LDB=m CONFIG_DRM_IMX_PARALLEL_DISPLAY=m @@ -464,15 +497,18 @@ CONFIG_REGULATOR_DA9052=m CONFIG_REGULATOR_DA9055=m # picoxcell -CONFIG_CRYPTO_DEV_PICOXCELL=m -CONFIG_HW_RANDOM_PICOXCELL=m +# CONFIG_CRYPTO_DEV_PICOXCELL is not set +# CONFIG_HW_RANDOM_PICOXCELL is not set + +# Rockchips +CONFIG_I2C_RK3X=m # ST Ericsson CONFIG_MACH_HREFV60=y CONFIG_MACH_SNOWBALL=y CONFIG_ABX500_CORE=y -CONFIG_ARM_U8500_CPUIDLE=y +# CONFIG_ARM_U8500_CPUIDLE is not set CONFIG_UX500_DEBUG_UART=2 CONFIG_AB8500_CORE=y CONFIG_STE_DMA40=y @@ -534,7 +570,6 @@ CONFIG_TEGRA_IOMMU_SMMU=y CONFIG_MMC_SDHCI_TEGRA=m CONFIG_TEGRA_WATCHDOG=m CONFIG_I2C_TEGRA=m - CONFIG_TEGRA_SYSTEM_DMA=y CONFIG_TEGRA_EMC_SCALING_ENABLE=y CONFIG_TEGRA_AHB=y @@ -542,7 +577,7 @@ CONFIG_TEGRA20_APB_DMA=y CONFIG_SPI_TEGRA114=m CONFIG_SPI_TEGRA20_SFLASH=m CONFIG_SPI_TEGRA20_SLINK=m - +CONFIG_PWM_TEGRA=m CONFIG_MFD_MAX8907=m CONFIG_KEYBOARD_TEGRA=m CONFIG_PINCTRL_TEGRA=y @@ -550,6 +585,7 @@ CONFIG_PINCTRL_TEGRA20=y CONFIG_PINCTRL_TEGRA30=y CONFIG_USB_EHCI_TEGRA=m CONFIG_RTC_DRV_TEGRA=m +CONFIG_CRYPTO_DEV_TEGRA_AES=m CONFIG_SND_SOC_TEGRA=m CONFIG_SND_SOC_TEGRA_ALC5632=m @@ -564,6 +600,7 @@ CONFIG_SND_SOC_TEGRA20_DAS=m CONFIG_SND_SOC_TEGRA20_SPDIF=m CONFIG_SND_SOC_TEGRA30_AHUB=m CONFIG_SND_SOC_TEGRA30_I2S=m +CONFIG_SND_HDA_TEGRA=m # AC100 (PAZ00) CONFIG_MFD_NVEC=y @@ -571,14 +608,18 @@ CONFIG_MFD_TPS80031=y CONFIG_KEYBOARD_NVEC=y CONFIG_SERIO_NVEC_PS2=y CONFIG_NVEC_POWER=y -CONFIG_POWER_SUPPLY=y CONFIG_NVEC_LEDS=y CONFIG_NVEC_PAZ00=y CONFIG_MFD_TPS6586X=y CONFIG_GPIO_TPS6586X=y CONFIG_RTC_DRV_TPS6586X=m -CONFIG_PWM_TEGRA=m +# Jetson TK1 +CONFIG_PINCTRL_AS3722=y +CONFIG_POWER_RESET_AS3722=y +CONFIG_MFD_AS3722=y +CONFIG_REGULATOR_AS3722=m +CONFIG_RTC_DRV_AS3722=y CONFIG_TEGRA_HOST1X=m CONFIG_TEGRA_HOST1X_FIREWALL=y @@ -591,8 +632,6 @@ CONFIG_DRM_PANEL_SIMPLE=m CONFIG_DRM_PANEL_LD9040=m CONFIG_DRM_PANEL_S6E8AA0=m -CONFIG_CRYPTO_DEV_TEGRA_AES=m - # OLPC XO CONFIG_SERIO_OLPC_APSP=m @@ -610,13 +649,18 @@ CONFIG_XILINX_EMACLITE=m CONFIG_GPIO_XILINX=y CONFIG_I2C_XILINX=m CONFIG_SPI_XILINX=m +CONFIG_SPI_CADENCE=m CONFIG_MMC_SDHCI_OF_ARASAN=m CONFIG_I2C_CADENCE=m CONFIG_XILINX_WATCHDOG=m CONFIG_XILINX_XADC=m +CONFIG_XILINX_VDMA=m CONFIG_SND_SOC_ADI=m CONFIG_SND_SOC_ADI_AXI_I2S=m CONFIG_SND_SOC_ADI_AXI_SPDIF=m +CONFIG_XILLYBUS=m +CONFIG_XILLYBUS_PCIE=m +CONFIG_XILLYBUS_OF=m # Multi function devices CONFIG_MFD_88PM800=m @@ -642,42 +686,3 @@ CONFIG_REGULATOR_MAX8660=m CONFIG_REGULATOR_MAX8907=m CONFIG_REGULATOR_MAX8952=m CONFIG_REGULATOR_MAX8973=m - -# Needs work/investigation -# CONFIG_MTD_AFS_PARTS is not set -# CONFIG_IP_PNP_RARP is not set -# CONFIG_PID_IN_CONTEXTIDR is not set -# CONFIG_DEPRECATED_PARAM_STRUCT is not set - -# CONFIG_ARM_KPROBES_TEST is not set - -# Defined config options we don't use yet -# CONFIG_PINCTRL_IMX35 is not set - -# CONFIG_MFD_SMSC is not set -# CONFIG_MFD_SEC_CORE is not set -# CONFIG_MFD_LP8788 is not set -# CONFIG_MFD_MAX77686 is not set -# CONFIG_MFD_MAX77693 is not set -# CONFIG_MFD_MAX8997 is not set -# CONFIG_MFD_MAX14577 is not set -# CONFIG_MFD_AAT2870_CORE is not set -# CONFIG_MFD_RC5T583 is not set -# CONFIG_MFD_SMSC is not set -# CONFIG_MFD_AS3711 is not set -# CONFIG_PMIC_DA903X is not set -# CONFIG_PMIC_ADP5520 is not set - -# CONFIG_DVB_USB_PCTV452E is not set -# We need to fix these as they should be either generic includes or kconfig fixes -# drivers/input/touchscreen/eeti_ts.c:65:2: error: implicit declaration of function 'irq_to_gpio' [-Werror=implicit-function-declaration] -# CONFIG_TOUCHSCREEN_EETI is not set -# CONFIG_TOUCHSCREEN_EGALAX is not set -# CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set - -# CONFIG_POWER_RESET_QNAP is not set -# CONFIG_OMAP2_DSS_DEBUG is not set -# CONFIG_CRYPTO_DEV_UX500_DEBUG is not set -# CONFIG_AB8500_DEBUG is not set - -# CONFIG_MMC_TMIO is not set diff --git a/freed-ora/current/master/config-armv7-generic b/freed-ora/current/master/config-armv7-generic index 1b6bea7ad..058b9514b 100644 --- a/freed-ora/current/master/config-armv7-generic +++ b/freed-ora/current/master/config-armv7-generic @@ -51,22 +51,23 @@ CONFIG_IRQ_CROSSBAR=y # CONFIG_ARM_VIRT_EXT is not set # Platforms enabled/disabled globally on ARMv7 +CONFIG_ARCH_EXYNOS=y CONFIG_ARCH_HIGHBANK=y CONFIG_ARCH_SUNXI=y CONFIG_ARCH_VEXPRESS_CA9X4=y CONFIG_ARCH_VEXPRESS_CORTEX_A5_A9_ERRATA=y -# CONFIG_ARCH_VEXPRESS_SPC is not set # CONFIG_ARCH_BCM is not set -# CONFIG_PLAT_SPEAR is not set -# CONFIG_ARCH_STI is not set -# CONFIG_ARCH_SIRF is not set -# CONFIG_ARCH_U8500 is not set -# CONFIG_ARCH_WM8850 is not set -# CONFIG_ARCH_SHMOBILE_MULTI is not set # CONFIG_ARCH_BERLIN is not set # CONFIG_ARCH_HI3xxx is not set # CONFIG_ARCH_MSM_DT is not set # CONFIG_ARCH_QCOM is not set +# CONFIG_ARCH_SHMOBILE_MULTI is not set +# CONFIG_ARCH_SIRF is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_STI is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_VEXPRESS_SPC is not set +# CONFIG_ARCH_WM8850 is not set # errata # v5/v6 @@ -123,12 +124,7 @@ CONFIG_XZ_DEC_ARM=y CONFIG_UACCESS_WITH_MEMCPY=y CONFIG_CC_STACKPROTECTOR=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y - -# Root as NFS, different from mainline -CONFIG_ROOT_NFS=y +CONFIG_PCI_HOST_GENERIC=y CONFIG_LBDAF=y @@ -162,6 +158,10 @@ CONFIG_ARM_HIGHBANK_CPUFREQ=m # CONFIG_ARM_HIGHBANK_CPUIDLE is not set # Allwinner +CONFIG_MACH_SUN4I=y +CONFIG_MACH_SUN5I=y +CONFIG_MACH_SUN6I=y +CONFIG_MACH_SUN7I=y CONFIG_PINCTRL_SUNXI=y CONFIG_SUNXI_WATCHDOG=m CONFIG_MDIO_SUN4I=m @@ -177,8 +177,113 @@ CONFIG_AHCI_SUNXI=m CONFIG_SPI_SUN4I=m CONFIG_SPI_SUN6I=m CONFIG_MMC_SUNXI=m +CONFIG_I2C_SUN6I_P2WI=m CONFIG_GPIO_PCA953X=m - +CONFIG_POWER_RESET_SUN6I=y +CONFIG_TOUCHSCREEN_SUN4I=m +CONFIG_MFD_AXP20X=y +CONFIG_REGULATOR_AXP20X=m + +# Exynos +CONFIG_ARCH_EXYNOS3=y +CONFIG_ARCH_EXYNOS4=y +CONFIG_ARCH_EXYNOS5=y +CONFIG_SOC_EXYNOS3250=y +CONFIG_SOC_EXYNOS4212=y +CONFIG_SOC_EXYNOS4412=y +CONFIG_SOC_EXYNOS5250=y +CONFIG_SOC_EXYNOS5420=y +CONFIG_SOC_EXYNOS5440=y +CONFIG_SOC_EXYNOS5260=y +CONFIG_SOC_EXYNOS5410=y +CONFIG_SOC_EXYNOS5800=y +CONFIG_SERIAL_SAMSUNG=y +CONFIG_SERIAL_SAMSUNG_CONSOLE=y +CONFIG_ARM_EXYNOS4210_CPUFREQ=y +CONFIG_ARM_EXYNOS4X12_CPUFREQ=y +CONFIG_ARM_EXYNOS5250_CPUFREQ=y +CONFIG_ARM_EXYNOS5440_CPUFREQ=y +CONFIG_ARM_EXYNOS_CPU_FREQ_BOOST_SW=y +CONFIG_ARM_EXYNOS_CPUIDLE=y + +CONFIG_I2C_EXYNOS5=m +CONFIG_I2C_S3C2410=m +CONFIG_SPI_S3C64XX=m +CONFIG_EXYNOS_THERMAL=m +CONFIG_EXYNOS_THERMAL_CORE=y +CONFIG_MMC_SDHCI_S3C=m +CONFIG_MMC_SDHCI_S3C_DMA=y +CONFIG_MMC_DW_EXYNOS=m +CONFIG_EXYNOS_IOMMU=y +CONFIG_PCI_EXYNOS=y +CONFIG_PHY_EXYNOS5_USBDRD=m +CONFIG_USB_EHCI_EXYNOS=m +CONFIG_USB_OHCI_EXYNOS=m +CONFIG_USB_DWC3_EXYNOS=m +CONFIG_PHY_EXYNOS5250_SATA=m +CONFIG_HW_RANDOM_EXYNOS=m +CONFIG_CRYPTO_DEV_S5P=m +CONFIG_PWM_SAMSUNG=m +CONFIG_S3C2410_WATCHDOG=m +CONFIG_MFD_SEC_CORE=y +CONFIG_REGULATOR_S2MPS11=m +CONFIG_REGULATOR_S5M8767=m +CONFIG_TCG_TIS_I2C_INFINEON=m +CONFIG_RTC_DRV_S5M=m +# CONFIG_RTC_DRV_S3C is not set + +CONFIG_EXYNOS_VIDEO=y +CONFIG_EXYNOS_MIPI_DSI=y +CONFIG_DRM_EXYNOS=m +CONFIG_DRM_EXYNOS_DMABUF=y +CONFIG_DRM_EXYNOS_DP=y +CONFIG_DRM_EXYNOS_DPI=y +CONFIG_DRM_EXYNOS_DSI=y +CONFIG_DRM_EXYNOS_FIMC=y +CONFIG_DRM_EXYNOS_FIMD=y +CONFIG_DRM_EXYNOS_G2D=y +CONFIG_DRM_EXYNOS_GSC=y +CONFIG_DRM_EXYNOS_HDMI=y +CONFIG_DRM_EXYNOS_IOMMU=y +CONFIG_DRM_EXYNOS_IPP=y +CONFIG_DRM_EXYNOS_ROTATOR=y +CONFIG_DRM_EXYNOS_VIDI=y +# CONFIG_FB_S3C is not set +# CONFIG_VIDEO_SAMSUNG_EXYNOS4_IS is not set +CONFIG_VIDEO_SAMSUNG_S5P_G2D=m +CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m +CONFIG_VIDEO_SAMSUNG_S5P_MFC=m +# CONFIG_VIDEO_SAMSUNG_S5P_TV is not set +CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m + +CONFIG_SND_SOC_SAMSUNG=m +CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF=m +CONFIG_SND_SOC_SAMSUNG_SMDK_WM8994=m +CONFIG_SND_SOC_SMDK_WM8994_PCM=m +CONFIG_SND_SOC_SNOW=m +# CONFIG_GPIO_WM8994 is not set +# CONFIG_REGULATOR_WM8994 is not set +# CONFIG_EXYNOS_IOMMU_DEBUG is not set +# CONFIG_SAMSUNG_PM_DEBUG is not set +# CONFIG_SAMSUNG_PM_CHECK is not set + +# Arndale/Origen +CONFIG_MFD_MAX8997=y +CONFIG_MFD_MAX77686=y +CONFIG_REGULATOR_MAX8997=m +CONFIG_REGULATOR_MAX77686=m +CONFIG_REGULATOR_S2MPA01=m +CONFIG_REGULATOR_S5M8767=m +CONFIG_COMMON_CLK_MAX77686=m +CONFIG_COMMON_CLK_S2MPS11=m +CONFIG_INPUT_MAX8997_HAPTIC=m +CONFIG_CHARGER_MAX8997=m +CONFIG_LEDS_MAX8997=m +CONFIG_RTC_DRV_MAX8997=m +CONFIG_RTC_DRV_MAX77686=m +CONFIG_EXTCON_MAX8997=m + +# regmap CONFIG_REGMAP=y CONFIG_REGMAP_I2C=m CONFIG_REGMAP_SPI=m @@ -271,6 +376,7 @@ CONFIG_MFD_TPS65912_SPI=y # CONFIG_MFD_WM831X_SPI is not set # CONFIG_MFD_MC13XXX_SPI is not set # CONFIG_MFD_PM8921_CORE is not set +# CONFIG_MFD_AXP20X is not set # Pin stuff CONFIG_PINMUX=y @@ -279,10 +385,11 @@ CONFIG_PINCTRL=y CONFIG_PINCTRL_SINGLE=y CONFIG_GENERIC_PINCONF=y # CONFIG_PINCTRL_SAMSUNG is not set -# CONFIG_PINCTRL_EXYNOS4 is not set # CONFIG_PINCTRL_CAPRI is not set # CONFIG_PINCTRL_MSM8X74 is not set # CONFIG_PINCTRL_BCM281XX is not set +# CONFIG_PINCTRL_APQ8064 is not set +# CONFIG_PINCTRL_IPQ8064 is not set # GPIO # CONFIG_GPIO_EM is not set @@ -319,12 +426,12 @@ CONFIG_SPI_DESIGNWARE=m CONFIG_SPI_LM70_LLP=m CONFIG_SPI_OC_TINY=m CONFIG_SPI_PL022=m -CONFIG_SPI_S3C64XX=m CONFIG_SPI_SC18IS602=m CONFIG_SPI_TLE62X0=m CONFIG_SPI_XCOMM=m CONFIG_SPI_XILINX=m # CONFIG_SPI_FSL_SPI is not set +# CONFIG_SPI_CADENCE is not set CONFIG_NFC_NCI_SPI=y @@ -332,6 +439,7 @@ CONFIG_NFC_NCI_SPI=y CONFIG_I2C_DESIGNWARE_CORE=m CONFIG_I2C_DESIGNWARE_PLATFORM=m CONFIG_I2C_MV64XXX=m +# CONFIG_I2C_CROS_EC_TUNNEL is not set # HW crypto and rng CONFIG_CRYPTO_SHA1_ARM=m @@ -394,21 +502,22 @@ CONFIG_MMC_DW_PCI=m CONFIG_SPI_DW_MMIO=m CONFIG_SPI_DW_PCI=m # CONFIG_MMC_DW_SOCFPGA is not set -# CONFIG_MMC_DW_EXYNOS is not set # CONFIG_MMC_DW_IDMAC is not set # CONFIG_MMC_DW_K3 is not set -CONFIG_USB_DWC2=m +CONFIG_USB_DWC2=y +CONFIG_USB_DWC2_HOST=m +CONFIG_USB_DWC2_PLATFORM=y +CONFIG_USB_DWC2_PCI=y +# CONFIG_USB_DWC2_PERIPHERAL is not set # CONFIG_USB_DWC2_DEBUG is not set # CONFIG_USB_DWC2_TRACK_MISSED_SOFS is not set CONFIG_USB_DWC3=m CONFIG_USB_DWC3_OMAP=m -CONFIG_USB_DWC3_EXYNOS=m CONFIG_USB_DWC3_PCI=m # CONFIG_USB_DWC3_DEBUG is not set # CONFIG_USB_DWC3_KEYSTONE is not set CONFIG_DW_WATCHDOG=m CONFIG_PCIE_DW=y -CONFIG_PCI_EXYNOS=y # Sound CONFIG_SND_SOC=m @@ -424,6 +533,8 @@ CONFIG_SND_SOC_ALL_CODECS=m CONFIG_SND_SOC_CACHE_LZO=y CONFIG_SND_SOC_DMIC=m CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y +CONFIG_SND_SOC_HDMI_CODEC=m +CONFIG_SND_SOC_SPDIF=m # CONFIG_SND_SOC_ADAU1701 is not set # CONFIG_SND_SOC_AK4104 is not set # CONFIG_SND_SOC_AK4554 is not set @@ -434,14 +545,12 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # CONFIG_SND_SOC_CS4270 is not set # CONFIG_SND_SOC_CS4271 is not set # CONFIG_SND_SOC_CS42XX8_I2C is not set -# CONFIG_SND_SOC_HDMI_CODEC is not set # CONFIG_SND_SOC_PCM1681 is not set # CONFIG_SND_SOC_PCM1792A is not set # CONFIG_SND_SOC_PCM512x_I2C is not set # CONFIG_SND_SOC_PCM512x_SPI is not set # CONFIG_SND_SOC_SGTL5000 is not set # CONFIG_SND_SOC_SIRF_AUDIO_CODEC is not set -# CONFIG_SND_SOC_SPDIF is not set # CONFIG_SND_SOC_TAS5086 is not set # CONFIG_SND_SOC_TLV320AIC3X is not set # CONFIG_SND_SOC_WM8510 is not set @@ -460,6 +569,14 @@ CONFIG_SND_SOC_GENERIC_DMAENGINE_PCM=y # CONFIG_SND_SOC_WM8903 is not set # CONFIG_SND_SOC_WM8962 is not set # CONFIG_SND_SOC_TPA6130A2 is not set +# CONFIG_SND_SOC_FSL_SAI is not set +# CONFIG_SND_SOC_FSL_SSI is not set +# CONFIG_SND_SOC_FSL_SPDIF is not set +# CONFIG_SND_SOC_FSL_ESAI is not set +# CONFIG_SND_SOC_IMX_AUDMUX is not set +# CONFIG_SND_SOC_ALC5623 is not set +# CONFIG_SND_SOC_CS42L56 is not set +# CONFIG_SND_SOC_STA350 is not set # CONFIG_SND_ATMEL_SOC is not set # Displays @@ -479,6 +596,9 @@ CONFIG_RTC_DRV_RX4581=m CONFIG_RTC_DRV_TPS65910=m CONFIG_RTC_DRV_TPS80031=m # CONFIG_RTC_DRV_DS1347 is not set +# CONFIG_RTC_DRV_DS1343 is not set +# CONFIG_RTC_DRV_MCP795 is not set +# CONFIG_RTC_DRV_XGENE is not set # Regulators CONFIG_REGULATOR=y @@ -514,6 +634,8 @@ CONFIG_REGULATOR_TPS6586X=m CONFIG_REGULATOR_TPS65910=m CONFIG_REGULATOR_TPS65912=m CONFIG_REGULATOR_TPS80031=m +CONFIG_REGULATOR_LTC3589=m +CONFIG_REGULATOR_ANATOP=m CONFIG_CHARGER_MANAGER=y CONFIG_CHARGER_BQ2415X=m @@ -614,55 +736,58 @@ CONFIG_KEYBOARD_CROS_EC=m # Should be in generic CONFIG_BPF_JIT=y -# CONFIG_NET_VENDOR_CIRRUS is not set -# CONFIG_NET_VENDOR_MICROCHIP is not set -# CONFIG_PATA_PLATFORM is not set -# CONFIG_DRM_EXYNOS is not set +# Needs work/investigation +# CONFIG_ARM_KPROBES_TEST is not set + +# HW Enabled in armv7 not lpae # CONFIG_DRM_TILCDC is not set # CONFIG_DRM_IMX is not set # CONFIG_AHCI_IMX is not set -# CONFIG_CS89x0 is not set -# CONFIG_DM9000 is not set -# CONFIG_HW_RANDOM_ATMEL is not set -# CONFIG_HW_RANDOM_EXYNOS is not set +# CONFIG_IMX_THERMAL is not set +# CONFIG_TI_DAC7512 is not set + +# Not needed on ARMv7 +# CONFIG_PATA_PLATFORM is not set +# CONFIG_NET_VENDOR_CIRRUS is not set +# CONFIG_NET_VENDOR_MICROCHIP is not set # CONFIG_MFD_T7L66XB is not set # CONFIG_MFD_TC6387XB is not set -# CONFIG_TI_DAC7512 is not set # CONFIG_EZX_PCAP is not set - -# Needs work/investigation -# CONFIG_ARM_CHARLCD is not set +# CONFIG_CS89x0 is not set +# CONFIG_DM9000 is not set +# CONFIG_HW_RANDOM_ATMEL is not set # CONFIG_MTD_AFS_PARTS is not set -# CONFIG_IP_PNP_RARP is not set +# CONFIG_SPI_PXA2XX is not set # CONFIG_DEPRECATED_PARAM_STRUCT is not set # CONFIG_LATTICE_ECP3_CONFIG is not set -# CONFIG_M25PXX_USE_FAST_READ is not set # CONFIG_SERIAL_8250_EM is not set # CONFIG_SERIAL_MAX3100 is not set # CONFIG_SERIAL_MAX310X is not set # CONFIG_SERIAL_IFX6X60 is not set -# CONFIG_COMMON_CLK_AXI_CLKGEN is not set -# CONFIG_SPI_TOPCLIFF_PCH is not set -# CONFIG_SPI_PXA2XX is not set -# CONFIG_SPI_FSL_DSPI is not set # CONFIG_FB_XILINX is not set -# CONFIG_USB_S3C_HSOTG is not set - -# these modules all fail with missing __bad_udelay -# http://www.spinics.net/lists/arm/msg15615.html provides some background +# CONFIG_BRCMSTB_GISB_ARB is not set # CONFIG_SUNGEM is not set # CONFIG_FB_SAVAGE is not set # CONFIG_FB_RADEON is not set -# CONFIG_DRM_RADEON is not set # CONFIG_ATM_HE is not set # CONFIG_SCSI_ACARD is not set # CONFIG_SFC is not set - -# these all currently fail due to missing symbols __bad_udelay or -# error: implicit declaration of function ‘iowrite32be’ # CONFIG_SND_ALI5451 is not set -# CONFIG_DRM_NOUVEAU is not set # CONFIG_MLX4_EN is not set +# CONFIG_POWER_RESET_QNAP is not set +# CONFIG_MMC_TMIO is not set +# CONFIG_PINCTRL_IMX35 is not set +# CONFIG_DVB_USB_PCTV452E is not set + +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX14577 is not set +# CONFIG_MFD_AAT2870_CORE is not set +# CONFIG_MFD_RC5T583 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_MFD_AS3711 is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_PMIC_ADP5520 is not set # Debug options. We need to deal with them at some point like x86 # CONFIG_DEBUG_USER is not set @@ -670,3 +795,6 @@ CONFIG_BPF_JIT=y # CONFIG_DEBUG_PINCTRL is not set # CONFIG_DMADEVICES_VDEBUG is not set # CONFIG_DMADEVICES_DEBUG is not set +# CONFIG_OMAP2_DSS_DEBUG is not set +# CONFIG_CRYPTO_DEV_UX500_DEBUG is not set +# CONFIG_AB8500_DEBUG is not set diff --git a/freed-ora/current/master/config-armv7-lpae b/freed-ora/current/master/config-armv7-lpae index bc9324fde..e86aaad26 100644 --- a/freed-ora/current/master/config-armv7-lpae +++ b/freed-ora/current/master/config-armv7-lpae @@ -15,6 +15,7 @@ CONFIG_ARCH_VIRT=y # CONFIG_ARCH_SOCFPGA is not set # CONFIG_ARCH_TEGRA is not set # CONFIG_ARCH_ZYNQ is not set +# CONFIG_ARCH_AXXIA is not set CONFIG_ARM_LPAE=y CONFIG_SYS_SUPPORTS_HUGETLBFS=y @@ -52,89 +53,18 @@ CONFIG_XEN_GRANT_DEV_ALLOC=m CONFIG_XEN_WDT=m # CONFIG_XEN_BALLOON is not set -CONFIG_SERIAL_SAMSUNG=y -CONFIG_SERIAL_SAMSUNG_CONSOLE=y -# CONFIG_SAMSUNG_PM_DEBUG is not set -# CONFIG_SAMSUNG_PM_CHECK is not set -CONFIG_SOC_EXYNOS5250=y -CONFIG_SOC_EXYNOS5420=y -CONFIG_SOC_EXYNOS5440=y -# CONFIG_ARM_EXYNOS5250_CPUFREQ is not set -# CONFIG_ARM_EXYNOS5440_CPUFREQ is not set -# CONFIG_ARM_EXYNOS_CPUFREQ is not set -CONFIG_EXYNOS_THERMAL=m -CONFIG_PCI_EXYNOS=y - -CONFIG_TCG_TIS_I2C_INFINEON=m - -# CONFIG_EXYNOS_ATAGS is not set -CONFIG_PINCTRL_EXYNOS=y -CONFIG_PINCTRL_EXYNOS5440=y -CONFIG_EXYNOS_IOMMU=y -CONFIG_VIDEO_SAMSUNG_S5P_G2D=m -CONFIG_VIDEO_SAMSUNG_S5P_JPEG=m -CONFIG_VIDEO_SAMSUNG_S5P_MFC=m -CONFIG_VIDEO_SAMSUNG_EXYNOS_GSC=m -CONFIG_EXYNOS_VIDEO=y -CONFIG_EXYNOS_MIPI_DSI=y -CONFIG_EXYNOS_DP=y -# CONFIG_EXYNOS_LCD_S6E8AX0 is not set -CONFIG_DRM_EXYNOS=m -CONFIG_DRM_EXYNOS_IOMMU=y -CONFIG_DRM_EXYNOS_DMABUF=y -CONFIG_DRM_EXYNOS_FIMD=y -CONFIG_DRM_EXYNOS_HDMI=y -CONFIG_DRM_EXYNOS_VIDI=y -CONFIG_DRM_EXYNOS_G2D=y -CONFIG_DRM_EXYNOS_IPP=y -CONFIG_DRM_EXYNOS_FIMC=y -CONFIG_DRM_EXYNOS_ROTATOR=y -CONFIG_DRM_EXYNOS_GSC=y -CONFIG_DRM_EXYNOS_DPI=y -CONFIG_DRM_EXYNOS_DSI=y -# CONFIG_FB_S3C is not set -CONFIG_SND_SOC_SAMSUNG=m -CONFIG_USB_EHCI_HCD=y -CONFIG_USB_EHCI_S5P=m -CONFIG_USB_OHCI_EXYNOS=y -CONFIG_PWM_SAMSUNG=m -CONFIG_SAMSUNG_GPIO_EXTRA=8 -CONFIG_SERIAL_SAMSUNG_CONSOLE=y -CONFIG_SND_SOC_SAMSUNG_SMDK_SPDIF=m -CONFIG_USB_EHCI_S5P=y -CONFIG_SAMSUNG_USBPHY=m -CONFIG_SAMSUNG_USB2PHY=m -CONFIG_SAMSUNG_USB3PHY=m -CONFIG_MMC_DW_EXYNOS=m -CONFIG_RTC_DRV_S3C=m - # TI Keystone CONFIG_KEYSTONE_USB_PHY=m CONFIG_USB_DWC3_KEYSTONE=m CONFIG_GPIO_DAVINCI=y CONFIG_I2C_DAVINCI=m CONFIG_TI_AEMIF=m -# CONFIG_DAVINCI_WATCHDOG is not set -# CONFIG_SPI_DAVINCI is not set +CONFIG_POWER_RESET_KEYSTONE=y +CONFIG_DAVINCI_WATCHDOG=m +CONFIG_SPI_DAVINCI=m # CONFIG_SND_DAVINCI_SOC is not set # CONFIG_TI_SOC_THERMAL is not set -# Arndale/Origen -CONFIG_MFD_MAX8997=y -CONFIG_MFD_SEC_CORE=y -CONFIG_REGULATOR_MAX8997=m -CONFIG_REGULATOR_S5M8767=m -CONFIG_COMMON_CLK_MAX77686=m - -CONFIG_S3C_LOWLEVEL_UART_PORT=1 -# CONFIG_EXYNOS4_SDHCI_CH0_8BIT is not set -# CONFIG_EXYNOS4_SDHCI_CH2_8BIT is not set - -# CONFIG_S3C_BOOT_ERROR_RESET is not set -# CONFIG_S3C_BOOT_UART_FORCE_FIFO is not set -# CONFIG_I2C_S3C2410 is not set -# CONFIG_S3C2410_WATCHDOG is not set -# CONFIG_MMC_SDHCI_S3C is not set # CONFIG_TEGRA_HOST1X is not set # CONFIG_DRM_PANEL_SIMPLE is not set # CONFIG_DRM_PANEL_LD9040 is not set diff --git a/freed-ora/current/master/config-debug b/freed-ora/current/master/config-debug index 6ad71f3f5..302280b6f 100644 --- a/freed-ora/current/master/config-debug +++ b/freed-ora/current/master/config-debug @@ -35,6 +35,7 @@ CONFIG_ACPI_DEBUG=y # CONFIG_ACPI_DEBUG_FUNC_TRACE is not set CONFIG_DEBUG_SG=y +CONFIG_DEBUG_PI_LIST=y # CONFIG_DEBUG_PAGEALLOC is not set diff --git a/freed-ora/current/master/config-generic b/freed-ora/current/master/config-generic index d6e6b94ac..bd0ea5710 100644 --- a/freed-ora/current/master/config-generic +++ b/freed-ora/current/master/config-generic @@ -15,7 +15,7 @@ CONFIG_DEFAULT_HOSTNAME="(none)" # CONFIG_EXPERIMENTAL=y CONFIG_HOTPLUG=y -CONFIG_UEVENT_HELPER_PATH="" +# CONFIG_UEVENT_HELPER is not set CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_STANDALONE=y @@ -147,10 +147,12 @@ CONFIG_MMC_CB710=m CONFIG_MMC_RICOH_MMC=y CONFIG_MMC_USHC=m CONFIG_MMC_REALTEK_PCI=m +CONFIG_MMC_REALTEK_USB=m CONFIG_MMC_VUB300=m # CONFIG_MMC_SDHCI_PXAV2 is not set # CONFIG_MMC_SDHCI_PXAV3 is not set # CONFIG_MMC_SDHCI_OF_ARASAN is not set +# CONFIG_MMC_USDHI6ROL0 is not set CONFIG_CB710_CORE=m @@ -277,6 +279,7 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_PHRAM is not set # CONFIG_MTD_MTDRAM is not set # CONFIG_MTD_BLOCK2MTD is not set +# CONFIG_MTD_SPI_NOR is not set # # Disk-On-Chip Device Drivers @@ -1054,6 +1057,7 @@ CONFIG_BRIDGE_EBT_T_FILTER=m CONFIG_BRIDGE_EBT_T_NAT=m CONFIG_BRIDGE_EBT_ULOG=m CONFIG_BRIDGE_EBT_VLAN=m +CONFIG_NFT_BRIDGE_META=m CONFIG_XFRM=y CONFIG_XFRM_MIGRATE=y CONFIG_XFRM_SUB_POLICY=y @@ -1317,6 +1321,8 @@ CONFIG_NET_VENDOR_AMD=y CONFIG_PCNET32=m CONFIG_AMD8111_ETH=m CONFIG_PCMCIA_NMCLAN=m +# CONFIG_AMD_XGBE is not set +# CONFIG_AMD_XGBE_PHY is not set CONFIG_NET_VENDOR_ARC=y CONFIG_ARC_EMAC=m @@ -1383,6 +1389,7 @@ CONFIG_VXGE=m # CONFIG_NET_VENDOR_FARADAY is not set # CONFIG_NET_VENDOR_FUJITSU is not set +# CONFIG_NET_VENDOR_HISILICON is not set # CONFIG_NET_VENDOR_HP is not set CONFIG_NET_VENDOR_INTEL=y CONFIG_E100=m @@ -1451,6 +1458,7 @@ CONFIG_QLCNIC=m CONFIG_QLCNIC_SRIOV=y CONFIG_QLCNIC_DCB=y CONFIG_QLCNIC_VXLAN=y +CONFIG_QLCNIC_HWMON=y CONFIG_QLGE=m CONFIG_NETXEN_NIC=m @@ -1707,9 +1715,10 @@ CONFIG_BRCMFMAC_USB=y # CONFIG_BRCM_TRACING is not set # CONFIG_BRCMISCAN is not set # CONFIG_BRCMDBG is not set +# CONFIG_SYSTEMPORT is not set CONFIG_HERMES=m CONFIG_HERMES_CACHE_FW_ON_INIT=y -# CONFIG_HERMES_PRISM is not set +CONFIG_HERMES_PRISM=y CONFIG_NORTEL_HERMES=m CONFIG_PCI_HERMES=m CONFIG_PLX_HERMES=m @@ -1877,6 +1886,9 @@ CONFIG_NFC_PN533=m CONFIG_NFC_MICROREAD=m CONFIG_NFC_MICROREAD_I2C=m CONFIG_NFC_TRF7970A=m +CONFIG_NFC_ST21NFCA=m +CONFIG_NFC_ST21NFCA_I2C=m + # # IrDA (infrared) support @@ -1997,6 +2009,7 @@ CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y CONFIG_ISDN_DRV_AVMB1_AVM_CS=m CONFIG_ISDN_CAPI_CAPIDRV=m +# CONFIG_ISDN_CAPI_CAPIDRV_VERBOSE is not set CONFIG_ISDN_DIVERSION=m CONFIG_HISAX_EURO=y @@ -2332,6 +2345,7 @@ CONFIG_CYCLADES=m # CONFIG_RIO is not set CONFIG_SERIAL_JSM=m # CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set # CONFIG_SERIAL_MFD_HSU is not set # CONFIG_SERIAL_ALTERA_JTAGUART is not set @@ -2427,6 +2441,7 @@ CONFIG_I2C_TINY_USB=m # CONFIG_I2C_VIAPRO is not set # CONFIG_I2C_DESIGNWARE is not set # CONFIG_I2C_XILINX is not set +# CONFIG_I2C_RK3X is not set CONFIG_I2C_DIOLAN_U2C=m @@ -2500,11 +2515,13 @@ CONFIG_SENSORS_MAX6650=m CONFIG_SENSORS_MAX6697=m CONFIG_SENSORS_MCP3021=m CONFIG_SENSORS_NCT6775=m +CONFIG_SENSORS_NCT6683=m CONFIG_SENSORS_NTC_THERMISTOR=m CONFIG_SENSORS_PC87360=m CONFIG_SENSORS_PC87427=m CONFIG_SENSORS_PCF8591=m CONFIG_SENSORS_SHT15=m +CONFIG_SENSORS_SHTC1=m CONFIG_SENSORS_SIS5595=m CONFIG_CHARGER_SMB347=m CONFIG_SENSORS_SMSC47M1=m @@ -2619,15 +2636,18 @@ CONFIG_IIO_ST_GYRO_3AXIS=m CONFIG_IIO_ST_MAGN_3AXIS=m CONFIG_IIO_ST_ACCEL_3AXIS=m CONFIG_HID_SENSOR_INCLINOMETER_3D=m +CONFIG_HID_SENSOR_DEVICE_ROTATION=m # CONFIG_ADJD_S311 is not set # CONFIG_SENSORS_TSL2563 is not set # CONFIG_VCNL4000 is not set # CONFIG_AK8975 is not set # CONFIG_MAG3110 is not set # CONFIG_TMP006 is not set +# CONFIG_MLX90614 is not set # CONFIG_HID_SENSOR_PRESS is not set # CONFIG_IIO_ST_PRESS is not set # CONFIG_KXSD9 is not set +# CONFIG_MMA8452 is not set # CONFIG_AD7266 is not set # CONFIG_AD7298 is not set # CONFIG_AD7476 is not set @@ -2659,7 +2679,9 @@ CONFIG_HID_SENSOR_INCLINOMETER_3D=m # CONFIG_ADIS16480 is not set # CONFIG_DHT11 is not set # CONFIG_MPL3115 is not set +# CONFIG_MPL115 is not set # CONFIG_SI7005 is not set +# CONFIG_AS3935 is not set # staging IIO drivers # CONFIG_AD7291 is not set @@ -2857,6 +2879,7 @@ CONFIG_RTC_DRV_ISL12022=m # CONFIG_RTC_DRV_HID_SENSOR_TIME is not set # CONFIG_RTC_DRV_MOXART is not set # CONFIG_RTC_DRV_ISL12057 is not set +# CONFIG_RTC_DRV_XGENE is not set CONFIG_R3964=m # CONFIG_APPLICOM is not set @@ -3450,6 +3473,7 @@ CONFIG_SND_USB_US122L=m CONFIG_SND_USB_UA101=m CONFIG_SND_USB_6FIRE=m CONFIG_SND_USB_HIFACE=m +# CONFIG_SND_BCD2000 is not set # # PCMCIA devices @@ -3461,6 +3485,8 @@ CONFIG_SND_FIREWIRE_SPEAKERS=m CONFIG_SND_ISIGHT=m CONFIG_SND_SCS1X=m CONFIG_SND_DICE=m +# CONFIG_SND_FIREWORKS is not set +# CONFIG_SND_BEBOB is not set # # Open Sound System @@ -3515,6 +3541,7 @@ CONFIG_USB_SL811_HCD_ISO=y # CONFIG_USB_R8A66597_HCD is not set CONFIG_USB_XHCI_HCD=y # CONFIG_USB_XHCI_HCD_DEBUGGING is not set +# CONFIG_USB_MAX3421_HCD is not set # # USB Device Class drivers @@ -3661,6 +3688,7 @@ CONFIG_USB_GSPCA_MR97310A=m CONFIG_USB_GSPCA_BENQ=m CONFIG_USB_GSPCA_CONEX=m CONFIG_USB_GSPCA_CPIA1=m +CONFIG_USB_GSPCA_DTCS033=m CONFIG_USB_GSPCA_ETOMS=m CONFIG_USB_GSPCA_FINEPIX=m CONFIG_USB_GSPCA_MARS=m @@ -3951,6 +3979,7 @@ CONFIG_MFD_VX855=m CONFIG_MFD_SM501=m CONFIG_MFD_SM501_GPIO=y CONFIG_MFD_RTSX_PCI=m +CONFIG_MFD_RTSX_USB=m # CONFIG_MFD_TI_AM335X_TSCADC is not set CONFIG_MFD_VIPERBOARD=m # CONFIG_MFD_RETU is not set @@ -3994,7 +4023,6 @@ CONFIG_MFD_VIPERBOARD=m # CONFIG_MFD_DA9063 is not set # CONFIG_MFD_LP3943 is not set # CONFIG_MFD_BCM590XX is not set -# CONFIG_MFD_RTSX_USB is not set # CONFIG_MFD_TPS65218 is not set @@ -4352,6 +4380,7 @@ CONFIG_DEBUG_NX_TEST=m CONFIG_DEBUG_SET_MODULE_RONX=y CONFIG_DEBUG_BOOT_PARAMS=y CONFIG_DEBUG_VM=y +# CONFIG_DEBUG_VM_VMACACHE is not set # CONFIG_DEBUG_VM_RB is not set # revisit this if performance isn't horrible # CONFIG_DEBUG_STRICT_USER_COPY_CHECKS is not set CONFIG_LOCKUP_DETECTOR=y @@ -4751,6 +4780,7 @@ CONFIG_FTRACE_MCOUNT_RECORD=y # CONFIG_FTRACE_STARTUP_TEST is not set # CONFIG_TRACE_BRANCH_PROFILING is not set CONFIG_FUNCTION_PROFILER=y +# CONFIG_TRACEPOINT_BENCHMARK is not set CONFIG_RING_BUFFER_BENCHMARK=m # CONFIG_RING_BUFFER_STARTUP_TEST is not set # CONFIG_RBTREE_TEST is not set @@ -4870,6 +4900,7 @@ CONFIG_MEMSTICK_TIFM_MS=m CONFIG_MEMSTICK_JMICRON_38X=m CONFIG_MEMSTICK_R592=m CONFIG_MEMSTICK_REALTEK_PCI=m +CONFIG_MEMSTICK_REALTEK_USB=m CONFIG_ACCESSIBILITY=y CONFIG_A11Y_BRAILLE_CONSOLE=y @@ -4963,6 +4994,8 @@ CONFIG_RTL8192E=m # CONFIG_VIDEO_CX25821 is not set # CONFIG_R8187SE is not set # CONFIG_R8188EU is not set +# Larry Finger maintains (rhbz 1113422) +CONFIG_R8192EE=m # CONFIG_R8821AE is not set # CONFIG_RTL8192U is not set CONFIG_R8723AU=m # Jes Sorensen maintains this (rhbz 1100162) @@ -5043,7 +5076,8 @@ CONFIG_STRIP_ASM_SYMS=y # CONFIG_RCU_FANOUT_EXACT is not set # FIXME: Revisit FAST_NO_HZ after it's fixed # CONFIG_RCU_FAST_NO_HZ is not set -# CONFIG_RCU_NOCB_CPU is not set +CONFIG_RCU_NOCB_CPU=y +CONFIG_RCU_NOCB_CPU_ALL=y CONFIG_RCU_CPU_STALL_TIMEOUT=60 # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_RCU_TRACE is not set @@ -5110,6 +5144,7 @@ CONFIG_GPIO_SYSFS=y # CONFIG_GPIO_ADP5588 is not set # CONFIG_GPIO_IT8761E is not set # CONFIG SB105x is not set +# CONFIG_GPIO_SYSCON is not set # CONFIG_GPIO_TS5500 is not set CONFIG_GPIO_VIPERBOARD=m # CONFIG_GPIO_MAX7300 is not set @@ -5165,6 +5200,7 @@ CONFIG_PSTORE_RAM=m # CONFIG_TEST_MODULE is not set # CONFIG_TEST_USER_COPY is not set +# CONFIG_TEST_BPF is not set # CONFIG_AVERAGE is not set # CONFIG_VMXNET3 is not set @@ -5214,3 +5250,6 @@ CONFIG_FMC_CHARDEV=m # CONFIG_CRYPTO_KEY_TYPE is not set # CONFIG_PGP_LIBRARY is not set # CONFIG_PGP_PRELOAD is not set + +# CONFIG_RTC_DRV_EFI is not set +# CONFIG_NET_XGENE is not set diff --git a/freed-ora/current/master/config-nodebug b/freed-ora/current/master/config-nodebug index c6b4b7902..e16a37b57 100644 --- a/freed-ora/current/master/config-nodebug +++ b/freed-ora/current/master/config-nodebug @@ -35,6 +35,7 @@ CONFIG_CPUMASK_OFFSTACK=y # CONFIG_ACPI_DEBUG_FUNC_TRACE is not set # CONFIG_DEBUG_SG is not set +# CONFIG_DEBUG_PI_LIST is not set # CONFIG_DEBUG_PAGEALLOC is not set diff --git a/freed-ora/current/master/config-s390x b/freed-ora/current/master/config-s390x index 6f3d3253e..874f80847 100644 --- a/freed-ora/current/master/config-s390x +++ b/freed-ora/current/master/config-s390x @@ -153,6 +153,7 @@ CONFIG_CHECK_STACK=y # CONFIG_SMALL_STACK is not set CONFIG_ZVM_WATCHDOG=m +CONFIG_DIAG288_WATCHDOG=m CONFIG_VMLOGRDR=m CONFIG_MONREADER=m diff --git a/freed-ora/current/master/config-x86-32-generic b/freed-ora/current/master/config-x86-32-generic index 6adcfb524..dac24a2c4 100644 --- a/freed-ora/current/master/config-x86-32-generic +++ b/freed-ora/current/master/config-x86-32-generic @@ -84,6 +84,7 @@ CONFIG_X86_SPEEDSTEP_LIB=y CONFIG_X86_LONGRUN=y # CONFIG_X86_LONGHAUL is not set # CONFIG_X86_CPUFREQ_NFORCE2 is not set +# CONFIG_GENERIC_CPUFREQ_CPU0 is not set # e_powersaver is dangerous # CONFIG_X86_E_POWERSAVER is not set @@ -230,5 +231,7 @@ CONFIG_BACKLIGHT_PWM=m # CONFIG_PINCTRL_CAPRI is not set # CONFIG_PINCTRL_MSM8X74 is not set # CONFIG_PINCTRL_BCM281XX is not set +# CONFIG_PINCTRL_APQ8064 is not set +# CONFIG_PINCTRL_IPQ8064 is not set # CONFIG_COMMON_CLK_SI570 is not set # CONFIG_COMMON_CLK_QCOM is not set diff --git a/freed-ora/current/master/config-x86-generic b/freed-ora/current/master/config-x86-generic index 92441b0a7..7968fdaea 100644 --- a/freed-ora/current/master/config-x86-generic +++ b/freed-ora/current/master/config-x86-generic @@ -225,6 +225,7 @@ CONFIG_HP_WMI=m # CONFIG_INTEL_SCU_IPC is not set CONFIG_DELL_WMI=m CONFIG_DELL_WMI_AIO=m +CONFIG_DELL_SMO8800=m CONFIG_EEEPC_WMI=m CONFIG_INTEL_OAKTRAIL=m CONFIG_SAMSUNG_Q10=m @@ -417,6 +418,7 @@ CONFIG_SCHED_SMT=y CONFIG_CC_STACKPROTECTOR=y CONFIG_CC_STACKPROTECTOR_STRONG=y CONFIG_RELOCATABLE=y +# CONFIG_RANDOMIZE_BASE is not set # revisit this CONFIG_HYPERV=m CONFIG_HYPERV_UTILS=m @@ -447,6 +449,8 @@ CONFIG_NFC_MICROREAD_MEI=m # Maybe enable in debug kernels? # CONFIG_DEBUG_NMI_SELFTEST is not set +# CONFIG_X86_GOLDFISH is not set + CONFIG_X86_INTEL_LPSS=y CONFIG_PWM_LPSS=m CONFIG_PINCTRL=y @@ -455,6 +459,7 @@ CONFIG_PINCTRL_BAYTRAIL=y # CONFIG_INTEL_POWERCLAMP is not set CONFIG_X86_PKG_TEMP_THERMAL=m CONFIG_ACPI_INT3403_THERMAL=m +CONFIG_INTEL_SOC_DTS_THERMAL=m CONFIG_VMWARE_VMCI=m CONFIG_VMWARE_VMCI_VSOCKETS=m diff --git a/freed-ora/current/master/config-x86_64-generic b/freed-ora/current/master/config-x86_64-generic index 02883b84b..2f098161f 100644 --- a/freed-ora/current/master/config-x86_64-generic +++ b/freed-ora/current/master/config-x86_64-generic @@ -74,6 +74,9 @@ CONFIG_CRYPTO_SERPENT_AVX_X86_64=m CONFIG_CRYPTO_SERPENT_AVX2_X86_64=m CONFIG_CRYPTO_TWOFISH_AVX_X86_64=m CONFIG_CRYPTO_TWOFISH_AVX2_X86_64=m +# staging crypto +# CONFIG_CRYPTO_SKEIN is not set +# CONFIG_CRYPTO_THREEFISH is not set # CONFIG_I2C_ALI1535 is not set # CONFIG_I2C_ALI1563 is not set diff --git a/freed-ora/current/master/deblob-3.15 b/freed-ora/current/master/deblob-3.16 index 850811f82..92a8b5cf2 100755 --- a/freed-ora/current/master/deblob-3.15 +++ b/freed-ora/current/master/deblob-3.16 @@ -48,7 +48,7 @@ # For each kver release, start extra with an empty string, then count # from 1 if changes are needed that require rebuilding the tarball. -kver=3.15 extra= +kver=3.16 extra= case $1 in --force) @@ -265,6 +265,10 @@ for f in \ drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnve0.fuc \ drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc.h \ drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnvf0.fuc \ + drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5.h \ + drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5 \ + drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5.h \ + drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5 \ drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h \ drivers/gpu/drm/nouveau/core/engine/graph/fuc/hub.fuc \ drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvc0.fuc.h \ @@ -275,6 +279,10 @@ for f in \ drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnve0.fuc \ drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc.h \ drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnvf0.fuc \ + drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5.h \ + drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5 \ + drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5.h \ + drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5 \ drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h \ drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc \ drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h \ @@ -568,6 +576,12 @@ clean_mk CONFIG_MOXA_INTELLIO drivers/tty/Makefile # gpu drm +announce DRM_AST - "AST server chips" +reject_firmware drivers/gpu/drm/ast/ast_dp501.c +clean_blob drivers/gpu/drm/ast/ast_dp501.c +clean_kconfig drivers/gpu/drm/ast/Kconfig 'DRM_AST' +clean_mk CONFIG_DRM_AST drivers/gpu/drm/ast/Makefile + announce DRM_NOUVEAU - "Nouveau (nVidia) cards" reject_firmware drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c clean_blob drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c @@ -643,6 +657,8 @@ reject_firmware drivers/gpu/drm/radeon/cik.c clean_blob drivers/gpu/drm/radeon/cik.c reject_firmware drivers/gpu/drm/radeon/radeon_uvd.c clean_blob drivers/gpu/drm/radeon/radeon_uvd.c +reject_firmware drivers/gpu/drm/radeon/radeon_vce.c +clean_blob drivers/gpu/drm/radeon/radeon_vce.c clean_kconfig drivers/gpu/drm/Kconfig 'DRM_RADEON' clean_mk CONFIG_DRM_RADEON drivers/gpu/drm/Makefile @@ -655,8 +671,12 @@ reject_firmware drivers/dma/imx-sdma.c clean_blob arch/arm/mach-imx/mm-imx25.c clean_blob arch/arm/mach-imx/mm-imx3.c clean_blob arch/arm/mach-imx/mm-imx5.c +clean_blob arch/arm/boot/dts/imx25.dtsi +clean_blob arch/arm/boot/dts/imx35.dtsi +clean_blob arch/arm/boot/dts/imx50.dtsi clean_blob arch/arm/boot/dts/imx51.dtsi clean_blob arch/arm/boot/dts/imx53.dtsi +clean_blob arch/arm/boot/dts/imx53-tx53.dtsi clean_blob arch/arm/boot/dts/imx6qdl.dtsi clean_blob arch/arm/boot/dts/imx6sl.dtsi clean_blob Documentation/devicetree/bindings/dma/fsl-imx-sdma.txt @@ -879,6 +899,19 @@ clean_sed ' clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_BCM3510' clean_mk CONFIG_DVB_BCM3510 drivers/media/dvb-frontends/Makefile +announce DVB_CX24116 - "Conexant CX24116 based" +undefault_firmware CX24116 drivers/media/dvb-frontends/cx24116.c +reject_firmware drivers/media/dvb-frontends/cx24116.c +clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_CX24116' +clean_mk CONFIG_DVB_CX24116 drivers/media/dvb-frontends/Makefile + +announce DVB_CX24117 - "Conexant CX24117 based" +undefault_firmware CX24117 drivers/media/dvb-frontends/cx24117.c +reject_firmware drivers/media/dvb-frontends/cx24117.c +clean_blob drivers/media/dvb-frontends/cx24117.c +clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_CX24117' +clean_mk CONFIG_DVB_CX24117 drivers/media/dvb-frontends/Makefile + announce DVB_DS3000 - "Montage Tehnology DS3000 based" undefault_firmware 'DS3000' \ drivers/media/dvb-frontends/ds3000.c @@ -887,12 +920,25 @@ clean_blob drivers/media/dvb-frontends/ds3000.c clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_DS3000' clean_mk CONFIG_DVB_DS3000 drivers/media/dvb-frontends/Makefile +announce DVB_DRX39XYJ - "Micronas DRX-J demodulator" +reject_firmware drivers/media/dvb-frontends/drx39xyj/drxj.c +clean_blob drivers/media/dvb-frontends/drx39xyj/drxj.c +clean_kconfig drivers/media/dvb-frontends/drx39xyj/Kconfig 'DVB_DRX39XYJ' +clean_mk CONFIG_DVB_DRX39XYJ drivers/media/dvb-frontends/drx39xyj/Makefile + announce DVB_LGS8GXX - "Legend Silicon LGS8913/LGS8GL5/LGS8GXX DMB-TH demodulator" reject_firmware drivers/media/dvb-frontends/lgs8gxx.c clean_blob drivers/media/dvb-frontends/lgs8gxx.c clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_LGS8GXX' clean_mk CONFIG_DVB_LGS8GXX drivers/media/dvb-frontends/Makefile +announce DVB_M88DS3103 - "Montage M88DS3103" +reject_firmware drivers/media/dvb-frontends/m88ds3103.c +clean_blob drivers/media/dvb-frontends/m88ds3103.c +clean_blob drivers/media/dvb-frontends/m88ds3103_priv.h +clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_M88DS3103' +clean_mk CONFIG_DVB_M88DS3103 drivers/media/dvb-frontends/Makefile + announce DVB_NXT200X - "NxtWave Communications NXT2002/NXT2004 based" undefault_firmware 'NXT200[24]' drivers/media/dvb-frontends/nxt200x.c reject_firmware drivers/media/dvb-frontends/nxt200x.c @@ -914,6 +960,13 @@ clean_blob drivers/media/dvb-frontends/or51211.c clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_OR51211' clean_mk CONFIG_DVB_OR51211 drivers/media/dvb-frontends/Makefile +announce DVB_SI2168 - "Silicon Labs Si2168" +reject_firmware drivers/media/dvb-frontends/si2168.c +clean_blob drivers/media/dvb-frontends/si2168.c +clean_blob drivers/media/dvb-frontends/si2168_priv.h +clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_SI2168' +clean_mk CONFIG_DVB_SI2168 drivers/media/dvb-frontends/Makefile + announce DVB_SP8870 - "Spase sp8870" undefault_firmware 'SP8870' drivers/media/dvb-frontends/sp8870.c reject_firmware drivers/media/dvb-frontends/sp8870.c @@ -922,19 +975,6 @@ clean_blob drivers/media/dvb-frontends/sp8870.c clean_kconfig drivers/media/dvb-frontends 'DVB_SP8870' clean_mk CONFIG_DVB_SP8870 drivers/media/dvb-frontends/Makefile -announce DVB_CX24116 - "Conexant CX24116 based" -undefault_firmware CX24116 drivers/media/dvb-frontends/cx24116.c -reject_firmware drivers/media/dvb-frontends/cx24116.c -clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_CX24116' -clean_mk CONFIG_DVB_CX24116 drivers/media/dvb-frontends/Makefile - -announce DVB_CX24117 - "Conexant CX24117 based" -undefault_firmware CX24117 drivers/media/dvb-frontends/cx24117.c -reject_firmware drivers/media/dvb-frontends/cx24117.c -clean_blob drivers/media/dvb-frontends/cx24117.c -clean_kconfig drivers/media/dvb-frontends/Kconfig 'DVB_CX24117' -clean_mk CONFIG_DVB_CX24117 drivers/media/dvb-frontends/Makefile - announce DVB_SP887X - "Spase sp887x based" undefault_firmware 'SP887X' drivers/media/dvb-frontends/sp887x.c reject_firmware drivers/media/dvb-frontends/sp887x.c @@ -1148,12 +1188,6 @@ clean_blob drivers/media/pci/saa7164/saa7164-fw.c clean_kconfig drivers/media/pci/saa7164/Kconfig 'VIDEO_SAA7164' clean_mk CONFIG_VIDEO_SAA7164 drivers/media/pci/saa7164/Makefile -announce VIDEO_TLG2300 - "Telegent TLG2300 USB video capture support" -reject_firmware drivers/media/usb/tlg2300/pd-main.c -clean_blob drivers/media/usb/tlg2300/pd-main.c -clean_kconfig drivers/media/usb/tlg2300/Kconfig 'VIDEO_TLG2300' -clean_mk CONFIG_VIDEO_TLG2300 drivers/media/usb/tlg2300/Makefile - announce VIDEO_S5C73M3 - "Samsung S5C73M3 sensor support" reject_firmware drivers/media/i2c/s5c73m3/s5c73m3-core.c clean_blob drivers/media/i2c/s5c73m3/s5c73m3-core.c @@ -1163,15 +1197,27 @@ clean_mk CONFIG_VIDEO_S5C73M3 drivers/media/i2c/s5c73m3/Makefile announce VIDEO_S5K4ECGX - "Samsung S5K4ECGX sensor support" reject_firmware drivers/media/i2c/s5k4ecgx.c clean_blob drivers/media/i2c/s5k4ecgx.c -clean_kconfig drivers/media/i2c/s5k4ecgx.c 'VIDEO_S5K4ECGX' +clean_kconfig drivers/media/i2c/Kconfig 'VIDEO_S5K4ECGX' clean_mk CONFIG_VIDEO_S5K4ECGX drivers/media/i2c/Makefile +announce VIDEO_S5K5BAF - "Samsung S5K5BAF sensor support" +reject_firmware drivers/media/i2c/s5k5baf.c +clean_blob drivers/media/i2c/s5k5baf.c +clean_kconfig drivers/media/i2c/Kconfig 'VIDEO_S5K5BAF' +clean_mk CONFIG_VIDEO_S5K5BAF drivers/media/i2c/Makefile + announce VIDEO_SAMSUNG_S5P_MFC - "Samsung S5P MFC 5.1 Video Codec" reject_firmware drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c clean_blob drivers/media/platform/s5p-mfc/s5p_mfc.c clean_kconfig drivers/media/platform/Kconfig 'VIDEO_SAMSUNG_S5P_MFC' clean_mk CONFIG_VIDEO_SAMSUNG_S5P_MFC drivers/media/platform/s5p-mfc/Makefile +announce VIDEO_TLG2300 - "Telegent TLG2300 USB video capture support" +reject_firmware drivers/media/usb/tlg2300/pd-main.c +clean_blob drivers/media/usb/tlg2300/pd-main.c +clean_kconfig drivers/media/usb/tlg2300/Kconfig 'VIDEO_TLG2300' +clean_mk CONFIG_VIDEO_TLG2300 drivers/media/usb/tlg2300/Makefile + announce USB_S2255 - "USB Sensoray 2255 video capture device" reject_firmware drivers/media/usb/s2255/s2255drv.c clean_blob drivers/media/usb/s2255/s2255drv.c @@ -1565,14 +1611,17 @@ clean_blob drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c clean_kconfig drivers/net/wireless/brcm80211/Kconfig 'BRCMSMAC' clean_mk CONFIG_BRCMSMAC drivers/net/wireless/brcm80211/Makefile +announce BRCMFMAC - "Broadcom IEEE802.11n embedded FullMAC WLAN driver" +reject_firmware drivers/net/wireless/brcm80211/brcmfmac/firmware.c +clean_kconfig drivers/net/wireless/brcm80211/Kconfig 'BRCMFMAC' +clean_mk CONFIG_BRCMFMAC drivers/net/wireless/brcm80211/brcmfmac/Makefile + announce BRCMFMAC_SDIO - "Broadcom IEEE802.11n SDIO FullMAC WLAN driver" -reject_firmware drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c clean_blob drivers/net/wireless/brcm80211/brcmfmac/dhd_sdio.c clean_kconfig drivers/net/wireless/brcm80211/Kconfig 'BRCMFMAC_SDIO' clean_mk CONFIG_BRCMFMAC_SDIO drivers/net/wireless/brcm80211/brcmfmac/Makefile announce BRCMFMAC_USB - "Broadcom IEEE802.11n USB FullMAC WLAN driver" -reject_firmware drivers/net/wireless/brcm80211/brcmfmac/usb.c clean_blob drivers/net/wireless/brcm80211/brcmfmac/usb.c clean_kconfig drivers/net/wireless/brcm80211/Kconfig 'BRCMFMAC_USB' clean_mk CONFIG_BRCMFMAC_USB drivers/net/wireless/brcm80211/brcmfmac/Makefile @@ -1642,18 +1691,23 @@ clean_mk CONFIG_IWL4965 drivers/net/wireless/iwlegacy/Makefile announce IWLWIFI - "Intel Wireless WiFi Next Gen AGN" reject_firmware drivers/net/wireless/iwlwifi/iwl-drv.c clean_blob drivers/net/wireless/iwlwifi/iwl-drv.c -clean_blob drivers/net/wireless/iwlwifi/iwl-5000.c -clean_blob drivers/net/wireless/iwlwifi/iwl-6000.c -clean_blob drivers/net/wireless/iwlwifi/iwl-7000.c -clean_blob drivers/net/wireless/iwlwifi/iwl-1000.c -clean_blob drivers/net/wireless/iwlwifi/iwl-2000.c clean_kconfig drivers/net/wireless/iwlwifi/Kconfig 'IWLWIFI' clean_mk CONFIG_IWLWIFI drivers/net/wireless/iwlwifi/Makefile +announce IWLDVM - "Intel Wireless WiFi DVM Firmware support" +clean_blob drivers/net/wireless/iwlwifi/iwl-1000.c +clean_blob drivers/net/wireless/iwlwifi/iwl-2000.c +clean_blob drivers/net/wireless/iwlwifi/iwl-5000.c +clean_blob drivers/net/wireless/iwlwifi/iwl-6000.c +clean_kconfig drivers/net/wireless/iwlwifi/Kconfig 'IWLDVM' +clean_mk CONFIG_IWLMVM drivers/net/wireless/iwlwifi/Makefile + announce IWLMVM - "Intel Wireless WiFi MVM Firmware support" reject_firmware drivers/net/wireless/iwlwifi/mvm/nvm.c -clean_kconfig drivers/net/wireless/iwlwifi/mvm/Kconfig 'IWLMVM' -clean_mk CONFIG_IWLMVM drivers/net/wireless/iwlwifi/mvm/Makefile +clean_blob drivers/net/wireless/iwlwifi/iwl-7000.c +clean_blob drivers/net/wireless/iwlwifi/iwl-8000.c +clean_kconfig drivers/net/wireless/iwlwifi/Kconfig 'IWLMVM' +clean_mk CONFIG_IWLMVM drivers/net/wireless/iwlwifi/Makefile announce LIBERTAS - "Marvell 8xxx Libertas WLAN driver support" reject_firmware drivers/net/wireless/libertas/firmware.c @@ -1799,6 +1853,23 @@ clean_blob drivers/net/wireless/prism54/islpci_dev.c clean_kconfig drivers/net/wireless/Kconfig 'PRISM54' clean_mk CONFIG_PRISM54 drivers/net/wireless/prism54/Makefile +announce RSI_91X - "Redpine Signals Inc 91x WLAN driver support" +clean_blob drivers/net/wireless/rsi/rsi_common.h +clean_kconfig drivers/net/wireless/rsi/Kconfig 'RSI_91X' +clean_mk CONFIG_RSI_91X drivers/net/wireless/rsi/Makefile + +announce RSI_SDIO - "Redpine Signals SDIO bus support" +reject_firmware drivers/net/wireless/rsi/rsi_91x_sdio_ops.c +clean_blob drivers/net/wireless/rsi/rsi_91x_sdio.c +clean_kconfig drivers/net/wireless/rsi/Kconfig 'RSI_SDIO' +clean_mk CONFIG_RSI_SDIO drivers/net/wireless/rsi/Makefile + +announce RSI_USB - "Redpine Signals USB bus support" +reject_firmware drivers/net/wireless/rsi/rsi_91x_usb_ops.c +clean_blob drivers/net/wireless/rsi/rsi_91x_usb.c +clean_kconfig drivers/net/wireless/rsi/Kconfig 'RSI_USB' +clean_mk CONFIG_RSI_USB drivers/net/wireless/rsi/Makefile + announce RT2X00_LIB_FIRMWARE - "Ralink driver firmware support" reject_firmware drivers/net/wireless/rt2x00/rt2x00firmware.c clean_kconfig drivers/net/wireless/rt2x00/Kconfig 'RT2X00_LIB_FIRMWARE' @@ -1828,6 +1899,11 @@ clean_blob drivers/net/wireless/rt2x00/rt2800usb.c clean_kconfig drivers/net/wireless/rt2x00/Kconfig RT2800USB clean_mk CONFIG_RT2800USB drivers/net/wireless/rt2x00/Makefile +announce RTLWIFI - "Realtek Wireless Network Adapters" +reject_firmware drivers/net/wireless/rtlwifi/core.c +clean_kconfig drivers/net/wireless/rtlwifi/Kconfig RTLWIFI +clean_mk CONFIG_RTLWIFI drivers/net/wireless/rtlwifi/Makefile + announce RTL8188EE - "Realtek RTL8188EE Wireless Network Adapter" reject_firmware drivers/net/wireless/rtlwifi/rtl8188ee/sw.c clean_blob drivers/net/wireless/rtlwifi/rtl8188ee/sw.c @@ -1868,12 +1944,16 @@ clean_mk CONFIG_RTL8192SE drivers/net/wireless/rtlwifi/rtl8192se/Makefile announce RTL8192E - "RealTek RTL8192E Wireless LAN NIC driver" reject_firmware drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c clean_blob drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.h -clean_blob drivers/staging/rtl8192e/rtl8192e/r8192E_firmware.c -clean_blob drivers/staging/rtl8192e/rtl8192e/r8192E_hwimg.c clean_blob drivers/staging/rtl8192e/rtl8192e/rtl_core.c clean_kconfig drivers/staging/rtl8192e/Kconfig RTL8192E clean_mk CONFIG_RTL8192E drivers/staging/rtl8192e/Makefile +announce R8192EE - "RealTek RTL8192EE Wireless Network Adapter" +reject_firmware drivers/staging/rtl8192ee/rtl8192ee/sw.c +clean_blob drivers/staging/rtl8192ee/rtl8192ee/sw.c +clean_kconfig drivers/staging/rtl8192ee/Kconfig R8192EE +clean_mk CONFIG_R8192EE drivers/staging/rtl8192ee/Makefile + announce RTL8192U - "RealTek RTL8192U Wireless LAN NIC driver" reject_firmware drivers/staging/rtl8192u/r819xU_firmware.c clean_blob drivers/staging/rtl8192u/r819xU_firmware.c @@ -1892,6 +1972,25 @@ clean_blob drivers/net/wireless/rtlwifi/rtl8723ae/sw.c clean_kconfig drivers/net/wireless/rtlwifi/Kconfig 'RTL8723AE' clean_mk CONFIG_RTL8723AE drivers/net/wireless/rtlwifi/rtl8723ae/Makefile +announce R8723AU - "RealTek RTL8723AU Wireless LAN NIC driver" +reject_firmware drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c +clean_blob drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c +clean_blob drivers/staging/rtl8723au/os_dep/os_intfs.c +clean_kconfig drivers/staging/rtl8723au/Kconfig 'R8723AU' +clean_mk CONFIG_R8723AU drivers/staging/rtl8723au/Makefile + +announce RTL8723BE - "Realtek RTL8723BE PCIe Wireless Network Adapter" +reject_firmware drivers/net/wireless/rtlwifi/rtl8723be/sw.c +clean_blob drivers/net/wireless/rtlwifi/rtl8723be/sw.c +clean_kconfig drivers/net/wireless/rtlwifi/Kconfig 'RTL8723BE' +clean_mk CONFIG_RTL8723BE drivers/net/wireless/rtlwifi/rtl8723be/Makefile + +announce R8821AE - "Realtek RTL8821AE Wireless LAN NIC driver" +reject_firmware drivers/staging/rtl8821ae/rtl8821ae/sw.c +clean_blob drivers/staging/rtl8821ae/rtl8821ae/sw.c +clean_kconfig drivers/staging/rtl8821ae/Kconfig 'R8821AE' +clean_mk CONFIG_R8821AE drivers/staging/rtl8821ae/Makefile + announce VT6656 - "VIA Technologies VT6656 support" reject_firmware drivers/staging/vt6656/firmware.c clean_blob drivers/staging/vt6656/firmware.c @@ -1981,6 +2080,12 @@ clean_blob Documentation/btmrvl.txt clean_kconfig drivers/bluetooth/Kconfig 'BT_MRVL_SDIO' clean_mk CONFIG_BT_MRVL_SDIO drivers/bluetooth/Makefile +announce BT_NOKIA_H4P - "HCI driver with H4 Nokia extensions" +reject_firmware drivers/staging/nokia_h4p/nokia_fw.c +clean_blob drivers/staging/nokia_h4p/nokia_fw.c +clean_kconfig drivers/staging/nokia_h4p/Kconfig 'BT_NOKIA_H4P' +clean_mk CONFIG_BT_NOKIA_H4P drivers/staging/nokia_h4p/Makefile + announce TI_ST - "Texas Instruments shared transport line discipline" reject_firmware drivers/misc/ti-st/st_kim.c clean_blob drivers/misc/ti-st/st_kim.c @@ -2067,6 +2172,12 @@ clean_mk CONFIG_MISDN_SPEEDFAX drivers/isdn/hardware/mISDN/Makefile # Serial # ########## +announce DGAP - "Digi EPCA PCI products" +reject_firmware drivers/staging/dgap/dgap.c +clean_blob drivers/staging/dgap/dgap.c +clean_kconfig drivers/staging/dgap/Kconfig 'DGAP' +clean_mk CONFIG_DGAP drivers/staging/dgap/Makefile + announce SERIAL_8250_CS - "8250/16550 PCMCIA device support" # These are not software; they're Free, but GPLed without in-tree sources. drop_fw_file firmware/cis/MT5634ZLX.cis.ihex firmware/cis/MT5634ZLX.cis @@ -2409,6 +2520,12 @@ clean_blob drivers/usb/serial/io_ti.c clean_kconfig drivers/usb/serial/Kconfig 'USB_SERIAL_EDGEPORT_TI' clean_mk CONFIG_USB_SERIAL_EDGEPORT_TI drivers/usb/serial/Makefile +announce USB_SERIAL_MXUPORT - "USB Moxa UPORT Serial Driver" +reject_firmware drivers/usb/serial/mxuport.c +clean_blob drivers/usb/serial/mxuport.c +clean_kconfig drivers/usb/serial/Kconfig 'USB_SERIAL_MXUPORT' +clean_mk CONFIG_USB_SERIAL_MXUPORT drivers/usb/serial/Makefile + announce USB_SERIAL_TI - "USB TI 3410/5052 Serial Driver" drop_fw_file firmware/ti_3410.fw.ihex firmware/ti_3410.fw drop_fw_file firmware/ti_5052.fw.ihex firmware/ti_5052.fw @@ -2703,9 +2820,25 @@ clean_blob sound/soc/codecs/adau1701.c clean_kconfig sound/soc/codecs/Kconfig 'SND_SOC_ADAU1701' clean_mk CONFIG_SND_SOC_ADAU1701 sound/soc/codecs/Makefile +announce SND_SOC_ADAU1761 - "ADAU1761 SigmaDSP processor" +clean_blob sound/soc/codecs/adau1761.c +clean_kconfig sound/soc/codecs/Kconfig 'SND_SOC_ADAU1761' +clean_mk CONFIG_SND_SOC_ADAU1761 sound/soc/codecs/Makefile + +announce SND_SOC_ADAU1781 - "ADAU1781 SigmaDSP processor" +clean_blob sound/soc/codecs/adau1781.c +clean_kconfig sound/soc/codecs/Kconfig 'SND_SOC_ADAU1781' +clean_mk CONFIG_SND_SOC_ADAU1781 sound/soc/codecs/Makefile + announce SND_SOC_SIGMADSP - "SigmaStudio firmware loader" maybe_reject_firmware sound/soc/codecs/sigmadsp.c +announce SND_SOC_INTEL_SST_ACPI - "Intel SST (LPE) Driver" +reject_firmware sound/soc/intel/sst-acpi.c +clean_blob sound/soc/intel/sst-acpi.c +clean_kconfig sound/soc/intel/Kconfig 'SND_SOC_INTEL_SST_ACPI' +clean_mk 'CONFIG_SND_SOC_INTEL_SST_ACPI' sound/soc/intel/Makefile + announce SND_SOC_WM0010 - "WM0010 DSP driver" reject_firmware sound/soc/codecs/wm0010.c clean_blob sound/soc/codecs/wm0010.c diff --git a/freed-ora/current/master/deblob-check b/freed-ora/current/master/deblob-check index 9e7457d85..20bb408c0 100755 --- a/freed-ora/current/master/deblob-check +++ b/freed-ora/current/master/deblob-check @@ -1,6 +1,6 @@ #! /bin/sh -# deblob-check version 2014-06-08 +# deblob-check version 2014-08-07 # Inspired in gNewSense's find-firmware script. # Written by Alexandre Oliva <lxoliva@fsfla.org> @@ -3485,8 +3485,8 @@ set_except () { defsnc '__visible[ ]const[ ]u64[ ]camellia_sp\(10011110\|22000222\|03303033\|00444404\|02220222\|30333033\|44044404\|11101110\)\[256\][ ]=' arch/x86/crypto/camellia_glue.c defsnc '__visible[ ]const[ ]u32[ ]crypto_[fi][tl]_tab\[4\]\[256\][ ]=' crypto/aes_generic.c defsnc '__visible[ ]const[ ]u32[ ]cast_s[1234]\[256\][ ]=' crypto/cast_common.c - defsnc '[ ]*interrupts[ ]=[ ]<[ ]*\(0[ ]2[012][0-9][ ]4[ \n]*\)*>[;]' Documentation/devicetree/bindings/dma/shdma.txt - defsnc '[ ][ ]interrupts[ ]=[ ]<\([\n][ ]*0x\([ef]\|1[01]\)[0-9a-f][ ]0[ ]0[ ]0\)*>[;]' Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt + accept '[ ]*interrupts[ ]=[ ]<[ ]*\(0[ ]2[012][0-9][ ]4[ \n]*\)*>[;]' Documentation/devicetree/bindings/dma/shdma.txt + accept '[ ][ ]interrupts[ ]=[ ]<\([\n][ ]*0x\([ef]\|1[01]\)[0-9a-f][ ]0[ ]0[ ]0\)*>[;]' Documentation/devicetree/bindings/powerpc/fsl/msi-pic.txt defsnc 'static[ ]const[ ]int[ ]a370_\(nb\|h\|dram\)clk_ratios\[32\]\[2\][ ]__initconst[ ]=' drivers/clk/mvebu/armada-370.c defsnc 'static[ ]const[ ]int[ ]axp_\(nb\|h\|dram\)clk_ratios\[32\]\[2\][ ]__initconst[ ]=' drivers/clk/mvebu/armada-xp.c defsnc 'static[ ]const[ ]int[ ]\(dove\|kirkwood\)_cpu_ddr_ratios\[16\]\[2\][ ]__initconst[ ]=' drivers/clk/mvebu/clk-core.c @@ -3592,6 +3592,171 @@ set_except () { blobname '%s%s\.ucode' drivers/net/wireless/iwlwifi/iwl-drv.c blobname 'ti-connectivity[/]wl18xx-fw-3\.bin' drivers/net/wireless/ti/wl18xx/main.c blobname 'ql2700_fw\.bin' drivers/scsi/qla2xxx/qla_os.c + + # New in 3.16 + defsnc '[\t]*atmel[,]pll-clk-output-ranges[ ]=[ ]<' 'Documentation/devicetree/bindings/clock/at91-clock\.txt\|arch/arm/boot/dts/at91sam9x5\.dtsi' + blobname 'imx[/]sdma[/]sdma-imx25\.bin' arch/arm/boot/dts/imx25.dtsi + blobname 'imx[/]sdma[/]sdma-imx35\.bin' arch/arm/boot/dts/imx35.dtsi + blobname 'imx[/]sdma[/]sdma-imx50\.bin' arch/arm/boot/dts/imx50.dtsi + blobname 'sdma-imx53\.bin' arch/arm/boot/dts/imx53-tx53.dtsi + defsnc 'struct[ ]sock_filter[ ]code\[\][ ]=' Documentation/networking/filter.txt + initnc '\.L\(Forward\|Reverse\)_Sbox:[\n][\t]\.byte[\t]*' arch/arm64/crypto/aes-neon.S + initnc '\.Lsha2_rcon:[\n][\t]\.word[\t]*' arch/arm64/crypto/sha2-ce-core.S + defsnc 'static[ ]const[ ]u8[ ]sata_phy_config[12]\[\][ ]*=' arch/mips/netlogic/xlp/ahci-init-xlp2.c + accept '[ ]*interrupts[ ]=[ ]<108[ ]0\([\n][ ]*1[012][0-9][ ]0\)*>[;]' arch/powerpc/boot/dts/akebono.dts + defsnc '[\t]static[ ]int[ ]sysdiv_code_to_x2\[\][ ]=' arch/powerpc/platforms/512x/clock-commonclk.c + accept '[#][#][ ]*0[ ]1[ ]2[ ]3[ ]4[ ]5[ ]6[ ]7[ ]8[ ]9[ ]0[ ]1[ ]2[ ]3[ ]4[ ]5[ ]6[ ]7[ ]8[ ]9[ ]0[ ]1[ ]2[ ]3[ ]4[ ]5[ ]6[ ]7[ ]8[ ]9[ ]0[ ]1' arch/x86/crypto/aesni-intel_avx-x86_64.S + defsc 'static[ ]struct[ ]aead_testvec[ ]hmac_sha\(1\|224\|256\|384\|512\)_\(aes\|des\|des3_ede\)_cbc_enc_tv_temp\[\][ ]=' crypto/testmgr.h + accept '#define[ \t]*ACPI_TABLE_FILE_SUFFIX[\t ]*["]\.dat["]' drivers/acpi/acpica/acapps.h + accept '[ ][*][ ]request_firmware\(_direct\)\?:[ ]-[ ]load[ ]firmware[ ]directly[ ]without[ ]usermode[ ]helper' drivers/base/firmware_class.c + accept '[ ][*][ ]This[ ]function[ ]works[ ]pretty[ ]much[ ]like[ ]request_firmware[(][)]' drivers/base/firmware_class.c + accept 'int[ ]request_firmware_direct[(]' 'drivers/base/firmware_class\.c\|include/linux/firmware\.h' + accept '[\t]ret[ ]=[ ]_request_firmware[(]firmware_p[,][ ]name[,][ ]device[,][ ]FW_OPT_UEVENT[)][;]' drivers/base/firmware_class.c + accept 'EXPORT_SYMBOL_GPL[(]request_firmware_direct[)][;]' drivers/base/firmware_class.c + defsnc 'static[ ]const[ ]int[ ]armada_375_cpu_\(l2\|ddr\)_ratios\[32\]\[2\][ ]__initconst[ ]=[ ]' drivers/clk/mvebu/armada-375.c + defsnc 'static[ ]const[ ]int[ ]armada_38x_cpu_\(l2\|ddr\)_ratios\[32\]\[2\][ ]__initconst[ ]=[ ]' drivers/clk/mvebu/armada-38x.c + defsnc 'static[ ]struct[ ]cpufreq_frequency_table[ ]s3c64xx_freq_table\[\][ ]=' drivers/cpufreq/s3c64xx-cpufreq.c + defsnc 'static[ ]const[ ]u8[ ]ccp_sha\(1\|224\|256\)_zero\[CCP_SHA_CTXSIZE\][ ]=' drivers/crpto/ccp/ccp-ops.c + blobname 'ast_dp501_fw\.bin' drivers/gpu/drm/ast/ast_dp501.c + accept '[\t]["]edid[/]\(800x600\)\.bin["]' drivers/gpu/drm/drm_edid_load.c + defsnc 'static[ ]void[ ][*]edid_load[(][^)]*[)][\n][{]\([\n]\+[^\n}][^\n]*\)*[^\n]*err[ ]=[ ]request_firmware[(][&]fw[,][ ]name[,][ ][&]pdev' drivers/gpu/drm/drm_edid_load.c + defsnc 'static[ ]const[ ]struct[ ]hdmiphy_config[ ]hdmiphy_5420_configs\[\][ ]=' drivers/gpu/drm/exynos/exynos_hdmi.c + # These seem too sparse to be code. + defsnc 'static[ ]const[ ]u32[ ]gen6_null_state_batch\[\][ ]=' drivers/gpu/drm/i915/intel_renderstate_gen6.c + defsnc 'static[ ]const[ ]u32[ ]gen7_null_state_batch\[\][ ]=' drivers/gpu/drm/i915/intel_renderstate_gen7.c + defsnc 'static[ ]const[ ]u32[ ]gen8_null_state_batch\[\][ ]=' drivers/gpu/drm/i915/intel_renderstate_gen8.c + defsnc 'nv50_disp_\(mast_mthd_head\|\(sync\|ovly\)_mthd_base\)[ ]=' drivers/gpu/drm/nouveau/core/engine/disp/nv50.c + defsnc 'nv84_disp_\(mast_mthd_head\|\(sync\|ovly\)_mthd_base\)[ ]=' drivers/gpu/drm/nouveau/core/engine/disp/nv84.c + defsnc 'nva0_disp_ovly_mthd_base[ ]=' drivers/gpu/drm/nouveau/core/engine/disp/nva0.c + defsnc 'nvd0_disp_\(mast_mthd_head\|\(sync\|ovly\)_mthd_base\)[ ]=' drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c + defsnc 'nve0_disp_\(mast_mthd_head\|ovly_mthd_base\)[ ]=' drivers/gpu/drm/nouveau/core/engine/disp/nve0.c + defsnc 'gm107_grctx_init_\(\(icmd\|b097\|fe\|ds\|pd\|be\|setup\|tex\|mpc\|sm\|wwdx\)_0\|gpc_unk_2\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c + defsnc 'nv108_grctx_init_\(icmd\|fe\|ds\|pd\|rstr2d\|be\|prop\|setup\|crstr\|tex\|sm\)_0\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/ctxnv108.c + defsnc 'nvc0_grctx_init_\(icmd\|9097\|902d\|90c0\|fe\|memfmt\|rstr2d\|prop\|setup\|crstr\|zcullr\|wwdx\|sm\)_0\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c + defsnc 'nvc1_grctx_init_\(icmd\|9097\|setup\|wwdx\|tex\|sm\)_0\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c + defsnc 'nvc4_grctx_init_\(tex\|sm\)_0\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc4.c + defsnc 'nvc8_grctx_init_\(icmd\|setup\)_0\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc8.c + defsnc 'nvd7_grctx_init_\(ds\|pd\|setup\|tex\|wwdx\)_0\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c + defsnc 'nvd9_grctx_init_\(icmd\|90c0\|fe\|ds\|prop\|setup\|crstr\|tex\|sm\)_0\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c + defsnc 'nve4_grctx_init_\(icmd\|a097\|fe\|memfmt\|ds\|pd\|be\|setup\|tex\|sm\)_0\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/ctxnve4.c + defsnc 'nvf0_grctx_init_\(icmd\|a197\|fe\|pd\|be\|setup\|tex\|sm\)_0\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/ctxnvf0.c + defsnc 'uint32_t[ ]gm107_grgpc_code\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcgm107.fuc5.h + defsnc 'uint32_t[ ]nv108_grgpc_code\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/fuc/gpcnv108.fuc5.h + defsnc 'uint32_t[ ]gm107_grhub_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubgm107.fuc5.h + defsnc 'uint32_t[ ]nv108_grhub_\(data\|code\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/fuc/hubnv108.fuc5.h + defsnc 'gm107_graph_init_\(main\|tpccs\|tex\|sm\|be\)_0\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/gm107.c + defsnc 'nv108_graph_init_\(main\|l1c\)_0\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/nv108.c + defsnc 'nvc4_graph_init_sm_0\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/nvc4.c + defsnc 'nvc8_graph_init_sm_0\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/nvc8.c + defsnc 'nvd9_graph_init_\(gpc_unk_1\|sm_0\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/nvd9.c + defsnc 'nve4_graph_init_\(\(main\|l1c\|sm\|be\)_0\|gpc_unk_1\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/nve4.c + defsnc 'nvf0_graph_init_\(\(l1c\|sm\)_0\|gpc_unk_1\)\[\][ ]=' drivers/gpu/drm/nouveau/core/engine/graph/nvf0.c + defsnc 'static[ ]u8[ ]const[ ]ld9040_gammas\[25\]\[22\][ ]=' drivers/gpu/drm/panel/panel-ld9040.c + defsnc 'static[ ]void[ ]s6e8aa0_panel_cond_set[(][^)]*[)][\n][{]\([\n]\+[^\n}][^\n]*\)*[^\n]*s6e8aa0_dcs_write_seq_static[(]ctx[,][\n\t0x0-9a-f, ]*[)][;]' drivers/gpu/drm/panel/panel-s6e8aa0.c + defsnc 'static[ ]const[ ]s6e8aa0_gamma_table[ ]s6e8aa0_gamma_tables_v\(142\|96\|32\)\[GAMMA_LEVEL_NUM\][ ]=' drivers/gpu/drm/panel/panel-s6e8aa0.c + blobname 'radeon[/]BONAIRE_vce\.bin' drivers/gpu/drm/radeon/radeon_vce.c + defsnc '[\t]static[ ]const[ ]__u8[ ]sixaxis_leds\[10\]\[4\][ ]=' drivers/hid/hid-sony.c + defsnc '[\t]union[ ]sixaxis_output_report_01[ ]report[ ]=' drivers/hid/hid-sony.c + defsnc 'static[ ]int[ ]twl4030_therm_tbl\[\][ ]=' drivers/iio/adc/twl4030-madc.c + defsnc 'static[ ]struct[ ]linear_segments[ ]strength_to_db_table\[\][ ]=' drivers/media/dvb-frontends/dib8000.c + blobname 'dvb-fe-drxj-mc-1\.0\.8\.fw' drivers/media/dvb-frontends/drx39xyj/drxj.c + defsnc 'static[ ]const[ ]u16[ ]nicam_presc_table_val\[43\][ ]=' drivers/media/dvb-frontends/drx39xyj/drxj.c + accept '[\t][\t]*demod->firmware[ ]=[ ]\(fw\|NULL\)[;]' drivers/media/dvb-frontends/drx39xyj/drxj.c + blobname 'dvb-demod-m88ds3103\.fw' drivers/media/dvb-frontends/m88ds3103_priv.h + defsnc 'static[ ]const[ ]struct[ ]m88ds3103_reg_val[ ]m88ds3103_dvbs2\?_init_reg_vals\[\][ ]=' drivers/media/dvb-frontends/m88ds3103_priv.h + blobname 'dvb-demod-si2168-02\.fw' drivers/media/dvb-frontends/si2168_priv.h + blobname 's5k5baf-cfg\.bin' drivers/media/i2c/s5k5baf.c + defsnc 'static[ ]const[ ]u16[ ]scaler_[hv]s_coeffs\[1[35]\]\[SC_NUM_PHASES[ ][*][ ]2[ ][*][ ]SC_[HV]_NUM_TAPS\][ ]=' drivers/media/platform/ti-vpe/sc_coeff.h + defsnc 'static[ ]const[ ]struct[ ]si4713_start_seq_table[ ]start_seq\[\][ ]=' drivers/media/radio/si4713/radio-usb-si4713.c + defsnc 'static[ ]const[ ]struct[ ]e4000_if_gain[ ]e4000_if_gain_lut\[\][ ]=' drivers/media/tuners/e4000_priv.h + defsnc 'static[ ]const[ ]struct[ ]dtcs033_usb_requests[ ]dtcs033_start_reqs\[\][ ]=' drivers/media/usb/gspca/dtcs033.c + defsnc 'static[ ]struct[ ]idxdata[ ]tbl_\(\(middle\|end\)_hvflip\(_\(low\|big\)\)\?\|init_post_alt_\(low[123]\|big\|3B\)\)\[\][ ]=' drivers/media/usb/gspca/gl860/gl860-mi2020.c + defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm5110_revd_patch\[\][ ]=' drivers/mfd/wm5110-tables.c + defsnc 'static[ ]const[ ]u32[ ]tuning_block_128\[\][ ]=' drivers/mmc/host/sdhci-msm.c + defsnc 'static[ ]struct[ ]nand_ecclayout[ ]hwecc4_2048[ ]=' drivers/mtd/nand/davinci_nand.c + defsnc 'static[ ]struct[ ]nand_ecclayout[ ]ecc_layout_[24]KB_bch[48]bit[ ]=' drivers/mtd/nand/pxa3xx_nand.c + defsnc '[\t]static[ ]char[ ]packet\[\][ ]=' drivers/net/ethernet/intel/i40e/i40e_txrx.c + defsnc 'u8[ ]netvsc_hash_key\[HASH_KEYLEN\][ ]=' drivers/net/hyperv/rndis_filter.c + defsnc 'static[ ]const[ ]u32[ ]ar9300Modes_high_power_tx_gain_table_buffalo\[\]\[5\][ ]=' drivers/net/wireless/ath/ath9k/ar9003_buffalo_initvals.h + defsnc 'static[ ]const[ ]u32[ ]ar9340_cus227_tx_gain_table_1p0\[\]\[5\][ ]=' drivers/net/wireless/ath/ath9k/ar9340_initvals.h + defsnc 'static[ ]const[ ]u32[ ]ar9462_2p0_common_\(mixed_\)\?rx_gain\[\]\[2\][ ]=' drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h + defsnc 'static[ ]const[ ]u32[ ]ar9462_2p0_modes_\(low\|mix\|high\)_ob_db_tx_gain\[\]\[5\][ ]=' drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h + defsnc 'static[ ]const[ ]u32[ ]qca953x_1p[01]_\(\(mac\|baseband\|radio\)_core\|modes_\(no_\)\?xpa_tx_gain_table\)\[\]\[2\][ ]=' drivers/net/wireless/ath/ath9k/ar953x_initvals.h + defsnc 'static[ ]const[ ]u32[ ]qca953x_1p0_\(baseband\|radio\)_postamble\[\]\[5\][ ]=' drivers/net/wireless/ath/ath9k/ar953x_initvals.h + accept '[ ]err[ ]=[ ]request_firmware_nowait[(][^\n]*,[ ]CARL9170FW_NAME,' drivers/net/wireless/carl9170/usb.c + defsnc 'static[ ]const[ ]struct[ ]b43_nphy_channeltab_entry_rev3[ ]b43_nphy_channeltab_\(phy\|radio\)_rev\([34568]\|7_9\|11\)\[\][ ]=' drivers/net/wireless/b43/radio_2056.c + defsnc 'static[ ]const[ ]u32[ ]b43_ntab_noisevar_r3\[\][ ]=' drivers/net/wireless/b43/tables_nphy.c + blobname 'iwlwifi-8000-' drivers/net/wireless/iwlwifi/iwl-8000.c + blobname 'iwl_nvm_8000\.bin' drivers/net/wireless/iwlwifi/iwl-8000.c + defsnc 'static[ ]const[ ]u8[ ]iwl_nvm_channels_family_8000\[\][ ]=' drivers/net/wireless/iwlwifi/iwl-nvm-parse.c + defsnc 'static[ ]const[ ]u16[ ]expected_tpt_\(siso\|mimo2\)_[248]0MHz\[4\]\[IWL_RATE_COUNT\][ ]=' drivers/net/wireless/iwlwifi/mvm/rs.c + blobname 'rsi_91x\.fw' drivers/net/wireless/rsi/rsi_common.h + defsnc 'static[ ]const[ ]u32[ ]RF_GAIN_TABLE\[\][ ]=' drivers/net/wireless/rtl818x/rtl8180/rtl8225se.c + defsnc 'static[ ]const[ ]u8[ ]\(cck_ofdm_gain_settings\|rtl8225se_tx_power_cck\(_ch14\)\?\|ZEBRA_AGC\|OFDM_CONFIG\)\[\][ ]=' drivers/net/wireless/rtl818x/rtl8180/rtl8225se.c + defsnc '[\t]u16[ ]toshiba_smid1\[\][ ]=' drivers/net/wireless/rtlwifi/rtl8723be/hw.c + blobname 'rtlwifi[/]rtl8723befw\.bin' drivers/net/wireless/rtlwifi/rtl8723be/sw.c + defsnc 'u32[ ]RTL8723BE\(PHY_REG\|_RADIOA\|MAC\|AGCTAB\)_\(1T_\?ARRAY\|ARRAY_PG\)\[\][ ]=' drivers/net/wireless/rtlwfi/rtl8723be/table.c + defsnc 'static[ ]\(const[ ]unsigned[ ]\)\?int[ ]tps65864[03]_sm2_voltages\[\][ ]=' drivers/regulator/tps6586x-regulator.c + defsnc 'static[ ]const[ ]uint32_t[ ]ql27xx_fwdt_default_template\[\][ ]=' drivers/scsi/qla2xxx/qla_tmpl.c + blobname 'dgap[/]\(sx\|cxp\|pci\|xr\)\(bios\|fep\)\.bin' drivers/staging/dgap/dgap.c + accept '[\t][ ]*kernel[ ]firmware[ ]framework[,][ ]request_firmware[(][)]' drivers/staging/gs_fpgaboot/README + defsnc 'static[ ]u8[ ]ecctable\[256\][ ]=' drivers/staging/keucr/smilecc.c + defsnc '[\t]u8[ ]data_ptr\[36\][ ]=' drivers/staging/keucr/smscsi.c + # This is a default for the user-supplied fpga configuration; it + # is overridable with a module parameter. + accept 'static[ ]char[ \t]*[*]file[ ]=[ ]["]xlinx_fpga_firmware\.bit["][;]' drivers/staging/gs_fpgaboot/gs_fpgaboot.c + accept '[\t]pr_info[(]["]load[ ]fpgaimage[ ]%s[\\]n["][,][ ]file[)][;][\n]*[\t]err[ ]=[ ]request_firmware[(][&]fimage->fw_entry[,]' drivers/staging/gs_fpgaboot/gs_fpgaboot.c + blobname '\(ti1273\(_\(pre\)\?le\)\?\|bc[m4]fw\)\.bin' drivers/staging/nokia_h4p/nokia_fw.c + defsnc '[\t]u8[ ]channel5g\[CHANNEL_MAX_NUMBER_5G\][ ]=' drivers/staging/rtl8192ee/rtl8192ee/hw.c + blobname 'rtlwifi[/]rtl8192eefw\.bin' drivers/staging/rtl8192ee/rtl8192ee/sw.c + defsnc 'u32[ ]RTL8192EE_\(PHY_REG\|RADIO[AB]\|MAC\|AGC_TAB\)_ARRAY\(_PG\)\?\[\][ ]=' drivers/staging/rtl8192ee/rtl8192ee/table.c + defsnc '[\t]u8[ ]Channel_5G\[45\][ ]=' drivers/staging/rtl8723au/core/rtw_mlme_ext.c + defsnc 'static[ ]const[ ]unsigned[ ]short[ ]Sbox1\[2\]\[256\]=' drivers/staging/rtl8723au/core/rtw_security.c + defsnc 'u32[ ]Rtl8723UPHY_REG_Array_PG\[Rtl8723UPHY_REG_Array_PGLength\][ ]=' drivers/staging/rtl8723au/hal/Hal8723UHWImg_CE.c + defsnc 'static[ ]u32[ ]Array_\(AGC_TAB\|PHY_REG\)_\(1T\|PG\)_8723A\[\][ ]=' drivers/staging/rtl8723au/hal/HalHWImg8723A_BB.c + defsnc 'static[ ]u32[ ]Array_MAC_REG_8723A\[\][ ]=' drivers/staging/rtl8723au/hal/HalHWImg8723A_MAC.c + defsnc 'static[ ]u32[ ]Array_RadioA_1T_8723A\[\][ ]=' drivers/staging/rtl8723au/hal/HalHWImg8723A_RF.c + blobname 'rtlwifi[/]rtl8723aufw_\(A\|B\(_NoBT\)\?\)\.bin' drivers/staging/rtl8723au/hal/rtl8723a_hal_init.c + defsnc 'u8[ ]rtl88\(12\|21\)ae_delta_swing_table_idx_5g[ab]_[np]_txpwrtrack\[\]\[DELTA_SWINGIDX_SIZE\][ ]=' drivers/staging/rtl8821ae/rtl8821ae/dm.c + defsnc 'static[ ]u8[ ]reserved_page_packet_8821\[TOTAL_RESERVED_PKT_LEN_8821\][ ]=' drivers/staging/rtl8821ae/rtl8821ae/fw.c + defsnc 'static[ ]u8[ ]reserved_page_packet_8812\[TOTAL_RESERVED_PKT_LEN_8812\][ ]=' drivers/staging/rtl8821ae/rtl8821ae/fw.c + defsnc '[\t]u8[ ]channel_5g\[CHANNEL_MAX_NUMBER_5G\][ ]=' 'drivers/staging/rtl8821ae/rtl8821ae/\(hw\|phy\)\.c' + defsnc '[\t]u8[ ]channel_all\[TARGET_CHNL_NUM_2G_5G_8812\][ ]=' drivers/staging/rtl8821ae/rtl8821ae/phy.c + blobname 'rtlwifi[/]rtl8821aefw\.bin' drivers/staging/rtl8821ae/rtl8821ae/sw.c + defsnc 'u32[ ]RTL88\(12\|21\)AE_\(\(PHY\|MAC\)_REG\|RADIO[AB]\|AGC_TAB\)_ARRAY\(_PG\)\?\[\][ ]=' drivers/staging/rtl8821ae/rtl8821ae/table.c + accept '#define[ ]CONFIG_PATH[\t]*["][/]etc[/]vntconfiguration[.]dat["]' drivers/staging/vt6656/device.h + defsnc 'static[ ]const[ ]u8[ ]TKIP_Sbox_\(Lower\|Upper\)\[256\][ ]=' drivers/staging/vt6656/tkip.c + blobname 'moxa[/]moxa-\(%04x\|[0-9a-f][0-9a-f][0-9a-f][0-9a-f]\)\.fw' drivers/usb/serial/mxuport.c + accept '#define[ \t]request_firmware_direct[ \t]request_firmware' include/linux/firmware.h + accept '[\t]report_missing_free_firmware[^\n]*[\n][\t]retval[ ]=[ ]request_firmware_direct[(]' include/linux/firmware.h + defsnc 'const[ ]u8[ ]crc7_be_syndrome_table\[256\][ ]=' lib/crc7.c + defsnc 'static[ ]struct[ ]bpf_test[ ]tests\[\][ ]=' lib/test_bpf.c + defsnc '[\t]static[ ]struct[ ]sock_filter[ ]ptp_filter\[\][ ]__initdata[ ]=' net/core/ptp_classifier.c + blobname 'adau1761\.bin' sound/soc/codecs/adau1761.c + accept '[\t][\t]ret[ ]=[ ]adau17x1_load_firmware[(]adau[,][ ]codec->dev[,][\n][\t ]*ADAU1761_FIRMWARE[)][;]' sound/soc/codecs/adau1761.c + blobname 'adau1[37]81\.bin' sound/soc/codecs/adau1781.c + accept '[\t][\t]firmware[ ]=[ ]ADAU1[37]81_FIRMWARE[;]\([\n][\n]*[\t][^\n]*\)*ret[ ]=[ ]adau17x1_load_firmware[(]adau[,][ ]codec->dev[,][ ]firmware[)][;]' sound/soc/codecs/adau1781.c + blobna 'adau17x1_load_firmware' sound/soc/codecs/adau17x1.c + accept 'int[ ]adau17x1_load_firmware[(]' 'sound/soc/codecs/adau17x1\.[ch]' + accept 'EXPORT_SYMBOL_GPL[(]adau17x1_load_firmware[)][;]' sound/soc/codecs/adau17x1.c + accept '[ ]*ret[ ]=[ ]process_sigma_firmware_regmap[(]dev[,][ ]adau->regmap[,][ ]firmware[)][;]' sound/soc/codecs/adau17x1.c + defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]adau1977_reg_defaults\[\][ ]=' sound/soc/codecs/adau1977.c + defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]ak4641_reg_defaults\[\][ ]=' sound/soc/codecs/ak4641.c + defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]ak464[28]_reg\[\][ ]=' sound/soc/codecs/ak4642.c + defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]rt5640_reg\[\][ ]=' sound/soc/codecs/rt5640.c + defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]rt5645_reg\[\][ ]=' sound/soc/codecs/rt5645.c + defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]rt5651_reg\[\][ ]=' sound/soc/codecs/rt5651.c + defsnc 'int[ ]_process_sigma_firmware[(]' sound/soc/codecs/sigmadsp.c + accept 'EXPORT_SYMBOL_GPL[(]_process_sigma_firmware[)]' sound/soc/codecs/sigmadsp.c + defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]sta350_regs\[\][ ]=' sound/soc/codecs/sta350.c + defsnc 'static[ ]const[ ]struct[ ]aic31xx_rate_divs[ ]aic31xx_divs\[\][ ]=' sound/soc/codecs/tlv320aic31xx.c + defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm5110_sysclk_revd_patch\[\][ ]=' sound/soc/codecs/wm5110.c + defsnc 'static[ ]const[ ]struct[ ]reg_default[ ]wm8974_reg_defaults\[\][ ]=' sound/soc/codecs/wm8974.c + blobname 'intel[/]IntcSST[12]\.bin' sound/soc/intel/sst-acpi.c + blobname 'intel[/]fw_sst_0f28\.bin-i2s_master' sound/soc/intel/sst-acpi.c + defsnc 'static[ ]unsigned[ ]char[ ]bcd2000_init_sequence\[\][ ]=' sound/usb/bcd2000/bcd2000.c + blobna '[ ][*][ ]xxd[ ]-r[ ]-p[ ]mXTXXX[^\n]*maxtouch\.fw[\n][ \t]*[*][/]' drivers/input/touchscreen/atmel_mxt_ts.c + blobname 's5p-mfc-v8\.fw' drivers/media/platform/s5p-mfc/s5p_mfc.c ;; */*freedo*.patch | */*logo*.patch) @@ -7591,7 +7756,19 @@ BAD regular expression: # Extract or otherwise munge... case /$input in *.tar*) - cmd="tar -xf - --to-command='echo \";/*begin \$TAR_FILENAME*/;\"; cat; echo; echo \";/*end \$TAR_FILENAME*/;\"'" + tarwrap=`mktemp -t deblob-check-tarwrap-XXXXXX` + tempfiles="$tempfiles $tarwrap" + + cat >> $tarwrap <<EOF +#! /bin/sh +echo='$echo' && +\$echo ";/*begin \$1*/;" && +cat && +echo && +\$echo ";/*end \$1*/;" +EOF + chmod +x $tarwrap + cmd="tar -xf - --to-command='$tarwrap \"\$TAR_FILENAME\"'" ;; *.patch | *.patch.*z* | */patch-* | *.diff | *.diff.*z*) if $reverse_patch; then diff --git a/freed-ora/current/master/defaults-acpi-video.patch b/freed-ora/current/master/defaults-acpi-video.patch deleted file mode 100644 index c1386c016..000000000 --- a/freed-ora/current/master/defaults-acpi-video.patch +++ /dev/null @@ -1,16 +0,0 @@ -Bugzilla: N/A -Upstream-status: Fedora mustard (but no idea why) - -diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c -index eaef02a..2029819 100644 ---- a/drivers/acpi/video.c -+++ b/drivers/acpi/video.c -@@ -69,7 +69,7 @@ MODULE_AUTHOR("Bruno Ducrot"); - MODULE_DESCRIPTION("ACPI Video Driver"); - MODULE_LICENSE("GPL"); - --static bool brightness_switch_enabled = 1; -+static bool brightness_switch_enabled = 0; - module_param(brightness_switch_enabled, bool, 0644); - - /* diff --git a/freed-ora/current/master/filter-i686.sh b/freed-ora/current/master/filter-i686.sh index 79072de11..7bc5b38d9 100644 --- a/freed-ora/current/master/filter-i686.sh +++ b/freed-ora/current/master/filter-i686.sh @@ -11,4 +11,4 @@ driverdirs="atm auxdisplay bcma bluetooth fmc infiniband isdn leds media memstick message mfd mmc mtd nfc ntb pcmcia platform power ssb staging uio uwb" -singlemods="ntb_netdev iscsi_ibft iscsi_boot_sysfs iscsi_tcp megaraid pmcraid qla1280 9pnet_rdma svcrdma xprtrdma hid-picolcd hid-prodikeys hwa-hc hwpoison-inject hid-sensor-hub hid-sensor-magn-3d hid-sensor-incl-3d hid-sensor-gyro-3d hid-sensor-iio-common hid-sensor-accel-3d hid-sensor-trigger hid-sensor-als" +singlemods="ntb_netdev iscsi_ibft iscsi_boot_sysfs iscsi_tcp megaraid pmcraid qla1280 9pnet_rdma svcrdma xprtrdma hid-picolcd hid-prodikeys hwa-hc hwpoison-inject hid-sensor-hub hid-sensor-magn-3d hid-sensor-incl-3d hid-sensor-gyro-3d hid-sensor-iio-common hid-sensor-accel-3d hid-sensor-trigger hid-sensor-als hid-sensor-rotation" diff --git a/freed-ora/current/master/ideapad-laptop-Blacklist-rfkill-control-on-the-Lenov.patch b/freed-ora/current/master/ideapad-laptop-Blacklist-rfkill-control-on-the-Lenov.patch deleted file mode 100644 index 86d608664..000000000 --- a/freed-ora/current/master/ideapad-laptop-Blacklist-rfkill-control-on-the-Lenov.patch +++ /dev/null @@ -1,73 +0,0 @@ -Bugzilla: N/A -Upstream-status: Sent upstream for 3.16 - -From ec5a006650d13c183124bd4279b95625f85efc6d Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 2 Jun 2014 17:41:00 +0200 -Subject: [PATCH 03/14] ideapad-laptop: Blacklist rfkill control on the Lenovo - Yoga 2 11 - -The Lenovo Yoga 2 11 always reports everything as blocked, causing userspace -to not even try to use the wlan / bluetooth even though they work fine. - -Note this patch also removes the "else priv->rfk[i] = NULL;" bit of the -rfkill initialization, it is not necessary as the priv struct is allocated -with kzalloc. - -Reported-and-tested-by: Vincent Gerris <vgerris@gmail.com> -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - drivers/platform/x86/ideapad-laptop.c | 23 ++++++++++++++++++----- - 1 file changed, 18 insertions(+), 5 deletions(-) - -diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c -index 6dd060a0bb65..219eb289a909 100644 ---- a/drivers/platform/x86/ideapad-laptop.c -+++ b/drivers/platform/x86/ideapad-laptop.c -@@ -36,6 +36,7 @@ - #include <linux/debugfs.h> - #include <linux/seq_file.h> - #include <linux/i8042.h> -+#include <linux/dmi.h> - - #define IDEAPAD_RFKILL_DEV_NUM (3) - -@@ -819,6 +820,19 @@ static void ideapad_acpi_notify(acpi_handle handle, u32 event, void *data) - } - } - -+/* Blacklist for devices where the ideapad rfkill interface does not work */ -+static struct dmi_system_id rfkill_blacklist[] = { -+ /* The Lenovo Yoga 2 11 always reports everything as blocked */ -+ { -+ .ident = "Lenovo Yoga 2 11", -+ .matches = { -+ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), -+ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Yoga 2 11"), -+ }, -+ }, -+ {} -+}; -+ - static int ideapad_acpi_add(struct platform_device *pdev) - { - int ret, i; -@@ -854,11 +868,10 @@ static int ideapad_acpi_add(struct platform_device *pdev) - if (ret) - goto input_failed; - -- for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) { -- if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) -- ideapad_register_rfkill(priv, i); -- else -- priv->rfk[i] = NULL; -+ if (!dmi_check_system(rfkill_blacklist)) { -+ for (i = 0; i < IDEAPAD_RFKILL_DEV_NUM; i++) -+ if (test_bit(ideapad_rfk_data[i].cfgbit, &priv->cfg)) -+ ideapad_register_rfkill(priv, i); - } - ideapad_sync_rfk_state(priv); - ideapad_sync_touchpad_state(priv); --- -1.9.0 - diff --git a/freed-ora/current/master/kernel-arm64.patch b/freed-ora/current/master/kernel-arm64.patch new file mode 100644 index 000000000..25f0479c8 --- /dev/null +++ b/freed-ora/current/master/kernel-arm64.patch @@ -0,0 +1,10179 @@ +commit db044807ca763c21bae298388239be6177c6ccec +Merge: 649c9e3 26bcd8b +Author: Kyle McMartin <kmcmarti@redhat.com> +Date: Wed Jul 30 14:31:24 2014 -0400 + + Merge branch 'master' into devel + + Conflicts: + virt/kvm/arm/vgic.c + +commit 649c9e3a45e81852daf80c126a332297b75cb109 +Author: Ard Biesheuvel <ard.biesheuvel@linaro.org> +Date: Tue Jul 29 12:49:10 2014 +0200 + + arm64/efi: efistub: don't abort if base of DRAM is occupied + + If we cannot relocate the kernel Image to its preferred offset of base of DRAM + plus TEXT_OFFSET, instead relocate it to the lowest available 2 MB boundary plus + TEXT_OFFSET. We may lose a bit of memory at the low end, but we can still + proceed normally otherwise. + + Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> + +commit 5102fd06b12467a0518537061805483a759bc856 +Author: Ard Biesheuvel <ard.biesheuvel@linaro.org> +Date: Tue Jul 29 12:49:09 2014 +0200 + + arm64/efi: efistub: cover entire static mem footprint in PE/COFF .text + + The static memory footprint of a kernel Image at boot is larger than the + Image file itself. Things like .bss data and initial page tables are allocated + statically but populated dynamically so their content is not contained in the + Image file. + + However, if EFI (or GRUB) has loaded the Image at precisely the desired offset + of base of DRAM + TEXT_OFFSET, the Image will be booted in place, and we have + to make sure that the allocation done by the PE/COFF loader is large enough. + + Fix this by growing the PE/COFF .text section to cover the entire static + memory footprint. The part of the section that is not covered by the payload + will be zero initialised by the PE/COFF loader. + + Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> + +commit 3b4dfb00a401b7fecf01d3c89b154907167dff52 +Author: Mark Rutland <mark.rutland@arm.com> +Date: Tue Jul 29 12:49:08 2014 +0200 + + arm64: spin-table: handle unmapped cpu-release-addrs + + In certain cases the cpu-release-addr of a CPU may not fall in the + linear mapping (e.g. when the kernel is loaded above this address due to + the presence of other images in memory). This is problematic for the + spin-table code as it assumes that it can trivially convert a + cpu-release-addr to a valid VA in the linear map. + + This patch modifies the spin-table code to use a temporary cached + mapping to write to a given cpu-release-addr, enabling us to support + addresses regardless of whether they are covered by the linear mapping. + + Signed-off-by: Mark Rutland <mark.rutland@arm.com> + +commit a49ad891b2e91338587dc5576c9da73b249a9d13 +Author: Mark Salter <msalter@redhat.com> +Date: Mon Jul 14 15:52:06 2014 -0400 + + pci/xgene: use pci_remap_iospace() instead of pci_ioremap_io() + + Signed-off-by: Mark Salter <msalter@redhat.com> + +commit 1a958ec71db226d35ed51756b7164142bb0a60a3 +Author: Tanmay Inamdar <tinamdar@apm.com> +Date: Wed Mar 19 16:12:42 2014 -0700 + + MAINTAINERS: entry for APM X-Gene PCIe host driver + + Add entry for AppliedMicro X-Gene PCIe host driver. + + Signed-off-by: Tanmay Inamdar <tinamdar@apm.com> + +commit 03dc92f35b8f8be898ca12e3dc7c15961f414907 +Author: Tanmay Inamdar <tinamdar@apm.com> +Date: Wed Mar 19 16:12:41 2014 -0700 + + dt-bindings: pci: xgene pcie device tree bindings + + This patch adds the bindings for X-Gene PCIe driver. The driver resides + under 'drivers/pci/host/pci-xgene.c' file. + + Signed-off-by: Tanmay Inamdar <tinamdar@apm.com> + +commit 1f8d894f2066d9db2b251d512f6f6f772ae7147f +Author: Tanmay Inamdar <tinamdar@apm.com> +Date: Wed Mar 19 16:12:40 2014 -0700 + + arm64: dts: APM X-Gene PCIe device tree nodes + + This patch adds the device tree nodes for APM X-Gene PCIe controller and + PCIe clock interface. Since X-Gene SOC supports maximum 5 ports, 5 dts + nodes are added. + + Signed-off-by: Tanmay Inamdar <tinamdar@apm.com> + +commit c0855fcf0cc9adcb1ba5e6b1318536c56244796d +Author: Tanmay Inamdar <tinamdar@apm.com> +Date: Wed Mar 19 16:12:39 2014 -0700 + + pci: APM X-Gene PCIe controller driver + + This patch adds the AppliedMicro X-Gene SOC PCIe controller driver. + X-Gene PCIe controller supports maximum up to 8 lanes and GEN3 speed. + X-Gene SOC supports maximum 5 PCIe ports. + + Signed-off-by: Tanmay Inamdar <tinamdar@apm.com> + +commit 1cc0c322237d3b58b08fe39e79e6c2e2f90a8c98 +Author: Liviu Dudau <Liviu.Dudau@arm.com> +Date: Tue Jul 1 19:44:00 2014 +0100 + + arm64: Add architectural support for PCI + + Use the generic host bridge functions to provide support for + PCI Express on arm64. + + Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com> + +commit aba1eca911a87959eb4be515110f7a6b8692e9a4 +Author: Liviu Dudau <Liviu.Dudau@arm.com> +Date: Tue Jul 1 19:43:34 2014 +0100 + + pci: Remap I/O bus resources into CPU space with pci_remap_iospace() + + Introduce a default implementation for remapping PCI bus I/O resources + onto the CPU address space. Architectures with special needs may + provide their own version, but most should be able to use this one. + + Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com> + +commit e1eacc3da10ca19eff1f88fb342a13586092b613 +Author: Liviu Dudau <liviu@dudau.co.uk> +Date: Tue Jul 1 21:50:50 2014 +0100 + + pci: Add support for creating a generic host_bridge from device tree + + Several platforms use a rather generic version of parsing + the device tree to find the host bridge ranges. Move the common code + into the generic PCI code and use it to create a pci_host_bridge + structure that can be used by arch code. + + Based on early attempts by Andrew Murray to unify the code. + Used powerpc and microblaze PCI code as starting point. + + Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com> + Tested-by: Tanmay Inamdar <tinamdar@apm.com> + +commit aee55d507eb451223b51b52e6617b06b8e518ea6 +Author: Liviu Dudau <Liviu.Dudau@arm.com> +Date: Tue Jul 1 19:43:32 2014 +0100 + + pci: of: Parse and map the IRQ when adding the PCI device. + + Enhance the default implementation of pcibios_add_device() to + parse and map the IRQ of the device if a DT binding is available. + + Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com> + +commit 0cf0470962f0498b598ff44e0c671407df54b22e +Author: Liviu Dudau <Liviu.Dudau@arm.com> +Date: Tue Jul 1 19:43:31 2014 +0100 + + pci: Introduce a domain number for pci_host_bridge. + + Make it easier to discover the domain number of a bus by storing + the number in pci_host_bridge for the root bus. Several architectures + have their own way of storing this information, so it makes sense + to try to unify the code. While at this, add a new function that + creates a root bus in a given domain and make pci_create_root_bus() + a wrapper around this function. + + Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com> + Tested-by: Tanmay Inamdar <tinamdar@apm.com> + +commit 1bc8fcf01469c202b4aea5f1d0a3a75c9302f3e2 +Author: Liviu Dudau <Liviu.Dudau@arm.com> +Date: Tue Jul 1 19:43:30 2014 +0100 + + pci: Create pci_host_bridge before its associated bus in pci_create_root_bus. + + Before commit 7b5436635800 the pci_host_bridge was created before the root bus. + As that commit has added a needless dependency on the bus for pci_alloc_host_bridge() + the creation order has been changed for no good reason. Revert the order of + creation as we are going to depend on the pci_host_bridge structure to retrieve the + domain number of the root bus. + + Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com> + Acked-by: Grant Likely <grant.likely@linaro.org> + Tested-by: Tanmay Inamdar <tinamdar@apm.com> + +commit 55353327169dc08c1047d994e00b8a38630f5a8d +Author: Liviu Dudau <Liviu.Dudau@arm.com> +Date: Tue Jul 1 19:43:29 2014 +0100 + + pci: OF: Fix the conversion of IO ranges into IO resources. + + The ranges property for a host bridge controller in DT describes + the mapping between the PCI bus address and the CPU physical address. + The resources framework however expects that the IO resources start + at a pseudo "port" address 0 (zero) and have a maximum size of IO_SPACE_LIMIT. + The conversion from pci ranges to resources failed to take that into account. + + In the process move the function into drivers/of/address.c as it now + depends on pci_address_to_pio() code and make it return an error message. + + Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com> + Tested-by: Tanmay Inamdar <tinamdar@apm.com> + +commit 34079a20796d5c74e2984c37a99baef4871709a6 +Author: Liviu Dudau <Liviu.Dudau@arm.com> +Date: Tue Jul 1 19:43:28 2014 +0100 + + pci: Introduce pci_register_io_range() helper function. + + Some architectures do not have a simple view of the PCI I/O space + and instead use a range of CPU addresses that map to bus addresses. For + some architectures these ranges will be expressed by OF bindings + in a device tree file. + + Introduce a pci_register_io_range() helper function with a generic + implementation that can be used by such architectures to keep track + of the I/O ranges described by the PCI bindings. If the PCI_IOBASE + macro is not defined that signals lack of support for PCI and we + return an error. + + Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com> + +commit a81abc095ab4b9b90e446ddbd59247e23df9d4ad +Author: Liviu Dudau <Liviu.Dudau@arm.com> +Date: Tue Jul 1 19:43:27 2014 +0100 + + pci: Export find_pci_host_bridge() function. + + This is a useful function and we should make it visible outside the + generic PCI code. Export it as a GPL symbol. + + Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com> + Tested-by: Tanmay Inamdar <tinamdar@apm.com> + +commit 78361698444e81bedbf30ec2b7aae1afd110d11f +Author: Liviu Dudau <Liviu.Dudau@arm.com> +Date: Tue Jul 1 19:43:26 2014 +0100 + + Fix ioport_map() for !CONFIG_GENERIC_IOMAP cases. + + The inline version of ioport_map() that gets used when !CONFIG_GENERIC_IOMAP + is wrong. It returns a mapped (i.e. virtual) address that can start from + zero and completely ignores the PCI_IOBASE and IO_SPACE_LIMIT that most + architectures that use !CONFIG_GENERIC_MAP define. + + Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com> + Acked-by: Arnd Bergmann <arnd@arndb.de> + Tested-by: Tanmay Inamdar <tinamdar@apm.com> + +commit 5540bbe2eca72e37be2e6a1c18e2fc7e73f0eab6 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:50 2014 +0100 + + arm64: KVM: vgic: enable GICv2 emulation on top on GICv3 hardware + + Add the last missing bits that enable GICv2 emulation on top of + GICv3 hardware. + + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit f057aaf81a7df641bcaa992965a257e3260ad36e +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:49 2014 +0100 + + arm64: KVM: vgic: add GICv3 world switch + + Introduce the GICv3 world switch code used to save/restore the + GICv3 context. + + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit 7f1b8a791bb375933fdc8420cd08f127d07dd259 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:48 2014 +0100 + + KVM: ARM: vgic: add the GICv3 backend + + Introduce the support code for emulating a GICv2 on top of GICv3 + hardware. + + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit 74428905c3b450eab53a21bee74236501629a443 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:47 2014 +0100 + + arm64: KVM: move HCR_EL2.{IMO, FMO} manipulation into the vgic switch code + + GICv3 requires the IMO and FMO bits to be tightly coupled with some + of the interrupt controller's register switch. + + In order to have similar code paths, move the manipulation of these + bits to the GICv2 switch code. + + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit b691c1f97f1fb5b29c3ae4cc836fdbefe61a11ff +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:46 2014 +0100 + + arm64: KVM: split GICv2 world switch from hyp code + + Move the GICv2 world switch code into its own file, and add the + necessary indirection to the arm64 switch code. + + Also introduce a new type field to the vgic_params structure. + + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit d3f4563f1bebed7f60f714bdab640e477a081c4b +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:45 2014 +0100 + + arm64: KVM: remove __kvm_hyp_code_{start, end} from hyp.S + + We already have __hyp_text_{start,end} to express the boundaries + of the HYP text section, and __kvm_hyp_code_{start,end} are getting + in the way of a more modular world switch code. + + Just turn __kvm_hyp_code_{start,end} into #defines mapping the + linker-emited symbols. + + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit 8ede261e09ad25ab8229d5efb476d5b4f6dc6434 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:44 2014 +0100 + + KVM: ARM: vgic: revisit implementation of irqchip_in_kernel + + So far, irqchip_in_kernel() was implemented by testing the value of + vctrl_base, which worked fine with GICv2. + + With GICv3, this field is useless, as we're using system registers + instead of a emmory mapped interface. To solve this, add a boolean + flag indicating if the we're using a vgic or not. + + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit ff7faf70feb47e5f1cf1e0f0d02e0f2807da11f5 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:43 2014 +0100 + + KVM: ARM: vgic: split GICv2 backend from the main vgic code + + Brutally hack the innocent vgic code, and move the GICv2 specific code + to its own file, using vgic_ops and vgic_params as a way to pass + information between the two blocks. + + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit 63480283c0e1dc92f506e5e5306be0ac9b239499 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:42 2014 +0100 + + KVM: ARM: introduce vgic_params structure + + Move all the data specific to a given GIC implementation into its own + little structure. + + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit dcb20f9b66d5615a3e7e492424fa7953c1fe9f01 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:41 2014 +0100 + + KVM: ARM: vgic: introduce vgic_enable + + Move the code dealing with enabling the VGIC on to vgic_ops. + + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit 67e3bcf8dd823eec79c74bc993fa62fb08b1acea +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:40 2014 +0100 + + KVM: ARM: vgic: abstract VMCR access + + Instead of directly messing with with the GICH_VMCR bits for the CPU + interface save/restore code, add accessors that encode/decode the + entire set of registers exposed by VMCR. + + Not the most efficient thing, but given that this code is only used + by the save/restore code, performance is far from being critical. + + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit 67caf34f138a4f2516a2afcd5657add2eaaf0ab4 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:39 2014 +0100 + + KVM: ARM: vgic: move underflow handling to vgic_ops + + Move the code dealing with LR underflow handling to its own functions, + and make them accessible through vgic_ops. + + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit 30acb0a340d388135ae89bed7e248bad203ec876 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:38 2014 +0100 + + KVM: ARM: vgic: abstract MISR decoding + + Instead of directly dealing with the GICH_MISR bits, move the code to + its own function and use a couple of public flags to represent the + actual state. + + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit 464cbe47011e07b654d161ab4d4bdd05b4d025b3 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:37 2014 +0100 + + KVM: ARM: vgic: abstract EISR bitmap access + + Move the GICH_EISR access to its own function. + + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit 33930dc5f401e9fc2268c2f128853eb5275e7ab1 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:36 2014 +0100 + + KVM: ARM: vgic: abstract access to the ELRSR bitmap + + Move the GICH_ELRSR access to its own functions, and add them to + the vgic_ops structure. + + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit 0dca962ccd5b96fb7174880c1bc25085dcc09927 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:35 2014 +0100 + + KVM: ARM: vgic: introduce vgic_ops and LR manipulation primitives + + In order to split the various register manipulation from the main vgic + code, introduce a vgic_ops structure, and start by abstracting the + LR manipulation code with a couple of accessors. + + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit e66aa6cbdaa25764c58ba8d21da8d1b7d75e7570 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:34 2014 +0100 + + KVM: arm/arm64: vgic: move GICv2 registers to their own structure + + In order to make way for the GICv3 registers, move the v2-specific + registers to their own structure. + + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit b04259737c6bb38592c02c93e939fd53909dad04 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:33 2014 +0100 + + arm64: boot protocol documentation update for GICv3 + + Linux has some requirements that must be satisfied in order to boot + on a system built with a GICv3. + + Acked-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit a864693311bd4305214d966b7ca0e0015216c2c4 +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:32 2014 +0100 + + arm64: GICv3 device tree binding documentation + + Add the necessary documentation to support GICv3. + + Cc: Thomas Gleixner <tglx@linutronix.de> + Cc: Mark Rutland <mark.rutland@arm.com> + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Acked-by: Rob Herring <robh@kernel.org> + Acked-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit af3035d3ddddb6e19bac9295f0c785bb2c8e718c +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:31 2014 +0100 + + irqchip: arm64: Initial support for GICv3 + + The Generic Interrupt Controller (version 3) offers services that are + similar to GICv2, with a number of additional features: + - Affinity routing based on the CPU MPIDR (ARE) + - System register for the CPU interfaces (SRE) + - Support for more that 8 CPUs + - Locality-specific Peripheral Interrupts (LPIs) + - Interrupt Translation Services (ITS) + + This patch adds preliminary support for GICv3 with ARE and SRE, + non-secure mode only. It relies on higher exception levels to grant ARE + and SRE access. + + Support for LPI and ITS will be added at a later time. + + Cc: Thomas Gleixner <tglx@linutronix.de> + Cc: Jason Cooper <jason@lakedaemon.net> + Reviewed-by: Zi Shen Lim <zlim@broadcom.com> + Reviewed-by: Christoffer Dall <christoffer.dall@linaro.org> + Reviewed-by: Tirumalesh Chalamarla <tchalamarla@cavium.com> + Reviewed-by: Yun Wu <wuyun.wu@huawei.com> + Reviewed-by: Zhen Lei <thunder.leizhen@huawei.com> + Tested-by: Tirumalesh Chalamarla<tchalamarla@cavium.com> + Tested-by: Radha Mohan Chintakuntla <rchintakuntla@cavium.com> + Acked-by: Radha Mohan Chintakuntla <rchintakuntla@cavium.com> + Acked-by: Catalin Marinas <catalin.marinas@arm.com> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit c50b02761c3ad5d37ce8fffe7c0bf6b46d23109e +Author: Marc Zyngier <marc.zyngier@arm.com> +Date: Mon Jun 30 16:01:30 2014 +0100 + + irqchip: ARM: GIC: Move some bits of GICv2 to a library-type file + + A few GICv2 low-level function are actually very useful to GICv3, + and it makes some sense to share them across the two drivers. + They end-up in their own file, with an additional parameter used + to ensure an optional synchronization (unused on GICv2). + + Cc: Thomas Gleixner <tglx@linutronix.de> + Cc: Jason Cooper <jason@lakedaemon.net> + Acked-by: Christoffer Dall <christoffer.dall@linaro.org> + Signed-off-by: Marc Zyngier <marc.zyngier@arm.com> + +commit 6a6033cdcbf6022c2848e2181ed6d8b7545af02e +Author: Mark Salter <msalter@redhat.com> +Date: Tue Jun 24 23:16:45 2014 -0400 + + perf: fix arm64 build error + + I'm seeing the following build error on arm64: + + In file included from util/event.c:3:0: + util/event.h:95:17: error: 'PERF_REGS_MAX' undeclared here (not in a function) + u64 cache_regs[PERF_REGS_MAX]; + ^ + + This patch adds a PEFF_REGS_MAX definition for arm64. + + Signed-off-by: Mark Salter <msalter@redhat.com> + +commit 1de8987fa549d421576c1b61282c4041c8c78a5f +Author: Mark Salter <msalter@redhat.com> +Date: Tue Jun 24 09:50:28 2014 -0400 + + arm64: use EFI as last resort for reboot and poweroff + + Wire in support for EFI reboot and poweroff functions. We use these + only if no other mechanism has been registered with arm_pm_reboot + and/or pm_power_off respectively. + + Signed-off-by: Mark Salter <msalter@redhat.com> + +commit 1c973051e86625be7ffb3db90d4a70b9ca4199c6 +Author: Matt Fleming <matt.fleming@intel.com> +Date: Fri Jun 13 12:39:55 2014 +0100 + + x86/reboot: Add EFI reboot quirk for ACPI Hardware Reduced flag + + It appears that the BayTrail-T class of hardware requires EFI in order + to powerdown and reboot and no other reliable method exists. + + This quirk is generally applicable to all hardware that has the ACPI + Hardware Reduced bit set, since usually ACPI would be the preferred + method. + + Cc: Len Brown <len.brown@intel.com> + Cc: Mark Salter <msalter@redhat.com> + Cc: "Rafael J. Wysocki" <rafael.j.wysocki@intel.com> + Signed-off-by: Matt Fleming <matt.fleming@intel.com> + +commit 621b2a0f1df86bd2f147799303b94575f3acee95 +Author: Matt Fleming <matt.fleming@intel.com> +Date: Fri Jun 13 12:35:21 2014 +0100 + + efi/reboot: Allow powering off machines using EFI + + Not only can EfiResetSystem() be used to reboot, it can also be used to + power down machines. + + By and large, this functionality doesn't work very well across the range + of EFI machines in the wild, so it should definitely only be used as a + last resort. In an ideal world, this wouldn't be needed at all. + + Unfortunately, we're starting to see machines where EFI is the *only* + reliable way to power down, and nothing else, not PCI, not ACPI, works. + + efi_poweroff_required() should be implemented on a per-architecture + basis, since exactly when we should be using EFI runtime services is a + platform-specific decision. There's no analogue for reboot because each + architecture handles reboot very differently - the x86 code in + particular is pretty complex. + + Patches to enable this for specific classes of hardware will be + submitted separately. + + Cc: Mark Salter <msalter@redhat.com> + Signed-off-by: Matt Fleming <matt.fleming@intel.com> + +commit 6b2e219b20933cad5d5ba34f7af4efc5317c0fb9 +Author: Matt Fleming <matt.fleming@intel.com> +Date: Fri Jun 13 12:22:22 2014 +0100 + + efi/reboot: Add generic wrapper around EfiResetSystem() + + Implement efi_reboot(), which is really just a wrapper around the + EfiResetSystem() EFI runtime service, but it does at least allow us to + funnel all callers through a single location. + + It also simplifies the callsites since users no longer need to check to + see whether EFI_RUNTIME_SERVICES are enabled. + + Cc: Tony Luck <tony.luck@intel.com> + Cc: Mark Salter <msalter@redhat.com> + Signed-off-by: Matt Fleming <matt.fleming@intel.com> + +commit d0d41b99122d97f81ad05868dff38ccf0a3ffd33 +Author: Saurabh Tangri <saurabh.tangri@intel.com> +Date: Mon Jun 2 05:18:35 2014 -0700 + + x86/efi: Move all workarounds to a separate file quirks.c + + Currently, it's difficult to find all the workarounds that are + applied when running on EFI, because they're littered throughout + various code paths. This change moves all of them into a separate + file with the hope that it will be come the single location for all + our well documented quirks. + + Signed-off-by: Saurabh Tangri <saurabh.tangri@intel.com> + Signed-off-by: Matt Fleming <matt.fleming@intel.com> + +commit b5e3a1e8825abb0406ead0e85436df4df20ddcdb +Author: Don Dutile <ddutile@redhat.com> +Date: Tue Mar 25 20:22:26 2014 -0400 + + pmu: Adding support for Xgene PMUs + + Message-id: <1395778948-47814-2-git-send-email-ddutile@redhat.com> + Patchwork-id: 78602 + O-Subject: [PATCH 1/3] pmu: Adding support for Xgene PMUs + Bugzilla: 1079110 + + Backport of these two posted (but not upstream) patches. + Combined into single patch due to gic-patch dependency. + + Signed-off-by: Donald Dutile <ddutile@redhat.com> + +commit 9f4c27693bb120a3134e3e7e8d452fb02d023e2b +Author: Mark Salter <msalter@redhat.com> +Date: Sun Jun 15 09:06:55 2014 -0400 + + arm64: fix up APM Mustang devicetree + + These are changes needed when loading device tree blob built with + kernel. i.e. with grub. These are not needed when using devicetree + from Tianocore which will be fixed up at tianocore runtime. + + Signed-off-by: Mark Salter <msalter@redhat.com> + +commit 1f3a5b228be88be3f734d7a43db3b3f81e160443 +Author: Iyappan Subramanian <isubramanian@apm.com> +Date: Mon Jul 14 15:18:05 2014 -0700 + + drivers: net: Add APM X-Gene SoC ethernet driver support. + + This patch adds network driver for APM X-Gene SoC ethernet. + + Signed-off-by: Iyappan Subramanian <isubramanian@apm.com> + Signed-off-by: Ravi Patel <rapatel@apm.com> + Signed-off-by: Keyur Chudgar <kchudgar@apm.com> + +commit 54b3fe04c4a953eeb6907ffe9f57aae282f59457 +Author: Iyappan Subramanian <isubramanian@apm.com> +Date: Mon Jul 14 15:18:04 2014 -0700 + + dts: Add bindings for APM X-Gene SoC ethernet driver + + This patch adds bindings for APM X-Gene SoC ethernet driver. + + Signed-off-by: Iyappan Subramanian <isubramanian@apm.com> + Signed-off-by: Ravi Patel <rapatel@apm.com> + Signed-off-by: Keyur Chudgar <kchudgar@apm.com> + +commit 85125c4e1c1b1ef53d6cb77966efa89062540f43 +Author: Iyappan Subramanian <isubramanian@apm.com> +Date: Mon Jul 14 15:18:03 2014 -0700 + + Documentation: dts: Add bindings for APM X-Gene SoC ethernet driver + + This patch adds documentation for APM X-Gene SoC ethernet DTS binding. + + Signed-off-by: Iyappan Subramanian <isubramanian@apm.com> + Signed-off-by: Ravi Patel <rapatel@apm.com> + Signed-off-by: Keyur Chudgar <kchudgar@apm.com> + +commit fe8ec437eedc45384c23e1e12a09baa82d24fa16 +Author: Iyappan Subramanian <isubramanian@apm.com> +Date: Mon Jul 14 15:18:02 2014 -0700 + + MAINTAINERS: Add entry for APM X-Gene SoC ethernet driver + + This patch adds a MAINTAINERS entry for APM X-Gene SoC + ethernet driver. + + Signed-off-by: Iyappan Subramanian <isubramanian@apm.com> + Signed-off-by: Ravi Patel <rapatel@apm.com> + Signed-off-by: Keyur Chudgar <kchudgar@apm.com> + +commit 237639e43c3d6587985a736f33264e129123d7a5 +Author: Mark Salter <msalter@redhat.com> +Date: Fri Jul 25 15:14:32 2014 -0400 + + arm/kvm: WIP fix for stage2 pgd memory leak + + Signed-off-by: Mark Salter <msalter@redhat.com> + +commit 0794e2900e5e4be4b7aa0b389e6b0bf8b55c5cd7 +Author: Mark Salter <msalter@redhat.com> +Date: Thu Jul 17 13:34:50 2014 -0400 + + ahci_xgene: add errata workaround for ATA_CMD_SMART + + commit 2a0bdff6b958d1b2: + + ahci_xgene: fix the dma state machine lockup for the IDENTIFY DEVICE PIO mode command. + + added a workaround for X-Gene AHCI controller errata. This was done + for all ATA_CMD_ID_ATA commands. The errata also appears to affect + ATA_CMD_SMART commands as well. This was discovered when running + smartd or just smartctl -x. This patch adds a dma engine restart for + ATA_CMD_SMART commands which clears up the issues seen with smartd. + + Signed-off-by: Mark Salter <msalter@redhat.com> + +commit 7adf85b63608b8bea1148f2faa84f475252a9e43 +Author: Mark Salter <msalter@redhat.com> +Date: Fri Jul 25 15:32:05 2014 -0400 + + rtc: ia64: allow other architectures to use EFI RTC + + Currently, the rtc-efi driver is restricted to ia64 only. Newer + architectures with EFI support may want to also use that driver. This + patch moves the platform device setup from ia64 into drivers/rtc and allow + any architecture with CONFIG_EFI=y to use the rtc-efi driver. + + Signed-off-by: Mark Salter <msalter@redhat.com> + Cc: Alessandro Zummo <a.zummo@towertech.it> + Cc: Tony Luck <tony.luck@intel.com> + Cc: Fenghua Yu <fenghua.yu@intel.com> + Cc: Andrew Morton <akpm@linux-foundation.org> + +commit 3b2f96c7a6bfbd46e7dee1d7000081422a7983ce +Author: Kyle McMartin <kmcmarti@redhat.com> +Date: Tue May 13 22:25:26 2014 -0400 + + arm64: don't set READ_IMPLIES_EXEC for EM_AARCH64 ELF objects + + Message-id: <20140513222526.GC26038@redacted.bos.redhat.com> + Patchwork-id: 79789 + O-Subject: [ACADIA PATCH] arm64: don't set READ_IMPLIES_EXEC for EM_AARCH64 ELF objects + Bugzilla: 1085528 + + BZ: https://bugzilla.redhat.com/show_bug.cgi?id=1085528 + Upstream: submitted soon + + [Sadly this isn't (yet) sufficient... but it fixes at least one issue + here... cat /proc/$$/personality shows READ_IMPLIES_EXEC before. I'll + try to figure the rest out tomorrow.] + + Currently, we're accidentally ending up with executable stacks on + AArch64 when the ABI says we shouldn't be, and relying on glibc to fix + things up for us when we're loaded. However, SELinux will deny us + mucking with the stack, and hit us with execmem AVCs. + + The reason this is happening is somewhat complex: + + fs/binfmt_elf.c:load_elf_binary() + - initializes executable_stack = EXSTACK_DEFAULT implying the + architecture should make up its mind. + - does a pile of loading goo + - runs through the program headers, looking for PT_GNU_STACK + and setting (or unsetting) executable_stack if it finds it. + + This is our first problem, we won't generate these unless an + executable stack is explicitly requested. + + - more ELF loading goo + - sets whether we're a compat task or not (TIF_32BIT) based on compat.h + - for compat reasons (pre-GNU_STACK) checks if the READ_IMPLIES_EXEC + flag should be set for ancient toolchains + + Here's our second problem, we test if read_implies_exec based on + stk != EXSTACK_DISABLE_X, which is true since stk == EXSTACK_DEFAULT. + + So we set current->personality |= READ_IMPLIES_EXEC like a broken + legacy toolchain would want. + + - Now we call setup_arg_pages to set up the stack... + + fs/exec.c:setup_arg_pages() + - lots of magic happens here + - vm_flags gets initialized to VM_STACK_FLAGS + + Here's our third problem, VM_STACK_FLAGS on arm64 is + VM_DEFAULT_DATA_FLAG which tests READ_IMPLIES_EXEC and sets VM_EXEC + if it's true. So we end up with an executable stack mapping, since we + don't have executable_stack set (it's still EXSTACK_DEFAULT at this + point) to unset it anywhere. + + Bang. execstack AVC when the program starts running. + + The easiest way I can see to fix this is to test if we're a legacy task + and fix it up there. But that's not as simple as it sounds, because + the 32-bit ABI depends on what revision of the CPU we've enabled (not + that it matters since we're ARMv8...) Regardless, in the compat case, + set READ_IMPLIES_EXEC if we've found a GNU_STACK header which explicitly + requested it as in arch/arm/kernel/elf.c:arm_elf_read_implies_exec(). + + Signed-off-by: Kyle McMartin <kmcmarti@redhat.com> + Signed-off-by: Donald Dutile <ddutile@redhat.com> + +commit 4b866971e92b925a44da8d876cb57864942a90b8 +Author: Mark Salter <msalter@redhat.com> +Date: Thu Jul 24 15:56:15 2014 +0100 + + arm64: fix soft lockup due to large tlb flush range + + Under certain loads, this soft lockup has been observed: + + BUG: soft lockup - CPU#2 stuck for 22s! [ip6tables:1016] + Modules linked in: ip6t_rpfilter ip6t_REJECT cfg80211 rfkill xt_conntrack ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_security ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_security iptable_raw vfat fat efivarfs xfs libcrc32c + + CPU: 2 PID: 1016 Comm: ip6tables Not tainted 3.13.0-0.rc7.30.sa2.aarch64 #1 + task: fffffe03e81d1400 ti: fffffe03f01f8000 task.ti: fffffe03f01f8000 + PC is at __cpu_flush_kern_tlb_range+0xc/0x40 + LR is at __purge_vmap_area_lazy+0x28c/0x3ac + pc : [<fffffe000009c5cc>] lr : [<fffffe0000182710>] pstate: 80000145 + sp : fffffe03f01fbb70 + x29: fffffe03f01fbb70 x28: fffffe03f01f8000 + x27: fffffe0000b19000 x26: 00000000000000d0 + x25: 000000000000001c x24: fffffe03f01fbc50 + x23: fffffe03f01fbc58 x22: fffffe03f01fbc10 + x21: fffffe0000b2a3f8 x20: 0000000000000802 + x19: fffffe0000b2a3c8 x18: 000003fffdf52710 + x17: 000003ff9d8bb910 x16: fffffe000050fbfc + x15: 0000000000005735 x14: 000003ff9d7e1a5c + x13: 0000000000000000 x12: 000003ff9d7e1a5c + x11: 0000000000000007 x10: fffffe0000c09af0 + x9 : fffffe0000ad1000 x8 : 000000000000005c + x7 : fffffe03e8624000 x6 : 0000000000000000 + x5 : 0000000000000000 x4 : 0000000000000000 + x3 : fffffe0000c09cc8 x2 : 0000000000000000 + x1 : 000fffffdfffca80 x0 : 000fffffcd742150 + + The __cpu_flush_kern_tlb_range() function looks like: + + ENTRY(__cpu_flush_kern_tlb_range) + dsb sy + lsr x0, x0, #12 + lsr x1, x1, #12 + 1: tlbi vaae1is, x0 + add x0, x0, #1 + cmp x0, x1 + b.lo 1b + dsb sy + isb + ret + ENDPROC(__cpu_flush_kern_tlb_range) + + The above soft lockup shows the PC at tlbi insn with: + + x0 = 0x000fffffcd742150 + x1 = 0x000fffffdfffca80 + + So __cpu_flush_kern_tlb_range has 0x128ba930 tlbi flushes left + after it has already been looping for 23 seconds!. + + Looking up one frame at __purge_vmap_area_lazy(), there is: + + ... + list_for_each_entry_rcu(va, &vmap_area_list, list) { + if (va->flags & VM_LAZY_FREE) { + if (va->va_start < *start) + *start = va->va_start; + if (va->va_end > *end) + *end = va->va_end; + nr += (va->va_end - va->va_start) >> PAGE_SHIFT; + list_add_tail(&va->purge_list, &valist); + va->flags |= VM_LAZY_FREEING; + va->flags &= ~VM_LAZY_FREE; + } + } + ... + if (nr || force_flush) + flush_tlb_kernel_range(*start, *end); + + So if two areas are being freed, the range passed to + flush_tlb_kernel_range() may be as large as the vmalloc + space. For arm64, this is ~240GB for 4k pagesize and ~2TB + for 64kpage size. + + This patch works around this problem by adding a loop limit. + If the range is larger than the limit, use flush_tlb_all() + rather than flushing based on individual pages. The limit + chosen is arbitrary as the TLB size is implementation + specific and not accessible in an architected way. The aim + of the arbitrary limit is to avoid soft lockup. + + Signed-off-by: Mark Salter <msalter@redhat.com> + [catalin.marinas@arm.com: commit log update] + [catalin.marinas@arm.com: marginal optimisation] + [catalin.marinas@arm.com: changed to MAX_TLB_RANGE and added comment] + Signed-off-by: Catalin Marinas <catalin.marinas@arm.com> + +diff --git a/Documentation/arm64/booting.txt b/Documentation/arm64/booting.txt +index 37fc4f6..da1d4bf 100644 +--- a/Documentation/arm64/booting.txt ++++ b/Documentation/arm64/booting.txt +@@ -141,6 +141,14 @@ Before jumping into the kernel, the following conditions must be met: + the kernel image will be entered must be initialised by software at a + higher exception level to prevent execution in an UNKNOWN state. + ++ For systems with a GICv3 interrupt controller: ++ - If EL3 is present: ++ ICC_SRE_EL3.Enable (bit 3) must be initialiased to 0b1. ++ ICC_SRE_EL3.SRE (bit 0) must be initialised to 0b1. ++ - If the kernel is entered at EL1: ++ ICC.SRE_EL2.Enable (bit 3) must be initialised to 0b1 ++ ICC_SRE_EL2.SRE (bit 0) must be initialised to 0b1. ++ + The requirements described above for CPU mode, caches, MMUs, architected + timers, coherency and system registers apply to all CPUs. All CPUs must + enter the kernel in the same exception level. +diff --git a/Documentation/devicetree/bindings/arm/gic-v3.txt b/Documentation/devicetree/bindings/arm/gic-v3.txt +new file mode 100644 +index 0000000..33cd05e +--- /dev/null ++++ b/Documentation/devicetree/bindings/arm/gic-v3.txt +@@ -0,0 +1,79 @@ ++* ARM Generic Interrupt Controller, version 3 ++ ++AArch64 SMP cores are often associated with a GICv3, providing Private ++Peripheral Interrupts (PPI), Shared Peripheral Interrupts (SPI), ++Software Generated Interrupts (SGI), and Locality-specific Peripheral ++Interrupts (LPI). ++ ++Main node required properties: ++ ++- compatible : should at least contain "arm,gic-v3". ++- interrupt-controller : Identifies the node as an interrupt controller ++- #interrupt-cells : Specifies the number of cells needed to encode an ++ interrupt source. Must be a single cell with a value of at least 3. ++ ++ The 1st cell is the interrupt type; 0 for SPI interrupts, 1 for PPI ++ interrupts. Other values are reserved for future use. ++ ++ The 2nd cell contains the interrupt number for the interrupt type. ++ SPI interrupts are in the range [0-987]. PPI interrupts are in the ++ range [0-15]. ++ ++ The 3rd cell is the flags, encoded as follows: ++ bits[3:0] trigger type and level flags. ++ 1 = edge triggered ++ 4 = level triggered ++ ++ Cells 4 and beyond are reserved for future use. When the 1st cell ++ has a value of 0 or 1, cells 4 and beyond act as padding, and may be ++ ignored. It is recommended that padding cells have a value of 0. ++ ++- reg : Specifies base physical address(s) and size of the GIC ++ registers, in the following order: ++ - GIC Distributor interface (GICD) ++ - GIC Redistributors (GICR), one range per redistributor region ++ - GIC CPU interface (GICC) ++ - GIC Hypervisor interface (GICH) ++ - GIC Virtual CPU interface (GICV) ++ ++ GICC, GICH and GICV are optional. ++ ++- interrupts : Interrupt source of the VGIC maintenance interrupt. ++ ++Optional ++ ++- redistributor-stride : If using padding pages, specifies the stride ++ of consecutive redistributors. Must be a multiple of 64kB. ++ ++- #redistributor-regions: The number of independent contiguous regions ++ occupied by the redistributors. Required if more than one such ++ region is present. ++ ++Examples: ++ ++ gic: interrupt-controller@2cf00000 { ++ compatible = "arm,gic-v3"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x0 0x2f000000 0 0x10000>, // GICD ++ <0x0 0x2f100000 0 0x200000>, // GICR ++ <0x0 0x2c000000 0 0x2000>, // GICC ++ <0x0 0x2c010000 0 0x2000>, // GICH ++ <0x0 0x2c020000 0 0x2000>; // GICV ++ interrupts = <1 9 4>; ++ }; ++ ++ gic: interrupt-controller@2c010000 { ++ compatible = "arm,gic-v3"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ redistributor-stride = <0x0 0x40000>; // 256kB stride ++ #redistributor-regions = <2>; ++ reg = <0x0 0x2c010000 0 0x10000>, // GICD ++ <0x0 0x2d000000 0 0x800000>, // GICR 1: CPUs 0-31 ++ <0x0 0x2e000000 0 0x800000>; // GICR 2: CPUs 32-63 ++ <0x0 0x2c040000 0 0x2000>, // GICC ++ <0x0 0x2c060000 0 0x2000>, // GICH ++ <0x0 0x2c080000 0 0x2000>; // GICV ++ interrupts = <1 9 4>; ++ }; +diff --git a/Documentation/devicetree/bindings/net/apm-xgene-enet.txt b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt +new file mode 100644 +index 0000000..3e2a295 +--- /dev/null ++++ b/Documentation/devicetree/bindings/net/apm-xgene-enet.txt +@@ -0,0 +1,72 @@ ++APM X-Gene SoC Ethernet nodes ++ ++Ethernet nodes are defined to describe on-chip ethernet interfaces in ++APM X-Gene SoC. ++ ++Required properties: ++- compatible: Should be "apm,xgene-enet" ++- reg: Address and length of the register set for the device. It contains the ++ information of registers in the same order as described by reg-names ++- reg-names: Should contain the register set names ++ "enet_csr": Ethernet control and status register address space ++ "ring_csr": Descriptor ring control and status register address space ++ "ring_cmd": Descriptor ring command register address space ++- interrupts: Ethernet main interrupt ++- clocks: Reference to the clock entry. ++- local-mac-address: MAC address assigned to this device ++- phy-connection-type: Interface type between ethernet device and PHY device ++- phy-handle: Reference to a PHY node connected to this device ++ ++- mdio: Device tree subnode with the following required ++ properties: ++ ++ - compatible: Must be "apm,xgene-mdio". ++ - #address-cells: Must be <1>. ++ - #size-cells: Must be <0>. ++ ++ For the phy on the mdio bus, there must be a node with the following ++ fields: ++ ++ - compatible: PHY identifier. Please refer ./phy.txt for the format. ++ - reg: The ID number for the phy. ++ ++Optional properties: ++- status : Should be "ok" or "disabled" for enabled/disabled. ++ Default is "ok". ++ ++ ++Example: ++ menetclk: menetclk { ++ compatible = "apm,xgene-device-clock"; ++ clock-output-names = "menetclk"; ++ status = "ok"; ++ }; ++ ++ menet: ethernet@17020000 { ++ compatible = "apm,xgene-enet"; ++ status = "disabled"; ++ reg = <0x0 0x17020000 0x0 0xd100>, ++ <0x0 0X17030000 0x0 0X400>, ++ <0x0 0X10000000 0x0 0X200>; ++ reg-names = "enet_csr", "ring_csr", "ring_cmd"; ++ interrupts = <0x0 0x3c 0x4>; ++ clocks = <&menetclk 0>; ++ local-mac-address = [00 01 73 00 00 01]; ++ phy-connection-type = "rgmii"; ++ phy-handle = <&menetphy>; ++ mdio { ++ compatible = "apm,xgene-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ menetphy: menetphy@3 { ++ compatible = "ethernet-phy-id001c.c915"; ++ reg = <0x3>; ++ }; ++ ++ }; ++ }; ++ ++/* Board-specific peripheral configurations */ ++&menet { ++ status = "ok"; ++}; +diff --git a/Documentation/devicetree/bindings/pci/xgene-pci.txt b/Documentation/devicetree/bindings/pci/xgene-pci.txt +new file mode 100644 +index 0000000..e19fdb8 +--- /dev/null ++++ b/Documentation/devicetree/bindings/pci/xgene-pci.txt +@@ -0,0 +1,52 @@ ++* AppliedMicro X-Gene PCIe interface ++ ++Required properties: ++- device_type: set to "pci" ++- compatible: should contain "apm,xgene-pcie" to identify the core. ++- reg: A list of physical base address and length for each set of controller ++ registers. Must contain an entry for each entry in the reg-names ++ property. ++- reg-names: Must include the following entries: ++ "csr": controller configuration registers. ++ "cfg": pcie configuration space registers. ++- #address-cells: set to <3> ++- #size-cells: set to <2> ++- ranges: ranges for the outbound memory, I/O regions. ++- dma-ranges: ranges for the inbound memory regions. ++- #interrupt-cells: set to <1> ++- interrupt-map-mask and interrupt-map: standard PCI properties ++ to define the mapping of the PCIe interface to interrupt ++ numbers. ++- clocks: from common clock binding: handle to pci clock. ++ ++Optional properties: ++- status: Either "ok" or "disabled". ++ ++Example: ++ ++SoC specific DT Entry: ++ pcie0: pcie@1f2b0000 { ++ status = "disabled"; ++ device_type = "pci"; ++ compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; ++ #interrupt-cells = <1>; ++ #size-cells = <2>; ++ #address-cells = <3>; ++ reg = < 0x00 0x1f2b0000 0x0 0x00010000 /* Controller registers */ ++ 0xe0 0xd0000000 0x0 0x00200000>; /* PCI config space */ ++ reg-names = "csr", "cfg"; ++ ranges = <0x01000000 0x00 0x00000000 0xe0 0x00000000 0x00 0x00010000 /* io */ ++ 0x02000000 0x00 0x10000000 0xe0 0x10000000 0x00 0x80000000>; /* mem */ ++ dma-ranges = <0x42000000 0x40 0x00000000 0x40 0x00000000 0x40 0x00000000>; ++ interrupt-map-mask = <0x0 0x0 0x0 0x7>; ++ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc2 0x1 ++ 0x0 0x0 0x0 0x2 &gic 0x0 0xc3 0x1 ++ 0x0 0x0 0x0 0x3 &gic 0x0 0xc4 0x1 ++ 0x0 0x0 0x0 0x4 &gic 0x0 0xc5 0x1>; ++ clocks = <&pcie0clk 0>; ++ }; ++ ++Board specific DT Entry: ++ &pcie0 { ++ status = "ok"; ++ }; +diff --git a/MAINTAINERS b/MAINTAINERS +index 86efa7e..14a3ef1 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -699,6 +699,14 @@ S: Maintained + F: drivers/net/appletalk/ + F: net/appletalk/ + ++APPLIED MICRO (APM) X-GENE SOC ETHERNET DRIVER ++M: Iyappan Subramanian <isubramanian@apm.com> ++M: Keyur Chudgar <kchudgar@apm.com> ++M: Ravi Patel <rapatel@apm.com> ++S: Supported ++F: drivers/net/ethernet/apm/xgene/ ++F: Documentation/devicetree/bindings/net/apm-xgene-enet.txt ++ + APTINA CAMERA SENSOR PLL + M: Laurent Pinchart <Laurent.pinchart@ideasonboard.com> + L: linux-media@vger.kernel.org +@@ -6851,6 +6859,13 @@ S: Maintained + F: Documentation/devicetree/bindings/pci/host-generic-pci.txt + F: drivers/pci/host/pci-host-generic.c + ++PCI DRIVER FOR APPLIEDMICRO XGENE ++M: Tanmay Inamdar <tinamdar@apm.com> ++L: linux-pci@vger.kernel.org ++L: linux-arm-kernel@lists.infradead.org ++S: Maintained ++F: drivers/pci/host/pci-xgene.c ++ + PCMCIA SUBSYSTEM + P: Linux PCMCIA Team + L: linux-pcmcia@lists.infradead.org +diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h +index 193ceaf..d6d5227 100644 +--- a/arch/arm/include/asm/kvm_host.h ++++ b/arch/arm/include/asm/kvm_host.h +@@ -225,6 +225,11 @@ static inline int kvm_arch_dev_ioctl_check_extension(long ext) + return 0; + } + ++static inline void vgic_arch_setup(const struct vgic_params *vgic) ++{ ++ BUG_ON(vgic->type != VGIC_V2); ++} ++ + int kvm_perf_init(void); + int kvm_perf_teardown(void); + +diff --git a/arch/arm/kernel/asm-offsets.c b/arch/arm/kernel/asm-offsets.c +index 85598b5..713e807 100644 +--- a/arch/arm/kernel/asm-offsets.c ++++ b/arch/arm/kernel/asm-offsets.c +@@ -182,13 +182,13 @@ int main(void) + DEFINE(VCPU_HYP_PC, offsetof(struct kvm_vcpu, arch.fault.hyp_pc)); + #ifdef CONFIG_KVM_ARM_VGIC + DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); +- DEFINE(VGIC_CPU_HCR, offsetof(struct vgic_cpu, vgic_hcr)); +- DEFINE(VGIC_CPU_VMCR, offsetof(struct vgic_cpu, vgic_vmcr)); +- DEFINE(VGIC_CPU_MISR, offsetof(struct vgic_cpu, vgic_misr)); +- DEFINE(VGIC_CPU_EISR, offsetof(struct vgic_cpu, vgic_eisr)); +- DEFINE(VGIC_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_elrsr)); +- DEFINE(VGIC_CPU_APR, offsetof(struct vgic_cpu, vgic_apr)); +- DEFINE(VGIC_CPU_LR, offsetof(struct vgic_cpu, vgic_lr)); ++ DEFINE(VGIC_V2_CPU_HCR, offsetof(struct vgic_cpu, vgic_v2.vgic_hcr)); ++ DEFINE(VGIC_V2_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr)); ++ DEFINE(VGIC_V2_CPU_MISR, offsetof(struct vgic_cpu, vgic_v2.vgic_misr)); ++ DEFINE(VGIC_V2_CPU_EISR, offsetof(struct vgic_cpu, vgic_v2.vgic_eisr)); ++ DEFINE(VGIC_V2_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v2.vgic_elrsr)); ++ DEFINE(VGIC_V2_CPU_APR, offsetof(struct vgic_cpu, vgic_v2.vgic_apr)); ++ DEFINE(VGIC_V2_CPU_LR, offsetof(struct vgic_cpu, vgic_v2.vgic_lr)); + DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); + #ifdef CONFIG_KVM_ARM_TIMER + DEFINE(VCPU_TIMER_CNTV_CTL, offsetof(struct kvm_vcpu, arch.timer_cpu.cntv_ctl)); +diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile +index 789bca9..f7057ed 100644 +--- a/arch/arm/kvm/Makefile ++++ b/arch/arm/kvm/Makefile +@@ -21,4 +21,5 @@ obj-y += kvm-arm.o init.o interrupts.o + obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o + obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o + obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o ++obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o + obj-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o +diff --git a/arch/arm/kvm/interrupts_head.S b/arch/arm/kvm/interrupts_head.S +index 76af9302..e4eaf30 100644 +--- a/arch/arm/kvm/interrupts_head.S ++++ b/arch/arm/kvm/interrupts_head.S +@@ -421,14 +421,14 @@ vcpu .req r0 @ vcpu pointer always in r0 + ldr r9, [r2, #GICH_ELRSR1] + ldr r10, [r2, #GICH_APR] + +- str r3, [r11, #VGIC_CPU_HCR] +- str r4, [r11, #VGIC_CPU_VMCR] +- str r5, [r11, #VGIC_CPU_MISR] +- str r6, [r11, #VGIC_CPU_EISR] +- str r7, [r11, #(VGIC_CPU_EISR + 4)] +- str r8, [r11, #VGIC_CPU_ELRSR] +- str r9, [r11, #(VGIC_CPU_ELRSR + 4)] +- str r10, [r11, #VGIC_CPU_APR] ++ str r3, [r11, #VGIC_V2_CPU_HCR] ++ str r4, [r11, #VGIC_V2_CPU_VMCR] ++ str r5, [r11, #VGIC_V2_CPU_MISR] ++ str r6, [r11, #VGIC_V2_CPU_EISR] ++ str r7, [r11, #(VGIC_V2_CPU_EISR + 4)] ++ str r8, [r11, #VGIC_V2_CPU_ELRSR] ++ str r9, [r11, #(VGIC_V2_CPU_ELRSR + 4)] ++ str r10, [r11, #VGIC_V2_CPU_APR] + + /* Clear GICH_HCR */ + mov r5, #0 +@@ -436,7 +436,7 @@ vcpu .req r0 @ vcpu pointer always in r0 + + /* Save list registers */ + add r2, r2, #GICH_LR0 +- add r3, r11, #VGIC_CPU_LR ++ add r3, r11, #VGIC_V2_CPU_LR + ldr r4, [r11, #VGIC_CPU_NR_LR] + 1: ldr r6, [r2], #4 + str r6, [r3], #4 +@@ -463,9 +463,9 @@ vcpu .req r0 @ vcpu pointer always in r0 + add r11, vcpu, #VCPU_VGIC_CPU + + /* We only restore a minimal set of registers */ +- ldr r3, [r11, #VGIC_CPU_HCR] +- ldr r4, [r11, #VGIC_CPU_VMCR] +- ldr r8, [r11, #VGIC_CPU_APR] ++ ldr r3, [r11, #VGIC_V2_CPU_HCR] ++ ldr r4, [r11, #VGIC_V2_CPU_VMCR] ++ ldr r8, [r11, #VGIC_V2_CPU_APR] + + str r3, [r2, #GICH_HCR] + str r4, [r2, #GICH_VMCR] +@@ -473,7 +473,7 @@ vcpu .req r0 @ vcpu pointer always in r0 + + /* Restore list registers */ + add r2, r2, #GICH_LR0 +- add r3, r11, #VGIC_CPU_LR ++ add r3, r11, #VGIC_V2_CPU_LR + ldr r4, [r11, #VGIC_CPU_NR_LR] + 1: ldr r6, [r3], #4 + str r6, [r2], #4 +diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig +index 839f48c..23871dd 100644 +--- a/arch/arm64/Kconfig ++++ b/arch/arm64/Kconfig +@@ -11,6 +11,7 @@ config ARM64 + select ARM_AMBA + select ARM_ARCH_TIMER + select ARM_GIC ++ select ARM_GIC_V3 + select BUILDTIME_EXTABLE_SORT + select CLONE_BACKWARDS + select COMMON_CLK +@@ -76,7 +77,7 @@ config MMU + def_bool y + + config NO_IOPORT_MAP +- def_bool y ++ def_bool y if !PCI + + config STACKTRACE_SUPPORT + def_bool y +@@ -151,6 +152,23 @@ menu "Bus support" + config ARM_AMBA + bool + ++config PCI ++ bool "PCI support" ++ help ++ This feature enables support for PCIe bus system. If you say Y ++ here, the kernel will include drivers and infrastructure code ++ to support PCIe bus devices. ++ ++config PCI_DOMAINS ++ def_bool PCI ++ ++config PCI_SYSCALL ++ def_bool PCI ++ ++source "drivers/pci/Kconfig" ++source "drivers/pci/pcie/Kconfig" ++source "drivers/pci/hotplug/Kconfig" ++ + endmenu + + menu "Kernel Features" +diff --git a/arch/arm64/boot/dts/apm-mustang.dts b/arch/arm64/boot/dts/apm-mustang.dts +index 6541962..0cb67fc 100644 +--- a/arch/arm64/boot/dts/apm-mustang.dts ++++ b/arch/arm64/boot/dts/apm-mustang.dts +@@ -28,3 +28,15 @@ + &serial0 { + status = "ok"; + }; ++ ++&menet { ++ status = "ok"; ++}; ++ ++&pcie0clk { ++ status = "ok"; ++}; ++ ++&pcie0 { ++ status = "ok"; ++}; +diff --git a/arch/arm64/boot/dts/apm-storm.dtsi b/arch/arm64/boot/dts/apm-storm.dtsi +index 40aa96c..fb2ee54 100644 +--- a/arch/arm64/boot/dts/apm-storm.dtsi ++++ b/arch/arm64/boot/dts/apm-storm.dtsi +@@ -24,56 +24,56 @@ + compatible = "apm,potenza", "arm,armv8"; + reg = <0x0 0x000>; + enable-method = "spin-table"; +- cpu-release-addr = <0x1 0x0000fff8>; ++ cpu-release-addr = <0x40 0x0000f000>; + }; + cpu@001 { + device_type = "cpu"; + compatible = "apm,potenza", "arm,armv8"; + reg = <0x0 0x001>; + enable-method = "spin-table"; +- cpu-release-addr = <0x1 0x0000fff8>; ++ cpu-release-addr = <0x40 0x0000f000>; + }; + cpu@100 { + device_type = "cpu"; + compatible = "apm,potenza", "arm,armv8"; + reg = <0x0 0x100>; + enable-method = "spin-table"; +- cpu-release-addr = <0x1 0x0000fff8>; ++ cpu-release-addr = <0x40 0x0000f000>; + }; + cpu@101 { + device_type = "cpu"; + compatible = "apm,potenza", "arm,armv8"; + reg = <0x0 0x101>; + enable-method = "spin-table"; +- cpu-release-addr = <0x1 0x0000fff8>; ++ cpu-release-addr = <0x40 0x0000f000>; + }; + cpu@200 { + device_type = "cpu"; + compatible = "apm,potenza", "arm,armv8"; + reg = <0x0 0x200>; + enable-method = "spin-table"; +- cpu-release-addr = <0x1 0x0000fff8>; ++ cpu-release-addr = <0x40 0x0000f000>; + }; + cpu@201 { + device_type = "cpu"; + compatible = "apm,potenza", "arm,armv8"; + reg = <0x0 0x201>; + enable-method = "spin-table"; +- cpu-release-addr = <0x1 0x0000fff8>; ++ cpu-release-addr = <0x40 0x0000f000>; + }; + cpu@300 { + device_type = "cpu"; + compatible = "apm,potenza", "arm,armv8"; + reg = <0x0 0x300>; + enable-method = "spin-table"; +- cpu-release-addr = <0x1 0x0000fff8>; ++ cpu-release-addr = <0x40 0x0000f000>; + }; + cpu@301 { + device_type = "cpu"; + compatible = "apm,potenza", "arm,armv8"; + reg = <0x0 0x301>; + enable-method = "spin-table"; +- cpu-release-addr = <0x1 0x0000fff8>; ++ cpu-release-addr = <0x40 0x0000f000>; + }; + }; + +@@ -97,6 +97,11 @@ + clock-frequency = <50000000>; + }; + ++ pmu { ++ compatible = "arm,armv8-pmuv3"; ++ interrupts = <1 12 0xff04>; ++ }; ++ + soc { + compatible = "simple-bus"; + #address-cells = <2>; +@@ -167,14 +172,13 @@ + clock-output-names = "ethclk"; + }; + +- eth8clk: eth8clk { ++ menetclk: menetclk { + compatible = "apm,xgene-device-clock"; + #clock-cells = <1>; + clocks = <ðclk 0>; +- clock-names = "eth8clk"; + reg = <0x0 0x1702C000 0x0 0x1000>; + reg-names = "csr-reg"; +- clock-output-names = "eth8clk"; ++ clock-output-names = "menetclk"; + }; + + sataphy1clk: sataphy1clk@1f21c000 { +@@ -270,6 +274,161 @@ + enable-mask = <0x2>; + clock-output-names = "rtcclk"; + }; ++ ++ pcie0clk: pcie0clk@1f2bc000 { ++ status = "disabled"; ++ compatible = "apm,xgene-device-clock"; ++ #clock-cells = <1>; ++ clocks = <&socplldiv2 0>; ++ reg = <0x0 0x1f2bc000 0x0 0x1000>; ++ reg-names = "csr-reg"; ++ clock-output-names = "pcie0clk"; ++ }; ++ ++ pcie1clk: pcie1clk@1f2cc000 { ++ status = "disabled"; ++ compatible = "apm,xgene-device-clock"; ++ #clock-cells = <1>; ++ clocks = <&socplldiv2 0>; ++ reg = <0x0 0x1f2cc000 0x0 0x1000>; ++ reg-names = "csr-reg"; ++ clock-output-names = "pcie1clk"; ++ }; ++ ++ pcie2clk: pcie2clk@1f2dc000 { ++ status = "disabled"; ++ compatible = "apm,xgene-device-clock"; ++ #clock-cells = <1>; ++ clocks = <&socplldiv2 0>; ++ reg = <0x0 0x1f2dc000 0x0 0x1000>; ++ reg-names = "csr-reg"; ++ clock-output-names = "pcie2clk"; ++ }; ++ ++ pcie3clk: pcie3clk@1f50c000 { ++ status = "disabled"; ++ compatible = "apm,xgene-device-clock"; ++ #clock-cells = <1>; ++ clocks = <&socplldiv2 0>; ++ reg = <0x0 0x1f50c000 0x0 0x1000>; ++ reg-names = "csr-reg"; ++ clock-output-names = "pcie3clk"; ++ }; ++ ++ pcie4clk: pcie4clk@1f51c000 { ++ status = "disabled"; ++ compatible = "apm,xgene-device-clock"; ++ #clock-cells = <1>; ++ clocks = <&socplldiv2 0>; ++ reg = <0x0 0x1f51c000 0x0 0x1000>; ++ reg-names = "csr-reg"; ++ clock-output-names = "pcie4clk"; ++ }; ++ }; ++ ++ pcie0: pcie@1f2b0000 { ++ status = "disabled"; ++ device_type = "pci"; ++ compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; ++ #interrupt-cells = <1>; ++ #size-cells = <2>; ++ #address-cells = <3>; ++ reg = < 0x00 0x1f2b0000 0x0 0x00010000 /* Controller registers */ ++ 0xe0 0xd0000000 0x0 0x00200000>; /* PCI config space */ ++ reg-names = "csr", "cfg"; ++ ranges = <0x01000000 0x00 0x00000000 0xe0 0x00000000 0x00 0x00010000 /* io */ ++ 0x02000000 0x00 0x10000000 0xe0 0x10000000 0x00 0x80000000>; /* mem */ ++ dma-ranges = <0x42000000 0x40 0x00000000 0x40 0x00000000 0x40 0x00000000>; ++ interrupt-map-mask = <0x0 0x0 0x0 0x7>; ++ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc2 0x1 ++ 0x0 0x0 0x0 0x2 &gic 0x0 0xc3 0x1 ++ 0x0 0x0 0x0 0x3 &gic 0x0 0xc4 0x1 ++ 0x0 0x0 0x0 0x4 &gic 0x0 0xc5 0x1>; ++ clocks = <&pcie0clk 0>; ++ }; ++ ++ pcie1: pcie@1f2c0000 { ++ status = "disabled"; ++ device_type = "pci"; ++ compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; ++ #interrupt-cells = <1>; ++ #size-cells = <2>; ++ #address-cells = <3>; ++ reg = < 0x00 0x1f2c0000 0x0 0x00010000 /* Controller registers */ ++ 0xd0 0xd0000000 0x0 0x00200000>; /* PCI config space */ ++ reg-names = "csr", "cfg"; ++ ranges = <0x01000000 0x0 0x00000000 0xd0 0x00000000 0x00 0x00010000 /* io */ ++ 0x02000000 0x0 0x10000000 0xd0 0x10000000 0x00 0x80000000>; /* mem */ ++ dma-ranges = <0x42000000 0x40 0x00000000 0x40 0x00000000 0x40 0x00000000>; ++ interrupt-map-mask = <0x0 0x0 0x0 0x7>; ++ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xc8 0x1 ++ 0x0 0x0 0x0 0x2 &gic 0x0 0xc9 0x1 ++ 0x0 0x0 0x0 0x3 &gic 0x0 0xca 0x1 ++ 0x0 0x0 0x0 0x4 &gic 0x0 0xcb 0x1>; ++ clocks = <&pcie1clk 0>; ++ }; ++ ++ pcie2: pcie@1f2d0000 { ++ status = "disabled"; ++ device_type = "pci"; ++ compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; ++ #interrupt-cells = <1>; ++ #size-cells = <2>; ++ #address-cells = <3>; ++ reg = < 0x00 0x1f2d0000 0x0 0x00010000 /* Controller registers */ ++ 0x90 0xd0000000 0x0 0x00200000>; /* PCI config space */ ++ reg-names = "csr", "cfg"; ++ ranges = <0x01000000 0x0 0x00000000 0x90 0x00000000 0x0 0x00010000 /* io */ ++ 0x02000000 0x0 0x10000000 0x90 0x10000000 0x0 0x80000000>; /* mem */ ++ dma-ranges = <0x42000000 0x40 0x00000000 0x40 0x00000000 0x40 0x00000000>; ++ interrupt-map-mask = <0x0 0x0 0x0 0x7>; ++ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xce 0x1 ++ 0x0 0x0 0x0 0x2 &gic 0x0 0xcf 0x1 ++ 0x0 0x0 0x0 0x3 &gic 0x0 0xd0 0x1 ++ 0x0 0x0 0x0 0x4 &gic 0x0 0xd1 0x1>; ++ clocks = <&pcie2clk 0>; ++ }; ++ ++ pcie3: pcie@1f500000 { ++ status = "disabled"; ++ device_type = "pci"; ++ compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; ++ #interrupt-cells = <1>; ++ #size-cells = <2>; ++ #address-cells = <3>; ++ reg = < 0x00 0x1f500000 0x0 0x00010000 /* Controller registers */ ++ 0xa0 0xd0000000 0x0 0x00200000>; /* PCI config space */ ++ reg-names = "csr", "cfg"; ++ ranges = <0x01000000 0x0 0x00000000 0xa0 0x00000000 0x0 0x00010000 /* io */ ++ 0x02000000 0x0 0x10000000 0xa0 0x10000000 0x0 0x80000000>; /* mem */ ++ dma-ranges = <0x42000000 0x40 0x00000000 0x40 0x00000000 0x40 0x00000000>; ++ interrupt-map-mask = <0x0 0x0 0x0 0x7>; ++ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xd4 0x1 ++ 0x0 0x0 0x0 0x2 &gic 0x0 0xd5 0x1 ++ 0x0 0x0 0x0 0x3 &gic 0x0 0xd6 0x1 ++ 0x0 0x0 0x0 0x4 &gic 0x0 0xd7 0x1>; ++ clocks = <&pcie3clk 0>; ++ }; ++ ++ pcie4: pcie@1f510000 { ++ status = "disabled"; ++ device_type = "pci"; ++ compatible = "apm,xgene-storm-pcie", "apm,xgene-pcie"; ++ #interrupt-cells = <1>; ++ #size-cells = <2>; ++ #address-cells = <3>; ++ reg = < 0x00 0x1f510000 0x0 0x00010000 /* Controller registers */ ++ 0xc0 0xd0000000 0x0 0x00200000>; /* PCI config space */ ++ reg-names = "csr", "cfg"; ++ ranges = <0x01000000 0x0 0x00000000 0xc0 0x00000000 0x0 0x00010000 /* io */ ++ 0x02000000 0x0 0x10000000 0xc0 0x10000000 0x0 0x80000000>; /* mem */ ++ dma-ranges = <0x42000000 0x40 0x00000000 0x40 0x00000000 0x40 0x00000000>; ++ interrupt-map-mask = <0x0 0x0 0x0 0x7>; ++ interrupt-map = <0x0 0x0 0x0 0x1 &gic 0x0 0xda 0x1 ++ 0x0 0x0 0x0 0x2 &gic 0x0 0xdb 0x1 ++ 0x0 0x0 0x0 0x3 &gic 0x0 0xdc 0x1 ++ 0x0 0x0 0x0 0x4 &gic 0x0 0xdd 0x1>; ++ clocks = <&pcie4clk 0>; + }; + + serial0: serial@1c020000 { +@@ -278,7 +437,7 @@ + compatible = "ns16550a"; + reg = <0 0x1c020000 0x0 0x1000>; + reg-shift = <2>; +- clock-frequency = <10000000>; /* Updated by bootloader */ ++ clock-frequency = <50000000>; /* Updated by bootloader */ + interrupt-parent = <&gic>; + interrupts = <0x0 0x4c 0x4>; + }; +@@ -397,5 +556,30 @@ + #clock-cells = <1>; + clocks = <&rtcclk 0>; + }; ++ ++ menet: ethernet@17020000 { ++ compatible = "apm,xgene-enet"; ++ status = "disabled"; ++ reg = <0x0 0x17020000 0x0 0xd100>, ++ <0x0 0X17030000 0x0 0X400>, ++ <0x0 0X10000000 0x0 0X200>; ++ reg-names = "enet_csr", "ring_csr", "ring_cmd"; ++ interrupts = <0x0 0x3c 0x4>; ++ dma-coherent; ++ clocks = <&menetclk 0>; ++ local-mac-address = [00 00 00 00 00 00]; ++ phy-connection-type = "rgmii"; ++ phy-handle = <&menetphy>; ++ mdio { ++ compatible = "apm,xgene-mdio"; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ menetphy: menetphy@3 { ++ compatible = "ethernet-phy-id001c.c915"; ++ reg = <0x3>; ++ }; ++ ++ }; ++ }; + }; + }; +diff --git a/arch/arm64/include/asm/Kbuild b/arch/arm64/include/asm/Kbuild +index 0b3fcf8..07cb417 100644 +--- a/arch/arm64/include/asm/Kbuild ++++ b/arch/arm64/include/asm/Kbuild +@@ -29,6 +29,7 @@ generic-y += mman.h + generic-y += msgbuf.h + generic-y += mutex.h + generic-y += pci.h ++generic-y += pci-bridge.h + generic-y += poll.h + generic-y += preempt.h + generic-y += resource.h +diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h +index 01d3aab..8186df6 100644 +--- a/arch/arm64/include/asm/elf.h ++++ b/arch/arm64/include/asm/elf.h +@@ -114,7 +114,8 @@ typedef struct user_fpsimd_state elf_fpregset_t; + */ + #define elf_check_arch(x) ((x)->e_machine == EM_AARCH64) + +-#define elf_read_implies_exec(ex,stk) (stk != EXSTACK_DISABLE_X) ++#define elf_read_implies_exec(ex,stk) (test_thread_flag(TIF_32BIT) \ ++ ? (stk == EXSTACK_ENABLE_X) : 0) + + #define CORE_DUMP_USE_REGSET + #define ELF_EXEC_PAGESIZE PAGE_SIZE +diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h +index e0ecdcf..dc34039 100644 +--- a/arch/arm64/include/asm/io.h ++++ b/arch/arm64/include/asm/io.h +@@ -121,7 +121,8 @@ static inline u64 __raw_readq(const volatile void __iomem *addr) + /* + * I/O port access primitives. + */ +-#define IO_SPACE_LIMIT 0xffff ++#define arch_has_dev_port() (1) ++#define IO_SPACE_LIMIT 0x1ffffff + #define PCI_IOBASE ((void __iomem *)(MODULES_VADDR - SZ_32M)) + + static inline u8 inb(unsigned long addr) +diff --git a/arch/arm64/include/asm/kvm_arm.h b/arch/arm64/include/asm/kvm_arm.h +index 3d69030..cc83520 100644 +--- a/arch/arm64/include/asm/kvm_arm.h ++++ b/arch/arm64/include/asm/kvm_arm.h +@@ -76,9 +76,10 @@ + */ + #define HCR_GUEST_FLAGS (HCR_TSC | HCR_TSW | HCR_TWE | HCR_TWI | HCR_VM | \ + HCR_TVM | HCR_BSU_IS | HCR_FB | HCR_TAC | \ +- HCR_AMO | HCR_IMO | HCR_FMO | \ +- HCR_SWIO | HCR_TIDCP | HCR_RW) ++ HCR_AMO | HCR_SWIO | HCR_TIDCP | HCR_RW) + #define HCR_VIRT_EXCP_MASK (HCR_VA | HCR_VI | HCR_VF) ++#define HCR_INT_OVERRIDE (HCR_FMO | HCR_IMO) ++ + + /* Hyp System Control Register (SCTLR_EL2) bits */ + #define SCTLR_EL2_EE (1 << 25) +diff --git a/arch/arm64/include/asm/kvm_asm.h b/arch/arm64/include/asm/kvm_asm.h +index 9fcd54b..a28c35b 100644 +--- a/arch/arm64/include/asm/kvm_asm.h ++++ b/arch/arm64/include/asm/kvm_asm.h +@@ -18,6 +18,8 @@ + #ifndef __ARM_KVM_ASM_H__ + #define __ARM_KVM_ASM_H__ + ++#include <asm/virt.h> ++ + /* + * 0 is reserved as an invalid value. + * Order *must* be kept in sync with the hyp switch code. +@@ -96,13 +98,21 @@ extern char __kvm_hyp_init_end[]; + + extern char __kvm_hyp_vector[]; + +-extern char __kvm_hyp_code_start[]; +-extern char __kvm_hyp_code_end[]; ++#define __kvm_hyp_code_start __hyp_text_start ++#define __kvm_hyp_code_end __hyp_text_end + + extern void __kvm_flush_vm_context(void); + extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa); + + extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu); ++ ++extern u64 __vgic_v3_get_ich_vtr_el2(void); ++ ++extern char __save_vgic_v2_state[]; ++extern char __restore_vgic_v2_state[]; ++extern char __save_vgic_v3_state[]; ++extern char __restore_vgic_v3_state[]; ++ + #endif + + #endif /* __ARM_KVM_ASM_H__ */ +diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h +index 92242ce..4ae9213 100644 +--- a/arch/arm64/include/asm/kvm_host.h ++++ b/arch/arm64/include/asm/kvm_host.h +@@ -200,4 +200,32 @@ static inline void __cpu_init_hyp_mode(phys_addr_t boot_pgd_ptr, + hyp_stack_ptr, vector_ptr); + } + ++struct vgic_sr_vectors { ++ void *save_vgic; ++ void *restore_vgic; ++}; ++ ++static inline void vgic_arch_setup(const struct vgic_params *vgic) ++{ ++ extern struct vgic_sr_vectors __vgic_sr_vectors; ++ ++ switch(vgic->type) ++ { ++ case VGIC_V2: ++ __vgic_sr_vectors.save_vgic = __save_vgic_v2_state; ++ __vgic_sr_vectors.restore_vgic = __restore_vgic_v2_state; ++ break; ++ ++#ifdef CONFIG_ARM_GIC_V3 ++ case VGIC_V3: ++ __vgic_sr_vectors.save_vgic = __save_vgic_v3_state; ++ __vgic_sr_vectors.restore_vgic = __restore_vgic_v3_state; ++ break; ++#endif ++ ++ default: ++ BUG(); ++ } ++} ++ + #endif /* __ARM64_KVM_HOST_H__ */ +diff --git a/arch/arm64/include/asm/kvm_mmu.h b/arch/arm64/include/asm/kvm_mmu.h +index 7d29847..d7f77ff 100644 +--- a/arch/arm64/include/asm/kvm_mmu.h ++++ b/arch/arm64/include/asm/kvm_mmu.h +@@ -122,8 +122,16 @@ static inline void kvm_set_s2pmd_writable(pmd_t *pmd) + } + + #define kvm_pgd_addr_end(addr, end) pgd_addr_end(addr, end) +-#define kvm_pud_addr_end(addr, end) pud_addr_end(addr, end) +-#define kvm_pmd_addr_end(addr, end) pmd_addr_end(addr, end) ++ ++#define kvm_pud_addr_end(addr, end) \ ++({ unsigned long __boundary = ((addr) + PUD_SIZE) & PUD_MASK; \ ++ (__boundary - 1 < (end) - 1)? __boundary: (end); \ ++}) ++ ++#define kvm_pmd_addr_end(addr, end) \ ++({ unsigned long __boundary = ((addr) + PMD_SIZE) & PMD_MASK; \ ++ (__boundary - 1 < (end) - 1)? __boundary: (end); \ ++}) + + struct kvm; + +diff --git a/arch/arm64/include/asm/pci.h b/arch/arm64/include/asm/pci.h +new file mode 100644 +index 0000000..3f7856e +--- /dev/null ++++ b/arch/arm64/include/asm/pci.h +@@ -0,0 +1,49 @@ ++#ifndef __ASM_PCI_H ++#define __ASM_PCI_H ++#ifdef __KERNEL__ ++ ++#include <linux/types.h> ++#include <linux/slab.h> ++#include <linux/dma-mapping.h> ++ ++#include <asm/io.h> ++#include <asm-generic/pci-bridge.h> ++#include <asm-generic/pci-dma-compat.h> ++ ++#define PCIBIOS_MIN_IO 0x1000 ++#define PCIBIOS_MIN_MEM 0 ++ ++struct pci_host_bridge *find_pci_host_bridge(struct pci_bus *bus); ++ ++/* ++ * Set to 1 if the kernel should re-assign all PCI bus numbers ++ */ ++#define pcibios_assign_all_busses() \ ++ (pci_has_flag(PCI_REASSIGN_ALL_BUS)) ++ ++/* ++ * PCI address space differs from physical memory address space ++ */ ++#define PCI_DMA_BUS_IS_PHYS (0) ++ ++extern int isa_dma_bridge_buggy; ++ ++#ifdef CONFIG_PCI ++static inline int pci_domain_nr(struct pci_bus *bus) ++{ ++ struct pci_host_bridge *bridge = find_pci_host_bridge(bus); ++ ++ if (bridge) ++ return bridge->domain_nr; ++ ++ return 0; ++} ++ ++static inline int pci_proc_domain(struct pci_bus *bus) ++{ ++ return 1; ++} ++#endif /* CONFIG_PCI */ ++ ++#endif /* __KERNEL__ */ ++#endif /* __ASM_PCI_H */ +diff --git a/arch/arm64/include/asm/tlbflush.h b/arch/arm64/include/asm/tlbflush.h +index b9349c4..ecbd081 100644 +--- a/arch/arm64/include/asm/tlbflush.h ++++ b/arch/arm64/include/asm/tlbflush.h +@@ -98,8 +98,8 @@ static inline void flush_tlb_page(struct vm_area_struct *vma, + dsb(ish); + } + +-static inline void flush_tlb_range(struct vm_area_struct *vma, +- unsigned long start, unsigned long end) ++static inline void __flush_tlb_range(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end) + { + unsigned long asid = (unsigned long)ASID(vma->vm_mm) << 48; + unsigned long addr; +@@ -112,7 +112,7 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, + dsb(ish); + } + +-static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) ++static inline void __flush_tlb_kernel_range(unsigned long start, unsigned long end) + { + unsigned long addr; + start >>= 12; +@@ -125,6 +125,29 @@ static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end + } + + /* ++ * This is meant to avoid soft lock-ups on large TLB flushing ranges and not ++ * necessarily a performance improvement. ++ */ ++#define MAX_TLB_RANGE (1024UL << PAGE_SHIFT) ++ ++static inline void flush_tlb_range(struct vm_area_struct *vma, ++ unsigned long start, unsigned long end) ++{ ++ if ((end - start) <= MAX_TLB_RANGE) ++ __flush_tlb_range(vma, start, end); ++ else ++ flush_tlb_mm(vma->vm_mm); ++} ++ ++static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) ++{ ++ if ((end - start) <= MAX_TLB_RANGE) ++ __flush_tlb_kernel_range(start, end); ++ else ++ flush_tlb_all(); ++} ++ ++/* + * On AArch64, the cache coherency is handled via the set_pte_at() function. + */ + static inline void update_mmu_cache(struct vm_area_struct *vma, +diff --git a/arch/arm64/include/asm/virt.h b/arch/arm64/include/asm/virt.h +index 215ad46..7a5df52 100644 +--- a/arch/arm64/include/asm/virt.h ++++ b/arch/arm64/include/asm/virt.h +@@ -50,6 +50,10 @@ static inline bool is_hyp_mode_mismatched(void) + return __boot_cpu_mode[0] != __boot_cpu_mode[1]; + } + ++/* The section containing the hypervisor text */ ++extern char __hyp_text_start[]; ++extern char __hyp_text_end[]; ++ + #endif /* __ASSEMBLY__ */ + + #endif /* ! __ASM__VIRT_H */ +diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile +index cdaedad..36b117a 100644 +--- a/arch/arm64/kernel/Makefile ++++ b/arch/arm64/kernel/Makefile +@@ -29,6 +29,7 @@ arm64-obj-$(CONFIG_ARM64_CPU_SUSPEND) += sleep.o suspend.o + arm64-obj-$(CONFIG_JUMP_LABEL) += jump_label.o + arm64-obj-$(CONFIG_KGDB) += kgdb.o + arm64-obj-$(CONFIG_EFI) += efi.o efi-stub.o efi-entry.o ++arm64-obj-$(CONFIG_PCI) += pci.o + + obj-y += $(arm64-obj-y) vdso/ + obj-m += $(arm64-obj-m) +diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c +index 646f888..e74654c 100644 +--- a/arch/arm64/kernel/asm-offsets.c ++++ b/arch/arm64/kernel/asm-offsets.c +@@ -129,13 +129,24 @@ int main(void) + DEFINE(KVM_TIMER_ENABLED, offsetof(struct kvm, arch.timer.enabled)); + DEFINE(VCPU_KVM, offsetof(struct kvm_vcpu, kvm)); + DEFINE(VCPU_VGIC_CPU, offsetof(struct kvm_vcpu, arch.vgic_cpu)); +- DEFINE(VGIC_CPU_HCR, offsetof(struct vgic_cpu, vgic_hcr)); +- DEFINE(VGIC_CPU_VMCR, offsetof(struct vgic_cpu, vgic_vmcr)); +- DEFINE(VGIC_CPU_MISR, offsetof(struct vgic_cpu, vgic_misr)); +- DEFINE(VGIC_CPU_EISR, offsetof(struct vgic_cpu, vgic_eisr)); +- DEFINE(VGIC_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_elrsr)); +- DEFINE(VGIC_CPU_APR, offsetof(struct vgic_cpu, vgic_apr)); +- DEFINE(VGIC_CPU_LR, offsetof(struct vgic_cpu, vgic_lr)); ++ DEFINE(VGIC_SAVE_FN, offsetof(struct vgic_sr_vectors, save_vgic)); ++ DEFINE(VGIC_RESTORE_FN, offsetof(struct vgic_sr_vectors, restore_vgic)); ++ DEFINE(VGIC_SR_VECTOR_SZ, sizeof(struct vgic_sr_vectors)); ++ DEFINE(VGIC_V2_CPU_HCR, offsetof(struct vgic_cpu, vgic_v2.vgic_hcr)); ++ DEFINE(VGIC_V2_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v2.vgic_vmcr)); ++ DEFINE(VGIC_V2_CPU_MISR, offsetof(struct vgic_cpu, vgic_v2.vgic_misr)); ++ DEFINE(VGIC_V2_CPU_EISR, offsetof(struct vgic_cpu, vgic_v2.vgic_eisr)); ++ DEFINE(VGIC_V2_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v2.vgic_elrsr)); ++ DEFINE(VGIC_V2_CPU_APR, offsetof(struct vgic_cpu, vgic_v2.vgic_apr)); ++ DEFINE(VGIC_V2_CPU_LR, offsetof(struct vgic_cpu, vgic_v2.vgic_lr)); ++ DEFINE(VGIC_V3_CPU_HCR, offsetof(struct vgic_cpu, vgic_v3.vgic_hcr)); ++ DEFINE(VGIC_V3_CPU_VMCR, offsetof(struct vgic_cpu, vgic_v3.vgic_vmcr)); ++ DEFINE(VGIC_V3_CPU_MISR, offsetof(struct vgic_cpu, vgic_v3.vgic_misr)); ++ DEFINE(VGIC_V3_CPU_EISR, offsetof(struct vgic_cpu, vgic_v3.vgic_eisr)); ++ DEFINE(VGIC_V3_CPU_ELRSR, offsetof(struct vgic_cpu, vgic_v3.vgic_elrsr)); ++ DEFINE(VGIC_V3_CPU_AP0R, offsetof(struct vgic_cpu, vgic_v3.vgic_ap0r)); ++ DEFINE(VGIC_V3_CPU_AP1R, offsetof(struct vgic_cpu, vgic_v3.vgic_ap1r)); ++ DEFINE(VGIC_V3_CPU_LR, offsetof(struct vgic_cpu, vgic_v3.vgic_lr)); + DEFINE(VGIC_CPU_NR_LR, offsetof(struct vgic_cpu, nr_lr)); + DEFINE(KVM_VTTBR, offsetof(struct kvm, arch.vttbr)); + DEFINE(KVM_VGIC_VCTRL, offsetof(struct kvm, arch.vgic.vctrl_base)); +diff --git a/arch/arm64/kernel/efi-stub.c b/arch/arm64/kernel/efi-stub.c +index e786e6c..320ef48 100644 +--- a/arch/arm64/kernel/efi-stub.c ++++ b/arch/arm64/kernel/efi-stub.c +@@ -58,20 +58,16 @@ static efi_status_t handle_kernel_image(efi_system_table_t *sys_table, + kernel_size = _edata - _text; + if (*image_addr != (dram_base + TEXT_OFFSET)) { + kernel_memsize = kernel_size + (_end - _edata); +- status = efi_relocate_kernel(sys_table, image_addr, +- kernel_size, kernel_memsize, +- dram_base + TEXT_OFFSET, +- PAGE_SIZE); ++ status = efi_low_alloc(sys_table, kernel_memsize + TEXT_OFFSET, ++ SZ_2M, reserve_addr); + if (status != EFI_SUCCESS) { + pr_efi_err(sys_table, "Failed to relocate kernel\n"); + return status; + } +- if (*image_addr != (dram_base + TEXT_OFFSET)) { +- pr_efi_err(sys_table, "Failed to alloc kernel memory\n"); +- efi_free(sys_table, kernel_memsize, *image_addr); +- return EFI_ERROR; +- } +- *image_size = kernel_memsize; ++ memcpy((void *)*reserve_addr + TEXT_OFFSET, (void *)*image_addr, ++ kernel_size); ++ *image_addr = *reserve_addr + TEXT_OFFSET; ++ *reserve_size = kernel_memsize + TEXT_OFFSET; + } + + +diff --git a/arch/arm64/kernel/efi.c b/arch/arm64/kernel/efi.c +index 14db1f6..453b7f8 100644 +--- a/arch/arm64/kernel/efi.c ++++ b/arch/arm64/kernel/efi.c +@@ -467,3 +467,14 @@ static int __init arm64_enter_virtual_mode(void) + return 0; + } + early_initcall(arm64_enter_virtual_mode); ++ ++/* ++ * If nothing else is handling pm_power_off, use EFI ++ * ++ * This is called from a late_initcall after other mechanisms ++ * have had a chance to register a handler. ++ */ ++bool efi_poweroff_required(void) ++{ ++ return pm_power_off == NULL; ++} +diff --git a/arch/arm64/kernel/head.S b/arch/arm64/kernel/head.S +index a2c1195..8df59be 100644 +--- a/arch/arm64/kernel/head.S ++++ b/arch/arm64/kernel/head.S +@@ -22,6 +22,7 @@ + + #include <linux/linkage.h> + #include <linux/init.h> ++#include <linux/irqchip/arm-gic-v3.h> + + #include <asm/assembler.h> + #include <asm/ptrace.h> +@@ -156,7 +157,7 @@ optional_header: + .short 0x20b // PE32+ format + .byte 0x02 // MajorLinkerVersion + .byte 0x14 // MinorLinkerVersion +- .long _edata - stext // SizeOfCode ++ .long _end - stext // SizeOfCode + .long 0 // SizeOfInitializedData + .long 0 // SizeOfUninitializedData + .long efi_stub_entry - efi_head // AddressOfEntryPoint +@@ -174,7 +175,7 @@ extra_header_fields: + .short 0 // MinorSubsystemVersion + .long 0 // Win32VersionValue + +- .long _edata - efi_head // SizeOfImage ++ .long _end - efi_head // SizeOfImage + + // Everything before the kernel image is considered part of the header + .long stext - efi_head // SizeOfHeaders +@@ -221,7 +222,7 @@ section_table: + .byte 0 + .byte 0 + .byte 0 // end of 0 padding of section name +- .long _edata - stext // VirtualSize ++ .long _end - stext // VirtualSize + .long stext - efi_head // VirtualAddress + .long _edata - stext // SizeOfRawData + .long stext - efi_head // PointerToRawData +@@ -295,6 +296,23 @@ CPU_LE( bic x0, x0, #(3 << 24) ) // Clear the EE and E0E bits for EL1 + msr cnthctl_el2, x0 + msr cntvoff_el2, xzr // Clear virtual offset + ++#ifdef CONFIG_ARM_GIC_V3 ++ /* GICv3 system register access */ ++ mrs x0, id_aa64pfr0_el1 ++ ubfx x0, x0, #24, #4 ++ cmp x0, #1 ++ b.ne 3f ++ ++ mrs x0, ICC_SRE_EL2 ++ orr x0, x0, #ICC_SRE_EL2_SRE // Set ICC_SRE_EL2.SRE==1 ++ orr x0, x0, #ICC_SRE_EL2_ENABLE // Set ICC_SRE_EL2.Enable==1 ++ msr ICC_SRE_EL2, x0 ++ isb // Make sure SRE is now set ++ msr ICH_HCR_EL2, xzr // Reset ICC_HCR_EL2 to defaults ++ ++3: ++#endif ++ + /* Populate ID registers. */ + mrs x0, midr_el1 + mrs x1, mpidr_el1 +diff --git a/arch/arm64/kernel/hyp-stub.S b/arch/arm64/kernel/hyp-stub.S +index 0959611..a272f33 100644 +--- a/arch/arm64/kernel/hyp-stub.S ++++ b/arch/arm64/kernel/hyp-stub.S +@@ -19,6 +19,7 @@ + + #include <linux/init.h> + #include <linux/linkage.h> ++#include <linux/irqchip/arm-gic-v3.h> + + #include <asm/assembler.h> + #include <asm/ptrace.h> +diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c +new file mode 100644 +index 0000000..955d6d1 +--- /dev/null ++++ b/arch/arm64/kernel/pci.c +@@ -0,0 +1,38 @@ ++/* ++ * Code borrowed from powerpc/kernel/pci-common.c ++ * ++ * Copyright (C) 2003 Anton Blanchard <anton@au.ibm.com>, IBM ++ * Copyright (C) 2014 ARM Ltd. ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * version 2 as published by the Free Software Foundation. ++ * ++ */ ++ ++#include <linux/init.h> ++#include <linux/io.h> ++#include <linux/kernel.h> ++#include <linux/mm.h> ++#include <linux/of_pci.h> ++#include <linux/of_platform.h> ++#include <linux/slab.h> ++ ++#include <asm/pci-bridge.h> ++ ++/* ++ * Called after each bus is probed, but before its children are examined ++ */ ++void pcibios_fixup_bus(struct pci_bus *bus) ++{ ++ /* nothing to do, expected to be removed in the future */ ++} ++ ++/* ++ * We don't have to worry about legacy ISA devices, so nothing to do here ++ */ ++resource_size_t pcibios_align_resource(void *data, const struct resource *res, ++ resource_size_t size, resource_size_t align) ++{ ++ return res->start; ++} +diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c +index 43b7c34..ec5cbbe 100644 +--- a/arch/arm64/kernel/process.c ++++ b/arch/arm64/kernel/process.c +@@ -43,6 +43,7 @@ + #include <linux/hw_breakpoint.h> + #include <linux/personality.h> + #include <linux/notifier.h> ++#include <linux/efi.h> + + #include <asm/compat.h> + #include <asm/cacheflush.h> +@@ -176,6 +177,11 @@ void machine_restart(char *cmd) + arm_pm_restart(reboot_mode, cmd); + + /* ++ * If all else fails, try EFI ++ */ ++ efi_reboot(reboot_mode, cmd); ++ ++ /* + * Whoops - the architecture was unable to reboot. + */ + printk("Reboot failed -- System halted\n"); +diff --git a/arch/arm64/kernel/smp_spin_table.c b/arch/arm64/kernel/smp_spin_table.c +index 0347d38..70181c1 100644 +--- a/arch/arm64/kernel/smp_spin_table.c ++++ b/arch/arm64/kernel/smp_spin_table.c +@@ -20,6 +20,7 @@ + #include <linux/init.h> + #include <linux/of.h> + #include <linux/smp.h> ++#include <linux/types.h> + + #include <asm/cacheflush.h> + #include <asm/cpu_ops.h> +@@ -65,12 +66,21 @@ static int smp_spin_table_cpu_init(struct device_node *dn, unsigned int cpu) + + static int smp_spin_table_cpu_prepare(unsigned int cpu) + { +- void **release_addr; ++ __le64 __iomem *release_addr; + + if (!cpu_release_addr[cpu]) + return -ENODEV; + +- release_addr = __va(cpu_release_addr[cpu]); ++ /* ++ * The cpu-release-addr may or may not be inside the linear mapping. ++ * As ioremap_cache will either give us a new mapping or reuse the ++ * existing linear mapping, we can use it to cover both cases. In ++ * either case the memory will be MT_NORMAL. ++ */ ++ release_addr = ioremap_cache(cpu_release_addr[cpu], ++ sizeof(*release_addr)); ++ if (!release_addr) ++ return -ENOMEM; + + /* + * We write the release address as LE regardless of the native +@@ -79,15 +89,16 @@ static int smp_spin_table_cpu_prepare(unsigned int cpu) + * boot-loader's endianess before jumping. This is mandated by + * the boot protocol. + */ +- release_addr[0] = (void *) cpu_to_le64(__pa(secondary_holding_pen)); +- +- __flush_dcache_area(release_addr, sizeof(release_addr[0])); ++ writeq_relaxed(__pa(secondary_holding_pen), release_addr); ++ __flush_dcache_area(release_addr, sizeof(*release_addr)); + + /* + * Send an event to wake up the secondary CPU. + */ + sev(); + ++ iounmap(release_addr); ++ + return 0; + } + +diff --git a/arch/arm64/kvm/Makefile b/arch/arm64/kvm/Makefile +index 72a9fd5..32a0961 100644 +--- a/arch/arm64/kvm/Makefile ++++ b/arch/arm64/kvm/Makefile +@@ -20,4 +20,8 @@ kvm-$(CONFIG_KVM_ARM_HOST) += hyp.o hyp-init.o handle_exit.o + kvm-$(CONFIG_KVM_ARM_HOST) += guest.o reset.o sys_regs.o sys_regs_generic_v8.o + + kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o ++kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o ++kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v2-switch.o ++kvm-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v3.o ++kvm-$(CONFIG_KVM_ARM_VGIC) += vgic-v3-switch.o + kvm-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o +diff --git a/arch/arm64/kvm/hyp.S b/arch/arm64/kvm/hyp.S +index b0d1512..5945f3b 100644 +--- a/arch/arm64/kvm/hyp.S ++++ b/arch/arm64/kvm/hyp.S +@@ -16,7 +16,6 @@ + */ + + #include <linux/linkage.h> +-#include <linux/irqchip/arm-gic.h> + + #include <asm/assembler.h> + #include <asm/memory.h> +@@ -36,9 +35,6 @@ + .pushsection .hyp.text, "ax" + .align PAGE_SHIFT + +-__kvm_hyp_code_start: +- .globl __kvm_hyp_code_start +- + .macro save_common_regs + // x2: base address for cpu context + // x3: tmp register +@@ -339,11 +335,8 @@ __kvm_hyp_code_start: + .endm + + .macro activate_traps +- ldr x2, [x0, #VCPU_IRQ_LINES] +- ldr x1, [x0, #VCPU_HCR_EL2] +- orr x2, x2, x1 +- msr hcr_el2, x2 +- ++ ldr x2, [x0, #VCPU_HCR_EL2] ++ msr hcr_el2, x2 + ldr x2, =(CPTR_EL2_TTA) + msr cptr_el2, x2 + +@@ -379,100 +372,33 @@ __kvm_hyp_code_start: + .endm + + /* +- * Save the VGIC CPU state into memory +- * x0: Register pointing to VCPU struct +- * Do not corrupt x1!!! ++ * Call into the vgic backend for state saving + */ + .macro save_vgic_state +- /* Get VGIC VCTRL base into x2 */ +- ldr x2, [x0, #VCPU_KVM] +- kern_hyp_va x2 +- ldr x2, [x2, #KVM_VGIC_VCTRL] +- kern_hyp_va x2 +- cbz x2, 2f // disabled +- +- /* Compute the address of struct vgic_cpu */ +- add x3, x0, #VCPU_VGIC_CPU +- +- /* Save all interesting registers */ +- ldr w4, [x2, #GICH_HCR] +- ldr w5, [x2, #GICH_VMCR] +- ldr w6, [x2, #GICH_MISR] +- ldr w7, [x2, #GICH_EISR0] +- ldr w8, [x2, #GICH_EISR1] +- ldr w9, [x2, #GICH_ELRSR0] +- ldr w10, [x2, #GICH_ELRSR1] +- ldr w11, [x2, #GICH_APR] +-CPU_BE( rev w4, w4 ) +-CPU_BE( rev w5, w5 ) +-CPU_BE( rev w6, w6 ) +-CPU_BE( rev w7, w7 ) +-CPU_BE( rev w8, w8 ) +-CPU_BE( rev w9, w9 ) +-CPU_BE( rev w10, w10 ) +-CPU_BE( rev w11, w11 ) +- +- str w4, [x3, #VGIC_CPU_HCR] +- str w5, [x3, #VGIC_CPU_VMCR] +- str w6, [x3, #VGIC_CPU_MISR] +- str w7, [x3, #VGIC_CPU_EISR] +- str w8, [x3, #(VGIC_CPU_EISR + 4)] +- str w9, [x3, #VGIC_CPU_ELRSR] +- str w10, [x3, #(VGIC_CPU_ELRSR + 4)] +- str w11, [x3, #VGIC_CPU_APR] +- +- /* Clear GICH_HCR */ +- str wzr, [x2, #GICH_HCR] +- +- /* Save list registers */ +- add x2, x2, #GICH_LR0 +- ldr w4, [x3, #VGIC_CPU_NR_LR] +- add x3, x3, #VGIC_CPU_LR +-1: ldr w5, [x2], #4 +-CPU_BE( rev w5, w5 ) +- str w5, [x3], #4 +- sub w4, w4, #1 +- cbnz w4, 1b +-2: ++ adr x24, __vgic_sr_vectors ++ ldr x24, [x24, VGIC_SAVE_FN] ++ kern_hyp_va x24 ++ blr x24 ++ mrs x24, hcr_el2 ++ mov x25, #HCR_INT_OVERRIDE ++ neg x25, x25 ++ and x24, x24, x25 ++ msr hcr_el2, x24 + .endm + + /* +- * Restore the VGIC CPU state from memory +- * x0: Register pointing to VCPU struct ++ * Call into the vgic backend for state restoring + */ + .macro restore_vgic_state +- /* Get VGIC VCTRL base into x2 */ +- ldr x2, [x0, #VCPU_KVM] +- kern_hyp_va x2 +- ldr x2, [x2, #KVM_VGIC_VCTRL] +- kern_hyp_va x2 +- cbz x2, 2f // disabled +- +- /* Compute the address of struct vgic_cpu */ +- add x3, x0, #VCPU_VGIC_CPU +- +- /* We only restore a minimal set of registers */ +- ldr w4, [x3, #VGIC_CPU_HCR] +- ldr w5, [x3, #VGIC_CPU_VMCR] +- ldr w6, [x3, #VGIC_CPU_APR] +-CPU_BE( rev w4, w4 ) +-CPU_BE( rev w5, w5 ) +-CPU_BE( rev w6, w6 ) +- +- str w4, [x2, #GICH_HCR] +- str w5, [x2, #GICH_VMCR] +- str w6, [x2, #GICH_APR] +- +- /* Restore list registers */ +- add x2, x2, #GICH_LR0 +- ldr w4, [x3, #VGIC_CPU_NR_LR] +- add x3, x3, #VGIC_CPU_LR +-1: ldr w5, [x3], #4 +-CPU_BE( rev w5, w5 ) +- str w5, [x2], #4 +- sub w4, w4, #1 +- cbnz w4, 1b +-2: ++ mrs x24, hcr_el2 ++ ldr x25, [x0, #VCPU_IRQ_LINES] ++ orr x24, x24, #HCR_INT_OVERRIDE ++ orr x24, x24, x25 ++ msr hcr_el2, x24 ++ adr x24, __vgic_sr_vectors ++ ldr x24, [x24, #VGIC_RESTORE_FN] ++ kern_hyp_va x24 ++ blr x24 + .endm + + .macro save_timer_state +@@ -653,6 +579,12 @@ ENTRY(__kvm_flush_vm_context) + ret + ENDPROC(__kvm_flush_vm_context) + ++ // struct vgic_sr_vectors __vgi_sr_vectors; ++ .align 3 ++ENTRY(__vgic_sr_vectors) ++ .skip VGIC_SR_VECTOR_SZ ++ENDPROC(__vgic_sr_vectors) ++ + __kvm_hyp_panic: + // Guess the context by looking at VTTBR: + // If zero, then we're already a host. +@@ -880,7 +812,4 @@ ENTRY(__kvm_hyp_vector) + ventry el1_error_invalid // Error 32-bit EL1 + ENDPROC(__kvm_hyp_vector) + +-__kvm_hyp_code_end: +- .globl __kvm_hyp_code_end +- + .popsection +diff --git a/arch/arm64/kvm/vgic-v2-switch.S b/arch/arm64/kvm/vgic-v2-switch.S +new file mode 100644 +index 0000000..ae21177 +--- /dev/null ++++ b/arch/arm64/kvm/vgic-v2-switch.S +@@ -0,0 +1,133 @@ ++/* ++ * Copyright (C) 2012,2013 - ARM Ltd ++ * Author: Marc Zyngier <marc.zyngier@arm.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#include <linux/linkage.h> ++#include <linux/irqchip/arm-gic.h> ++ ++#include <asm/assembler.h> ++#include <asm/memory.h> ++#include <asm/asm-offsets.h> ++#include <asm/kvm.h> ++#include <asm/kvm_asm.h> ++#include <asm/kvm_arm.h> ++#include <asm/kvm_mmu.h> ++ ++ .text ++ .pushsection .hyp.text, "ax" ++ ++/* ++ * Save the VGIC CPU state into memory ++ * x0: Register pointing to VCPU struct ++ * Do not corrupt x1!!! ++ */ ++ENTRY(__save_vgic_v2_state) ++__save_vgic_v2_state: ++ /* Get VGIC VCTRL base into x2 */ ++ ldr x2, [x0, #VCPU_KVM] ++ kern_hyp_va x2 ++ ldr x2, [x2, #KVM_VGIC_VCTRL] ++ kern_hyp_va x2 ++ cbz x2, 2f // disabled ++ ++ /* Compute the address of struct vgic_cpu */ ++ add x3, x0, #VCPU_VGIC_CPU ++ ++ /* Save all interesting registers */ ++ ldr w4, [x2, #GICH_HCR] ++ ldr w5, [x2, #GICH_VMCR] ++ ldr w6, [x2, #GICH_MISR] ++ ldr w7, [x2, #GICH_EISR0] ++ ldr w8, [x2, #GICH_EISR1] ++ ldr w9, [x2, #GICH_ELRSR0] ++ ldr w10, [x2, #GICH_ELRSR1] ++ ldr w11, [x2, #GICH_APR] ++CPU_BE( rev w4, w4 ) ++CPU_BE( rev w5, w5 ) ++CPU_BE( rev w6, w6 ) ++CPU_BE( rev w7, w7 ) ++CPU_BE( rev w8, w8 ) ++CPU_BE( rev w9, w9 ) ++CPU_BE( rev w10, w10 ) ++CPU_BE( rev w11, w11 ) ++ ++ str w4, [x3, #VGIC_V2_CPU_HCR] ++ str w5, [x3, #VGIC_V2_CPU_VMCR] ++ str w6, [x3, #VGIC_V2_CPU_MISR] ++ str w7, [x3, #VGIC_V2_CPU_EISR] ++ str w8, [x3, #(VGIC_V2_CPU_EISR + 4)] ++ str w9, [x3, #VGIC_V2_CPU_ELRSR] ++ str w10, [x3, #(VGIC_V2_CPU_ELRSR + 4)] ++ str w11, [x3, #VGIC_V2_CPU_APR] ++ ++ /* Clear GICH_HCR */ ++ str wzr, [x2, #GICH_HCR] ++ ++ /* Save list registers */ ++ add x2, x2, #GICH_LR0 ++ ldr w4, [x3, #VGIC_CPU_NR_LR] ++ add x3, x3, #VGIC_V2_CPU_LR ++1: ldr w5, [x2], #4 ++CPU_BE( rev w5, w5 ) ++ str w5, [x3], #4 ++ sub w4, w4, #1 ++ cbnz w4, 1b ++2: ++ ret ++ENDPROC(__save_vgic_v2_state) ++ ++/* ++ * Restore the VGIC CPU state from memory ++ * x0: Register pointing to VCPU struct ++ */ ++ENTRY(__restore_vgic_v2_state) ++__restore_vgic_v2_state: ++ /* Get VGIC VCTRL base into x2 */ ++ ldr x2, [x0, #VCPU_KVM] ++ kern_hyp_va x2 ++ ldr x2, [x2, #KVM_VGIC_VCTRL] ++ kern_hyp_va x2 ++ cbz x2, 2f // disabled ++ ++ /* Compute the address of struct vgic_cpu */ ++ add x3, x0, #VCPU_VGIC_CPU ++ ++ /* We only restore a minimal set of registers */ ++ ldr w4, [x3, #VGIC_V2_CPU_HCR] ++ ldr w5, [x3, #VGIC_V2_CPU_VMCR] ++ ldr w6, [x3, #VGIC_V2_CPU_APR] ++CPU_BE( rev w4, w4 ) ++CPU_BE( rev w5, w5 ) ++CPU_BE( rev w6, w6 ) ++ ++ str w4, [x2, #GICH_HCR] ++ str w5, [x2, #GICH_VMCR] ++ str w6, [x2, #GICH_APR] ++ ++ /* Restore list registers */ ++ add x2, x2, #GICH_LR0 ++ ldr w4, [x3, #VGIC_CPU_NR_LR] ++ add x3, x3, #VGIC_V2_CPU_LR ++1: ldr w5, [x3], #4 ++CPU_BE( rev w5, w5 ) ++ str w5, [x2], #4 ++ sub w4, w4, #1 ++ cbnz w4, 1b ++2: ++ ret ++ENDPROC(__restore_vgic_v2_state) ++ ++ .popsection +diff --git a/arch/arm64/kvm/vgic-v3-switch.S b/arch/arm64/kvm/vgic-v3-switch.S +new file mode 100644 +index 0000000..21e68f6 +--- /dev/null ++++ b/arch/arm64/kvm/vgic-v3-switch.S +@@ -0,0 +1,267 @@ ++/* ++ * Copyright (C) 2012,2013 - ARM Ltd ++ * Author: Marc Zyngier <marc.zyngier@arm.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#include <linux/linkage.h> ++#include <linux/irqchip/arm-gic-v3.h> ++ ++#include <asm/assembler.h> ++#include <asm/memory.h> ++#include <asm/asm-offsets.h> ++#include <asm/kvm.h> ++#include <asm/kvm_asm.h> ++#include <asm/kvm_arm.h> ++ ++ .text ++ .pushsection .hyp.text, "ax" ++ ++/* ++ * We store LRs in reverse order to let the CPU deal with streaming ++ * access. Use this macro to make it look saner... ++ */ ++#define LR_OFFSET(n) (VGIC_V3_CPU_LR + (15 - n) * 8) ++ ++/* ++ * Save the VGIC CPU state into memory ++ * x0: Register pointing to VCPU struct ++ * Do not corrupt x1!!! ++ */ ++.macro save_vgic_v3_state ++ // Compute the address of struct vgic_cpu ++ add x3, x0, #VCPU_VGIC_CPU ++ ++ // Make sure stores to the GIC via the memory mapped interface ++ // are now visible to the system register interface ++ dsb st ++ ++ // Save all interesting registers ++ mrs x4, ICH_HCR_EL2 ++ mrs x5, ICH_VMCR_EL2 ++ mrs x6, ICH_MISR_EL2 ++ mrs x7, ICH_EISR_EL2 ++ mrs x8, ICH_ELSR_EL2 ++ ++ str w4, [x3, #VGIC_V3_CPU_HCR] ++ str w5, [x3, #VGIC_V3_CPU_VMCR] ++ str w6, [x3, #VGIC_V3_CPU_MISR] ++ str w7, [x3, #VGIC_V3_CPU_EISR] ++ str w8, [x3, #VGIC_V3_CPU_ELRSR] ++ ++ msr ICH_HCR_EL2, xzr ++ ++ mrs x21, ICH_VTR_EL2 ++ mvn w22, w21 ++ ubfiz w23, w22, 2, 4 // w23 = (15 - ListRegs) * 4 ++ ++ adr x24, 1f ++ add x24, x24, x23 ++ br x24 ++ ++1: ++ mrs x20, ICH_LR15_EL2 ++ mrs x19, ICH_LR14_EL2 ++ mrs x18, ICH_LR13_EL2 ++ mrs x17, ICH_LR12_EL2 ++ mrs x16, ICH_LR11_EL2 ++ mrs x15, ICH_LR10_EL2 ++ mrs x14, ICH_LR9_EL2 ++ mrs x13, ICH_LR8_EL2 ++ mrs x12, ICH_LR7_EL2 ++ mrs x11, ICH_LR6_EL2 ++ mrs x10, ICH_LR5_EL2 ++ mrs x9, ICH_LR4_EL2 ++ mrs x8, ICH_LR3_EL2 ++ mrs x7, ICH_LR2_EL2 ++ mrs x6, ICH_LR1_EL2 ++ mrs x5, ICH_LR0_EL2 ++ ++ adr x24, 1f ++ add x24, x24, x23 ++ br x24 ++ ++1: ++ str x20, [x3, #LR_OFFSET(15)] ++ str x19, [x3, #LR_OFFSET(14)] ++ str x18, [x3, #LR_OFFSET(13)] ++ str x17, [x3, #LR_OFFSET(12)] ++ str x16, [x3, #LR_OFFSET(11)] ++ str x15, [x3, #LR_OFFSET(10)] ++ str x14, [x3, #LR_OFFSET(9)] ++ str x13, [x3, #LR_OFFSET(8)] ++ str x12, [x3, #LR_OFFSET(7)] ++ str x11, [x3, #LR_OFFSET(6)] ++ str x10, [x3, #LR_OFFSET(5)] ++ str x9, [x3, #LR_OFFSET(4)] ++ str x8, [x3, #LR_OFFSET(3)] ++ str x7, [x3, #LR_OFFSET(2)] ++ str x6, [x3, #LR_OFFSET(1)] ++ str x5, [x3, #LR_OFFSET(0)] ++ ++ tbnz w21, #29, 6f // 6 bits ++ tbz w21, #30, 5f // 5 bits ++ // 7 bits ++ mrs x20, ICH_AP0R3_EL2 ++ str w20, [x3, #(VGIC_V3_CPU_AP0R + 3*4)] ++ mrs x19, ICH_AP0R2_EL2 ++ str w19, [x3, #(VGIC_V3_CPU_AP0R + 2*4)] ++6: mrs x18, ICH_AP0R1_EL2 ++ str w18, [x3, #(VGIC_V3_CPU_AP0R + 1*4)] ++5: mrs x17, ICH_AP0R0_EL2 ++ str w17, [x3, #VGIC_V3_CPU_AP0R] ++ ++ tbnz w21, #29, 6f // 6 bits ++ tbz w21, #30, 5f // 5 bits ++ // 7 bits ++ mrs x20, ICH_AP1R3_EL2 ++ str w20, [x3, #(VGIC_V3_CPU_AP1R + 3*4)] ++ mrs x19, ICH_AP1R2_EL2 ++ str w19, [x3, #(VGIC_V3_CPU_AP1R + 2*4)] ++6: mrs x18, ICH_AP1R1_EL2 ++ str w18, [x3, #(VGIC_V3_CPU_AP1R + 1*4)] ++5: mrs x17, ICH_AP1R0_EL2 ++ str w17, [x3, #VGIC_V3_CPU_AP1R] ++ ++ // Restore SRE_EL1 access and re-enable SRE at EL1. ++ mrs x5, ICC_SRE_EL2 ++ orr x5, x5, #ICC_SRE_EL2_ENABLE ++ msr ICC_SRE_EL2, x5 ++ isb ++ mov x5, #1 ++ msr ICC_SRE_EL1, x5 ++.endm ++ ++/* ++ * Restore the VGIC CPU state from memory ++ * x0: Register pointing to VCPU struct ++ */ ++.macro restore_vgic_v3_state ++ // Disable SRE_EL1 access. Necessary, otherwise ++ // ICH_VMCR_EL2.VFIQEn becomes one, and FIQ happens... ++ msr ICC_SRE_EL1, xzr ++ isb ++ ++ // Compute the address of struct vgic_cpu ++ add x3, x0, #VCPU_VGIC_CPU ++ ++ // Restore all interesting registers ++ ldr w4, [x3, #VGIC_V3_CPU_HCR] ++ ldr w5, [x3, #VGIC_V3_CPU_VMCR] ++ ++ msr ICH_HCR_EL2, x4 ++ msr ICH_VMCR_EL2, x5 ++ ++ mrs x21, ICH_VTR_EL2 ++ ++ tbnz w21, #29, 6f // 6 bits ++ tbz w21, #30, 5f // 5 bits ++ // 7 bits ++ ldr w20, [x3, #(VGIC_V3_CPU_AP1R + 3*4)] ++ msr ICH_AP1R3_EL2, x20 ++ ldr w19, [x3, #(VGIC_V3_CPU_AP1R + 2*4)] ++ msr ICH_AP1R2_EL2, x19 ++6: ldr w18, [x3, #(VGIC_V3_CPU_AP1R + 1*4)] ++ msr ICH_AP1R1_EL2, x18 ++5: ldr w17, [x3, #VGIC_V3_CPU_AP1R] ++ msr ICH_AP1R0_EL2, x17 ++ ++ tbnz w21, #29, 6f // 6 bits ++ tbz w21, #30, 5f // 5 bits ++ // 7 bits ++ ldr w20, [x3, #(VGIC_V3_CPU_AP0R + 3*4)] ++ msr ICH_AP0R3_EL2, x20 ++ ldr w19, [x3, #(VGIC_V3_CPU_AP0R + 2*4)] ++ msr ICH_AP0R2_EL2, x19 ++6: ldr w18, [x3, #(VGIC_V3_CPU_AP0R + 1*4)] ++ msr ICH_AP0R1_EL2, x18 ++5: ldr w17, [x3, #VGIC_V3_CPU_AP0R] ++ msr ICH_AP0R0_EL2, x17 ++ ++ and w22, w21, #0xf ++ mvn w22, w21 ++ ubfiz w23, w22, 2, 4 // w23 = (15 - ListRegs) * 4 ++ ++ adr x24, 1f ++ add x24, x24, x23 ++ br x24 ++ ++1: ++ ldr x20, [x3, #LR_OFFSET(15)] ++ ldr x19, [x3, #LR_OFFSET(14)] ++ ldr x18, [x3, #LR_OFFSET(13)] ++ ldr x17, [x3, #LR_OFFSET(12)] ++ ldr x16, [x3, #LR_OFFSET(11)] ++ ldr x15, [x3, #LR_OFFSET(10)] ++ ldr x14, [x3, #LR_OFFSET(9)] ++ ldr x13, [x3, #LR_OFFSET(8)] ++ ldr x12, [x3, #LR_OFFSET(7)] ++ ldr x11, [x3, #LR_OFFSET(6)] ++ ldr x10, [x3, #LR_OFFSET(5)] ++ ldr x9, [x3, #LR_OFFSET(4)] ++ ldr x8, [x3, #LR_OFFSET(3)] ++ ldr x7, [x3, #LR_OFFSET(2)] ++ ldr x6, [x3, #LR_OFFSET(1)] ++ ldr x5, [x3, #LR_OFFSET(0)] ++ ++ adr x24, 1f ++ add x24, x24, x23 ++ br x24 ++ ++1: ++ msr ICH_LR15_EL2, x20 ++ msr ICH_LR14_EL2, x19 ++ msr ICH_LR13_EL2, x18 ++ msr ICH_LR12_EL2, x17 ++ msr ICH_LR11_EL2, x16 ++ msr ICH_LR10_EL2, x15 ++ msr ICH_LR9_EL2, x14 ++ msr ICH_LR8_EL2, x13 ++ msr ICH_LR7_EL2, x12 ++ msr ICH_LR6_EL2, x11 ++ msr ICH_LR5_EL2, x10 ++ msr ICH_LR4_EL2, x9 ++ msr ICH_LR3_EL2, x8 ++ msr ICH_LR2_EL2, x7 ++ msr ICH_LR1_EL2, x6 ++ msr ICH_LR0_EL2, x5 ++ ++ // Ensure that the above will have reached the ++ // (re)distributors. This ensure the guest will read ++ // the correct values from the memory-mapped interface. ++ isb ++ dsb sy ++ ++ // Prevent the guest from touching the GIC system registers ++ mrs x5, ICC_SRE_EL2 ++ and x5, x5, #~ICC_SRE_EL2_ENABLE ++ msr ICC_SRE_EL2, x5 ++.endm ++ ++ENTRY(__save_vgic_v3_state) ++ save_vgic_v3_state ++ ret ++ENDPROC(__save_vgic_v3_state) ++ ++ENTRY(__restore_vgic_v3_state) ++ restore_vgic_v3_state ++ ret ++ENDPROC(__restore_vgic_v3_state) ++ ++ENTRY(__vgic_v3_get_ich_vtr_el2) ++ mrs x0, ICH_VTR_EL2 ++ ret ++ENDPROC(__vgic_v3_get_ich_vtr_el2) ++ ++ .popsection +diff --git a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c +index 55d4ba4..deed6fa 100644 +--- a/arch/ia64/kernel/process.c ++++ b/arch/ia64/kernel/process.c +@@ -662,7 +662,7 @@ void + machine_restart (char *restart_cmd) + { + (void) notify_die(DIE_MACHINE_RESTART, restart_cmd, NULL, 0, 0, 0); +- (*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL); ++ efi_reboot(REBOOT_WARM, NULL); + } + + void +diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c +index 71c52bc..a149c67 100644 +--- a/arch/ia64/kernel/time.c ++++ b/arch/ia64/kernel/time.c +@@ -384,21 +384,6 @@ static struct irqaction timer_irqaction = { + .name = "timer" + }; + +-static struct platform_device rtc_efi_dev = { +- .name = "rtc-efi", +- .id = -1, +-}; +- +-static int __init rtc_init(void) +-{ +- if (platform_device_register(&rtc_efi_dev) < 0) +- printk(KERN_ERR "unable to register rtc device...\n"); +- +- /* not necessarily an error */ +- return 0; +-} +-module_init(rtc_init); +- + void read_persistent_clock(struct timespec *ts) + { + efi_gettimeofday(ts); +diff --git a/arch/x86/include/asm/efi.h b/arch/x86/include/asm/efi.h +index 1eb5f64..5d71d0e 100644 +--- a/arch/x86/include/asm/efi.h ++++ b/arch/x86/include/asm/efi.h +@@ -104,6 +104,8 @@ extern void __init runtime_code_page_mkexec(void); + extern void __init efi_runtime_mkexec(void); + extern void __init efi_dump_pagetable(void); + extern void __init efi_apply_memmap_quirks(void); ++extern int __init efi_reuse_config(u64 tables, int nr_tables); ++extern void efi_delete_dummy_variable(void); + + struct efi_setup_data { + u64 fw_vendor; +@@ -156,6 +158,8 @@ static inline efi_status_t efi_thunk_set_virtual_address_map( + return EFI_SUCCESS; + } + #endif /* CONFIG_EFI_MIXED */ ++ ++extern bool efi_reboot_required(void); + #else + /* + * IF EFI is not configured, have the EFI calls return -ENOSYS. +@@ -168,6 +172,10 @@ static inline efi_status_t efi_thunk_set_virtual_address_map( + #define efi_call5(_f, _a1, _a2, _a3, _a4, _a5) (-ENOSYS) + #define efi_call6(_f, _a1, _a2, _a3, _a4, _a5, _a6) (-ENOSYS) + static inline void parse_efi_setup(u64 phys_addr, u32 data_len) {} ++static inline bool efi_reboot_required(void) ++{ ++ return false; ++} + #endif /* CONFIG_EFI */ + + #endif /* _ASM_X86_EFI_H */ +diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c +index 52b1157..17962e6 100644 +--- a/arch/x86/kernel/reboot.c ++++ b/arch/x86/kernel/reboot.c +@@ -28,6 +28,7 @@ + #include <linux/mc146818rtc.h> + #include <asm/realmode.h> + #include <asm/x86_init.h> ++#include <asm/efi.h> + + /* + * Power off function, if any +@@ -401,12 +402,25 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { + + static int __init reboot_init(void) + { ++ int rv; ++ + /* + * Only do the DMI check if reboot_type hasn't been overridden + * on the command line + */ +- if (reboot_default) +- dmi_check_system(reboot_dmi_table); ++ if (!reboot_default) ++ return 0; ++ ++ /* ++ * The DMI quirks table takes precedence. If no quirks entry ++ * matches and the ACPI Hardware Reduced bit is set, force EFI ++ * reboot. ++ */ ++ rv = dmi_check_system(reboot_dmi_table); ++ ++ if (!rv && efi_reboot_required()) ++ reboot_type = BOOT_EFI; ++ + return 0; + } + core_initcall(reboot_init); +@@ -528,11 +542,7 @@ static void native_machine_emergency_restart(void) + break; + + case BOOT_EFI: +- if (efi_enabled(EFI_RUNTIME_SERVICES)) +- efi.reset_system(reboot_mode == REBOOT_WARM ? +- EFI_RESET_WARM : +- EFI_RESET_COLD, +- EFI_SUCCESS, 0, NULL); ++ efi_reboot(reboot_mode, NULL); + reboot_type = BOOT_BIOS; + break; + +diff --git a/arch/x86/platform/efi/Makefile b/arch/x86/platform/efi/Makefile +index d51045a..2846aaa 100644 +--- a/arch/x86/platform/efi/Makefile ++++ b/arch/x86/platform/efi/Makefile +@@ -1,4 +1,4 @@ +-obj-$(CONFIG_EFI) += efi.o efi_$(BITS).o efi_stub_$(BITS).o ++obj-$(CONFIG_EFI) += quirks.o efi.o efi_$(BITS).o efi_stub_$(BITS).o + obj-$(CONFIG_ACPI_BGRT) += efi-bgrt.o + obj-$(CONFIG_EARLY_PRINTK_EFI) += early_printk.o + obj-$(CONFIG_EFI_MIXED) += efi_thunk_$(BITS).o +diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c +index 87fc96b..f852443 100644 +--- a/arch/x86/platform/efi/efi.c ++++ b/arch/x86/platform/efi/efi.c +@@ -56,13 +56,6 @@ + + #define EFI_DEBUG + +-#define EFI_MIN_RESERVE 5120 +- +-#define EFI_DUMMY_GUID \ +- EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9) +- +-static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; +- + struct efi_memory_map memmap; + + static struct efi efi_phys __initdata; +@@ -95,15 +88,6 @@ static int __init setup_add_efi_memmap(char *arg) + } + early_param("add_efi_memmap", setup_add_efi_memmap); + +-static bool efi_no_storage_paranoia; +- +-static int __init setup_storage_paranoia(char *arg) +-{ +- efi_no_storage_paranoia = true; +- return 0; +-} +-early_param("efi_no_storage_paranoia", setup_storage_paranoia); +- + static efi_status_t virt_efi_get_time(efi_time_t *tm, efi_time_cap_t *tc) + { + unsigned long flags; +@@ -392,37 +376,6 @@ static void __init print_efi_memmap(void) + #endif /* EFI_DEBUG */ + } + +-void __init efi_reserve_boot_services(void) +-{ +- void *p; +- +- for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { +- efi_memory_desc_t *md = p; +- u64 start = md->phys_addr; +- u64 size = md->num_pages << EFI_PAGE_SHIFT; +- +- if (md->type != EFI_BOOT_SERVICES_CODE && +- md->type != EFI_BOOT_SERVICES_DATA) +- continue; +- /* Only reserve where possible: +- * - Not within any already allocated areas +- * - Not over any memory area (really needed, if above?) +- * - Not within any part of the kernel +- * - Not the bios reserved area +- */ +- if ((start + size > __pa_symbol(_text) +- && start <= __pa_symbol(_end)) || +- !e820_all_mapped(start, start+size, E820_RAM) || +- memblock_is_region_reserved(start, size)) { +- /* Could not reserve, skip it */ +- md->num_pages = 0; +- memblock_dbg("Could not reserve boot range [0x%010llx-0x%010llx]\n", +- start, start+size-1); +- } else +- memblock_reserve(start, size); +- } +-} +- + void __init efi_unmap_memmap(void) + { + clear_bit(EFI_MEMMAP, &efi.flags); +@@ -432,29 +385,6 @@ void __init efi_unmap_memmap(void) + } + } + +-void __init efi_free_boot_services(void) +-{ +- void *p; +- +- for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { +- efi_memory_desc_t *md = p; +- unsigned long long start = md->phys_addr; +- unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; +- +- if (md->type != EFI_BOOT_SERVICES_CODE && +- md->type != EFI_BOOT_SERVICES_DATA) +- continue; +- +- /* Could not reserve boot area */ +- if (!size) +- continue; +- +- free_bootmem_late(start, size); +- } +- +- efi_unmap_memmap(); +-} +- + static int __init efi_systab_init(void *phys) + { + if (efi_enabled(EFI_64BIT)) { +@@ -649,62 +579,6 @@ static int __init efi_memmap_init(void) + return 0; + } + +-/* +- * A number of config table entries get remapped to virtual addresses +- * after entering EFI virtual mode. However, the kexec kernel requires +- * their physical addresses therefore we pass them via setup_data and +- * correct those entries to their respective physical addresses here. +- * +- * Currently only handles smbios which is necessary for some firmware +- * implementation. +- */ +-static int __init efi_reuse_config(u64 tables, int nr_tables) +-{ +- int i, sz, ret = 0; +- void *p, *tablep; +- struct efi_setup_data *data; +- +- if (!efi_setup) +- return 0; +- +- if (!efi_enabled(EFI_64BIT)) +- return 0; +- +- data = early_memremap(efi_setup, sizeof(*data)); +- if (!data) { +- ret = -ENOMEM; +- goto out; +- } +- +- if (!data->smbios) +- goto out_memremap; +- +- sz = sizeof(efi_config_table_64_t); +- +- p = tablep = early_memremap(tables, nr_tables * sz); +- if (!p) { +- pr_err("Could not map Configuration table!\n"); +- ret = -ENOMEM; +- goto out_memremap; +- } +- +- for (i = 0; i < efi.systab->nr_tables; i++) { +- efi_guid_t guid; +- +- guid = ((efi_config_table_64_t *)p)->guid; +- +- if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) +- ((efi_config_table_64_t *)p)->table = data->smbios; +- p += sz; +- } +- early_iounmap(tablep, nr_tables * sz); +- +-out_memremap: +- early_iounmap(data, sizeof(*data)); +-out: +- return ret; +-} +- + void __init efi_init(void) + { + efi_char16_t *c16; +@@ -1057,11 +931,7 @@ static void __init kexec_enter_virtual_mode(void) + runtime_code_page_mkexec(); + + /* clean DUMMY object */ +- efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, +- EFI_VARIABLE_NON_VOLATILE | +- EFI_VARIABLE_BOOTSERVICE_ACCESS | +- EFI_VARIABLE_RUNTIME_ACCESS, +- 0, NULL); ++ efi_delete_dummy_variable(); + #endif + } + +@@ -1179,11 +1049,7 @@ static void __init __efi_enter_virtual_mode(void) + free_pages((unsigned long)new_memmap, pg_shift); + + /* clean DUMMY object */ +- efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, +- EFI_VARIABLE_NON_VOLATILE | +- EFI_VARIABLE_BOOTSERVICE_ACCESS | +- EFI_VARIABLE_RUNTIME_ACCESS, +- 0, NULL); ++ efi_delete_dummy_variable(); + } + + void __init efi_enter_virtual_mode(void) +@@ -1230,86 +1096,6 @@ u64 efi_mem_attributes(unsigned long phys_addr) + return 0; + } + +-/* +- * Some firmware implementations refuse to boot if there's insufficient space +- * in the variable store. Ensure that we never use more than a safe limit. +- * +- * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable +- * store. +- */ +-efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) +-{ +- efi_status_t status; +- u64 storage_size, remaining_size, max_size; +- +- if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) +- return 0; +- +- status = efi.query_variable_info(attributes, &storage_size, +- &remaining_size, &max_size); +- if (status != EFI_SUCCESS) +- return status; +- +- /* +- * We account for that by refusing the write if permitting it would +- * reduce the available space to under 5KB. This figure was provided by +- * Samsung, so should be safe. +- */ +- if ((remaining_size - size < EFI_MIN_RESERVE) && +- !efi_no_storage_paranoia) { +- +- /* +- * Triggering garbage collection may require that the firmware +- * generate a real EFI_OUT_OF_RESOURCES error. We can force +- * that by attempting to use more space than is available. +- */ +- unsigned long dummy_size = remaining_size + 1024; +- void *dummy = kzalloc(dummy_size, GFP_ATOMIC); +- +- if (!dummy) +- return EFI_OUT_OF_RESOURCES; +- +- status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, +- EFI_VARIABLE_NON_VOLATILE | +- EFI_VARIABLE_BOOTSERVICE_ACCESS | +- EFI_VARIABLE_RUNTIME_ACCESS, +- dummy_size, dummy); +- +- if (status == EFI_SUCCESS) { +- /* +- * This should have failed, so if it didn't make sure +- * that we delete it... +- */ +- efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, +- EFI_VARIABLE_NON_VOLATILE | +- EFI_VARIABLE_BOOTSERVICE_ACCESS | +- EFI_VARIABLE_RUNTIME_ACCESS, +- 0, dummy); +- } +- +- kfree(dummy); +- +- /* +- * The runtime code may now have triggered a garbage collection +- * run, so check the variable info again +- */ +- status = efi.query_variable_info(attributes, &storage_size, +- &remaining_size, &max_size); +- +- if (status != EFI_SUCCESS) +- return status; +- +- /* +- * There still isn't enough room, so return an error +- */ +- if (remaining_size - size < EFI_MIN_RESERVE) +- return EFI_OUT_OF_RESOURCES; +- } +- +- return EFI_SUCCESS; +-} +-EXPORT_SYMBOL_GPL(efi_query_variable_store); +- + static int __init parse_efi_cmdline(char *str) + { + if (*str == '=') +@@ -1321,22 +1107,3 @@ static int __init parse_efi_cmdline(char *str) + return 0; + } + early_param("efi", parse_efi_cmdline); +- +-void __init efi_apply_memmap_quirks(void) +-{ +- /* +- * Once setup is done earlier, unmap the EFI memory map on mismatched +- * firmware/kernel architectures since there is no support for runtime +- * services. +- */ +- if (!efi_runtime_supported()) { +- pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); +- efi_unmap_memmap(); +- } +- +- /* +- * UV doesn't support the new EFI pagetable mapping yet. +- */ +- if (is_uv_system()) +- set_bit(EFI_OLD_MEMMAP, &efi.flags); +-} +diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c +new file mode 100644 +index 0000000..1b9c4c3 +--- /dev/null ++++ b/arch/x86/platform/efi/quirks.c +@@ -0,0 +1,290 @@ ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/string.h> ++#include <linux/time.h> ++#include <linux/types.h> ++#include <linux/efi.h> ++#include <linux/slab.h> ++#include <linux/memblock.h> ++#include <linux/bootmem.h> ++#include <linux/acpi.h> ++#include <asm/efi.h> ++#include <asm/uv/uv.h> ++ ++#define EFI_MIN_RESERVE 5120 ++ ++#define EFI_DUMMY_GUID \ ++ EFI_GUID(0x4424ac57, 0xbe4b, 0x47dd, 0x9e, 0x97, 0xed, 0x50, 0xf0, 0x9f, 0x92, 0xa9) ++ ++static efi_char16_t efi_dummy_name[6] = { 'D', 'U', 'M', 'M', 'Y', 0 }; ++ ++static bool efi_no_storage_paranoia; ++ ++/* ++ * Some firmware implementations refuse to boot if there's insufficient ++ * space in the variable store. The implementation of garbage collection ++ * in some FW versions causes stale (deleted) variables to take up space ++ * longer than intended and space is only freed once the store becomes ++ * almost completely full. ++ * ++ * Enabling this option disables the space checks in ++ * efi_query_variable_store() and forces garbage collection. ++ * ++ * Only enable this option if deleting EFI variables does not free up ++ * space in your variable store, e.g. if despite deleting variables ++ * you're unable to create new ones. ++ */ ++static int __init setup_storage_paranoia(char *arg) ++{ ++ efi_no_storage_paranoia = true; ++ return 0; ++} ++early_param("efi_no_storage_paranoia", setup_storage_paranoia); ++ ++/* ++ * Deleting the dummy variable which kicks off garbage collection ++*/ ++void efi_delete_dummy_variable(void) ++{ ++ efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, ++ EFI_VARIABLE_NON_VOLATILE | ++ EFI_VARIABLE_BOOTSERVICE_ACCESS | ++ EFI_VARIABLE_RUNTIME_ACCESS, ++ 0, NULL); ++} ++ ++/* ++ * Some firmware implementations refuse to boot if there's insufficient space ++ * in the variable store. Ensure that we never use more than a safe limit. ++ * ++ * Return EFI_SUCCESS if it is safe to write 'size' bytes to the variable ++ * store. ++ */ ++efi_status_t efi_query_variable_store(u32 attributes, unsigned long size) ++{ ++ efi_status_t status; ++ u64 storage_size, remaining_size, max_size; ++ ++ if (!(attributes & EFI_VARIABLE_NON_VOLATILE)) ++ return 0; ++ ++ status = efi.query_variable_info(attributes, &storage_size, ++ &remaining_size, &max_size); ++ if (status != EFI_SUCCESS) ++ return status; ++ ++ /* ++ * We account for that by refusing the write if permitting it would ++ * reduce the available space to under 5KB. This figure was provided by ++ * Samsung, so should be safe. ++ */ ++ if ((remaining_size - size < EFI_MIN_RESERVE) && ++ !efi_no_storage_paranoia) { ++ ++ /* ++ * Triggering garbage collection may require that the firmware ++ * generate a real EFI_OUT_OF_RESOURCES error. We can force ++ * that by attempting to use more space than is available. ++ */ ++ unsigned long dummy_size = remaining_size + 1024; ++ void *dummy = kzalloc(dummy_size, GFP_ATOMIC); ++ ++ if (!dummy) ++ return EFI_OUT_OF_RESOURCES; ++ ++ status = efi.set_variable(efi_dummy_name, &EFI_DUMMY_GUID, ++ EFI_VARIABLE_NON_VOLATILE | ++ EFI_VARIABLE_BOOTSERVICE_ACCESS | ++ EFI_VARIABLE_RUNTIME_ACCESS, ++ dummy_size, dummy); ++ ++ if (status == EFI_SUCCESS) { ++ /* ++ * This should have failed, so if it didn't make sure ++ * that we delete it... ++ */ ++ efi_delete_dummy_variable(); ++ } ++ ++ kfree(dummy); ++ ++ /* ++ * The runtime code may now have triggered a garbage collection ++ * run, so check the variable info again ++ */ ++ status = efi.query_variable_info(attributes, &storage_size, ++ &remaining_size, &max_size); ++ ++ if (status != EFI_SUCCESS) ++ return status; ++ ++ /* ++ * There still isn't enough room, so return an error ++ */ ++ if (remaining_size - size < EFI_MIN_RESERVE) ++ return EFI_OUT_OF_RESOURCES; ++ } ++ ++ return EFI_SUCCESS; ++} ++EXPORT_SYMBOL_GPL(efi_query_variable_store); ++ ++/* ++ * The UEFI specification makes it clear that the operating system is free to do ++ * whatever it wants with boot services code after ExitBootServices() has been ++ * called. Ignoring this recommendation a significant bunch of EFI implementations ++ * continue calling into boot services code (SetVirtualAddressMap). In order to ++ * work around such buggy implementations we reserve boot services region during ++ * EFI init and make sure it stays executable. Then, after SetVirtualAddressMap(), it ++* is discarded. ++*/ ++void __init efi_reserve_boot_services(void) ++{ ++ void *p; ++ ++ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { ++ efi_memory_desc_t *md = p; ++ u64 start = md->phys_addr; ++ u64 size = md->num_pages << EFI_PAGE_SHIFT; ++ ++ if (md->type != EFI_BOOT_SERVICES_CODE && ++ md->type != EFI_BOOT_SERVICES_DATA) ++ continue; ++ /* Only reserve where possible: ++ * - Not within any already allocated areas ++ * - Not over any memory area (really needed, if above?) ++ * - Not within any part of the kernel ++ * - Not the bios reserved area ++ */ ++ if ((start + size > __pa_symbol(_text) ++ && start <= __pa_symbol(_end)) || ++ !e820_all_mapped(start, start+size, E820_RAM) || ++ memblock_is_region_reserved(start, size)) { ++ /* Could not reserve, skip it */ ++ md->num_pages = 0; ++ memblock_dbg("Could not reserve boot range [0x%010llx-0x%010llx]\n", ++ start, start+size-1); ++ } else ++ memblock_reserve(start, size); ++ } ++} ++ ++void __init efi_free_boot_services(void) ++{ ++ void *p; ++ ++ for (p = memmap.map; p < memmap.map_end; p += memmap.desc_size) { ++ efi_memory_desc_t *md = p; ++ unsigned long long start = md->phys_addr; ++ unsigned long long size = md->num_pages << EFI_PAGE_SHIFT; ++ ++ if (md->type != EFI_BOOT_SERVICES_CODE && ++ md->type != EFI_BOOT_SERVICES_DATA) ++ continue; ++ ++ /* Could not reserve boot area */ ++ if (!size) ++ continue; ++ ++ free_bootmem_late(start, size); ++ } ++ ++ efi_unmap_memmap(); ++} ++ ++/* ++ * A number of config table entries get remapped to virtual addresses ++ * after entering EFI virtual mode. However, the kexec kernel requires ++ * their physical addresses therefore we pass them via setup_data and ++ * correct those entries to their respective physical addresses here. ++ * ++ * Currently only handles smbios which is necessary for some firmware ++ * implementation. ++ */ ++int __init efi_reuse_config(u64 tables, int nr_tables) ++{ ++ int i, sz, ret = 0; ++ void *p, *tablep; ++ struct efi_setup_data *data; ++ ++ if (!efi_setup) ++ return 0; ++ ++ if (!efi_enabled(EFI_64BIT)) ++ return 0; ++ ++ data = early_memremap(efi_setup, sizeof(*data)); ++ if (!data) { ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ if (!data->smbios) ++ goto out_memremap; ++ ++ sz = sizeof(efi_config_table_64_t); ++ ++ p = tablep = early_memremap(tables, nr_tables * sz); ++ if (!p) { ++ pr_err("Could not map Configuration table!\n"); ++ ret = -ENOMEM; ++ goto out_memremap; ++ } ++ ++ for (i = 0; i < efi.systab->nr_tables; i++) { ++ efi_guid_t guid; ++ ++ guid = ((efi_config_table_64_t *)p)->guid; ++ ++ if (!efi_guidcmp(guid, SMBIOS_TABLE_GUID)) ++ ((efi_config_table_64_t *)p)->table = data->smbios; ++ p += sz; ++ } ++ early_iounmap(tablep, nr_tables * sz); ++ ++out_memremap: ++ early_iounmap(data, sizeof(*data)); ++out: ++ return ret; ++} ++ ++void __init efi_apply_memmap_quirks(void) ++{ ++ /* ++ * Once setup is done earlier, unmap the EFI memory map on mismatched ++ * firmware/kernel architectures since there is no support for runtime ++ * services. ++ */ ++ if (!efi_runtime_supported()) { ++ pr_info("efi: Setup done, disabling due to 32/64-bit mismatch\n"); ++ efi_unmap_memmap(); ++ } ++ ++ /* ++ * UV doesn't support the new EFI pagetable mapping yet. ++ */ ++ if (is_uv_system()) ++ set_bit(EFI_OLD_MEMMAP, &efi.flags); ++} ++ ++/* ++ * For most modern platforms the preferred method of powering off is via ++ * ACPI. However, there are some that are known to require the use of ++ * EFI runtime services and for which ACPI does not work at all. ++ * ++ * Using EFI is a last resort, to be used only if no other option ++ * exists. ++ */ ++bool efi_reboot_required(void) ++{ ++ if (!acpi_gbl_reduced_hardware) ++ return false; ++ ++ efi_reboot_quirk_mode = EFI_RESET_WARM; ++ return true; ++} ++ ++bool efi_poweroff_required(void) ++{ ++ return !!acpi_gbl_reduced_hardware; ++} +diff --git a/drivers/ata/ahci_xgene.c b/drivers/ata/ahci_xgene.c +index ee3a365..f9431b4 100644 +--- a/drivers/ata/ahci_xgene.c ++++ b/drivers/ata/ahci_xgene.c +@@ -131,7 +131,8 @@ static unsigned int xgene_ahci_qc_issue(struct ata_queued_cmd *qc) + struct xgene_ahci_context *ctx = hpriv->plat_data; + int rc = 0; + +- if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA)) ++ if (unlikely(ctx->last_cmd[ap->port_no] == ATA_CMD_ID_ATA || ++ ctx->last_cmd[ap->port_no] == ATA_CMD_SMART)) + xgene_ahci_restart_engine(ap); + + rc = ahci_qc_issue(qc); +diff --git a/drivers/firmware/efi/Makefile b/drivers/firmware/efi/Makefile +index 9553496..c135154 100644 +--- a/drivers/firmware/efi/Makefile ++++ b/drivers/firmware/efi/Makefile +@@ -1,7 +1,7 @@ + # + # Makefile for linux kernel + # +-obj-$(CONFIG_EFI) += efi.o vars.o ++obj-$(CONFIG_EFI) += efi.o vars.o reboot.o + obj-$(CONFIG_EFI_VARS) += efivars.o + obj-$(CONFIG_EFI_VARS_PSTORE) += efi-pstore.o + obj-$(CONFIG_UEFI_CPER) += cper.o +diff --git a/drivers/firmware/efi/reboot.c b/drivers/firmware/efi/reboot.c +new file mode 100644 +index 0000000..f94fb95 +--- /dev/null ++++ b/drivers/firmware/efi/reboot.c +@@ -0,0 +1,55 @@ ++/* ++ * Copyright (C) 2014 Intel Corporation; author Matt Fleming ++ */ ++#include <linux/efi.h> ++#include <linux/reboot.h> ++ ++int efi_reboot_quirk_mode = -1; ++ ++void efi_reboot(enum reboot_mode reboot_mode, const char *__unused) ++{ ++ int efi_mode; ++ ++ if (!efi_enabled(EFI_RUNTIME_SERVICES)) ++ return; ++ ++ switch (reboot_mode) { ++ case REBOOT_WARM: ++ case REBOOT_SOFT: ++ efi_mode = EFI_RESET_WARM; ++ break; ++ default: ++ efi_mode = EFI_RESET_COLD; ++ break; ++ } ++ ++ /* ++ * If a quirk forced an EFI reset mode, always use that. ++ */ ++ if (efi_reboot_quirk_mode != -1) ++ efi_mode = efi_reboot_quirk_mode; ++ ++ efi.reset_system(efi_mode, EFI_SUCCESS, 0, NULL); ++} ++ ++bool __weak efi_poweroff_required(void) ++{ ++ return false; ++} ++ ++static void efi_power_off(void) ++{ ++ efi.reset_system(EFI_RESET_SHUTDOWN, EFI_SUCCESS, 0, NULL); ++} ++ ++static int __init efi_shutdown_init(void) ++{ ++ if (!efi_enabled(EFI_RUNTIME_SERVICES)) ++ return -ENODEV; ++ ++ if (efi_poweroff_required()) ++ pm_power_off = efi_power_off; ++ ++ return 0; ++} ++late_initcall(efi_shutdown_init); +diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig +index bbb746e..7f0c2a3 100644 +--- a/drivers/irqchip/Kconfig ++++ b/drivers/irqchip/Kconfig +@@ -10,6 +10,11 @@ config ARM_GIC + config GIC_NON_BANKED + bool + ++config ARM_GIC_V3 ++ bool ++ select IRQ_DOMAIN ++ select MULTI_IRQ_HANDLER ++ + config ARM_NVIC + bool + select IRQ_DOMAIN +diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile +index 62a13e5..c57e642 100644 +--- a/drivers/irqchip/Makefile ++++ b/drivers/irqchip/Makefile +@@ -15,7 +15,8 @@ obj-$(CONFIG_ORION_IRQCHIP) += irq-orion.o + obj-$(CONFIG_ARCH_SUNXI) += irq-sun4i.o + obj-$(CONFIG_ARCH_SUNXI) += irq-sunxi-nmi.o + obj-$(CONFIG_ARCH_SPEAR3XX) += spear-shirq.o +-obj-$(CONFIG_ARM_GIC) += irq-gic.o ++obj-$(CONFIG_ARM_GIC) += irq-gic.o irq-gic-common.o ++obj-$(CONFIG_ARM_GIC_V3) += irq-gic-v3.o irq-gic-common.o + obj-$(CONFIG_ARM_NVIC) += irq-nvic.o + obj-$(CONFIG_ARM_VIC) += irq-vic.o + obj-$(CONFIG_IMGPDC_IRQ) += irq-imgpdc.o +diff --git a/drivers/irqchip/irq-gic-common.c b/drivers/irqchip/irq-gic-common.c +new file mode 100644 +index 0000000..60ac704 +--- /dev/null ++++ b/drivers/irqchip/irq-gic-common.c +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (C) 2002 ARM Limited, All Rights Reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#include <linux/interrupt.h> ++#include <linux/io.h> ++#include <linux/irq.h> ++#include <linux/irqchip/arm-gic.h> ++ ++#include "irq-gic-common.h" ++ ++void gic_configure_irq(unsigned int irq, unsigned int type, ++ void __iomem *base, void (*sync_access)(void)) ++{ ++ u32 enablemask = 1 << (irq % 32); ++ u32 enableoff = (irq / 32) * 4; ++ u32 confmask = 0x2 << ((irq % 16) * 2); ++ u32 confoff = (irq / 16) * 4; ++ bool enabled = false; ++ u32 val; ++ ++ /* ++ * Read current configuration register, and insert the config ++ * for "irq", depending on "type". ++ */ ++ val = readl_relaxed(base + GIC_DIST_CONFIG + confoff); ++ if (type == IRQ_TYPE_LEVEL_HIGH) ++ val &= ~confmask; ++ else if (type == IRQ_TYPE_EDGE_RISING) ++ val |= confmask; ++ ++ /* ++ * As recommended by the spec, disable the interrupt before changing ++ * the configuration ++ */ ++ if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) { ++ writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff); ++ if (sync_access) ++ sync_access(); ++ enabled = true; ++ } ++ ++ /* ++ * Write back the new configuration, and possibly re-enable ++ * the interrupt. ++ */ ++ writel_relaxed(val, base + GIC_DIST_CONFIG + confoff); ++ ++ if (enabled) ++ writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff); ++ ++ if (sync_access) ++ sync_access(); ++} ++ ++void __init gic_dist_config(void __iomem *base, int gic_irqs, ++ void (*sync_access)(void)) ++{ ++ unsigned int i; ++ ++ /* ++ * Set all global interrupts to be level triggered, active low. ++ */ ++ for (i = 32; i < gic_irqs; i += 16) ++ writel_relaxed(0, base + GIC_DIST_CONFIG + i / 4); ++ ++ /* ++ * Set priority on all global interrupts. ++ */ ++ for (i = 32; i < gic_irqs; i += 4) ++ writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i); ++ ++ /* ++ * Disable all interrupts. Leave the PPI and SGIs alone ++ * as they are enabled by redistributor registers. ++ */ ++ for (i = 32; i < gic_irqs; i += 32) ++ writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i / 8); ++ ++ if (sync_access) ++ sync_access(); ++} ++ ++void gic_cpu_config(void __iomem *base, void (*sync_access)(void)) ++{ ++ int i; ++ ++ /* ++ * Deal with the banked PPI and SGI interrupts - disable all ++ * PPI interrupts, ensure all SGI interrupts are enabled. ++ */ ++ writel_relaxed(0xffff0000, base + GIC_DIST_ENABLE_CLEAR); ++ writel_relaxed(0x0000ffff, base + GIC_DIST_ENABLE_SET); ++ ++ /* ++ * Set priority on PPI and SGI interrupts ++ */ ++ for (i = 0; i < 32; i += 4) ++ writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); ++ ++ if (sync_access) ++ sync_access(); ++} +diff --git a/drivers/irqchip/irq-gic-common.h b/drivers/irqchip/irq-gic-common.h +new file mode 100644 +index 0000000..b41f024 +--- /dev/null ++++ b/drivers/irqchip/irq-gic-common.h +@@ -0,0 +1,29 @@ ++/* ++ * Copyright (C) 2002 ARM Limited, All Rights Reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#ifndef _IRQ_GIC_COMMON_H ++#define _IRQ_GIC_COMMON_H ++ ++#include <linux/of.h> ++#include <linux/irqdomain.h> ++ ++void gic_configure_irq(unsigned int irq, unsigned int type, ++ void __iomem *base, void (*sync_access)(void)); ++void gic_dist_config(void __iomem *base, int gic_irqs, ++ void (*sync_access)(void)); ++void gic_cpu_config(void __iomem *base, void (*sync_access)(void)); ++ ++#endif /* _IRQ_GIC_COMMON_H */ +diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c +new file mode 100644 +index 0000000..81519ba +--- /dev/null ++++ b/drivers/irqchip/irq-gic-v3.c +@@ -0,0 +1,692 @@ ++/* ++ * Copyright (C) 2013, 2014 ARM Limited, All Rights Reserved. ++ * Author: Marc Zyngier <marc.zyngier@arm.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#include <linux/cpu.h> ++#include <linux/delay.h> ++#include <linux/interrupt.h> ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++#include <linux/percpu.h> ++#include <linux/slab.h> ++ ++#include <linux/irqchip/arm-gic-v3.h> ++ ++#include <asm/cputype.h> ++#include <asm/exception.h> ++#include <asm/smp_plat.h> ++ ++#include "irq-gic-common.h" ++#include "irqchip.h" ++ ++struct gic_chip_data { ++ void __iomem *dist_base; ++ void __iomem **redist_base; ++ void __percpu __iomem **rdist; ++ struct irq_domain *domain; ++ u64 redist_stride; ++ u32 redist_regions; ++ unsigned int irq_nr; ++}; ++ ++static struct gic_chip_data gic_data __read_mostly; ++ ++#define gic_data_rdist() (this_cpu_ptr(gic_data.rdist)) ++#define gic_data_rdist_rd_base() (*gic_data_rdist()) ++#define gic_data_rdist_sgi_base() (gic_data_rdist_rd_base() + SZ_64K) ++ ++/* Our default, arbitrary priority value. Linux only uses one anyway. */ ++#define DEFAULT_PMR_VALUE 0xf0 ++ ++static inline unsigned int gic_irq(struct irq_data *d) ++{ ++ return d->hwirq; ++} ++ ++static inline int gic_irq_in_rdist(struct irq_data *d) ++{ ++ return gic_irq(d) < 32; ++} ++ ++static inline void __iomem *gic_dist_base(struct irq_data *d) ++{ ++ if (gic_irq_in_rdist(d)) /* SGI+PPI -> SGI_base for this CPU */ ++ return gic_data_rdist_sgi_base(); ++ ++ if (d->hwirq <= 1023) /* SPI -> dist_base */ ++ return gic_data.dist_base; ++ ++ if (d->hwirq >= 8192) ++ BUG(); /* LPI Detected!!! */ ++ ++ return NULL; ++} ++ ++static void gic_do_wait_for_rwp(void __iomem *base) ++{ ++ u32 count = 1000000; /* 1s! */ ++ ++ while (readl_relaxed(base + GICD_CTLR) & GICD_CTLR_RWP) { ++ count--; ++ if (!count) { ++ pr_err_ratelimited("RWP timeout, gone fishing\n"); ++ return; ++ } ++ cpu_relax(); ++ udelay(1); ++ }; ++} ++ ++/* Wait for completion of a distributor change */ ++static void gic_dist_wait_for_rwp(void) ++{ ++ gic_do_wait_for_rwp(gic_data.dist_base); ++} ++ ++/* Wait for completion of a redistributor change */ ++static void gic_redist_wait_for_rwp(void) ++{ ++ gic_do_wait_for_rwp(gic_data_rdist_rd_base()); ++} ++ ++/* Low level accessors */ ++static u64 gic_read_iar(void) ++{ ++ u64 irqstat; ++ ++ asm volatile("mrs %0, " __stringify(ICC_IAR1_EL1) : "=r" (irqstat)); ++ return irqstat; ++} ++ ++static void gic_write_pmr(u64 val) ++{ ++ asm volatile("msr " __stringify(ICC_PMR_EL1) ", %0" : : "r" (val)); ++} ++ ++static void gic_write_ctlr(u64 val) ++{ ++ asm volatile("msr " __stringify(ICC_CTLR_EL1) ", %0" : : "r" (val)); ++ isb(); ++} ++ ++static void gic_write_grpen1(u64 val) ++{ ++ asm volatile("msr " __stringify(ICC_GRPEN1_EL1) ", %0" : : "r" (val)); ++ isb(); ++} ++ ++static void gic_write_sgi1r(u64 val) ++{ ++ asm volatile("msr " __stringify(ICC_SGI1R_EL1) ", %0" : : "r" (val)); ++} ++ ++static void gic_enable_sre(void) ++{ ++ u64 val; ++ ++ asm volatile("mrs %0, " __stringify(ICC_SRE_EL1) : "=r" (val)); ++ val |= ICC_SRE_EL1_SRE; ++ asm volatile("msr " __stringify(ICC_SRE_EL1) ", %0" : : "r" (val)); ++ isb(); ++ ++ /* ++ * Need to check that the SRE bit has actually been set. If ++ * not, it means that SRE is disabled at EL2. We're going to ++ * die painfully, and there is nothing we can do about it. ++ * ++ * Kindly inform the luser. ++ */ ++ asm volatile("mrs %0, " __stringify(ICC_SRE_EL1) : "=r" (val)); ++ if (!(val & ICC_SRE_EL1_SRE)) ++ pr_err("GIC: unable to set SRE (disabled at EL2), panic ahead\n"); ++} ++ ++static void gic_enable_redist(void) ++{ ++ void __iomem *rbase; ++ u32 count = 1000000; /* 1s! */ ++ u32 val; ++ ++ rbase = gic_data_rdist_rd_base(); ++ ++ /* Wake up this CPU redistributor */ ++ val = readl_relaxed(rbase + GICR_WAKER); ++ val &= ~GICR_WAKER_ProcessorSleep; ++ writel_relaxed(val, rbase + GICR_WAKER); ++ ++ while (readl_relaxed(rbase + GICR_WAKER) & GICR_WAKER_ChildrenAsleep) { ++ count--; ++ if (!count) { ++ pr_err_ratelimited("redist didn't wake up...\n"); ++ return; ++ } ++ cpu_relax(); ++ udelay(1); ++ }; ++} ++ ++/* ++ * Routines to disable, enable, EOI and route interrupts ++ */ ++static void gic_poke_irq(struct irq_data *d, u32 offset) ++{ ++ u32 mask = 1 << (gic_irq(d) % 32); ++ void (*rwp_wait)(void); ++ void __iomem *base; ++ ++ if (gic_irq_in_rdist(d)) { ++ base = gic_data_rdist_sgi_base(); ++ rwp_wait = gic_redist_wait_for_rwp; ++ } else { ++ base = gic_data.dist_base; ++ rwp_wait = gic_dist_wait_for_rwp; ++ } ++ ++ writel_relaxed(mask, base + offset + (gic_irq(d) / 32) * 4); ++ rwp_wait(); ++} ++ ++static int gic_peek_irq(struct irq_data *d, u32 offset) ++{ ++ u32 mask = 1 << (gic_irq(d) % 32); ++ void __iomem *base; ++ ++ if (gic_irq_in_rdist(d)) ++ base = gic_data_rdist_sgi_base(); ++ else ++ base = gic_data.dist_base; ++ ++ return !!(readl_relaxed(base + offset + (gic_irq(d) / 32) * 4) & mask); ++} ++ ++static void gic_mask_irq(struct irq_data *d) ++{ ++ gic_poke_irq(d, GICD_ICENABLER); ++} ++ ++static void gic_unmask_irq(struct irq_data *d) ++{ ++ gic_poke_irq(d, GICD_ISENABLER); ++} ++ ++static void gic_eoi_irq(struct irq_data *d) ++{ ++ gic_write_eoir(gic_irq(d)); ++} ++ ++static int gic_set_type(struct irq_data *d, unsigned int type) ++{ ++ unsigned int irq = gic_irq(d); ++ void (*rwp_wait)(void); ++ void __iomem *base; ++ ++ /* Interrupt configuration for SGIs can't be changed */ ++ if (irq < 16) ++ return -EINVAL; ++ ++ if (type != IRQ_TYPE_LEVEL_HIGH && type != IRQ_TYPE_EDGE_RISING) ++ return -EINVAL; ++ ++ if (gic_irq_in_rdist(d)) { ++ base = gic_data_rdist_sgi_base(); ++ rwp_wait = gic_redist_wait_for_rwp; ++ } else { ++ base = gic_data.dist_base; ++ rwp_wait = gic_dist_wait_for_rwp; ++ } ++ ++ gic_configure_irq(irq, type, base, rwp_wait); ++ ++ return 0; ++} ++ ++static u64 gic_mpidr_to_affinity(u64 mpidr) ++{ ++ u64 aff; ++ ++ aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 32 | ++ MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 | ++ MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 | ++ MPIDR_AFFINITY_LEVEL(mpidr, 0)); ++ ++ return aff; ++} ++ ++static asmlinkage void __exception_irq_entry gic_handle_irq(struct pt_regs *regs) ++{ ++ u64 irqnr; ++ ++ do { ++ irqnr = gic_read_iar(); ++ ++ if (likely(irqnr > 15 && irqnr < 1020)) { ++ u64 irq = irq_find_mapping(gic_data.domain, irqnr); ++ if (likely(irq)) { ++ handle_IRQ(irq, regs); ++ continue; ++ } ++ ++ WARN_ONCE(true, "Unexpected SPI received!\n"); ++ gic_write_eoir(irqnr); ++ } ++ if (irqnr < 16) { ++ gic_write_eoir(irqnr); ++#ifdef CONFIG_SMP ++ handle_IPI(irqnr, regs); ++#else ++ WARN_ONCE(true, "Unexpected SGI received!\n"); ++#endif ++ continue; ++ } ++ } while (irqnr != ICC_IAR1_EL1_SPURIOUS); ++} ++ ++static void __init gic_dist_init(void) ++{ ++ unsigned int i; ++ u64 affinity; ++ void __iomem *base = gic_data.dist_base; ++ ++ /* Disable the distributor */ ++ writel_relaxed(0, base + GICD_CTLR); ++ gic_dist_wait_for_rwp(); ++ ++ gic_dist_config(base, gic_data.irq_nr, gic_dist_wait_for_rwp); ++ ++ /* Enable distributor with ARE, Group1 */ ++ writel_relaxed(GICD_CTLR_ARE_NS | GICD_CTLR_ENABLE_G1A | GICD_CTLR_ENABLE_G1, ++ base + GICD_CTLR); ++ ++ /* ++ * Set all global interrupts to the boot CPU only. ARE must be ++ * enabled. ++ */ ++ affinity = gic_mpidr_to_affinity(cpu_logical_map(smp_processor_id())); ++ for (i = 32; i < gic_data.irq_nr; i++) ++ writeq_relaxed(affinity, base + GICD_IROUTER + i * 8); ++} ++ ++static int gic_populate_rdist(void) ++{ ++ u64 mpidr = cpu_logical_map(smp_processor_id()); ++ u64 typer; ++ u32 aff; ++ int i; ++ ++ /* ++ * Convert affinity to a 32bit value that can be matched to ++ * GICR_TYPER bits [63:32]. ++ */ ++ aff = (MPIDR_AFFINITY_LEVEL(mpidr, 3) << 24 | ++ MPIDR_AFFINITY_LEVEL(mpidr, 2) << 16 | ++ MPIDR_AFFINITY_LEVEL(mpidr, 1) << 8 | ++ MPIDR_AFFINITY_LEVEL(mpidr, 0)); ++ ++ for (i = 0; i < gic_data.redist_regions; i++) { ++ void __iomem *ptr = gic_data.redist_base[i]; ++ u32 reg; ++ ++ reg = readl_relaxed(ptr + GICR_PIDR2) & GIC_PIDR2_ARCH_MASK; ++ if (reg != GIC_PIDR2_ARCH_GICv3 && ++ reg != GIC_PIDR2_ARCH_GICv4) { /* We're in trouble... */ ++ pr_warn("No redistributor present @%p\n", ptr); ++ break; ++ } ++ ++ do { ++ typer = readq_relaxed(ptr + GICR_TYPER); ++ if ((typer >> 32) == aff) { ++ gic_data_rdist_rd_base() = ptr; ++ pr_info("CPU%d: found redistributor %llx @%p\n", ++ smp_processor_id(), ++ (unsigned long long)mpidr, ptr); ++ return 0; ++ } ++ ++ if (gic_data.redist_stride) { ++ ptr += gic_data.redist_stride; ++ } else { ++ ptr += SZ_64K * 2; /* Skip RD_base + SGI_base */ ++ if (typer & GICR_TYPER_VLPIS) ++ ptr += SZ_64K * 2; /* Skip VLPI_base + reserved page */ ++ } ++ } while (!(typer & GICR_TYPER_LAST)); ++ } ++ ++ /* We couldn't even deal with ourselves... */ ++ WARN(true, "CPU%d: mpidr %llx has no re-distributor!\n", ++ smp_processor_id(), (unsigned long long)mpidr); ++ return -ENODEV; ++} ++ ++static void gic_cpu_init(void) ++{ ++ void __iomem *rbase; ++ ++ /* Register ourselves with the rest of the world */ ++ if (gic_populate_rdist()) ++ return; ++ ++ gic_enable_redist(); ++ ++ rbase = gic_data_rdist_sgi_base(); ++ ++ gic_cpu_config(rbase, gic_redist_wait_for_rwp); ++ ++ /* Enable system registers */ ++ gic_enable_sre(); ++ ++ /* Set priority mask register */ ++ gic_write_pmr(DEFAULT_PMR_VALUE); ++ ++ /* EOI deactivates interrupt too (mode 0) */ ++ gic_write_ctlr(ICC_CTLR_EL1_EOImode_drop_dir); ++ ++ /* ... and let's hit the road... */ ++ gic_write_grpen1(1); ++} ++ ++#ifdef CONFIG_SMP ++static int gic_secondary_init(struct notifier_block *nfb, ++ unsigned long action, void *hcpu) ++{ ++ if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) ++ gic_cpu_init(); ++ return NOTIFY_OK; ++} ++ ++/* ++ * Notifier for enabling the GIC CPU interface. Set an arbitrarily high ++ * priority because the GIC needs to be up before the ARM generic timers. ++ */ ++static struct notifier_block gic_cpu_notifier = { ++ .notifier_call = gic_secondary_init, ++ .priority = 100, ++}; ++ ++static u16 gic_compute_target_list(int *base_cpu, const struct cpumask *mask, ++ u64 cluster_id) ++{ ++ int cpu = *base_cpu; ++ u64 mpidr = cpu_logical_map(cpu); ++ u16 tlist = 0; ++ ++ while (cpu < nr_cpu_ids) { ++ /* ++ * If we ever get a cluster of more than 16 CPUs, just ++ * scream and skip that CPU. ++ */ ++ if (WARN_ON((mpidr & 0xff) >= 16)) ++ goto out; ++ ++ tlist |= 1 << (mpidr & 0xf); ++ ++ cpu = cpumask_next(cpu, mask); ++ if (cpu == nr_cpu_ids) ++ goto out; ++ ++ mpidr = cpu_logical_map(cpu); ++ ++ if (cluster_id != (mpidr & ~0xffUL)) { ++ cpu--; ++ goto out; ++ } ++ } ++out: ++ *base_cpu = cpu; ++ return tlist; ++} ++ ++static void gic_send_sgi(u64 cluster_id, u16 tlist, unsigned int irq) ++{ ++ u64 val; ++ ++ val = (MPIDR_AFFINITY_LEVEL(cluster_id, 3) << 48 | ++ MPIDR_AFFINITY_LEVEL(cluster_id, 2) << 32 | ++ irq << 24 | ++ MPIDR_AFFINITY_LEVEL(cluster_id, 1) << 16 | ++ tlist); ++ ++ pr_debug("CPU%d: ICC_SGI1R_EL1 %llx\n", smp_processor_id(), val); ++ gic_write_sgi1r(val); ++} ++ ++static void gic_raise_softirq(const struct cpumask *mask, unsigned int irq) ++{ ++ int cpu; ++ ++ if (WARN_ON(irq >= 16)) ++ return; ++ ++ /* ++ * Ensure that stores to Normal memory are visible to the ++ * other CPUs before issuing the IPI. ++ */ ++ smp_wmb(); ++ ++ for_each_cpu_mask(cpu, *mask) { ++ u64 cluster_id = cpu_logical_map(cpu) & ~0xffUL; ++ u16 tlist; ++ ++ tlist = gic_compute_target_list(&cpu, mask, cluster_id); ++ gic_send_sgi(cluster_id, tlist, irq); ++ } ++ ++ /* Force the above writes to ICC_SGI1R_EL1 to be executed */ ++ isb(); ++} ++ ++static void gic_smp_init(void) ++{ ++ set_smp_cross_call(gic_raise_softirq); ++ register_cpu_notifier(&gic_cpu_notifier); ++} ++ ++static int gic_set_affinity(struct irq_data *d, const struct cpumask *mask_val, ++ bool force) ++{ ++ unsigned int cpu = cpumask_any_and(mask_val, cpu_online_mask); ++ void __iomem *reg; ++ int enabled; ++ u64 val; ++ ++ if (gic_irq_in_rdist(d)) ++ return -EINVAL; ++ ++ /* If interrupt was enabled, disable it first */ ++ enabled = gic_peek_irq(d, GICD_ISENABLER); ++ if (enabled) ++ gic_mask_irq(d); ++ ++ reg = gic_dist_base(d) + GICD_IROUTER + (gic_irq(d) * 8); ++ val = gic_mpidr_to_affinity(cpu_logical_map(cpu)); ++ ++ writeq_relaxed(val, reg); ++ ++ /* ++ * If the interrupt was enabled, enabled it again. Otherwise, ++ * just wait for the distributor to have digested our changes. ++ */ ++ if (enabled) ++ gic_unmask_irq(d); ++ else ++ gic_dist_wait_for_rwp(); ++ ++ return IRQ_SET_MASK_OK; ++} ++#else ++#define gic_set_affinity NULL ++#define gic_smp_init() do { } while(0) ++#endif ++ ++static struct irq_chip gic_chip = { ++ .name = "GICv3", ++ .irq_mask = gic_mask_irq, ++ .irq_unmask = gic_unmask_irq, ++ .irq_eoi = gic_eoi_irq, ++ .irq_set_type = gic_set_type, ++ .irq_set_affinity = gic_set_affinity, ++}; ++ ++static int gic_irq_domain_map(struct irq_domain *d, unsigned int irq, ++ irq_hw_number_t hw) ++{ ++ /* SGIs are private to the core kernel */ ++ if (hw < 16) ++ return -EPERM; ++ /* PPIs */ ++ if (hw < 32) { ++ irq_set_percpu_devid(irq); ++ irq_set_chip_and_handler(irq, &gic_chip, ++ handle_percpu_devid_irq); ++ set_irq_flags(irq, IRQF_VALID | IRQF_NOAUTOEN); ++ } ++ /* SPIs */ ++ if (hw >= 32 && hw < gic_data.irq_nr) { ++ irq_set_chip_and_handler(irq, &gic_chip, ++ handle_fasteoi_irq); ++ set_irq_flags(irq, IRQF_VALID | IRQF_PROBE); ++ } ++ irq_set_chip_data(irq, d->host_data); ++ return 0; ++} ++ ++static int gic_irq_domain_xlate(struct irq_domain *d, ++ struct device_node *controller, ++ const u32 *intspec, unsigned int intsize, ++ unsigned long *out_hwirq, unsigned int *out_type) ++{ ++ if (d->of_node != controller) ++ return -EINVAL; ++ if (intsize < 3) ++ return -EINVAL; ++ ++ switch(intspec[0]) { ++ case 0: /* SPI */ ++ *out_hwirq = intspec[1] + 32; ++ break; ++ case 1: /* PPI */ ++ *out_hwirq = intspec[1] + 16; ++ break; ++ default: ++ return -EINVAL; ++ } ++ ++ *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; ++ return 0; ++} ++ ++static const struct irq_domain_ops gic_irq_domain_ops = { ++ .map = gic_irq_domain_map, ++ .xlate = gic_irq_domain_xlate, ++}; ++ ++static int __init gic_of_init(struct device_node *node, struct device_node *parent) ++{ ++ void __iomem *dist_base; ++ void __iomem **redist_base; ++ u64 redist_stride; ++ u32 redist_regions; ++ u32 reg; ++ int gic_irqs; ++ int err; ++ int i; ++ ++ dist_base = of_iomap(node, 0); ++ if (!dist_base) { ++ pr_err("%s: unable to map gic dist registers\n", ++ node->full_name); ++ return -ENXIO; ++ } ++ ++ reg = readl_relaxed(dist_base + GICD_PIDR2) & GIC_PIDR2_ARCH_MASK; ++ if (reg != GIC_PIDR2_ARCH_GICv3 && reg != GIC_PIDR2_ARCH_GICv4) { ++ pr_err("%s: no distributor detected, giving up\n", ++ node->full_name); ++ err = -ENODEV; ++ goto out_unmap_dist; ++ } ++ ++ if (of_property_read_u32(node, "#redistributor-regions", &redist_regions)) ++ redist_regions = 1; ++ ++ redist_base = kzalloc(sizeof(*redist_base) * redist_regions, GFP_KERNEL); ++ if (!redist_base) { ++ err = -ENOMEM; ++ goto out_unmap_dist; ++ } ++ ++ for (i = 0; i < redist_regions; i++) { ++ redist_base[i] = of_iomap(node, 1 + i); ++ if (!redist_base[i]) { ++ pr_err("%s: couldn't map region %d\n", ++ node->full_name, i); ++ err = -ENODEV; ++ goto out_unmap_rdist; ++ } ++ } ++ ++ if (of_property_read_u64(node, "redistributor-stride", &redist_stride)) ++ redist_stride = 0; ++ ++ gic_data.dist_base = dist_base; ++ gic_data.redist_base = redist_base; ++ gic_data.redist_regions = redist_regions; ++ gic_data.redist_stride = redist_stride; ++ ++ /* ++ * Find out how many interrupts are supported. ++ * The GIC only supports up to 1020 interrupt sources (SGI+PPI+SPI) ++ */ ++ gic_irqs = readl_relaxed(gic_data.dist_base + GICD_TYPER) & 0x1f; ++ gic_irqs = (gic_irqs + 1) * 32; ++ if (gic_irqs > 1020) ++ gic_irqs = 1020; ++ gic_data.irq_nr = gic_irqs; ++ ++ gic_data.domain = irq_domain_add_tree(node, &gic_irq_domain_ops, ++ &gic_data); ++ gic_data.rdist = alloc_percpu(typeof(*gic_data.rdist)); ++ ++ if (WARN_ON(!gic_data.domain) || WARN_ON(!gic_data.rdist)) { ++ err = -ENOMEM; ++ goto out_free; ++ } ++ ++ set_handle_irq(gic_handle_irq); ++ ++ gic_smp_init(); ++ gic_dist_init(); ++ gic_cpu_init(); ++ ++ return 0; ++ ++out_free: ++ if (gic_data.domain) ++ irq_domain_remove(gic_data.domain); ++ free_percpu(gic_data.rdist); ++out_unmap_rdist: ++ for (i = 0; i < redist_regions; i++) ++ if (redist_base[i]) ++ iounmap(redist_base[i]); ++ kfree(redist_base); ++out_unmap_dist: ++ iounmap(dist_base); ++ return err; ++} ++ ++IRQCHIP_DECLARE(gic_v3, "arm,gic-v3", gic_of_init); +diff --git a/drivers/irqchip/irq-gic.c b/drivers/irqchip/irq-gic.c +index 7c131cf..1ddfdde 100644 +--- a/drivers/irqchip/irq-gic.c ++++ b/drivers/irqchip/irq-gic.c +@@ -47,6 +47,7 @@ + #include <asm/exception.h> + #include <asm/smp_plat.h> + ++#include "irq-gic-common.h" + #include "irqchip.h" + + union gic_base { +@@ -189,12 +190,6 @@ static int gic_set_type(struct irq_data *d, unsigned int type) + { + void __iomem *base = gic_dist_base(d); + unsigned int gicirq = gic_irq(d); +- u32 enablemask = 1 << (gicirq % 32); +- u32 enableoff = (gicirq / 32) * 4; +- u32 confmask = 0x2 << ((gicirq % 16) * 2); +- u32 confoff = (gicirq / 16) * 4; +- bool enabled = false; +- u32 val; + + /* Interrupt configuration for SGIs can't be changed */ + if (gicirq < 16) +@@ -208,25 +203,7 @@ static int gic_set_type(struct irq_data *d, unsigned int type) + if (gic_arch_extn.irq_set_type) + gic_arch_extn.irq_set_type(d, type); + +- val = readl_relaxed(base + GIC_DIST_CONFIG + confoff); +- if (type == IRQ_TYPE_LEVEL_HIGH) +- val &= ~confmask; +- else if (type == IRQ_TYPE_EDGE_RISING) +- val |= confmask; +- +- /* +- * As recommended by the spec, disable the interrupt before changing +- * the configuration +- */ +- if (readl_relaxed(base + GIC_DIST_ENABLE_SET + enableoff) & enablemask) { +- writel_relaxed(enablemask, base + GIC_DIST_ENABLE_CLEAR + enableoff); +- enabled = true; +- } +- +- writel_relaxed(val, base + GIC_DIST_CONFIG + confoff); +- +- if (enabled) +- writel_relaxed(enablemask, base + GIC_DIST_ENABLE_SET + enableoff); ++ gic_configure_irq(gicirq, type, base, NULL); + + raw_spin_unlock(&irq_controller_lock); + +@@ -388,12 +365,6 @@ static void __init gic_dist_init(struct gic_chip_data *gic) + writel_relaxed(0, base + GIC_DIST_CTRL); + + /* +- * Set all global interrupts to be level triggered, active low. +- */ +- for (i = 32; i < gic_irqs; i += 16) +- writel_relaxed(0, base + GIC_DIST_CONFIG + i * 4 / 16); +- +- /* + * Set all global interrupts to this CPU only. + */ + cpumask = gic_get_cpumask(gic); +@@ -402,18 +373,7 @@ static void __init gic_dist_init(struct gic_chip_data *gic) + for (i = 32; i < gic_irqs; i += 4) + writel_relaxed(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); + +- /* +- * Set priority on all global interrupts. +- */ +- for (i = 32; i < gic_irqs; i += 4) +- writel_relaxed(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); +- +- /* +- * Disable all interrupts. Leave the PPI and SGIs alone +- * as these enables are banked registers. +- */ +- for (i = 32; i < gic_irqs; i += 32) +- writel_relaxed(0xffffffff, base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); ++ gic_dist_config(base, gic_irqs, NULL); + + writel_relaxed(1, base + GIC_DIST_CTRL); + } +@@ -423,6 +383,7 @@ static void gic_cpu_init(struct gic_chip_data *gic) + void __iomem *dist_base = gic_data_dist_base(gic); + void __iomem *base = gic_data_cpu_base(gic); + unsigned int cpu_mask, cpu = smp_processor_id(); ++ unsigned int ctrl_mask; + int i; + + /* +@@ -440,27 +401,32 @@ static void gic_cpu_init(struct gic_chip_data *gic) + if (i != cpu) + gic_cpu_map[i] &= ~cpu_mask; + +- /* +- * Deal with the banked PPI and SGI interrupts - disable all +- * PPI interrupts, ensure all SGI interrupts are enabled. +- */ +- writel_relaxed(0xffff0000, dist_base + GIC_DIST_ENABLE_CLEAR); +- writel_relaxed(0x0000ffff, dist_base + GIC_DIST_ENABLE_SET); +- +- /* +- * Set priority on PPI and SGI interrupts +- */ +- for (i = 0; i < 32; i += 4) +- writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4 / 4); ++ gic_cpu_config(dist_base, NULL); + + writel_relaxed(0xf0, base + GIC_CPU_PRIMASK); +- writel_relaxed(1, base + GIC_CPU_CTRL); ++ ++ ctrl_mask = readl(base + GIC_CPU_CTRL); ++ ++ /* Mask out the gic v2 bypass bits */ ++ ctrl_mask &= 0x1e0; ++ ++ /* Enable group 0 */ ++ ctrl_mask |= 0x1; ++ writel_relaxed(ctrl_mask, base + GIC_CPU_CTRL); + } + + void gic_cpu_if_down(void) + { ++ unsigned int ctrl_mask; + void __iomem *cpu_base = gic_data_cpu_base(&gic_data[0]); +- writel_relaxed(0, cpu_base + GIC_CPU_CTRL); ++ ++ ctrl_mask = readl(cpu_base + GIC_CPU_CTRL); ++ /* ++ * Disable grp enable bit, leave the bypass bits alone as changing ++ * them could leave the system unstable ++ */ ++ ctrl_mask &= 0x1e0; ++ writel_relaxed(ctrl_mask, cpu_base + GIC_CPU_CTRL); + } + + #ifdef CONFIG_CPU_PM +@@ -571,6 +537,7 @@ static void gic_cpu_restore(unsigned int gic_nr) + { + int i; + u32 *ptr; ++ unsigned int ctrl_mask; + void __iomem *dist_base; + void __iomem *cpu_base; + +@@ -595,7 +562,15 @@ static void gic_cpu_restore(unsigned int gic_nr) + writel_relaxed(0xa0a0a0a0, dist_base + GIC_DIST_PRI + i * 4); + + writel_relaxed(0xf0, cpu_base + GIC_CPU_PRIMASK); +- writel_relaxed(1, cpu_base + GIC_CPU_CTRL); ++ ++ ctrl_mask = readl(cpu_base + GIC_CPU_CTRL); ++ ++ /* Mask out the gic v2 bypass bits */ ++ ctrl_mask &= 0x1e0; ++ ++ /* Enable group 0 */ ++ ctrl_mask |= 0x1; ++ writel_relaxed(ctrl_mask, cpu_base + GIC_CPU_CTRL); + } + + static int gic_notifier(struct notifier_block *self, unsigned long cmd, void *v) +diff --git a/drivers/net/ethernet/Kconfig b/drivers/net/ethernet/Kconfig +index edb7186..dc7406c 100644 +--- a/drivers/net/ethernet/Kconfig ++++ b/drivers/net/ethernet/Kconfig +@@ -24,6 +24,7 @@ source "drivers/net/ethernet/allwinner/Kconfig" + source "drivers/net/ethernet/alteon/Kconfig" + source "drivers/net/ethernet/altera/Kconfig" + source "drivers/net/ethernet/amd/Kconfig" ++source "drivers/net/ethernet/apm/Kconfig" + source "drivers/net/ethernet/apple/Kconfig" + source "drivers/net/ethernet/arc/Kconfig" + source "drivers/net/ethernet/atheros/Kconfig" +diff --git a/drivers/net/ethernet/Makefile b/drivers/net/ethernet/Makefile +index 58de333..224a018 100644 +--- a/drivers/net/ethernet/Makefile ++++ b/drivers/net/ethernet/Makefile +@@ -10,6 +10,7 @@ obj-$(CONFIG_NET_VENDOR_ALLWINNER) += allwinner/ + obj-$(CONFIG_NET_VENDOR_ALTEON) += alteon/ + obj-$(CONFIG_ALTERA_TSE) += altera/ + obj-$(CONFIG_NET_VENDOR_AMD) += amd/ ++obj-$(CONFIG_NET_XGENE) += apm/ + obj-$(CONFIG_NET_VENDOR_APPLE) += apple/ + obj-$(CONFIG_NET_VENDOR_ARC) += arc/ + obj-$(CONFIG_NET_VENDOR_ATHEROS) += atheros/ +diff --git a/drivers/net/ethernet/apm/Kconfig b/drivers/net/ethernet/apm/Kconfig +new file mode 100644 +index 0000000..ec63d70 +--- /dev/null ++++ b/drivers/net/ethernet/apm/Kconfig +@@ -0,0 +1 @@ ++source "drivers/net/ethernet/apm/xgene/Kconfig" +diff --git a/drivers/net/ethernet/apm/Makefile b/drivers/net/ethernet/apm/Makefile +new file mode 100644 +index 0000000..65ce32a +--- /dev/null ++++ b/drivers/net/ethernet/apm/Makefile +@@ -0,0 +1,5 @@ ++# ++# Makefile for APM X-GENE Ethernet driver. ++# ++ ++obj-$(CONFIG_NET_XGENE) += xgene/ +diff --git a/drivers/net/ethernet/apm/xgene/Kconfig b/drivers/net/ethernet/apm/xgene/Kconfig +new file mode 100644 +index 0000000..616dff6 +--- /dev/null ++++ b/drivers/net/ethernet/apm/xgene/Kconfig +@@ -0,0 +1,9 @@ ++config NET_XGENE ++ tristate "APM X-Gene SoC Ethernet Driver" ++ select PHYLIB ++ help ++ This is the Ethernet driver for the on-chip ethernet interface on the ++ APM X-Gene SoC. ++ ++ To compile this driver as a module, choose M here. This module will ++ be called xgene_enet. +diff --git a/drivers/net/ethernet/apm/xgene/Makefile b/drivers/net/ethernet/apm/xgene/Makefile +new file mode 100644 +index 0000000..c643e8a +--- /dev/null ++++ b/drivers/net/ethernet/apm/xgene/Makefile +@@ -0,0 +1,6 @@ ++# ++# Makefile for APM X-Gene Ethernet Driver. ++# ++ ++xgene-enet-objs := xgene_enet_hw.o xgene_enet_main.o xgene_enet_ethtool.o ++obj-$(CONFIG_NET_XGENE) += xgene-enet.o +diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c +new file mode 100644 +index 0000000..63f2aa5 +--- /dev/null ++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_ethtool.c +@@ -0,0 +1,125 @@ ++/* Applied Micro X-Gene SoC Ethernet Driver ++ * ++ * Copyright (c) 2014, Applied Micro Circuits Corporation ++ * Authors: Iyappan Subramanian <isubramanian@apm.com> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#include <linux/ethtool.h> ++#include "xgene_enet_main.h" ++ ++struct xgene_gstrings_stats { ++ char name[ETH_GSTRING_LEN]; ++ int offset; ++}; ++ ++#define XGENE_STAT(m) { #m, offsetof(struct xgene_enet_pdata, stats.m) } ++ ++static const struct xgene_gstrings_stats gstrings_stats[] = { ++ XGENE_STAT(rx_packets), ++ XGENE_STAT(tx_packets), ++ XGENE_STAT(rx_bytes), ++ XGENE_STAT(tx_bytes), ++ XGENE_STAT(rx_errors), ++ XGENE_STAT(tx_errors), ++ XGENE_STAT(rx_length_errors), ++ XGENE_STAT(rx_crc_errors), ++ XGENE_STAT(rx_frame_errors), ++ XGENE_STAT(rx_fifo_errors) ++}; ++ ++#define XGENE_STATS_LEN ARRAY_SIZE(gstrings_stats) ++ ++static void xgene_get_drvinfo(struct net_device *ndev, ++ struct ethtool_drvinfo *info) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ struct platform_device *pdev = pdata->pdev; ++ ++ strcpy(info->driver, "xgene_enet"); ++ strcpy(info->version, XGENE_DRV_VERSION); ++ snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "N/A"); ++ sprintf(info->bus_info, "%s", pdev->name); ++} ++ ++static int xgene_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ struct phy_device *phydev = pdata->phy_dev; ++ ++ if (phydev == NULL) ++ return -ENODEV; ++ ++ return phy_ethtool_gset(phydev, cmd); ++} ++ ++static int xgene_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ struct phy_device *phydev = pdata->phy_dev; ++ ++ if (phydev == NULL) ++ return -ENODEV; ++ ++ return phy_ethtool_sset(phydev, cmd); ++} ++ ++static void xgene_get_strings(struct net_device *ndev, u32 stringset, u8 *data) ++{ ++ int i; ++ u8 *p = data; ++ ++ if (stringset != ETH_SS_STATS) ++ return; ++ ++ for (i = 0; i < XGENE_STATS_LEN; i++) { ++ memcpy(p, gstrings_stats[i].name, ETH_GSTRING_LEN); ++ p += ETH_GSTRING_LEN; ++ } ++} ++ ++static int xgene_get_sset_count(struct net_device *ndev, int sset) ++{ ++ if (sset != ETH_SS_STATS) ++ return -EINVAL; ++ ++ return XGENE_STATS_LEN; ++} ++ ++static void xgene_get_ethtool_stats(struct net_device *ndev, ++ struct ethtool_stats *dummy, ++ u64 *data) ++{ ++ void *pdata = netdev_priv(ndev); ++ int i; ++ ++ for (i = 0; i < XGENE_STATS_LEN; i++) ++ *data++ = *(u64 *)(pdata + gstrings_stats[i].offset); ++} ++ ++static const struct ethtool_ops xgene_ethtool_ops = { ++ .get_drvinfo = xgene_get_drvinfo, ++ .get_settings = xgene_get_settings, ++ .set_settings = xgene_set_settings, ++ .get_link = ethtool_op_get_link, ++ .get_strings = xgene_get_strings, ++ .get_sset_count = xgene_get_sset_count, ++ .get_ethtool_stats = xgene_get_ethtool_stats ++}; ++ ++void xgene_enet_set_ethtool_ops(struct net_device *ndev) ++{ ++ ndev->ethtool_ops = &xgene_ethtool_ops; ++} +diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c +new file mode 100644 +index 0000000..e52af60 +--- /dev/null ++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.c +@@ -0,0 +1,747 @@ ++/* Applied Micro X-Gene SoC Ethernet Driver ++ * ++ * Copyright (c) 2014, Applied Micro Circuits Corporation ++ * Authors: Iyappan Subramanian <isubramanian@apm.com> ++ * Ravi Patel <rapatel@apm.com> ++ * Keyur Chudgar <kchudgar@apm.com> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#include "xgene_enet_main.h" ++#include "xgene_enet_hw.h" ++ ++static void xgene_enet_ring_init(struct xgene_enet_desc_ring *ring) ++{ ++ u32 *ring_cfg = ring->state; ++ u64 addr = ring->dma; ++ enum xgene_enet_ring_cfgsize cfgsize = ring->cfgsize; ++ ++ ring_cfg[4] |= (1 << SELTHRSH_POS) & ++ CREATE_MASK(SELTHRSH_POS, SELTHRSH_LEN); ++ ring_cfg[3] |= ACCEPTLERR; ++ ring_cfg[2] |= QCOHERENT; ++ ++ addr >>= 8; ++ ring_cfg[2] |= (addr << RINGADDRL_POS) & ++ CREATE_MASK_ULL(RINGADDRL_POS, RINGADDRL_LEN); ++ addr >>= RINGADDRL_LEN; ++ ring_cfg[3] |= addr & CREATE_MASK_ULL(RINGADDRH_POS, RINGADDRH_LEN); ++ ring_cfg[3] |= ((u32) cfgsize << RINGSIZE_POS) & ++ CREATE_MASK(RINGSIZE_POS, RINGSIZE_LEN); ++} ++ ++static void xgene_enet_ring_set_type(struct xgene_enet_desc_ring *ring) ++{ ++ u32 *ring_cfg = ring->state; ++ bool is_bufpool; ++ u32 val; ++ ++ is_bufpool = xgene_enet_is_bufpool(ring->id); ++ val = (is_bufpool) ? RING_BUFPOOL : RING_REGULAR; ++ ring_cfg[4] |= (val << RINGTYPE_POS) & ++ CREATE_MASK(RINGTYPE_POS, RINGTYPE_LEN); ++ ++ if (is_bufpool) { ++ ring_cfg[3] |= (BUFPOOL_MODE << RINGMODE_POS) & ++ CREATE_MASK(RINGMODE_POS, RINGMODE_LEN); ++ } ++} ++ ++static void xgene_enet_ring_set_recombbuf(struct xgene_enet_desc_ring *ring) ++{ ++ u32 *ring_cfg = ring->state; ++ ++ ring_cfg[3] |= RECOMBBUF; ++ ring_cfg[3] |= (0xf << RECOMTIMEOUTL_POS) & ++ CREATE_MASK(RECOMTIMEOUTL_POS, RECOMTIMEOUTL_LEN); ++ ring_cfg[4] |= 0x7 & CREATE_MASK(RECOMTIMEOUTH_POS, RECOMTIMEOUTH_LEN); ++} ++ ++static void xgene_enet_ring_wr32(struct xgene_enet_desc_ring *ring, ++ u32 offset, u32 data) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev); ++ ++ iowrite32(data, pdata->ring_csr_addr + offset); ++} ++ ++static void xgene_enet_ring_rd32(struct xgene_enet_desc_ring *ring, ++ u32 offset, u32 *data) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev); ++ ++ *data = ioread32(pdata->ring_csr_addr + offset); ++} ++ ++static void xgene_enet_write_ring_state(struct xgene_enet_desc_ring *ring) ++{ ++ int i; ++ ++ xgene_enet_ring_wr32(ring, CSR_RING_CONFIG, ring->num); ++ for (i = 0; i < NUM_RING_CONFIG; i++) { ++ xgene_enet_ring_wr32(ring, CSR_RING_WR_BASE + (i * 4), ++ ring->state[i]); ++ } ++} ++ ++static void xgene_enet_clr_ring_state(struct xgene_enet_desc_ring *ring) ++{ ++ memset(ring->state, 0, sizeof(u32) * NUM_RING_CONFIG); ++ xgene_enet_write_ring_state(ring); ++} ++ ++static void xgene_enet_set_ring_state(struct xgene_enet_desc_ring *ring) ++{ ++ xgene_enet_ring_set_type(ring); ++ ++ if (xgene_enet_ring_owner(ring->id) == RING_OWNER_ETH0) ++ xgene_enet_ring_set_recombbuf(ring); ++ ++ xgene_enet_ring_init(ring); ++ xgene_enet_write_ring_state(ring); ++} ++ ++static void xgene_enet_set_ring_id(struct xgene_enet_desc_ring *ring) ++{ ++ u32 ring_id_val, ring_id_buf; ++ bool is_bufpool; ++ ++ is_bufpool = xgene_enet_is_bufpool(ring->id); ++ ++ ring_id_val = ring->id & GENMASK(9, 0); ++ ring_id_val |= OVERWRITE; ++ ++ ring_id_buf = (ring->num << 9) & GENMASK(18, 9); ++ ring_id_buf |= PREFETCH_BUF_EN; ++ if (is_bufpool) ++ ring_id_buf |= IS_BUFFER_POOL; ++ ++ xgene_enet_ring_wr32(ring, CSR_RING_ID, ring_id_val); ++ xgene_enet_ring_wr32(ring, CSR_RING_ID_BUF, ring_id_buf); ++} ++ ++static void xgene_enet_clr_desc_ring_id(struct xgene_enet_desc_ring *ring) ++{ ++ u32 ring_id; ++ ++ ring_id = ring->id | OVERWRITE; ++ xgene_enet_ring_wr32(ring, CSR_RING_ID, ring_id); ++ xgene_enet_ring_wr32(ring, CSR_RING_ID_BUF, 0); ++} ++ ++struct xgene_enet_desc_ring *xgene_enet_setup_ring( ++ struct xgene_enet_desc_ring *ring) ++{ ++ u32 size = ring->size; ++ u32 i, data; ++ u64 *desc; ++ bool is_bufpool; ++ ++ xgene_enet_clr_ring_state(ring); ++ xgene_enet_set_ring_state(ring); ++ xgene_enet_set_ring_id(ring); ++ ++ ring->slots = xgene_enet_get_numslots(ring->id, size); ++ ++ is_bufpool = xgene_enet_is_bufpool(ring->id); ++ if (is_bufpool || xgene_enet_ring_owner(ring->id) != RING_OWNER_CPU) ++ return ring; ++ ++ for (i = 0; i < ring->slots; i++) { ++ desc = (u64 *)&ring->raw_desc[i]; ++ desc[EMPTY_SLOT_INDEX] = EMPTY_SLOT; ++ } ++ ++ xgene_enet_ring_rd32(ring, CSR_RING_NE_INT_MODE, &data); ++ data |= BIT(31 - xgene_enet_ring_bufnum(ring->id)); ++ xgene_enet_ring_wr32(ring, CSR_RING_NE_INT_MODE, data); ++ ++ return ring; ++} ++ ++void xgene_enet_clear_ring(struct xgene_enet_desc_ring *ring) ++{ ++ u32 data; ++ bool is_bufpool; ++ ++ is_bufpool = xgene_enet_is_bufpool(ring->id); ++ if (is_bufpool || xgene_enet_ring_owner(ring->id) != RING_OWNER_CPU) ++ goto out; ++ ++ xgene_enet_ring_rd32(ring, CSR_RING_NE_INT_MODE, &data); ++ data &= ~BIT(31 - xgene_enet_ring_bufnum(ring->id)); ++ xgene_enet_ring_wr32(ring, CSR_RING_NE_INT_MODE, data); ++ ++out: ++ xgene_enet_clr_desc_ring_id(ring); ++ xgene_enet_clr_ring_state(ring); ++} ++ ++void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring, ++ struct xgene_enet_pdata *pdata, ++ enum xgene_enet_err_code status) ++{ ++ struct rtnl_link_stats64 *stats = &pdata->stats; ++ ++ switch (status) { ++ case INGRESS_CRC: ++ stats->rx_crc_errors++; ++ break; ++ case INGRESS_CHECKSUM: ++ case INGRESS_CHECKSUM_COMPUTE: ++ stats->rx_errors++; ++ break; ++ case INGRESS_TRUNC_FRAME: ++ stats->rx_frame_errors++; ++ break; ++ case INGRESS_PKT_LEN: ++ stats->rx_length_errors++; ++ break; ++ case INGRESS_PKT_UNDER: ++ stats->rx_frame_errors++; ++ break; ++ case INGRESS_FIFO_OVERRUN: ++ stats->rx_fifo_errors++; ++ break; ++ default: ++ break; ++ } ++} ++ ++static void xgene_enet_wr_csr(struct xgene_enet_pdata *pdata, ++ u32 offset, u32 val) ++{ ++ void __iomem *addr = pdata->eth_csr_addr + offset; ++ ++ iowrite32(val, addr); ++} ++ ++static void xgene_enet_wr_ring_if(struct xgene_enet_pdata *pdata, ++ u32 offset, u32 val) ++{ ++ void __iomem *addr = pdata->eth_ring_if_addr + offset; ++ ++ iowrite32(val, addr); ++} ++ ++static void xgene_enet_wr_diag_csr(struct xgene_enet_pdata *pdata, ++ u32 offset, u32 val) ++{ ++ void __iomem *addr = pdata->eth_diag_csr_addr + offset; ++ ++ iowrite32(val, addr); ++} ++ ++static void xgene_enet_wr_mcx_csr(struct xgene_enet_pdata *pdata, ++ u32 offset, u32 val) ++{ ++ void __iomem *addr = pdata->mcx_mac_csr_addr + offset; ++ ++ iowrite32(val, addr); ++} ++ ++static bool xgene_enet_wr_indirect(void __iomem *addr, void __iomem *wr, ++ void __iomem *cmd, void __iomem *cmd_done, ++ u32 wr_addr, u32 wr_data) ++{ ++ u32 done; ++ u8 wait = 10; ++ ++ iowrite32(wr_addr, addr); ++ iowrite32(wr_data, wr); ++ iowrite32(XGENE_ENET_WR_CMD, cmd); ++ ++ /* wait for write command to complete */ ++ while (!(done = ioread32(cmd_done)) && wait--) ++ udelay(1); ++ ++ if (!done) ++ return false; ++ ++ iowrite32(0, cmd); ++ ++ return true; ++} ++ ++static void xgene_enet_wr_mcx_mac(struct xgene_enet_pdata *pdata, ++ u32 wr_addr, u32 wr_data) ++{ ++ void __iomem *addr, *wr, *cmd, *cmd_done; ++ bool ret; ++ ++ addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET; ++ wr = pdata->mcx_mac_addr + MAC_WRITE_REG_OFFSET; ++ cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET; ++ cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET; ++ ++ ret = xgene_enet_wr_indirect(addr, wr, cmd, cmd_done, wr_addr, wr_data); ++ if (!ret) ++ netdev_err(pdata->ndev, "MCX mac write failed, addr: %04x\n", ++ wr_addr); ++} ++ ++static void xgene_enet_rd_csr(struct xgene_enet_pdata *pdata, ++ u32 offset, u32 *val) ++{ ++ void __iomem *addr = pdata->eth_csr_addr + offset; ++ ++ *val = ioread32(addr); ++} ++ ++static void xgene_enet_rd_diag_csr(struct xgene_enet_pdata *pdata, ++ u32 offset, u32 *val) ++{ ++ void __iomem *addr = pdata->eth_diag_csr_addr + offset; ++ ++ *val = ioread32(addr); ++} ++ ++static void xgene_enet_rd_mcx_csr(struct xgene_enet_pdata *pdata, ++ u32 offset, u32 *val) ++{ ++ void __iomem *addr = pdata->mcx_mac_csr_addr + offset; ++ ++ *val = ioread32(addr); ++} ++ ++static bool xgene_enet_rd_indirect(void __iomem *addr, void __iomem *rd, ++ void __iomem *cmd, void __iomem *cmd_done, ++ u32 rd_addr, u32 *rd_data) ++{ ++ u32 done; ++ u8 wait = 10; ++ ++ iowrite32(rd_addr, addr); ++ iowrite32(XGENE_ENET_RD_CMD, cmd); ++ ++ /* wait for read command to complete */ ++ while (!(done = ioread32(cmd_done)) && wait--) ++ udelay(1); ++ ++ if (!done) ++ return false; ++ ++ *rd_data = ioread32(rd); ++ iowrite32(0, cmd); ++ ++ return true; ++} ++ ++static void xgene_enet_rd_mcx_mac(struct xgene_enet_pdata *pdata, ++ u32 rd_addr, u32 *rd_data) ++{ ++ void __iomem *addr, *rd, *cmd, *cmd_done; ++ bool ret; ++ ++ addr = pdata->mcx_mac_addr + MAC_ADDR_REG_OFFSET; ++ rd = pdata->mcx_mac_addr + MAC_READ_REG_OFFSET; ++ cmd = pdata->mcx_mac_addr + MAC_COMMAND_REG_OFFSET; ++ cmd_done = pdata->mcx_mac_addr + MAC_COMMAND_DONE_REG_OFFSET; ++ ++ ret = xgene_enet_rd_indirect(addr, rd, cmd, cmd_done, rd_addr, rd_data); ++ if (!ret) ++ netdev_err(pdata->ndev, "MCX mac read failed, addr: %04x\n", ++ rd_addr); ++} ++ ++static int xgene_mii_phy_write(struct xgene_enet_pdata *pdata, int phy_id, ++ u32 reg, u16 data) ++{ ++ u32 addr = 0, wr_data = 0; ++ u32 done; ++ u8 wait = 10; ++ ++ PHY_ADDR_SET(&addr, phy_id); ++ REG_ADDR_SET(&addr, reg); ++ xgene_enet_wr_mcx_mac(pdata, MII_MGMT_ADDRESS_ADDR, addr); ++ ++ PHY_CONTROL_SET(&wr_data, data); ++ xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONTROL_ADDR, wr_data); ++ do { ++ usleep_range(5, 10); ++ xgene_enet_rd_mcx_mac(pdata, MII_MGMT_INDICATORS_ADDR, &done); ++ } while ((done & BUSY_MASK) && wait--); ++ ++ if (done & BUSY_MASK) { ++ netdev_err(pdata->ndev, "MII_MGMT write failed\n"); ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static int xgene_mii_phy_read(struct xgene_enet_pdata *pdata, ++ u8 phy_id, u32 reg) ++{ ++ u32 addr = 0; ++ u32 data, done; ++ u8 wait = 10; ++ ++ PHY_ADDR_SET(&addr, phy_id); ++ REG_ADDR_SET(&addr, reg); ++ xgene_enet_wr_mcx_mac(pdata, MII_MGMT_ADDRESS_ADDR, addr); ++ xgene_enet_wr_mcx_mac(pdata, MII_MGMT_COMMAND_ADDR, READ_CYCLE_MASK); ++ do { ++ usleep_range(5, 10); ++ xgene_enet_rd_mcx_mac(pdata, MII_MGMT_INDICATORS_ADDR, &done); ++ } while ((done & BUSY_MASK) && wait--); ++ ++ if (done & BUSY_MASK) { ++ netdev_err(pdata->ndev, "MII_MGMT read failed\n"); ++ return -1; ++ } ++ ++ xgene_enet_rd_mcx_mac(pdata, MII_MGMT_STATUS_ADDR, &data); ++ xgene_enet_wr_mcx_mac(pdata, MII_MGMT_COMMAND_ADDR, 0); ++ ++ return data; ++} ++ ++void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata) ++{ ++ u32 addr0, addr1; ++ u8 *dev_addr = pdata->ndev->dev_addr; ++ ++ addr0 = (dev_addr[3] << 24) | (dev_addr[2] << 16) | ++ (dev_addr[1] << 8) | dev_addr[0]; ++ addr1 = (dev_addr[5] << 24) | (dev_addr[4] << 16); ++ addr1 |= pdata->phy_addr & 0xFFFF; ++ ++ xgene_enet_wr_mcx_mac(pdata, STATION_ADDR0_ADDR, addr0); ++ xgene_enet_wr_mcx_mac(pdata, STATION_ADDR1_ADDR, addr1); ++} ++ ++static int xgene_enet_ecc_init(struct xgene_enet_pdata *pdata) ++{ ++ struct net_device *ndev = pdata->ndev; ++ u32 data; ++ u8 wait = 10; ++ ++ xgene_enet_wr_diag_csr(pdata, ENET_CFG_MEM_RAM_SHUTDOWN_ADDR, 0x0); ++ do { ++ usleep_range(100, 110); ++ xgene_enet_rd_diag_csr(pdata, ENET_BLOCK_MEM_RDY_ADDR, &data); ++ } while ((data != 0xffffffff) && wait--); ++ ++ if (data != 0xffffffff) { ++ netdev_err(ndev, "Failed to release memory from shutdown\n"); ++ return -ENODEV; ++ } ++ ++ return 0; ++} ++ ++void xgene_gmac_reset(struct xgene_enet_pdata *pdata) ++{ ++ xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, SOFT_RESET1); ++ xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, 0); ++} ++ ++void xgene_gmac_init(struct xgene_enet_pdata *pdata, int speed) ++{ ++ u32 value, mc2; ++ u32 intf_ctl, rgmii; ++ u32 icm0, icm2; ++ ++ xgene_gmac_reset(pdata); ++ ++ xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG0_REG_0_ADDR, &icm0); ++ xgene_enet_rd_mcx_csr(pdata, ICM_CONFIG2_REG_0_ADDR, &icm2); ++ xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_2_ADDR, &mc2); ++ xgene_enet_rd_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, &intf_ctl); ++ xgene_enet_rd_csr(pdata, RGMII_REG_0_ADDR, &rgmii); ++ ++ switch (speed) { ++ case SPEED_10: ++ ENET_INTERFACE_MODE2_SET(&mc2, 1); ++ CFG_MACMODE_SET(&icm0, 0); ++ CFG_WAITASYNCRD_SET(&icm2, 500); ++ rgmii &= ~CFG_SPEED_1250; ++ break; ++ case SPEED_100: ++ ENET_INTERFACE_MODE2_SET(&mc2, 1); ++ intf_ctl |= ENET_LHD_MODE; ++ CFG_MACMODE_SET(&icm0, 1); ++ CFG_WAITASYNCRD_SET(&icm2, 80); ++ rgmii &= ~CFG_SPEED_1250; ++ break; ++ default: ++ ENET_INTERFACE_MODE2_SET(&mc2, 2); ++ intf_ctl |= ENET_GHD_MODE; ++ CFG_TXCLK_MUXSEL0_SET(&rgmii, 4); ++ xgene_enet_rd_csr(pdata, DEBUG_REG_ADDR, &value); ++ value |= CFG_BYPASS_UNISEC_TX | CFG_BYPASS_UNISEC_RX; ++ xgene_enet_wr_csr(pdata, DEBUG_REG_ADDR, value); ++ break; ++ } ++ ++ mc2 |= FULL_DUPLEX2; ++ xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_2_ADDR, mc2); ++ xgene_enet_wr_mcx_mac(pdata, INTERFACE_CONTROL_ADDR, intf_ctl); ++ ++ xgene_gmac_set_mac_addr(pdata); ++ ++ /* Adjust MDC clock frequency */ ++ xgene_enet_rd_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, &value); ++ MGMT_CLOCK_SEL_SET(&value, 7); ++ xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, value); ++ ++ /* Enable drop if bufpool not available */ ++ xgene_enet_rd_csr(pdata, RSIF_CONFIG_REG_ADDR, &value); ++ value |= CFG_RSIF_FPBUFF_TIMEOUT_EN; ++ xgene_enet_wr_csr(pdata, RSIF_CONFIG_REG_ADDR, value); ++ ++ /* Rtype should be copied from FP */ ++ xgene_enet_wr_csr(pdata, RSIF_RAM_DBG_REG0_ADDR, 0); ++ xgene_enet_wr_csr(pdata, RGMII_REG_0_ADDR, rgmii); ++ ++ /* Rx-Tx traffic resume */ ++ xgene_enet_wr_csr(pdata, CFG_LINK_AGGR_RESUME_0_ADDR, TX_PORT0); ++ ++ xgene_enet_wr_mcx_csr(pdata, ICM_CONFIG0_REG_0_ADDR, icm0); ++ xgene_enet_wr_mcx_csr(pdata, ICM_CONFIG2_REG_0_ADDR, icm2); ++ ++ xgene_enet_rd_mcx_csr(pdata, RX_DV_GATE_REG_0_ADDR, &value); ++ value &= ~TX_DV_GATE_EN0; ++ value &= ~RX_DV_GATE_EN0; ++ value |= RESUME_RX0; ++ xgene_enet_wr_mcx_csr(pdata, RX_DV_GATE_REG_0_ADDR, value); ++ ++ xgene_enet_wr_csr(pdata, CFG_BYPASS_ADDR, RESUME_TX); ++} ++ ++static void xgene_enet_config_ring_if_assoc(struct xgene_enet_pdata *pdata) ++{ ++ u32 val = 0xffffffff; ++ ++ xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIWQASSOC_ADDR, val); ++ xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIFPQASSOC_ADDR, val); ++ xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIQMLITEWQASSOC_ADDR, val); ++ xgene_enet_wr_ring_if(pdata, ENET_CFGSSQMIQMLITEFPQASSOC_ADDR, val); ++} ++ ++void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata, ++ u32 dst_ring_num, u16 bufpool_id) ++{ ++ u32 cb; ++ u32 fpsel; ++ ++ fpsel = xgene_enet_ring_bufnum(bufpool_id) - 0x20; ++ ++ xgene_enet_rd_csr(pdata, CLE_BYPASS_REG0_0_ADDR, &cb); ++ cb |= CFG_CLE_BYPASS_EN0; ++ CFG_CLE_IP_PROTOCOL0_SET(&cb, 3); ++ xgene_enet_wr_csr(pdata, CLE_BYPASS_REG0_0_ADDR, cb); ++ ++ xgene_enet_rd_csr(pdata, CLE_BYPASS_REG1_0_ADDR, &cb); ++ CFG_CLE_DSTQID0_SET(&cb, dst_ring_num); ++ CFG_CLE_FPSEL0_SET(&cb, fpsel); ++ xgene_enet_wr_csr(pdata, CLE_BYPASS_REG1_0_ADDR, cb); ++} ++ ++void xgene_gmac_rx_enable(struct xgene_enet_pdata *pdata) ++{ ++ u32 data; ++ ++ xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data); ++ xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data | RX_EN); ++} ++ ++void xgene_gmac_tx_enable(struct xgene_enet_pdata *pdata) ++{ ++ u32 data; ++ ++ xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data); ++ xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data | TX_EN); ++} ++ ++void xgene_gmac_rx_disable(struct xgene_enet_pdata *pdata) ++{ ++ u32 data; ++ ++ xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data); ++ xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data & ~RX_EN); ++} ++ ++void xgene_gmac_tx_disable(struct xgene_enet_pdata *pdata) ++{ ++ u32 data; ++ ++ xgene_enet_rd_mcx_mac(pdata, MAC_CONFIG_1_ADDR, &data); ++ xgene_enet_wr_mcx_mac(pdata, MAC_CONFIG_1_ADDR, data & ~TX_EN); ++} ++ ++void xgene_enet_reset(struct xgene_enet_pdata *pdata) ++{ ++ u32 val; ++ ++ clk_prepare_enable(pdata->clk); ++ clk_disable_unprepare(pdata->clk); ++ clk_prepare_enable(pdata->clk); ++ xgene_enet_ecc_init(pdata); ++ xgene_enet_config_ring_if_assoc(pdata); ++ ++ /* Enable auto-incr for scanning */ ++ xgene_enet_rd_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, &val); ++ val |= SCAN_AUTO_INCR; ++ MGMT_CLOCK_SEL_SET(&val, 1); ++ xgene_enet_wr_mcx_mac(pdata, MII_MGMT_CONFIG_ADDR, val); ++} ++ ++void xgene_gport_shutdown(struct xgene_enet_pdata *pdata) ++{ ++ clk_disable_unprepare(pdata->clk); ++} ++ ++static int xgene_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum) ++{ ++ struct xgene_enet_pdata *pdata = bus->priv; ++ u32 val; ++ ++ val = xgene_mii_phy_read(pdata, mii_id, regnum); ++ netdev_dbg(pdata->ndev, "mdio_rd: bus=%d reg=%d val=%x\n", ++ mii_id, regnum, val); ++ ++ return val; ++} ++ ++static int xgene_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum, ++ u16 val) ++{ ++ struct xgene_enet_pdata *pdata = bus->priv; ++ int ret; ++ ++ netdev_dbg(pdata->ndev, "mdio_wr: bus=%d reg=%d val=%x\n", ++ mii_id, regnum, val); ++ ret = xgene_mii_phy_write(pdata, mii_id, regnum, val); ++ ++ return ret; ++} ++ ++static void xgene_enet_adjust_link(struct net_device *ndev) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ struct phy_device *phydev = pdata->phy_dev; ++ ++ if (phydev->link) { ++ if (pdata->phy_speed != phydev->speed) { ++ xgene_gmac_init(pdata, phydev->speed); ++ xgene_gmac_rx_enable(pdata); ++ xgene_gmac_tx_enable(pdata); ++ pdata->phy_speed = phydev->speed; ++ phy_print_status(phydev); ++ } ++ } else { ++ xgene_gmac_rx_disable(pdata); ++ xgene_gmac_tx_disable(pdata); ++ pdata->phy_speed = SPEED_UNKNOWN; ++ phy_print_status(phydev); ++ } ++} ++ ++static int xgene_enet_phy_connect(struct net_device *ndev) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ struct device_node *phy_np; ++ struct phy_device *phy_dev; ++ struct device *dev = &pdata->pdev->dev; ++ ++ phy_np = of_parse_phandle(dev->of_node, "phy-handle", 0); ++ if (!phy_np) { ++ netdev_dbg(ndev, "No phy-handle found\n"); ++ return -ENODEV; ++ } ++ ++ phy_dev = of_phy_connect(ndev, phy_np, &xgene_enet_adjust_link, ++ 0, pdata->phy_mode); ++ if (!phy_dev) { ++ netdev_err(ndev, "Could not connect to PHY\n"); ++ return -ENODEV; ++ } ++ ++ pdata->phy_speed = SPEED_UNKNOWN; ++ phy_dev->supported &= ~SUPPORTED_10baseT_Half & ++ ~SUPPORTED_100baseT_Half & ++ ~SUPPORTED_1000baseT_Half; ++ phy_dev->advertising = phy_dev->supported; ++ pdata->phy_dev = phy_dev; ++ ++ return 0; ++} ++ ++int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata) ++{ ++ struct net_device *ndev = pdata->ndev; ++ struct device *dev = &pdata->pdev->dev; ++ struct device_node *child_np; ++ struct device_node *mdio_np = NULL; ++ struct mii_bus *mdio_bus; ++ int ret; ++ ++ for_each_child_of_node(dev->of_node, child_np) { ++ if (of_device_is_compatible(child_np, "apm,xgene-mdio")) { ++ mdio_np = child_np; ++ break; ++ } ++ } ++ ++ if (!mdio_np) { ++ netdev_dbg(ndev, "No mdio node in the dts\n"); ++ return -1; ++ } ++ ++ mdio_bus = mdiobus_alloc(); ++ if (!mdio_bus) ++ return -ENOMEM; ++ ++ mdio_bus->name = "APM X-Gene MDIO bus"; ++ mdio_bus->read = xgene_enet_mdio_read; ++ mdio_bus->write = xgene_enet_mdio_write; ++ snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%s", "xgene-mii", ++ ndev->name); ++ ++ mdio_bus->priv = pdata; ++ mdio_bus->parent = &ndev->dev; ++ ++ ret = of_mdiobus_register(mdio_bus, mdio_np); ++ if (ret) { ++ netdev_err(ndev, "Failed to register MDIO bus\n"); ++ goto err; ++ } ++ pdata->mdio_bus = mdio_bus; ++ ++ ret = xgene_enet_phy_connect(ndev); ++ if (ret) ++ goto err; ++ ++ return ret; ++ ++err: ++ mdiobus_free(mdio_bus); ++ ++ return ret; ++} ++ ++int xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata) ++{ ++ struct mii_bus *mdio_bus; ++ ++ mdio_bus = pdata->mdio_bus; ++ mdiobus_unregister(mdio_bus); ++ mdiobus_free(mdio_bus); ++ pdata->mdio_bus = NULL; ++ ++ return 0; ++} +diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h +new file mode 100644 +index 0000000..2041313 +--- /dev/null ++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_hw.h +@@ -0,0 +1,375 @@ ++/* Applied Micro X-Gene SoC Ethernet Driver ++ * ++ * Copyright (c) 2014, Applied Micro Circuits Corporation ++ * Authors: Iyappan Subramanian <isubramanian@apm.com> ++ * Ravi Patel <rapatel@apm.com> ++ * Keyur Chudgar <kchudgar@apm.com> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#ifndef __XGENE_ENET_HW_H__ ++#define __XGENE_ENET_HW_H__ ++ ++#include "xgene_enet_main.h" ++ ++struct xgene_enet_pdata; ++struct xgene_enet_stats; ++ ++/* clears and then set bits */ ++static inline void xgene_set_bits(u32 *dst, u32 val, u32 start, u32 len) ++{ ++ u32 end = start + len - 1; ++ u32 mask = GENMASK(end, start); ++ ++ *dst &= ~mask; ++ *dst |= (val << start) & mask; ++} ++ ++static inline u32 xgene_get_bits(u32 val, u32 start, u32 end) ++{ ++ return (val & GENMASK(end, start)) >> start; ++} ++ ++#define CSR_RING_ID 0x0008 ++#define OVERWRITE BIT(31) ++#define IS_BUFFER_POOL BIT(20) ++#define PREFETCH_BUF_EN BIT(21) ++#define CSR_RING_ID_BUF 0x000c ++#define CSR_RING_NE_INT_MODE 0x017c ++#define CSR_RING_CONFIG 0x006c ++#define CSR_RING_WR_BASE 0x0070 ++#define NUM_RING_CONFIG 5 ++#define BUFPOOL_MODE 3 ++#define RM3 3 ++#define INC_DEC_CMD_ADDR 0x002c ++#define UDP_HDR_SIZE 2 ++#define BUF_LEN_CODE_2K 0x5000 ++ ++#define CREATE_MASK(pos, len) GENMASK((pos)+(len)-1, (pos)) ++#define CREATE_MASK_ULL(pos, len) GENMASK_ULL((pos)+(len)-1, (pos)) ++ ++/* Empty slot soft signature */ ++#define EMPTY_SLOT_INDEX 1 ++#define EMPTY_SLOT ~0ULL ++ ++#define WORK_DESC_SIZE 32 ++#define BUFPOOL_DESC_SIZE 16 ++ ++#define RING_OWNER_MASK GENMASK(9, 6) ++#define RING_BUFNUM_MASK GENMASK(5, 0) ++ ++#define SELTHRSH_POS 3 ++#define SELTHRSH_LEN 3 ++#define RINGADDRL_POS 5 ++#define RINGADDRL_LEN 27 ++#define RINGADDRH_POS 0 ++#define RINGADDRH_LEN 6 ++#define RINGSIZE_POS 23 ++#define RINGSIZE_LEN 3 ++#define RINGTYPE_POS 19 ++#define RINGTYPE_LEN 2 ++#define RINGMODE_POS 20 ++#define RINGMODE_LEN 3 ++#define RECOMTIMEOUTL_POS 28 ++#define RECOMTIMEOUTL_LEN 3 ++#define RECOMTIMEOUTH_POS 0 ++#define RECOMTIMEOUTH_LEN 2 ++#define NUMMSGSINQ_POS 1 ++#define NUMMSGSINQ_LEN 16 ++#define ACCEPTLERR BIT(19) ++#define QCOHERENT BIT(4) ++#define RECOMBBUF BIT(27) ++ ++#define BLOCK_ETH_CSR_OFFSET 0x2000 ++#define BLOCK_ETH_RING_IF_OFFSET 0x9000 ++#define BLOCK_ETH_CLKRST_CSR_OFFSET 0xC000 ++#define BLOCK_ETH_DIAG_CSR_OFFSET 0xD000 ++ ++#define BLOCK_ETH_MAC_OFFSET 0x0000 ++#define BLOCK_ETH_STATS_OFFSET 0x0014 ++#define BLOCK_ETH_MAC_CSR_OFFSET 0x2800 ++ ++#define MAC_ADDR_REG_OFFSET 0x00 ++#define MAC_COMMAND_REG_OFFSET 0x04 ++#define MAC_WRITE_REG_OFFSET 0x08 ++#define MAC_READ_REG_OFFSET 0x0c ++#define MAC_COMMAND_DONE_REG_OFFSET 0x10 ++ ++#define STAT_ADDR_REG_OFFSET 0x00 ++#define STAT_COMMAND_REG_OFFSET 0x04 ++#define STAT_WRITE_REG_OFFSET 0x08 ++#define STAT_READ_REG_OFFSET 0x0c ++#define STAT_COMMAND_DONE_REG_OFFSET 0x10 ++ ++#define MII_MGMT_CONFIG_ADDR 0x20 ++#define MII_MGMT_COMMAND_ADDR 0x24 ++#define MII_MGMT_ADDRESS_ADDR 0x28 ++#define MII_MGMT_CONTROL_ADDR 0x2c ++#define MII_MGMT_STATUS_ADDR 0x30 ++#define MII_MGMT_INDICATORS_ADDR 0x34 ++ ++#define BUSY_MASK BIT(0) ++#define READ_CYCLE_MASK BIT(0) ++#define PHY_CONTROL_SET(dst, val) xgene_set_bits(dst, val, 0, 16) ++ ++#define ENET_SPARE_CFG_REG_ADDR 0x0750 ++#define RSIF_CONFIG_REG_ADDR 0x0010 ++#define RSIF_RAM_DBG_REG0_ADDR 0x0048 ++#define RGMII_REG_0_ADDR 0x07e0 ++#define CFG_LINK_AGGR_RESUME_0_ADDR 0x07c8 ++#define DEBUG_REG_ADDR 0x0700 ++#define CFG_BYPASS_ADDR 0x0294 ++#define CLE_BYPASS_REG0_0_ADDR 0x0490 ++#define CLE_BYPASS_REG1_0_ADDR 0x0494 ++#define CFG_RSIF_FPBUFF_TIMEOUT_EN BIT(31) ++#define RESUME_TX BIT(0) ++#define CFG_SPEED_1250 BIT(24) ++#define TX_PORT0 BIT(0) ++#define CFG_BYPASS_UNISEC_TX BIT(2) ++#define CFG_BYPASS_UNISEC_RX BIT(1) ++#define CFG_CLE_BYPASS_EN0 BIT(31) ++#define CFG_TXCLK_MUXSEL0_SET(dst, val) xgene_set_bits(dst, val, 29, 3) ++ ++#define CFG_CLE_IP_PROTOCOL0_SET(dst, val) xgene_set_bits(dst, val, 16, 2) ++#define CFG_CLE_DSTQID0_SET(dst, val) xgene_set_bits(dst, val, 0, 12) ++#define CFG_CLE_FPSEL0_SET(dst, val) xgene_set_bits(dst, val, 16, 4) ++#define CFG_MACMODE_SET(dst, val) xgene_set_bits(dst, val, 18, 2) ++#define CFG_WAITASYNCRD_SET(dst, val) xgene_set_bits(dst, val, 0, 16) ++#define ICM_CONFIG0_REG_0_ADDR 0x0400 ++#define ICM_CONFIG2_REG_0_ADDR 0x0410 ++#define RX_DV_GATE_REG_0_ADDR 0x05fc ++#define TX_DV_GATE_EN0 BIT(2) ++#define RX_DV_GATE_EN0 BIT(1) ++#define RESUME_RX0 BIT(0) ++#define ENET_CFGSSQMIWQASSOC_ADDR 0xe0 ++#define ENET_CFGSSQMIFPQASSOC_ADDR 0xdc ++#define ENET_CFGSSQMIQMLITEFPQASSOC_ADDR 0xf0 ++#define ENET_CFGSSQMIQMLITEWQASSOC_ADDR 0xf4 ++#define ENET_CFG_MEM_RAM_SHUTDOWN_ADDR 0x70 ++#define ENET_BLOCK_MEM_RDY_ADDR 0x74 ++#define MAC_CONFIG_1_ADDR 0x00 ++#define MAC_CONFIG_2_ADDR 0x04 ++#define MAX_FRAME_LEN_ADDR 0x10 ++#define INTERFACE_CONTROL_ADDR 0x38 ++#define STATION_ADDR0_ADDR 0x40 ++#define STATION_ADDR1_ADDR 0x44 ++#define PHY_ADDR_SET(dst, val) xgene_set_bits(dst, val, 8, 5) ++#define REG_ADDR_SET(dst, val) xgene_set_bits(dst, val, 0, 5) ++#define ENET_INTERFACE_MODE2_SET(dst, val) xgene_set_bits(dst, val, 8, 2) ++#define MGMT_CLOCK_SEL_SET(dst, val) xgene_set_bits(dst, val, 0, 3) ++#define SOFT_RESET1 BIT(31) ++#define TX_EN BIT(0) ++#define RX_EN BIT(2) ++#define ENET_LHD_MODE BIT(25) ++#define ENET_GHD_MODE BIT(26) ++#define FULL_DUPLEX2 BIT(0) ++#define SCAN_AUTO_INCR BIT(5) ++#define TBYT_ADDR 0x38 ++#define TPKT_ADDR 0x39 ++#define TDRP_ADDR 0x45 ++#define TFCS_ADDR 0x47 ++#define TUND_ADDR 0x4a ++ ++#define TSO_IPPROTO_TCP 1 ++#define FULL_DUPLEX 2 ++ ++#define USERINFO_POS 0 ++#define USERINFO_LEN 32 ++#define FPQNUM_POS 32 ++#define FPQNUM_LEN 12 ++#define LERR_POS 60 ++#define LERR_LEN 3 ++#define STASH_POS 52 ++#define STASH_LEN 2 ++#define BUFDATALEN_POS 48 ++#define BUFDATALEN_LEN 12 ++#define DATAADDR_POS 0 ++#define DATAADDR_LEN 42 ++#define COHERENT_POS 63 ++#define HENQNUM_POS 48 ++#define HENQNUM_LEN 12 ++#define TYPESEL_POS 44 ++#define TYPESEL_LEN 4 ++#define ETHHDR_POS 12 ++#define IC_POS 35 /* Insert CRC */ ++#define TCPHDR_POS 0 ++#define TCPHDR_LEN 6 ++#define IPHDR_POS 6 ++#define IPHDR_LEN 6 ++#define EC_POS 22 /* Enable checksum */ ++#define IS_POS 24 /* IP protocol select */ ++ ++#define DATAADDR_MASK CREATE_MASK_ULL(DATAADDR_POS, DATAADDR_LEN) ++#define BUFDATALEN_MASK CREATE_MASK_ULL(BUFDATALEN_POS, BUFDATALEN_LEN) ++#define USERINFO_MASK CREATE_MASK_ULL(USERINFO_POS, USERINFO_LEN) ++#define FPQNUM_MASK CREATE_MASK_ULL(FPQNUM_POS, FPQNUM_LEN) ++#define LERR_MASK CREATE_MASK_ULL(LERR_POS, LERR_LEN) ++#define STASHING_MASK CREATE_MASK_ULL(STASH_POS, STASH_LEN) ++#define COHERENT_MASK BIT_ULL(COHERENT_POS) ++#define HENQNUM_MASK CREATE_MASK_ULL(HENQNUM_POS, HENQNUM_LEN) ++#define TCPHDR_MASK CREATE_MASK(TCPHDR_POS, TCPHDR_LEN) ++#define IPHDR_MASK CREATE_MASK(IPHDR_POS, IPHDR_LEN) ++#define EC_MASK BIT(EC_POS) ++#define IS_MASK BIT(IS_POS) ++#define INSERT_CRC BIT_ULL(IC_POS) ++#define TYPE_ETH_WORK_MESSAGE BIT_ULL(44) ++ ++struct xgene_enet_raw_desc { ++ u64 m0; ++ u64 m1; ++ u64 m2; ++ u64 m3; ++}; ++ ++struct xgene_enet_raw_desc16 { ++ u64 m0; ++ u64 m1; ++}; ++ ++static inline void xgene_enet_cpu_to_le64(void *desc_ptr, int count) ++{ ++ u64 *desc = desc_ptr; ++ int i; ++ ++ for (i = 0; i < count; i++) ++ desc[i] = cpu_to_le64(desc[i]); ++} ++ ++static inline void xgene_enet_le64_to_cpu(void *desc_ptr, int count) ++{ ++ u64 *desc = desc_ptr; ++ int i; ++ ++ for (i = 0; i < count; i++) ++ desc[i] = le64_to_cpu(desc[i]); ++} ++ ++static inline void xgene_enet_desc16_to_le64(void *desc_ptr) ++{ ++ u64 *desc; ++ ++ desc = desc_ptr; ++ desc[1] = cpu_to_le64(desc[1]); ++} ++ ++static inline void xgene_enet_le64_to_desc16(void *desc_ptr) ++{ ++ u64 *desc; ++ ++ desc = desc_ptr; ++ desc[1] = le64_to_cpu(desc[1]); ++} ++ ++enum xgene_enet_ring_cfgsize { ++ RING_CFGSIZE_512B, ++ RING_CFGSIZE_2KB, ++ RING_CFGSIZE_16KB, ++ RING_CFGSIZE_64KB, ++ RING_CFGSIZE_512KB, ++ RING_CFGSIZE_INVALID ++}; ++ ++enum xgene_enet_ring_type { ++ RING_DISABLED, ++ RING_REGULAR, ++ RING_BUFPOOL ++}; ++ ++enum xgene_ring_owner { ++ RING_OWNER_ETH0, ++ RING_OWNER_CPU = 15, ++ RING_OWNER_INVALID ++}; ++ ++enum xgene_enet_ring_bufnum { ++ RING_BUFNUM_REGULAR = 0x0, ++ RING_BUFNUM_BUFPOOL = 0x20, ++ RING_BUFNUM_INVALID ++}; ++ ++enum xgene_enet_cmd { ++ XGENE_ENET_WR_CMD = BIT(31), ++ XGENE_ENET_RD_CMD = BIT(30) ++}; ++ ++enum xgene_enet_err_code { ++ HBF_READ_DATA = 3, ++ HBF_LL_READ = 4, ++ BAD_WORK_MSG = 6, ++ BUFPOOL_TIMEOUT = 15, ++ INGRESS_CRC = 16, ++ INGRESS_CHECKSUM = 17, ++ INGRESS_TRUNC_FRAME = 18, ++ INGRESS_PKT_LEN = 19, ++ INGRESS_PKT_UNDER = 20, ++ INGRESS_FIFO_OVERRUN = 21, ++ INGRESS_CHECKSUM_COMPUTE = 26, ++ ERR_CODE_INVALID ++}; ++ ++static inline enum xgene_ring_owner xgene_enet_ring_owner(u16 id) ++{ ++ return (id & RING_OWNER_MASK) >> 6; ++} ++ ++static inline u8 xgene_enet_ring_bufnum(u16 id) ++{ ++ return id & RING_BUFNUM_MASK; ++} ++ ++static inline bool xgene_enet_is_bufpool(u16 id) ++{ ++ return ((id & RING_BUFNUM_MASK) >= 0x20) ? true : false; ++} ++ ++static inline u16 xgene_enet_get_numslots(u16 id, u32 size) ++{ ++ bool is_bufpool = xgene_enet_is_bufpool(id); ++ ++ return (is_bufpool) ? size / BUFPOOL_DESC_SIZE : ++ size / WORK_DESC_SIZE; ++} ++ ++struct xgene_enet_desc_ring *xgene_enet_setup_ring( ++ struct xgene_enet_desc_ring *ring); ++void xgene_enet_clear_ring(struct xgene_enet_desc_ring *ring); ++ ++void xgene_set_tx_desc(struct xgene_enet_desc_ring *ring, ++ struct xgene_enet_raw_desc *raw_desc); ++void xgene_get_desc(struct xgene_enet_desc_ring *ring, ++ struct xgene_enet_raw_desc *raw_desc); ++void xgene_get_bufpool_desc(struct xgene_enet_desc_ring *ring, ++ struct xgene_enet_raw_desc16 *raw_desc); ++void xgene_enet_parse_error(struct xgene_enet_desc_ring *ring, ++ struct xgene_enet_pdata *pdata, ++ enum xgene_enet_err_code status); ++ ++void xgene_enet_reset(struct xgene_enet_pdata *priv); ++void xgene_gmac_reset(struct xgene_enet_pdata *priv); ++void xgene_gmac_init(struct xgene_enet_pdata *priv, int speed); ++void xgene_gmac_tx_enable(struct xgene_enet_pdata *priv); ++void xgene_gmac_rx_enable(struct xgene_enet_pdata *priv); ++void xgene_gmac_tx_disable(struct xgene_enet_pdata *priv); ++void xgene_gmac_rx_disable(struct xgene_enet_pdata *priv); ++void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata); ++void xgene_enet_cle_bypass(struct xgene_enet_pdata *pdata, ++ u32 dst_ring_num, u16 bufpool_id); ++void xgene_gport_shutdown(struct xgene_enet_pdata *priv); ++void xgene_gmac_get_tx_stats(struct xgene_enet_pdata *pdata); ++ ++int xgene_enet_mdio_config(struct xgene_enet_pdata *pdata); ++int xgene_enet_mdio_remove(struct xgene_enet_pdata *pdata); ++ ++#endif /* __XGENE_ENET_HW_H__ */ +diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +new file mode 100644 +index 0000000..756523a +--- /dev/null ++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +@@ -0,0 +1,962 @@ ++/* Applied Micro X-Gene SoC Ethernet Driver ++ * ++ * Copyright (c) 2014, Applied Micro Circuits Corporation ++ * Authors: Iyappan Subramanian <isubramanian@apm.com> ++ * Ravi Patel <rapatel@apm.com> ++ * Keyur Chudgar <kchudgar@apm.com> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#include "xgene_enet_main.h" ++#include "xgene_enet_hw.h" ++ ++static void xgene_enet_init_bufpool(struct xgene_enet_desc_ring *buf_pool) ++{ ++ struct xgene_enet_raw_desc16 *raw_desc; ++ int i; ++ ++ for (i = 0; i < buf_pool->slots; i++) { ++ raw_desc = &buf_pool->raw_desc16[i]; ++ ++ /* Hardware expects descriptor in little endian format */ ++ raw_desc->m0 = cpu_to_le64(i | ++ (((u64)buf_pool->dst_ring_num << FPQNUM_POS) & ++ FPQNUM_MASK) | STASHING_MASK); ++ } ++} ++ ++static struct device *ndev_to_dev(struct net_device *ndev) ++{ ++ return ndev->dev.parent; ++} ++ ++static int xgene_enet_refill_bufpool(struct xgene_enet_desc_ring *buf_pool, ++ u32 nbuf) ++{ ++ struct sk_buff *skb; ++ struct xgene_enet_raw_desc16 *raw_desc; ++ struct net_device *ndev; ++ struct device *dev; ++ dma_addr_t dma_addr; ++ u32 tail = buf_pool->tail; ++ u32 slots = buf_pool->slots - 1; ++ u16 bufdatalen, len; ++ int i; ++ ++ ndev = buf_pool->ndev; ++ dev = ndev_to_dev(buf_pool->ndev); ++ bufdatalen = BUF_LEN_CODE_2K | (SKB_BUFFER_SIZE & GENMASK(11, 0)); ++ len = XGENE_ENET_MAX_MTU; ++ ++ for (i = 0; i < nbuf; i++) { ++ raw_desc = &buf_pool->raw_desc16[tail]; ++ ++ skb = netdev_alloc_skb_ip_align(ndev, len); ++ if (unlikely(!skb)) ++ return -ENOMEM; ++ buf_pool->rx_skb[tail] = skb; ++ ++ dma_addr = dma_map_single(dev, skb->data, len, DMA_FROM_DEVICE); ++ if (dma_mapping_error(dev, dma_addr)) { ++ netdev_err(ndev, "DMA mapping error\n"); ++ dev_kfree_skb_any(skb); ++ return -EINVAL; ++ } ++ ++ raw_desc->m1 = cpu_to_le64((dma_addr & DATAADDR_MASK) | ++ (((u64)bufdatalen << BUFDATALEN_POS) & ++ BUFDATALEN_MASK) | COHERENT_MASK); ++ tail = (tail + 1) & slots; ++ } ++ ++ iowrite32(nbuf, buf_pool->cmd); ++ buf_pool->tail = tail; ++ ++ return 0; ++} ++ ++static u16 xgene_enet_dst_ring_num(struct xgene_enet_desc_ring *ring) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev); ++ ++ return ((u16)pdata->rm << 10) | ring->num; ++} ++ ++static u8 xgene_enet_hdr_len(const void *data) ++{ ++ const struct ethhdr *eth = data; ++ ++ return (eth->h_proto == htons(ETH_P_8021Q)) ? VLAN_ETH_HLEN : ETH_HLEN; ++} ++ ++static u32 xgene_enet_ring_len(struct xgene_enet_desc_ring *ring) ++{ ++ u32 *cmd_base = ring->cmd_base; ++ u32 ring_state, num_msgs; ++ ++ ring_state = ioread32(&cmd_base[1]); ++ num_msgs = ring_state & CREATE_MASK(NUMMSGSINQ_POS, NUMMSGSINQ_LEN); ++ ++ return num_msgs >> NUMMSGSINQ_POS; ++} ++ ++static void xgene_enet_delete_bufpool(struct xgene_enet_desc_ring *buf_pool) ++{ ++ struct xgene_enet_raw_desc16 *raw_desc; ++ u32 slots = buf_pool->slots - 1; ++ u32 tail = buf_pool->tail; ++ u32 userinfo; ++ int i, len; ++ ++ len = xgene_enet_ring_len(buf_pool); ++ for (i = 0; i < len; i++) { ++ tail = (tail - 1) & slots; ++ raw_desc = &buf_pool->raw_desc16[tail]; ++ ++ /* Hardware stores descriptor in little endian format */ ++ userinfo = le64_to_cpu(raw_desc->m0) & USERINFO_MASK; ++ dev_kfree_skb_any(buf_pool->rx_skb[userinfo]); ++ } ++ ++ iowrite32(-len, buf_pool->cmd); ++ buf_pool->tail = tail; ++} ++ ++static irqreturn_t xgene_enet_rx_irq(const int irq, void *data) ++{ ++ struct xgene_enet_desc_ring *rx_ring = data; ++ ++ if (napi_schedule_prep(&rx_ring->napi)) { ++ disable_irq_nosync(irq); ++ __napi_schedule(&rx_ring->napi); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static int xgene_enet_tx_completion(struct xgene_enet_desc_ring *cp_ring, ++ struct xgene_enet_raw_desc *raw_desc) ++{ ++ struct sk_buff *skb; ++ struct device *dev; ++ u16 skb_index; ++ u8 status; ++ int ret = 0; ++ ++ skb_index = raw_desc->m0 & USERINFO_MASK; ++ skb = cp_ring->cp_skb[skb_index]; ++ ++ dev = ndev_to_dev(cp_ring->ndev); ++ dma_unmap_single(dev, raw_desc->m1 & DATAADDR_MASK, ++ (raw_desc->m1 & BUFDATALEN_MASK) >> BUFDATALEN_POS, ++ DMA_TO_DEVICE); ++ ++ /* Checking for error */ ++ status = (raw_desc->m0 & LERR_MASK) >> LERR_POS; ++ if (unlikely(status > 2)) { ++ xgene_enet_parse_error(cp_ring, netdev_priv(cp_ring->ndev), ++ status); ++ ret = -1; ++ } ++ ++ if (likely(skb)) { ++ dev_kfree_skb_any(skb); ++ } else { ++ netdev_err(cp_ring->ndev, "completion skb is NULL\n"); ++ ret = -1; ++ } ++ ++ return ret; ++} ++ ++static u64 xgene_enet_work_msg(struct sk_buff *skb) ++{ ++ struct iphdr *iph; ++ u8 l3hlen, l4hlen = 0; ++ u8 csum_enable = 0; ++ u8 proto = 0; ++ u8 ethhdr; ++ u64 hopinfo; ++ ++ if (unlikely(skb->protocol != htons(ETH_P_IP)) && ++ unlikely(skb->protocol != htons(ETH_P_8021Q))) ++ goto out; ++ ++ if (unlikely(!(skb->dev->features & NETIF_F_IP_CSUM))) ++ goto out; ++ ++ iph = ip_hdr(skb); ++ if (unlikely(ip_is_fragment(iph))) ++ goto out; ++ ++ if (likely(iph->protocol == IPPROTO_TCP)) { ++ l4hlen = tcp_hdrlen(skb) >> 2; ++ csum_enable = 1; ++ proto = TSO_IPPROTO_TCP; ++ } else if (iph->protocol == IPPROTO_UDP) { ++ l4hlen = UDP_HDR_SIZE; ++ csum_enable = 1; ++ } ++out: ++ l3hlen = ip_hdrlen(skb) >> 2; ++ ethhdr = xgene_enet_hdr_len(skb->data); ++ hopinfo = (l4hlen & TCPHDR_MASK) | ++ ((l3hlen << IPHDR_POS) & IPHDR_MASK) | ++ (ethhdr << ETHHDR_POS) | ++ (csum_enable << EC_POS) | ++ (proto << IS_POS) | ++ INSERT_CRC | ++ TYPE_ETH_WORK_MESSAGE; ++ ++ return hopinfo; ++} ++ ++static int xgene_enet_setup_tx_desc(struct xgene_enet_desc_ring *tx_ring, ++ struct sk_buff *skb) ++{ ++ struct device *dev = ndev_to_dev(tx_ring->ndev); ++ struct xgene_enet_raw_desc *raw_desc; ++ dma_addr_t dma_addr; ++ u16 tail = tx_ring->tail; ++ u64 hopinfo; ++ ++ raw_desc = &tx_ring->raw_desc[tail]; ++ memset(raw_desc, 0, sizeof(struct xgene_enet_raw_desc)); ++ ++ dma_addr = dma_map_single(dev, skb->data, skb->len, DMA_TO_DEVICE); ++ if (dma_mapping_error(dev, dma_addr)) { ++ netdev_err(tx_ring->ndev, "DMA mapping error\n"); ++ return -EINVAL; ++ } ++ ++ /* Hardware expects descriptor in little endian format */ ++ raw_desc->m0 = cpu_to_le64(tail); ++ raw_desc->m1 = cpu_to_le64((dma_addr & DATAADDR_MASK) | ++ (((u64)skb->len << BUFDATALEN_POS) & BUFDATALEN_MASK) | ++ COHERENT_MASK); ++ hopinfo = xgene_enet_work_msg(skb); ++ raw_desc->m3 = cpu_to_le64( ++ (((u64)tx_ring->dst_ring_num << HENQNUM_POS) & ++ HENQNUM_MASK) | hopinfo); ++ tx_ring->cp_ring->cp_skb[tail] = skb; ++ ++ return 0; ++} ++ ++static netdev_tx_t xgene_enet_start_xmit(struct sk_buff *skb, ++ struct net_device *ndev) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ struct xgene_enet_desc_ring *tx_ring = pdata->tx_ring; ++ struct xgene_enet_desc_ring *cp_ring = tx_ring->cp_ring; ++ u32 tx_level, cq_level; ++ ++ tx_level = xgene_enet_ring_len(tx_ring); ++ cq_level = xgene_enet_ring_len(cp_ring); ++ if (unlikely(tx_level > pdata->tx_qcnt_hi || ++ cq_level > pdata->cp_qcnt_hi)) { ++ netif_stop_queue(ndev); ++ return NETDEV_TX_BUSY; ++ } ++ ++ if (xgene_enet_setup_tx_desc(tx_ring, skb)) { ++ dev_kfree_skb_any(skb); ++ return NETDEV_TX_OK; ++ } ++ ++ iowrite32(1, tx_ring->cmd); ++ skb_tx_timestamp(skb); ++ tx_ring->tail = (tx_ring->tail + 1) & (tx_ring->slots - 1); ++ ++ pdata->stats.tx_packets++; ++ pdata->stats.tx_bytes += skb->len; ++ ++ return NETDEV_TX_OK; ++} ++ ++static void xgene_enet_skip_csum(struct sk_buff *skb) ++{ ++ struct iphdr *iph = ip_hdr(skb); ++ ++ if (!ip_is_fragment(iph) || ++ (iph->protocol != IPPROTO_TCP && iph->protocol != IPPROTO_UDP)) { ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ } ++} ++ ++static int xgene_enet_rx_frame(struct xgene_enet_desc_ring *rx_ring, ++ struct xgene_enet_raw_desc *raw_desc) ++{ ++ struct net_device *ndev; ++ struct xgene_enet_pdata *pdata; ++ struct device *dev; ++ struct xgene_enet_desc_ring *buf_pool; ++ u32 datalen, skb_index; ++ struct sk_buff *skb; ++ u8 status; ++ int ret = 0; ++ ++ ndev = rx_ring->ndev; ++ pdata = netdev_priv(ndev); ++ dev = ndev_to_dev(rx_ring->ndev); ++ buf_pool = rx_ring->buf_pool; ++ ++ dma_unmap_single(dev, raw_desc->m1 & DATAADDR_MASK, XGENE_ENET_MAX_MTU, ++ DMA_FROM_DEVICE); ++ skb_index = raw_desc->m0 & USERINFO_MASK; ++ skb = buf_pool->rx_skb[skb_index]; ++ ++ /* checking for error */ ++ status = (raw_desc->m0 & LERR_MASK) >> LERR_POS; ++ if (unlikely(status > 2)) { ++ dev_kfree_skb_any(skb); ++ xgene_enet_parse_error(rx_ring, netdev_priv(rx_ring->ndev), ++ status); ++ pdata->stats.rx_dropped++; ++ ret = -1; ++ goto out; ++ } ++ ++ /* strip off CRC as HW isn't doing this */ ++ datalen = (raw_desc->m1 & BUFDATALEN_MASK) >> BUFDATALEN_POS; ++ datalen -= 4; ++ prefetch(skb->data - NET_IP_ALIGN); ++ skb_put(skb, datalen); ++ ++ skb_checksum_none_assert(skb); ++ skb->protocol = eth_type_trans(skb, ndev); ++ if (likely((ndev->features & NETIF_F_IP_CSUM) && ++ skb->protocol == htons(ETH_P_IP))) { ++ xgene_enet_skip_csum(skb); ++ } ++ ++ pdata->stats.rx_packets++; ++ pdata->stats.rx_bytes += datalen; ++ napi_gro_receive(&rx_ring->napi, skb); ++out: ++ if (--rx_ring->nbufpool == 0) { ++ ret = xgene_enet_refill_bufpool(buf_pool, NUM_BUFPOOL); ++ rx_ring->nbufpool = NUM_BUFPOOL; ++ } ++ ++ return ret; ++} ++ ++static bool is_rx_desc(struct xgene_enet_raw_desc *raw_desc) ++{ ++ /* Hardware stores descriptor in little endian format */ ++ raw_desc->m0 = le64_to_cpu(raw_desc->m0); ++ raw_desc->m1 = le64_to_cpu(raw_desc->m1); ++ return ((raw_desc->m0 & FPQNUM_MASK) >> FPQNUM_POS) ? true : false; ++} ++ ++static int xgene_enet_process_ring(struct xgene_enet_desc_ring *ring, ++ int budget) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ring->ndev); ++ struct xgene_enet_raw_desc *raw_desc; ++ u16 head = ring->head; ++ u16 slots = ring->slots - 1; ++ int ret, count = 0; ++ ++ do { ++ raw_desc = &ring->raw_desc[head]; ++ if (unlikely(((u64 *)raw_desc)[EMPTY_SLOT_INDEX] == EMPTY_SLOT)) ++ break; ++ ++ if (is_rx_desc(raw_desc)) ++ ret = xgene_enet_rx_frame(ring, raw_desc); ++ else ++ ret = xgene_enet_tx_completion(ring, raw_desc); ++ ((u64 *)raw_desc)[EMPTY_SLOT_INDEX] = EMPTY_SLOT; ++ ++ head = (head + 1) & slots; ++ count++; ++ ++ if (ret) ++ break; ++ } while (--budget); ++ ++ if (likely(count)) { ++ iowrite32(-count, ring->cmd); ++ ring->head = head; ++ ++ if (netif_queue_stopped(ring->ndev)) { ++ if (xgene_enet_ring_len(ring) < pdata->cp_qcnt_low) ++ netif_wake_queue(ring->ndev); ++ } ++ } ++ ++ return budget; ++} ++ ++static int xgene_enet_napi(struct napi_struct *napi, const int budget) ++{ ++ struct xgene_enet_desc_ring *ring; ++ int processed; ++ ++ ring = container_of(napi, struct xgene_enet_desc_ring, napi); ++ processed = xgene_enet_process_ring(ring, budget); ++ ++ if (processed != budget) { ++ napi_complete(napi); ++ enable_irq(ring->irq); ++ } ++ ++ return processed; ++} ++ ++static void xgene_enet_timeout(struct net_device *ndev) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ ++ xgene_gmac_reset(pdata); ++} ++ ++static int xgene_enet_register_irq(struct net_device *ndev) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ struct device *dev = ndev_to_dev(ndev); ++ int ret; ++ ++ ret = devm_request_irq(dev, pdata->rx_ring->irq, xgene_enet_rx_irq, ++ IRQF_SHARED, ndev->name, pdata->rx_ring); ++ if (ret) { ++ netdev_err(ndev, "rx%d interrupt request failed\n", ++ pdata->rx_ring->irq); ++ } ++ ++ return ret; ++} ++ ++static void xgene_enet_free_irq(struct net_device *ndev) ++{ ++ struct xgene_enet_pdata *pdata; ++ struct device *dev; ++ ++ pdata = netdev_priv(ndev); ++ dev = ndev_to_dev(ndev); ++ devm_free_irq(dev, pdata->rx_ring->irq, pdata->rx_ring); ++} ++ ++static int xgene_enet_open(struct net_device *ndev) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ int ret; ++ ++ xgene_gmac_tx_enable(pdata); ++ xgene_gmac_rx_enable(pdata); ++ ++ ret = xgene_enet_register_irq(ndev); ++ if (ret) ++ return ret; ++ napi_enable(&pdata->rx_ring->napi); ++ ++ if (pdata->phy_dev) ++ phy_start(pdata->phy_dev); ++ ++ netif_start_queue(ndev); ++ ++ return ret; ++} ++ ++static int xgene_enet_close(struct net_device *ndev) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ ++ netif_stop_queue(ndev); ++ ++ if (pdata->phy_dev) ++ phy_stop(pdata->phy_dev); ++ ++ napi_disable(&pdata->rx_ring->napi); ++ xgene_enet_free_irq(ndev); ++ xgene_enet_process_ring(pdata->rx_ring, -1); ++ ++ xgene_gmac_tx_disable(pdata); ++ xgene_gmac_rx_disable(pdata); ++ ++ return 0; ++} ++ ++static void xgene_enet_delete_ring(struct xgene_enet_desc_ring *ring) ++{ ++ struct xgene_enet_pdata *pdata; ++ struct device *dev; ++ ++ pdata = netdev_priv(ring->ndev); ++ dev = ndev_to_dev(ring->ndev); ++ ++ xgene_enet_clear_ring(ring); ++ dma_free_coherent(dev, ring->size, ring->desc_addr, ring->dma); ++} ++ ++static void xgene_enet_delete_desc_rings(struct xgene_enet_pdata *pdata) ++{ ++ struct xgene_enet_desc_ring *buf_pool; ++ ++ if (pdata->tx_ring) { ++ xgene_enet_delete_ring(pdata->tx_ring); ++ pdata->tx_ring = NULL; ++ } ++ ++ if (pdata->rx_ring) { ++ buf_pool = pdata->rx_ring->buf_pool; ++ xgene_enet_delete_bufpool(buf_pool); ++ xgene_enet_delete_ring(buf_pool); ++ xgene_enet_delete_ring(pdata->rx_ring); ++ pdata->rx_ring = NULL; ++ } ++} ++ ++static int xgene_enet_get_ring_size(struct device *dev, ++ enum xgene_enet_ring_cfgsize cfgsize) ++{ ++ int size = -EINVAL; ++ ++ switch (cfgsize) { ++ case RING_CFGSIZE_512B: ++ size = 0x200; ++ break; ++ case RING_CFGSIZE_2KB: ++ size = 0x800; ++ break; ++ case RING_CFGSIZE_16KB: ++ size = 0x4000; ++ break; ++ case RING_CFGSIZE_64KB: ++ size = 0x10000; ++ break; ++ case RING_CFGSIZE_512KB: ++ size = 0x80000; ++ break; ++ default: ++ dev_err(dev, "Unsupported cfg ring size %d\n", cfgsize); ++ break; ++ } ++ ++ return size; ++} ++ ++static void xgene_enet_free_desc_ring(struct xgene_enet_desc_ring *ring) ++{ ++ struct device *dev; ++ ++ if (!ring) ++ return; ++ ++ dev = ndev_to_dev(ring->ndev); ++ ++ if (ring->desc_addr) { ++ xgene_enet_clear_ring(ring); ++ dma_free_coherent(dev, ring->size, ring->desc_addr, ring->dma); ++ } ++ devm_kfree(dev, ring); ++} ++ ++static void xgene_enet_free_desc_rings(struct xgene_enet_pdata *pdata) ++{ ++ struct device *dev = &pdata->pdev->dev; ++ struct xgene_enet_desc_ring *ring; ++ ++ ring = pdata->tx_ring; ++ if (ring && ring->cp_ring && ring->cp_ring->cp_skb) ++ devm_kfree(dev, ring->cp_ring->cp_skb); ++ xgene_enet_free_desc_ring(ring); ++ ++ ring = pdata->rx_ring; ++ if (ring && ring->buf_pool && ring->buf_pool->rx_skb) ++ devm_kfree(dev, ring->buf_pool->rx_skb); ++ xgene_enet_free_desc_ring(ring->buf_pool); ++ xgene_enet_free_desc_ring(ring); ++} ++ ++static struct xgene_enet_desc_ring *xgene_enet_create_desc_ring( ++ struct net_device *ndev, u32 ring_num, ++ enum xgene_enet_ring_cfgsize cfgsize, u32 ring_id) ++{ ++ struct xgene_enet_desc_ring *ring; ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ struct device *dev = ndev_to_dev(ndev); ++ u32 size; ++ ++ ring = devm_kzalloc(dev, sizeof(struct xgene_enet_desc_ring), ++ GFP_KERNEL); ++ if (!ring) ++ return NULL; ++ ++ ring->ndev = ndev; ++ ring->num = ring_num; ++ ring->cfgsize = cfgsize; ++ ring->id = ring_id; ++ ++ size = xgene_enet_get_ring_size(dev, cfgsize); ++ ring->desc_addr = dma_zalloc_coherent(dev, size, &ring->dma, ++ GFP_KERNEL); ++ if (!ring->desc_addr) { ++ devm_kfree(dev, ring); ++ return NULL; ++ } ++ ring->size = size; ++ ++ ring->cmd_base = pdata->ring_cmd_addr + (ring->num << 6); ++ ring->cmd = ring->cmd_base + INC_DEC_CMD_ADDR; ++ pdata->rm = RM3; ++ ring = xgene_enet_setup_ring(ring); ++ netdev_dbg(ndev, "ring info: num=%d size=%d id=%d slots=%d\n", ++ ring->num, ring->size, ring->id, ring->slots); ++ ++ return ring; ++} ++ ++static u16 xgene_enet_get_ring_id(enum xgene_ring_owner owner, u8 bufnum) ++{ ++ return (owner << 6) | (bufnum & GENMASK(5, 0)); ++} ++ ++static int xgene_enet_create_desc_rings(struct net_device *ndev) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ struct device *dev = ndev_to_dev(ndev); ++ struct xgene_enet_desc_ring *rx_ring, *tx_ring, *cp_ring; ++ struct xgene_enet_desc_ring *buf_pool = NULL; ++ u8 cpu_bufnum = 0, eth_bufnum = 0; ++ u8 bp_bufnum = 0x20; ++ u16 ring_id, ring_num = 0; ++ int ret; ++ ++ /* allocate rx descriptor ring */ ++ ring_id = xgene_enet_get_ring_id(RING_OWNER_CPU, cpu_bufnum++); ++ rx_ring = xgene_enet_create_desc_ring(ndev, ring_num++, ++ RING_CFGSIZE_16KB, ring_id); ++ if (!rx_ring) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ /* allocate buffer pool for receiving packets */ ++ ring_id = xgene_enet_get_ring_id(RING_OWNER_ETH0, bp_bufnum++); ++ buf_pool = xgene_enet_create_desc_ring(ndev, ring_num++, ++ RING_CFGSIZE_2KB, ring_id); ++ if (!buf_pool) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ rx_ring->nbufpool = NUM_BUFPOOL; ++ rx_ring->buf_pool = buf_pool; ++ rx_ring->irq = pdata->rx_irq; ++ buf_pool->rx_skb = devm_kcalloc(dev, buf_pool->slots, ++ sizeof(struct sk_buff *), GFP_KERNEL); ++ if (!buf_pool->rx_skb) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ buf_pool->dst_ring_num = xgene_enet_dst_ring_num(buf_pool); ++ rx_ring->buf_pool = buf_pool; ++ pdata->rx_ring = rx_ring; ++ ++ /* allocate tx descriptor ring */ ++ ring_id = xgene_enet_get_ring_id(RING_OWNER_ETH0, eth_bufnum++); ++ tx_ring = xgene_enet_create_desc_ring(ndev, ring_num++, ++ RING_CFGSIZE_16KB, ring_id); ++ if (!tx_ring) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ pdata->tx_ring = tx_ring; ++ ++ cp_ring = pdata->rx_ring; ++ cp_ring->cp_skb = devm_kcalloc(dev, tx_ring->slots, ++ sizeof(struct sk_buff *), GFP_KERNEL); ++ if (!cp_ring->cp_skb) { ++ ret = -ENOMEM; ++ goto err; ++ } ++ pdata->tx_ring->cp_ring = cp_ring; ++ pdata->tx_ring->dst_ring_num = xgene_enet_dst_ring_num(cp_ring); ++ ++ pdata->tx_qcnt_hi = pdata->tx_ring->slots / 2; ++ pdata->cp_qcnt_hi = pdata->rx_ring->slots / 2; ++ pdata->cp_qcnt_low = pdata->cp_qcnt_hi / 2; ++ ++ return 0; ++ ++err: ++ xgene_enet_free_desc_rings(pdata); ++ return ret; ++} ++ ++static struct rtnl_link_stats64 *xgene_enet_get_stats64( ++ struct net_device *ndev, ++ struct rtnl_link_stats64 *storage) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ struct rtnl_link_stats64 *stats = &pdata->stats; ++ ++ spin_lock(&pdata->stats_lock); ++ stats->rx_errors += stats->rx_length_errors + ++ stats->rx_crc_errors + ++ stats->rx_frame_errors + ++ stats->rx_fifo_errors; ++ memcpy(storage, &pdata->stats, sizeof(struct rtnl_link_stats64)); ++ spin_unlock(&pdata->stats_lock); ++ ++ return storage; ++} ++ ++static int xgene_enet_set_mac_address(struct net_device *ndev, void *addr) ++{ ++ struct xgene_enet_pdata *pdata = netdev_priv(ndev); ++ int ret; ++ ++ ret = eth_mac_addr(ndev, addr); ++ if (ret) ++ return ret; ++ xgene_gmac_set_mac_addr(pdata); ++ ++ return ret; ++} ++ ++static const struct net_device_ops xgene_ndev_ops = { ++ .ndo_open = xgene_enet_open, ++ .ndo_stop = xgene_enet_close, ++ .ndo_start_xmit = xgene_enet_start_xmit, ++ .ndo_tx_timeout = xgene_enet_timeout, ++ .ndo_get_stats64 = xgene_enet_get_stats64, ++ .ndo_change_mtu = eth_change_mtu, ++ .ndo_set_mac_address = xgene_enet_set_mac_address, ++}; ++ ++static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata) ++{ ++ struct platform_device *pdev; ++ struct net_device *ndev; ++ struct device *dev; ++ struct resource *res; ++ void *base_addr; ++ const char *mac; ++ int ret; ++ ++ pdev = pdata->pdev; ++ dev = &pdev->dev; ++ ndev = pdata->ndev; ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "enet_csr"); ++ if (!res) { ++ dev_err(dev, "Resource enet_csr not defined\n"); ++ return -ENODEV; ++ } ++ pdata->base_addr = devm_ioremap_resource(dev, res); ++ if (IS_ERR(pdata->base_addr)) { ++ dev_err(dev, "Unable to retrieve ENET Port CSR region\n"); ++ return PTR_ERR(pdata->base_addr); ++ } ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ring_csr"); ++ if (!res) { ++ dev_err(dev, "Resource ring_csr not defined\n"); ++ return -ENODEV; ++ } ++ pdata->ring_csr_addr = devm_ioremap_resource(dev, res); ++ if (IS_ERR(pdata->ring_csr_addr)) { ++ dev_err(dev, "Unable to retrieve ENET Ring CSR region\n"); ++ return PTR_ERR(pdata->ring_csr_addr); ++ } ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ring_cmd"); ++ if (!res) { ++ dev_err(dev, "Resource ring_cmd not defined\n"); ++ return -ENODEV; ++ } ++ pdata->ring_cmd_addr = devm_ioremap_resource(dev, res); ++ if (IS_ERR(pdata->ring_cmd_addr)) { ++ dev_err(dev, "Unable to retrieve ENET Ring command region\n"); ++ return PTR_ERR(pdata->ring_cmd_addr); ++ } ++ ++ ret = platform_get_irq(pdev, 0); ++ if (ret <= 0) { ++ dev_err(dev, "Unable to get ENET Rx IRQ\n"); ++ ret = ret ? : -ENXIO; ++ return ret; ++ } ++ pdata->rx_irq = ret; ++ ++ mac = of_get_mac_address(dev->of_node); ++ if (mac) ++ memcpy(ndev->dev_addr, mac, ndev->addr_len); ++ else ++ eth_hw_addr_random(ndev); ++ memcpy(ndev->perm_addr, ndev->dev_addr, ndev->addr_len); ++ ++ pdata->phy_mode = of_get_phy_mode(pdev->dev.of_node); ++ if (pdata->phy_mode < 0) { ++ dev_err(dev, "Incorrect phy-connection-type in DTS\n"); ++ return -EINVAL; ++ } ++ ++ pdata->clk = devm_clk_get(&pdev->dev, NULL); ++ ret = IS_ERR(pdata->clk); ++ if (IS_ERR(pdata->clk)) { ++ dev_err(&pdev->dev, "can't get clock\n"); ++ ret = PTR_ERR(pdata->clk); ++ return ret; ++ } ++ ++ base_addr = pdata->base_addr; ++ pdata->eth_csr_addr = base_addr + BLOCK_ETH_CSR_OFFSET; ++ pdata->eth_ring_if_addr = base_addr + BLOCK_ETH_RING_IF_OFFSET; ++ pdata->eth_diag_csr_addr = base_addr + BLOCK_ETH_DIAG_CSR_OFFSET; ++ pdata->mcx_mac_addr = base_addr + BLOCK_ETH_MAC_OFFSET; ++ pdata->mcx_stats_addr = base_addr + BLOCK_ETH_STATS_OFFSET; ++ pdata->mcx_mac_csr_addr = base_addr + BLOCK_ETH_MAC_CSR_OFFSET; ++ pdata->rx_buff_cnt = NUM_PKT_BUF; ++ ++ return ret; ++} ++ ++static int xgene_enet_init_hw(struct xgene_enet_pdata *pdata) ++{ ++ struct net_device *ndev = pdata->ndev; ++ struct xgene_enet_desc_ring *buf_pool; ++ u16 dst_ring_num; ++ int ret; ++ ++ xgene_gmac_tx_disable(pdata); ++ xgene_gmac_rx_disable(pdata); ++ ++ ret = xgene_enet_create_desc_rings(ndev); ++ if (ret) { ++ netdev_err(ndev, "Error in ring configuration\n"); ++ return ret; ++ } ++ ++ /* setup buffer pool */ ++ buf_pool = pdata->rx_ring->buf_pool; ++ xgene_enet_init_bufpool(buf_pool); ++ ret = xgene_enet_refill_bufpool(buf_pool, pdata->rx_buff_cnt); ++ if (ret) ++ return ret; ++ ++ dst_ring_num = xgene_enet_dst_ring_num(pdata->rx_ring); ++ xgene_enet_cle_bypass(pdata, dst_ring_num, buf_pool->id); ++ ++ return ret; ++} ++ ++static int xgene_enet_probe(struct platform_device *pdev) ++{ ++ struct net_device *ndev; ++ struct xgene_enet_pdata *pdata; ++ struct device *dev = &pdev->dev; ++ struct napi_struct *napi; ++ int ret; ++ ++ ndev = alloc_etherdev(sizeof(struct xgene_enet_pdata)); ++ if (!ndev) ++ return -ENOMEM; ++ ++ pdata = netdev_priv(ndev); ++ ++ pdata->pdev = pdev; ++ pdata->ndev = ndev; ++ SET_NETDEV_DEV(ndev, dev); ++ platform_set_drvdata(pdev, pdata); ++ ndev->netdev_ops = &xgene_ndev_ops; ++ xgene_enet_set_ethtool_ops(ndev); ++ ndev->features |= NETIF_F_IP_CSUM | ++ NETIF_F_GSO | ++ NETIF_F_GRO; ++ ++ ret = xgene_enet_get_resources(pdata); ++ if (ret) ++ goto err; ++ ++ xgene_enet_reset(pdata); ++ xgene_gmac_init(pdata, SPEED_1000); ++ ++ spin_lock_init(&pdata->stats_lock); ++ ret = register_netdev(ndev); ++ if (ret) { ++ netdev_err(ndev, "Failed to register netdev\n"); ++ goto err; ++ } ++ ++ ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); ++ if (ret) { ++ netdev_err(ndev, "No usable DMA configuration\n"); ++ goto err; ++ } ++ ++ ret = xgene_enet_init_hw(pdata); ++ if (ret) ++ goto err; ++ ++ napi = &pdata->rx_ring->napi; ++ netif_napi_add(ndev, napi, xgene_enet_napi, NAPI_POLL_WEIGHT); ++ ret = xgene_enet_mdio_config(pdata); ++ ++ return ret; ++err: ++ free_netdev(ndev); ++ return ret; ++} ++ ++static int xgene_enet_remove(struct platform_device *pdev) ++{ ++ struct xgene_enet_pdata *pdata; ++ struct net_device *ndev; ++ ++ pdata = platform_get_drvdata(pdev); ++ ndev = pdata->ndev; ++ ++ xgene_gmac_rx_disable(pdata); ++ xgene_gmac_tx_disable(pdata); ++ ++ netif_napi_del(&pdata->rx_ring->napi); ++ xgene_enet_mdio_remove(pdata); ++ xgene_enet_delete_desc_rings(pdata); ++ unregister_netdev(ndev); ++ xgene_gport_shutdown(pdata); ++ free_netdev(ndev); ++ ++ return 0; ++} ++ ++static struct of_device_id xgene_enet_match[] = { ++ {.compatible = "apm,xgene-enet",}, ++ {}, ++}; ++ ++MODULE_DEVICE_TABLE(of, xgene_enet_match); ++ ++static struct platform_driver xgene_enet_driver = { ++ .driver = { ++ .name = "xgene-enet", ++ .owner = THIS_MODULE, ++ .of_match_table = xgene_enet_match, ++ }, ++ .probe = xgene_enet_probe, ++ .remove = xgene_enet_remove, ++}; ++ ++module_platform_driver(xgene_enet_driver); ++ ++MODULE_DESCRIPTION("APM X-Gene SoC Ethernet driver"); ++MODULE_VERSION(XGENE_DRV_VERSION); ++MODULE_AUTHOR("Keyur Chudgar <kchudgar@apm.com>"); ++MODULE_LICENSE("GPL"); +diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.h b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h +new file mode 100644 +index 0000000..f4f7e4a +--- /dev/null ++++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.h +@@ -0,0 +1,107 @@ ++/* Applied Micro X-Gene SoC Ethernet Driver ++ * ++ * Copyright (c) 2014, Applied Micro Circuits Corporation ++ * Authors: Iyappan Subramanian <isubramanian@apm.com> ++ * Ravi Patel <rapatel@apm.com> ++ * Keyur Chudgar <kchudgar@apm.com> ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#ifndef __XGENE_ENET_MAIN_H__ ++#define __XGENE_ENET_MAIN_H__ ++ ++#include <linux/clk.h> ++#include <linux/of_platform.h> ++#include <linux/of_net.h> ++#include <linux/of_mdio.h> ++#include <linux/module.h> ++#include <net/ip.h> ++#include <linux/prefetch.h> ++#include <linux/if_vlan.h> ++#include <linux/phy.h> ++#include "xgene_enet_hw.h" ++ ++#define XGENE_DRV_VERSION "v1.0" ++#define XGENE_ENET_MAX_MTU 1536 ++#define SKB_BUFFER_SIZE (XGENE_ENET_MAX_MTU - NET_IP_ALIGN) ++#define NUM_PKT_BUF 64 ++#define NUM_BUFPOOL 32 ++ ++/* software context of a descriptor ring */ ++struct xgene_enet_desc_ring { ++ struct net_device *ndev; ++ u16 id; ++ u16 num; ++ u16 head; ++ u16 tail; ++ u16 slots; ++ u16 irq; ++ u32 size; ++ u32 state[NUM_RING_CONFIG]; ++ void __iomem *cmd_base; ++ void __iomem *cmd; ++ dma_addr_t dma; ++ u16 dst_ring_num; ++ u8 nbufpool; ++ struct sk_buff *(*rx_skb); ++ struct sk_buff *(*cp_skb); ++ enum xgene_enet_ring_cfgsize cfgsize; ++ struct xgene_enet_desc_ring *cp_ring; ++ struct xgene_enet_desc_ring *buf_pool; ++ struct napi_struct napi; ++ union { ++ void *desc_addr; ++ struct xgene_enet_raw_desc *raw_desc; ++ struct xgene_enet_raw_desc16 *raw_desc16; ++ }; ++}; ++ ++/* ethernet private data */ ++struct xgene_enet_pdata { ++ struct net_device *ndev; ++ struct mii_bus *mdio_bus; ++ struct phy_device *phy_dev; ++ int phy_speed; ++ struct clk *clk; ++ struct platform_device *pdev; ++ struct xgene_enet_desc_ring *tx_ring; ++ struct xgene_enet_desc_ring *rx_ring; ++ char *dev_name; ++ u32 rx_buff_cnt; ++ u32 tx_qcnt_hi; ++ u32 cp_qcnt_hi; ++ u32 cp_qcnt_low; ++ u32 rx_irq; ++ void __iomem *eth_csr_addr; ++ void __iomem *eth_ring_if_addr; ++ void __iomem *eth_diag_csr_addr; ++ void __iomem *mcx_mac_addr; ++ void __iomem *mcx_stats_addr; ++ void __iomem *mcx_mac_csr_addr; ++ void __iomem *base_addr; ++ void __iomem *ring_csr_addr; ++ void __iomem *ring_cmd_addr; ++ u32 phy_addr; ++ int phy_mode; ++ u32 speed; ++ u16 rm; ++ struct rtnl_link_stats64 stats; ++ /* statistics lock */ ++ spinlock_t stats_lock; ++}; ++ ++void xgene_enet_set_ethtool_ops(struct net_device *netdev); ++ ++#endif /* __XGENE_ENET_MAIN_H__ */ +diff --git a/drivers/of/address.c b/drivers/of/address.c +index 5edfcb0..cbbaed2 100644 +--- a/drivers/of/address.c ++++ b/drivers/of/address.c +@@ -5,6 +5,7 @@ + #include <linux/module.h> + #include <linux/of_address.h> + #include <linux/pci_regs.h> ++#include <linux/slab.h> + #include <linux/string.h> + + /* Max address size we deal with */ +@@ -601,12 +602,72 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, + } + EXPORT_SYMBOL(of_get_address); + ++struct io_range { ++ struct list_head list; ++ phys_addr_t start; ++ resource_size_t size; ++}; ++ ++static LIST_HEAD(io_range_list); ++ ++/* ++ * Record the PCI IO range (expressed as CPU physical address + size). ++ * Return a negative value if an error has occured, zero otherwise ++ */ ++int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size) ++{ ++#ifdef PCI_IOBASE ++ struct io_range *res; ++ resource_size_t allocated_size = 0; ++ ++ /* check if the range hasn't been previously recorded */ ++ list_for_each_entry(res, &io_range_list, list) { ++ if (addr >= res->start && addr + size <= res->start + size) ++ return 0; ++ allocated_size += res->size; ++ } ++ ++ /* range not registed yet, check for available space */ ++ if (allocated_size + size - 1 > IO_SPACE_LIMIT) ++ return -E2BIG; ++ ++ /* add the range to the list */ ++ res = kzalloc(sizeof(*res), GFP_KERNEL); ++ if (!res) ++ return -ENOMEM; ++ ++ res->start = addr; ++ res->size = size; ++ ++ list_add_tail(&res->list, &io_range_list); ++ ++ return 0; ++#else ++ return -EINVAL; ++#endif ++} ++ + unsigned long __weak pci_address_to_pio(phys_addr_t address) + { ++#ifdef PCI_IOBASE ++ struct io_range *res; ++ resource_size_t offset = 0; ++ ++ list_for_each_entry(res, &io_range_list, list) { ++ if (address >= res->start && ++ address < res->start + res->size) { ++ return res->start - address + offset; ++ } ++ offset += res->size; ++ } ++ ++ return (unsigned long)-1; ++#else + if (address > IO_SPACE_LIMIT) + return (unsigned long)-1; + + return (unsigned long) address; ++#endif + } + + static int __of_address_to_resource(struct device_node *dev, +@@ -811,3 +872,50 @@ bool of_dma_is_coherent(struct device_node *np) + return false; + } + EXPORT_SYMBOL_GPL(of_dma_is_coherent); ++ ++/* ++ * of_pci_range_to_resource - Create a resource from an of_pci_range ++ * @range: the PCI range that describes the resource ++ * @np: device node where the range belongs to ++ * @res: pointer to a valid resource that will be updated to ++ * reflect the values contained in the range. ++ * ++ * Returns EINVAL if the range cannot be converted to resource. ++ * ++ * Note that if the range is an IO range, the resource will be converted ++ * using pci_address_to_pio() which can fail if it is called too early or ++ * if the range cannot be matched to any host bridge IO space (our case here). ++ * To guard against that we try to register the IO range first. ++ * If that fails we know that pci_address_to_pio() will do too. ++ */ ++int of_pci_range_to_resource(struct of_pci_range *range, ++ struct device_node *np, struct resource *res) ++{ ++ int err; ++ res->flags = range->flags; ++ res->parent = res->child = res->sibling = NULL; ++ res->name = np->full_name; ++ ++ if (res->flags & IORESOURCE_IO) { ++ unsigned long port = -1; ++ err = pci_register_io_range(range->cpu_addr, range->size); ++ if (err) ++ goto invalid_range; ++ port = pci_address_to_pio(range->cpu_addr); ++ if (port == (unsigned long)-1) { ++ err = -EINVAL; ++ goto invalid_range; ++ } ++ res->start = port; ++ } else { ++ res->start = range->cpu_addr; ++ } ++ res->end = res->start + range->size - 1; ++ return 0; ++ ++invalid_range: ++ res->start = (resource_size_t)OF_BAD_ADDR; ++ res->end = (resource_size_t)OF_BAD_ADDR; ++ return err; ++} ++ +diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c +index 8481996..e81402a 100644 +--- a/drivers/of/of_pci.c ++++ b/drivers/of/of_pci.c +@@ -1,6 +1,7 @@ + #include <linux/kernel.h> + #include <linux/export.h> + #include <linux/of.h> ++#include <linux/of_address.h> + #include <linux/of_pci.h> + + static inline int __of_pci_pci_compare(struct device_node *node, +@@ -89,6 +90,141 @@ int of_pci_parse_bus_range(struct device_node *node, struct resource *res) + } + EXPORT_SYMBOL_GPL(of_pci_parse_bus_range); + ++/** ++ * pci_host_bridge_of_get_ranges - Parse PCI host bridge resources from DT ++ * @dev: device node of the host bridge having the range property ++ * @resources: list where the range of resources will be added after DT parsing ++ * @io_base: pointer to a variable that will contain the physical address for ++ * the start of the I/O range. ++ * ++ * It is the callers job to free the @resources list if an error is returned. ++ * ++ * This function will parse the "ranges" property of a PCI host bridge device ++ * node and setup the resource mapping based on its content. It is expected ++ * that the property conforms with the Power ePAPR document. ++ * ++ * Each architecture is then offered the chance of applying their own ++ * filtering of pci_host_bridge_windows based on their own restrictions by ++ * calling pcibios_fixup_bridge_ranges(). The filtered list of windows ++ * can then be used when creating a pci_host_bridge structure. ++ */ ++static int pci_host_bridge_of_get_ranges(struct device_node *dev, ++ struct list_head *resources, resource_size_t *io_base) ++{ ++ struct resource *res; ++ struct of_pci_range range; ++ struct of_pci_range_parser parser; ++ int err; ++ ++ pr_info("PCI host bridge %s ranges:\n", dev->full_name); ++ ++ /* Check for ranges property */ ++ err = of_pci_range_parser_init(&parser, dev); ++ if (err) ++ return err; ++ ++ pr_debug("Parsing ranges property...\n"); ++ for_each_of_pci_range(&parser, &range) { ++ /* Read next ranges element */ ++ pr_debug("pci_space: 0x%08x pci_addr:0x%016llx cpu_addr:0x%016llx size:0x%016llx\n", ++ range.pci_space, range.pci_addr, range.cpu_addr, range.size); ++ ++ /* ++ * If we failed translation or got a zero-sized region ++ * then skip this range ++ */ ++ if (range.cpu_addr == OF_BAD_ADDR || range.size == 0) ++ continue; ++ ++ res = kzalloc(sizeof(struct resource), GFP_KERNEL); ++ if (!res) ++ return -ENOMEM; ++ ++ err = of_pci_range_to_resource(&range, dev, res); ++ if (err) ++ return err; ++ ++ if (resource_type(res) == IORESOURCE_IO) ++ *io_base = range.cpu_addr; ++ ++ pci_add_resource_offset(resources, res, ++ res->start - range.pci_addr); ++ } ++ ++ /* Apply architecture specific fixups for the ranges */ ++ return pcibios_fixup_bridge_ranges(resources); ++} ++ ++static atomic_t domain_nr = ATOMIC_INIT(-1); ++ ++/** ++ * of_create_pci_host_bridge - Create a PCI host bridge structure using ++ * information passed in the DT. ++ * @parent: device owning this host bridge ++ * @ops: pci_ops associated with the host controller ++ * @host_data: opaque data structure used by the host controller. ++ * ++ * returns a pointer to the newly created pci_host_bridge structure, or ++ * NULL if the call failed. ++ * ++ * This function will try to obtain the host bridge domain number by ++ * using of_alias_get_id() call with "pci-domain" as a stem. If that ++ * fails, a local allocator will be used that will put each host bridge ++ * in a new domain. ++ */ ++struct pci_host_bridge * ++of_create_pci_host_bridge(struct device *parent, struct pci_ops *ops, void *host_data) ++{ ++ int err, domain, busno; ++ struct resource *bus_range; ++ struct pci_bus *root_bus; ++ struct pci_host_bridge *bridge; ++ resource_size_t io_base = 0; ++ LIST_HEAD(res); ++ ++ bus_range = kzalloc(sizeof(*bus_range), GFP_KERNEL); ++ if (!bus_range) ++ return ERR_PTR(-ENOMEM); ++ ++ domain = of_alias_get_id(parent->of_node, "pci-domain"); ++ if (domain == -ENODEV) ++ domain = atomic_inc_return(&domain_nr); ++ ++ err = of_pci_parse_bus_range(parent->of_node, bus_range); ++ if (err) { ++ dev_info(parent, "No bus range for %s, using default [0-255]\n", ++ parent->of_node->full_name); ++ bus_range->start = 0; ++ bus_range->end = 255; ++ bus_range->flags = IORESOURCE_BUS; ++ } ++ busno = bus_range->start; ++ pci_add_resource(&res, bus_range); ++ ++ /* now parse the rest of host bridge bus ranges */ ++ err = pci_host_bridge_of_get_ranges(parent->of_node, &res, &io_base); ++ if (err) ++ goto err_create; ++ ++ /* then create the root bus */ ++ root_bus = pci_create_root_bus_in_domain(parent, domain, busno, ++ ops, host_data, &res); ++ if (IS_ERR(root_bus)) { ++ err = PTR_ERR(root_bus); ++ goto err_create; ++ } ++ ++ bridge = to_pci_host_bridge(root_bus->bridge); ++ bridge->io_base = io_base; ++ ++ return bridge; ++ ++err_create: ++ pci_free_resource_list(&res); ++ return ERR_PTR(err); ++} ++EXPORT_SYMBOL_GPL(of_create_pci_host_bridge); ++ + #ifdef CONFIG_PCI_MSI + + static LIST_HEAD(of_pci_msi_chip_list); +diff --git a/drivers/pci/host-bridge.c b/drivers/pci/host-bridge.c +index 0e5f3c9..54ceafd 100644 +--- a/drivers/pci/host-bridge.c ++++ b/drivers/pci/host-bridge.c +@@ -16,12 +16,13 @@ static struct pci_bus *find_pci_root_bus(struct pci_bus *bus) + return bus; + } + +-static struct pci_host_bridge *find_pci_host_bridge(struct pci_bus *bus) ++struct pci_host_bridge *find_pci_host_bridge(struct pci_bus *bus) + { + struct pci_bus *root_bus = find_pci_root_bus(bus); + + return to_pci_host_bridge(root_bus->bridge); + } ++EXPORT_SYMBOL_GPL(find_pci_host_bridge); + + void pci_set_host_bridge_release(struct pci_host_bridge *bridge, + void (*release_fn)(struct pci_host_bridge *), +@@ -82,3 +83,18 @@ void pcibios_bus_to_resource(struct pci_bus *bus, struct resource *res, + res->end = region->end + offset; + } + EXPORT_SYMBOL(pcibios_bus_to_resource); ++ ++/** ++ * Simple version of the platform specific code for filtering the list ++ * of resources obtained from the ranges declaration in DT. ++ * ++ * Platforms can override this function in order to impose stronger ++ * constraints onto the list of resources that a host bridge can use. ++ * The filtered list will then be used to create a root bus and associate ++ * it with the host bridge. ++ * ++ */ ++int __weak pcibios_fixup_bridge_ranges(struct list_head *resources) ++{ ++ return 0; ++} +diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig +index 21df477..3b988a2 100644 +--- a/drivers/pci/host/Kconfig ++++ b/drivers/pci/host/Kconfig +@@ -46,4 +46,14 @@ config PCI_HOST_GENERIC + Say Y here if you want to support a simple generic PCI host + controller, such as the one emulated by kvmtool. + ++config PCI_XGENE ++ bool "X-Gene PCIe controller" ++ depends on ARCH_XGENE ++ depends on OF ++ select PCIEPORTBUS ++ help ++ Say Y here if you want internal PCI support on APM X-Gene SoC. ++ There are 5 internal PCIe ports available. Each port is GEN3 capable ++ and have varied lanes from x1 to x8. ++ + endmenu +diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile +index 611ba4b..0801606 100644 +--- a/drivers/pci/host/Makefile ++++ b/drivers/pci/host/Makefile +@@ -6,3 +6,4 @@ obj-$(CONFIG_PCI_TEGRA) += pci-tegra.o + obj-$(CONFIG_PCI_RCAR_GEN2) += pci-rcar-gen2.o + obj-$(CONFIG_PCI_RCAR_GEN2_PCIE) += pcie-rcar.o + obj-$(CONFIG_PCI_HOST_GENERIC) += pci-host-generic.o ++obj-$(CONFIG_PCI_XGENE) += pci-xgene.o +diff --git a/drivers/pci/host/pci-xgene.c b/drivers/pci/host/pci-xgene.c +new file mode 100644 +index 0000000..7bf4ac7 +--- /dev/null ++++ b/drivers/pci/host/pci-xgene.c +@@ -0,0 +1,725 @@ ++/** ++ * APM X-Gene PCIe Driver ++ * ++ * Copyright (c) 2013 Applied Micro Circuits Corporation. ++ * ++ * Author: Tanmay Inamdar <tinamdar@apm.com>. ++ * ++ * This program is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by the ++ * Free Software Foundation; either version 2 of the License, or (at your ++ * option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ */ ++#include <linux/clk-private.h> ++#include <linux/delay.h> ++#include <linux/io.h> ++#include <linux/jiffies.h> ++#include <linux/memblock.h> ++#include <linux/module.h> ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++#include <linux/of_pci.h> ++#include <linux/pci.h> ++#include <linux/platform_device.h> ++#include <linux/slab.h> ++ ++#define PCIECORE_LTSSM 0x4c ++#define PCIECORE_CTLANDSTATUS 0x50 ++#define INTXSTATUSMASK 0x6c ++#define PIM1_1L 0x80 ++#define IBAR2 0x98 ++#define IR2MSK 0x9c ++#define PIM2_1L 0xa0 ++#define IBAR3L 0xb4 ++#define IR3MSKL 0xbc ++#define PIM3_1L 0xc4 ++#define OMR1BARL 0x100 ++#define OMR2BARL 0x118 ++#define OMR3BARL 0x130 ++#define CFGBARL 0x154 ++#define CFGBARH 0x158 ++#define CFGCTL 0x15c ++#define RTDID 0x160 ++#define BRIDGE_CFG_0 0x2000 ++#define BRIDGE_CFG_1 0x2004 ++#define BRIDGE_CFG_4 0x2010 ++#define BRIDGE_CFG_32 0x2030 ++#define BRIDGE_CFG_14 0x2038 ++#define BRIDGE_CTRL_1 0x2204 ++#define BRIDGE_CTRL_2 0x2208 ++#define BRIDGE_CTRL_5 0x2214 ++#define BRIDGE_STATUS_0 0x2600 ++#define MEM_RAM_SHUTDOWN 0xd070 ++#define BLOCK_MEM_RDY 0xd074 ++ ++#define DEVICE_PORT_TYPE_MASK 0x03c00000 ++#define PM_FORCE_RP_MODE_MASK 0x00000400 ++#define SWITCH_PORT_MODE_MASK 0x00000800 ++#define CLASS_CODE_MASK 0xffffff00 ++#define LINK_UP_MASK 0x00000100 ++#define AER_OPTIONAL_ERROR_EN 0xffc00000 ++#define XGENE_PCIE_DEV_CTRL 0x2f0f ++#define AXI_EP_CFG_ACCESS 0x10000 ++#define ENABLE_ASPM 0x08000000 ++#define XGENE_PORT_TYPE_RC 0x05000000 ++#define BLOCK_MEM_RDY_VAL 0xFFFFFFFF ++#define EN_COHERENCY 0xF0000000 ++#define EN_REG 0x00000001 ++#define OB_LO_IO 0x00000002 ++#define XGENE_PCIE_VENDORID 0xE008 ++#define XGENE_PCIE_DEVICEID 0xE004 ++#define XGENE_PCIE_ECC_TIMEOUT 10 /* ms */ ++#define XGENE_LTSSM_DETECT_WAIT 20 /* ms */ ++#define XGENE_LTSSM_L0_WAIT 4 /* ms */ ++#define SZ_1T (SZ_1G*1024ULL) ++#define PIPE_PHY_RATE_RD(src) ((0xc000 & (u32)(src)) >> 0xe) ++ ++struct xgene_pcie_port { ++ struct device_node *node; ++ struct device *dev; ++ struct clk *clk; ++ void __iomem *csr_base; ++ void __iomem *cfg_base; ++ u8 link_up; ++}; ++ ++static inline u32 pcie_bar_low_val(u32 addr, u32 flags) ++{ ++ return (addr & PCI_BASE_ADDRESS_MEM_MASK) | flags; ++} ++ ++/* PCIE Configuration Out/In */ ++static inline void xgene_pcie_cfg_out32(void __iomem *addr, int offset, u32 val) ++{ ++ writel(val, addr + offset); ++} ++ ++static inline void xgene_pcie_cfg_out16(void __iomem *addr, int offset, u16 val) ++{ ++ u32 val32 = readl(addr + (offset & ~0x3)); ++ ++ switch (offset & 0x3) { ++ case 2: ++ val32 &= ~0xFFFF0000; ++ val32 |= (u32)val << 16; ++ break; ++ case 0: ++ default: ++ val32 &= ~0xFFFF; ++ val32 |= val; ++ break; ++ } ++ writel(val32, addr + (offset & ~0x3)); ++} ++ ++static inline void xgene_pcie_cfg_out8(void __iomem *addr, int offset, u8 val) ++{ ++ u32 val32 = readl(addr + (offset & ~0x3)); ++ ++ switch (offset & 0x3) { ++ case 0: ++ val32 &= ~0xFF; ++ val32 |= val; ++ break; ++ case 1: ++ val32 &= ~0xFF00; ++ val32 |= (u32)val << 8; ++ break; ++ case 2: ++ val32 &= ~0xFF0000; ++ val32 |= (u32)val << 16; ++ break; ++ case 3: ++ default: ++ val32 &= ~0xFF000000; ++ val32 |= (u32)val << 24; ++ break; ++ } ++ writel(val32, addr + (offset & ~0x3)); ++} ++ ++static inline void xgene_pcie_cfg_in32(void __iomem *addr, int offset, u32 *val) ++{ ++ *val = readl(addr + offset); ++} ++ ++static inline void ++xgene_pcie_cfg_in16(void __iomem *addr, int offset, u32 *val) ++{ ++ *val = readl(addr + (offset & ~0x3)); ++ ++ switch (offset & 0x3) { ++ case 2: ++ *val >>= 16; ++ break; ++ } ++ ++ *val &= 0xFFFF; ++} ++ ++static inline void ++xgene_pcie_cfg_in8(void __iomem *addr, int offset, u32 *val) ++{ ++ *val = readl(addr + (offset & ~0x3)); ++ ++ switch (offset & 0x3) { ++ case 3: ++ *val = *val >> 24; ++ break; ++ case 2: ++ *val = *val >> 16; ++ break; ++ case 1: ++ *val = *val >> 8; ++ break; ++ } ++ *val &= 0xFF; ++} ++ ++/* When the address bit [17:16] is 2'b01, the Configuration access will be ++ * treated as Type 1 and it will be forwarded to external PCIe device. ++ */ ++static void __iomem *xgene_pcie_get_cfg_base(struct pci_bus *bus) ++{ ++ struct xgene_pcie_port *port = bus->sysdata; ++ ++ if (bus->number >= (bus->primary + 1)) ++ return port->cfg_base + AXI_EP_CFG_ACCESS; ++ ++ return port->cfg_base; ++} ++ ++/* For Configuration request, RTDID register is used as Bus Number, ++ * Device Number and Function number of the header fields. ++ */ ++static void xgene_pcie_set_rtdid_reg(struct pci_bus *bus, uint devfn) ++{ ++ struct xgene_pcie_port *port = bus->sysdata; ++ unsigned int b, d, f; ++ u32 rtdid_val = 0; ++ ++ b = bus->number; ++ d = PCI_SLOT(devfn); ++ f = PCI_FUNC(devfn); ++ ++ if (!pci_is_root_bus(bus)) ++ rtdid_val = (b << 8) | (d << 3) | f; ++ ++ writel(rtdid_val, port->csr_base + RTDID); ++ /* read the register back to ensure flush */ ++ readl(port->csr_base + RTDID); ++} ++ ++static int xgene_pcie_read_config(struct pci_bus *bus, unsigned int devfn, ++ int offset, int len, u32 *val) ++{ ++ struct xgene_pcie_port *port = bus->sysdata; ++ void __iomem *addr; ++ ++ if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ xgene_pcie_set_rtdid_reg(bus, devfn); ++ addr = xgene_pcie_get_cfg_base(bus); ++ switch (len) { ++ case 1: ++ xgene_pcie_cfg_in8(addr, offset, val); ++ break; ++ case 2: ++ xgene_pcie_cfg_in16(addr, offset, val); ++ break; ++ default: ++ xgene_pcie_cfg_in32(addr, offset, val); ++ break; ++ } ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int xgene_pcie_write_config(struct pci_bus *bus, unsigned int devfn, ++ int offset, int len, u32 val) ++{ ++ struct xgene_pcie_port *port = bus->sysdata; ++ void __iomem *addr; ++ ++ if ((pci_is_root_bus(bus) && devfn != 0) || !port->link_up) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ xgene_pcie_set_rtdid_reg(bus, devfn); ++ addr = xgene_pcie_get_cfg_base(bus); ++ switch (len) { ++ case 1: ++ xgene_pcie_cfg_out8(addr, offset, (u8)val); ++ break; ++ case 2: ++ xgene_pcie_cfg_out16(addr, offset, (u16)val); ++ break; ++ default: ++ xgene_pcie_cfg_out32(addr, offset, val); ++ break; ++ } ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static struct pci_ops xgene_pcie_ops = { ++ .read = xgene_pcie_read_config, ++ .write = xgene_pcie_write_config ++}; ++ ++static void xgene_pcie_program_core(void __iomem *csr_base) ++{ ++ u32 val; ++ ++ val = readl(csr_base + BRIDGE_CFG_0); ++ val |= AER_OPTIONAL_ERROR_EN; ++ writel(val, csr_base + BRIDGE_CFG_0); ++ writel(0x0, csr_base + INTXSTATUSMASK); ++ val = readl(csr_base + BRIDGE_CTRL_1); ++ val = (val & ~0xffff) | XGENE_PCIE_DEV_CTRL; ++ writel(val, csr_base + BRIDGE_CTRL_1); ++} ++ ++static u64 xgene_pcie_set_ib_mask(void __iomem *csr_base, u32 addr, ++ u32 flags, u64 size) ++{ ++ u64 mask = (~(size - 1) & PCI_BASE_ADDRESS_MEM_MASK) | flags; ++ u32 val32 = 0; ++ u32 val; ++ ++ val32 = readl(csr_base + addr); ++ val = (val32 & 0x0000ffff) | (lower_32_bits(mask) << 16); ++ writel(val, csr_base + addr); ++ ++ val32 = readl(csr_base + addr + 0x04); ++ val = (val32 & 0xffff0000) | (lower_32_bits(mask) >> 16); ++ writel(val, csr_base + addr + 0x04); ++ ++ val32 = readl(csr_base + addr + 0x04); ++ val = (val32 & 0x0000ffff) | (upper_32_bits(mask) << 16); ++ writel(val, csr_base + addr + 0x04); ++ ++ val32 = readl(csr_base + addr + 0x08); ++ val = (val32 & 0xffff0000) | (upper_32_bits(mask) >> 16); ++ writel(val, csr_base + addr + 0x08); ++ ++ return mask; ++} ++ ++static void xgene_pcie_poll_linkup(struct xgene_pcie_port *port, ++ u32 *lanes, u32 *speed) ++{ ++ void __iomem *csr_base = port->csr_base; ++ ulong timeout; ++ u32 val32; ++ ++ /* ++ * A component enters the LTSSM Detect state within ++ * 20ms of the end of fundamental core reset. ++ */ ++ msleep(XGENE_LTSSM_DETECT_WAIT); ++ port->link_up = 0; ++ timeout = jiffies + msecs_to_jiffies(XGENE_LTSSM_L0_WAIT); ++ while (time_before(jiffies, timeout)) { ++ val32 = readl(csr_base + PCIECORE_CTLANDSTATUS); ++ if (val32 & LINK_UP_MASK) { ++ port->link_up = 1; ++ *speed = PIPE_PHY_RATE_RD(val32); ++ val32 = readl(csr_base + BRIDGE_STATUS_0); ++ *lanes = val32 >> 26; ++ break; ++ } ++ msleep(1); ++ } ++} ++ ++static void xgene_pcie_setup_root_complex(struct xgene_pcie_port *port) ++{ ++ void __iomem *csr_base = port->csr_base; ++ u32 val; ++ ++ val = (XGENE_PCIE_DEVICEID << 16) | XGENE_PCIE_VENDORID; ++ writel(val, csr_base + BRIDGE_CFG_0); ++ ++ val = readl(csr_base + BRIDGE_CFG_1); ++ val &= ~CLASS_CODE_MASK; ++ val |= PCI_CLASS_BRIDGE_PCI << 16; ++ writel(val, csr_base + BRIDGE_CFG_1); ++ ++ val = readl(csr_base + BRIDGE_CFG_14); ++ val |= SWITCH_PORT_MODE_MASK; ++ val &= ~PM_FORCE_RP_MODE_MASK; ++ writel(val, csr_base + BRIDGE_CFG_14); ++ ++ val = readl(csr_base + BRIDGE_CTRL_5); ++ val &= ~DEVICE_PORT_TYPE_MASK; ++ val |= XGENE_PORT_TYPE_RC; ++ writel(val, csr_base + BRIDGE_CTRL_5); ++ ++ val = readl(csr_base + BRIDGE_CTRL_2); ++ val |= ENABLE_ASPM; ++ writel(val, csr_base + BRIDGE_CTRL_2); ++ ++ val = readl(csr_base + BRIDGE_CFG_32); ++ writel(val | (1 << 19), csr_base + BRIDGE_CFG_32); ++} ++ ++/* Return 0 on success */ ++static int xgene_pcie_init_ecc(struct xgene_pcie_port *port) ++{ ++ void __iomem *csr_base = port->csr_base; ++ ulong timeout; ++ u32 val; ++ ++ val = readl(csr_base + MEM_RAM_SHUTDOWN); ++ if (!val) ++ return 0; ++ writel(0x0, csr_base + MEM_RAM_SHUTDOWN); ++ timeout = jiffies + msecs_to_jiffies(XGENE_PCIE_ECC_TIMEOUT); ++ while (time_before(jiffies, timeout)) { ++ val = readl(csr_base + BLOCK_MEM_RDY); ++ if (val == BLOCK_MEM_RDY_VAL) ++ return 0; ++ msleep(1); ++ } ++ ++ return 1; ++} ++ ++static int xgene_pcie_init_port(struct xgene_pcie_port *port) ++{ ++ int rc; ++ ++ port->clk = clk_get(port->dev, NULL); ++ if (IS_ERR(port->clk)) { ++ dev_err(port->dev, "clock not available\n"); ++ return -ENODEV; ++ } ++ ++ rc = clk_prepare_enable(port->clk); ++ if (rc) { ++ dev_err(port->dev, "clock enable failed\n"); ++ return rc; ++ } ++ ++ rc = xgene_pcie_init_ecc(port); ++ if (rc) { ++ dev_err(port->dev, "memory init failed\n"); ++ return rc; ++ } ++ ++ return 0; ++} ++ ++static void xgene_pcie_fixup_bridge(struct pci_dev *dev) ++{ ++ int i; ++ ++ /* Hide the PCI host BARs from the kernel as their content doesn't ++ * fit well in the resource management ++ */ ++ for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { ++ dev->resource[i].start = dev->resource[i].end = 0; ++ dev->resource[i].flags = 0; ++ } ++ dev_info(&dev->dev, "Hiding X-Gene pci host bridge resources %s\n", ++ pci_name(dev)); ++} ++DECLARE_PCI_FIXUP_HEADER(XGENE_PCIE_VENDORID, XGENE_PCIE_DEVICEID, ++ xgene_pcie_fixup_bridge); ++ ++static int xgene_pcie_map_reg(struct xgene_pcie_port *port, ++ struct platform_device *pdev, u64 *cfg_addr) ++{ ++ struct resource *res; ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr"); ++ port->csr_base = devm_ioremap_resource(port->dev, res); ++ if (IS_ERR(port->csr_base)) ++ return PTR_ERR(port->csr_base); ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg"); ++ port->cfg_base = devm_ioremap_resource(port->dev, res); ++ if (IS_ERR(port->cfg_base)) ++ return PTR_ERR(port->cfg_base); ++ *cfg_addr = res->start; ++ ++ return 0; ++} ++ ++static void xgene_pcie_setup_ob_reg(struct xgene_pcie_port *port, ++ struct resource *res, u32 offset, u64 addr) ++{ ++ void __iomem *base = port->csr_base + offset; ++ resource_size_t size = resource_size(res); ++ u64 restype = resource_type(res); ++ u64 cpu_addr, pci_addr; ++ u64 mask = 0; ++ u32 min_size; ++ u32 flag = EN_REG; ++ ++ if (restype == IORESOURCE_MEM) { ++ cpu_addr = res->start; ++ pci_addr = addr; ++ min_size = SZ_128M; ++ } else { ++ cpu_addr = addr; ++ pci_addr = res->start; ++ min_size = 128; ++ flag |= OB_LO_IO; ++ } ++ if (size >= min_size) ++ mask = ~(size - 1) | flag; ++ else ++ dev_warn(port->dev, "res size 0x%llx less than minimum 0x%x\n", ++ (u64)size, min_size); ++ writel(lower_32_bits(cpu_addr), base); ++ writel(upper_32_bits(cpu_addr), base + 0x04); ++ writel(lower_32_bits(mask), base + 0x08); ++ writel(upper_32_bits(mask), base + 0x0c); ++ writel(lower_32_bits(pci_addr), base + 0x10); ++ writel(upper_32_bits(pci_addr), base + 0x14); ++} ++ ++static void xgene_pcie_setup_cfg_reg(void __iomem *csr_base, u64 addr) ++{ ++ writel(lower_32_bits(addr), csr_base + CFGBARL); ++ writel(upper_32_bits(addr), csr_base + CFGBARH); ++ writel(EN_REG, csr_base + CFGCTL); ++} ++ ++static int xgene_pcie_map_ranges(struct xgene_pcie_port *port, ++ struct pci_host_bridge *bridge, ++ u64 cfg_addr) ++{ ++ struct device *dev = port->dev; ++ struct pci_host_bridge_window *window; ++ int ret; ++ ++ list_for_each_entry(window, &bridge->windows, list) { ++ struct resource *res = window->res; ++ u64 restype = resource_type(res); ++ dev_dbg(port->dev, "0x%08lx 0x%016llx...0x%016llx\n", ++ res->flags, res->start, res->end); ++ ++ switch (restype) { ++ case IORESOURCE_IO: ++ xgene_pcie_setup_ob_reg(port, res, OMR2BARL, ++ bridge->io_base); ++ ret = pci_remap_iospace(res, bridge->io_base); ++ if (ret < 0) ++ return ret; ++ break; ++ case IORESOURCE_MEM: ++ xgene_pcie_setup_ob_reg(port, res, OMR3BARL, ++ res->start - window->offset); ++ break; ++ case IORESOURCE_BUS: ++ break; ++ default: ++ dev_err(dev, "invalid io resource!"); ++ return -EINVAL; ++ } ++ } ++ xgene_pcie_setup_cfg_reg(port->csr_base, cfg_addr); ++ return 0; ++} ++ ++static void xgene_pcie_setup_pims(void *addr, u64 pim, u64 size) ++{ ++ writel(lower_32_bits(pim), addr); ++ writel(upper_32_bits(pim) | EN_COHERENCY, addr + 0x04); ++ writel(lower_32_bits(size), addr + 0x10); ++ writel(upper_32_bits(size), addr + 0x14); ++} ++ ++/* ++ * X-Gene PCIe support maximum 3 inbound memory regions ++ * This function helps to select a region based on size of region ++ */ ++static int xgene_pcie_select_ib_reg(u8 *ib_reg_mask, u64 size) ++{ ++ if ((size > 4) && (size < SZ_16M) && !(*ib_reg_mask & (1 << 1))) { ++ *ib_reg_mask |= (1 << 1); ++ return 1; ++ } ++ ++ if ((size > SZ_1K) && (size < SZ_1T) && !(*ib_reg_mask & (1 << 0))) { ++ *ib_reg_mask |= (1 << 0); ++ return 0; ++ } ++ ++ if ((size > SZ_1M) && (size < SZ_1T) && !(*ib_reg_mask & (1 << 2))) { ++ *ib_reg_mask |= (1 << 2); ++ return 2; ++ } ++ return -EINVAL; ++} ++ ++static void xgene_pcie_setup_ib_reg(struct xgene_pcie_port *port, ++ struct of_pci_range *range, u8 *ib_reg_mask) ++{ ++ void __iomem *csr_base = port->csr_base; ++ void __iomem *cfg_base = port->cfg_base; ++ void *bar_addr; ++ void *pim_addr; ++ u64 restype = range->flags & IORESOURCE_TYPE_BITS; ++ u64 cpu_addr = range->cpu_addr; ++ u64 pci_addr = range->pci_addr; ++ u64 size = range->size; ++ u64 mask = ~(size - 1) | EN_REG; ++ u32 flags = PCI_BASE_ADDRESS_MEM_TYPE_64; ++ u32 bar_low; ++ int region; ++ ++ region = xgene_pcie_select_ib_reg(ib_reg_mask, range->size); ++ if (region < 0) { ++ dev_warn(port->dev, "invalid pcie dma-range config\n"); ++ return; ++ } ++ ++ if (restype == PCI_BASE_ADDRESS_MEM_PREFETCH) ++ flags |= PCI_BASE_ADDRESS_MEM_PREFETCH; ++ ++ bar_low = pcie_bar_low_val((u32)cpu_addr, flags); ++ switch (region) { ++ case 0: ++ xgene_pcie_set_ib_mask(csr_base, BRIDGE_CFG_4, flags, size); ++ bar_addr = cfg_base + PCI_BASE_ADDRESS_0; ++ writel(bar_low, bar_addr); ++ writel(upper_32_bits(cpu_addr), bar_addr + 0x4); ++ pim_addr = csr_base + PIM1_1L; ++ break; ++ case 1: ++ bar_addr = csr_base + IBAR2; ++ writel(bar_low, bar_addr); ++ writel(lower_32_bits(mask), csr_base + IR2MSK); ++ pim_addr = csr_base + PIM2_1L; ++ break; ++ case 2: ++ bar_addr = csr_base + IBAR3L; ++ writel(bar_low, bar_addr); ++ writel(upper_32_bits(cpu_addr), bar_addr + 0x4); ++ writel(lower_32_bits(mask), csr_base + IR3MSKL); ++ writel(upper_32_bits(mask), csr_base + IR3MSKL + 0x4); ++ pim_addr = csr_base + PIM3_1L; ++ break; ++ } ++ ++ xgene_pcie_setup_pims(pim_addr, pci_addr, size); ++} ++ ++static int pci_dma_range_parser_init(struct of_pci_range_parser *parser, ++ struct device_node *node) ++{ ++ const int na = 3, ns = 2; ++ int rlen; ++ ++ parser->node = node; ++ parser->pna = of_n_addr_cells(node); ++ parser->np = parser->pna + na + ns; ++ ++ parser->range = of_get_property(node, "dma-ranges", &rlen); ++ if (!parser->range) ++ return -ENOENT; ++ ++ parser->end = parser->range + rlen / sizeof(__be32); ++ return 0; ++} ++ ++static int xgene_pcie_parse_map_dma_ranges(struct xgene_pcie_port *port) ++{ ++ struct device_node *np = port->node; ++ struct of_pci_range range; ++ struct of_pci_range_parser parser; ++ struct device *dev = port->dev; ++ u8 ib_reg_mask = 0; ++ ++ if (pci_dma_range_parser_init(&parser, np)) { ++ dev_err(dev, "missing dma-ranges property\n"); ++ return -EINVAL; ++ } ++ ++ /* Get the dma-ranges from DT */ ++ for_each_of_pci_range(&parser, &range) { ++ u64 end = range.cpu_addr + range.size - 1; ++ dev_dbg(port->dev, "0x%08x 0x%016llx..0x%016llx -> 0x%016llx\n", ++ range.flags, range.cpu_addr, end, range.pci_addr); ++ xgene_pcie_setup_ib_reg(port, &range, &ib_reg_mask); ++ } ++ return 0; ++} ++ ++static int xgene_pcie_probe_bridge(struct platform_device *pdev) ++{ ++ struct device_node *np = of_node_get(pdev->dev.of_node); ++ struct xgene_pcie_port *port; ++ struct pci_host_bridge *bridge; ++ resource_size_t lastbus; ++ u32 lanes = 0, speed = 0; ++ u64 cfg_addr = 0; ++ int ret; ++ ++ port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); ++ if (!port) ++ return -ENOMEM; ++ port->node = np; ++ port->dev = &pdev->dev; ++ ++ ret = xgene_pcie_map_reg(port, pdev, &cfg_addr); ++ if (ret) ++ return ret; ++ ++ ret = xgene_pcie_init_port(port); ++ if (ret) ++ return ret; ++ xgene_pcie_program_core(port->csr_base); ++ xgene_pcie_setup_root_complex(port); ++ ++ bridge = of_create_pci_host_bridge(&pdev->dev, &xgene_pcie_ops, port); ++ if (IS_ERR_OR_NULL(bridge)) ++ return PTR_ERR(bridge); ++ ++ ret = xgene_pcie_map_ranges(port, bridge, cfg_addr); ++ if (ret) ++ return ret; ++ ++ ret = xgene_pcie_parse_map_dma_ranges(port); ++ if (ret) ++ return ret; ++ ++ xgene_pcie_poll_linkup(port, &lanes, &speed); ++ if (!port->link_up) ++ dev_info(port->dev, "(rc) link down\n"); ++ else ++ dev_info(port->dev, "(rc) x%d gen-%d link up\n", ++ lanes, speed + 1); ++ platform_set_drvdata(pdev, port); ++ lastbus = pci_rescan_bus(bridge->bus); ++ pci_bus_update_busn_res_end(bridge->bus, lastbus); ++ return 0; ++} ++ ++static const struct of_device_id xgene_pcie_match_table[] = { ++ {.compatible = "apm,xgene-pcie",}, ++ {}, ++}; ++ ++static struct platform_driver xgene_pcie_driver = { ++ .driver = { ++ .name = "xgene-pcie", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(xgene_pcie_match_table), ++ }, ++ .probe = xgene_pcie_probe_bridge, ++}; ++module_platform_driver(xgene_pcie_driver); ++ ++MODULE_AUTHOR("Tanmay Inamdar <tinamdar@apm.com>"); ++MODULE_DESCRIPTION("APM X-Gene PCIe driver"); ++MODULE_LICENSE("GPL v2"); +diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c +index 1c8592b..b81dc68 100644 +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -17,6 +17,7 @@ + #include <linux/spinlock.h> + #include <linux/string.h> + #include <linux/log2.h> ++#include <linux/of_pci.h> + #include <linux/pci-aspm.h> + #include <linux/pm_wakeup.h> + #include <linux/interrupt.h> +@@ -1453,6 +1454,9 @@ EXPORT_SYMBOL(pcim_pin_device); + */ + int __weak pcibios_add_device(struct pci_dev *dev) + { ++#ifdef CONFIG_OF ++ dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); ++#endif + return 0; + } + +@@ -2704,6 +2708,39 @@ int pci_request_regions_exclusive(struct pci_dev *pdev, const char *res_name) + } + EXPORT_SYMBOL(pci_request_regions_exclusive); + ++/** ++ * pci_remap_iospace - Remap the memory mapped I/O space ++ * @res: Resource describing the I/O space ++ * @phys_addr: physical address where the range will be mapped. ++ * ++ * Remap the memory mapped I/O space described by the @res ++ * into the CPU physical address space. Only architectures ++ * that have memory mapped IO defined (and hence PCI_IOBASE) ++ * should call this function. ++ */ ++int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) ++{ ++ int err = -ENODEV; ++ ++#ifdef PCI_IOBASE ++ if (!(res->flags & IORESOURCE_IO)) ++ return -EINVAL; ++ ++ if (res->end > IO_SPACE_LIMIT) ++ return -EINVAL; ++ ++ err = ioremap_page_range(res->start + (unsigned long)PCI_IOBASE, ++ res->end + 1 + (unsigned long)PCI_IOBASE, ++ phys_addr, __pgprot(PROT_DEVICE_nGnRE)); ++#else ++ /* this architecture does not have memory mapped I/O space, ++ so this function should never be called */ ++ WARN_ON(1); ++#endif ++ ++ return err; ++} ++ + static void __pci_set_master(struct pci_dev *dev, bool enable) + { + u16 old_cmd, cmd; +diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c +index e3cf8a2..abf5e82 100644 +--- a/drivers/pci/probe.c ++++ b/drivers/pci/probe.c +@@ -515,7 +515,7 @@ static void pci_release_host_bridge_dev(struct device *dev) + kfree(bridge); + } + +-static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b) ++static struct pci_host_bridge *pci_alloc_host_bridge(void) + { + struct pci_host_bridge *bridge; + +@@ -524,7 +524,6 @@ static struct pci_host_bridge *pci_alloc_host_bridge(struct pci_bus *b) + return NULL; + + INIT_LIST_HEAD(&bridge->windows); +- bridge->bus = b; + return bridge; + } + +@@ -1749,8 +1748,9 @@ void __weak pcibios_remove_bus(struct pci_bus *bus) + { + } + +-struct pci_bus *pci_create_root_bus(struct device *parent, int bus, +- struct pci_ops *ops, void *sysdata, struct list_head *resources) ++struct pci_bus *pci_create_root_bus_in_domain(struct device *parent, ++ int domain, int bus, struct pci_ops *ops, void *sysdata, ++ struct list_head *resources) + { + int error; + struct pci_host_bridge *bridge; +@@ -1761,37 +1761,41 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, + char bus_addr[64]; + char *fmt; + ++ bridge = pci_alloc_host_bridge(); ++ if (!bridge) ++ return ERR_PTR(-ENOMEM); ++ ++ bridge->dev.parent = parent; ++ bridge->dev.release = pci_release_host_bridge_dev; ++ bridge->domain_nr = domain; ++ + b = pci_alloc_bus(); +- if (!b) +- return NULL; ++ if (!b) { ++ error = -ENOMEM; ++ goto err_out; ++ } + + b->sysdata = sysdata; + b->ops = ops; + b->number = b->busn_res.start = bus; +- b2 = pci_find_bus(pci_domain_nr(b), bus); ++ b2 = pci_find_bus(bridge->domain_nr, bus); + if (b2) { + /* If we already got to this bus through a different bridge, ignore it */ + dev_dbg(&b2->dev, "bus already known\n"); +- goto err_out; ++ error = -EEXIST; ++ goto err_bus_out; + } + +- bridge = pci_alloc_host_bridge(b); +- if (!bridge) +- goto err_out; +- +- bridge->dev.parent = parent; +- bridge->dev.release = pci_release_host_bridge_dev; +- dev_set_name(&bridge->dev, "pci%04x:%02x", pci_domain_nr(b), bus); ++ bridge->bus = b; ++ dev_set_name(&bridge->dev, "pci%04x:%02x", bridge->domain_nr, bus); + error = pcibios_root_bridge_prepare(bridge); +- if (error) { +- kfree(bridge); ++ if (error) + goto err_out; +- } + + error = device_register(&bridge->dev); + if (error) { + put_device(&bridge->dev); +- goto err_out; ++ goto err_bus_out; + } + b->bridge = get_device(&bridge->dev); + device_enable_async_suspend(b->bridge); +@@ -1802,7 +1806,7 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, + + b->dev.class = &pcibus_class; + b->dev.parent = b->bridge; +- dev_set_name(&b->dev, "%04x:%02x", pci_domain_nr(b), bus); ++ dev_set_name(&b->dev, "%04x:%02x", bridge->domain_nr, bus); + error = device_register(&b->dev); + if (error) + goto class_dev_reg_err; +@@ -1848,9 +1852,31 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, + class_dev_reg_err: + put_device(&bridge->dev); + device_unregister(&bridge->dev); ++err_bus_out: ++ kfree(b); + err_out: ++ kfree(bridge); ++ return ERR_PTR(error); ++} ++ ++struct pci_bus *pci_create_root_bus(struct device *parent, int bus, ++ struct pci_ops *ops, void *sysdata, struct list_head *resources) ++{ ++ int domain_nr; ++ struct pci_bus *b = pci_alloc_bus(); ++ if (!b) ++ return NULL; ++ ++ b->sysdata = sysdata; ++ domain_nr = pci_domain_nr(b); + kfree(b); +- return NULL; ++ ++ b = pci_create_root_bus_in_domain(parent, domain_nr, bus, ++ ops, sysdata, resources); ++ if (IS_ERR(b)) ++ return NULL; ++ ++ return b; + } + + int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) +diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig +index 0754f5c..4478a59 100644 +--- a/drivers/rtc/Kconfig ++++ b/drivers/rtc/Kconfig +@@ -789,7 +789,7 @@ config RTC_DRV_DA9063 + + config RTC_DRV_EFI + tristate "EFI RTC" +- depends on IA64 ++ depends on EFI + help + If you say yes here you will get support for the EFI + Real Time Clock. +diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile +index 70347d0..f1dfc36 100644 +--- a/drivers/rtc/Makefile ++++ b/drivers/rtc/Makefile +@@ -10,6 +10,10 @@ obj-$(CONFIG_RTC_SYSTOHC) += systohc.o + obj-$(CONFIG_RTC_CLASS) += rtc-core.o + rtc-core-y := class.o interface.o + ++ifdef CONFIG_RTC_DRV_EFI ++rtc-core-y += rtc-efi-platform.o ++endif ++ + rtc-core-$(CONFIG_RTC_INTF_DEV) += rtc-dev.o + rtc-core-$(CONFIG_RTC_INTF_PROC) += rtc-proc.o + rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o +diff --git a/drivers/rtc/rtc-efi-platform.c b/drivers/rtc/rtc-efi-platform.c +new file mode 100644 +index 0000000..b40fbe3 +--- /dev/null ++++ b/drivers/rtc/rtc-efi-platform.c +@@ -0,0 +1,31 @@ ++/* ++ * Moved from arch/ia64/kernel/time.c ++ * ++ * Copyright (C) 1998-2003 Hewlett-Packard Co ++ * Stephane Eranian <eranian@hpl.hp.com> ++ * David Mosberger <davidm@hpl.hp.com> ++ * Copyright (C) 1999 Don Dugger <don.dugger@intel.com> ++ * Copyright (C) 1999-2000 VA Linux Systems ++ * Copyright (C) 1999-2000 Walt Drummond <drummond@valinux.com> ++ */ ++#include <linux/init.h> ++#include <linux/kernel.h> ++#include <linux/module.h> ++#include <linux/efi.h> ++#include <linux/platform_device.h> ++ ++static struct platform_device rtc_efi_dev = { ++ .name = "rtc-efi", ++ .id = -1, ++}; ++ ++static int __init rtc_init(void) ++{ ++ if (efi_enabled(EFI_RUNTIME_SERVICES)) ++ if (platform_device_register(&rtc_efi_dev) < 0) ++ pr_err("unable to register rtc device...\n"); ++ ++ /* not necessarily an error */ ++ return 0; ++} ++module_init(rtc_init); +diff --git a/include/asm-generic/io.h b/include/asm-generic/io.h +index 975e1cc..2e2161b 100644 +--- a/include/asm-generic/io.h ++++ b/include/asm-generic/io.h +@@ -331,7 +331,7 @@ static inline void iounmap(void __iomem *addr) + #ifndef CONFIG_GENERIC_IOMAP + static inline void __iomem *ioport_map(unsigned long port, unsigned int nr) + { +- return (void __iomem *) port; ++ return (void __iomem *)(PCI_IOBASE + (port & IO_SPACE_LIMIT)); + } + + static inline void ioport_unmap(void __iomem *p) +diff --git a/include/kvm/arm_vgic.h b/include/kvm/arm_vgic.h +index f27000f..35b0c12 100644 +--- a/include/kvm/arm_vgic.h ++++ b/include/kvm/arm_vgic.h +@@ -24,7 +24,6 @@ + #include <linux/irqreturn.h> + #include <linux/spinlock.h> + #include <linux/types.h> +-#include <linux/irqchip/arm-gic.h> + + #define VGIC_NR_IRQS 256 + #define VGIC_NR_SGIS 16 +@@ -32,7 +31,9 @@ + #define VGIC_NR_PRIVATE_IRQS (VGIC_NR_SGIS + VGIC_NR_PPIS) + #define VGIC_NR_SHARED_IRQS (VGIC_NR_IRQS - VGIC_NR_PRIVATE_IRQS) + #define VGIC_MAX_CPUS KVM_MAX_VCPUS +-#define VGIC_MAX_LRS (1 << 6) ++ ++#define VGIC_V2_MAX_LRS (1 << 6) ++#define VGIC_V3_MAX_LRS 16 + + /* Sanity checks... */ + #if (VGIC_MAX_CPUS > 8) +@@ -68,9 +69,62 @@ struct vgic_bytemap { + u32 shared[VGIC_NR_SHARED_IRQS / 4]; + }; + ++struct kvm_vcpu; ++ ++enum vgic_type { ++ VGIC_V2, /* Good ol' GICv2 */ ++ VGIC_V3, /* New fancy GICv3 */ ++}; ++ ++#define LR_STATE_PENDING (1 << 0) ++#define LR_STATE_ACTIVE (1 << 1) ++#define LR_STATE_MASK (3 << 0) ++#define LR_EOI_INT (1 << 2) ++ ++struct vgic_lr { ++ u16 irq; ++ u8 source; ++ u8 state; ++}; ++ ++struct vgic_vmcr { ++ u32 ctlr; ++ u32 abpr; ++ u32 bpr; ++ u32 pmr; ++}; ++ ++struct vgic_ops { ++ struct vgic_lr (*get_lr)(const struct kvm_vcpu *, int); ++ void (*set_lr)(struct kvm_vcpu *, int, struct vgic_lr); ++ void (*sync_lr_elrsr)(struct kvm_vcpu *, int, struct vgic_lr); ++ u64 (*get_elrsr)(const struct kvm_vcpu *vcpu); ++ u64 (*get_eisr)(const struct kvm_vcpu *vcpu); ++ u32 (*get_interrupt_status)(const struct kvm_vcpu *vcpu); ++ void (*enable_underflow)(struct kvm_vcpu *vcpu); ++ void (*disable_underflow)(struct kvm_vcpu *vcpu); ++ void (*get_vmcr)(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); ++ void (*set_vmcr)(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); ++ void (*enable)(struct kvm_vcpu *vcpu); ++}; ++ ++struct vgic_params { ++ /* vgic type */ ++ enum vgic_type type; ++ /* Physical address of vgic virtual cpu interface */ ++ phys_addr_t vcpu_base; ++ /* Number of list registers */ ++ u32 nr_lr; ++ /* Interrupt number */ ++ unsigned int maint_irq; ++ /* Virtual control interface base address */ ++ void __iomem *vctrl_base; ++}; ++ + struct vgic_dist { + #ifdef CONFIG_KVM_ARM_VGIC + spinlock_t lock; ++ bool in_kernel; + bool ready; + + /* Virtual control interface mapping */ +@@ -110,6 +164,29 @@ struct vgic_dist { + #endif + }; + ++struct vgic_v2_cpu_if { ++ u32 vgic_hcr; ++ u32 vgic_vmcr; ++ u32 vgic_misr; /* Saved only */ ++ u32 vgic_eisr[2]; /* Saved only */ ++ u32 vgic_elrsr[2]; /* Saved only */ ++ u32 vgic_apr; ++ u32 vgic_lr[VGIC_V2_MAX_LRS]; ++}; ++ ++struct vgic_v3_cpu_if { ++#ifdef CONFIG_ARM_GIC_V3 ++ u32 vgic_hcr; ++ u32 vgic_vmcr; ++ u32 vgic_misr; /* Saved only */ ++ u32 vgic_eisr; /* Saved only */ ++ u32 vgic_elrsr; /* Saved only */ ++ u32 vgic_ap0r[4]; ++ u32 vgic_ap1r[4]; ++ u64 vgic_lr[VGIC_V3_MAX_LRS]; ++#endif ++}; ++ + struct vgic_cpu { + #ifdef CONFIG_KVM_ARM_VGIC + /* per IRQ to LR mapping */ +@@ -120,24 +197,24 @@ struct vgic_cpu { + DECLARE_BITMAP( pending_shared, VGIC_NR_SHARED_IRQS); + + /* Bitmap of used/free list registers */ +- DECLARE_BITMAP( lr_used, VGIC_MAX_LRS); ++ DECLARE_BITMAP( lr_used, VGIC_V2_MAX_LRS); + + /* Number of list registers on this CPU */ + int nr_lr; + + /* CPU vif control registers for world switch */ +- u32 vgic_hcr; +- u32 vgic_vmcr; +- u32 vgic_misr; /* Saved only */ +- u32 vgic_eisr[2]; /* Saved only */ +- u32 vgic_elrsr[2]; /* Saved only */ +- u32 vgic_apr; +- u32 vgic_lr[VGIC_MAX_LRS]; ++ union { ++ struct vgic_v2_cpu_if vgic_v2; ++ struct vgic_v3_cpu_if vgic_v3; ++ }; + #endif + }; + + #define LR_EMPTY 0xff + ++#define INT_STATUS_EOI (1 << 0) ++#define INT_STATUS_UNDERFLOW (1 << 1) ++ + struct kvm; + struct kvm_vcpu; + struct kvm_run; +@@ -157,9 +234,25 @@ int kvm_vgic_vcpu_pending_irq(struct kvm_vcpu *vcpu); + bool vgic_handle_mmio(struct kvm_vcpu *vcpu, struct kvm_run *run, + struct kvm_exit_mmio *mmio); + +-#define irqchip_in_kernel(k) (!!((k)->arch.vgic.vctrl_base)) ++#define irqchip_in_kernel(k) (!!((k)->arch.vgic.in_kernel)) + #define vgic_initialized(k) ((k)->arch.vgic.ready) + ++int vgic_v2_probe(struct device_node *vgic_node, ++ const struct vgic_ops **ops, ++ const struct vgic_params **params); ++#ifdef CONFIG_ARM_GIC_V3 ++int vgic_v3_probe(struct device_node *vgic_node, ++ const struct vgic_ops **ops, ++ const struct vgic_params **params); ++#else ++static inline int vgic_v3_probe(struct device_node *vgic_node, ++ const struct vgic_ops **ops, ++ const struct vgic_params **params) ++{ ++ return -ENODEV; ++} ++#endif ++ + #else + static inline int kvm_vgic_hyp_init(void) + { +diff --git a/include/linux/efi.h b/include/linux/efi.h +index 41bbf8b..b3fac7c 100644 +--- a/include/linux/efi.h ++++ b/include/linux/efi.h +@@ -20,6 +20,7 @@ + #include <linux/ioport.h> + #include <linux/pfn.h> + #include <linux/pstore.h> ++#include <linux/reboot.h> + + #include <asm/page.h> + +@@ -875,6 +876,9 @@ extern void efi_reserve_boot_services(void); + extern int efi_get_fdt_params(struct efi_fdt_params *params, int verbose); + extern struct efi_memory_map memmap; + ++extern int efi_reboot_quirk_mode; ++extern bool efi_poweroff_required(void); ++ + /* Iterate through an efi_memory_map */ + #define for_each_efi_memory_desc(m, md) \ + for ((md) = (m)->map; \ +@@ -926,11 +930,14 @@ static inline bool efi_enabled(int feature) + { + return test_bit(feature, &efi.flags) != 0; + } ++extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused); + #else + static inline bool efi_enabled(int feature) + { + return false; + } ++static inline void ++efi_reboot(enum reboot_mode reboot_mode, const char *__unused) {} + #endif + + /* +diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h +new file mode 100644 +index 0000000..30cb755 +--- /dev/null ++++ b/include/linux/irqchip/arm-gic-v3.h +@@ -0,0 +1,198 @@ ++/* ++ * Copyright (C) 2013, 2014 ARM Limited, All Rights Reserved. ++ * Author: Marc Zyngier <marc.zyngier@arm.com> ++ * ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++#ifndef __LINUX_IRQCHIP_ARM_GIC_V3_H ++#define __LINUX_IRQCHIP_ARM_GIC_V3_H ++ ++/* ++ * Distributor registers. We assume we're running non-secure, with ARE ++ * being set. Secure-only and non-ARE registers are not described. ++ */ ++#define GICD_CTLR 0x0000 ++#define GICD_TYPER 0x0004 ++#define GICD_IIDR 0x0008 ++#define GICD_STATUSR 0x0010 ++#define GICD_SETSPI_NSR 0x0040 ++#define GICD_CLRSPI_NSR 0x0048 ++#define GICD_SETSPI_SR 0x0050 ++#define GICD_CLRSPI_SR 0x0058 ++#define GICD_SEIR 0x0068 ++#define GICD_ISENABLER 0x0100 ++#define GICD_ICENABLER 0x0180 ++#define GICD_ISPENDR 0x0200 ++#define GICD_ICPENDR 0x0280 ++#define GICD_ISACTIVER 0x0300 ++#define GICD_ICACTIVER 0x0380 ++#define GICD_IPRIORITYR 0x0400 ++#define GICD_ICFGR 0x0C00 ++#define GICD_IROUTER 0x6000 ++#define GICD_PIDR2 0xFFE8 ++ ++#define GICD_CTLR_RWP (1U << 31) ++#define GICD_CTLR_ARE_NS (1U << 4) ++#define GICD_CTLR_ENABLE_G1A (1U << 1) ++#define GICD_CTLR_ENABLE_G1 (1U << 0) ++ ++#define GICD_IROUTER_SPI_MODE_ONE (0U << 31) ++#define GICD_IROUTER_SPI_MODE_ANY (1U << 31) ++ ++#define GIC_PIDR2_ARCH_MASK 0xf0 ++#define GIC_PIDR2_ARCH_GICv3 0x30 ++#define GIC_PIDR2_ARCH_GICv4 0x40 ++ ++/* ++ * Re-Distributor registers, offsets from RD_base ++ */ ++#define GICR_CTLR GICD_CTLR ++#define GICR_IIDR 0x0004 ++#define GICR_TYPER 0x0008 ++#define GICR_STATUSR GICD_STATUSR ++#define GICR_WAKER 0x0014 ++#define GICR_SETLPIR 0x0040 ++#define GICR_CLRLPIR 0x0048 ++#define GICR_SEIR GICD_SEIR ++#define GICR_PROPBASER 0x0070 ++#define GICR_PENDBASER 0x0078 ++#define GICR_INVLPIR 0x00A0 ++#define GICR_INVALLR 0x00B0 ++#define GICR_SYNCR 0x00C0 ++#define GICR_MOVLPIR 0x0100 ++#define GICR_MOVALLR 0x0110 ++#define GICR_PIDR2 GICD_PIDR2 ++ ++#define GICR_WAKER_ProcessorSleep (1U << 1) ++#define GICR_WAKER_ChildrenAsleep (1U << 2) ++ ++/* ++ * Re-Distributor registers, offsets from SGI_base ++ */ ++#define GICR_ISENABLER0 GICD_ISENABLER ++#define GICR_ICENABLER0 GICD_ICENABLER ++#define GICR_ISPENDR0 GICD_ISPENDR ++#define GICR_ICPENDR0 GICD_ICPENDR ++#define GICR_ISACTIVER0 GICD_ISACTIVER ++#define GICR_ICACTIVER0 GICD_ICACTIVER ++#define GICR_IPRIORITYR0 GICD_IPRIORITYR ++#define GICR_ICFGR0 GICD_ICFGR ++ ++#define GICR_TYPER_VLPIS (1U << 1) ++#define GICR_TYPER_LAST (1U << 4) ++ ++/* ++ * CPU interface registers ++ */ ++#define ICC_CTLR_EL1_EOImode_drop_dir (0U << 1) ++#define ICC_CTLR_EL1_EOImode_drop (1U << 1) ++#define ICC_SRE_EL1_SRE (1U << 0) ++ ++/* ++ * Hypervisor interface registers (SRE only) ++ */ ++#define ICH_LR_VIRTUAL_ID_MASK ((1UL << 32) - 1) ++ ++#define ICH_LR_EOI (1UL << 41) ++#define ICH_LR_GROUP (1UL << 60) ++#define ICH_LR_STATE (3UL << 62) ++#define ICH_LR_PENDING_BIT (1UL << 62) ++#define ICH_LR_ACTIVE_BIT (1UL << 63) ++ ++#define ICH_MISR_EOI (1 << 0) ++#define ICH_MISR_U (1 << 1) ++ ++#define ICH_HCR_EN (1 << 0) ++#define ICH_HCR_UIE (1 << 1) ++ ++#define ICH_VMCR_CTLR_SHIFT 0 ++#define ICH_VMCR_CTLR_MASK (0x21f << ICH_VMCR_CTLR_SHIFT) ++#define ICH_VMCR_BPR1_SHIFT 18 ++#define ICH_VMCR_BPR1_MASK (7 << ICH_VMCR_BPR1_SHIFT) ++#define ICH_VMCR_BPR0_SHIFT 21 ++#define ICH_VMCR_BPR0_MASK (7 << ICH_VMCR_BPR0_SHIFT) ++#define ICH_VMCR_PMR_SHIFT 24 ++#define ICH_VMCR_PMR_MASK (0xffUL << ICH_VMCR_PMR_SHIFT) ++ ++#define ICC_EOIR1_EL1 S3_0_C12_C12_1 ++#define ICC_IAR1_EL1 S3_0_C12_C12_0 ++#define ICC_SGI1R_EL1 S3_0_C12_C11_5 ++#define ICC_PMR_EL1 S3_0_C4_C6_0 ++#define ICC_CTLR_EL1 S3_0_C12_C12_4 ++#define ICC_SRE_EL1 S3_0_C12_C12_5 ++#define ICC_GRPEN1_EL1 S3_0_C12_C12_7 ++ ++#define ICC_IAR1_EL1_SPURIOUS 0x3ff ++ ++#define ICC_SRE_EL2 S3_4_C12_C9_5 ++ ++#define ICC_SRE_EL2_SRE (1 << 0) ++#define ICC_SRE_EL2_ENABLE (1 << 3) ++ ++/* ++ * System register definitions ++ */ ++#define ICH_VSEIR_EL2 S3_4_C12_C9_4 ++#define ICH_HCR_EL2 S3_4_C12_C11_0 ++#define ICH_VTR_EL2 S3_4_C12_C11_1 ++#define ICH_MISR_EL2 S3_4_C12_C11_2 ++#define ICH_EISR_EL2 S3_4_C12_C11_3 ++#define ICH_ELSR_EL2 S3_4_C12_C11_5 ++#define ICH_VMCR_EL2 S3_4_C12_C11_7 ++ ++#define __LR0_EL2(x) S3_4_C12_C12_ ## x ++#define __LR8_EL2(x) S3_4_C12_C13_ ## x ++ ++#define ICH_LR0_EL2 __LR0_EL2(0) ++#define ICH_LR1_EL2 __LR0_EL2(1) ++#define ICH_LR2_EL2 __LR0_EL2(2) ++#define ICH_LR3_EL2 __LR0_EL2(3) ++#define ICH_LR4_EL2 __LR0_EL2(4) ++#define ICH_LR5_EL2 __LR0_EL2(5) ++#define ICH_LR6_EL2 __LR0_EL2(6) ++#define ICH_LR7_EL2 __LR0_EL2(7) ++#define ICH_LR8_EL2 __LR8_EL2(0) ++#define ICH_LR9_EL2 __LR8_EL2(1) ++#define ICH_LR10_EL2 __LR8_EL2(2) ++#define ICH_LR11_EL2 __LR8_EL2(3) ++#define ICH_LR12_EL2 __LR8_EL2(4) ++#define ICH_LR13_EL2 __LR8_EL2(5) ++#define ICH_LR14_EL2 __LR8_EL2(6) ++#define ICH_LR15_EL2 __LR8_EL2(7) ++ ++#define __AP0Rx_EL2(x) S3_4_C12_C8_ ## x ++#define ICH_AP0R0_EL2 __AP0Rx_EL2(0) ++#define ICH_AP0R1_EL2 __AP0Rx_EL2(1) ++#define ICH_AP0R2_EL2 __AP0Rx_EL2(2) ++#define ICH_AP0R3_EL2 __AP0Rx_EL2(3) ++ ++#define __AP1Rx_EL2(x) S3_4_C12_C9_ ## x ++#define ICH_AP1R0_EL2 __AP1Rx_EL2(0) ++#define ICH_AP1R1_EL2 __AP1Rx_EL2(1) ++#define ICH_AP1R2_EL2 __AP1Rx_EL2(2) ++#define ICH_AP1R3_EL2 __AP1Rx_EL2(3) ++ ++#ifndef __ASSEMBLY__ ++ ++#include <linux/stringify.h> ++ ++static inline void gic_write_eoir(u64 irq) ++{ ++ asm volatile("msr " __stringify(ICC_EOIR1_EL1) ", %0" : : "r" (irq)); ++ isb(); ++} ++ ++#endif ++ ++#endif +diff --git a/include/linux/of_address.h b/include/linux/of_address.h +index c13b878..33c0420 100644 +--- a/include/linux/of_address.h ++++ b/include/linux/of_address.h +@@ -23,17 +23,8 @@ struct of_pci_range { + #define for_each_of_pci_range(parser, range) \ + for (; of_pci_range_parser_one(parser, range);) + +-static inline void of_pci_range_to_resource(struct of_pci_range *range, +- struct device_node *np, +- struct resource *res) +-{ +- res->flags = range->flags; +- res->start = range->cpu_addr; +- res->end = range->cpu_addr + range->size - 1; +- res->parent = res->child = res->sibling = NULL; +- res->name = np->full_name; +-} +- ++extern int of_pci_range_to_resource(struct of_pci_range *range, ++ struct device_node *np, struct resource *res); + /* Translate a DMA address from device space to CPU space */ + extern u64 of_translate_dma_address(struct device_node *dev, + const __be32 *in_addr); +@@ -55,6 +46,7 @@ extern void __iomem *of_iomap(struct device_node *device, int index); + extern const __be32 *of_get_address(struct device_node *dev, int index, + u64 *size, unsigned int *flags); + ++extern int pci_register_io_range(phys_addr_t addr, resource_size_t size); + extern unsigned long pci_address_to_pio(phys_addr_t addr); + + extern int of_pci_range_parser_init(struct of_pci_range_parser *parser, +diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h +index dde3a4a..71e36d0 100644 +--- a/include/linux/of_pci.h ++++ b/include/linux/of_pci.h +@@ -15,6 +15,9 @@ struct device_node *of_pci_find_child_device(struct device_node *parent, + int of_pci_get_devfn(struct device_node *np); + int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin); + int of_pci_parse_bus_range(struct device_node *node, struct resource *res); ++struct pci_host_bridge *of_create_pci_host_bridge(struct device *parent, ++ struct pci_ops *ops, void *host_data); ++ + #else + static inline int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq) + { +@@ -43,6 +46,13 @@ of_pci_parse_bus_range(struct device_node *node, struct resource *res) + { + return -EINVAL; + } ++ ++static inline struct pci_host_bridge * ++of_create_pci_host_bridge(struct device *parent, struct pci_ops *ops, ++ void *host_data) ++{ ++ return NULL; ++} + #endif + + #if defined(CONFIG_OF) && defined(CONFIG_PCI_MSI) +diff --git a/include/linux/pci.h b/include/linux/pci.h +index 466bcd1..65fb1fc 100644 +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -401,6 +401,8 @@ struct pci_host_bridge_window { + struct pci_host_bridge { + struct device dev; + struct pci_bus *bus; /* root bus */ ++ int domain_nr; ++ resource_size_t io_base; /* physical address for the start of I/O area */ + struct list_head windows; /* pci_host_bridge_windows */ + void (*release_fn)(struct pci_host_bridge *); + void *release_data; +@@ -769,6 +771,9 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata); + struct pci_bus *pci_create_root_bus(struct device *parent, int bus, + struct pci_ops *ops, void *sysdata, + struct list_head *resources); ++struct pci_bus *pci_create_root_bus_in_domain(struct device *parent, ++ int domain, int bus, struct pci_ops *ops, ++ void *sysdata, struct list_head *resources); + int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); + int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); + void pci_bus_release_busn_res(struct pci_bus *b); +@@ -1095,6 +1100,9 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus, + resource_size_t), + void *alignf_data); + ++ ++int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr); ++ + static inline dma_addr_t pci_bus_address(struct pci_dev *pdev, int bar) + { + struct pci_bus_region region; +@@ -1805,8 +1813,15 @@ static inline void pci_set_of_node(struct pci_dev *dev) { } + static inline void pci_release_of_node(struct pci_dev *dev) { } + static inline void pci_set_bus_of_node(struct pci_bus *bus) { } + static inline void pci_release_bus_of_node(struct pci_bus *bus) { } ++ + #endif /* CONFIG_OF */ + ++/* Used by architecture code to apply any quirks to the list of ++ * pci_host_bridge resource ranges before they are being used ++ * by of_create_pci_host_bridge() ++ */ ++extern int pcibios_fixup_bridge_ranges(struct list_head *resources); ++ + #ifdef CONFIG_EEH + static inline struct eeh_dev *pci_dev_to_eeh_dev(struct pci_dev *pdev) + { +diff --git a/tools/perf/arch/arm64/include/perf_regs.h b/tools/perf/arch/arm64/include/perf_regs.h +index e9441b9..1d3f39c 100644 +--- a/tools/perf/arch/arm64/include/perf_regs.h ++++ b/tools/perf/arch/arm64/include/perf_regs.h +@@ -6,6 +6,8 @@ + #include <asm/perf_regs.h> + + #define PERF_REGS_MASK ((1ULL << PERF_REG_ARM64_MAX) - 1) ++#define PERF_REGS_MAX PERF_REG_ARM64_MAX ++ + #define PERF_REG_IP PERF_REG_ARM64_PC + #define PERF_REG_SP PERF_REG_ARM64_SP + +diff --git a/virt/kvm/arm/vgic-v2.c b/virt/kvm/arm/vgic-v2.c +new file mode 100644 +index 0000000..ff597d8 +--- /dev/null ++++ b/virt/kvm/arm/vgic-v2.c +@@ -0,0 +1,259 @@ ++/* ++ * Copyright (C) 2012,2013 ARM Limited, All Rights Reserved. ++ * Author: Marc Zyngier <marc.zyngier@arm.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#include <linux/cpu.h> ++#include <linux/kvm.h> ++#include <linux/kvm_host.h> ++#include <linux/interrupt.h> ++#include <linux/io.h> ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++ ++#include <linux/irqchip/arm-gic.h> ++ ++#include <asm/kvm_emulate.h> ++#include <asm/kvm_arm.h> ++#include <asm/kvm_mmu.h> ++ ++static struct vgic_lr vgic_v2_get_lr(const struct kvm_vcpu *vcpu, int lr) ++{ ++ struct vgic_lr lr_desc; ++ u32 val = vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr]; ++ ++ lr_desc.irq = val & GICH_LR_VIRTUALID; ++ if (lr_desc.irq <= 15) ++ lr_desc.source = (val >> GICH_LR_PHYSID_CPUID_SHIFT) & 0x7; ++ else ++ lr_desc.source = 0; ++ lr_desc.state = 0; ++ ++ if (val & GICH_LR_PENDING_BIT) ++ lr_desc.state |= LR_STATE_PENDING; ++ if (val & GICH_LR_ACTIVE_BIT) ++ lr_desc.state |= LR_STATE_ACTIVE; ++ if (val & GICH_LR_EOI) ++ lr_desc.state |= LR_EOI_INT; ++ ++ return lr_desc; ++} ++ ++static void vgic_v2_set_lr(struct kvm_vcpu *vcpu, int lr, ++ struct vgic_lr lr_desc) ++{ ++ u32 lr_val = (lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT) | lr_desc.irq; ++ ++ if (lr_desc.state & LR_STATE_PENDING) ++ lr_val |= GICH_LR_PENDING_BIT; ++ if (lr_desc.state & LR_STATE_ACTIVE) ++ lr_val |= GICH_LR_ACTIVE_BIT; ++ if (lr_desc.state & LR_EOI_INT) ++ lr_val |= GICH_LR_EOI; ++ ++ vcpu->arch.vgic_cpu.vgic_v2.vgic_lr[lr] = lr_val; ++} ++ ++static void vgic_v2_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr, ++ struct vgic_lr lr_desc) ++{ ++ if (!(lr_desc.state & LR_STATE_MASK)) ++ set_bit(lr, (unsigned long *)vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr); ++} ++ ++static u64 vgic_v2_get_elrsr(const struct kvm_vcpu *vcpu) ++{ ++ u64 val; ++ ++ val = vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr[1]; ++ val <<= 32; ++ val |= vcpu->arch.vgic_cpu.vgic_v2.vgic_elrsr[0]; ++ ++ return val; ++} ++ ++static u64 vgic_v2_get_eisr(const struct kvm_vcpu *vcpu) ++{ ++ u64 val; ++ ++ val = vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[1]; ++ val <<= 32; ++ val |= vcpu->arch.vgic_cpu.vgic_v2.vgic_eisr[0]; ++ ++ return val; ++} ++ ++static u32 vgic_v2_get_interrupt_status(const struct kvm_vcpu *vcpu) ++{ ++ u32 misr = vcpu->arch.vgic_cpu.vgic_v2.vgic_misr; ++ u32 ret = 0; ++ ++ if (misr & GICH_MISR_EOI) ++ ret |= INT_STATUS_EOI; ++ if (misr & GICH_MISR_U) ++ ret |= INT_STATUS_UNDERFLOW; ++ ++ return ret; ++} ++ ++static void vgic_v2_enable_underflow(struct kvm_vcpu *vcpu) ++{ ++ vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr |= GICH_HCR_UIE; ++} ++ ++static void vgic_v2_disable_underflow(struct kvm_vcpu *vcpu) ++{ ++ vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr &= ~GICH_HCR_UIE; ++} ++ ++static void vgic_v2_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) ++{ ++ u32 vmcr = vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr; ++ ++ vmcrp->ctlr = (vmcr & GICH_VMCR_CTRL_MASK) >> GICH_VMCR_CTRL_SHIFT; ++ vmcrp->abpr = (vmcr & GICH_VMCR_ALIAS_BINPOINT_MASK) >> GICH_VMCR_ALIAS_BINPOINT_SHIFT; ++ vmcrp->bpr = (vmcr & GICH_VMCR_BINPOINT_MASK) >> GICH_VMCR_BINPOINT_SHIFT; ++ vmcrp->pmr = (vmcr & GICH_VMCR_PRIMASK_MASK) >> GICH_VMCR_PRIMASK_SHIFT; ++} ++ ++static void vgic_v2_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) ++{ ++ u32 vmcr; ++ ++ vmcr = (vmcrp->ctlr << GICH_VMCR_CTRL_SHIFT) & GICH_VMCR_CTRL_MASK; ++ vmcr |= (vmcrp->abpr << GICH_VMCR_ALIAS_BINPOINT_SHIFT) & GICH_VMCR_ALIAS_BINPOINT_MASK; ++ vmcr |= (vmcrp->bpr << GICH_VMCR_BINPOINT_SHIFT) & GICH_VMCR_BINPOINT_MASK; ++ vmcr |= (vmcrp->pmr << GICH_VMCR_PRIMASK_SHIFT) & GICH_VMCR_PRIMASK_MASK; ++ ++ vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = vmcr; ++} ++ ++static void vgic_v2_enable(struct kvm_vcpu *vcpu) ++{ ++ /* ++ * By forcing VMCR to zero, the GIC will restore the binary ++ * points to their reset values. Anything else resets to zero ++ * anyway. ++ */ ++ vcpu->arch.vgic_cpu.vgic_v2.vgic_vmcr = 0; ++ ++ /* Get the show on the road... */ ++ vcpu->arch.vgic_cpu.vgic_v2.vgic_hcr = GICH_HCR_EN; ++} ++ ++static const struct vgic_ops vgic_v2_ops = { ++ .get_lr = vgic_v2_get_lr, ++ .set_lr = vgic_v2_set_lr, ++ .sync_lr_elrsr = vgic_v2_sync_lr_elrsr, ++ .get_elrsr = vgic_v2_get_elrsr, ++ .get_eisr = vgic_v2_get_eisr, ++ .get_interrupt_status = vgic_v2_get_interrupt_status, ++ .enable_underflow = vgic_v2_enable_underflow, ++ .disable_underflow = vgic_v2_disable_underflow, ++ .get_vmcr = vgic_v2_get_vmcr, ++ .set_vmcr = vgic_v2_set_vmcr, ++ .enable = vgic_v2_enable, ++}; ++ ++static struct vgic_params vgic_v2_params; ++ ++/** ++ * vgic_v2_probe - probe for a GICv2 compatible interrupt controller in DT ++ * @node: pointer to the DT node ++ * @ops: address of a pointer to the GICv2 operations ++ * @params: address of a pointer to HW-specific parameters ++ * ++ * Returns 0 if a GICv2 has been found, with the low level operations ++ * in *ops and the HW parameters in *params. Returns an error code ++ * otherwise. ++ */ ++int vgic_v2_probe(struct device_node *vgic_node, ++ const struct vgic_ops **ops, ++ const struct vgic_params **params) ++{ ++ int ret; ++ struct resource vctrl_res; ++ struct resource vcpu_res; ++ struct vgic_params *vgic = &vgic_v2_params; ++ ++ vgic->maint_irq = irq_of_parse_and_map(vgic_node, 0); ++ if (!vgic->maint_irq) { ++ kvm_err("error getting vgic maintenance irq from DT\n"); ++ ret = -ENXIO; ++ goto out; ++ } ++ ++ ret = of_address_to_resource(vgic_node, 2, &vctrl_res); ++ if (ret) { ++ kvm_err("Cannot obtain GICH resource\n"); ++ goto out; ++ } ++ ++ vgic->vctrl_base = of_iomap(vgic_node, 2); ++ if (!vgic->vctrl_base) { ++ kvm_err("Cannot ioremap GICH\n"); ++ ret = -ENOMEM; ++ goto out; ++ } ++ ++ vgic->nr_lr = readl_relaxed(vgic->vctrl_base + GICH_VTR); ++ vgic->nr_lr = (vgic->nr_lr & 0x3f) + 1; ++ ++ ret = create_hyp_io_mappings(vgic->vctrl_base, ++ vgic->vctrl_base + resource_size(&vctrl_res), ++ vctrl_res.start); ++ if (ret) { ++ kvm_err("Cannot map VCTRL into hyp\n"); ++ goto out_unmap; ++ } ++ ++ if (of_address_to_resource(vgic_node, 3, &vcpu_res)) { ++ kvm_err("Cannot obtain GICV resource\n"); ++ ret = -ENXIO; ++ goto out_unmap; ++ } ++ ++ if (!PAGE_ALIGNED(vcpu_res.start)) { ++ kvm_err("GICV physical address 0x%llx not page aligned\n", ++ (unsigned long long)vcpu_res.start); ++ ret = -ENXIO; ++ goto out_unmap; ++ } ++ ++ if (!PAGE_ALIGNED(resource_size(&vcpu_res))) { ++ kvm_err("GICV size 0x%llx not a multiple of page size 0x%lx\n", ++ (unsigned long long)resource_size(&vcpu_res), ++ PAGE_SIZE); ++ ret = -ENXIO; ++ goto out_unmap; ++ } ++ ++ vgic->vcpu_base = vcpu_res.start; ++ ++ kvm_info("%s@%llx IRQ%d\n", vgic_node->name, ++ vgic->vctrl_base, vgic->maint_irq); ++ ++ vgic->type = VGIC_V2; ++ *ops = &vgic_v2_ops; ++ *params = vgic; ++ goto out; ++ ++out_unmap: ++ iounmap(vgic->vctrl_base); ++out: ++ of_node_put(vgic_node); ++ return ret; ++} +diff --git a/virt/kvm/arm/vgic-v3.c b/virt/kvm/arm/vgic-v3.c +new file mode 100644 +index 0000000..f01d446 +--- /dev/null ++++ b/virt/kvm/arm/vgic-v3.c +@@ -0,0 +1,231 @@ ++/* ++ * Copyright (C) 2013 ARM Limited, All Rights Reserved. ++ * Author: Marc Zyngier <marc.zyngier@arm.com> ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see <http://www.gnu.org/licenses/>. ++ */ ++ ++#include <linux/cpu.h> ++#include <linux/kvm.h> ++#include <linux/kvm_host.h> ++#include <linux/interrupt.h> ++#include <linux/io.h> ++#include <linux/of.h> ++#include <linux/of_address.h> ++#include <linux/of_irq.h> ++ ++#include <linux/irqchip/arm-gic-v3.h> ++ ++#include <asm/kvm_emulate.h> ++#include <asm/kvm_arm.h> ++#include <asm/kvm_mmu.h> ++ ++/* These are for GICv2 emulation only */ ++#define GICH_LR_VIRTUALID (0x3ffUL << 0) ++#define GICH_LR_PHYSID_CPUID_SHIFT (10) ++#define GICH_LR_PHYSID_CPUID (7UL << GICH_LR_PHYSID_CPUID_SHIFT) ++ ++/* ++ * LRs are stored in reverse order in memory. make sure we index them ++ * correctly. ++ */ ++#define LR_INDEX(lr) (VGIC_V3_MAX_LRS - 1 - lr) ++ ++static u32 ich_vtr_el2; ++ ++static struct vgic_lr vgic_v3_get_lr(const struct kvm_vcpu *vcpu, int lr) ++{ ++ struct vgic_lr lr_desc; ++ u64 val = vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[LR_INDEX(lr)]; ++ ++ lr_desc.irq = val & GICH_LR_VIRTUALID; ++ if (lr_desc.irq <= 15) ++ lr_desc.source = (val >> GICH_LR_PHYSID_CPUID_SHIFT) & 0x7; ++ else ++ lr_desc.source = 0; ++ lr_desc.state = 0; ++ ++ if (val & ICH_LR_PENDING_BIT) ++ lr_desc.state |= LR_STATE_PENDING; ++ if (val & ICH_LR_ACTIVE_BIT) ++ lr_desc.state |= LR_STATE_ACTIVE; ++ if (val & ICH_LR_EOI) ++ lr_desc.state |= LR_EOI_INT; ++ ++ return lr_desc; ++} ++ ++static void vgic_v3_set_lr(struct kvm_vcpu *vcpu, int lr, ++ struct vgic_lr lr_desc) ++{ ++ u64 lr_val = (((u32)lr_desc.source << GICH_LR_PHYSID_CPUID_SHIFT) | ++ lr_desc.irq); ++ ++ if (lr_desc.state & LR_STATE_PENDING) ++ lr_val |= ICH_LR_PENDING_BIT; ++ if (lr_desc.state & LR_STATE_ACTIVE) ++ lr_val |= ICH_LR_ACTIVE_BIT; ++ if (lr_desc.state & LR_EOI_INT) ++ lr_val |= ICH_LR_EOI; ++ ++ vcpu->arch.vgic_cpu.vgic_v3.vgic_lr[LR_INDEX(lr)] = lr_val; ++} ++ ++static void vgic_v3_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr, ++ struct vgic_lr lr_desc) ++{ ++ if (!(lr_desc.state & LR_STATE_MASK)) ++ vcpu->arch.vgic_cpu.vgic_v3.vgic_elrsr |= (1U << lr); ++} ++ ++static u64 vgic_v3_get_elrsr(const struct kvm_vcpu *vcpu) ++{ ++ return vcpu->arch.vgic_cpu.vgic_v3.vgic_elrsr; ++} ++ ++static u64 vgic_v3_get_eisr(const struct kvm_vcpu *vcpu) ++{ ++ return vcpu->arch.vgic_cpu.vgic_v3.vgic_eisr; ++} ++ ++static u32 vgic_v3_get_interrupt_status(const struct kvm_vcpu *vcpu) ++{ ++ u32 misr = vcpu->arch.vgic_cpu.vgic_v3.vgic_misr; ++ u32 ret = 0; ++ ++ if (misr & ICH_MISR_EOI) ++ ret |= INT_STATUS_EOI; ++ if (misr & ICH_MISR_U) ++ ret |= INT_STATUS_UNDERFLOW; ++ ++ return ret; ++} ++ ++static void vgic_v3_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) ++{ ++ u32 vmcr = vcpu->arch.vgic_cpu.vgic_v3.vgic_vmcr; ++ ++ vmcrp->ctlr = (vmcr & ICH_VMCR_CTLR_MASK) >> ICH_VMCR_CTLR_SHIFT; ++ vmcrp->abpr = (vmcr & ICH_VMCR_BPR1_MASK) >> ICH_VMCR_BPR1_SHIFT; ++ vmcrp->bpr = (vmcr & ICH_VMCR_BPR0_MASK) >> ICH_VMCR_BPR0_SHIFT; ++ vmcrp->pmr = (vmcr & ICH_VMCR_PMR_MASK) >> ICH_VMCR_PMR_SHIFT; ++} ++ ++static void vgic_v3_enable_underflow(struct kvm_vcpu *vcpu) ++{ ++ vcpu->arch.vgic_cpu.vgic_v3.vgic_hcr |= ICH_HCR_UIE; ++} ++ ++static void vgic_v3_disable_underflow(struct kvm_vcpu *vcpu) ++{ ++ vcpu->arch.vgic_cpu.vgic_v3.vgic_hcr &= ~ICH_HCR_UIE; ++} ++ ++static void vgic_v3_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcrp) ++{ ++ u32 vmcr; ++ ++ vmcr = (vmcrp->ctlr << ICH_VMCR_CTLR_SHIFT) & ICH_VMCR_CTLR_MASK; ++ vmcr |= (vmcrp->abpr << ICH_VMCR_BPR1_SHIFT) & ICH_VMCR_BPR1_MASK; ++ vmcr |= (vmcrp->bpr << ICH_VMCR_BPR0_SHIFT) & ICH_VMCR_BPR0_MASK; ++ vmcr |= (vmcrp->pmr << ICH_VMCR_PMR_SHIFT) & ICH_VMCR_PMR_MASK; ++ ++ vcpu->arch.vgic_cpu.vgic_v3.vgic_vmcr = vmcr; ++} ++ ++static void vgic_v3_enable(struct kvm_vcpu *vcpu) ++{ ++ /* ++ * By forcing VMCR to zero, the GIC will restore the binary ++ * points to their reset values. Anything else resets to zero ++ * anyway. ++ */ ++ vcpu->arch.vgic_cpu.vgic_v3.vgic_vmcr = 0; ++ ++ /* Get the show on the road... */ ++ vcpu->arch.vgic_cpu.vgic_v3.vgic_hcr = ICH_HCR_EN; ++} ++ ++static const struct vgic_ops vgic_v3_ops = { ++ .get_lr = vgic_v3_get_lr, ++ .set_lr = vgic_v3_set_lr, ++ .sync_lr_elrsr = vgic_v3_sync_lr_elrsr, ++ .get_elrsr = vgic_v3_get_elrsr, ++ .get_eisr = vgic_v3_get_eisr, ++ .get_interrupt_status = vgic_v3_get_interrupt_status, ++ .enable_underflow = vgic_v3_enable_underflow, ++ .disable_underflow = vgic_v3_disable_underflow, ++ .get_vmcr = vgic_v3_get_vmcr, ++ .set_vmcr = vgic_v3_set_vmcr, ++ .enable = vgic_v3_enable, ++}; ++ ++static struct vgic_params vgic_v3_params; ++ ++/** ++ * vgic_v3_probe - probe for a GICv3 compatible interrupt controller in DT ++ * @node: pointer to the DT node ++ * @ops: address of a pointer to the GICv3 operations ++ * @params: address of a pointer to HW-specific parameters ++ * ++ * Returns 0 if a GICv3 has been found, with the low level operations ++ * in *ops and the HW parameters in *params. Returns an error code ++ * otherwise. ++ */ ++int vgic_v3_probe(struct device_node *vgic_node, ++ const struct vgic_ops **ops, ++ const struct vgic_params **params) ++{ ++ int ret = 0; ++ u32 gicv_idx; ++ struct resource vcpu_res; ++ struct vgic_params *vgic = &vgic_v3_params; ++ ++ vgic->maint_irq = irq_of_parse_and_map(vgic_node, 0); ++ if (!vgic->maint_irq) { ++ kvm_err("error getting vgic maintenance irq from DT\n"); ++ ret = -ENXIO; ++ goto out; ++ } ++ ++ ich_vtr_el2 = kvm_call_hyp(__vgic_v3_get_ich_vtr_el2); ++ ++ /* ++ * The ListRegs field is 5 bits, but there is a architectural ++ * maximum of 16 list registers. Just ignore bit 4... ++ */ ++ vgic->nr_lr = (ich_vtr_el2 & 0xf) + 1; ++ ++ if (of_property_read_u32(vgic_node, "#redistributor-regions", &gicv_idx)) ++ gicv_idx = 1; ++ ++ gicv_idx += 3; /* Also skip GICD, GICC, GICH */ ++ if (of_address_to_resource(vgic_node, gicv_idx, &vcpu_res)) { ++ kvm_err("Cannot obtain GICV region\n"); ++ ret = -ENXIO; ++ goto out; ++ } ++ vgic->vcpu_base = vcpu_res.start; ++ vgic->vctrl_base = NULL; ++ vgic->type = VGIC_V3; ++ ++ kvm_info("%s@%llx IRQ%d\n", vgic_node->name, ++ vcpu_res.start, vgic->maint_irq); ++ ++ *ops = &vgic_v3_ops; ++ *params = vgic; ++ ++out: ++ of_node_put(vgic_node); ++ return ret; ++} +diff --git a/virt/kvm/arm/vgic.c b/virt/kvm/arm/vgic.c +index 476d3bf..795ab48 100644 +--- a/virt/kvm/arm/vgic.c ++++ b/virt/kvm/arm/vgic.c +@@ -76,14 +76,6 @@ + #define IMPLEMENTER_ARM 0x43b + #define GICC_ARCH_VERSION_V2 0x2 + +-/* Physical address of vgic virtual cpu interface */ +-static phys_addr_t vgic_vcpu_base; +- +-/* Virtual control interface base address */ +-static void __iomem *vgic_vctrl_base; +- +-static struct device_node *vgic_node; +- + #define ACCESS_READ_VALUE (1 << 0) + #define ACCESS_READ_RAZ (0 << 0) + #define ACCESS_READ_MASK(x) ((x) & (1 << 0)) +@@ -94,12 +86,17 @@ static struct device_node *vgic_node; + #define ACCESS_WRITE_MASK(x) ((x) & (3 << 1)) + + static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu); ++static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu); + static void vgic_update_state(struct kvm *kvm); + static void vgic_kick_vcpus(struct kvm *kvm); + static void vgic_dispatch_sgi(struct kvm_vcpu *vcpu, u32 reg); +-static u32 vgic_nr_lr; ++static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr); ++static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, struct vgic_lr lr_desc); ++static void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); ++static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr); + +-static unsigned int vgic_maint_irq; ++static const struct vgic_ops *vgic_ops; ++static const struct vgic_params *vgic; + + static u32 *vgic_bitmap_get_reg(struct vgic_bitmap *x, + int cpuid, u32 offset) +@@ -593,18 +590,6 @@ static bool handle_mmio_sgi_reg(struct kvm_vcpu *vcpu, + return false; + } + +-#define LR_CPUID(lr) \ +- (((lr) & GICH_LR_PHYSID_CPUID) >> GICH_LR_PHYSID_CPUID_SHIFT) +-#define LR_IRQID(lr) \ +- ((lr) & GICH_LR_VIRTUALID) +- +-static void vgic_retire_lr(int lr_nr, int irq, struct vgic_cpu *vgic_cpu) +-{ +- clear_bit(lr_nr, vgic_cpu->lr_used); +- vgic_cpu->vgic_lr[lr_nr] &= ~GICH_LR_STATE; +- vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY; +-} +- + /** + * vgic_unqueue_irqs - move pending IRQs from LRs to the distributor + * @vgic_cpu: Pointer to the vgic_cpu struct holding the LRs +@@ -622,13 +607,10 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu) + struct vgic_dist *dist = &vcpu->kvm->arch.vgic; + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + int vcpu_id = vcpu->vcpu_id; +- int i, irq, source_cpu; +- u32 *lr; ++ int i; + + for_each_set_bit(i, vgic_cpu->lr_used, vgic_cpu->nr_lr) { +- lr = &vgic_cpu->vgic_lr[i]; +- irq = LR_IRQID(*lr); +- source_cpu = LR_CPUID(*lr); ++ struct vgic_lr lr = vgic_get_lr(vcpu, i); + + /* + * There are three options for the state bits: +@@ -640,7 +622,7 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu) + * If the LR holds only an active interrupt (not pending) then + * just leave it alone. + */ +- if ((*lr & GICH_LR_STATE) == GICH_LR_ACTIVE_BIT) ++ if ((lr.state & LR_STATE_MASK) == LR_STATE_ACTIVE) + continue; + + /* +@@ -649,18 +631,19 @@ static void vgic_unqueue_irqs(struct kvm_vcpu *vcpu) + * is fine, then we are only setting a few bits that were + * already set. + */ +- vgic_dist_irq_set(vcpu, irq); +- if (irq < VGIC_NR_SGIS) +- dist->irq_sgi_sources[vcpu_id][irq] |= 1 << source_cpu; +- *lr &= ~GICH_LR_PENDING_BIT; ++ vgic_dist_irq_set(vcpu, lr.irq); ++ if (lr.irq < VGIC_NR_SGIS) ++ dist->irq_sgi_sources[vcpu_id][lr.irq] |= 1 << lr.source; ++ lr.state &= ~LR_STATE_PENDING; ++ vgic_set_lr(vcpu, i, lr); + + /* + * If there's no state left on the LR (it could still be + * active), then the LR does not hold any useful info and can + * be marked as free for other use. + */ +- if (!(*lr & GICH_LR_STATE)) +- vgic_retire_lr(i, irq, vgic_cpu); ++ if (!(lr.state & LR_STATE_MASK)) ++ vgic_retire_lr(i, lr.irq, vcpu); + + /* Finally update the VGIC state. */ + vgic_update_state(vcpu->kvm); +@@ -989,8 +972,73 @@ static void vgic_update_state(struct kvm *kvm) + } + } + +-#define MK_LR_PEND(src, irq) \ +- (GICH_LR_PENDING_BIT | ((src) << GICH_LR_PHYSID_CPUID_SHIFT) | (irq)) ++static struct vgic_lr vgic_get_lr(const struct kvm_vcpu *vcpu, int lr) ++{ ++ return vgic_ops->get_lr(vcpu, lr); ++} ++ ++static void vgic_set_lr(struct kvm_vcpu *vcpu, int lr, ++ struct vgic_lr vlr) ++{ ++ vgic_ops->set_lr(vcpu, lr, vlr); ++} ++ ++static void vgic_sync_lr_elrsr(struct kvm_vcpu *vcpu, int lr, ++ struct vgic_lr vlr) ++{ ++ vgic_ops->sync_lr_elrsr(vcpu, lr, vlr); ++} ++ ++static inline u64 vgic_get_elrsr(struct kvm_vcpu *vcpu) ++{ ++ return vgic_ops->get_elrsr(vcpu); ++} ++ ++static inline u64 vgic_get_eisr(struct kvm_vcpu *vcpu) ++{ ++ return vgic_ops->get_eisr(vcpu); ++} ++ ++static inline u32 vgic_get_interrupt_status(struct kvm_vcpu *vcpu) ++{ ++ return vgic_ops->get_interrupt_status(vcpu); ++} ++ ++static inline void vgic_enable_underflow(struct kvm_vcpu *vcpu) ++{ ++ vgic_ops->enable_underflow(vcpu); ++} ++ ++static inline void vgic_disable_underflow(struct kvm_vcpu *vcpu) ++{ ++ vgic_ops->disable_underflow(vcpu); ++} ++ ++static inline void vgic_get_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr) ++{ ++ vgic_ops->get_vmcr(vcpu, vmcr); ++} ++ ++static void vgic_set_vmcr(struct kvm_vcpu *vcpu, struct vgic_vmcr *vmcr) ++{ ++ vgic_ops->set_vmcr(vcpu, vmcr); ++} ++ ++static inline void vgic_enable(struct kvm_vcpu *vcpu) ++{ ++ vgic_ops->enable(vcpu); ++} ++ ++static void vgic_retire_lr(int lr_nr, int irq, struct kvm_vcpu *vcpu) ++{ ++ struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; ++ struct vgic_lr vlr = vgic_get_lr(vcpu, lr_nr); ++ ++ vlr.state = 0; ++ vgic_set_lr(vcpu, lr_nr, vlr); ++ clear_bit(lr_nr, vgic_cpu->lr_used); ++ vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY; ++} + + /* + * An interrupt may have been disabled after being made pending on the +@@ -1006,13 +1054,13 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu) + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + int lr; + +- for_each_set_bit(lr, vgic_cpu->lr_used, vgic_cpu->nr_lr) { +- int irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID; ++ for_each_set_bit(lr, vgic_cpu->lr_used, vgic->nr_lr) { ++ struct vgic_lr vlr = vgic_get_lr(vcpu, lr); + +- if (!vgic_irq_is_enabled(vcpu, irq)) { +- vgic_retire_lr(lr, irq, vgic_cpu); +- if (vgic_irq_is_active(vcpu, irq)) +- vgic_irq_clear_active(vcpu, irq); ++ if (!vgic_irq_is_enabled(vcpu, vlr.irq)) { ++ vgic_retire_lr(lr, vlr.irq, vcpu); ++ if (vgic_irq_is_active(vcpu, vlr.irq)) ++ vgic_irq_clear_active(vcpu, vlr.irq); + } + } + } +@@ -1024,6 +1072,7 @@ static void vgic_retire_disabled_irqs(struct kvm_vcpu *vcpu) + static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) + { + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; ++ struct vgic_lr vlr; + int lr; + + /* Sanitize the input... */ +@@ -1036,28 +1085,34 @@ static bool vgic_queue_irq(struct kvm_vcpu *vcpu, u8 sgi_source_id, int irq) + lr = vgic_cpu->vgic_irq_lr_map[irq]; + + /* Do we have an active interrupt for the same CPUID? */ +- if (lr != LR_EMPTY && +- (LR_CPUID(vgic_cpu->vgic_lr[lr]) == sgi_source_id)) { +- kvm_debug("LR%d piggyback for IRQ%d %x\n", +- lr, irq, vgic_cpu->vgic_lr[lr]); +- BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); +- vgic_cpu->vgic_lr[lr] |= GICH_LR_PENDING_BIT; +- return true; ++ if (lr != LR_EMPTY) { ++ vlr = vgic_get_lr(vcpu, lr); ++ if (vlr.source == sgi_source_id) { ++ kvm_debug("LR%d piggyback for IRQ%d\n", lr, vlr.irq); ++ BUG_ON(!test_bit(lr, vgic_cpu->lr_used)); ++ vlr.state |= LR_STATE_PENDING; ++ vgic_set_lr(vcpu, lr, vlr); ++ return true; ++ } + } + + /* Try to use another LR for this interrupt */ + lr = find_first_zero_bit((unsigned long *)vgic_cpu->lr_used, +- vgic_cpu->nr_lr); +- if (lr >= vgic_cpu->nr_lr) ++ vgic->nr_lr); ++ if (lr >= vgic->nr_lr) + return false; + + kvm_debug("LR%d allocated for IRQ%d %x\n", lr, irq, sgi_source_id); +- vgic_cpu->vgic_lr[lr] = MK_LR_PEND(sgi_source_id, irq); + vgic_cpu->vgic_irq_lr_map[irq] = lr; + set_bit(lr, vgic_cpu->lr_used); + ++ vlr.irq = irq; ++ vlr.source = sgi_source_id; ++ vlr.state = LR_STATE_PENDING; + if (!vgic_irq_is_edge(vcpu, irq)) +- vgic_cpu->vgic_lr[lr] |= GICH_LR_EOI; ++ vlr.state |= LR_EOI_INT; ++ ++ vgic_set_lr(vcpu, lr, vlr); + + return true; + } +@@ -1155,9 +1210,9 @@ static void __kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu) + + epilog: + if (overflow) { +- vgic_cpu->vgic_hcr |= GICH_HCR_UIE; ++ vgic_enable_underflow(vcpu); + } else { +- vgic_cpu->vgic_hcr &= ~GICH_HCR_UIE; ++ vgic_disable_underflow(vcpu); + /* + * We're about to run this VCPU, and we've consumed + * everything the distributor had in store for +@@ -1170,44 +1225,46 @@ epilog: + + static bool vgic_process_maintenance(struct kvm_vcpu *vcpu) + { +- struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; ++ u32 status = vgic_get_interrupt_status(vcpu); + bool level_pending = false; + +- kvm_debug("MISR = %08x\n", vgic_cpu->vgic_misr); ++ kvm_debug("STATUS = %08x\n", status); + +- if (vgic_cpu->vgic_misr & GICH_MISR_EOI) { ++ if (status & INT_STATUS_EOI) { + /* + * Some level interrupts have been EOIed. Clear their + * active bit. + */ +- int lr, irq; ++ u64 eisr = vgic_get_eisr(vcpu); ++ unsigned long *eisr_ptr = (unsigned long *)&eisr; ++ int lr; + +- for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_eisr, +- vgic_cpu->nr_lr) { +- irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID; ++ for_each_set_bit(lr, eisr_ptr, vgic->nr_lr) { ++ struct vgic_lr vlr = vgic_get_lr(vcpu, lr); + +- vgic_irq_clear_active(vcpu, irq); +- vgic_cpu->vgic_lr[lr] &= ~GICH_LR_EOI; ++ vgic_irq_clear_active(vcpu, vlr.irq); ++ WARN_ON(vlr.state & LR_STATE_MASK); ++ vlr.state = 0; ++ vgic_set_lr(vcpu, lr, vlr); + + /* Any additional pending interrupt? */ +- if (vgic_dist_irq_is_pending(vcpu, irq)) { +- vgic_cpu_irq_set(vcpu, irq); ++ if (vgic_dist_irq_is_pending(vcpu, vlr.irq)) { ++ vgic_cpu_irq_set(vcpu, vlr.irq); + level_pending = true; + } else { +- vgic_cpu_irq_clear(vcpu, irq); ++ vgic_cpu_irq_clear(vcpu, vlr.irq); + } + + /* + * Despite being EOIed, the LR may not have + * been marked as empty. + */ +- set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr); +- vgic_cpu->vgic_lr[lr] &= ~GICH_LR_ACTIVE_BIT; ++ vgic_sync_lr_elrsr(vcpu, lr, vlr); + } + } + +- if (vgic_cpu->vgic_misr & GICH_MISR_U) +- vgic_cpu->vgic_hcr &= ~GICH_HCR_UIE; ++ if (status & INT_STATUS_UNDERFLOW) ++ vgic_disable_underflow(vcpu); + + return level_pending; + } +@@ -1220,29 +1277,31 @@ static void __kvm_vgic_sync_hwstate(struct kvm_vcpu *vcpu) + { + struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; + struct vgic_dist *dist = &vcpu->kvm->arch.vgic; ++ u64 elrsr; ++ unsigned long *elrsr_ptr; + int lr, pending; + bool level_pending; + + level_pending = vgic_process_maintenance(vcpu); ++ elrsr = vgic_get_elrsr(vcpu); ++ elrsr_ptr = (unsigned long *)&elrsr; + + /* Clear mappings for empty LRs */ +- for_each_set_bit(lr, (unsigned long *)vgic_cpu->vgic_elrsr, +- vgic_cpu->nr_lr) { +- int irq; ++ for_each_set_bit(lr, elrsr_ptr, vgic->nr_lr) { ++ struct vgic_lr vlr; + + if (!test_and_clear_bit(lr, vgic_cpu->lr_used)) + continue; + +- irq = vgic_cpu->vgic_lr[lr] & GICH_LR_VIRTUALID; ++ vlr = vgic_get_lr(vcpu, lr); + +- BUG_ON(irq >= VGIC_NR_IRQS); +- vgic_cpu->vgic_irq_lr_map[irq] = LR_EMPTY; ++ BUG_ON(vlr.irq >= VGIC_NR_IRQS); ++ vgic_cpu->vgic_irq_lr_map[vlr.irq] = LR_EMPTY; + } + + /* Check if we still have something up our sleeve... */ +- pending = find_first_zero_bit((unsigned long *)vgic_cpu->vgic_elrsr, +- vgic_cpu->nr_lr); +- if (level_pending || pending < vgic_cpu->nr_lr) ++ pending = find_first_zero_bit(elrsr_ptr, vgic->nr_lr); ++ if (level_pending || pending < vgic->nr_lr) + set_bit(vcpu->vcpu_id, &dist->irq_pending_on_cpu); + } + +@@ -1432,21 +1491,20 @@ int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu) + } + + /* +- * By forcing VMCR to zero, the GIC will restore the binary +- * points to their reset values. Anything else resets to zero +- * anyway. ++ * Store the number of LRs per vcpu, so we don't have to go ++ * all the way to the distributor structure to find out. Only ++ * assembly code should use this one. + */ +- vgic_cpu->vgic_vmcr = 0; ++ vgic_cpu->nr_lr = vgic->nr_lr; + +- vgic_cpu->nr_lr = vgic_nr_lr; +- vgic_cpu->vgic_hcr = GICH_HCR_EN; /* Get the show on the road... */ ++ vgic_enable(vcpu); + + return 0; + } + + static void vgic_init_maintenance_interrupt(void *info) + { +- enable_percpu_irq(vgic_maint_irq, 0); ++ enable_percpu_irq(vgic->maint_irq, 0); + } + + static int vgic_cpu_notify(struct notifier_block *self, +@@ -1459,7 +1517,7 @@ static int vgic_cpu_notify(struct notifier_block *self, + break; + case CPU_DYING: + case CPU_DYING_FROZEN: +- disable_percpu_irq(vgic_maint_irq); ++ disable_percpu_irq(vgic->maint_irq); + break; + } + +@@ -1470,30 +1528,37 @@ static struct notifier_block vgic_cpu_nb = { + .notifier_call = vgic_cpu_notify, + }; + ++static const struct of_device_id vgic_ids[] = { ++ { .compatible = "arm,cortex-a15-gic", .data = vgic_v2_probe, }, ++ { .compatible = "arm,gic-v3", .data = vgic_v3_probe, }, ++ {}, ++}; ++ + int kvm_vgic_hyp_init(void) + { ++ const struct of_device_id *matched_id; ++ int (*vgic_probe)(struct device_node *,const struct vgic_ops **, ++ const struct vgic_params **); ++ struct device_node *vgic_node; + int ret; +- struct resource vctrl_res; +- struct resource vcpu_res; + +- vgic_node = of_find_compatible_node(NULL, NULL, "arm,cortex-a15-gic"); ++ vgic_node = of_find_matching_node_and_match(NULL, ++ vgic_ids, &matched_id); + if (!vgic_node) { +- kvm_err("error: no compatible vgic node in DT\n"); ++ kvm_err("error: no compatible GIC node found\n"); + return -ENODEV; + } + +- vgic_maint_irq = irq_of_parse_and_map(vgic_node, 0); +- if (!vgic_maint_irq) { +- kvm_err("error getting vgic maintenance irq from DT\n"); +- ret = -ENXIO; +- goto out; +- } ++ vgic_probe = matched_id->data; ++ ret = vgic_probe(vgic_node, &vgic_ops, &vgic); ++ if (ret) ++ return ret; + +- ret = request_percpu_irq(vgic_maint_irq, vgic_maintenance_handler, ++ ret = request_percpu_irq(vgic->maint_irq, vgic_maintenance_handler, + "vgic", kvm_get_running_vcpus()); + if (ret) { +- kvm_err("Cannot register interrupt %d\n", vgic_maint_irq); +- goto out; ++ kvm_err("Cannot register interrupt %d\n", vgic->maint_irq); ++ return ret; + } + + ret = __register_cpu_notifier(&vgic_cpu_nb); +@@ -1502,65 +1567,15 @@ int kvm_vgic_hyp_init(void) + goto out_free_irq; + } + +- ret = of_address_to_resource(vgic_node, 2, &vctrl_res); +- if (ret) { +- kvm_err("Cannot obtain VCTRL resource\n"); +- goto out_free_irq; +- } +- +- vgic_vctrl_base = of_iomap(vgic_node, 2); +- if (!vgic_vctrl_base) { +- kvm_err("Cannot ioremap VCTRL\n"); +- ret = -ENOMEM; +- goto out_free_irq; +- } +- +- vgic_nr_lr = readl_relaxed(vgic_vctrl_base + GICH_VTR); +- vgic_nr_lr = (vgic_nr_lr & 0x3f) + 1; +- +- ret = create_hyp_io_mappings(vgic_vctrl_base, +- vgic_vctrl_base + resource_size(&vctrl_res), +- vctrl_res.start); +- if (ret) { +- kvm_err("Cannot map VCTRL into hyp\n"); +- goto out_unmap; +- } +- +- if (of_address_to_resource(vgic_node, 3, &vcpu_res)) { +- kvm_err("Cannot obtain VCPU resource\n"); +- ret = -ENXIO; +- goto out_unmap; +- } +- +- if (!PAGE_ALIGNED(vcpu_res.start)) { +- kvm_err("GICV physical address 0x%llx not page aligned\n", +- (unsigned long long)vcpu_res.start); +- ret = -ENXIO; +- goto out_unmap; +- } +- +- if (!PAGE_ALIGNED(resource_size(&vcpu_res))) { +- kvm_err("GICV size 0x%llx not a multiple of page size 0x%lx\n", +- (unsigned long long)resource_size(&vcpu_res), +- PAGE_SIZE); +- ret = -ENXIO; +- goto out_unmap; +- } +- +- vgic_vcpu_base = vcpu_res.start; +- +- kvm_info("%s@%llx IRQ%d\n", vgic_node->name, +- vctrl_res.start, vgic_maint_irq); + on_each_cpu(vgic_init_maintenance_interrupt, NULL, 1); + +- goto out; ++ /* Callback into for arch code for setup */ ++ vgic_arch_setup(vgic); ++ ++ return 0; + +-out_unmap: +- iounmap(vgic_vctrl_base); + out_free_irq: +- free_percpu_irq(vgic_maint_irq, kvm_get_running_vcpus()); +-out: +- of_node_put(vgic_node); ++ free_percpu_irq(vgic->maint_irq, kvm_get_running_vcpus()); + return ret; + } + +@@ -1593,7 +1608,7 @@ int kvm_vgic_init(struct kvm *kvm) + } + + ret = kvm_phys_addr_ioremap(kvm, kvm->arch.vgic.vgic_cpu_base, +- vgic_vcpu_base, KVM_VGIC_V2_CPU_SIZE); ++ vgic->vcpu_base, KVM_VGIC_V2_CPU_SIZE); + if (ret) { + kvm_err("Unable to remap VGIC CPU to VCPU\n"); + goto out; +@@ -1639,7 +1654,8 @@ int kvm_vgic_create(struct kvm *kvm) + } + + spin_lock_init(&kvm->arch.vgic.lock); +- kvm->arch.vgic.vctrl_base = vgic_vctrl_base; ++ kvm->arch.vgic.in_kernel = true; ++ kvm->arch.vgic.vctrl_base = vgic->vctrl_base; + kvm->arch.vgic.vgic_dist_base = VGIC_ADDR_UNDEF; + kvm->arch.vgic.vgic_cpu_base = VGIC_ADDR_UNDEF; + +@@ -1738,39 +1754,40 @@ int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write) + static bool handle_cpu_mmio_misc(struct kvm_vcpu *vcpu, + struct kvm_exit_mmio *mmio, phys_addr_t offset) + { +- struct vgic_cpu *vgic_cpu = &vcpu->arch.vgic_cpu; +- u32 reg, mask = 0, shift = 0; + bool updated = false; ++ struct vgic_vmcr vmcr; ++ u32 *vmcr_field; ++ u32 reg; ++ ++ vgic_get_vmcr(vcpu, &vmcr); + + switch (offset & ~0x3) { + case GIC_CPU_CTRL: +- mask = GICH_VMCR_CTRL_MASK; +- shift = GICH_VMCR_CTRL_SHIFT; ++ vmcr_field = &vmcr.ctlr; + break; + case GIC_CPU_PRIMASK: +- mask = GICH_VMCR_PRIMASK_MASK; +- shift = GICH_VMCR_PRIMASK_SHIFT; ++ vmcr_field = &vmcr.pmr; + break; + case GIC_CPU_BINPOINT: +- mask = GICH_VMCR_BINPOINT_MASK; +- shift = GICH_VMCR_BINPOINT_SHIFT; ++ vmcr_field = &vmcr.bpr; + break; + case GIC_CPU_ALIAS_BINPOINT: +- mask = GICH_VMCR_ALIAS_BINPOINT_MASK; +- shift = GICH_VMCR_ALIAS_BINPOINT_SHIFT; ++ vmcr_field = &vmcr.abpr; + break; ++ default: ++ BUG(); + } + + if (!mmio->is_write) { +- reg = (vgic_cpu->vgic_vmcr & mask) >> shift; ++ reg = *vmcr_field; + mmio_data_write(mmio, ~0, reg); + } else { + reg = mmio_data_read(mmio, ~0); +- reg = (reg << shift) & mask; +- if (reg != (vgic_cpu->vgic_vmcr & mask)) ++ if (reg != *vmcr_field) { ++ *vmcr_field = reg; ++ vgic_set_vmcr(vcpu, &vmcr); + updated = true; +- vgic_cpu->vgic_vmcr &= ~mask; +- vgic_cpu->vgic_vmcr |= reg; ++ } + } + return updated; + } diff --git a/freed-ora/current/master/kernel.spec b/freed-ora/current/master/kernel.spec index 6df853420..2e91872dc 100644 --- a/freed-ora/current/master/kernel.spec +++ b/freed-ora/current/master/kernel.spec @@ -8,6 +8,8 @@ Summary: The Linux kernel # be 0. %global released_kernel 1 +%global aarch64patches 1 + # Sign modules on x86. Make sure the config files match this setting if more # architectures are added. %ifarch %{ix86} x86_64 @@ -46,7 +48,7 @@ Summary: The Linux kernel # base_sublevel is the kernel version we're starting with and patching # on top of -- for example, 3.1-rc7-git1 starts with a 3.0 base, # which yields a base_sublevel of 0. -%define base_sublevel 15 +%define base_sublevel 16 # librev starts empty, then 1, etc, as the linux-libre tarball # changes. This is only used to determine which tarball to use. @@ -56,9 +58,9 @@ Summary: The Linux kernel %define basegnu -gnu%{?librev} # To be inserted between "patch" and "-2.6.". -#define stablelibre -3.14%{?stablegnux} -%define rcrevlibre -3.14%{?rcrevgnux} -#define gitrevlibre -3.14%{?gitrevgnux} +#define stablelibre -3.16%{?stablegnux} +%define rcrevlibre -3.16%{?rcrevgnux} +#define gitrevlibre -3.16%{?gitrevgnux} %if 0%{?stablelibre:1} %define stablegnu -gnu%{?librev} @@ -408,7 +410,11 @@ Summary: The Linux kernel # Which is a BadThing(tm). # We only build kernel-headers on the following... +%if 0%{?aarch64patches} %define nobuildarches i386 s390 +%else +%define nobuildarches i386 s390 aarch64 +%endif %ifarch %nobuildarches %define with_up 0 @@ -593,8 +599,6 @@ Patch09: upstream-reverts.patch # Standalone patches -Patch390: defaults-acpi-video.patch - Patch450: input-kill-stupid-messages.patch Patch452: no-pcspkr-modalias.patch @@ -602,6 +606,8 @@ Patch460: serial-460800.patch Patch470: die-floppy-die.patch +Patch500: Revert-Revert-ACPI-video-change-acpi-video-brightnes.patch + Patch510: silence-noise.patch Patch530: silence-fbcon-logo.patch @@ -617,7 +623,7 @@ Patch800: crash-driver.patch # secure boot Patch1000: secure-modules.patch Patch1001: modsign-uefi.patch -Patch1002: sb-hibernate.patch +# atch1002: sb-hibernate.patch Patch1003: sysrq-secure-boot.patch # virt + ksm patches @@ -645,19 +651,12 @@ Patch15000: nowatchdog-on-virt.patch # ARM64 -# ARM - -# lpae - -# ARM omap - -# ARM tegra +# ARMv7 Patch21020: arm-tegra-usb-no-reset-linux33.patch - -# ARM i.MX6 - -# ARM sunxi (AllWinner) -Patch21025: 0001-ARM-sunxi-Add-driver-for-SD-MMC-hosts-found-on-Allwi.patch +Patch21021: arm-beagle.patch +Patch21022: arm-imx6-utilite.patch +# http://www.spinics.net/lists/linux-tegra/msg17948.html +Patch21023: arm-tegra-drmdetection.patch #rhbz 754518 Patch21235: scsi-sd_revalidate_disk-prevent-NULL-ptr-deref.patch @@ -675,42 +674,29 @@ Patch25047: drm-radeon-Disable-writeback-by-default-on-ppc.patch #rhbz 1025603 Patch25063: disable-libdw-unwind-on-non-x86.patch -#rhbz 1048314 -Patch25048: 0001-HID-rmi-introduce-RMI-driver-for-Synaptics-touchpads.patch - -#rhbz 1089583 -Patch25064: 0001-HID-rmi-do-not-handle-touchscreens-through-hid-rmi.patch - -#rhbz 1090161 -Patch25072: HID-rmi-do-not-fetch-more-than-16-bytes-in-a-query.patch - #rhbz 983342 1093120 Patch25069: 0001-acpi-video-Add-4-new-models-to-the-use_native_backli.patch -Patch25071: s390-appldata-add-slab.h-for-kzalloc-kfree.patch - - -# CVE-2014-3917 rhbz 1102571 1102715 -Patch25093: auditsc-audit_krule-mask-accesses-need-bounds-checking.patch - Patch26000: perf-lib64.patch # Patch series from Hans for various backlight and platform driver fixes -Patch26001: thinkpad_acpi-Add-mappings-for-F9-F12-hotkeys-on-X24.patch Patch26002: samsung-laptop-Add-broken-acpi-video-quirk-for-NC210.patch -Patch26003: ideapad-laptop-Blacklist-rfkill-control-on-the-Lenov.patch Patch26004: asus-wmi-Add-a-no-backlight-quirk.patch Patch26005: eeepc-wmi-Add-no-backlight-quirk-for-Asus-H87I-PLUS-.patch -Patch26006: acpi-video-Don-t-register-acpi_video_resume-notifier.patch -Patch26007: acpi-video-Add-an-acpi_video_unregister_backlight-fu.patch -Patch26008: acer-wmi-Switch-to-acpi_video_unregister_backlight.patch -Patch26009: acer-wmi-Add-Aspire-5741-to-video_vendor_dmi_table.patch -Patch26010: nouveau-Don-t-check-acpi_video_backlight_support-bef.patch -Patch26011: backlight-Add-backlight-device-un-registration-notif.patch -Patch26012: acpi-video-Unregister-the-backlight-device-if-a-raw-.patch Patch26013: acpi-video-Add-use-native-backlight-quirk-for-the-Th.patch Patch26014: acpi-video-Add-use_native_backlight-quirk-for-HP-Pro.patch +Patch25109: revert-input-wacom-testing-result-shows-get_report-is-unnecessary.patch + +#rhbz 1021036, submitted upstream +Patch25110: 0001-ideapad-laptop-Change-Lenovo-Yoga-2-series-rfkill-ha.patch + +#rhbz 1117942 +Patch25118: sched-fix-sched_setparam-policy-1-logic.patch + +# git clone ssh://git.fedorahosted.org/git/kernel-arm64.git, git diff master...devel +Patch30000: kernel-arm64.patch + # END OF PATCH DEFINITIONS %endif @@ -1392,7 +1378,9 @@ ApplyPatch 0001-lib-cpumask-Make-CPUMASK_OFFSTACK-usable-without-deb.patch # ARM # ApplyPatch arm-tegra-usb-no-reset-linux33.patch -ApplyPatch 0001-ARM-sunxi-Add-driver-for-SD-MMC-hosts-found-on-Allwi.patch +ApplyPatch arm-beagle.patch +ApplyPatch arm-imx6-utilite.patch +ApplyPatch arm-tegra-drmdetection.patch # # bugfixes to drivers and filesystems @@ -1413,7 +1401,6 @@ ApplyPatch 0001-ARM-sunxi-Add-driver-for-SD-MMC-hosts-found-on-Allwi.patch # WMI # ACPI -ApplyPatch defaults-acpi-video.patch # # PCI @@ -1425,6 +1412,8 @@ ApplyPatch defaults-acpi-video.patch # ACPI +ApplyPatch Revert-Revert-ACPI-video-change-acpi-video-brightnes.patch + # ALSA # Networking @@ -1460,7 +1449,7 @@ ApplyPatch crash-driver.patch # secure boot ApplyPatch secure-modules.patch ApplyPatch modsign-uefi.patch -ApplyPatch sb-hibernate.patch +# pplyPatch sb-hibernate.patch ApplyPatch sysrq-secure-boot.patch # Assorted Virt Fixes @@ -1498,42 +1487,36 @@ ApplyPatch ath9k_rx_dma_stop_check.patch ApplyPatch drm-radeon-Disable-writeback-by-default-on-ppc.patch -#rhbz 1048314 -ApplyPatch 0001-HID-rmi-introduce-RMI-driver-for-Synaptics-touchpads.patch -#rhbz 1089583 -ApplyPatch 0001-HID-rmi-do-not-handle-touchscreens-through-hid-rmi.patch -#rhbz 1090161 -ApplyPatch HID-rmi-do-not-fetch-more-than-16-bytes-in-a-query.patch - #rhbz 1025603 ApplyPatch disable-libdw-unwind-on-non-x86.patch #rhbz 983342 1093120 ApplyPatch 0001-acpi-video-Add-4-new-models-to-the-use_native_backli.patch -ApplyPatch s390-appldata-add-slab.h-for-kzalloc-kfree.patch - -# CVE-2014-3917 rhbz 1102571 1102715 -ApplyPatch auditsc-audit_krule-mask-accesses-need-bounds-checking.patch - ApplyPatch perf-lib64.patch # Patch series from Hans for various backlight and platform driver fixes -ApplyPatch thinkpad_acpi-Add-mappings-for-F9-F12-hotkeys-on-X24.patch ApplyPatch samsung-laptop-Add-broken-acpi-video-quirk-for-NC210.patch -ApplyPatch ideapad-laptop-Blacklist-rfkill-control-on-the-Lenov.patch ApplyPatch asus-wmi-Add-a-no-backlight-quirk.patch ApplyPatch eeepc-wmi-Add-no-backlight-quirk-for-Asus-H87I-PLUS-.patch -ApplyPatch acpi-video-Don-t-register-acpi_video_resume-notifier.patch -ApplyPatch acpi-video-Add-an-acpi_video_unregister_backlight-fu.patch -ApplyPatch acer-wmi-Switch-to-acpi_video_unregister_backlight.patch -ApplyPatch acer-wmi-Add-Aspire-5741-to-video_vendor_dmi_table.patch -ApplyPatch nouveau-Don-t-check-acpi_video_backlight_support-bef.patch -ApplyPatch backlight-Add-backlight-device-un-registration-notif.patch -ApplyPatch acpi-video-Unregister-the-backlight-device-if-a-raw-.patch ApplyPatch acpi-video-Add-use-native-backlight-quirk-for-the-Th.patch ApplyPatch acpi-video-Add-use_native_backlight-quirk-for-HP-Pro.patch +ApplyPatch revert-input-wacom-testing-result-shows-get_report-is-unnecessary.patch + +#rhbz 1021036, submitted upstream +ApplyPatch 0001-ideapad-laptop-Change-Lenovo-Yoga-2-series-rfkill-ha.patch + +#rhbz 1117942 +ApplyPatch sched-fix-sched_setparam-policy-1-logic.patch + +%if 0%{?aarch64patches} +ApplyPatch kernel-arm64.patch +%ifnarch aarch64 # this is stupid, but i want to notice before secondary koji does. +ApplyPatch kernel-arm64.patch -R +%endif +%endif + # END OF PATCH APPLICATIONS %endif @@ -1719,6 +1702,7 @@ BuildKernel() { fi %{__install} -D -m 444 ldconfig-kernel.conf \ $RPM_BUILD_ROOT/etc/ld.so.conf.d/kernel-$KernelVer.conf + rm -rf $RPM_BUILD_ROOT/lib/modules/$KernelVer/vdso/.build-id %endif # And save the headers/makefiles etc for building modules against @@ -2356,6 +2340,8 @@ fi %if %{1}\ %{expand:%%files -f kernel-%{?2:%{2}-}core.list %{?2:%{2}-}core}\ %defattr(-,root,root)\ +%{!?_licensedir:%global license %%doc}\ +%license linux-%{KVERREL}/COPYING\ /%{image_install_path}/%{?-k:%{-k*}}%{!?-k:vmlinuz}-%{KVERREL}%{?2:+%{2}}\ /%{image_install_path}/.vmlinuz-%{KVERREL}%{?2:+%{2}}.hmac \ %ifarch %{arm} aarch64\ @@ -2410,15 +2396,265 @@ fi # # # ___________________________________________________________ -# / This branch is for Fedora 21. You probably want to commit \ -# _____ ____ _ \ to the F-20 branch instead, or in addition to this one. / -# | ___|___ \/ | ----------------------------------------------------------- -# | |_ __) | | \ ^__^ -# | _| / __/| | \ (@@)\_______ -# |_| |_____|_| (__)\ )\/\ +# / This branch is for Fedora 22. You probably want to commit \ +# _____ ____ ____ \ to the f21 branch instead, or in addition to this one. / +# | ___|___ \|___ \ ----------------------------------------------------------- +# | |_ __) | __) | \ ^__^ +# | _| / __/ / __/ \ (@@)\_______ +# |_| |_____|_____| (__)\ )\/\ # ||----w | # || || %changelog +* Thu Aug 7 2014 Alexandre Oliva <lxoliva@fsfla.org> -libre +- GNU Linux-libre 3.16-gnu. + +* Mon Aug 04 2014 Josh Boyer <jwboyer@gmail.com> - 3.16.0-1 +- Linux v3.16 +- Disable debugging options. + +* Sun Aug 3 2014 Peter Robinson <pbrobinson@redhat.com> +- Minor config updates for Armada and Sunxi ARM devices + +* Fri Aug 01 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc7.git4.1 +- Linux v3.16-rc7-84-g6f0928036bcb + +* Thu Jul 31 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc7.git3.1 +- Linux v3.16-rc7-76-g3a1122d26c62 + +* Wed Jul 30 2014 Kyle McMartin <kyle@fedoraproject.org> +- kernel-arm64.patch: fix up merge conflict and re-enable + +* Wed Jul 30 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc7.git2.1 +- Linux v3.16-rc7-64-g26bcd8b72563 +- Temporarily disable aarch64patches + +* Wed Jul 30 2014 Josh Boyer <jwboyer@fedoraproject.org> +- Apply different patch from Milan Broz to fix LUKS partitions (rhbz 1115120) + +* Tue Jul 29 2014 Kyle McMartin <kyle@fedoraproject.org> +- kernel-arm64.patch: update from upstream git. + +* Tue Jul 29 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc7.git1.1 +- Linux v3.16-rc7-7-g31dab719fa50 +- Reenable debugging options. + +* Mon Jul 28 2014 Josh Boyer <jwboyer@fedoraproject.org> +- Make sure acpi brightness_switch is disabled (like forever in Fedora) +- CVE-2014-5077 sctp: fix NULL ptr dereference (rhbz 1122982 1123696) + +* Mon Jul 28 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc7.git0.1 +- Linux v3.16-rc7 +- Disable debugging options. + +* Mon Jul 28 2014 Peter Robinson <pbrobinson@fedoraproject.org> +- Add patch to fix loading of tegra drm using device tree + +* Sat Jul 26 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc6.git3.1 +- Linux v3.16-rc6-139-g9c5502189fa0 + +* Fri Jul 25 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc6.git2.1 +- Linux v3.16-rc6-118-g82e13c71bc65 +- Fix selinux sock_graft hook for AF_ALG address family (rhbz 1115120) + +* Thu Jul 24 2014 Kyle McMartin <kyle@fedoraproject.org> +- kernel-arm64.patch: update from upstream git. +- arm64: update config-arm64 to include PCI support. + +* Thu Jul 24 2014 Josh Boyer <jwboyer@fedoraproject.org> +- CVE-2014-5045 vfs: refcount issues during lazy umount on symlink (rhbz 1122471 1122482) +- Fix regression in sched_setparam (rhbz 1117942) + +* Tue Jul 22 2014 Justin M. Forbes <jforbes@fedoraproject.org> - 3.16.0-0.rc6.git1.1 +- Linux v3.16-rc6-75-g15ba223 +- Reenable debugging options. + +* Mon Jul 21 2014 Justin M. Forbes <jforbes@fedoraproject.org> - 3.16.0-0.rc6.git0.1 +- Linux v3.16-rc6 +- Disable debugging options. + +* Mon Jul 21 2014 Peter Robinson <pbrobinson@fedoraproject.org> +- Minor ARMv7 config update + +* Thu Jul 17 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc5.git2.1 +- Linux v3.16-rc5-143-gb6603fe574af + +* Wed Jul 16 2014 Josh Boyer <jwboyer@fedoraproject.org> +- Enable hermes prism driver (rhbz 1120393) + +* Wed Jul 16 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc5.git1.1 +- Linux v3.16-rc5-130-g2da294474093 +- Reenable debugging options. + +* Mon Jul 14 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc5.git0.1 +- Linux v3.16-rc5 +- Fix i915 regression with external monitors (rhbz 1117008) +- Disable debugging options. + +* Sat Jul 12 2014 Tom Callaway <spot@fedoraproject.org> +- Fix license handling (I hope) + +* Fri Jul 11 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc4.git3.1 +- Linux v3.16-rc4-120-g85d90faed31e + +* Thu Jul 10 2014 Peter Robinson <pbrobinson@fedoraproject.org> +- Rebase Utilute and BeagleBone patches +- Minor ARM updates +- Enable ISL12057 RTC for ARM (NetGear ReadyNAS) + +* Wed Jul 09 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc4.git2.1 +- Linux v3.16-rc4-28-g163e40743f73 +- Fix bogus vdso .build-id links (rhbz 1117563) + +* Tue Jul 08 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc4.git1.1 +- Linux v3.16-rc4-20-g448bfad8a185 +- Reenable debugging options. + +* Sun Jul 06 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc4.git0.1 +- Linux v3.16-rc4 +- Disable debugging options. + +* Fri Jul 04 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc3.git3.1 +- Linux v3.16-rc3-149-g034a0f6b7db7 + +* Wed Jul 02 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc3.git2.1 +- Linux v3.16-rc3-62-gd92a333a65a1 +- Add patch to fix virt_blk oops (rhbz 1113805) + +* Wed Jul 02 2014 Kyle McMartin <kyle@fedoraproject.org> +- arm64: build-in ahci, ethernet, and rtc drivers. + +* Tue Jul 01 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc3.git1.1 +- Linux v3.16-rc3-6-g16874b2cb867 +- Reenable debugging options. + +* Tue Jul 1 2014 Peter Robinson <pbrobinson@fedoraproject.org> +- Minor ARMv7 cleanup + +* Mon Jun 30 2014 Kyle McMartin <kyle@fedoraproject.org> +- kernel-arm64.patch, update from git. + +* Mon Jun 30 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc3.git0.1.1 +- Linux v3.16-rc3 +- Enable USB rtsx drivers (rhbz 1114229) +- Disable debugging options. + +* Fri Jun 27 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc2.git4.1 +- Linux v3.16-rc2-222-g3493860c76eb + +* Fri Jun 27 2014 Hans de Goede <hdegoede@redhat.com> +- Add patch to fix wifi on lenove yoga 2 series (rhbz#1021036) + +* Thu Jun 26 2014 Josh Boyer <jwboyer@fedoraproject.org> +- Enable rtl8192ee (rhbz 1113422) + +* Thu Jun 26 2014 Kyle McMartin <kyle@fedoraproject.org> - 3.16.0-0.rc2.git3.2 +- Add kernel-arm64.patch, which contains AArch64 support destined for upstream. + ssh://git.fedorahosted.org/git/kernel-arm64.git is Mark Salter's source tree + integrating these patches on the devel branch. I've added a twiddle to the + top of the spec file to disable the aarch64 patchset, and also set aarch64 + to nobuildarches, so we still get kernel-headers, but no one accidentally + installs a non-booting kernel if the patchset causes rejects during a + rebase. + +* Thu Jun 26 2014 Josh Boyer <jwboyer@fedoraproject.org> +- Trimmed changelog, see fedpkg git for earlier history. + +* Thu Jun 26 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc2.git3.1 +- Linux v3.16-rc2-211-gd7933ab727ed + +* Wed Jun 25 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc2.git2.1 +- Linux v3.16-rc2-69-gd91d66e88ea9 + +* Wed Jun 25 2014 Josh Boyer <jwboyer@fedoraproject.org> +- Revert commit that breaks Wacom Intuos4 from Benjamin Tissoires + +* Tue Jun 24 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc2.git1.1 +- Linux v3.16-rc2-35-g8b8f5d971584 +- Reenable debugging options. + +* Mon Jun 23 2014 Josh Boyer <jwboyer@fedoraproject.org> +- CVE-2014-4508 BUG in x86_32 syscall auditing (rhbz 1111590 1112073) + +* Mon Jun 23 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc2.git0.1 +- Linux v3.16-rc2 +- Disable debugging options. + +* Sun Jun 22 2014 Peter Robinson <pbrobinson@fedoraproject.org> +- Enable Exynos now it's finally multi platform capable +- Minor TI Keystone update +- ARM config cleanups + +* Fri Jun 20 2014 Josh Boyer <jwboyer@fedoraproject.org> +- Bring in intel_pstate regression fixes for BayTrail (rhbz 1111920) + +* Fri Jun 20 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc1.git4.1 +- Linux v3.16-rc1-215-g3c8fb5044583 + +* Thu Jun 19 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc1.git3.1 +- Linux v3.16-rc1-112-g894e552cfaa3 + +* Thu Jun 19 2014 Peter Robinson <pbrobinson@fedoraproject.org> +- Add missing bits for NVIDIA Jetson TK1 (thanks Stephen Warren) + +* Wed Jun 18 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc1.git2.1 +- Linux v3.16-rc1-17-ge99cfa2d0634 + +* Tue Jun 17 2014 Dennis Gilmore <dennis@ausil.us> +- when ipuv3 moved out of staging the config was renamed +- adjust the config to suit + +* Tue Jun 17 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc1.git1.1 +- Linux v3.16-rc1-2-gebe06187bf2a +- Reenable debugging options. + +* Mon Jun 16 2014 Peter Robinson <pbrobinson@fedoraproject.org> +- Enable Qualcomm SoCs on ARM + +* Mon Jun 16 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc1.git0.1 +- Linux v3.16-rc1 +- Disable debugging options. + +* Mon Jun 16 2014 Peter Robinson <pbrobinson@fedoraproject.org> +- ARM config updates for 3.16 + +* Sat Jun 14 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc0.git11.1 +- Linux v3.15-9930-g0e04c641b199 +- Enable CONFIG_RCU_NOCB_CPU(_ALL) (rbhz 1109113) + +* Fri Jun 13 2014 Peter Robinson <pbrobinson@fedoraproject.org> +- Add patch to fix build failure on aarch64 + +* Fri Jun 13 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc0.git10.1 +- Linux v3.15-9837-g682b7c1c8ea8 + +* Fri Jun 13 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc0.git9.1 +- Linux v3.15-8981-g5c02c392cd23 + +* Fri Jun 13 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc0.git8.1 +- Linux v3.15-8835-g859862ddd2b6 + +* Fri Jun 13 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc0.git7.1 +- Linux v3.15-8556-gdfb945473ae8 + +* Fri Jun 13 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc0.git6.1 +- Linux v3.15-8351-g9ee4d7a65383 + +* Thu Jun 12 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc0.git5.1 +- Linux v3.15-8163-g5b174fd6472b + +* Thu Jun 12 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc0.git4.1 +- Linux v3.15-7926-gd53b47c08d8f + +* Thu Jun 12 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc0.git3.1 +- Linux v3.15-7378-g14208b0ec569 + +* Wed Jun 11 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc0.git2.1 +- Linux v3.15-7283-gda85d191f58a + +* Tue Jun 10 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.16.0-0.rc0.git1.1 +- Linux v3.15-7218-g3f17ea6dea8b +- Reenable debugging options. + * Tue Jun 10 2014 Alexandre Oliva <lxoliva@fsfla.org> -libre - GNU Linux-libre 3.15-gnu. @@ -3032,6 +3268,7 @@ fi - Linux v3.13 - Disable debugging options. - Use versioned perf man pages tarball +<<<<<<< HEAD * Sat Jan 18 2014 Josh Boyer <jwboyer@fedoraproject.org> - 3.13.0-0.rc8.git4.1 - Linux v3.13-rc8-76-g7d0d46d @@ -4955,6 +5192,8 @@ fi * Tue Dec 11 2012 Dave Jones <davej@redhat.com> - 3.7.0-1 - Linux v3.7 +======= +>>>>>>> 9c9c166 ### # The following Emacs magic makes C-c C-e use UTC dates. # Local Variables: diff --git a/freed-ora/current/master/linux-libre-3.15-gnu.tar.xz.sign b/freed-ora/current/master/linux-libre-3.15-gnu.tar.xz.sign deleted file mode 100644 index e9480a945..000000000 --- a/freed-ora/current/master/linux-libre-3.15-gnu.tar.xz.sign +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v2.0.22 (GNU/Linux) - -iEYEABECAAYFAlOUzMkACgkQvLfPh359R6c4EACfaiJCVV77vCaaxhja+lKaC/we -MRQAnj/ZeKQQonle/OgGPtJ7v4PEVY9R -=RYoE ------END PGP SIGNATURE----- diff --git a/freed-ora/current/master/linux-libre-3.15-gnu.xdelta.xz b/freed-ora/current/master/linux-libre-3.15-gnu.xdelta.xz Binary files differdeleted file mode 100644 index c2d5b6c29..000000000 --- a/freed-ora/current/master/linux-libre-3.15-gnu.xdelta.xz +++ /dev/null diff --git a/freed-ora/current/master/linux-libre-3.15-gnu.xdelta.xz.sign b/freed-ora/current/master/linux-libre-3.15-gnu.xdelta.xz.sign deleted file mode 100644 index f598dd132..000000000 --- a/freed-ora/current/master/linux-libre-3.15-gnu.xdelta.xz.sign +++ /dev/null @@ -1,7 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v2.0.22 (GNU/Linux) - -iEYEABECAAYFAlOUzNAACgkQvLfPh359R6epsQCdHFTp+Qltdu/uHyG993ek4Reu -iZEAn1D9DkIy+Po4eRQUuAco8PItuOmY -=p8I5 ------END PGP SIGNATURE----- diff --git a/freed-ora/current/master/linux-libre-3.16-gnu.tar.xz.sign b/freed-ora/current/master/linux-libre-3.16-gnu.tar.xz.sign new file mode 100644 index 000000000..3e8561b7a --- /dev/null +++ b/freed-ora/current/master/linux-libre-3.16-gnu.tar.xz.sign @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iEYEABECAAYFAlPjSGsACgkQvLfPh359R6cckACeOH0z9GjXitaPNVMPNiRG20+p +r/4AmwaHeWNpVeiG46FutTuprz1Pur0C +=YBE5 +-----END PGP SIGNATURE----- diff --git a/freed-ora/current/master/linux-libre-3.16-gnu.xdelta.xz b/freed-ora/current/master/linux-libre-3.16-gnu.xdelta.xz Binary files differnew file mode 100644 index 000000000..cb1e91464 --- /dev/null +++ b/freed-ora/current/master/linux-libre-3.16-gnu.xdelta.xz diff --git a/freed-ora/current/master/linux-libre-3.16-gnu.xdelta.xz.sign b/freed-ora/current/master/linux-libre-3.16-gnu.xdelta.xz.sign new file mode 100644 index 000000000..ba33aa808 --- /dev/null +++ b/freed-ora/current/master/linux-libre-3.16-gnu.xdelta.xz.sign @@ -0,0 +1,7 @@ +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v2 + +iEYEABECAAYFAlPjSG0ACgkQvLfPh359R6duqACfZTCNloyjCHUy46DgcFKYzywE +4QoAnirQKn2z4U/tqe5dl4xELljo5vu2 +=PfGz +-----END PGP SIGNATURE----- diff --git a/freed-ora/current/master/modsign-uefi.patch b/freed-ora/current/master/modsign-uefi.patch index af6844d5a..5f8cc3313 100644 --- a/freed-ora/current/master/modsign-uefi.patch +++ b/freed-ora/current/master/modsign-uefi.patch @@ -1,7 +1,7 @@ Bugzilla: N/A Upstream-status: Fedora mustard for now -From 779183da2955e33a221c3f7a622766cd53e06d45 Mon Sep 17 00:00:00 2001 +From fa2bfe718da40bf24f92c85846577e9bc788882c Mon Sep 17 00:00:00 2001 From: Dave Howells <dhowells@redhat.com> Date: Tue, 23 Oct 2012 09:30:54 -0400 Subject: [PATCH 1/5] Add EFI signature data types @@ -15,12 +15,12 @@ Signed-off-by: David Howells <dhowells@redhat.com> 1 file changed, 20 insertions(+) diff --git a/include/linux/efi.h b/include/linux/efi.h -index 3a77a70fff27..4c7f7011ea19 100644 +index e73f391fd3c8..3d66a61bbbca 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h -@@ -575,6 +575,12 @@ typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long si - #define EFI_FILE_SYSTEM_GUID \ - EFI_GUID( 0x964e5b22, 0x6459, 0x11d2, 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b ) +@@ -578,6 +578,12 @@ typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long si + #define DEVICE_TREE_GUID \ + EFI_GUID( 0xb1b621d5, 0xf19c, 0x41a5, 0x83, 0x0b, 0xd9, 0x15, 0x2c, 0x69, 0xaa, 0xe0 ) +#define EFI_CERT_SHA256_GUID \ + EFI_GUID( 0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28 ) @@ -31,7 +31,7 @@ index 3a77a70fff27..4c7f7011ea19 100644 typedef struct { efi_guid_t guid; u64 table; -@@ -782,6 +788,20 @@ typedef struct _efi_file_io_interface { +@@ -793,6 +799,20 @@ typedef struct _efi_file_io_interface { #define EFI_INVALID_TABLE_ADDR (~0UL) @@ -53,10 +53,10 @@ index 3a77a70fff27..4c7f7011ea19 100644 * All runtime access to EFI goes through this structure: */ -- -1.9.0 +1.9.3 -From 8592d1f6a8cc8d901c94582b9d0b57d170a0940b Mon Sep 17 00:00:00 2001 +From 922e0512ce70101b596558d5bb075cd40a450322 Mon Sep 17 00:00:00 2001 From: Dave Howells <dhowells@redhat.com> Date: Tue, 23 Oct 2012 09:36:28 -0400 Subject: [PATCH 2/5] Add an EFI signature blob parser and key loader. @@ -218,12 +218,12 @@ index 000000000000..424896a0b169 + return 0; +} diff --git a/include/linux/efi.h b/include/linux/efi.h -index 4c7f7011ea19..96174a7f9e90 100644 +index 3d66a61bbbca..7854ff3c0f11 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h -@@ -883,6 +883,10 @@ extern int efi_set_rtc_mmss(const struct timespec *now); - extern void efi_reserve_boot_services(void); - extern struct efi_memory_map memmap; +@@ -901,6 +901,10 @@ extern struct efi_memory_map memmap; + (md) <= (efi_memory_desc_t *)((m)->map_end - (m)->desc_size); \ + (md) = (void *)(md) + (m)->desc_size) +struct key; +extern int __init parse_efi_signature_list(const void *data, size_t size, @@ -233,10 +233,10 @@ index 4c7f7011ea19..96174a7f9e90 100644 * efi_range_is_wc - check the WC bit on an address range * @start: starting kvirt address -- -1.9.0 +1.9.3 -From a4da3547b2eb4e0c7111eee7e5d5043413142835 Mon Sep 17 00:00:00 2001 +From 2534dedee545507c00973279d5db515e122b5104 Mon Sep 17 00:00:00 2001 From: Josh Boyer <jwboyer@fedoraproject.org> Date: Fri, 26 Oct 2012 12:36:24 -0400 Subject: [PATCH 3/5] KEYS: Add a system blacklist keyring @@ -270,10 +270,10 @@ index 8dabc399bd1d..e466de10ceec 100644 #endif /* _KEYS_SYSTEM_KEYRING_H */ diff --git a/init/Kconfig b/init/Kconfig -index 9d3585bb2a7a..932f22f7cc40 100644 +index 9d76b99af1b9..ac5f580437a0 100644 --- a/init/Kconfig +++ b/init/Kconfig -@@ -1658,6 +1658,15 @@ config SYSTEM_TRUSTED_KEYRING +@@ -1677,6 +1677,15 @@ config SYSTEM_TRUSTED_KEYRING Keys in this keyring are used by module signature checking. @@ -348,10 +348,10 @@ index 52ebc70263f4..478c4f8ec908 100644 } -- -1.9.0 +1.9.3 -From 25adb4e43fb5c23723f33a806399ad484f8dcfa5 Mon Sep 17 00:00:00 2001 +From a72ed58241f0d62b7f9fbf4e1fbbcc1e02145098 Mon Sep 17 00:00:00 2001 From: Josh Boyer <jwboyer@fedoraproject.org> Date: Fri, 26 Oct 2012 12:42:16 -0400 Subject: [PATCH 4/5] MODSIGN: Import certificates from UEFI Secure Boot @@ -379,10 +379,10 @@ Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org> create mode 100644 kernel/modsign_uefi.c diff --git a/include/linux/efi.h b/include/linux/efi.h -index 96174a7f9e90..8f7466023105 100644 +index 7854ff3c0f11..31fd75e7230b 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h -@@ -581,6 +581,12 @@ typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long si +@@ -584,6 +584,12 @@ typedef efi_status_t efi_query_variable_store_t(u32 attributes, unsigned long si #define EFI_CERT_X509_GUID \ EFI_GUID( 0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72 ) @@ -396,10 +396,10 @@ index 96174a7f9e90..8f7466023105 100644 efi_guid_t guid; u64 table; diff --git a/init/Kconfig b/init/Kconfig -index 932f22f7cc40..6023af12ef4f 100644 +index ac5f580437a0..ca7268b594aa 100644 --- a/init/Kconfig +++ b/init/Kconfig -@@ -1812,6 +1812,15 @@ config MODULE_SIG_ALL +@@ -1831,6 +1831,15 @@ config MODULE_SIG_ALL comment "Do not forget to sign required modules with scripts/sign-file" depends on MODULE_SIG_FORCE && !MODULE_SIG_ALL @@ -535,10 +535,10 @@ index 000000000000..94b0eb38a284 +} +late_initcall(load_uefi_certs); -- -1.9.0 +1.9.3 -From 20b7de055a87e6f5555c27de8188b7c975e3e330 Mon Sep 17 00:00:00 2001 +From 11bb98e3a62de77fc66a3e2197578dd9d891b998 Mon Sep 17 00:00:00 2001 From: Josh Boyer <jwboyer@fedoraproject.org> Date: Thu, 3 Oct 2013 10:14:23 -0400 Subject: [PATCH 5/5] MODSIGN: Support not importing certs from db @@ -620,5 +620,5 @@ index 94b0eb38a284..ae28b974d49a 100644 mok = get_cert_list(L"MokListRT", &mok_var, &moksize); -- -1.9.0 +1.9.3 diff --git a/freed-ora/current/master/nouveau-Don-t-check-acpi_video_backlight_support-bef.patch b/freed-ora/current/master/nouveau-Don-t-check-acpi_video_backlight_support-bef.patch deleted file mode 100644 index b6ed45c39..000000000 --- a/freed-ora/current/master/nouveau-Don-t-check-acpi_video_backlight_support-bef.patch +++ /dev/null @@ -1,79 +0,0 @@ -Bugzilla: 1093171 -Upstream-status: Queued for 3.16 - -From abf17f7885656ccc181a608d2a9ee770b23d9e23 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 2 Jun 2014 17:41:07 +0200 -Subject: [PATCH 10/14] nouveau: Don't check acpi_video_backlight_support() - before registering backlight - -acpi_video_backlight_support() is supposed to be called by other (vendor -specific) firmware backlight controls, not by native / raw backlight controls -like nv_backlight. - -Userspace will normally prefer firmware interfaces over raw interfaces, so -if acpi_video backlight support is present it will use that even if -nv_backlight is registered as well. - -Except when video.use_native_backlight is present on the kernel cmdline -(or enabled through a dmi based quirk). As the name indicates the goal here -is to make only the raw interface available to userspace so that it will use -that (it only does this when it sees a win8 compliant bios). - -This is done by: -1) Not registering any acpi_video# backlight devices; and -2) Making acpi_video_backlight_support() return true so that other firmware -drivers, ie acer_wmi, thinkpad_acpi, dell_laptop, etc. Don't register their -own vender specific interfaces. - -Currently nouveau breaks this setup, as when acpi_video_backlight_support() -returns true, it does not register itself, resulting in no backlight control -at all. - -This is esp. going to be a problem with 3.16 which will default to -video.use_native_backlight=1, and thus nouveau based laptops with a win8 bios -will get no backlight control at all. - -This also likely explains why the previous attempt to make -video.use_native_backlight=1 the default was not a success, as without this -patch having a default of video.use_native_backlight=1 will cause regressions. - -Note this effectively reverts commit 5bead799 - -Also see: https://bugzilla.redhat.com/show_bug.cgi?id=1093171 - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - drivers/gpu/drm/nouveau/nouveau_backlight.c | 9 --------- - 1 file changed, 9 deletions(-) - -diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c -index 630f6e84fc01..2c1e4aad7da3 100644 ---- a/drivers/gpu/drm/nouveau/nouveau_backlight.c -+++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c -@@ -31,7 +31,6 @@ - */ - - #include <linux/backlight.h> --#include <linux/acpi.h> - - #include "nouveau_drm.h" - #include "nouveau_reg.h" -@@ -222,14 +221,6 @@ nouveau_backlight_init(struct drm_device *dev) - struct nouveau_device *device = nv_device(drm->device); - struct drm_connector *connector; - --#ifdef CONFIG_ACPI -- if (acpi_video_backlight_support()) { -- NV_INFO(drm, "ACPI backlight interface available, " -- "not registering our own\n"); -- return 0; -- } --#endif -- - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && - connector->connector_type != DRM_MODE_CONNECTOR_eDP) --- -1.9.0 - diff --git a/freed-ora/current/master/nowatchdog-on-virt.patch b/freed-ora/current/master/nowatchdog-on-virt.patch index c78029a31..d8cf87953 100644 --- a/freed-ora/current/master/nowatchdog-on-virt.patch +++ b/freed-ora/current/master/nowatchdog-on-virt.patch @@ -1,7 +1,10 @@ Bugzilla: 971139 Upstream-status: Fedora mustard for now -Disable watchdog on virtual machines. +From 17109685bfce322c73a816e097b137458fbd55ae Mon Sep 17 00:00:00 2001 +From: Dave Jones <davej@redhat.com> +Date: Tue, 24 Jun 2014 08:43:34 -0400 +Subject: [PATCH] Disable watchdog on virtual machines. For various reasons, VMs seem to trigger the soft lockup detector a lot, in cases where it's just not possible for a lockup to occur. @@ -13,9 +16,12 @@ the VM for a very long time (Could be the host was under heavy load). Just disable the detector on VMs. Signed-off-by: Dave Jones <davej@redhat.com> +--- + kernel/watchdog.c | 29 +++++++++++++++++++++++++++++ + 1 file changed, 29 insertions(+) diff --git a/kernel/watchdog.c b/kernel/watchdog.c -index 1241d8c..b2dc4e4 100644 +index c3319bd1b040..0e3687675aaa 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c @@ -24,6 +24,7 @@ @@ -26,9 +32,9 @@ index 1241d8c..b2dc4e4 100644 #include <asm/irq_regs.h> #include <linux/kvm_para.h> -@@ -96,6 +97,32 @@ static int __init nosoftlockup_setup(char *str) - __setup("nosoftlockup", nosoftlockup_setup); - /* */ +@@ -112,6 +113,32 @@ static int __init softlockup_all_cpu_backtrace_setup(char *str) + __setup("softlockup_all_cpu_backtrace=", softlockup_all_cpu_backtrace_setup); + #endif +static int disable_watchdog(const struct dmi_system_id *d) +{ @@ -59,7 +65,7 @@ index 1241d8c..b2dc4e4 100644 /* * Hard-lockup warnings should be triggered after just a few seconds. Soft- * lockups can have false positives under extreme conditions. So we generally -@@ -551,6 +578,8 @@ int proc_dowatchdog(struct ctl_table *table, int write, +@@ -641,6 +668,8 @@ out: void __init lockup_detector_init(void) { @@ -67,4 +73,7 @@ index 1241d8c..b2dc4e4 100644 + set_sample_period(); - #ifdef CONFIG_NO_HZ_FULL + if (watchdog_user_enabled) +-- +1.9.3 + diff --git a/freed-ora/current/master/revert-input-wacom-testing-result-shows-get_report-is-unnecessary.patch b/freed-ora/current/master/revert-input-wacom-testing-result-shows-get_report-is-unnecessary.patch new file mode 100644 index 000000000..f9f4a72a0 --- /dev/null +++ b/freed-ora/current/master/revert-input-wacom-testing-result-shows-get_report-is-unnecessary.patch @@ -0,0 +1,40 @@ +Bugzilla: N/A +Upstream-status: Sent upstream + +This reverts commit 1b2faaf7e219fc2905d75afcd4c815e5d39eda80. + +The Intuos4 series presents a bug in which it hangs if it receives +a set feature command while switching to the enhanced mode. +This bug is triggered when plugging an Intuos 4 while having +a gnome user session up and running. + +Signed-off-by: Benjamin Tissoires <benjamin.tissoires@xxxxxxxxxx> +--- + +Hi Aris, + +actually, you bisected the bug, so can I consider that I have your signed-off-by? + +Cheers, +Benjamin + + drivers/input/tablet/wacom_sys.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/input/tablet/wacom_sys.c b/drivers/input/tablet/wacom_sys.c +index 7087b33..319a3ff 100644 +--- a/drivers/input/tablet/wacom_sys.c ++++ b/drivers/input/tablet/wacom_sys.c +@@ -536,6 +536,9 @@ static int wacom_set_device_mode(struct usb_interface *intf, int report_id, int + + error = wacom_set_report(intf, WAC_HID_FEATURE_REPORT, + report_id, rep_data, length, 1); ++ if (error >= 0) ++ error = wacom_get_report(intf, WAC_HID_FEATURE_REPORT, ++ report_id, rep_data, length, 1); + } while ((error < 0 || rep_data[1] != mode) && limit++ < WAC_MSG_RETRIES); + + kfree(rep_data); +-- +1.9.0 + diff --git a/freed-ora/current/master/s390-appldata-add-slab.h-for-kzalloc-kfree.patch b/freed-ora/current/master/s390-appldata-add-slab.h-for-kzalloc-kfree.patch deleted file mode 100644 index 3716ce8b1..000000000 --- a/freed-ora/current/master/s390-appldata-add-slab.h-for-kzalloc-kfree.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 1eb5e8b7449ff017c2f358d97bd2fcd4eb87cc53 Mon Sep 17 00:00:00 2001 -From: Jeff Mahoney <jeffm@suse.com> -Date: Sun, 27 Apr 2014 17:35:43 -0400 -Subject: s390/appldata: add slab.h for kzalloc/kfree - -This fixes: -arch/s390/appldata/appldata_mem.c:135:2: error: implicit declaration of function 'kzalloc' [-Werror=implicit-function-declaration] -arch/s390/appldata/appldata_mem.c:141:3: error: implicit declaration of function 'kfree' [-Werror=implicit-function-declaration] - -Signed-off-by: Jeff Mahoney <jeffm@suse.com> -Signed-off-by: Heiko Carstens <heiko.carstens@de.ibm.com> -Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com> - -diff --git a/arch/s390/appldata/appldata_mem.c b/arch/s390/appldata/appldata_mem.c -index 42be537..edcf2a7 100644 ---- a/arch/s390/appldata/appldata_mem.c -+++ b/arch/s390/appldata/appldata_mem.c -@@ -13,6 +13,7 @@ - #include <linux/kernel_stat.h> - #include <linux/pagemap.h> - #include <linux/swap.h> -+#include <linux/slab.h> - #include <asm/io.h> - - #include "appldata.h" --- -cgit v0.10.1 - diff --git a/freed-ora/current/master/samsung-laptop-Add-broken-acpi-video-quirk-for-NC210.patch b/freed-ora/current/master/samsung-laptop-Add-broken-acpi-video-quirk-for-NC210.patch index ce83ed21c..93c4073ce 100644 --- a/freed-ora/current/master/samsung-laptop-Add-broken-acpi-video-quirk-for-NC210.patch +++ b/freed-ora/current/master/samsung-laptop-Add-broken-acpi-video-quirk-for-NC210.patch @@ -15,13 +15,14 @@ Signed-off-by: Hans de Goede <hdegoede@redhat.com> drivers/platform/x86/samsung-laptop.c | 10 ++++++++++ 1 file changed, 10 insertions(+) + diff --git a/drivers/platform/x86/samsung-laptop.c b/drivers/platform/x86/samsung-laptop.c -index d1f030053176..98f61f677627 100644 +index 5a5966512277..0d7954e0fc74 100644 --- a/drivers/platform/x86/samsung-laptop.c +++ b/drivers/platform/x86/samsung-laptop.c -@@ -1534,6 +1534,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { +@@ -1568,6 +1568,16 @@ static struct dmi_system_id __initdata samsung_dmi_table[] = { }, - .driver_data = &samsung_broken_acpi_video, + .driver_data = &samsung_np740u3e, }, + { + .callback = samsung_dmi_matched, @@ -36,6 +37,3 @@ index d1f030053176..98f61f677627 100644 { }, }; MODULE_DEVICE_TABLE(dmi, samsung_dmi_table); --- -1.9.0 - diff --git a/freed-ora/current/master/sb-hibernate.patch b/freed-ora/current/master/sb-hibernate.patch index da7bb7428..4b1bd1673 100644 --- a/freed-ora/current/master/sb-hibernate.patch +++ b/freed-ora/current/master/sb-hibernate.patch @@ -1,7 +1,7 @@ Bugzilla: N/A Upstream-status: Fedora mustard -From ffe1ee94d526900ce1e5191cdd38934477dd209a Mon Sep 17 00:00:00 2001 +From 9cdffb6980a2c573844b4b87f907da24d68fb916 Mon Sep 17 00:00:00 2001 From: Josh Boyer <jwboyer@fedoraproject.org> Date: Fri, 26 Oct 2012 14:02:09 -0400 Subject: [PATCH] hibernate: Disable in a signed modules environment @@ -19,19 +19,19 @@ Signed-off-by: Josh Boyer <jwboyer@fedoraproject.com> 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c -index b26f5f1..e65228b 100644 +index 49e0a20fd010..777eff68e8ef 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c -@@ -28,6 +28,8 @@ - #include <linux/syscore_ops.h> +@@ -29,6 +29,8 @@ #include <linux/ctype.h> #include <linux/genhd.h> -+#include <linux/efi.h> + #include <trace/events/power.h> +#include <linux/module.h> ++#include <linux/efi.h> #include "power.h" -@@ -632,6 +634,10 @@ int hibernate(void) +@@ -642,6 +644,10 @@ int hibernate(void) { int error; @@ -42,7 +42,7 @@ index b26f5f1..e65228b 100644 lock_system_sleep(); /* The snapshot device should not be opened while we're running */ if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { -@@ -723,7 +729,7 @@ static int software_resume(void) +@@ -734,7 +740,7 @@ static int software_resume(void) /* * If the user said "noresume".. bail out early. */ @@ -51,7 +51,7 @@ index b26f5f1..e65228b 100644 return 0; /* -@@ -889,6 +895,11 @@ static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr, +@@ -900,6 +906,11 @@ static ssize_t disk_show(struct kobject *kobj, struct kobj_attribute *attr, int i; char *start = buf; @@ -63,7 +63,7 @@ index b26f5f1..e65228b 100644 for (i = HIBERNATION_FIRST; i <= HIBERNATION_MAX; i++) { if (!hibernation_modes[i]) continue; -@@ -923,6 +934,9 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, +@@ -934,6 +945,9 @@ static ssize_t disk_store(struct kobject *kobj, struct kobj_attribute *attr, char *p; int mode = HIBERNATION_INVALID; @@ -74,7 +74,7 @@ index b26f5f1..e65228b 100644 len = p ? p - buf : n; diff --git a/kernel/power/main.c b/kernel/power/main.c -index 1d1bf63..300f300 100644 +index 573410d6647e..f5201093adc4 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -15,6 +15,7 @@ @@ -86,7 +86,7 @@ index 1d1bf63..300f300 100644 #include "power.h" @@ -301,7 +302,11 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr, - } + #endif #ifdef CONFIG_HIBERNATION - s += sprintf(s, "%s\n", "disk"); @@ -99,7 +99,7 @@ index 1d1bf63..300f300 100644 if (s != buf) /* convert the last space to a newline */ diff --git a/kernel/power/user.c b/kernel/power/user.c -index 15cb72f..fa85ed5 100644 +index efe99dee9510..5f5d1026f1e2 100644 --- a/kernel/power/user.c +++ b/kernel/power/user.c @@ -25,6 +25,7 @@ @@ -111,5 +111,5 @@ index 15cb72f..fa85ed5 100644 #include <asm/uaccess.h> -- -1.8.3.1 +1.9.3 diff --git a/freed-ora/current/master/sched-fix-sched_setparam-policy-1-logic.patch b/freed-ora/current/master/sched-fix-sched_setparam-policy-1-logic.patch new file mode 100644 index 000000000..060e0dcef --- /dev/null +++ b/freed-ora/current/master/sched-fix-sched_setparam-policy-1-logic.patch @@ -0,0 +1,68 @@ +Bugzilla: 1117942 +Upstream-status: Sent for 3.16 and seen by peterz + +The scheduler uses policy=-1 to preserve the current policy state to +implement sched_setparam(). But, as (int) -1 is equals to 0xffffffff, +it's matching the if (policy & SCHED_RESET_ON_FORK) on +_sched_setscheduler(). This match changes the policy value to an +invalid value, breaking the sched_setparam() syscall. + +This patch checks policy=-1 before check the SCHED_RESET_ON_FORK flag. + +The following program shows the bug: + +int main(void) +{ + struct sched_param param = { + .sched_priority = 5, + }; + + sched_setscheduler(0, SCHED_FIFO, ¶m); + param.sched_priority = 1; + sched_setparam(0, ¶m); + param.sched_priority = 0; + sched_getparam(0, ¶m); + if (param.sched_priority != 1) + printf("failed priority setting (found %d instead of 1)\n", + param.sched_priority); + else + printf("priority setting fine\n"); +} + +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Ingo Molnar <mingo@kernel.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: stable@vger.kernel.org # 3.14+ +Fixes: 7479f3c9cf67 "sched: Move SCHED_RESET_ON_FORK into attr::sched_flags" +Reviewed-by: Steven Rostedt <rostedt@goodmis.org> +Signed-off-by: Daniel Bristot de Oliveira <bristot@redhat.com> + +--- + kernel/sched/core.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/kernel/sched/core.c b/kernel/sched/core.c +index bc1638b..0acf96b 100644 +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -3558,9 +3558,10 @@ static int _sched_setscheduler(struct task_struct *p, int policy, + }; + + /* +- * Fixup the legacy SCHED_RESET_ON_FORK hack ++ * Fixup the legacy SCHED_RESET_ON_FORK hack, except if ++ * the policy=-1 was passed by sched_setparam(). + */ +- if (policy & SCHED_RESET_ON_FORK) { ++ if ((policy != -1) && (policy & SCHED_RESET_ON_FORK)) { + attr.sched_flags |= SCHED_FLAG_RESET_ON_FORK; + policy &= ~SCHED_RESET_ON_FORK; + attr.sched_policy = policy; +-- +1.9.3 + +-- +To unsubscribe from this list: send the line "unsubscribe linux-kernel" in +the body of a message to majordomo@vger.kernel.org +More majordomo info at http://vger.kernel.org/majordomo-info.html +Please read the FAQ at http://www.tux.org/lkml/ diff --git a/freed-ora/current/master/secure-modules.patch b/freed-ora/current/master/secure-modules.patch index 478c62ff5..2d3174c22 100644 --- a/freed-ora/current/master/secure-modules.patch +++ b/freed-ora/current/master/secure-modules.patch @@ -1,7 +1,7 @@ Bugzilla: N/A Upstream-status: Fedora mustard. Replaced by securelevels, but that was nak'd -From 0f81a4461431941c17ff26fd3d5e284ede4a368a Mon Sep 17 00:00:00 2001 +From 952dbcbea4cffb1a05773af3b5f41e8ed477c5fe Mon Sep 17 00:00:00 2001 From: Matthew Garrett <matthew.garrett@nebula.com> Date: Fri, 9 Aug 2013 17:58:15 -0400 Subject: [PATCH 01/14] Add secure_modules() call @@ -42,10 +42,10 @@ index f520a767c86c..fc9b54eb779e 100644 #ifdef CONFIG_SYSFS diff --git a/kernel/module.c b/kernel/module.c -index 11869408f79b..2b9204fe055f 100644 +index 81e727cf6df9..fc14f48915dd 100644 --- a/kernel/module.c +++ b/kernel/module.c -@@ -3835,3 +3835,13 @@ void module_layout(struct module *mod, +@@ -3843,3 +3843,13 @@ void module_layout(struct module *mod, } EXPORT_SYMBOL(module_layout); #endif @@ -60,10 +60,10 @@ index 11869408f79b..2b9204fe055f 100644 +} +EXPORT_SYMBOL(secure_modules); -- -1.8.5.3 +1.9.3 -From 806c4ee0e6484b529b88b3d0ceb49f6edf96ae11 Mon Sep 17 00:00:00 2001 +From 3b451a12e60a47d152ecce1c02634c4d7320b024 Mon Sep 17 00:00:00 2001 From: Matthew Garrett <matthew.garrett@nebula.com> Date: Thu, 8 Mar 2012 10:10:38 -0500 Subject: [PATCH 02/14] PCI: Lock down BAR access when module security is @@ -83,20 +83,20 @@ Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c -index 4e0acefb7565..01b56d13d021 100644 +index 9ff0a901ecf7..8d0d5d92b8d9 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c -@@ -29,6 +29,7 @@ - #include <linux/slab.h> +@@ -30,6 +30,7 @@ #include <linux/vgaarb.h> #include <linux/pm_runtime.h> + #include <linux/of.h> +#include <linux/module.h> #include "pci.h" static int sysfs_initialized; /* = 0 */ -@@ -652,6 +653,9 @@ pci_write_config(struct file* filp, struct kobject *kobj, +@@ -704,6 +705,9 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj, loff_t init_off = off; - u8 *data = (u8*) buf; + u8 *data = (u8 *) buf; + if (secure_modules()) + return -EPERM; @@ -104,7 +104,7 @@ index 4e0acefb7565..01b56d13d021 100644 if (off > dev->cfg_size) return 0; if (off + count > dev->cfg_size) { -@@ -958,6 +962,9 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, +@@ -998,6 +1002,9 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, resource_size_t start, end; int i; @@ -114,9 +114,9 @@ index 4e0acefb7565..01b56d13d021 100644 for (i = 0; i < PCI_ROM_RESOURCE; i++) if (res == &pdev->resource[i]) break; -@@ -1065,6 +1072,9 @@ pci_write_resource_io(struct file *filp, struct kobject *kobj, - struct bin_attribute *attr, char *buf, - loff_t off, size_t count) +@@ -1099,6 +1106,9 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) { + if (secure_modules()) + return -EPERM; @@ -125,10 +125,10 @@ index 4e0acefb7565..01b56d13d021 100644 } diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c -index 46d1378f2e9e..294fe7b34af0 100644 +index 3f155e78513f..4265ea07e3b0 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c -@@ -117,6 +117,9 @@ proc_bus_pci_write(struct file *file, const char __user *buf, size_t nbytes, lof +@@ -116,6 +116,9 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf, int size = dev->cfg_size; int cnt; @@ -138,7 +138,7 @@ index 46d1378f2e9e..294fe7b34af0 100644 if (pos >= size) return 0; if (nbytes >= size) -@@ -196,6 +199,9 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd, +@@ -195,6 +198,9 @@ static long proc_bus_pci_ioctl(struct file *file, unsigned int cmd, #endif /* HAVE_PCI_MMAP */ int ret = 0; @@ -148,7 +148,7 @@ index 46d1378f2e9e..294fe7b34af0 100644 switch (cmd) { case PCIIOC_CONTROLLER: ret = pci_domain_nr(dev->bus); -@@ -234,7 +240,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) +@@ -233,7 +239,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) struct pci_filp_private *fpriv = file->private_data; int i, ret; @@ -158,7 +158,7 @@ index 46d1378f2e9e..294fe7b34af0 100644 /* Make sure the caller is mapping a real resource for this device */ diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c -index 24750a1b39b6..fa57896b97dd 100644 +index b91c4da68365..98f5637304d1 100644 --- a/drivers/pci/syscall.c +++ b/drivers/pci/syscall.c @@ -10,6 +10,7 @@ @@ -179,10 +179,10 @@ index 24750a1b39b6..fa57896b97dd 100644 dev = pci_get_bus_and_slot(bus, dfn); -- -1.8.5.3 +1.9.3 -From 16ee82e2add8684e374451e6ba34be3ee41e4ef1 Mon Sep 17 00:00:00 2001 +From 42a620055ac873fb378ec69731c7a2200f6779cc Mon Sep 17 00:00:00 2001 From: Matthew Garrett <matthew.garrett@nebula.com> Date: Thu, 8 Mar 2012 10:35:59 -0500 Subject: [PATCH 03/14] x86: Lock down IO port access when module security is @@ -252,10 +252,10 @@ index 917403fe10da..cdf839f9defe 100644 return -EFAULT; while (count-- > 0 && i < 65536) { -- -1.8.5.3 +1.9.3 -From 2fd4b35393b19cde87e4770d3b85d12760e72f6a Mon Sep 17 00:00:00 2001 +From 8019fb7c7b5f18b19f7c980987953680ee218c9f Mon Sep 17 00:00:00 2001 From: Matthew Garrett <matthew.garrett@nebula.com> Date: Fri, 9 Mar 2012 08:39:37 -0500 Subject: [PATCH 04/14] ACPI: Limit access to custom_method @@ -284,10 +284,10 @@ index c68e72414a67..4277938af700 100644 /* parse the table header to get the table length */ if (count <= sizeof(struct acpi_table_header)) -- -1.8.5.3 +1.9.3 -From 543d64276237adb782ec30a5dab67d0b21afc1d4 Mon Sep 17 00:00:00 2001 +From bf84e9e1022b2d3d0c97ae48fb8b61e5336c50f8 Mon Sep 17 00:00:00 2001 From: Matthew Garrett <matthew.garrett@nebula.com> Date: Fri, 9 Mar 2012 08:46:50 -0500 Subject: [PATCH 05/14] asus-wmi: Restrict debugfs interface when module @@ -305,10 +305,10 @@ Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> 1 file changed, 9 insertions(+) diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c -index c5e082fb82fa..03c57fc8de8a 100644 +index 3c6ccedc82b6..960c46536c65 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c -@@ -1595,6 +1595,9 @@ static int show_dsts(struct seq_file *m, void *data) +@@ -1592,6 +1592,9 @@ static int show_dsts(struct seq_file *m, void *data) int err; u32 retval = -1; @@ -318,7 +318,7 @@ index c5e082fb82fa..03c57fc8de8a 100644 err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval); if (err < 0) -@@ -1611,6 +1614,9 @@ static int show_devs(struct seq_file *m, void *data) +@@ -1608,6 +1611,9 @@ static int show_devs(struct seq_file *m, void *data) int err; u32 retval = -1; @@ -328,7 +328,7 @@ index c5e082fb82fa..03c57fc8de8a 100644 err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param, &retval); -@@ -1635,6 +1641,9 @@ static int show_call(struct seq_file *m, void *data) +@@ -1632,6 +1638,9 @@ static int show_call(struct seq_file *m, void *data) union acpi_object *obj; acpi_status status; @@ -339,10 +339,10 @@ index c5e082fb82fa..03c57fc8de8a 100644 1, asus->debug.method_id, &input, &output); -- -1.8.5.3 +1.9.3 -From 6e2fec5547b597c43ca72e34729b8a402660a7c1 Mon Sep 17 00:00:00 2001 +From 9a56e8715d3b6dc84989997f34b6b5d407cabad2 Mon Sep 17 00:00:00 2001 From: Matthew Garrett <matthew.garrett@nebula.com> Date: Fri, 9 Mar 2012 09:28:15 -0500 Subject: [PATCH 06/14] Restrict /dev/mem and /dev/kmem when module loading is @@ -382,10 +382,10 @@ index cdf839f9defe..c63cf93b00eb 100644 unsigned long to_write = min_t(unsigned long, count, (unsigned long)high_memory - p); -- -1.8.5.3 +1.9.3 -From 358cea0a54f726fa61839b411f3f54284d4588bf Mon Sep 17 00:00:00 2001 +From 8d6faa19bbbaa4df411becda7e40c4ea0684c134 Mon Sep 17 00:00:00 2001 From: Josh Boyer <jwboyer@redhat.com> Date: Mon, 25 Jun 2012 19:57:30 -0400 Subject: [PATCH 07/14] acpi: Ignore acpi_rsdp kernel parameter when module @@ -401,7 +401,7 @@ Signed-off-by: Josh Boyer <jwboyer@redhat.com> 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c -index f7fd72ac69cf..ccdae1c8c386 100644 +index bad25b070fe0..0606585e8b93 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c @@ -44,6 +44,7 @@ @@ -412,7 +412,7 @@ index f7fd72ac69cf..ccdae1c8c386 100644 #include <asm/io.h> #include <asm/uaccess.h> -@@ -244,7 +245,7 @@ early_param("acpi_rsdp", setup_acpi_rsdp); +@@ -245,7 +246,7 @@ early_param("acpi_rsdp", setup_acpi_rsdp); acpi_physical_address __init acpi_os_get_root_pointer(void) { #ifdef CONFIG_KEXEC @@ -422,10 +422,10 @@ index f7fd72ac69cf..ccdae1c8c386 100644 #endif -- -1.8.5.3 +1.9.3 -From 89751b3ad4dea7cf5b806cd14126dd70657a9148 Mon Sep 17 00:00:00 2001 +From 1ff86ddea019f543f6668b56889f86811028f303 Mon Sep 17 00:00:00 2001 From: Matthew Garrett <matthew.garrett@nebula.com> Date: Fri, 9 Aug 2013 03:33:56 -0400 Subject: [PATCH 08/14] kexec: Disable at runtime if the kernel enforces module @@ -441,18 +441,18 @@ Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> 1 file changed, 8 insertions(+) diff --git a/kernel/kexec.c b/kernel/kexec.c -index c8380ad203bc..e6eb239f567a 100644 +index 4b8f0c925884..df14daa323a9 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c -@@ -33,6 +33,7 @@ - #include <linux/swap.h> +@@ -34,6 +34,7 @@ #include <linux/syscore_ops.h> #include <linux/compiler.h> + #include <linux/hugetlb.h> +#include <linux/module.h> #include <asm/page.h> #include <asm/uaccess.h> -@@ -948,6 +949,13 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, +@@ -947,6 +948,13 @@ SYSCALL_DEFINE4(kexec_load, unsigned long, entry, unsigned long, nr_segments, return -EPERM; /* @@ -467,53 +467,13 @@ index c8380ad203bc..e6eb239f567a 100644 * This leaves us room for future extensions. */ -- -1.8.5.3 +1.9.3 -From 31174421a7103571a1c3faf7ba27d4045e5fbc18 Mon Sep 17 00:00:00 2001 -From: Matthew Garrett <matthew.garrett@nebula.com> -Date: Tue, 3 Sep 2013 11:23:29 -0400 -Subject: [PATCH 09/14] uswsusp: Disable when module loading is restricted - -uswsusp allows a user process to dump and then restore kernel state, which -makes it possible to avoid module loading restrictions. Prevent this when -any restrictions have been imposed on loading modules. - -Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> ---- - kernel/power/user.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/kernel/power/user.c b/kernel/power/user.c -index 98d357584cd6..efe99dee9510 100644 ---- a/kernel/power/user.c -+++ b/kernel/power/user.c -@@ -24,6 +24,7 @@ - #include <linux/console.h> - #include <linux/cpu.h> - #include <linux/freezer.h> -+#include <linux/module.h> - - #include <asm/uaccess.h> - -@@ -49,6 +50,9 @@ static int snapshot_open(struct inode *inode, struct file *filp) - struct snapshot_data *data; - int error; - -+ if (secure_modules()) -+ return -EPERM; -+ - lock_system_sleep(); - - if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { --- -1.8.5.3 - - -From ea5cf8801db979fa7d5f90ab3faf72eb22490f9b Mon Sep 17 00:00:00 2001 +From 4d56368f1364b45c18067bab1d6abc5ce0f67183 Mon Sep 17 00:00:00 2001 From: Matthew Garrett <matthew.garrett@nebula.com> Date: Fri, 8 Feb 2013 11:12:13 -0800 -Subject: [PATCH 10/14] x86: Restrict MSR access when module loading is +Subject: [PATCH 09/14] x86: Restrict MSR access when module loading is restricted Writing to MSRs should not be allowed if module loading is restricted, @@ -552,13 +512,13 @@ index c9603ac80de5..8bef43fc3f40 100644 err = -EFAULT; break; -- -1.8.5.3 +1.9.3 -From 2985684ff78972bde7ebf1e295b52afd9bea29e0 Mon Sep 17 00:00:00 2001 +From aab8ba85241a85a0b2ed622edd7874c74cafa496 Mon Sep 17 00:00:00 2001 From: Matthew Garrett <matthew.garrett@nebula.com> Date: Fri, 9 Aug 2013 18:36:30 -0400 -Subject: [PATCH 11/14] Add option to automatically enforce module signatures +Subject: [PATCH 10/14] Add option to automatically enforce module signatures when in Secure Boot mode UEFI Secure Boot provides a mechanism for ensuring that the firmware will @@ -591,10 +551,10 @@ index 199f453cb4de..ec38acf00b40 100644 290/040 ALL edd_mbr_sig_buffer EDD MBR signatures 2D0/A00 ALL e820_map E820 memory map table diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index 5b8ec0f53b57..085d5eb36361 100644 +index d24887b645dc..870aac9520b3 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -1534,6 +1534,16 @@ config EFI_MIXED +@@ -1557,6 +1557,16 @@ config EFI_MIXED If unsure, say N. @@ -612,7 +572,7 @@ index 5b8ec0f53b57..085d5eb36361 100644 def_bool y prompt "Enable seccomp to safely compute untrusted bytecode" diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c -index 1e6146137f8e..b00745ff398a 100644 +index 0331d765c2bb..85defaf5a27c 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -12,6 +12,7 @@ @@ -634,7 +594,7 @@ index 1e6146137f8e..b00745ff398a 100644 + efi_guid_t var_guid = EFI_GLOBAL_VARIABLE_GUID; + efi_status_t status; + -+ status = efi_call_phys5(sys_table->runtime->get_variable, ++ status = efi_early->call((unsigned long)sys_table->runtime->get_variable, + L"SecureBoot", &var_guid, NULL, &datasize, &sb); + + if (status != EFI_SUCCESS) @@ -644,7 +604,7 @@ index 1e6146137f8e..b00745ff398a 100644 + return 0; + + -+ status = efi_call_phys5(sys_table->runtime->get_variable, ++ status = efi_early->call((unsigned long)sys_table->runtime->get_variable, + L"SetupMode", &var_guid, NULL, &datasize, + &setup); + @@ -687,7 +647,7 @@ index 225b0988043a..90dbfb73e11f 100644 * The sentinel is set to a nonzero value (0xff) in header.S. * diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index 09c76d265550..5a61d732fd5c 100644 +index 78a0e6298922..8ecfec85e527 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1142,6 +1142,12 @@ void __init setup_arch(char **cmdline_p) @@ -721,10 +681,10 @@ index fc9b54eb779e..7377bc851461 100644 extern int modules_disabled; /* for sysctl */ diff --git a/kernel/module.c b/kernel/module.c -index 2b9204fe055f..2b8cc2d57c16 100644 +index fc14f48915dd..2d68d276f3b6 100644 --- a/kernel/module.c +++ b/kernel/module.c -@@ -3836,6 +3836,13 @@ void module_layout(struct module *mod, +@@ -3844,6 +3844,13 @@ void module_layout(struct module *mod, EXPORT_SYMBOL(module_layout); #endif @@ -739,13 +699,13 @@ index 2b9204fe055f..2b8cc2d57c16 100644 { #ifdef CONFIG_MODULE_SIG -- -1.8.5.3 +1.9.3 -From b2e4ea728ccab2befbd5fe1bd834881a7dd8f34b Mon Sep 17 00:00:00 2001 -From: Josh Boyer <jwboyer@redhat.com> +From eae8a80ddc185b3f233e2620dbfc6454b6f0c3a6 Mon Sep 17 00:00:00 2001 +From: Josh Boyer <jwboyer@fedoraproject.org> Date: Tue, 5 Feb 2013 19:25:05 -0500 -Subject: [PATCH 12/14] efi: Disable secure boot if shim is in insecure mode +Subject: [PATCH 11/14] efi: Disable secure boot if shim is in insecure mode A user can manually tell the shim boot loader to disable validation of images it loads. When a user does this, it creates a UEFI variable called @@ -753,13 +713,13 @@ MokSBState that does not have the runtime attribute set. Given that the user explicitly disabled validation, we can honor that and not enable secure boot mode if that variable is set. -Signed-off-by: Josh Boyer <jwboyer@redhat.com> +Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org> --- arch/x86/boot/compressed/eboot.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/arch/x86/boot/compressed/eboot.c b/arch/x86/boot/compressed/eboot.c -index b00745ff398a..bf42cc5f083d 100644 +index 85defaf5a27c..b4013a4ba005 100644 --- a/arch/x86/boot/compressed/eboot.c +++ b/arch/x86/boot/compressed/eboot.c @@ -812,8 +812,9 @@ out: @@ -781,7 +741,7 @@ index b00745ff398a..bf42cc5f083d 100644 + * doesn't have the runtime attribute set, we might as well honor that. + */ + var_guid = EFI_SHIM_LOCK_GUID; -+ status = efi_call_phys5(sys_table->runtime->get_variable, ++ status = efi_early->call((unsigned long)sys_table->runtime->get_variable, + L"MokSBState", &var_guid, &attr, &datasize, + &moksbstate); + @@ -798,13 +758,13 @@ index b00745ff398a..bf42cc5f083d 100644 } -- -1.8.5.3 +1.9.3 -From fb418c682d01c447d30b5591a591fdbf33b1334e Mon Sep 17 00:00:00 2001 +From 9728a4f49b284b7354876e1d77174d5838306e21 Mon Sep 17 00:00:00 2001 From: Josh Boyer <jwboyer@fedoraproject.org> Date: Tue, 27 Aug 2013 13:28:43 -0400 -Subject: [PATCH 13/14] efi: Make EFI_SECURE_BOOT_SIG_ENFORCE depend on EFI +Subject: [PATCH 12/14] efi: Make EFI_SECURE_BOOT_SIG_ENFORCE depend on EFI The functionality of the config option is dependent upon the platform being UEFI based. Reflect this in the config deps. @@ -815,10 +775,10 @@ Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org> 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig -index 085d5eb36361..3e8d398a976d 100644 +index 870aac9520b3..7aecd3f9f8ee 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig -@@ -1535,7 +1535,8 @@ config EFI_MIXED +@@ -1558,7 +1558,8 @@ config EFI_MIXED If unsure, say N. config EFI_SECURE_BOOT_SIG_ENFORCE @@ -829,13 +789,13 @@ index 085d5eb36361..3e8d398a976d 100644 ---help--- UEFI Secure Boot provides a mechanism for ensuring that the -- -1.8.5.3 +1.9.3 -From 87bf357dd4589cfca043ec4b641b912a088b1234 Mon Sep 17 00:00:00 2001 +From 4211b4919b8ccecc4f4cdc0a46ead7294478b687 Mon Sep 17 00:00:00 2001 From: Josh Boyer <jwboyer@fedoraproject.org> Date: Tue, 27 Aug 2013 13:33:03 -0400 -Subject: [PATCH 14/14] efi: Add EFI_SECURE_BOOT bit +Subject: [PATCH 13/14] efi: Add EFI_SECURE_BOOT bit UEFI machines can be booted in Secure Boot mode. Add a EFI_SECURE_BOOT bit for use with efi_enabled. @@ -847,7 +807,7 @@ Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org> 2 files changed, 3 insertions(+) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index 5a61d732fd5c..23fe9bf3c401 100644 +index 8ecfec85e527..5ce785fc9f05 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -1144,7 +1144,9 @@ void __init setup_arch(char **cmdline_p) @@ -861,10 +821,10 @@ index 5a61d732fd5c..23fe9bf3c401 100644 #endif diff --git a/include/linux/efi.h b/include/linux/efi.h -index 6c100ff0cae4..3a77a70fff27 100644 +index 41bbf8ba4ba8..e73f391fd3c8 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h -@@ -899,6 +899,7 @@ extern int __init efi_setup_pcdp_console(char *); +@@ -917,6 +917,7 @@ extern int __init efi_setup_pcdp_console(char *); #define EFI_MEMMAP 4 /* Can we use EFI memory map? */ #define EFI_64BIT 5 /* Is the firmware 64-bit? */ #define EFI_ARCH_1 6 /* First arch-specific bit */ @@ -873,5 +833,45 @@ index 6c100ff0cae4..3a77a70fff27 100644 #ifdef CONFIG_EFI /* -- -1.8.5.3 +1.9.3 + + +From 18b50c6f0597b606cb03cbd8a9fdef7478cb2b21 Mon Sep 17 00:00:00 2001 +From: Josh Boyer <jwboyer@fedoraproject.org> +Date: Fri, 20 Jun 2014 08:53:24 -0400 +Subject: [PATCH 14/14] hibernate: Disable in a signed modules environment + +There is currently no way to verify the resume image when returning +from hibernate. This might compromise the signed modules trust model, +so until we can work with signed hibernate images we disable it in +a secure modules environment. + +Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org> +--- + kernel/power/hibernate.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c +index fcc2611d3f14..61711801a9c4 100644 +--- a/kernel/power/hibernate.c ++++ b/kernel/power/hibernate.c +@@ -28,6 +28,7 @@ + #include <linux/syscore_ops.h> + #include <linux/ctype.h> + #include <linux/genhd.h> ++#include <linux/module.h> + #include <trace/events/power.h> + + #include "power.h" +@@ -65,7 +66,7 @@ static const struct platform_hibernation_ops *hibernation_ops; + + bool hibernation_available(void) + { +- return (nohibernate == 0); ++ return ((nohibernate == 0) && !secure_modules()); + } + + /** +-- +1.9.3 diff --git a/freed-ora/current/master/sources b/freed-ora/current/master/sources index 3a1470761..33f6e7f9d 100644 --- a/freed-ora/current/master/sources +++ b/freed-ora/current/master/sources @@ -1,2 +1,2 @@ -3e6ef6e8e5153050cbc0ecd305cb2cb9 linux-libre-3.15-gnu.tar.xz -ef8f4db937f521a7e323ec589536ba25 perf-man-3.15.tar.gz +71e2d15b48e14db5a464424878362b42 linux-libre-3.16-gnu.tar.xz +49868ce6467b35cd9ffea1120d129462 perf-man-3.16.tar.gz diff --git a/freed-ora/current/master/sysrq-secure-boot.patch b/freed-ora/current/master/sysrq-secure-boot.patch index c73e3d252..1b1399340 100644 --- a/freed-ora/current/master/sysrq-secure-boot.patch +++ b/freed-ora/current/master/sysrq-secure-boot.patch @@ -1,7 +1,7 @@ Bugzilla: N/A Upstream-status: Fedora mustard -From 29c1f71a2d0845a71ea2ebd2fb33542373dc52dd Mon Sep 17 00:00:00 2001 +From 603230771bdbca78e6530d29dbe8b239cdcc8473 Mon Sep 17 00:00:00 2001 From: Kyle McMartin <kyle@redhat.com> Date: Fri, 30 Aug 2013 09:28:51 -0400 Subject: [PATCH] Add sysrq option to disable secure boot mode @@ -17,7 +17,7 @@ Subject: [PATCH] Add sysrq option to disable secure boot mode 7 files changed, 65 insertions(+), 10 deletions(-) diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c -index c773add..92c480c 100644 +index 5ce785fc9f05..2024cbb7169b 100644 --- a/arch/x86/kernel/setup.c +++ b/arch/x86/kernel/setup.c @@ -70,6 +70,11 @@ @@ -32,7 +32,7 @@ index c773add..92c480c 100644 #include <video/edid.h> #include <asm/mtrr.h> -@@ -1275,6 +1280,37 @@ void __init i386_reserve_resources(void) +@@ -1268,6 +1273,37 @@ void __init i386_reserve_resources(void) #endif /* CONFIG_X86_32 */ @@ -71,10 +71,10 @@ index c773add..92c480c 100644 .notifier_call = dump_kernel_offset }; diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c -index 7728359..a3e8ba8 100644 +index 856936247500..1e87a1ea704b 100644 --- a/drivers/input/misc/uinput.c +++ b/drivers/input/misc/uinput.c -@@ -351,6 +351,7 @@ static int uinput_allocate_device(struct uinput_device *udev) +@@ -353,6 +353,7 @@ static int uinput_allocate_device(struct uinput_device *udev) if (!udev->dev) return -ENOMEM; @@ -83,10 +83,10 @@ index 7728359..a3e8ba8 100644 input_set_drvdata(udev->dev, udev); diff --git a/drivers/tty/sysrq.c b/drivers/tty/sysrq.c -index ce396ec..aee594a 100644 +index 454b65898e2c..19d67594a3b8 100644 --- a/drivers/tty/sysrq.c +++ b/drivers/tty/sysrq.c -@@ -462,6 +462,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = { +@@ -463,6 +463,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = { &sysrq_showstate_blocked_op, /* w */ /* x: May be registered on ppc/powerpc for xmon */ /* x: May be registered on sparc64 for global PMU dump */ @@ -94,7 +94,7 @@ index ce396ec..aee594a 100644 NULL, /* x */ /* y: May be registered on sparc64 for global register dump */ NULL, /* y */ -@@ -505,7 +506,7 @@ static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p) +@@ -506,7 +507,7 @@ static void __sysrq_put_key_op(int key, struct sysrq_key_op *op_p) sysrq_key_table[i] = op_p; } @@ -103,7 +103,7 @@ index ce396ec..aee594a 100644 { struct sysrq_key_op *op_p; int orig_log_level; -@@ -525,11 +526,15 @@ void __handle_sysrq(int key, bool check_mask) +@@ -526,11 +527,15 @@ void __handle_sysrq(int key, bool check_mask) op_p = __sysrq_get_key_op(key); if (op_p) { @@ -120,7 +120,7 @@ index ce396ec..aee594a 100644 printk("%s\n", op_p->action_msg); console_loglevel = orig_log_level; op_p->handler(key); -@@ -560,7 +565,7 @@ void __handle_sysrq(int key, bool check_mask) +@@ -562,7 +567,7 @@ void __handle_sysrq(int key, bool check_mask) void handle_sysrq(int key) { if (sysrq_on()) @@ -129,7 +129,7 @@ index ce396ec..aee594a 100644 } EXPORT_SYMBOL(handle_sysrq); -@@ -640,7 +645,7 @@ static void sysrq_do_reset(unsigned long _state) +@@ -642,7 +647,7 @@ static void sysrq_do_reset(unsigned long _state) static void sysrq_handle_reset_request(struct sysrq_state *state) { if (state->reset_requested) @@ -138,7 +138,7 @@ index ce396ec..aee594a 100644 if (sysrq_reset_downtime_ms) mod_timer(&state->keyreset_timer, -@@ -791,8 +796,10 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq, +@@ -793,8 +798,10 @@ static bool sysrq_handle_keypress(struct sysrq_state *sysrq, default: if (sysrq->active && value && value != 2) { @@ -150,7 +150,7 @@ index ce396ec..aee594a 100644 } break; } -@@ -1080,7 +1087,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, +@@ -1089,7 +1096,7 @@ static ssize_t write_sysrq_trigger(struct file *file, const char __user *buf, if (get_user(c, buf)) return -EFAULT; @@ -160,7 +160,7 @@ index ce396ec..aee594a 100644 return count; diff --git a/include/linux/input.h b/include/linux/input.h -index 82ce323..9e534f2 100644 +index 82ce323b9986..9e534f228945 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -42,6 +42,7 @@ struct input_value { @@ -190,7 +190,7 @@ index 82ce323..9e534f2 100644 * Verify that we are in sync with input_device_id mod_devicetable.h #defines */ diff --git a/include/linux/sysrq.h b/include/linux/sysrq.h -index 387fa7d..4b07e30 100644 +index 387fa7d05c98..4b07e30b3279 100644 --- a/include/linux/sysrq.h +++ b/include/linux/sysrq.h @@ -28,6 +28,8 @@ @@ -217,7 +217,7 @@ index 387fa7d..4b07e30 100644 int unregister_sysrq_key(int key, struct sysrq_key_op *op); struct sysrq_key_op *__sysrq_get_key_op(int key); diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c -index 0b097c8..18b400d 100644 +index 2f7c760305ca..abb29d9811af 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -1924,7 +1924,7 @@ static int kdb_sr(int argc, const char **argv) @@ -230,7 +230,7 @@ index 0b097c8..18b400d 100644 return 0; diff --git a/kernel/module.c b/kernel/module.c -index 92b73b1..a44fb2a 100644 +index 452079124fb7..37dabbc1e902 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -109,9 +109,9 @@ struct list_head *kdb_modules = &modules; /* kdb needs the list of modules */ @@ -246,5 +246,5 @@ index 92b73b1..a44fb2a 100644 static int param_set_bool_enable_only(const char *val, const struct kernel_param *kp) -- -1.8.4.2 +1.9.3 diff --git a/freed-ora/current/master/thinkpad_acpi-Add-mappings-for-F9-F12-hotkeys-on-X24.patch b/freed-ora/current/master/thinkpad_acpi-Add-mappings-for-F9-F12-hotkeys-on-X24.patch deleted file mode 100644 index 9f82b7d66..000000000 --- a/freed-ora/current/master/thinkpad_acpi-Add-mappings-for-F9-F12-hotkeys-on-X24.patch +++ /dev/null @@ -1,45 +0,0 @@ -Bugzilla: N/A -Upstream-status: Sent for 3.16 - -From a02f11f85e2cb2e0aced78913ebcf060d6055203 Mon Sep 17 00:00:00 2001 -From: Hans de Goede <hdegoede@redhat.com> -Date: Mon, 2 Jun 2014 17:40:58 +0200 -Subject: [PATCH 01/14] thinkpad_acpi: Add mappings for F9 - F12 hotkeys on - X240 / T440 / T540 -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -The T440s user guide says that when Fn-lock is not active, the *40s' F9 - F12 -keys should be mapped to: control-panel, search, show-all-windows and Computer. - -These keys generate the sofar unused 28 - 31 hotkey scancodes. - -For the first 2 this nicely matches the icons on the keys, for the latter 2 -the icons are somewhat creative, which is why I ended up looking them up in -the user manual. - -Signed-off-by: Hans de Goede <hdegoede@redhat.com> ---- - drivers/platform/x86/thinkpad_acpi.c | 4 +++- - 1 file changed, 3 insertions(+), 1 deletion(-) - -diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c -index 15e61c16736e..d82f196e3cfe 100644 ---- a/drivers/platform/x86/thinkpad_acpi.c -+++ b/drivers/platform/x86/thinkpad_acpi.c -@@ -3171,8 +3171,10 @@ static int __init hotkey_init(struct ibm_init_struct *iibm) - KEY_MICMUTE, /* 0x1a: Mic mute (since ?400 or so) */ - - /* (assignments unknown, please report if found) */ -- KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, KEY_UNKNOWN, - KEY_UNKNOWN, -+ -+ /* Extra keys in use since the X240 / T440 / T540 */ -+ KEY_CONFIG, KEY_SEARCH, KEY_SCALE, KEY_COMPUTER, - }, - }; - --- -1.9.0 - |