CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=y
CONFIG_I2C_IMX=y
+CONFIG_I2C_MUX=y
+CONFIG_I2C_MUX_PCA954x=y
# CONFIG_IMX2_WDT is not set
CONFIG_INITRAMFS_SOURCE=""
CONFIG_IOMMU_HELPER=y
CONFIG_ZLIB_INFLATE=y
CONFIG_MTD_SPI_NOR=y
CONFIG_SPI_FSL_QUADSPI=y
+CONFIG_FSL_MC_BUS=y
+CONFIG_FSL_MC_RESTOOL=y
+CONFIG_FSL_MC_DPIO=y
+# CONFIG_FSL_QBMAN_DEBUG is not set
+CONFIG_FSL_DPAA2=y
+CONFIG_FSL_DPAA2_ETH=y
+# CONFIG_FSL_DPAA2_ETH_USE_ERR_QUEUE is not set
+CONFIG_FSL_DPAA2_MAC=y
+# CONFIG_FSL_DPAA2_MAC_NETDEVS is not set
+CONFIG_FSL_DPAA2_EVB=y
+CONFIG_FSL_DPAA2_ETHSW=y
endef
TARGET_DEVICES += ls1012ardb
+define Device/ls1088ardb
+ DEVICE_TITLE := ls1088ardb-$(SUBTARGET)
+ DEVICE_PACKAGES += rcw-layerscape-ls1088ardb uboot-layerscape-$(SUBTARGET)-ls1088ardb mc-binary-ls1088ardb
+ifeq ($(SUBTARGET),64b)
+ DEVICE_DTS = freescale/fsl-ls1088a-rdb
+endif
+ifeq ($(SUBTARGET),32b)
+ DEVICE_DTS = ../../../arm64/boot/dts/freescale/fsl-ls1088a-rdb
+endif
+ IMAGE/firmware.bin = append-ls-dtb $$(DEVICE_DTS) | pad-to 1M | append-kernel | pad-to 6M | \
+ append-ls-rootfs-ext4 $(1) 17M | check-size 24117249
+endef
+TARGET_DEVICES += ls1088ardb
+
$(eval $(call BuildImage))
--- /dev/null
+From cbacf87fa6fb262c98033405f15697798c3a9c5d Mon Sep 17 00:00:00 2001
+From: Zhao Qiang <qiang.zhao@nxp.com>
+Date: Sun, 9 Oct 2016 14:31:50 +0800
+Subject: [PATCH 135/141] arm64: Add DTS support for FSL's LS1088ARDB
+
+Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
+---
+ arch/arm64/boot/dts/freescale/Makefile | 1 +
+ arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts | 203 ++++++++
+ arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 557 +++++++++++++++++++++
+ 3 files changed, 761 insertions(+)
+ create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
+ create mode 100644 arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+
+--- a/arch/arm64/boot/dts/freescale/Makefile
++++ b/arch/arm64/boot/dts/freescale/Makefile
+@@ -5,6 +5,7 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1
+ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-rdb.dtb
+ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1012a-frdm.dtb
+ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1046a-rdb.dtb
++dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-ls1088a-rdb.dtb
+
+ always := $(dtb-y)
+ subdir-y := $(dts-dirs)
+--- /dev/null
++++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
+@@ -0,0 +1,203 @@
++/*
++ * Device Tree file for Freescale LS1088a RDB board
++ *
++ * Copyright (C) 2015, Freescale Semiconductor
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2. This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ */
++
++/dts-v1/;
++
++#include "fsl-ls1088a.dtsi"
++
++/ {
++ model = "Freescale Layerscape 1088a RDB Board";
++ compatible = "fsl,ls1088a-rdb", "fsl,ls1088a";
++};
++
++&esdhc {
++ status = "okay";
++};
++
++&ifc {
++ status = "disabled";
++};
++
++&ftm0 {
++ status = "okay";
++};
++
++&i2c0 {
++ status = "okay";
++ pca9547@77 {
++ compatible = "philips,pca9547";
++ reg = <0x77>;
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ i2c@2 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x2>;
++
++ ina220@40 {
++ compatible = "ti,ina220";
++ reg = <0x40>;
++ shunt-resistor = <1000>;
++ };
++ };
++
++ i2c@3 {
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x3>;
++
++ rtc@51 {
++ compatible = "nxp,pcf2129";
++ reg = <0x51>;
++ /* IRQ10_B */
++ interrupts = <0 150 0x4>;
++ };
++
++ adt7461a@4c {
++ compatible = "adt7461a";
++ reg = <0x4c>;
++ };
++ };
++ };
++};
++
++&i2c1 {
++ status = "disabled";
++};
++
++&i2c2 {
++ status = "disabled";
++};
++
++&i2c3 {
++ status = "disabled";
++};
++
++&dspi {
++ status = "disabled";
++};
++
++&qspi {
++ status = "okay";
++ qflash0: s25fs512s@0 {
++ compatible = "spansion,m25p80";
++ #address-cells = <1>;
++ #size-cells = <1>;
++ spi-max-frequency = <20000000>;
++ reg = <0>;
++ };
++
++ qflash1: s25fs512s@1 {
++ compatible = "spansion,m25p80";
++ #address-cells = <1>;
++ #size-cells = <1>;
++ spi-max-frequency = <20000000>;
++ reg = <1>;
++ };
++};
++
++&sata0 {
++ status = "okay";
++};
++
++&usb0 {
++ status = "okay";
++};
++
++&usb1 {
++ status = "okay";
++};
++
++&serial0 {
++ status = "okay";
++};
++
++&serial1 {
++ status = "okay";
++};
++
++&emdio1 {
++ /* Freescale F104 PHY1 */
++ mdio1_phy1: emdio1_phy@1 {
++ reg = <0x1c>;
++ phy-connection-type = "qsgmii";
++ };
++ mdio1_phy2: emdio1_phy@2 {
++ reg = <0x1d>;
++ phy-connection-type = "qsgmii";
++ };
++ mdio1_phy3: emdio1_phy@3 {
++ reg = <0x1e>;
++ phy-connection-type = "qsgmii";
++ };
++ mdio1_phy4: emdio1_phy@4 {
++ reg = <0x1f>;
++ phy-connection-type = "qsgmii";
++ };
++ /* F104 PHY2 */
++ mdio1_phy5: emdio1_phy@5 {
++ reg = <0x0c>;
++ phy-connection-type = "qsgmii";
++ };
++ mdio1_phy6: emdio1_phy@6 {
++ reg = <0x0d>;
++ phy-connection-type = "qsgmii";
++ };
++ mdio1_phy7: emdio1_phy@7 {
++ reg = <0x0e>;
++ phy-connection-type = "qsgmii";
++ };
++ mdio1_phy8: emdio1_phy@8 {
++ reg = <0x0f>;
++ phy-connection-type = "qsgmii";
++ };
++};
++
++&emdio2 {
++ /* Aquantia AQR105 10G PHY */
++ mdio2_phy1: emdio2_phy@1 {
++ compatible = "ethernet-phy-ieee802.3-c45";
++ reg = <0x0>;
++ phy-connection-type = "xfi";
++ };
++};
++
++/* DPMAC connections to external PHYs
++ * based on LS1088A RM RevC - $24.1.2 SerDes Options
++ */
++/* DPMAC1 is 10G SFP+, fixed link */
++&dpmac2 {
++ phy-handle = <&mdio2_phy1>;
++};
++&dpmac3 {
++ phy-handle = <&mdio1_phy5>;
++};
++&dpmac4 {
++ phy-handle = <&mdio1_phy6>;
++};
++&dpmac5 {
++ phy-handle = <&mdio1_phy7>;
++};
++&dpmac6 {
++ phy-handle = <&mdio1_phy8>;
++};
++&dpmac7 {
++ phy-handle = <&mdio1_phy1>;
++};
++&dpmac8 {
++ phy-handle = <&mdio1_phy2>;
++};
++&dpmac9 {
++ phy-handle = <&mdio1_phy3>;
++};
++&dpmac10 {
++ phy-handle = <&mdio1_phy4>;
++};
+--- /dev/null
++++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+@@ -0,0 +1,557 @@
++/*
++ * Device Tree Include file for Freescale Layerscape-1088A family SoC.
++ *
++ * Copyright (C) 2015, Freescale Semiconductor
++ *
++ */
++
++/memreserve/ 0x80000000 0x00010000;
++
++/ {
++ compatible = "fsl,ls1088a";
++ interrupt-parent = <&gic>;
++ #address-cells = <2>;
++ #size-cells = <2>;
++
++ cpus {
++ #address-cells = <2>;
++ #size-cells = <0>;
++
++ /* We have 2 clusters having 4 Cortex-A57 cores each */
++ cpu0: cpu@0 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53";
++ reg = <0x0 0x0>;
++ clocks = <&clockgen 1 0>;
++ };
++
++ cpu1: cpu@1 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53";
++ reg = <0x0 0x1>;
++ clocks = <&clockgen 1 0>;
++ };
++
++ cpu2: cpu@2 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53";
++ reg = <0x0 0x2>;
++ clocks = <&clockgen 1 0>;
++ };
++
++ cpu3: cpu@3 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53";
++ reg = <0x0 0x3>;
++ clocks = <&clockgen 1 0>;
++ };
++
++ cpu4: cpu@100 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53";
++ reg = <0x0 0x100>;
++ clocks = <&clockgen 1 1>;
++ };
++
++ cpu5: cpu@101 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53";
++ reg = <0x0 0x101>;
++ clocks = <&clockgen 1 1>;
++ };
++
++ cpu6: cpu@102 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53";
++ reg = <0x0 0x102>;
++ clocks = <&clockgen 1 1>;
++ };
++
++ cpu7: cpu@103 {
++ device_type = "cpu";
++ compatible = "arm,cortex-a53";
++ reg = <0x0 0x103>;
++ clocks = <&clockgen 1 1>;
++ };
++ };
++
++ pmu {
++ compatible = "arm,armv8-pmuv3";
++ interrupts = <1 7 0x8>; /* PMU PPI, Level low type */
++ };
++
++ gic: interrupt-controller@6000000 {
++ compatible = "arm,gic-v3";
++ reg = <0x0 0x06000000 0 0x10000>, /* GIC Dist */
++ <0x0 0x06100000 0 0x100000>, /* GICR(RD_base+SGI_base)*/
++ <0x0 0x0c0c0000 0 0x2000>, /* GICC */
++ <0x0 0x0c0d0000 0 0x1000>, /* GICH */
++ <0x0 0x0c0e0000 0 0x20000>; /* GICV */
++ #interrupt-cells = <3>;
++ #address-cells = <2>;
++ #size-cells = <2>;
++ ranges;
++ interrupt-controller;
++ interrupts = <1 9 0x4>;
++
++ its: gic-its@6020000 {
++ compatible = "arm,gic-v3-its";
++ msi-controller;
++ reg = <0x0 0x6020000 0 0x20000>;
++ };
++ };
++
++ sysclk: sysclk {
++ compatible = "fixed-clock";
++ #clock-cells = <0>;
++ clock-frequency = <100000000>;
++ clock-output-names = "sysclk";
++ };
++
++ clockgen: clocking@1300000 {
++ compatible = "fsl,ls2080a-clockgen", "fsl,ls1088a-clockgen";
++ reg = <0 0x1300000 0 0xa0000>;
++ #clock-cells = <2>;
++ clocks = <&sysclk>;
++ };
++
++ serial0: serial@21c0500 {
++ device_type = "serial";
++ compatible = "fsl,ns16550", "ns16550a";
++ reg = <0x0 0x21c0500 0x0 0x100>;
++ clocks = <&clockgen 4 3>;
++ interrupts = <0 32 0x4>; /* Level high type */
++ };
++
++ serial1: serial@21c0600 {
++ device_type = "serial";
++ compatible = "fsl,ns16550", "ns16550a";
++ reg = <0x0 0x21c0600 0x0 0x100>;
++ clocks = <&clockgen 4 3>;
++ interrupts = <0 32 0x4>; /* Level high type */
++ };
++
++ gpio0: gpio@2300000 {
++ compatible = "fsl,qoriq-gpio";
++ reg = <0x0 0x2300000 0x0 0x10000>;
++ interrupts = <0 36 0x4>; /* Level high type */
++ gpio-controller;
++ little-endian;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ };
++
++ gpio1: gpio@2310000 {
++ compatible = "fsl,qoriq-gpio";
++ reg = <0x0 0x2310000 0x0 0x10000>;
++ interrupts = <0 36 0x4>; /* Level high type */
++ gpio-controller;
++ little-endian;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ };
++
++ gpio2: gpio@2320000 {
++ compatible = "fsl,qoriq-gpio";
++ reg = <0x0 0x2320000 0x0 0x10000>;
++ interrupts = <0 37 0x4>; /* Level high type */
++ gpio-controller;
++ little-endian;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ };
++
++ gpio3: gpio@2330000 {
++ compatible = "fsl,qoriq-gpio";
++ reg = <0x0 0x2330000 0x0 0x10000>;
++ interrupts = <0 37 0x4>; /* Level high type */
++ gpio-controller;
++ little-endian;
++ #gpio-cells = <2>;
++ interrupt-controller;
++ #interrupt-cells = <2>;
++ };
++
++ /* TODO: WRIOP (CCSR?) */
++ emdio1: mdio@0x8B96000 { /* WRIOP0: 0x8B8_0000, E-MDIO1: 0x1_6000 */
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8B96000 0x0 0x1000>;
++ device_type = "mdio";
++ little-endian; /* force the driver in LE mode */
++
++ /* Not necessary on the QDS, but needed on the RDB */
++ #address-cells = <1>;
++ #size-cells = <0>;
++ };
++
++ emdio2: mdio@0x8B97000 { /* WRIOP0: 0x8B8_0000, E-MDIO2: 0x1_7000 */
++ compatible = "fsl,fman-memac-mdio";
++ reg = <0x0 0x8B97000 0x0 0x1000>;
++ device_type = "mdio";
++ little-endian; /* force the driver in LE mode */
++
++ #address-cells = <1>;
++ #size-cells = <0>;
++ };
++
++ ifc: ifc@2240000 {
++ compatible = "fsl,ifc", "simple-bus";
++ reg = <0x0 0x2240000 0x0 0x20000>;
++ interrupts = <0 21 0x4>; /* Level high type */
++ little-endian;
++ #address-cells = <2>;
++ #size-cells = <1>;
++
++ ranges = <0 0 0x5 0x80000000 0x08000000
++ 2 0 0x5 0x30000000 0x00010000
++ 3 0 0x5 0x20000000 0x00010000>;
++ };
++
++ esdhc: esdhc@2140000 {
++ compatible = "fsl,ls2080a-esdhc", "fsl,ls1088a-esdhc", "fsl,esdhc";
++ reg = <0x0 0x2140000 0x0 0x10000>;
++ interrupts = <0 28 0x4>; /* Level high type */
++ clock-frequency = <0>;
++ voltage-ranges = <1800 1800 3300 3300>;
++ sdhci,auto-cmd12;
++ little-endian;
++ bus-width = <4>;
++ };
++
++ ftm0: ftm0@2800000 {
++ compatible = "fsl,ftm-alarm";
++ reg = <0x0 0x2800000 0x0 0x10000>;
++ interrupts = <0 44 4>;
++ };
++
++ reset: reset@1E60000 {
++ compatible = "fsl,ls-reset";
++ reg = <0x0 0x1E60000 0x0 0x10000>;
++ };
++
++ dspi: dspi@2100000 {
++ compatible = "fsl,ls2085a-dspi", "fsl,ls1088a-dspi";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x0 0x2100000 0x0 0x10000>;
++ interrupts = <0 26 0x4>; /* Level high type */
++ clocks = <&clockgen 4 3>;
++ clock-names = "dspi";
++ spi-num-chipselects = <5>;
++ bus-num = <0>;
++ };
++
++ i2c0: i2c@2000000 {
++ compatible = "fsl,vf610-i2c";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x0 0x2000000 0x0 0x10000>;
++ interrupts = <0 34 0x4>; /* Level high type */
++ clock-names = "i2c";
++ clocks = <&clockgen 4 3>;
++ };
++
++ i2c1: i2c@2010000 {
++ compatible = "fsl,vf610-i2c";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x0 0x2010000 0x0 0x10000>;
++ interrupts = <0 34 0x4>; /* Level high type */
++ clock-names = "i2c";
++ clocks = <&clockgen 4 3>;
++ };
++
++ i2c2: i2c@2020000 {
++ compatible = "fsl,vf610-i2c";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x0 0x2020000 0x0 0x10000>;
++ interrupts = <0 35 0x4>; /* Level high type */
++ clock-names = "i2c";
++ clocks = <&clockgen 4 3>;
++ };
++
++ i2c3: i2c@2030000 {
++ compatible = "fsl,vf610-i2c";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x0 0x2030000 0x0 0x10000>;
++ interrupts = <0 35 0x4>; /* Level high type */
++ clock-names = "i2c";
++ clocks = <&clockgen 4 3>;
++ };
++
++ qspi: quadspi@20c0000 {
++ compatible = "fsl,ls2080a-qspi", "fsl,ls1088a-qspi";
++ #address-cells = <1>;
++ #size-cells = <0>;
++ reg = <0x0 0x20c0000 0x0 0x10000>,
++ <0x0 0x20000000 0x0 0x10000000>;
++ reg-names = "QuadSPI", "QuadSPI-memory";
++ interrupts = <0 25 0x4>; /* Level high type */
++ clocks = <&clockgen 4 3>, <&clockgen 4 3>;
++ clock-names = "qspi_en", "qspi";
++ };
++
++ pcie@3400000 {
++ compatible = "fsl,ls1088a-pcie", "snps,dw-pcie";
++ reg = <0x00 0x03400000 0x0 0x00100000 /* controller registers */
++ 0x20 0x00000000 0x0 0x00002000>; /* configuration space */
++ reg-names = "regs", "config";
++ interrupts = <0 108 0x4>; /* aer interrupt */
++ interrupt-names = "aer";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ device_type = "pci";
++ dma-coherent;
++ num-lanes = <4>;
++ bus-range = <0x0 0xff>;
++ ranges = <0x81000000 0x0 0x00000000 0x20 0x00010000 0x0 0x00010000 /* downstream I/O */
++ 0x82000000 0x0 0x40000000 0x20 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
++ msi-parent = <&its>;
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 7>;
++ interrupt-map = <0000 0 0 1 &gic 0 0 0 109 4>,
++ <0000 0 0 2 &gic 0 0 0 110 4>,
++ <0000 0 0 3 &gic 0 0 0 111 4>,
++ <0000 0 0 4 &gic 0 0 0 112 4>;
++ };
++ pcie@3500000 {
++ compatible = "fsl,ls1088a-pcie", "snps,dw-pcie";
++ reg = <0x00 0x03500000 0x0 0x00100000 /* controller registers */
++ 0x28 0x00000000 0x0 0x00002000>; /* configuration space */
++ reg-names = "regs", "config";
++ interrupts = <0 113 0x4>; /* aer interrupt */
++ interrupt-names = "aer";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ device_type = "pci";
++ dma-coherent;
++ num-lanes = <4>;
++ bus-range = <0x0 0xff>;
++ ranges = <0x81000000 0x0 0x00000000 0x28 0x00010000 0x0 0x00010000 /* downstream I/O */
++ 0x82000000 0x0 0x40000000 0x28 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
++ msi-parent = <&its>;
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 7>;
++ interrupt-map = <0000 0 0 1 &gic 0 0 0 114 4>,
++ <0000 0 0 2 &gic 0 0 0 115 4>,
++ <0000 0 0 3 &gic 0 0 0 116 4>,
++ <0000 0 0 4 &gic 0 0 0 117 4>;
++ };
++
++ pcie@3600000 {
++ compatible = "fsl,ls1088a-pcie", "snps,dw-pcie";
++ reg = <0x00 0x03600000 0x0 0x00100000 /* controller registers */
++ 0x30 0x00000000 0x0 0x00002000>; /* configuration space */
++ reg-names = "regs", "config";
++ interrupts = <0 118 0x4>; /* aer interrupt */
++ interrupt-names = "aer";
++ #address-cells = <3>;
++ #size-cells = <2>;
++ device_type = "pci";
++ dma-coherent;
++ num-lanes = <8>;
++ bus-range = <0x0 0xff>;
++ ranges = <0x81000000 0x0 0x00000000 0x30 0x00010000 0x0 0x00010000 /* downstream I/O */
++ 0x82000000 0x0 0x40000000 0x30 0x40000000 0x0 0x40000000>; /* non-prefetchable memory */
++ msi-parent = <&its>;
++ #interrupt-cells = <1>;
++ interrupt-map-mask = <0 0 0 7>;
++ interrupt-map = <0000 0 0 1 &gic 0 0 0 119 4>,
++ <0000 0 0 2 &gic 0 0 0 120 4>,
++ <0000 0 0 3 &gic 0 0 0 121 4>,
++ <0000 0 0 4 &gic 0 0 0 122 4>;
++ };
++
++ sata0: sata@3200000 {
++ compatible = "fsl,ls1088a-ahci", "fsl,ls1043a-ahci";
++ reg = <0x0 0x3200000 0x0 0x10000>;
++ interrupts = <0 133 0x4>; /* Level high type */
++ clocks = <&clockgen 4 3>;
++ };
++
++ usb0: usb3@3100000 {
++ compatible = "snps,dwc3";
++ reg = <0x0 0x3100000 0x0 0x10000>;
++ interrupts = <0 80 0x4>; /* Level high type */
++ dr_mode = "host";
++ configure-gfladj;
++ snps,dis_rxdet_inp3_quirk;
++ };
++
++ usb1: usb3@3110000 {
++ compatible = "snps,dwc3";
++ reg = <0x0 0x3110000 0x0 0x10000>;
++ interrupts = <0 81 0x4>; /* Level high type */
++ dr_mode = "host";
++ configure-gfladj;
++ snps,dis_rxdet_inp3_quirk;
++ };
++
++ smmu: iommu@5000000 {
++ compatible = "arm,mmu-500";
++ reg = <0 0x5000000 0 0x800000>;
++ #global-interrupts = <12>;
++ interrupts = <0 13 4>, /* global secure fault */
++ <0 14 4>, /* combined secure interrupt */
++ <0 15 4>, /* global non-secure fault */
++ <0 16 4>, /* combined non-secure interrupt */
++ /* performance counter interrupts 0-7 */
++ <0 211 4>,
++ <0 212 4>,
++ <0 213 4>,
++ <0 214 4>,
++ <0 215 4>,
++ <0 216 4>,
++ <0 217 4>,
++ <0 218 4>,
++ /* per context interrupt, 64 interrupts */
++ <0 146 4>,
++ <0 147 4>,
++ <0 148 4>,
++ <0 149 4>,
++ <0 150 4>,
++ <0 151 4>,
++ <0 152 4>,
++ <0 153 4>,
++ <0 154 4>,
++ <0 155 4>,
++ <0 156 4>,
++ <0 157 4>,
++ <0 158 4>,
++ <0 159 4>,
++ <0 160 4>,
++ <0 161 4>,
++ <0 162 4>,
++ <0 163 4>,
++ <0 164 4>,
++ <0 165 4>,
++ <0 166 4>,
++ <0 167 4>,
++ <0 168 4>,
++ <0 169 4>,
++ <0 170 4>,
++ <0 171 4>,
++ <0 172 4>,
++ <0 173 4>,
++ <0 174 4>,
++ <0 175 4>,
++ <0 176 4>,
++ <0 177 4>,
++ <0 178 4>,
++ <0 179 4>,
++ <0 180 4>,
++ <0 181 4>,
++ <0 182 4>,
++ <0 183 4>,
++ <0 184 4>,
++ <0 185 4>,
++ <0 186 4>,
++ <0 187 4>,
++ <0 188 4>,
++ <0 189 4>,
++ <0 190 4>,
++ <0 191 4>,
++ <0 192 4>,
++ <0 193 4>,
++ <0 194 4>,
++ <0 195 4>,
++ <0 196 4>,
++ <0 197 4>,
++ <0 198 4>,
++ <0 199 4>,
++ <0 200 4>,
++ <0 201 4>,
++ <0 202 4>,
++ <0 203 4>,
++ <0 204 4>,
++ <0 205 4>,
++ <0 206 4>,
++ <0 207 4>,
++ <0 208 4>,
++ <0 209 4>;
++ mmu-masters = <&fsl_mc 0x300 0>;
++ };
++
++ timer {
++ compatible = "arm,armv8-timer";
++ interrupts = <1 13 0x1>,/*Phy Secure PPI, edge triggered*/
++ <1 14 0x1>, /*Phy Non-Secure PPI, edge triggered*/
++ <1 11 0x1>, /*Virtual PPI, edge triggered */
++ <1 10 0x1>; /*Hypervisor PPI, edge triggered */
++ };
++
++ fsl_mc: fsl-mc@80c000000 {
++ compatible = "fsl,qoriq-mc";
++ #stream-id-cells = <2>;
++ reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */
++ <0x00000000 0x08340000 0 0x40000>; /* MC control reg */
++ msi-parent = <&its>;
++ #address-cells = <3>;
++ #size-cells = <1>;
++
++ /*
++ * Region type 0x0 - MC portals
++ * Region type 0x1 - QBMAN portals
++ */
++ ranges = <0x0 0x0 0x0 0x8 0x0c000000 0x4000000
++ 0x1 0x0 0x0 0x8 0x18000000 0x8000000>;
++
++ dpmacs {
++ #address-cells = <1>;
++ #size-cells = <0>;
++
++ dpmac1: dpmac@1 {
++ compatible = "fsl,qoriq-mc-dpmac";
++ reg = <1>;
++ };
++ dpmac2: dpmac@2 {
++ compatible = "fsl,qoriq-mc-dpmac";
++ reg = <2>;
++ };
++ dpmac3: dpmac@3 {
++ compatible = "fsl,qoriq-mc-dpmac";
++ reg = <3>;
++ };
++ dpmac4: dpmac@4 {
++ compatible = "fsl,qoriq-mc-dpmac";
++ reg = <4>;
++ };
++ dpmac5: dpmac@5 {
++ compatible = "fsl,qoriq-mc-dpmac";
++ reg = <5>;
++ };
++ dpmac6: dpmac@6 {
++ compatible = "fsl,qoriq-mc-dpmac";
++ reg = <6>;
++ };
++ dpmac7: dpmac@7 {
++ compatible = "fsl,qoriq-mc-dpmac";
++ reg = <7>;
++ };
++ dpmac8: dpmac@8 {
++ compatible = "fsl,qoriq-mc-dpmac";
++ reg = <8>;
++ };
++ dpmac9: dpmac@9 {
++ compatible = "fsl,qoriq-mc-dpmac";
++ reg = <9>;
++ };
++ dpmac10: dpmac@10 {
++ compatible = "fsl,qoriq-mc-dpmac";
++ reg = <0xa>;
++ };
++ };
++ };
++
++
++ memory@80000000 {
++ device_type = "memory";
++ reg = <0x00000000 0x80000000 0 0x80000000>;
++ /* DRAM space 1 - 2 GB DRAM */
++ };
++};
--- /dev/null
+From caaab508dc2ba749d8394b5934353b1c47f37d75 Mon Sep 17 00:00:00 2001
+From: Zhao Qiang <qiang.zhao@nxp.com>
+Date: Sun, 9 Oct 2016 15:14:16 +0800
+Subject: [PATCH 139/141] ls1088ardb: add ITS file
+
+Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
+---
+ kernel-ls1088a-rdb.its | 55 ++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 55 insertions(+)
+ create mode 100644 kernel-ls1088a-rdb.its
+
+--- /dev/null
++++ b/kernel-ls1088a-rdb.its
+@@ -0,0 +1,55 @@
++/*
++ * Copyright (C) 2015, Freescale Semiconductor
++ *
++ * Raghav Dogra <raghav@freescale.com>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2. This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ */
++
++/dts-v1/;
++
++/ {
++ description = "Simulator Image file for the LS1088A Linux Kernel";
++ #address-cells = <1>;
++
++ images {
++ kernel@1 {
++ description = "ARM64 Linux kernel";
++ data = /incbin/("./arch/arm64/boot/Image.gz");
++ type = "kernel";
++ arch = "arm64";
++ os = "linux";
++ compression = "gzip";
++ load = <0x80080000>;
++ entry = <0x80080000>;
++ };
++ fdt@1 {
++ description = "Flattened Device Tree blob";
++ data = /incbin/("./arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dtb");
++ type = "flat_dt";
++ arch = "arm64";
++ compression = "none";
++ load = <0x90000000>;
++ };
++ ramdisk@1 {
++ description = "LS2 Ramdisk";
++ data = /incbin/("./fsl-image-core-ls1088ardb-be.ext2.gz");
++ type = "ramdisk";
++ arch = "arm64";
++ os = "linux";
++ compression = "none";
++ };
++ };
++
++ configurations {
++ default = "config@1";
++ config@1 {
++ description = "Boot Linux kernel";
++ kernel = "kernel@1";
++ fdt = "fdt@1";
++ ramdisk = "ramdisk@1";
++ };
++ };
++};
--- /dev/null
+From 89b3b66aa955fed15585a4ba7120cf63f9e92aba Mon Sep 17 00:00:00 2001
+From: Zhao Qiang <qiang.zhao@nxp.com>
+Date: Thu, 13 Oct 2016 10:19:08 +0800
+Subject: [PATCH 141/141] caam: add caam node for ls1088a
+
+Signed-off-by: Zhao Qiang <qiang.zhao@nxp.com>
+---
+ arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 43 ++++++++++++++++++++++++
+ 1 file changed, 43 insertions(+)
+
+--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
++++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+@@ -485,6 +485,49 @@
+ <1 10 0x1>; /*Hypervisor PPI, edge triggered */
+ };
+
++ crypto: crypto@8000000 {
++ compatible = "fsl,sec-v5.4", "fsl,sec-v5.0",
++ "fsl,sec-v4.0";
++ fsl,sec-era = <8>;
++ #address-cells = <1>;
++ #size-cells = <1>;
++ ranges = <0x0 0x00 0x8000000 0x100000>;
++ reg = <0x00 0x8000000 0x0 0x100000>;
++ interrupts = <0 139 0x4>;
++
++ sec_jr0: jr@10000 {
++ compatible = "fsl,sec-v5.4-job-ring",
++ "fsl,sec-v5.0-job-ring",
++ "fsl,sec-v4.0-job-ring";
++ reg = <0x10000 0x10000>;
++ interrupts = <0 140 0x4>;
++ };
++
++ sec_jr1: jr@20000 {
++ compatible = "fsl,sec-v5.4-job-ring",
++ "fsl,sec-v5.0-job-ring",
++ "fsl,sec-v4.0-job-ring";
++ reg = <0x20000 0x10000>;
++ interrupts = <0 141 0x4>;
++ };
++
++ sec_jr2: jr@30000 {
++ compatible = "fsl,sec-v5.4-job-ring",
++ "fsl,sec-v5.0-job-ring",
++ "fsl,sec-v4.0-job-ring";
++ reg = <0x30000 0x10000>;
++ interrupts = <0 142 0x4>;
++ };
++
++ sec_jr3: jr@40000 {
++ compatible = "fsl,sec-v5.4-job-ring",
++ "fsl,sec-v5.0-job-ring",
++ "fsl,sec-v4.0-job-ring";
++ reg = <0x40000 0x10000>;
++ interrupts = <0 143 0x4>;
++ };
++ };
++
+ fsl_mc: fsl-mc@80c000000 {
+ compatible = "fsl,qoriq-mc";
+ #stream-id-cells = <2>;
--- /dev/null
+From 72b250c04f543d4eeda06b32e699444b15cac5cc Mon Sep 17 00:00:00 2001
+From: "ying.zhang" <ying.zhang22455@nxp.com>
+Date: Sat, 17 Dec 2016 00:39:28 +0800
+Subject: [PATCH 226/226] mtd:spi-nor:fsl-quadspi:Enable fast-read for
+ LS1088ARDB
+
+Add fast-read mode for LS1088ARDB board.
+
+Signed-off-by: Yuan Yao <yao.yuan@nxp.com>
+Integrated-by: Jiang Yutang <yutang.jiang@nxp.com>
+---
+ arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts | 2 ++
+ arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi | 1 +
+ 2 files changed, 3 insertions(+)
+
+--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
++++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a-rdb.dts
+@@ -91,6 +91,7 @@
+ compatible = "spansion,m25p80";
+ #address-cells = <1>;
+ #size-cells = <1>;
++ m25p,fast-read;
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+@@ -99,6 +100,7 @@
+ compatible = "spansion,m25p80";
+ #address-cells = <1>;
+ #size-cells = <1>;
++ m25p,fast-read;
+ spi-max-frequency = <20000000>;
+ reg = <1>;
+ };
+--- a/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
++++ b/arch/arm64/boot/dts/freescale/fsl-ls1088a.dtsi
+@@ -294,6 +294,7 @@
+ interrupts = <0 25 0x4>; /* Level high type */
+ clocks = <&clockgen 4 3>, <&clockgen 4 3>;
+ clock-names = "qspi_en", "qspi";
++ fsl,qspi-has-second-chip;
+ };
+
+ pcie@3400000 {
+
--- /dev/null
+From 0ac69de37277aec31d18a8c7b9d9a3a65b629526 Mon Sep 17 00:00:00 2001
+From: Yangbo Lu <yangbo.lu@nxp.com>
+Date: Wed, 12 Oct 2016 16:30:57 +0800
+Subject: [PATCH 144/226] dpaa: call arch_setup_dma_ops before using dma_ops
+
+A previous patch caused dpaa call trace. This patch provides
+a temporary workaround for this until this is fixed by upstream.
+
+Fixes: 1dccb598df54 ("arm64: simplify dma_get_ops")
+Signed-off-by: Yangbo Lu <yangbo.lu@nxp.com>
+---
+ .../ethernet/freescale/sdk_dpaa/dpaa_eth_common.c | 12 ++++++------
+ drivers/staging/fsl_qbman/qman_high.c | 1 +
+ 2 files changed, 7 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
++++ b/drivers/net/ethernet/freescale/sdk_dpaa/dpaa_eth_common.c
+@@ -754,6 +754,12 @@ dpa_bp_alloc(struct dpa_bp *dpa_bp)
+ goto pdev_register_failed;
+ }
+
++#ifdef CONFIG_FMAN_ARM
++ /* force coherency */
++ pdev->dev.archdata.dma_coherent = true;
++ arch_setup_dma_ops(&pdev->dev, 0, 0, NULL, true);
++#endif
++
+ err = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(40));
+ if (err)
+ goto pdev_mask_failed;
+@@ -765,12 +771,6 @@ dpa_bp_alloc(struct dpa_bp *dpa_bp)
+ goto pdev_mask_failed;
+ }
+
+-#ifdef CONFIG_FMAN_ARM
+- /* force coherency */
+- pdev->dev.archdata.dma_coherent = true;
+- arch_setup_dma_ops(&pdev->dev, 0, 0, NULL, true);
+-#endif
+-
+ dpa_bp->dev = &pdev->dev;
+
+ if (dpa_bp->seed_cb) {
+--- a/drivers/staging/fsl_qbman/qman_high.c
++++ b/drivers/staging/fsl_qbman/qman_high.c
+@@ -662,6 +662,7 @@ struct qman_portal *qman_create_portal(
+ portal->pdev->dev.coherent_dma_mask = DMA_BIT_MASK(40);
+ portal->pdev->dev.dma_mask = &portal->pdev->dev.coherent_dma_mask;
+ #else
++ arch_setup_dma_ops(&portal->pdev->dev, 0, 0, NULL, false);
+ if (dma_set_mask(&portal->pdev->dev, DMA_BIT_MASK(40))) {
+ pr_err("qman_portal - dma_set_mask() failed\n");
+ goto fail_devadd;
--- /dev/null
+From 8ebb892cd56d14e72580ab36c3b5eb2d4603a7fe Mon Sep 17 00:00:00 2001
+From: "J. German Rivera" <German.Rivera@freescale.com>
+Date: Wed, 6 Jan 2016 16:03:21 -0600
+Subject: [PATCH 145/226] staging: fsl-mc: Added generic MSI support for
+ FSL-MC devices
+
+Created an MSI domain for the fsl-mc bus-- including functions
+to create a domain, find a domain, alloc/free domain irqs, and
+bus specific overrides for domain and irq_chip ops.
+
+Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/Kconfig | 1 +
+ drivers/staging/fsl-mc/bus/Makefile | 1 +
+ drivers/staging/fsl-mc/bus/mc-msi.c | 276 +++++++++++++++++++++++++++
+ drivers/staging/fsl-mc/include/dprc.h | 2 +-
+ drivers/staging/fsl-mc/include/mc-private.h | 17 ++
+ drivers/staging/fsl-mc/include/mc.h | 17 ++
+ 6 files changed, 313 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/staging/fsl-mc/bus/mc-msi.c
+
+--- a/drivers/staging/fsl-mc/bus/Kconfig
++++ b/drivers/staging/fsl-mc/bus/Kconfig
+@@ -9,6 +9,7 @@
+ config FSL_MC_BUS
+ tristate "Freescale Management Complex (MC) bus driver"
+ depends on OF && ARM64
++ select GENERIC_MSI_IRQ_DOMAIN
+ help
+ Driver to enable the bus infrastructure for the Freescale
+ QorIQ Management Complex (fsl-mc). The fsl-mc is a hardware
+--- a/drivers/staging/fsl-mc/bus/Makefile
++++ b/drivers/staging/fsl-mc/bus/Makefile
+@@ -13,5 +13,6 @@ mc-bus-driver-objs := mc-bus.o \
+ dpmng.o \
+ dprc-driver.o \
+ mc-allocator.o \
++ mc-msi.o \
+ dpmcp.o \
+ dpbp.o
+--- /dev/null
++++ b/drivers/staging/fsl-mc/bus/mc-msi.c
+@@ -0,0 +1,276 @@
++/*
++ * Freescale Management Complex (MC) bus driver MSI support
++ *
++ * Copyright (C) 2015 Freescale Semiconductor, Inc.
++ * Author: German Rivera <German.Rivera@freescale.com>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2. This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ */
++
++#include "../include/mc-private.h"
++#include <linux/of_device.h>
++#include <linux/of_address.h>
++#include <linux/irqchip/arm-gic-v3.h>
++#include <linux/of_irq.h>
++#include <linux/irq.h>
++#include <linux/irqdomain.h>
++#include <linux/msi.h>
++#include "../include/mc-sys.h"
++#include "dprc-cmd.h"
++
++static void fsl_mc_msi_set_desc(msi_alloc_info_t *arg,
++ struct msi_desc *desc)
++{
++ arg->desc = desc;
++ arg->hwirq = (irq_hw_number_t)desc->fsl_mc.msi_index;
++}
++
++static void fsl_mc_msi_update_dom_ops(struct msi_domain_info *info)
++{
++ struct msi_domain_ops *ops = info->ops;
++
++ if (WARN_ON(!ops))
++ return;
++
++ /*
++ * set_desc should not be set by the caller
++ */
++ if (WARN_ON(ops->set_desc))
++ return;
++
++ ops->set_desc = fsl_mc_msi_set_desc;
++}
++
++static void __fsl_mc_msi_write_msg(struct fsl_mc_device *mc_bus_dev,
++ struct fsl_mc_device_irq *mc_dev_irq)
++{
++ int error;
++ struct fsl_mc_device *owner_mc_dev = mc_dev_irq->mc_dev;
++ struct msi_desc *msi_desc = mc_dev_irq->msi_desc;
++ struct dprc_irq_cfg irq_cfg;
++
++ /*
++ * msi_desc->msg.address is 0x0 when this function is invoked in
++ * the free_irq() code path. In this case, for the MC, we don't
++ * really need to "unprogram" the MSI, so we just return.
++ */
++ if (msi_desc->msg.address_lo == 0x0 && msi_desc->msg.address_hi == 0x0)
++ return;
++
++ if (WARN_ON(!owner_mc_dev))
++ return;
++
++ irq_cfg.paddr = ((u64)msi_desc->msg.address_hi << 32) |
++ msi_desc->msg.address_lo;
++ irq_cfg.val = msi_desc->msg.data;
++ irq_cfg.user_irq_id = msi_desc->irq;
++
++ if (owner_mc_dev == mc_bus_dev) {
++ /*
++ * IRQ is for the mc_bus_dev's DPRC itself
++ */
++ error = dprc_set_irq(mc_bus_dev->mc_io,
++ MC_CMD_FLAG_INTR_DIS | MC_CMD_FLAG_PRI,
++ mc_bus_dev->mc_handle,
++ mc_dev_irq->dev_irq_index,
++ &irq_cfg);
++ if (error < 0) {
++ dev_err(&owner_mc_dev->dev,
++ "dprc_set_irq() failed: %d\n", error);
++ }
++ } else {
++ /*
++ * IRQ is for for a child device of mc_bus_dev
++ */
++ error = dprc_set_obj_irq(mc_bus_dev->mc_io,
++ MC_CMD_FLAG_INTR_DIS | MC_CMD_FLAG_PRI,
++ mc_bus_dev->mc_handle,
++ owner_mc_dev->obj_desc.type,
++ owner_mc_dev->obj_desc.id,
++ mc_dev_irq->dev_irq_index,
++ &irq_cfg);
++ if (error < 0) {
++ dev_err(&owner_mc_dev->dev,
++ "dprc_obj_set_irq() failed: %d\n", error);
++ }
++ }
++}
++
++/*
++ * NOTE: This function is invoked with interrupts disabled
++ */
++static void fsl_mc_msi_write_msg(struct irq_data *irq_data,
++ struct msi_msg *msg)
++{
++ struct msi_desc *msi_desc = irq_data_get_msi_desc(irq_data);
++ struct fsl_mc_device *mc_bus_dev = to_fsl_mc_device(msi_desc->dev);
++ struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
++ struct fsl_mc_device_irq *mc_dev_irq =
++ &mc_bus->irq_resources[msi_desc->fsl_mc.msi_index];
++
++ WARN_ON(mc_dev_irq->msi_desc != msi_desc);
++ msi_desc->msg = *msg;
++
++ /*
++ * Program the MSI (paddr, value) pair in the device:
++ */
++ __fsl_mc_msi_write_msg(mc_bus_dev, mc_dev_irq);
++}
++
++static void fsl_mc_msi_update_chip_ops(struct msi_domain_info *info)
++{
++ struct irq_chip *chip = info->chip;
++
++ if (WARN_ON((!chip)))
++ return;
++
++ /*
++ * irq_write_msi_msg should not be set by the caller
++ */
++ if (WARN_ON(chip->irq_write_msi_msg))
++ return;
++
++ chip->irq_write_msi_msg = fsl_mc_msi_write_msg;
++}
++
++/**
++ * fsl_mc_msi_create_irq_domain - Create a fsl-mc MSI interrupt domain
++ * @np: Optional device-tree node of the interrupt controller
++ * @info: MSI domain info
++ * @parent: Parent irq domain
++ *
++ * Updates the domain and chip ops and creates a fsl-mc MSI
++ * interrupt domain.
++ *
++ * Returns:
++ * A domain pointer or NULL in case of failure.
++ */
++struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode,
++ struct msi_domain_info *info,
++ struct irq_domain *parent)
++{
++ struct irq_domain *domain;
++
++ if (info->flags & MSI_FLAG_USE_DEF_DOM_OPS)
++ fsl_mc_msi_update_dom_ops(info);
++ if (info->flags & MSI_FLAG_USE_DEF_CHIP_OPS)
++ fsl_mc_msi_update_chip_ops(info);
++
++ domain = msi_create_irq_domain(fwnode, info, parent);
++ if (domain)
++ domain->bus_token = DOMAIN_BUS_FSL_MC_MSI;
++
++ return domain;
++}
++
++int fsl_mc_find_msi_domain(struct device *mc_platform_dev,
++ struct irq_domain **mc_msi_domain)
++{
++ struct irq_domain *msi_domain;
++ struct device_node *mc_of_node = mc_platform_dev->of_node;
++
++ msi_domain = of_msi_get_domain(mc_platform_dev, mc_of_node,
++ DOMAIN_BUS_FSL_MC_MSI);
++ if (!msi_domain) {
++ pr_err("Unable to find fsl-mc MSI domain for %s\n",
++ mc_of_node->full_name);
++
++ return -ENOENT;
++ }
++
++ *mc_msi_domain = msi_domain;
++ return 0;
++}
++
++static void fsl_mc_msi_free_descs(struct device *dev)
++{
++ struct msi_desc *desc, *tmp;
++
++ list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) {
++ list_del(&desc->list);
++ free_msi_entry(desc);
++ }
++}
++
++static int fsl_mc_msi_alloc_descs(struct device *dev, unsigned int irq_count)
++
++{
++ unsigned int i;
++ int error;
++ struct msi_desc *msi_desc;
++
++ for (i = 0; i < irq_count; i++) {
++ msi_desc = alloc_msi_entry(dev);
++ if (!msi_desc) {
++ dev_err(dev, "Failed to allocate msi entry\n");
++ error = -ENOMEM;
++ goto cleanup_msi_descs;
++ }
++
++ msi_desc->fsl_mc.msi_index = i;
++ msi_desc->nvec_used = 1;
++ INIT_LIST_HEAD(&msi_desc->list);
++ list_add_tail(&msi_desc->list, dev_to_msi_list(dev));
++ }
++
++ return 0;
++
++cleanup_msi_descs:
++ fsl_mc_msi_free_descs(dev);
++ return error;
++}
++
++int fsl_mc_msi_domain_alloc_irqs(struct device *dev,
++ unsigned int irq_count)
++{
++ struct irq_domain *msi_domain;
++ int error;
++
++ if (WARN_ON(!list_empty(dev_to_msi_list(dev))))
++ return -EINVAL;
++
++ error = fsl_mc_msi_alloc_descs(dev, irq_count);
++ if (error < 0)
++ return error;
++
++ msi_domain = dev_get_msi_domain(dev);
++ if (WARN_ON(!msi_domain)) {
++ error = -EINVAL;
++ goto cleanup_msi_descs;
++ }
++
++ /*
++ * NOTE: Calling this function will trigger the invocation of the
++ * its_fsl_mc_msi_prepare() callback
++ */
++ error = msi_domain_alloc_irqs(msi_domain, dev, irq_count);
++
++ if (error) {
++ dev_err(dev, "Failed to allocate IRQs\n");
++ goto cleanup_msi_descs;
++ }
++
++ return 0;
++
++cleanup_msi_descs:
++ fsl_mc_msi_free_descs(dev);
++ return error;
++}
++
++void fsl_mc_msi_domain_free_irqs(struct device *dev)
++{
++ struct irq_domain *msi_domain;
++
++ msi_domain = dev_get_msi_domain(dev);
++ if (WARN_ON(!msi_domain))
++ return;
++
++ msi_domain_free_irqs(msi_domain, dev);
++
++ if (WARN_ON(list_empty(dev_to_msi_list(dev))))
++ return;
++
++ fsl_mc_msi_free_descs(dev);
++}
+--- a/drivers/staging/fsl-mc/include/dprc.h
++++ b/drivers/staging/fsl-mc/include/dprc.h
+@@ -176,7 +176,7 @@ int dprc_reset_container(struct fsl_mc_i
+ * @user_irq_id: A user defined number associated with this IRQ
+ */
+ struct dprc_irq_cfg {
+- u64 paddr;
++ phys_addr_t paddr;
+ u32 val;
+ int user_irq_id;
+ };
+--- a/drivers/staging/fsl-mc/include/mc-private.h
++++ b/drivers/staging/fsl-mc/include/mc-private.h
+@@ -26,6 +26,9 @@
+ strcmp(_obj_type, "dpmcp") == 0 || \
+ strcmp(_obj_type, "dpcon") == 0)
+
++struct irq_domain;
++struct msi_domain_info;
++
+ /**
+ * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device
+ * @root_mc_bus_dev: MC object device representing the root DPRC
+@@ -79,11 +82,13 @@ struct fsl_mc_resource_pool {
+ * @resource_pools: array of resource pools (one pool per resource type)
+ * for this MC bus. These resources represent allocatable entities
+ * from the physical DPRC.
++ * @irq_resources: Pointer to array of IRQ objects for the IRQ pool
+ * @scan_mutex: Serializes bus scanning
+ */
+ struct fsl_mc_bus {
+ struct fsl_mc_device mc_dev;
+ struct fsl_mc_resource_pool resource_pools[FSL_MC_NUM_POOL_TYPES];
++ struct fsl_mc_device_irq *irq_resources;
+ struct mutex scan_mutex; /* serializes bus scanning */
+ };
+
+@@ -116,4 +121,16 @@ int __must_check fsl_mc_resource_allocat
+
+ void fsl_mc_resource_free(struct fsl_mc_resource *resource);
+
++struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode,
++ struct msi_domain_info *info,
++ struct irq_domain *parent);
++
++int fsl_mc_find_msi_domain(struct device *mc_platform_dev,
++ struct irq_domain **mc_msi_domain);
++
++int fsl_mc_msi_domain_alloc_irqs(struct device *dev,
++ unsigned int irq_count);
++
++void fsl_mc_msi_domain_free_irqs(struct device *dev);
++
+ #endif /* _FSL_MC_PRIVATE_H_ */
+--- a/drivers/staging/fsl-mc/include/mc.h
++++ b/drivers/staging/fsl-mc/include/mc.h
+@@ -104,6 +104,23 @@ struct fsl_mc_resource {
+ };
+
+ /**
++ * struct fsl_mc_device_irq - MC object device message-based interrupt
++ * @msi_desc: pointer to MSI descriptor allocated by fsl_mc_msi_alloc_descs()
++ * @mc_dev: MC object device that owns this interrupt
++ * @dev_irq_index: device-relative IRQ index
++ * @resource: MC generic resource associated with the interrupt
++ */
++struct fsl_mc_device_irq {
++ struct msi_desc *msi_desc;
++ struct fsl_mc_device *mc_dev;
++ u8 dev_irq_index;
++ struct fsl_mc_resource resource;
++};
++
++#define to_fsl_mc_irq(_mc_resource) \
++ container_of(_mc_resource, struct fsl_mc_device_irq, resource)
++
++/**
+ * Bit masks for a MC object device (struct fsl_mc_device) flags
+ */
+ #define FSL_MC_IS_DPRC 0x0001
--- /dev/null
+From 85cb8ae26b6c69f0a118f32b7b7cd4f22d782da3 Mon Sep 17 00:00:00 2001
+From: "J. German Rivera" <German.Rivera@freescale.com>
+Date: Wed, 6 Jan 2016 16:03:22 -0600
+Subject: [PATCH 146/226] staging: fsl-mc: Added GICv3-ITS support for FSL-MC
+ MSIs
+
+Added platform-specific MSI support layer for FSL-MC devices.
+
+Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/Makefile | 1 +
+ .../staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c | 127 ++++++++++++++++++++
+ drivers/staging/fsl-mc/include/mc-private.h | 4 +
+ 3 files changed, 132 insertions(+)
+ create mode 100644 drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
+
+--- a/drivers/staging/fsl-mc/bus/Makefile
++++ b/drivers/staging/fsl-mc/bus/Makefile
+@@ -14,5 +14,6 @@ mc-bus-driver-objs := mc-bus.o \
+ dprc-driver.o \
+ mc-allocator.o \
+ mc-msi.o \
++ irq-gic-v3-its-fsl-mc-msi.o \
+ dpmcp.o \
+ dpbp.o
+--- /dev/null
++++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
+@@ -0,0 +1,127 @@
++/*
++ * Freescale Management Complex (MC) bus driver MSI support
++ *
++ * Copyright (C) 2015 Freescale Semiconductor, Inc.
++ * Author: German Rivera <German.Rivera@freescale.com>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2. This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ */
++
++#include "../include/mc-private.h"
++#include <linux/of_device.h>
++#include <linux/of_address.h>
++#include <linux/irqchip/arm-gic-v3.h>
++#include <linux/irq.h>
++#include <linux/msi.h>
++#include <linux/of.h>
++#include <linux/of_irq.h>
++#include "../include/mc-sys.h"
++#include "dprc-cmd.h"
++
++static struct irq_chip its_msi_irq_chip = {
++ .name = "fsl-mc-bus-msi",
++ .irq_mask = irq_chip_mask_parent,
++ .irq_unmask = irq_chip_unmask_parent,
++ .irq_eoi = irq_chip_eoi_parent,
++ .irq_set_affinity = msi_domain_set_affinity
++};
++
++static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain,
++ struct device *dev,
++ int nvec, msi_alloc_info_t *info)
++{
++ struct fsl_mc_device *mc_bus_dev;
++ struct msi_domain_info *msi_info;
++
++ if (WARN_ON(dev->bus != &fsl_mc_bus_type))
++ return -EINVAL;
++
++ mc_bus_dev = to_fsl_mc_device(dev);
++ if (WARN_ON(!(mc_bus_dev->flags & FSL_MC_IS_DPRC)))
++ return -EINVAL;
++
++ /*
++ * Set the device Id to be passed to the GIC-ITS:
++ *
++ * NOTE: This device id corresponds to the IOMMU stream ID
++ * associated with the DPRC object (ICID).
++ */
++ info->scratchpad[0].ul = mc_bus_dev->icid;
++ msi_info = msi_get_domain_info(msi_domain->parent);
++ return msi_info->ops->msi_prepare(msi_domain->parent, dev, nvec, info);
++}
++
++static struct msi_domain_ops its_fsl_mc_msi_ops = {
++ .msi_prepare = its_fsl_mc_msi_prepare,
++};
++
++static struct msi_domain_info its_fsl_mc_msi_domain_info = {
++ .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS),
++ .ops = &its_fsl_mc_msi_ops,
++ .chip = &its_msi_irq_chip,
++};
++
++static const struct of_device_id its_device_id[] = {
++ { .compatible = "arm,gic-v3-its", },
++ {},
++};
++
++int __init its_fsl_mc_msi_init(void)
++{
++ struct device_node *np;
++ struct irq_domain *parent;
++ struct irq_domain *mc_msi_domain;
++
++ for (np = of_find_matching_node(NULL, its_device_id); np;
++ np = of_find_matching_node(np, its_device_id)) {
++ if (!of_property_read_bool(np, "msi-controller"))
++ continue;
++
++ parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS);
++ if (!parent || !msi_get_domain_info(parent)) {
++ pr_err("%s: unable to locate ITS domain\n",
++ np->full_name);
++ continue;
++ }
++
++ mc_msi_domain = fsl_mc_msi_create_irq_domain(
++ of_node_to_fwnode(np),
++ &its_fsl_mc_msi_domain_info,
++ parent);
++ if (!mc_msi_domain) {
++ pr_err("%s: unable to create fsl-mc domain\n",
++ np->full_name);
++ continue;
++ }
++
++ WARN_ON(mc_msi_domain->
++ host_data != &its_fsl_mc_msi_domain_info);
++
++ pr_info("fsl-mc MSI: %s domain created\n", np->full_name);
++ }
++
++ return 0;
++}
++
++void its_fsl_mc_msi_cleanup(void)
++{
++ struct device_node *np;
++
++ for (np = of_find_matching_node(NULL, its_device_id); np;
++ np = of_find_matching_node(np, its_device_id)) {
++ struct irq_domain *mc_msi_domain = irq_find_matching_host(
++ np,
++ DOMAIN_BUS_FSL_MC_MSI);
++
++ if (!of_property_read_bool(np, "msi-controller"))
++ continue;
++
++ mc_msi_domain = irq_find_matching_host(np,
++ DOMAIN_BUS_FSL_MC_MSI);
++ if (mc_msi_domain &&
++ mc_msi_domain->host_data == &its_fsl_mc_msi_domain_info)
++ irq_domain_remove(mc_msi_domain);
++ }
++}
+--- a/drivers/staging/fsl-mc/include/mc-private.h
++++ b/drivers/staging/fsl-mc/include/mc-private.h
+@@ -133,4 +133,8 @@ int fsl_mc_msi_domain_alloc_irqs(struct
+
+ void fsl_mc_msi_domain_free_irqs(struct device *dev);
+
++int __init its_fsl_mc_msi_init(void);
++
++void its_fsl_mc_msi_cleanup(void);
++
+ #endif /* _FSL_MC_PRIVATE_H_ */
--- /dev/null
+From 23b09c6b4162a8264b600f35d7048256a7afc0cd Mon Sep 17 00:00:00 2001
+From: "J. German Rivera" <German.Rivera@freescale.com>
+Date: Wed, 6 Jan 2016 16:03:23 -0600
+Subject: [PATCH 147/226] staging: fsl-mc: Extended MC bus allocator to
+ include IRQs
+
+All the IRQs for DPAA2 objects in the same DPRC must use
+the ICID of that DPRC, as their device Id in the GIC-ITS.
+Thus, all these IRQs must share the same ITT table in the GIC.
+As a result, a pool of IRQs with the same device Id must be
+preallocated per DPRC (fsl-mc bus instance). So, the fsl-mc
+bus object allocator is extended to also provide services
+to allocate IRQs to DPAA2 devices, from their parent fsl-mc bus
+IRQ pool.
+
+Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-allocator.c | 199 +++++++++++++++++++++++++++
+ drivers/staging/fsl-mc/include/mc-private.h | 15 ++
+ drivers/staging/fsl-mc/include/mc.h | 9 ++
+ 3 files changed, 223 insertions(+)
+
+--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
++++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
+@@ -15,6 +15,7 @@
+ #include "../include/dpcon-cmd.h"
+ #include "dpmcp-cmd.h"
+ #include "dpmcp.h"
++#include <linux/msi.h>
+
+ /**
+ * fsl_mc_resource_pool_add_device - add allocatable device to a resource
+@@ -160,6 +161,7 @@ static const char *const fsl_mc_pool_typ
+ [FSL_MC_POOL_DPMCP] = "dpmcp",
+ [FSL_MC_POOL_DPBP] = "dpbp",
+ [FSL_MC_POOL_DPCON] = "dpcon",
++ [FSL_MC_POOL_IRQ] = "irq",
+ };
+
+ static int __must_check object_type_to_pool_type(const char *object_type,
+@@ -465,6 +467,203 @@ void fsl_mc_object_free(struct fsl_mc_de
+ }
+ EXPORT_SYMBOL_GPL(fsl_mc_object_free);
+
++/*
++ * Initialize the interrupt pool associated with a MC bus.
++ * It allocates a block of IRQs from the GIC-ITS
++ */
++int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
++ unsigned int irq_count)
++{
++ unsigned int i;
++ struct msi_desc *msi_desc;
++ struct fsl_mc_device_irq *irq_resources;
++ struct fsl_mc_device_irq *mc_dev_irq;
++ int error;
++ struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
++ struct fsl_mc_resource_pool *res_pool =
++ &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
++
++ if (WARN_ON(irq_count == 0 ||
++ irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS))
++ return -EINVAL;
++
++ error = fsl_mc_msi_domain_alloc_irqs(&mc_bus_dev->dev, irq_count);
++ if (error < 0)
++ return error;
++
++ irq_resources = devm_kzalloc(&mc_bus_dev->dev,
++ sizeof(*irq_resources) * irq_count,
++ GFP_KERNEL);
++ if (!irq_resources) {
++ error = -ENOMEM;
++ goto cleanup_msi_irqs;
++ }
++
++ for (i = 0; i < irq_count; i++) {
++ mc_dev_irq = &irq_resources[i];
++
++ /*
++ * NOTE: This mc_dev_irq's MSI addr/value pair will be set
++ * by the fsl_mc_msi_write_msg() callback
++ */
++ mc_dev_irq->resource.type = res_pool->type;
++ mc_dev_irq->resource.data = mc_dev_irq;
++ mc_dev_irq->resource.parent_pool = res_pool;
++ INIT_LIST_HEAD(&mc_dev_irq->resource.node);
++ list_add_tail(&mc_dev_irq->resource.node, &res_pool->free_list);
++ }
++
++ for_each_msi_entry(msi_desc, &mc_bus_dev->dev) {
++ mc_dev_irq = &irq_resources[msi_desc->fsl_mc.msi_index];
++ mc_dev_irq->msi_desc = msi_desc;
++ mc_dev_irq->resource.id = msi_desc->irq;
++ }
++
++ res_pool->max_count = irq_count;
++ res_pool->free_count = irq_count;
++ mc_bus->irq_resources = irq_resources;
++ return 0;
++
++cleanup_msi_irqs:
++ fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
++ return error;
++}
++EXPORT_SYMBOL_GPL(fsl_mc_populate_irq_pool);
++
++/**
++ * Teardown the interrupt pool associated with an MC bus.
++ * It frees the IRQs that were allocated to the pool, back to the GIC-ITS.
++ */
++void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus)
++{
++ struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
++ struct fsl_mc_resource_pool *res_pool =
++ &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
++
++ if (WARN_ON(!mc_bus->irq_resources))
++ return;
++
++ if (WARN_ON(res_pool->max_count == 0))
++ return;
++
++ if (WARN_ON(res_pool->free_count != res_pool->max_count))
++ return;
++
++ INIT_LIST_HEAD(&res_pool->free_list);
++ res_pool->max_count = 0;
++ res_pool->free_count = 0;
++ mc_bus->irq_resources = NULL;
++ fsl_mc_msi_domain_free_irqs(&mc_bus_dev->dev);
++}
++EXPORT_SYMBOL_GPL(fsl_mc_cleanup_irq_pool);
++
++/**
++ * It allocates the IRQs required by a given MC object device. The
++ * IRQs are allocated from the interrupt pool associated with the
++ * MC bus that contains the device, if the device is not a DPRC device.
++ * Otherwise, the IRQs are allocated from the interrupt pool associated
++ * with the MC bus that represents the DPRC device itself.
++ */
++int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev)
++{
++ int i;
++ int irq_count;
++ int res_allocated_count = 0;
++ int error = -EINVAL;
++ struct fsl_mc_device_irq **irqs = NULL;
++ struct fsl_mc_bus *mc_bus;
++ struct fsl_mc_resource_pool *res_pool;
++
++ if (WARN_ON(mc_dev->irqs))
++ return -EINVAL;
++
++ irq_count = mc_dev->obj_desc.irq_count;
++ if (WARN_ON(irq_count == 0))
++ return -EINVAL;
++
++ if (strcmp(mc_dev->obj_desc.type, "dprc") == 0)
++ mc_bus = to_fsl_mc_bus(mc_dev);
++ else
++ mc_bus = to_fsl_mc_bus(to_fsl_mc_device(mc_dev->dev.parent));
++
++ if (WARN_ON(!mc_bus->irq_resources))
++ return -EINVAL;
++
++ res_pool = &mc_bus->resource_pools[FSL_MC_POOL_IRQ];
++ if (res_pool->free_count < irq_count) {
++ dev_err(&mc_dev->dev,
++ "Not able to allocate %u irqs for device\n", irq_count);
++ return -ENOSPC;
++ }
++
++ irqs = devm_kzalloc(&mc_dev->dev, irq_count * sizeof(irqs[0]),
++ GFP_KERNEL);
++ if (!irqs)
++ return -ENOMEM;
++
++ for (i = 0; i < irq_count; i++) {
++ struct fsl_mc_resource *resource;
++
++ error = fsl_mc_resource_allocate(mc_bus, FSL_MC_POOL_IRQ,
++ &resource);
++ if (error < 0)
++ goto error_resource_alloc;
++
++ irqs[i] = to_fsl_mc_irq(resource);
++ res_allocated_count++;
++
++ WARN_ON(irqs[i]->mc_dev);
++ irqs[i]->mc_dev = mc_dev;
++ irqs[i]->dev_irq_index = i;
++ }
++
++ mc_dev->irqs = irqs;
++ return 0;
++
++error_resource_alloc:
++ for (i = 0; i < res_allocated_count; i++) {
++ irqs[i]->mc_dev = NULL;
++ fsl_mc_resource_free(&irqs[i]->resource);
++ }
++
++ return error;
++}
++EXPORT_SYMBOL_GPL(fsl_mc_allocate_irqs);
++
++/*
++ * It frees the IRQs that were allocated for a MC object device, by
++ * returning them to the corresponding interrupt pool.
++ */
++void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev)
++{
++ int i;
++ int irq_count;
++ struct fsl_mc_bus *mc_bus;
++ struct fsl_mc_device_irq **irqs = mc_dev->irqs;
++
++ if (WARN_ON(!irqs))
++ return;
++
++ irq_count = mc_dev->obj_desc.irq_count;
++
++ if (strcmp(mc_dev->obj_desc.type, "dprc") == 0)
++ mc_bus = to_fsl_mc_bus(mc_dev);
++ else
++ mc_bus = to_fsl_mc_bus(to_fsl_mc_device(mc_dev->dev.parent));
++
++ if (WARN_ON(!mc_bus->irq_resources))
++ return;
++
++ for (i = 0; i < irq_count; i++) {
++ WARN_ON(!irqs[i]->mc_dev);
++ irqs[i]->mc_dev = NULL;
++ fsl_mc_resource_free(&irqs[i]->resource);
++ }
++
++ mc_dev->irqs = NULL;
++}
++EXPORT_SYMBOL_GPL(fsl_mc_free_irqs);
++
+ /**
+ * fsl_mc_allocator_probe - callback invoked when an allocatable device is
+ * being added to the system
+--- a/drivers/staging/fsl-mc/include/mc-private.h
++++ b/drivers/staging/fsl-mc/include/mc-private.h
+@@ -30,6 +30,16 @@ struct irq_domain;
+ struct msi_domain_info;
+
+ /**
++ * Maximum number of total IRQs that can be pre-allocated for an MC bus'
++ * IRQ pool
++ */
++#define FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS 256
++
++struct device_node;
++struct irq_domain;
++struct msi_domain_info;
++
++/**
+ * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device
+ * @root_mc_bus_dev: MC object device representing the root DPRC
+ * @num_translation_ranges: number of entries in addr_translation_ranges
+@@ -137,4 +147,9 @@ int __init its_fsl_mc_msi_init(void);
+
+ void its_fsl_mc_msi_cleanup(void);
+
++int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus,
++ unsigned int irq_count);
++
++void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus);
++
+ #endif /* _FSL_MC_PRIVATE_H_ */
+--- a/drivers/staging/fsl-mc/include/mc.h
++++ b/drivers/staging/fsl-mc/include/mc.h
+@@ -14,12 +14,14 @@
+ #include <linux/device.h>
+ #include <linux/mod_devicetable.h>
+ #include <linux/list.h>
++#include <linux/interrupt.h>
+ #include "../include/dprc.h"
+
+ #define FSL_MC_VENDOR_FREESCALE 0x1957
+
+ struct fsl_mc_device;
+ struct fsl_mc_io;
++struct fsl_mc_bus;
+
+ /**
+ * struct fsl_mc_driver - MC object device driver object
+@@ -75,6 +77,7 @@ enum fsl_mc_pool_type {
+ FSL_MC_POOL_DPMCP = 0x0, /* corresponds to "dpmcp" in the MC */
+ FSL_MC_POOL_DPBP, /* corresponds to "dpbp" in the MC */
+ FSL_MC_POOL_DPCON, /* corresponds to "dpcon" in the MC */
++ FSL_MC_POOL_IRQ,
+
+ /*
+ * NOTE: New resource pool types must be added before this entry
+@@ -141,6 +144,7 @@ struct fsl_mc_device_irq {
+ * NULL if none.
+ * @obj_desc: MC description of the DPAA device
+ * @regions: pointer to array of MMIO region entries
++ * @irqs: pointer to array of pointers to interrupts allocated to this device
+ * @resource: generic resource associated with this MC object device, if any.
+ *
+ * Generic device object for MC object devices that are "attached" to a
+@@ -172,6 +176,7 @@ struct fsl_mc_device {
+ struct fsl_mc_io *mc_io;
+ struct dprc_obj_desc obj_desc;
+ struct resource *regions;
++ struct fsl_mc_device_irq **irqs;
+ struct fsl_mc_resource *resource;
+ };
+
+@@ -215,6 +220,10 @@ int __must_check fsl_mc_object_allocate(
+
+ void fsl_mc_object_free(struct fsl_mc_device *mc_adev);
+
++int __must_check fsl_mc_allocate_irqs(struct fsl_mc_device *mc_dev);
++
++void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev);
++
+ extern struct bus_type fsl_mc_bus_type;
+
+ #endif /* _FSL_MC_H_ */
--- /dev/null
+From 0f2a65dea2024b7898e3c0b42e0a7864d6538567 Mon Sep 17 00:00:00 2001
+From: "J. German Rivera" <German.Rivera@freescale.com>
+Date: Wed, 6 Jan 2016 16:03:24 -0600
+Subject: [PATCH 148/226] staging: fsl-mc: Changed DPRC built-in portal's
+ mc_io to be atomic
+
+The DPRC built-in portal's mc_io is used to send commands to the MC
+to program MSIs for MC objects. This is done by the
+fsl_mc_msi_write_msg() callback, which is invoked by the generic MSI
+layer with interrupts disabled. As a result, the mc_io used in
+fsl_mc_msi_write_msg needs to be an atomic mc_io.
+
+Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 4 +++-
+ drivers/staging/fsl-mc/bus/mc-bus.c | 3 ++-
+ 2 files changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -396,7 +396,9 @@ static int dprc_probe(struct fsl_mc_devi
+ error = fsl_create_mc_io(&mc_dev->dev,
+ mc_dev->regions[0].start,
+ region_size,
+- NULL, 0, &mc_dev->mc_io);
++ NULL,
++ FSL_MC_IO_ATOMIC_CONTEXT_PORTAL,
++ &mc_dev->mc_io);
+ if (error < 0)
+ return error;
+ }
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -702,7 +702,8 @@ static int fsl_mc_bus_probe(struct platf
+ mc_portal_phys_addr = res.start;
+ mc_portal_size = resource_size(&res);
+ error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr,
+- mc_portal_size, NULL, 0, &mc_io);
++ mc_portal_size, NULL,
++ FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io);
+ if (error < 0)
+ return error;
+
--- /dev/null
+From 78ab7589777526022757e9c95b9d5864786eb4e5 Mon Sep 17 00:00:00 2001
+From: "J. German Rivera" <German.Rivera@freescale.com>
+Date: Wed, 6 Jan 2016 16:03:25 -0600
+Subject: [PATCH 149/226] staging: fsl-mc: Populate the IRQ pool for an MC bus
+ instance
+
+Scan the corresponding DPRC container to get total count
+of IRQs needed by all its child DPAA2 objects. Then,
+preallocate a set of MSI IRQs with the DPRC's ICID
+(GIT-ITS device Id) to populate the the DPRC's IRQ pool.
+Each child DPAA2 object in the DPRC and the DPRC object itself
+will allocate their necessary MSI IRQs from the DPRC's IRQ pool,
+in their driver probe function.
+
+Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 24 ++++++++++++++++++++++--
+ drivers/staging/fsl-mc/include/mc-private.h | 3 ++-
+ 2 files changed, 24 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -241,6 +241,7 @@ static void dprc_cleanup_all_resource_po
+ * dprc_scan_objects - Discover objects in a DPRC
+ *
+ * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
++ * @total_irq_count: total number of IRQs needed by objects in the DPRC.
+ *
+ * Detects objects added and removed from a DPRC and synchronizes the
+ * state of the Linux bus driver, MC by adding and removing
+@@ -254,11 +255,13 @@ static void dprc_cleanup_all_resource_po
+ * populated before they can get allocation requests from probe callbacks
+ * of the device drivers for the non-allocatable devices.
+ */
+-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev)
++int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
++ unsigned int *total_irq_count)
+ {
+ int num_child_objects;
+ int dprc_get_obj_failures;
+ int error;
++ unsigned int irq_count = mc_bus_dev->obj_desc.irq_count;
+ struct dprc_obj_desc *child_obj_desc_array = NULL;
+
+ error = dprc_get_obj_count(mc_bus_dev->mc_io,
+@@ -307,6 +310,7 @@ int dprc_scan_objects(struct fsl_mc_devi
+ continue;
+ }
+
++ irq_count += obj_desc->irq_count;
+ dev_dbg(&mc_bus_dev->dev,
+ "Discovered object: type %s, id %d\n",
+ obj_desc->type, obj_desc->id);
+@@ -319,6 +323,7 @@ int dprc_scan_objects(struct fsl_mc_devi
+ }
+ }
+
++ *total_irq_count = irq_count;
+ dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
+ num_child_objects);
+
+@@ -344,6 +349,7 @@ EXPORT_SYMBOL_GPL(dprc_scan_objects);
+ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev)
+ {
+ int error;
++ unsigned int irq_count;
+ struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
+
+ dprc_init_all_resource_pools(mc_bus_dev);
+@@ -352,11 +358,25 @@ int dprc_scan_container(struct fsl_mc_de
+ * Discover objects in the DPRC:
+ */
+ mutex_lock(&mc_bus->scan_mutex);
+- error = dprc_scan_objects(mc_bus_dev);
++ error = dprc_scan_objects(mc_bus_dev, &irq_count);
+ mutex_unlock(&mc_bus->scan_mutex);
+ if (error < 0)
+ goto error;
+
++ if (dev_get_msi_domain(&mc_bus_dev->dev) && !mc_bus->irq_resources) {
++ if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
++ dev_warn(&mc_bus_dev->dev,
++ "IRQs needed (%u) exceed IRQs preallocated (%u)\n",
++ irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
++ }
++
++ error = fsl_mc_populate_irq_pool(
++ mc_bus,
++ FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
++ if (error < 0)
++ goto error;
++ }
++
+ return 0;
+ error:
+ dprc_cleanup_all_resource_pools(mc_bus_dev);
+--- a/drivers/staging/fsl-mc/include/mc-private.h
++++ b/drivers/staging/fsl-mc/include/mc-private.h
+@@ -114,7 +114,8 @@ void fsl_mc_device_remove(struct fsl_mc_
+
+ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev);
+
+-int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev);
++int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
++ unsigned int *total_irq_count);
+
+ int __init dprc_driver_init(void);
+
--- /dev/null
+From 15bfab2641c61fb50a876860e8909ab84d2b8701 Mon Sep 17 00:00:00 2001
+From: "J. German Rivera" <German.Rivera@freescale.com>
+Date: Wed, 6 Jan 2016 16:03:26 -0600
+Subject: [PATCH 150/226] staging: fsl-mc: set MSI domain for DPRC objects
+
+THE MSI domain associated with a root DPRC object is
+obtained form the device tree. Child DPRCs inherit
+the parent DPRC MSI domain.
+
+Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 39 ++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -13,6 +13,7 @@
+ #include "../include/mc-sys.h"
+ #include <linux/module.h>
+ #include <linux/slab.h>
++#include <linux/interrupt.h>
+ #include "dprc-cmd.h"
+
+ struct dprc_child_objs {
+@@ -398,11 +399,16 @@ static int dprc_probe(struct fsl_mc_devi
+ {
+ int error;
+ size_t region_size;
++ struct device *parent_dev = mc_dev->dev.parent;
+ struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
++ bool msi_domain_set = false;
+
+ if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
+ return -EINVAL;
+
++ if (WARN_ON(dev_get_msi_domain(&mc_dev->dev)))
++ return -EINVAL;
++
+ if (!mc_dev->mc_io) {
+ /*
+ * This is a child DPRC:
+@@ -421,6 +427,30 @@ static int dprc_probe(struct fsl_mc_devi
+ &mc_dev->mc_io);
+ if (error < 0)
+ return error;
++ /*
++ * Inherit parent MSI domain:
++ */
++ dev_set_msi_domain(&mc_dev->dev,
++ dev_get_msi_domain(parent_dev));
++ msi_domain_set = true;
++ } else {
++ /*
++ * This is a root DPRC
++ */
++ struct irq_domain *mc_msi_domain;
++
++ if (WARN_ON(parent_dev->bus == &fsl_mc_bus_type))
++ return -EINVAL;
++
++ error = fsl_mc_find_msi_domain(parent_dev,
++ &mc_msi_domain);
++ if (error < 0) {
++ dev_warn(&mc_dev->dev,
++ "WARNING: MC bus without interrupt support\n");
++ } else {
++ dev_set_msi_domain(&mc_dev->dev, mc_msi_domain);
++ msi_domain_set = true;
++ }
+ }
+
+ error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id,
+@@ -446,6 +476,9 @@ error_cleanup_open:
+ (void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
+
+ error_cleanup_mc_io:
++ if (msi_domain_set)
++ dev_set_msi_domain(&mc_dev->dev, NULL);
++
+ fsl_destroy_mc_io(mc_dev->mc_io);
+ return error;
+ }
+@@ -463,6 +496,7 @@ error_cleanup_mc_io:
+ static int dprc_remove(struct fsl_mc_device *mc_dev)
+ {
+ int error;
++ struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+
+ if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
+ return -EINVAL;
+@@ -475,6 +509,11 @@ static int dprc_remove(struct fsl_mc_dev
+ if (error < 0)
+ dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);
+
++ if (dev_get_msi_domain(&mc_dev->dev)) {
++ fsl_mc_cleanup_irq_pool(mc_bus);
++ dev_set_msi_domain(&mc_dev->dev, NULL);
++ }
++
+ dev_info(&mc_dev->dev, "DPRC device unbound from driver");
+ return 0;
+ }
--- /dev/null
+From 22aa842ae501ea8724afd45fcb0d7b17a67cb950 Mon Sep 17 00:00:00 2001
+From: "J. German Rivera" <German.Rivera@freescale.com>
+Date: Wed, 6 Jan 2016 16:03:27 -0600
+Subject: [PATCH 151/226] staging: fsl-mc: Fixed bug in dprc_probe() error
+ path
+
+Destroy mc_io in error path in dprc_probe() only if the mc_io was
+created in this function.
+
+Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 17 ++++++++++++++---
+ 1 file changed, 14 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -401,6 +401,7 @@ static int dprc_probe(struct fsl_mc_devi
+ size_t region_size;
+ struct device *parent_dev = mc_dev->dev.parent;
+ struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
++ bool mc_io_created = false;
+ bool msi_domain_set = false;
+
+ if (WARN_ON(strcmp(mc_dev->obj_desc.type, "dprc") != 0))
+@@ -413,6 +414,9 @@ static int dprc_probe(struct fsl_mc_devi
+ /*
+ * This is a child DPRC:
+ */
++ if (WARN_ON(parent_dev->bus != &fsl_mc_bus_type))
++ return -EINVAL;
++
+ if (WARN_ON(mc_dev->obj_desc.region_count == 0))
+ return -EINVAL;
+
+@@ -427,6 +431,9 @@ static int dprc_probe(struct fsl_mc_devi
+ &mc_dev->mc_io);
+ if (error < 0)
+ return error;
++
++ mc_io_created = true;
++
+ /*
+ * Inherit parent MSI domain:
+ */
+@@ -457,7 +464,7 @@ static int dprc_probe(struct fsl_mc_devi
+ &mc_dev->mc_handle);
+ if (error < 0) {
+ dev_err(&mc_dev->dev, "dprc_open() failed: %d\n", error);
+- goto error_cleanup_mc_io;
++ goto error_cleanup_msi_domain;
+ }
+
+ mutex_init(&mc_bus->scan_mutex);
+@@ -475,11 +482,15 @@ static int dprc_probe(struct fsl_mc_devi
+ error_cleanup_open:
+ (void)dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
+
+-error_cleanup_mc_io:
++error_cleanup_msi_domain:
+ if (msi_domain_set)
+ dev_set_msi_domain(&mc_dev->dev, NULL);
+
+- fsl_destroy_mc_io(mc_dev->mc_io);
++ if (mc_io_created) {
++ fsl_destroy_mc_io(mc_dev->mc_io);
++ mc_dev->mc_io = NULL;
++ }
++
+ return error;
+ }
+
--- /dev/null
+From aa83997b14c31b34d9af24cb42726b55fa630464 Mon Sep 17 00:00:00 2001
+From: "J. German Rivera" <German.Rivera@freescale.com>
+Date: Wed, 6 Jan 2016 16:03:28 -0600
+Subject: [PATCH 152/226] staging: fsl-mc: Added DPRC interrupt handler
+
+The interrupt handler for DPRC IRQs is added. DPRC IRQs are
+generated for hot plug events related to DPAA2 objects in a given
+DPRC. These events include, creating/destroying DPAA2 objects in
+the DPRC, changing the "plugged" state of DPAA2 objects and moving
+objects between DPRCs.
+
+Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 247 ++++++++++++++++++++++++++++++
+ 1 file changed, 247 insertions(+)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -14,6 +14,7 @@
+ #include <linux/module.h>
+ #include <linux/slab.h>
+ #include <linux/interrupt.h>
++#include <linux/msi.h>
+ #include "dprc-cmd.h"
+
+ struct dprc_child_objs {
+@@ -386,6 +387,230 @@ error:
+ EXPORT_SYMBOL_GPL(dprc_scan_container);
+
+ /**
++ * dprc_irq0_handler - Regular ISR for DPRC interrupt 0
++ *
++ * @irq: IRQ number of the interrupt being handled
++ * @arg: Pointer to device structure
++ */
++static irqreturn_t dprc_irq0_handler(int irq_num, void *arg)
++{
++ return IRQ_WAKE_THREAD;
++}
++
++/**
++ * dprc_irq0_handler_thread - Handler thread function for DPRC interrupt 0
++ *
++ * @irq: IRQ number of the interrupt being handled
++ * @arg: Pointer to device structure
++ */
++static irqreturn_t dprc_irq0_handler_thread(int irq_num, void *arg)
++{
++ int error;
++ u32 status;
++ struct device *dev = (struct device *)arg;
++ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
++ struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
++ struct fsl_mc_io *mc_io = mc_dev->mc_io;
++ struct msi_desc *msi_desc = mc_dev->irqs[0]->msi_desc;
++
++ dev_dbg(dev, "DPRC IRQ %d triggered on CPU %u\n",
++ irq_num, smp_processor_id());
++
++ if (WARN_ON(!(mc_dev->flags & FSL_MC_IS_DPRC)))
++ return IRQ_HANDLED;
++
++ mutex_lock(&mc_bus->scan_mutex);
++ if (WARN_ON(!msi_desc || msi_desc->irq != (u32)irq_num))
++ goto out;
++
++ error = dprc_get_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
++ &status);
++ if (error < 0) {
++ dev_err(dev,
++ "dprc_get_irq_status() failed: %d\n", error);
++ goto out;
++ }
++
++ error = dprc_clear_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
++ status);
++ if (error < 0) {
++ dev_err(dev,
++ "dprc_clear_irq_status() failed: %d\n", error);
++ goto out;
++ }
++
++ if (status & (DPRC_IRQ_EVENT_OBJ_ADDED |
++ DPRC_IRQ_EVENT_OBJ_REMOVED |
++ DPRC_IRQ_EVENT_CONTAINER_DESTROYED |
++ DPRC_IRQ_EVENT_OBJ_DESTROYED |
++ DPRC_IRQ_EVENT_OBJ_CREATED)) {
++ unsigned int irq_count;
++
++ error = dprc_scan_objects(mc_dev, &irq_count);
++ if (error < 0) {
++ /*
++ * If the error is -ENXIO, we ignore it, as it indicates
++ * that the object scan was aborted, as we detected that
++ * an object was removed from the DPRC in the MC, while
++ * we were scanning the DPRC.
++ */
++ if (error != -ENXIO) {
++ dev_err(dev, "dprc_scan_objects() failed: %d\n",
++ error);
++ }
++
++ goto out;
++ }
++
++ if (irq_count > FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS) {
++ dev_warn(dev,
++ "IRQs needed (%u) exceed IRQs preallocated (%u)\n",
++ irq_count, FSL_MC_IRQ_POOL_MAX_TOTAL_IRQS);
++ }
++ }
++
++out:
++ mutex_unlock(&mc_bus->scan_mutex);
++ return IRQ_HANDLED;
++}
++
++/*
++ * Disable and clear interrupt for a given DPRC object
++ */
++static int disable_dprc_irq(struct fsl_mc_device *mc_dev)
++{
++ int error;
++ struct fsl_mc_io *mc_io = mc_dev->mc_io;
++
++ WARN_ON(mc_dev->obj_desc.irq_count != 1);
++
++ /*
++ * Disable generation of interrupt, while we configure it:
++ */
++ error = dprc_set_irq_enable(mc_io, 0, mc_dev->mc_handle, 0, 0);
++ if (error < 0) {
++ dev_err(&mc_dev->dev,
++ "Disabling DPRC IRQ failed: dprc_set_irq_enable() failed: %d\n",
++ error);
++ return error;
++ }
++
++ /*
++ * Disable all interrupt causes for the interrupt:
++ */
++ error = dprc_set_irq_mask(mc_io, 0, mc_dev->mc_handle, 0, 0x0);
++ if (error < 0) {
++ dev_err(&mc_dev->dev,
++ "Disabling DPRC IRQ failed: dprc_set_irq_mask() failed: %d\n",
++ error);
++ return error;
++ }
++
++ /*
++ * Clear any leftover interrupts:
++ */
++ error = dprc_clear_irq_status(mc_io, 0, mc_dev->mc_handle, 0, ~0x0U);
++ if (error < 0) {
++ dev_err(&mc_dev->dev,
++ "Disabling DPRC IRQ failed: dprc_clear_irq_status() failed: %d\n",
++ error);
++ return error;
++ }
++
++ return 0;
++}
++
++static int register_dprc_irq_handler(struct fsl_mc_device *mc_dev)
++{
++ int error;
++ struct fsl_mc_device_irq *irq = mc_dev->irqs[0];
++
++ WARN_ON(mc_dev->obj_desc.irq_count != 1);
++
++ /*
++ * NOTE: devm_request_threaded_irq() invokes the device-specific
++ * function that programs the MSI physically in the device
++ */
++ error = devm_request_threaded_irq(&mc_dev->dev,
++ irq->msi_desc->irq,
++ dprc_irq0_handler,
++ dprc_irq0_handler_thread,
++ IRQF_NO_SUSPEND | IRQF_ONESHOT,
++ "FSL MC DPRC irq0",
++ &mc_dev->dev);
++ if (error < 0) {
++ dev_err(&mc_dev->dev,
++ "devm_request_threaded_irq() failed: %d\n",
++ error);
++ return error;
++ }
++
++ return 0;
++}
++
++static int enable_dprc_irq(struct fsl_mc_device *mc_dev)
++{
++ int error;
++
++ /*
++ * Enable all interrupt causes for the interrupt:
++ */
++ error = dprc_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle, 0,
++ ~0x0u);
++ if (error < 0) {
++ dev_err(&mc_dev->dev,
++ "Enabling DPRC IRQ failed: dprc_set_irq_mask() failed: %d\n",
++ error);
++
++ return error;
++ }
++
++ /*
++ * Enable generation of the interrupt:
++ */
++ error = dprc_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle, 0, 1);
++ if (error < 0) {
++ dev_err(&mc_dev->dev,
++ "Enabling DPRC IRQ failed: dprc_set_irq_enable() failed: %d\n",
++ error);
++
++ return error;
++ }
++
++ return 0;
++}
++
++/*
++ * Setup interrupt for a given DPRC device
++ */
++static int dprc_setup_irq(struct fsl_mc_device *mc_dev)
++{
++ int error;
++
++ error = fsl_mc_allocate_irqs(mc_dev);
++ if (error < 0)
++ return error;
++
++ error = disable_dprc_irq(mc_dev);
++ if (error < 0)
++ goto error_free_irqs;
++
++ error = register_dprc_irq_handler(mc_dev);
++ if (error < 0)
++ goto error_free_irqs;
++
++ error = enable_dprc_irq(mc_dev);
++ if (error < 0)
++ goto error_free_irqs;
++
++ return 0;
++
++error_free_irqs:
++ fsl_mc_free_irqs(mc_dev);
++ return error;
++}
++
++/**
+ * dprc_probe - callback invoked when a DPRC is being bound to this driver
+ *
+ * @mc_dev: Pointer to fsl-mc device representing a DPRC
+@@ -476,6 +701,13 @@ static int dprc_probe(struct fsl_mc_devi
+ if (error < 0)
+ goto error_cleanup_open;
+
++ /*
++ * Configure interrupt for the DPRC object associated with this MC bus:
++ */
++ error = dprc_setup_irq(mc_dev);
++ if (error < 0)
++ goto error_cleanup_open;
++
+ dev_info(&mc_dev->dev, "DPRC device bound to driver");
+ return 0;
+
+@@ -494,6 +726,15 @@ error_cleanup_msi_domain:
+ return error;
+ }
+
++/*
++ * Tear down interrupt for a given DPRC object
++ */
++static void dprc_teardown_irq(struct fsl_mc_device *mc_dev)
++{
++ (void)disable_dprc_irq(mc_dev);
++ fsl_mc_free_irqs(mc_dev);
++}
++
+ /**
+ * dprc_remove - callback invoked when a DPRC is being unbound from this driver
+ *
+@@ -514,6 +755,12 @@ static int dprc_remove(struct fsl_mc_dev
+ if (WARN_ON(!mc_dev->mc_io))
+ return -EINVAL;
+
++ if (WARN_ON(!mc_bus->irq_resources))
++ return -EINVAL;
++
++ if (dev_get_msi_domain(&mc_dev->dev))
++ dprc_teardown_irq(mc_dev);
++
+ device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove);
+ dprc_cleanup_all_resource_pools(mc_dev);
+ error = dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
--- /dev/null
+From f588a135d9260f2e7fe29b0bb0b5294fc9c99f6c Mon Sep 17 00:00:00 2001
+From: "J. German Rivera" <German.Rivera@freescale.com>
+Date: Wed, 6 Jan 2016 16:03:29 -0600
+Subject: [PATCH 153/226] staging: fsl-mc: Added MSI support to the MC bus
+ driver
+
+Initialize/Cleanup ITS-MSI support for the MC bus driver at driver
+init/exit time. Associate an MSI domain with each DPAA2 child device.
+
+Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -16,6 +16,8 @@
+ #include <linux/ioport.h>
+ #include <linux/slab.h>
+ #include <linux/limits.h>
++#include <linux/bitops.h>
++#include <linux/msi.h>
+ #include "../include/dpmng.h"
+ #include "../include/mc-sys.h"
+ #include "dprc-cmd.h"
+@@ -472,6 +474,8 @@ int fsl_mc_device_add(struct dprc_obj_de
+ mc_dev->icid = parent_mc_dev->icid;
+ mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK;
+ mc_dev->dev.dma_mask = &mc_dev->dma_mask;
++ dev_set_msi_domain(&mc_dev->dev,
++ dev_get_msi_domain(&parent_mc_dev->dev));
+ }
+
+ /*
+@@ -833,8 +837,15 @@ static int __init fsl_mc_bus_driver_init
+ if (error < 0)
+ goto error_cleanup_dprc_driver;
+
++ error = its_fsl_mc_msi_init();
++ if (error < 0)
++ goto error_cleanup_mc_allocator;
++
+ return 0;
+
++error_cleanup_mc_allocator:
++ fsl_mc_allocator_driver_exit();
++
+ error_cleanup_dprc_driver:
+ dprc_driver_exit();
+
+@@ -856,6 +867,7 @@ static void __exit fsl_mc_bus_driver_exi
+ if (WARN_ON(!mc_dev_cache))
+ return;
+
++ its_fsl_mc_msi_cleanup();
+ fsl_mc_allocator_driver_exit();
+ dprc_driver_exit();
+ platform_driver_unregister(&fsl_mc_bus_driver);
--- /dev/null
+From 6ce3c078c4eac406b38de689c8e366d7345a51ba Mon Sep 17 00:00:00 2001
+From: Janani Ravichandran <janani.rvchndrn@gmail.com>
+Date: Thu, 11 Feb 2016 18:00:25 -0500
+Subject: [PATCH 154/226] staging: fsl-mc: Remove unneeded parentheses
+
+Remove unneeded parentheses on the right hand side of assignment
+statements.
+Semantic patch:
+
+@@
+expression a, b, c;
+@@
+
+(
+ a = (b == c)
+|
+ a =
+- (
+ b
+- )
+)
+
+Signed-off-by: Janani Ravichandran <janani.rvchndrn@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -129,7 +129,7 @@ static void check_plugged_state_change(s
+ {
+ int error;
+ u32 plugged_flag_at_mc =
+- (obj_desc->state & DPRC_OBJ_STATE_PLUGGED);
++ obj_desc->state & DPRC_OBJ_STATE_PLUGGED;
+
+ if (plugged_flag_at_mc !=
+ (mc_dev->obj_desc.state & DPRC_OBJ_STATE_PLUGGED)) {
--- /dev/null
+From 322ff2fe86ec4dead2d2bceb20b624c72bdd1405 Mon Sep 17 00:00:00 2001
+From: Thierry Reding <treding@nvidia.com>
+Date: Mon, 15 Feb 2016 14:22:22 +0100
+Subject: [PATCH 155/226] staging: fsl-mc: Do not allow building as a module
+
+This driver uses functionality (MSI IRQ domain) whose symbols aren't
+exported, and hence the modular build fails. While arguably there might
+be reasons to make these symbols available to modules, that change would
+be fairly involved and the set of exported functions should be carefully
+auditioned. Fix the build failure for now by marking the driver boolean.
+
+Cc: J. German Rivera <German.Rivera@freescale.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/Kconfig | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/fsl-mc/bus/Kconfig
++++ b/drivers/staging/fsl-mc/bus/Kconfig
+@@ -7,7 +7,7 @@
+ #
+
+ config FSL_MC_BUS
+- tristate "Freescale Management Complex (MC) bus driver"
++ bool "Freescale Management Complex (MC) bus driver"
+ depends on OF && ARM64
+ select GENERIC_MSI_IRQ_DOMAIN
+ help
--- /dev/null
+From b2e5cfb43faf26517d191de65121f1a40166340f Mon Sep 17 00:00:00 2001
+From: Thierry Reding <treding@nvidia.com>
+Date: Mon, 15 Feb 2016 14:22:23 +0100
+Subject: [PATCH 156/226] staging: fsl-mc: Avoid section mismatch
+
+The fsl_mc_allocator_driver_exit() function is marked __exit, but is
+called by the error handling code in fsl_mc_allocator_driver_init().
+This results in a section mismatch, which in turn could lead to
+executing random code.
+
+Remove the __exit annotation to fix this.
+
+Cc: J. German Rivera <German.Rivera@freescale.com>
+Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Signed-off-by: Thierry Reding <treding@nvidia.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-allocator.c | 2 +-
+ drivers/staging/fsl-mc/include/mc-private.h | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
++++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
+@@ -756,7 +756,7 @@ int __init fsl_mc_allocator_driver_init(
+ return fsl_mc_driver_register(&fsl_mc_allocator_driver);
+ }
+
+-void __exit fsl_mc_allocator_driver_exit(void)
++void fsl_mc_allocator_driver_exit(void)
+ {
+ fsl_mc_driver_unregister(&fsl_mc_allocator_driver);
+ }
+--- a/drivers/staging/fsl-mc/include/mc-private.h
++++ b/drivers/staging/fsl-mc/include/mc-private.h
+@@ -123,7 +123,7 @@ void dprc_driver_exit(void);
+
+ int __init fsl_mc_allocator_driver_init(void);
+
+-void __exit fsl_mc_allocator_driver_exit(void);
++void fsl_mc_allocator_driver_exit(void);
+
+ int __must_check fsl_mc_resource_allocate(struct fsl_mc_bus *mc_bus,
+ enum fsl_mc_pool_type pool_type,
--- /dev/null
+From 5f82c6ff69f3a4bb635e619a893292bea711421e Mon Sep 17 00:00:00 2001
+From: Janani Ravichandran <janani.rvchndrn@gmail.com>
+Date: Thu, 18 Feb 2016 17:22:50 -0500
+Subject: [PATCH 157/226] staging: fsl-mc: Remove unneeded else following a
+ return
+
+Remove unnecessary else when there is a return statement in the
+corresponding if block. Coccinelle patch used:
+
+@rule1@
+expression e1;
+@@
+
+ if (e1) { ... return ...; }
+- else{
+ ...
+- }
+
+@rule2@
+expression e2;
+statement s1;
+@@
+
+ if(e2) { ... return ...; }
+- else
+ s1
+
+Signed-off-by: Janani Ravichandran <janani.rvchndrn@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -248,8 +248,7 @@ static bool fsl_mc_is_root_dprc(struct d
+ fsl_mc_get_root_dprc(dev, &root_dprc_dev);
+ if (!root_dprc_dev)
+ return false;
+- else
+- return dev == root_dprc_dev;
++ return dev == root_dprc_dev;
+ }
+
+ static int get_dprc_icid(struct fsl_mc_io *mc_io,
--- /dev/null
+From d9605741556a15dceed105afd7369d644aa46207 Mon Sep 17 00:00:00 2001
+From: Janani Ravichandran <janani.rvchndrn@gmail.com>
+Date: Thu, 25 Feb 2016 14:46:11 -0500
+Subject: [PATCH 158/226] staging: fsl-mc: Drop unneeded void pointer cast
+
+Void pointers need not be cast to other pointer types.
+Semantic patch used:
+
+@r@
+expression x;
+void *e;
+type T;
+identifier f;
+@@
+
+(
+ *((T *)e)
+|
+ ((T *)x) [...]
+|
+ ((T *)x)->f
+|
+- (T *)
+ e
+)
+
+Signed-off-by: Janani Ravichandran <janani.rvchndrn@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -407,7 +407,7 @@ static irqreturn_t dprc_irq0_handler_thr
+ {
+ int error;
+ u32 status;
+- struct device *dev = (struct device *)arg;
++ struct device *dev = arg;
+ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+ struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_dev);
+ struct fsl_mc_io *mc_io = mc_dev->mc_io;
--- /dev/null
+From ecd7b5d9616e50f48a400749f17db19fd8a43f25 Mon Sep 17 00:00:00 2001
+From: Bhaktipriya Shridhar <bhaktipriya96@gmail.com>
+Date: Sun, 28 Feb 2016 23:58:05 +0530
+Subject: [PATCH 159/226] staging: fsl-mc: bus: Eliminate double function call
+
+A call to irq_find_matching_host was already made and the result
+has been stored in mc_msi_domain. mc_msi_domain is again reassigned
+using the same function call which is redundant.
+
+irq_find_matching_host returns/locates a domain for a given fwnode.
+The domain is identified using device node and bus_token(if several
+domains have same device node but different purposes they can be
+distinguished using bus-specific token).
+http://www.bricktou.com/include/linux/irqdomain_irq_find_matching_host_en.html
+
+Also, of_property_read_bool finds and reads a boolean from a property
+device node from which the property value is to be read. It doesn't
+alter the device node.
+http://lists.infradead.org/pipermail/linux-arm-kernel/2012-February/083698.html
+
+Since, both the function calls have the same device node and bus_token,
+the return values shall be the same. Hence, the second call has been
+removed.
+
+This was done using Coccinelle:
+
+@r@
+idexpression *x;
+identifier f;
+position p1,p2;
+@@
+
+x@p1 = f(...)
+... when != x
+(
+x@p2 = f(...)
+)
+
+@script:python@
+p1 << r.p1;
+p2 << r.p2;
+@@
+
+if (p1[0].line == p2[0].line):
+ cocci.include_match(False)
+
+@@
+idexpression *x;
+identifier f;
+position r.p1,r.p2;
+@@
+
+*x@p1 = f(...)
+...
+*x@p2 = f(...)
+
+Signed-off-by: Bhaktipriya Shridhar <bhaktipriya96@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ .../staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
++++ b/drivers/staging/fsl-mc/bus/irq-gic-v3-its-fsl-mc-msi.c
+@@ -118,8 +118,6 @@ void its_fsl_mc_msi_cleanup(void)
+ if (!of_property_read_bool(np, "msi-controller"))
+ continue;
+
+- mc_msi_domain = irq_find_matching_host(np,
+- DOMAIN_BUS_FSL_MC_MSI);
+ if (mc_msi_domain &&
+ mc_msi_domain->host_data == &its_fsl_mc_msi_domain_info)
+ irq_domain_remove(mc_msi_domain);
--- /dev/null
+From 8727f71717b449a4c74a5a599374c05822d525f7 Mon Sep 17 00:00:00 2001
+From: Bhumika Goyal <bhumirks@gmail.com>
+Date: Fri, 4 Mar 2016 19:14:52 +0530
+Subject: [PATCH 160/226] Staging: fsl-mc: Replace pr_debug with dev_dbg
+
+This patch replaces pr_debug calls with dev_dbg when the device structure
+is available as dev_* prints identifying information about the struct
+device.
+Done using coccinelle:
+
+@r exists@
+identifier f, s;
+identifier x;
+position p;
+@@
+f(...,struct s *x,...) {
+<+...
+when != x == NULL
+\(pr_err@p\|pr_debug@p\|pr_info\)(...);
+...+>
+}
+
+@r2@
+identifier fld2;
+identifier r.s;
+@@
+
+struct s {
+ ...
+ struct device *fld2;
+ ...
+};
+
+@@
+identifier r.x,r2.fld2;
+position r.p;
+@@
+
+(
+-pr_err@p
++dev_err
+ (
++ &x->fld2,
+...)
+|
+- pr_debug@p
++ dev_dbg
+ (
++ &x->fld2,
+...)
+|
+- pr_info@p
++ dev_info
+ (
++ &x->fld2,
+...)
+)
+
+Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-sys.c | 9 ++++++---
+ 1 file changed, 6 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-sys.c
++++ b/drivers/staging/fsl-mc/bus/mc-sys.c
+@@ -328,7 +328,8 @@ static int mc_polling_wait_preemptible(s
+ MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS);
+
+ if (time_after_eq(jiffies, jiffies_until_timeout)) {
+- pr_debug("MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n",
++ dev_dbg(&mc_io->dev,
++ "MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n",
+ mc_io->portal_phys_addr,
+ (unsigned int)
+ MC_CMD_HDR_READ_TOKEN(cmd->header),
+@@ -369,7 +370,8 @@ static int mc_polling_wait_atomic(struct
+ udelay(MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS);
+ timeout_usecs -= MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS;
+ if (timeout_usecs == 0) {
+- pr_debug("MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n",
++ dev_dbg(&mc_io->dev,
++ "MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n",
+ mc_io->portal_phys_addr,
+ (unsigned int)
+ MC_CMD_HDR_READ_TOKEN(cmd->header),
+@@ -424,7 +426,8 @@ int mc_send_command(struct fsl_mc_io *mc
+ goto common_exit;
+
+ if (status != MC_CMD_STATUS_OK) {
+- pr_debug("MC command failed: portal: %#llx, obj handle: %#x, command: %#x, status: %s (%#x)\n",
++ dev_dbg(&mc_io->dev,
++ "MC command failed: portal: %#llx, obj handle: %#x, command: %#x, status: %s (%#x)\n",
+ mc_io->portal_phys_addr,
+ (unsigned int)MC_CMD_HDR_READ_TOKEN(cmd->header),
+ (unsigned int)MC_CMD_HDR_READ_CMDID(cmd->header),
--- /dev/null
+From 79b4625a6ab72251e00aa94ee22a6bfe32dbeeda Mon Sep 17 00:00:00 2001
+From: Bhumika Goyal <bhumirks@gmail.com>
+Date: Fri, 4 Mar 2016 19:15:55 +0530
+Subject: [PATCH 161/226] Staging: fsl-mc: Replace pr_err with dev_err
+
+This patch replaces pr_err calls with dev_err when the device structure
+is available as dev_* prints identifying information about the struct device.
+Done using coccinelle:
+
+@r exists@
+identifier f, s;
+identifier x;
+position p;
+@@
+f(...,struct s *x,...) {
+<+...
+when != x == NULL
+\(pr_err@p\|pr_debug@p\|pr_info\)(...);
+...+>
+}
+
+@r2@
+identifier fld2;
+identifier r.s;
+@@
+
+struct s {
+ ...
+ struct device *fld2;
+ ...
+};
+
+@@
+identifier r.x,r2.fld2;
+position r.p;
+@@
+
+(
+-pr_err@p
++dev_err
+ (
++ &x->fld2,
+...)
+|
+- pr_debug@p
++ dev_dbg
+ (
++ &x->fld2,
+...)
+|
+- pr_info@p
++ dev_info
+ (
++ &x->fld2,
+...)
+)
+
+Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -260,14 +260,15 @@ static int get_dprc_icid(struct fsl_mc_i
+
+ error = dprc_open(mc_io, 0, container_id, &dprc_handle);
+ if (error < 0) {
+- pr_err("dprc_open() failed: %d\n", error);
++ dev_err(&mc_io->dev, "dprc_open() failed: %d\n", error);
+ return error;
+ }
+
+ memset(&attr, 0, sizeof(attr));
+ error = dprc_get_attributes(mc_io, 0, dprc_handle, &attr);
+ if (error < 0) {
+- pr_err("dprc_get_attributes() failed: %d\n", error);
++ dev_err(&mc_io->dev, "dprc_get_attributes() failed: %d\n",
++ error);
+ goto common_cleanup;
+ }
+
--- /dev/null
+From 83e0f572a74bceeb3736b19b929c91d12d1d6d80 Mon Sep 17 00:00:00 2001
+From: Cihangir Akturk <cakturk@gmail.com>
+Date: Mon, 14 Mar 2016 18:14:06 +0200
+Subject: [PATCH 162/226] staging: fsl-mc: fix incorrect type passed to
+ dev_dbg macros
+
+dev_dbg macros expect const struct device ** as its second
+argument but here the argument we are passing is of type
+struct device ** this patch fixes this error.
+
+Fixes: de71daf5c839 ("Staging: fsl-mc: Replace pr_debug with dev_dbg")
+Cc: Bhumika Goyal <bhumirks@gmail.com>
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Cihangir Akturk <cakturk@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-sys.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-sys.c
++++ b/drivers/staging/fsl-mc/bus/mc-sys.c
+@@ -328,7 +328,7 @@ static int mc_polling_wait_preemptible(s
+ MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS);
+
+ if (time_after_eq(jiffies, jiffies_until_timeout)) {
+- dev_dbg(&mc_io->dev,
++ dev_dbg(mc_io->dev,
+ "MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n",
+ mc_io->portal_phys_addr,
+ (unsigned int)
+@@ -370,7 +370,7 @@ static int mc_polling_wait_atomic(struct
+ udelay(MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS);
+ timeout_usecs -= MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS;
+ if (timeout_usecs == 0) {
+- dev_dbg(&mc_io->dev,
++ dev_dbg(mc_io->dev,
+ "MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n",
+ mc_io->portal_phys_addr,
+ (unsigned int)
+@@ -426,7 +426,7 @@ int mc_send_command(struct fsl_mc_io *mc
+ goto common_exit;
+
+ if (status != MC_CMD_STATUS_OK) {
+- dev_dbg(&mc_io->dev,
++ dev_dbg(mc_io->dev,
+ "MC command failed: portal: %#llx, obj handle: %#x, command: %#x, status: %s (%#x)\n",
+ mc_io->portal_phys_addr,
+ (unsigned int)MC_CMD_HDR_READ_TOKEN(cmd->header),
--- /dev/null
+From 79929c151efbc047a8a82f9cafcb9238465caa86 Mon Sep 17 00:00:00 2001
+From: Cihangir Akturk <cakturk@gmail.com>
+Date: Mon, 14 Mar 2016 18:14:07 +0200
+Subject: [PATCH 163/226] staging: fsl-mc: fix incorrect type passed to
+ dev_err macros
+
+dev_err macros expect const struct device ** as its second
+argument, but here the argument we are passing is of typ
+struct device **. This patch fixes this error.
+
+Fixes: 454b0ec8bf99 ("Staging: fsl-mc: Replace pr_err with dev_err")
+Cc: Bhumika Goyal <bhumirks@gmail.com>
+Reported-by: Guenter Roeck <linux@roeck-us.net>
+Signed-off-by: Cihangir Akturk <cakturk@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -260,14 +260,14 @@ static int get_dprc_icid(struct fsl_mc_i
+
+ error = dprc_open(mc_io, 0, container_id, &dprc_handle);
+ if (error < 0) {
+- dev_err(&mc_io->dev, "dprc_open() failed: %d\n", error);
++ dev_err(mc_io->dev, "dprc_open() failed: %d\n", error);
+ return error;
+ }
+
+ memset(&attr, 0, sizeof(attr));
+ error = dprc_get_attributes(mc_io, 0, dprc_handle, &attr);
+ if (error < 0) {
+- dev_err(&mc_io->dev, "dprc_get_attributes() failed: %d\n",
++ dev_err(mc_io->dev, "dprc_get_attributes() failed: %d\n",
+ error);
+ goto common_cleanup;
+ }
--- /dev/null
+From d36a6b361a3a181559daebcf32e11ab18431a854 Mon Sep 17 00:00:00 2001
+From: Cihangir Akturk <cakturk@gmail.com>
+Date: Sat, 9 Apr 2016 21:45:18 +0300
+Subject: [PATCH 164/226] staging: fsl-mc: get rid of mutex_locked variables
+
+Remove mutex_locked variables which are used to determine whether mutex is
+locked, instead add another label to unlock mutex on premature exits due to
+an error.
+
+This patch also addresses the folowing warnings reported by coccinelle:
+
+drivers/staging/fsl-mc/bus/mc-allocator.c:237:1-7: preceding lock on line 204
+drivers/staging/fsl-mc/bus/mc-allocator.c:89:1-7: preceding lock on line 57
+drivers/staging/fsl-mc/bus/mc-allocator.c:157:1-7: preceding lock on line 124
+
+Signed-off-by: Cihangir Akturk <cakturk@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-allocator.c | 61 ++++++++++++-----------------
+ 1 file changed, 24 insertions(+), 37 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
++++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
+@@ -39,7 +39,6 @@ static int __must_check fsl_mc_resource_
+ struct fsl_mc_resource *resource;
+ struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+ int error = -EINVAL;
+- bool mutex_locked = false;
+
+ if (WARN_ON(pool_type < 0 || pool_type >= FSL_MC_NUM_POOL_TYPES))
+ goto out;
+@@ -55,13 +54,12 @@ static int __must_check fsl_mc_resource_
+ goto out;
+
+ mutex_lock(&res_pool->mutex);
+- mutex_locked = true;
+
+ if (WARN_ON(res_pool->max_count < 0))
+- goto out;
++ goto out_unlock;
+ if (WARN_ON(res_pool->free_count < 0 ||
+ res_pool->free_count > res_pool->max_count))
+- goto out;
++ goto out_unlock;
+
+ resource = devm_kzalloc(&mc_bus_dev->dev, sizeof(*resource),
+ GFP_KERNEL);
+@@ -69,7 +67,7 @@ static int __must_check fsl_mc_resource_
+ error = -ENOMEM;
+ dev_err(&mc_bus_dev->dev,
+ "Failed to allocate memory for fsl_mc_resource\n");
+- goto out;
++ goto out_unlock;
+ }
+
+ resource->type = pool_type;
+@@ -82,10 +80,9 @@ static int __must_check fsl_mc_resource_
+ res_pool->free_count++;
+ res_pool->max_count++;
+ error = 0;
++out_unlock:
++ mutex_unlock(&res_pool->mutex);
+ out:
+- if (mutex_locked)
+- mutex_unlock(&res_pool->mutex);
+-
+ return error;
+ }
+
+@@ -106,7 +103,6 @@ static int __must_check fsl_mc_resource_
+ struct fsl_mc_resource_pool *res_pool;
+ struct fsl_mc_resource *resource;
+ int error = -EINVAL;
+- bool mutex_locked = false;
+
+ if (WARN_ON(!FSL_MC_IS_ALLOCATABLE(mc_dev->obj_desc.type)))
+ goto out;
+@@ -122,13 +118,12 @@ static int __must_check fsl_mc_resource_
+ goto out;
+
+ mutex_lock(&res_pool->mutex);
+- mutex_locked = true;
+
+ if (WARN_ON(res_pool->max_count <= 0))
+- goto out;
++ goto out_unlock;
+ if (WARN_ON(res_pool->free_count <= 0 ||
+ res_pool->free_count > res_pool->max_count))
+- goto out;
++ goto out_unlock;
+
+ /*
+ * If the device is currently allocated, its resource is not
+@@ -139,7 +134,7 @@ static int __must_check fsl_mc_resource_
+ dev_err(&mc_bus_dev->dev,
+ "Device %s cannot be removed from resource pool\n",
+ dev_name(&mc_dev->dev));
+- goto out;
++ goto out_unlock;
+ }
+
+ list_del(&resource->node);
+@@ -150,10 +145,9 @@ static int __must_check fsl_mc_resource_
+ devm_kfree(&mc_bus_dev->dev, resource);
+ mc_dev->resource = NULL;
+ error = 0;
++out_unlock:
++ mutex_unlock(&res_pool->mutex);
+ out:
+- if (mutex_locked)
+- mutex_unlock(&res_pool->mutex);
+-
+ return error;
+ }
+
+@@ -188,21 +182,19 @@ int __must_check fsl_mc_resource_allocat
+ struct fsl_mc_resource *resource;
+ struct fsl_mc_device *mc_bus_dev = &mc_bus->mc_dev;
+ int error = -EINVAL;
+- bool mutex_locked = false;
+
+ BUILD_BUG_ON(ARRAY_SIZE(fsl_mc_pool_type_strings) !=
+ FSL_MC_NUM_POOL_TYPES);
+
+ *new_resource = NULL;
+ if (WARN_ON(pool_type < 0 || pool_type >= FSL_MC_NUM_POOL_TYPES))
+- goto error;
++ goto out;
+
+ res_pool = &mc_bus->resource_pools[pool_type];
+ if (WARN_ON(res_pool->mc_bus != mc_bus))
+- goto error;
++ goto out;
+
+ mutex_lock(&res_pool->mutex);
+- mutex_locked = true;
+ resource = list_first_entry_or_null(&res_pool->free_list,
+ struct fsl_mc_resource, node);
+
+@@ -212,28 +204,26 @@ int __must_check fsl_mc_resource_allocat
+ dev_err(&mc_bus_dev->dev,
+ "No more resources of type %s left\n",
+ fsl_mc_pool_type_strings[pool_type]);
+- goto error;
++ goto out_unlock;
+ }
+
+ if (WARN_ON(resource->type != pool_type))
+- goto error;
++ goto out_unlock;
+ if (WARN_ON(resource->parent_pool != res_pool))
+- goto error;
++ goto out_unlock;
+ if (WARN_ON(res_pool->free_count <= 0 ||
+ res_pool->free_count > res_pool->max_count))
+- goto error;
++ goto out_unlock;
+
+ list_del(&resource->node);
+ INIT_LIST_HEAD(&resource->node);
+
+ res_pool->free_count--;
++ error = 0;
++out_unlock:
+ mutex_unlock(&res_pool->mutex);
+ *new_resource = resource;
+- return 0;
+-error:
+- if (mutex_locked)
+- mutex_unlock(&res_pool->mutex);
+-
++out:
+ return error;
+ }
+ EXPORT_SYMBOL_GPL(fsl_mc_resource_allocate);
+@@ -241,26 +231,23 @@ EXPORT_SYMBOL_GPL(fsl_mc_resource_alloca
+ void fsl_mc_resource_free(struct fsl_mc_resource *resource)
+ {
+ struct fsl_mc_resource_pool *res_pool;
+- bool mutex_locked = false;
+
+ res_pool = resource->parent_pool;
+ if (WARN_ON(resource->type != res_pool->type))
+- goto out;
++ return;
+
+ mutex_lock(&res_pool->mutex);
+- mutex_locked = true;
+ if (WARN_ON(res_pool->free_count < 0 ||
+ res_pool->free_count >= res_pool->max_count))
+- goto out;
++ goto out_unlock;
+
+ if (WARN_ON(!list_empty(&resource->node)))
+- goto out;
++ goto out_unlock;
+
+ list_add_tail(&resource->node, &res_pool->free_list);
+ res_pool->free_count++;
+-out:
+- if (mutex_locked)
+- mutex_unlock(&res_pool->mutex);
++out_unlock:
++ mutex_unlock(&res_pool->mutex);
+ }
+ EXPORT_SYMBOL_GPL(fsl_mc_resource_free);
+
--- /dev/null
+From 7b3bffea6d36f396faf1814088f03a6b8efe1ccb Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Mon, 11 Apr 2016 11:48:37 -0500
+Subject: [PATCH 165/226] staging: fsl-mc: TODO updates
+
+remove 3 of the remaining TODO items:
+
+ -multiple root fsl-mc buses-- done in patch series starting with
+ commit 14f928054a05 ("staging: fsl-mc: abstract test for existence
+ of fsl-mc bus")
+
+ -interrupt support-- done in patch series starting with
+ commit 9b1b282ccd81 ("irqdomain: Added domain bus token
+ DOMAIN_BUS_FSL_MC_MSI")
+
+ -MC command serialization-- done in commit 63f2be5c3b358 ("staging:
+ fsl-mc: Added serialization to mc_send_command()")
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Acked-by: German Rivera <german.rivera@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/TODO | 13 -------------
+ 1 file changed, 13 deletions(-)
+
+--- a/drivers/staging/fsl-mc/TODO
++++ b/drivers/staging/fsl-mc/TODO
+@@ -1,21 +1,8 @@
+-* Decide if multiple root fsl-mc buses will be supported per Linux instance,
+- and if so add support for this.
+-
+ * Add at least one device driver for a DPAA2 object (child device of the
+ fsl-mc bus). Most likely candidate for this is adding DPAA2 Ethernet
+ driver support, which depends on drivers for several objects: DPNI,
+ DPIO, DPMAC. Other pre-requisites include:
+
+- * interrupt support. for meaningful driver support we need
+- interrupts, and thus need message interrupt support by the bus
+- driver.
+- -Note: this has dependencies on generic MSI support work
+- in process upstream, see [1] and [2].
+-
+- * Management Complex (MC) command serialization. locking mechanisms
+- are needed by drivers to serialize commands sent to the MC, including
+- from atomic context.
+-
+ * MC firmware uprev. The MC firmware upon which the fsl-mc
+ bus driver and DPAA2 object drivers are based is continuing
+ to evolve, so minor updates are needed to keep in sync with binary
--- /dev/null
+From 720bf9c9a6fdff63ecc4b382a5092c0020fb7b42 Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Mon, 11 Apr 2016 11:48:42 -0500
+Subject: [PATCH 166/226] staging: fsl-mc: DPAA2 overview readme update
+
+incorporated feedback from review comments, other misc cleanup/tweaks
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Acked-by: German Rivera <german.rivera@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/README.txt | 138 +++++++++++++++++++++----------------
+ 1 file changed, 80 insertions(+), 58 deletions(-)
+
+--- a/drivers/staging/fsl-mc/README.txt
++++ b/drivers/staging/fsl-mc/README.txt
+@@ -11,11 +11,11 @@ Contents summary
+ -Overview of DPAA2 objects
+ -DPAA2 Linux driver architecture overview
+ -bus driver
+- -dprc driver
++ -DPRC driver
+ -allocator
+- -dpio driver
++ -DPIO driver
+ -Ethernet
+- -mac
++ -MAC
+
+ DPAA2 Overview
+ --------------
+@@ -37,6 +37,9 @@ interfaces, an L2 switch, or accelerator
+ The MC provides memory-mapped I/O command interfaces (MC portals)
+ which DPAA2 software drivers use to operate on DPAA2 objects:
+
++The diagram below shows an overview of the DPAA2 resource management
++architecture:
++
+ +--------------------------------------+
+ | OS |
+ | DPAA2 drivers |
+@@ -77,13 +80,13 @@ DPIO objects.
+
+ Overview of DPAA2 Objects
+ -------------------------
+-The section provides a brief overview of some key objects
+-in the DPAA2 hardware. A simple scenario is described illustrating
+-the objects involved in creating a network interfaces.
++The section provides a brief overview of some key DPAA2 objects.
++A simple scenario is described illustrating the objects involved
++in creating a network interfaces.
+
+ -DPRC (Datapath Resource Container)
+
+- A DPRC is an container object that holds all the other
++ A DPRC is a container object that holds all the other
+ types of DPAA2 objects. In the example diagram below there
+ are 8 objects of 5 types (DPMCP, DPIO, DPBP, DPNI, and DPMAC)
+ in the container.
+@@ -101,23 +104,23 @@ the objects involved in creating a netwo
+ | |
+ +---------------------------------------------------------+
+
+- From the point of view of an OS, a DPRC is bus-like. Like
+- a plug-and-play bus, such as PCI, DPRC commands can be used to
+- enumerate the contents of the DPRC, discover the hardware
+- objects present (including mappable regions and interrupts).
++ From the point of view of an OS, a DPRC behaves similar to a plug and
++ play bus, like PCI. DPRC commands can be used to enumerate the contents
++ of the DPRC, discover the hardware objects present (including mappable
++ regions and interrupts).
+
+- dprc.1 (bus)
++ DPRC.1 (bus)
+ |
+ +--+--------+-------+-------+-------+
+ | | | | |
+- dpmcp.1 dpio.1 dpbp.1 dpni.1 dpmac.1
+- dpmcp.2 dpio.2
+- dpmcp.3
++ DPMCP.1 DPIO.1 DPBP.1 DPNI.1 DPMAC.1
++ DPMCP.2 DPIO.2
++ DPMCP.3
+
+ Hardware objects can be created and destroyed dynamically, providing
+ the ability to hot plug/unplug objects in and out of the DPRC.
+
+- A DPRC has a mappable mmio region (an MC portal) that can be used
++ A DPRC has a mappable MMIO region (an MC portal) that can be used
+ to send MC commands. It has an interrupt for status events (like
+ hotplug).
+
+@@ -137,10 +140,11 @@ the objects involved in creating a netwo
+ A typical Ethernet NIC is monolithic-- the NIC device contains TX/RX
+ queuing mechanisms, configuration mechanisms, buffer management,
+ physical ports, and interrupts. DPAA2 uses a more granular approach
+- utilizing multiple hardware objects. Each object has specialized
+- functions, and are used together by software to provide Ethernet network
+- interface functionality. This approach provides efficient use of finite
+- hardware resources, flexibility, and performance advantages.
++ utilizing multiple hardware objects. Each object provides specialized
++ functions. Groups of these objects are used by software to provide
++ Ethernet network interface functionality. This approach provides
++ efficient use of finite hardware resources, flexibility, and
++ performance advantages.
+
+ The diagram below shows the objects needed for a simple
+ network interface configuration on a system with 2 CPUs.
+@@ -168,46 +172,52 @@ the objects involved in creating a netwo
+
+ Below the objects are described. For each object a brief description
+ is provided along with a summary of the kinds of operations the object
+- supports and a summary of key resources of the object (mmio regions
+- and irqs).
++ supports and a summary of key resources of the object (MMIO regions
++ and IRQs).
+
+ -DPMAC (Datapath Ethernet MAC): represents an Ethernet MAC, a
+ hardware device that connects to an Ethernet PHY and allows
+ physical transmission and reception of Ethernet frames.
+- -mmio regions: none
+- -irqs: dpni link change
++ -MMIO regions: none
++ -IRQs: DPNI link change
+ -commands: set link up/down, link config, get stats,
+- irq config, enable, reset
++ IRQ config, enable, reset
+
+ -DPNI (Datapath Network Interface): contains TX/RX queues,
+- network interface configuration, and rx buffer pool configuration
+- mechanisms.
+- -mmio regions: none
+- -irqs: link state
++ network interface configuration, and RX buffer pool configuration
++ mechanisms. The TX/RX queues are in memory and are identified by
++ queue number.
++ -MMIO regions: none
++ -IRQs: link state
+ -commands: port config, offload config, queue config,
+- parse/classify config, irq config, enable, reset
++ parse/classify config, IRQ config, enable, reset
+
+ -DPIO (Datapath I/O): provides interfaces to enqueue and dequeue
+- packets and do hardware buffer pool management operations. For
+- optimum performance there is typically DPIO per CPU. This allows
+- each CPU to perform simultaneous enqueue/dequeue operations.
+- -mmio regions: queue operations, buffer mgmt
+- -irqs: data availability, congestion notification, buffer
++ packets and do hardware buffer pool management operations. The DPAA2
++ architecture separates the mechanism to access queues (the DPIO object)
++ from the queues themselves. The DPIO provides an MMIO interface to
++ enqueue/dequeue packets. To enqueue something a descriptor is written
++ to the DPIO MMIO region, which includes the target queue number.
++ There will typically be one DPIO assigned to each CPU. This allows all
++ CPUs to simultaneously perform enqueue/dequeued operations. DPIOs are
++ expected to be shared by different DPAA2 drivers.
++ -MMIO regions: queue operations, buffer management
++ -IRQs: data availability, congestion notification, buffer
+ pool depletion
+- -commands: irq config, enable, reset
++ -commands: IRQ config, enable, reset
+
+ -DPBP (Datapath Buffer Pool): represents a hardware buffer
+ pool.
+- -mmio regions: none
+- -irqs: none
++ -MMIO regions: none
++ -IRQs: none
+ -commands: enable, reset
+
+ -DPMCP (Datapath MC Portal): provides an MC command portal.
+ Used by drivers to send commands to the MC to manage
+ objects.
+- -mmio regions: MC command portal
+- -irqs: command completion
+- -commands: irq config, enable, reset
++ -MMIO regions: MC command portal
++ -IRQs: command completion
++ -commands: IRQ config, enable, reset
+
+ Object Connections
+ ------------------
+@@ -268,22 +278,22 @@ of each driver follows.
+ | Stack |
+ +------------+ +------------+
+ | Allocator |. . . . . . . | Ethernet |
+- |(dpmcp,dpbp)| | (dpni) |
++ |(DPMCP,DPBP)| | (DPNI) |
+ +-.----------+ +---+---+----+
+ . . ^ |
+ . . <data avail, | |<enqueue,
+ . . tx confirm> | | dequeue>
+ +-------------+ . | |
+ | DPRC driver | . +---+---V----+ +---------+
+- | (dprc) | . . . . . .| DPIO driver| | MAC |
+- +----------+--+ | (dpio) | | (dpmac) |
++ | (DPRC) | . . . . . .| DPIO driver| | MAC |
++ +----------+--+ | (DPIO) | | (DPMAC) |
+ | +------+-----+ +-----+---+
+ |<dev add/remove> | |
+ | | |
+ +----+--------------+ | +--+---+
+- | mc-bus driver | | | PHY |
++ | MC-bus driver | | | PHY |
+ | | | |driver|
+- | /fsl-mc@80c000000 | | +--+---+
++ | /soc/fsl-mc | | +--+---+
+ +-------------------+ | |
+ | |
+ ================================ HARDWARE =========|=================|======
+@@ -298,25 +308,27 @@ of each driver follows.
+
+ A brief description of each driver is provided below.
+
+- mc-bus driver
++ MC-bus driver
+ -------------
+- The mc-bus driver is a platform driver and is probed from an
+- "/fsl-mc@xxxx" node in the device tree passed in by boot firmware.
+- It is responsible for bootstrapping the DPAA2 kernel infrastructure.
++ The MC-bus driver is a platform driver and is probed from a
++ node in the device tree (compatible "fsl,qoriq-mc") passed in by boot
++ firmware. It is responsible for bootstrapping the DPAA2 kernel
++ infrastructure.
+ Key functions include:
+ -registering a new bus type named "fsl-mc" with the kernel,
+ and implementing bus call-backs (e.g. match/uevent/dev_groups)
+- -implemeting APIs for DPAA2 driver registration and for device
++ -implementing APIs for DPAA2 driver registration and for device
+ add/remove
+- -creates an MSI irq domain
+- -do a device add of the 'root' DPRC device, which is needed
+- to bootstrap things
++ -creates an MSI IRQ domain
++ -doing a 'device add' to expose the 'root' DPRC, in turn triggering
++ a bind of the root DPRC to the DPRC driver
+
+ DPRC driver
+ -----------
+- The dprc-driver is bound DPRC objects and does runtime management
++ The DPRC driver is bound to DPRC objects and does runtime management
+ of a bus instance. It performs the initial bus scan of the DPRC
+- and handles interrupts for container events such as hot plug.
++ and handles interrupts for container events such as hot plug by
++ re-scanning the DPRC.
+
+ Allocator
+ ----------
+@@ -334,14 +346,20 @@ A brief description of each driver is pr
+ DPIO driver
+ -----------
+ The DPIO driver is bound to DPIO objects and provides services that allow
+- other drivers such as the Ethernet driver to receive and transmit data.
++ other drivers such as the Ethernet driver to enqueue and dequeue data for
++ their respective objects.
+ Key services include:
+ -data availability notifications
+ -hardware queuing operations (enqueue and dequeue of data)
+ -hardware buffer pool management
+
++ To transmit a packet the Ethernet driver puts data on a queue and
++ invokes a DPIO API. For receive, the Ethernet driver registers
++ a data availability notification callback. To dequeue a packet
++ a DPIO API is used.
++
+ There is typically one DPIO object per physical CPU for optimum
+- performance, allowing each CPU to simultaneously enqueue
++ performance, allowing different CPUs to simultaneously enqueue
+ and dequeue data.
+
+ The DPIO driver operates on behalf of all DPAA2 drivers
+@@ -362,3 +380,7 @@ A brief description of each driver is pr
+ by the appropriate PHY driver via an mdio bus. The MAC driver
+ plays a role of being a proxy between the PHY driver and the
+ MC. It does this proxy via the MC commands to a DPMAC object.
++ If the PHY driver signals a link change, the MAC driver notifies
++ the MC via a DPMAC command. If a network interface is brought
++ up or down, the MC notifies the DPMAC driver via an interrupt and
++ the driver can take appropriate action.
--- /dev/null
+From fa245614c92ffbdaec6a56552032432b5343b1dc Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Mon, 11 Apr 2016 11:48:48 -0500
+Subject: [PATCH 167/226] staging: fsl-mc: update dpmcp binary interface to
+ v3.0
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Acked-by: German Rivera <german.rivera@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dpmcp-cmd.h | 5 ++---
+ drivers/staging/fsl-mc/bus/dpmcp.c | 35 ++------------------------------
+ drivers/staging/fsl-mc/bus/dpmcp.h | 10 ++-------
+ 3 files changed, 6 insertions(+), 44 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h
++++ b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h
+@@ -33,8 +33,8 @@
+ #define _FSL_DPMCP_CMD_H
+
+ /* DPMCP Version */
+-#define DPMCP_VER_MAJOR 2
+-#define DPMCP_VER_MINOR 1
++#define DPMCP_VER_MAJOR 3
++#define DPMCP_VER_MINOR 0
+
+ /* Command IDs */
+ #define DPMCP_CMDID_CLOSE 0x800
+@@ -52,6 +52,5 @@
+ #define DPMCP_CMDID_SET_IRQ_MASK 0x014
+ #define DPMCP_CMDID_GET_IRQ_MASK 0x015
+ #define DPMCP_CMDID_GET_IRQ_STATUS 0x016
+-#define DPMCP_CMDID_CLEAR_IRQ_STATUS 0x017
+
+ #endif /* _FSL_DPMCP_CMD_H */
+--- a/drivers/staging/fsl-mc/bus/dpmcp.c
++++ b/drivers/staging/fsl-mc/bus/dpmcp.c
+@@ -213,7 +213,7 @@ int dpmcp_set_irq(struct fsl_mc_io *mc_i
+ cmd.params[0] |= mc_enc(0, 8, irq_index);
+ cmd.params[0] |= mc_enc(32, 32, irq_cfg->val);
+ cmd.params[1] |= mc_enc(0, 64, irq_cfg->paddr);
+- cmd.params[2] |= mc_enc(0, 32, irq_cfg->user_irq_id);
++ cmd.params[2] |= mc_enc(0, 32, irq_cfg->irq_num);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+@@ -254,7 +254,7 @@ int dpmcp_get_irq(struct fsl_mc_io *mc_i
+ /* retrieve response parameters */
+ irq_cfg->val = (u32)mc_dec(cmd.params[0], 0, 32);
+ irq_cfg->paddr = (u64)mc_dec(cmd.params[1], 0, 64);
+- irq_cfg->user_irq_id = (int)mc_dec(cmd.params[2], 0, 32);
++ irq_cfg->irq_num = (int)mc_dec(cmd.params[2], 0, 32);
+ *type = (int)mc_dec(cmd.params[2], 32, 32);
+ return 0;
+ }
+@@ -435,37 +435,6 @@ int dpmcp_get_irq_status(struct fsl_mc_i
+ }
+
+ /**
+- * dpmcp_clear_irq_status() - Clear a pending interrupt's status
+- *
+- * @mc_io: Pointer to MC portal's I/O object
+- * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
+- * @token: Token of DPMCP object
+- * @irq_index: The interrupt index to configure
+- * @status: Bits to clear (W1C) - one bit per cause:
+- * 0 = don't change
+- * 1 = clear status bit
+- *
+- * Return: '0' on Success; Error code otherwise.
+- */
+-int dpmcp_clear_irq_status(struct fsl_mc_io *mc_io,
+- u32 cmd_flags,
+- u16 token,
+- u8 irq_index,
+- u32 status)
+-{
+- struct mc_command cmd = { 0 };
+-
+- /* prepare command */
+- cmd.header = mc_encode_cmd_header(DPMCP_CMDID_CLEAR_IRQ_STATUS,
+- cmd_flags, token);
+- cmd.params[0] |= mc_enc(0, 32, status);
+- cmd.params[0] |= mc_enc(32, 8, irq_index);
+-
+- /* send command to mc*/
+- return mc_send_command(mc_io, &cmd);
+-}
+-
+-/**
+ * dpmcp_get_attributes - Retrieve DPMCP attributes.
+ *
+ * @mc_io: Pointer to MC portal's I/O object
+--- a/drivers/staging/fsl-mc/bus/dpmcp.h
++++ b/drivers/staging/fsl-mc/bus/dpmcp.h
+@@ -82,12 +82,12 @@ int dpmcp_reset(struct fsl_mc_io *mc_io,
+ * struct dpmcp_irq_cfg - IRQ configuration
+ * @paddr: Address that must be written to signal a message-based interrupt
+ * @val: Value to write into irq_addr address
+- * @user_irq_id: A user defined number associated with this IRQ
++ * @irq_num: A user defined number associated with this IRQ
+ */
+ struct dpmcp_irq_cfg {
+ uint64_t paddr;
+ uint32_t val;
+- int user_irq_id;
++ int irq_num;
+ };
+
+ int dpmcp_set_irq(struct fsl_mc_io *mc_io,
+@@ -133,12 +133,6 @@ int dpmcp_get_irq_status(struct fsl_mc_i
+ uint8_t irq_index,
+ uint32_t *status);
+
+-int dpmcp_clear_irq_status(struct fsl_mc_io *mc_io,
+- uint32_t cmd_flags,
+- uint16_t token,
+- uint8_t irq_index,
+- uint32_t status);
+-
+ /**
+ * struct dpmcp_attr - Structure representing DPMCP attributes
+ * @id: DPMCP object ID
--- /dev/null
+From de0fa9842d52e4e80576d378f32aa9ca76a4270b Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Mon, 11 Apr 2016 11:48:54 -0500
+Subject: [PATCH 168/226] staging: fsl-mc: update dpbp binary interface to
+ v2.2
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Acked-by: German Rivera <german.rivera@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dpbp.c | 77 ++++++++++++++++++++++++++++-
+ drivers/staging/fsl-mc/include/dpbp-cmd.h | 4 +-
+ drivers/staging/fsl-mc/include/dpbp.h | 51 ++++++++++++++++++-
+ 3 files changed, 127 insertions(+), 5 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dpbp.c
++++ b/drivers/staging/fsl-mc/bus/dpbp.c
+@@ -293,7 +293,7 @@ int dpbp_set_irq(struct fsl_mc_io *mc_io
+ cmd.params[0] |= mc_enc(0, 8, irq_index);
+ cmd.params[0] |= mc_enc(32, 32, irq_cfg->val);
+ cmd.params[1] |= mc_enc(0, 64, irq_cfg->addr);
+- cmd.params[2] |= mc_enc(0, 32, irq_cfg->user_irq_id);
++ cmd.params[2] |= mc_enc(0, 32, irq_cfg->irq_num);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+@@ -334,7 +334,7 @@ int dpbp_get_irq(struct fsl_mc_io *mc_io
+ /* retrieve response parameters */
+ irq_cfg->val = (u32)mc_dec(cmd.params[0], 0, 32);
+ irq_cfg->addr = (u64)mc_dec(cmd.params[1], 0, 64);
+- irq_cfg->user_irq_id = (int)mc_dec(cmd.params[2], 0, 32);
++ irq_cfg->irq_num = (int)mc_dec(cmd.params[2], 0, 32);
+ *type = (int)mc_dec(cmd.params[2], 32, 32);
+ return 0;
+ }
+@@ -502,6 +502,7 @@ int dpbp_get_irq_status(struct fsl_mc_io
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_IRQ_STATUS,
+ cmd_flags, token);
++ cmd.params[0] |= mc_enc(0, 32, *status);
+ cmd.params[0] |= mc_enc(32, 8, irq_index);
+
+ /* send command to mc*/
+@@ -580,3 +581,75 @@ int dpbp_get_attributes(struct fsl_mc_io
+ return 0;
+ }
+ EXPORT_SYMBOL(dpbp_get_attributes);
++
++/**
++ * dpbp_set_notifications() - Set notifications towards software
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPBP object
++ * @cfg: notifications configuration
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpbp_set_notifications(struct fsl_mc_io *mc_io,
++ u32 cmd_flags,
++ u16 token,
++ struct dpbp_notification_cfg *cfg)
++{
++ struct mc_command cmd = { 0 };
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPBP_CMDID_SET_NOTIFICATIONS,
++ cmd_flags,
++ token);
++
++ cmd.params[0] |= mc_enc(0, 32, cfg->depletion_entry);
++ cmd.params[0] |= mc_enc(32, 32, cfg->depletion_exit);
++ cmd.params[1] |= mc_enc(0, 32, cfg->surplus_entry);
++ cmd.params[1] |= mc_enc(32, 32, cfg->surplus_exit);
++ cmd.params[2] |= mc_enc(0, 16, cfg->options);
++ cmd.params[3] |= mc_enc(0, 64, cfg->message_ctx);
++ cmd.params[4] |= mc_enc(0, 64, cfg->message_iova);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++
++/**
++ * dpbp_get_notifications() - Get the notifications configuration
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPBP object
++ * @cfg: notifications configuration
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpbp_get_notifications(struct fsl_mc_io *mc_io,
++ u32 cmd_flags,
++ u16 token,
++ struct dpbp_notification_cfg *cfg)
++{
++ struct mc_command cmd = { 0 };
++ int err;
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPBP_CMDID_GET_NOTIFICATIONS,
++ cmd_flags,
++ token);
++
++ /* send command to mc*/
++ err = mc_send_command(mc_io, &cmd);
++ if (err)
++ return err;
++
++ /* retrieve response parameters */
++ cfg->depletion_entry = (u32)mc_dec(cmd.params[0], 0, 32);
++ cfg->depletion_exit = (u32)mc_dec(cmd.params[0], 32, 32);
++ cfg->surplus_entry = (u32)mc_dec(cmd.params[1], 0, 32);
++ cfg->surplus_exit = (u32)mc_dec(cmd.params[1], 32, 32);
++ cfg->options = (u16)mc_dec(cmd.params[2], 0, 16);
++ cfg->message_ctx = (u64)mc_dec(cmd.params[3], 0, 64);
++ cfg->message_iova = (u64)mc_dec(cmd.params[4], 0, 64);
++
++ return 0;
++}
+--- a/drivers/staging/fsl-mc/include/dpbp-cmd.h
++++ b/drivers/staging/fsl-mc/include/dpbp-cmd.h
+@@ -34,7 +34,7 @@
+
+ /* DPBP Version */
+ #define DPBP_VER_MAJOR 2
+-#define DPBP_VER_MINOR 1
++#define DPBP_VER_MINOR 2
+
+ /* Command IDs */
+ #define DPBP_CMDID_CLOSE 0x800
+@@ -57,4 +57,6 @@
+ #define DPBP_CMDID_GET_IRQ_STATUS 0x016
+ #define DPBP_CMDID_CLEAR_IRQ_STATUS 0x017
+
++#define DPBP_CMDID_SET_NOTIFICATIONS 0x01b0
++#define DPBP_CMDID_GET_NOTIFICATIONS 0x01b1
+ #endif /* _FSL_DPBP_CMD_H */
+--- a/drivers/staging/fsl-mc/include/dpbp.h
++++ b/drivers/staging/fsl-mc/include/dpbp.h
+@@ -85,12 +85,12 @@ int dpbp_reset(struct fsl_mc_io *mc_io,
+ * struct dpbp_irq_cfg - IRQ configuration
+ * @addr: Address that must be written to signal a message-based interrupt
+ * @val: Value to write into irq_addr address
+- * @user_irq_id: A user defined number associated with this IRQ
++ * @irq_num: A user defined number associated with this IRQ
+ */
+ struct dpbp_irq_cfg {
+ u64 addr;
+ u32 val;
+- int user_irq_id;
++ int irq_num;
+ };
+
+ int dpbp_set_irq(struct fsl_mc_io *mc_io,
+@@ -168,6 +168,53 @@ int dpbp_get_attributes(struct fsl_mc_io
+ u16 token,
+ struct dpbp_attr *attr);
+
++/**
++ * DPBP notifications options
++ */
++
++/**
++ * BPSCN write will attempt to allocate into a cache (coherent write)
++ */
++#define DPBP_NOTIF_OPT_COHERENT_WRITE 0x00000001
++
++/**
++ * struct dpbp_notification_cfg - Structure representing DPBP notifications
++ * towards software
++ * @depletion_entry: below this threshold the pool is "depleted";
++ * set it to '0' to disable it
++ * @depletion_exit: greater than or equal to this threshold the pool exit its
++ * "depleted" state
++ * @surplus_entry: above this threshold the pool is in "surplus" state;
++ * set it to '0' to disable it
++ * @surplus_exit: less than or equal to this threshold the pool exit its
++ * "surplus" state
++ * @message_iova: MUST be given if either 'depletion_entry' or 'surplus_entry'
++ * is not '0' (enable); I/O virtual address (must be in DMA-able memory),
++ * must be 16B aligned.
++ * @message_ctx: The context that will be part of the BPSCN message and will
++ * be written to 'message_iova'
++ * @options: Mask of available options; use 'DPBP_NOTIF_OPT_<X>' values
++ */
++struct dpbp_notification_cfg {
++ u32 depletion_entry;
++ u32 depletion_exit;
++ u32 surplus_entry;
++ u32 surplus_exit;
++ u64 message_iova;
++ u64 message_ctx;
++ u16 options;
++};
++
++int dpbp_set_notifications(struct fsl_mc_io *mc_io,
++ u32 cmd_flags,
++ u16 token,
++ struct dpbp_notification_cfg *cfg);
++
++int dpbp_get_notifications(struct fsl_mc_io *mc_io,
++ u32 cmd_flags,
++ u16 token,
++ struct dpbp_notification_cfg *cfg);
++
+ /** @} */
+
+ #endif /* __FSL_DPBP_H */
--- /dev/null
+From 45dce4cd82ddc618ade56747620a2a29f7d9a99d Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Mon, 11 Apr 2016 11:48:59 -0500
+Subject: [PATCH 169/226] staging: fsl-mc: update dprc binary interface to
+ v5.1
+
+The meaning of the "status" parameter in dprc_get_irq_status
+has changed, and this patch updates the flib and caller
+of the API.
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Acked-by: German Rivera <german.rivera@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-cmd.h | 4 ++--
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 1 +
+ drivers/staging/fsl-mc/bus/dprc.c | 26 +++++++++++++-------------
+ drivers/staging/fsl-mc/bus/mc-msi.c | 2 +-
+ drivers/staging/fsl-mc/include/dprc.h | 19 ++++++++++++-------
+ 5 files changed, 29 insertions(+), 23 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-cmd.h
++++ b/drivers/staging/fsl-mc/bus/dprc-cmd.h
+@@ -41,8 +41,8 @@
+ #define _FSL_DPRC_CMD_H
+
+ /* DPRC Version */
+-#define DPRC_VER_MAJOR 4
+-#define DPRC_VER_MINOR 0
++#define DPRC_VER_MAJOR 5
++#define DPRC_VER_MINOR 1
+
+ /* Command IDs */
+ #define DPRC_CMDID_CLOSE 0x800
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -423,6 +423,7 @@ static irqreturn_t dprc_irq0_handler_thr
+ if (WARN_ON(!msi_desc || msi_desc->irq != (u32)irq_num))
+ goto out;
+
++ status = 0;
+ error = dprc_get_irq_status(mc_io, 0, mc_dev->mc_handle, 0,
+ &status);
+ if (error < 0) {
+--- a/drivers/staging/fsl-mc/bus/dprc.c
++++ b/drivers/staging/fsl-mc/bus/dprc.c
+@@ -265,7 +265,7 @@ int dprc_get_irq(struct fsl_mc_io *mc_io
+ /* retrieve response parameters */
+ irq_cfg->val = mc_dec(cmd.params[0], 0, 32);
+ irq_cfg->paddr = mc_dec(cmd.params[1], 0, 64);
+- irq_cfg->user_irq_id = mc_dec(cmd.params[2], 0, 32);
++ irq_cfg->irq_num = mc_dec(cmd.params[2], 0, 32);
+ *type = mc_dec(cmd.params[2], 32, 32);
+
+ return 0;
+@@ -296,7 +296,7 @@ int dprc_set_irq(struct fsl_mc_io *mc_io
+ cmd.params[0] |= mc_enc(32, 8, irq_index);
+ cmd.params[0] |= mc_enc(0, 32, irq_cfg->val);
+ cmd.params[1] |= mc_enc(0, 64, irq_cfg->paddr);
+- cmd.params[2] |= mc_enc(0, 32, irq_cfg->user_irq_id);
++ cmd.params[2] |= mc_enc(0, 32, irq_cfg->irq_num);
+
+ /* send command to mc*/
+ return mc_send_command(mc_io, &cmd);
+@@ -466,6 +466,7 @@ int dprc_get_irq_status(struct fsl_mc_io
+ /* prepare command */
+ cmd.header = mc_encode_cmd_header(DPRC_CMDID_GET_IRQ_STATUS,
+ cmd_flags, token);
++ cmd.params[0] |= mc_enc(0, 32, *status);
+ cmd.params[0] |= mc_enc(32, 8, irq_index);
+
+ /* send command to mc*/
+@@ -948,6 +949,7 @@ int dprc_get_obj(struct fsl_mc_io *mc_io
+ obj_desc->state = mc_dec(cmd.params[1], 32, 32);
+ obj_desc->ver_major = mc_dec(cmd.params[2], 0, 16);
+ obj_desc->ver_minor = mc_dec(cmd.params[2], 16, 16);
++ obj_desc->flags = mc_dec(cmd.params[2], 32, 16);
+ obj_desc->type[0] = mc_dec(cmd.params[3], 0, 8);
+ obj_desc->type[1] = mc_dec(cmd.params[3], 8, 8);
+ obj_desc->type[2] = mc_dec(cmd.params[3], 16, 8);
+@@ -1042,6 +1044,7 @@ int dprc_get_obj_desc(struct fsl_mc_io *
+ obj_desc->state = (u32)mc_dec(cmd.params[1], 32, 32);
+ obj_desc->ver_major = (u16)mc_dec(cmd.params[2], 0, 16);
+ obj_desc->ver_minor = (u16)mc_dec(cmd.params[2], 16, 16);
++ obj_desc->flags = mc_dec(cmd.params[2], 32, 16);
+ obj_desc->type[0] = (char)mc_dec(cmd.params[3], 0, 8);
+ obj_desc->type[1] = (char)mc_dec(cmd.params[3], 8, 8);
+ obj_desc->type[2] = (char)mc_dec(cmd.params[3], 16, 8);
+@@ -1108,7 +1111,7 @@ int dprc_set_obj_irq(struct fsl_mc_io *m
+ cmd.params[0] |= mc_enc(32, 8, irq_index);
+ cmd.params[0] |= mc_enc(0, 32, irq_cfg->val);
+ cmd.params[1] |= mc_enc(0, 64, irq_cfg->paddr);
+- cmd.params[2] |= mc_enc(0, 32, irq_cfg->user_irq_id);
++ cmd.params[2] |= mc_enc(0, 32, irq_cfg->irq_num);
+ cmd.params[2] |= mc_enc(32, 32, obj_id);
+ cmd.params[3] |= mc_enc(0, 8, obj_type[0]);
+ cmd.params[3] |= mc_enc(8, 8, obj_type[1]);
+@@ -1189,7 +1192,7 @@ int dprc_get_obj_irq(struct fsl_mc_io *m
+ /* retrieve response parameters */
+ irq_cfg->val = (u32)mc_dec(cmd.params[0], 0, 32);
+ irq_cfg->paddr = (u64)mc_dec(cmd.params[1], 0, 64);
+- irq_cfg->user_irq_id = (int)mc_dec(cmd.params[2], 0, 32);
++ irq_cfg->irq_num = (int)mc_dec(cmd.params[2], 0, 32);
+ *type = (int)mc_dec(cmd.params[2], 32, 32);
+
+ return 0;
+@@ -1437,14 +1440,8 @@ EXPORT_SYMBOL(dprc_set_obj_label);
+ * @endpoint1: Endpoint 1 configuration parameters
+ * @endpoint2: Endpoint 2 configuration parameters
+ * @cfg: Connection configuration. The connection configuration is ignored for
+- * connections made to DPMAC objects, where rate is set according to
+- * MAC configuration.
+- * The committed rate is the guaranteed rate for the connection.
+- * The maximum rate is an upper limit allowed for the connection; it is
+- * expected to be equal or higher than the committed rate.
+- * When committed and maximum rates are both zero, the connection is set
+- * to "best effort" mode, having lower priority compared to connections
+- * with committed or maximum rates.
++ * connections made to DPMAC objects, where rate is retrieved from the
++ * MAC configuration.
+ *
+ * Return: '0' on Success; Error code otherwise.
+ */
+@@ -1555,7 +1552,10 @@ int dprc_disconnect(struct fsl_mc_io *mc
+ * @token: Token of DPRC object
+ * @endpoint1: Endpoint 1 configuration parameters
+ * @endpoint2: Returned endpoint 2 configuration parameters
+-* @state: Returned link state: 1 - link is up, 0 - link is down
++* @state: Returned link state:
++* 1 - link is up;
++* 0 - link is down;
++* -1 - no connection (endpoint2 information is irrelevant)
+ *
+ * Return: '0' on Success; -ENAVAIL if connection does not exist.
+ */
+--- a/drivers/staging/fsl-mc/bus/mc-msi.c
++++ b/drivers/staging/fsl-mc/bus/mc-msi.c
+@@ -65,7 +65,7 @@ static void __fsl_mc_msi_write_msg(struc
+ irq_cfg.paddr = ((u64)msi_desc->msg.address_hi << 32) |
+ msi_desc->msg.address_lo;
+ irq_cfg.val = msi_desc->msg.data;
+- irq_cfg.user_irq_id = msi_desc->irq;
++ irq_cfg.irq_num = msi_desc->irq;
+
+ if (owner_mc_dev == mc_bus_dev) {
+ /*
+--- a/drivers/staging/fsl-mc/include/dprc.h
++++ b/drivers/staging/fsl-mc/include/dprc.h
+@@ -94,11 +94,6 @@ int dprc_close(struct fsl_mc_io *mc_io,
+ */
+ #define DPRC_CFG_OPT_TOPOLOGY_CHANGES_ALLOWED 0x00000008
+
+-/* IOMMU bypass - indicates whether objects of this container are permitted
+- * to bypass the IOMMU.
+- */
+-#define DPRC_CFG_OPT_IOMMU_BYPASS 0x00000010
+-
+ /* AIOP - Indicates that container belongs to AIOP. */
+ #define DPRC_CFG_OPT_AIOP 0x00000020
+
+@@ -173,12 +168,12 @@ int dprc_reset_container(struct fsl_mc_i
+ * struct dprc_irq_cfg - IRQ configuration
+ * @paddr: Address that must be written to signal a message-based interrupt
+ * @val: Value to write into irq_addr address
+- * @user_irq_id: A user defined number associated with this IRQ
++ * @irq_num: A user defined number associated with this IRQ
+ */
+ struct dprc_irq_cfg {
+ phys_addr_t paddr;
+ u32 val;
+- int user_irq_id;
++ int irq_num;
+ };
+
+ int dprc_set_irq(struct fsl_mc_io *mc_io,
+@@ -353,6 +348,14 @@ int dprc_get_obj_count(struct fsl_mc_io
+ #define DPRC_OBJ_STATE_PLUGGED 0x00000002
+
+ /**
++ * Shareability flag - Object flag indicating no memory shareability.
++ * the object generates memory accesses that are non coherent with other
++ * masters;
++ * user is responsible for proper memory handling through IOMMU configuration.
++ */
++#define DPRC_OBJ_FLAG_NO_MEM_SHAREABILITY 0x0001
++
++/**
+ * struct dprc_obj_desc - Object descriptor, returned from dprc_get_obj()
+ * @type: Type of object: NULL terminated string
+ * @id: ID of logical object resource
+@@ -363,6 +366,7 @@ int dprc_get_obj_count(struct fsl_mc_io
+ * @region_count: Number of mappable regions supported by the object
+ * @state: Object state: combination of DPRC_OBJ_STATE_ states
+ * @label: Object label
++ * @flags: Object's flags
+ */
+ struct dprc_obj_desc {
+ char type[16];
+@@ -374,6 +378,7 @@ struct dprc_obj_desc {
+ u8 region_count;
+ u32 state;
+ char label[16];
++ u16 flags;
+ };
+
+ int dprc_get_obj(struct fsl_mc_io *mc_io,
--- /dev/null
+From 9382e1723e4de9832407f7e65bd4812b31e5a51d Mon Sep 17 00:00:00 2001
+From: Itai Katz <itai.katz@nxp.com>
+Date: Mon, 11 Apr 2016 11:55:40 -0500
+Subject: [PATCH 170/226] staging: fsl-mc: don't use object versions to make
+ binding decisions
+
+Up until now if the object version expected by a driver (in the API header
+file) did not match the actual object version in the MC hardware the bus
+driver refused to bind the object to the driver or printed out WARN_ON
+dumps.
+
+This patch removes those checks, and the responsibility of object version
+checking should now be done in the object drivers themselves. If the actual
+version discovered is not supported, the driver's probe function should fail.
+Drivers should use version checks to support new features and provide
+backwards compatibility if at all possible.
+
+This patch also removes the checks that caused bus driver probing to fail
+if the overall MC version discovered did not match the firmware version
+from the API header...this was too strict. The overall MC version is
+informational like a release number, and continues to be printed in the
+boot log.
+
+Signed-off-by: Itai Katz <itai.katz@nxp.com>
+(Stuart: reworded commit log)
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Acked-by: German Rivera <german.rivera@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 4 +--
+ drivers/staging/fsl-mc/bus/mc-allocator.c | 6 -----
+ drivers/staging/fsl-mc/bus/mc-bus.c | 38 +----------------------------
+ 3 files changed, 2 insertions(+), 46 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -780,9 +780,7 @@ static int dprc_remove(struct fsl_mc_dev
+ static const struct fsl_mc_device_match_id match_id_table[] = {
+ {
+ .vendor = FSL_MC_VENDOR_FREESCALE,
+- .obj_type = "dprc",
+- .ver_major = DPRC_VER_MAJOR,
+- .ver_minor = DPRC_VER_MINOR},
++ .obj_type = "dprc"},
+ {.vendor = 0x0},
+ };
+
+--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
++++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
+@@ -709,20 +709,14 @@ static const struct fsl_mc_device_match_
+ {
+ .vendor = FSL_MC_VENDOR_FREESCALE,
+ .obj_type = "dpbp",
+- .ver_major = DPBP_VER_MAJOR,
+- .ver_minor = DPBP_VER_MINOR
+ },
+ {
+ .vendor = FSL_MC_VENDOR_FREESCALE,
+ .obj_type = "dpmcp",
+- .ver_major = DPMCP_VER_MAJOR,
+- .ver_minor = DPMCP_VER_MINOR
+ },
+ {
+ .vendor = FSL_MC_VENDOR_FREESCALE,
+ .obj_type = "dpcon",
+- .ver_major = DPCON_VER_MAJOR,
+- .ver_minor = DPCON_VER_MINOR
+ },
+ {.vendor = 0x0},
+ };
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -40,8 +40,6 @@ static int fsl_mc_bus_match(struct devic
+ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+ struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
+ bool found = false;
+- bool major_version_mismatch = false;
+- bool minor_version_mismatch = false;
+
+ if (WARN_ON(!fsl_mc_bus_exists()))
+ goto out;
+@@ -64,32 +62,12 @@ static int fsl_mc_bus_match(struct devic
+ for (id = mc_drv->match_id_table; id->vendor != 0x0; id++) {
+ if (id->vendor == mc_dev->obj_desc.vendor &&
+ strcmp(id->obj_type, mc_dev->obj_desc.type) == 0) {
+- if (id->ver_major == mc_dev->obj_desc.ver_major) {
+- found = true;
+- if (id->ver_minor != mc_dev->obj_desc.ver_minor)
+- minor_version_mismatch = true;
+- } else {
+- major_version_mismatch = true;
+- }
++ found = true;
+
+ break;
+ }
+ }
+
+- if (major_version_mismatch) {
+- dev_warn(dev,
+- "Major version mismatch: driver version %u.%u, MC object version %u.%u\n",
+- id->ver_major, id->ver_minor,
+- mc_dev->obj_desc.ver_major,
+- mc_dev->obj_desc.ver_minor);
+- } else if (minor_version_mismatch) {
+- dev_warn(dev,
+- "Minor version mismatch: driver version %u.%u, MC object version %u.%u\n",
+- id->ver_major, id->ver_minor,
+- mc_dev->obj_desc.ver_major,
+- mc_dev->obj_desc.ver_minor);
+- }
+-
+ out:
+ dev_dbg(dev, "%smatched\n", found ? "" : "not ");
+ return found;
+@@ -722,20 +700,6 @@ static int fsl_mc_bus_probe(struct platf
+ "Freescale Management Complex Firmware version: %u.%u.%u\n",
+ mc_version.major, mc_version.minor, mc_version.revision);
+
+- if (mc_version.major < MC_VER_MAJOR) {
+- dev_err(&pdev->dev,
+- "ERROR: MC firmware version not supported by driver (driver version: %u.%u)\n",
+- MC_VER_MAJOR, MC_VER_MINOR);
+- error = -ENOTSUPP;
+- goto error_cleanup_mc_io;
+- }
+-
+- if (mc_version.major > MC_VER_MAJOR) {
+- dev_warn(&pdev->dev,
+- "WARNING: driver may not support newer MC firmware features (driver version: %u.%u)\n",
+- MC_VER_MAJOR, MC_VER_MINOR);
+- }
+-
+ error = get_mc_addr_translation_ranges(&pdev->dev,
+ &mc->translation_ranges,
+ &mc->num_translation_ranges);
--- /dev/null
+From 3657147d6fea1977c07373325626bf50fe15bcfc Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Mon, 11 Apr 2016 11:49:13 -0500
+Subject: [PATCH 171/226] staging: fsl-mc: set up coherent dma ops for added
+ devices
+
+Unless discovered devices have the no shareability flag set,
+set up coherent dma ops for them.
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Acked-by: German Rivera <german.rivera@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -469,6 +469,10 @@ int fsl_mc_device_add(struct dprc_obj_de
+ goto error_cleanup_dev;
+ }
+
++ /* Objects are coherent, unless 'no shareability' flag set. */
++ if (!(obj_desc->flags & DPRC_OBJ_FLAG_NO_MEM_SHAREABILITY))
++ arch_setup_dma_ops(&mc_dev->dev, 0, 0, NULL, true);
++
+ /*
+ * The device-specific probe callback will get invoked by device_add()
+ */
--- /dev/null
+From f7011c18a26d40a07b837a79d0efdad795ad7250 Mon Sep 17 00:00:00 2001
+From: Itai Katz <itai.katz@nxp.com>
+Date: Mon, 11 Apr 2016 11:55:48 -0500
+Subject: [PATCH 172/226] staging: fsl-mc: set cacheable flag for added
+ devices if applicable
+
+Some DPAA2 devices have mmio regions that should be mapped as
+cacheable by drivers. Set IORESOURCE_CACHEABLE in the region's
+flags if applicable.
+
+Signed-off-by: Itai Katz <itai.katz@nxp.com>
+[Stuart: update subject and commit message]
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Acked-by: German Rivera <german.rivera@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -354,6 +354,8 @@ static int fsl_mc_device_get_mmio_region
+ regions[i].end = regions[i].start + region_desc.size - 1;
+ regions[i].name = "fsl-mc object MMIO region";
+ regions[i].flags = IORESOURCE_IO;
++ if (region_desc.flags & DPRC_REGION_CACHEABLE)
++ regions[i].flags |= IORESOURCE_CACHEABLE;
+ }
+
+ mc_dev->regions = regions;
--- /dev/null
+From 2df13a365ecda7e3321cf9d4e1a9ebd63e58c28b Mon Sep 17 00:00:00 2001
+From: Itai Katz <itai.katz@nxp.com>
+Date: Mon, 11 Apr 2016 11:55:55 -0500
+Subject: [PATCH 173/226] staging: fsl-mc: get version of root dprc from MC
+ hardware
+
+The root dprc is discovered as a platform device in the device tree. The
+version of that dprc was previously set using hardcoded values from the API
+header in the kernel). This patch removes the use of the hardcoded version
+numbers and instead reads the actual dprc version from the hardware.
+
+Signed-off-by: Itai Katz <itai.katz@nxp.com>
+(Stuart: resolved merge conflict, updated commit subject/log)
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Acked-by: German Rivera <german.rivera@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 45 ++++++++++++++++++++++++++++-------
+ 1 file changed, 37 insertions(+), 8 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -229,11 +229,10 @@ static bool fsl_mc_is_root_dprc(struct d
+ return dev == root_dprc_dev;
+ }
+
+-static int get_dprc_icid(struct fsl_mc_io *mc_io,
+- int container_id, u16 *icid)
++static int get_dprc_attr(struct fsl_mc_io *mc_io,
++ int container_id, struct dprc_attributes *attr)
+ {
+ u16 dprc_handle;
+- struct dprc_attributes attr;
+ int error;
+
+ error = dprc_open(mc_io, 0, container_id, &dprc_handle);
+@@ -242,15 +241,14 @@ static int get_dprc_icid(struct fsl_mc_i
+ return error;
+ }
+
+- memset(&attr, 0, sizeof(attr));
+- error = dprc_get_attributes(mc_io, 0, dprc_handle, &attr);
++ memset(attr, 0, sizeof(struct dprc_attributes));
++ error = dprc_get_attributes(mc_io, 0, dprc_handle, attr);
+ if (error < 0) {
+ dev_err(mc_io->dev, "dprc_get_attributes() failed: %d\n",
+ error);
+ goto common_cleanup;
+ }
+
+- *icid = attr.icid;
+ error = 0;
+
+ common_cleanup:
+@@ -258,6 +256,34 @@ common_cleanup:
+ return error;
+ }
+
++static int get_dprc_icid(struct fsl_mc_io *mc_io,
++ int container_id, u16 *icid)
++{
++ struct dprc_attributes attr;
++ int error;
++
++ error = get_dprc_attr(mc_io, container_id, &attr);
++ if (error == 0)
++ *icid = attr.icid;
++
++ return error;
++}
++
++static int get_dprc_version(struct fsl_mc_io *mc_io,
++ int container_id, u16 *major, u16 *minor)
++{
++ struct dprc_attributes attr;
++ int error;
++
++ error = get_dprc_attr(mc_io, container_id, &attr);
++ if (error == 0) {
++ *major = attr.version.major;
++ *minor = attr.version.minor;
++ }
++
++ return error;
++}
++
+ static int translate_mc_addr(struct fsl_mc_device *mc_dev,
+ enum dprc_region_type mc_region_type,
+ u64 mc_offset, phys_addr_t *phys_addr)
+@@ -719,11 +745,14 @@ static int fsl_mc_bus_probe(struct platf
+ goto error_cleanup_mc_io;
+ }
+
++ error = get_dprc_version(mc_io, container_id,
++ &obj_desc.ver_major, &obj_desc.ver_minor);
++ if (error < 0)
++ goto error_cleanup_mc_io;
++
+ obj_desc.vendor = FSL_MC_VENDOR_FREESCALE;
+ strcpy(obj_desc.type, "dprc");
+ obj_desc.id = container_id;
+- obj_desc.ver_major = DPRC_VER_MAJOR;
+- obj_desc.ver_minor = DPRC_VER_MINOR;
+ obj_desc.irq_count = 1;
+ obj_desc.region_count = 0;
+
--- /dev/null
+From 653898b483e5448084b15214a8c20959b418dbe7 Mon Sep 17 00:00:00 2001
+From: Itai Katz <itai.katz@nxp.com>
+Date: Mon, 11 Apr 2016 11:56:05 -0500
+Subject: [PATCH 174/226] staging: fsl-mc: add dprc version check
+
+The dprc driver supports dprc version 5.0 and above.
+This patch adds the code to check the version.
+
+Signed-off-by: Itai Katz <itai.katz@nxp.com>
+(Stuart: resolved merge conflicts, split dpseci quirk into separate patch)
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Acked-by: German Rivera <german.rivera@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-cmd.h | 6 +++---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 19 +++++++++++++++++++
+ drivers/staging/fsl-mc/bus/mc-bus.c | 1 +
+ drivers/staging/fsl-mc/include/mc-private.h | 2 ++
+ 4 files changed, 25 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-cmd.h
++++ b/drivers/staging/fsl-mc/bus/dprc-cmd.h
+@@ -40,9 +40,9 @@
+ #ifndef _FSL_DPRC_CMD_H
+ #define _FSL_DPRC_CMD_H
+
+-/* DPRC Version */
+-#define DPRC_VER_MAJOR 5
+-#define DPRC_VER_MINOR 1
++/* Minimal supported DPRC Version */
++#define DPRC_MIN_VER_MAJOR 5
++#define DPRC_MIN_VER_MINOR 0
+
+ /* Command IDs */
+ #define DPRC_CMDID_CLOSE 0x800
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -693,6 +693,25 @@ static int dprc_probe(struct fsl_mc_devi
+ goto error_cleanup_msi_domain;
+ }
+
++ error = dprc_get_attributes(mc_dev->mc_io, 0, mc_dev->mc_handle,
++ &mc_bus->dprc_attr);
++ if (error < 0) {
++ dev_err(&mc_dev->dev, "dprc_get_attributes() failed: %d\n",
++ error);
++ goto error_cleanup_open;
++ }
++
++ if (mc_bus->dprc_attr.version.major < DPRC_MIN_VER_MAJOR ||
++ (mc_bus->dprc_attr.version.major == DPRC_MIN_VER_MAJOR &&
++ mc_bus->dprc_attr.version.minor < DPRC_MIN_VER_MINOR)) {
++ dev_err(&mc_dev->dev,
++ "ERROR: DPRC version %d.%d not supported\n",
++ mc_bus->dprc_attr.version.major,
++ mc_bus->dprc_attr.version.minor);
++ error = -ENOTSUPP;
++ goto error_cleanup_open;
++ }
++
+ mutex_init(&mc_bus->scan_mutex);
+
+ /*
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -745,6 +745,7 @@ static int fsl_mc_bus_probe(struct platf
+ goto error_cleanup_mc_io;
+ }
+
++ memset(&obj_desc, 0, sizeof(struct dprc_obj_desc));
+ error = get_dprc_version(mc_io, container_id,
+ &obj_desc.ver_major, &obj_desc.ver_minor);
+ if (error < 0)
+--- a/drivers/staging/fsl-mc/include/mc-private.h
++++ b/drivers/staging/fsl-mc/include/mc-private.h
+@@ -94,12 +94,14 @@ struct fsl_mc_resource_pool {
+ * from the physical DPRC.
+ * @irq_resources: Pointer to array of IRQ objects for the IRQ pool
+ * @scan_mutex: Serializes bus scanning
++ * @dprc_attr: DPRC attributes
+ */
+ struct fsl_mc_bus {
+ struct fsl_mc_device mc_dev;
+ struct fsl_mc_resource_pool resource_pools[FSL_MC_NUM_POOL_TYPES];
+ struct fsl_mc_device_irq *irq_resources;
+ struct mutex scan_mutex; /* serializes bus scanning */
++ struct dprc_attributes dprc_attr;
+ };
+
+ #define to_fsl_mc_bus(_mc_dev) \
--- /dev/null
+From 5366dc8896ca7cf028db73643860821b189a1dfd Mon Sep 17 00:00:00 2001
+From: Horia Geanta <horia.geanta@nxp.com>
+Date: Mon, 11 Apr 2016 11:50:26 -0500
+Subject: [PATCH 175/226] staging: fsl-mc: add quirk handling for dpseci
+ objects < 4.0
+
+dpseci objects < 4.0 are not coherent-- in spite of the fact
+that the MC reports them to be coherent in certain versions.
+Add a special case to set the no shareability flag for dpseci
+objects < 4.0.
+
+Signed-off-by: Horia Geanta <horia.geanta@nxp.com>
+(Stuart: reworded commit message, updated comment in patch)
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Acked-by: German Rivera <german.rivera@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -312,6 +312,15 @@ int dprc_scan_objects(struct fsl_mc_devi
+ continue;
+ }
+
++ /*
++ * add a quirk for all versions of dpsec < 4.0...none
++ * are coherent regardless of what the MC reports.
++ */
++ if ((strcmp(obj_desc->type, "dpseci") == 0) &&
++ (obj_desc->ver_major < 4))
++ obj_desc->flags |=
++ DPRC_OBJ_FLAG_NO_MEM_SHAREABILITY;
++
+ irq_count += obj_desc->irq_count;
+ dev_dbg(&mc_bus_dev->dev,
+ "Discovered object: type %s, id %d\n",
--- /dev/null
+From 035789ffb3b89b9764d7cc79d209a5795c18fa93 Mon Sep 17 00:00:00 2001
+From: Itai Katz <itai.katz@nxp.com>
+Date: Mon, 11 Apr 2016 11:56:11 -0500
+Subject: [PATCH 176/226] staging: fsl-mc: add dpmcp version check
+
+The dpmcp driver supports dpmcp version 3.0 and above.
+This patch adds the code to check the version.
+
+Signed-off-by: Itai Katz <itai.katz@nxp.com>
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Acked-by: German Rivera <german.rivera@nxp.com>
+
+ drivers/staging/fsl-mc/bus/dpmcp-cmd.h | 6 +++---
+ drivers/staging/fsl-mc/bus/mc-allocator.c | 11 +++++++++++
+ 2 files changed, 14 insertions(+), 3 deletions(-)
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dpmcp-cmd.h | 6 +++---
+ drivers/staging/fsl-mc/bus/mc-allocator.c | 11 +++++++++++
+ 2 files changed, 14 insertions(+), 3 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dpmcp-cmd.h
++++ b/drivers/staging/fsl-mc/bus/dpmcp-cmd.h
+@@ -32,9 +32,9 @@
+ #ifndef _FSL_DPMCP_CMD_H
+ #define _FSL_DPMCP_CMD_H
+
+-/* DPMCP Version */
+-#define DPMCP_VER_MAJOR 3
+-#define DPMCP_VER_MINOR 0
++/* Minimal supported DPMCP Version */
++#define DPMCP_MIN_VER_MAJOR 3
++#define DPMCP_MIN_VER_MINOR 0
+
+ /* Command IDs */
+ #define DPMCP_CMDID_CLOSE 0x800
+--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
++++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
+@@ -297,6 +297,17 @@ int __must_check fsl_mc_portal_allocate(
+ if (WARN_ON(!dpmcp_dev))
+ goto error_cleanup_resource;
+
++ if (dpmcp_dev->obj_desc.ver_major < DPMCP_MIN_VER_MAJOR ||
++ (dpmcp_dev->obj_desc.ver_major == DPMCP_MIN_VER_MAJOR &&
++ dpmcp_dev->obj_desc.ver_minor < DPMCP_MIN_VER_MINOR)) {
++ dev_err(&dpmcp_dev->dev,
++ "ERROR: Version %d.%d of DPMCP not supported.\n",
++ dpmcp_dev->obj_desc.ver_major,
++ dpmcp_dev->obj_desc.ver_minor);
++ error = -ENOTSUPP;
++ goto error_cleanup_resource;
++ }
++
+ if (WARN_ON(dpmcp_dev->obj_desc.region_count == 0))
+ goto error_cleanup_resource;
+
--- /dev/null
+From 324147c1a6806301d9441a8d83c7c5ac880140cd Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Horia=20Geant=C4=83?= <horia.geanta@nxp.com>
+Date: Mon, 11 Apr 2016 11:56:16 -0500
+Subject: [PATCH 177/226] staging: fsl-mc: return -EINVAL for all
+ fsl_mc_portal_allocate() failures
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There are some error paths that allow for a NULL new_mc_io and err = 0
+return code. Return -EINVAL instead.
+
+Signed-off-by: Horia Geantă <horia.geanta@nxp.com>
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Acked-by: German Rivera <german.rivera@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-allocator.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
++++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
+@@ -293,6 +293,7 @@ int __must_check fsl_mc_portal_allocate(
+ if (error < 0)
+ return error;
+
++ error = -EINVAL;
+ dpmcp_dev = resource->data;
+ if (WARN_ON(!dpmcp_dev))
+ goto error_cleanup_resource;
--- /dev/null
+From 9821898bbfa5a21254baafe19b3cc97516fc6019 Mon Sep 17 00:00:00 2001
+From: Matthias Brugger <mbrugger@suse.com>
+Date: Thu, 14 Apr 2016 23:24:26 +0200
+Subject: [PATCH 178/226] staging: fsl-mc: bus: Drop warning
+
+When updating the irq_chip and msi_domain_ops, the code checkes for
+already present functions.
+When more then one ITS controller are present in the system,
+irq_chip and msi_domain_ops got already set and a warning is invoked.
+
+This patch deletes the warning, as the funtions are just already set to
+the needed callbacks.
+
+Signed-off-by: Matthias Brugger <mbrugger@suse.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-msi.c | 12 ++++--------
+ 1 file changed, 4 insertions(+), 8 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-msi.c
++++ b/drivers/staging/fsl-mc/bus/mc-msi.c
+@@ -37,10 +37,8 @@ static void fsl_mc_msi_update_dom_ops(st
+ /*
+ * set_desc should not be set by the caller
+ */
+- if (WARN_ON(ops->set_desc))
+- return;
+-
+- ops->set_desc = fsl_mc_msi_set_desc;
++ if (ops->set_desc == NULL)
++ ops->set_desc = fsl_mc_msi_set_desc;
+ }
+
+ static void __fsl_mc_msi_write_msg(struct fsl_mc_device *mc_bus_dev,
+@@ -129,10 +127,8 @@ static void fsl_mc_msi_update_chip_ops(s
+ /*
+ * irq_write_msi_msg should not be set by the caller
+ */
+- if (WARN_ON(chip->irq_write_msi_msg))
+- return;
+-
+- chip->irq_write_msi_msg = fsl_mc_msi_write_msg;
++ if (chip->irq_write_msi_msg == NULL)
++ chip->irq_write_msi_msg = fsl_mc_msi_write_msg;
+ }
+
+ /**
--- /dev/null
+From 227c693741ce1fbf0ad146c87f03369334941f2e Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Wed, 22 Jun 2016 16:40:42 -0500
+Subject: [PATCH 179/226] staging: fsl-mc: add support for the modalias sysfs
+ attribute
+
+In order to support uevent based module loading implement modalias support
+for the fsl-mc bus driver. Aliases are based on vendor and object/device
+id and are of the form "fsl-mc:vNdN".
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 25 +++++++++++++++++++++++++
+ 1 file changed, 25 insertions(+)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -82,10 +82,35 @@ static int fsl_mc_bus_uevent(struct devi
+ return 0;
+ }
+
++static ssize_t modalias_show(struct device *dev, struct device_attribute *attr,
++ char *buf)
++{
++ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
++
++ return sprintf(buf, "fsl-mc:v%08Xd%s\n", mc_dev->obj_desc.vendor,
++ mc_dev->obj_desc.type);
++}
++static DEVICE_ATTR_RO(modalias);
++
++static struct attribute *fsl_mc_dev_attrs[] = {
++ &dev_attr_modalias.attr,
++ NULL,
++};
++
++static const struct attribute_group fsl_mc_dev_group = {
++ .attrs = fsl_mc_dev_attrs,
++};
++
++static const struct attribute_group *fsl_mc_dev_groups[] = {
++ &fsl_mc_dev_group,
++ NULL,
++};
++
+ struct bus_type fsl_mc_bus_type = {
+ .name = "fsl-mc",
+ .match = fsl_mc_bus_match,
+ .uevent = fsl_mc_bus_uevent,
++ .dev_groups = fsl_mc_dev_groups,
+ };
+ EXPORT_SYMBOL_GPL(fsl_mc_bus_type);
+
--- /dev/null
+From 721966c3990bc4596c6270afc1ea68c756b72f0d Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Wed, 22 Jun 2016 16:40:43 -0500
+Subject: [PATCH 180/226] staging: fsl-mc: implement uevent callback and set
+ the modalias
+
+Replace placeholder code in the uevent callback to properly
+set the MODALIAS env variable.
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -78,7 +78,13 @@ out:
+ */
+ static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
+ {
+- pr_debug("%s invoked\n", __func__);
++ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
++
++ if (add_uevent_var(env, "MODALIAS=fsl-mc:v%08Xd%s",
++ mc_dev->obj_desc.vendor,
++ mc_dev->obj_desc.type))
++ return -ENOMEM;
++
+ return 0;
+ }
+
--- /dev/null
+From c7b1e04ae4f47323800ca2b3d3430ecf1d9ed7df Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Wed, 22 Jun 2016 16:40:44 -0500
+Subject: [PATCH 181/226] staging: fsl-mc: clean up the device id struct
+
+-rename the struct used for fsl-mc device ids to be more
+ consistent with other busses
+-remove the now obsolete and unused version fields
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 2 +-
+ drivers/staging/fsl-mc/bus/mc-allocator.c | 2 +-
+ drivers/staging/fsl-mc/bus/mc-bus.c | 2 +-
+ drivers/staging/fsl-mc/include/mc.h | 10 +++-------
+ 4 files changed, 6 insertions(+), 10 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -805,7 +805,7 @@ static int dprc_remove(struct fsl_mc_dev
+ return 0;
+ }
+
+-static const struct fsl_mc_device_match_id match_id_table[] = {
++static const struct fsl_mc_device_id match_id_table[] = {
+ {
+ .vendor = FSL_MC_VENDOR_FREESCALE,
+ .obj_type = "dprc"},
+--- a/drivers/staging/fsl-mc/bus/mc-allocator.c
++++ b/drivers/staging/fsl-mc/bus/mc-allocator.c
+@@ -717,7 +717,7 @@ static int fsl_mc_allocator_remove(struc
+ return 0;
+ }
+
+-static const struct fsl_mc_device_match_id match_id_table[] = {
++static const struct fsl_mc_device_id match_id_table[] = {
+ {
+ .vendor = FSL_MC_VENDOR_FREESCALE,
+ .obj_type = "dpbp",
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -36,7 +36,7 @@ static bool fsl_mc_is_root_dprc(struct d
+ */
+ static int fsl_mc_bus_match(struct device *dev, struct device_driver *drv)
+ {
+- const struct fsl_mc_device_match_id *id;
++ const struct fsl_mc_device_id *id;
+ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
+ struct fsl_mc_driver *mc_drv = to_fsl_mc_driver(drv);
+ bool found = false;
+--- a/drivers/staging/fsl-mc/include/mc.h
++++ b/drivers/staging/fsl-mc/include/mc.h
+@@ -39,7 +39,7 @@ struct fsl_mc_bus;
+ */
+ struct fsl_mc_driver {
+ struct device_driver driver;
+- const struct fsl_mc_device_match_id *match_id_table;
++ const struct fsl_mc_device_id *match_id_table;
+ int (*probe)(struct fsl_mc_device *dev);
+ int (*remove)(struct fsl_mc_device *dev);
+ void (*shutdown)(struct fsl_mc_device *dev);
+@@ -51,20 +51,16 @@ struct fsl_mc_driver {
+ container_of(_drv, struct fsl_mc_driver, driver)
+
+ /**
+- * struct fsl_mc_device_match_id - MC object device Id entry for driver matching
++ * struct fsl_mc_device_id - MC object device Id entry for driver matching
+ * @vendor: vendor ID
+ * @obj_type: MC object type
+- * @ver_major: MC object version major number
+- * @ver_minor: MC object version minor number
+ *
+ * Type of entries in the "device Id" table for MC object devices supported by
+ * a MC object device driver. The last entry of the table has vendor set to 0x0
+ */
+-struct fsl_mc_device_match_id {
++struct fsl_mc_device_id {
+ u16 vendor;
+ const char obj_type[16];
+- u32 ver_major;
+- u32 ver_minor;
+ };
+
+ /**
--- /dev/null
+From bd83c4253992d263cb83108e26b4687058f11deb Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Wed, 22 Jun 2016 16:40:45 -0500
+Subject: [PATCH 182/226] staging: fsl-mc: add support for device table
+ matching
+
+Move the definition of fsl_mc_device_id to its proper location in
+mod_devicetable.h, and add fsl-mc bus support to devicetable-offsets.c
+and file2alias.c to enable device table matching. With this patch udev
+based module loading of fsl-mc drivers is supported.
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/include/mc.h | 13 -------------
+ include/linux/mod_devicetable.h | 16 ++++++++++++++++
+ scripts/mod/devicetable-offsets.c | 4 ++++
+ scripts/mod/file2alias.c | 12 ++++++++++++
+ 4 files changed, 32 insertions(+), 13 deletions(-)
+
+--- a/drivers/staging/fsl-mc/include/mc.h
++++ b/drivers/staging/fsl-mc/include/mc.h
+@@ -51,19 +51,6 @@ struct fsl_mc_driver {
+ container_of(_drv, struct fsl_mc_driver, driver)
+
+ /**
+- * struct fsl_mc_device_id - MC object device Id entry for driver matching
+- * @vendor: vendor ID
+- * @obj_type: MC object type
+- *
+- * Type of entries in the "device Id" table for MC object devices supported by
+- * a MC object device driver. The last entry of the table has vendor set to 0x0
+- */
+-struct fsl_mc_device_id {
+- u16 vendor;
+- const char obj_type[16];
+-};
+-
+-/**
+ * enum fsl_mc_pool_type - Types of allocatable MC bus resources
+ *
+ * Entries in these enum are used as indices in the array of resource
+--- a/include/linux/mod_devicetable.h
++++ b/include/linux/mod_devicetable.h
+@@ -657,4 +657,20 @@ struct ulpi_device_id {
+ kernel_ulong_t driver_data;
+ };
+
++/**
++ * struct fsl_mc_device_id - MC object device identifier
++ * @vendor: vendor ID
++ * @obj_type: MC object type
++ * @ver_major: MC object version major number
++ * @ver_minor: MC object version minor number
++ *
++ * Type of entries in the "device Id" table for MC object devices supported by
++ * a MC object device driver. The last entry of the table has vendor set to 0x0
++ */
++struct fsl_mc_device_id {
++ __u16 vendor;
++ const char obj_type[16];
++};
++
++
+ #endif /* LINUX_MOD_DEVICETABLE_H */
+--- a/scripts/mod/devicetable-offsets.c
++++ b/scripts/mod/devicetable-offsets.c
+@@ -202,5 +202,9 @@ int main(void)
+ DEVID_FIELD(hda_device_id, rev_id);
+ DEVID_FIELD(hda_device_id, api_version);
+
++ DEVID(fsl_mc_device_id);
++ DEVID_FIELD(fsl_mc_device_id, vendor);
++ DEVID_FIELD(fsl_mc_device_id, obj_type);
++
+ return 0;
+ }
+--- a/scripts/mod/file2alias.c
++++ b/scripts/mod/file2alias.c
+@@ -1271,6 +1271,18 @@ static int do_hda_entry(const char *file
+ }
+ ADD_TO_DEVTABLE("hdaudio", hda_device_id, do_hda_entry);
+
++/* Looks like: fsl-mc:vNdN */
++static int do_fsl_mc_entry(const char *filename, void *symval,
++ char *alias)
++{
++ DEF_FIELD(symval, fsl_mc_device_id, vendor);
++ DEF_FIELD_ADDR(symval, fsl_mc_device_id, obj_type);
++
++ sprintf(alias, "fsl-mc:v%08Xd%s", vendor, *obj_type);
++ return 1;
++}
++ADD_TO_DEVTABLE("fslmc", fsl_mc_device_id, do_fsl_mc_entry);
++
+ /* Does namelen bytes of name exactly match the symbol? */
+ static bool sym_is(const char *name, unsigned namelen, const char *symbol)
+ {
--- /dev/null
+From 4087dc71f82a71c25f9d051773094f4ae3f4238d Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Wed, 22 Jun 2016 16:40:46 -0500
+Subject: [PATCH 183/226] staging: fsl-mc: export mc_get_version
+
+some drivers (built as modules) rely on mc_get_version()
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dpmng.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/staging/fsl-mc/bus/dpmng.c
++++ b/drivers/staging/fsl-mc/bus/dpmng.c
+@@ -67,6 +67,7 @@ int mc_get_version(struct fsl_mc_io *mc_
+
+ return 0;
+ }
++EXPORT_SYMBOL(mc_get_version);
+
+ /**
+ * dpmng_get_container_id() - Get container ID associated with a given portal.
--- /dev/null
+From 82981b28f3a8a7f4ac61d8dc87a0abaeebfbe6dc Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Wed, 22 Jun 2016 16:40:47 -0500
+Subject: [PATCH 184/226] staging: fsl-mc: make fsl_mc_is_root_dprc() global
+
+make fsl_mc_is_root_dprc() global so that the dprc driver
+can use it
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 28 +++++++++++++---------------
+ drivers/staging/fsl-mc/include/mc.h | 2 ++
+ 2 files changed, 15 insertions(+), 15 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -24,8 +24,6 @@
+
+ static struct kmem_cache *mc_dev_cache;
+
+-static bool fsl_mc_is_root_dprc(struct device *dev);
+-
+ /**
+ * fsl_mc_bus_match - device to driver matching callback
+ * @dev: the MC object device structure to match against
+@@ -247,19 +245,6 @@ static void fsl_mc_get_root_dprc(struct
+ }
+ }
+
+-/**
+- * fsl_mc_is_root_dprc - function to check if a given device is a root dprc
+- */
+-static bool fsl_mc_is_root_dprc(struct device *dev)
+-{
+- struct device *root_dprc_dev;
+-
+- fsl_mc_get_root_dprc(dev, &root_dprc_dev);
+- if (!root_dprc_dev)
+- return false;
+- return dev == root_dprc_dev;
+-}
+-
+ static int get_dprc_attr(struct fsl_mc_io *mc_io,
+ int container_id, struct dprc_attributes *attr)
+ {
+@@ -424,6 +409,19 @@ error_cleanup_regions:
+ }
+
+ /**
++ * fsl_mc_is_root_dprc - function to check if a given device is a root dprc
++ */
++bool fsl_mc_is_root_dprc(struct device *dev)
++{
++ struct device *root_dprc_dev;
++
++ fsl_mc_get_root_dprc(dev, &root_dprc_dev);
++ if (!root_dprc_dev)
++ return false;
++ return dev == root_dprc_dev;
++}
++
++/**
+ * Add a newly discovered MC object device to be visible in Linux
+ */
+ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
+--- a/drivers/staging/fsl-mc/include/mc.h
++++ b/drivers/staging/fsl-mc/include/mc.h
+@@ -207,6 +207,8 @@ int __must_check fsl_mc_allocate_irqs(st
+
+ void fsl_mc_free_irqs(struct fsl_mc_device *mc_dev);
+
++bool fsl_mc_is_root_dprc(struct device *dev);
++
+ extern struct bus_type fsl_mc_bus_type;
+
+ #endif /* _FSL_MC_H_ */
--- /dev/null
+From 4e55a4c296d3a93c95320cdac0b8e72f3cfefb98 Mon Sep 17 00:00:00 2001
+From: Bharat Bhushan <Bharat.Bhushan@nxp.com>
+Date: Wed, 22 Jun 2016 16:40:48 -0500
+Subject: [PATCH 185/226] staging: fsl-mc: fix asymmetry in destroy of mc_io
+
+An mc_io represents a mapped MC portal. Previously, an mc_io was
+created for the root dprc in fsl_mc_bus_probe() and for child dprcs
+in dprc_probe(). But the free of that data structure happened in the
+general bus remove callback. This asymmetry resulted in some bugs due
+to unwanted destroys of mc_io object in some scenarios (e.g. vfio).
+
+Fix this bug by making things symmetric-- mc_io created in
+fsl_mc_bus_probe() is freed in fsl_mc_bus_remove(). The mc_io created
+in dprc_probe() is freed in dprc_remove().
+
+Signed-off-by: Bharat Bhushan <Bharat.Bhushan@nxp.com>
+[Stuart: added check for root dprc and reworded commit message]
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 5 +++++
+ drivers/staging/fsl-mc/bus/mc-bus.c | 8 ++++----
+ 2 files changed, 9 insertions(+), 4 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -801,6 +801,11 @@ static int dprc_remove(struct fsl_mc_dev
+ dev_set_msi_domain(&mc_dev->dev, NULL);
+ }
+
++ if (!fsl_mc_is_root_dprc(&mc_dev->dev)) {
++ fsl_destroy_mc_io(mc_dev->mc_io);
++ mc_dev->mc_io = NULL;
++ }
++
+ dev_info(&mc_dev->dev, "DPRC device unbound from driver");
+ return 0;
+ }
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -579,10 +579,6 @@ void fsl_mc_device_remove(struct fsl_mc_
+
+ if (strcmp(mc_dev->obj_desc.type, "dprc") == 0) {
+ mc_bus = to_fsl_mc_bus(mc_dev);
+- if (mc_dev->mc_io) {
+- fsl_destroy_mc_io(mc_dev->mc_io);
+- mc_dev->mc_io = NULL;
+- }
+
+ if (fsl_mc_is_root_dprc(&mc_dev->dev)) {
+ if (atomic_read(&root_dprc_count) > 0)
+@@ -810,6 +806,10 @@ static int fsl_mc_bus_remove(struct plat
+ return -EINVAL;
+
+ fsl_mc_device_remove(mc->root_mc_bus_dev);
++
++ fsl_destroy_mc_io(mc->root_mc_bus_dev->mc_io);
++ mc->root_mc_bus_dev->mc_io = NULL;
++
+ dev_info(&pdev->dev, "Root MC bus device removed");
+ return 0;
+ }
--- /dev/null
+From 159abffaa5e2acf910b5e4cdca81a7b6d2dd958f Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Wed, 22 Jun 2016 16:40:49 -0500
+Subject: [PATCH 186/226] staging: fsl-mc: dprc: add missing irq free
+
+add missing free of the Linux irq when tearing down interrupts
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -760,7 +760,12 @@ error_cleanup_msi_domain:
+ */
+ static void dprc_teardown_irq(struct fsl_mc_device *mc_dev)
+ {
++ struct fsl_mc_device_irq *irq = mc_dev->irqs[0];
++
+ (void)disable_dprc_irq(mc_dev);
++
++ devm_free_irq(&mc_dev->dev, irq->msi_desc->irq, &mc_dev->dev);
++
+ fsl_mc_free_irqs(mc_dev);
+ }
+
--- /dev/null
+From b104ed7497745e2e6da214b37ef22edaf38098c7 Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Wed, 22 Jun 2016 16:40:50 -0500
+Subject: [PATCH 187/226] staging: fsl-mc: dprc: fix ordering problem freeing
+ resources in remove of dprc
+
+When unbinding a dprc from the dprc driver the cleanup of
+the resource pools must happen after irq pool cleanup
+is done.
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -796,16 +796,18 @@ static int dprc_remove(struct fsl_mc_dev
+ dprc_teardown_irq(mc_dev);
+
+ device_for_each_child(&mc_dev->dev, NULL, __fsl_mc_device_remove);
+- dprc_cleanup_all_resource_pools(mc_dev);
+- error = dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
+- if (error < 0)
+- dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);
+
+ if (dev_get_msi_domain(&mc_dev->dev)) {
+ fsl_mc_cleanup_irq_pool(mc_bus);
+ dev_set_msi_domain(&mc_dev->dev, NULL);
+ }
+
++ dprc_cleanup_all_resource_pools(mc_dev);
++
++ error = dprc_close(mc_dev->mc_io, 0, mc_dev->mc_handle);
++ if (error < 0)
++ dev_err(&mc_dev->dev, "dprc_close() failed: %d\n", error);
++
+ if (!fsl_mc_is_root_dprc(&mc_dev->dev)) {
+ fsl_destroy_mc_io(mc_dev->mc_io);
+ mc_dev->mc_io = NULL;
--- /dev/null
+From f5f9462cb947922817225b69240740e637de0149 Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Wed, 22 Jun 2016 16:40:51 -0500
+Subject: [PATCH 188/226] staging: fsl-mc: properly set hwirq in msi set_desc
+
+For an MSI domain the hwirq is an arbitrary but unique
+id to identify an interrupt. Previously the hwirq was set to
+the MSI index of the interrupt, but that only works if there is
+one DPRC. Additional DPRCs require an expanded namespace. Use
+both the ICID (which is unique per DPRC) and the MSI index to
+compose a hwirq value.
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/staging/fsl-mc/bus/mc-msi.c | 17 ++++++++++++++++-
+ 1 file changed, 16 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-msi.c
++++ b/drivers/staging/fsl-mc/bus/mc-msi.c
+@@ -20,11 +20,26 @@
+ #include "../include/mc-sys.h"
+ #include "dprc-cmd.h"
+
++/*
++ * Generate a unique ID identifying the interrupt (only used within the MSI
++ * irqdomain. Combine the icid with the interrupt index.
++ */
++static irq_hw_number_t fsl_mc_domain_calc_hwirq(struct fsl_mc_device *dev,
++ struct msi_desc *desc)
++{
++ /*
++ * Make the base hwirq value for ICID*10000 so it is readable
++ * as a decimal value in /proc/interrupts.
++ */
++ return (irq_hw_number_t)(desc->fsl_mc.msi_index + (dev->icid * 10000));
++}
++
+ static void fsl_mc_msi_set_desc(msi_alloc_info_t *arg,
+ struct msi_desc *desc)
+ {
+ arg->desc = desc;
+- arg->hwirq = (irq_hw_number_t)desc->fsl_mc.msi_index;
++ arg->hwirq = fsl_mc_domain_calc_hwirq(to_fsl_mc_device(desc->dev),
++ desc);
+ }
+
+ static void fsl_mc_msi_update_dom_ops(struct msi_domain_info *info)
--- /dev/null
+From 95c8565453e068db2664b5ee9cb0b7eced9a8d24 Mon Sep 17 00:00:00 2001
+From: Ioana Radulescu <ruxandra.radulescu@freescale.com>
+Date: Fri, 3 Jul 2015 19:02:45 +0300
+Subject: [PATCH 189/226] staging: fsl-mc: update dpcon binary interface to
+ v2.2
+
+-this includes adding the command building/parsing
+ wrapper functions
+
+Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
+---
+ drivers/staging/fsl-mc/bus/Makefile | 3 +-
+ drivers/staging/fsl-mc/bus/dpcon.c | 407 ++++++++++++++++++++++++++++
+ drivers/staging/fsl-mc/include/dpcon-cmd.h | 102 ++++++-
+ drivers/staging/fsl-mc/include/dpcon.h | 407 ++++++++++++++++++++++++++++
+ 4 files changed, 917 insertions(+), 2 deletions(-)
+ create mode 100644 drivers/staging/fsl-mc/bus/dpcon.c
+ create mode 100644 drivers/staging/fsl-mc/include/dpcon.h
+
+--- a/drivers/staging/fsl-mc/bus/Makefile
++++ b/drivers/staging/fsl-mc/bus/Makefile
+@@ -16,4 +16,5 @@ mc-bus-driver-objs := mc-bus.o \
+ mc-msi.o \
+ irq-gic-v3-its-fsl-mc-msi.o \
+ dpmcp.o \
+- dpbp.o
++ dpbp.o \
++ dpcon.o
+--- /dev/null
++++ b/drivers/staging/fsl-mc/bus/dpcon.c
+@@ -0,0 +1,407 @@
++/* Copyright 2013-2015 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 the above-listed copyright holders nor the
++ * names of any 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++#include "../include/mc-sys.h"
++#include "../include/mc-cmd.h"
++#include "../include/dpcon.h"
++#include "../include/dpcon-cmd.h"
++
++int dpcon_open(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ int dpcon_id,
++ uint16_t *token)
++{
++ struct mc_command cmd = { 0 };
++ int err;
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_OPEN,
++ cmd_flags,
++ 0);
++ DPCON_CMD_OPEN(cmd, dpcon_id);
++
++ /* send command to mc*/
++ err = mc_send_command(mc_io, &cmd);
++ if (err)
++ return err;
++
++ /* retrieve response parameters */
++ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
++
++ return 0;
++}
++EXPORT_SYMBOL(dpcon_open);
++
++int dpcon_close(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token)
++{
++ struct mc_command cmd = { 0 };
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_CLOSE,
++ cmd_flags,
++ token);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++EXPORT_SYMBOL(dpcon_close);
++
++int dpcon_create(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ const struct dpcon_cfg *cfg,
++ uint16_t *token)
++{
++ struct mc_command cmd = { 0 };
++ int err;
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_CREATE,
++ cmd_flags,
++ 0);
++ DPCON_CMD_CREATE(cmd, cfg);
++
++ /* send command to mc*/
++ err = mc_send_command(mc_io, &cmd);
++ if (err)
++ return err;
++
++ /* retrieve response parameters */
++ *token = MC_CMD_HDR_READ_TOKEN(cmd.header);
++
++ return 0;
++}
++
++int dpcon_destroy(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token)
++{
++ struct mc_command cmd = { 0 };
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_DESTROY,
++ cmd_flags,
++ token);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++
++int dpcon_enable(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token)
++{
++ struct mc_command cmd = { 0 };
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_ENABLE,
++ cmd_flags,
++ token);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++EXPORT_SYMBOL(dpcon_enable);
++
++int dpcon_disable(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token)
++{
++ struct mc_command cmd = { 0 };
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_DISABLE,
++ cmd_flags,
++ token);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++EXPORT_SYMBOL(dpcon_disable);
++
++int dpcon_is_enabled(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ int *en)
++{
++ struct mc_command cmd = { 0 };
++ int err;
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_IS_ENABLED,
++ cmd_flags,
++ token);
++
++ /* send command to mc*/
++ err = mc_send_command(mc_io, &cmd);
++ if (err)
++ return err;
++
++ /* retrieve response parameters */
++ DPCON_RSP_IS_ENABLED(cmd, *en);
++
++ return 0;
++}
++
++int dpcon_reset(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token)
++{
++ struct mc_command cmd = { 0 };
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_RESET,
++ cmd_flags, token);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++
++int dpcon_set_irq(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ struct dpcon_irq_cfg *irq_cfg)
++{
++ struct mc_command cmd = { 0 };
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_SET_IRQ,
++ cmd_flags,
++ token);
++ DPCON_CMD_SET_IRQ(cmd, irq_index, irq_cfg);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++
++int dpcon_get_irq(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ int *type,
++ struct dpcon_irq_cfg *irq_cfg)
++{
++ struct mc_command cmd = { 0 };
++ int err;
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_GET_IRQ,
++ cmd_flags,
++ token);
++ DPCON_CMD_GET_IRQ(cmd, irq_index);
++
++ /* send command to mc*/
++ err = mc_send_command(mc_io, &cmd);
++ if (err)
++ return err;
++
++ /* retrieve response parameters */
++ DPCON_RSP_GET_IRQ(cmd, *type, irq_cfg);
++
++ return 0;
++}
++
++int dpcon_set_irq_enable(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ uint8_t en)
++{
++ struct mc_command cmd = { 0 };
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_SET_IRQ_ENABLE,
++ cmd_flags,
++ token);
++ DPCON_CMD_SET_IRQ_ENABLE(cmd, irq_index, en);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++
++int dpcon_get_irq_enable(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ uint8_t *en)
++{
++ struct mc_command cmd = { 0 };
++ int err;
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_GET_IRQ_ENABLE,
++ cmd_flags,
++ token);
++ DPCON_CMD_GET_IRQ_ENABLE(cmd, irq_index);
++
++ /* send command to mc*/
++ err = mc_send_command(mc_io, &cmd);
++ if (err)
++ return err;
++
++ /* retrieve response parameters */
++ DPCON_RSP_GET_IRQ_ENABLE(cmd, *en);
++
++ return 0;
++}
++
++int dpcon_set_irq_mask(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ uint32_t mask)
++{
++ struct mc_command cmd = { 0 };
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_SET_IRQ_MASK,
++ cmd_flags,
++ token);
++ DPCON_CMD_SET_IRQ_MASK(cmd, irq_index, mask);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++
++int dpcon_get_irq_mask(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ uint32_t *mask)
++{
++ struct mc_command cmd = { 0 };
++ int err;
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_GET_IRQ_MASK,
++ cmd_flags,
++ token);
++ DPCON_CMD_GET_IRQ_MASK(cmd, irq_index);
++
++ /* send command to mc*/
++ err = mc_send_command(mc_io, &cmd);
++ if (err)
++ return err;
++
++ /* retrieve response parameters */
++ DPCON_RSP_GET_IRQ_MASK(cmd, *mask);
++
++ return 0;
++}
++
++int dpcon_get_irq_status(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ uint32_t *status)
++{
++ struct mc_command cmd = { 0 };
++ int err;
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_GET_IRQ_STATUS,
++ cmd_flags,
++ token);
++ DPCON_CMD_GET_IRQ_STATUS(cmd, irq_index, *status);
++
++ /* send command to mc*/
++ err = mc_send_command(mc_io, &cmd);
++ if (err)
++ return err;
++
++ /* retrieve response parameters */
++ DPCON_RSP_GET_IRQ_STATUS(cmd, *status);
++
++ return 0;
++}
++
++int dpcon_clear_irq_status(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ uint32_t status)
++{
++ struct mc_command cmd = { 0 };
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_CLEAR_IRQ_STATUS,
++ cmd_flags,
++ token);
++ DPCON_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++
++int dpcon_get_attributes(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ struct dpcon_attr *attr)
++{
++ struct mc_command cmd = { 0 };
++ int err;
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_GET_ATTR,
++ cmd_flags,
++ token);
++
++ /* send command to mc*/
++ err = mc_send_command(mc_io, &cmd);
++ if (err)
++ return err;
++
++ /* retrieve response parameters */
++ DPCON_RSP_GET_ATTR(cmd, attr);
++
++ return 0;
++}
++EXPORT_SYMBOL(dpcon_get_attributes);
++
++int dpcon_set_notification(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ struct dpcon_notification_cfg *cfg)
++{
++ struct mc_command cmd = { 0 };
++
++ /* prepare command */
++ cmd.header = mc_encode_cmd_header(DPCON_CMDID_SET_NOTIFICATION,
++ cmd_flags,
++ token);
++ DPCON_CMD_SET_NOTIFICATION(cmd, cfg);
++
++ /* send command to mc*/
++ return mc_send_command(mc_io, &cmd);
++}
++EXPORT_SYMBOL(dpcon_set_notification);
++
+--- a/drivers/staging/fsl-mc/include/dpcon-cmd.h
++++ b/drivers/staging/fsl-mc/include/dpcon-cmd.h
+@@ -34,7 +34,7 @@
+
+ /* DPCON Version */
+ #define DPCON_VER_MAJOR 2
+-#define DPCON_VER_MINOR 1
++#define DPCON_VER_MINOR 2
+
+ /* Command IDs */
+ #define DPCON_CMDID_CLOSE 0x800
+@@ -59,4 +59,104 @@
+
+ #define DPCON_CMDID_SET_NOTIFICATION 0x100
+
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_CMD_OPEN(cmd, dpcon_id) \
++ MC_CMD_OP(cmd, 0, 0, 32, int, dpcon_id)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_CMD_CREATE(cmd, cfg) \
++ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, cfg->num_priorities)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_RSP_IS_ENABLED(cmd, en) \
++ MC_RSP_OP(cmd, 0, 0, 1, int, en)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_CMD_SET_IRQ(cmd, irq_index, irq_cfg) \
++do { \
++ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, irq_index);\
++ MC_CMD_OP(cmd, 0, 32, 32, uint32_t, irq_cfg->val);\
++ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\
++ MC_CMD_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
++} while (0)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_CMD_GET_IRQ(cmd, irq_index) \
++ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_RSP_GET_IRQ(cmd, type, irq_cfg) \
++do { \
++ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, irq_cfg->val);\
++ MC_RSP_OP(cmd, 1, 0, 64, uint64_t, irq_cfg->addr);\
++ MC_RSP_OP(cmd, 2, 0, 32, int, irq_cfg->irq_num); \
++ MC_RSP_OP(cmd, 2, 32, 32, int, type);\
++} while (0)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_CMD_SET_IRQ_ENABLE(cmd, irq_index, en) \
++do { \
++ MC_CMD_OP(cmd, 0, 0, 8, uint8_t, en); \
++ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
++} while (0)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_CMD_GET_IRQ_ENABLE(cmd, irq_index) \
++ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_RSP_GET_IRQ_ENABLE(cmd, en) \
++ MC_RSP_OP(cmd, 0, 0, 8, uint8_t, en)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_CMD_SET_IRQ_MASK(cmd, irq_index, mask) \
++do { \
++ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, mask); \
++ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
++} while (0)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_CMD_GET_IRQ_MASK(cmd, irq_index) \
++ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_RSP_GET_IRQ_MASK(cmd, mask) \
++ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, mask)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_CMD_GET_IRQ_STATUS(cmd, irq_index, status) \
++do { \
++ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status);\
++ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
++} while (0)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_RSP_GET_IRQ_STATUS(cmd, status) \
++ MC_RSP_OP(cmd, 0, 0, 32, uint32_t, status)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_CMD_CLEAR_IRQ_STATUS(cmd, irq_index, status) \
++do { \
++ MC_CMD_OP(cmd, 0, 0, 32, uint32_t, status); \
++ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, irq_index);\
++} while (0)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_RSP_GET_ATTR(cmd, attr) \
++do { \
++ MC_RSP_OP(cmd, 0, 0, 32, int, attr->id);\
++ MC_RSP_OP(cmd, 0, 32, 16, uint16_t, attr->qbman_ch_id);\
++ MC_RSP_OP(cmd, 0, 48, 8, uint8_t, attr->num_priorities);\
++ MC_RSP_OP(cmd, 1, 0, 16, uint16_t, attr->version.major);\
++ MC_RSP_OP(cmd, 1, 16, 16, uint16_t, attr->version.minor);\
++} while (0)
++
++/* cmd, param, offset, width, type, arg_name */
++#define DPCON_CMD_SET_NOTIFICATION(cmd, cfg) \
++do { \
++ MC_CMD_OP(cmd, 0, 0, 32, int, cfg->dpio_id);\
++ MC_CMD_OP(cmd, 0, 32, 8, uint8_t, cfg->priority);\
++ MC_CMD_OP(cmd, 1, 0, 64, uint64_t, cfg->user_ctx);\
++} while (0)
++
+ #endif /* _FSL_DPCON_CMD_H */
+--- /dev/null
++++ b/drivers/staging/fsl-mc/include/dpcon.h
+@@ -0,0 +1,407 @@
++/* Copyright 2013-2015 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 the above-listed copyright holders nor the
++ * names of any 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
++ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
++ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
++ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
++ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
++ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
++ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
++ * POSSIBILITY OF SUCH DAMAGE.
++ */
++#ifndef __FSL_DPCON_H
++#define __FSL_DPCON_H
++
++/* Data Path Concentrator API
++ * Contains initialization APIs and runtime control APIs for DPCON
++ */
++
++struct fsl_mc_io;
++
++/** General DPCON macros */
++
++/**
++ * Use it to disable notifications; see dpcon_set_notification()
++ */
++#define DPCON_INVALID_DPIO_ID (int)(-1)
++
++/**
++ * dpcon_open() - Open a control session for the specified object
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @dpcon_id: DPCON unique ID
++ * @token: Returned token; use in subsequent API calls
++ *
++ * This function can be used to open a control session for an
++ * already created object; an object may have been declared in
++ * the DPL or by calling the dpcon_create() function.
++ * This function returns a unique authentication token,
++ * associated with the specific object ID and the specific MC
++ * portal; this token must be used in all subsequent commands for
++ * this specific object.
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_open(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ int dpcon_id,
++ uint16_t *token);
++
++/**
++ * dpcon_close() - Close the control session of the object
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ *
++ * After this function is called, no further operations are
++ * allowed on the object without opening a new control session.
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_close(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token);
++
++/**
++ * struct dpcon_cfg - Structure representing DPCON configuration
++ * @num_priorities: Number of priorities for the DPCON channel (1-8)
++ */
++struct dpcon_cfg {
++ uint8_t num_priorities;
++};
++
++/**
++ * dpcon_create() - Create the DPCON object.
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @cfg: Configuration structure
++ * @token: Returned token; use in subsequent API calls
++ *
++ * Create the DPCON object, allocate required resources and
++ * perform required initialization.
++ *
++ * The object can be created either by declaring it in the
++ * DPL file, or by calling this function.
++ *
++ * This function returns a unique authentication token,
++ * associated with the specific object ID and the specific MC
++ * portal; this token must be used in all subsequent calls to
++ * this specific object. For objects that are created using the
++ * DPL file, call dpcon_open() function to get an authentication
++ * token first.
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_create(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ const struct dpcon_cfg *cfg,
++ uint16_t *token);
++
++/**
++ * dpcon_destroy() - Destroy the DPCON object and release all its resources.
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ *
++ * Return: '0' on Success; error code otherwise.
++ */
++int dpcon_destroy(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token);
++
++/**
++ * dpcon_enable() - Enable the DPCON
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ *
++ * Return: '0' on Success; Error code otherwise
++ */
++int dpcon_enable(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token);
++
++/**
++ * dpcon_disable() - Disable the DPCON
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ *
++ * Return: '0' on Success; Error code otherwise
++ */
++int dpcon_disable(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token);
++
++/**
++ * dpcon_is_enabled() - Check if the DPCON is enabled.
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ * @en: Returns '1' if object is enabled; '0' otherwise
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_is_enabled(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ int *en);
++
++/**
++ * dpcon_reset() - Reset the DPCON, returns the object to initial state.
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_reset(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token);
++
++/**
++ * struct dpcon_irq_cfg - IRQ configuration
++ * @addr: Address that must be written to signal a message-based interrupt
++ * @val: Value to write into irq_addr address
++ * @irq_num: A user defined number associated with this IRQ
++ */
++struct dpcon_irq_cfg {
++ uint64_t addr;
++ uint32_t val;
++ int irq_num;
++};
++
++/**
++ * dpcon_set_irq() - Set IRQ information for the DPCON to trigger an interrupt.
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ * @irq_index: Identifies the interrupt index to configure
++ * @irq_cfg: IRQ configuration
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_set_irq(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ struct dpcon_irq_cfg *irq_cfg);
++
++/**
++ * dpcon_get_irq() - Get IRQ information from the DPCON.
++ *
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ * @irq_index: The interrupt index to configure
++ * @type: Interrupt type: 0 represents message interrupt
++ * type (both irq_addr and irq_val are valid)
++ * @irq_cfg: IRQ attributes
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_get_irq(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ int *type,
++ struct dpcon_irq_cfg *irq_cfg);
++
++/**
++ * dpcon_set_irq_enable() - Set overall interrupt state.
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ * @irq_index: The interrupt index to configure
++ * @en: Interrupt state - enable = 1, disable = 0
++ *
++ * Allows GPP software to control when interrupts are generated.
++ * Each interrupt can have up to 32 causes. The enable/disable control's the
++ * overall interrupt state. if the interrupt is disabled no causes will cause
++ * an interrupt.
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_set_irq_enable(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ uint8_t en);
++
++/**
++ * dpcon_get_irq_enable() - Get overall interrupt state.
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ * @irq_index: The interrupt index to configure
++ * @en: Returned interrupt state - enable = 1, disable = 0
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_get_irq_enable(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ uint8_t *en);
++
++/**
++ * dpcon_set_irq_mask() - Set interrupt mask.
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ * @irq_index: The interrupt index to configure
++ * @mask: Event mask to trigger interrupt;
++ * each bit:
++ * 0 = ignore event
++ * 1 = consider event for asserting IRQ
++ *
++ * Every interrupt can have up to 32 causes and the interrupt model supports
++ * masking/unmasking each cause independently
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_set_irq_mask(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ uint32_t mask);
++
++/**
++ * dpcon_get_irq_mask() - Get interrupt mask.
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ * @irq_index: The interrupt index to configure
++ * @mask: Returned event mask to trigger interrupt
++ *
++ * Every interrupt can have up to 32 causes and the interrupt model supports
++ * masking/unmasking each cause independently
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_get_irq_mask(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ uint32_t *mask);
++
++/**
++ * dpcon_get_irq_status() - Get the current status of any pending interrupts.
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ * @irq_index: The interrupt index to configure
++ * @status: interrupts status - one bit per cause:
++ * 0 = no interrupt pending
++ * 1 = interrupt pending
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_get_irq_status(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ uint32_t *status);
++
++/**
++ * dpcon_clear_irq_status() - Clear a pending interrupt's status
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ * @irq_index: The interrupt index to configure
++ * @status: bits to clear (W1C) - one bit per cause:
++ * 0 = don't change
++ * 1 = clear status bit
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_clear_irq_status(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ uint8_t irq_index,
++ uint32_t status);
++
++/**
++ * struct dpcon_attr - Structure representing DPCON attributes
++ * @id: DPCON object ID
++ * @version: DPCON version
++ * @qbman_ch_id: Channel ID to be used by dequeue operation
++ * @num_priorities: Number of priorities for the DPCON channel (1-8)
++ */
++struct dpcon_attr {
++ int id;
++ /**
++ * struct version - DPCON version
++ * @major: DPCON major version
++ * @minor: DPCON minor version
++ */
++ struct {
++ uint16_t major;
++ uint16_t minor;
++ } version;
++ uint16_t qbman_ch_id;
++ uint8_t num_priorities;
++};
++
++/**
++ * dpcon_get_attributes() - Retrieve DPCON attributes.
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ * @attr: Object's attributes
++ *
++ * Return: '0' on Success; Error code otherwise.
++ */
++int dpcon_get_attributes(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ struct dpcon_attr *attr);
++
++/**
++ * struct dpcon_notification_cfg - Structure representing notification parameters
++ * @dpio_id: DPIO object ID; must be configured with a notification channel;
++ * to disable notifications set it to 'DPCON_INVALID_DPIO_ID';
++ * @priority: Priority selection within the DPIO channel; valid values
++ * are 0-7, depending on the number of priorities in that channel
++ * @user_ctx: User context value provided with each CDAN message
++ */
++struct dpcon_notification_cfg {
++ int dpio_id;
++ uint8_t priority;
++ uint64_t user_ctx;
++};
++
++/**
++ * dpcon_set_notification() - Set DPCON notification destination
++ * @mc_io: Pointer to MC portal's I/O object
++ * @cmd_flags: Command flags; one or more of 'MC_CMD_FLAG_'
++ * @token: Token of DPCON object
++ * @cfg: Notification parameters
++ *
++ * Return: '0' on Success; Error code otherwise
++ */
++int dpcon_set_notification(struct fsl_mc_io *mc_io,
++ uint32_t cmd_flags,
++ uint16_t token,
++ struct dpcon_notification_cfg *cfg);
++
++#endif /* __FSL_DPCON_H */
--- /dev/null
+From 75b607ff8725eac74f3375b3370f7d121d1827a3 Mon Sep 17 00:00:00 2001
+From: Lijun Pan <Lijun.Pan@freescale.com>
+Date: Mon, 8 Feb 2016 17:40:14 -0600
+Subject: [PATCH 190/226] staging: fsl-mc: root dprc rescan attribute to sync
+ kernel with MC
+
+Introduce the rescan attribute as a device attribute to
+synchronize the fsl-mc bus objects and the MC firmware.
+
+To rescan the root dprc only, e.g.
+echo 1 > /sys/bus/fsl-mc/devices/dprc.1/rescan
+
+Signed-off-by: Lijun Pan <Lijun.Pan@freescale.com>
+[Stuart: resolved merge conflict]
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 29 +++++++++++++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -96,8 +96,37 @@ static ssize_t modalias_show(struct devi
+ }
+ static DEVICE_ATTR_RO(modalias);
+
++static ssize_t rescan_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ unsigned long val;
++ unsigned int irq_count;
++ struct fsl_mc_device *root_mc_dev;
++ struct fsl_mc_bus *root_mc_bus;
++
++ if (!fsl_mc_is_root_dprc(dev))
++ return -EINVAL;
++
++ root_mc_dev = to_fsl_mc_device(dev);
++ root_mc_bus = to_fsl_mc_bus(root_mc_dev);
++
++ if (kstrtoul(buf, 0, &val) < 0)
++ return -EINVAL;
++
++ if (val) {
++ mutex_lock(&root_mc_bus->scan_mutex);
++ dprc_scan_objects(root_mc_dev, &irq_count);
++ mutex_unlock(&root_mc_bus->scan_mutex);
++ }
++
++ return count;
++}
++static DEVICE_ATTR_WO(rescan);
++
+ static struct attribute *fsl_mc_dev_attrs[] = {
+ &dev_attr_modalias.attr,
++ &dev_attr_rescan.attr,
+ NULL,
+ };
+
--- /dev/null
+From 417d71b1e291725c01893bf1553478924d05952f Mon Sep 17 00:00:00 2001
+From: Lijun Pan <Lijun.Pan@freescale.com>
+Date: Mon, 8 Feb 2016 17:40:16 -0600
+Subject: [PATCH 191/226] staging: fsl-mc: bus rescan attribute to sync kernel
+ with MC
+
+Introduce the rescan attribute as a bus attribute to
+synchronize the fsl-mc bus objects and the MC firmware.
+
+To rescan the fsl-mc bus, e.g.,
+echo 1 > /sys/bus/fsl-mc/rescan
+
+Signed-off-by: Lijun Pan <Lijun.Pan@freescale.com>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 47 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 47 insertions(+)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -139,11 +139,58 @@ static const struct attribute_group *fsl
+ NULL,
+ };
+
++static int scan_fsl_mc_bus(struct device *dev, void *data)
++{
++ unsigned int irq_count;
++ struct fsl_mc_device *root_mc_dev;
++ struct fsl_mc_bus *root_mc_bus;
++
++ if (fsl_mc_is_root_dprc(dev)) {
++ root_mc_dev = to_fsl_mc_device(dev);
++ root_mc_bus = to_fsl_mc_bus(root_mc_dev);
++ mutex_lock(&root_mc_bus->scan_mutex);
++ dprc_scan_objects(root_mc_dev, &irq_count);
++ mutex_unlock(&root_mc_bus->scan_mutex);
++ }
++
++ return 0;
++}
++
++static ssize_t bus_rescan_store(struct bus_type *bus,
++ const char *buf, size_t count)
++{
++ unsigned long val;
++
++ if (kstrtoul(buf, 0, &val) < 0)
++ return -EINVAL;
++
++ if (val)
++ bus_for_each_dev(bus, NULL, NULL, scan_fsl_mc_bus);
++
++ return count;
++}
++static BUS_ATTR(rescan, (S_IWUSR | S_IWGRP), NULL, bus_rescan_store);
++
++static struct attribute *fsl_mc_bus_attrs[] = {
++ &bus_attr_rescan.attr,
++ NULL,
++};
++
++static const struct attribute_group fsl_mc_bus_group = {
++ .attrs = fsl_mc_bus_attrs,
++};
++
++static const struct attribute_group *fsl_mc_bus_groups[] = {
++ &fsl_mc_bus_group,
++ NULL,
++};
++
+ struct bus_type fsl_mc_bus_type = {
+ .name = "fsl-mc",
+ .match = fsl_mc_bus_match,
+ .uevent = fsl_mc_bus_uevent,
+ .dev_groups = fsl_mc_dev_groups,
++ .bus_groups = fsl_mc_bus_groups,
+ };
+ EXPORT_SYMBOL_GPL(fsl_mc_bus_type);
+
--- /dev/null
+From 2b9110586a96afc0d0e246835da176c48ae7c973 Mon Sep 17 00:00:00 2001
+From: "J. German Rivera" <German.Rivera@freescale.com>
+Date: Fri, 13 Mar 2015 15:03:32 -0500
+Subject: [PATCH 192/226] staging: fsl-mc: Propagate driver_override for a
+ child DPRC's children
+
+When a child DPRC is bound to the vfio_fsl_mc driver via driver_override,
+its own children should not be bound to corresponding host kernel
+drivers, but instead should be bound to the vfio_fsl_mc driver as
+well.
+
+Currently, when a child container is scanned by the vfio_fsl_mc driver,
+child devices found are automatically bound to corresponding host kernel
+drivers (e.g., DPMCP and DPBP objects are bound to the fsl_mc_allocator
+driver, DPNI objects are bound to the ldpaa_eth driver, etc), Then,
+the user has to manually unbind these child devices from their drivers,
+set the driver_override sysfs attribute to vfio_fsl_mc driver, for each
+of them and rebind them.
+
+Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 14 ++++++++++----
+ drivers/staging/fsl-mc/bus/mc-bus.c | 20 +++++++++++++++++---
+ drivers/staging/fsl-mc/include/mc-private.h | 2 ++
+ drivers/staging/fsl-mc/include/mc.h | 2 ++
+ 4 files changed, 31 insertions(+), 7 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -152,6 +152,8 @@ static void check_plugged_state_change(s
+ * dprc_add_new_devices - Adds devices to the logical bus for a DPRC
+ *
+ * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
++ * @driver_override: driver override to apply to new objects found in the DPRC,
++ * or NULL, if none.
+ * @obj_desc_array: array of device descriptors for child devices currently
+ * present in the physical DPRC.
+ * @num_child_objects_in_mc: number of entries in obj_desc_array
+@@ -161,6 +163,7 @@ static void check_plugged_state_change(s
+ * in the physical DPRC.
+ */
+ static void dprc_add_new_devices(struct fsl_mc_device *mc_bus_dev,
++ const char *driver_override,
+ struct dprc_obj_desc *obj_desc_array,
+ int num_child_objects_in_mc)
+ {
+@@ -184,7 +187,7 @@ static void dprc_add_new_devices(struct
+ }
+
+ error = fsl_mc_device_add(obj_desc, NULL, &mc_bus_dev->dev,
+- &child_dev);
++ driver_override, &child_dev);
+ if (error < 0)
+ continue;
+ }
+@@ -243,6 +246,8 @@ static void dprc_cleanup_all_resource_po
+ * dprc_scan_objects - Discover objects in a DPRC
+ *
+ * @mc_bus_dev: pointer to the fsl-mc device that represents a DPRC object
++ * @driver_override: driver override to apply to new objects found in the DPRC,
++ * or NULL, if none.
+ * @total_irq_count: total number of IRQs needed by objects in the DPRC.
+ *
+ * Detects objects added and removed from a DPRC and synchronizes the
+@@ -258,6 +263,7 @@ static void dprc_cleanup_all_resource_po
+ * of the device drivers for the non-allocatable devices.
+ */
+ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
++ const char *driver_override,
+ unsigned int *total_irq_count)
+ {
+ int num_child_objects;
+@@ -338,7 +344,7 @@ int dprc_scan_objects(struct fsl_mc_devi
+ dprc_remove_devices(mc_bus_dev, child_obj_desc_array,
+ num_child_objects);
+
+- dprc_add_new_devices(mc_bus_dev, child_obj_desc_array,
++ dprc_add_new_devices(mc_bus_dev, driver_override, child_obj_desc_array,
+ num_child_objects);
+
+ if (child_obj_desc_array)
+@@ -369,7 +375,7 @@ int dprc_scan_container(struct fsl_mc_de
+ * Discover objects in the DPRC:
+ */
+ mutex_lock(&mc_bus->scan_mutex);
+- error = dprc_scan_objects(mc_bus_dev, &irq_count);
++ error = dprc_scan_objects(mc_bus_dev, NULL, &irq_count);
+ mutex_unlock(&mc_bus->scan_mutex);
+ if (error < 0)
+ goto error;
+@@ -456,7 +462,7 @@ static irqreturn_t dprc_irq0_handler_thr
+ DPRC_IRQ_EVENT_OBJ_CREATED)) {
+ unsigned int irq_count;
+
+- error = dprc_scan_objects(mc_dev, &irq_count);
++ error = dprc_scan_objects(mc_dev, NULL, &irq_count);
+ if (error < 0) {
+ /*
+ * If the error is -ENXIO, we ignore it, as it indicates
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -116,7 +116,7 @@ static ssize_t rescan_store(struct devic
+
+ if (val) {
+ mutex_lock(&root_mc_bus->scan_mutex);
+- dprc_scan_objects(root_mc_dev, &irq_count);
++ dprc_scan_objects(root_mc_dev, NULL, &irq_count);
+ mutex_unlock(&root_mc_bus->scan_mutex);
+ }
+
+@@ -149,7 +149,7 @@ static int scan_fsl_mc_bus(struct device
+ root_mc_dev = to_fsl_mc_device(dev);
+ root_mc_bus = to_fsl_mc_bus(root_mc_dev);
+ mutex_lock(&root_mc_bus->scan_mutex);
+- dprc_scan_objects(root_mc_dev, &irq_count);
++ dprc_scan_objects(root_mc_dev, NULL, &irq_count);
+ mutex_unlock(&root_mc_bus->scan_mutex);
+ }
+
+@@ -503,6 +503,7 @@ bool fsl_mc_is_root_dprc(struct device *
+ int fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
+ struct fsl_mc_io *mc_io,
+ struct device *parent_dev,
++ const char *driver_override,
+ struct fsl_mc_device **new_mc_dev)
+ {
+ int error;
+@@ -535,6 +536,18 @@ int fsl_mc_device_add(struct dprc_obj_de
+
+ mc_dev->obj_desc = *obj_desc;
+ mc_dev->mc_io = mc_io;
++ if (driver_override) {
++ /*
++ * We trust driver_override, so we don't need to use
++ * kstrndup() here
++ */
++ mc_dev->driver_override = kstrdup(driver_override, GFP_KERNEL);
++ if (!mc_dev->driver_override) {
++ error = -ENOMEM;
++ goto error_cleanup_dev;
++ }
++ }
++
+ device_initialize(&mc_dev->dev);
+ mc_dev->dev.parent = parent_dev;
+ mc_dev->dev.bus = &fsl_mc_bus_type;
+@@ -858,7 +871,8 @@ static int fsl_mc_bus_probe(struct platf
+ obj_desc.irq_count = 1;
+ obj_desc.region_count = 0;
+
+- error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, &mc_bus_dev);
++ error = fsl_mc_device_add(&obj_desc, mc_io, &pdev->dev, NULL,
++ &mc_bus_dev);
+ if (error < 0)
+ goto error_cleanup_mc_io;
+
+--- a/drivers/staging/fsl-mc/include/mc-private.h
++++ b/drivers/staging/fsl-mc/include/mc-private.h
+@@ -110,6 +110,7 @@ struct fsl_mc_bus {
+ int __must_check fsl_mc_device_add(struct dprc_obj_desc *obj_desc,
+ struct fsl_mc_io *mc_io,
+ struct device *parent_dev,
++ const char *driver_override,
+ struct fsl_mc_device **new_mc_dev);
+
+ void fsl_mc_device_remove(struct fsl_mc_device *mc_dev);
+@@ -117,6 +118,7 @@ void fsl_mc_device_remove(struct fsl_mc_
+ int dprc_scan_container(struct fsl_mc_device *mc_bus_dev);
+
+ int dprc_scan_objects(struct fsl_mc_device *mc_bus_dev,
++ const char *driver_override,
+ unsigned int *total_irq_count);
+
+ int __init dprc_driver_init(void);
+--- a/drivers/staging/fsl-mc/include/mc.h
++++ b/drivers/staging/fsl-mc/include/mc.h
+@@ -129,6 +129,7 @@ struct fsl_mc_device_irq {
+ * @regions: pointer to array of MMIO region entries
+ * @irqs: pointer to array of pointers to interrupts allocated to this device
+ * @resource: generic resource associated with this MC object device, if any.
++ * @driver_override: Driver name to force a match
+ *
+ * Generic device object for MC object devices that are "attached" to a
+ * MC bus.
+@@ -161,6 +162,7 @@ struct fsl_mc_device {
+ struct resource *regions;
+ struct fsl_mc_device_irq **irqs;
+ struct fsl_mc_resource *resource;
++ const char *driver_override;
+ };
+
+ #define to_fsl_mc_device(_dev) \
--- /dev/null
+From 0bda83c15b2ecfc45fac0656df15d4f4fa65afa9 Mon Sep 17 00:00:00 2001
+From: Bharat Bhushan <bharat.bhushan@freescale.com>
+Date: Wed, 18 Mar 2015 17:32:59 -0500
+Subject: [PATCH 193/226] staging: fsl-mc: add device binding path
+ 'driver_override'
+
+This patch is required for vfio-fsl-mc meta driver to successfully bind
+layerscape container devices for device passthrough. This patch adds
+a mechanism to allow a layerscape device to specify a driver rather than
+a layerscape driver provide a device match.
+
+This patch is based on following proposed patches for PCI and platform devices
+- https://lkml.org/lkml/2014/4/8/571 :- For Platform devices
+- http://lists-archives.com/linux-kernel/28030441-pci-introduce-new-device-binding-path-using-pci_dev-driver_override.html :- For PCI devices
+
+Example to allow a device (dprc.1) to specifically bind
+with driver (vfio-fsl-mc):-
+- echo vfio-fsl-mc > /sys/bus/fsl-mc/devices/dprc.1/driver_override
+- echo dprc.1 > /sys/bus/fsl-mc/drivers/fsl_mc_dprc/unbind
+- echo dprc.1 > /sys/bus/fsl-mc/drivers/vfio-fsl-mc/bind
+
+Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
+(Stuart: resolved merge conflicts)
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 53 +++++++++++++++++++++++++++++++++++
+ 1 file changed, 53 insertions(+)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -42,6 +42,12 @@ static int fsl_mc_bus_match(struct devic
+ if (WARN_ON(!fsl_mc_bus_exists()))
+ goto out;
+
++ /* When driver_override is set, only bind to the matching driver */
++ if (mc_dev->driver_override) {
++ found = !strcmp(mc_dev->driver_override, mc_drv->driver.name);
++ goto out;
++ }
++
+ if (!mc_drv->match_id_table)
+ goto out;
+
+@@ -96,6 +102,50 @@ static ssize_t modalias_show(struct devi
+ }
+ static DEVICE_ATTR_RO(modalias);
+
++static ssize_t driver_override_store(struct device *dev,
++ struct device_attribute *attr,
++ const char *buf, size_t count)
++{
++ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
++ const char *driver_override, *old = mc_dev->driver_override;
++ char *cp;
++
++ if (WARN_ON(dev->bus != &fsl_mc_bus_type))
++ return -EINVAL;
++
++ if (count > PATH_MAX)
++ return -EINVAL;
++
++ driver_override = kstrndup(buf, count, GFP_KERNEL);
++ if (!driver_override)
++ return -ENOMEM;
++
++ cp = strchr(driver_override, '\n');
++ if (cp)
++ *cp = '\0';
++
++ if (strlen(driver_override)) {
++ mc_dev->driver_override = driver_override;
++ } else {
++ kfree(driver_override);
++ mc_dev->driver_override = NULL;
++ }
++
++ kfree(old);
++
++ return count;
++}
++
++static ssize_t driver_override_show(struct device *dev,
++ struct device_attribute *attr, char *buf)
++{
++ struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
++
++ return sprintf(buf, "%s\n", mc_dev->driver_override);
++}
++
++static DEVICE_ATTR_RW(driver_override);
++
+ static ssize_t rescan_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+@@ -127,6 +177,7 @@ static DEVICE_ATTR_WO(rescan);
+ static struct attribute *fsl_mc_dev_attrs[] = {
+ &dev_attr_modalias.attr,
+ &dev_attr_rescan.attr,
++ &dev_attr_driver_override.attr,
+ NULL,
+ };
+
+@@ -677,6 +728,8 @@ void fsl_mc_device_remove(struct fsl_mc_
+ }
+ }
+
++ kfree(mc_dev->driver_override);
++ mc_dev->driver_override = NULL;
+ if (mc_bus)
+ devm_kfree(mc_dev->dev.parent, mc_bus);
+ else
--- /dev/null
+From 552d628c887d970b9a97d8db2629adc4820fb8e3 Mon Sep 17 00:00:00 2001
+From: Bharat Bhushan <Bharat.Bhushan@freescale.com>
+Date: Thu, 16 Jul 2015 14:44:24 +0530
+Subject: [PATCH 194/226] staging: fsl-mc: export irq cleanup for vfio to use
+
+VFIO driver needs these basic functions for
+setting up itt/its of dprc's bound to it.
+
+Signed-off-by: Bharat Bhushan <Bharat.Bhushan@freescale.com>
+(Stuart: resolved merge conflict, commit log cleanup)
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+---
+ drivers/staging/fsl-mc/bus/dprc-driver.c | 4 ++--
+ drivers/staging/fsl-mc/include/mc-private.h | 4 ++++
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/dprc-driver.c
++++ b/drivers/staging/fsl-mc/bus/dprc-driver.c
+@@ -193,7 +193,7 @@ static void dprc_add_new_devices(struct
+ }
+ }
+
+-static void dprc_init_all_resource_pools(struct fsl_mc_device *mc_bus_dev)
++void dprc_init_all_resource_pools(struct fsl_mc_device *mc_bus_dev)
+ {
+ int pool_type;
+ struct fsl_mc_bus *mc_bus = to_fsl_mc_bus(mc_bus_dev);
+@@ -234,7 +234,7 @@ static void dprc_cleanup_resource_pool(s
+ WARN_ON(free_count != res_pool->free_count);
+ }
+
+-static void dprc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev)
++void dprc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev)
+ {
+ int pool_type;
+
+--- a/drivers/staging/fsl-mc/include/mc-private.h
++++ b/drivers/staging/fsl-mc/include/mc-private.h
+@@ -157,4 +157,8 @@ int fsl_mc_populate_irq_pool(struct fsl_
+
+ void fsl_mc_cleanup_irq_pool(struct fsl_mc_bus *mc_bus);
+
++void dprc_init_all_resource_pools(struct fsl_mc_device *mc_bus_dev);
++
++void dprc_cleanup_all_resource_pools(struct fsl_mc_device *mc_bus_dev);
++
+ #endif /* _FSL_MC_PRIVATE_H_ */
--- /dev/null
+From 71d19cd1107fa435d056e08e7d7ef7d8f714cf35 Mon Sep 17 00:00:00 2001
+From: Lijun Pan <Lijun.Pan@freescale.com>
+Date: Fri, 31 Jul 2015 15:07:32 -0500
+Subject: [PATCH 195/226] increment MC_CMD_COMPLETION_TIMEOUT_MS
+
+5000ms is barely enough for dpsw/dpdmux creation.
+If MC firmware could run faster, we would decrement the value later on.
+
+Signed-off-by: Lijun Pan <Lijun.Pan@freescale.com>
+(Stuart: resolved merge conflict)
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+---
+ drivers/staging/fsl-mc/bus/mc-sys.c | 38 +++++++++++++++--------------------
+ 1 file changed, 16 insertions(+), 22 deletions(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-sys.c
++++ b/drivers/staging/fsl-mc/bus/mc-sys.c
+@@ -43,8 +43,10 @@
+
+ /**
+ * Timeout in milliseconds to wait for the completion of an MC command
++ * 5000 ms is barely enough for dpsw/dpdmux creation
++ * TODO: if MC firmware could response faster, we should decrease this value
+ */
+-#define MC_CMD_COMPLETION_TIMEOUT_MS 500
++#define MC_CMD_COMPLETION_TIMEOUT_MS 5000
+
+ /*
+ * usleep_range() min and max values used to throttle down polling
+@@ -327,17 +329,8 @@ static int mc_polling_wait_preemptible(s
+ usleep_range(MC_CMD_COMPLETION_POLLING_MIN_SLEEP_USECS,
+ MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS);
+
+- if (time_after_eq(jiffies, jiffies_until_timeout)) {
+- dev_dbg(mc_io->dev,
+- "MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n",
+- mc_io->portal_phys_addr,
+- (unsigned int)
+- MC_CMD_HDR_READ_TOKEN(cmd->header),
+- (unsigned int)
+- MC_CMD_HDR_READ_CMDID(cmd->header));
+-
++ if (time_after_eq(jiffies, jiffies_until_timeout))
+ return -ETIMEDOUT;
+- }
+ }
+
+ *mc_status = status;
+@@ -369,17 +362,8 @@ static int mc_polling_wait_atomic(struct
+
+ udelay(MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS);
+ timeout_usecs -= MC_CMD_COMPLETION_POLLING_MAX_SLEEP_USECS;
+- if (timeout_usecs == 0) {
+- dev_dbg(mc_io->dev,
+- "MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n",
+- mc_io->portal_phys_addr,
+- (unsigned int)
+- MC_CMD_HDR_READ_TOKEN(cmd->header),
+- (unsigned int)
+- MC_CMD_HDR_READ_CMDID(cmd->header));
+-
++ if (timeout_usecs == 0)
+ return -ETIMEDOUT;
+- }
+ }
+
+ *mc_status = status;
+@@ -422,9 +406,19 @@ int mc_send_command(struct fsl_mc_io *mc
+ else
+ error = mc_polling_wait_atomic(mc_io, cmd, &status);
+
+- if (error < 0)
++ if (error < 0) {
++ if (error == -ETIMEDOUT) {
++ pr_debug("MC command timed out (portal: %#llx, obj handle: %#x, command: %#x)\n",
++ mc_io->portal_phys_addr,
++ (unsigned int)
++ MC_CMD_HDR_READ_TOKEN(cmd->header),
++ (unsigned int)
++ MC_CMD_HDR_READ_CMDID(cmd->header));
++ }
+ goto common_exit;
+
++ }
++
+ if (status != MC_CMD_STATUS_OK) {
+ dev_dbg(mc_io->dev,
+ "MC command failed: portal: %#llx, obj handle: %#x, command: %#x, status: %s (%#x)\n",
--- /dev/null
+From 12b1317fb3ab5b56efd833fa3b22965adf1d2c96 Mon Sep 17 00:00:00 2001
+From: Stuart Yoder <stuart.yoder@nxp.com>
+Date: Fri, 15 Apr 2016 17:07:16 -0500
+Subject: [PATCH 196/226] staging: fsl-mc: make fsl_mc_get_root_dprc public
+
+this is needed by other components (e.g. vfio) to find
+the root dprc
+
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+---
+ drivers/staging/fsl-mc/bus/mc-bus.c | 3 ++-
+ drivers/staging/fsl-mc/include/mc.h | 3 +++
+ 2 files changed, 5 insertions(+), 1 deletion(-)
+
+--- a/drivers/staging/fsl-mc/bus/mc-bus.c
++++ b/drivers/staging/fsl-mc/bus/mc-bus.c
+@@ -358,7 +358,7 @@ EXPORT_SYMBOL_GPL(fsl_mc_bus_exists);
+ /**
+ * fsl_mc_get_root_dprc - function to traverse to the root dprc
+ */
+-static void fsl_mc_get_root_dprc(struct device *dev,
++void fsl_mc_get_root_dprc(struct device *dev,
+ struct device **root_dprc_dev)
+ {
+ if (WARN_ON(!dev)) {
+@@ -371,6 +371,7 @@ static void fsl_mc_get_root_dprc(struct
+ *root_dprc_dev = (*root_dprc_dev)->parent;
+ }
+ }
++EXPORT_SYMBOL_GPL(fsl_mc_get_root_dprc);
+
+ static int get_dprc_attr(struct fsl_mc_io *mc_io,
+ int container_id, struct dprc_attributes *attr)
+--- a/drivers/staging/fsl-mc/include/mc.h
++++ b/drivers/staging/fsl-mc/include/mc.h
+@@ -191,6 +191,9 @@ void fsl_mc_driver_unregister(struct fsl
+
+ bool fsl_mc_bus_exists(void);
+
++void fsl_mc_get_root_dprc(struct device *dev,
++ struct device **root_dprc_dev);
++
+ int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev,
+ u16 mc_io_flags,
+ struct fsl_mc_io **new_mc_io);
--- /dev/null
+From fb4881d149742e4c5595aca8bf86c99d2ea155ad Mon Sep 17 00:00:00 2001
+From: Lijun Pan <Lijun.Pan@freescale.com>
+Date: Mon, 8 Feb 2016 17:40:18 -0600
+Subject: [PATCH 197/226] staging: fsl-mc: Management Complex restool driver
+
+The kernel support for the restool (a user space resource management
+tool) is a driver for the /dev/dprc.N device file.
+Its purpose is to provide an ioctl interface,
+which the restool uses to interact with the MC bus driver
+and with the MC firmware.
+We allocate a dpmcp at driver initialization,
+and keep that dpmcp until driver exit.
+We use that dpmcp by default.
+If that dpmcp is in use, we create another portal at run time
+and destroy the newly created portal after use.
+The ioctl RESTOOL_SEND_MC_COMMAND sends user space command to fsl-mc
+bus and utilizes the fsl-mc bus to communicate with MC firmware.
+The ioctl RESTOOL_DPRC_SYNC request the mc-bus launch
+objects scan under root dprc.
+In order to support multiple root dprc, we utilize the bus notify
+mechanism to scan fsl_mc_bus_type for the newly added root dprc.
+After discovering the root dprc, it creates a miscdevice
+/dev/dprc.N to associate with this root dprc.
+
+Signed-off-by: Lijun Pan <Lijun.Pan@freescale.com>
+[Stuart: minor fix to resolve compile error]
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+---
+ Documentation/ioctl/ioctl-number.txt | 1 +
+ drivers/staging/fsl-mc/bus/Kconfig | 7 +-
+ drivers/staging/fsl-mc/bus/Makefile | 3 +
+ drivers/staging/fsl-mc/bus/mc-ioctl.h | 22 ++
+ drivers/staging/fsl-mc/bus/mc-restool.c | 392 +++++++++++++++++++++++++++++++
+ 5 files changed, 424 insertions(+), 1 deletion(-)
+ create mode 100644 drivers/staging/fsl-mc/bus/mc-ioctl.h
+ create mode 100644 drivers/staging/fsl-mc/bus/mc-restool.c
+
+--- a/Documentation/ioctl/ioctl-number.txt
++++ b/Documentation/ioctl/ioctl-number.txt
+@@ -170,6 +170,7 @@ Code Seq#(hex) Include File Comments
+ 'R' 00-1F linux/random.h conflict!
+ 'R' 01 linux/rfkill.h conflict!
+ 'R' C0-DF net/bluetooth/rfcomm.h
++'R' E0-EF drivers/staging/fsl-mc/bus/mc-ioctl.h
+ 'S' all linux/cdrom.h conflict!
+ 'S' 80-81 scsi/scsi_ioctl.h conflict!
+ 'S' 82-FF scsi/scsi.h conflict!
+--- a/drivers/staging/fsl-mc/bus/Kconfig
++++ b/drivers/staging/fsl-mc/bus/Kconfig
+@@ -22,4 +22,9 @@ config FSL_MC_BUS
+ Only enable this option when building the kernel for
+ Freescale QorQIQ LS2xxxx SoCs.
+
+-
++config FSL_MC_RESTOOL
++ tristate "Freescale Management Complex (MC) restool driver"
++ depends on FSL_MC_BUS
++ help
++ Driver that provides kernel support for the Freescale Management
++ Complex resource manager user-space tool.
+--- a/drivers/staging/fsl-mc/bus/Makefile
++++ b/drivers/staging/fsl-mc/bus/Makefile
+@@ -18,3 +18,6 @@ mc-bus-driver-objs := mc-bus.o \
+ dpmcp.o \
+ dpbp.o \
+ dpcon.o
++
++# MC restool kernel support
++obj-$(CONFIG_FSL_MC_RESTOOL) += mc-restool.o
+--- /dev/null
++++ b/drivers/staging/fsl-mc/bus/mc-ioctl.h
+@@ -0,0 +1,22 @@
++/*
++ * Freescale Management Complex (MC) ioclt interface
++ *
++ * Copyright (C) 2014 Freescale Semiconductor, Inc.
++ * Author: Lijun Pan <Lijun.Pan@freescale.com>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2. This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ */
++#ifndef _FSL_MC_IOCTL_H_
++#define _FSL_MC_IOCTL_H_
++
++#include <linux/ioctl.h>
++#include "../include/mc-sys.h"
++
++#define RESTOOL_IOCTL_TYPE 'R'
++
++#define RESTOOL_SEND_MC_COMMAND \
++ _IOWR(RESTOOL_IOCTL_TYPE, 0xE0, struct mc_command)
++
++#endif /* _FSL_MC_IOCTL_H_ */
+--- /dev/null
++++ b/drivers/staging/fsl-mc/bus/mc-restool.c
+@@ -0,0 +1,392 @@
++/*
++ * Freescale Management Complex (MC) restool driver
++ *
++ * Copyright (C) 2014 Freescale Semiconductor, Inc.
++ * Author: Lijun Pan <Lijun.Pan@freescale.com>
++ *
++ * This file is licensed under the terms of the GNU General Public
++ * License version 2. This program is licensed "as is" without any
++ * warranty of any kind, whether express or implied.
++ */
++
++#include "../include/mc-private.h"
++#include <linux/module.h>
++#include <linux/fs.h>
++#include <linux/miscdevice.h>
++#include <linux/mm.h>
++#include <linux/slab.h>
++#include <linux/uaccess.h>
++#include <linux/mutex.h>
++#include <linux/platform_device.h>
++#include "mc-ioctl.h"
++#include "../include/mc-sys.h"
++#include "../include/mc-cmd.h"
++#include "../include/dpmng.h"
++
++/**
++ * Maximum number of DPRCs that can be opened at the same time
++ */
++#define MAX_DPRC_HANDLES 64
++
++/**
++ * restool_misc - information associated with the newly added miscdevice
++ * @misc: newly created miscdevice associated with root dprc
++ * @miscdevt: device id of this miscdevice
++ * @list: a linked list node representing this miscdevcie
++ * @static_mc_io: pointer to the static MC I/O object used by the restool
++ * @dynamic_instance_count: number of dynamically created instances
++ * @static_instance_in_use: static instance is in use or not
++ * @mutex: mutex lock to serialze the open/release operations
++ * @dev: root dprc associated with this miscdevice
++ */
++struct restool_misc {
++ struct miscdevice misc;
++ dev_t miscdevt;
++ struct list_head list;
++ struct fsl_mc_io *static_mc_io;
++ u32 dynamic_instance_count;
++ bool static_instance_in_use;
++ struct mutex mutex; /* serialze the open/release operations */
++ struct device *dev;
++};
++
++/*
++ * initialize a global list to link all
++ * the miscdevice nodes (struct restool_misc)
++ */
++static LIST_HEAD(misc_list);
++static DEFINE_MUTEX(misc_list_mutex);
++
++static int fsl_mc_restool_dev_open(struct inode *inode, struct file *filep)
++{
++ struct fsl_mc_device *root_mc_dev;
++ int error;
++ struct fsl_mc_io *dynamic_mc_io = NULL;
++ struct restool_misc *restool_misc = NULL;
++ struct restool_misc *restool_misc_cursor;
++
++ mutex_lock(&misc_list_mutex);
++
++ list_for_each_entry(restool_misc_cursor, &misc_list, list) {
++ if (restool_misc_cursor->miscdevt == inode->i_rdev) {
++ restool_misc = restool_misc_cursor;
++ break;
++ }
++ }
++
++ mutex_unlock(&misc_list_mutex);
++
++ if (!restool_misc)
++ return -EINVAL;
++
++ if (WARN_ON(!restool_misc->dev))
++ return -EINVAL;
++
++ mutex_lock(&restool_misc->mutex);
++
++ if (!restool_misc->static_instance_in_use) {
++ restool_misc->static_instance_in_use = true;
++ filep->private_data = restool_misc->static_mc_io;
++ } else {
++ dynamic_mc_io = kzalloc(sizeof(*dynamic_mc_io), GFP_KERNEL);
++ if (!dynamic_mc_io) {
++ error = -ENOMEM;
++ goto err_unlock;
++ }
++
++ root_mc_dev = to_fsl_mc_device(restool_misc->dev);
++ error = fsl_mc_portal_allocate(root_mc_dev, 0, &dynamic_mc_io);
++ if (error < 0) {
++ pr_err("Not able to allocate MC portal\n");
++ goto free_dynamic_mc_io;
++ }
++ ++restool_misc->dynamic_instance_count;
++ filep->private_data = dynamic_mc_io;
++ }
++
++ mutex_unlock(&restool_misc->mutex);
++
++ return 0;
++
++free_dynamic_mc_io:
++ kfree(dynamic_mc_io);
++err_unlock:
++ mutex_unlock(&restool_misc->mutex);
++
++ return error;
++}
++
++static int fsl_mc_restool_dev_release(struct inode *inode, struct file *filep)
++{
++ struct fsl_mc_io *local_mc_io = filep->private_data;
++ struct restool_misc *restool_misc = NULL;
++ struct restool_misc *restool_misc_cursor;
++
++ if (WARN_ON(!filep->private_data))
++ return -EINVAL;
++
++ mutex_lock(&misc_list_mutex);
++
++ list_for_each_entry(restool_misc_cursor, &misc_list, list) {
++ if (restool_misc_cursor->miscdevt == inode->i_rdev) {
++ restool_misc = restool_misc_cursor;
++ break;
++ }
++ }
++
++ mutex_unlock(&misc_list_mutex);
++
++ if (!restool_misc)
++ return -EINVAL;
++
++ mutex_lock(&restool_misc->mutex);
++
++ if (WARN_ON(restool_misc->dynamic_instance_count == 0 &&
++ !restool_misc->static_instance_in_use)) {
++ mutex_unlock(&restool_misc->mutex);
++ return -EINVAL;
++ }
++
++ /* Globally clean up opened/untracked handles */
++ fsl_mc_portal_reset(local_mc_io);
++
++ /*
++ * must check
++ * whether local_mc_io is dynamic or static instance
++ * Otherwise it will free up the reserved portal by accident
++ * or even not free up the dynamic allocated portal
++ * if 2 or more instances running concurrently
++ */
++ if (local_mc_io == restool_misc->static_mc_io) {
++ restool_misc->static_instance_in_use = false;
++ } else {
++ fsl_mc_portal_free(local_mc_io);
++ kfree(filep->private_data);
++ --restool_misc->dynamic_instance_count;
++ }
++
++ filep->private_data = NULL;
++ mutex_unlock(&restool_misc->mutex);
++
++ return 0;
++}
++
++static int restool_send_mc_command(unsigned long arg,
++ struct fsl_mc_io *local_mc_io)
++{
++ int error;
++ struct mc_command mc_cmd;
++
++ if (copy_from_user(&mc_cmd, (void __user *)arg, sizeof(mc_cmd)))
++ return -EFAULT;
++
++ /*
++ * Send MC command to the MC:
++ */
++ error = mc_send_command(local_mc_io, &mc_cmd);
++ if (error < 0)
++ return error;
++
++ if (copy_to_user((void __user *)arg, &mc_cmd, sizeof(mc_cmd)))
++ return -EFAULT;
++
++ return 0;
++}
++
++static long
++fsl_mc_restool_dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
++{
++ int error;
++
++ switch (cmd) {
++ case RESTOOL_SEND_MC_COMMAND:
++ error = restool_send_mc_command(arg, file->private_data);
++ break;
++ default:
++ pr_err("%s: unexpected ioctl call number\n", __func__);
++ error = -EINVAL;
++ }
++
++ return error;
++}
++
++static const struct file_operations fsl_mc_restool_dev_fops = {
++ .owner = THIS_MODULE,
++ .open = fsl_mc_restool_dev_open,
++ .release = fsl_mc_restool_dev_release,
++ .unlocked_ioctl = fsl_mc_restool_dev_ioctl,
++};
++
++static int restool_add_device_file(struct device *dev)
++{
++ u32 name1 = 0;
++ char name2[20] = {0};
++ int error;
++ struct fsl_mc_device *root_mc_dev;
++ struct restool_misc *restool_misc;
++
++ if (dev->bus == &platform_bus_type && dev->driver_data) {
++ if (sscanf(dev_name(dev), "%x.%s", &name1, name2) != 2)
++ return -EINVAL;
++
++ if (strcmp(name2, "fsl-mc") == 0)
++ pr_debug("platform's root dprc name is: %s\n",
++ dev_name(&(((struct fsl_mc *)
++ (dev->driver_data))->root_mc_bus_dev->dev)));
++ }
++
++ if (!fsl_mc_is_root_dprc(dev))
++ return 0;
++
++ restool_misc = kzalloc(sizeof(*restool_misc), GFP_KERNEL);
++ if (!restool_misc)
++ return -ENOMEM;
++
++ restool_misc->dev = dev;
++ root_mc_dev = to_fsl_mc_device(dev);
++ error = fsl_mc_portal_allocate(root_mc_dev, 0,
++ &restool_misc->static_mc_io);
++ if (error < 0) {
++ pr_err("Not able to allocate MC portal\n");
++ goto free_restool_misc;
++ }
++
++ restool_misc->misc.minor = MISC_DYNAMIC_MINOR;
++ restool_misc->misc.name = dev_name(dev);
++ restool_misc->misc.fops = &fsl_mc_restool_dev_fops;
++
++ error = misc_register(&restool_misc->misc);
++ if (error < 0) {
++ pr_err("misc_register() failed: %d\n", error);
++ goto free_portal;
++ }
++
++ restool_misc->miscdevt = restool_misc->misc.this_device->devt;
++ mutex_init(&restool_misc->mutex);
++ mutex_lock(&misc_list_mutex);
++ list_add(&restool_misc->list, &misc_list);
++ mutex_unlock(&misc_list_mutex);
++
++ pr_info("/dev/%s driver registered\n", dev_name(dev));
++
++ return 0;
++
++free_portal:
++ fsl_mc_portal_free(restool_misc->static_mc_io);
++free_restool_misc:
++ kfree(restool_misc);
++
++ return error;
++}
++
++static int restool_bus_notifier(struct notifier_block *nb,
++ unsigned long action, void *data)
++{
++ int error;
++ struct device *dev = data;
++
++ switch (action) {
++ case BUS_NOTIFY_ADD_DEVICE:
++ error = restool_add_device_file(dev);
++ if (error)
++ return error;
++ break;
++ case BUS_NOTIFY_DEL_DEVICE:
++ case BUS_NOTIFY_REMOVED_DEVICE:
++ case BUS_NOTIFY_BIND_DRIVER:
++ case BUS_NOTIFY_BOUND_DRIVER:
++ case BUS_NOTIFY_UNBIND_DRIVER:
++ case BUS_NOTIFY_UNBOUND_DRIVER:
++ break;
++ default:
++ pr_err("%s: unrecognized device action from %s\n", __func__,
++ dev_name(dev));
++ return -EINVAL;
++ }
++
++ return 0;
++}
++
++static int add_to_restool(struct device *dev, void *data)
++{
++ return restool_add_device_file(dev);
++}
++
++static int __init fsl_mc_restool_driver_init(void)
++{
++ int error;
++ struct notifier_block *nb;
++
++ nb = kzalloc(sizeof(*nb), GFP_KERNEL);
++ if (!nb)
++ return -ENOMEM;
++
++ nb->notifier_call = restool_bus_notifier;
++ error = bus_register_notifier(&fsl_mc_bus_type, nb);
++ if (error)
++ goto free_nb;
++
++ /*
++ * This driver runs after fsl-mc bus driver runs.
++ * Hence, many of the root dprcs are already attached to fsl-mc bus
++ * In order to make sure we find all the root dprcs,
++ * we need to scan the fsl_mc_bus_type.
++ */
++ error = bus_for_each_dev(&fsl_mc_bus_type, NULL, NULL, add_to_restool);
++ if (error) {
++ bus_unregister_notifier(&fsl_mc_bus_type, nb);
++ kfree(nb);
++ pr_err("restool driver registration failure\n");
++ return error;
++ }
++
++ return 0;
++
++free_nb:
++ kfree(nb);
++ return error;
++}
++
++module_init(fsl_mc_restool_driver_init);
++
++static void __exit fsl_mc_restool_driver_exit(void)
++{
++ struct restool_misc *restool_misc;
++ struct restool_misc *restool_misc_tmp;
++ char name1[20] = {0};
++ u32 name2 = 0;
++
++ list_for_each_entry_safe(restool_misc, restool_misc_tmp,
++ &misc_list, list) {
++ if (sscanf(restool_misc->misc.name, "%4s.%u", name1, &name2)
++ != 2)
++ continue;
++
++ pr_debug("name1=%s,name2=%u\n", name1, name2);
++ pr_debug("misc-device: %s\n", restool_misc->misc.name);
++ if (strcmp(name1, "dprc") != 0)
++ continue;
++
++ if (WARN_ON(!restool_misc->static_mc_io))
++ return;
++
++ if (WARN_ON(restool_misc->dynamic_instance_count != 0))
++ return;
++
++ if (WARN_ON(restool_misc->static_instance_in_use))
++ return;
++
++ misc_deregister(&restool_misc->misc);
++ pr_info("/dev/%s driver unregistered\n",
++ restool_misc->misc.name);
++ fsl_mc_portal_free(restool_misc->static_mc_io);
++ list_del(&restool_misc->list);
++ kfree(restool_misc);
++ }
++}
++
++module_exit(fsl_mc_restool_driver_exit);
++
++MODULE_AUTHOR("Freescale Semiconductor Inc.");
++MODULE_DESCRIPTION("Freescale's MC restool driver");
++MODULE_LICENSE("GPL");
--- /dev/null
+From 331b26080961f0289c3a8a8e5e65f6524b23be19 Mon Sep 17 00:00:00 2001
+From: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com>
+Date: Tue, 7 Apr 2015 23:24:55 -0400
+Subject: [PATCH 198/226] staging: fsl-mc: dpio services driver
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This is a commit of a squash of the cummulative dpio services patches
+in the sdk 2.0 kernel as of 3/7/2016.
+
+staging: fsl-mc: dpio: initial implementation of dpio services
+
+* Port from kernel 3.16 to 3.19
+* upgrade to match MC fw 7.0.0
+* return -EPROBE_DEFER if fsl_mc_portal_allocate() fails.
+* enable DPIO interrupt support
+* implement service FQDAN handling
+* DPIO service selects DPIO objects using crude algorithms for now, we
+ will look to make this smarter later on.
+* Locks all DPIO ops that aren't innately lockless. Smarter selection
+ logic may allow locking to be relaxed eventually.
+* Portable QBMan driver source (and low-level MC flib code for DPIO) is
+ included and encapsulated within the DPIO driver.
+
+Signed-off-by: Geoff Thorpe <Geoff.Thorpe@freescale.com>
+Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
+Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
+Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
+Signed-off-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
+Signed-off-by: Cristian Sovaiala <cristian.sovaiala@freescale.com>
+Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
+Signed-off-by: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com>
+[Stuart: resolved merge conflicts]
+Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
+
+dpio: Use locks when querying fq state
+
+merged from patch in 3.19-bringup branch.
+
+Signed-off-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
+Signed-off-by: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com>
+Change-Id: Ia4d09f8a0cf4d8a4a2aa1cb39be789c34425286d
+Reviewed-on: http://git.am.freescale.net:8181/34707
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+
+qbman: Fix potential race in VDQCR handling
+
+Remove atomic_read() check of the VDQCR busy marker. These checks were racy
+as the flag could be incorrectly cleared if checked while another thread was
+starting a pull command. The check is unneeded since we can determine the
+owner of the outstanding pull command through other means.
+
+Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
+Change-Id: Icc64577c0a4ce6dadef208975e980adfc6796c86
+Reviewed-on: http://git.am.freescale.net:8181/34705
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com>
+Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+
+dpio: Fix IRQ handler and remove useless spinlock
+
+The IRQ handler for a threaded IRQ requires two parts: initally the handler
+should check status and inhibit the IRQ then the threaded portion should
+process and reenable.
+
+Also remove a spinlock that was redundant with the QMan driver and a debug
+check that could trigger under a race condition
+
+Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
+Signed-off-by: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com>
+Change-Id: I64926583af0be954228de94ae354fa005c8ec88a
+Reviewed-on: http://git.am.freescale.net:8181/34706
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com>
+Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+
+staging: fsl-mc: dpio: Implement polling if IRQ not available
+
+Temporarly add a polling mode to DPIO in the case that the IRQ
+registration fails
+
+Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
+Change-Id: Iebbd488fd14dd9878ef846e40f3ebcbcd0eb1e80
+Reviewed-on: http://git.am.freescale.net:8181/34775
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Jeffrey Ladouceur <Jeffrey.Ladouceur@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+
+fsl-mc-dpio: Fix to make this work without interrupt
+
+Some additional fixes to make dpio driver work in poll mode.
+This is needed for direct assignment to KVM Guest.
+
+Signed-off-by: Bharat Bhushan <Bharat.Bhushan@freescale.com>
+Change-Id: Icf66b8c0c7f7e1610118f78396534c067f594934
+Reviewed-on: http://git.am.freescale.net:8181/35333
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+
+fsl-mc-dpio: Make QBMan token tracking internal
+
+Previousy the QBMan portal code required the caller to properly set and
+check for a token value used by the driver to detect when the QMan
+hardware had completed a dequeue. This patch simplifes the driver
+interface by internally dealing with token values. The driver will now
+set the token value to 0 once it has dequeued a frame while a token
+value of 1 indicates the HW has completed the dequeue but SW has not
+consumed the frame yet.
+
+Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
+Change-Id: If94d9728b0faa0fd79b47108f5cb05a425b89c18
+Reviewed-on: http://git.am.freescale.net:8181/35433
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+
+fsl-mc-dpio: Distribute DPIO IRQs among cores
+
+Configure the DPIO IRQ affinities across all available cores
+
+Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
+Change-Id: Ib45968a070460b7e9410bfe6067b20ecd3524c54
+Reviewed-on: http://git.am.freescale.net:8181/35540
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Haiying Wang <Haiying.Wang@freescale.com>
+Reviewed-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+
+dpio/qbman: add flush after finishing cena write
+
+Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
+Change-Id: I19537f101f7f5b443d60c0ad0e5d96c1dc302223
+Reviewed-on: http://git.am.freescale.net:8181/35854
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+
+dpio/qbman: rename qbman_dq_entry to qbman_result
+
+Currently qbman_dq_entry is used for both dq result in dqrr
+and memory, and notifications in dqrr and memory. It doesn't
+make sense to have dq_entry in name for those notifications
+which have nothing to do with dq. So we rename this as
+qbman_result which is meaningful for both cases.
+
+Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
+Change-Id: I62b3e729c571a1195e8802a9fab3fca97a14eae4
+Reviewed-on: http://git.am.freescale.net:8181/35535
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+
+dpio/qbman: add APIs to parse BPSCN and CGCU
+
+BPSCN and CGCU are notifications which can only be written to memory.
+We need to consider the host endianness while parsing these notification.
+Also modify the check of FQRN/CSCN_MEM with the same consideration.
+
+Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
+Change-Id: I572e0aa126107aed40e1ce326d5df7956882a939
+Reviewed-on: http://git.am.freescale.net:8181/35536
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+
+dpio/qbman: remove EXPORT_SYMBOL for qbman APIs
+
+because they are only used by dpio.
+
+Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
+Change-Id: I12e7b81c2d32f3c7b3df9fd73b742b1b675f4b8b
+Reviewed-on: http://git.am.freescale.net:8181/35537
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+
+dpio/qbman: add invalidate and prefetch support
+
+for cachable memory access.
+Also remove the redundant memory barriers.
+
+Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
+Change-Id: I452a768278d1c5ef37e5741e9b011d725cb57b30
+Reviewed-on: http://git.am.freescale.net:8181/35873
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+
+dpio-driver: Fix qman-portal interrupt masking in poll mode
+
+DPIO driver should mask qman-portal interrupt reporting When
+working in poll mode. has_irq flag is used for same, but
+interrupt maksing was happening before it was decided that
+system will work in poll mode of interrupt mode.
+
+This patch fixes the issue and not irq masking/enabling is
+happening after irq/poll mode is decided.
+
+Signed-off-by: Bharat Bhushan <Bharat.Bhushan@freescale.com>
+Change-Id: I44de07b6142e80b3daea45e7d51a2d2799b2ed8d
+Reviewed-on: http://git.am.freescale.net:8181/37100
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Roy Pledge <roy.pledge@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+(cherry picked from commit 3579244250dcb287a0fe58bcc3b3780076d040a2)
+
+dpio: Add a function to query buffer pool depth
+
+Add a debug function thay allows users to query the number
+of buffers in a specific buffer pool
+
+Signed-off-by: Roy Pledge <Roy.Pledge@freescale.com>
+Change-Id: Ie9a5f2e86d6a04ae61868bcc807121780c53cf6c
+Reviewed-on: http://git.am.freescale.net:8181/36069
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+(cherry picked from commit 3c749d860592f62f6b219232580ca35fd1075337)
+
+dpio: Use normal cachable non-shareable memory for qbman cena
+
+QBMan SWP CENA portal memory requires the memory to be cacheable,
+and non-shareable.
+
+Signed-off-by: Haiying Wang <Haiying.Wang@freescale.com>
+Change-Id: I1c01cffe9ff2503fea2396d7cc761508f6e1ca85
+Reviewed-on: http://git.am.freescale.net:8181/35487
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+(cherry picked from commit 2a7e1ede7e155d9219006999893912e0b029ce4c)
+
+fsl-dpio: Process frames in IRQ context
+
+Stop using threaded IRQs and move back to hardirq top-halves.
+This is the first patch of a small series adapting the DPIO and Ethernet
+code to these changes.
+
+Signed-off-by: Roy Pledge <roy.pledge@freescale.com>
+Tested-by: Ioana Radulescu <ruxandra.radulescu@freescale.com>
+Tested-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
+Tested-by: Review Code-CDREVIEW <CDREVIEW@freescale.com>
+Reviewed-by: Bogdan Hamciuc <bogdan.hamciuc@freescale.com>
+Reviewed-by: Stuart Yoder <stuart.yoder@freescale.com>
+[Stuart: split out dpaa-eth part separately]
+Signed-off-by: Stuart Yoder <stuart.yoder@freescale.com>
+
+fsl-dpio: Fast DPIO object selection
+
+The DPIO service code had a couple of problems with performance impact:
+ - The&nb