layerscape: add ls1088ardb device support

LS1088A is an ARMv8 implementation combining eight ARM A53 processor
cores. The LS1088ARDB is an evaluatoin platform that supports the
LS1088A family SoCs.

Features summary:
- Eight 64-bit ARM v8 Cortex-A53 CPUs
- Data path acceleration architecture 2.0 (DPAA2)
- Ethernet interfaces
- QUADSPI flash, 3 PCIe, 2 USB, 1 SD, 2 DUARTs etc

Signed-off-by: Yutang Jiang <yutang.jiang@nxp.com>
This commit is contained in:
Yutang Jiang 2016-12-24 01:11:32 +08:00 committed by Jo-Philipp Wich
parent c6d3a62919
commit 1866368a8a
90 changed files with 44749 additions and 0 deletions

View file

@ -169,6 +169,8 @@ CONFIG_I2C=y
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
@ -296,3 +298,14 @@ CONFIG_XPS=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

View file

@ -92,4 +92,18 @@ endif
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))

View file

@ -0,0 +1,790 @@
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 */
+ };
+};

View file

@ -0,0 +1,69 @@
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";
+ };
+ };
+};

View file

@ -0,0 +1,62 @@
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>;

View file

@ -0,0 +1,44 @@
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 {

View file

@ -0,0 +1,53 @@
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;

View file

@ -0,0 +1,400 @@
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

View file

@ -0,0 +1,167 @@
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_ */

View file

@ -0,0 +1,326 @@
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_ */

View file

@ -0,0 +1,44 @@
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;

View file

@ -0,0 +1,109 @@
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);

View file

@ -0,0 +1,103 @@
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;
}

View file

@ -0,0 +1,72 @@
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;
}

View file

@ -0,0 +1,301 @@
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);

View file

@ -0,0 +1,59 @@
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);

View file

@ -0,0 +1,39 @@
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)) {

View file

@ -0,0 +1,30 @@
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

View file

@ -0,0 +1,43 @@
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,

View file

@ -0,0 +1,45 @@
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,

View file

@ -0,0 +1,43 @@
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;

View file

@ -0,0 +1,73 @@
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);

View file

@ -0,0 +1,96 @@
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),

View file

@ -0,0 +1,83 @@
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;
}

View file

@ -0,0 +1,48 @@
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),

View file

@ -0,0 +1,38 @@
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;
}

View file

@ -0,0 +1,207 @@
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);

View file

@ -0,0 +1,49 @@
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

View file

@ -0,0 +1,279 @@
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.

View file

@ -0,0 +1,123 @@
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

View file

@ -0,0 +1,208 @@
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 */

View file

@ -0,0 +1,206 @@
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,

View file

@ -0,0 +1,136 @@
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);

View file

@ -0,0 +1,29 @@
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()
*/

View file

@ -0,0 +1,30 @@
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;

View file

@ -0,0 +1,106 @@
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;

View file

@ -0,0 +1,90 @@
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) \

View file

@ -0,0 +1,38 @@
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",

View file

@ -0,0 +1,56 @@
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;

View file

@ -0,0 +1,30 @@
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;

View file

@ -0,0 +1,47 @@
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;
}
/**

View file

@ -0,0 +1,54 @@
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);

View file

@ -0,0 +1,32 @@
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;
}

View file

@ -0,0 +1,85 @@
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;
};
/**

View file

@ -0,0 +1,98 @@
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)
{

View file

@ -0,0 +1,23 @@
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.

View file

@ -0,0 +1,77 @@
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_ */

View file

@ -0,0 +1,62 @@
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;
}

View file

@ -0,0 +1,28 @@
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);
}

View file

@ -0,0 +1,41 @@
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;

View file

@ -0,0 +1,48 @@
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)

View file

@ -0,0 +1,964 @@
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 */

View file

@ -0,0 +1,59 @@
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,
};

View file

@ -0,0 +1,78 @@
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);

View file

@ -0,0 +1,193 @@
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) \

View file

@ -0,0 +1,111 @@
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

View file

@ -0,0 +1,47 @@
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_ */

View file

@ -0,0 +1,88 @@
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",

View file

@ -0,0 +1,45 @@
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);

View file

@ -0,0 +1,489 @@
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");

View file

@ -0,0 +1,35 @@
From a4150e8ec8da3add3933dd026c7154dcca2ee2e7 Mon Sep 17 00:00:00 2001
From: Mihai Caraman <mihai.caraman@freescale.com>
Date: Tue, 5 Apr 2016 14:47:57 +0000
Subject: [PATCH 199/226] dpaa2-dpio: Cosmetic cleanup
Replace obsolete terms.
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
drivers/staging/fsl-mc/bus/dpio/fsl_qbman_base.h | 2 +-
drivers/staging/fsl-mc/bus/dpio/qbman_portal.h | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/staging/fsl-mc/bus/dpio/fsl_qbman_base.h
+++ b/drivers/staging/fsl-mc/bus/dpio/fsl_qbman_base.h
@@ -51,7 +51,7 @@ struct qbman_block_desc {
* Descriptor for a QBMan software portal, expressed in terms that make sense to
* the user context. Ie. on MC, this information is likely to be true-physical,
* and instantiated statically at compile-time. On GPP, this information is
- * likely to be obtained via "discovery" over a partition's "layerscape bus"
+ * likely to be obtained via "discovery" over a partition's "MC bus"
* (ie. in response to a MC portal command), and would take into account any
* virtualisation of the GPP user's address space and/or interrupt numbering.
*/
--- a/drivers/staging/fsl-mc/bus/dpio/qbman_portal.h
+++ b/drivers/staging/fsl-mc/bus/dpio/qbman_portal.h
@@ -138,7 +138,7 @@ static inline void *qbman_swp_mc_complet
/* This struct locates a sub-field within a QBMan portal (CENA) cacheline which
* is either serving as a configuration command or a query result. The
* representation is inherently little-endian, as the indexing of the words is
- * itself little-endian in nature and layerscape is little endian for anything
+ * itself little-endian in nature and DPAA2 is little endian for anything
* that crosses a word boundary too (64-bit fields are the obvious examples).
*/
struct qb_attr_code {

View file

@ -0,0 +1,26 @@
From 3cc23880ecb98efe2d868254201ac58f945d9e1d Mon Sep 17 00:00:00 2001
From: Stuart Yoder <stuart.yoder@nxp.com>
Date: Wed, 15 Jun 2016 14:05:08 -0500
Subject: [PATCH 200/226] staging: fsl-mc: dpio driver match id cleanup
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
drivers/staging/fsl-mc/bus/dpio/dpio-drv.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/staging/fsl-mc/bus/dpio/dpio-drv.c
+++ b/drivers/staging/fsl-mc/bus/dpio/dpio-drv.c
@@ -364,12 +364,10 @@ err_mcportal:
return err;
}
-static const struct fsl_mc_device_match_id dpaa2_dpio_match_id_table[] = {
+static const struct fsl_mc_device_id dpaa2_dpio_match_id_table[] = {
{
.vendor = FSL_MC_VENDOR_FREESCALE,
.obj_type = "dpio",
- .ver_major = DPIO_VER_MAJOR,
- .ver_minor = DPIO_VER_MINOR
},
{ .vendor = 0x0 }
};

View file

@ -0,0 +1,37 @@
From 727de4692d731655dea96702aa099f4f4d3a5203 Mon Sep 17 00:00:00 2001
From: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
Date: Mon, 21 Mar 2016 16:10:01 +0200
Subject: [PATCH 203/226] fsl-dpaa2: eth: Update description of DPNI counters
Update description of DPNI counters presented with "ethtool -S".
Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
(cherry picked from commit f68aab60355d00af13fdff2ded7bf38809beacd3)
---
drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c
@@ -39,15 +39,18 @@
char dpaa2_ethtool_stats[][ETH_GSTRING_LEN] = {
"rx frames",
"rx bytes",
- "rx frames dropped",
- "rx err frames",
+ /* rx frames filtered/policed */
+ "rx filtered frames",
+ /* rx frames dropped with errors */
+ "rx discarded frames",
"rx mcast frames",
"rx mcast bytes",
"rx bcast frames",
"rx bcast bytes",
"tx frames",
"tx bytes",
- "tx err frames",
+ /* tx frames dropped with errors */
+ "tx discarded frames",
};
#define DPAA2_ETH_NUM_STATS ARRAY_SIZE(dpaa2_ethtool_stats)

View file

@ -0,0 +1,38 @@
From 9a38e2ce3b46a2bdc90b4ad190a26f9418909450 Mon Sep 17 00:00:00 2001
From: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
Date: Tue, 29 Mar 2016 13:23:50 +0300
Subject: [PATCH 204/226] fsl-dpaa2: eth: dpni: Clear compiler warnings
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Clear two warnings given by -Wcast-qual:
warning: cast discards __attribute__((const)) qualifier from pointer
target type
Signed-off-by: Bogdan Hamciuc <bogdan.hamciuc@nxp.com>
(cherry picked from commit 96d14f291c2750e8b09268cecb84bfe7f013294d)
---
drivers/staging/fsl-dpaa2/ethernet/dpni.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/staging/fsl-dpaa2/ethernet/dpni.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpni.c
@@ -128,7 +128,7 @@ int dpni_prepare_extended_cfg(const stru
int dpni_extract_extended_cfg(struct dpni_extended_cfg *cfg,
const uint8_t *ext_cfg_buf)
{
- uint64_t *ext_params = (uint64_t *)ext_cfg_buf;
+ const uint64_t *ext_params = (const uint64_t *)ext_cfg_buf;
DPNI_EXT_EXTENDED_CFG(ext_params, cfg);
@@ -1651,7 +1651,7 @@ void dpni_prepare_early_drop(const struc
void dpni_extract_early_drop(struct dpni_early_drop_cfg *cfg,
const uint8_t *early_drop_buf)
{
- uint64_t *ext_params = (uint64_t *)early_drop_buf;
+ const uint64_t *ext_params = (const uint64_t *)early_drop_buf;
DPNI_EXT_EARLY_DROP(ext_params, cfg);
}

View file

@ -0,0 +1,57 @@
From 51106cb1fd14dfbf62c2760921463376f56ac732 Mon Sep 17 00:00:00 2001
From: Bogdan Purcareata <bogdan.purcareata@nxp.com>
Date: Tue, 21 Jun 2016 18:40:47 +0000
Subject: [PATCH 205/226] fsl-dpaa2: eth: sanitize supported private flags
On linux-v4.6 with CONFIG_MACVLAN=y, when bringing up a ni interface, the
network stack crashes due to a segfault. This is related to the
macvlan_device_event notifier, which registers itself to all the network
interface in the system.
The notifier reads the netdev private flags and incorrectly qualifies
the interface as a macvlan port, since both the IFF_MACVLAN_PORT and
IFF_PROMISC flags have the same offset. Code spelunking reveals that
IFF_PROMISC is only used as an interface flag, not a private interface
flag.
A similar situation happens with IFF_ALLMULTI, which overlaps with
IFF_BRIDGE_PORT. No info on the consequences of this, since I haven't
tested bridge scenarios. The interface can still be set in allmulti
mode using userspace tools (e.g. ifconfig).
IFF_MULTICAST overlaps with IFF_UNICAST_FLT, therefore the current code
has no effect as it is. The closest multicast activation based on device
capabilities has been seen in the case of the Aeroflex Gaisler Ethernet
MAC (aeroflex/greth.c) - here, the runtime (not private) flag is set on
device probe. On a side node, ether_setup enables IFF_MULTICAST by default.
Remove IFF_PROMISC, IFF_ALLMULTI and IFF_MULTICAST from device capabilities
init.
Signed-off-by: Bogdan Purcareata <bogdan.purcareata@nxp.com>
---
drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -1176,18 +1176,13 @@ static int dpaa2_eth_init(struct net_dev
u32 options = priv->dpni_attrs.options;
/* Capabilities listing */
- supported |= IFF_LIVE_ADDR_CHANGE | IFF_PROMISC | IFF_ALLMULTI;
+ supported |= IFF_LIVE_ADDR_CHANGE;
if (options & DPNI_OPT_UNICAST_FILTER)
supported |= IFF_UNICAST_FLT;
else
not_supported |= IFF_UNICAST_FLT;
- if (options & DPNI_OPT_MULTICAST_FILTER)
- supported |= IFF_MULTICAST;
- else
- not_supported |= IFF_MULTICAST;
-
net_dev->priv_flags |= supported;
net_dev->priv_flags &= ~not_supported;

View file

@ -0,0 +1,26 @@
From 7e536d0c2f870b39480268c20af6fc3d21abe611 Mon Sep 17 00:00:00 2001
From: Stuart Yoder <stuart.yoder@nxp.com>
Date: Wed, 15 Jun 2016 14:03:43 -0500
Subject: [PATCH 206/226] fsl-dpaa2: eth: match id cleanup
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -2787,12 +2787,10 @@ static int dpaa2_eth_remove(struct fsl_m
return 0;
}
-static const struct fsl_mc_device_match_id dpaa2_eth_match_id_table[] = {
+static const struct fsl_mc_device_id dpaa2_eth_match_id_table[] = {
{
.vendor = FSL_MC_VENDOR_FREESCALE,
.obj_type = "dpni",
- .ver_major = DPNI_VER_MAJOR,
- .ver_minor = DPNI_VER_MINOR
},
{ .vendor = 0x0 }
};

View file

@ -0,0 +1,22 @@
From 8557c8a3823b341607e16048d8318a1958eab3a9 Mon Sep 17 00:00:00 2001
From: Stuart Yoder <stuart.yoder@nxp.com>
Date: Thu, 12 May 2016 17:52:28 -0500
Subject: [PATCH 207/226] fsl-dpaa2: eth: add device table to driver
this is needed to have the driver loaded as a module
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -2794,6 +2794,7 @@ static const struct fsl_mc_device_id dpa
},
{ .vendor = 0x0 }
};
+MODULE_DEVICE_TABLE(fslmc, dpaa2_eth_match_id_table);
static struct fsl_mc_driver dpaa2_eth_driver = {
.driver = {

View file

@ -0,0 +1,182 @@
From bb42890533f9592e8d30654b4e0b19c3cf7caaec Mon Sep 17 00:00:00 2001
From: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Date: Fri, 1 Apr 2016 18:38:18 +0300
Subject: [PATCH 209/226] staging: fsl-dpaa2/mac: Interrupt code cleanup
Cleanup and a couple of minor fixes for the interrupt
handling code:
* Removed a few unnecessary checks, unify format for others
* Don't print error/debug messages in interrupt handler
* No need to explicitly disable DPMAC interrupts before
configuring them
* Use unlikely in interrupt handler routine error checks
* if status register is zero or we're unable to read its value,
return IRQ_NONE instead of IRQ_HANDLED
* always clear the entire status register, not just the bit(s)
that were treated
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
(cherry picked from commit 4b46eec16c56e4f453ca1558af9aceaf6ffe831a)
(Stuart:resolved merge conflict)
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
drivers/staging/fsl-dpaa2/mac/mac.c | 77 ++++++++---------------------------
1 file changed, 16 insertions(+), 61 deletions(-)
--- a/drivers/staging/fsl-dpaa2/mac/mac.c
+++ b/drivers/staging/fsl-dpaa2/mac/mac.c
@@ -132,7 +132,7 @@ static void dpaa2_mac_link_changed(struc
}
/* IRQ bits that we handle */
-static const u32 dpmac_irq_mask = DPMAC_IRQ_EVENT_LINK_CFG_REQ;
+static const u32 dpmac_irq_mask = DPMAC_IRQ_EVENT_LINK_CFG_REQ;
#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS
static netdev_tx_t dpaa2_mac_drop_frame(struct sk_buff *skb,
@@ -345,16 +345,13 @@ static const struct ethtool_ops dpaa2_ma
};
#endif /* CONFIG_FSL_DPAA2_MAC_NETDEVS */
-static int configure_link(struct dpaa2_mac_priv *priv,
- struct dpmac_link_cfg *cfg)
+static void configure_link(struct dpaa2_mac_priv *priv,
+ struct dpmac_link_cfg *cfg)
{
struct phy_device *phydev = priv->netdev->phydev;
- if (!phydev) {
- dev_warn(priv->netdev->dev.parent,
- "asked to change PHY settings but PHY ref is NULL, ignoring\n");
- return 0;
- }
+ if (unlikely(!phydev))
+ return;
phydev->speed = cfg->rate;
phydev->duplex = !!(cfg->options & DPMAC_LINK_OPT_HALF_DUPLEX);
@@ -368,8 +365,6 @@ static int configure_link(struct dpaa2_m
}
phy_start_aneg(phydev);
-
- return 0;
}
static irqreturn_t dpaa2_mac_irq_handler(int irq_num, void *arg)
@@ -378,53 +373,29 @@ static irqreturn_t dpaa2_mac_irq_handler
struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev);
struct dpaa2_mac_priv *priv = dev_get_drvdata(dev);
struct dpmac_link_cfg link_cfg;
- u8 irq_index = DPMAC_IRQ_INDEX;
- u32 status, clear = 0;
+ u32 status;
int err;
- if (mc_dev->irqs[0]->msi_desc->irq != irq_num) {
- dev_err(dev, "received unexpected interrupt %d!\n", irq_num);
- goto err;
- }
-
err = dpmac_get_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle,
- irq_index, &status);
- if (err) {
- dev_err(dev, "dpmac_get_irq_status err %d\n", err);
- clear = ~0x0u;
- goto out;
- }
+ DPMAC_IRQ_INDEX, &status);
+ if (unlikely(err || !status))
+ return IRQ_NONE;
/* DPNI-initiated link configuration; 'ifconfig up' also calls this */
if (status & DPMAC_IRQ_EVENT_LINK_CFG_REQ) {
- dev_dbg(dev, "DPMAC IRQ %d - LINK_CFG_REQ\n", irq_num);
- clear |= DPMAC_IRQ_EVENT_LINK_CFG_REQ;
-
err = dpmac_get_link_cfg(mc_dev->mc_io, 0, mc_dev->mc_handle,
&link_cfg);
- if (err) {
- dev_err(dev, "dpmac_get_link_cfg err %d\n", err);
+ if (unlikely(err))
goto out;
- }
- err = configure_link(priv, &link_cfg);
- if (err) {
- dev_err(dev, "cannot configure link\n");
- goto out;
- }
+ configure_link(priv, &link_cfg);
}
out:
- err = dpmac_clear_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle,
- irq_index, clear);
- if (err < 0)
- dev_err(&mc_dev->dev, "dpmac_clear_irq_status() err %d\n", err);
+ dpmac_clear_irq_status(mc_dev->mc_io, 0, mc_dev->mc_handle,
+ DPMAC_IRQ_INDEX, status);
return IRQ_HANDLED;
-
-err:
- dev_warn(dev, "DPMAC IRQ %d was not handled!\n", irq_num);
- return IRQ_NONE;
}
static int setup_irqs(struct fsl_mc_device *mc_dev)
@@ -437,19 +408,6 @@ static int setup_irqs(struct fsl_mc_devi
return err;
}
- err = dpmac_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle,
- DPMAC_IRQ_INDEX, dpmac_irq_mask);
- if (err < 0) {
- dev_err(&mc_dev->dev, "dpmac_set_irq_mask err %d\n", err);
- goto free_irq;
- }
- err = dpmac_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle,
- DPMAC_IRQ_INDEX, 0);
- if (err) {
- dev_err(&mc_dev->dev, "dpmac_set_irq_enable err %d\n", err);
- goto free_irq;
- }
-
err = devm_request_threaded_irq(&mc_dev->dev,
mc_dev->irqs[0]->msi_desc->irq,
NULL, &dpaa2_mac_irq_handler,
@@ -463,7 +421,7 @@ static int setup_irqs(struct fsl_mc_devi
err = dpmac_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle,
DPMAC_IRQ_INDEX, dpmac_irq_mask);
- if (err < 0) {
+ if (err) {
dev_err(&mc_dev->dev, "dpmac_set_irq_mask err %d\n", err);
goto free_irq;
}
@@ -490,12 +448,12 @@ static void teardown_irqs(struct fsl_mc_
err = dpmac_set_irq_mask(mc_dev->mc_io, 0, mc_dev->mc_handle,
DPMAC_IRQ_INDEX, dpmac_irq_mask);
- if (err < 0)
+ if (err)
dev_err(&mc_dev->dev, "dpmac_set_irq_mask err %d\n", err);
err = dpmac_set_irq_enable(mc_dev->mc_io, 0, mc_dev->mc_handle,
DPMAC_IRQ_INDEX, 0);
- if (err < 0)
+ if (err)
dev_err(&mc_dev->dev, "dpmac_set_irq_enable err %d\n", err);
devm_free_irq(&mc_dev->dev, mc_dev->irqs[0]->msi_desc->irq, &mc_dev->dev);
@@ -562,9 +520,6 @@ static int dpaa2_mac_probe(struct fsl_mc
phy_interface_t if_mode;
int err = 0;
- /* just being completely paranoid */
- if (!mc_dev)
- return -EFAULT;
dev = &mc_dev->dev;
/* prepare a net_dev structure to make the phy lib API happy */

View file

@ -0,0 +1,42 @@
From e74b6010eca026625ba4e39c80620320ca777deb Mon Sep 17 00:00:00 2001
From: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Date: Tue, 5 Apr 2016 13:35:14 +0300
Subject: [PATCH 210/226] staging: fsl-dpaa2/mac: Fix unregister_netdev issue
We only register the netdevice associated with a mac object if
ONFIG_FSL_DPAA2_MAC_NETDEV is set, but we always unregister it
during device remove(). Fix this by ifdef-ing the unregister
operation.
Also ifdef the change in netdevice name as it only makes sense
under this option.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
(cherry picked from commit dd6a5313e194168d46fef495a6e3bc5207801473)
---
drivers/staging/fsl-dpaa2/mac/mac.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/drivers/staging/fsl-dpaa2/mac/mac.c
+++ b/drivers/staging/fsl-dpaa2/mac/mac.c
@@ -534,7 +534,10 @@ static int dpaa2_mac_probe(struct fsl_mc
priv->netdev = netdev;
SET_NETDEV_DEV(netdev, dev);
+
+#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS
snprintf(netdev->name, IFNAMSIZ, "mac%d", mc_dev->obj_desc.id);
+#endif
dev_set_drvdata(dev, priv);
@@ -684,7 +687,9 @@ static int dpaa2_mac_remove(struct fsl_m
struct device *dev = &mc_dev->dev;
struct dpaa2_mac_priv *priv = dev_get_drvdata(dev);
+#ifdef CONFIG_FSL_DPAA2_MAC_NETDEVS
unregister_netdev(priv->netdev);
+#endif
teardown_irqs(priv->mc_dev);
dpmac_close(priv->mc_dev->mc_io, 0, priv->mc_dev->mc_handle);
fsl_mc_portal_free(priv->mc_dev->mc_io);

View file

@ -0,0 +1,42 @@
From b4d01330c66cbab3563c58f66f73f55726c09aec Mon Sep 17 00:00:00 2001
From: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Date: Tue, 5 Apr 2016 17:54:14 +0300
Subject: [PATCH 211/226] staging: fsl-dpaa2/mac: Don't call devm_free_irq
MAC interrupts are registered with devm_request_threaded_irq(), so
there's no need to explicitly unregister them in case of a probe
error or at device remove, as the kernel will take care of that for us.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
(cherry picked from commit 58e0fd23ade4b13e0a3c7e5f201802013e12df1c)
(Stuart: resolved merge conflict)
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
drivers/staging/fsl-dpaa2/mac/mac.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
--- a/drivers/staging/fsl-dpaa2/mac/mac.c
+++ b/drivers/staging/fsl-dpaa2/mac/mac.c
@@ -429,13 +429,11 @@ static int setup_irqs(struct fsl_mc_devi
DPMAC_IRQ_INDEX, 1);
if (err) {
dev_err(&mc_dev->dev, "dpmac_set_irq_enable err %d\n", err);
- goto unregister_irq;
+ goto free_irq;
}
return 0;
-unregister_irq:
- devm_free_irq(&mc_dev->dev, mc_dev->irqs[0]->msi_desc->irq, &mc_dev->dev);
free_irq:
fsl_mc_free_irqs(mc_dev);
@@ -456,7 +454,6 @@ static void teardown_irqs(struct fsl_mc_
if (err)
dev_err(&mc_dev->dev, "dpmac_set_irq_enable err %d\n", err);
- devm_free_irq(&mc_dev->dev, mc_dev->irqs[0]->msi_desc->irq, &mc_dev->dev);
fsl_mc_free_irqs(mc_dev);
}

View file

@ -0,0 +1,43 @@
From e554a03fe11719db373be3c54ce8f230a98dd5e4 Mon Sep 17 00:00:00 2001
From: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Date: Wed, 6 Apr 2016 15:05:47 +0300
Subject: [PATCH 212/226] staging: fsl-dpaa2/mac: Use of_property_read_32()
Simplify reading of the dpmac id from device tree.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
(cherry picked from commit b0562bda063f95923bcd8b78dea84a6e0587d3da)
---
drivers/staging/fsl-dpaa2/mac/mac.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
--- a/drivers/staging/fsl-dpaa2/mac/mac.c
+++ b/drivers/staging/fsl-dpaa2/mac/mac.c
@@ -461,9 +461,8 @@ static struct device_node *lookup_node(s
{
struct device_node *dpmacs, *dpmac = NULL;
struct device_node *mc_node = dev->of_node;
- const void *id;
- int lenp;
- int dpmac_id_be32 = cpu_to_be32(dpmac_id);
+ u32 id;
+ int err;
dpmacs = of_find_node_by_name(mc_node, "dpmacs");
if (!dpmacs) {
@@ -472,12 +471,10 @@ static struct device_node *lookup_node(s
}
while ((dpmac = of_get_next_child(dpmacs, dpmac))) {
- id = of_get_property(dpmac, "reg", &lenp);
- if (!id || lenp != sizeof(int)) {
- dev_warn(dev, "Unsuitable reg property in dpmac node\n");
+ err = of_property_read_u32(dpmac, "reg", &id);
+ if (err)
continue;
- }
- if (*(int *)id == dpmac_id_be32)
+ if (id == dpmac_id)
return dpmac;
}

View file

@ -0,0 +1,61 @@
From 3e4dc755337ca86d29c9f21f5225a77595aee032 Mon Sep 17 00:00:00 2001
From: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Date: Wed, 6 Apr 2016 12:12:06 +0300
Subject: [PATCH 213/226] staging: fsl-dpaa2/mac: Remove version checks
We intend to ensure backward compatibility with all MC versions
going forward, so we don't require an exact version match anymore
between MAC driver, DPMAC API version and DPMAC object version in
MC firmware.
Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
(cherry picked from commit eafc210ef421fb0dca67b67bf1a2fe98cd060c31)
---
drivers/staging/fsl-dpaa2/mac/mac.c | 29 ++---------------------------
1 file changed, 2 insertions(+), 27 deletions(-)
--- a/drivers/staging/fsl-dpaa2/mac/mac.c
+++ b/drivers/staging/fsl-dpaa2/mac/mac.c
@@ -481,30 +481,6 @@ static struct device_node *lookup_node(s
return NULL;
}
-static int check_dpmac_version(struct dpaa2_mac_priv *priv)
-{
- struct device *dev = &priv->mc_dev->dev;
- int mc_version = priv->attr.version.major;
-
- /* Check that the FLIB-defined version matches the one reported by MC */
- if (mc_version != DPMAC_VER_MAJOR) {
- dev_err(dev, "DPMAC FLIB version mismatch: MC says %d, we have %d\n",
- mc_version, DPMAC_VER_MAJOR);
- return -EINVAL;
- }
-
- /* ... and that we actually support it */
- if (mc_version < DPAA2_SUPPORTED_DPMAC_VERSION) {
- dev_err(dev, "Unsupported DPMAC FLIB version (%d)\n",
- mc_version);
- return -EINVAL;
- }
-
- dev_dbg(dev, "Using DPMAC FLIB version %d\n", mc_version);
-
- return 0;
-}
-
static int dpaa2_mac_probe(struct fsl_mc_device *mc_dev)
{
struct device *dev;
@@ -558,9 +534,8 @@ static int dpaa2_mac_probe(struct fsl_mc
goto err_close;
}
- err = check_dpmac_version(priv);
- if (err)
- goto err_close;
+ dev_info_once(dev, "Using DPMAC API %d.%d\n",
+ priv->attr.version.major, priv->attr.version.minor);
/* Look up the DPMAC node in the device-tree. */
dpmac_node = lookup_node(dev, priv->attr.id);

View file

@ -0,0 +1,26 @@
From 137f5f17bad655024d18123b1be696ad6b9ec729 Mon Sep 17 00:00:00 2001
From: Stuart Yoder <stuart.yoder@nxp.com>
Date: Wed, 15 Jun 2016 14:04:32 -0500
Subject: [PATCH 214/226] staging: fsl-dpaa2/mac: match id cleanup
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
drivers/staging/fsl-dpaa2/mac/mac.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/staging/fsl-dpaa2/mac/mac.c
+++ b/drivers/staging/fsl-dpaa2/mac/mac.c
@@ -670,12 +670,10 @@ static int dpaa2_mac_remove(struct fsl_m
return 0;
}
-static const struct fsl_mc_device_match_id dpaa2_mac_match_id_table[] = {
+static const struct fsl_mc_device_id dpaa2_mac_match_id_table[] = {
{
.vendor = FSL_MC_VENDOR_FREESCALE,
.obj_type = "dpmac",
- .ver_major = DPMAC_VER_MAJOR,
- .ver_minor = DPMAC_VER_MINOR,
},
{}
};

View file

@ -0,0 +1,69 @@
From 4efb592d8a931669df5df04bedcae8cbc85c3700 Mon Sep 17 00:00:00 2001
From: Razvan Stefanescu <razvan.stefanescu@freescale.com>
Date: Wed, 17 Feb 2016 16:31:01 +0200
Subject: [PATCH 216/226] dpaa2-evb: Fix interrupt handling
Mask only the events handled by the driver - DPDMUX_IRQ_EVENT_LINK_CHANGED.
Use clear-on-read mechanism for the interrupt status and avoid calling
dpdmux_clear_irq_status(). Status contains the events handled (only link
state change for the moment) and masks the first 16-bits, as they are used
to store the interface ID that generated the event.
Signed-off-by: Razvan Stefanescu <razvan.stefanescu@freescale.com>
---
drivers/staging/fsl-dpaa2/evb/evb.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
--- a/drivers/staging/fsl-dpaa2/evb/evb.c
+++ b/drivers/staging/fsl-dpaa2/evb/evb.c
@@ -151,7 +151,9 @@ static irqreturn_t _evb_irq0_handler_thr
struct fsl_mc_io *io = priv->mc_io;
uint16_t token = priv->mux_handle;
int irq_index = DPDMUX_IRQ_INDEX_IF;
- uint32_t status = 0, clear = 0;
+
+ /* Mask the events and the if_id reserved bits to be cleared on read */
+ uint32_t status = DPDMUX_IRQ_EVENT_LINK_CHANGED | 0xFFFF0000;
int err;
/* Sanity check */
@@ -163,23 +165,21 @@ static irqreturn_t _evb_irq0_handler_thr
err = dpdmux_get_irq_status(io, 0, token, irq_index, &status);
if (unlikely(err)) {
netdev_err(netdev, "Can't get irq status (err %d)", err);
- clear = 0xffffffff;
+ err = dpdmux_clear_irq_status(io, 0, token, irq_index,
+ 0xFFFFFFFF);
+ if (unlikely(err))
+ netdev_err(netdev, "Can't clear irq status (err %d)",
+ err);
goto out;
}
- /* FIXME clear irq status */
-
if (status & DPDMUX_IRQ_EVENT_LINK_CHANGED) {
- clear |= DPDMUX_IRQ_EVENT_LINK_CHANGED;
-
err = evb_links_state_update(priv);
if (unlikely(err))
goto out;
}
+
out:
- err = dpdmux_clear_irq_status(io, 0, token, irq_index, clear);
- if (unlikely(err))
- netdev_err(netdev, "Can't clear irq status (err %d)", err);
return IRQ_HANDLED;
}
@@ -191,7 +191,7 @@ static int evb_setup_irqs(struct fsl_mc_
int err = 0;
struct fsl_mc_device_irq *irq;
const int irq_index = DPDMUX_IRQ_INDEX_IF;
- uint32_t mask = ~0x0u; /* FIXME: unmask handled irqs */
+ uint32_t mask = DPDMUX_IRQ_EVENT_LINK_CHANGED;
err = fsl_mc_allocate_irqs(evb_dev);
if (unlikely(err)) {

View file

@ -0,0 +1,43 @@
From 213c59501bbd6da8c56e95f90f8a8c6af2682002 Mon Sep 17 00:00:00 2001
From: Razvan Stefanescu <razvan.stefanescu@freescale.com>
Date: Thu, 18 Feb 2016 10:54:40 +0200
Subject: [PATCH 217/226] dpaa2-evb: Add object version check
Abort probing if DPDMUX object version is smaller than required.
Signed-off-by: Razvan Stefanescu <razvan.stefanescu@freescale.com>
---
drivers/staging/fsl-dpaa2/evb/evb.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/drivers/staging/fsl-dpaa2/evb/evb.c
+++ b/drivers/staging/fsl-dpaa2/evb/evb.c
@@ -44,6 +44,10 @@
#include "dpdmux.h"
#include "dpdmux-cmd.h"
+/* Minimal supported DPDMUX version */
+#define DPDMUX_MIN_VER_MAJOR 5
+#define DPDMUX_MIN_VER_MINOR 0
+
/* IRQ index */
#define DPDMUX_MAX_IRQ_NUM 2
@@ -1004,6 +1008,17 @@ static int evb_init(struct fsl_mc_device
goto err_close;
}
+ /* Minimum supported DPDMUX version check */
+ if (priv->attr.version.major < DPDMUX_MIN_VER_MAJOR ||
+ (priv->attr.version.major == DPDMUX_MIN_VER_MAJOR &&
+ priv->attr.version.minor < DPDMUX_MIN_VER_MINOR)) {
+ dev_err(dev, "DPDMUX version %d.%d not supported. Use %d.%d or greater.\n",
+ priv->attr.version.major, priv->attr.version.minor,
+ DPDMUX_MIN_VER_MAJOR, DPDMUX_MIN_VER_MAJOR);
+ err = -ENOTSUPP;
+ goto err_close;
+ }
+
err = dpdmux_reset(priv->mc_io, 0, priv->mux_handle);
if (unlikely(err)) {
dev_err(dev, "dpdmux_reset err %d\n", err);

View file

@ -0,0 +1,20 @@
From 54d026dafa1f7d17758615736123917cc4f3f203 Mon Sep 17 00:00:00 2001
From: Mihai Caraman <mihai.caraman@freescale.com>
Date: Tue, 5 Apr 2016 14:12:10 +0000
Subject: [PATCH 218/226] dpaa2-evb: Cosmetic cleanup
Replace obsolete terms.
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
drivers/staging/fsl-dpaa2/evb/evb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/staging/fsl-dpaa2/evb/evb.c
+++ b/drivers/staging/fsl-dpaa2/evb/evb.c
@@ -1228,4 +1228,4 @@ static struct fsl_mc_driver evb_drv = {
module_fsl_mc_driver(evb_drv);
MODULE_LICENSE("GPL");
-MODULE_DESCRIPTION("Layerscape DPAA Edge Virtual Bridge driver (prototype)");
+MODULE_DESCRIPTION("DPAA2 Edge Virtual Bridge driver (prototype)");

View file

@ -0,0 +1,26 @@
From 744bd6494a51443c2a7d32ed76e94e4fc5bd2404 Mon Sep 17 00:00:00 2001
From: Stuart Yoder <stuart.yoder@nxp.com>
Date: Thu, 14 Jul 2016 17:32:23 -0500
Subject: [PATCH 219/226] dpaa2-evb: match id cleanup
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
drivers/staging/fsl-dpaa2/evb/evb.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/staging/fsl-dpaa2/evb/evb.c
+++ b/drivers/staging/fsl-dpaa2/evb/evb.c
@@ -1205,12 +1205,10 @@ err_free_netdev:
return err;
}
-static const struct fsl_mc_device_match_id evb_match_id_table[] = {
+static const struct fsl_mc_device_id evb_match_id_table[] = {
{
.vendor = FSL_MC_VENDOR_FREESCALE,
.obj_type = "dpdmux",
- .ver_major = DPDMUX_VER_MAJOR,
- .ver_minor = DPDMUX_VER_MINOR,
},
{}
};

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,26 @@
From 535826c8b725f752e5da17ea576d6d96e7d53f13 Mon Sep 17 00:00:00 2001
From: Stuart Yoder <stuart.yoder@nxp.com>
Date: Fri, 15 Jul 2016 13:13:41 -0500
Subject: [PATCH 221/226] dpaa2-ethsw: match id cleanup
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
drivers/staging/fsl-dpaa2/ethsw/switch.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/staging/fsl-dpaa2/ethsw/switch.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/switch.c
@@ -1685,12 +1685,10 @@ err_free_netdev:
return err;
}
-static const struct fsl_mc_device_match_id ethsw_match_id_table[] = {
+static const struct fsl_mc_device_id ethsw_match_id_table[] = {
{
.vendor = FSL_MC_VENDOR_FREESCALE,
.obj_type = "dpsw",
- .ver_major = DPSW_VER_MAJOR,
- .ver_minor = DPSW_VER_MINOR,
},
{}
};

View file

@ -0,0 +1,21 @@
From c51ed10a001d3fd5b80b7bb92f2d5182f1d9fa5a Mon Sep 17 00:00:00 2001
From: Stuart Yoder <stuart.yoder@nxp.com>
Date: Thu, 25 Aug 2016 16:10:12 -0500
Subject: [PATCH 222/226] dpaa2-ethsw: fix compile error on backport to 4.4
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
drivers/staging/fsl-dpaa2/ethsw/switch.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/staging/fsl-dpaa2/ethsw/switch.c
+++ b/drivers/staging/fsl-dpaa2/ethsw/switch.c
@@ -1625,7 +1625,7 @@ ethsw_probe(struct fsl_mc_device *sw_dev
rtnl_lock();
- err = netdev_master_upper_dev_link(port_netdev, netdev, NULL, NULL);
+ err = netdev_master_upper_dev_link(port_netdev, netdev);
if (err) {
dev_err(dev, "netdev_master_upper_dev_link error %d\n",
err);

View file

@ -0,0 +1,26 @@
From b565bd9a6011819ff66bd4fa0a50f7e54dff2753 Mon Sep 17 00:00:00 2001
From: "J. German Rivera" <German.Rivera@freescale.com>
Date: Wed, 6 Jan 2016 16:03:19 -0600
Subject: [PATCH 223/226] irqdomain: Added domain bus token
DOMAIN_BUS_FSL_MC_MSI
Since an FSL-MC bus is a new bus type that is neither PCI nor
PLATFORM, we need a new domain bus token to disambiguate the
IRQ domain for FSL-MC MSIs.
Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/linux/irqdomain.h | 1 +
1 file changed, 1 insertion(+)
--- a/include/linux/irqdomain.h
+++ b/include/linux/irqdomain.h
@@ -73,6 +73,7 @@ enum irq_domain_bus_token {
DOMAIN_BUS_PCI_MSI,
DOMAIN_BUS_PLATFORM_MSI,
DOMAIN_BUS_NEXUS,
+ DOMAIN_BUS_FSL_MC_MSI,
};
/**

View file

@ -0,0 +1,40 @@
From 359c7977e003781024154da61e55181b92b12bdf Mon Sep 17 00:00:00 2001
From: "J. German Rivera" <German.Rivera@freescale.com>
Date: Wed, 6 Jan 2016 16:03:20 -0600
Subject: [PATCH 224/226] fsl-mc: msi: Added FSL-MC-specific member to the
msi_desc's union
FSL-MC is a bus type different from PCI and platform, so it needs
its own member in the msi_desc's union.
Signed-off-by: J. German Rivera <German.Rivera@freescale.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/linux/msi.h | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -33,6 +33,14 @@ struct platform_msi_desc {
};
/**
+ * fsl_mc_msi_desc - FSL-MC device specific msi descriptor data
+ * @msi_index: The index of the MSI descriptor
+ */
+struct fsl_mc_msi_desc {
+ u16 msi_index;
+};
+
+/**
* struct msi_desc - Descriptor structure for MSI based interrupts
* @list: List head for management
* @irq: The base interrupt number
@@ -87,6 +95,7 @@ struct msi_desc {
* tree wide cleanup.
*/
struct platform_msi_desc platform;
+ struct fsl_mc_msi_desc fsl_mc;
};
};

View file

@ -0,0 +1,21 @@
From dbdf9b1fe83f88090d88bce980885df4fac46162 Mon Sep 17 00:00:00 2001
From: Stuart Yoder <stuart.yoder@nxp.com>
Date: Thu, 25 Aug 2016 11:17:52 -0500
Subject: [PATCH 225/226] dpaa2-evb: fix 4.4 backport compile error
Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
drivers/staging/fsl-dpaa2/evb/evb.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/staging/fsl-dpaa2/evb/evb.c
+++ b/drivers/staging/fsl-dpaa2/evb/evb.c
@@ -1153,7 +1153,7 @@ static int evb_probe(struct fsl_mc_devic
}
rtnl_lock();
- err = netdev_master_upper_dev_link(port_netdev, netdev, NULL, NULL);
+ err = netdev_master_upper_dev_link(port_netdev, netdev);
if (unlikely(err)) {
dev_err(dev, "netdev_master_upper_dev_link err %d\n",
err);

View file

@ -0,0 +1,24 @@
From f6f7c6ecdecfb75412a17205d9ac4905f6bc2851 Mon Sep 17 00:00:00 2001
From: Rai Harninder <harninder.rai@nxp.com>
Date: Thu, 18 Feb 2016 16:35:35 +0530
Subject: [PATCH 136/141] drivers/mmc: Add compatible string for LS1088A
Signed-off-by: Rai Harninder <harninder.rai@nxp.com>
Signed-off-by: Pratiyush Mohan Srivastava <pratiyush.srivastava@nxp.com>
Signed-off-by: Raghav Dogra <raghav.dogra@nxp.com>
---
drivers/mmc/host/sdhci-pltfm.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/mmc/host/sdhci-pltfm.c
+++ b/drivers/mmc/host/sdhci-pltfm.c
@@ -93,6 +93,9 @@ void sdhci_get_of_property(struct platfo
if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc"))
host->quirks |= SDHCI_QUIRK_BROKEN_DMA;
+ if (of_device_is_compatible(np, "fsl,ls1088a-esdhc"))
+ host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
+
if (of_device_is_compatible(np, "fsl,p2020-esdhc") ||
of_device_is_compatible(np, "fsl,p1010-esdhc") ||
of_device_is_compatible(np, "fsl,t4240-esdhc") ||

View file

@ -0,0 +1,38 @@
From 1aeb63c52ade1219032161fcdb923aa4c62b3796 Mon Sep 17 00:00:00 2001
From: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
Date: Sun, 9 Oct 2016 14:52:49 +0800
Subject: [PATCH 137/141] armv8: ls1088a: Add PCIe compatible
commit: 1a089a382b187c80390f022d1e3f3749b2adcc64
[don't apply dtsi]
Signed-off-by: Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>
Integrated-by: Zhao Qiang <qiang.zhao@nxp.com>
---
drivers/pci/host/pci-layerscape.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/drivers/pci/host/pci-layerscape.c
+++ b/drivers/pci/host/pci-layerscape.c
@@ -215,6 +215,13 @@ static struct ls_pcie_drvdata ls1046_drv
.ops = &ls_pcie_host_ops,
};
+static struct ls_pcie_drvdata ls1088_drvdata = {
+ .lut_offset = 0x80000,
+ .ltssm_shift = 0,
+ .lut_dbg = 0x407fc,
+ .ops = &ls_pcie_host_ops,
+};
+
static struct ls_pcie_drvdata ls2080_drvdata = {
.lut_offset = 0x80000,
.ltssm_shift = 0,
@@ -227,6 +234,7 @@ static const struct of_device_id ls_pcie
{ .compatible = "fsl,ls1021a-pcie", .data = &ls1021_drvdata },
{ .compatible = "fsl,ls1043a-pcie", .data = &ls1043_drvdata },
{ .compatible = "fsl,ls1046a-pcie", .data = &ls1046_drvdata },
+ { .compatible = "fsl,ls1088a-pcie", .data = &ls1088_drvdata },
{ .compatible = "fsl,ls2080a-pcie", .data = &ls2080_drvdata },
{ .compatible = "fsl,ls2085a-pcie", .data = &ls2080_drvdata },
{ },