LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 2/3] dts: mpc512x: adjust clock specs for FEC nodes
From: Gerhard Sittig @ 2014-03-03  9:22 UTC (permalink / raw)
  To: devicetree, linux-arm-kernel, linuxppc-dev
  Cc: Mark Rutland, Shawn Guo, Mike Turquette, Pawel Moll, Ian Campbell,
	Rob Herring, Anatolij Gustschin
In-Reply-To: <1393237557-31406-2-git-send-email-gsi@denx.de>

On Mon, Feb 24, 2014 at 11:25 +0100, Gerhard Sittig wrote:
> 
> a recent FEC binding document update that was motivated by i.MX
> development revealed that ARM and PowerPC implementations in Linux
> did not agree on the clock names to use for the FEC nodes
> 
> change clock names from "per" to "ipg" in the FEC nodes of the
> mpc5121.dtsi include file such that the .dts specs comply with
> the common FEC binding
> 
> this "incompatible" change does not break operation, because
> - COMMON_CLK support for MPC5121/23/25 and adjusted .dts files
>   were only introduced in Linux v3.14-rc1, no mainline release
>   provided these specs before
> - if this change won't make it for v3.14, the MPC512x CCF support
>   provides full backwards compability, and keeps operating with
>   device trees which lack clock specs or don't match in the names
> 
> Signed-off-by: Gerhard Sittig <gsi@denx.de>

ping

Are there opinions about making PowerPC users of FEC use the same
clock names as ARM users do, to re-use (actually: keep sharing)
the FEC binding?  The alternative would be to fragment the FEC
binding into several bindings for ARM and PowerPC, which I feel
would be undesirable, and is not necessary.

It would be nice to ship v3.14 (the first release with proper CCF
support for MPC512x) in a shape that is consistent with other FEC
users (ARM i.MX).  We are lucky to have noticed the difference
before the release, and need not introduce the incompatibility,
and need not document and support obsolete conditions but can fix
them instead.

> ---
>  arch/powerpc/boot/dts/mpc5121.dtsi |    4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi b/arch/powerpc/boot/dts/mpc5121.dtsi
> index 2c0e1552d20b..a5a375598ed8 100644
> --- a/arch/powerpc/boot/dts/mpc5121.dtsi
> +++ b/arch/powerpc/boot/dts/mpc5121.dtsi
> @@ -281,7 +281,7 @@
>  			#address-cells = <1>;
>  			#size-cells = <0>;
>  			clocks = <&clks MPC512x_CLK_FEC>;
> -			clock-names = "per";
> +			clock-names = "ipg";
>  		};
>  
>  		eth0: ethernet@2800 {
> @@ -291,7 +291,7 @@
>  			local-mac-address = [ 00 00 00 00 00 00 ];
>  			interrupts = <4 0x8>;
>  			clocks = <&clks MPC512x_CLK_FEC>;
> -			clock-names = "per";
> +			clock-names = "ipg";
>  		};
>  
>  		/* USB1 using external ULPI PHY */
> -- 
> 1.7.10.4


virtually yours
Gerhard Sittig
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr. 5, D-82194 Groebenzell, Germany
Phone: +49-8142-66989-0 Fax: +49-8142-66989-80  Email: office@denx.de

^ permalink raw reply

* [PATCH 1/3] powerpc/fsl-booke: Add support for T2080/T2081 SoC
From: Shengzhou Liu @ 2014-03-03  9:50 UTC (permalink / raw)
  To: linuxppc-dev, scottwood; +Cc: Shengzhou Liu

Add support for T2080/T2081 SoC without DPAA components.

The T2080 SoC includes the following function and features:
- Four dual-threaded 64-bit Power architecture e6500 cores, up to 1.8GHz
- 2MB L2 cache and 512KB CoreNet platform cache (CPC)
- Hierarchical interconnect fabric
- One 32-/64-bit DDR3/3L SDRAM memory controllers with ECC and interleaving
- Data Path Acceleration Architecture (DPAA) incorporating acceleration
- 16 SerDes lanes up to 10.3125 GHz
- 8 Ethernet interfaces (multiple 1G/2.5G/10G MACs)
- High-speed peripheral interfaces
  - Four PCI Express controllers (two PCIe 2.0 and two PCIe 3.0)
  - Two Serial RapidIO 2.0 controllers/ports running at up to 5 GHz
- Additional peripheral interfaces
  - Two serial ATA (SATA 2.0) controllers
  - Two high-speed USB 2.0 controllers with integrated PHY
  - Enhanced secure digital host controller (SD/SDXC/eMMC)
  - Enhanced serial peripheral interface (eSPI)
  - Four I2C controllers
  - Four 2-pin UARTs or two 4-pin UARTs
  - Integrated Flash Controller supporting NAND and NOR flash
- Three eight-channel DMA engines
- Support for hardware virtualization and partitioning enforcement
- QorIQ Platform's Trust Architecture 2.0

T2081 is a reduced personality of T2080 without SATA, sRIO, RMan,
Aurora, and with less SerDes lanes and ethernet interfaces.

Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
---
 arch/powerpc/boot/dts/fsl/t2080si-post.dtsi |  60 +++++
 arch/powerpc/boot/dts/fsl/t2081si-post.dtsi | 344 ++++++++++++++++++++++++++++
 arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi  |  96 ++++++++
 arch/powerpc/include/asm/mpc85xx.h          |   2 +
 4 files changed, 502 insertions(+)
 create mode 100644 arch/powerpc/boot/dts/fsl/t2080si-post.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
 create mode 100644 arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi

diff --git a/arch/powerpc/boot/dts/fsl/t2080si-post.dtsi b/arch/powerpc/boot/dts/fsl/t2080si-post.dtsi
new file mode 100644
index 0000000..1a902fe
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t2080si-post.dtsi
@@ -0,0 +1,60 @@
+/*
+ * T2080 Silicon/SoC Device Tree Source (post include)
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "t2081si-post.dtsi"
+
+&soc {
+/include/ "qoriq-sata2-0.dtsi"
+/include/ "qoriq-sata2-1.dtsi"
+};
+
+&rio {
+	compatible = "fsl,srio";
+	interrupts = <16 2 1 11>;
+	#address-cells = <2>;
+	#size-cells = <2>;
+	ranges;
+
+	port1 {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		cell-index = <1>;
+	};
+
+	port2 {
+		#address-cells = <2>;
+		#size-cells = <2>;
+		cell-index = <2>;
+	};
+};
diff --git a/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
new file mode 100644
index 0000000..0f05be2
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t2081si-post.dtsi
@@ -0,0 +1,344 @@
+/*
+ * T2081 Silicon/SoC Device Tree Source (post include)
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *	 notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *	 notice, this list of conditions and the following disclaimer in the
+ *	 documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *	 names of its contributors may be used to endorse or promote products
+ *	 derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+&ifc {
+	#address-cells = <2>;
+	#size-cells = <1>;
+	compatible = "fsl,ifc", "simple-bus";
+	interrupts = <25 2 0 0>;
+};
+
+/* controller at 0x240000 */
+&pci0 {
+	compatible = "fsl,t2080-pcie", "fsl,qoriq-pcie";
+	device_type = "pci";
+	#size-cells = <2>;
+	#address-cells = <3>;
+	bus-range = <0x0 0xff>;
+	interrupts = <20 2 0 0>;
+	pcie@0 {
+		reg = <0 0 0 0 0>;
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		device_type = "pci";
+		interrupts = <20 2 0 0>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0 0 1 &mpic 40 1 0 0
+			0000 0 0 2 &mpic 1 1 0 0
+			0000 0 0 3 &mpic 2 1 0 0
+			0000 0 0 4 &mpic 3 1 0 0
+			>;
+	};
+};
+
+/* controller at 0x250000 */
+&pci1 {
+	compatible = "fsl,t2080-pcie", "fsl,qoriq-pcie";
+	device_type = "pci";
+	#size-cells = <2>;
+	#address-cells = <3>;
+	bus-range = <0 0xff>;
+	interrupts = <21 2 0 0>;
+	pcie@0 {
+		reg = <0 0 0 0 0>;
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		device_type = "pci";
+		interrupts = <21 2 0 0>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0 0 1 &mpic 41 1 0 0
+			0000 0 0 2 &mpic 5 1 0 0
+			0000 0 0 3 &mpic 6 1 0 0
+			0000 0 0 4 &mpic 7 1 0 0
+			>;
+	};
+};
+
+/* controller at 0x260000 */
+&pci2 {
+	compatible = "fsl,t2080-pcie", "fsl,qoriq-pcie";
+	device_type = "pci";
+	#size-cells = <2>;
+	#address-cells = <3>;
+	bus-range = <0x0 0xff>;
+	interrupts = <22 2 0 0>;
+	pcie@0 {
+		reg = <0 0 0 0 0>;
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		device_type = "pci";
+		interrupts = <22 2 0 0>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0 0 1 &mpic 42 1 0 0
+			0000 0 0 2 &mpic 9 1 0 0
+			0000 0 0 3 &mpic 10 1 0 0
+			0000 0 0 4 &mpic 11 1 0 0
+			>;
+	};
+};
+
+/* controller at 0x270000 */
+&pci3 {
+	compatible = "fsl,t2080-pcie", "fsl,qoriq-pcie";
+	device_type = "pci";
+	#size-cells = <2>;
+	#address-cells = <3>;
+	bus-range = <0x0 0xff>;
+	interrupts = <23 2 0 0>;
+	pcie@0 {
+		reg = <0 0 0 0 0>;
+		#interrupt-cells = <1>;
+		#size-cells = <2>;
+		#address-cells = <3>;
+		device_type = "pci";
+		interrupts = <23 2 0 0>;
+		interrupt-map-mask = <0xf800 0 0 7>;
+		interrupt-map = <
+			/* IDSEL 0x0 */
+			0000 0 0 1 &mpic 43 1 0 0
+			0000 0 0 2 &mpic 0 1 0 0
+			0000 0 0 3 &mpic 4 1 0 0
+			0000 0 0 4 &mpic 8 1 0 0
+			>;
+	};
+};
+
+&dcsr {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	compatible = "fsl,dcsr", "simple-bus";
+
+	dcsr-epu@0 {
+		compatible = "fsl,t2080-dcsr-epu", "fsl,dcsr-epu";
+		interrupts = <52 2 0 0
+			      84 2 0 0
+			      85 2 0 0
+			      94 2 0 0
+			      95 2 0 0>;
+		reg = <0x0 0x1000>;
+	};
+	dcsr-npc {
+		compatible = "fsl,t2080-dcsr-cnpc", "fsl,dcsr-cnpc";
+		reg = <0x1000 0x1000 0x1002000 0x10000>;
+	};
+	dcsr-nxc@2000 {
+		compatible = "fsl,dcsr-nxc";
+		reg = <0x2000 0x1000>;
+	};
+	dcsr-corenet {
+		compatible = "fsl,dcsr-corenet";
+		reg = <0x8000 0x1000 0x1A000 0x1000>;
+	};
+	dcsr-ocn@11000 {
+		compatible = "fsl,t2080-dcsr-ocn", "fsl,dcsr-ocn";
+		reg = <0x11000 0x1000>;
+	};
+	dcsr-ddr@12000 {
+		compatible = "fsl,dcsr-ddr";
+		dev-handle = <&ddr1>;
+		reg = <0x12000 0x1000>;
+	};
+	dcsr-nal@18000 {
+		compatible = "fsl,t2080-dcsr-nal", "fsl,dcsr-nal";
+		reg = <0x18000 0x1000>;
+	};
+	dcsr-rcpm@22000 {
+		compatible = "fsl,t2080-dcsr-rcpm", "fsl,dcsr-rcpm";
+		reg = <0x22000 0x1000>;
+	};
+	dcsr-snpc@30000 {
+		compatible = "fsl,t2080-dcsr-snpc", "fsl,dcsr-snpc";
+		reg = <0x30000 0x1000 0x1022000 0x10000>;
+	};
+	dcsr-snpc@31000 {
+		compatible = "fsl,t2080-dcsr-snpc", "fsl,dcsr-snpc";
+		reg = <0x31000 0x1000 0x1042000 0x10000>;
+	};
+	dcsr-snpc@32000 {
+		compatible = "fsl,t2080-dcsr-snpc", "fsl,dcsr-snpc";
+		reg = <0x32000 0x1000 0x1062000 0x10000>;
+	};
+	dcsr-cpu-sb-proxy@100000 {
+		compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+		cpu-handle = <&cpu0>;
+		reg = <0x100000 0x1000 0x101000 0x1000>;
+	};
+	dcsr-cpu-sb-proxy@108000 {
+		compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+		cpu-handle = <&cpu1>;
+		reg = <0x108000 0x1000 0x109000 0x1000>;
+	};
+	dcsr-cpu-sb-proxy@110000 {
+		compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+		cpu-handle = <&cpu2>;
+		reg = <0x110000 0x1000 0x111000 0x1000>;
+	};
+	dcsr-cpu-sb-proxy@118000 {
+		compatible = "fsl,dcsr-e6500-sb-proxy", "fsl,dcsr-cpu-sb-proxy";
+		cpu-handle = <&cpu3>;
+		reg = <0x118000 0x1000 0x119000 0x1000>;
+	};
+};
+
+&soc {
+	#address-cells = <1>;
+	#size-cells = <1>;
+	device_type = "soc";
+	compatible = "simple-bus";
+
+	soc-sram-error {
+		compatible = "fsl,soc-sram-error";
+		interrupts = <16 2 1 29>;
+	};
+
+	corenet-law@0 {
+		compatible = "fsl,corenet-law";
+		reg = <0x0 0x1000>;
+		fsl,num-laws = <32>;
+	};
+
+	ddr1: memory-controller@8000 {
+		compatible = "fsl,qoriq-memory-controller-v4.7",
+				"fsl,qoriq-memory-controller";
+		reg = <0x8000 0x1000>;
+		interrupts = <16 2 1 23>;
+	};
+
+	cpc: l3-cache-controller@10000 {
+		compatible = "fsl,t2080-l3-cache-controller", "cache";
+		reg = <0x10000 0x1000
+		       0x11000 0x1000
+		       0x12000 0x1000>;
+		interrupts = <16 2 1 27
+			      16 2 1 26
+			      16 2 1 25>;
+	};
+
+	corenet-cf@18000 {
+		compatible = "fsl,corenet-cf";
+		reg = <0x18000 0x1000>;
+		interrupts = <16 2 1 31>;
+		fsl,ccf-num-csdids = <32>;
+		fsl,ccf-num-snoopids = <32>;
+	};
+
+	iommu@20000 {
+		compatible = "fsl,pamu-v1.0", "fsl,pamu";
+		reg = <0x20000 0x6000>;
+		interrupts = <
+			24 2 0 0
+			16 2 1 30>;
+	};
+
+/include/ "qoriq-mpic4.3.dtsi"
+
+	guts: global-utilities@e0000 {
+		compatible = "fsl,t2080-device-config", "fsl,qoriq-device-config-2.0";
+		reg = <0xe0000 0xe00>;
+		fsl,has-rstcr;
+		fsl,liodn-bits = <12>;
+	};
+
+	clockgen: global-utilities@e1000 {
+		compatible = "fsl,t2080-clockgen", "fsl,qoriq-clockgen-2.0";
+		reg = <0xe1000 0x1000>;
+	};
+
+	rcpm: global-utilities@e2000 {
+		compatible = "fsl,t2080-rcpm", "fsl,qoriq-rcpm-2.0";
+		reg = <0xe2000 0x1000>;
+	};
+
+	sfp: sfp@e8000 {
+		compatible = "fsl,t2080-sfp";
+		reg = <0xe8000 0x1000>;
+	};
+
+	serdes: serdes@ea000 {
+		compatible = "fsl,t2080-serdes";
+		reg = <0xea000 0x4000>;
+	};
+
+/include/ "elo3-dma-0.dtsi"
+/include/ "elo3-dma-1.dtsi"
+/include/ "elo3-dma-2.dtsi"
+
+/include/ "qoriq-espi-0.dtsi"
+	spi@110000 {
+		fsl,espi-num-chipselects = <4>;
+	};
+
+/include/ "qoriq-esdhc-0.dtsi"
+	sdhc@114000 {
+		compatible = "fsl,t2080-esdhc", "fsl,esdhc";
+		sdhci,auto-cmd12;
+	};
+/include/ "qoriq-i2c-0.dtsi"
+/include/ "qoriq-i2c-1.dtsi"
+/include/ "qoriq-duart-0.dtsi"
+/include/ "qoriq-duart-1.dtsi"
+/include/ "qoriq-gpio-0.dtsi"
+/include/ "qoriq-gpio-1.dtsi"
+/include/ "qoriq-gpio-2.dtsi"
+/include/ "qoriq-gpio-3.dtsi"
+/include/ "qoriq-usb2-mph-0.dtsi"
+	usb0: usb@210000 {
+		compatible = "fsl-usb2-mph-v2.4", "fsl-usb2-mph";
+		phy_type = "utmi";
+		port0;
+	};
+/include/ "qoriq-usb2-dr-0.dtsi"
+	usb1: usb@211000 {
+		compatible = "fsl-usb2-dr-v2.4", "fsl-usb2-dr";
+		dr_mode = "host";
+		phy_type = "utmi";
+	};
+/include/ "qoriq-sec5.2-0.dtsi"
+
+	L2_1: l2-cache-controller@c20000 {
+		/* Cluster 0 L2 cache */
+		compatible = "fsl,t2080-l2-cache-controller";
+		reg = <0xc20000 0x40000>;
+		next-level-cache = <&cpc>;
+	};
+};
diff --git a/arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi b/arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi
new file mode 100644
index 0000000..2628f1b
--- /dev/null
+++ b/arch/powerpc/boot/dts/fsl/t208xsi-pre.dtsi
@@ -0,0 +1,96 @@
+/*
+ * T2080/T2081 Silicon/SoC Device Tree Source (pre include)
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *	 notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *	 notice, this list of conditions and the following disclaimer in the
+ *	 documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *	 names of its contributors may be used to endorse or promote products
+ *	 derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/dts-v1/;
+
+/include/ "e6500_power_isa.dtsi"
+
+/ {
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&mpic>;
+
+	aliases {
+		ccsr = &soc;
+		dcsr = &dcsr;
+
+		serial0 = &serial0;
+		serial1 = &serial1;
+		serial2 = &serial2;
+		serial3 = &serial3;
+
+		crypto = &crypto;
+		pci0 = &pci0;
+		pci1 = &pci1;
+		pci2 = &pci2;
+		pci3 = &pci3;
+		usb0 = &usb0;
+		usb1 = &usb1;
+		dma0 = &dma0;
+		dma1 = &dma1;
+		dma2 = &dma2;
+		sdhc = &sdhc;
+	};
+
+	cpus {
+		#address-cells = <1>;
+		#size-cells = <0>;
+
+		/*
+		 * Temporarily add next-level-cache info in each cpu node so
+		 * that uboot can do L2 cache fixup. This can be removed once
+		 * u-boot can create cpu node with cache info.
+		 */
+		cpu0: PowerPC,e6500@0 {
+			device_type = "cpu";
+			reg = <0 1>;
+			next-level-cache = <&L2_1>;
+		};
+		cpu1: PowerPC,e6500@2 {
+			device_type = "cpu";
+			reg = <2 3>;
+			next-level-cache = <&L2_1>;
+		};
+		cpu2: PowerPC,e6500@4 {
+			device_type = "cpu";
+			reg = <4 5>;
+			next-level-cache = <&L2_1>;
+		};
+		cpu3: PowerPC,e6500@6 {
+			device_type = "cpu";
+			reg = <6 7>;
+			next-level-cache = <&L2_1>;
+		};
+	};
+};
diff --git a/arch/powerpc/include/asm/mpc85xx.h b/arch/powerpc/include/asm/mpc85xx.h
index 736d4ac..3bef74a 100644
--- a/arch/powerpc/include/asm/mpc85xx.h
+++ b/arch/powerpc/include/asm/mpc85xx.h
@@ -77,6 +77,8 @@
 #define SVR_T1020	0x852100
 #define SVR_T1021	0x852101
 #define SVR_T1022	0x852102
+#define SVR_T2080	0x853000
+#define SVR_T2081	0x853100
 
 #define SVR_8610	0x80A000
 #define SVR_8641	0x809000
-- 
1.8.0

^ permalink raw reply related

* [PATCH 3/3] powerpc/t2080rdb: Add T2080RDB board support
From: Shengzhou Liu @ 2014-03-03  9:50 UTC (permalink / raw)
  To: linuxppc-dev, scottwood; +Cc: Shengzhou Liu
In-Reply-To: <1393840220-31086-1-git-send-email-Shengzhou.Liu@freescale.com>

T2080PCIe-RDB is a Freescale Reference Design Board that hosts the T2080 SoC.
The board feature overview:
Processor:
 - T2080 SoC integrating four 64-bit dual-threads e6500 cores up to 1.8GHz
DDR Memory:
 - Single memory controller capable of supporting DDR3 and DDR3-LP devices
 - 72bit 4GB DDR3-LP SODIMM in slot
Ethernet interfaces:
 - Two 10M/100M/1Gbps RGMII ports on-board
 - Two 10Gbps SFP+ ports on-board
 - Two 10Gbps Base-T ports on-board
Accelerator:
 - DPAA components consist of FMan, BMan, QMan, PME, DCE and SEC
SerDes 16 lanes configuration:
 - SerDes-1 Lane A-B: to two 10G SFP+ (MAC9 & MAC10)
 - SerDes-1 Lane C-D: to two 10G Base-T (MAC1 & MAC2)
 - SerDes-1 Lane E-H: to PCIe goldfinger (PCIe4 x4, Gen3)
 - SerDes-2 Lane A-D: to PCIe slot (PCIe1 x4, Gen2)
 - SerDes-2 Lane E-F: to C293 secure co-processor (PCIe2 x2)
 - SerDes-2 Lane G-H: to SATA1 & SATA2
IFC/Local Bus
 - NOR:  128MB 16-bit NOR flash
 - NAND: 512MB 8-bit NAND flash
 - CPLD: for system controlling with programable header on-board
eSPI:
 - 64MB N25Q512 SPI flash
USB:
 - Two USB2.0 ports with internal PHY (both Type-A)
PCIe:
 - One PCIe x4 gold-finger
 - One PCIe x4 connector
 - One PCIe x2 end-point device (C293 crypto co-processor)
SATA:
 - Two SATA 2.0 ports on-board
SDHC:
 - support a TF-card on-board
I2C:
 - Four I2C controllers.
UART:
 - Dual 4-pins UART serial ports

This board can work in two mode: standalone mode and PCIe endpoint mode.

Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
---
 arch/powerpc/boot/dts/t2080rdb.dts            |  57 +++++++
 arch/powerpc/boot/dts/t208xrdb.dtsi           | 210 ++++++++++++++++++++++++++
 arch/powerpc/platforms/85xx/Kconfig           |   2 +-
 arch/powerpc/platforms/85xx/corenet_generic.c |   4 +-
 4 files changed, 271 insertions(+), 2 deletions(-)
 create mode 100644 arch/powerpc/boot/dts/t2080rdb.dts
 create mode 100644 arch/powerpc/boot/dts/t208xrdb.dtsi

diff --git a/arch/powerpc/boot/dts/t2080rdb.dts b/arch/powerpc/boot/dts/t2080rdb.dts
new file mode 100644
index 0000000..e889104
--- /dev/null
+++ b/arch/powerpc/boot/dts/t2080rdb.dts
@@ -0,0 +1,57 @@
+/*
+ * T2080PCIe-RDB Board Device Tree Source
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *	 notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *	 notice, this list of conditions and the following disclaimer in the
+ *	 documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *	 names of its contributors may be used to endorse or promote products
+ *	 derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "fsl/t208xsi-pre.dtsi"
+/include/ "t208xrdb.dtsi"
+
+/ {
+	model = "fsl,T2080RDB";
+	compatible = "fsl,T2080RDB";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&mpic>;
+
+	rio: rapidio@ffe0c0000 {
+		reg = <0xf 0xfe0c0000 0 0x11000>;
+
+		port1 {
+			ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+		};
+		port2 {
+			ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+		};
+	};
+};
+
+/include/ "fsl/t2080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t208xrdb.dtsi b/arch/powerpc/boot/dts/t208xrdb.dtsi
new file mode 100644
index 0000000..439a5c1
--- /dev/null
+++ b/arch/powerpc/boot/dts/t208xrdb.dtsi
@@ -0,0 +1,210 @@
+/*
+ * T2080/T2081PCIe-RDB Board Device Tree Source
+ *
+ * Copyright 2014 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *	 notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *	 notice, this list of conditions and the following disclaimer in the
+ *	 documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *	 names of its contributors may be used to endorse or promote products
+ *	 derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/ {
+	model = "fsl,T2080RDB";
+	compatible = "fsl,T2080RDB";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&mpic>;
+
+	ifc: localbus@ffe124000 {
+		reg = <0xf 0xfe124000 0 0x2000>;
+		ranges = <0 0 0xf 0xe8000000 0x08000000
+			  2 0 0xf 0xff800000 0x00010000
+			  3 0 0xf 0xffdf0000 0x00008000>;
+
+		nor@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x0 0x8000000>;
+
+			bank-width = <2>;
+			device-width = <1>;
+		};
+
+		nand@1,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,ifc-nand";
+			reg = <0x2 0x0 0x10000>;
+		};
+
+		boardctrl: board-control@2,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,t2080-cpld";
+			reg = <3 0 0x300>;
+			ranges = <0 3 0 0x300>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	dcsr: dcsr@f00000000 {
+		ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+	};
+
+	soc: soc@ffe000000 {
+		ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+		reg = <0xf 0xfe000000 0 0x00001000>;
+		spi@110000 {
+			flash@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "micron,n25q512a";
+				reg = <0>;
+				spi-max-frequency = <10000000>; /* input clock */
+			};
+
+
+			flash@1 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "sst,sst25wf040";
+				reg = <1>;
+				spi-max-frequency = <40000000>; /* input clock */
+			};
+		};
+
+		i2c@118000 {
+			pca9547@77 {
+				compatible = "nxp,pca9547";
+				reg = <0x77>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				i2c@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x0>;
+
+					eeprom@50 {
+						compatible = "at24,24c256";
+						reg = <0x50>;
+					};
+
+					eeprom@51 {
+						compatible = "at24,24c02";
+						reg = <0x51>;
+					};
+
+					rtc@68 {
+						compatible = "dallas,ds3232";
+						reg = <0x68>;
+						interrupts = <0x1 0x1 0 0>;
+					};
+				};
+
+				i2c@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x1>;
+
+					eeprom@55 {
+						compatible = "at24,24c02";
+						reg = <0x55>;
+					};
+				};
+			};
+		};
+
+		sdhc@114000 {
+			voltage-ranges = <1800 1800 3300 3300>;
+		};
+	};
+
+	pci0: pcie@ffe240000 {
+		reg = <0xf 0xfe240000 0 0x10000>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+			  0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci1: pcie@ffe250000 {
+		reg = <0xf 0xfe250000 0 0x10000>;
+		ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x10000000
+			  0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci2: pcie@ffe260000 {
+		reg = <0xf 0xfe260000 0 0x1000>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci3: pcie@ffe270000 {
+		reg = <0xf 0xfe270000 0 0x10000>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+};
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index e3578b7..a8a0f2f 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -259,7 +259,7 @@ config CORENET_GENERIC
 	  For 32bit kernel, the following boards are supported:
 	    P2041 RDB, P3041 DS and P4080 DS
 	  For 64bit kernel, the following boards are supported:
-	    T208x QDS, T4240 QDS and B4 QDS
+	    T208x QDS/RDB, T4240 QDS and B4 QDS
 	  The following boards are supported for both 32bit and 64bit kernel:
 	    P5020 DS and P5040 DS
 
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
index 77fd71f..a4fdb7e 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -103,6 +103,7 @@ static const char * const boards[] __initconst = {
 	"fsl,P5020DS",
 	"fsl,P5040DS",
 	"fsl,T2080QDS",
+	"fsl,T2080RDB",
 	"fsl,T2081QDS",
 	"fsl,T4240QDS",
 	"fsl,B4860QDS",
@@ -118,7 +119,8 @@ static const char * const hv_boards[] __initconst = {
 	"fsl,P5020DS-hv",
 	"fsl,P5040DS-hv",
 	"fsl,T2080QDS-hv",
-	"fsl,T2081QDS-hv"
+	"fsl,T2080RDB-hv",
+	"fsl,T2081QDS-hv",
 	"fsl,T4240QDS-hv",
 	"fsl,B4860QDS-hv",
 	"fsl,B4420QDS-hv",
-- 
1.8.0

^ permalink raw reply related

* [PATCH 2/3] powerpc/fsl-booke: Add initial T208x QDS board support
From: Shengzhou Liu @ 2014-03-03  9:50 UTC (permalink / raw)
  To: linuxppc-dev, scottwood; +Cc: Shengzhou Liu
In-Reply-To: <1393840220-31086-1-git-send-email-Shengzhou.Liu@freescale.com>

Add support for Freescale T2080/T2081 QDS Development System Board.
T2081QDS board shares the same PCB with T1040QDS with some differences.

The T2080QDS Development System is a high-performance computing,
evaluation, and development platform that supports T2080 QorIQ
Power Architecture processor, with following major features:

T2080QDS feature overview:
Processor:
 - T2080 SoC integrating four 64-bit dual-threads e6500 cores up to 1.8GHz
Memory:
 - Single memory controller capable of supporting DDR3 and DDR3-LV devices
 - Two DDR3 memory, 4GB, Dual rank @ 1866 Mbps data rate, and ECC support
Ethernet interfaces:
 - Two 1Gbps RGMII on-board ports
 - Four 10Gbps XFI on-board cages
 - 1Gbps/2.5Gbps SGMII Riser card
 - 10Gbps XAUI Riser card
Accelerator:
 - DPAA components consist of FMan, BMan, QMan, PME, DCE and SEC
SerDes:
 - 16 lanes up to 10.3125GHz
 - Supports Aurora debug, PEX, SATA, SGMII, sRIO, HiGig, XFI and XAUI
IFC:
 - 128MB NOR Flash, 512MB NAND Flash, PromJet debug port and FPGA
eSPI:
 - Three SPI flash (16MB N25Q128A + 16MB EN25S64 + 512KB SST25WF040)
USB:
 - Two USB2.0 ports with internal PHY (one Type-A + one micro Type-AB)
PCIE:
 - Four PCI Express controllers (two PCIe 2.0 and two PCIe 3.0 with SR-IOV)
SATA:
 - Two SATA 2.0 ports on-board
SRIO:
 - Two Serial RapidIO 2.0 ports up to 5 GHz
eSDHC:
 - Supports SD/MMC/eMMC Card
DMA:
 - Three 8-channels DMA controllers
I2C:
 - Four I2C controllers.
UART:
 - Dual 4-pins UART serial ports
System Logic:
 - QIXIS-II FPGA system controll

Differences between T2080 and T2081:
  Feature               T2080 T2081
  1G Ethernet numbers:  8     6
  10G Ethernet numbers: 4     2
  SerDes lanes:         16    8
  Serial RapidIO,RMan:  2     no
  SATA Controller:      2     no
  Aurora:               yes   no
  SoC Package:          896-pins 780-pins

Signed-off-by: Shengzhou Liu <Shengzhou.Liu@freescale.com>
---
 arch/powerpc/boot/dts/t2080qds.dts            |  57 +++++++
 arch/powerpc/boot/dts/t2081qds.dts            |  48 ++++++
 arch/powerpc/boot/dts/t208xqds.dtsi           | 213 ++++++++++++++++++++++++++
 arch/powerpc/platforms/85xx/Kconfig           |   2 +-
 arch/powerpc/platforms/85xx/corenet_generic.c |   4 +
 5 files changed, 323 insertions(+), 1 deletion(-)
 create mode 100644 arch/powerpc/boot/dts/t2080qds.dts
 create mode 100644 arch/powerpc/boot/dts/t2081qds.dts
 create mode 100644 arch/powerpc/boot/dts/t208xqds.dtsi

diff --git a/arch/powerpc/boot/dts/t2080qds.dts b/arch/powerpc/boot/dts/t2080qds.dts
new file mode 100644
index 0000000..aa1d6d8
--- /dev/null
+++ b/arch/powerpc/boot/dts/t2080qds.dts
@@ -0,0 +1,57 @@
+/*
+ * T2080QDS Device Tree Source
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *	 notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *	 notice, this list of conditions and the following disclaimer in the
+ *	 documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *	 names of its contributors may be used to endorse or promote products
+ *	 derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "fsl/t208xsi-pre.dtsi"
+/include/ "t208xqds.dtsi"
+
+/ {
+	model = "fsl,T2080QDS";
+	compatible = "fsl,T2080QDS";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&mpic>;
+
+	rio: rapidio@ffe0c0000 {
+		reg = <0xf 0xfe0c0000 0 0x11000>;
+
+		port1 {
+			ranges = <0 0 0xc 0x20000000 0 0x10000000>;
+		};
+		port2 {
+			ranges = <0 0 0xc 0x30000000 0 0x10000000>;
+		};
+	};
+};
+
+/include/ "fsl/t2080si-post.dtsi"
diff --git a/arch/powerpc/boot/dts/t2081qds.dts b/arch/powerpc/boot/dts/t2081qds.dts
new file mode 100644
index 0000000..8ed92a0
--- /dev/null
+++ b/arch/powerpc/boot/dts/t2081qds.dts
@@ -0,0 +1,48 @@
+/*
+ * T2081QDS Device Tree Source
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *	 notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *	 notice, this list of conditions and the following disclaimer in the
+ *	 documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *	 names of its contributors may be used to endorse or promote products
+ *	 derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/include/ "fsl/t208xsi-pre.dtsi"
+/include/ "t208xqds.dtsi"
+
+/ {
+	model = "fsl,T2081QDS";
+	compatible = "fsl,T2081QDS";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&mpic>;
+};
+
+/include/ "fsl/t2081si-post.dtsi"
+/include/ "fsl/qoriq-dpaa-res3.dtsi"
+/include/ "fsl/qoriq-qman-ceetm0.dtsi"
diff --git a/arch/powerpc/boot/dts/t208xqds.dtsi b/arch/powerpc/boot/dts/t208xqds.dtsi
new file mode 100644
index 0000000..54e2a1e
--- /dev/null
+++ b/arch/powerpc/boot/dts/t208xqds.dtsi
@@ -0,0 +1,213 @@
+/*
+ * T2080/T2081 QDS Device Tree Source
+ *
+ * Copyright 2013 Freescale Semiconductor Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *	 notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *	 notice, this list of conditions and the following disclaimer in the
+ *	 documentation and/or other materials provided with the distribution.
+ *     * Neither the name of Freescale Semiconductor nor the
+ *	 names of its contributors may be used to endorse or promote products
+ *	 derived from this software without specific prior written permission.
+ *
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/ {
+	model = "fsl,T2080QDS";
+	compatible = "fsl,T2080QDS";
+	#address-cells = <2>;
+	#size-cells = <2>;
+	interrupt-parent = <&mpic>;
+
+	ifc: localbus@ffe124000 {
+		reg = <0xf 0xfe124000 0 0x2000>;
+		ranges = <0 0 0xf 0xe8000000 0x08000000
+			  2 0 0xf 0xff800000 0x00010000
+			  3 0 0xf 0xffdf0000 0x00008000>;
+
+		nor@0,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "cfi-flash";
+			reg = <0x0 0x0 0x8000000>;
+			bank-width = <2>;
+			device-width = <1>;
+		};
+
+		nand@2,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,ifc-nand";
+			reg = <0x2 0x0 0x10000>;
+		};
+
+		boardctrl: board-control@3,0 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "fsl,fpga-qixis";
+			reg = <3 0 0x300>;
+			ranges = <0 3 0 0x300>;
+		};
+	};
+
+	memory {
+		device_type = "memory";
+	};
+
+	dcsr: dcsr@f00000000 {
+		ranges = <0x00000000 0xf 0x00000000 0x01072000>;
+	};
+
+	soc: soc@ffe000000 {
+		ranges = <0x00000000 0xf 0xfe000000 0x1000000>;
+		reg = <0xf 0xfe000000 0 0x00001000>;
+		spi@110000 {
+			flash@0 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "spansion,s25sl12801";
+				reg = <0>;
+				spi-max-frequency = <40000000>; /* input clock */
+			};
+
+			flash@1 {
+				#address-cells = <1>;
+				#size-cells = <1>;
+				compatible = "sst,sst25wf040";
+				reg = <1>;
+				spi-max-frequency = <40000000>; /* input clock */
+			};
+		};
+
+		i2c@118000 {
+			pca9547@77 {
+				compatible = "nxp,pca9547";
+				reg = <0x77>;
+				#address-cells = <1>;
+				#size-cells = <0>;
+
+				i2c@0 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x0>;
+
+					eeprom@50 {
+						compatible = "at24,24c256";
+						reg = <0x50>;
+					};
+
+					eeprom@51 {
+						compatible = "at24,24c02";
+						reg = <0x51>;
+					};
+
+					eeprom@57 {
+						compatible = "at24,24c02";
+						reg = <0x57>;
+					};
+
+					rtc@68 {
+						compatible = "dallas,ds3232";
+						reg = <0x68>;
+						interrupts = <0x1 0x1 0 0>;
+					};
+				};
+
+				i2c@1 {
+					#address-cells = <1>;
+					#size-cells = <0>;
+					reg = <0x1>;
+
+					eeprom@55 {
+						compatible = "at24,24c02";
+						reg = <0x55>;
+					};
+				};
+			};
+		};
+
+		sdhc@114000 {
+			voltage-ranges = <1800 1800 3300 3300>;
+		};
+	};
+
+	pci0: pcie@ffe240000 {
+		reg = <0xf 0xfe240000 0 0x10000>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x00000000 0x0 0x20000000
+			  0x01000000 0 0x00000000 0xf 0xf8000000 0x0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci1: pcie@ffe250000 {
+		reg = <0xf 0xfe250000 0 0x10000>;
+		ranges = <0x02000000 0x0 0xe0000000 0xc 0x20000000 0x0 0x10000000
+			  0x01000000 0x0 0x00000000 0xf 0xf8010000 0x0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci2: pcie@ffe260000 {
+		reg = <0xf 0xfe260000 0 0x1000>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x30000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xf 0xf8020000 0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+
+	pci3: pcie@ffe270000 {
+		reg = <0xf 0xfe270000 0 0x10000>;
+		ranges = <0x02000000 0 0xe0000000 0xc 0x40000000 0 0x10000000
+			  0x01000000 0 0x00000000 0xf 0xf8030000 0 0x00010000>;
+		pcie@0 {
+			ranges = <0x02000000 0 0xe0000000
+				  0x02000000 0 0xe0000000
+				  0 0x20000000
+
+				  0x01000000 0 0x00000000
+				  0x01000000 0 0x00000000
+				  0 0x00010000>;
+		};
+	};
+};
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 4d46349..e3578b7 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -259,7 +259,7 @@ config CORENET_GENERIC
 	  For 32bit kernel, the following boards are supported:
 	    P2041 RDB, P3041 DS and P4080 DS
 	  For 64bit kernel, the following boards are supported:
-	    T4240 QDS and B4 QDS
+	    T208x QDS, T4240 QDS and B4 QDS
 	  The following boards are supported for both 32bit and 64bit kernel:
 	    P5020 DS and P5040 DS
 
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
index fbd871e..77fd71f 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -102,6 +102,8 @@ static const char * const boards[] __initconst = {
 	"fsl,P4080DS",
 	"fsl,P5020DS",
 	"fsl,P5040DS",
+	"fsl,T2080QDS",
+	"fsl,T2081QDS",
 	"fsl,T4240QDS",
 	"fsl,B4860QDS",
 	"fsl,B4420QDS",
@@ -115,6 +117,8 @@ static const char * const hv_boards[] __initconst = {
 	"fsl,P4080DS-hv",
 	"fsl,P5020DS-hv",
 	"fsl,P5040DS-hv",
+	"fsl,T2080QDS-hv",
+	"fsl,T2081QDS-hv"
 	"fsl,T4240QDS-hv",
 	"fsl,B4860QDS-hv",
 	"fsl,B4420QDS-hv",
-- 
1.8.0

^ permalink raw reply related

* [RFC PATCH] vfio-pci: avoid deadlock between unbind and VFIO_DEVICE_RESET
From: Thadeu Lima de Souza Cascardo @ 2014-03-03 14:33 UTC (permalink / raw)
  To: alex.williamson
  Cc: kvm, aik, linux-kernel, kvm-ppc, Thadeu Lima de Souza Cascardo,
	bhelgaas, linuxppc-dev

When we unbind vfio-pci from a device, while running a guest, we might
have a deadlock when such a guest reboots.

Unbind takes device_lock at device_release_driver, and waits for
release_q at vfio_del_group_dev.

release_q will only be woken up when all references to vfio_device are
gone, and that includes open file descriptors, like the ones a guest
on qemu will hold.

If you try to reboot the guest, it will call VFIO_DEVICE_RESET, which
calls pci_reset_function, which now grabs the device_lock, and we are
deadlocked.

Using device_trylock allow us to handle the case when the lock is
already taken, and avoid this situation.

Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
---

Not tested yet, but I would like some comments now, like would it be
better to have a pci_try_reset_function, or do trylock on
pci_reset_function itself?

---
 drivers/vfio/pci/vfio_pci.c |   14 ++++++++++++--
 1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
index 3b76dc8..d1d2242 100644
--- a/drivers/vfio/pci/vfio_pci.c
+++ b/drivers/vfio/pci/vfio_pci.c
@@ -513,8 +513,18 @@ static long vfio_pci_ioctl(void *device_data,
 		return ret;
 
 	} else if (cmd == VFIO_DEVICE_RESET) {
-		return vdev->reset_works ?
-			pci_reset_function(vdev->pdev) : -EINVAL;
+		struct pci_dev *pdev = vdev->pdev;
+		int ret = -EBUSY;
+		if (!vdev->reset_works)
+			return -EINVAL;
+		if (pci_cfg_access_trylock(pdev)) {
+			if (device_trylock(&pdev->dev)) {
+				ret = __pci_reset_function_locked(pdev);
+				device_unlock(&pdev->dev);
+			}
+			pci_cfg_access_unlock(pdev);
+		}
+		return ret;
 
 	} else if (cmd == VFIO_DEVICE_GET_PCI_HOT_RESET_INFO) {
 		struct vfio_pci_hot_reset_info hdr;
-- 
1.7.1

^ permalink raw reply related

* Re: [RFC PATCH] vfio-pci: avoid deadlock between unbind and VFIO_DEVICE_RESET
From: Alex Williamson @ 2014-03-03 15:09 UTC (permalink / raw)
  To: Thadeu Lima de Souza Cascardo
  Cc: kvm, aik, linux-kernel, kvm-ppc, bhelgaas, linuxppc-dev
In-Reply-To: <1393857192-28360-1-git-send-email-cascardo@linux.vnet.ibm.com>

On Mon, 2014-03-03 at 11:33 -0300, Thadeu Lima de Souza Cascardo wrote:
> When we unbind vfio-pci from a device, while running a guest, we might
> have a deadlock when such a guest reboots.
> 
> Unbind takes device_lock at device_release_driver, and waits for
> release_q at vfio_del_group_dev.
> 
> release_q will only be woken up when all references to vfio_device are
> gone, and that includes open file descriptors, like the ones a guest
> on qemu will hold.
> 
> If you try to reboot the guest, it will call VFIO_DEVICE_RESET, which
> calls pci_reset_function, which now grabs the device_lock, and we are
> deadlocked.
> 
> Using device_trylock allow us to handle the case when the lock is
> already taken, and avoid this situation.
> 
> Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
> ---
> 
> Not tested yet, but I would like some comments now, like would it be
> better to have a pci_try_reset_function, or do trylock on
> pci_reset_function itself?


We already have it:

http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=61cf16d8bd38c3dc52033ea75d5b1f8368514a17
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=890ed578df82f5b7b5a874f9f2fa4f117305df5f

Is there something insufficient about these or are you testing on and
older kernel?  Thanks,

Alex


> ---
>  drivers/vfio/pci/vfio_pci.c |   14 ++++++++++++--
>  1 files changed, 12 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
> index 3b76dc8..d1d2242 100644
> --- a/drivers/vfio/pci/vfio_pci.c
> +++ b/drivers/vfio/pci/vfio_pci.c
> @@ -513,8 +513,18 @@ static long vfio_pci_ioctl(void *device_data,
>  		return ret;
>  
>  	} else if (cmd == VFIO_DEVICE_RESET) {
> -		return vdev->reset_works ?
> -			pci_reset_function(vdev->pdev) : -EINVAL;
> +		struct pci_dev *pdev = vdev->pdev;
> +		int ret = -EBUSY;
> +		if (!vdev->reset_works)
> +			return -EINVAL;
> +		if (pci_cfg_access_trylock(pdev)) {
> +			if (device_trylock(&pdev->dev)) {
> +				ret = __pci_reset_function_locked(pdev);
> +				device_unlock(&pdev->dev);
> +			}
> +			pci_cfg_access_unlock(pdev);
> +		}
> +		return ret;
>  
>  	} else if (cmd == VFIO_DEVICE_GET_PCI_HOT_RESET_INFO) {
>  		struct vfio_pci_hot_reset_info hdr;

^ permalink raw reply

* Re: [RFC PATCH] vfio-pci: avoid deadlock between unbind and VFIO_DEVICE_RESET
From: Thadeu Lima de Souza Cascardo @ 2014-03-03 15:28 UTC (permalink / raw)
  To: Alex Williamson; +Cc: kvm, aik, linux-kernel, kvm-ppc, bhelgaas, linuxppc-dev
In-Reply-To: <1393859362.2895.34.camel@ul30vt.home>

On Mon, Mar 03, 2014 at 08:09:22AM -0700, Alex Williamson wrote:
> On Mon, 2014-03-03 at 11:33 -0300, Thadeu Lima de Souza Cascardo wrote:
> > When we unbind vfio-pci from a device, while running a guest, we might
> > have a deadlock when such a guest reboots.
> > 
> > Unbind takes device_lock at device_release_driver, and waits for
> > release_q at vfio_del_group_dev.
> > 
> > release_q will only be woken up when all references to vfio_device are
> > gone, and that includes open file descriptors, like the ones a guest
> > on qemu will hold.
> > 
> > If you try to reboot the guest, it will call VFIO_DEVICE_RESET, which
> > calls pci_reset_function, which now grabs the device_lock, and we are
> > deadlocked.
> > 
> > Using device_trylock allow us to handle the case when the lock is
> > already taken, and avoid this situation.
> > 
> > Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
> > ---
> > 
> > Not tested yet, but I would like some comments now, like would it be
> > better to have a pci_try_reset_function, or do trylock on
> > pci_reset_function itself?
> 
> 
> We already have it:
> 
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=61cf16d8bd38c3dc52033ea75d5b1f8368514a17
> http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=890ed578df82f5b7b5a874f9f2fa4f117305df5f
> 
> Is there something insufficient about these or are you testing on and
> older kernel?  Thanks,
> 
> Alex

Sorry I missed it. On the rush to report and fix it, I looked only on my
local branch. Should we backport those two patches to long term stable
3.10? I can reproduce the issue there.

Thanks.
Cascardo.

> 
> 
> > ---
> >  drivers/vfio/pci/vfio_pci.c |   14 ++++++++++++--
> >  1 files changed, 12 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
> > index 3b76dc8..d1d2242 100644
> > --- a/drivers/vfio/pci/vfio_pci.c
> > +++ b/drivers/vfio/pci/vfio_pci.c
> > @@ -513,8 +513,18 @@ static long vfio_pci_ioctl(void *device_data,
> >  		return ret;
> >  
> >  	} else if (cmd == VFIO_DEVICE_RESET) {
> > -		return vdev->reset_works ?
> > -			pci_reset_function(vdev->pdev) : -EINVAL;
> > +		struct pci_dev *pdev = vdev->pdev;
> > +		int ret = -EBUSY;
> > +		if (!vdev->reset_works)
> > +			return -EINVAL;
> > +		if (pci_cfg_access_trylock(pdev)) {
> > +			if (device_trylock(&pdev->dev)) {
> > +				ret = __pci_reset_function_locked(pdev);
> > +				device_unlock(&pdev->dev);
> > +			}
> > +			pci_cfg_access_unlock(pdev);
> > +		}
> > +		return ret;
> >  
> >  	} else if (cmd == VFIO_DEVICE_GET_PCI_HOT_RESET_INFO) {
> >  		struct vfio_pci_hot_reset_info hdr;
> 
> 
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Re: [RFC PATCH] vfio-pci: avoid deadlock between unbind and VFIO_DEVICE_RESET
From: Alex Williamson @ 2014-03-03 15:47 UTC (permalink / raw)
  To: Thadeu Lima de Souza Cascardo
  Cc: kvm, aik, linux-kernel, kvm-ppc, bhelgaas, linuxppc-dev
In-Reply-To: <20140303152851.GA20894@oc0268524204.ibm.com>

On Mon, 2014-03-03 at 12:28 -0300, Thadeu Lima de Souza Cascardo wrote:
> On Mon, Mar 03, 2014 at 08:09:22AM -0700, Alex Williamson wrote:
> > On Mon, 2014-03-03 at 11:33 -0300, Thadeu Lima de Souza Cascardo wrote:
> > > When we unbind vfio-pci from a device, while running a guest, we might
> > > have a deadlock when such a guest reboots.
> > > 
> > > Unbind takes device_lock at device_release_driver, and waits for
> > > release_q at vfio_del_group_dev.
> > > 
> > > release_q will only be woken up when all references to vfio_device are
> > > gone, and that includes open file descriptors, like the ones a guest
> > > on qemu will hold.
> > > 
> > > If you try to reboot the guest, it will call VFIO_DEVICE_RESET, which
> > > calls pci_reset_function, which now grabs the device_lock, and we are
> > > deadlocked.
> > > 
> > > Using device_trylock allow us to handle the case when the lock is
> > > already taken, and avoid this situation.
> > > 
> > > Signed-off-by: Thadeu Lima de Souza Cascardo <cascardo@linux.vnet.ibm.com>
> > > ---
> > > 
> > > Not tested yet, but I would like some comments now, like would it be
> > > better to have a pci_try_reset_function, or do trylock on
> > > pci_reset_function itself?
> > 
> > 
> > We already have it:
> > 
> > http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=61cf16d8bd38c3dc52033ea75d5b1f8368514a17
> > http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=890ed578df82f5b7b5a874f9f2fa4f117305df5f
> > 
> > Is there something insufficient about these or are you testing on and
> > older kernel?  Thanks,
> > 
> > Alex
> 
> Sorry I missed it. On the rush to report and fix it, I looked only on my
> local branch. Should we backport those two patches to long term stable
> 3.10? I can reproduce the issue there.

Sure, if you're trying to exercise this path, it's easy to reproduce.
It's also relatively easy to avoid once you know it's there.  It's not
obvious to me that this fix meets the stable patch rules though, it's
bigger than suggested, I'm not sure it really bothers people outside of
QA testing, it does cause a hang, but not a system hang.  I'd certainly
suggest any downstream based on 3.10 that cares about vfio to pick it
up, does that make it sufficient for upstream stable?  Thanks,

Alex
 
> > > ---
> > >  drivers/vfio/pci/vfio_pci.c |   14 ++++++++++++--
> > >  1 files changed, 12 insertions(+), 2 deletions(-)
> > > 
> > > diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
> > > index 3b76dc8..d1d2242 100644
> > > --- a/drivers/vfio/pci/vfio_pci.c
> > > +++ b/drivers/vfio/pci/vfio_pci.c
> > > @@ -513,8 +513,18 @@ static long vfio_pci_ioctl(void *device_data,
> > >  		return ret;
> > >  
> > >  	} else if (cmd == VFIO_DEVICE_RESET) {
> > > -		return vdev->reset_works ?
> > > -			pci_reset_function(vdev->pdev) : -EINVAL;
> > > +		struct pci_dev *pdev = vdev->pdev;
> > > +		int ret = -EBUSY;
> > > +		if (!vdev->reset_works)
> > > +			return -EINVAL;
> > > +		if (pci_cfg_access_trylock(pdev)) {
> > > +			if (device_trylock(&pdev->dev)) {
> > > +				ret = __pci_reset_function_locked(pdev);
> > > +				device_unlock(&pdev->dev);
> > > +			}
> > > +			pci_cfg_access_unlock(pdev);
> > > +		}
> > > +		return ret;
> > >  
> > >  	} else if (cmd == VFIO_DEVICE_GET_PCI_HOT_RESET_INFO) {
> > >  		struct vfio_pci_hot_reset_info hdr;
> > 
> > 
> > 
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/linuxppc-dev
> 
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH] Corenet: Add QE platform support for Corenet
From: Kumar Gala @ 2014-03-03 15:51 UTC (permalink / raw)
  To: Zhao Qiang; +Cc: B07421, R63061, linuxppc-dev
In-Reply-To: <1393577309-41445-1-git-send-email-B45475@freescale.com>


On Feb 28, 2014, at 2:48 AM, Zhao Qiang <B45475@freescale.com> wrote:

> There is QE on platform T104x, add support.
> Call funcs qe_ic_init and qe_init if CONFIG_QUICC_ENGINE is defined.
>=20
> Signed-off-by: Zhao Qiang <B45475@freescale.com>
> ---
> arch/powerpc/platforms/85xx/corenet_generic.c | 32 =
+++++++++++++++++++++++++++
> 1 file changed, 32 insertions(+)

Can you use mpc85xx_qe_init() instead?

>=20
> diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c =
b/arch/powerpc/platforms/85xx/corenet_generic.c
> index fbd871e..f8c8e0c 100644
> --- a/arch/powerpc/platforms/85xx/corenet_generic.c
> +++ b/arch/powerpc/platforms/85xx/corenet_generic.c
> @@ -26,6 +26,8 @@
> #include <asm/udbg.h>
> #include <asm/mpic.h>
> #include <asm/ehv_pic.h>
> +#include <asm/qe.h>
> +#include <asm/qe_ic.h>
>=20
> #include <linux/of_platform.h>
> #include <sysdev/fsl_soc.h>
> @@ -38,6 +40,10 @@ void __init corenet_gen_pic_init(void)
> 	unsigned int flags =3D MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU |
> 		MPIC_NO_RESET;
>=20
> +#ifdef CONFIG_QUICC_ENGINE
> +	struct device_node *np;
> +#endif
> +
> 	if (ppc_md.get_irq =3D=3D mpic_get_coreint_irq)
> 		flags |=3D MPIC_ENABLE_COREINT;
>=20
> @@ -45,6 +51,16 @@ void __init corenet_gen_pic_init(void)
> 	BUG_ON(mpic =3D=3D NULL);
>=20
> 	mpic_init(mpic);
> +
> +#ifdef CONFIG_QUICC_ENGINE
> +	np =3D of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
> +	if (np) {
> +		qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
> +				qe_ic_cascade_high_mpic);
> +		of_node_put(np);
> +	}
> +#endif
> +
> }
>=20
> /*
> @@ -52,11 +68,24 @@ void __init corenet_gen_pic_init(void)
>  */
> void __init corenet_gen_setup_arch(void)
> {
> +#ifdef CONFIG_QUICC_ENGINE
> +	struct device_node *np;
> +#endif
> 	mpc85xx_smp_init();
>=20
> 	swiotlb_detect_4g();
>=20
> 	pr_info("%s board from Freescale Semiconductor\n", ppc_md.name);
> +
> +#ifdef CONFIG_QUICC_ENGINE
> +	np =3D of_find_compatible_node(NULL, NULL, "fsl,qe");
> +	if (!np) {
> +		pr_err("%s: Could not find Quicc Engine node\n", =
__func__);
> +		return;

This doesn=92t seem like an reasonable error message for common corenet =
platform.  It seems reasonable to build QE support but boot on a chip =
w/o QE.

> +	}
> +	qe_reset();
> +	of_node_put(np);
> +#endif
> }
>=20
> static const struct of_device_id of_device_ids[] =3D {
> @@ -81,6 +110,9 @@ static const struct of_device_id of_device_ids[] =3D =
{
> 	{
> 		.compatible	=3D "fsl,qoriq-pcie-v3.0",
> 	},
> +	{
> +		.compatible	=3D "fsl,qe",
> +	},
> 	/* The following two are for the Freescale hypervisor */
> 	{
> 		.name		=3D "hypervisor",
> --=20
> 1.8.5
>=20
>=20
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* Re: Panic on ppc64 with numa_balancing and !sparsemem_vmemmap
From: Mel Gorman @ 2014-03-03 17:26 UTC (permalink / raw)
  To: Srikar Dronamraju
  Cc: riel, Peter Zijlstra, linux-mm, paulus, Aneesh Kumar,
	linuxppc-dev
In-Reply-To: <20140219180200.GA29257@linux.vnet.ibm.com>

On Wed, Feb 19, 2014 at 11:32:00PM +0530, Srikar Dronamraju wrote:
> 
> On a powerpc machine with CONFIG_NUMA_BALANCING=y and CONFIG_SPARSEMEM_VMEMMAP
> not enabled,  kernel panics.
> 

This?

---8<---
sched: numa: Do not group tasks if last cpu is not set

On configurations with vmemmap disabled, the following partial is observed

[  299.268623] CPU: 47 PID: 4366 Comm: numa01 Tainted: G      D      3.14.0-rc5-vanilla #4
[  299.278295] Hardware name: Dell Inc. PowerEdge R810/0TT6JF, BIOS 2.7.4 04/26/2012
[  299.287452] task: ffff880c670bc110 ti: ffff880c66db6000 task.ti: ffff880c66db6000
[  299.296642] RIP: 0010:[<ffffffff8109013f>]  [<ffffffff8109013f>] task_numa_fault+0x50f/0x8b0
[  299.306778] RSP: 0000:ffff880c66db7670  EFLAGS: 00010282
[  299.313769] RAX: 00000000000033ee RBX: ffff880c670bc110 RCX: 0000000000000001
[  299.322590] RDX: 0000000000000001 RSI: 0000000000000003 RDI: 00000000ffffffff
[  299.331394] RBP: ffff880c66db76c8 R08: 0000000000000000 R09: 00000000000166b0
[  299.340203] R10: ffff880c7ffecd80 R11: 0000000000000000 R12: 00000000000001ff
[  299.348989] R13: 00000000000000ff R14: 00000000ffffffff R15: 0000000000000003
[  299.357763] FS:  00007f5a60a3f700(0000) GS:ffff88106f2c0000(0000) knlGS:0000000000000000
[  299.367510] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[  299.374913] CR2: 00000000000037da CR3: 0000000868ed4000 CR4: 00000000000007e0
[  299.383726] Stack:
[  299.387414]  0000000000000003 0000000000000000 0000000100000003 0000000100000003
[  299.396564]  ffffffff811888f4 ffff880c66db7698 0000000000000003 ffff880c7f9b3ac0
[  299.405730]  ffff880c66ccebd8 00000000ffffffff 0000000000000003 ffff880c66db7718
[  299.414907] Call Trace:
[  299.419095]  [<ffffffff811888f4>] ? migrate_misplaced_page+0xb4/0x140
[  299.427301]  [<ffffffff8115950c>] do_numa_page+0x18c/0x1f0
[  299.434554]  [<ffffffff8115a6f7>] handle_mm_fault+0x617/0xf70
[  ..........]  SNIPPED

The oops occurs in task_numa_group looking up cpu_rq(LAST__CPU_MASK). The
bug exists for all configurations but will manifest differently. On vmemmap
configurations, it looks up garbage and on !vmemmap configuraitons it
will oops. This patch adds the necessary check and also fixes the type
for LAST__PID_MASK and LAST__CPU_MASK which are currently signed instead
of unsigned integers.

Signed-off-by: Mel Gorman <mgorman@suse.de>
Cc: stable@vger.kernel.org

diff --git a/include/linux/page-flags-layout.h b/include/linux/page-flags-layout.h
index da52366..6f661d9 100644
--- a/include/linux/page-flags-layout.h
+++ b/include/linux/page-flags-layout.h
@@ -63,10 +63,10 @@
 
 #ifdef CONFIG_NUMA_BALANCING
 #define LAST__PID_SHIFT 8
-#define LAST__PID_MASK  ((1 << LAST__PID_SHIFT)-1)
+#define LAST__PID_MASK  ((1UL << LAST__PID_SHIFT)-1)
 
 #define LAST__CPU_SHIFT NR_CPUS_BITS
-#define LAST__CPU_MASK  ((1 << LAST__CPU_SHIFT)-1)
+#define LAST__CPU_MASK  ((1UL << LAST__CPU_SHIFT)-1)
 
 #define LAST_CPUPID_SHIFT (LAST__PID_SHIFT+LAST__CPU_SHIFT)
 #else
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 7815709..b44a8b1 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1463,6 +1463,9 @@ static void task_numa_group(struct task_struct *p, int cpupid, int flags,
 	int cpu = cpupid_to_cpu(cpupid);
 	int i;
 
+	if (unlikely(cpu == LAST__CPU_MASK && !cpu_online(cpu)))
+		return;
+
 	if (unlikely(!p->numa_group)) {
 		unsigned int size = sizeof(struct numa_group) +
 				    2*nr_node_ids*sizeof(unsigned long);

^ permalink raw reply related

* Re: Panic on ppc64 with numa_balancing and !sparsemem_vmemmap
From: Aneesh Kumar K.V @ 2014-03-03 19:15 UTC (permalink / raw)
  To: Mel Gorman, Srikar Dronamraju
  Cc: riel, Peter Zijlstra, linux-mm, paulus, linuxppc-dev
In-Reply-To: <20140303172649.GU6732@suse.de>

Mel Gorman <mgorman@suse.de> writes:

> On Wed, Feb 19, 2014 at 11:32:00PM +0530, Srikar Dronamraju wrote:
>> 
>> On a powerpc machine with CONFIG_NUMA_BALANCING=y and CONFIG_SPARSEMEM_VMEMMAP
>> not enabled,  kernel panics.
>> 
>
> This?

This one fixed that crash on ppc64

http://mid.gmane.org/1393578122-6500-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com

-aneesh

^ permalink raw reply

* Re: Panic on ppc64 with numa_balancing and !sparsemem_vmemmap
From: Mel Gorman @ 2014-03-03 20:04 UTC (permalink / raw)
  To: Aneesh Kumar K.V
  Cc: riel, Srikar Dronamraju, Peter Zijlstra, linux-mm, paulus,
	linuxppc-dev
In-Reply-To: <874n3fxfeg.fsf@linux.vnet.ibm.com>

On Tue, Mar 04, 2014 at 12:45:19AM +0530, Aneesh Kumar K.V wrote:
> Mel Gorman <mgorman@suse.de> writes:
> 
> > On Wed, Feb 19, 2014 at 11:32:00PM +0530, Srikar Dronamraju wrote:
> >> 
> >> On a powerpc machine with CONFIG_NUMA_BALANCING=y and CONFIG_SPARSEMEM_VMEMMAP
> >> not enabled,  kernel panics.
> >> 
> >
> > This?
> 
> This one fixed that crash on ppc64
> 
> http://mid.gmane.org/1393578122-6500-1-git-send-email-aneesh.kumar@linux.vnet.ibm.com
> 

Thanks.

-- 
Mel Gorman
SUSE Labs

^ permalink raw reply

* [PATCH] powerpc: Align p_dyn, p_rela and p_st symbols
From: Anton Blanchard @ 2014-03-03 21:31 UTC (permalink / raw)
  To: benh, paulus, ldufour; +Cc: linuxppc-dev


The 64bit relocation code places a few symbols in the text segment.
These symbols are only 4 byte aligned where they need to be 8 byte
aligned. Add an explicit alignment.

Signed-off-by: Anton Blanchard <anton@samba.org>
Cc: stable@vger.kernel.org
---

diff --git a/arch/powerpc/kernel/reloc_64.S b/arch/powerpc/kernel/reloc_64.S
index 1482327..d88736f 100644
--- a/arch/powerpc/kernel/reloc_64.S
+++ b/arch/powerpc/kernel/reloc_64.S
@@ -81,6 +81,7 @@ _GLOBAL(relocate)
 
 6:	blr
 
+.balign 8
 p_dyn:	.llong	__dynamic_start - 0b
 p_rela:	.llong	__rela_dyn_start - 0b
 p_st:	.llong	_stext - 0b

^ permalink raw reply related

* [PATCH] powerpc: Check that all cpu features are in the possible map
From: Michael Ellerman @ 2014-03-04  2:44 UTC (permalink / raw)
  To: linuxppc-dev

cpu_has_feature() has an optimisation where it maintains a map of
possible cpu features. This allows the compiler to determine at compile
time that some cpu_has_feature() checks will always return 0, and
therefore the code guarded by the check can be elided.

However we have no logic to check whether the set of cpu features in the
current cpu spec are in the possible map. Although that should never
happen, if it does things are likely to go badly. So add a check and
print a warning.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/kernel/cputable.c | 9 +++++++++
 1 file changed, 9 insertions(+)

diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 6c8dd5d..eb31713 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -2255,6 +2255,15 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset,
 	}
 #endif /* CONFIG_PPC64 || CONFIG_BOOKE */
 
+	/*
+	 * Check that all CPU features are in the possible mask. We don't want
+	 * to WARN() because we're called very early, and doing so will kill
+	 * the machine, so just printk() instead.
+	 */
+	if (t->cpu_features != (t->cpu_features & CPU_FTRS_POSSIBLE))
+		printk("WARNING: cpu spec contains impossible features! 0x%lx\n",
+			(t->cpu_features & ~CPU_FTRS_POSSIBLE));
+
 	return t;
 }
 
-- 
1.8.3.2

^ permalink raw reply related

* Re: [PATCH] powerpc: Check that all cpu features are in the possible map
From: Michael Ellerman @ 2014-03-04  3:38 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1393901079-25319-1-git-send-email-mpe@ellerman.id.au>

On Tue, 2014-03-04 at 13:44 +1100, Michael Ellerman wrote:
> diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
> index 6c8dd5d..eb31713 100644
> --- a/arch/powerpc/kernel/cputable.c
> +++ b/arch/powerpc/kernel/cputable.c
> @@ -2255,6 +2255,15 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset,
>  	}
>  #endif /* CONFIG_PPC64 || CONFIG_BOOKE */
>  
> +	/*
> +	 * Check that all CPU features are in the possible mask. We don't want
> +	 * to WARN() because we're called very early, and doing so will kill
> +	 * the machine, so just printk() instead.
> +	 */
> +	if (t->cpu_features != (t->cpu_features & CPU_FTRS_POSSIBLE))
> +		printk("WARNING: cpu spec contains impossible features! 0x%lx\n",
> +			(t->cpu_features & ~CPU_FTRS_POSSIBLE));


Actually even this is not safe.

printk() takes the logbuf_lock, but we don't have a paca yet, so our LOCK_TOKEN
will be some random guff in low memory. And although that's OK, we're single
threaded, it's a bit fishy.

What's worse is printk() does local_irq_save(), which will _store_ to our paca
(soft_enabled), and so we risk flipping a value somewhere.

Interestingly lockdep appears to be OK, even though we haven't initialised it
yet. printk() helpfully turns lockdep off before doing any locking.

cheers

^ permalink raw reply

* Re: [PATCH v3 02/11] perf: add PMU_FORMAT_RANGE() helper for use by sw-like pmus
From: Michael Ellerman @ 2014-03-04  5:19 UTC (permalink / raw)
  To: Cody P Schafer, Linux PPC, Arnaldo Carvalho de Melo, Ingo Molnar,
	Paul Mackerras, Peter Zijlstra
  Cc: Peter Zijlstra, scottwood, Cody P Schafer, LKML
In-Reply-To: <1393535105-7528-3-git-send-email-cody@linux.vnet.ibm.com>

On Thu, 2014-27-02 at 21:04:55 UTC, Cody P Schafer wrote:
> Add PMU_FORMAT_RANGE() and PMU_FORMAT_RANGE_RESERVED() (for reserved
> areas) which generate functions to extract the relevent bits from
> event->attr.config{,1,2} for use by sw-like pmus where the
> 'config{,1,2}' values don't map directly to hardware registers.
> 
> Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
> ---
>  include/linux/perf_event.h | 17 +++++++++++++++++
>  1 file changed, 17 insertions(+)
> 
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index e56b07f..3da5081 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -871,4 +871,21 @@ _name##_show(struct device *dev,					\
>  									\
>  static struct device_attribute format_attr_##_name = __ATTR_RO(_name)
>  
> +#define PMU_FORMAT_RANGE(name, attr_var, bit_start, bit_end)		\
> +PMU_FORMAT_ATTR(name, #attr_var ":" #bit_start "-" #bit_end);		\
> +PMU_FORMAT_RANGE_RESERVED(name, attr_var, bit_start, bit_end)

I really think these should have event in the name.

Someone looking at the code is going to see event_get_foo() and wonder where
that is defined. Grep won't find a definition, tags won't find a definition,
the least you can do is have the macro name give some hint.

> +#define PMU_FORMAT_RANGE_RESERVED(name, attr_var, bit_start, bit_end)	\

It doesn't generate a format attribute.

> +static u64 event_get_##name##_max(void)					\
> +{									\
> +	int bits = (bit_end) - (bit_start) + 1;				\
> +	return ((0x1ULL << (bits - 1ULL)) - 1ULL) |			\
> +		(0xFULL << (bits - 4ULL));				\

What's wrong with:

	(0x1ULL << ((bit_end) - (bit_start) + 1)) - 1ULL;

cheers

^ permalink raw reply

* Re: [PATCH v3 03/11] perf: provide a common perf_event_nop_0() for use with .event_idx
From: Michael Ellerman @ 2014-03-04  5:19 UTC (permalink / raw)
  To: Cody P Schafer, Linux PPC, Arnaldo Carvalho de Melo, Ingo Molnar,
	Paul Mackerras, Peter Zijlstra
  Cc: Peter Zijlstra, scottwood, Cody P Schafer, LKML
In-Reply-To: <1393535105-7528-4-git-send-email-cody@linux.vnet.ibm.com>

On Thu, 2014-27-02 at 21:04:56 UTC, Cody P Schafer wrote:
> Rather an having every pmu that needs a function that just returns 0 for
> .event_idx define their own copy, reuse the one in kernel/events/core.c.
> 
> Rename from perf_swevent_event_idx() because we're no longer using it
> for just software events. Naming is based on the perf_pmu_nop_*()
> functions.

You could just use perf_pmu_nop_int() directly.

Peterz, OK by you?

cheers

> Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
> ---
>  include/linux/perf_event.h |  1 +
>  kernel/events/core.c       | 10 +++++-----
>  2 files changed, 6 insertions(+), 5 deletions(-)
> 
> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
> index 3da5081..24a7b45 100644
> --- a/include/linux/perf_event.h
> +++ b/include/linux/perf_event.h
> @@ -560,6 +560,7 @@ extern void perf_pmu_migrate_context(struct pmu *pmu,
>  extern u64 perf_event_read_value(struct perf_event *event,
>  				 u64 *enabled, u64 *running);
>  
> +extern int perf_event_nop_0(struct perf_event *event);
>  
>  struct perf_sample_data {
>  	u64				type;
> diff --git a/kernel/events/core.c b/kernel/events/core.c
> index 56003c6..2938a77 100644
> --- a/kernel/events/core.c
> +++ b/kernel/events/core.c
> @@ -5816,7 +5816,7 @@ static int perf_swevent_init(struct perf_event *event)
>  	return 0;
>  }
>  
> -static int perf_swevent_event_idx(struct perf_event *event)
> +int perf_event_nop_0(struct perf_event *event)
>  {
>  	return 0;
>  }
> @@ -5831,7 +5831,7 @@ static struct pmu perf_swevent = {
>  	.stop		= perf_swevent_stop,
>  	.read		= perf_swevent_read,
>  
> -	.event_idx	= perf_swevent_event_idx,
> +	.event_idx	= perf_event_nop_0,
>  };
>  
>  #ifdef CONFIG_EVENT_TRACING
> @@ -5950,7 +5950,7 @@ static struct pmu perf_tracepoint = {
>  	.stop		= perf_swevent_stop,
>  	.read		= perf_swevent_read,
>  
> -	.event_idx	= perf_swevent_event_idx,
> +	.event_idx	= perf_event_nop_0,
>  };
>  
>  static inline void perf_tp_register(void)
> @@ -6177,7 +6177,7 @@ static struct pmu perf_cpu_clock = {
>  	.stop		= cpu_clock_event_stop,
>  	.read		= cpu_clock_event_read,
>  
> -	.event_idx	= perf_swevent_event_idx,
> +	.event_idx	= perf_event_nop_0,
>  };
>  
>  /*
> @@ -6257,7 +6257,7 @@ static struct pmu perf_task_clock = {
>  	.stop		= task_clock_event_stop,
>  	.read		= task_clock_event_read,
>  
> -	.event_idx	= perf_swevent_event_idx,
> +	.event_idx	= perf_event_nop_0,
>  };
>  
>  static void perf_pmu_nop_void(struct pmu *pmu)
> -- 
> 1.9.0
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

^ permalink raw reply

* [PATCH v3 1/2] powerpc: Add a cpu feature CPU_FTR_PMAO_BUG
From: Michael Ellerman @ 2014-03-04  5:31 UTC (permalink / raw)
  To: linuxppc-dev

Some power8 revisions have a hardware bug where we can lose a
Performance Monitor (PMU) exception under certain circumstances.

We will be adding a workaround for this case, see the next commit for
details. The observed behaviour is that writing PMAO doesn't cause an
exception as we would expect, hence the name of the feature.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/cputable.h | 6 ++++--
 arch/powerpc/kernel/cputable.c      | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

v3: Add CPU_FTRS_POWER8E to the possible map!
v2: Set the bit directly via the cputable entry for POWER8E.

diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h
index 617cc76..bc23477 100644
--- a/arch/powerpc/include/asm/cputable.h
+++ b/arch/powerpc/include/asm/cputable.h
@@ -189,6 +189,7 @@ extern const char *powerpc_base_platform;
 #define	CPU_FTR_HAS_PPR			LONG_ASM_CONST(0x0200000000000000)
 #define CPU_FTR_DAWR			LONG_ASM_CONST(0x0400000000000000)
 #define CPU_FTR_DABRX			LONG_ASM_CONST(0x0800000000000000)
+#define CPU_FTR_PMAO_BUG		LONG_ASM_CONST(0x1000000000000000)
 
 #ifndef __ASSEMBLY__
 
@@ -445,6 +446,7 @@ extern const char *powerpc_base_platform;
 	    CPU_FTR_ICSWX | CPU_FTR_CFAR | CPU_FTR_HVMODE | CPU_FTR_VMX_COPY | \
 	    CPU_FTR_DBELL | CPU_FTR_HAS_PPR | CPU_FTR_DAWR | \
 	    CPU_FTR_ARCH_207S | CPU_FTR_TM_COMP)
+#define CPU_FTRS_POWER8E (CPU_FTRS_POWER8 | CPU_FTR_PMAO_BUG)
 #define CPU_FTRS_CELL	(CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \
 	    CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
 	    CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -466,8 +468,8 @@ extern const char *powerpc_base_platform;
 #define CPU_FTRS_POSSIBLE	\
 	    (CPU_FTRS_POWER3 | CPU_FTRS_RS64 | CPU_FTRS_POWER4 |	\
 	    CPU_FTRS_PPC970 | CPU_FTRS_POWER5 | CPU_FTRS_POWER6 |	\
-	    CPU_FTRS_POWER7 | CPU_FTRS_POWER8 | CPU_FTRS_CELL |		\
-	    CPU_FTRS_PA6T | CPU_FTR_VSX)
+	    CPU_FTRS_POWER7 | CPU_FTRS_POWER8E | CPU_FTRS_POWER8 |	\
+	    CPU_FTRS_CELL | CPU_FTRS_PA6T | CPU_FTR_VSX)
 #endif
 #else
 enum {
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 6c8dd5d..c1faade 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -510,7 +510,7 @@ static struct cpu_spec __initdata cpu_specs[] = {
 		.pvr_mask		= 0xffff0000,
 		.pvr_value		= 0x004b0000,
 		.cpu_name		= "POWER8E (raw)",
-		.cpu_features		= CPU_FTRS_POWER8,
+		.cpu_features		= CPU_FTRS_POWER8E,
 		.cpu_user_features	= COMMON_USER_POWER8,
 		.cpu_user_features2	= COMMON_USER2_POWER8,
 		.mmu_features		= MMU_FTRS_POWER8,
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH v3 2/2] powerpc/perf: Add lost exception workaround
From: Michael Ellerman @ 2014-03-04  5:31 UTC (permalink / raw)
  To: linuxppc-dev
In-Reply-To: <1393911093-8248-1-git-send-email-mpe@ellerman.id.au>

Some power8 revisions have a hardware bug where we can lose a PMU
exception, this commit adds a workaround to detect the bad condition and
rectify the situation.

See the comment in the commit for a full description.

Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
---
 arch/powerpc/include/asm/reg.h  |   2 +
 arch/powerpc/perf/core-book3s.c | 100 +++++++++++++++++++++++++++++++++++++++-
 arch/powerpc/perf/power8-pmu.c  |   5 ++
 3 files changed, 105 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h
index 90c06ec..3003472 100644
--- a/arch/powerpc/include/asm/reg.h
+++ b/arch/powerpc/include/asm/reg.h
@@ -670,6 +670,7 @@
 #define   MMCR0_PMC1CE	0x00008000UL /* PMC1 count enable*/
 #define   MMCR0_PMCjCE	0x00004000UL /* PMCj count enable*/
 #define   MMCR0_TRIGGER	0x00002000UL /* TRIGGER enable */
+#define   MMCR0_PMAO_SYNC 0x00000800UL /* PMU interrupt is synchronous */
 #define   MMCR0_PMAO	0x00000080UL /* performance monitor alert has occurred, set to 0 after handling exception */
 #define   MMCR0_SHRFC	0x00000040UL /* SHRre freeze conditions between threads */
 #define   MMCR0_FC56	0x00000010UL /* freeze counters 5 and 6 */
@@ -703,6 +704,7 @@
 #define SPRN_EBBHR	804	/* Event based branch handler register */
 #define SPRN_EBBRR	805	/* Event based branch return register */
 #define SPRN_BESCR	806	/* Branch event status and control register */
+#define   BESCR_GE	0x8000000000000000ULL /* Global Enable */
 #define SPRN_WORT	895	/* Workload optimization register - thread */
 
 #define SPRN_PMC1	787
diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c
index 67cf220..9b3065d 100644
--- a/arch/powerpc/perf/core-book3s.c
+++ b/arch/powerpc/perf/core-book3s.c
@@ -120,6 +120,7 @@ static inline void power_pmu_bhrb_enable(struct perf_event *event) {}
 static inline void power_pmu_bhrb_disable(struct perf_event *event) {}
 void power_pmu_flush_branch_stack(void) {}
 static inline void power_pmu_bhrb_read(struct cpu_hw_events *cpuhw) {}
+static void pmao_restore_workaround(bool ebb) { }
 #endif /* CONFIG_PPC32 */
 
 static bool regs_use_siar(struct pt_regs *regs)
@@ -545,10 +546,18 @@ static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0)
 	/* Enable EBB and read/write to all 6 PMCs for userspace */
 	mmcr0 |= MMCR0_EBE | MMCR0_PMCC_U6;
 
-	/* Add any bits from the user reg, FC or PMAO */
+	/*
+	 * Add any bits from the user MMCR0, FC or PMAO. This is compatible
+	 * with pmao_restore_workaround() because we may add PMAO but we never
+	 * clear it here.
+	 */
 	mmcr0 |= current->thread.mmcr0;
 
-	/* Be careful not to set PMXE if userspace had it cleared */
+	/*
+	 * Be careful not to set PMXE if userspace had it cleared. This is also
+	 * compatible with pmao_restore_workaround() because it has already
+	 * cleared PMXE and we leave PMAO alone.
+	 */
 	if (!(current->thread.mmcr0 & MMCR0_PMXE))
 		mmcr0 &= ~MMCR0_PMXE;
 
@@ -559,6 +568,91 @@ static unsigned long ebb_switch_in(bool ebb, unsigned long mmcr0)
 out:
 	return mmcr0;
 }
+
+static void pmao_restore_workaround(bool ebb)
+{
+	unsigned pmcs[6];
+
+	if (!cpu_has_feature(CPU_FTR_PMAO_BUG))
+		return;
+
+	/*
+	 * On POWER8E there is a hardware defect which affects the PMU context
+	 * switch logic, ie. power_pmu_disable/enable().
+	 *
+	 * When a counter overflows PMXE is cleared and FC/PMAO is set in MMCR0
+	 * by the hardware. Sometime later the actual PMU exception is
+	 * delivered.
+	 *
+	 * If we context switch, or simply disable/enable, the PMU prior to the
+	 * exception arriving, the exception will be lost when we clear PMAO.
+	 *
+	 * When we reenable the PMU, we will write the saved MMCR0 with PMAO
+	 * set, and this _should_ generate an exception. However because of the
+	 * defect no exception is generated when we write PMAO, and we get
+	 * stuck with no counters counting but no exception delivered.
+	 *
+	 * The workaround is to detect this case and tweak the hardware to
+	 * create another pending PMU exception.
+	 *
+	 * We do that by setting up PMC6 (cycles) for an imminent overflow and
+	 * enabling the PMU. That causes a new exception to be generated in the
+	 * chip, but we don't take it yet because we have interrupts hard
+	 * disabled. We then write back the PMU state as we want it to be seen
+	 * by the exception handler. When we reenable interrupts the exception
+	 * handler will be called and see the correct state.
+	 *
+	 * The logic is the same for EBB, except that the exception is gated by
+	 * us having interrupts hard disabled as well as the fact that we are
+	 * not in userspace. The exception is finally delivered when we return
+	 * to userspace.
+	 */
+
+	/* Only if PMAO is set and PMAO_SYNC is clear */
+	if ((current->thread.mmcr0 & (MMCR0_PMAO | MMCR0_PMAO_SYNC)) != MMCR0_PMAO)
+		return;
+
+	/* If we're doing EBB, only if BESCR[GE] is set */
+	if (ebb && !(current->thread.bescr & BESCR_GE))
+		return;
+
+	/*
+	 * We are already soft-disabled in power_pmu_enable(). We need to hard
+	 * enable to actually prevent the PMU exception from firing.
+	 */
+	hard_irq_disable();
+
+	/*
+	 * This is a bit gross, but we know we're on POWER8E and have 6 PMCs.
+	 * Using read/write_pmc() in a for loop adds 12 function calls and
+	 * almost doubles our code size.
+	 */
+	pmcs[0] = mfspr(SPRN_PMC1);
+	pmcs[1] = mfspr(SPRN_PMC2);
+	pmcs[2] = mfspr(SPRN_PMC3);
+	pmcs[3] = mfspr(SPRN_PMC4);
+	pmcs[4] = mfspr(SPRN_PMC5);
+	pmcs[5] = mfspr(SPRN_PMC6);
+
+	/* Ensure all freeze bits are unset */
+	mtspr(SPRN_MMCR2, 0);
+
+	/* Set up PMC6 to overflow in one cycle */
+	mtspr(SPRN_PMC6, 0x7FFFFFFE);
+
+	/* Enable exceptions and unfreeze PMC6 */
+	mtspr(SPRN_MMCR0, MMCR0_PMXE | MMCR0_PMCjCE | MMCR0_PMAO);
+
+	/* Now we need to refreeze and restore the PMCs */
+	mtspr(SPRN_MMCR0, MMCR0_FC | MMCR0_PMAO);
+
+	mtspr(SPRN_PMC1, pmcs[0]);
+	mtspr(SPRN_PMC2, pmcs[1]);
+	mtspr(SPRN_PMC3, pmcs[2]);
+	mtspr(SPRN_PMC4, pmcs[3]);
+	mtspr(SPRN_PMC5, pmcs[4]);
+	mtspr(SPRN_PMC6, pmcs[5]);
+}
 #endif /* CONFIG_PPC64 */
 
 static void perf_event_interrupt(struct pt_regs *regs);
@@ -1144,6 +1238,8 @@ static void power_pmu_enable(struct pmu *pmu)
 	cpuhw->mmcr[0] |= MMCR0_PMXE | MMCR0_FCECE;
 
  out_enable:
+	pmao_restore_workaround(ebb);
+
 	mmcr0 = ebb_switch_in(ebb, cpuhw->mmcr[0]);
 
 	mb();
diff --git a/arch/powerpc/perf/power8-pmu.c b/arch/powerpc/perf/power8-pmu.c
index 96cee20..64f04cf 100644
--- a/arch/powerpc/perf/power8-pmu.c
+++ b/arch/powerpc/perf/power8-pmu.c
@@ -10,6 +10,8 @@
  * 2 of the License, or (at your option) any later version.
  */
 
+#define pr_fmt(fmt)	"power8-pmu: " fmt
+
 #include <linux/kernel.h>
 #include <linux/perf_event.h>
 #include <asm/firmware.h>
@@ -774,6 +776,9 @@ static int __init init_power8_pmu(void)
 	/* Tell userspace that EBB is supported */
 	cur_cpu_spec->cpu_user_features2 |= PPC_FEATURE2_EBB;
 
+	if (cpu_has_feature(CPU_FTR_PMAO_BUG))
+		pr_info("PMAO restore workaround active.\n");
+
 	return 0;
 }
 early_initcall(init_power8_pmu);
-- 
1.8.3.2

^ permalink raw reply related

* Re: [PATCH v3 03/11] perf: provide a common perf_event_nop_0() for use with .event_idx
From: Cody P Schafer @ 2014-03-04  7:01 UTC (permalink / raw)
  To: Michael Ellerman, Linux PPC, Arnaldo Carvalho de Melo,
	Ingo Molnar, Paul Mackerras, Peter Zijlstra
  Cc: Peter Zijlstra, scottwood, LKML
In-Reply-To: <20140304051936.97CBF2C020A@ozlabs.org>

On 03/03/2014 09:19 PM, Michael Ellerman wrote:
> On Thu, 2014-27-02 at 21:04:56 UTC, Cody P Schafer wrote:
>> Rather an having every pmu that needs a function that just returns 0 for
>> .event_idx define their own copy, reuse the one in kernel/events/core.c.
>>
>> Rename from perf_swevent_event_idx() because we're no longer using it
>> for just software events. Naming is based on the perf_pmu_nop_*()
>> functions.
>
> You could just use perf_pmu_nop_int() directly.

No, .event_idx needs something that takes a (struct perf_event *), 
perf_pmu_nop_int() takes a (struct pmu *).

^ permalink raw reply

* [PATCH] net/mlx4: Support shutdown() interface
From: Gavin Shan @ 2014-03-04  7:35 UTC (permalink / raw)
  To: netdev, linuxppc-dev; +Cc: weiyang, amirv, davem, Gavin Shan

In kexec scenario, we failed to load the mlx4 driver in the
second kernel because the ownership bit was hold by the first
kernel without release correctly.

The patch adds shutdown() interface so that the ownership can
be released correctly in the first kernel. It also helps avoiding
EEH error happened during boot stage of the second kernel because
of undesired traffic, which can't be handled by hardware during
that stage on Power platform.

Signed-off-by: Gavin Shan <shangw@linux.vnet.ibm.com>
Tested-by: Wei Yang <weiyang@linux.vnet.ibm.com>
---
 drivers/net/ethernet/mellanox/mlx4/main.c |    1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c
index d711158..5a6105f 100644
--- a/drivers/net/ethernet/mellanox/mlx4/main.c
+++ b/drivers/net/ethernet/mellanox/mlx4/main.c
@@ -2684,6 +2684,7 @@ static struct pci_driver mlx4_driver = {
 	.name		= DRV_NAME,
 	.id_table	= mlx4_pci_table,
 	.probe		= mlx4_init_one,
+	.shutdown	= mlx4_remove_one,
 	.remove		= mlx4_remove_one,
 	.err_handler    = &mlx4_err_handler,
 };
-- 
1.7.10.4

^ permalink raw reply related

* UART Fifo mode
From: Poonam.Aggrwal @ 2014-03-04  7:52 UTC (permalink / raw)
  To: linuxppc-dev@lists.ozlabs.org

[-- Attachment #1: Type: text/plain, Size: 1077 bytes --]

Hello All

I am debugging a UART issue on a Freescale PowerPC SOC.

My observations are:

When FiFo mode is enabled FCR[FEN]=1, and the Fifo size is 16byte. I see console prints not coming properly, lot of missing characters.

But here when I change the tx_loadsz to 8, the UART works fine.

        [PORT_16550A] = {
                .name           = "16550A",
                .fifo_size      = 16,
-               .tx_loadsz      = 16,
+               .tx_loadsz      = 8,
                .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
                .flags          = UART_CAP_FIFO,
        },

Can anybody help to understand what is the significance of tx_loadsz. From the code (drivers/serial/tty/8250/8250.c), looks like this parameter controls the bytes we write to the UART Tx register at one  time.
So ideally this should be equal to the Fifo size.

I also see certain UARTs where tx_loadsz is not equal to fifo_size, less than fifo_size.

Please help me to understand how should tx_loadsz be determined?

Many Thanks
Poonam

[-- Attachment #2: Type: text/html, Size: 5012 bytes --]

^ permalink raw reply

* Re: [PATCH v3 02/11] perf: add PMU_FORMAT_RANGE() helper for use by sw-like pmus
From: Cody P Schafer @ 2014-03-04  8:09 UTC (permalink / raw)
  To: Michael Ellerman, Linux PPC, Arnaldo Carvalho de Melo,
	Ingo Molnar, Paul Mackerras, Peter Zijlstra
  Cc: Peter Zijlstra, scottwood, LKML
In-Reply-To: <20140304051936.33A712C01AB@ozlabs.org>

On 03/03/2014 09:19 PM, Michael Ellerman wrote:
> On Thu, 2014-27-02 at 21:04:55 UTC, Cody P Schafer wrote:
>> Add PMU_FORMAT_RANGE() and PMU_FORMAT_RANGE_RESERVED() (for reserved
>> areas) which generate functions to extract the relevent bits from
>> event->attr.config{,1,2} for use by sw-like pmus where the
>> 'config{,1,2}' values don't map directly to hardware registers.
>>
>> Signed-off-by: Cody P Schafer <cody@linux.vnet.ibm.com>
>> ---
>>   include/linux/perf_event.h | 17 +++++++++++++++++
>>   1 file changed, 17 insertions(+)
>>
>> diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
>> index e56b07f..3da5081 100644
>> --- a/include/linux/perf_event.h
>> +++ b/include/linux/perf_event.h
>> @@ -871,4 +871,21 @@ _name##_show(struct device *dev,					\
>>   									\
>>   static struct device_attribute format_attr_##_name = __ATTR_RO(_name)
>>
>> +#define PMU_FORMAT_RANGE(name, attr_var, bit_start, bit_end)		\
>> +PMU_FORMAT_ATTR(name, #attr_var ":" #bit_start "-" #bit_end);		\
>> +PMU_FORMAT_RANGE_RESERVED(name, attr_var, bit_start, bit_end)
>
> I really think these should have event in the name.
>
> Someone looking at the code is going to see event_get_foo() and wonder where
> that is defined. Grep won't find a definition, tags won't find a definition,
> the least you can do is have the macro name give some hint.
>

That is a good point (grep-ability). Let me think about this. There is 
also the possibility that I could adjust the event_get_*() naming to 
something else. format_get_*()? event_get_format_*()? (these names keep 
growing...)

>> +#define PMU_FORMAT_RANGE_RESERVED(name, attr_var, bit_start, bit_end)	\
>
> It doesn't generate a format attribute.

This was done with the idea that the term "format" didn't just refer to 
the attribute exposed in sysfs, it referred to "some subset of bits 
extractable from attr.config{,1,2}". Which is also the reasoning for the 
above naming.

>> +static u64 event_get_##name##_max(void)					\
>> +{									\
>> +	int bits = (bit_end) - (bit_start) + 1;				\
>> +	return ((0x1ULL << (bits - 1ULL)) - 1ULL) |			\
>> +		(0xFULL << (bits - 4ULL));				\
>
> What's wrong with:
>
> 	(0x1ULL << ((bit_end) - (bit_start) + 1)) - 1ULL;

Overflowing the << when bit_end = 63 and bit_start = 0 results in max(0, 
63) = 0.
That said, the current implementation is wrong when (bits < 4). Here's 
one that actually works (without overflowing):

         return (((1ull << (bit_end - bit_start)) - 1) << 1) + 1;

And an examination of the problematic case:

         #if 0
         typedef unsigned long long ull;
         ull a = bits - 1; /* 63 */
         ull b = 1 << a;   /* 0x8000000000000000 */
         ull c = b - 1;    /* 0x7fffffffffffffff */
         ull d = b << 1;   /* 0xfffffffffffffffe */
         ull e = d + 1;    /* 0xffffffffffffffff */
         return e;
         #endif

Small number of valid inputs, so I also tested it for all of them using

	unsigned bits = (bit_end) - (bit_start) + 1;
	return (bits < (sizeof(0ULL) * CHAR_BIT))
			? ((1ULL << bits) - 1ULL)
			: ~0ULL;

As the baseline correct one.

^ permalink raw reply

* RE: [PATCH] Corenet: Add QE platform support for Corenet
From: qiang.zhao @ 2014-03-04  9:09 UTC (permalink / raw)
  To: Kumar Gala; +Cc: Scott Wood, linuxppc-dev@lists.ozlabs.org, Xiaobo Xie
In-Reply-To: <62FC0C4F-26FD-44B4-BC07-BDF1904AE637@kernel.crashing.org>

On Mar 3, 2014, at 11:51 PM, Kumar Gala [galak@kernel.crashing.org] wrote:



> -----Original Message-----
> From: Kumar Gala [mailto:galak@kernel.crashing.org]
> Sent: Monday, March 03, 2014 11:51 PM
> To: Zhao Qiang-B45475
> Cc: linuxppc-dev@lists.ozlabs.org; Wood Scott-B07421; Xie Xiaobo-R63061
> Subject: Re: [PATCH] Corenet: Add QE platform support for Corenet
>=20
>=20
> On Feb 28, 2014, at 2:48 AM, Zhao Qiang <B45475@freescale.com> wrote:
>=20
> > There is QE on platform T104x, add support.
> > Call funcs qe_ic_init and qe_init if CONFIG_QUICC_ENGINE is defined.
> >
> > Signed-off-by: Zhao Qiang <B45475@freescale.com>
> > ---
> > arch/powerpc/platforms/85xx/corenet_generic.c | 32
> > +++++++++++++++++++++++++++
> > 1 file changed, 32 insertions(+)
>=20
> Can you use mpc85xx_qe_init() instead?


mpc85xx_qe_init() is for old QE which is different from new QE.
New QE has no par_io, and it is not correct to init=20
par_io(par_io_init() called in mpc85xx_qe_init()) for new QE.=20

>=20
> >
> > diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c
> > b/arch/powerpc/platforms/85xx/corenet_generic.c
> > index fbd871e..f8c8e0c 100644
> > --- a/arch/powerpc/platforms/85xx/corenet_generic.c
> > +++ b/arch/powerpc/platforms/85xx/corenet_generic.c
> >
> > /*
> > @@ -52,11 +68,24 @@ void __init corenet_gen_pic_init(void)  */ void
> > __init corenet_gen_setup_arch(void) {
> > +#ifdef CONFIG_QUICC_ENGINE
> > +	struct device_node *np;
> > +#endif
> > 	mpc85xx_smp_init();
> >
> > 	swiotlb_detect_4g();
> >
> > 	pr_info("%s board from Freescale Semiconductor\n", ppc_md.name);
> > +
> > +#ifdef CONFIG_QUICC_ENGINE
> > +	np =3D of_find_compatible_node(NULL, NULL, "fsl,qe");
> > +	if (!np) {
> > +		pr_err("%s: Could not find Quicc Engine node\n", __func__);
> > +		return;
>=20
> This doesn't seem like an reasonable error message for common corenet
> platform.  It seems reasonable to build QE support but boot on a chip w/o
> QE.
>=20
> > +	}
> > +	qe_reset();
> > +	of_node_put(np);
> > +#endif
> > }
> > _______________________________________________
> > Linuxppc-dev mailing list
> > Linuxppc-dev@lists.ozlabs.org
> > https://lists.ozlabs.org/listinfo/linuxppc-dev
>=20
>=20


Regards,
Zhao Qiang

^ permalink raw reply

* Re: [PATCH v3] powerpc/powernv Platform dump interface
From: Vasant Hegde @ 2014-03-04 12:22 UTC (permalink / raw)
  To: Stewart Smith, benh, linuxppc-dev
In-Reply-To: <1393802742-3891-1-git-send-email-stewart@linux.vnet.ibm.com>

On 03/03/2014 04:55 AM, Stewart Smith wrote:
> This enables support for userspace to fetch and initiate FSP and
> Platform dumps from the service processor (via firmware) through sysfs.
>
> Based on original patch from Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
>
> Flow:
>    - We register for OPAL notification events.
>    - OPAL sends new dump available notification.
>    - We make information on dump available via sysfs
>    - Userspace requests dump contents
>    - We retrieve the dump via OPAL interface
>    - User copies the dump data
>    - userspace sends ack for dump
>    - We send ACK to OPAL.
>
> sysfs files:
>    - We add the /sys/firmware/opal/dump directory
>    - echoing 1 (well, anything, but in future we may support
>      different dump types) to /sys/firmware/opal/dump/initiate_dump
>      will initiate a dump.

Stewart,

s/initiate/initiate FSP/

>    - Each dump that we've been notified of gets a directory
>      in /sys/firmware/opal/dump/ with a name of the dump type and ID (in hex,
>      as this is what's used elsewhere to identify the dump).
>    - Each dump has files: id, type, dump and acknowledge
>      dump is binary and is the dump itself.
>      echoing 'ack' to acknowledge (currently any string will do) will
>      acknowledge the dump and it will soon after disappear from sysfs.
>
> OPAL APIs:
>    - opal_dump_init()
>    - opal_dump_info()

opal_dump_info2()

>    - opal_dump_read()
>    - opal_dump_ack()
>    - opal_dump_resend_notification()
>
> Currently we are only ever notified for one dump at a time (until
> the user explicitly acks the current dump, then we get a notification
> of the next dump), but this kernel code should "just work" when OPAL
> starts notifying us of all the dumps present.
>
> Changes since v2:
>   - fix bug where we would free the dump buffer after userspace read it,
>     refetching if needed. Refetching doesn't currently work, so we must
>     keep the dump around for subsequent reads.
>
> Changes since v1:
>   - Add support for getting dump type from OPAL through new OPAL call
>     (falling back to old OPAL_DUMP_INFO call if OPAL_DUMP_INFO2 isn't
>      supported)
>   - use dump type in directory name for dump
>
> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
> ---
>   Documentation/ABI/stable/sysfs-firmware-opal-dump |   41 ++
>   arch/powerpc/include/asm/opal.h                   |   14 +
>   arch/powerpc/platforms/powernv/Makefile           |    2 +-
>   arch/powerpc/platforms/powernv/opal-dump.c        |  525 +++++++++++++++++++++
>   arch/powerpc/platforms/powernv/opal-wrappers.S    |    6 +
>   arch/powerpc/platforms/powernv/opal.c             |    2 +
>   6 files changed, 589 insertions(+), 1 deletion(-)
>   create mode 100644 Documentation/ABI/stable/sysfs-firmware-opal-dump
>   create mode 100644 arch/powerpc/platforms/powernv/opal-dump.c
>
> diff --git a/Documentation/ABI/stable/sysfs-firmware-opal-dump b/Documentation/ABI/stable/sysfs-firmware-opal-dump
> new file mode 100644
> index 0000000..32fe7f5
> --- /dev/null
> +++ b/Documentation/ABI/stable/sysfs-firmware-opal-dump
> @@ -0,0 +1,41 @@
> +What:		/sys/firmware/opal/dump
> +Date:		Feb 2014
> +Contact:	Stewart Smith <stewart@linux.vnet.ibm.com>
> +Description:
> +		This directory exposes interfaces for interacting with
> +		the FSP and platform dumps through OPAL firmware interface.
> +
> +		This is only for the powerpc/powernv platform.
> +
> +		initiate_dump:	When '1' is written to it,
> +				we will initiate a dump.

initiate FSP dump

> +				Read this file for supported commands.
> +
> +		0xXX-0xYYYY:	A directory for dump of type 0xXX and
> +				id 0xYYYY (in hex). The name of this
> +				directory should not be relied upon to
> +				be in this format, only that it's unique
> +				among all dumps. For determining the type
> +				and ID of the dump, use the id and type files.
> +				Do not rely on any particular size of dump
> +				type or dump id.
> +
> +		Each dump has the following files:
> +		id:		An ASCII representation of the dump ID
> +				in hex (e.g. '0x01')
> +		type:		An ASCII representation of the type of
> +				dump in the format "0x%x %s" with the ID

Better 0x%x - %s ?

> +				in hex and a description of the dump type
> +				(or 'unknown').
> +				Type '0xffffffff unknown' is used when
> +				we could not get the type from firmware.
> +				e.g. '0x02 System/Platform Dump'
> +		dump:		A binary file containing the dump.
> +				The size of the dump is the size of this file.
> +		acknowledge:	When 'ack' is written to this, we will
> +				acknowledge that we've retrieved the
> +				dump to the service processor. It will
> +				then remove it, making the dump
> +				inaccessible.
> +				Reading this file will get a list of
> +				supported actions.
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index 40157e2..89c840c 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -154,9 +154,15 @@ extern int opal_enter_rtas(struct rtas_args *args,
>   #define OPAL_FLASH_VALIDATE			76
>   #define OPAL_FLASH_MANAGE			77
>   #define OPAL_FLASH_UPDATE			78
> +#define OPAL_DUMP_INIT				81
> +#define OPAL_DUMP_INFO				82
> +#define OPAL_DUMP_READ				83
> +#define OPAL_DUMP_ACK				84
>   #define OPAL_GET_MSG				85
>   #define OPAL_CHECK_ASYNC_COMPLETION		86
> +#define OPAL_DUMP_RESEND			91
>   #define OPAL_SYNC_HOST_REBOOT			87
> +#define OPAL_DUMP_INFO2				94
>
>   #ifndef __ASSEMBLY__
>
> @@ -237,6 +243,7 @@ enum OpalPendingState {
>   	OPAL_EVENT_EPOW			= 0x80,
>   	OPAL_EVENT_LED_STATUS		= 0x100,
>   	OPAL_EVENT_PCI_ERROR		= 0x200,
> +	OPAL_EVENT_DUMP_AVAIL		= 0x400,
>   	OPAL_EVENT_MSG_PENDING		= 0x800,
>   };
>
> @@ -826,6 +833,12 @@ int64_t opal_lpc_read(uint32_t chip_id, enum OpalLPCAddressType addr_type,
>   int64_t opal_validate_flash(uint64_t buffer, uint32_t *size, uint32_t *result);
>   int64_t opal_manage_flash(uint8_t op);
>   int64_t opal_update_flash(uint64_t blk_list);
> +int64_t opal_dump_init(uint8_t dump_type);
> +int64_t opal_dump_info(uint32_t *dump_id, uint32_t *dump_size);
> +int64_t opal_dump_info2(uint32_t *dump_id, uint32_t *dump_size, uint32_t *dump_type);
> +int64_t opal_dump_read(uint32_t dump_id, uint64_t buffer);
> +int64_t opal_dump_ack(uint32_t dump_id);
> +int64_t opal_dump_resend_notification(void);
>
>   int64_t opal_get_msg(uint64_t buffer, size_t size);
>   int64_t opal_check_completion(uint64_t buffer, size_t size, uint64_t token);
> @@ -861,6 +874,7 @@ extern void opal_get_rtc_time(struct rtc_time *tm);
>   extern unsigned long opal_get_boot_time(void);
>   extern void opal_nvram_init(void);
>   extern void opal_flash_init(void);
> +extern void opal_platform_dump_init(void);
>
>   extern int opal_machine_check(struct pt_regs *regs);
>
> diff --git a/arch/powerpc/platforms/powernv/Makefile b/arch/powerpc/platforms/powernv/Makefile
> index 8d767fd..3528c11 100644
> --- a/arch/powerpc/platforms/powernv/Makefile
> +++ b/arch/powerpc/platforms/powernv/Makefile
> @@ -1,6 +1,6 @@
>   obj-y			+= setup.o opal-takeover.o opal-wrappers.o opal.o
>   obj-y			+= opal-rtc.o opal-nvram.o opal-lpc.o opal-flash.o
> -obj-y			+= rng.o
> +obj-y			+= rng.o opal-dump.o
>
>   obj-$(CONFIG_SMP)	+= smp.o
>   obj-$(CONFIG_PCI)	+= pci.o pci-p5ioc2.o pci-ioda.o
> diff --git a/arch/powerpc/platforms/powernv/opal-dump.c b/arch/powerpc/platforms/powernv/opal-dump.c
> new file mode 100644
> index 0000000..0c767c5
> --- /dev/null
> +++ b/arch/powerpc/platforms/powernv/opal-dump.c
> @@ -0,0 +1,525 @@
> +/*
> + * PowerNV OPAL Dump Interface
> + *
> + * Copyright 2013,2014 IBM Corp.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include <linux/kobject.h>
> +#include <linux/mm.h>
> +#include <linux/slab.h>
> +#include <linux/vmalloc.h>
> +#include <linux/pagemap.h>
> +#include <linux/delay.h>
> +
> +#include <asm/opal.h>
> +
> +#define DUMP_TYPE_FSP	0x01

Better define other dump type (sysdump etc) here and use it below ?

> +
> +struct dump_obj {
> +	struct kobject  kobj;
> +	struct bin_attribute dump_attr;
> +	uint32_t	id;  /* becomes object name */
> +	uint32_t	type;
> +	uint32_t	size;
> +	char		*buffer;
> +};
> +#define to_dump_obj(x) container_of(x, struct dump_obj, kobj)
> +
> +struct dump_attribute {
> +	struct attribute attr;
> +	ssize_t (*show)(struct dump_obj *dump, struct dump_attribute *attr,
> +			char *buf);
> +	ssize_t (*store)(struct dump_obj *dump, struct dump_attribute *attr,
> +			 const char *buf, size_t count);
> +};
> +#define to_dump_attr(x) container_of(x, struct dump_attribute, attr)
> +
> +static ssize_t dump_id_show(struct dump_obj *dump_obj,
> +			    struct dump_attribute *attr,
> +			    char *buf)
> +{
> +	return sprintf(buf, "0x%x\n", dump_obj->id);
> +}
> +
> +static const char* dump_type_to_string(uint32_t type)
> +{
> +	switch (type) {
> +	case 0x01: return "SP Dump";
> +	case 0x02: return "System/Platform Dump";
> +	case 0x03: return "SMA Dump";
> +	default: return "unknown";
> +	}
> +}
> +
> +static ssize_t dump_type_show(struct dump_obj *dump_obj,
> +			      struct dump_attribute *attr,
> +			      char *buf)
> +{
> +	
> +	return sprintf(buf, "0x%x %s\n", dump_obj->type,

Better 0x%x - %s ?

> +		       dump_type_to_string(dump_obj->type));
> +}
> +
> +static ssize_t dump_ack_show(struct dump_obj *dump_obj,
> +			     struct dump_attribute *attr,
> +			     char *buf)
> +{
> +	return sprintf(buf, "ack - acknowledge dump\n");

Not sure but better "echo ack - acknowledge dump"?

> +}
> +
> +/*
> + * Send acknowledgement to OPAL
> + */
> +static int64_t dump_send_ack(uint32_t dump_id)
> +{
> +	int rc;
> +
> +	rc = opal_dump_ack(dump_id);
> +	if (rc)
> +		pr_warn("%s: Failed to send ack to Dump ID 0x%x (%d)\n",
> +			__func__, dump_id, rc);
> +	return rc;
> +}
> +
> +static void delay_release_kobj(void *kobj)
> +{
> +	kobject_put((struct kobject *)kobj);
> +}
> +
> +static ssize_t dump_ack_store(struct dump_obj *dump_obj,
> +			      struct dump_attribute *attr,
> +			      const char *buf,
> +			      size_t count)
> +{
> +	dump_send_ack(dump_obj->id);
> +	sysfs_schedule_callback(&dump_obj->kobj, delay_release_kobj,
> +				&dump_obj->kobj, THIS_MODULE);
> +	return count;
> +}
> +
> +/* Attributes of a dump
> + * The binary attribute of the dump itself is dynamic
> + * due to the dynamic size of the dump
> + */
> +static struct dump_attribute id_attribute =
> +	__ATTR(id, 0666, dump_id_show, NULL);
> +static struct dump_attribute type_attribute =
> +	__ATTR(type, 0666, dump_type_show, NULL);
> +static struct dump_attribute ack_attribute =
> +	__ATTR(acknowledge, 0660, dump_ack_show, dump_ack_store);
> +
> +static ssize_t init_dump_show(struct dump_obj *dump_obj,
> +			      struct dump_attribute *attr,
> +			      char *buf)
> +{
> +	return sprintf(buf, "1 - initiate dump\n");

initiate FSP dump

> +}
> +
> +static int64_t dump_fips_init(uint8_t type)
> +{
> +	int rc;
> +
> +	rc = opal_dump_init(type);
> +	if (rc)
> +		pr_warn("%s: Failed to initiate FipS dump (%d)\n",
> +			__func__, rc);
> +	return rc;
> +}
> +
> +static ssize_t init_dump_store(struct dump_obj *dump_obj,
> +			       struct dump_attribute *attr,
> +			       const char *buf,
> +			       size_t count)
> +{
> +	dump_fips_init(DUMP_TYPE_FSP);
> +	pr_info("%s: Initiated FSP dump\n", __func__);

This might mislead if OPAL fails to initiate FSP dump.. Better move this to 
dump_fips_init () ?

> +	return count;
> +}
> +
> +static struct dump_attribute initiate_attribute =
> +	__ATTR(initiate_dump, 0600, init_dump_show, init_dump_store);
> +
> +static struct attribute *initiate_attrs[] = {
> +	&initiate_attribute.attr,
> +	NULL,
> +};
> +
> +static struct attribute_group initiate_attr_group = {
> +	.attrs = initiate_attrs,
> +};
> +
> +static struct kset *dump_kset;
> +
> +static ssize_t dump_attr_show(struct kobject *kobj,
> +			      struct attribute *attr,
> +			      char *buf)
> +{
> +	struct dump_attribute *attribute;
> +	struct dump_obj *dump;
> +
> +	attribute = to_dump_attr(attr);
> +	dump = to_dump_obj(kobj);
> +
> +	if (!attribute->show)
> +		return -EIO;
> +
> +	return attribute->show(dump, attribute, buf);
> +}
> +
> +static ssize_t dump_attr_store(struct kobject *kobj,
> +			       struct attribute *attr,
> +			       const char *buf, size_t len)
> +{
> +	struct dump_attribute *attribute;
> +	struct dump_obj *dump;
> +
> +	attribute = to_dump_attr(attr);
> +	dump = to_dump_obj(kobj);
> +
> +	if (!attribute->store)
> +		return -EIO;
> +
> +	return attribute->store(dump, attribute, buf, len);
> +}
> +
> +static const struct sysfs_ops dump_sysfs_ops = {
> +	.show = dump_attr_show,
> +	.store = dump_attr_store,
> +};
> +
> +static void dump_release(struct kobject *kobj)
> +{
> +	struct dump_obj *dump;
> +
> +	dump = to_dump_obj(kobj);
> +	vfree(dump->buffer);
> +	kfree(dump);
> +}
> +
> +static struct attribute *dump_default_attrs[] = {
> +	&id_attribute.attr,
> +	&type_attribute.attr,
> +	&ack_attribute.attr,
> +	NULL,
> +};
> +
> +static struct kobj_type dump_ktype = {
> +	.sysfs_ops = &dump_sysfs_ops,
> +	.release = &dump_release,
> +	.default_attrs = dump_default_attrs,
> +};
> +
> +static void free_dump_sg_list(struct opal_sg_list *list)
> +{
> +	struct opal_sg_list *sg1;
> +	while (list) {
> +		sg1 = list->next;
> +		kfree(list);
> +		list = sg1;
> +	}
> +	list = NULL;
> +}
> +
> +static struct opal_sg_list *dump_data_to_sglist(struct dump_obj *dump)
> +{
> +	struct opal_sg_list *sg1, *list = NULL;
> +	void *addr;
> +	int64_t size;
> +
> +	addr = dump->buffer;
> +	size = dump->size;
> +
> +	sg1 = kzalloc(PAGE_SIZE, GFP_KERNEL);
> +	if (!sg1)
> +		goto nomem;
> +
> +	list = sg1;
> +	sg1->num_entries = 0;
> +	while (size > 0) {
> +		/* Translate virtual address to physical address */
> +		sg1->entry[sg1->num_entries].data =
> +			(void *)(vmalloc_to_pfn(addr) << PAGE_SHIFT);
> +
> +		if (size > PAGE_SIZE)
> +			sg1->entry[sg1->num_entries].length = PAGE_SIZE;
> +		else
> +			sg1->entry[sg1->num_entries].length = size;
> +
> +		sg1->num_entries++;
> +		if (sg1->num_entries >= SG_ENTRIES_PER_NODE) {
> +			sg1->next = kzalloc(PAGE_SIZE, GFP_KERNEL);
> +			if (!sg1->next)
> +				goto nomem;
> +
> +			sg1 = sg1->next;
> +			sg1->num_entries = 0;
> +		}
> +		addr += PAGE_SIZE;
> +		size -= PAGE_SIZE;
> +	}
> +	return list;
> +
> +nomem:
> +	pr_err("%s : Failed to allocate memory\n", __func__);
> +	free_dump_sg_list(list);
> +	return NULL;
> +}
> +
> +static void sglist_to_phy_addr(struct opal_sg_list *list)
> +{
> +	struct opal_sg_list *sg, *next;
> +
> +	for (sg = list; sg; sg = next) {
> +		next = sg->next;
> +		/* Don't translate NULL pointer for last entry */
> +		if (sg->next)
> +			sg->next = (struct opal_sg_list *)__pa(sg->next);
> +		else
> +			sg->next = NULL;
> +
> +		/* Convert num_entries to length */
> +		sg->num_entries =
> +			sg->num_entries * sizeof(struct opal_sg_entry) + 16;
> +	}
> +}
> +
> +static int64_t dump_read_info(uint32_t *id, uint32_t *size, uint32_t *type)
> +{
> +	int rc;
> +	*type = 0xffffffff;
> +
> +	rc = opal_dump_info2(id, size, type);
> +
> +	if (rc == OPAL_PARAMETER)
> +		rc = opal_dump_info(id, size);
> +
> +	if (rc)
> +		pr_warn("%s: Failed to get dump info (%d)\n",
> +			__func__, rc);
> +	return rc;
> +}
> +
> +static int64_t dump_read_data(struct dump_obj *dump)
> +{
> +	struct opal_sg_list *list;
> +	uint64_t addr;
> +	int64_t rc;
> +
> +	/* Allocate memory */
> +	dump->buffer = vzalloc(PAGE_ALIGN(dump->size));
> +	if (!dump->buffer) {
> +		pr_err("%s : Failed to allocate memory\n", __func__);
> +		rc = -ENOMEM;
> +		goto out;
> +	}
> +
> +	/* Generate SG list */
> +	list = dump_data_to_sglist(dump);
> +	if (!list) {
> +		rc = -ENOMEM;
> +		goto out;
> +	}
> +
> +	/* Translate sg list addr to real address */
> +	sglist_to_phy_addr(list);
> +
> +	/* First entry address */
> +	addr = __pa(list);
> +
> +	/* Fetch data */
> +	rc = OPAL_BUSY_EVENT;
> +	while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
> +		rc = opal_dump_read(dump->id, addr);
> +		if (rc == OPAL_BUSY_EVENT) {
> +			opal_poll_events(NULL);
> +			msleep(20);
> +		}
> +	}
> +
> +	if (rc != OPAL_SUCCESS && rc != OPAL_PARTIAL)
> +		pr_warn("%s: Extract dump failed for ID 0x%x\n",
> +			__func__, dump->id);
> +
> +	/* Free SG list */
> +	free_dump_sg_list(list);
> +
> +out:
> +	return rc;
> +}
> +
> +static ssize_t dump_attr_read(struct file *filep, struct kobject *kobj,
> +			      struct bin_attribute *bin_attr,
> +			      char *buffer, loff_t pos, size_t count)
> +{
> +	ssize_t rc;
> +
> +	struct dump_obj *dump = to_dump_obj(kobj);
> +
> +	if (!dump->buffer) {
> +		rc = dump_read_data(dump);
> +
> +		if (rc != OPAL_SUCCESS && rc != OPAL_PARTIAL) {
> +			vfree(dump->buffer);
> +			dump->buffer = NULL;
> +
> +			return -EIO;
> +		}
> +		if (rc == OPAL_PARTIAL) {
> +			/* On a partial read, we just return EIO
> +			 * and rely on userspace to ask us to try
> +			 * again.
> +			 */
> +			pr_info("%s: Platform dump partially read.ID = 0x%x\n",

s/read.ID/read. ID/

Rest looks good.

-Vasant

> +				__func__, dump->id);
> +			return -EIO;
> +		}
> +	}
> +
> +	memcpy(buffer, dump->buffer + pos, count);
> +
> +	/* You may think we could free the dump buffer now and retrieve
> +	 * it again later if needed, but due to current firmware limitation,
> +	 * that's not the case. So, once read into userspace once,
> +	 * we keep the dump around until it's acknowledged by userspace.
> +	 */
> +
> +	return count;
> +}
> +
> +static struct dump_obj *create_dump_obj(uint32_t id, size_t size,
> +					uint32_t type)
> +{
> +	struct dump_obj *dump;
> +	int rc;
> +
> +	dump = kzalloc(sizeof(*dump), GFP_KERNEL);
> +	if (!dump)
> +		return NULL;
> +
> +	dump->kobj.kset = dump_kset;
> +
> +	kobject_init(&dump->kobj, &dump_ktype);
> +
> +	sysfs_bin_attr_init(&dump->dump_attr);
> +
> +	dump->dump_attr.attr.name = "dump";
> +	dump->dump_attr.attr.mode = 0400;
> +	dump->dump_attr.size = size;
> +	dump->dump_attr.read = dump_attr_read;
> +
> +	dump->id = id;
> +	dump->size = size;
> +	dump->type = type;
> +
> +	rc = kobject_add(&dump->kobj, NULL, "0x%x-0x%x", type, id);
> +	if (rc) {
> +		kobject_put(&dump->kobj);
> +		return NULL;
> +	}
> +
> +	rc = sysfs_create_bin_file(&dump->kobj, &dump->dump_attr);
> +	if (rc) {
> +		kobject_put(&dump->kobj);
> +		return NULL;
> +	}
> +
> +	pr_info("%s: New platform dump. ID = 0x%x Size %u\n",
> +		__func__, dump->id, dump->size);
> +
> +	kobject_uevent(&dump->kobj, KOBJ_ADD);
> +
> +	return dump;
> +}
> +
> +static int process_dump(void)
> +{
> +	int rc;
> +	uint32_t dump_id, dump_size, dump_type;
> +	struct dump_obj *dump;
> +	char name[22];
> +
> +	rc = dump_read_info(&dump_id, &dump_size, &dump_type);
> +	if (rc != OPAL_SUCCESS)
> +		return rc;
> +
> +	sprintf(name, "0x%x-0x%x", dump_type, dump_id);
> +
> +	/* we may get notified twice, let's handle
> +	 * that gracefully and not create two conflicting
> +	 * entries.
> +	 */
> +	if (kset_find_obj(dump_kset, name))
> +		return 0;
> +
> +	dump = create_dump_obj(dump_id, dump_size, dump_type);
> +	if (!dump)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static void dump_work_fn(struct work_struct *work)
> +{
> +	process_dump();
> +}
> +
> +static DECLARE_WORK(dump_work, dump_work_fn);
> +
> +static void schedule_process_dump(void)
> +{
> +	schedule_work(&dump_work);
> +}
> +
> +/*
> + * New dump available notification
> + *
> + * Once we get notification, we add sysfs entries for it.
> + * We only fetch the dump on demand, and create sysfs asynchronously.
> + */
> +static int dump_event(struct notifier_block *nb,
> +		      unsigned long events, void *change)
> +{
> +	if (events & OPAL_EVENT_DUMP_AVAIL)
> +		schedule_process_dump();
> +
> +	return 0;
> +}
> +
> +static struct notifier_block dump_nb = {
> +	.notifier_call  = dump_event,
> +	.next           = NULL,
> +	.priority       = 0
> +};
> +
> +void __init opal_platform_dump_init(void)
> +{
> +	int rc;
> +
> +	dump_kset = kset_create_and_add("dump", NULL, opal_kobj);
> +	if (!dump_kset) {
> +		pr_warn("%s: Failed to create dump kset\n", __func__);
> +		return;
> +	}
> +
> +	rc = sysfs_create_group(&dump_kset->kobj, &initiate_attr_group);
> +	if (rc) {
> +		pr_warn("%s: Failed to create initiate dump attr group\n",
> +			__func__);
> +		kobject_put(&dump_kset->kobj);
> +		return;
> +	}
> +
> +	rc = opal_notifier_register(&dump_nb);
> +	if (rc) {
> +		pr_warn("%s: Can't register OPAL event notifier (%d)\n",
> +			__func__, rc);
> +		return;
> +	}
> +
> +	opal_dump_resend_notification();
> +}
> diff --git a/arch/powerpc/platforms/powernv/opal-wrappers.S b/arch/powerpc/platforms/powernv/opal-wrappers.S
> index 3e8829c..3e02783 100644
> --- a/arch/powerpc/platforms/powernv/opal-wrappers.S
> +++ b/arch/powerpc/platforms/powernv/opal-wrappers.S
> @@ -126,6 +126,12 @@ OPAL_CALL(opal_return_cpu,			OPAL_RETURN_CPU);
>   OPAL_CALL(opal_validate_flash,			OPAL_FLASH_VALIDATE);
>   OPAL_CALL(opal_manage_flash,			OPAL_FLASH_MANAGE);
>   OPAL_CALL(opal_update_flash,			OPAL_FLASH_UPDATE);
> +OPAL_CALL(opal_dump_init,			OPAL_DUMP_INIT);
> +OPAL_CALL(opal_dump_info,			OPAL_DUMP_INFO);
> +OPAL_CALL(opal_dump_info2,			OPAL_DUMP_INFO2);
> +OPAL_CALL(opal_dump_read,			OPAL_DUMP_READ);
> +OPAL_CALL(opal_dump_ack,			OPAL_DUMP_ACK);
>   OPAL_CALL(opal_get_msg,				OPAL_GET_MSG);
>   OPAL_CALL(opal_check_completion,		OPAL_CHECK_ASYNC_COMPLETION);
> +OPAL_CALL(opal_dump_resend_notification,	OPAL_DUMP_RESEND);
>   OPAL_CALL(opal_sync_host_reboot,		OPAL_SYNC_HOST_REBOOT);
> diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c
> index 65499ad..262cd1a 100644
> --- a/arch/powerpc/platforms/powernv/opal.c
> +++ b/arch/powerpc/platforms/powernv/opal.c
> @@ -474,6 +474,8 @@ static int __init opal_init(void)
>   	if (rc == 0) {
>   		/* Setup code update interface */
>   		opal_flash_init();
> +		/* Setup platform dump extract interface */
> +		opal_platform_dump_init();
>   	}
>
>   	return 0;
>

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox