]> git.kernelconcepts.de Git - meta-kc-bsp.git/commitdiff
linux-karo: Add initial version of linux-karo 4.9.11 based on NXP kernel tree
authorFlorian Boor <florian@kernelconcepts.de>
Sat, 2 Jun 2018 22:34:15 +0000 (00:34 +0200)
committerFlorian Boor <florian@kernelconcepts.de>
Sat, 2 Jun 2018 22:34:15 +0000 (00:34 +0200)
56 files changed:
recipes-kernel/linux/linux-imx.inc [new file with mode: 0644]
recipes-kernel/linux/linux-karo-4.9.11/0001-DTS-Add-Stratec-TX6-devicetree.patch [new file with mode: 0644]
recipes-kernel/linux/linux-karo-4.9.11/add-support-for-edt-m12-touch.patch [new file with mode: 0644]
recipes-kernel/linux/linux-karo-4.9.11/edt-ft5x06-fixes.patch [new file with mode: 0644]
recipes-kernel/linux/linux-karo-4.9.11/edt-ft5x06-make-distinction-between.patch [new file with mode: 0644]
recipes-kernel/linux/linux-karo-4.9.11/ethernet-update-driver.patch [new file with mode: 0644]
recipes-kernel/linux/linux-karo-4.9.11/gpu-viv_gcc6_indent_warning_error_fix.patch [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/reset-phy-minimal.patch [new file with mode: 0644]
recipes-kernel/linux/linux-karo-4.9.11/reset_ethernet_phy_whenever_the_enet_out_clock_is_being_enabled.patch [new file with mode: 0644]
recipes-kernel/linux/linux-karo-4.9.11/set-enet_ref_clk-to-50-mhz.patch [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/tx6/defconfig [new file with mode: 0644]
recipes-kernel/linux/linux-karo-4.9.11/tx6/imx6qdl-tx6-gpio.h [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/tx6/imx6qdl-tx6.dtsi [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6dl-tx6-emmc-aclavis-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6dl-tx6-nand-aclavis-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6q-tx6-emmc-aclavis-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6q-tx6-nand-aclavis-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6qp-tx6-emmc-aclavis-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6s-tx6-emmc-aclavis-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6s-tx6-nand-aclavis-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/txbase-aclavis-lvds.dtsi [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6dl-tx6-emmc-aclavis.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6dl-tx6-nand-aclavis.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6q-tx6-emmc-aclavis.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6q-tx6-nand-aclavis.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6qp-tx6-emmc-aclavis.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6s-tx6-emmc-aclavis.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6s-tx6-nand-aclavis.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/txbase-aclavis.dtsi [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6dl-tx6-emmc-evalkit.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6dl-tx6-nand-evalkit.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6q-tx6-emmc-evalkit.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6q-tx6-nand-evalkit.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6qp-tx6-emmc-evalkit.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6s-tx6-emmc-evalkit.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6s-tx6-nand-evalkit.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/txbase-evalkit.dtsi [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6dl-tx6-emmc-mb7-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6dl-tx6-nand-mb7-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6q-tx6-emmc-mb7-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6q-tx6-nand-mb7-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6qp-tx6-emmc-mb7-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6s-tx6-emmc-mb7-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6s-tx6-nand-mb7-lvds.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/txbase-mb7-lvds.dtsi [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6dl-tx6-emmc-mb7.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6dl-tx6-nand-mb7.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6q-tx6-emmc-mb7.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6q-tx6-nand-mb7.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6qp-tx6-emmc-mb7.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6s-tx6-emmc-mb7.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6s-tx6-nand-mb7.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/txbase-mb7.dtsi [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/myboard/imx6s-tx6-emmc-myboard.dts [new file with mode: 0755]
recipes-kernel/linux/linux-karo-4.9.11/txbase/myboard/txbase-myboard.dtsi [new file with mode: 0755]
recipes-kernel/linux/linux-karo_4.9.11.bb [new file with mode: 0644]

diff --git a/recipes-kernel/linux/linux-imx.inc b/recipes-kernel/linux/linux-imx.inc
new file mode 100644 (file)
index 0000000..9a8a035
--- /dev/null
@@ -0,0 +1,22 @@
+# Copyright (C) 2012, 2015 O.S. Systems Software LTDA.
+# Released under the MIT license (see COPYING.MIT for the terms)
+
+LICENSE = "GPLv2"
+LIC_FILES_CHKSUM = "file://COPYING;md5=d7810fab7487fb0aad327b76f1be7cd7"
+
+inherit kernel fsl-kernel-localversion fsl-vivante-kernel-driver-handler
+
+# Put a local version until we have a true SRCREV to point to
+LOCALVERSION ?= ""
+SCMVERSION ?= "y"
+SRCBRANCH ?= ""
+
+SRC_URI = "git://source.codeaurora.org/external/imx/linux-imx;protocol=https;branch=${SRCBRANCH} \
+           file://defconfig \
+"
+
+S = "${WORKDIR}/git"
+
+# We need to pass it as param since kernel might support more then one
+# machine, with different entry points
+KERNEL_EXTRA_ARGS += "LOADADDR=${UBOOT_ENTRYPOINT}"
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/0001-DTS-Add-Stratec-TX6-devicetree.patch b/recipes-kernel/linux/linux-karo-4.9.11/0001-DTS-Add-Stratec-TX6-devicetree.patch
new file mode 100644 (file)
index 0000000..f30ba1d
--- /dev/null
@@ -0,0 +1,160 @@
+From 52902ee8a80e2aec3135e47a9189811f5d209c3c Mon Sep 17 00:00:00 2001
+From: Florian Boor <florian.boor@kernelconcepts.de>
+Date: Tue, 6 Mar 2018 13:59:22 +0100
+Subject: [PATCH] DTS: Add Stratec TX6 devicetree
+
+---
+ arch/arm/boot/dts/Makefile                        |   1 +
+ arch/arm/boot/dts/imx6dl-tx6-emmc-mb7-stratec.dts | 128 ++++++++++++++++++++++
+ 2 files changed, 129 insertions(+)
+ create mode 100644 arch/arm/boot/dts/imx6dl-tx6-emmc-mb7-stratec.dts
+
+diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
+index f151ec7..e03cd14 100644
+--- a/arch/arm/boot/dts/Makefile
++++ b/arch/arm/boot/dts/Makefile
+@@ -400,6 +400,7 @@ dtb-$(CONFIG_SOC_IMX6Q) += \
+       imx6dl-tx6u-8033-mb7.dtb \
+       imx6dl-tx6u-811x.dtb \
+       imx6dl-tx6u-81xx-mb7.dtb \
++      imx6dl-tx6-emmc-mb7-stratec.dtb \
+       imx6dl-udoo.dtb \
+       imx6dl-wandboard.dtb \
+       imx6dl-wandboard-revb1.dtb \
+diff --git a/arch/arm/boot/dts/imx6dl-tx6-emmc-mb7-stratec.dts b/arch/arm/boot/dts/imx6dl-tx6-emmc-mb7-stratec.dts
+new file mode 100644
+index 0000000..0270e6c
+--- /dev/null
++++ b/arch/arm/boot/dts/imx6dl-tx6-emmc-mb7-stratec.dts
+@@ -0,0 +1,128 @@
++/*
++ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
++ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
++ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
++ *
++ * This file is dual-licensed: you can use it either under the terms
++ * of the GPL or the X11 license, at your option. Note that this dual
++ * licensing only applies to this file, and not this project as a
++ * whole.
++ *
++ *  a) This file is free software; you can redistribute it and/or
++ *     modify it under the terms of the GNU General Public License
++ *     version 2 as published by the Free Software Foundation.
++ *
++ *     This file is distributed in the hope that it will be useful,
++ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ *     GNU General Public License for more details.
++ *
++ * Or, alternatively,
++ *
++ *  b) Permission is hereby granted, free of charge, to any person
++ *     obtaining a copy of this software and associated documentation
++ *     files (the "Software"), to deal in the Software without
++ *     restriction, including without limitation the rights to use,
++ *     copy, modify, merge, publish, distribute, sublicense, and/or
++ *     sell copies of the Software, and to permit persons to whom the
++ *     Software is furnished to do so, subject to the following
++ *     conditions:
++ *
++ *     The above copyright notice and this permission notice shall be
++ *     included in all copies or substantial portions of the Software.
++ *
++ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
++ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
++ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
++ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
++ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
++ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
++ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
++ *     OTHER DEALINGS IN THE SOFTWARE.
++ */
++
++/*
++ * Please be reminded that - in general - DTSI file(s) are include files that
++ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
++ * be edited. For end-user products it should be the DTS file(s) that choose
++ * which devices and pins are active and setup.
++ *
++ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
++ * different, non-standard, implementation to the mainline Linux kernel.
++ */
++
++/*
++ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
++ * for the definitions like TX_NAND or TX_EMMC, etc.
++ */
++
++/dts-v1/;
++
++#include "imx6dl.dtsi"
++#include "imx6qdl-tx6.dtsi"
++#include "txbase-mb7.dtsi"
++
++/ {
++      model = "Ka-Ro electronics TX6U Module (eMMC & RGB)";
++      compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
++};
++
++/*
++ * Every VOU is multi parted: backlight, device, framebuffer, pwm
++ * Thus all parts have to be enabled before a display can be used on the
++ * specific port.
++ */
++
++&backlight0 {
++      status = "okay";
++};
++
++/*
++ * NVM setup
++ */
++
++TX_EMMC {
++      status = "okay";
++};
++
++/*
++ * Remaining device references in alphabetical order
++ */
++
++TX_LCD {
++      status = "okay";
++      /*
++       * Users should add their custom timing here, therewith
++       * therewith overwriting the default/pre-defined timings. For more see:
++       *
++       * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
++       *
++       * e.g.:
++       * txbase/mb7-lvds/txbase-aclavis.dtsi
++       */
++};
++
++TX_LCD_FB {
++      status = "okay";
++};
++
++TX_I2C {
++      status = "okay";
++
++      rtc@6f {
++              compatible = "microchip,mcp7940x";
++              reg = <0x6f>;
++      };
++
++      polytouch: edt-ft5x06@38 {
++              compatible = "edt,edt-ft5x06";
++              reg = <0x38>;
++              pinctrl-names = "default";
++              pinctrl-0 = <&pinctrl_edt_ft5x06>;
++              interrupts-extended = <TX_GPIO_PIN148 0>;
++              reset-gpios = <TX_GPIO_PIN149 GPIO_ACTIVE_LOW>;
++              wake-gpios = <TX_GPIO_PIN152 GPIO_ACTIVE_HIGH>;
++              linux,wakeup;
++      };
++};
++
+-- 
+2.1.4
+
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/add-support-for-edt-m12-touch.patch b/recipes-kernel/linux/linux-karo-4.9.11/add-support-for-edt-m12-touch.patch
new file mode 100644 (file)
index 0000000..791eb55
--- /dev/null
@@ -0,0 +1,182 @@
+From patchwork Thu Oct  5 15:35:08 2017
+Content-Type: text/plain; charset="utf-8"
+MIME-Version: 1.0
+Content-Transfer-Encoding: 7bit
+Subject: [3/3] input: edt-ft5x06: implement support for the EDT-M12 series.
+From: Simon Budig <simon.budig@kernelconcepts.de>
+X-Patchwork-Id: 9987471
+Message-Id: <20171005153508.32127-3-simon.budig@kernelconcepts.de>
+To: linux-input@vger.kernel.org
+Cc: dmitry.torokhov@gmail.com, Simon Budig <simon.budig@kernelconcepts.de>
+Date: Thu,  5 Oct 2017 17:35:08 +0200
+
+From: Simon Budig <simon.budig@kernelconcepts.de>
+
+This adds support for the EDT M12 series of touchscreens.
+
+Signed-off-by: Simon Budig <simon.budig@kernelconcepts.de>
+---
+ drivers/input/touchscreen/edt-ft5x06.c | 48 +++++++++++++++++++++++++++-------
+ 1 file changed, 38 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
+index d128445..8f5c2c0 100644
+--- a/drivers/input/touchscreen/edt-ft5x06.c
++++ b/drivers/input/touchscreen/edt-ft5x06.c
+@@ -72,6 +72,7 @@
+ enum edt_ver {
+       EDT_M06,
+       EDT_M09,
++      EDT_M12,
+       GENERIC_FT,
+ };
+@@ -188,6 +189,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
+               break;
+       case EDT_M09:
++      case EDT_M12:
+       case GENERIC_FT:
+               cmd = 0x0;
+               offset = 3;
+@@ -211,7 +213,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
+               goto out;
+       }
+-      /* M09 does not send header or CRC */
++      /* M09/M12 does not send header or CRC */
+       if (tsdata->version == EDT_M06) {
+               if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa ||
+                       rdbuf[2] != datalen) {
+@@ -274,6 +276,7 @@ static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata,
+               return edt_ft5x06_ts_readwrite(tsdata->client, 4,
+                                       wrbuf, 0, NULL);
+       case EDT_M09:
++      case EDT_M12:
+       case GENERIC_FT:
+               wrbuf[0] = addr;
+               wrbuf[1] = value;
+@@ -313,6 +316,7 @@ static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
+               break;
+       case EDT_M09:
++      case EDT_M12:
+       case GENERIC_FT:
+               wrbuf[0] = addr;
+               error = edt_ft5x06_ts_readwrite(tsdata->client, 1,
+@@ -377,6 +381,7 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
+               break;
+       case EDT_M09:
++      case EDT_M12:
+       case GENERIC_FT:
+               addr = attr->addr_m09;
+               break;
+@@ -447,6 +452,7 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
+               break;
+       case EDT_M09:
++      case EDT_M12:
+       case GENERIC_FT:
+               addr = attr->addr_m09;
+               break;
+@@ -472,14 +478,18 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
+       return error ?: count;
+ }
++/* m06, m09: range 0-31, m12: range 0-5 */
+ static EDT_ATTR(gain, S_IWUSR | S_IRUGO, WORK_REGISTER_GAIN,
+               M09_REGISTER_GAIN, 0, 31);
++/* m06, m09: range 0-31, m12: range 0-16 */
+ static EDT_ATTR(offset, S_IWUSR | S_IRUGO, WORK_REGISTER_OFFSET,
+               M09_REGISTER_OFFSET, 0, 31);
++/* m06: range 20 to 80, m09: range 0 to 30, m12: range 1 to 255... */
+ static EDT_ATTR(threshold, S_IWUSR | S_IRUGO, WORK_REGISTER_THRESHOLD,
+-              M09_REGISTER_THRESHOLD, 0, 80);
++              M09_REGISTER_THRESHOLD, 0, 255);
++/* m06: range 3 to 14, m12: (0x64: 100Hz) */
+ static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO, WORK_REGISTER_REPORT_RATE,
+-              NO_REGISTER, 3, 14);
++              NO_REGISTER, 0, 255);
+ static struct attribute *edt_ft5x06_attrs[] = {
+       &edt_ft5x06_attr_gain.dattr.attr,
+@@ -551,7 +561,7 @@ static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
+       return error;
+ m09_out:
+-      dev_err(&client->dev, "No factory mode support for M09/GENERIC_FT\n");
++      dev_err(&client->dev, "No factory mode support for M09/M12/GENERIC_FT\n");
+       return -EINVAL;
+ }
+@@ -776,13 +786,14 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
+        * to have garbage in there
+        */
+       memset(rdbuf, 0, sizeof(rdbuf));
+-      error = edt_ft5x06_ts_readwrite(client, 1, "\xbb",
++      error = edt_ft5x06_ts_readwrite(client, 1, "\xBB",
+                                       EDT_NAME_LEN - 1, rdbuf);
+       if (error)
+               return error;
+-      /* if we find something consistent, stay with that assumption
+-       * at least M09 won't send 3 bytes here
++      /* probe content for something consistent.
++       * M06 starts with a response byte, M12 gives the data directly.
++       * M09/Generic does not provide model number information.
+        */
+       if (!(strncasecmp(rdbuf + 1, "EP0", 3))) {
+               tsdata->version = EDT_M06;
+@@ -798,8 +809,22 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
+                       *p++ = '\0';
+               strlcpy(model_name, rdbuf + 1, EDT_NAME_LEN);
+               strlcpy(fw_version, p ? p : "", EDT_NAME_LEN);
++      } else if (!(strncasecmp(rdbuf, "EP0", 3))) {
++              tsdata->version = EDT_M12;
++
++              /* remove last '$' end marker */
++              rdbuf[EDT_NAME_LEN - 2] = '\0';
++              if (rdbuf[EDT_NAME_LEN - 3] == '$')
++                      rdbuf[EDT_NAME_LEN - 3] = '\0';
++
++              /* look for Model/Version separator */
++              p = strchr(rdbuf, '*');
++              if (p)
++                      *p++ = '\0';
++              strlcpy(model_name, rdbuf, EDT_NAME_LEN);
++              strlcpy(fw_version, p ? p : "", EDT_NAME_LEN);
+       } else {
+-              /* If it is not an EDT M06 touchscreen, then the model
++              /* if it is not an EDT M06/M12 touchscreen then the model
+                * detection is a bit hairy. The different ft5x06
+                * firmares around don't reliably implement the
+                * identification registers. Well. we'll take a shot.
+@@ -894,7 +919,8 @@ edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data *tsdata)
+               tsdata->report_rate = edt_ft5x06_register_read(tsdata,
+                                               reg_addr->reg_report_rate);
+       if (tsdata->version == EDT_M06 ||
+-          tsdata->version == EDT_M09) {
++          tsdata->version == EDT_M09 ||
++          tsdata->version == EDT_M12) {
+               tsdata->num_x = edt_ft5x06_register_read(tsdata,
+                                                        reg_addr->reg_num_x);
+               tsdata->num_y = edt_ft5x06_register_read(tsdata,
+@@ -921,6 +947,7 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
+               break;
+       case EDT_M09:
++      case EDT_M12:
+               reg_addr->reg_threshold = M09_REGISTER_THRESHOLD;
+               reg_addr->reg_report_rate = NO_REGISTER;
+               reg_addr->reg_gain = M09_REGISTER_GAIN;
+@@ -1029,7 +1056,8 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
+       input->dev.parent = &client->dev;
+       if (tsdata->version == EDT_M06 ||
+-          tsdata->version == EDT_M09) {
++          tsdata->version == EDT_M09 ||
++          tsdata->version == EDT_M12) {
+               input_set_abs_params(input, ABS_MT_POSITION_X,
+                                    0, tsdata->num_x * 64 - 1, 0, 0);
+               input_set_abs_params(input, ABS_MT_POSITION_Y,
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/edt-ft5x06-fixes.patch b/recipes-kernel/linux/linux-karo-4.9.11/edt-ft5x06-fixes.patch
new file mode 100644 (file)
index 0000000..3e9cb95
--- /dev/null
@@ -0,0 +1,95 @@
+From aa3d4409b664813ceb86a24bd09458cdd29cbb8a Mon Sep 17 00:00:00 2001
+From: Martin Kepplinger <martin.kepplinger@ginzinger.com>
+Date: Mon, 22 May 2017 17:19:45 -0700
+Subject: [PATCH] Input: edt-ft5x06 - increase allowed data range for threshold
+ parameter
+
+The datasheet and application note does not mention an allowed range for
+the M09_REGISTER_THRESHOLD parameter. One of our customers needs to set
+lower values than 20 and they seem to work just fine on EDT EP0xx0M09 with
+T5x06 touch.
+
+So, lacking a known lower limit, we increase the range for thresholds,
+and set the lower limit to 0. The documentation is updated accordingly.
+
+Signed-off-by: Schoefegger Stefan <stefan.schoefegger@ginzinger.com>
+Signed-off-by: Manfred Schlaegl <manfred.schlaegl@ginzinger.com>
+Signed-off-by: Martin Kepplinger <martin.kepplinger@ginzinger.com>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+---
+ Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt | 2 +-
+ drivers/input/touchscreen/edt-ft5x06.c                             | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
+index 6db22103e2dd5..025cf8c9324ac 100644
+--- a/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
++++ b/Documentation/devicetree/bindings/input/touchscreen/edt-ft5x06.txt
+@@ -36,7 +36,7 @@ Optional properties:
+                 control gpios
+  - threshold:   allows setting the "click"-threshold in the range
+-                from 20 to 80.
++                from 0 to 80.
+  - gain:        allows setting the sensitivity in the range from 0 to
+                 31. Note that lower values indicate higher
+diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
+index 8cf8d8d5d4ef4..f872817e81e46 100644
+--- a/drivers/input/touchscreen/edt-ft5x06.c
++++ b/drivers/input/touchscreen/edt-ft5x06.c
+@@ -471,7 +471,7 @@ static EDT_ATTR(gain, S_IWUSR | S_IRUGO, WORK_REGISTER_GAIN,
+ static EDT_ATTR(offset, S_IWUSR | S_IRUGO, WORK_REGISTER_OFFSET,
+               M09_REGISTER_OFFSET, 0, 31);
+ static EDT_ATTR(threshold, S_IWUSR | S_IRUGO, WORK_REGISTER_THRESHOLD,
+-              M09_REGISTER_THRESHOLD, 20, 80);
++              M09_REGISTER_THRESHOLD, 0, 80);
+ static EDT_ATTR(report_rate, S_IWUSR | S_IRUGO, WORK_REGISTER_REPORT_RATE,
+               NO_REGISTER, 3, 14);
+From 47014752829ed1b52fa6f876b381774ae530503c Mon Sep 17 00:00:00 2001
+From: Luca Ceresoli <luca@lucaceresoli.net>
+Date: Thu, 7 Sep 2017 14:28:28 -0700
+Subject: [PATCH] Input: edt-ft5x06 - fix access to non-existing register
+
+reg_addr->reg_report_rate is supposed to exist in M06, not M09.
+
+The driver is written to skip avoids access to non-existing registers
+when the register address is NO_REGISTER (0xff). But
+reg_addr->reg_report_rate is initialized to 0x00 by devm_kzalloc() (in
+edt_ft5x06_ts_probe()) and not changed thereafter. So the checks do
+not work and an access to register 0x00 is done.
+
+Fix by setting reg_addr->reg_report_rate to NO_REGISTER.
+
+Also fix the only place where reg_report_rate is checked against zero
+instead of NO_REGISTER.
+
+Signed-off-by: Luca Ceresoli <luca@lucaceresoli.net>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+---
+ drivers/input/touchscreen/edt-ft5x06.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
+index f872817e81e46..5bf63f76dddac 100644
+--- a/drivers/input/touchscreen/edt-ft5x06.c
++++ b/drivers/input/touchscreen/edt-ft5x06.c
+@@ -593,7 +593,7 @@ static int edt_ft5x06_work_mode(struct edt_ft5x06_ts_data *tsdata)
+                                 tsdata->gain);
+       edt_ft5x06_register_write(tsdata, reg_addr->reg_offset,
+                                 tsdata->offset);
+-      if (reg_addr->reg_report_rate)
++      if (reg_addr->reg_report_rate != NO_REGISTER)
+               edt_ft5x06_register_write(tsdata, reg_addr->reg_report_rate,
+                                 tsdata->report_rate);
+@@ -874,6 +874,7 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
+       case M09:
+               reg_addr->reg_threshold = M09_REGISTER_THRESHOLD;
++              reg_addr->reg_report_rate = NO_REGISTER;
+               reg_addr->reg_gain = M09_REGISTER_GAIN;
+               reg_addr->reg_offset = M09_REGISTER_OFFSET;
+               reg_addr->reg_num_x = M09_REGISTER_NUM_X;
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/edt-ft5x06-make-distinction-between.patch b/recipes-kernel/linux/linux-karo-4.9.11/edt-ft5x06-make-distinction-between.patch
new file mode 100644 (file)
index 0000000..2cc16b8
--- /dev/null
@@ -0,0 +1,296 @@
+From 169110c3645621497ca0b1d0d7bc80dcea8ff9d4 Mon Sep 17 00:00:00 2001
+From: Simon Budig <simon.budig@kernelconcepts.de>
+Date: Mon, 9 Oct 2017 20:58:11 -0700
+Subject: [PATCH] Input: edt-ft5x06 - make distinction between m06/m09/generic
+ more clear
+
+Since the driver also is useful for some non-EDT touchscreens based on
+the focaltec chips introduce the concept of a "generic" focaltec based
+touch.
+
+Use a better heuristics for model detection and be more specific in the
+source.
+
+Signed-off-by: Simon Budig <simon.budig@kernelconcepts.de>
+Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
+---
+ drivers/input/touchscreen/edt-ft5x06.c | 122 +++++++++++++++++++++++++--------
+ 1 file changed, 93 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/input/touchscreen/edt-ft5x06.c b/drivers/input/touchscreen/edt-ft5x06.c
+index f879d14f7ffcc..56bfd0c14c91a 100644
+--- a/drivers/input/touchscreen/edt-ft5x06.c
++++ b/drivers/input/touchscreen/edt-ft5x06.c
+@@ -70,8 +70,9 @@
+ #define EDT_RAW_DATA_DELAY            1000 /* usec */
+ enum edt_ver {
+-      M06,
+-      M09,
++      EDT_M06,
++      EDT_M09,
++      GENERIC_FT,
+ };
+ struct edt_reg_addr {
+@@ -179,14 +180,15 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
+       int error;
+       switch (tsdata->version) {
+-      case M06:
++      case EDT_M06:
+               cmd = 0xf9; /* tell the controller to send touch data */
+               offset = 5; /* where the actual touch data starts */
+               tplen = 4;  /* data comes in so called frames */
+               crclen = 1; /* length of the crc data */
+               break;
+-      case M09:
++      case EDT_M09:
++      case GENERIC_FT:
+               cmd = 0x0;
+               offset = 3;
+               tplen = 6;
+@@ -210,7 +212,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
+       }
+       /* M09 does not send header or CRC */
+-      if (tsdata->version == M06) {
++      if (tsdata->version == EDT_M06) {
+               if (rdbuf[0] != 0xaa || rdbuf[1] != 0xaa ||
+                       rdbuf[2] != datalen) {
+                       dev_err_ratelimited(dev,
+@@ -233,7 +235,7 @@ static irqreturn_t edt_ft5x06_ts_isr(int irq, void *dev_id)
+                       continue;
+               /* M06 sometimes sends bogus coordinates in TOUCH_DOWN */
+-              if (tsdata->version == M06 && type == TOUCH_EVENT_DOWN)
++              if (tsdata->version == EDT_M06 && type == TOUCH_EVENT_DOWN)
+                       continue;
+               x = ((buf[0] << 8) | buf[1]) & 0x0fff;
+@@ -264,14 +266,15 @@ static int edt_ft5x06_register_write(struct edt_ft5x06_ts_data *tsdata,
+       u8 wrbuf[4];
+       switch (tsdata->version) {
+-      case M06:
++      case EDT_M06:
+               wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
+               wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
+               wrbuf[2] = value;
+               wrbuf[3] = wrbuf[0] ^ wrbuf[1] ^ wrbuf[2];
+               return edt_ft5x06_ts_readwrite(tsdata->client, 4,
+                                       wrbuf, 0, NULL);
+-      case M09:
++      case EDT_M09:
++      case GENERIC_FT:
+               wrbuf[0] = addr;
+               wrbuf[1] = value;
+@@ -290,7 +293,7 @@ static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
+       int error;
+       switch (tsdata->version) {
+-      case M06:
++      case EDT_M06:
+               wrbuf[0] = tsdata->factory_mode ? 0xf3 : 0xfc;
+               wrbuf[1] = tsdata->factory_mode ? addr & 0x7f : addr & 0x3f;
+               wrbuf[1] |= tsdata->factory_mode ? 0x80 : 0x40;
+@@ -309,7 +312,8 @@ static int edt_ft5x06_register_read(struct edt_ft5x06_ts_data *tsdata,
+               }
+               break;
+-      case M09:
++      case EDT_M09:
++      case GENERIC_FT:
+               wrbuf[0] = addr;
+               error = edt_ft5x06_ts_readwrite(tsdata->client, 1,
+                                               wrbuf, 1, rdbuf);
+@@ -368,11 +372,12 @@ static ssize_t edt_ft5x06_setting_show(struct device *dev,
+       }
+       switch (tsdata->version) {
+-      case M06:
++      case EDT_M06:
+               addr = attr->addr_m06;
+               break;
+-      case M09:
++      case EDT_M09:
++      case GENERIC_FT:
+               addr = attr->addr_m09;
+               break;
+@@ -437,11 +442,12 @@ static ssize_t edt_ft5x06_setting_store(struct device *dev,
+       }
+       switch (tsdata->version) {
+-      case M06:
++      case EDT_M06:
+               addr = attr->addr_m06;
+               break;
+-      case M09:
++      case EDT_M09:
++      case GENERIC_FT:
+               addr = attr->addr_m09;
+               break;
+@@ -508,7 +514,7 @@ static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
+       }
+       /* mode register is 0x3c when in the work mode */
+-      if (tsdata->version == M09)
++      if (tsdata->version != EDT_M06)
+               goto m09_out;
+       error = edt_ft5x06_register_write(tsdata, WORK_REGISTER_OPMODE, 0x03);
+@@ -545,7 +551,7 @@ static int edt_ft5x06_factory_mode(struct edt_ft5x06_ts_data *tsdata)
+       return error;
+ m09_out:
+-      dev_err(&client->dev, "No factory mode support for M09\n");
++      dev_err(&client->dev, "No factory mode support for M09/GENERIC_FT\n");
+       return -EINVAL;
+ }
+@@ -779,7 +785,7 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
+        * at least M09 won't send 3 bytes here
+        */
+       if (!(strncasecmp(rdbuf + 1, "EP0", 3))) {
+-              tsdata->version = M06;
++              tsdata->version = EDT_M06;
+               /* remove last '$' end marker */
+               rdbuf[EDT_NAME_LEN - 1] = '\0';
+@@ -793,8 +799,16 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
+               strlcpy(model_name, rdbuf + 1, EDT_NAME_LEN);
+               strlcpy(fw_version, p ? p : "", EDT_NAME_LEN);
+       } else {
+-              /* since there are only two versions around (M06, M09) */
+-              tsdata->version = M09;
++              /* If it is not an EDT M06 touchscreen, then the model
++               * detection is a bit hairy. The different ft5x06
++               * firmares around don't reliably implement the
++               * identification registers. Well, we'll take a shot.
++               *
++               * The main difference between generic focaltec based
++               * touches and EDT M09 is that we know how to retrieve
++               * the max coordinates for the latter.
++               */
++              tsdata->version = GENERIC_FT;
+               error = edt_ft5x06_ts_readwrite(client, 1, "\xA6",
+                                               2, rdbuf);
+@@ -808,8 +822,34 @@ static int edt_ft5x06_ts_identify(struct i2c_client *client,
+               if (error)
+                       return error;
+-              snprintf(model_name, EDT_NAME_LEN, "EP0%i%i0M09",
+-                      rdbuf[0] >> 4, rdbuf[0] & 0x0F);
++              /* This "model identification" is not exact. Unfortunately
++               * not all firmwares for the ft5x06 put useful values in
++               * the identification registers.
++               */
++              switch (rdbuf[0]) {
++              case 0x35:   /* EDT EP0350M09 */
++              case 0x43:   /* EDT EP0430M09 */
++              case 0x50:   /* EDT EP0500M09 */
++              case 0x57:   /* EDT EP0570M09 */
++              case 0x70:   /* EDT EP0700M09 */
++                      tsdata->version = EDT_M09;
++                      snprintf(model_name, EDT_NAME_LEN, "EP0%i%i0M09",
++                              rdbuf[0] >> 4, rdbuf[0] & 0x0F);
++                      break;
++              case 0xa1:   /* EDT EP1010ML00 */
++                      tsdata->version = EDT_M09;
++                      snprintf(model_name, EDT_NAME_LEN, "EP%i%i0ML00",
++                              rdbuf[0] >> 4, rdbuf[0] & 0x0F);
++                      break;
++              case 0x5a:   /* Solomon Goldentek Display */
++                      snprintf(model_name, EDT_NAME_LEN, "GKTW50SCED1R0");
++                      break;
++              default:
++                      snprintf(model_name, EDT_NAME_LEN,
++                               "generic ft5x06 (%02x)",
++                               rdbuf[0]);
++                      break;
++              }
+       }
+       return 0;
+@@ -853,8 +893,16 @@ edt_ft5x06_ts_get_parameters(struct edt_ft5x06_ts_data *tsdata)
+       if (reg_addr->reg_report_rate != NO_REGISTER)
+               tsdata->report_rate = edt_ft5x06_register_read(tsdata,
+                                               reg_addr->reg_report_rate);
+-      tsdata->num_x = edt_ft5x06_register_read(tsdata, reg_addr->reg_num_x);
+-      tsdata->num_y = edt_ft5x06_register_read(tsdata, reg_addr->reg_num_y);
++      if (tsdata->version == EDT_M06 ||
++          tsdata->version == EDT_M09) {
++              tsdata->num_x = edt_ft5x06_register_read(tsdata,
++                                                       reg_addr->reg_num_x);
++              tsdata->num_y = edt_ft5x06_register_read(tsdata,
++                                                       reg_addr->reg_num_y);
++      } else {
++              tsdata->num_x = -1;
++              tsdata->num_y = -1;
++      }
+ }
+ static void
+@@ -863,7 +911,7 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
+       struct edt_reg_addr *reg_addr = &tsdata->reg_addr;
+       switch (tsdata->version) {
+-      case M06:
++      case EDT_M06:
+               reg_addr->reg_threshold = WORK_REGISTER_THRESHOLD;
+               reg_addr->reg_report_rate = WORK_REGISTER_REPORT_RATE;
+               reg_addr->reg_gain = WORK_REGISTER_GAIN;
+@@ -872,7 +920,7 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
+               reg_addr->reg_num_y = WORK_REGISTER_NUM_Y;
+               break;
+-      case M09:
++      case EDT_M09:
+               reg_addr->reg_threshold = M09_REGISTER_THRESHOLD;
+               reg_addr->reg_report_rate = NO_REGISTER;
+               reg_addr->reg_gain = M09_REGISTER_GAIN;
+@@ -880,6 +928,13 @@ edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata)
+               reg_addr->reg_num_x = M09_REGISTER_NUM_X;
+               reg_addr->reg_num_y = M09_REGISTER_NUM_Y;
+               break;
++
++      case GENERIC_FT:
++              /* this is a guesswork */
++              reg_addr->reg_threshold = M09_REGISTER_THRESHOLD;
++              reg_addr->reg_gain = M09_REGISTER_GAIN;
++              reg_addr->reg_offset = M09_REGISTER_OFFSET;
++              break;
+       }
+ }
+@@ -969,10 +1024,19 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client,
+       input->id.bustype = BUS_I2C;
+       input->dev.parent = &client->dev;
+-      input_set_abs_params(input, ABS_MT_POSITION_X,
+-                           0, tsdata->num_x * 64 - 1, 0, 0);
+-      input_set_abs_params(input, ABS_MT_POSITION_Y,
+-                           0, tsdata->num_y * 64 - 1, 0, 0);
++      if (tsdata->version == EDT_M06 ||
++          tsdata->version == EDT_M09) {
++              input_set_abs_params(input, ABS_MT_POSITION_X,
++                                   0, tsdata->num_x * 64 - 1, 0, 0);
++              input_set_abs_params(input, ABS_MT_POSITION_Y,
++                                   0, tsdata->num_y * 64 - 1, 0, 0);
++      } else {
++              /* Unknown maximum values. Specify via devicetree */
++              input_set_abs_params(input, ABS_MT_POSITION_X,
++                                   0, 65535, 0, 0);
++              input_set_abs_params(input, ABS_MT_POSITION_Y,
++                                   0, 65535, 0, 0);
++      }
+       touchscreen_parse_properties(input, true, &tsdata->prop);
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/ethernet-update-driver.patch b/recipes-kernel/linux/linux-karo-4.9.11/ethernet-update-driver.patch
new file mode 100644 (file)
index 0000000..854443c
--- /dev/null
@@ -0,0 +1,17985 @@
+diff --git a/drivers/net/ethernet/freescale/Kconfig b/drivers/net/ethernet/freescale/Kconfig
+index 2204c57..25e3425 100644
+--- a/drivers/net/ethernet/freescale/Kconfig
++++ b/drivers/net/ethernet/freescale/Kconfig
+@@ -7,10 +7,11 @@ config NET_VENDOR_FREESCALE
+       default y
+       depends on FSL_SOC || QUICC_ENGINE || CPM1 || CPM2 || PPC_MPC512x || \
+                  M523x || M527x || M5272 || M528x || M520x || M532x || \
+-                 ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM) || \
+-                 ARCH_LAYERSCAPE
++                 ARCH_MXC || ARCH_MXS || (PPC_MPC52xx && PPC_BESTCOMM)
+       ---help---
+-        If you have a network (Ethernet) card belonging to this class, say Y.
++        If you have a network (Ethernet) card belonging to this class, say Y
++        and read the Ethernet-HOWTO, available from
++        <http://www.tldp.org/docs.html#howto>.
+         Note that the answer to this question doesn't directly affect the
+         kernel: saying N will just cause the configurator to skip all
+@@ -22,8 +23,8 @@ if NET_VENDOR_FREESCALE
+ config FEC
+       tristate "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
+       depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \
+-                 ARM || ARM64)
+-      default y
++                 ARCH_MXC || SOC_IMX28)
++      default ARCH_MXC || SOC_IMX28 if ARM
+       select PHYLIB
+       select PTP_1588_CLOCK
+       ---help---
+@@ -54,7 +55,6 @@ config FEC_MPC52xx_MDIO
+         If compiled as module, it will be called fec_mpc52xx_phy.
+ source "drivers/net/ethernet/freescale/fs_enet/Kconfig"
+-source "drivers/net/ethernet/freescale/fman/Kconfig"
+ config FSL_PQ_MDIO
+       tristate "Freescale PQ MDIO"
+@@ -85,12 +85,12 @@ config UGETH_TX_ON_DEMAND
+ config GIANFAR
+       tristate "Gianfar Ethernet"
++      depends on FSL_SOC
+       select FSL_PQ_MDIO
+       select PHYLIB
+       select CRC32
+       ---help---
+         This driver supports the Gigabit TSEC on the MPC83xx, MPC85xx,
+-        and MPC86xx family of chips, the eTSEC on LS1021A and the FEC
+-        on the 8540.
++        and MPC86xx family of chips, and the FEC on the 8540.
+ endif # NET_VENDOR_FREESCALE
+diff --git a/drivers/net/ethernet/freescale/Makefile b/drivers/net/ethernet/freescale/Makefile
+index 7f022dd..71debd1 100644
+--- a/drivers/net/ethernet/freescale/Makefile
++++ b/drivers/net/ethernet/freescale/Makefile
+@@ -3,10 +3,7 @@
+ #
+ obj-$(CONFIG_FEC) += fec.o
+-fec-objs :=fec_main.o fec_fixup.o fec_ptp.o
+-CFLAGS_fec_main.o := -D__CHECK_ENDIAN__
+-CFLAGS_fec_ptp.o := -D__CHECK_ENDIAN__
+-
++fec-objs :=fec_main.o fec_ptp.o
+ obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o
+ ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y)
+       obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx_phy.o
+@@ -20,5 +17,3 @@ gianfar_driver-objs := gianfar.o \
+               gianfar_ethtool.o
+ obj-$(CONFIG_UCC_GETH) += ucc_geth_driver.o
+ ucc_geth_driver-objs := ucc_geth.o ucc_geth_ethtool.o
+-
+-obj-$(CONFIG_FSL_FMAN) += fman/
+diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
+index 1d7b3cc..ecdc711 100644
+--- a/drivers/net/ethernet/freescale/fec.h
++++ b/drivers/net/ethernet/freescale/fec.h
+@@ -20,8 +20,8 @@
+ #include <linux/timecounter.h>
+ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+-    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \
+-    defined(CONFIG_ARM64)
++    defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
++    defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
+ /*
+  *    Just figures, Motorola would have to change the offsets for
+  *    registers in the same peripheral device on different models
+@@ -192,45 +192,28 @@
+ /*
+  *    Define the buffer descriptor structure.
+- *
+- *    Evidently, ARM SoCs have the FEC block generated in a
+- *    little endian mode so adjust endianness accordingly.
+  */
+-#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
+-#define fec32_to_cpu le32_to_cpu
+-#define fec16_to_cpu le16_to_cpu
+-#define cpu_to_fec32 cpu_to_le32
+-#define cpu_to_fec16 cpu_to_le16
+-#define __fec32 __le32
+-#define __fec16 __le16
+-
++#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
+ struct bufdesc {
+-      __fec16 cbd_datlen;     /* Data length */
+-      __fec16 cbd_sc;         /* Control and status info */
+-      __fec32 cbd_bufaddr;    /* Buffer address */
++      unsigned short cbd_datlen;      /* Data length */
++      unsigned short cbd_sc;  /* Control and status info */
++      unsigned long cbd_bufaddr;      /* Buffer address */
+ };
+ #else
+-#define fec32_to_cpu be32_to_cpu
+-#define fec16_to_cpu be16_to_cpu
+-#define cpu_to_fec32 cpu_to_be32
+-#define cpu_to_fec16 cpu_to_be16
+-#define __fec32 __be32
+-#define __fec16 __be16
+-
+ struct bufdesc {
+-      __fec16 cbd_sc;         /* Control and status info */
+-      __fec16 cbd_datlen;     /* Data length */
+-      __fec32 cbd_bufaddr;    /* Buffer address */
++      unsigned short  cbd_sc;                 /* Control and status info */
++      unsigned short  cbd_datlen;             /* Data length */
++      unsigned long   cbd_bufaddr;            /* Buffer address */
+ };
+ #endif
+ struct bufdesc_ex {
+       struct bufdesc desc;
+-      __fec32 cbd_esc;
+-      __fec32 cbd_prot;
+-      __fec32 cbd_bdu;
+-      __fec32 ts;
+-      __fec16 res0[4];
++      unsigned long cbd_esc;
++      unsigned long cbd_prot;
++      unsigned long cbd_bdu;
++      unsigned long ts;
++      unsigned short res0[4];
+ };
+ /*
+@@ -294,7 +277,7 @@ struct bufdesc_ex {
+ /* This device has up to three irqs on some platforms */
+-#define FEC_IRQ_NUM           4
++#define FEC_IRQ_NUM           3
+ /* Maximum number of queues supported
+  * ENET with AVB IP can support up to 3 independent tx queues and rx queues.
+@@ -312,6 +295,12 @@ struct bufdesc_ex {
+ #define FEC_R_BUFF_SIZE(X)    (((X) == 1) ? FEC_R_BUFF_SIZE_1 : \
+                               (((X) == 2) ? \
+                                       FEC_R_BUFF_SIZE_2 : FEC_R_BUFF_SIZE_0))
++#define FEC_R_DES_ACTIVE(X)   (((X) == 1) ? FEC_R_DES_ACTIVE_1 : \
++                              (((X) == 2) ? \
++                                 FEC_R_DES_ACTIVE_2 : FEC_R_DES_ACTIVE_0))
++#define FEC_X_DES_ACTIVE(X)   (((X) == 1) ? FEC_X_DES_ACTIVE_1 : \
++                              (((X) == 2) ? \
++                                 FEC_X_DES_ACTIVE_2 : FEC_X_DES_ACTIVE_0))
+ #define FEC_DMA_CFG(X)                (((X) == 2) ? FEC_DMA_CFG_2 : FEC_DMA_CFG_1)
+@@ -379,7 +368,6 @@ struct bufdesc_ex {
+ #define FEC_ENET_TS_TIMER       ((uint)0x00008000)
+ #define FEC_DEFAULT_IMASK (FEC_ENET_TXF | FEC_ENET_RXF | FEC_ENET_MII | FEC_ENET_TS_TIMER)
+-#define FEC_NAPI_IMASK        (FEC_ENET_MII | FEC_ENET_TS_TIMER)
+ #define FEC_RX_DISABLED_IMASK (FEC_DEFAULT_IMASK & (~FEC_ENET_RXF))
+ #define FEC_ENET_ETHEREN      ((uint)0x00000002)
+@@ -448,32 +436,12 @@ struct bufdesc_ex {
+ #define FEC_QUIRK_SINGLE_MDIO         (1 << 11)
+ /* Controller supports RACC register */
+ #define FEC_QUIRK_HAS_RACC            (1 << 12)
+-/* Controller supports interrupt coalesc */
+-#define FEC_QUIRK_HAS_COALESCE                (1 << 13)
+-/* Interrupt doesn't wake CPU from deep idle */
+-#define FEC_QUIRK_ERR006687           (1 << 14)
+ /*
+  * i.MX6Q/DL ENET cannot wake up system in wait mode because ENET tx & rx
+  * interrupt signal don't connect to GPC. So use pm qos to avoid cpu enter
+  * to wait mode.
+  */
+-#define FEC_QUIRK_BUG_WAITMODE                (1 << 15)
+-
+-/* PHY fixup flag define */
+-#define FEC_QUIRK_AR8031_FIXUP                (1 << 0)
+-
+-struct bufdesc_prop {
+-      int qid;
+-      /* Address of Rx and Tx buffers */
+-      struct bufdesc  *base;
+-      struct bufdesc  *last;
+-      struct bufdesc  *cur;
+-      void __iomem    *reg_desc_active;
+-      dma_addr_t      dma;
+-      unsigned short ring_size;
+-      unsigned char dsize;
+-      unsigned char dsize_log2;
+-};
++#define FEC_QUIRK_BUG_WAITMODE         (1 << 13)
+ struct fec_enet_stop_mode {
+       struct regmap *gpr;
+@@ -482,21 +450,32 @@ struct fec_enet_stop_mode {
+ };
+ struct fec_enet_priv_tx_q {
+-      struct bufdesc_prop bd;
++      int index;
+       unsigned char *tx_bounce[TX_RING_SIZE];
+       struct  sk_buff *tx_skbuff[TX_RING_SIZE];
++      dma_addr_t      bd_dma;
++      struct bufdesc  *tx_bd_base;
++      uint tx_ring_size;
++
+       unsigned short tx_stop_threshold;
+       unsigned short tx_wake_threshold;
++      struct bufdesc  *cur_tx;
+       struct bufdesc  *dirty_tx;
+       char *tso_hdrs;
+       dma_addr_t tso_hdrs_dma;
+ };
+ struct fec_enet_priv_rx_q {
+-      struct bufdesc_prop bd;
++      int index;
+       struct  sk_buff *rx_skbuff[RX_RING_SIZE];
++
++      dma_addr_t      bd_dma;
++      struct bufdesc  *rx_bd_base;
++      uint rx_ring_size;
++
++      struct bufdesc  *cur_rx;
+ };
+ /* The FEC buffer descriptors track the ring buffers.  The rx_bd_base and
+@@ -536,20 +515,22 @@ struct fec_enet_private {
+       unsigned long work_ts;
+       unsigned long work_mdio;
++      unsigned short bufdesc_size;
++
+       struct  platform_device *pdev;
+       int     dev_id;
+       /* Phylib and MDIO interface */
+       struct  mii_bus *mii_bus;
++      struct  phy_device *phy_dev;
+       int     mii_timeout;
+       int     mii_bus_share;
+-      bool    active_in_suspend;
++      bool    miibus_up_failed;
+       uint    phy_speed;
+       phy_interface_t phy_interface;
+       struct device_node *phy_node;
+       int     link;
+-      bool    fixed_link;
+       int     full_duplex;
+       int     speed;
+       struct  completion mdio_done;
+@@ -559,7 +540,8 @@ struct fec_enet_private {
+       int     wol_flag;
+       int     wake_irq;
+       u32     quirks;
+-      u32     fixups;
++      int phy_reset_gpio;
++      int phy_reset_duration;
+       struct  napi_struct napi;
+       int     csum_flags;
+@@ -602,19 +584,14 @@ struct fec_enet_private {
+       int pps_enable;
+       unsigned int next_counter;
+-      u64 ethtool_stats[0];
+-
+       struct fec_enet_stop_mode gpr;
+ };
+ void fec_ptp_init(struct platform_device *pdev);
+-void fec_ptp_stop(struct platform_device *pdev);
+ void fec_ptp_start_cyclecounter(struct net_device *ndev);
+ int fec_ptp_set(struct net_device *ndev, struct ifreq *ifr);
+ int fec_ptp_get(struct net_device *ndev, struct ifreq *ifr);
+ uint fec_ptp_check_pps_event(struct fec_enet_private *fep);
+-void fec_enet_register_fixup(struct net_device *ndev);
+-int of_fec_enet_parse_fixup(struct device_node *np);
+ /****************************************************************************/
+ #endif /* FEC_H */
+diff --git a/drivers/net/ethernet/freescale/fec_fixup.c b/drivers/net/ethernet/freescale/fec_fixup.c
+deleted file mode 100644
+index 5a8497c..0000000
+--- a/drivers/net/ethernet/freescale/fec_fixup.c
++++ /dev/null
+@@ -1,74 +0,0 @@
+-/*
+- * Copyright 2017 NXP
+- *
+- * This program is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU General Public License
+- * as published by the Free Software Foundation; either version 2
+- * of the License, or (at your option) any later version.
+- *
+- * This program is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+- * GNU General Public License for more details.
+- */
+-
+-#include <linux/netdevice.h>
+-#include <linux/phy.h>
+-#include "fec.h"
+-
+-#define PHY_ID_AR8031   0x004dd074
+-
+-static int ar8031_phy_fixup(struct phy_device *dev)
+-{
+-      u16 val;
+-
+-      /* Set RGMII IO voltage to 1.8V */
+-      phy_write(dev, 0x1d, 0x1f);
+-      phy_write(dev, 0x1e, 0x8);
+-
+-      /* Disable phy AR8031 SmartEEE function */
+-      phy_write(dev, 0xd, 0x3);
+-      phy_write(dev, 0xe, 0x805d);
+-      phy_write(dev, 0xd, 0x4003);
+-      val = phy_read(dev, 0xe);
+-      val &= ~(0x1 << 8);
+-      phy_write(dev, 0xe, val);
+-
+-      /* Introduce tx clock delay */
+-      phy_write(dev, 0x1d, 0x5);
+-      phy_write(dev, 0x1e, 0x100);
+-
+-      return 0;
+-}
+-
+-void fec_enet_register_fixup(struct net_device *ndev)
+-{
+-      struct fec_enet_private *fep = netdev_priv(ndev);
+-      static int registered = 0;
+-      int err;
+-
+-      if (!IS_BUILTIN(CONFIG_PHYLIB))
+-              return;
+-
+-      if (fep->fixups & FEC_QUIRK_AR8031_FIXUP) {
+-              static int ar8031_registered = 0;
+-
+-              if (ar8031_registered)
+-                      return;
+-              err = phy_register_fixup_for_uid(PHY_ID_AR8031, 0xffffffef,
+-                                      ar8031_phy_fixup);
+-              if (err)
+-                      netdev_info(ndev, "Cannot register PHY board fixup\n");
+-              registered = 1;
+-      }
+-}
+-
+-int of_fec_enet_parse_fixup(struct device_node *np)
+-{
+-      int fixups = 0;
+-
+-      if (of_get_property(np, "fsl,ar8031-phy-fixup", NULL))
+-              fixups |= FEC_QUIRK_AR8031_FIXUP;
+-
+-      return fixups;
+-}
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index 41a31f2..15c06df 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -19,8 +19,6 @@
+  * Copyright (c) 2004-2006 Macq Electronique SA.
+  *
+  * Copyright (C) 2010-2014 Freescale Semiconductor, Inc.
+- *
+- * Copyright 2017 NXP
+  */
+ #include <linux/module.h>
+@@ -48,9 +46,7 @@
+ #include <linux/io.h>
+ #include <linux/irq.h>
+ #include <linux/clk.h>
+-#include <linux/clk/clk-conf.h>
+ #include <linux/platform_device.h>
+-#include <linux/mdio.h>
+ #include <linux/phy.h>
+ #include <linux/fec.h>
+ #include <linux/of.h>
+@@ -68,12 +64,12 @@
+ #include <linux/regmap.h>
+ #include <asm/cacheflush.h>
+-#include <soc/imx/cpuidle.h>
+ #include "fec.h"
+ static void set_multicast_list(struct net_device *ndev);
+ static void fec_enet_itr_coal_init(struct net_device *ndev);
++static void fec_reset_phy(struct platform_device *pdev);
+ #define DRIVER_NAME   "fec"
+@@ -87,7 +83,6 @@ static const u16 fec_enet_vlan_pri_to_queue[8] = {1, 1, 1, 1, 2, 2, 2, 2};
+ #define FEC_ENET_RAEM_V       0x8
+ #define FEC_ENET_RAFL_V       0x8
+ #define FEC_ENET_OPD_V        0xFFF0
+-#define FEC_MDIO_PM_TIMEOUT  100 /* ms */
+ static struct platform_device_id fec_devtype[] = {
+       {
+@@ -96,10 +91,10 @@ static struct platform_device_id fec_devtype[] = {
+               .driver_data = 0,
+       }, {
+               .name = "imx25-fec",
+-              .driver_data = FEC_QUIRK_USE_GASKET,
++              .driver_data = FEC_QUIRK_USE_GASKET | FEC_QUIRK_HAS_RACC,
+       }, {
+               .name = "imx27-fec",
+-              .driver_data = 0,
++              .driver_data = FEC_QUIRK_HAS_RACC,
+       }, {
+               .name = "imx28-fec",
+               .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_SWAP_FRAME |
+@@ -119,20 +114,12 @@ static struct platform_device_id fec_devtype[] = {
+                               FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
+                               FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
+                               FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
+-                              FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE,
++                              FEC_QUIRK_HAS_RACC,
+       }, {
+               .name = "imx6ul-fec",
+               .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
+                               FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
+-                              FEC_QUIRK_HAS_VLAN | FEC_QUIRK_BUG_CAPTURE |
+-                              FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE,
+-      }, {
+-              .name = "imx8qm-fec",
+-              .driver_data = FEC_QUIRK_ENET_MAC | FEC_QUIRK_HAS_GBIT |
+-                              FEC_QUIRK_HAS_BUFDESC_EX | FEC_QUIRK_HAS_CSUM |
+-                              FEC_QUIRK_HAS_VLAN | FEC_QUIRK_HAS_AVB |
+-                              FEC_QUIRK_ERR007885 | FEC_QUIRK_BUG_CAPTURE |
+-                              FEC_QUIRK_HAS_RACC | FEC_QUIRK_HAS_COALESCE,
++                              FEC_QUIRK_HAS_VLAN,
+       }, {
+               /* sentinel */
+       }
+@@ -147,7 +134,6 @@ enum imx_fec_type {
+       MVF600_FEC,
+       IMX6SX_FEC,
+       IMX6UL_FEC,
+-      IMX8QM_FEC,
+ };
+ static const struct of_device_id fec_dt_ids[] = {
+@@ -158,7 +144,6 @@ static const struct of_device_id fec_dt_ids[] = {
+       { .compatible = "fsl,mvf600-fec", .data = &fec_devtype[MVF600_FEC], },
+       { .compatible = "fsl,imx6sx-fec", .data = &fec_devtype[IMX6SX_FEC], },
+       { .compatible = "fsl,imx6ul-fec", .data = &fec_devtype[IMX6UL_FEC], },
+-      { .compatible = "fsl,imx8qm-fec", .data = &fec_devtype[IMX8QM_FEC], },
+       { /* sentinel */ }
+ };
+ MODULE_DEVICE_TABLE(of, fec_dt_ids);
+@@ -196,7 +181,6 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
+ /* FEC receive acceleration */
+ #define FEC_RACC_IPDIS                (1 << 1)
+ #define FEC_RACC_PRODIS               (1 << 2)
+-#define FEC_RACC_SHIFT16      BIT(7)
+ #define FEC_RACC_OPTIONS      (FEC_RACC_IPDIS | FEC_RACC_PRODIS)
+ /*
+@@ -205,8 +189,7 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
+  * account when setting it.
+  */
+ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+-    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \
+-    defined(CONFIG_ARM64)
++    defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM)
+ #define       OPT_FRAME_SIZE  (PKT_MAXBUF_SIZE << 16)
+ #else
+ #define       OPT_FRAME_SIZE  0
+@@ -244,38 +227,86 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
+ #define IS_TSO_HEADER(txq, addr) \
+       ((addr >= txq->tso_hdrs_dma) && \
+-      (addr < txq->tso_hdrs_dma + txq->bd.ring_size * TSO_HEADER_SIZE))
++      (addr < txq->tso_hdrs_dma + txq->tx_ring_size * TSO_HEADER_SIZE))
+ static int mii_cnt;
+-static struct bufdesc *fec_enet_get_nextdesc(struct bufdesc *bdp,
+-                                           struct bufdesc_prop *bd)
+-{
+-      return (bdp >= bd->last) ? bd->base
+-                      : (struct bufdesc *)(((void *)bdp) + bd->dsize);
+-}
++static inline
++struct bufdesc *fec_enet_get_nextdesc(struct bufdesc *bdp,
++                                    struct fec_enet_private *fep,
++                                    int queue_id)
++{
++      struct bufdesc *new_bd = bdp + 1;
++      struct bufdesc_ex *ex_new_bd = (struct bufdesc_ex *)bdp + 1;
++      struct fec_enet_priv_tx_q *txq = fep->tx_queue[queue_id];
++      struct fec_enet_priv_rx_q *rxq = fep->rx_queue[queue_id];
++      struct bufdesc_ex *ex_base;
++      struct bufdesc *base;
++      int ring_size;
++
++      if (bdp >= txq->tx_bd_base) {
++              base = txq->tx_bd_base;
++              ring_size = txq->tx_ring_size;
++              ex_base = (struct bufdesc_ex *)txq->tx_bd_base;
++      } else {
++              base = rxq->rx_bd_base;
++              ring_size = rxq->rx_ring_size;
++              ex_base = (struct bufdesc_ex *)rxq->rx_bd_base;
++      }
+-static struct bufdesc *fec_enet_get_prevdesc(struct bufdesc *bdp,
+-                                           struct bufdesc_prop *bd)
+-{
+-      return (bdp <= bd->base) ? bd->last
+-                      : (struct bufdesc *)(((void *)bdp) - bd->dsize);
++      if (fep->bufdesc_ex)
++              return (struct bufdesc *)((ex_new_bd >= (ex_base + ring_size)) ?
++                      ex_base : ex_new_bd);
++      else
++              return (new_bd >= (base + ring_size)) ?
++                      base : new_bd;
++}
++
++static inline
++struct bufdesc *fec_enet_get_prevdesc(struct bufdesc *bdp,
++                                    struct fec_enet_private *fep,
++                                    int queue_id)
++{
++      struct bufdesc *new_bd = bdp - 1;
++      struct bufdesc_ex *ex_new_bd = (struct bufdesc_ex *)bdp - 1;
++      struct fec_enet_priv_tx_q *txq = fep->tx_queue[queue_id];
++      struct fec_enet_priv_rx_q *rxq = fep->rx_queue[queue_id];
++      struct bufdesc_ex *ex_base;
++      struct bufdesc *base;
++      int ring_size;
++
++      if (bdp >= txq->tx_bd_base) {
++              base = txq->tx_bd_base;
++              ring_size = txq->tx_ring_size;
++              ex_base = (struct bufdesc_ex *)txq->tx_bd_base;
++      } else {
++              base = rxq->rx_bd_base;
++              ring_size = rxq->rx_ring_size;
++              ex_base = (struct bufdesc_ex *)rxq->rx_bd_base;
++      }
++
++      if (fep->bufdesc_ex)
++              return (struct bufdesc *)((ex_new_bd < ex_base) ?
++                      (ex_new_bd + ring_size) : ex_new_bd);
++      else
++              return (new_bd < base) ? (new_bd + ring_size) : new_bd;
+ }
+-static int fec_enet_get_bd_index(struct bufdesc *bdp,
+-                               struct bufdesc_prop *bd)
++static int fec_enet_get_bd_index(struct bufdesc *base, struct bufdesc *bdp,
++                              struct fec_enet_private *fep)
+ {
+-      return ((const char *)bdp - (const char *)bd->base) >> bd->dsize_log2;
++      return ((const char *)bdp - (const char *)base) / fep->bufdesc_size;
+ }
+-static int fec_enet_get_free_txdesc_num(struct fec_enet_priv_tx_q *txq)
++static int fec_enet_get_free_txdesc_num(struct fec_enet_private *fep,
++                                      struct fec_enet_priv_tx_q *txq)
+ {
+       int entries;
+-      entries = (((const char *)txq->dirty_tx -
+-                      (const char *)txq->bd.cur) >> txq->bd.dsize_log2) - 1;
++      entries = ((const char *)txq->dirty_tx -
++                      (const char *)txq->cur_tx) / fep->bufdesc_size - 1;
+-      return entries >= 0 ? entries : entries + txq->bd.ring_size;
++      return entries >= 0 ? entries : entries + txq->tx_ring_size;
+ }
+ static void swap_buffer(void *bufaddr, int len)
+@@ -308,20 +339,18 @@ static void fec_dump(struct net_device *ndev)
+       pr_info("Nr     SC     addr       len  SKB\n");
+       txq = fep->tx_queue[0];
+-      bdp = txq->bd.base;
++      bdp = txq->tx_bd_base;
+       do {
+-              pr_info("%3u %c%c 0x%04x 0x%08x %4u %p\n",
++              pr_info("%3u %c%c 0x%04x 0x%08lx %4u %p\n",
+                       index,
+-                      bdp == txq->bd.cur ? 'S' : ' ',
++                      bdp == txq->cur_tx ? 'S' : ' ',
+                       bdp == txq->dirty_tx ? 'H' : ' ',
+-                      fec16_to_cpu(bdp->cbd_sc),
+-                      fec32_to_cpu(bdp->cbd_bufaddr),
+-                      fec16_to_cpu(bdp->cbd_datlen),
++                      bdp->cbd_sc, bdp->cbd_bufaddr, bdp->cbd_datlen,
+                       txq->tx_skbuff[index]);
+-              bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
++              bdp = fec_enet_get_nextdesc(bdp, fep, 0);
+               index++;
+-      } while (bdp != txq->bd.base);
++      } while (bdp != txq->tx_bd_base);
+ }
+ static inline bool is_ipv4_pkt(struct sk_buff *skb)
+@@ -352,9 +381,10 @@ fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq,
+                            struct net_device *ndev)
+ {
+       struct fec_enet_private *fep = netdev_priv(ndev);
+-      struct bufdesc *bdp = txq->bd.cur;
++      struct bufdesc *bdp = txq->cur_tx;
+       struct bufdesc_ex *ebdp;
+       int nr_frags = skb_shinfo(skb)->nr_frags;
++      unsigned short queue = skb_get_queue_mapping(skb);
+       int frag, frag_len;
+       unsigned short status;
+       unsigned int estatus = 0;
+@@ -366,10 +396,10 @@ fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq,
+       for (frag = 0; frag < nr_frags; frag++) {
+               this_frag = &skb_shinfo(skb)->frags[frag];
+-              bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
++              bdp = fec_enet_get_nextdesc(bdp, fep, queue);
+               ebdp = (struct bufdesc_ex *)bdp;
+-              status = fec16_to_cpu(bdp->cbd_sc);
++              status = bdp->cbd_sc;
+               status &= ~BD_ENET_TX_STATS;
+               status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
+               frag_len = skb_shinfo(skb)->frags[frag].size;
+@@ -387,16 +417,16 @@ fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq,
+               if (fep->bufdesc_ex) {
+                       if (fep->quirks & FEC_QUIRK_HAS_AVB)
+-                              estatus |= FEC_TX_BD_FTYPE(txq->bd.qid);
++                              estatus |= FEC_TX_BD_FTYPE(queue);
+                       if (skb->ip_summed == CHECKSUM_PARTIAL)
+                               estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
+                       ebdp->cbd_bdu = 0;
+-                      ebdp->cbd_esc = cpu_to_fec32(estatus);
++                      ebdp->cbd_esc = estatus;
+               }
+               bufaddr = page_address(this_frag->page.p) + this_frag->page_offset;
+-              index = fec_enet_get_bd_index(bdp, &txq->bd);
++              index = fec_enet_get_bd_index(txq->tx_bd_base, bdp, fep);
+               if (((unsigned long) bufaddr) & fep->tx_align ||
+                       fep->quirks & FEC_QUIRK_SWAP_FRAME) {
+                       memcpy(txq->tx_bounce[index], bufaddr, frag_len);
+@@ -409,27 +439,24 @@ fec_enet_txq_submit_frag_skb(struct fec_enet_priv_tx_q *txq,
+               addr = dma_map_single(&fep->pdev->dev, bufaddr, frag_len,
+                                     DMA_TO_DEVICE);
+               if (dma_mapping_error(&fep->pdev->dev, addr)) {
++                      dev_kfree_skb_any(skb);
+                       if (net_ratelimit())
+                               netdev_err(ndev, "Tx DMA memory map failed\n");
+                       goto dma_mapping_error;
+               }
+-              bdp->cbd_bufaddr = cpu_to_fec32(addr);
+-              bdp->cbd_datlen = cpu_to_fec16(frag_len);
+-              /* Make sure the updates to rest of the descriptor are
+-               * performed before transferring ownership.
+-               */
+-              wmb();
+-              bdp->cbd_sc = cpu_to_fec16(status);
++              bdp->cbd_bufaddr = addr;
++              bdp->cbd_datlen = frag_len;
++              bdp->cbd_sc = status;
+       }
+       return bdp;
+ dma_mapping_error:
+-      bdp = txq->bd.cur;
++      bdp = txq->cur_tx;
+       for (i = 0; i < frag; i++) {
+-              bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
+-              dma_unmap_single(&fep->pdev->dev, fec32_to_cpu(bdp->cbd_bufaddr),
+-                               fec16_to_cpu(bdp->cbd_datlen), DMA_TO_DEVICE);
++              bdp = fec_enet_get_nextdesc(bdp, fep, queue);
++              dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
++                              bdp->cbd_datlen, DMA_TO_DEVICE);
+       }
+       return ERR_PTR(-ENOMEM);
+ }
+@@ -444,11 +471,12 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
+       dma_addr_t addr;
+       unsigned short status;
+       unsigned short buflen;
++      unsigned short queue;
+       unsigned int estatus = 0;
+       unsigned int index;
+       int entries_free;
+-      entries_free = fec_enet_get_free_txdesc_num(txq);
++      entries_free = fec_enet_get_free_txdesc_num(fep, txq);
+       if (entries_free < MAX_SKB_FRAGS + 1) {
+               dev_kfree_skb_any(skb);
+               if (net_ratelimit())
+@@ -463,16 +491,17 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
+       }
+       /* Fill in a Tx ring entry */
+-      bdp = txq->bd.cur;
++      bdp = txq->cur_tx;
+       last_bdp = bdp;
+-      status = fec16_to_cpu(bdp->cbd_sc);
++      status = bdp->cbd_sc;
+       status &= ~BD_ENET_TX_STATS;
+       /* Set buffer length and buffer pointer */
+       bufaddr = skb->data;
+       buflen = skb_headlen(skb);
+-      index = fec_enet_get_bd_index(bdp, &txq->bd);
++      queue = skb_get_queue_mapping(skb);
++      index = fec_enet_get_bd_index(txq->tx_bd_base, bdp, fep);
+       if (((unsigned long) bufaddr) & fep->tx_align ||
+               fep->quirks & FEC_QUIRK_SWAP_FRAME) {
+               memcpy(txq->tx_bounce[index], skb->data, buflen);
+@@ -493,12 +522,8 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
+       if (nr_frags) {
+               last_bdp = fec_enet_txq_submit_frag_skb(txq, skb, ndev);
+-              if (IS_ERR(last_bdp)) {
+-                      dma_unmap_single(&fep->pdev->dev, addr,
+-                                       buflen, DMA_TO_DEVICE);
+-                      dev_kfree_skb_any(skb);
++              if (IS_ERR(last_bdp))
+                       return NETDEV_TX_OK;
+-              }
+       } else {
+               status |= (BD_ENET_TX_INTR | BD_ENET_TX_LAST);
+               if (fep->bufdesc_ex) {
+@@ -508,8 +533,6 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
+                               estatus |= BD_ENET_TX_TS;
+               }
+       }
+-      bdp->cbd_bufaddr = cpu_to_fec32(addr);
+-      bdp->cbd_datlen = cpu_to_fec16(buflen);
+       if (fep->bufdesc_ex) {
+@@ -520,43 +543,41 @@ static int fec_enet_txq_submit_skb(struct fec_enet_priv_tx_q *txq,
+                       skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+               if (fep->quirks & FEC_QUIRK_HAS_AVB)
+-                      estatus |= FEC_TX_BD_FTYPE(txq->bd.qid);
++                      estatus |= FEC_TX_BD_FTYPE(queue);
+               if (skb->ip_summed == CHECKSUM_PARTIAL)
+                       estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
+               ebdp->cbd_bdu = 0;
+-              ebdp->cbd_esc = cpu_to_fec32(estatus);
++              ebdp->cbd_esc = estatus;
+       }
+-      index = fec_enet_get_bd_index(last_bdp, &txq->bd);
++      index = fec_enet_get_bd_index(txq->tx_bd_base, last_bdp, fep);
+       /* Save skb pointer */
+       txq->tx_skbuff[index] = skb;
+-      /* Make sure the updates to rest of the descriptor are performed before
+-       * transferring ownership.
+-       */
+-      wmb();
++      bdp->cbd_datlen = buflen;
++      bdp->cbd_bufaddr = addr;
+       /* Send it on its way.  Tell FEC it's ready, interrupt when done,
+        * it's the last BD of the frame, and to put the CRC on the end.
+        */
+       status |= (BD_ENET_TX_READY | BD_ENET_TX_TC);
+-      bdp->cbd_sc = cpu_to_fec16(status);
++      bdp->cbd_sc = status;
+       /* If this was the last BD in the ring, start at the beginning again. */
+-      bdp = fec_enet_get_nextdesc(last_bdp, &txq->bd);
++      bdp = fec_enet_get_nextdesc(last_bdp, fep, queue);
+       skb_tx_timestamp(skb);
+       /* Make sure the update to bdp and tx_skbuff are performed before
+-       * txq->bd.cur.
++       * cur_tx.
+        */
+       wmb();
+-      txq->bd.cur = bdp;
++      txq->cur_tx = bdp;
+       /* Trigger transmission start */
+-      writel(0, txq->bd.reg_desc_active);
++      writel(0, fep->hwp + FEC_X_DES_ACTIVE(queue));
+       return 0;
+ }
+@@ -569,11 +590,12 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
+ {
+       struct fec_enet_private *fep = netdev_priv(ndev);
+       struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc);
++      unsigned short queue = skb_get_queue_mapping(skb);
+       unsigned short status;
+       unsigned int estatus = 0;
+       dma_addr_t addr;
+-      status = fec16_to_cpu(bdp->cbd_sc);
++      status = bdp->cbd_sc;
+       status &= ~BD_ENET_TX_STATS;
+       status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
+@@ -595,16 +617,16 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
+               return NETDEV_TX_BUSY;
+       }
+-      bdp->cbd_datlen = cpu_to_fec16(size);
+-      bdp->cbd_bufaddr = cpu_to_fec32(addr);
++      bdp->cbd_datlen = size;
++      bdp->cbd_bufaddr = addr;
+       if (fep->bufdesc_ex) {
+               if (fep->quirks & FEC_QUIRK_HAS_AVB)
+-                      estatus |= FEC_TX_BD_FTYPE(txq->bd.qid);
++                      estatus |= FEC_TX_BD_FTYPE(queue);
+               if (skb->ip_summed == CHECKSUM_PARTIAL)
+                       estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
+               ebdp->cbd_bdu = 0;
+-              ebdp->cbd_esc = cpu_to_fec32(estatus);
++              ebdp->cbd_esc = estatus;
+       }
+       /* Handle the last BD specially */
+@@ -613,10 +635,10 @@ fec_enet_txq_put_data_tso(struct fec_enet_priv_tx_q *txq, struct sk_buff *skb,
+       if (is_last) {
+               status |= BD_ENET_TX_INTR;
+               if (fep->bufdesc_ex)
+-                      ebdp->cbd_esc |= cpu_to_fec32(BD_ENET_TX_INT);
++                      ebdp->cbd_esc |= BD_ENET_TX_INT;
+       }
+-      bdp->cbd_sc = cpu_to_fec16(status);
++      bdp->cbd_sc = status;
+       return 0;
+ }
+@@ -629,12 +651,13 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
+       struct fec_enet_private *fep = netdev_priv(ndev);
+       int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+       struct bufdesc_ex *ebdp = container_of(bdp, struct bufdesc_ex, desc);
++      unsigned short queue = skb_get_queue_mapping(skb);
+       void *bufaddr;
+       unsigned long dmabuf;
+       unsigned short status;
+       unsigned int estatus = 0;
+-      status = fec16_to_cpu(bdp->cbd_sc);
++      status = bdp->cbd_sc;
+       status &= ~BD_ENET_TX_STATS;
+       status |= (BD_ENET_TX_TC | BD_ENET_TX_READY);
+@@ -658,19 +681,19 @@ fec_enet_txq_put_hdr_tso(struct fec_enet_priv_tx_q *txq,
+               }
+       }
+-      bdp->cbd_bufaddr = cpu_to_fec32(dmabuf);
+-      bdp->cbd_datlen = cpu_to_fec16(hdr_len);
++      bdp->cbd_bufaddr = dmabuf;
++      bdp->cbd_datlen = hdr_len;
+       if (fep->bufdesc_ex) {
+               if (fep->quirks & FEC_QUIRK_HAS_AVB)
+-                      estatus |= FEC_TX_BD_FTYPE(txq->bd.qid);
++                      estatus |= FEC_TX_BD_FTYPE(queue);
+               if (skb->ip_summed == CHECKSUM_PARTIAL)
+                       estatus |= BD_ENET_TX_PINS | BD_ENET_TX_IINS;
+               ebdp->cbd_bdu = 0;
+-              ebdp->cbd_esc = cpu_to_fec32(estatus);
++              ebdp->cbd_esc = estatus;
+       }
+-      bdp->cbd_sc = cpu_to_fec16(status);
++      bdp->cbd_sc = status;
+       return 0;
+ }
+@@ -682,12 +705,13 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
+       struct fec_enet_private *fep = netdev_priv(ndev);
+       int hdr_len = skb_transport_offset(skb) + tcp_hdrlen(skb);
+       int total_len, data_left;
+-      struct bufdesc *bdp = txq->bd.cur;
++      struct bufdesc *bdp = txq->cur_tx;
++      unsigned short queue = skb_get_queue_mapping(skb);
+       struct tso_t tso;
+       unsigned int index = 0;
+       int ret;
+-      if (tso_count_descs(skb) >= fec_enet_get_free_txdesc_num(txq)) {
++      if (tso_count_descs(skb) >= fec_enet_get_free_txdesc_num(fep, txq)) {
+               dev_kfree_skb_any(skb);
+               if (net_ratelimit())
+                       netdev_err(ndev, "NOT enough BD for TSO!\n");
+@@ -707,7 +731,7 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
+       while (total_len > 0) {
+               char *hdr;
+-              index = fec_enet_get_bd_index(bdp, &txq->bd);
++              index = fec_enet_get_bd_index(txq->tx_bd_base, bdp, fep);
+               data_left = min_t(int, skb_shinfo(skb)->gso_size, total_len);
+               total_len -= data_left;
+@@ -722,8 +746,9 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
+                       int size;
+                       size = min_t(int, tso.size, data_left);
+-                      bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
+-                      index = fec_enet_get_bd_index(bdp, &txq->bd);
++                      bdp = fec_enet_get_nextdesc(bdp, fep, queue);
++                      index = fec_enet_get_bd_index(txq->tx_bd_base,
++                                                    bdp, fep);
+                       ret = fec_enet_txq_put_data_tso(txq, skb, ndev,
+                                                       bdp, index,
+                                                       tso.data, size,
+@@ -736,22 +761,22 @@ static int fec_enet_txq_submit_tso(struct fec_enet_priv_tx_q *txq,
+                       tso_build_data(skb, &tso, size);
+               }
+-              bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
++              bdp = fec_enet_get_nextdesc(bdp, fep, queue);
+       }
+       /* Save skb pointer */
+       txq->tx_skbuff[index] = skb;
+       skb_tx_timestamp(skb);
+-      txq->bd.cur = bdp;
++      txq->cur_tx = bdp;
+       /* Trigger transmission start */
+       if (!(fep->quirks & FEC_QUIRK_ERR007885) ||
+-          !readl(txq->bd.reg_desc_active) ||
+-          !readl(txq->bd.reg_desc_active) ||
+-          !readl(txq->bd.reg_desc_active) ||
+-          !readl(txq->bd.reg_desc_active))
+-              writel(0, txq->bd.reg_desc_active);
++          !readl(fep->hwp + FEC_X_DES_ACTIVE(queue)) ||
++          !readl(fep->hwp + FEC_X_DES_ACTIVE(queue)) ||
++          !readl(fep->hwp + FEC_X_DES_ACTIVE(queue)) ||
++          !readl(fep->hwp + FEC_X_DES_ACTIVE(queue)))
++              writel(0, fep->hwp + FEC_X_DES_ACTIVE(queue));
+       return 0;
+@@ -781,7 +806,7 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *ndev)
+       if (ret)
+               return ret;
+-      entries_free = fec_enet_get_free_txdesc_num(txq);
++      entries_free = fec_enet_get_free_txdesc_num(fep, txq);
+       if (entries_free <= txq->tx_stop_threshold)
+               netif_tx_stop_queue(nq);
+@@ -802,45 +827,45 @@ static void fec_enet_bd_init(struct net_device *dev)
+       for (q = 0; q < fep->num_rx_queues; q++) {
+               /* Initialize the receive buffer descriptors. */
+               rxq = fep->rx_queue[q];
+-              bdp = rxq->bd.base;
++              bdp = rxq->rx_bd_base;
+-              for (i = 0; i < rxq->bd.ring_size; i++) {
++              for (i = 0; i < rxq->rx_ring_size; i++) {
+                       /* Initialize the BD for every fragment in the page. */
+                       if (bdp->cbd_bufaddr)
+-                              bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY);
++                              bdp->cbd_sc = BD_ENET_RX_EMPTY;
+                       else
+-                              bdp->cbd_sc = cpu_to_fec16(0);
+-                      bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
++                              bdp->cbd_sc = 0;
++                      bdp = fec_enet_get_nextdesc(bdp, fep, q);
+               }
+               /* Set the last buffer to wrap */
+-              bdp = fec_enet_get_prevdesc(bdp, &rxq->bd);
+-              bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
++              bdp = fec_enet_get_prevdesc(bdp, fep, q);
++              bdp->cbd_sc |= BD_SC_WRAP;
+-              rxq->bd.cur = rxq->bd.base;
++              rxq->cur_rx = rxq->rx_bd_base;
+       }
+       for (q = 0; q < fep->num_tx_queues; q++) {
+               /* ...and the same for transmit */
+               txq = fep->tx_queue[q];
+-              bdp = txq->bd.base;
+-              txq->bd.cur = bdp;
++              bdp = txq->tx_bd_base;
++              txq->cur_tx = bdp;
+-              for (i = 0; i < txq->bd.ring_size; i++) {
++              for (i = 0; i < txq->tx_ring_size; i++) {
+                       /* Initialize the BD for every fragment in the page. */
+-                      bdp->cbd_sc = cpu_to_fec16(0);
++                      bdp->cbd_sc = 0;
+                       if (txq->tx_skbuff[i]) {
+                               dev_kfree_skb_any(txq->tx_skbuff[i]);
+                               txq->tx_skbuff[i] = NULL;
+                       }
+-                      bdp->cbd_bufaddr = cpu_to_fec32(0);
+-                      bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
++                      bdp->cbd_bufaddr = 0;
++                      bdp = fec_enet_get_nextdesc(bdp, fep, q);
+               }
+               /* Set the last buffer to wrap */
+-              bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
+-              bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
++              bdp = fec_enet_get_prevdesc(bdp, fep, q);
++              bdp->cbd_sc |= BD_SC_WRAP;
+               txq->dirty_tx = bdp;
+       }
+ }
+@@ -851,7 +876,7 @@ static void fec_enet_active_rxring(struct net_device *ndev)
+       int i;
+       for (i = 0; i < fep->num_rx_queues; i++)
+-              writel(0, fep->rx_queue[i]->bd.reg_desc_active);
++              writel(0, fep->hwp + FEC_R_DES_ACTIVE(i));
+ }
+ static void fec_enet_enable_ring(struct net_device *ndev)
+@@ -863,7 +888,7 @@ static void fec_enet_enable_ring(struct net_device *ndev)
+       for (i = 0; i < fep->num_rx_queues; i++) {
+               rxq = fep->rx_queue[i];
+-              writel(rxq->bd.dma, fep->hwp + FEC_R_DES_START(i));
++              writel(rxq->bd_dma, fep->hwp + FEC_R_DES_START(i));
+               writel(PKT_MAXBLR_SIZE, fep->hwp + FEC_R_BUFF_SIZE(i));
+               /* enable DMA1/2 */
+@@ -874,7 +899,7 @@ static void fec_enet_enable_ring(struct net_device *ndev)
+       for (i = 0; i < fep->num_tx_queues; i++) {
+               txq = fep->tx_queue[i];
+-              writel(txq->bd.dma, fep->hwp + FEC_X_DES_START(i));
++              writel(txq->bd_dma, fep->hwp + FEC_X_DES_START(i));
+               /* enable DMA1/2 */
+               if (i)
+@@ -892,7 +917,7 @@ static void fec_enet_reset_skb(struct net_device *ndev)
+       for (i = 0; i < fep->num_tx_queues; i++) {
+               txq = fep->tx_queue[i];
+-              for (j = 0; j < txq->bd.ring_size; j++) {
++              for (j = 0; j < txq->tx_ring_size; j++) {
+                       if (txq->tx_skbuff[j]) {
+                               dev_kfree_skb_any(txq->tx_skbuff[j]);
+                               txq->tx_skbuff[j] = NULL;
+@@ -930,11 +955,11 @@ fec_restart(struct net_device *ndev)
+        * enet-mac reset will reset mac address registers too,
+        * so need to reconfigure it.
+        */
+-      memcpy(&temp_mac, ndev->dev_addr, ETH_ALEN);
+-      writel((__force u32)cpu_to_be32(temp_mac[0]),
+-             fep->hwp + FEC_ADDR_LOW);
+-      writel((__force u32)cpu_to_be32(temp_mac[1]),
+-             fep->hwp + FEC_ADDR_HIGH);
++      if (fep->quirks & FEC_QUIRK_ENET_MAC) {
++              memcpy(&temp_mac, ndev->dev_addr, ETH_ALEN);
++              writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
++              writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
++      }
+       /* Clear any outstanding interrupt. */
+       writel(0xffffffff, fep->hwp + FEC_IEVENT);
+@@ -961,16 +986,13 @@ fec_restart(struct net_device *ndev)
+ #if !defined(CONFIG_M5272)
+       if (fep->quirks & FEC_QUIRK_HAS_RACC) {
++              /* set RX checksum */
+               val = readl(fep->hwp + FEC_RACC);
+-              /* align IP header */
+-              val |= FEC_RACC_SHIFT16;
+               if (fep->csum_flags & FLAG_RX_CSUM_ENABLED)
+-                      /* set RX checksum */
+                       val |= FEC_RACC_OPTIONS;
+               else
+                       val &= ~FEC_RACC_OPTIONS;
+               writel(val, fep->hwp + FEC_RACC);
+-              writel(PKT_MAXBUF_SIZE, fep->hwp + FEC_FTRL);
+       }
+       writel(PKT_MAXBUF_SIZE, fep->hwp + FEC_FTRL);
+ #endif
+@@ -995,10 +1017,10 @@ fec_restart(struct net_device *ndev)
+                       rcntl &= ~(1 << 8);
+               /* 1G, 100M or 10M */
+-              if (ndev->phydev) {
+-                      if (ndev->phydev->speed == SPEED_1000)
++              if (fep->phy_dev) {
++                      if (fep->phy_dev->speed == SPEED_1000)
+                               ecntl |= (1 << 5);
+-                      else if (ndev->phydev->speed == SPEED_100)
++                      else if (fep->phy_dev->speed == SPEED_100)
+                               rcntl &= ~(1 << 9);
+                       else
+                               rcntl |= (1 << 9);
+@@ -1019,7 +1041,7 @@ fec_restart(struct net_device *ndev)
+                        */
+                       cfgr = (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
+                               ? BM_MIIGSK_CFGR_RMII : BM_MIIGSK_CFGR_MII;
+-                      if (ndev->phydev && ndev->phydev->speed == SPEED_10)
++                      if (fep->phy_dev && fep->phy_dev->speed == SPEED_10)
+                               cfgr |= BM_MIIGSK_CFGR_FRCONT_10M;
+                       writel(cfgr, fep->hwp + FEC_MIIGSK_CFGR);
+@@ -1033,7 +1055,7 @@ fec_restart(struct net_device *ndev)
+       /* enable pause frame*/
+       if ((fep->pause_flag & FEC_PAUSE_FLAG_ENABLE) ||
+           ((fep->pause_flag & FEC_PAUSE_FLAG_AUTONEG) &&
+-           ndev->phydev && ndev->phydev->pause)) {
++           fep->phy_dev && fep->phy_dev->pause)) {
+               rcntl |= FEC_ENET_FCE;
+               /* set FIFO threshold parameter to reduce overrun */
+@@ -1213,12 +1235,13 @@ static void
+ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
+ {
+       struct  fec_enet_private *fep;
+-      struct bufdesc *bdp;
++      struct bufdesc *bdp, *bdp_t;
+       unsigned short status;
+       struct  sk_buff *skb;
+       struct fec_enet_priv_tx_q *txq;
+       struct netdev_queue *nq;
+       int     index = 0;
++      int     i, bdnum;
+       int     entries_free;
+       fep = netdev_priv(ndev);
+@@ -1231,27 +1254,37 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
+       bdp = txq->dirty_tx;
+       /* get next bdp of dirty_tx */
+-      bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
++      bdp = fec_enet_get_nextdesc(bdp, fep, queue_id);
+-      while (bdp != READ_ONCE(txq->bd.cur)) {
+-              /* Order the load of bd.cur and cbd_sc */
++      while (bdp != READ_ONCE(txq->cur_tx)) {
++              /* Order the load of cur_tx and cbd_sc */
+               rmb();
+-              status = fec16_to_cpu(READ_ONCE(bdp->cbd_sc));
++              status = READ_ONCE(bdp->cbd_sc);
+               if (status & BD_ENET_TX_READY)
+                       break;
+-              index = fec_enet_get_bd_index(bdp, &txq->bd);
+-
++              bdp_t = bdp;
++              bdnum = 1;
++              index = fec_enet_get_bd_index(txq->tx_bd_base, bdp_t, fep);
+               skb = txq->tx_skbuff[index];
++              while (!skb) {
++                      bdp_t = fec_enet_get_nextdesc(bdp_t, fep, queue_id);
++                      index = fec_enet_get_bd_index(txq->tx_bd_base, bdp_t, fep);
++                      skb = txq->tx_skbuff[index];
++                      bdnum++;
++              }
++              if ((status = bdp_t->cbd_sc) & BD_ENET_TX_READY)
++                      break;
++
++              for (i = 0; i < bdnum; i++) {
++                      if (!IS_TSO_HEADER(txq, bdp->cbd_bufaddr))
++                              dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
++                                               bdp->cbd_datlen, DMA_TO_DEVICE);
++                      bdp->cbd_bufaddr = 0;
++                      if (i < bdnum - 1)
++                              bdp = fec_enet_get_nextdesc(bdp, fep, queue_id);
++              }
+               txq->tx_skbuff[index] = NULL;
+-              if (!IS_TSO_HEADER(txq, fec32_to_cpu(bdp->cbd_bufaddr)))
+-                      dma_unmap_single(&fep->pdev->dev,
+-                                       fec32_to_cpu(bdp->cbd_bufaddr),
+-                                       fec16_to_cpu(bdp->cbd_datlen),
+-                                       DMA_TO_DEVICE);
+-              bdp->cbd_bufaddr = cpu_to_fec32(0);
+-              if (!skb)
+-                      goto skb_done;
+               /* Check for errors. */
+               if (status & (BD_ENET_TX_HB | BD_ENET_TX_LC |
+@@ -1278,7 +1311,7 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
+                       struct skb_shared_hwtstamps shhwtstamps;
+                       struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
+-                      fec_enet_hwtstamp(fep, fec32_to_cpu(ebdp->ts), &shhwtstamps);
++                      fec_enet_hwtstamp(fep, ebdp->ts, &shhwtstamps);
+                       skb_tstamp_tx(skb, &shhwtstamps);
+               }
+@@ -1290,7 +1323,7 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
+               /* Free the sk buffer associated with this last transmit */
+               dev_kfree_skb_any(skb);
+-skb_done:
++
+               /* Make sure the update to bdp and tx_skbuff are performed
+                * before dirty_tx
+                */
+@@ -1298,21 +1331,21 @@ fec_enet_tx_queue(struct net_device *ndev, u16 queue_id)
+               txq->dirty_tx = bdp;
+               /* Update pointer to next buffer descriptor to be transmitted */
+-              bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
++              bdp = fec_enet_get_nextdesc(bdp, fep, queue_id);
+               /* Since we have freed up a buffer, the ring is no longer full
+                */
+               if (netif_queue_stopped(ndev)) {
+-                      entries_free = fec_enet_get_free_txdesc_num(txq);
++                      entries_free = fec_enet_get_free_txdesc_num(fep, txq);
+                       if (entries_free >= txq->tx_wake_threshold)
+                               netif_tx_wake_queue(nq);
+               }
+       }
+       /* ERR006538: Keep the transmitter going */
+-      if (bdp != txq->bd.cur &&
+-          readl(txq->bd.reg_desc_active) == 0)
+-              writel(0, txq->bd.reg_desc_active);
++      if (bdp != txq->cur_tx &&
++          readl(fep->hwp + FEC_X_DES_ACTIVE(queue_id)) == 0)
++              writel(0, fep->hwp + FEC_X_DES_ACTIVE(queue_id));
+ }
+ static void
+@@ -1338,8 +1371,10 @@ fec_enet_new_rxbdp(struct net_device *ndev, struct bufdesc *bdp, struct sk_buff
+       if (off)
+               skb_reserve(skb, fep->rx_align + 1 - off);
+-      bdp->cbd_bufaddr = cpu_to_fec32(dma_map_single(&fep->pdev->dev, skb->data, FEC_ENET_RX_FRSIZE - fep->rx_align, DMA_FROM_DEVICE));
+-      if (dma_mapping_error(&fep->pdev->dev, fec32_to_cpu(bdp->cbd_bufaddr))) {
++      bdp->cbd_bufaddr = dma_map_single(&fep->pdev->dev, skb->data,
++                                        FEC_ENET_RX_FRSIZE - fep->rx_align,
++                                        DMA_FROM_DEVICE);
++      if (dma_mapping_error(&fep->pdev->dev, bdp->cbd_bufaddr)) {
+               if (net_ratelimit())
+                       netdev_err(ndev, "Rx DMA memory map failed\n");
+               return -ENOMEM;
+@@ -1361,8 +1396,7 @@ static bool fec_enet_copybreak(struct net_device *ndev, struct sk_buff **skb,
+       if (!new_skb)
+               return false;
+-      dma_sync_single_for_cpu(&fep->pdev->dev,
+-                              fec32_to_cpu(bdp->cbd_bufaddr),
++      dma_sync_single_for_cpu(&fep->pdev->dev, bdp->cbd_bufaddr,
+                               FEC_ENET_RX_FRSIZE - fep->rx_align,
+                               DMA_FROM_DEVICE);
+       if (!swap)
+@@ -1374,7 +1408,7 @@ static bool fec_enet_copybreak(struct net_device *ndev, struct sk_buff **skb,
+       return true;
+ }
+-/* During a receive, the bd_rx.cur points to the current incoming buffer.
++/* During a receive, the cur_rx points to the current incoming buffer.
+  * When we update through the ring, if the next incoming buffer has
+  * not been given to the system, we just set the empty indicator,
+  * effectively tossing the packet.
+@@ -1407,9 +1441,9 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+       /* First, grab all of the stats for the incoming packet.
+        * These get messed up if we get called due to a busy condition.
+        */
+-      bdp = rxq->bd.cur;
++      bdp = rxq->cur_rx;
+-      while (!((status = fec16_to_cpu(bdp->cbd_sc)) & BD_ENET_RX_EMPTY)) {
++      while (!((status = bdp->cbd_sc) & BD_ENET_RX_EMPTY)) {
+               if (pkt_received >= budget)
+                       break;
+@@ -1445,10 +1479,10 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+               /* Process the incoming frame. */
+               ndev->stats.rx_packets++;
+-              pkt_len = fec16_to_cpu(bdp->cbd_datlen);
++              pkt_len = bdp->cbd_datlen;
+               ndev->stats.rx_bytes += pkt_len;
+-              index = fec_enet_get_bd_index(bdp, &rxq->bd);
++              index = fec_enet_get_bd_index(rxq->rx_bd_base, bdp, fep);
+               skb = rxq->rx_skbuff[index];
+               /* The packet length includes FCS, but we don't want to
+@@ -1463,8 +1497,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+                               ndev->stats.rx_dropped++;
+                               goto rx_processing_done;
+                       }
+-                      dma_unmap_single(&fep->pdev->dev,
+-                                       fec32_to_cpu(bdp->cbd_bufaddr),
++                      dma_unmap_single(&fep->pdev->dev, bdp->cbd_bufaddr,
+                                        FEC_ENET_RX_FRSIZE - fep->rx_align,
+                                        DMA_FROM_DEVICE);
+               }
+@@ -1472,15 +1505,9 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+               prefetch(skb->data - NET_IP_ALIGN);
+               skb_put(skb, pkt_len - 4);
+               data = skb->data;
+-
+               if (!is_copybreak && need_swap)
+                       swap_buffer(data, pkt_len);
+-#if !defined(CONFIG_M5272)
+-              if (fep->quirks & FEC_QUIRK_HAS_RACC)
+-                      data = skb_pull_inline(skb, 2);
+-#endif
+-
+               /* Extract the enhanced buffer descriptor */
+               ebdp = NULL;
+               if (fep->bufdesc_ex)
+@@ -1489,8 +1516,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+               /* If this is a VLAN packet remove the VLAN Tag */
+               vlan_packet_rcvd = false;
+               if ((ndev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
+-                  fep->bufdesc_ex &&
+-                  (ebdp->cbd_esc & cpu_to_fec32(BD_ENET_RX_VLAN))) {
++                      fep->bufdesc_ex && (ebdp->cbd_esc & BD_ENET_RX_VLAN)) {
+                       /* Push and remove the vlan tag */
+                       struct vlan_hdr *vlan_header =
+                                       (struct vlan_hdr *) (data + ETH_HLEN);
+@@ -1506,12 +1532,12 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+               /* Get receive timestamp from the skb */
+               if (fep->hwts_rx_en && fep->bufdesc_ex)
+-                      fec_enet_hwtstamp(fep, fec32_to_cpu(ebdp->ts),
++                      fec_enet_hwtstamp(fep, ebdp->ts,
+                                         skb_hwtstamps(skb));
+               if (fep->bufdesc_ex &&
+                   (fep->csum_flags & FLAG_RX_CSUM_ENABLED)) {
+-                      if (!(ebdp->cbd_esc & cpu_to_fec32(FLAG_RX_CSUM_ERROR))) {
++                      if (!(ebdp->cbd_esc & FLAG_RX_CSUM_ERROR)) {
+                               /* don't check it */
+                               skb->ip_summed = CHECKSUM_UNNECESSARY;
+                       } else {
+@@ -1528,8 +1554,7 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+               napi_gro_receive(&fep->napi, skb);
+               if (is_copybreak) {
+-                      dma_sync_single_for_device(&fep->pdev->dev,
+-                                                 fec32_to_cpu(bdp->cbd_bufaddr),
++                      dma_sync_single_for_device(&fep->pdev->dev, bdp->cbd_bufaddr,
+                                                  FEC_ENET_RX_FRSIZE - fep->rx_align,
+                                                  DMA_FROM_DEVICE);
+               } else {
+@@ -1543,30 +1568,26 @@ fec_enet_rx_queue(struct net_device *ndev, int budget, u16 queue_id)
+               /* Mark the buffer empty */
+               status |= BD_ENET_RX_EMPTY;
++              bdp->cbd_sc = status;
+               if (fep->bufdesc_ex) {
+                       struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
+-                      ebdp->cbd_esc = cpu_to_fec32(BD_ENET_RX_INT);
++                      ebdp->cbd_esc = BD_ENET_RX_INT;
+                       ebdp->cbd_prot = 0;
+                       ebdp->cbd_bdu = 0;
+               }
+-              /* Make sure the updates to rest of the descriptor are
+-               * performed before transferring ownership.
+-               */
+-              wmb();
+-              bdp->cbd_sc = cpu_to_fec16(status);
+               /* Update BD pointer to next entry */
+-              bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
++              bdp = fec_enet_get_nextdesc(bdp, fep, queue_id);
+               /* Doing this here will keep the FEC running while we process
+                * incoming frames.  On a heavily loaded network, we should be
+                * able to keep up at the expense of system resources.
+                */
+-              writel(0, rxq->bd.reg_desc_active);
++              writel(0, fep->hwp + FEC_R_DES_ACTIVE(queue_id));
+       }
+-      rxq->bd.cur = bdp;
++      rxq->cur_rx = bdp;
+       return pkt_received;
+ }
+@@ -1578,15 +1599,9 @@ fec_enet_rx(struct net_device *ndev, int budget)
+       struct fec_enet_private *fep = netdev_priv(ndev);
+       for_each_set_bit(queue_id, &fep->work_rx, FEC_ENET_MAX_RX_QS) {
+-              int ret;
+-
+-              ret = fec_enet_rx_queue(ndev,
++              clear_bit(queue_id, &fep->work_rx);
++              pkt_received += fec_enet_rx_queue(ndev,
+                                       budget - pkt_received, queue_id);
+-
+-              if (ret < budget - pkt_received)
+-                      clear_bit(queue_id, &fep->work_rx);
+-
+-              pkt_received += ret;
+       }
+       return pkt_received;
+ }
+@@ -1631,7 +1646,7 @@ fec_enet_interrupt(int irq, void *dev_id)
+               if (napi_schedule_prep(&fep->napi)) {
+                       /* Disable the NAPI interrupts */
+-                      writel(FEC_NAPI_IMASK, fep->hwp + FEC_IMASK);
++                      writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
+                       __napi_schedule(&fep->napi);
+               }
+       }
+@@ -1742,7 +1757,7 @@ static void fec_get_mac(struct net_device *ndev)
+ static void fec_enet_adjust_link(struct net_device *ndev)
+ {
+       struct fec_enet_private *fep = netdev_priv(ndev);
+-      struct phy_device *phy_dev = ndev->phydev;
++      struct phy_device *phy_dev = fep->phy_dev;
+       int status_change = 0;
+       /* Prevent a state halted on mii error */
+@@ -1802,16 +1817,10 @@ static void fec_enet_adjust_link(struct net_device *ndev)
+ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+ {
+       struct fec_enet_private *fep = bus->priv;
+-      struct device *dev = &fep->pdev->dev;
+       unsigned long time_left;
+-      int ret = 0;
+-
+-      ret = pm_runtime_get_sync(dev);
+-      if (ret < 0)
+-              return ret;
+       fep->mii_timeout = 0;
+-      reinit_completion(&fep->mdio_done);
++      init_completion(&fep->mdio_done);
+       /* start a read op */
+       writel(FEC_MMFR_ST | FEC_MMFR_OP_READ |
+@@ -1824,35 +1833,21 @@ static int fec_enet_mdio_read(struct mii_bus *bus, int mii_id, int regnum)
+       if (time_left == 0) {
+               fep->mii_timeout = 1;
+               netdev_err(fep->netdev, "MDIO read timeout\n");
+-              ret = -ETIMEDOUT;
+-              goto out;
++              return -ETIMEDOUT;
+       }
+-      ret = FEC_MMFR_DATA(readl(fep->hwp + FEC_MII_DATA));
+-
+-out:
+-      pm_runtime_mark_last_busy(dev);
+-      pm_runtime_put_autosuspend(dev);
+-
+-      return ret;
++      /* return value */
++      return FEC_MMFR_DATA(readl(fep->hwp + FEC_MII_DATA));
+ }
+ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+                          u16 value)
+ {
+       struct fec_enet_private *fep = bus->priv;
+-      struct device *dev = &fep->pdev->dev;
+       unsigned long time_left;
+-      int ret;
+-
+-      ret = pm_runtime_get_sync(dev);
+-      if (ret < 0)
+-              return ret;
+-      else
+-              ret = 0;
+       fep->mii_timeout = 0;
+-      reinit_completion(&fep->mdio_done);
++      init_completion(&fep->mdio_done);
+       /* start a write op */
+       writel(FEC_MMFR_ST | FEC_MMFR_OP_WRITE |
+@@ -1866,13 +1861,10 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+       if (time_left == 0) {
+               fep->mii_timeout = 1;
+               netdev_err(fep->netdev, "MDIO write timeout\n");
+-              ret  = -ETIMEDOUT;
++              return -ETIMEDOUT;
+       }
+-      pm_runtime_mark_last_busy(dev);
+-      pm_runtime_put_autosuspend(dev);
+-
+-      return ret;
++      return 0;
+ }
+ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
+@@ -1881,10 +1873,18 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
+       int ret;
+       if (enable) {
++              ret = clk_prepare_enable(fep->clk_ahb);
++              if (ret)
++                      return ret;
++              ret = clk_prepare_enable(fep->clk_ipg);
++              if (ret)
++                      goto failed_clk_ipg;
+               if (fep->clk_enet_out) {
+                       ret = clk_prepare_enable(fep->clk_enet_out);
+                       if (ret)
+-                              return ret;
++                              goto failed_clk_enet_out;
++
++                      fec_reset_phy(fep->pdev);
+               }
+               if (fep->clk_ptp) {
+                       mutex_lock(&fep->ptp_clk_mutex);
+@@ -1903,6 +1903,8 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
+                               goto failed_clk_ref;
+               }
+       } else {
++              clk_disable_unprepare(fep->clk_ahb);
++              clk_disable_unprepare(fep->clk_ipg);
+               if (fep->clk_enet_out)
+                       clk_disable_unprepare(fep->clk_enet_out);
+               if (fep->clk_ptp) {
+@@ -1923,27 +1925,23 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
+ failed_clk_ptp:
+       if (fep->clk_enet_out)
+               clk_disable_unprepare(fep->clk_enet_out);
++failed_clk_enet_out:
++              clk_disable_unprepare(fep->clk_ipg);
++failed_clk_ipg:
++              clk_disable_unprepare(fep->clk_ahb);
+       return ret;
+ }
+-static int fec_restore_mii_bus(struct net_device *ndev)
++static void fec_restore_mii_bus(struct net_device *ndev)
+ {
+       struct fec_enet_private *fep = netdev_priv(ndev);
+-      int ret;
+-
+-      ret = pm_runtime_get_sync(&fep->pdev->dev);
+-      if (ret < 0)
+-              return ret;
++      fec_enet_clk_enable(ndev, true);
+       writel(0xffc00000, fep->hwp + FEC_IEVENT);
+       writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
+       writel(FEC_ENET_MII, fep->hwp + FEC_IMASK);
+       writel(FEC_ENET_ETHEREN, fep->hwp + FEC_ECNTRL);
+-
+-      pm_runtime_mark_last_busy(&fep->pdev->dev);
+-      pm_runtime_put_autosuspend(&fep->pdev->dev);
+-      return 0;
+ }
+ static int fec_enet_mii_probe(struct net_device *ndev)
+@@ -1955,6 +1953,8 @@ static int fec_enet_mii_probe(struct net_device *ndev)
+       int phy_id;
+       int dev_id = fep->dev_id;
++      fep->phy_dev = NULL;
++
+       if (fep->phy_node) {
+               phy_dev = of_phy_connect(ndev, fep->phy_node,
+                                        &fec_enet_adjust_link, 0,
+@@ -1964,7 +1964,11 @@ static int fec_enet_mii_probe(struct net_device *ndev)
+       } else {
+               /* check for attached phy */
+               for (phy_id = 0; (phy_id < PHY_MAX_ADDR); phy_id++) {
+-                      if (!mdiobus_is_registered_device(fep->mii_bus, phy_id))
++                      if ((fep->mii_bus->phy_mask & (1 << phy_id)))
++                              continue;
++                      if (fep->mii_bus->mdio_map[phy_id] == NULL)
++                              continue;
++                      if (fep->mii_bus->mdio_map[phy_id]->addr == 0)
+                               continue;
+                       if (dev_id--)
+                               continue;
+@@ -2002,10 +2006,13 @@ static int fec_enet_mii_probe(struct net_device *ndev)
+       phy_dev->advertising = phy_dev->supported;
++      fep->phy_dev = phy_dev;
+       fep->link = 0;
+       fep->full_duplex = 0;
+-      phy_attached_info(phy_dev);
++      netdev_info(ndev, "Freescale FEC PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
++                  fep->phy_dev->drv->name, NULL,
++                  fep->phy_dev->irq);
+       return 0;
+ }
+@@ -2017,7 +2024,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct fec_enet_private *fep = netdev_priv(ndev);
+       struct device_node *node;
+-      int err = -ENXIO;
++      int err = -ENXIO, i;
+       u32 mii_speed, holdtime;
+       /*
+@@ -2036,7 +2043,7 @@ static int fec_enet_mii_init(struct platform_device *pdev)
+        * mdio interface in board design, and need to be configured by
+        * fec0 mii_bus.
+        */
+-      if ((fep->quirks & FEC_QUIRK_SINGLE_MDIO) && fep->dev_id > 0) {
++      if ((fep->quirks & FEC_QUIRK_ENET_MAC) && fep->dev_id > 0) {
+               /* fec1 uses fec0 mii_bus */
+               if (mii_cnt && fec0_mii_bus) {
+                       fep->mii_bus = fec0_mii_bus;
+@@ -2100,29 +2107,38 @@ static int fec_enet_mii_init(struct platform_device *pdev)
+       fep->mii_bus->priv = fep;
+       fep->mii_bus->parent = &pdev->dev;
++/*    fep->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
++      if (!fep->mii_bus->irq) {
++              err = -ENOMEM;
++              goto err_out_free_mdiobus;
++      }
++*/
++      for (i = 0; i < PHY_MAX_ADDR; i++)
++              fep->mii_bus->irq[i] = PHY_POLL;
++
+       node = of_get_child_by_name(pdev->dev.of_node, "mdio");
+       if (node) {
+               err = of_mdiobus_register(fep->mii_bus, node);
+               of_node_put(node);
+-      } else if (fep->phy_node && !fep->fixed_link) {
+-              err = -EPROBE_DEFER;
+       } else {
+               err = mdiobus_register(fep->mii_bus);
+       }
+       if (err)
+-              goto err_out_free_mdiobus;
++              goto err_out_free_mdio_irq;
+       mii_cnt++;
+       /* save fec0 mii_bus */
+-      if (fep->quirks & FEC_QUIRK_SINGLE_MDIO) {
++      if (fep->quirks & FEC_QUIRK_ENET_MAC) {
+               fec0_mii_bus = fep->mii_bus;
+               fec_mii_bus_share = &fep->mii_bus_share;
+       }
+       return 0;
++err_out_free_mdio_irq:
++      kfree(fep->mii_bus->irq);
+ err_out_free_mdiobus:
+       mdiobus_free(fep->mii_bus);
+ err_out:
+@@ -2133,10 +2149,35 @@ static void fec_enet_mii_remove(struct fec_enet_private *fep)
+ {
+       if (--mii_cnt == 0) {
+               mdiobus_unregister(fep->mii_bus);
++              kfree(fep->mii_bus->irq);
+               mdiobus_free(fep->mii_bus);
+       }
+ }
++static int fec_enet_get_settings(struct net_device *ndev,
++                                struct ethtool_cmd *cmd)
++{
++      struct fec_enet_private *fep = netdev_priv(ndev);
++      struct phy_device *phydev = fep->phy_dev;
++
++      if (!phydev)
++              return -ENODEV;
++
++      return phy_ethtool_gset(phydev, cmd);
++}
++
++static int fec_enet_set_settings(struct net_device *ndev,
++                               struct ethtool_cmd *cmd)
++{
++      struct fec_enet_private *fep = netdev_priv(ndev);
++      struct phy_device *phydev = fep->phy_dev;
++
++      if (!phydev)
++              return -ENODEV;
++
++      return phy_ethtool_sset(phydev, cmd);
++}
++
+ static void fec_enet_get_drvinfo(struct net_device *ndev,
+                                struct ethtool_drvinfo *info)
+ {
+@@ -2163,8 +2204,8 @@ static int fec_enet_get_regs_len(struct net_device *ndev)
+ /* List of registers that can be safety be read to dump them with ethtool */
+ #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+-      defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARM) || \
+-      defined(CONFIG_ARM64)
++      defined(CONFIG_M520x) || defined(CONFIG_M532x) ||               \
++      defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
+ static u32 fec_enet_register_offset[] = {
+       FEC_IEVENT, FEC_IMASK, FEC_R_DES_ACTIVE_0, FEC_X_DES_ACTIVE_0,
+       FEC_ECNTRL, FEC_MII_DATA, FEC_MII_SPEED, FEC_MIB_CTRLSTAT, FEC_R_CNTRL,
+@@ -2270,7 +2311,7 @@ static int fec_enet_set_pauseparam(struct net_device *ndev,
+ {
+       struct fec_enet_private *fep = netdev_priv(ndev);
+-      if (!ndev->phydev)
++      if (!fep->phy_dev)
+               return -ENODEV;
+       if (pause->tx_pause != pause->rx_pause) {
+@@ -2286,17 +2327,17 @@ static int fec_enet_set_pauseparam(struct net_device *ndev,
+       fep->pause_flag |= pause->autoneg ? FEC_PAUSE_FLAG_AUTONEG : 0;
+       if (pause->rx_pause || pause->autoneg) {
+-              ndev->phydev->supported |= ADVERTISED_Pause;
+-              ndev->phydev->advertising |= ADVERTISED_Pause;
++              fep->phy_dev->supported |= ADVERTISED_Pause;
++              fep->phy_dev->advertising |= ADVERTISED_Pause;
+       } else {
+-              ndev->phydev->supported &= ~ADVERTISED_Pause;
+-              ndev->phydev->advertising &= ~ADVERTISED_Pause;
++              fep->phy_dev->supported &= ~ADVERTISED_Pause;
++              fep->phy_dev->advertising &= ~ADVERTISED_Pause;
+       }
+       if (pause->autoneg) {
+               if (netif_running(ndev))
+                       fec_stop(ndev);
+-              phy_start_aneg(ndev->phydev);
++              phy_start_aneg(fep->phy_dev);
+       }
+       if (netif_running(ndev)) {
+               napi_disable(&fep->napi);
+@@ -2376,26 +2417,14 @@ static const struct fec_stat {
+       { "IEEE_rx_octets_ok", IEEE_R_OCTETS_OK },
+ };
+-#define FEC_STATS_SIZE                (ARRAY_SIZE(fec_stats) * sizeof(u64))
+-
+-static void fec_enet_update_ethtool_stats(struct net_device *dev)
++static void fec_enet_get_ethtool_stats(struct net_device *dev,
++      struct ethtool_stats *stats, u64 *data)
+ {
+       struct fec_enet_private *fep = netdev_priv(dev);
+       int i;
+       for (i = 0; i < ARRAY_SIZE(fec_stats); i++)
+-              fep->ethtool_stats[i] = readl(fep->hwp + fec_stats[i].offset);
+-}
+-
+-static void fec_enet_get_ethtool_stats(struct net_device *dev,
+-                                     struct ethtool_stats *stats, u64 *data)
+-{
+-      struct fec_enet_private *fep = netdev_priv(dev);
+-
+-      if (netif_running(dev))
+-              fec_enet_update_ethtool_stats(dev);
+-
+-      memcpy(data, fep->ethtool_stats, FEC_STATS_SIZE);
++              data[i] = readl(fep->hwp + fec_stats[i].offset);
+ }
+ static void fec_enet_get_strings(struct net_device *netdev,
+@@ -2420,17 +2449,12 @@ static int fec_enet_get_sset_count(struct net_device *dev, int sset)
+               return -EOPNOTSUPP;
+       }
+ }
+-
+-#else /* !defined(CONFIG_M5272) */
+-#define FEC_STATS_SIZE        0
+-static inline void fec_enet_update_ethtool_stats(struct net_device *dev)
+-{
+-}
+ #endif /* !defined(CONFIG_M5272) */
+ static int fec_enet_nway_reset(struct net_device *dev)
+ {
+-      struct phy_device *phydev = dev->phydev;
++      struct fec_enet_private *fep = netdev_priv(dev);
++      struct phy_device *phydev = fep->phy_dev;
+       if (!phydev)
+               return -ENODEV;
+@@ -2455,6 +2479,9 @@ static void fec_enet_itr_coal_set(struct net_device *ndev)
+       struct fec_enet_private *fep = netdev_priv(ndev);
+       int rx_itr, tx_itr;
++      if (!(fep->quirks & FEC_QUIRK_HAS_AVB))
++              return;
++
+       /* Must be greater than zero to avoid unpredictable behavior */
+       if (!fep->rx_time_itr || !fep->rx_pkts_itr ||
+           !fep->tx_time_itr || !fep->tx_pkts_itr)
+@@ -2477,12 +2504,10 @@ static void fec_enet_itr_coal_set(struct net_device *ndev)
+       writel(tx_itr, fep->hwp + FEC_TXIC0);
+       writel(rx_itr, fep->hwp + FEC_RXIC0);
+-      if (fep->quirks & FEC_QUIRK_HAS_AVB) {
+-              writel(tx_itr, fep->hwp + FEC_TXIC1);
+-              writel(rx_itr, fep->hwp + FEC_RXIC1);
+-              writel(tx_itr, fep->hwp + FEC_TXIC2);
+-              writel(rx_itr, fep->hwp + FEC_RXIC2);
+-      }
++      writel(tx_itr, fep->hwp + FEC_TXIC1);
++      writel(rx_itr, fep->hwp + FEC_RXIC1);
++      writel(tx_itr, fep->hwp + FEC_TXIC2);
++      writel(rx_itr, fep->hwp + FEC_RXIC2);
+ }
+ static int
+@@ -2490,7 +2515,7 @@ fec_enet_get_coalesce(struct net_device *ndev, struct ethtool_coalesce *ec)
+ {
+       struct fec_enet_private *fep = netdev_priv(ndev);
+-      if (!(fep->quirks & FEC_QUIRK_HAS_COALESCE))
++      if (!(fep->quirks & FEC_QUIRK_HAS_AVB))
+               return -EOPNOTSUPP;
+       ec->rx_coalesce_usecs = fep->rx_time_itr;
+@@ -2508,28 +2533,28 @@ fec_enet_set_coalesce(struct net_device *ndev, struct ethtool_coalesce *ec)
+       struct fec_enet_private *fep = netdev_priv(ndev);
+       unsigned int cycle;
+-      if (!(fep->quirks & FEC_QUIRK_HAS_COALESCE))
++      if (!(fep->quirks & FEC_QUIRK_HAS_AVB))
+               return -EOPNOTSUPP;
+       if (ec->rx_max_coalesced_frames > 255) {
+-              pr_err("Rx coalesced frames exceed hardware limitation\n");
++              pr_err("Rx coalesced frames exceed hardware limiation");
+               return -EINVAL;
+       }
+       if (ec->tx_max_coalesced_frames > 255) {
+-              pr_err("Tx coalesced frame exceed hardware limitation\n");
++              pr_err("Tx coalesced frame exceed hardware limiation");
+               return -EINVAL;
+       }
+       cycle = fec_enet_us_to_itr_clock(ndev, fep->rx_time_itr);
+       if (cycle > 0xFFFF) {
+-              pr_err("Rx coalesced usec exceed hardware limitation\n");
++              pr_err("Rx coalesed usec exceeed hardware limiation");
+               return -EINVAL;
+       }
+       cycle = fec_enet_us_to_itr_clock(ndev, fep->tx_time_itr);
+       if (cycle > 0xFFFF) {
+-              pr_err("Rx coalesced usec exceed hardware limitation\n");
++              pr_err("Rx coalesed usec exceeed hardware limiation");
+               return -EINVAL;
+       }
+@@ -2629,6 +2654,8 @@ fec_enet_set_wol(struct net_device *ndev, struct ethtool_wolinfo *wol)
+ }
+ static const struct ethtool_ops fec_enet_ethtool_ops = {
++      .get_settings           = fec_enet_get_settings,
++      .set_settings           = fec_enet_set_settings,
+       .get_drvinfo            = fec_enet_get_drvinfo,
+       .get_regs_len           = fec_enet_get_regs_len,
+       .get_regs               = fec_enet_get_regs,
+@@ -2648,14 +2675,12 @@ static const struct ethtool_ops fec_enet_ethtool_ops = {
+       .set_tunable            = fec_enet_set_tunable,
+       .get_wol                = fec_enet_get_wol,
+       .set_wol                = fec_enet_set_wol,
+-      .get_link_ksettings     = phy_ethtool_get_link_ksettings,
+-      .set_link_ksettings     = phy_ethtool_set_link_ksettings,
+ };
+ static int fec_enet_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
+ {
+       struct fec_enet_private *fep = netdev_priv(ndev);
+-      struct phy_device *phydev = ndev->phydev;
++      struct phy_device *phydev = fep->phy_dev;
+       if (!netif_running(ndev))
+               return -EINVAL;
+@@ -2685,25 +2710,25 @@ static void fec_enet_free_buffers(struct net_device *ndev)
+       for (q = 0; q < fep->num_rx_queues; q++) {
+               rxq = fep->rx_queue[q];
+-              bdp = rxq->bd.base;
+-              for (i = 0; i < rxq->bd.ring_size; i++) {
++              bdp = rxq->rx_bd_base;
++              for (i = 0; i < rxq->rx_ring_size; i++) {
+                       skb = rxq->rx_skbuff[i];
+                       rxq->rx_skbuff[i] = NULL;
+                       if (skb) {
+                               dma_unmap_single(&fep->pdev->dev,
+-                                               fec32_to_cpu(bdp->cbd_bufaddr),
++                                               bdp->cbd_bufaddr,
+                                                FEC_ENET_RX_FRSIZE - fep->rx_align,
+                                                DMA_FROM_DEVICE);
+                               dev_kfree_skb(skb);
+                       }
+-                      bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
++                      bdp = fec_enet_get_nextdesc(bdp, fep, q);
+               }
+       }
+       for (q = 0; q < fep->num_tx_queues; q++) {
+               txq = fep->tx_queue[q];
+-              bdp = txq->bd.base;
+-              for (i = 0; i < txq->bd.ring_size; i++) {
++              bdp = txq->tx_bd_base;
++              for (i = 0; i < txq->tx_ring_size; i++) {
+                       kfree(txq->tx_bounce[i]);
+                       txq->tx_bounce[i] = NULL;
+                       skb = txq->tx_skbuff[i];
+@@ -2722,8 +2747,8 @@ static void fec_enet_free_queue(struct net_device *ndev)
+       for (i = 0; i < fep->num_tx_queues; i++)
+               if (fep->tx_queue[i] && fep->tx_queue[i]->tso_hdrs) {
+                       txq = fep->tx_queue[i];
+-                      dma_free_coherent(&fep->pdev->dev,
+-                                        txq->bd.ring_size * TSO_HEADER_SIZE,
++                      dma_free_coherent(NULL,
++                                        txq->tx_ring_size * TSO_HEADER_SIZE,
+                                         txq->tso_hdrs,
+                                         txq->tso_hdrs_dma);
+               }
+@@ -2749,15 +2774,15 @@ static int fec_enet_alloc_queue(struct net_device *ndev)
+               }
+               fep->tx_queue[i] = txq;
+-              txq->bd.ring_size = TX_RING_SIZE;
+-              fep->total_tx_ring_size += fep->tx_queue[i]->bd.ring_size;
++              txq->tx_ring_size = TX_RING_SIZE;
++              fep->total_tx_ring_size += fep->tx_queue[i]->tx_ring_size;
+               txq->tx_stop_threshold = FEC_MAX_SKB_DESCS;
+               txq->tx_wake_threshold =
+-                      (txq->bd.ring_size - txq->tx_stop_threshold) / 2;
++                              (txq->tx_ring_size - txq->tx_stop_threshold) / 2;
+-              txq->tso_hdrs = dma_alloc_coherent(&fep->pdev->dev,
+-                                      txq->bd.ring_size * TSO_HEADER_SIZE,
++              txq->tso_hdrs = dma_alloc_coherent(NULL,
++                                      txq->tx_ring_size * TSO_HEADER_SIZE,
+                                       &txq->tso_hdrs_dma,
+                                       GFP_KERNEL);
+               if (!txq->tso_hdrs) {
+@@ -2774,8 +2799,8 @@ static int fec_enet_alloc_queue(struct net_device *ndev)
+                       goto alloc_failed;
+               }
+-              fep->rx_queue[i]->bd.ring_size = RX_RING_SIZE;
+-              fep->total_rx_ring_size += fep->rx_queue[i]->bd.ring_size;
++              fep->rx_queue[i]->rx_ring_size = RX_RING_SIZE;
++              fep->total_rx_ring_size += fep->rx_queue[i]->rx_ring_size;
+       }
+       return ret;
+@@ -2794,8 +2819,8 @@ fec_enet_alloc_rxq_buffers(struct net_device *ndev, unsigned int queue)
+       struct fec_enet_priv_rx_q *rxq;
+       rxq = fep->rx_queue[queue];
+-      bdp = rxq->bd.base;
+-      for (i = 0; i < rxq->bd.ring_size; i++) {
++      bdp = rxq->rx_bd_base;
++      for (i = 0; i < rxq->rx_ring_size; i++) {
+               skb = netdev_alloc_skb(ndev, FEC_ENET_RX_FRSIZE);
+               if (!skb)
+                       goto err_alloc;
+@@ -2806,19 +2831,19 @@ fec_enet_alloc_rxq_buffers(struct net_device *ndev, unsigned int queue)
+               }
+               rxq->rx_skbuff[i] = skb;
+-              bdp->cbd_sc = cpu_to_fec16(BD_ENET_RX_EMPTY);
++              bdp->cbd_sc = BD_ENET_RX_EMPTY;
+               if (fep->bufdesc_ex) {
+                       struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
+-                      ebdp->cbd_esc = cpu_to_fec32(BD_ENET_RX_INT);
++                      ebdp->cbd_esc = BD_ENET_RX_INT;
+               }
+-              bdp = fec_enet_get_nextdesc(bdp, &rxq->bd);
++              bdp = fec_enet_get_nextdesc(bdp, fep, queue);
+       }
+       /* Set the last buffer to wrap. */
+-      bdp = fec_enet_get_prevdesc(bdp, &rxq->bd);
+-      bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
++      bdp = fec_enet_get_prevdesc(bdp, fep, queue);
++      bdp->cbd_sc |= BD_SC_WRAP;
+       return 0;
+  err_alloc:
+@@ -2835,26 +2860,26 @@ fec_enet_alloc_txq_buffers(struct net_device *ndev, unsigned int queue)
+       struct fec_enet_priv_tx_q *txq;
+       txq = fep->tx_queue[queue];
+-      bdp = txq->bd.base;
+-      for (i = 0; i < txq->bd.ring_size; i++) {
++      bdp = txq->tx_bd_base;
++      for (i = 0; i < txq->tx_ring_size; i++) {
+               txq->tx_bounce[i] = kmalloc(FEC_ENET_TX_FRSIZE, GFP_KERNEL);
+               if (!txq->tx_bounce[i])
+                       goto err_alloc;
+-              bdp->cbd_sc = cpu_to_fec16(0);
+-              bdp->cbd_bufaddr = cpu_to_fec32(0);
++              bdp->cbd_sc = 0;
++              bdp->cbd_bufaddr = 0;
+               if (fep->bufdesc_ex) {
+                       struct bufdesc_ex *ebdp = (struct bufdesc_ex *)bdp;
+-                      ebdp->cbd_esc = cpu_to_fec32(BD_ENET_TX_INT);
++                      ebdp->cbd_esc = BD_ENET_TX_INT;
+               }
+-              bdp = fec_enet_get_nextdesc(bdp, &txq->bd);
++              bdp = fec_enet_get_nextdesc(bdp, fep, queue);
+       }
+       /* Set the last buffer to wrap. */
+-      bdp = fec_enet_get_prevdesc(bdp, &txq->bd);
+-      bdp->cbd_sc |= cpu_to_fec16(BD_SC_WRAP);
++      bdp = fec_enet_get_prevdesc(bdp, fep, queue);
++      bdp->cbd_sc |= BD_SC_WRAP;
+       return 0;
+@@ -2903,14 +2928,10 @@ fec_enet_open(struct net_device *ndev)
+                               platform_get_device_id(fep->pdev);
+       int ret;
+-      ret = pm_runtime_get_sync(&fep->pdev->dev);
+-      if (ret < 0)
+-              return ret;
+-
+       pinctrl_pm_select_default_state(&fep->pdev->dev);
+       ret = fec_enet_clk_enable(ndev, true);
+       if (ret)
+-              goto clk_enable;
++              return ret;
+       /* I should reset the ring buffers here, but I don't yet know
+        * a simple way to do that.
+@@ -2928,13 +2949,11 @@ fec_enet_open(struct net_device *ndev)
+       if (ret)
+               goto err_enet_mii_probe;
+-      if (fep->quirks & FEC_QUIRK_ERR006687)
+-              imx6q_cpuidle_fec_irqs_used();
+-
+       napi_enable(&fep->napi);
+-      phy_start(ndev->phydev);
++      phy_start(fep->phy_dev);
+       netif_tx_start_all_queues(ndev);
++      pm_runtime_get_sync(ndev->dev.parent);
+       if ((id_entry->driver_data & FEC_QUIRK_BUG_WAITMODE) &&
+           !fec_enet_irq_workaround(fep))
+               pm_qos_add_request(&fep->pm_qos_req,
+@@ -2947,16 +2966,14 @@ fec_enet_open(struct net_device *ndev)
+       device_set_wakeup_enable(&ndev->dev, fep->wol_flag &
+                                FEC_WOL_FLAG_ENABLE);
++      fep->miibus_up_failed = false;
+       return 0;
+ err_enet_mii_probe:
+       fec_enet_free_buffers(ndev);
+ err_enet_alloc:
+-      fec_enet_clk_enable(ndev, false);
+-clk_enable:
+-      pm_runtime_mark_last_busy(&fep->pdev->dev);
+-      pm_runtime_put_autosuspend(&fep->pdev->dev);
++      fep->miibus_up_failed = true;
+       if (!fep->mii_bus_share)
+               pinctrl_pm_select_sleep_state(&fep->pdev->dev);
+       return ret;
+@@ -2967,7 +2984,7 @@ fec_enet_close(struct net_device *ndev)
+ {
+       struct fec_enet_private *fep = netdev_priv(ndev);
+-      phy_stop(ndev->phydev);
++      phy_stop(fep->phy_dev);
+       if (netif_device_present(ndev)) {
+               napi_disable(&fep->napi);
+@@ -2975,21 +2992,13 @@ fec_enet_close(struct net_device *ndev)
+               fec_stop(ndev);
+       }
+-      phy_disconnect(ndev->phydev);
+-      ndev->phydev = NULL;
+-
+-      if (fep->quirks & FEC_QUIRK_ERR006687)
+-              imx6q_cpuidle_fec_irqs_unused();
+-
+-      fec_enet_update_ethtool_stats(ndev);
++      phy_disconnect(fep->phy_dev);
++      fep->phy_dev = NULL;
+       fec_enet_clk_enable(ndev, false);
+       pm_qos_remove_request(&fep->pm_qos_req);
+-      if (!fep->mii_bus_share)
+-              pinctrl_pm_select_sleep_state(&fep->pdev->dev);
+-      pm_runtime_mark_last_busy(&fep->pdev->dev);
+-      pm_runtime_put_autosuspend(&fep->pdev->dev);
+-
++      pinctrl_pm_select_sleep_state(&fep->pdev->dev);
++      pm_runtime_put_sync_suspend(ndev->dev.parent);
+       fec_enet_free_buffers(ndev);
+       return 0;
+@@ -3005,7 +3014,7 @@ fec_enet_close(struct net_device *ndev)
+  * this kind of feature?).
+  */
+-#define FEC_HASH_BITS 6               /* #bits in hash */
++#define HASH_BITS     6               /* #bits in hash */
+ #define CRC32_POLY    0xEDB88320
+ static void set_multicast_list(struct net_device *ndev)
+@@ -3014,7 +3023,6 @@ static void set_multicast_list(struct net_device *ndev)
+       struct netdev_hw_addr *ha;
+       unsigned int i, bit, data, crc, tmp;
+       unsigned char hash;
+-      unsigned int hash_high, hash_low;
+       if (ndev->flags & IFF_PROMISC) {
+               tmp = readl(fep->hwp + FEC_R_CNTRL);
+@@ -3037,10 +3045,10 @@ static void set_multicast_list(struct net_device *ndev)
+               return;
+       }
+-      /* Add the addresses in hash register
++      /* Clear filter and add the addresses in hash register
+        */
+-      hash_high = 0;
+-      hash_low = 0;
++      writel(0, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
++      writel(0, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+       netdev_for_each_mc_addr(ha, ndev) {
+               /* calculate crc32 value of mac address */
+@@ -3054,20 +3062,21 @@ static void set_multicast_list(struct net_device *ndev)
+                       }
+               }
+-              /* only upper 6 bits (FEC_HASH_BITS) are used
++              /* only upper 6 bits (HASH_BITS) are used
+                * which point to specific bit in he hash registers
+                */
+-              hash = (crc >> (32 - FEC_HASH_BITS)) & 0x3f;
++              hash = (crc >> (32 - HASH_BITS)) & 0x3f;
+               if (hash > 31) {
+-                      hash_high |= 1 << (hash - 32);
++                      tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
++                      tmp |= 1 << (hash - 32);
++                      writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+               } else {
+-                      hash_low |= 1 << hash;
++                      tmp = readl(fep->hwp + FEC_GRP_HASH_TABLE_LOW);
++                      tmp |= 1 << hash;
++                      writel(tmp, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+               }
+       }
+-
+-      writel_relaxed(hash_high, fep->hwp + FEC_GRP_HASH_TABLE_HIGH);
+-      writel_relaxed(hash_low, fep->hwp + FEC_GRP_HASH_TABLE_LOW);
+ }
+ /* Set a MAC change in hardware. */
+@@ -3122,6 +3131,7 @@ static void fec_poll_controller(struct net_device *dev)
+ }
+ #endif
++#define FEATURES_NEED_QUIESCE NETIF_F_RXCSUM
+ static inline void fec_enet_set_netdev_features(struct net_device *netdev,
+       netdev_features_t features)
+ {
+@@ -3145,7 +3155,7 @@ static int fec_set_features(struct net_device *netdev,
+       struct fec_enet_private *fep = netdev_priv(netdev);
+       netdev_features_t changed = features ^ netdev->features;
+-      if (netif_running(netdev) && changed & NETIF_F_RXCSUM) {
++      if (netif_running(netdev) && changed & FEATURES_NEED_QUIESCE) {
+               napi_disable(&fep->napi);
+               netif_tx_lock_bh(netdev);
+               fec_stop(netdev);
+@@ -3209,14 +3219,6 @@ static const struct net_device_ops fec_netdev_ops = {
+       .ndo_set_features       = fec_set_features,
+ };
+-static const unsigned short offset_des_active_rxq[] = {
+-      FEC_R_DES_ACTIVE_0, FEC_R_DES_ACTIVE_1, FEC_R_DES_ACTIVE_2
+-};
+-
+-static const unsigned short offset_des_active_txq[] = {
+-      FEC_X_DES_ACTIVE_0, FEC_X_DES_ACTIVE_1, FEC_X_DES_ACTIVE_2
+-};
+-
+  /*
+   * XXX:  We need to clean up on failure exits here.
+   *
+@@ -3224,16 +3226,14 @@ static const unsigned short offset_des_active_txq[] = {
+ static int fec_enet_init(struct net_device *ndev)
+ {
+       struct fec_enet_private *fep = netdev_priv(ndev);
++      struct fec_enet_priv_tx_q *txq;
++      struct fec_enet_priv_rx_q *rxq;
+       struct bufdesc *cbd_base;
+       dma_addr_t bd_dma;
+       int bd_size;
+       unsigned int i;
+-      unsigned dsize = fep->bufdesc_ex ? sizeof(struct bufdesc_ex) :
+-                      sizeof(struct bufdesc);
+-      unsigned dsize_log2 = __fls(dsize);
+-      WARN_ON(dsize != (1 << dsize_log2));
+-#if defined(CONFIG_ARM) || defined(CONFIG_ARM64)
++#if defined(CONFIG_ARM)
+       fep->rx_align = 0xf;
+       fep->tx_align = 0xf;
+ #else
+@@ -3243,11 +3243,16 @@ static int fec_enet_init(struct net_device *ndev)
+       fec_enet_alloc_queue(ndev);
+-      bd_size = (fep->total_tx_ring_size + fep->total_rx_ring_size) * dsize;
++      if (fep->bufdesc_ex)
++              fep->bufdesc_size = sizeof(struct bufdesc_ex);
++      else
++              fep->bufdesc_size = sizeof(struct bufdesc);
++      bd_size = (fep->total_tx_ring_size + fep->total_rx_ring_size) *
++                      fep->bufdesc_size;
+       /* Allocate memory for buffer descriptors. */
+-      cbd_base = dmam_alloc_coherent(&fep->pdev->dev, bd_size, &bd_dma,
+-                                     GFP_KERNEL);
++      cbd_base = dma_alloc_coherent(NULL, bd_size, &bd_dma,
++                                    GFP_KERNEL);
+       if (!cbd_base) {
+               return -ENOMEM;
+       }
+@@ -3261,35 +3266,33 @@ static int fec_enet_init(struct net_device *ndev)
+       /* Set receive and transmit descriptor base. */
+       for (i = 0; i < fep->num_rx_queues; i++) {
+-              struct fec_enet_priv_rx_q *rxq = fep->rx_queue[i];
+-              unsigned size = dsize * rxq->bd.ring_size;
+-
+-              rxq->bd.qid = i;
+-              rxq->bd.base = cbd_base;
+-              rxq->bd.cur = cbd_base;
+-              rxq->bd.dma = bd_dma;
+-              rxq->bd.dsize = dsize;
+-              rxq->bd.dsize_log2 = dsize_log2;
+-              rxq->bd.reg_desc_active = fep->hwp + offset_des_active_rxq[i];
+-              bd_dma += size;
+-              cbd_base = (struct bufdesc *)(((void *)cbd_base) + size);
+-              rxq->bd.last = (struct bufdesc *)(((void *)cbd_base) - dsize);
++              rxq = fep->rx_queue[i];
++              rxq->index = i;
++              rxq->rx_bd_base = (struct bufdesc *)cbd_base;
++              rxq->bd_dma = bd_dma;
++              if (fep->bufdesc_ex) {
++                      bd_dma += sizeof(struct bufdesc_ex) * rxq->rx_ring_size;
++                      cbd_base = (struct bufdesc *)
++                              (((struct bufdesc_ex *)cbd_base) + rxq->rx_ring_size);
++              } else {
++                      bd_dma += sizeof(struct bufdesc) * rxq->rx_ring_size;
++                      cbd_base += rxq->rx_ring_size;
++              }
+       }
+       for (i = 0; i < fep->num_tx_queues; i++) {
+-              struct fec_enet_priv_tx_q *txq = fep->tx_queue[i];
+-              unsigned size = dsize * txq->bd.ring_size;
+-
+-              txq->bd.qid = i;
+-              txq->bd.base = cbd_base;
+-              txq->bd.cur = cbd_base;
+-              txq->bd.dma = bd_dma;
+-              txq->bd.dsize = dsize;
+-              txq->bd.dsize_log2 = dsize_log2;
+-              txq->bd.reg_desc_active = fep->hwp + offset_des_active_txq[i];
+-              bd_dma += size;
+-              cbd_base = (struct bufdesc *)(((void *)cbd_base) + size);
+-              txq->bd.last = (struct bufdesc *)(((void *)cbd_base) - dsize);
++              txq = fep->tx_queue[i];
++              txq->index = i;
++              txq->tx_bd_base = (struct bufdesc *)cbd_base;
++              txq->bd_dma = bd_dma;
++              if (fep->bufdesc_ex) {
++                      bd_dma += sizeof(struct bufdesc_ex) * txq->tx_ring_size;
++                      cbd_base = (struct bufdesc *)
++                       (((struct bufdesc_ex *)cbd_base) + txq->tx_ring_size);
++              } else {
++                      bd_dma += sizeof(struct bufdesc) * txq->tx_ring_size;
++                      cbd_base += txq->tx_ring_size;
++              }
+       }
+@@ -3323,60 +3326,62 @@ static int fec_enet_init(struct net_device *ndev)
+       fec_restart(ndev);
+-      fec_enet_update_ethtool_stats(ndev);
+-
+       return 0;
+ }
+ #ifdef CONFIG_OF
+-static int fec_reset_phy(struct platform_device *pdev)
++static void fec_reset_phy(struct platform_device *pdev)
++{
++      struct net_device *ndev = platform_get_drvdata(pdev);
++      struct fec_enet_private *fep = netdev_priv(ndev);
++
++      if (!gpio_is_valid(fep->phy_reset_gpio))
++              return;
++
++      gpio_set_value_cansleep(fep->phy_reset_gpio, 0);
++      msleep(fep->phy_reset_duration);
++      gpio_set_value_cansleep(fep->phy_reset_gpio, 1);
++}
++
++static int fec_get_reset_gpio(struct platform_device *pdev)
+ {
+       int err, phy_reset;
+-      bool active_high = false;
+       int msec = 1;
+       struct device_node *np = pdev->dev.of_node;
+-
+-      if (!np)
+-              return 0;
+-
+-      err = of_property_read_u32(np, "phy-reset-duration", &msec);
+-      /* A sane reset duration should not be longer than 1s */
+-      if (!err && msec > 1000)
+-              msec = 1;
++      struct net_device *ndev = platform_get_drvdata(pdev);
++      struct fec_enet_private *fep = netdev_priv(ndev);
+       phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
+-      if (phy_reset == -EPROBE_DEFER)
++      if (!gpio_is_valid(phy_reset))
+               return phy_reset;
+-      else if (!gpio_is_valid(phy_reset))
+-              return 0;
+-
+-      active_high = of_property_read_bool(np, "phy-reset-active-high");
+       err = devm_gpio_request_one(&pdev->dev, phy_reset,
+-                      active_high ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
+-                      "phy-reset");
++                                  GPIOF_OUT_INIT_LOW, "phy-reset");
+       if (err) {
+               dev_err(&pdev->dev, "failed to get phy-reset-gpios: %d\n", err);
+               return err;
+       }
+-
+-      if (msec > 20)
+-              msleep(msec);
+-      else
+-              usleep_range(msec * 1000, msec * 1000 + 1000);
+-
+-      gpio_set_value_cansleep(phy_reset, !active_high);
+-
+-      return 0;
++      
++      of_property_read_u32(np, "phy-reset-duration", &msec);
++      /* A sane reset duration should not be longer than 1s */
++      if (msec > 1000)
++              msec = 1;
++      fep->phy_reset_duration = msec;
++      
++      return phy_reset;
+ }
+ #else /* CONFIG_OF */
+-static int fec_reset_phy(struct platform_device *pdev)
++static void fec_reset_phy(struct platform_device *pdev)
+ {
+       /*
+        * In case of platform probe, the reset has been done
+        * by machine code.
+        */
+-      return 0;
++}
++
++static inline int fec_get_reset_gpio(struct platform_device *pdev)
++{
++      return -EINVAL;
+ }
+ #endif /* CONFIG_OF */
+@@ -3384,6 +3389,7 @@ static void
+ fec_enet_get_queue_num(struct platform_device *pdev, int *num_tx, int *num_rx)
+ {
+       struct device_node *np = pdev->dev.of_node;
++      int err;
+       *num_tx = *num_rx = 1;
+@@ -3391,9 +3397,13 @@ fec_enet_get_queue_num(struct platform_device *pdev, int *num_tx, int *num_rx)
+               return;
+       /* parse the num of tx and rx queues */
+-      of_property_read_u32(np, "fsl,num-tx-queues", num_tx);
++      err = of_property_read_u32(np, "fsl,num-tx-queues", num_tx);
++      if (err)
++              *num_tx = 1;
+-      of_property_read_u32(np, "fsl,num-rx-queues", num_rx);
++      err = of_property_read_u32(np, "fsl,num-rx-queues", num_rx);
++      if (err)
++              *num_rx = 1;
+       if (*num_tx < 1 || *num_tx > FEC_ENET_MAX_TX_QS) {
+               dev_warn(&pdev->dev, "Invalid num_tx(=%d), fall back to 1\n",
+@@ -3460,13 +3470,11 @@ fec_probe(struct platform_device *pdev)
+       int num_tx_qs;
+       int num_rx_qs;
+-      of_dma_configure(&pdev->dev, np);
+-
+       fec_enet_get_queue_num(pdev, &num_tx_qs, &num_rx_qs);
+       /* Init network device */
+-      ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private) +
+-                                FEC_STATS_SIZE, num_tx_qs, num_rx_qs);
++      ndev = alloc_etherdev_mqs(sizeof(struct fec_enet_private),
++                                num_tx_qs, num_rx_qs);
+       if (!ndev)
+               return -ENOMEM;
+@@ -3505,13 +3513,14 @@ fec_probe(struct platform_device *pdev)
+       platform_set_drvdata(pdev, ndev);
+-      if ((of_machine_is_compatible("fsl,imx6q") ||
+-           of_machine_is_compatible("fsl,imx6dl")) &&
+-          !of_property_read_bool(np, "fsl,err006687-workaround-present"))
+-              fep->quirks |= FEC_QUIRK_ERR006687;
+-
+       fec_enet_of_parse_stop_mode(pdev);
++      ret = fec_get_reset_gpio(pdev);
++      if (ret == -EPROBE_DEFER)
++              goto gpio_defer;
++      fep->phy_reset_gpio = ret;
++      
++
+       if (of_get_property(np, "fsl,magic-packet", NULL))
+               fep->wol_flag |= FEC_WOL_HAS_MAGIC_PACKET;
+@@ -3524,7 +3533,6 @@ fec_probe(struct platform_device *pdev)
+                       goto failed_phy;
+               }
+               phy_node = of_node_get(np);
+-              fep->fixed_link = true;
+       }
+       fep->phy_node = phy_node;
+@@ -3539,10 +3547,6 @@ fec_probe(struct platform_device *pdev)
+               fep->phy_interface = ret;
+       }
+-#if !defined(CONFIG_ARM64)
+-      request_bus_freq(BUS_FREQ_HIGH);
+-#endif
+-
+       fep->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
+       if (IS_ERR(fep->clk_ipg)) {
+               ret = PTR_ERR(fep->clk_ipg);
+@@ -3577,39 +3581,24 @@ fec_probe(struct platform_device *pdev)
+               fep->bufdesc_ex = false;
+       }
++      pm_runtime_enable(&pdev->dev);
+       ret = fec_enet_clk_enable(ndev, true);
+       if (ret)
+               goto failed_clk;
+-      ret = clk_prepare_enable(fep->clk_ipg);
+-      if (ret)
+-              goto failed_clk_ipg;
+-      ret = clk_prepare_enable(fep->clk_ahb);
+-      if (ret)
+-              goto failed_clk_ahb;
+-
+       fep->reg_phy = devm_regulator_get(&pdev->dev, "phy");
+       if (!IS_ERR(fep->reg_phy)) {
+               ret = regulator_enable(fep->reg_phy);
+               if (ret) {
+                       dev_err(&pdev->dev,
+                               "Failed to enable phy regulator: %d\n", ret);
+-                      clk_disable_unprepare(fep->clk_ipg);
+                       goto failed_regulator;
+               }
+       } else {
+               fep->reg_phy = NULL;
+       }
+-      pm_runtime_set_autosuspend_delay(&pdev->dev, FEC_MDIO_PM_TIMEOUT);
+-      pm_runtime_use_autosuspend(&pdev->dev);
+-      pm_runtime_get_noresume(&pdev->dev);
+-      pm_runtime_set_active(&pdev->dev);
+-      pm_runtime_enable(&pdev->dev);
+-
+-      ret = fec_reset_phy(pdev);
+-      if (ret)
+-              goto failed_reset;
++      fec_reset_phy(pdev);
+       if (fep->bufdesc_ex)
+               fec_ptp_init(pdev);
+@@ -3641,15 +3630,9 @@ fec_probe(struct platform_device *pdev)
+               fep->wake_irq = fep->irq[0];
+       init_completion(&fep->mdio_done);
+-
+-      /* board only enable one mii bus in default */
+-      if (!of_get_property(np, "fsl,mii-exclusive", NULL))
+-              fep->quirks |= FEC_QUIRK_SINGLE_MDIO;
+       ret = fec_enet_mii_init(pdev);
+-      if (ret) {
+-              dev_id = 0;
++      if (ret)
+               goto failed_mii_init;
+-      }
+       /* Carrier starts down, phylib will bring it up */
+       netif_carrier_off(ndev);
+@@ -3660,11 +3643,6 @@ fec_probe(struct platform_device *pdev)
+       if (ret)
+               goto failed_register;
+-      if (!fep->fixed_link) {
+-              fep->fixups = of_fec_enet_parse_fixup(np);
+-              fec_enet_register_fixup(ndev);
+-      }
+-
+       device_init_wakeup(&ndev->dev, fep->wol_flag &
+                          FEC_WOL_HAS_MAGIC_PACKET);
+@@ -3673,10 +3651,6 @@ fec_probe(struct platform_device *pdev)
+       fep->rx_copybreak = COPYBREAK_DEFAULT;
+       INIT_WORK(&fep->tx_timeout_work, fec_enet_timeout_work);
+-
+-      pm_runtime_mark_last_busy(&pdev->dev);
+-      pm_runtime_put_autosuspend(&pdev->dev);
+-
+       return 0;
+ failed_register:
+@@ -3684,22 +3658,14 @@ fec_probe(struct platform_device *pdev)
+ failed_mii_init:
+ failed_irq:
+ failed_init:
+-      fec_ptp_stop(pdev);
+       if (fep->reg_phy)
+               regulator_disable(fep->reg_phy);
+-failed_reset:
+-      pm_runtime_put(&pdev->dev);
+-      pm_runtime_disable(&pdev->dev);
+ failed_regulator:
+-failed_clk_ahb:
+-      clk_disable_unprepare(fep->clk_ipg);
+-failed_clk_ipg:
+       fec_enet_clk_enable(ndev, false);
+ failed_clk:
+-      if (of_phy_is_fixed_link(np))
+-              of_phy_deregister_fixed_link(np);
+ failed_phy:
+       of_node_put(phy_node);
++gpio_defer:
+ failed_ioremap:
+       free_netdev(ndev);
+@@ -3711,16 +3677,15 @@ fec_drv_remove(struct platform_device *pdev)
+ {
+       struct net_device *ndev = platform_get_drvdata(pdev);
+       struct fec_enet_private *fep = netdev_priv(ndev);
+-      struct device_node *np = pdev->dev.of_node;
++      cancel_delayed_work_sync(&fep->time_keep);
+       cancel_work_sync(&fep->tx_timeout_work);
+-      fec_ptp_stop(pdev);
+       unregister_netdev(ndev);
+       fec_enet_mii_remove(fep);
+       if (fep->reg_phy)
+               regulator_disable(fep->reg_phy);
+-      if (of_phy_is_fixed_link(np))
+-              of_phy_deregister_fixed_link(np);
++      if (fep->ptp_clock)
++              ptp_clock_unregister(fep->ptp_clock);
+       of_node_put(fep->phy_node);
+       free_netdev(ndev);
+@@ -3731,13 +3696,12 @@ static int __maybe_unused fec_suspend(struct device *dev)
+ {
+       struct net_device *ndev = dev_get_drvdata(dev);
+       struct fec_enet_private *fep = netdev_priv(ndev);
+-      int ret = 0;
+       rtnl_lock();
+       if (netif_running(ndev)) {
+               if (fep->wol_flag & FEC_WOL_FLAG_ENABLE)
+                       fep->wol_flag |= FEC_WOL_FLAG_SLEEP_ON;
+-              phy_stop(ndev->phydev);
++              phy_stop(fep->phy_dev);
+               napi_disable(&fep->napi);
+               netif_tx_lock_bh(ndev);
+               netif_device_detach(ndev);
+@@ -3751,12 +3715,8 @@ static int __maybe_unused fec_suspend(struct device *dev)
+                       enable_irq_wake(fep->wake_irq);
+               }
+               fec_enet_clk_enable(ndev, false);
+-              fep->active_in_suspend = !pm_runtime_status_suspended(dev);
+-              if (fep->active_in_suspend)
+-                      ret = pm_runtime_force_suspend(dev);
+-              if (ret < 0)
+-                      return ret;
+-      } else if (fep->mii_bus_share && !ndev->phydev) {
++      } else if (fep->mii_bus_share && fep->miibus_up_failed && !fep->phy_dev) {
++              fec_enet_clk_enable(ndev, false);
+               pinctrl_pm_select_sleep_state(&fep->pdev->dev);
+       }
+       rtnl_unlock();
+@@ -3777,7 +3737,7 @@ static int __maybe_unused fec_resume(struct device *dev)
+ {
+       struct net_device *ndev = dev_get_drvdata(dev);
+       struct fec_enet_private *fep = netdev_priv(ndev);
+-      int ret = 0;
++      int ret;
+       int val;
+       if (fep->reg_phy && !(fep->wol_flag & FEC_WOL_FLAG_ENABLE)) {
+@@ -3788,8 +3748,6 @@ static int __maybe_unused fec_resume(struct device *dev)
+       rtnl_lock();
+       if (netif_running(ndev)) {
+-              if (fep->active_in_suspend)
+-                      pm_runtime_force_resume(dev);
+               ret = fec_enet_clk_enable(ndev, true);
+               if (ret) {
+                       rtnl_unlock();
+@@ -3812,15 +3770,16 @@ static int __maybe_unused fec_resume(struct device *dev)
+               netif_device_attach(ndev);
+               netif_tx_unlock_bh(ndev);
+               napi_enable(&fep->napi);
+-              phy_start(ndev->phydev);
+-      } else if (fep->mii_bus_share && !ndev->phydev) {
++              phy_start(fep->phy_dev);
++      } else if (fep->mii_bus_share && !fep->phy_dev) {
+               pinctrl_pm_select_default_state(&fep->pdev->dev);
++              fep->miibus_up_failed = true;
+               /* And then recovery mii bus */
+-              ret = fec_restore_mii_bus(ndev);
++              fec_restore_mii_bus(ndev);
+       }
+       rtnl_unlock();
+-      return ret;
++      return 0;
+ failed_clk:
+       if (fep->reg_phy)
+@@ -3828,46 +3787,21 @@ static int __maybe_unused fec_resume(struct device *dev)
+       return ret;
+ }
+-static int __maybe_unused fec_runtime_suspend(struct device *dev)
++static int fec_runtime_suspend(struct device *dev)
+ {
+-      struct net_device *ndev = dev_get_drvdata(dev);
+-      struct fec_enet_private *fep = netdev_priv(ndev);
+-
+-      clk_disable_unprepare(fep->clk_ahb);
+-      clk_disable_unprepare(fep->clk_ipg);
+-#if !defined(CONFIG_ARM64)
+       release_bus_freq(BUS_FREQ_HIGH);
+-#endif
+-
+       return 0;
+ }
+-static int __maybe_unused fec_runtime_resume(struct device *dev)
++static int fec_runtime_resume(struct device *dev)
+ {
+-      struct net_device *ndev = dev_get_drvdata(dev);
+-      struct fec_enet_private *fep = netdev_priv(ndev);
+-      int ret;
+-
+-#if !defined(CONFIG_ARM64)
+       request_bus_freq(BUS_FREQ_HIGH);
+-#endif
+-      ret = clk_prepare_enable(fep->clk_ahb);
+-      if (ret)
+-              return ret;
+-      ret = clk_prepare_enable(fep->clk_ipg);
+-      if (ret)
+-              goto failed_clk_ipg;
+-
+       return 0;
+-
+-failed_clk_ipg:
+-      clk_disable_unprepare(fep->clk_ahb);
+-      return ret;
+ }
+ static const struct dev_pm_ops fec_pm_ops = {
+-      SET_SYSTEM_SLEEP_PM_OPS(fec_suspend, fec_resume)
+       SET_RUNTIME_PM_OPS(fec_runtime_suspend, fec_runtime_resume, NULL)
++      SET_SYSTEM_SLEEP_PM_OPS(fec_suspend, fec_resume)
+ };
+ static struct platform_driver fec_driver = {
+diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx.c b/drivers/net/ethernet/freescale/fec_mpc52xx.c
+index 446ae9d..afe7f39 100644
+--- a/drivers/net/ethernet/freescale/fec_mpc52xx.c
++++ b/drivers/net/ethernet/freescale/fec_mpc52xx.c
+@@ -66,6 +66,7 @@ struct mpc52xx_fec_priv {
+       /* MDIO link details */
+       unsigned int mdio_speed;
+       struct device_node *phy_node;
++      struct phy_device *phydev;
+       enum phy_state link;
+       int seven_wire_mode;
+ };
+@@ -164,7 +165,7 @@ static int mpc52xx_fec_alloc_rx_buffers(struct net_device *dev, struct bcom_task
+ static void mpc52xx_fec_adjust_link(struct net_device *dev)
+ {
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+-      struct phy_device *phydev = dev->phydev;
++      struct phy_device *phydev = priv->phydev;
+       int new_state = 0;
+       if (phydev->link != PHY_DOWN) {
+@@ -214,17 +215,16 @@ static void mpc52xx_fec_adjust_link(struct net_device *dev)
+ static int mpc52xx_fec_open(struct net_device *dev)
+ {
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+-      struct phy_device *phydev = NULL;
+       int err = -EBUSY;
+       if (priv->phy_node) {
+-              phydev = of_phy_connect(priv->ndev, priv->phy_node,
+-                                      mpc52xx_fec_adjust_link, 0, 0);
+-              if (!phydev) {
++              priv->phydev = of_phy_connect(priv->ndev, priv->phy_node,
++                                            mpc52xx_fec_adjust_link, 0, 0);
++              if (!priv->phydev) {
+                       dev_err(&dev->dev, "of_phy_connect failed\n");
+                       return -ENODEV;
+               }
+-              phy_start(phydev);
++              phy_start(priv->phydev);
+       }
+       if (request_irq(dev->irq, mpc52xx_fec_interrupt, IRQF_SHARED,
+@@ -268,9 +268,10 @@ static int mpc52xx_fec_open(struct net_device *dev)
+  free_ctrl_irq:
+       free_irq(dev->irq, dev);
+  free_phy:
+-      if (phydev) {
+-              phy_stop(phydev);
+-              phy_disconnect(phydev);
++      if (priv->phydev) {
++              phy_stop(priv->phydev);
++              phy_disconnect(priv->phydev);
++              priv->phydev = NULL;
+       }
+       return err;
+@@ -279,7 +280,6 @@ static int mpc52xx_fec_open(struct net_device *dev)
+ static int mpc52xx_fec_close(struct net_device *dev)
+ {
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+-      struct phy_device *phydev = dev->phydev;
+       netif_stop_queue(dev);
+@@ -291,10 +291,11 @@ static int mpc52xx_fec_close(struct net_device *dev)
+       free_irq(priv->r_irq, dev);
+       free_irq(priv->t_irq, dev);
+-      if (phydev) {
++      if (priv->phydev) {
+               /* power down phy */
+-              phy_stop(phydev);
+-              phy_disconnect(phydev);
++              phy_stop(priv->phydev);
++              phy_disconnect(priv->phydev);
++              priv->phydev = NULL;
+       }
+       return 0;
+@@ -762,6 +763,26 @@ static void mpc52xx_fec_reset(struct net_device *dev)
+ /* ethtool interface */
++static int mpc52xx_fec_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++      struct mpc52xx_fec_priv *priv = netdev_priv(dev);
++
++      if (!priv->phydev)
++              return -ENODEV;
++
++      return phy_ethtool_gset(priv->phydev, cmd);
++}
++
++static int mpc52xx_fec_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++      struct mpc52xx_fec_priv *priv = netdev_priv(dev);
++
++      if (!priv->phydev)
++              return -ENODEV;
++
++      return phy_ethtool_sset(priv->phydev, cmd);
++}
++
+ static u32 mpc52xx_fec_get_msglevel(struct net_device *dev)
+ {
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+@@ -775,23 +796,23 @@ static void mpc52xx_fec_set_msglevel(struct net_device *dev, u32 level)
+ }
+ static const struct ethtool_ops mpc52xx_fec_ethtool_ops = {
++      .get_settings = mpc52xx_fec_get_settings,
++      .set_settings = mpc52xx_fec_set_settings,
+       .get_link = ethtool_op_get_link,
+       .get_msglevel = mpc52xx_fec_get_msglevel,
+       .set_msglevel = mpc52xx_fec_set_msglevel,
+       .get_ts_info = ethtool_op_get_ts_info,
+-      .get_link_ksettings = phy_ethtool_get_link_ksettings,
+-      .set_link_ksettings = phy_ethtool_set_link_ksettings,
+ };
+ static int mpc52xx_fec_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ {
+-      struct phy_device *phydev = dev->phydev;
++      struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+-      if (!phydev)
++      if (!priv->phydev)
+               return -ENOTSUPP;
+-      return phy_mii_ioctl(phydev, rq, cmd);
++      return phy_mii_ioctl(priv->phydev, rq, cmd);
+ }
+ static const struct net_device_ops mpc52xx_fec_netdev_ops = {
+@@ -1063,23 +1084,27 @@ static struct platform_driver mpc52xx_fec_driver = {
+ /* Module                                                                   */
+ /* ======================================================================== */
+-static struct platform_driver * const drivers[] = {
+-#ifdef CONFIG_FEC_MPC52xx_MDIO
+-      &mpc52xx_fec_mdio_driver,
+-#endif
+-      &mpc52xx_fec_driver,
+-};
+-
+ static int __init
+ mpc52xx_fec_init(void)
+ {
+-      return platform_register_drivers(drivers, ARRAY_SIZE(drivers));
++#ifdef CONFIG_FEC_MPC52xx_MDIO
++      int ret;
++      ret = platform_driver_register(&mpc52xx_fec_mdio_driver);
++      if (ret) {
++              pr_err("failed to register mdio driver\n");
++              return ret;
++      }
++#endif
++      return platform_driver_register(&mpc52xx_fec_driver);
+ }
+ static void __exit
+ mpc52xx_fec_exit(void)
+ {
+-      platform_unregister_drivers(drivers, ARRAY_SIZE(drivers));
++      platform_driver_unregister(&mpc52xx_fec_driver);
++#ifdef CONFIG_FEC_MPC52xx_MDIO
++      platform_driver_unregister(&mpc52xx_fec_mdio_driver);
++#endif
+ }
+diff --git a/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c b/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
+index b5497e3..1e647be 100644
+--- a/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
++++ b/drivers/net/ethernet/freescale/fec_mpc52xx_phy.c
+@@ -22,6 +22,7 @@
+ struct mpc52xx_fec_mdio_priv {
+       struct mpc52xx_fec __iomem *regs;
++      int mdio_irqs[PHY_MAX_ADDR];
+ };
+ static int mpc52xx_fec_mdio_transfer(struct mii_bus *bus, int phy_id,
+@@ -82,6 +83,9 @@ static int mpc52xx_fec_mdio_probe(struct platform_device *of)
+       bus->read = mpc52xx_fec_mdio_read;
+       bus->write = mpc52xx_fec_mdio_write;
++      /* setup irqs */
++      bus->irq = priv->mdio_irqs;
++
+       /* setup registers */
+       err = of_address_to_resource(np, 0, &res);
+       if (err)
+diff --git a/drivers/net/ethernet/freescale/fec_ptp.c b/drivers/net/ethernet/freescale/fec_ptp.c
+index f9e7446..7a8386a 100644
+--- a/drivers/net/ethernet/freescale/fec_ptp.c
++++ b/drivers/net/ethernet/freescale/fec_ptp.c
+@@ -112,8 +112,9 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
+       unsigned long flags;
+       u32 val, tempval;
+       int inc;
+-      struct timespec64 ts;
++      struct timespec ts;
+       u64 ns;
++      u32 remainder;
+       val = 0;
+       if (!(fep->hwts_tx_en || fep->hwts_rx_en)) {
+@@ -162,7 +163,8 @@ static int fec_ptp_enable_pps(struct fec_enet_private *fep, uint enable)
+               tempval = readl(fep->hwp + FEC_ATIME);
+               /* Convert the ptp local counter to 1588 timestamp */
+               ns = timecounter_cyc2time(&fep->tc, tempval);
+-              ts = ns_to_timespec64(ns);
++              ts.tv_sec = div_u64_rem(ns, 1000000000ULL, &remainder);
++              ts.tv_nsec = remainder;
+               /* The tempval is  less than 3 seconds, and  so val is less than
+                * 4 seconds. No overflow for 32bit calculation.
+@@ -596,16 +598,6 @@ void fec_ptp_init(struct platform_device *pdev)
+       schedule_delayed_work(&fep->time_keep, HZ);
+ }
+-void fec_ptp_stop(struct platform_device *pdev)
+-{
+-      struct net_device *ndev = platform_get_drvdata(pdev);
+-      struct fec_enet_private *fep = netdev_priv(ndev);
+-
+-      cancel_delayed_work_sync(&fep->time_keep);
+-      if (fep->ptp_clock)
+-              ptp_clock_unregister(fep->ptp_clock);
+-}
+-
+ /**
+  * fec_ptp_check_pps_event
+  * @fep: the fec_enet_private structure handle
+diff --git a/drivers/net/ethernet/freescale/fman/Kconfig b/drivers/net/ethernet/freescale/fman/Kconfig
+deleted file mode 100644
+index 79b7c84..0000000
+--- a/drivers/net/ethernet/freescale/fman/Kconfig
++++ /dev/null
+@@ -1,9 +0,0 @@
+-config FSL_FMAN
+-      tristate "FMan support"
+-      depends on FSL_SOC || COMPILE_TEST
+-      select GENERIC_ALLOCATOR
+-      select PHYLIB
+-      default n
+-      help
+-              Freescale Data-Path Acceleration Architecture Frame Manager
+-              (FMan) support
+diff --git a/drivers/net/ethernet/freescale/fman/Makefile b/drivers/net/ethernet/freescale/fman/Makefile
+deleted file mode 100644
+index 6049177..0000000
+--- a/drivers/net/ethernet/freescale/fman/Makefile
++++ /dev/null
+@@ -1,9 +0,0 @@
+-subdir-ccflags-y +=  -I$(srctree)/drivers/net/ethernet/freescale/fman
+-
+-obj-$(CONFIG_FSL_FMAN) += fsl_fman.o
+-obj-$(CONFIG_FSL_FMAN) += fsl_fman_port.o
+-obj-$(CONFIG_FSL_FMAN) += fsl_mac.o
+-
+-fsl_fman-objs := fman_muram.o fman.o fman_sp.o
+-fsl_fman_port-objs := fman_port.o
+-fsl_mac-objs:= mac.o fman_dtsec.o fman_memac.o fman_tgec.o
+diff --git a/drivers/net/ethernet/freescale/fman/fman.c b/drivers/net/ethernet/freescale/fman/fman.c
+deleted file mode 100644
+index dafd9e1..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman.c
++++ /dev/null
+@@ -1,2967 +0,0 @@
+-/*
+- * Copyright 2008-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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+-
+-#include "fman.h"
+-#include "fman_muram.h"
+-
+-#include <linux/fsl/guts.h>
+-#include <linux/slab.h>
+-#include <linux/delay.h>
+-#include <linux/module.h>
+-#include <linux/of_platform.h>
+-#include <linux/clk.h>
+-#include <linux/of_address.h>
+-#include <linux/of_irq.h>
+-#include <linux/interrupt.h>
+-#include <linux/libfdt_env.h>
+-
+-/* General defines */
+-#define FMAN_LIODN_TBL                        64      /* size of LIODN table */
+-#define MAX_NUM_OF_MACS                       10
+-#define FM_NUM_OF_FMAN_CTRL_EVENT_REGS        4
+-#define BASE_RX_PORTID                        0x08
+-#define BASE_TX_PORTID                        0x28
+-
+-/* Modules registers offsets */
+-#define BMI_OFFSET            0x00080000
+-#define QMI_OFFSET            0x00080400
+-#define DMA_OFFSET            0x000C2000
+-#define FPM_OFFSET            0x000C3000
+-#define IMEM_OFFSET           0x000C4000
+-#define CGP_OFFSET            0x000DB000
+-
+-/* Exceptions bit map */
+-#define EX_DMA_BUS_ERROR              0x80000000
+-#define EX_DMA_READ_ECC                       0x40000000
+-#define EX_DMA_SYSTEM_WRITE_ECC       0x20000000
+-#define EX_DMA_FM_WRITE_ECC           0x10000000
+-#define EX_FPM_STALL_ON_TASKS         0x08000000
+-#define EX_FPM_SINGLE_ECC             0x04000000
+-#define EX_FPM_DOUBLE_ECC             0x02000000
+-#define EX_QMI_SINGLE_ECC             0x01000000
+-#define EX_QMI_DEQ_FROM_UNKNOWN_PORTID        0x00800000
+-#define EX_QMI_DOUBLE_ECC             0x00400000
+-#define EX_BMI_LIST_RAM_ECC           0x00200000
+-#define EX_BMI_STORAGE_PROFILE_ECC    0x00100000
+-#define EX_BMI_STATISTICS_RAM_ECC     0x00080000
+-#define EX_IRAM_ECC                   0x00040000
+-#define EX_MURAM_ECC                  0x00020000
+-#define EX_BMI_DISPATCH_RAM_ECC       0x00010000
+-#define EX_DMA_SINGLE_PORT_ECC                0x00008000
+-
+-/* DMA defines */
+-/* masks */
+-#define DMA_MODE_BER                  0x00200000
+-#define DMA_MODE_ECC                  0x00000020
+-#define DMA_MODE_SECURE_PROT          0x00000800
+-#define DMA_MODE_AXI_DBG_MASK         0x0F000000
+-
+-#define DMA_TRANSFER_PORTID_MASK      0xFF000000
+-#define DMA_TRANSFER_TNUM_MASK                0x00FF0000
+-#define DMA_TRANSFER_LIODN_MASK       0x00000FFF
+-
+-#define DMA_STATUS_BUS_ERR            0x08000000
+-#define DMA_STATUS_READ_ECC           0x04000000
+-#define DMA_STATUS_SYSTEM_WRITE_ECC   0x02000000
+-#define DMA_STATUS_FM_WRITE_ECC       0x01000000
+-#define DMA_STATUS_FM_SPDAT_ECC       0x00080000
+-
+-#define DMA_MODE_CACHE_OR_SHIFT               30
+-#define DMA_MODE_AXI_DBG_SHIFT                        24
+-#define DMA_MODE_CEN_SHIFT                    13
+-#define DMA_MODE_CEN_MASK                     0x00000007
+-#define DMA_MODE_DBG_SHIFT                    7
+-#define DMA_MODE_AID_MODE_SHIFT               4
+-
+-#define DMA_THRESH_COMMQ_SHIFT                        24
+-#define DMA_THRESH_READ_INT_BUF_SHIFT         16
+-#define DMA_THRESH_READ_INT_BUF_MASK          0x0000003f
+-#define DMA_THRESH_WRITE_INT_BUF_MASK         0x0000003f
+-
+-#define DMA_TRANSFER_PORTID_SHIFT             24
+-#define DMA_TRANSFER_TNUM_SHIFT               16
+-
+-#define DMA_CAM_SIZEOF_ENTRY                  0x40
+-#define DMA_CAM_UNITS                         8
+-
+-#define DMA_LIODN_SHIFT               16
+-#define DMA_LIODN_BASE_MASK   0x00000FFF
+-
+-/* FPM defines */
+-#define FPM_EV_MASK_DOUBLE_ECC                0x80000000
+-#define FPM_EV_MASK_STALL             0x40000000
+-#define FPM_EV_MASK_SINGLE_ECC                0x20000000
+-#define FPM_EV_MASK_RELEASE_FM                0x00010000
+-#define FPM_EV_MASK_DOUBLE_ECC_EN     0x00008000
+-#define FPM_EV_MASK_STALL_EN          0x00004000
+-#define FPM_EV_MASK_SINGLE_ECC_EN     0x00002000
+-#define FPM_EV_MASK_EXTERNAL_HALT     0x00000008
+-#define FPM_EV_MASK_ECC_ERR_HALT      0x00000004
+-
+-#define FPM_RAM_MURAM_ECC             0x00008000
+-#define FPM_RAM_IRAM_ECC              0x00004000
+-#define FPM_IRAM_ECC_ERR_EX_EN                0x00020000
+-#define FPM_MURAM_ECC_ERR_EX_EN       0x00040000
+-#define FPM_RAM_IRAM_ECC_EN           0x40000000
+-#define FPM_RAM_RAMS_ECC_EN           0x80000000
+-#define FPM_RAM_RAMS_ECC_EN_SRC_SEL   0x08000000
+-
+-#define FPM_REV1_MAJOR_MASK           0x0000FF00
+-#define FPM_REV1_MINOR_MASK           0x000000FF
+-
+-#define FPM_DISP_LIMIT_SHIFT          24
+-
+-#define FPM_PRT_FM_CTL1                       0x00000001
+-#define FPM_PRT_FM_CTL2                       0x00000002
+-#define FPM_PORT_FM_CTL_PORTID_SHIFT  24
+-#define FPM_PRC_ORA_FM_CTL_SEL_SHIFT  16
+-
+-#define FPM_THR1_PRS_SHIFT            24
+-#define FPM_THR1_KG_SHIFT             16
+-#define FPM_THR1_PLCR_SHIFT           8
+-#define FPM_THR1_BMI_SHIFT            0
+-
+-#define FPM_THR2_QMI_ENQ_SHIFT                24
+-#define FPM_THR2_QMI_DEQ_SHIFT                0
+-#define FPM_THR2_FM_CTL1_SHIFT                16
+-#define FPM_THR2_FM_CTL2_SHIFT                8
+-
+-#define FPM_EV_MASK_CAT_ERR_SHIFT     1
+-#define FPM_EV_MASK_DMA_ERR_SHIFT     0
+-
+-#define FPM_REV1_MAJOR_SHIFT          8
+-
+-#define FPM_RSTC_FM_RESET             0x80000000
+-#define FPM_RSTC_MAC0_RESET           0x40000000
+-#define FPM_RSTC_MAC1_RESET           0x20000000
+-#define FPM_RSTC_MAC2_RESET           0x10000000
+-#define FPM_RSTC_MAC3_RESET           0x08000000
+-#define FPM_RSTC_MAC8_RESET           0x04000000
+-#define FPM_RSTC_MAC4_RESET           0x02000000
+-#define FPM_RSTC_MAC5_RESET           0x01000000
+-#define FPM_RSTC_MAC6_RESET           0x00800000
+-#define FPM_RSTC_MAC7_RESET           0x00400000
+-#define FPM_RSTC_MAC9_RESET           0x00200000
+-
+-#define FPM_TS_INT_SHIFT              16
+-#define FPM_TS_CTL_EN                 0x80000000
+-
+-/* BMI defines */
+-#define BMI_INIT_START                                0x80000000
+-#define BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC   0x80000000
+-#define BMI_ERR_INTR_EN_LIST_RAM_ECC          0x40000000
+-#define BMI_ERR_INTR_EN_STATISTICS_RAM_ECC    0x20000000
+-#define BMI_ERR_INTR_EN_DISPATCH_RAM_ECC      0x10000000
+-#define BMI_NUM_OF_TASKS_MASK                 0x3F000000
+-#define BMI_NUM_OF_EXTRA_TASKS_MASK           0x000F0000
+-#define BMI_NUM_OF_DMAS_MASK                  0x00000F00
+-#define BMI_NUM_OF_EXTRA_DMAS_MASK            0x0000000F
+-#define BMI_FIFO_SIZE_MASK                    0x000003FF
+-#define BMI_EXTRA_FIFO_SIZE_MASK              0x03FF0000
+-#define BMI_CFG2_DMAS_MASK                    0x0000003F
+-#define BMI_CFG2_TASKS_MASK                   0x0000003F
+-
+-#define BMI_CFG2_TASKS_SHIFT          16
+-#define BMI_CFG2_DMAS_SHIFT           0
+-#define BMI_CFG1_FIFO_SIZE_SHIFT      16
+-#define BMI_NUM_OF_TASKS_SHIFT                24
+-#define BMI_EXTRA_NUM_OF_TASKS_SHIFT  16
+-#define BMI_NUM_OF_DMAS_SHIFT         8
+-#define BMI_EXTRA_NUM_OF_DMAS_SHIFT   0
+-
+-#define BMI_FIFO_ALIGN                        0x100
+-
+-#define BMI_EXTRA_FIFO_SIZE_SHIFT     16
+-
+-/* QMI defines */
+-#define QMI_CFG_ENQ_EN                        0x80000000
+-#define QMI_CFG_DEQ_EN                        0x40000000
+-#define QMI_CFG_EN_COUNTERS           0x10000000
+-#define QMI_CFG_DEQ_MASK              0x0000003F
+-#define QMI_CFG_ENQ_MASK              0x00003F00
+-#define QMI_CFG_ENQ_SHIFT             8
+-
+-#define QMI_ERR_INTR_EN_DOUBLE_ECC    0x80000000
+-#define QMI_ERR_INTR_EN_DEQ_FROM_DEF  0x40000000
+-#define QMI_INTR_EN_SINGLE_ECC                0x80000000
+-
+-#define QMI_GS_HALT_NOT_BUSY          0x00000002
+-
+-/* IRAM defines */
+-#define IRAM_IADD_AIE                 0x80000000
+-#define IRAM_READY                    0x80000000
+-
+-/* Default values */
+-#define DEFAULT_CATASTROPHIC_ERR              0
+-#define DEFAULT_DMA_ERR                               0
+-#define DEFAULT_AID_MODE                      FMAN_DMA_AID_OUT_TNUM
+-#define DEFAULT_DMA_COMM_Q_LOW                        0x2A
+-#define DEFAULT_DMA_COMM_Q_HIGH               0x3F
+-#define DEFAULT_CACHE_OVERRIDE                        0
+-#define DEFAULT_DMA_CAM_NUM_OF_ENTRIES                64
+-#define DEFAULT_DMA_DBG_CNT_MODE              0
+-#define DEFAULT_DMA_SOS_EMERGENCY             0
+-#define DEFAULT_DMA_WATCHDOG                  0
+-#define DEFAULT_DISP_LIMIT                    0
+-#define DEFAULT_PRS_DISP_TH                   16
+-#define DEFAULT_PLCR_DISP_TH                  16
+-#define DEFAULT_KG_DISP_TH                    16
+-#define DEFAULT_BMI_DISP_TH                   16
+-#define DEFAULT_QMI_ENQ_DISP_TH               16
+-#define DEFAULT_QMI_DEQ_DISP_TH               16
+-#define DEFAULT_FM_CTL1_DISP_TH               16
+-#define DEFAULT_FM_CTL2_DISP_TH               16
+-
+-#define DFLT_AXI_DBG_NUM_OF_BEATS             1
+-
+-#define DFLT_DMA_READ_INT_BUF_LOW(dma_thresh_max_buf) \
+-      ((dma_thresh_max_buf + 1) / 2)
+-#define DFLT_DMA_READ_INT_BUF_HIGH(dma_thresh_max_buf)        \
+-      ((dma_thresh_max_buf + 1) * 3 / 4)
+-#define DFLT_DMA_WRITE_INT_BUF_LOW(dma_thresh_max_buf)        \
+-      ((dma_thresh_max_buf + 1) / 2)
+-#define DFLT_DMA_WRITE_INT_BUF_HIGH(dma_thresh_max_buf)\
+-      ((dma_thresh_max_buf + 1) * 3 / 4)
+-
+-#define DMA_COMM_Q_LOW_FMAN_V3                0x2A
+-#define DMA_COMM_Q_LOW_FMAN_V2(dma_thresh_max_commq)          \
+-      ((dma_thresh_max_commq + 1) / 2)
+-#define DFLT_DMA_COMM_Q_LOW(major, dma_thresh_max_commq)      \
+-      ((major == 6) ? DMA_COMM_Q_LOW_FMAN_V3 :                \
+-      DMA_COMM_Q_LOW_FMAN_V2(dma_thresh_max_commq))
+-
+-#define DMA_COMM_Q_HIGH_FMAN_V3       0x3f
+-#define DMA_COMM_Q_HIGH_FMAN_V2(dma_thresh_max_commq)         \
+-      ((dma_thresh_max_commq + 1) * 3 / 4)
+-#define DFLT_DMA_COMM_Q_HIGH(major, dma_thresh_max_commq)     \
+-      ((major == 6) ? DMA_COMM_Q_HIGH_FMAN_V3 :               \
+-      DMA_COMM_Q_HIGH_FMAN_V2(dma_thresh_max_commq))
+-
+-#define TOTAL_NUM_OF_TASKS_FMAN_V3L   59
+-#define TOTAL_NUM_OF_TASKS_FMAN_V3H   124
+-#define DFLT_TOTAL_NUM_OF_TASKS(major, minor, bmi_max_num_of_tasks)   \
+-      ((major == 6) ? ((minor == 1 || minor == 4) ?                   \
+-      TOTAL_NUM_OF_TASKS_FMAN_V3L : TOTAL_NUM_OF_TASKS_FMAN_V3H) :    \
+-      bmi_max_num_of_tasks)
+-
+-#define DMA_CAM_NUM_OF_ENTRIES_FMAN_V3                64
+-#define DMA_CAM_NUM_OF_ENTRIES_FMAN_V2                32
+-#define DFLT_DMA_CAM_NUM_OF_ENTRIES(major)                    \
+-      (major == 6 ? DMA_CAM_NUM_OF_ENTRIES_FMAN_V3 :          \
+-      DMA_CAM_NUM_OF_ENTRIES_FMAN_V2)
+-
+-#define FM_TIMESTAMP_1_USEC_BIT             8
+-
+-/* Defines used for enabling/disabling FMan interrupts */
+-#define ERR_INTR_EN_DMA         0x00010000
+-#define ERR_INTR_EN_FPM         0x80000000
+-#define ERR_INTR_EN_BMI         0x00800000
+-#define ERR_INTR_EN_QMI         0x00400000
+-#define ERR_INTR_EN_MURAM       0x00040000
+-#define ERR_INTR_EN_MAC0        0x00004000
+-#define ERR_INTR_EN_MAC1        0x00002000
+-#define ERR_INTR_EN_MAC2        0x00001000
+-#define ERR_INTR_EN_MAC3        0x00000800
+-#define ERR_INTR_EN_MAC4        0x00000400
+-#define ERR_INTR_EN_MAC5        0x00000200
+-#define ERR_INTR_EN_MAC6        0x00000100
+-#define ERR_INTR_EN_MAC7        0x00000080
+-#define ERR_INTR_EN_MAC8        0x00008000
+-#define ERR_INTR_EN_MAC9        0x00000040
+-
+-#define INTR_EN_QMI             0x40000000
+-#define INTR_EN_MAC0            0x00080000
+-#define INTR_EN_MAC1            0x00040000
+-#define INTR_EN_MAC2            0x00020000
+-#define INTR_EN_MAC3            0x00010000
+-#define INTR_EN_MAC4            0x00000040
+-#define INTR_EN_MAC5            0x00000020
+-#define INTR_EN_MAC6            0x00000008
+-#define INTR_EN_MAC7            0x00000002
+-#define INTR_EN_MAC8            0x00200000
+-#define INTR_EN_MAC9            0x00100000
+-#define INTR_EN_REV0            0x00008000
+-#define INTR_EN_REV1            0x00004000
+-#define INTR_EN_REV2            0x00002000
+-#define INTR_EN_REV3            0x00001000
+-#define INTR_EN_TMR             0x01000000
+-
+-enum fman_dma_aid_mode {
+-      FMAN_DMA_AID_OUT_PORT_ID = 0,             /* 4 LSB of PORT_ID */
+-      FMAN_DMA_AID_OUT_TNUM                     /* 4 LSB of TNUM */
+-};
+-
+-struct fman_iram_regs {
+-      u32 iadd;       /* FM IRAM instruction address register */
+-      u32 idata;      /* FM IRAM instruction data register */
+-      u32 itcfg;      /* FM IRAM timing config register */
+-      u32 iready;     /* FM IRAM ready register */
+-};
+-
+-struct fman_fpm_regs {
+-      u32 fmfp_tnc;           /* FPM TNUM Control 0x00 */
+-      u32 fmfp_prc;           /* FPM Port_ID FmCtl Association 0x04 */
+-      u32 fmfp_brkc;          /* FPM Breakpoint Control 0x08 */
+-      u32 fmfp_mxd;           /* FPM Flush Control 0x0c */
+-      u32 fmfp_dist1;         /* FPM Dispatch Thresholds1 0x10 */
+-      u32 fmfp_dist2;         /* FPM Dispatch Thresholds2 0x14 */
+-      u32 fm_epi;             /* FM Error Pending Interrupts 0x18 */
+-      u32 fm_rie;             /* FM Error Interrupt Enable 0x1c */
+-      u32 fmfp_fcev[4];       /* FPM FMan-Controller Event 1-4 0x20-0x2f */
+-      u32 res0030[4];         /* res 0x30 - 0x3f */
+-      u32 fmfp_cee[4];        /* PM FMan-Controller Event 1-4 0x40-0x4f */
+-      u32 res0050[4];         /* res 0x50-0x5f */
+-      u32 fmfp_tsc1;          /* FPM TimeStamp Control1 0x60 */
+-      u32 fmfp_tsc2;          /* FPM TimeStamp Control2 0x64 */
+-      u32 fmfp_tsp;           /* FPM Time Stamp 0x68 */
+-      u32 fmfp_tsf;           /* FPM Time Stamp Fraction 0x6c */
+-      u32 fm_rcr;             /* FM Rams Control 0x70 */
+-      u32 fmfp_extc;          /* FPM External Requests Control 0x74 */
+-      u32 fmfp_ext1;          /* FPM External Requests Config1 0x78 */
+-      u32 fmfp_ext2;          /* FPM External Requests Config2 0x7c */
+-      u32 fmfp_drd[16];       /* FPM Data_Ram Data 0-15 0x80 - 0xbf */
+-      u32 fmfp_dra;           /* FPM Data Ram Access 0xc0 */
+-      u32 fm_ip_rev_1;        /* FM IP Block Revision 1 0xc4 */
+-      u32 fm_ip_rev_2;        /* FM IP Block Revision 2 0xc8 */
+-      u32 fm_rstc;            /* FM Reset Command 0xcc */
+-      u32 fm_cld;             /* FM Classifier Debug 0xd0 */
+-      u32 fm_npi;             /* FM Normal Pending Interrupts 0xd4 */
+-      u32 fmfp_exte;          /* FPM External Requests Enable 0xd8 */
+-      u32 fmfp_ee;            /* FPM Event&Mask 0xdc */
+-      u32 fmfp_cev[4];        /* FPM CPU Event 1-4 0xe0-0xef */
+-      u32 res00f0[4];         /* res 0xf0-0xff */
+-      u32 fmfp_ps[50];        /* FPM Port Status 0x100-0x1c7 */
+-      u32 res01c8[14];        /* res 0x1c8-0x1ff */
+-      u32 fmfp_clfabc;        /* FPM CLFABC 0x200 */
+-      u32 fmfp_clfcc;         /* FPM CLFCC 0x204 */
+-      u32 fmfp_clfaval;       /* FPM CLFAVAL 0x208 */
+-      u32 fmfp_clfbval;       /* FPM CLFBVAL 0x20c */
+-      u32 fmfp_clfcval;       /* FPM CLFCVAL 0x210 */
+-      u32 fmfp_clfamsk;       /* FPM CLFAMSK 0x214 */
+-      u32 fmfp_clfbmsk;       /* FPM CLFBMSK 0x218 */
+-      u32 fmfp_clfcmsk;       /* FPM CLFCMSK 0x21c */
+-      u32 fmfp_clfamc;        /* FPM CLFAMC 0x220 */
+-      u32 fmfp_clfbmc;        /* FPM CLFBMC 0x224 */
+-      u32 fmfp_clfcmc;        /* FPM CLFCMC 0x228 */
+-      u32 fmfp_decceh;        /* FPM DECCEH 0x22c */
+-      u32 res0230[116];       /* res 0x230 - 0x3ff */
+-      u32 fmfp_ts[128];       /* 0x400: FPM Task Status 0x400 - 0x5ff */
+-      u32 res0600[0x400 - 384];
+-};
+-
+-struct fman_bmi_regs {
+-      u32 fmbm_init;          /* BMI Initialization 0x00 */
+-      u32 fmbm_cfg1;          /* BMI Configuration 1 0x04 */
+-      u32 fmbm_cfg2;          /* BMI Configuration 2 0x08 */
+-      u32 res000c[5];         /* 0x0c - 0x1f */
+-      u32 fmbm_ievr;          /* Interrupt Event Register 0x20 */
+-      u32 fmbm_ier;           /* Interrupt Enable Register 0x24 */
+-      u32 fmbm_ifr;           /* Interrupt Force Register 0x28 */
+-      u32 res002c[5];         /* 0x2c - 0x3f */
+-      u32 fmbm_arb[8];        /* BMI Arbitration 0x40 - 0x5f */
+-      u32 res0060[12];        /* 0x60 - 0x8f */
+-      u32 fmbm_dtc[3];        /* Debug Trap Counter 0x90 - 0x9b */
+-      u32 res009c;            /* 0x9c */
+-      u32 fmbm_dcv[3][4];     /* Debug Compare val 0xa0-0xcf */
+-      u32 fmbm_dcm[3][4];     /* Debug Compare Mask 0xd0-0xff */
+-      u32 fmbm_gde;           /* BMI Global Debug Enable 0x100 */
+-      u32 fmbm_pp[63];        /* BMI Port Parameters 0x104 - 0x1ff */
+-      u32 res0200;            /* 0x200 */
+-      u32 fmbm_pfs[63];       /* BMI Port FIFO Size 0x204 - 0x2ff */
+-      u32 res0300;            /* 0x300 */
+-      u32 fmbm_spliodn[63];   /* Port Partition ID 0x304 - 0x3ff */
+-};
+-
+-struct fman_qmi_regs {
+-      u32 fmqm_gc;            /* General Configuration Register 0x00 */
+-      u32 res0004;            /* 0x04 */
+-      u32 fmqm_eie;           /* Error Interrupt Event Register 0x08 */
+-      u32 fmqm_eien;          /* Error Interrupt Enable Register 0x0c */
+-      u32 fmqm_eif;           /* Error Interrupt Force Register 0x10 */
+-      u32 fmqm_ie;            /* Interrupt Event Register 0x14 */
+-      u32 fmqm_ien;           /* Interrupt Enable Register 0x18 */
+-      u32 fmqm_if;            /* Interrupt Force Register 0x1c */
+-      u32 fmqm_gs;            /* Global Status Register 0x20 */
+-      u32 fmqm_ts;            /* Task Status Register 0x24 */
+-      u32 fmqm_etfc;          /* Enqueue Total Frame Counter 0x28 */
+-      u32 fmqm_dtfc;          /* Dequeue Total Frame Counter 0x2c */
+-      u32 fmqm_dc0;           /* Dequeue Counter 0 0x30 */
+-      u32 fmqm_dc1;           /* Dequeue Counter 1 0x34 */
+-      u32 fmqm_dc2;           /* Dequeue Counter 2 0x38 */
+-      u32 fmqm_dc3;           /* Dequeue Counter 3 0x3c */
+-      u32 fmqm_dfdc;          /* Dequeue FQID from Default Counter 0x40 */
+-      u32 fmqm_dfcc;          /* Dequeue FQID from Context Counter 0x44 */
+-      u32 fmqm_dffc;          /* Dequeue FQID from FD Counter 0x48 */
+-      u32 fmqm_dcc;           /* Dequeue Confirm Counter 0x4c */
+-      u32 res0050[7];         /* 0x50 - 0x6b */
+-      u32 fmqm_tapc;          /* Tnum Aging Period Control 0x6c */
+-      u32 fmqm_dmcvc;         /* Dequeue MAC Command Valid Counter 0x70 */
+-      u32 fmqm_difdcc;        /* Dequeue Invalid FD Command Counter 0x74 */
+-      u32 fmqm_da1v;          /* Dequeue A1 Valid Counter 0x78 */
+-      u32 res007c;            /* 0x7c */
+-      u32 fmqm_dtc;           /* 0x80 Debug Trap Counter 0x80 */
+-      u32 fmqm_efddd;         /* 0x84 Enqueue Frame desc Dynamic dbg 0x84 */
+-      u32 res0088[2];         /* 0x88 - 0x8f */
+-      struct {
+-              u32 fmqm_dtcfg1;        /* 0x90 dbg trap cfg 1 Register 0x00 */
+-              u32 fmqm_dtval1;        /* Debug Trap Value 1 Register 0x04 */
+-              u32 fmqm_dtm1;          /* Debug Trap Mask 1 Register 0x08 */
+-              u32 fmqm_dtc1;          /* Debug Trap Counter 1 Register 0x0c */
+-              u32 fmqm_dtcfg2;        /* dbg Trap cfg 2 Register 0x10 */
+-              u32 fmqm_dtval2;        /* Debug Trap Value 2 Register 0x14 */
+-              u32 fmqm_dtm2;          /* Debug Trap Mask 2 Register 0x18 */
+-              u32 res001c;            /* 0x1c */
+-      } dbg_traps[3];                 /* 0x90 - 0xef */
+-      u8 res00f0[0x400 - 0xf0];       /* 0xf0 - 0x3ff */
+-};
+-
+-struct fman_dma_regs {
+-      u32 fmdmsr;     /* FM DMA status register 0x00 */
+-      u32 fmdmmr;     /* FM DMA mode register 0x04 */
+-      u32 fmdmtr;     /* FM DMA bus threshold register 0x08 */
+-      u32 fmdmhy;     /* FM DMA bus hysteresis register 0x0c */
+-      u32 fmdmsetr;   /* FM DMA SOS emergency Threshold Register 0x10 */
+-      u32 fmdmtah;    /* FM DMA transfer bus address high reg 0x14 */
+-      u32 fmdmtal;    /* FM DMA transfer bus address low reg 0x18 */
+-      u32 fmdmtcid;   /* FM DMA transfer bus communication ID reg 0x1c */
+-      u32 fmdmra;     /* FM DMA bus internal ram address register 0x20 */
+-      u32 fmdmrd;     /* FM DMA bus internal ram data register 0x24 */
+-      u32 fmdmwcr;    /* FM DMA CAM watchdog counter value 0x28 */
+-      u32 fmdmebcr;   /* FM DMA CAM base in MURAM register 0x2c */
+-      u32 fmdmccqdr;  /* FM DMA CAM and CMD Queue Debug reg 0x30 */
+-      u32 fmdmccqvr1; /* FM DMA CAM and CMD Queue Value reg #1 0x34 */
+-      u32 fmdmccqvr2; /* FM DMA CAM and CMD Queue Value reg #2 0x38 */
+-      u32 fmdmcqvr3;  /* FM DMA CMD Queue Value register #3 0x3c */
+-      u32 fmdmcqvr4;  /* FM DMA CMD Queue Value register #4 0x40 */
+-      u32 fmdmcqvr5;  /* FM DMA CMD Queue Value register #5 0x44 */
+-      u32 fmdmsefrc;  /* FM DMA Semaphore Entry Full Reject Cntr 0x48 */
+-      u32 fmdmsqfrc;  /* FM DMA Semaphore Queue Full Reject Cntr 0x4c */
+-      u32 fmdmssrc;   /* FM DMA Semaphore SYNC Reject Counter 0x50 */
+-      u32 fmdmdcr;    /* FM DMA Debug Counter 0x54 */
+-      u32 fmdmemsr;   /* FM DMA Emergency Smoother Register 0x58 */
+-      u32 res005c;    /* 0x5c */
+-      u32 fmdmplr[FMAN_LIODN_TBL / 2];        /* DMA LIODN regs 0x60-0xdf */
+-      u32 res00e0[0x400 - 56];
+-};
+-
+-/* Structure that holds current FMan state.
+- * Used for saving run time information.
+- */
+-struct fman_state_struct {
+-      u8 fm_id;
+-      u16 fm_clk_freq;
+-      struct fman_rev_info rev_info;
+-      bool enabled_time_stamp;
+-      u8 count1_micro_bit;
+-      u8 total_num_of_tasks;
+-      u8 accumulated_num_of_tasks;
+-      u32 accumulated_fifo_size;
+-      u8 accumulated_num_of_open_dmas;
+-      u8 accumulated_num_of_deq_tnums;
+-      u32 exceptions;
+-      u32 extra_fifo_pool_size;
+-      u8 extra_tasks_pool_size;
+-      u8 extra_open_dmas_pool_size;
+-      u16 port_mfl[MAX_NUM_OF_MACS];
+-      u16 mac_mfl[MAX_NUM_OF_MACS];
+-
+-      /* SOC specific */
+-      u32 fm_iram_size;
+-      /* DMA */
+-      u32 dma_thresh_max_commq;
+-      u32 dma_thresh_max_buf;
+-      u32 max_num_of_open_dmas;
+-      /* QMI */
+-      u32 qmi_max_num_of_tnums;
+-      u32 qmi_def_tnums_thresh;
+-      /* BMI */
+-      u32 bmi_max_num_of_tasks;
+-      u32 bmi_max_fifo_size;
+-      /* General */
+-      u32 fm_port_num_of_cg;
+-      u32 num_of_rx_ports;
+-      u32 total_fifo_size;
+-
+-      u32 qman_channel_base;
+-      u32 num_of_qman_channels;
+-
+-      struct resource *res;
+-};
+-
+-/* Structure that holds FMan initial configuration */
+-struct fman_cfg {
+-      u8 disp_limit_tsh;
+-      u8 prs_disp_tsh;
+-      u8 plcr_disp_tsh;
+-      u8 kg_disp_tsh;
+-      u8 bmi_disp_tsh;
+-      u8 qmi_enq_disp_tsh;
+-      u8 qmi_deq_disp_tsh;
+-      u8 fm_ctl1_disp_tsh;
+-      u8 fm_ctl2_disp_tsh;
+-      int dma_cache_override;
+-      enum fman_dma_aid_mode dma_aid_mode;
+-      u32 dma_axi_dbg_num_of_beats;
+-      u32 dma_cam_num_of_entries;
+-      u32 dma_watchdog;
+-      u8 dma_comm_qtsh_asrt_emer;
+-      u32 dma_write_buf_tsh_asrt_emer;
+-      u32 dma_read_buf_tsh_asrt_emer;
+-      u8 dma_comm_qtsh_clr_emer;
+-      u32 dma_write_buf_tsh_clr_emer;
+-      u32 dma_read_buf_tsh_clr_emer;
+-      u32 dma_sos_emergency;
+-      int dma_dbg_cnt_mode;
+-      int catastrophic_err;
+-      int dma_err;
+-      u32 exceptions;
+-      u16 clk_freq;
+-      u32 cam_base_addr;
+-      u32 fifo_base_addr;
+-      u32 total_fifo_size;
+-      u32 total_num_of_tasks;
+-      u32 qmi_def_tnums_thresh;
+-};
+-
+-/* Structure that holds information received from device tree */
+-struct fman_dts_params {
+-      void __iomem *base_addr;                /* FMan virtual address */
+-      struct resource *res;                   /* FMan memory resource */
+-      u8 id;                                  /* FMan ID */
+-
+-      int err_irq;                            /* FMan Error IRQ */
+-
+-      u16 clk_freq;                           /* FMan clock freq (In Mhz) */
+-
+-      u32 qman_channel_base;                  /* QMan channels base */
+-      u32 num_of_qman_channels;               /* Number of QMan channels */
+-
+-      struct resource muram_res;              /* MURAM resource */
+-};
+-
+-/** fman_exceptions_cb
+- * fman               - Pointer to FMan
+- * exception  - The exception.
+- *
+- * Exceptions user callback routine, will be called upon an exception
+- * passing the exception identification.
+- *
+- * Return: irq status
+- */
+-typedef irqreturn_t (fman_exceptions_cb)(struct fman *fman,
+-                                       enum fman_exceptions exception);
+-
+-/** fman_bus_error_cb
+- * fman               - Pointer to FMan
+- * port_id    - Port id
+- * addr               - Address that caused the error
+- * tnum               - Owner of error
+- * liodn      - Logical IO device number
+- *
+- * Bus error user callback routine, will be called upon bus error,
+- * passing parameters describing the errors and the owner.
+- *
+- * Return: IRQ status
+- */
+-typedef irqreturn_t (fman_bus_error_cb)(struct fman *fman, u8 port_id,
+-                                      u64 addr, u8 tnum, u16 liodn);
+-
+-struct fman {
+-      struct device *dev;
+-      void __iomem *base_addr;
+-      struct fman_intr_src intr_mng[FMAN_EV_CNT];
+-
+-      struct fman_fpm_regs __iomem *fpm_regs;
+-      struct fman_bmi_regs __iomem *bmi_regs;
+-      struct fman_qmi_regs __iomem *qmi_regs;
+-      struct fman_dma_regs __iomem *dma_regs;
+-      fman_exceptions_cb *exception_cb;
+-      fman_bus_error_cb *bus_error_cb;
+-      /* Spinlock for FMan use */
+-      spinlock_t spinlock;
+-      struct fman_state_struct *state;
+-
+-      struct fman_cfg *cfg;
+-      struct muram_info *muram;
+-      /* cam section in muram */
+-      unsigned long cam_offset;
+-      size_t cam_size;
+-      /* Fifo in MURAM */
+-      unsigned long fifo_offset;
+-      size_t fifo_size;
+-
+-      u32 liodn_base[64];
+-      u32 liodn_offset[64];
+-
+-      struct fman_dts_params dts_params;
+-};
+-
+-static irqreturn_t fman_exceptions(struct fman *fman,
+-                                 enum fman_exceptions exception)
+-{
+-      dev_dbg(fman->dev, "%s: FMan[%d] exception %d\n",
+-              __func__, fman->state->fm_id, exception);
+-
+-      return IRQ_HANDLED;
+-}
+-
+-static irqreturn_t fman_bus_error(struct fman *fman, u8 __maybe_unused port_id,
+-                                u64 __maybe_unused addr,
+-                                u8 __maybe_unused tnum,
+-                                u16 __maybe_unused liodn)
+-{
+-      dev_dbg(fman->dev, "%s: FMan[%d] bus error: port_id[%d]\n",
+-              __func__, fman->state->fm_id, port_id);
+-
+-      return IRQ_HANDLED;
+-}
+-
+-static inline irqreturn_t call_mac_isr(struct fman *fman, u8 id)
+-{
+-      if (fman->intr_mng[id].isr_cb) {
+-              fman->intr_mng[id].isr_cb(fman->intr_mng[id].src_handle);
+-
+-              return IRQ_HANDLED;
+-      }
+-
+-      return IRQ_NONE;
+-}
+-
+-static inline u8 hw_port_id_to_sw_port_id(u8 major, u8 hw_port_id)
+-{
+-      u8 sw_port_id = 0;
+-
+-      if (hw_port_id >= BASE_TX_PORTID)
+-              sw_port_id = hw_port_id - BASE_TX_PORTID;
+-      else if (hw_port_id >= BASE_RX_PORTID)
+-              sw_port_id = hw_port_id - BASE_RX_PORTID;
+-      else
+-              sw_port_id = 0;
+-
+-      return sw_port_id;
+-}
+-
+-static void set_port_order_restoration(struct fman_fpm_regs __iomem *fpm_rg,
+-                                     u8 port_id)
+-{
+-      u32 tmp = 0;
+-
+-      tmp = port_id << FPM_PORT_FM_CTL_PORTID_SHIFT;
+-
+-      tmp |= FPM_PRT_FM_CTL2 | FPM_PRT_FM_CTL1;
+-
+-      /* order restoration */
+-      if (port_id % 2)
+-              tmp |= FPM_PRT_FM_CTL1 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT;
+-      else
+-              tmp |= FPM_PRT_FM_CTL2 << FPM_PRC_ORA_FM_CTL_SEL_SHIFT;
+-
+-      iowrite32be(tmp, &fpm_rg->fmfp_prc);
+-}
+-
+-static void set_port_liodn(struct fman *fman, u8 port_id,
+-                         u32 liodn_base, u32 liodn_ofst)
+-{
+-      u32 tmp;
+-
+-      /* set LIODN base for this port */
+-      tmp = ioread32be(&fman->dma_regs->fmdmplr[port_id / 2]);
+-      if (port_id % 2) {
+-              tmp &= ~DMA_LIODN_BASE_MASK;
+-              tmp |= liodn_base;
+-      } else {
+-              tmp &= ~(DMA_LIODN_BASE_MASK << DMA_LIODN_SHIFT);
+-              tmp |= liodn_base << DMA_LIODN_SHIFT;
+-      }
+-      iowrite32be(tmp, &fman->dma_regs->fmdmplr[port_id / 2]);
+-      iowrite32be(liodn_ofst, &fman->bmi_regs->fmbm_spliodn[port_id - 1]);
+-}
+-
+-static void enable_rams_ecc(struct fman_fpm_regs __iomem *fpm_rg)
+-{
+-      u32 tmp;
+-
+-      tmp = ioread32be(&fpm_rg->fm_rcr);
+-      if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
+-              iowrite32be(tmp | FPM_RAM_IRAM_ECC_EN, &fpm_rg->fm_rcr);
+-      else
+-              iowrite32be(tmp | FPM_RAM_RAMS_ECC_EN |
+-                          FPM_RAM_IRAM_ECC_EN, &fpm_rg->fm_rcr);
+-}
+-
+-static void disable_rams_ecc(struct fman_fpm_regs __iomem *fpm_rg)
+-{
+-      u32 tmp;
+-
+-      tmp = ioread32be(&fpm_rg->fm_rcr);
+-      if (tmp & FPM_RAM_RAMS_ECC_EN_SRC_SEL)
+-              iowrite32be(tmp & ~FPM_RAM_IRAM_ECC_EN, &fpm_rg->fm_rcr);
+-      else
+-              iowrite32be(tmp & ~(FPM_RAM_RAMS_ECC_EN | FPM_RAM_IRAM_ECC_EN),
+-                          &fpm_rg->fm_rcr);
+-}
+-
+-static void fman_defconfig(struct fman_cfg *cfg)
+-{
+-      memset(cfg, 0, sizeof(struct fman_cfg));
+-
+-      cfg->catastrophic_err = DEFAULT_CATASTROPHIC_ERR;
+-      cfg->dma_err = DEFAULT_DMA_ERR;
+-      cfg->dma_aid_mode = DEFAULT_AID_MODE;
+-      cfg->dma_comm_qtsh_clr_emer = DEFAULT_DMA_COMM_Q_LOW;
+-      cfg->dma_comm_qtsh_asrt_emer = DEFAULT_DMA_COMM_Q_HIGH;
+-      cfg->dma_cache_override = DEFAULT_CACHE_OVERRIDE;
+-      cfg->dma_cam_num_of_entries = DEFAULT_DMA_CAM_NUM_OF_ENTRIES;
+-      cfg->dma_dbg_cnt_mode = DEFAULT_DMA_DBG_CNT_MODE;
+-      cfg->dma_sos_emergency = DEFAULT_DMA_SOS_EMERGENCY;
+-      cfg->dma_watchdog = DEFAULT_DMA_WATCHDOG;
+-      cfg->disp_limit_tsh = DEFAULT_DISP_LIMIT;
+-      cfg->prs_disp_tsh = DEFAULT_PRS_DISP_TH;
+-      cfg->plcr_disp_tsh = DEFAULT_PLCR_DISP_TH;
+-      cfg->kg_disp_tsh = DEFAULT_KG_DISP_TH;
+-      cfg->bmi_disp_tsh = DEFAULT_BMI_DISP_TH;
+-      cfg->qmi_enq_disp_tsh = DEFAULT_QMI_ENQ_DISP_TH;
+-      cfg->qmi_deq_disp_tsh = DEFAULT_QMI_DEQ_DISP_TH;
+-      cfg->fm_ctl1_disp_tsh = DEFAULT_FM_CTL1_DISP_TH;
+-      cfg->fm_ctl2_disp_tsh = DEFAULT_FM_CTL2_DISP_TH;
+-}
+-
+-static int dma_init(struct fman *fman)
+-{
+-      struct fman_dma_regs __iomem *dma_rg = fman->dma_regs;
+-      struct fman_cfg *cfg = fman->cfg;
+-      u32 tmp_reg;
+-
+-      /* Init DMA Registers */
+-
+-      /* clear status reg events */
+-      tmp_reg = (DMA_STATUS_BUS_ERR | DMA_STATUS_READ_ECC |
+-                 DMA_STATUS_SYSTEM_WRITE_ECC | DMA_STATUS_FM_WRITE_ECC);
+-      iowrite32be(ioread32be(&dma_rg->fmdmsr) | tmp_reg, &dma_rg->fmdmsr);
+-
+-      /* configure mode register */
+-      tmp_reg = 0;
+-      tmp_reg |= cfg->dma_cache_override << DMA_MODE_CACHE_OR_SHIFT;
+-      if (cfg->exceptions & EX_DMA_BUS_ERROR)
+-              tmp_reg |= DMA_MODE_BER;
+-      if ((cfg->exceptions & EX_DMA_SYSTEM_WRITE_ECC) |
+-          (cfg->exceptions & EX_DMA_READ_ECC) |
+-          (cfg->exceptions & EX_DMA_FM_WRITE_ECC))
+-              tmp_reg |= DMA_MODE_ECC;
+-      if (cfg->dma_axi_dbg_num_of_beats)
+-              tmp_reg |= (DMA_MODE_AXI_DBG_MASK &
+-                      ((cfg->dma_axi_dbg_num_of_beats - 1)
+-                      << DMA_MODE_AXI_DBG_SHIFT));
+-
+-      tmp_reg |= (((cfg->dma_cam_num_of_entries / DMA_CAM_UNITS) - 1) &
+-              DMA_MODE_CEN_MASK) << DMA_MODE_CEN_SHIFT;
+-      tmp_reg |= DMA_MODE_SECURE_PROT;
+-      tmp_reg |= cfg->dma_dbg_cnt_mode << DMA_MODE_DBG_SHIFT;
+-      tmp_reg |= cfg->dma_aid_mode << DMA_MODE_AID_MODE_SHIFT;
+-
+-      iowrite32be(tmp_reg, &dma_rg->fmdmmr);
+-
+-      /* configure thresholds register */
+-      tmp_reg = ((u32)cfg->dma_comm_qtsh_asrt_emer <<
+-              DMA_THRESH_COMMQ_SHIFT);
+-      tmp_reg |= (cfg->dma_read_buf_tsh_asrt_emer &
+-              DMA_THRESH_READ_INT_BUF_MASK) << DMA_THRESH_READ_INT_BUF_SHIFT;
+-      tmp_reg |= cfg->dma_write_buf_tsh_asrt_emer &
+-              DMA_THRESH_WRITE_INT_BUF_MASK;
+-
+-      iowrite32be(tmp_reg, &dma_rg->fmdmtr);
+-
+-      /* configure hysteresis register */
+-      tmp_reg = ((u32)cfg->dma_comm_qtsh_clr_emer <<
+-              DMA_THRESH_COMMQ_SHIFT);
+-      tmp_reg |= (cfg->dma_read_buf_tsh_clr_emer &
+-              DMA_THRESH_READ_INT_BUF_MASK) << DMA_THRESH_READ_INT_BUF_SHIFT;
+-      tmp_reg |= cfg->dma_write_buf_tsh_clr_emer &
+-              DMA_THRESH_WRITE_INT_BUF_MASK;
+-
+-      iowrite32be(tmp_reg, &dma_rg->fmdmhy);
+-
+-      /* configure emergency threshold */
+-      iowrite32be(cfg->dma_sos_emergency, &dma_rg->fmdmsetr);
+-
+-      /* configure Watchdog */
+-      iowrite32be((cfg->dma_watchdog * cfg->clk_freq), &dma_rg->fmdmwcr);
+-
+-      iowrite32be(cfg->cam_base_addr, &dma_rg->fmdmebcr);
+-
+-      /* Allocate MURAM for CAM */
+-      fman->cam_size =
+-              (u32)(fman->cfg->dma_cam_num_of_entries * DMA_CAM_SIZEOF_ENTRY);
+-      fman->cam_offset = fman_muram_alloc(fman->muram, fman->cam_size);
+-      if (IS_ERR_VALUE(fman->cam_offset)) {
+-              dev_err(fman->dev, "%s: MURAM alloc for DMA CAM failed\n",
+-                      __func__);
+-              return -ENOMEM;
+-      }
+-
+-      if (fman->state->rev_info.major == 2) {
+-              u32 __iomem *cam_base_addr;
+-
+-              fman_muram_free_mem(fman->muram, fman->cam_offset,
+-                                  fman->cam_size);
+-
+-              fman->cam_size = fman->cfg->dma_cam_num_of_entries * 72 + 128;
+-              fman->cam_offset = fman_muram_alloc(fman->muram,
+-                                                  fman->cam_size);
+-              if (IS_ERR_VALUE(fman->cam_offset)) {
+-                      dev_err(fman->dev, "%s: MURAM alloc for DMA CAM failed\n",
+-                              __func__);
+-                      return -ENOMEM;
+-              }
+-
+-              if (fman->cfg->dma_cam_num_of_entries % 8 ||
+-                  fman->cfg->dma_cam_num_of_entries > 32) {
+-                      dev_err(fman->dev, "%s: wrong dma_cam_num_of_entries\n",
+-                              __func__);
+-                      return -EINVAL;
+-              }
+-
+-              cam_base_addr = (u32 __iomem *)
+-                      fman_muram_offset_to_vbase(fman->muram,
+-                                                 fman->cam_offset);
+-              iowrite32be(~((1 <<
+-                          (32 - fman->cfg->dma_cam_num_of_entries)) - 1),
+-                          cam_base_addr);
+-      }
+-
+-      fman->cfg->cam_base_addr = fman->cam_offset;
+-
+-      return 0;
+-}
+-
+-static void fpm_init(struct fman_fpm_regs __iomem *fpm_rg, struct fman_cfg *cfg)
+-{
+-      u32 tmp_reg;
+-      int i;
+-
+-      /* Init FPM Registers */
+-
+-      tmp_reg = (u32)(cfg->disp_limit_tsh << FPM_DISP_LIMIT_SHIFT);
+-      iowrite32be(tmp_reg, &fpm_rg->fmfp_mxd);
+-
+-      tmp_reg = (((u32)cfg->prs_disp_tsh << FPM_THR1_PRS_SHIFT) |
+-                 ((u32)cfg->kg_disp_tsh << FPM_THR1_KG_SHIFT) |
+-                 ((u32)cfg->plcr_disp_tsh << FPM_THR1_PLCR_SHIFT) |
+-                 ((u32)cfg->bmi_disp_tsh << FPM_THR1_BMI_SHIFT));
+-      iowrite32be(tmp_reg, &fpm_rg->fmfp_dist1);
+-
+-      tmp_reg =
+-              (((u32)cfg->qmi_enq_disp_tsh << FPM_THR2_QMI_ENQ_SHIFT) |
+-               ((u32)cfg->qmi_deq_disp_tsh << FPM_THR2_QMI_DEQ_SHIFT) |
+-               ((u32)cfg->fm_ctl1_disp_tsh << FPM_THR2_FM_CTL1_SHIFT) |
+-               ((u32)cfg->fm_ctl2_disp_tsh << FPM_THR2_FM_CTL2_SHIFT));
+-      iowrite32be(tmp_reg, &fpm_rg->fmfp_dist2);
+-
+-      /* define exceptions and error behavior */
+-      tmp_reg = 0;
+-      /* Clear events */
+-      tmp_reg |= (FPM_EV_MASK_STALL | FPM_EV_MASK_DOUBLE_ECC |
+-                  FPM_EV_MASK_SINGLE_ECC);
+-      /* enable interrupts */
+-      if (cfg->exceptions & EX_FPM_STALL_ON_TASKS)
+-              tmp_reg |= FPM_EV_MASK_STALL_EN;
+-      if (cfg->exceptions & EX_FPM_SINGLE_ECC)
+-              tmp_reg |= FPM_EV_MASK_SINGLE_ECC_EN;
+-      if (cfg->exceptions & EX_FPM_DOUBLE_ECC)
+-              tmp_reg |= FPM_EV_MASK_DOUBLE_ECC_EN;
+-      tmp_reg |= (cfg->catastrophic_err << FPM_EV_MASK_CAT_ERR_SHIFT);
+-      tmp_reg |= (cfg->dma_err << FPM_EV_MASK_DMA_ERR_SHIFT);
+-      /* FMan is not halted upon external halt activation */
+-      tmp_reg |= FPM_EV_MASK_EXTERNAL_HALT;
+-      /* Man is not halted upon  Unrecoverable ECC error behavior */
+-      tmp_reg |= FPM_EV_MASK_ECC_ERR_HALT;
+-      iowrite32be(tmp_reg, &fpm_rg->fmfp_ee);
+-
+-      /* clear all fmCtls event registers */
+-      for (i = 0; i < FM_NUM_OF_FMAN_CTRL_EVENT_REGS; i++)
+-              iowrite32be(0xFFFFFFFF, &fpm_rg->fmfp_cev[i]);
+-
+-      /* RAM ECC -  enable and clear events */
+-      /* first we need to clear all parser memory,
+-       * as it is uninitialized and may cause ECC errors
+-       */
+-      /* event bits */
+-      tmp_reg = (FPM_RAM_MURAM_ECC | FPM_RAM_IRAM_ECC);
+-
+-      iowrite32be(tmp_reg, &fpm_rg->fm_rcr);
+-
+-      tmp_reg = 0;
+-      if (cfg->exceptions & EX_IRAM_ECC) {
+-              tmp_reg |= FPM_IRAM_ECC_ERR_EX_EN;
+-              enable_rams_ecc(fpm_rg);
+-      }
+-      if (cfg->exceptions & EX_MURAM_ECC) {
+-              tmp_reg |= FPM_MURAM_ECC_ERR_EX_EN;
+-              enable_rams_ecc(fpm_rg);
+-      }
+-      iowrite32be(tmp_reg, &fpm_rg->fm_rie);
+-}
+-
+-static void bmi_init(struct fman_bmi_regs __iomem *bmi_rg,
+-                   struct fman_cfg *cfg)
+-{
+-      u32 tmp_reg;
+-
+-      /* Init BMI Registers */
+-
+-      /* define common resources */
+-      tmp_reg = cfg->fifo_base_addr;
+-      tmp_reg = tmp_reg / BMI_FIFO_ALIGN;
+-
+-      tmp_reg |= ((cfg->total_fifo_size / FMAN_BMI_FIFO_UNITS - 1) <<
+-                  BMI_CFG1_FIFO_SIZE_SHIFT);
+-      iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg1);
+-
+-      tmp_reg = ((cfg->total_num_of_tasks - 1) & BMI_CFG2_TASKS_MASK) <<
+-                 BMI_CFG2_TASKS_SHIFT;
+-      /* num of DMA's will be dynamically updated when each port is set */
+-      iowrite32be(tmp_reg, &bmi_rg->fmbm_cfg2);
+-
+-      /* define unmaskable exceptions, enable and clear events */
+-      tmp_reg = 0;
+-      iowrite32be(BMI_ERR_INTR_EN_LIST_RAM_ECC |
+-                  BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC |
+-                  BMI_ERR_INTR_EN_STATISTICS_RAM_ECC |
+-                  BMI_ERR_INTR_EN_DISPATCH_RAM_ECC, &bmi_rg->fmbm_ievr);
+-
+-      if (cfg->exceptions & EX_BMI_LIST_RAM_ECC)
+-              tmp_reg |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
+-      if (cfg->exceptions & EX_BMI_STORAGE_PROFILE_ECC)
+-              tmp_reg |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
+-      if (cfg->exceptions & EX_BMI_STATISTICS_RAM_ECC)
+-              tmp_reg |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
+-      if (cfg->exceptions & EX_BMI_DISPATCH_RAM_ECC)
+-              tmp_reg |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
+-      iowrite32be(tmp_reg, &bmi_rg->fmbm_ier);
+-}
+-
+-static void qmi_init(struct fman_qmi_regs __iomem *qmi_rg,
+-                   struct fman_cfg *cfg)
+-{
+-      u32 tmp_reg;
+-
+-      /* Init QMI Registers */
+-
+-      /* Clear error interrupt events */
+-
+-      iowrite32be(QMI_ERR_INTR_EN_DOUBLE_ECC | QMI_ERR_INTR_EN_DEQ_FROM_DEF,
+-                  &qmi_rg->fmqm_eie);
+-      tmp_reg = 0;
+-      if (cfg->exceptions & EX_QMI_DEQ_FROM_UNKNOWN_PORTID)
+-              tmp_reg |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
+-      if (cfg->exceptions & EX_QMI_DOUBLE_ECC)
+-              tmp_reg |= QMI_ERR_INTR_EN_DOUBLE_ECC;
+-      /* enable events */
+-      iowrite32be(tmp_reg, &qmi_rg->fmqm_eien);
+-
+-      tmp_reg = 0;
+-      /* Clear interrupt events */
+-      iowrite32be(QMI_INTR_EN_SINGLE_ECC, &qmi_rg->fmqm_ie);
+-      if (cfg->exceptions & EX_QMI_SINGLE_ECC)
+-              tmp_reg |= QMI_INTR_EN_SINGLE_ECC;
+-      /* enable events */
+-      iowrite32be(tmp_reg, &qmi_rg->fmqm_ien);
+-}
+-
+-static int enable(struct fman *fman, struct fman_cfg *cfg)
+-{
+-      u32 cfg_reg = 0;
+-
+-      /* Enable all modules */
+-
+-      /* clear&enable global counters - calculate reg and save for later,
+-       * because it's the same reg for QMI enable
+-       */
+-      cfg_reg = QMI_CFG_EN_COUNTERS;
+-
+-      /* Set enqueue and dequeue thresholds */
+-      cfg_reg |= (cfg->qmi_def_tnums_thresh << 8) | cfg->qmi_def_tnums_thresh;
+-
+-      iowrite32be(BMI_INIT_START, &fman->bmi_regs->fmbm_init);
+-      iowrite32be(cfg_reg | QMI_CFG_ENQ_EN | QMI_CFG_DEQ_EN,
+-                  &fman->qmi_regs->fmqm_gc);
+-
+-      return 0;
+-}
+-
+-static int set_exception(struct fman *fman,
+-                       enum fman_exceptions exception, bool enable)
+-{
+-      u32 tmp;
+-
+-      switch (exception) {
+-      case FMAN_EX_DMA_BUS_ERROR:
+-              tmp = ioread32be(&fman->dma_regs->fmdmmr);
+-              if (enable)
+-                      tmp |= DMA_MODE_BER;
+-              else
+-                      tmp &= ~DMA_MODE_BER;
+-              /* disable bus error */
+-              iowrite32be(tmp, &fman->dma_regs->fmdmmr);
+-              break;
+-      case FMAN_EX_DMA_READ_ECC:
+-      case FMAN_EX_DMA_SYSTEM_WRITE_ECC:
+-      case FMAN_EX_DMA_FM_WRITE_ECC:
+-              tmp = ioread32be(&fman->dma_regs->fmdmmr);
+-              if (enable)
+-                      tmp |= DMA_MODE_ECC;
+-              else
+-                      tmp &= ~DMA_MODE_ECC;
+-              iowrite32be(tmp, &fman->dma_regs->fmdmmr);
+-              break;
+-      case FMAN_EX_FPM_STALL_ON_TASKS:
+-              tmp = ioread32be(&fman->fpm_regs->fmfp_ee);
+-              if (enable)
+-                      tmp |= FPM_EV_MASK_STALL_EN;
+-              else
+-                      tmp &= ~FPM_EV_MASK_STALL_EN;
+-              iowrite32be(tmp, &fman->fpm_regs->fmfp_ee);
+-              break;
+-      case FMAN_EX_FPM_SINGLE_ECC:
+-              tmp = ioread32be(&fman->fpm_regs->fmfp_ee);
+-              if (enable)
+-                      tmp |= FPM_EV_MASK_SINGLE_ECC_EN;
+-              else
+-                      tmp &= ~FPM_EV_MASK_SINGLE_ECC_EN;
+-              iowrite32be(tmp, &fman->fpm_regs->fmfp_ee);
+-              break;
+-      case FMAN_EX_FPM_DOUBLE_ECC:
+-              tmp = ioread32be(&fman->fpm_regs->fmfp_ee);
+-              if (enable)
+-                      tmp |= FPM_EV_MASK_DOUBLE_ECC_EN;
+-              else
+-                      tmp &= ~FPM_EV_MASK_DOUBLE_ECC_EN;
+-              iowrite32be(tmp, &fman->fpm_regs->fmfp_ee);
+-              break;
+-      case FMAN_EX_QMI_SINGLE_ECC:
+-              tmp = ioread32be(&fman->qmi_regs->fmqm_ien);
+-              if (enable)
+-                      tmp |= QMI_INTR_EN_SINGLE_ECC;
+-              else
+-                      tmp &= ~QMI_INTR_EN_SINGLE_ECC;
+-              iowrite32be(tmp, &fman->qmi_regs->fmqm_ien);
+-              break;
+-      case FMAN_EX_QMI_DOUBLE_ECC:
+-              tmp = ioread32be(&fman->qmi_regs->fmqm_eien);
+-              if (enable)
+-                      tmp |= QMI_ERR_INTR_EN_DOUBLE_ECC;
+-              else
+-                      tmp &= ~QMI_ERR_INTR_EN_DOUBLE_ECC;
+-              iowrite32be(tmp, &fman->qmi_regs->fmqm_eien);
+-              break;
+-      case FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
+-              tmp = ioread32be(&fman->qmi_regs->fmqm_eien);
+-              if (enable)
+-                      tmp |= QMI_ERR_INTR_EN_DEQ_FROM_DEF;
+-              else
+-                      tmp &= ~QMI_ERR_INTR_EN_DEQ_FROM_DEF;
+-              iowrite32be(tmp, &fman->qmi_regs->fmqm_eien);
+-              break;
+-      case FMAN_EX_BMI_LIST_RAM_ECC:
+-              tmp = ioread32be(&fman->bmi_regs->fmbm_ier);
+-              if (enable)
+-                      tmp |= BMI_ERR_INTR_EN_LIST_RAM_ECC;
+-              else
+-                      tmp &= ~BMI_ERR_INTR_EN_LIST_RAM_ECC;
+-              iowrite32be(tmp, &fman->bmi_regs->fmbm_ier);
+-              break;
+-      case FMAN_EX_BMI_STORAGE_PROFILE_ECC:
+-              tmp = ioread32be(&fman->bmi_regs->fmbm_ier);
+-              if (enable)
+-                      tmp |= BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
+-              else
+-                      tmp &= ~BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC;
+-              iowrite32be(tmp, &fman->bmi_regs->fmbm_ier);
+-              break;
+-      case FMAN_EX_BMI_STATISTICS_RAM_ECC:
+-              tmp = ioread32be(&fman->bmi_regs->fmbm_ier);
+-              if (enable)
+-                      tmp |= BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
+-              else
+-                      tmp &= ~BMI_ERR_INTR_EN_STATISTICS_RAM_ECC;
+-              iowrite32be(tmp, &fman->bmi_regs->fmbm_ier);
+-              break;
+-      case FMAN_EX_BMI_DISPATCH_RAM_ECC:
+-              tmp = ioread32be(&fman->bmi_regs->fmbm_ier);
+-              if (enable)
+-                      tmp |= BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
+-              else
+-                      tmp &= ~BMI_ERR_INTR_EN_DISPATCH_RAM_ECC;
+-              iowrite32be(tmp, &fman->bmi_regs->fmbm_ier);
+-              break;
+-      case FMAN_EX_IRAM_ECC:
+-              tmp = ioread32be(&fman->fpm_regs->fm_rie);
+-              if (enable) {
+-                      /* enable ECC if not enabled */
+-                      enable_rams_ecc(fman->fpm_regs);
+-                      /* enable ECC interrupts */
+-                      tmp |= FPM_IRAM_ECC_ERR_EX_EN;
+-              } else {
+-                      /* ECC mechanism may be disabled,
+-                       * depending on driver status
+-                       */
+-                      disable_rams_ecc(fman->fpm_regs);
+-                      tmp &= ~FPM_IRAM_ECC_ERR_EX_EN;
+-              }
+-              iowrite32be(tmp, &fman->fpm_regs->fm_rie);
+-              break;
+-      case FMAN_EX_MURAM_ECC:
+-              tmp = ioread32be(&fman->fpm_regs->fm_rie);
+-              if (enable) {
+-                      /* enable ECC if not enabled */
+-                      enable_rams_ecc(fman->fpm_regs);
+-                      /* enable ECC interrupts */
+-                      tmp |= FPM_MURAM_ECC_ERR_EX_EN;
+-              } else {
+-                      /* ECC mechanism may be disabled,
+-                       * depending on driver status
+-                       */
+-                      disable_rams_ecc(fman->fpm_regs);
+-                      tmp &= ~FPM_MURAM_ECC_ERR_EX_EN;
+-              }
+-              iowrite32be(tmp, &fman->fpm_regs->fm_rie);
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-      return 0;
+-}
+-
+-static void resume(struct fman_fpm_regs __iomem *fpm_rg)
+-{
+-      u32 tmp;
+-
+-      tmp = ioread32be(&fpm_rg->fmfp_ee);
+-      /* clear tmp_reg event bits in order not to clear standing events */
+-      tmp &= ~(FPM_EV_MASK_DOUBLE_ECC |
+-               FPM_EV_MASK_STALL | FPM_EV_MASK_SINGLE_ECC);
+-      tmp |= FPM_EV_MASK_RELEASE_FM;
+-
+-      iowrite32be(tmp, &fpm_rg->fmfp_ee);
+-}
+-
+-static int fill_soc_specific_params(struct fman_state_struct *state)
+-{
+-      u8 minor = state->rev_info.minor;
+-      /* P4080 - Major 2
+-       * P2041/P3041/P5020/P5040 - Major 3
+-       * Tx/Bx - Major 6
+-       */
+-      switch (state->rev_info.major) {
+-      case 3:
+-              state->bmi_max_fifo_size        = 160 * 1024;
+-              state->fm_iram_size             = 64 * 1024;
+-              state->dma_thresh_max_commq     = 31;
+-              state->dma_thresh_max_buf       = 127;
+-              state->qmi_max_num_of_tnums     = 64;
+-              state->qmi_def_tnums_thresh     = 48;
+-              state->bmi_max_num_of_tasks     = 128;
+-              state->max_num_of_open_dmas     = 32;
+-              state->fm_port_num_of_cg        = 256;
+-              state->num_of_rx_ports  = 6;
+-              state->total_fifo_size  = 122 * 1024;
+-              break;
+-
+-      case 2:
+-              state->bmi_max_fifo_size        = 160 * 1024;
+-              state->fm_iram_size             = 64 * 1024;
+-              state->dma_thresh_max_commq     = 31;
+-              state->dma_thresh_max_buf       = 127;
+-              state->qmi_max_num_of_tnums     = 64;
+-              state->qmi_def_tnums_thresh     = 48;
+-              state->bmi_max_num_of_tasks     = 128;
+-              state->max_num_of_open_dmas     = 32;
+-              state->fm_port_num_of_cg        = 256;
+-              state->num_of_rx_ports  = 5;
+-              state->total_fifo_size  = 100 * 1024;
+-              break;
+-
+-      case 6:
+-              state->dma_thresh_max_commq     = 83;
+-              state->dma_thresh_max_buf       = 127;
+-              state->qmi_max_num_of_tnums     = 64;
+-              state->qmi_def_tnums_thresh     = 32;
+-              state->fm_port_num_of_cg        = 256;
+-
+-              /* FManV3L */
+-              if (minor == 1 || minor == 4) {
+-                      state->bmi_max_fifo_size        = 192 * 1024;
+-                      state->bmi_max_num_of_tasks     = 64;
+-                      state->max_num_of_open_dmas     = 32;
+-                      state->num_of_rx_ports          = 5;
+-                      if (minor == 1)
+-                              state->fm_iram_size     = 32 * 1024;
+-                      else
+-                              state->fm_iram_size     = 64 * 1024;
+-                      state->total_fifo_size          = 156 * 1024;
+-              }
+-              /* FManV3H */
+-              else if (minor == 0 || minor == 2 || minor == 3) {
+-                      state->bmi_max_fifo_size        = 384 * 1024;
+-                      state->fm_iram_size             = 64 * 1024;
+-                      state->bmi_max_num_of_tasks     = 128;
+-                      state->max_num_of_open_dmas     = 84;
+-                      state->num_of_rx_ports          = 8;
+-                      state->total_fifo_size          = 295 * 1024;
+-              } else {
+-                      pr_err("Unsupported FManv3 version\n");
+-                      return -EINVAL;
+-              }
+-
+-              break;
+-      default:
+-              pr_err("Unsupported FMan version\n");
+-              return -EINVAL;
+-      }
+-
+-      return 0;
+-}
+-
+-static bool is_init_done(struct fman_cfg *cfg)
+-{
+-      /* Checks if FMan driver parameters were initialized */
+-      if (!cfg)
+-              return true;
+-
+-      return false;
+-}
+-
+-static void free_init_resources(struct fman *fman)
+-{
+-      if (fman->cam_offset)
+-              fman_muram_free_mem(fman->muram, fman->cam_offset,
+-                                  fman->cam_size);
+-      if (fman->fifo_offset)
+-              fman_muram_free_mem(fman->muram, fman->fifo_offset,
+-                                  fman->fifo_size);
+-}
+-
+-static irqreturn_t bmi_err_event(struct fman *fman)
+-{
+-      u32 event, mask, force;
+-      struct fman_bmi_regs __iomem *bmi_rg = fman->bmi_regs;
+-      irqreturn_t ret = IRQ_NONE;
+-
+-      event = ioread32be(&bmi_rg->fmbm_ievr);
+-      mask = ioread32be(&bmi_rg->fmbm_ier);
+-      event &= mask;
+-      /* clear the forced events */
+-      force = ioread32be(&bmi_rg->fmbm_ifr);
+-      if (force & event)
+-              iowrite32be(force & ~event, &bmi_rg->fmbm_ifr);
+-      /* clear the acknowledged events */
+-      iowrite32be(event, &bmi_rg->fmbm_ievr);
+-
+-      if (event & BMI_ERR_INTR_EN_STORAGE_PROFILE_ECC)
+-              ret = fman->exception_cb(fman, FMAN_EX_BMI_STORAGE_PROFILE_ECC);
+-      if (event & BMI_ERR_INTR_EN_LIST_RAM_ECC)
+-              ret = fman->exception_cb(fman, FMAN_EX_BMI_LIST_RAM_ECC);
+-      if (event & BMI_ERR_INTR_EN_STATISTICS_RAM_ECC)
+-              ret = fman->exception_cb(fman, FMAN_EX_BMI_STATISTICS_RAM_ECC);
+-      if (event & BMI_ERR_INTR_EN_DISPATCH_RAM_ECC)
+-              ret = fman->exception_cb(fman, FMAN_EX_BMI_DISPATCH_RAM_ECC);
+-
+-      return ret;
+-}
+-
+-static irqreturn_t qmi_err_event(struct fman *fman)
+-{
+-      u32 event, mask, force;
+-      struct fman_qmi_regs __iomem *qmi_rg = fman->qmi_regs;
+-      irqreturn_t ret = IRQ_NONE;
+-
+-      event = ioread32be(&qmi_rg->fmqm_eie);
+-      mask = ioread32be(&qmi_rg->fmqm_eien);
+-      event &= mask;
+-
+-      /* clear the forced events */
+-      force = ioread32be(&qmi_rg->fmqm_eif);
+-      if (force & event)
+-              iowrite32be(force & ~event, &qmi_rg->fmqm_eif);
+-      /* clear the acknowledged events */
+-      iowrite32be(event, &qmi_rg->fmqm_eie);
+-
+-      if (event & QMI_ERR_INTR_EN_DOUBLE_ECC)
+-              ret = fman->exception_cb(fman, FMAN_EX_QMI_DOUBLE_ECC);
+-      if (event & QMI_ERR_INTR_EN_DEQ_FROM_DEF)
+-              ret = fman->exception_cb(fman,
+-                                       FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID);
+-
+-      return ret;
+-}
+-
+-static irqreturn_t dma_err_event(struct fman *fman)
+-{
+-      u32 status, mask, com_id;
+-      u8 tnum, port_id, relative_port_id;
+-      u16 liodn;
+-      struct fman_dma_regs __iomem *dma_rg = fman->dma_regs;
+-      irqreturn_t ret = IRQ_NONE;
+-
+-      status = ioread32be(&dma_rg->fmdmsr);
+-      mask = ioread32be(&dma_rg->fmdmmr);
+-
+-      /* clear DMA_STATUS_BUS_ERR if mask has no DMA_MODE_BER */
+-      if ((mask & DMA_MODE_BER) != DMA_MODE_BER)
+-              status &= ~DMA_STATUS_BUS_ERR;
+-
+-      /* clear relevant bits if mask has no DMA_MODE_ECC */
+-      if ((mask & DMA_MODE_ECC) != DMA_MODE_ECC)
+-              status &= ~(DMA_STATUS_FM_SPDAT_ECC |
+-                          DMA_STATUS_READ_ECC |
+-                          DMA_STATUS_SYSTEM_WRITE_ECC |
+-                          DMA_STATUS_FM_WRITE_ECC);
+-
+-      /* clear set events */
+-      iowrite32be(status, &dma_rg->fmdmsr);
+-
+-      if (status & DMA_STATUS_BUS_ERR) {
+-              u64 addr;
+-
+-              addr = (u64)ioread32be(&dma_rg->fmdmtal);
+-              addr |= ((u64)(ioread32be(&dma_rg->fmdmtah)) << 32);
+-
+-              com_id = ioread32be(&dma_rg->fmdmtcid);
+-              port_id = (u8)(((com_id & DMA_TRANSFER_PORTID_MASK) >>
+-                             DMA_TRANSFER_PORTID_SHIFT));
+-              relative_port_id =
+-              hw_port_id_to_sw_port_id(fman->state->rev_info.major, port_id);
+-              tnum = (u8)((com_id & DMA_TRANSFER_TNUM_MASK) >>
+-                          DMA_TRANSFER_TNUM_SHIFT);
+-              liodn = (u16)(com_id & DMA_TRANSFER_LIODN_MASK);
+-              ret = fman->bus_error_cb(fman, relative_port_id, addr, tnum,
+-                                       liodn);
+-      }
+-      if (status & DMA_STATUS_FM_SPDAT_ECC)
+-              ret = fman->exception_cb(fman, FMAN_EX_DMA_SINGLE_PORT_ECC);
+-      if (status & DMA_STATUS_READ_ECC)
+-              ret = fman->exception_cb(fman, FMAN_EX_DMA_READ_ECC);
+-      if (status & DMA_STATUS_SYSTEM_WRITE_ECC)
+-              ret = fman->exception_cb(fman, FMAN_EX_DMA_SYSTEM_WRITE_ECC);
+-      if (status & DMA_STATUS_FM_WRITE_ECC)
+-              ret = fman->exception_cb(fman, FMAN_EX_DMA_FM_WRITE_ECC);
+-
+-      return ret;
+-}
+-
+-static irqreturn_t fpm_err_event(struct fman *fman)
+-{
+-      u32 event;
+-      struct fman_fpm_regs __iomem *fpm_rg = fman->fpm_regs;
+-      irqreturn_t ret = IRQ_NONE;
+-
+-      event = ioread32be(&fpm_rg->fmfp_ee);
+-      /* clear the all occurred events */
+-      iowrite32be(event, &fpm_rg->fmfp_ee);
+-
+-      if ((event & FPM_EV_MASK_DOUBLE_ECC) &&
+-          (event & FPM_EV_MASK_DOUBLE_ECC_EN))
+-              ret = fman->exception_cb(fman, FMAN_EX_FPM_DOUBLE_ECC);
+-      if ((event & FPM_EV_MASK_STALL) && (event & FPM_EV_MASK_STALL_EN))
+-              ret = fman->exception_cb(fman, FMAN_EX_FPM_STALL_ON_TASKS);
+-      if ((event & FPM_EV_MASK_SINGLE_ECC) &&
+-          (event & FPM_EV_MASK_SINGLE_ECC_EN))
+-              ret = fman->exception_cb(fman, FMAN_EX_FPM_SINGLE_ECC);
+-
+-      return ret;
+-}
+-
+-static irqreturn_t muram_err_intr(struct fman *fman)
+-{
+-      u32 event, mask;
+-      struct fman_fpm_regs __iomem *fpm_rg = fman->fpm_regs;
+-      irqreturn_t ret = IRQ_NONE;
+-
+-      event = ioread32be(&fpm_rg->fm_rcr);
+-      mask = ioread32be(&fpm_rg->fm_rie);
+-
+-      /* clear MURAM event bit (do not clear IRAM event) */
+-      iowrite32be(event & ~FPM_RAM_IRAM_ECC, &fpm_rg->fm_rcr);
+-
+-      if ((mask & FPM_MURAM_ECC_ERR_EX_EN) && (event & FPM_RAM_MURAM_ECC))
+-              ret = fman->exception_cb(fman, FMAN_EX_MURAM_ECC);
+-
+-      return ret;
+-}
+-
+-static irqreturn_t qmi_event(struct fman *fman)
+-{
+-      u32 event, mask, force;
+-      struct fman_qmi_regs __iomem *qmi_rg = fman->qmi_regs;
+-      irqreturn_t ret = IRQ_NONE;
+-
+-      event = ioread32be(&qmi_rg->fmqm_ie);
+-      mask = ioread32be(&qmi_rg->fmqm_ien);
+-      event &= mask;
+-      /* clear the forced events */
+-      force = ioread32be(&qmi_rg->fmqm_if);
+-      if (force & event)
+-              iowrite32be(force & ~event, &qmi_rg->fmqm_if);
+-      /* clear the acknowledged events */
+-      iowrite32be(event, &qmi_rg->fmqm_ie);
+-
+-      if (event & QMI_INTR_EN_SINGLE_ECC)
+-              ret = fman->exception_cb(fman, FMAN_EX_QMI_SINGLE_ECC);
+-
+-      return ret;
+-}
+-
+-static void enable_time_stamp(struct fman *fman)
+-{
+-      struct fman_fpm_regs __iomem *fpm_rg = fman->fpm_regs;
+-      u16 fm_clk_freq = fman->state->fm_clk_freq;
+-      u32 tmp, intgr, ts_freq;
+-      u64 frac;
+-
+-      ts_freq = (u32)(1 << fman->state->count1_micro_bit);
+-      /* configure timestamp so that bit 8 will count 1 microsecond
+-       * Find effective count rate at TIMESTAMP least significant bits:
+-       * Effective_Count_Rate = 1MHz x 2^8 = 256MHz
+-       * Find frequency ratio between effective count rate and the clock:
+-       * Effective_Count_Rate / CLK e.g. for 600 MHz clock:
+-       * 256/600 = 0.4266666...
+-       */
+-
+-      intgr = ts_freq / fm_clk_freq;
+-      /* we multiply by 2^16 to keep the fraction of the division
+-       * we do not div back, since we write this value as a fraction
+-       * see spec
+-       */
+-
+-      frac = ((ts_freq << 16) - (intgr << 16) * fm_clk_freq) / fm_clk_freq;
+-      /* we check remainder of the division in order to round up if not int */
+-      if (((ts_freq << 16) - (intgr << 16) * fm_clk_freq) % fm_clk_freq)
+-              frac++;
+-
+-      tmp = (intgr << FPM_TS_INT_SHIFT) | (u16)frac;
+-      iowrite32be(tmp, &fpm_rg->fmfp_tsc2);
+-
+-      /* enable timestamp with original clock */
+-      iowrite32be(FPM_TS_CTL_EN, &fpm_rg->fmfp_tsc1);
+-      fman->state->enabled_time_stamp = true;
+-}
+-
+-static int clear_iram(struct fman *fman)
+-{
+-      struct fman_iram_regs __iomem *iram;
+-      int i, count;
+-
+-      iram = fman->base_addr + IMEM_OFFSET;
+-
+-      /* Enable the auto-increment */
+-      iowrite32be(IRAM_IADD_AIE, &iram->iadd);
+-      count = 100;
+-      do {
+-              udelay(1);
+-      } while ((ioread32be(&iram->iadd) != IRAM_IADD_AIE) && --count);
+-      if (count == 0)
+-              return -EBUSY;
+-
+-      for (i = 0; i < (fman->state->fm_iram_size / 4); i++)
+-              iowrite32be(0xffffffff, &iram->idata);
+-
+-      iowrite32be(fman->state->fm_iram_size - 4, &iram->iadd);
+-      count = 100;
+-      do {
+-              udelay(1);
+-      } while ((ioread32be(&iram->idata) != 0xffffffff) && --count);
+-      if (count == 0)
+-              return -EBUSY;
+-
+-      return 0;
+-}
+-
+-static u32 get_exception_flag(enum fman_exceptions exception)
+-{
+-      u32 bit_mask;
+-
+-      switch (exception) {
+-      case FMAN_EX_DMA_BUS_ERROR:
+-              bit_mask = EX_DMA_BUS_ERROR;
+-              break;
+-      case FMAN_EX_DMA_SINGLE_PORT_ECC:
+-              bit_mask = EX_DMA_SINGLE_PORT_ECC;
+-              break;
+-      case FMAN_EX_DMA_READ_ECC:
+-              bit_mask = EX_DMA_READ_ECC;
+-              break;
+-      case FMAN_EX_DMA_SYSTEM_WRITE_ECC:
+-              bit_mask = EX_DMA_SYSTEM_WRITE_ECC;
+-              break;
+-      case FMAN_EX_DMA_FM_WRITE_ECC:
+-              bit_mask = EX_DMA_FM_WRITE_ECC;
+-              break;
+-      case FMAN_EX_FPM_STALL_ON_TASKS:
+-              bit_mask = EX_FPM_STALL_ON_TASKS;
+-              break;
+-      case FMAN_EX_FPM_SINGLE_ECC:
+-              bit_mask = EX_FPM_SINGLE_ECC;
+-              break;
+-      case FMAN_EX_FPM_DOUBLE_ECC:
+-              bit_mask = EX_FPM_DOUBLE_ECC;
+-              break;
+-      case FMAN_EX_QMI_SINGLE_ECC:
+-              bit_mask = EX_QMI_SINGLE_ECC;
+-              break;
+-      case FMAN_EX_QMI_DOUBLE_ECC:
+-              bit_mask = EX_QMI_DOUBLE_ECC;
+-              break;
+-      case FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID:
+-              bit_mask = EX_QMI_DEQ_FROM_UNKNOWN_PORTID;
+-              break;
+-      case FMAN_EX_BMI_LIST_RAM_ECC:
+-              bit_mask = EX_BMI_LIST_RAM_ECC;
+-              break;
+-      case FMAN_EX_BMI_STORAGE_PROFILE_ECC:
+-              bit_mask = EX_BMI_STORAGE_PROFILE_ECC;
+-              break;
+-      case FMAN_EX_BMI_STATISTICS_RAM_ECC:
+-              bit_mask = EX_BMI_STATISTICS_RAM_ECC;
+-              break;
+-      case FMAN_EX_BMI_DISPATCH_RAM_ECC:
+-              bit_mask = EX_BMI_DISPATCH_RAM_ECC;
+-              break;
+-      case FMAN_EX_MURAM_ECC:
+-              bit_mask = EX_MURAM_ECC;
+-              break;
+-      default:
+-              bit_mask = 0;
+-              break;
+-      }
+-
+-      return bit_mask;
+-}
+-
+-static int get_module_event(enum fman_event_modules module, u8 mod_id,
+-                          enum fman_intr_type intr_type)
+-{
+-      int event;
+-
+-      switch (module) {
+-      case FMAN_MOD_MAC:
+-              if (intr_type == FMAN_INTR_TYPE_ERR)
+-                      event = FMAN_EV_ERR_MAC0 + mod_id;
+-              else
+-                      event = FMAN_EV_MAC0 + mod_id;
+-              break;
+-      case FMAN_MOD_FMAN_CTRL:
+-              if (intr_type == FMAN_INTR_TYPE_ERR)
+-                      event = FMAN_EV_CNT;
+-              else
+-                      event = (FMAN_EV_FMAN_CTRL_0 + mod_id);
+-              break;
+-      case FMAN_MOD_DUMMY_LAST:
+-              event = FMAN_EV_CNT;
+-              break;
+-      default:
+-              event = FMAN_EV_CNT;
+-              break;
+-      }
+-
+-      return event;
+-}
+-
+-static int set_size_of_fifo(struct fman *fman, u8 port_id, u32 *size_of_fifo,
+-                          u32 *extra_size_of_fifo)
+-{
+-      struct fman_bmi_regs __iomem *bmi_rg = fman->bmi_regs;
+-      u32 fifo = *size_of_fifo;
+-      u32 extra_fifo = *extra_size_of_fifo;
+-      u32 tmp;
+-
+-      /* if this is the first time a port requires extra_fifo_pool_size,
+-       * the total extra_fifo_pool_size must be initialized to 1 buffer per
+-       * port
+-       */
+-      if (extra_fifo && !fman->state->extra_fifo_pool_size)
+-              fman->state->extra_fifo_pool_size =
+-                      fman->state->num_of_rx_ports * FMAN_BMI_FIFO_UNITS;
+-
+-      fman->state->extra_fifo_pool_size =
+-              max(fman->state->extra_fifo_pool_size, extra_fifo);
+-
+-      /* check that there are enough uncommitted fifo size */
+-      if ((fman->state->accumulated_fifo_size + fifo) >
+-          (fman->state->total_fifo_size -
+-          fman->state->extra_fifo_pool_size)) {
+-              dev_err(fman->dev, "%s: Requested fifo size and extra size exceed total FIFO size.\n",
+-                      __func__);
+-              return -EAGAIN;
+-      }
+-
+-      /* Read, modify and write to HW */
+-      tmp = (fifo / FMAN_BMI_FIFO_UNITS - 1) |
+-             ((extra_fifo / FMAN_BMI_FIFO_UNITS) <<
+-             BMI_EXTRA_FIFO_SIZE_SHIFT);
+-      iowrite32be(tmp, &bmi_rg->fmbm_pfs[port_id - 1]);
+-
+-      /* update accumulated */
+-      fman->state->accumulated_fifo_size += fifo;
+-
+-      return 0;
+-}
+-
+-static int set_num_of_tasks(struct fman *fman, u8 port_id, u8 *num_of_tasks,
+-                          u8 *num_of_extra_tasks)
+-{
+-      struct fman_bmi_regs __iomem *bmi_rg = fman->bmi_regs;
+-      u8 tasks = *num_of_tasks;
+-      u8 extra_tasks = *num_of_extra_tasks;
+-      u32 tmp;
+-
+-      if (extra_tasks)
+-              fman->state->extra_tasks_pool_size =
+-              max(fman->state->extra_tasks_pool_size, extra_tasks);
+-
+-      /* check that there are enough uncommitted tasks */
+-      if ((fman->state->accumulated_num_of_tasks + tasks) >
+-          (fman->state->total_num_of_tasks -
+-           fman->state->extra_tasks_pool_size)) {
+-              dev_err(fman->dev, "%s: Requested num_of_tasks and extra tasks pool for fm%d exceed total num_of_tasks.\n",
+-                      __func__, fman->state->fm_id);
+-              return -EAGAIN;
+-      }
+-      /* update accumulated */
+-      fman->state->accumulated_num_of_tasks += tasks;
+-
+-      /* Write to HW */
+-      tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
+-          ~(BMI_NUM_OF_TASKS_MASK | BMI_NUM_OF_EXTRA_TASKS_MASK);
+-      tmp |= ((u32)((tasks - 1) << BMI_NUM_OF_TASKS_SHIFT) |
+-              (u32)(extra_tasks << BMI_EXTRA_NUM_OF_TASKS_SHIFT));
+-      iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
+-
+-      return 0;
+-}
+-
+-static int set_num_of_open_dmas(struct fman *fman, u8 port_id,
+-                              u8 *num_of_open_dmas,
+-                              u8 *num_of_extra_open_dmas)
+-{
+-      struct fman_bmi_regs __iomem *bmi_rg = fman->bmi_regs;
+-      u8 open_dmas = *num_of_open_dmas;
+-      u8 extra_open_dmas = *num_of_extra_open_dmas;
+-      u8 total_num_dmas = 0, current_val = 0, current_extra_val = 0;
+-      u32 tmp;
+-
+-      if (!open_dmas) {
+-              /* Configuration according to values in the HW.
+-               * read the current number of open Dma's
+-               */
+-              tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
+-              current_extra_val = (u8)((tmp & BMI_NUM_OF_EXTRA_DMAS_MASK) >>
+-                                       BMI_EXTRA_NUM_OF_DMAS_SHIFT);
+-
+-              tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]);
+-              current_val = (u8)(((tmp & BMI_NUM_OF_DMAS_MASK) >>
+-                                 BMI_NUM_OF_DMAS_SHIFT) + 1);
+-
+-              /* This is the first configuration and user did not
+-               * specify value (!open_dmas), reset values will be used
+-               * and we just save these values for resource management
+-               */
+-              fman->state->extra_open_dmas_pool_size =
+-                      (u8)max(fman->state->extra_open_dmas_pool_size,
+-                              current_extra_val);
+-              fman->state->accumulated_num_of_open_dmas += current_val;
+-              *num_of_open_dmas = current_val;
+-              *num_of_extra_open_dmas = current_extra_val;
+-              return 0;
+-      }
+-
+-      if (extra_open_dmas > current_extra_val)
+-              fman->state->extra_open_dmas_pool_size =
+-                  (u8)max(fman->state->extra_open_dmas_pool_size,
+-                          extra_open_dmas);
+-
+-      if ((fman->state->rev_info.major < 6) &&
+-          (fman->state->accumulated_num_of_open_dmas - current_val +
+-           open_dmas > fman->state->max_num_of_open_dmas)) {
+-              dev_err(fman->dev, "%s: Requested num_of_open_dmas for fm%d exceeds total num_of_open_dmas.\n",
+-                      __func__, fman->state->fm_id);
+-              return -EAGAIN;
+-      } else if ((fman->state->rev_info.major >= 6) &&
+-                 !((fman->state->rev_info.major == 6) &&
+-                 (fman->state->rev_info.minor == 0)) &&
+-                 (fman->state->accumulated_num_of_open_dmas -
+-                 current_val + open_dmas >
+-                 fman->state->dma_thresh_max_commq + 1)) {
+-              dev_err(fman->dev, "%s: Requested num_of_open_dmas for fm%d exceeds DMA Command queue (%d)\n",
+-                      __func__, fman->state->fm_id,
+-                     fman->state->dma_thresh_max_commq + 1);
+-              return -EAGAIN;
+-      }
+-
+-      WARN_ON(fman->state->accumulated_num_of_open_dmas < current_val);
+-      /* update acummulated */
+-      fman->state->accumulated_num_of_open_dmas -= current_val;
+-      fman->state->accumulated_num_of_open_dmas += open_dmas;
+-
+-      if (fman->state->rev_info.major < 6)
+-              total_num_dmas =
+-                  (u8)(fman->state->accumulated_num_of_open_dmas +
+-                  fman->state->extra_open_dmas_pool_size);
+-
+-      /* calculate reg */
+-      tmp = ioread32be(&bmi_rg->fmbm_pp[port_id - 1]) &
+-          ~(BMI_NUM_OF_DMAS_MASK | BMI_NUM_OF_EXTRA_DMAS_MASK);
+-      tmp |= (u32)(((open_dmas - 1) << BMI_NUM_OF_DMAS_SHIFT) |
+-                         (extra_open_dmas << BMI_EXTRA_NUM_OF_DMAS_SHIFT));
+-      iowrite32be(tmp, &bmi_rg->fmbm_pp[port_id - 1]);
+-
+-      /* update total num of DMA's with committed number of open DMAS,
+-       * and max uncommitted pool.
+-       */
+-      if (total_num_dmas) {
+-              tmp = ioread32be(&bmi_rg->fmbm_cfg2) & ~BMI_CFG2_DMAS_MASK;
+-              tmp |= (u32)(total_num_dmas - 1) << BMI_CFG2_DMAS_SHIFT;
+-              iowrite32be(tmp, &bmi_rg->fmbm_cfg2);
+-      }
+-
+-      return 0;
+-}
+-
+-static int fman_config(struct fman *fman)
+-{
+-      void __iomem *base_addr;
+-      int err;
+-
+-      base_addr = fman->dts_params.base_addr;
+-
+-      fman->state = kzalloc(sizeof(*fman->state), GFP_KERNEL);
+-      if (!fman->state)
+-              goto err_fm_state;
+-
+-      /* Allocate the FM driver's parameters structure */
+-      fman->cfg = kzalloc(sizeof(*fman->cfg), GFP_KERNEL);
+-      if (!fman->cfg)
+-              goto err_fm_drv;
+-
+-      /* Initialize MURAM block */
+-      fman->muram =
+-              fman_muram_init(fman->dts_params.muram_res.start,
+-                              resource_size(&fman->dts_params.muram_res));
+-      if (!fman->muram)
+-              goto err_fm_soc_specific;
+-
+-      /* Initialize FM parameters which will be kept by the driver */
+-      fman->state->fm_id = fman->dts_params.id;
+-      fman->state->fm_clk_freq = fman->dts_params.clk_freq;
+-      fman->state->qman_channel_base = fman->dts_params.qman_channel_base;
+-      fman->state->num_of_qman_channels =
+-              fman->dts_params.num_of_qman_channels;
+-      fman->state->res = fman->dts_params.res;
+-      fman->exception_cb = fman_exceptions;
+-      fman->bus_error_cb = fman_bus_error;
+-      fman->fpm_regs = base_addr + FPM_OFFSET;
+-      fman->bmi_regs = base_addr + BMI_OFFSET;
+-      fman->qmi_regs = base_addr + QMI_OFFSET;
+-      fman->dma_regs = base_addr + DMA_OFFSET;
+-      fman->base_addr = base_addr;
+-
+-      spin_lock_init(&fman->spinlock);
+-      fman_defconfig(fman->cfg);
+-
+-      fman->state->extra_fifo_pool_size = 0;
+-      fman->state->exceptions = (EX_DMA_BUS_ERROR                 |
+-                                      EX_DMA_READ_ECC              |
+-                                      EX_DMA_SYSTEM_WRITE_ECC      |
+-                                      EX_DMA_FM_WRITE_ECC          |
+-                                      EX_FPM_STALL_ON_TASKS        |
+-                                      EX_FPM_SINGLE_ECC            |
+-                                      EX_FPM_DOUBLE_ECC            |
+-                                      EX_QMI_DEQ_FROM_UNKNOWN_PORTID |
+-                                      EX_BMI_LIST_RAM_ECC          |
+-                                      EX_BMI_STORAGE_PROFILE_ECC   |
+-                                      EX_BMI_STATISTICS_RAM_ECC    |
+-                                      EX_MURAM_ECC                 |
+-                                      EX_BMI_DISPATCH_RAM_ECC      |
+-                                      EX_QMI_DOUBLE_ECC            |
+-                                      EX_QMI_SINGLE_ECC);
+-
+-      /* Read FMan revision for future use*/
+-      fman_get_revision(fman, &fman->state->rev_info);
+-
+-      err = fill_soc_specific_params(fman->state);
+-      if (err)
+-              goto err_fm_soc_specific;
+-
+-      /* FM_AID_MODE_NO_TNUM_SW005 Errata workaround */
+-      if (fman->state->rev_info.major >= 6)
+-              fman->cfg->dma_aid_mode = FMAN_DMA_AID_OUT_PORT_ID;
+-
+-      fman->cfg->qmi_def_tnums_thresh = fman->state->qmi_def_tnums_thresh;
+-
+-      fman->state->total_num_of_tasks =
+-      (u8)DFLT_TOTAL_NUM_OF_TASKS(fman->state->rev_info.major,
+-                                  fman->state->rev_info.minor,
+-                                  fman->state->bmi_max_num_of_tasks);
+-
+-      if (fman->state->rev_info.major < 6) {
+-              fman->cfg->dma_comm_qtsh_clr_emer =
+-              (u8)DFLT_DMA_COMM_Q_LOW(fman->state->rev_info.major,
+-                                      fman->state->dma_thresh_max_commq);
+-
+-              fman->cfg->dma_comm_qtsh_asrt_emer =
+-              (u8)DFLT_DMA_COMM_Q_HIGH(fman->state->rev_info.major,
+-                                       fman->state->dma_thresh_max_commq);
+-
+-              fman->cfg->dma_cam_num_of_entries =
+-              DFLT_DMA_CAM_NUM_OF_ENTRIES(fman->state->rev_info.major);
+-
+-              fman->cfg->dma_read_buf_tsh_clr_emer =
+-              DFLT_DMA_READ_INT_BUF_LOW(fman->state->dma_thresh_max_buf);
+-
+-              fman->cfg->dma_read_buf_tsh_asrt_emer =
+-              DFLT_DMA_READ_INT_BUF_HIGH(fman->state->dma_thresh_max_buf);
+-
+-              fman->cfg->dma_write_buf_tsh_clr_emer =
+-              DFLT_DMA_WRITE_INT_BUF_LOW(fman->state->dma_thresh_max_buf);
+-
+-              fman->cfg->dma_write_buf_tsh_asrt_emer =
+-              DFLT_DMA_WRITE_INT_BUF_HIGH(fman->state->dma_thresh_max_buf);
+-
+-              fman->cfg->dma_axi_dbg_num_of_beats =
+-              DFLT_AXI_DBG_NUM_OF_BEATS;
+-      }
+-
+-      return 0;
+-
+-err_fm_soc_specific:
+-      kfree(fman->cfg);
+-err_fm_drv:
+-      kfree(fman->state);
+-err_fm_state:
+-      kfree(fman);
+-      return -EINVAL;
+-}
+-
+-static int fman_reset(struct fman *fman)
+-{
+-      u32 count;
+-      int err = 0;
+-
+-      if (fman->state->rev_info.major < 6) {
+-              iowrite32be(FPM_RSTC_FM_RESET, &fman->fpm_regs->fm_rstc);
+-              /* Wait for reset completion */
+-              count = 100;
+-              do {
+-                      udelay(1);
+-              } while (((ioread32be(&fman->fpm_regs->fm_rstc)) &
+-                       FPM_RSTC_FM_RESET) && --count);
+-              if (count == 0)
+-                      err = -EBUSY;
+-
+-              goto _return;
+-      } else {
+-              struct device_node *guts_node;
+-              struct ccsr_guts __iomem *guts_regs;
+-              u32 devdisr2, reg;
+-
+-              /* Errata A007273 */
+-              guts_node =
+-                      of_find_compatible_node(NULL, NULL,
+-                                              "fsl,qoriq-device-config-2.0");
+-              if (!guts_node) {
+-                      dev_err(fman->dev, "%s: Couldn't find guts node\n",
+-                              __func__);
+-                      goto guts_node;
+-              }
+-
+-              guts_regs = of_iomap(guts_node, 0);
+-              if (!guts_regs) {
+-                      dev_err(fman->dev, "%s: Couldn't map %s regs\n",
+-                              __func__, guts_node->full_name);
+-                      goto guts_regs;
+-              }
+-#define FMAN1_ALL_MACS_MASK   0xFCC00000
+-#define FMAN2_ALL_MACS_MASK   0x000FCC00
+-              /* Read current state */
+-              devdisr2 = ioread32be(&guts_regs->devdisr2);
+-              if (fman->dts_params.id == 0)
+-                      reg = devdisr2 & ~FMAN1_ALL_MACS_MASK;
+-              else
+-                      reg = devdisr2 & ~FMAN2_ALL_MACS_MASK;
+-
+-              /* Enable all MACs */
+-              iowrite32be(reg, &guts_regs->devdisr2);
+-
+-              /* Perform FMan reset */
+-              iowrite32be(FPM_RSTC_FM_RESET, &fman->fpm_regs->fm_rstc);
+-
+-              /* Wait for reset completion */
+-              count = 100;
+-              do {
+-                      udelay(1);
+-              } while (((ioread32be(&fman->fpm_regs->fm_rstc)) &
+-                       FPM_RSTC_FM_RESET) && --count);
+-              if (count == 0) {
+-                      iounmap(guts_regs);
+-                      of_node_put(guts_node);
+-                      err = -EBUSY;
+-                      goto _return;
+-              }
+-
+-              /* Restore devdisr2 value */
+-              iowrite32be(devdisr2, &guts_regs->devdisr2);
+-
+-              iounmap(guts_regs);
+-              of_node_put(guts_node);
+-
+-              goto _return;
+-
+-guts_regs:
+-              of_node_put(guts_node);
+-guts_node:
+-              dev_dbg(fman->dev, "%s: Didn't perform FManV3 reset due to Errata A007273!\n",
+-                      __func__);
+-      }
+-_return:
+-      return err;
+-}
+-
+-static int fman_init(struct fman *fman)
+-{
+-      struct fman_cfg *cfg = NULL;
+-      int err = 0, i, count;
+-
+-      if (is_init_done(fman->cfg))
+-              return -EINVAL;
+-
+-      fman->state->count1_micro_bit = FM_TIMESTAMP_1_USEC_BIT;
+-
+-      cfg = fman->cfg;
+-
+-      /* clear revision-dependent non existing exception */
+-      if (fman->state->rev_info.major < 6)
+-              fman->state->exceptions &= ~FMAN_EX_BMI_DISPATCH_RAM_ECC;
+-
+-      if (fman->state->rev_info.major >= 6)
+-              fman->state->exceptions &= ~FMAN_EX_QMI_SINGLE_ECC;
+-
+-      /* clear CPG */
+-      memset_io((void __iomem *)(fman->base_addr + CGP_OFFSET), 0,
+-                fman->state->fm_port_num_of_cg);
+-
+-      /* Save LIODN info before FMan reset
+-       * Skipping non-existent port 0 (i = 1)
+-       */
+-      for (i = 1; i < FMAN_LIODN_TBL; i++) {
+-              u32 liodn_base;
+-
+-              fman->liodn_offset[i] =
+-                      ioread32be(&fman->bmi_regs->fmbm_spliodn[i - 1]);
+-              liodn_base = ioread32be(&fman->dma_regs->fmdmplr[i / 2]);
+-              if (i % 2) {
+-                      /* FMDM_PLR LSB holds LIODN base for odd ports */
+-                      liodn_base &= DMA_LIODN_BASE_MASK;
+-              } else {
+-                      /* FMDM_PLR MSB holds LIODN base for even ports */
+-                      liodn_base >>= DMA_LIODN_SHIFT;
+-                      liodn_base &= DMA_LIODN_BASE_MASK;
+-              }
+-              fman->liodn_base[i] = liodn_base;
+-      }
+-
+-      err = fman_reset(fman);
+-      if (err)
+-              return err;
+-
+-      if (ioread32be(&fman->qmi_regs->fmqm_gs) & QMI_GS_HALT_NOT_BUSY) {
+-              resume(fman->fpm_regs);
+-              /* Wait until QMI is not in halt not busy state */
+-              count = 100;
+-              do {
+-                      udelay(1);
+-              } while (((ioread32be(&fman->qmi_regs->fmqm_gs)) &
+-                       QMI_GS_HALT_NOT_BUSY) && --count);
+-              if (count == 0)
+-                      dev_warn(fman->dev, "%s: QMI is in halt not busy state\n",
+-                               __func__);
+-      }
+-
+-      if (clear_iram(fman) != 0)
+-              return -EINVAL;
+-
+-      cfg->exceptions = fman->state->exceptions;
+-
+-      /* Init DMA Registers */
+-
+-      err = dma_init(fman);
+-      if (err != 0) {
+-              free_init_resources(fman);
+-              return err;
+-      }
+-
+-      /* Init FPM Registers */
+-      fpm_init(fman->fpm_regs, fman->cfg);
+-
+-      /* define common resources */
+-      /* allocate MURAM for FIFO according to total size */
+-      fman->fifo_offset = fman_muram_alloc(fman->muram,
+-                                           fman->state->total_fifo_size);
+-      if (IS_ERR_VALUE(fman->fifo_offset)) {
+-              free_init_resources(fman);
+-              dev_err(fman->dev, "%s: MURAM alloc for BMI FIFO failed\n",
+-                      __func__);
+-              return -ENOMEM;
+-      }
+-
+-      cfg->fifo_base_addr = fman->fifo_offset;
+-      cfg->total_fifo_size = fman->state->total_fifo_size;
+-      cfg->total_num_of_tasks = fman->state->total_num_of_tasks;
+-      cfg->clk_freq = fman->state->fm_clk_freq;
+-
+-      /* Init BMI Registers */
+-      bmi_init(fman->bmi_regs, fman->cfg);
+-
+-      /* Init QMI Registers */
+-      qmi_init(fman->qmi_regs, fman->cfg);
+-
+-      err = enable(fman, cfg);
+-      if (err != 0)
+-              return err;
+-
+-      enable_time_stamp(fman);
+-
+-      kfree(fman->cfg);
+-      fman->cfg = NULL;
+-
+-      return 0;
+-}
+-
+-static int fman_set_exception(struct fman *fman,
+-                            enum fman_exceptions exception, bool enable)
+-{
+-      u32 bit_mask = 0;
+-
+-      if (!is_init_done(fman->cfg))
+-              return -EINVAL;
+-
+-      bit_mask = get_exception_flag(exception);
+-      if (bit_mask) {
+-              if (enable)
+-                      fman->state->exceptions |= bit_mask;
+-              else
+-                      fman->state->exceptions &= ~bit_mask;
+-      } else {
+-              dev_err(fman->dev, "%s: Undefined exception (%d)\n",
+-                      __func__, exception);
+-              return -EINVAL;
+-      }
+-
+-      return set_exception(fman, exception, enable);
+-}
+-
+-/**
+- * fman_register_intr
+- * @fman:     A Pointer to FMan device
+- * @mod:      Calling module
+- * @mod_id:   Module id (if more than 1 exists, '0' if not)
+- * @intr_type:        Interrupt type (error/normal) selection.
+- * @f_isr:    The interrupt service routine.
+- * @h_src_arg:        Argument to be passed to f_isr.
+- *
+- * Used to register an event handler to be processed by FMan
+- *
+- * Return: 0 on success; Error code otherwise.
+- */
+-void fman_register_intr(struct fman *fman, enum fman_event_modules module,
+-                      u8 mod_id, enum fman_intr_type intr_type,
+-                      void (*isr_cb)(void *src_arg), void *src_arg)
+-{
+-      int event = 0;
+-
+-      event = get_module_event(module, mod_id, intr_type);
+-      WARN_ON(event >= FMAN_EV_CNT);
+-
+-      /* register in local FM structure */
+-      fman->intr_mng[event].isr_cb = isr_cb;
+-      fman->intr_mng[event].src_handle = src_arg;
+-}
+-EXPORT_SYMBOL(fman_register_intr);
+-
+-/**
+- * fman_unregister_intr
+- * @fman:     A Pointer to FMan device
+- * @mod:      Calling module
+- * @mod_id:   Module id (if more than 1 exists, '0' if not)
+- * @intr_type:        Interrupt type (error/normal) selection.
+- *
+- * Used to unregister an event handler to be processed by FMan
+- *
+- * Return: 0 on success; Error code otherwise.
+- */
+-void fman_unregister_intr(struct fman *fman, enum fman_event_modules module,
+-                        u8 mod_id, enum fman_intr_type intr_type)
+-{
+-      int event = 0;
+-
+-      event = get_module_event(module, mod_id, intr_type);
+-      WARN_ON(event >= FMAN_EV_CNT);
+-
+-      fman->intr_mng[event].isr_cb = NULL;
+-      fman->intr_mng[event].src_handle = NULL;
+-}
+-EXPORT_SYMBOL(fman_unregister_intr);
+-
+-/**
+- * fman_set_port_params
+- * @fman:             A Pointer to FMan device
+- * @port_params:      Port parameters
+- *
+- * Used by FMan Port to pass parameters to the FMan
+- *
+- * Return: 0 on success; Error code otherwise.
+- */
+-int fman_set_port_params(struct fman *fman,
+-                       struct fman_port_init_params *port_params)
+-{
+-      int err;
+-      unsigned long flags;
+-      u8 port_id = port_params->port_id, mac_id;
+-
+-      spin_lock_irqsave(&fman->spinlock, flags);
+-
+-      err = set_num_of_tasks(fman, port_params->port_id,
+-                             &port_params->num_of_tasks,
+-                             &port_params->num_of_extra_tasks);
+-      if (err)
+-              goto return_err;
+-
+-      /* TX Ports */
+-      if (port_params->port_type != FMAN_PORT_TYPE_RX) {
+-              u32 enq_th, deq_th, reg;
+-
+-              /* update qmi ENQ/DEQ threshold */
+-              fman->state->accumulated_num_of_deq_tnums +=
+-                      port_params->deq_pipeline_depth;
+-              enq_th = (ioread32be(&fman->qmi_regs->fmqm_gc) &
+-                        QMI_CFG_ENQ_MASK) >> QMI_CFG_ENQ_SHIFT;
+-              /* if enq_th is too big, we reduce it to the max value
+-               * that is still 0
+-               */
+-              if (enq_th >= (fman->state->qmi_max_num_of_tnums -
+-                  fman->state->accumulated_num_of_deq_tnums)) {
+-                      enq_th =
+-                      fman->state->qmi_max_num_of_tnums -
+-                      fman->state->accumulated_num_of_deq_tnums - 1;
+-
+-                      reg = ioread32be(&fman->qmi_regs->fmqm_gc);
+-                      reg &= ~QMI_CFG_ENQ_MASK;
+-                      reg |= (enq_th << QMI_CFG_ENQ_SHIFT);
+-                      iowrite32be(reg, &fman->qmi_regs->fmqm_gc);
+-              }
+-
+-              deq_th = ioread32be(&fman->qmi_regs->fmqm_gc) &
+-                                  QMI_CFG_DEQ_MASK;
+-              /* if deq_th is too small, we enlarge it to the min
+-               * value that is still 0.
+-               * depTh may not be larger than 63
+-               * (fman->state->qmi_max_num_of_tnums-1).
+-               */
+-              if ((deq_th <= fman->state->accumulated_num_of_deq_tnums) &&
+-                  (deq_th < fman->state->qmi_max_num_of_tnums - 1)) {
+-                      deq_th = fman->state->accumulated_num_of_deq_tnums + 1;
+-                      reg = ioread32be(&fman->qmi_regs->fmqm_gc);
+-                      reg &= ~QMI_CFG_DEQ_MASK;
+-                      reg |= deq_th;
+-                      iowrite32be(reg, &fman->qmi_regs->fmqm_gc);
+-              }
+-      }
+-
+-      err = set_size_of_fifo(fman, port_params->port_id,
+-                             &port_params->size_of_fifo,
+-                             &port_params->extra_size_of_fifo);
+-      if (err)
+-              goto return_err;
+-
+-      err = set_num_of_open_dmas(fman, port_params->port_id,
+-                                 &port_params->num_of_open_dmas,
+-                                 &port_params->num_of_extra_open_dmas);
+-      if (err)
+-              goto return_err;
+-
+-      set_port_liodn(fman, port_id, fman->liodn_base[port_id],
+-                     fman->liodn_offset[port_id]);
+-
+-      if (fman->state->rev_info.major < 6)
+-              set_port_order_restoration(fman->fpm_regs, port_id);
+-
+-      mac_id = hw_port_id_to_sw_port_id(fman->state->rev_info.major, port_id);
+-
+-      if (port_params->max_frame_length >= fman->state->mac_mfl[mac_id]) {
+-              fman->state->port_mfl[mac_id] = port_params->max_frame_length;
+-      } else {
+-              dev_warn(fman->dev, "%s: Port (%d) max_frame_length is smaller than MAC (%d) current MTU\n",
+-                       __func__, port_id, mac_id);
+-              err = -EINVAL;
+-              goto return_err;
+-      }
+-
+-      spin_unlock_irqrestore(&fman->spinlock, flags);
+-
+-      return 0;
+-
+-return_err:
+-      spin_unlock_irqrestore(&fman->spinlock, flags);
+-      return err;
+-}
+-EXPORT_SYMBOL(fman_set_port_params);
+-
+-/**
+- * fman_reset_mac
+- * @fman:     A Pointer to FMan device
+- * @mac_id:   MAC id to be reset
+- *
+- * Reset a specific MAC
+- *
+- * Return: 0 on success; Error code otherwise.
+- */
+-int fman_reset_mac(struct fman *fman, u8 mac_id)
+-{
+-      struct fman_fpm_regs __iomem *fpm_rg = fman->fpm_regs;
+-      u32 msk, timeout = 100;
+-
+-      if (fman->state->rev_info.major >= 6) {
+-              dev_err(fman->dev, "%s: FMan MAC reset no available for FMan V3!\n",
+-                      __func__);
+-              return -EINVAL;
+-      }
+-
+-      /* Get the relevant bit mask */
+-      switch (mac_id) {
+-      case 0:
+-              msk = FPM_RSTC_MAC0_RESET;
+-              break;
+-      case 1:
+-              msk = FPM_RSTC_MAC1_RESET;
+-              break;
+-      case 2:
+-              msk = FPM_RSTC_MAC2_RESET;
+-              break;
+-      case 3:
+-              msk = FPM_RSTC_MAC3_RESET;
+-              break;
+-      case 4:
+-              msk = FPM_RSTC_MAC4_RESET;
+-              break;
+-      case 5:
+-              msk = FPM_RSTC_MAC5_RESET;
+-              break;
+-      case 6:
+-              msk = FPM_RSTC_MAC6_RESET;
+-              break;
+-      case 7:
+-              msk = FPM_RSTC_MAC7_RESET;
+-              break;
+-      case 8:
+-              msk = FPM_RSTC_MAC8_RESET;
+-              break;
+-      case 9:
+-              msk = FPM_RSTC_MAC9_RESET;
+-              break;
+-      default:
+-              dev_warn(fman->dev, "%s: Illegal MAC Id [%d]\n",
+-                       __func__, mac_id);
+-              return -EINVAL;
+-      }
+-
+-      /* reset */
+-      iowrite32be(msk, &fpm_rg->fm_rstc);
+-      while ((ioread32be(&fpm_rg->fm_rstc) & msk) && --timeout)
+-              udelay(10);
+-
+-      if (!timeout)
+-              return -EIO;
+-
+-      return 0;
+-}
+-EXPORT_SYMBOL(fman_reset_mac);
+-
+-/**
+- * fman_set_mac_max_frame
+- * @fman:     A Pointer to FMan device
+- * @mac_id:   MAC id
+- * @mfl:      Maximum frame length
+- *
+- * Set maximum frame length of specific MAC in FMan driver
+- *
+- * Return: 0 on success; Error code otherwise.
+- */
+-int fman_set_mac_max_frame(struct fman *fman, u8 mac_id, u16 mfl)
+-{
+-      /* if port is already initialized, check that MaxFrameLength is smaller
+-       * or equal to the port's max
+-       */
+-      if ((!fman->state->port_mfl[mac_id]) ||
+-          (mfl <= fman->state->port_mfl[mac_id])) {
+-              fman->state->mac_mfl[mac_id] = mfl;
+-      } else {
+-              dev_warn(fman->dev, "%s: MAC max_frame_length is larger than Port max_frame_length\n",
+-                       __func__);
+-              return -EINVAL;
+-      }
+-      return 0;
+-}
+-EXPORT_SYMBOL(fman_set_mac_max_frame);
+-
+-/**
+- * fman_get_clock_freq
+- * @fman:     A Pointer to FMan device
+- *
+- * Get FMan clock frequency
+- *
+- * Return: FMan clock frequency
+- */
+-u16 fman_get_clock_freq(struct fman *fman)
+-{
+-      return fman->state->fm_clk_freq;
+-}
+-
+-/**
+- * fman_get_bmi_max_fifo_size
+- * @fman:     A Pointer to FMan device
+- *
+- * Get FMan maximum FIFO size
+- *
+- * Return: FMan Maximum FIFO size
+- */
+-u32 fman_get_bmi_max_fifo_size(struct fman *fman)
+-{
+-      return fman->state->bmi_max_fifo_size;
+-}
+-EXPORT_SYMBOL(fman_get_bmi_max_fifo_size);
+-
+-/**
+- * fman_get_revision
+- * @fman              - Pointer to the FMan module
+- * @rev_info          - A structure of revision information parameters.
+- *
+- * Returns the FM revision
+- *
+- * Allowed only following fman_init().
+- *
+- * Return: 0 on success; Error code otherwise.
+- */
+-void fman_get_revision(struct fman *fman, struct fman_rev_info *rev_info)
+-{
+-      u32 tmp;
+-
+-      tmp = ioread32be(&fman->fpm_regs->fm_ip_rev_1);
+-      rev_info->major = (u8)((tmp & FPM_REV1_MAJOR_MASK) >>
+-                              FPM_REV1_MAJOR_SHIFT);
+-      rev_info->minor = tmp & FPM_REV1_MINOR_MASK;
+-}
+-EXPORT_SYMBOL(fman_get_revision);
+-
+-/**
+- * fman_get_qman_channel_id
+- * @fman:     A Pointer to FMan device
+- * @port_id:  Port id
+- *
+- * Get QMan channel ID associated to the Port id
+- *
+- * Return: QMan channel ID
+- */
+-u32 fman_get_qman_channel_id(struct fman *fman, u32 port_id)
+-{
+-      int i;
+-
+-      if (fman->state->rev_info.major >= 6) {
+-              u32 port_ids[] = {0x30, 0x31, 0x28, 0x29, 0x2a, 0x2b,
+-                                0x2c, 0x2d, 0x2, 0x3, 0x4, 0x5, 0x7, 0x7};
+-              for (i = 0; i < fman->state->num_of_qman_channels; i++) {
+-                      if (port_ids[i] == port_id)
+-                              break;
+-              }
+-      } else {
+-              u32 port_ids[] = {0x30, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x1,
+-                                0x2, 0x3, 0x4, 0x5, 0x7, 0x7};
+-              for (i = 0; i < fman->state->num_of_qman_channels; i++) {
+-                      if (port_ids[i] == port_id)
+-                              break;
+-              }
+-      }
+-
+-      if (i == fman->state->num_of_qman_channels)
+-              return 0;
+-
+-      return fman->state->qman_channel_base + i;
+-}
+-EXPORT_SYMBOL(fman_get_qman_channel_id);
+-
+-/**
+- * fman_get_mem_region
+- * @fman:     A Pointer to FMan device
+- *
+- * Get FMan memory region
+- *
+- * Return: A structure with FMan memory region information
+- */
+-struct resource *fman_get_mem_region(struct fman *fman)
+-{
+-      return fman->state->res;
+-}
+-EXPORT_SYMBOL(fman_get_mem_region);
+-
+-/* Bootargs defines */
+-/* Extra headroom for RX buffers - Default, min and max */
+-#define FSL_FM_RX_EXTRA_HEADROOM      64
+-#define FSL_FM_RX_EXTRA_HEADROOM_MIN  16
+-#define FSL_FM_RX_EXTRA_HEADROOM_MAX  384
+-
+-/* Maximum frame length */
+-#define FSL_FM_MAX_FRAME_SIZE                 1522
+-#define FSL_FM_MAX_POSSIBLE_FRAME_SIZE                9600
+-#define FSL_FM_MIN_POSSIBLE_FRAME_SIZE                64
+-
+-/* Extra headroom for Rx buffers.
+- * FMan is instructed to allocate, on the Rx path, this amount of
+- * space at the beginning of a data buffer, beside the DPA private
+- * data area and the IC fields.
+- * Does not impact Tx buffer layout.
+- * Configurable from bootargs. 64 by default, it's needed on
+- * particular forwarding scenarios that add extra headers to the
+- * forwarded frame.
+- */
+-static int fsl_fm_rx_extra_headroom = FSL_FM_RX_EXTRA_HEADROOM;
+-module_param(fsl_fm_rx_extra_headroom, int, 0);
+-MODULE_PARM_DESC(fsl_fm_rx_extra_headroom, "Extra headroom for Rx buffers");
+-
+-/* Max frame size, across all interfaces.
+- * Configurable from bootargs, to avoid allocating oversized (socket)
+- * buffers when not using jumbo frames.
+- * Must be large enough to accommodate the network MTU, but small enough
+- * to avoid wasting skb memory.
+- *
+- * Could be overridden once, at boot-time, via the
+- * fm_set_max_frm() callback.
+- */
+-static int fsl_fm_max_frm = FSL_FM_MAX_FRAME_SIZE;
+-module_param(fsl_fm_max_frm, int, 0);
+-MODULE_PARM_DESC(fsl_fm_max_frm, "Maximum frame size, across all interfaces");
+-
+-/**
+- * fman_get_max_frm
+- *
+- * Return: Max frame length configured in the FM driver
+- */
+-u16 fman_get_max_frm(void)
+-{
+-      static bool fm_check_mfl;
+-
+-      if (!fm_check_mfl) {
+-              if (fsl_fm_max_frm > FSL_FM_MAX_POSSIBLE_FRAME_SIZE ||
+-                  fsl_fm_max_frm < FSL_FM_MIN_POSSIBLE_FRAME_SIZE) {
+-                      pr_warn("Invalid fsl_fm_max_frm value (%d) in bootargs, valid range is %d-%d. Falling back to the default (%d)\n",
+-                              fsl_fm_max_frm,
+-                              FSL_FM_MIN_POSSIBLE_FRAME_SIZE,
+-                              FSL_FM_MAX_POSSIBLE_FRAME_SIZE,
+-                              FSL_FM_MAX_FRAME_SIZE);
+-                      fsl_fm_max_frm = FSL_FM_MAX_FRAME_SIZE;
+-              }
+-              fm_check_mfl = true;
+-      }
+-
+-      return fsl_fm_max_frm;
+-}
+-EXPORT_SYMBOL(fman_get_max_frm);
+-
+-/**
+- * fman_get_rx_extra_headroom
+- *
+- * Return: Extra headroom size configured in the FM driver
+- */
+-int fman_get_rx_extra_headroom(void)
+-{
+-      static bool fm_check_rx_extra_headroom;
+-
+-      if (!fm_check_rx_extra_headroom) {
+-              if (fsl_fm_rx_extra_headroom > FSL_FM_RX_EXTRA_HEADROOM_MAX ||
+-                  fsl_fm_rx_extra_headroom < FSL_FM_RX_EXTRA_HEADROOM_MIN) {
+-                      pr_warn("Invalid fsl_fm_rx_extra_headroom value (%d) in bootargs, valid range is %d-%d. Falling back to the default (%d)\n",
+-                              fsl_fm_rx_extra_headroom,
+-                              FSL_FM_RX_EXTRA_HEADROOM_MIN,
+-                              FSL_FM_RX_EXTRA_HEADROOM_MAX,
+-                              FSL_FM_RX_EXTRA_HEADROOM);
+-                      fsl_fm_rx_extra_headroom = FSL_FM_RX_EXTRA_HEADROOM;
+-              }
+-
+-              fm_check_rx_extra_headroom = true;
+-              fsl_fm_rx_extra_headroom = ALIGN(fsl_fm_rx_extra_headroom, 16);
+-      }
+-
+-      return fsl_fm_rx_extra_headroom;
+-}
+-EXPORT_SYMBOL(fman_get_rx_extra_headroom);
+-
+-/**
+- * fman_bind
+- * @dev:      FMan OF device pointer
+- *
+- * Bind to a specific FMan device.
+- *
+- * Allowed only after the port was created.
+- *
+- * Return: A pointer to the FMan device
+- */
+-struct fman *fman_bind(struct device *fm_dev)
+-{
+-      return (struct fman *)(dev_get_drvdata(get_device(fm_dev)));
+-}
+-EXPORT_SYMBOL(fman_bind);
+-
+-static irqreturn_t fman_err_irq(int irq, void *handle)
+-{
+-      struct fman *fman = (struct fman *)handle;
+-      u32 pending;
+-      struct fman_fpm_regs __iomem *fpm_rg;
+-      irqreturn_t single_ret, ret = IRQ_NONE;
+-
+-      if (!is_init_done(fman->cfg))
+-              return IRQ_NONE;
+-
+-      fpm_rg = fman->fpm_regs;
+-
+-      /* error interrupts */
+-      pending = ioread32be(&fpm_rg->fm_epi);
+-      if (!pending)
+-              return IRQ_NONE;
+-
+-      if (pending & ERR_INTR_EN_BMI) {
+-              single_ret = bmi_err_event(fman);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & ERR_INTR_EN_QMI) {
+-              single_ret = qmi_err_event(fman);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & ERR_INTR_EN_FPM) {
+-              single_ret = fpm_err_event(fman);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & ERR_INTR_EN_DMA) {
+-              single_ret = dma_err_event(fman);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & ERR_INTR_EN_MURAM) {
+-              single_ret = muram_err_intr(fman);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-
+-      /* MAC error interrupts */
+-      if (pending & ERR_INTR_EN_MAC0) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_ERR_MAC0 + 0);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & ERR_INTR_EN_MAC1) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_ERR_MAC0 + 1);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & ERR_INTR_EN_MAC2) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_ERR_MAC0 + 2);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & ERR_INTR_EN_MAC3) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_ERR_MAC0 + 3);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & ERR_INTR_EN_MAC4) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_ERR_MAC0 + 4);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & ERR_INTR_EN_MAC5) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_ERR_MAC0 + 5);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & ERR_INTR_EN_MAC6) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_ERR_MAC0 + 6);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & ERR_INTR_EN_MAC7) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_ERR_MAC0 + 7);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & ERR_INTR_EN_MAC8) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_ERR_MAC0 + 8);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & ERR_INTR_EN_MAC9) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_ERR_MAC0 + 9);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-
+-      return ret;
+-}
+-
+-static irqreturn_t fman_irq(int irq, void *handle)
+-{
+-      struct fman *fman = (struct fman *)handle;
+-      u32 pending;
+-      struct fman_fpm_regs __iomem *fpm_rg;
+-      irqreturn_t single_ret, ret = IRQ_NONE;
+-
+-      if (!is_init_done(fman->cfg))
+-              return IRQ_NONE;
+-
+-      fpm_rg = fman->fpm_regs;
+-
+-      /* normal interrupts */
+-      pending = ioread32be(&fpm_rg->fm_npi);
+-      if (!pending)
+-              return IRQ_NONE;
+-
+-      if (pending & INTR_EN_QMI) {
+-              single_ret = qmi_event(fman);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-
+-      /* MAC interrupts */
+-      if (pending & INTR_EN_MAC0) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_MAC0 + 0);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & INTR_EN_MAC1) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_MAC0 + 1);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & INTR_EN_MAC2) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_MAC0 + 2);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & INTR_EN_MAC3) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_MAC0 + 3);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & INTR_EN_MAC4) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_MAC0 + 4);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & INTR_EN_MAC5) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_MAC0 + 5);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & INTR_EN_MAC6) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_MAC0 + 6);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & INTR_EN_MAC7) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_MAC0 + 7);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & INTR_EN_MAC8) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_MAC0 + 8);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-      if (pending & INTR_EN_MAC9) {
+-              single_ret = call_mac_isr(fman, FMAN_EV_MAC0 + 9);
+-              if (single_ret == IRQ_HANDLED)
+-                      ret = IRQ_HANDLED;
+-      }
+-
+-      return ret;
+-}
+-
+-static const struct of_device_id fman_muram_match[] = {
+-      {
+-              .compatible = "fsl,fman-muram"},
+-      {}
+-};
+-MODULE_DEVICE_TABLE(of, fman_muram_match);
+-
+-static struct fman *read_dts_node(struct platform_device *of_dev)
+-{
+-      struct fman *fman;
+-      struct device_node *fm_node, *muram_node;
+-      struct resource *res;
+-      u32 val, range[2];
+-      int err, irq;
+-      struct clk *clk;
+-      u32 clk_rate;
+-      phys_addr_t phys_base_addr;
+-      resource_size_t mem_size;
+-
+-      fman = kzalloc(sizeof(*fman), GFP_KERNEL);
+-      if (!fman)
+-              return NULL;
+-
+-      fm_node = of_node_get(of_dev->dev.of_node);
+-
+-      err = of_property_read_u32(fm_node, "cell-index", &val);
+-      if (err) {
+-              dev_err(&of_dev->dev, "%s: failed to read cell-index for %s\n",
+-                      __func__, fm_node->full_name);
+-              goto fman_node_put;
+-      }
+-      fman->dts_params.id = (u8)val;
+-
+-      /* Get the FM interrupt */
+-      res = platform_get_resource(of_dev, IORESOURCE_IRQ, 0);
+-      if (!res) {
+-              dev_err(&of_dev->dev, "%s: Can't get FMan IRQ resource\n",
+-                      __func__);
+-              goto fman_node_put;
+-      }
+-      irq = res->start;
+-
+-      /* Get the FM error interrupt */
+-      res = platform_get_resource(of_dev, IORESOURCE_IRQ, 1);
+-      if (!res) {
+-              dev_err(&of_dev->dev, "%s: Can't get FMan Error IRQ resource\n",
+-                      __func__);
+-              goto fman_node_put;
+-      }
+-      fman->dts_params.err_irq = res->start;
+-
+-      /* Get the FM address */
+-      res = platform_get_resource(of_dev, IORESOURCE_MEM, 0);
+-      if (!res) {
+-              dev_err(&of_dev->dev, "%s: Can't get FMan memory resource\n",
+-                      __func__);
+-              goto fman_node_put;
+-      }
+-
+-      phys_base_addr = res->start;
+-      mem_size = resource_size(res);
+-
+-      clk = of_clk_get(fm_node, 0);
+-      if (IS_ERR(clk)) {
+-              dev_err(&of_dev->dev, "%s: Failed to get FM%d clock structure\n",
+-                      __func__, fman->dts_params.id);
+-              goto fman_node_put;
+-      }
+-
+-      clk_rate = clk_get_rate(clk);
+-      if (!clk_rate) {
+-              dev_err(&of_dev->dev, "%s: Failed to determine FM%d clock rate\n",
+-                      __func__, fman->dts_params.id);
+-              goto fman_node_put;
+-      }
+-      /* Rounding to MHz */
+-      fman->dts_params.clk_freq = DIV_ROUND_UP(clk_rate, 1000000);
+-
+-      err = of_property_read_u32_array(fm_node, "fsl,qman-channel-range",
+-                                       &range[0], 2);
+-      if (err) {
+-              dev_err(&of_dev->dev, "%s: failed to read fsl,qman-channel-range for %s\n",
+-                      __func__, fm_node->full_name);
+-              goto fman_node_put;
+-      }
+-      fman->dts_params.qman_channel_base = range[0];
+-      fman->dts_params.num_of_qman_channels = range[1];
+-
+-      /* Get the MURAM base address and size */
+-      muram_node = of_find_matching_node(fm_node, fman_muram_match);
+-      if (!muram_node) {
+-              dev_err(&of_dev->dev, "%s: could not find MURAM node\n",
+-                      __func__);
+-              goto fman_node_put;
+-      }
+-
+-      err = of_address_to_resource(muram_node, 0,
+-                                   &fman->dts_params.muram_res);
+-      if (err) {
+-              of_node_put(muram_node);
+-              dev_err(&of_dev->dev, "%s: of_address_to_resource() = %d\n",
+-                      __func__, err);
+-              goto fman_node_put;
+-      }
+-
+-      of_node_put(muram_node);
+-      of_node_put(fm_node);
+-
+-      err = devm_request_irq(&of_dev->dev, irq, fman_irq, 0, "fman", fman);
+-      if (err < 0) {
+-              dev_err(&of_dev->dev, "%s: irq %d allocation failed (error = %d)\n",
+-                      __func__, irq, err);
+-              goto fman_free;
+-      }
+-
+-      if (fman->dts_params.err_irq != 0) {
+-              err = devm_request_irq(&of_dev->dev, fman->dts_params.err_irq,
+-                                     fman_err_irq, IRQF_SHARED,
+-                                     "fman-err", fman);
+-              if (err < 0) {
+-                      dev_err(&of_dev->dev, "%s: irq %d allocation failed (error = %d)\n",
+-                              __func__, fman->dts_params.err_irq, err);
+-                      goto fman_free;
+-              }
+-      }
+-
+-      fman->dts_params.res =
+-              devm_request_mem_region(&of_dev->dev, phys_base_addr,
+-                                      mem_size, "fman");
+-      if (!fman->dts_params.res) {
+-              dev_err(&of_dev->dev, "%s: request_mem_region() failed\n",
+-                      __func__);
+-              goto fman_free;
+-      }
+-
+-      fman->dts_params.base_addr =
+-              devm_ioremap(&of_dev->dev, phys_base_addr, mem_size);
+-      if (!fman->dts_params.base_addr) {
+-              dev_err(&of_dev->dev, "%s: devm_ioremap() failed\n", __func__);
+-              goto fman_free;
+-      }
+-
+-      fman->dev = &of_dev->dev;
+-
+-      return fman;
+-
+-fman_node_put:
+-      of_node_put(fm_node);
+-fman_free:
+-      kfree(fman);
+-      return NULL;
+-}
+-
+-static int fman_probe(struct platform_device *of_dev)
+-{
+-      struct fman *fman;
+-      struct device *dev;
+-      int err;
+-
+-      dev = &of_dev->dev;
+-
+-      fman = read_dts_node(of_dev);
+-      if (!fman)
+-              return -EIO;
+-
+-      err = fman_config(fman);
+-      if (err) {
+-              dev_err(dev, "%s: FMan config failed\n", __func__);
+-              return -EINVAL;
+-      }
+-
+-      if (fman_init(fman) != 0) {
+-              dev_err(dev, "%s: FMan init failed\n", __func__);
+-              return -EINVAL;
+-      }
+-
+-      if (fman->dts_params.err_irq == 0) {
+-              fman_set_exception(fman, FMAN_EX_DMA_BUS_ERROR, false);
+-              fman_set_exception(fman, FMAN_EX_DMA_READ_ECC, false);
+-              fman_set_exception(fman, FMAN_EX_DMA_SYSTEM_WRITE_ECC, false);
+-              fman_set_exception(fman, FMAN_EX_DMA_FM_WRITE_ECC, false);
+-              fman_set_exception(fman, FMAN_EX_DMA_SINGLE_PORT_ECC, false);
+-              fman_set_exception(fman, FMAN_EX_FPM_STALL_ON_TASKS, false);
+-              fman_set_exception(fman, FMAN_EX_FPM_SINGLE_ECC, false);
+-              fman_set_exception(fman, FMAN_EX_FPM_DOUBLE_ECC, false);
+-              fman_set_exception(fman, FMAN_EX_QMI_SINGLE_ECC, false);
+-              fman_set_exception(fman, FMAN_EX_QMI_DOUBLE_ECC, false);
+-              fman_set_exception(fman,
+-                                 FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID, false);
+-              fman_set_exception(fman, FMAN_EX_BMI_LIST_RAM_ECC, false);
+-              fman_set_exception(fman, FMAN_EX_BMI_STORAGE_PROFILE_ECC,
+-                                 false);
+-              fman_set_exception(fman, FMAN_EX_BMI_STATISTICS_RAM_ECC, false);
+-              fman_set_exception(fman, FMAN_EX_BMI_DISPATCH_RAM_ECC, false);
+-      }
+-
+-      dev_set_drvdata(dev, fman);
+-
+-      dev_dbg(dev, "FMan%d probed\n", fman->dts_params.id);
+-
+-      return 0;
+-}
+-
+-static const struct of_device_id fman_match[] = {
+-      {
+-              .compatible = "fsl,fman"},
+-      {}
+-};
+-
+-MODULE_DEVICE_TABLE(of, fman_match);
+-
+-static struct platform_driver fman_driver = {
+-      .driver = {
+-              .name = "fsl-fman",
+-              .of_match_table = fman_match,
+-      },
+-      .probe = fman_probe,
+-};
+-
+-static int __init fman_load(void)
+-{
+-      int err;
+-
+-      pr_debug("FSL DPAA FMan driver\n");
+-
+-      err = platform_driver_register(&fman_driver);
+-      if (err < 0)
+-              pr_err("Error, platform_driver_register() = %d\n", err);
+-
+-      return err;
+-}
+-module_init(fman_load);
+-
+-static void __exit fman_unload(void)
+-{
+-      platform_driver_unregister(&fman_driver);
+-}
+-module_exit(fman_unload);
+-
+-MODULE_LICENSE("Dual BSD/GPL");
+-MODULE_DESCRIPTION("Freescale DPAA Frame Manager driver");
+diff --git a/drivers/net/ethernet/freescale/fman/fman.h b/drivers/net/ethernet/freescale/fman/fman.h
+deleted file mode 100644
+index 57aae8d..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman.h
++++ /dev/null
+@@ -1,325 +0,0 @@
+-/*
+- * Copyright 2008-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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#ifndef __FM_H
+-#define __FM_H
+-
+-#include <linux/io.h>
+-
+-/* FM Frame descriptor macros  */
+-/* Frame queue Context Override */
+-#define FM_FD_CMD_FCO                   0x80000000
+-#define FM_FD_CMD_RPD                   0x40000000  /* Read Prepended Data */
+-#define FM_FD_CMD_DTC                   0x10000000  /* Do L4 Checksum */
+-
+-/* TX-Port: Unsupported Format */
+-#define FM_FD_ERR_UNSUPPORTED_FORMAT    0x04000000
+-/* TX Port: Length Error */
+-#define FM_FD_ERR_LENGTH                0x02000000
+-#define FM_FD_ERR_DMA                   0x01000000  /* DMA Data error */
+-
+-/* IPR frame (not error) */
+-#define FM_FD_IPR                       0x00000001
+-/* IPR non-consistent-sp */
+-#define FM_FD_ERR_IPR_NCSP              (0x00100000 | FM_FD_IPR)
+-/* IPR error */
+-#define FM_FD_ERR_IPR                   (0x00200000 | FM_FD_IPR)
+-/* IPR timeout */
+-#define FM_FD_ERR_IPR_TO                (0x00300000 | FM_FD_IPR)
+-/* TX Port: Length Error */
+-#define FM_FD_ERR_IPRE                  (FM_FD_ERR_IPR & ~FM_FD_IPR)
+-
+-/* Rx FIFO overflow, FCS error, code error, running disparity error
+- * (SGMII and TBI modes), FIFO parity error. PHY Sequence error,
+- * PHY error control character detected.
+- */
+-#define FM_FD_ERR_PHYSICAL              0x00080000
+-/* Frame too long OR Frame size exceeds max_length_frame  */
+-#define FM_FD_ERR_SIZE                  0x00040000
+-/* classification discard */
+-#define FM_FD_ERR_CLS_DISCARD           0x00020000
+-/* Extract Out of Frame */
+-#define FM_FD_ERR_EXTRACTION            0x00008000
+-/* No Scheme Selected */
+-#define FM_FD_ERR_NO_SCHEME             0x00004000
+-/* Keysize Overflow */
+-#define FM_FD_ERR_KEYSIZE_OVERFLOW      0x00002000
+-/* Frame color is red */
+-#define FM_FD_ERR_COLOR_RED             0x00000800
+-/* Frame color is yellow */
+-#define FM_FD_ERR_COLOR_YELLOW          0x00000400
+-/* Parser Time out Exceed */
+-#define FM_FD_ERR_PRS_TIMEOUT           0x00000080
+-/* Invalid Soft Parser instruction */
+-#define FM_FD_ERR_PRS_ILL_INSTRUCT      0x00000040
+-/* Header error was identified during parsing */
+-#define FM_FD_ERR_PRS_HDR_ERR           0x00000020
+-/* Frame parsed beyind 256 first bytes */
+-#define FM_FD_ERR_BLOCK_LIMIT_EXCEEDED  0x00000008
+-
+-/* non Frame-Manager error */
+-#define FM_FD_RX_STATUS_ERR_NON_FM      0x00400000
+-
+-/* FMan driver defines */
+-#define FMAN_BMI_FIFO_UNITS           0x100
+-#define OFFSET_UNITS                  16
+-
+-/* BMan defines */
+-#define BM_MAX_NUM_OF_POOLS           64 /* Buffers pools */
+-#define FMAN_PORT_MAX_EXT_POOLS_NUM   8  /* External BM pools per Rx port */
+-
+-struct fman; /* FMan data */
+-
+-/* Enum for defining port types */
+-enum fman_port_type {
+-      FMAN_PORT_TYPE_TX = 0,  /* TX Port */
+-      FMAN_PORT_TYPE_RX,      /* RX Port */
+-};
+-
+-struct fman_rev_info {
+-      u8 major;                       /* Major revision */
+-      u8 minor;                       /* Minor revision */
+-};
+-
+-enum fman_exceptions {
+-      FMAN_EX_DMA_BUS_ERROR = 0,      /* DMA bus error. */
+-      FMAN_EX_DMA_READ_ECC,           /* Read Buffer ECC error */
+-      FMAN_EX_DMA_SYSTEM_WRITE_ECC,   /* Write Buffer ECC err on sys side */
+-      FMAN_EX_DMA_FM_WRITE_ECC,       /* Write Buffer ECC error on FM side */
+-      FMAN_EX_DMA_SINGLE_PORT_ECC,    /* Single Port ECC error on FM side */
+-      FMAN_EX_FPM_STALL_ON_TASKS,     /* Stall of tasks on FPM */
+-      FMAN_EX_FPM_SINGLE_ECC,         /* Single ECC on FPM. */
+-      FMAN_EX_FPM_DOUBLE_ECC,         /* Double ECC error on FPM ram access */
+-      FMAN_EX_QMI_SINGLE_ECC, /* Single ECC on QMI. */
+-      FMAN_EX_QMI_DOUBLE_ECC, /* Double bit ECC occurred on QMI */
+-      FMAN_EX_QMI_DEQ_FROM_UNKNOWN_PORTID,/* DeQ from unknown port id */
+-      FMAN_EX_BMI_LIST_RAM_ECC,       /* Linked List RAM ECC error */
+-      FMAN_EX_BMI_STORAGE_PROFILE_ECC,/* storage profile */
+-      FMAN_EX_BMI_STATISTICS_RAM_ECC,/* Statistics RAM ECC Err Enable */
+-      FMAN_EX_BMI_DISPATCH_RAM_ECC,   /* Dispatch RAM ECC Error Enable */
+-      FMAN_EX_IRAM_ECC,               /* Double bit ECC occurred on IRAM */
+-      FMAN_EX_MURAM_ECC               /* Double bit ECC occurred on MURAM */
+-};
+-
+-/* Parse results memory layout */
+-struct fman_prs_result {
+-      u8 lpid;                /* Logical port id */
+-      u8 shimr;               /* Shim header result  */
+-      u16 l2r;                /* Layer 2 result */
+-      u16 l3r;                /* Layer 3 result */
+-      u8 l4r;         /* Layer 4 result */
+-      u8 cplan;               /* Classification plan id */
+-      u16 nxthdr;             /* Next Header  */
+-      u16 cksum;              /* Running-sum */
+-      /* Flags&fragment-offset field of the last IP-header */
+-      u16 flags_frag_off;
+-      /* Routing type field of a IPV6 routing extension header */
+-      u8 route_type;
+-      /* Routing Extension Header Present; last bit is IP valid */
+-      u8 rhp_ip_valid;
+-      u8 shim_off[2];         /* Shim offset */
+-      u8 ip_pid_off;          /* IP PID (last IP-proto) offset */
+-      u8 eth_off;             /* ETH offset */
+-      u8 llc_snap_off;        /* LLC_SNAP offset */
+-      u8 vlan_off[2];         /* VLAN offset */
+-      u8 etype_off;           /* ETYPE offset */
+-      u8 pppoe_off;           /* PPP offset */
+-      u8 mpls_off[2];         /* MPLS offset */
+-      u8 ip_off[2];           /* IP offset */
+-      u8 gre_off;             /* GRE offset */
+-      u8 l4_off;              /* Layer 4 offset */
+-      u8 nxthdr_off;          /* Parser end point */
+-};
+-
+-/* A structure for defining buffer prefix area content. */
+-struct fman_buffer_prefix_content {
+-      /* Number of bytes to be left at the beginning of the external
+-       * buffer; Note that the private-area will start from the base
+-       * of the buffer address.
+-       */
+-      u16 priv_data_size;
+-      /* true to pass the parse result to/from the FM;
+-       * User may use FM_PORT_GetBufferPrsResult() in
+-       * order to get the parser-result from a buffer.
+-       */
+-      bool pass_prs_result;
+-      /* true to pass the timeStamp to/from the FM User */
+-      bool pass_time_stamp;
+-      /* true to pass the KG hash result to/from the FM User may
+-       * use FM_PORT_GetBufferHashResult() in order to get the
+-       * parser-result from a buffer.
+-       */
+-      bool pass_hash_result;
+-      /* Add all other Internal-Context information: AD,
+-       * hash-result, key, etc.
+-       */
+-      u16 data_align;
+-};
+-
+-/* A structure of information about each of the external
+- * buffer pools used by a port or storage-profile.
+- */
+-struct fman_ext_pool_params {
+-      u8 id;              /* External buffer pool id */
+-      u16 size;                   /* External buffer pool buffer size */
+-};
+-
+-/* A structure for informing the driver about the external
+- * buffer pools allocated in the BM and used by a port or a
+- * storage-profile.
+- */
+-struct fman_ext_pools {
+-      u8 num_of_pools_used; /* Number of pools use by this port */
+-      struct fman_ext_pool_params ext_buf_pool[FMAN_PORT_MAX_EXT_POOLS_NUM];
+-                                      /* Parameters for each port */
+-};
+-
+-/* A structure for defining BM pool depletion criteria */
+-struct fman_buf_pool_depletion {
+-      /* select mode in which pause frames will be sent after a
+-       * number of pools (all together!) are depleted
+-       */
+-      bool pools_grp_mode_enable;
+-      /* the number of depleted pools that will invoke pause
+-       * frames transmission.
+-       */
+-      u8 num_of_pools;
+-      /* For each pool, true if it should be considered for
+-       * depletion (Note - this pool must be used by this port!).
+-       */
+-      bool pools_to_consider[BM_MAX_NUM_OF_POOLS];
+-      /* select mode in which pause frames will be sent
+-       * after a single-pool is depleted;
+-       */
+-      bool single_pool_mode_enable;
+-      /* For each pool, true if it should be considered
+-       * for depletion (Note - this pool must be used by this port!)
+-       */
+-      bool pools_to_consider_for_single_mode[BM_MAX_NUM_OF_POOLS];
+-};
+-
+-/* Enum for inter-module interrupts registration */
+-enum fman_event_modules {
+-      FMAN_MOD_MAC = 0,               /* MAC event */
+-      FMAN_MOD_FMAN_CTRL,     /* FMAN Controller */
+-      FMAN_MOD_DUMMY_LAST
+-};
+-
+-/* Enum for interrupts types */
+-enum fman_intr_type {
+-      FMAN_INTR_TYPE_ERR,
+-      FMAN_INTR_TYPE_NORMAL
+-};
+-
+-/* Enum for inter-module interrupts registration */
+-enum fman_inter_module_event {
+-      FMAN_EV_ERR_MAC0 = 0,   /* MAC 0 error event */
+-      FMAN_EV_ERR_MAC1,               /* MAC 1 error event */
+-      FMAN_EV_ERR_MAC2,               /* MAC 2 error event */
+-      FMAN_EV_ERR_MAC3,               /* MAC 3 error event */
+-      FMAN_EV_ERR_MAC4,               /* MAC 4 error event */
+-      FMAN_EV_ERR_MAC5,               /* MAC 5 error event */
+-      FMAN_EV_ERR_MAC6,               /* MAC 6 error event */
+-      FMAN_EV_ERR_MAC7,               /* MAC 7 error event */
+-      FMAN_EV_ERR_MAC8,               /* MAC 8 error event */
+-      FMAN_EV_ERR_MAC9,               /* MAC 9 error event */
+-      FMAN_EV_MAC0,           /* MAC 0 event (Magic packet detection) */
+-      FMAN_EV_MAC1,           /* MAC 1 event (Magic packet detection) */
+-      FMAN_EV_MAC2,           /* MAC 2 (Magic packet detection) */
+-      FMAN_EV_MAC3,           /* MAC 3 (Magic packet detection) */
+-      FMAN_EV_MAC4,           /* MAC 4 (Magic packet detection) */
+-      FMAN_EV_MAC5,           /* MAC 5 (Magic packet detection) */
+-      FMAN_EV_MAC6,           /* MAC 6 (Magic packet detection) */
+-      FMAN_EV_MAC7,           /* MAC 7 (Magic packet detection) */
+-      FMAN_EV_MAC8,           /* MAC 8 event (Magic packet detection) */
+-      FMAN_EV_MAC9,           /* MAC 9 event (Magic packet detection) */
+-      FMAN_EV_FMAN_CTRL_0,    /* Fman controller event 0 */
+-      FMAN_EV_FMAN_CTRL_1,    /* Fman controller event 1 */
+-      FMAN_EV_FMAN_CTRL_2,    /* Fman controller event 2 */
+-      FMAN_EV_FMAN_CTRL_3,    /* Fman controller event 3 */
+-      FMAN_EV_CNT
+-};
+-
+-struct fman_intr_src {
+-      void (*isr_cb)(void *src_arg);
+-      void *src_handle;
+-};
+-
+-/* Structure for port-FM communication during fman_port_init. */
+-struct fman_port_init_params {
+-      u8 port_id;                     /* port Id */
+-      enum fman_port_type port_type;  /* Port type */
+-      u16 port_speed;                 /* Port speed */
+-      u16 liodn_offset;               /* Port's requested resource */
+-      u8 num_of_tasks;                /* Port's requested resource */
+-      u8 num_of_extra_tasks;          /* Port's requested resource */
+-      u8 num_of_open_dmas;            /* Port's requested resource */
+-      u8 num_of_extra_open_dmas;      /* Port's requested resource */
+-      u32 size_of_fifo;               /* Port's requested resource */
+-      u32 extra_size_of_fifo;         /* Port's requested resource */
+-      u8 deq_pipeline_depth;          /* Port's requested resource */
+-      u16 max_frame_length;           /* Port's max frame length. */
+-      u16 liodn_base;
+-      /* LIODN base for this port, to be used together with LIODN offset. */
+-};
+-
+-void fman_get_revision(struct fman *fman, struct fman_rev_info *rev_info);
+-
+-void fman_register_intr(struct fman *fman, enum fman_event_modules mod,
+-                      u8 mod_id, enum fman_intr_type intr_type,
+-                      void (*f_isr)(void *h_src_arg), void *h_src_arg);
+-
+-void fman_unregister_intr(struct fman *fman, enum fman_event_modules mod,
+-                        u8 mod_id, enum fman_intr_type intr_type);
+-
+-int fman_set_port_params(struct fman *fman,
+-                       struct fman_port_init_params *port_params);
+-
+-int fman_reset_mac(struct fman *fman, u8 mac_id);
+-
+-u16 fman_get_clock_freq(struct fman *fman);
+-
+-u32 fman_get_bmi_max_fifo_size(struct fman *fman);
+-
+-int fman_set_mac_max_frame(struct fman *fman, u8 mac_id, u16 mfl);
+-
+-u32 fman_get_qman_channel_id(struct fman *fman, u32 port_id);
+-
+-struct resource *fman_get_mem_region(struct fman *fman);
+-
+-u16 fman_get_max_frm(void);
+-
+-int fman_get_rx_extra_headroom(void);
+-
+-struct fman *fman_bind(struct device *dev);
+-
+-#endif /* __FM_H */
+diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.c b/drivers/net/ethernet/freescale/fman/fman_dtsec.c
+deleted file mode 100644
+index c88918c..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.c
++++ /dev/null
+@@ -1,1451 +0,0 @@
+-/*
+- * Copyright 2008-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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+-
+-#include "fman_dtsec.h"
+-#include "fman.h"
+-
+-#include <linux/slab.h>
+-#include <linux/bitrev.h>
+-#include <linux/io.h>
+-#include <linux/delay.h>
+-#include <linux/phy.h>
+-#include <linux/crc32.h>
+-#include <linux/of_mdio.h>
+-#include <linux/mii.h>
+-
+-/* TBI register addresses */
+-#define MII_TBICON            0x11
+-
+-/* TBICON register bit fields */
+-#define TBICON_SOFT_RESET     0x8000  /* Soft reset */
+-#define TBICON_DISABLE_RX_DIS 0x2000  /* Disable receive disparity */
+-#define TBICON_DISABLE_TX_DIS 0x1000  /* Disable transmit disparity */
+-#define TBICON_AN_SENSE               0x0100  /* Auto-negotiation sense enable */
+-#define TBICON_CLK_SELECT     0x0020  /* Clock select */
+-#define TBICON_MI_MODE                0x0010  /* GMII mode (TBI if not set) */
+-
+-#define TBIANA_SGMII          0x4001
+-#define TBIANA_1000X          0x01a0
+-
+-/* Interrupt Mask Register (IMASK) */
+-#define DTSEC_IMASK_BREN      0x80000000
+-#define DTSEC_IMASK_RXCEN     0x40000000
+-#define DTSEC_IMASK_MSROEN    0x04000000
+-#define DTSEC_IMASK_GTSCEN    0x02000000
+-#define DTSEC_IMASK_BTEN      0x01000000
+-#define DTSEC_IMASK_TXCEN     0x00800000
+-#define DTSEC_IMASK_TXEEN     0x00400000
+-#define DTSEC_IMASK_LCEN      0x00040000
+-#define DTSEC_IMASK_CRLEN     0x00020000
+-#define DTSEC_IMASK_XFUNEN    0x00010000
+-#define DTSEC_IMASK_ABRTEN    0x00008000
+-#define DTSEC_IMASK_IFERREN   0x00004000
+-#define DTSEC_IMASK_MAGEN     0x00000800
+-#define DTSEC_IMASK_MMRDEN    0x00000400
+-#define DTSEC_IMASK_MMWREN    0x00000200
+-#define DTSEC_IMASK_GRSCEN    0x00000100
+-#define DTSEC_IMASK_TDPEEN    0x00000002
+-#define DTSEC_IMASK_RDPEEN    0x00000001
+-
+-#define DTSEC_EVENTS_MASK             \
+-       ((u32)(DTSEC_IMASK_BREN    |   \
+-              DTSEC_IMASK_RXCEN   |   \
+-              DTSEC_IMASK_BTEN    |   \
+-              DTSEC_IMASK_TXCEN   |   \
+-              DTSEC_IMASK_TXEEN   |   \
+-              DTSEC_IMASK_ABRTEN  |   \
+-              DTSEC_IMASK_LCEN    |   \
+-              DTSEC_IMASK_CRLEN   |   \
+-              DTSEC_IMASK_XFUNEN  |   \
+-              DTSEC_IMASK_IFERREN |   \
+-              DTSEC_IMASK_MAGEN   |   \
+-              DTSEC_IMASK_TDPEEN  |   \
+-              DTSEC_IMASK_RDPEEN))
+-
+-/* dtsec timestamp event bits */
+-#define TMR_PEMASK_TSREEN     0x00010000
+-#define TMR_PEVENT_TSRE               0x00010000
+-
+-/* Group address bit indication */
+-#define MAC_GROUP_ADDRESS     0x0000010000000000ULL
+-
+-/* Defaults */
+-#define DEFAULT_HALFDUP_RETRANSMIT            0xf
+-#define DEFAULT_HALFDUP_COLL_WINDOW           0x37
+-#define DEFAULT_TX_PAUSE_TIME                 0xf000
+-#define DEFAULT_RX_PREPEND                    0
+-#define DEFAULT_PREAMBLE_LEN                  7
+-#define DEFAULT_TX_PAUSE_TIME_EXTD            0
+-#define DEFAULT_NON_BACK_TO_BACK_IPG1         0x40
+-#define DEFAULT_NON_BACK_TO_BACK_IPG2         0x60
+-#define DEFAULT_MIN_IFG_ENFORCEMENT           0x50
+-#define DEFAULT_BACK_TO_BACK_IPG              0x60
+-#define DEFAULT_MAXIMUM_FRAME                 0x600
+-
+-/* register related defines (bits, field offsets..) */
+-#define DTSEC_ID2_INT_REDUCED_OFF     0x00010000
+-
+-#define DTSEC_ECNTRL_GMIIM            0x00000040
+-#define DTSEC_ECNTRL_TBIM             0x00000020
+-#define DTSEC_ECNTRL_SGMIIM           0x00000002
+-#define DTSEC_ECNTRL_RPM              0x00000010
+-#define DTSEC_ECNTRL_R100M            0x00000008
+-#define DTSEC_ECNTRL_QSGMIIM          0x00000001
+-
+-#define DTSEC_TCTRL_GTS                       0x00000020
+-
+-#define RCTRL_PAL_MASK                        0x001f0000
+-#define RCTRL_PAL_SHIFT                       16
+-#define RCTRL_GHTX                    0x00000400
+-#define RCTRL_GRS                     0x00000020
+-#define RCTRL_MPROM                   0x00000008
+-#define RCTRL_RSF                     0x00000004
+-#define RCTRL_UPROM                   0x00000001
+-
+-#define MACCFG1_SOFT_RESET            0x80000000
+-#define MACCFG1_RX_FLOW                       0x00000020
+-#define MACCFG1_TX_FLOW                       0x00000010
+-#define MACCFG1_TX_EN                 0x00000001
+-#define MACCFG1_RX_EN                 0x00000004
+-
+-#define MACCFG2_NIBBLE_MODE           0x00000100
+-#define MACCFG2_BYTE_MODE             0x00000200
+-#define MACCFG2_PAD_CRC_EN            0x00000004
+-#define MACCFG2_FULL_DUPLEX           0x00000001
+-#define MACCFG2_PREAMBLE_LENGTH_MASK  0x0000f000
+-#define MACCFG2_PREAMBLE_LENGTH_SHIFT 12
+-
+-#define IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT   24
+-#define IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT   16
+-#define IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT      8
+-
+-#define IPGIFG_NON_BACK_TO_BACK_IPG_1 0x7F000000
+-#define IPGIFG_NON_BACK_TO_BACK_IPG_2 0x007F0000
+-#define IPGIFG_MIN_IFG_ENFORCEMENT    0x0000FF00
+-#define IPGIFG_BACK_TO_BACK_IPG       0x0000007F
+-
+-#define HAFDUP_EXCESS_DEFER                   0x00010000
+-#define HAFDUP_COLLISION_WINDOW               0x000003ff
+-#define HAFDUP_RETRANSMISSION_MAX_SHIFT       12
+-#define HAFDUP_RETRANSMISSION_MAX             0x0000f000
+-
+-#define NUM_OF_HASH_REGS      8       /* Number of hash table registers */
+-
+-#define PTV_PTE_MASK          0xffff0000
+-#define PTV_PT_MASK           0x0000ffff
+-#define PTV_PTE_SHIFT         16
+-
+-#define MAX_PACKET_ALIGNMENT          31
+-#define MAX_INTER_PACKET_GAP          0x7f
+-#define MAX_RETRANSMISSION            0x0f
+-#define MAX_COLLISION_WINDOW          0x03ff
+-
+-/* Hash table size (32 bits*8 regs) */
+-#define DTSEC_HASH_TABLE_SIZE         256
+-/* Extended Hash table size (32 bits*16 regs) */
+-#define EXTENDED_HASH_TABLE_SIZE      512
+-
+-/* dTSEC Memory Map registers */
+-struct dtsec_regs {
+-      /* dTSEC General Control and Status Registers */
+-      u32 tsec_id;            /* 0x000 ETSEC_ID register */
+-      u32 tsec_id2;           /* 0x004 ETSEC_ID2 register */
+-      u32 ievent;             /* 0x008 Interrupt event register */
+-      u32 imask;              /* 0x00C Interrupt mask register */
+-      u32 reserved0010[1];
+-      u32 ecntrl;             /* 0x014 E control register */
+-      u32 ptv;                /* 0x018 Pause time value register */
+-      u32 tbipa;              /* 0x01C TBI PHY address register */
+-      u32 tmr_ctrl;           /* 0x020 Time-stamp Control register */
+-      u32 tmr_pevent;         /* 0x024 Time-stamp event register */
+-      u32 tmr_pemask;         /* 0x028 Timer event mask register */
+-      u32 reserved002c[5];
+-      u32 tctrl;              /* 0x040 Transmit control register */
+-      u32 reserved0044[3];
+-      u32 rctrl;              /* 0x050 Receive control register */
+-      u32 reserved0054[11];
+-      u32 igaddr[8];          /* 0x080-0x09C Individual/group address */
+-      u32 gaddr[8];           /* 0x0A0-0x0BC Group address registers 0-7 */
+-      u32 reserved00c0[16];
+-      u32 maccfg1;            /* 0x100 MAC configuration #1 */
+-      u32 maccfg2;            /* 0x104 MAC configuration #2 */
+-      u32 ipgifg;             /* 0x108 IPG/IFG */
+-      u32 hafdup;             /* 0x10C Half-duplex */
+-      u32 maxfrm;             /* 0x110 Maximum frame */
+-      u32 reserved0114[10];
+-      u32 ifstat;             /* 0x13C Interface status */
+-      u32 macstnaddr1;        /* 0x140 Station Address,part 1 */
+-      u32 macstnaddr2;        /* 0x144 Station Address,part 2 */
+-      struct {
+-              u32 exact_match1;       /* octets 1-4 */
+-              u32 exact_match2;       /* octets 5-6 */
+-      } macaddr[15];          /* 0x148-0x1BC mac exact match addresses 1-15 */
+-      u32 reserved01c0[16];
+-      u32 tr64;       /* 0x200 Tx and Rx 64 byte frame counter */
+-      u32 tr127;      /* 0x204 Tx and Rx 65 to 127 byte frame counter */
+-      u32 tr255;      /* 0x208 Tx and Rx 128 to 255 byte frame counter */
+-      u32 tr511;      /* 0x20C Tx and Rx 256 to 511 byte frame counter */
+-      u32 tr1k;       /* 0x210 Tx and Rx 512 to 1023 byte frame counter */
+-      u32 trmax;      /* 0x214 Tx and Rx 1024 to 1518 byte frame counter */
+-      u32 trmgv;
+-      /* 0x218 Tx and Rx 1519 to 1522 byte good VLAN frame count */
+-      u32 rbyt;       /* 0x21C receive byte counter */
+-      u32 rpkt;       /* 0x220 receive packet counter */
+-      u32 rfcs;       /* 0x224 receive FCS error counter */
+-      u32 rmca;       /* 0x228 RMCA Rx multicast packet counter */
+-      u32 rbca;       /* 0x22C Rx broadcast packet counter */
+-      u32 rxcf;       /* 0x230 Rx control frame packet counter */
+-      u32 rxpf;       /* 0x234 Rx pause frame packet counter */
+-      u32 rxuo;       /* 0x238 Rx unknown OP code counter */
+-      u32 raln;       /* 0x23C Rx alignment error counter */
+-      u32 rflr;       /* 0x240 Rx frame length error counter */
+-      u32 rcde;       /* 0x244 Rx code error counter */
+-      u32 rcse;       /* 0x248 Rx carrier sense error counter */
+-      u32 rund;       /* 0x24C Rx undersize packet counter */
+-      u32 rovr;       /* 0x250 Rx oversize packet counter */
+-      u32 rfrg;       /* 0x254 Rx fragments counter */
+-      u32 rjbr;       /* 0x258 Rx jabber counter */
+-      u32 rdrp;       /* 0x25C Rx drop */
+-      u32 tbyt;       /* 0x260 Tx byte counter */
+-      u32 tpkt;       /* 0x264 Tx packet counter */
+-      u32 tmca;       /* 0x268 Tx multicast packet counter */
+-      u32 tbca;       /* 0x26C Tx broadcast packet counter */
+-      u32 txpf;       /* 0x270 Tx pause control frame counter */
+-      u32 tdfr;       /* 0x274 Tx deferral packet counter */
+-      u32 tedf;       /* 0x278 Tx excessive deferral packet counter */
+-      u32 tscl;       /* 0x27C Tx single collision packet counter */
+-      u32 tmcl;       /* 0x280 Tx multiple collision packet counter */
+-      u32 tlcl;       /* 0x284 Tx late collision packet counter */
+-      u32 txcl;       /* 0x288 Tx excessive collision packet counter */
+-      u32 tncl;       /* 0x28C Tx total collision counter */
+-      u32 reserved0290[1];
+-      u32 tdrp;       /* 0x294 Tx drop frame counter */
+-      u32 tjbr;       /* 0x298 Tx jabber frame counter */
+-      u32 tfcs;       /* 0x29C Tx FCS error counter */
+-      u32 txcf;       /* 0x2A0 Tx control frame counter */
+-      u32 tovr;       /* 0x2A4 Tx oversize frame counter */
+-      u32 tund;       /* 0x2A8 Tx undersize frame counter */
+-      u32 tfrg;       /* 0x2AC Tx fragments frame counter */
+-      u32 car1;       /* 0x2B0 carry register one register* */
+-      u32 car2;       /* 0x2B4 carry register two register* */
+-      u32 cam1;       /* 0x2B8 carry register one mask register */
+-      u32 cam2;       /* 0x2BC carry register two mask register */
+-      u32 reserved02c0[848];
+-};
+-
+-/* struct dtsec_cfg - dTSEC configuration
+- * Transmit half-duplex flow control, under software control for 10/100-Mbps
+- * half-duplex media. If set, back pressure is applied to media by raising
+- * carrier.
+- * halfdup_retransmit:
+- * Number of retransmission attempts following a collision.
+- * If this is exceeded dTSEC aborts transmission due to excessive collisions.
+- * The standard specifies the attempt limit to be 15.
+- * halfdup_coll_window:
+- * The number of bytes of the frame during which collisions may occur.
+- * The default value of 55 corresponds to the frame byte at the end of the
+- * standard 512-bit slot time window. If collisions are detected after this
+- * byte, the late collision event is asserted and transmission of current
+- * frame is aborted.
+- * tx_pad_crc:
+- * Pad and append CRC. If set, the MAC pads all ransmitted short frames and
+- * appends a CRC to every frame regardless of padding requirement.
+- * tx_pause_time:
+- * Transmit pause time value. This pause value is used as part of the pause
+- * frame to be sent when a transmit pause frame is initiated.
+- * If set to 0 this disables transmission of pause frames.
+- * preamble_len:
+- * Length, in bytes, of the preamble field preceding each Ethernet
+- * start-of-frame delimiter byte. The default value of 0x7 should be used in
+- * order to guarantee reliable operation with IEEE 802.3 compliant hardware.
+- * rx_prepend:
+- * Packet alignment padding length. The specified number of bytes (1-31)
+- * of zero padding are inserted before the start of each received frame.
+- * For Ethernet, where optional preamble extraction is enabled, the padding
+- * appears before the preamble, otherwise the padding precedes the
+- * layer 2 header.
+- *
+- * This structure contains basic dTSEC configuration and must be passed to
+- * init() function. A default set of configuration values can be
+- * obtained by calling set_dflts().
+- */
+-struct dtsec_cfg {
+-      u16 halfdup_retransmit;
+-      u16 halfdup_coll_window;
+-      bool tx_pad_crc;
+-      u16 tx_pause_time;
+-      bool ptp_tsu_en;
+-      bool ptp_exception_en;
+-      u32 preamble_len;
+-      u32 rx_prepend;
+-      u16 tx_pause_time_extd;
+-      u16 maximum_frame;
+-      u32 non_back_to_back_ipg1;
+-      u32 non_back_to_back_ipg2;
+-      u32 min_ifg_enforcement;
+-      u32 back_to_back_ipg;
+-};
+-
+-struct fman_mac {
+-      /* pointer to dTSEC memory mapped registers */
+-      struct dtsec_regs __iomem *regs;
+-      /* MAC address of device */
+-      u64 addr;
+-      /* Ethernet physical interface */
+-      phy_interface_t phy_if;
+-      u16 max_speed;
+-      void *dev_id; /* device cookie used by the exception cbs */
+-      fman_mac_exception_cb *exception_cb;
+-      fman_mac_exception_cb *event_cb;
+-      /* Number of individual addresses in registers for this station */
+-      u8 num_of_ind_addr_in_regs;
+-      /* pointer to driver's global address hash table */
+-      struct eth_hash_t *multicast_addr_hash;
+-      /* pointer to driver's individual address hash table */
+-      struct eth_hash_t *unicast_addr_hash;
+-      u8 mac_id;
+-      u32 exceptions;
+-      bool ptp_tsu_enabled;
+-      bool en_tsu_err_exeption;
+-      struct dtsec_cfg *dtsec_drv_param;
+-      void *fm;
+-      struct fman_rev_info fm_rev_info;
+-      bool basex_if;
+-      struct phy_device *tbiphy;
+-};
+-
+-static void set_dflts(struct dtsec_cfg *cfg)
+-{
+-      cfg->halfdup_retransmit = DEFAULT_HALFDUP_RETRANSMIT;
+-      cfg->halfdup_coll_window = DEFAULT_HALFDUP_COLL_WINDOW;
+-      cfg->tx_pad_crc = true;
+-      cfg->tx_pause_time = DEFAULT_TX_PAUSE_TIME;
+-      /* PHY address 0 is reserved (DPAA RM) */
+-      cfg->rx_prepend = DEFAULT_RX_PREPEND;
+-      cfg->ptp_tsu_en = true;
+-      cfg->ptp_exception_en = true;
+-      cfg->preamble_len = DEFAULT_PREAMBLE_LEN;
+-      cfg->tx_pause_time_extd = DEFAULT_TX_PAUSE_TIME_EXTD;
+-      cfg->non_back_to_back_ipg1 = DEFAULT_NON_BACK_TO_BACK_IPG1;
+-      cfg->non_back_to_back_ipg2 = DEFAULT_NON_BACK_TO_BACK_IPG2;
+-      cfg->min_ifg_enforcement = DEFAULT_MIN_IFG_ENFORCEMENT;
+-      cfg->back_to_back_ipg = DEFAULT_BACK_TO_BACK_IPG;
+-      cfg->maximum_frame = DEFAULT_MAXIMUM_FRAME;
+-}
+-
+-static int init(struct dtsec_regs __iomem *regs, struct dtsec_cfg *cfg,
+-              phy_interface_t iface, u16 iface_speed, u8 *macaddr,
+-              u32 exception_mask, u8 tbi_addr)
+-{
+-      bool is_rgmii, is_sgmii, is_qsgmii;
+-      int i;
+-      u32 tmp;
+-
+-      /* Soft reset */
+-      iowrite32be(MACCFG1_SOFT_RESET, &regs->maccfg1);
+-      iowrite32be(0, &regs->maccfg1);
+-
+-      /* dtsec_id2 */
+-      tmp = ioread32be(&regs->tsec_id2);
+-
+-      /* check RGMII support */
+-      if (iface == PHY_INTERFACE_MODE_RGMII ||
+-          iface == PHY_INTERFACE_MODE_RMII)
+-              if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
+-                      return -EINVAL;
+-
+-      if (iface == PHY_INTERFACE_MODE_SGMII ||
+-          iface == PHY_INTERFACE_MODE_MII)
+-              if (tmp & DTSEC_ID2_INT_REDUCED_OFF)
+-                      return -EINVAL;
+-
+-      is_rgmii = iface == PHY_INTERFACE_MODE_RGMII;
+-      is_sgmii = iface == PHY_INTERFACE_MODE_SGMII;
+-      is_qsgmii = iface == PHY_INTERFACE_MODE_QSGMII;
+-
+-      tmp = 0;
+-      if (is_rgmii || iface == PHY_INTERFACE_MODE_GMII)
+-              tmp |= DTSEC_ECNTRL_GMIIM;
+-      if (is_sgmii)
+-              tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM);
+-      if (is_qsgmii)
+-              tmp |= (DTSEC_ECNTRL_SGMIIM | DTSEC_ECNTRL_TBIM |
+-                      DTSEC_ECNTRL_QSGMIIM);
+-      if (is_rgmii)
+-              tmp |= DTSEC_ECNTRL_RPM;
+-      if (iface_speed == SPEED_100)
+-              tmp |= DTSEC_ECNTRL_R100M;
+-
+-      iowrite32be(tmp, &regs->ecntrl);
+-
+-      tmp = 0;
+-
+-      if (cfg->tx_pause_time)
+-              tmp |= cfg->tx_pause_time;
+-      if (cfg->tx_pause_time_extd)
+-              tmp |= cfg->tx_pause_time_extd << PTV_PTE_SHIFT;
+-      iowrite32be(tmp, &regs->ptv);
+-
+-      tmp = 0;
+-      tmp |= (cfg->rx_prepend << RCTRL_PAL_SHIFT) & RCTRL_PAL_MASK;
+-      /* Accept short frames */
+-      tmp |= RCTRL_RSF;
+-
+-      iowrite32be(tmp, &regs->rctrl);
+-
+-      /* Assign a Phy Address to the TBI (TBIPA).
+-       * Done also in cases where TBI is not selected to avoid conflict with
+-       * the external PHY's Physical address
+-       */
+-      iowrite32be(tbi_addr, &regs->tbipa);
+-
+-      iowrite32be(0, &regs->tmr_ctrl);
+-
+-      if (cfg->ptp_tsu_en) {
+-              tmp = 0;
+-              tmp |= TMR_PEVENT_TSRE;
+-              iowrite32be(tmp, &regs->tmr_pevent);
+-
+-              if (cfg->ptp_exception_en) {
+-                      tmp = 0;
+-                      tmp |= TMR_PEMASK_TSREEN;
+-                      iowrite32be(tmp, &regs->tmr_pemask);
+-              }
+-      }
+-
+-      tmp = 0;
+-      tmp |= MACCFG1_RX_FLOW;
+-      tmp |= MACCFG1_TX_FLOW;
+-      iowrite32be(tmp, &regs->maccfg1);
+-
+-      tmp = 0;
+-
+-      if (iface_speed < SPEED_1000)
+-              tmp |= MACCFG2_NIBBLE_MODE;
+-      else if (iface_speed == SPEED_1000)
+-              tmp |= MACCFG2_BYTE_MODE;
+-
+-      tmp |= (cfg->preamble_len << MACCFG2_PREAMBLE_LENGTH_SHIFT) &
+-              MACCFG2_PREAMBLE_LENGTH_MASK;
+-      if (cfg->tx_pad_crc)
+-              tmp |= MACCFG2_PAD_CRC_EN;
+-      /* Full Duplex */
+-      tmp |= MACCFG2_FULL_DUPLEX;
+-      iowrite32be(tmp, &regs->maccfg2);
+-
+-      tmp = (((cfg->non_back_to_back_ipg1 <<
+-               IPGIFG_NON_BACK_TO_BACK_IPG_1_SHIFT)
+-              & IPGIFG_NON_BACK_TO_BACK_IPG_1)
+-             | ((cfg->non_back_to_back_ipg2 <<
+-                 IPGIFG_NON_BACK_TO_BACK_IPG_2_SHIFT)
+-               & IPGIFG_NON_BACK_TO_BACK_IPG_2)
+-             | ((cfg->min_ifg_enforcement << IPGIFG_MIN_IFG_ENFORCEMENT_SHIFT)
+-               & IPGIFG_MIN_IFG_ENFORCEMENT)
+-             | (cfg->back_to_back_ipg & IPGIFG_BACK_TO_BACK_IPG));
+-      iowrite32be(tmp, &regs->ipgifg);
+-
+-      tmp = 0;
+-      tmp |= HAFDUP_EXCESS_DEFER;
+-      tmp |= ((cfg->halfdup_retransmit << HAFDUP_RETRANSMISSION_MAX_SHIFT)
+-              & HAFDUP_RETRANSMISSION_MAX);
+-      tmp |= (cfg->halfdup_coll_window & HAFDUP_COLLISION_WINDOW);
+-
+-      iowrite32be(tmp, &regs->hafdup);
+-
+-      /* Initialize Maximum frame length */
+-      iowrite32be(cfg->maximum_frame, &regs->maxfrm);
+-
+-      iowrite32be(0xffffffff, &regs->cam1);
+-      iowrite32be(0xffffffff, &regs->cam2);
+-
+-      iowrite32be(exception_mask, &regs->imask);
+-
+-      iowrite32be(0xffffffff, &regs->ievent);
+-
+-      tmp = (u32)((macaddr[5] << 24) |
+-                  (macaddr[4] << 16) | (macaddr[3] << 8) | macaddr[2]);
+-      iowrite32be(tmp, &regs->macstnaddr1);
+-
+-      tmp = (u32)((macaddr[1] << 24) | (macaddr[0] << 16));
+-      iowrite32be(tmp, &regs->macstnaddr2);
+-
+-      /* HASH */
+-      for (i = 0; i < NUM_OF_HASH_REGS; i++) {
+-              /* Initialize IADDRx */
+-              iowrite32be(0, &regs->igaddr[i]);
+-              /* Initialize GADDRx */
+-              iowrite32be(0, &regs->gaddr[i]);
+-      }
+-
+-      return 0;
+-}
+-
+-static void set_mac_address(struct dtsec_regs __iomem *regs, u8 *adr)
+-{
+-      u32 tmp;
+-
+-      tmp = (u32)((adr[5] << 24) |
+-                  (adr[4] << 16) | (adr[3] << 8) | adr[2]);
+-      iowrite32be(tmp, &regs->macstnaddr1);
+-
+-      tmp = (u32)((adr[1] << 24) | (adr[0] << 16));
+-      iowrite32be(tmp, &regs->macstnaddr2);
+-}
+-
+-static void set_bucket(struct dtsec_regs __iomem *regs, int bucket,
+-                     bool enable)
+-{
+-      int reg_idx = (bucket >> 5) & 0xf;
+-      int bit_idx = bucket & 0x1f;
+-      u32 bit_mask = 0x80000000 >> bit_idx;
+-      u32 __iomem *reg;
+-
+-      if (reg_idx > 7)
+-              reg = &regs->gaddr[reg_idx - 8];
+-      else
+-              reg = &regs->igaddr[reg_idx];
+-
+-      if (enable)
+-              iowrite32be(ioread32be(reg) | bit_mask, reg);
+-      else
+-              iowrite32be(ioread32be(reg) & (~bit_mask), reg);
+-}
+-
+-static int check_init_parameters(struct fman_mac *dtsec)
+-{
+-      if (dtsec->max_speed >= SPEED_10000) {
+-              pr_err("1G MAC driver supports 1G or lower speeds\n");
+-              return -EINVAL;
+-      }
+-      if (dtsec->addr == 0) {
+-              pr_err("Ethernet MAC Must have a valid MAC Address\n");
+-              return -EINVAL;
+-      }
+-      if ((dtsec->dtsec_drv_param)->rx_prepend >
+-          MAX_PACKET_ALIGNMENT) {
+-              pr_err("packetAlignmentPadding can't be > than %d\n",
+-                     MAX_PACKET_ALIGNMENT);
+-              return -EINVAL;
+-      }
+-      if (((dtsec->dtsec_drv_param)->non_back_to_back_ipg1 >
+-           MAX_INTER_PACKET_GAP) ||
+-          ((dtsec->dtsec_drv_param)->non_back_to_back_ipg2 >
+-           MAX_INTER_PACKET_GAP) ||
+-           ((dtsec->dtsec_drv_param)->back_to_back_ipg >
+-            MAX_INTER_PACKET_GAP)) {
+-              pr_err("Inter packet gap can't be greater than %d\n",
+-                     MAX_INTER_PACKET_GAP);
+-              return -EINVAL;
+-      }
+-      if ((dtsec->dtsec_drv_param)->halfdup_retransmit >
+-          MAX_RETRANSMISSION) {
+-              pr_err("maxRetransmission can't be greater than %d\n",
+-                     MAX_RETRANSMISSION);
+-              return -EINVAL;
+-      }
+-      if ((dtsec->dtsec_drv_param)->halfdup_coll_window >
+-          MAX_COLLISION_WINDOW) {
+-              pr_err("collisionWindow can't be greater than %d\n",
+-                     MAX_COLLISION_WINDOW);
+-              return -EINVAL;
+-      /* If Auto negotiation process is disabled, need to set up the PHY
+-       * using the MII Management Interface
+-       */
+-      }
+-      if (!dtsec->exception_cb) {
+-              pr_err("uninitialized exception_cb\n");
+-              return -EINVAL;
+-      }
+-      if (!dtsec->event_cb) {
+-              pr_err("uninitialized event_cb\n");
+-              return -EINVAL;
+-      }
+-
+-      return 0;
+-}
+-
+-static int get_exception_flag(enum fman_mac_exceptions exception)
+-{
+-      u32 bit_mask;
+-
+-      switch (exception) {
+-      case FM_MAC_EX_1G_BAB_RX:
+-              bit_mask = DTSEC_IMASK_BREN;
+-              break;
+-      case FM_MAC_EX_1G_RX_CTL:
+-              bit_mask = DTSEC_IMASK_RXCEN;
+-              break;
+-      case FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET:
+-              bit_mask = DTSEC_IMASK_GTSCEN;
+-              break;
+-      case FM_MAC_EX_1G_BAB_TX:
+-              bit_mask = DTSEC_IMASK_BTEN;
+-              break;
+-      case FM_MAC_EX_1G_TX_CTL:
+-              bit_mask = DTSEC_IMASK_TXCEN;
+-              break;
+-      case FM_MAC_EX_1G_TX_ERR:
+-              bit_mask = DTSEC_IMASK_TXEEN;
+-              break;
+-      case FM_MAC_EX_1G_LATE_COL:
+-              bit_mask = DTSEC_IMASK_LCEN;
+-              break;
+-      case FM_MAC_EX_1G_COL_RET_LMT:
+-              bit_mask = DTSEC_IMASK_CRLEN;
+-              break;
+-      case FM_MAC_EX_1G_TX_FIFO_UNDRN:
+-              bit_mask = DTSEC_IMASK_XFUNEN;
+-              break;
+-      case FM_MAC_EX_1G_MAG_PCKT:
+-              bit_mask = DTSEC_IMASK_MAGEN;
+-              break;
+-      case FM_MAC_EX_1G_MII_MNG_RD_COMPLET:
+-              bit_mask = DTSEC_IMASK_MMRDEN;
+-              break;
+-      case FM_MAC_EX_1G_MII_MNG_WR_COMPLET:
+-              bit_mask = DTSEC_IMASK_MMWREN;
+-              break;
+-      case FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET:
+-              bit_mask = DTSEC_IMASK_GRSCEN;
+-              break;
+-      case FM_MAC_EX_1G_DATA_ERR:
+-              bit_mask = DTSEC_IMASK_TDPEEN;
+-              break;
+-      case FM_MAC_EX_1G_RX_MIB_CNT_OVFL:
+-              bit_mask = DTSEC_IMASK_MSROEN;
+-              break;
+-      default:
+-              bit_mask = 0;
+-              break;
+-      }
+-
+-      return bit_mask;
+-}
+-
+-static bool is_init_done(struct dtsec_cfg *dtsec_drv_params)
+-{
+-      /* Checks if dTSEC driver parameters were initialized */
+-      if (!dtsec_drv_params)
+-              return true;
+-
+-      return false;
+-}
+-
+-static u16 dtsec_get_max_frame_length(struct fman_mac *dtsec)
+-{
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-
+-      if (is_init_done(dtsec->dtsec_drv_param))
+-              return 0;
+-
+-      return (u16)ioread32be(&regs->maxfrm);
+-}
+-
+-static void dtsec_isr(void *handle)
+-{
+-      struct fman_mac *dtsec = (struct fman_mac *)handle;
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      u32 event;
+-
+-      /* do not handle MDIO events */
+-      event = ioread32be(&regs->ievent) &
+-              (u32)(~(DTSEC_IMASK_MMRDEN | DTSEC_IMASK_MMWREN));
+-
+-      event &= ioread32be(&regs->imask);
+-
+-      iowrite32be(event, &regs->ievent);
+-
+-      if (event & DTSEC_IMASK_BREN)
+-              dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_BAB_RX);
+-      if (event & DTSEC_IMASK_RXCEN)
+-              dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_RX_CTL);
+-      if (event & DTSEC_IMASK_GTSCEN)
+-              dtsec->exception_cb(dtsec->dev_id,
+-                                  FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET);
+-      if (event & DTSEC_IMASK_BTEN)
+-              dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_BAB_TX);
+-      if (event & DTSEC_IMASK_TXCEN)
+-              dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_TX_CTL);
+-      if (event & DTSEC_IMASK_TXEEN)
+-              dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_TX_ERR);
+-      if (event & DTSEC_IMASK_LCEN)
+-              dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_LATE_COL);
+-      if (event & DTSEC_IMASK_CRLEN)
+-              dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_COL_RET_LMT);
+-      if (event & DTSEC_IMASK_XFUNEN) {
+-              /* FM_TX_LOCKUP_ERRATA_DTSEC6 Errata workaround */
+-              if (dtsec->fm_rev_info.major == 2) {
+-                      u32 tpkt1, tmp_reg1, tpkt2, tmp_reg2, i;
+-                      /* a. Write 0x00E0_0C00 to DTSEC_ID
+-                       *      This is a read only register
+-                       * b. Read and save the value of TPKT
+-                       */
+-                      tpkt1 = ioread32be(&regs->tpkt);
+-
+-                      /* c. Read the register at dTSEC address offset 0x32C */
+-                      tmp_reg1 = ioread32be(&regs->reserved02c0[27]);
+-
+-                      /* d. Compare bits [9:15] to bits [25:31] of the
+-                       * register at address offset 0x32C.
+-                       */
+-                      if ((tmp_reg1 & 0x007F0000) !=
+-                              (tmp_reg1 & 0x0000007F)) {
+-                              /* If they are not equal, save the value of
+-                               * this register and wait for at least
+-                               * MAXFRM*16 ns
+-                               */
+-                              usleep_range((u32)(min
+-                                      (dtsec_get_max_frame_length(dtsec) *
+-                                      16 / 1000, 1)), (u32)
+-                                      (min(dtsec_get_max_frame_length
+-                                      (dtsec) * 16 / 1000, 1) + 1));
+-                      }
+-
+-                      /* e. Read and save TPKT again and read the register
+-                       * at dTSEC address offset 0x32C again
+-                       */
+-                      tpkt2 = ioread32be(&regs->tpkt);
+-                      tmp_reg2 = ioread32be(&regs->reserved02c0[27]);
+-
+-                      /* f. Compare the value of TPKT saved in step b to
+-                       * value read in step e. Also compare bits [9:15] of
+-                       * the register at offset 0x32C saved in step d to the
+-                       * value of bits [9:15] saved in step e. If the two
+-                       * registers values are unchanged, then the transmit
+-                       * portion of the dTSEC controller is locked up and
+-                       * the user should proceed to the recover sequence.
+-                       */
+-                      if ((tpkt1 == tpkt2) && ((tmp_reg1 & 0x007F0000) ==
+-                              (tmp_reg2 & 0x007F0000))) {
+-                              /* recover sequence */
+-
+-                              /* a.Write a 1 to RCTRL[GRS] */
+-
+-                              iowrite32be(ioread32be(&regs->rctrl) |
+-                                          RCTRL_GRS, &regs->rctrl);
+-
+-                              /* b.Wait until IEVENT[GRSC]=1, or at least
+-                               * 100 us has elapsed.
+-                               */
+-                              for (i = 0; i < 100; i++) {
+-                                      if (ioread32be(&regs->ievent) &
+-                                          DTSEC_IMASK_GRSCEN)
+-                                              break;
+-                                      udelay(1);
+-                              }
+-                              if (ioread32be(&regs->ievent) &
+-                                  DTSEC_IMASK_GRSCEN)
+-                                      iowrite32be(DTSEC_IMASK_GRSCEN,
+-                                                  &regs->ievent);
+-                              else
+-                                      pr_debug("Rx lockup due to Tx lockup\n");
+-
+-                              /* c.Write a 1 to bit n of FM_RSTC
+-                               * (offset 0x0CC of FPM)
+-                               */
+-                              fman_reset_mac(dtsec->fm, dtsec->mac_id);
+-
+-                              /* d.Wait 4 Tx clocks (32 ns) */
+-                              udelay(1);
+-
+-                              /* e.Write a 0 to bit n of FM_RSTC. */
+-                              /* cleared by FMAN
+-                               */
+-                      }
+-              }
+-
+-              dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_TX_FIFO_UNDRN);
+-      }
+-      if (event & DTSEC_IMASK_MAGEN)
+-              dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_MAG_PCKT);
+-      if (event & DTSEC_IMASK_GRSCEN)
+-              dtsec->exception_cb(dtsec->dev_id,
+-                                  FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET);
+-      if (event & DTSEC_IMASK_TDPEEN)
+-              dtsec->exception_cb(dtsec->dev_id, FM_MAC_EX_1G_DATA_ERR);
+-      if (event & DTSEC_IMASK_RDPEEN)
+-              dtsec->exception_cb(dtsec->dev_id, FM_MAC_1G_RX_DATA_ERR);
+-
+-      /* masked interrupts */
+-      WARN_ON(event & DTSEC_IMASK_ABRTEN);
+-      WARN_ON(event & DTSEC_IMASK_IFERREN);
+-}
+-
+-static void dtsec_1588_isr(void *handle)
+-{
+-      struct fman_mac *dtsec = (struct fman_mac *)handle;
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      u32 event;
+-
+-      if (dtsec->ptp_tsu_enabled) {
+-              event = ioread32be(&regs->tmr_pevent);
+-              event &= ioread32be(&regs->tmr_pemask);
+-
+-              if (event) {
+-                      iowrite32be(event, &regs->tmr_pevent);
+-                      WARN_ON(event & TMR_PEVENT_TSRE);
+-                      dtsec->exception_cb(dtsec->dev_id,
+-                                          FM_MAC_EX_1G_1588_TS_RX_ERR);
+-              }
+-      }
+-}
+-
+-static void free_init_resources(struct fman_mac *dtsec)
+-{
+-      fman_unregister_intr(dtsec->fm, FMAN_MOD_MAC, dtsec->mac_id,
+-                           FMAN_INTR_TYPE_ERR);
+-      fman_unregister_intr(dtsec->fm, FMAN_MOD_MAC, dtsec->mac_id,
+-                           FMAN_INTR_TYPE_NORMAL);
+-
+-      /* release the driver's group hash table */
+-      free_hash_table(dtsec->multicast_addr_hash);
+-      dtsec->multicast_addr_hash = NULL;
+-
+-      /* release the driver's individual hash table */
+-      free_hash_table(dtsec->unicast_addr_hash);
+-      dtsec->unicast_addr_hash = NULL;
+-}
+-
+-int dtsec_cfg_max_frame_len(struct fman_mac *dtsec, u16 new_val)
+-{
+-      if (is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      dtsec->dtsec_drv_param->maximum_frame = new_val;
+-
+-      return 0;
+-}
+-
+-int dtsec_cfg_pad_and_crc(struct fman_mac *dtsec, bool new_val)
+-{
+-      if (is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      dtsec->dtsec_drv_param->tx_pad_crc = new_val;
+-
+-      return 0;
+-}
+-
+-int dtsec_enable(struct fman_mac *dtsec, enum comm_mode mode)
+-{
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      /* Enable */
+-      tmp = ioread32be(&regs->maccfg1);
+-      if (mode & COMM_MODE_RX)
+-              tmp |= MACCFG1_RX_EN;
+-      if (mode & COMM_MODE_TX)
+-              tmp |= MACCFG1_TX_EN;
+-
+-      iowrite32be(tmp, &regs->maccfg1);
+-
+-      /* Graceful start - clear the graceful receive stop bit */
+-      if (mode & COMM_MODE_TX)
+-              iowrite32be(ioread32be(&regs->tctrl) & ~DTSEC_TCTRL_GTS,
+-                          &regs->tctrl);
+-      if (mode & COMM_MODE_RX)
+-              iowrite32be(ioread32be(&regs->rctrl) & ~RCTRL_GRS,
+-                          &regs->rctrl);
+-
+-      return 0;
+-}
+-
+-int dtsec_disable(struct fman_mac *dtsec, enum comm_mode mode)
+-{
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      /* Gracefull stop - Assert the graceful transmit stop bit */
+-      if (mode & COMM_MODE_RX) {
+-              tmp = ioread32be(&regs->rctrl) | RCTRL_GRS;
+-              iowrite32be(tmp, &regs->rctrl);
+-
+-              if (dtsec->fm_rev_info.major == 2)
+-                      usleep_range(100, 200);
+-              else
+-                      udelay(10);
+-      }
+-
+-      if (mode & COMM_MODE_TX) {
+-              if (dtsec->fm_rev_info.major == 2)
+-                      pr_debug("GTS not supported due to DTSEC_A004 errata.\n");
+-              else
+-                      pr_debug("GTS not supported due to DTSEC_A0014 errata.\n");
+-      }
+-
+-      tmp = ioread32be(&regs->maccfg1);
+-      if (mode & COMM_MODE_RX)
+-              tmp &= ~MACCFG1_RX_EN;
+-      if (mode & COMM_MODE_TX)
+-              tmp &= ~MACCFG1_TX_EN;
+-
+-      iowrite32be(tmp, &regs->maccfg1);
+-
+-      return 0;
+-}
+-
+-int dtsec_set_tx_pause_frames(struct fman_mac *dtsec,
+-                            u8 __maybe_unused priority,
+-                            u16 pause_time, u16 __maybe_unused thresh_time)
+-{
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      u32 ptv = 0;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      if (pause_time) {
+-              /* FM_BAD_TX_TS_IN_B_2_B_ERRATA_DTSEC_A003 Errata workaround */
+-              if (dtsec->fm_rev_info.major == 2 && pause_time <= 320) {
+-                      pr_warn("pause-time: %d illegal.Should be > 320\n",
+-                              pause_time);
+-                      return -EINVAL;
+-              }
+-
+-              ptv = ioread32be(&regs->ptv);
+-              ptv &= PTV_PTE_MASK;
+-              ptv |= pause_time & PTV_PT_MASK;
+-              iowrite32be(ptv, &regs->ptv);
+-
+-              /* trigger the transmission of a flow-control pause frame */
+-              iowrite32be(ioread32be(&regs->maccfg1) | MACCFG1_TX_FLOW,
+-                          &regs->maccfg1);
+-      } else
+-              iowrite32be(ioread32be(&regs->maccfg1) & ~MACCFG1_TX_FLOW,
+-                          &regs->maccfg1);
+-
+-      return 0;
+-}
+-
+-int dtsec_accept_rx_pause_frames(struct fman_mac *dtsec, bool en)
+-{
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->maccfg1);
+-      if (en)
+-              tmp |= MACCFG1_RX_FLOW;
+-      else
+-              tmp &= ~MACCFG1_RX_FLOW;
+-      iowrite32be(tmp, &regs->maccfg1);
+-
+-      return 0;
+-}
+-
+-int dtsec_modify_mac_address(struct fman_mac *dtsec, enet_addr_t *enet_addr)
+-{
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      /* Initialize MAC Station Address registers (1 & 2)
+-       * Station address have to be swapped (big endian to little endian
+-       */
+-      dtsec->addr = ENET_ADDR_TO_UINT64(*enet_addr);
+-      set_mac_address(dtsec->regs, (u8 *)(*enet_addr));
+-
+-      return 0;
+-}
+-
+-int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
+-{
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      struct eth_hash_entry *hash_entry;
+-      u64 addr;
+-      s32 bucket;
+-      u32 crc = 0xFFFFFFFF;
+-      bool mcast, ghtx;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      addr = ENET_ADDR_TO_UINT64(*eth_addr);
+-
+-      ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? true : false);
+-      mcast = (bool)((addr & MAC_GROUP_ADDRESS) ? true : false);
+-
+-      /* Cannot handle unicast mac addr when GHTX is on */
+-      if (ghtx && !mcast) {
+-              pr_err("Could not compute hash bucket\n");
+-              return -EINVAL;
+-      }
+-      crc = crc32_le(crc, (u8 *)eth_addr, ETH_ALEN);
+-      crc = bitrev32(crc);
+-
+-      /* considering the 9 highest order bits in crc H[8:0]:
+-       *if ghtx = 0 H[8:6] (highest order 3 bits) identify the hash register
+-       *and H[5:1] (next 5 bits) identify the hash bit
+-       *if ghts = 1 H[8:5] (highest order 4 bits) identify the hash register
+-       *and H[4:0] (next 5 bits) identify the hash bit.
+-       *
+-       *In bucket index output the low 5 bits identify the hash register
+-       *bit, while the higher 4 bits identify the hash register
+-       */
+-
+-      if (ghtx) {
+-              bucket = (s32)((crc >> 23) & 0x1ff);
+-      } else {
+-              bucket = (s32)((crc >> 24) & 0xff);
+-              /* if !ghtx and mcast the bit must be set in gaddr instead of
+-               *igaddr.
+-               */
+-              if (mcast)
+-                      bucket += 0x100;
+-      }
+-
+-      set_bucket(dtsec->regs, bucket, true);
+-
+-      /* Create element to be added to the driver hash table */
+-      hash_entry = kmalloc(sizeof(*hash_entry), GFP_KERNEL);
+-      if (!hash_entry)
+-              return -ENOMEM;
+-      hash_entry->addr = addr;
+-      INIT_LIST_HEAD(&hash_entry->node);
+-
+-      if (addr & MAC_GROUP_ADDRESS)
+-              /* Group Address */
+-              list_add_tail(&hash_entry->node,
+-                            &dtsec->multicast_addr_hash->lsts[bucket]);
+-      else
+-              list_add_tail(&hash_entry->node,
+-                            &dtsec->unicast_addr_hash->lsts[bucket]);
+-
+-      return 0;
+-}
+-
+-int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr)
+-{
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      struct list_head *pos;
+-      struct eth_hash_entry *hash_entry = NULL;
+-      u64 addr;
+-      s32 bucket;
+-      u32 crc = 0xFFFFFFFF;
+-      bool mcast, ghtx;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      addr = ENET_ADDR_TO_UINT64(*eth_addr);
+-
+-      ghtx = (bool)((ioread32be(&regs->rctrl) & RCTRL_GHTX) ? true : false);
+-      mcast = (bool)((addr & MAC_GROUP_ADDRESS) ? true : false);
+-
+-      /* Cannot handle unicast mac addr when GHTX is on */
+-      if (ghtx && !mcast) {
+-              pr_err("Could not compute hash bucket\n");
+-              return -EINVAL;
+-      }
+-      crc = crc32_le(crc, (u8 *)eth_addr, ETH_ALEN);
+-      crc = bitrev32(crc);
+-
+-      if (ghtx) {
+-              bucket = (s32)((crc >> 23) & 0x1ff);
+-      } else {
+-              bucket = (s32)((crc >> 24) & 0xff);
+-              /* if !ghtx and mcast the bit must be set
+-               * in gaddr instead of igaddr.
+-               */
+-              if (mcast)
+-                      bucket += 0x100;
+-      }
+-
+-      if (addr & MAC_GROUP_ADDRESS) {
+-              /* Group Address */
+-              list_for_each(pos,
+-                            &dtsec->multicast_addr_hash->lsts[bucket]) {
+-                      hash_entry = ETH_HASH_ENTRY_OBJ(pos);
+-                      if (hash_entry->addr == addr) {
+-                              list_del_init(&hash_entry->node);
+-                              kfree(hash_entry);
+-                              break;
+-                      }
+-              }
+-              if (list_empty(&dtsec->multicast_addr_hash->lsts[bucket]))
+-                      set_bucket(dtsec->regs, bucket, false);
+-      } else {
+-              /* Individual Address */
+-              list_for_each(pos,
+-                            &dtsec->unicast_addr_hash->lsts[bucket]) {
+-                      hash_entry = ETH_HASH_ENTRY_OBJ(pos);
+-                      if (hash_entry->addr == addr) {
+-                              list_del_init(&hash_entry->node);
+-                              kfree(hash_entry);
+-                              break;
+-                      }
+-              }
+-              if (list_empty(&dtsec->unicast_addr_hash->lsts[bucket]))
+-                      set_bucket(dtsec->regs, bucket, false);
+-      }
+-
+-      /* address does not exist */
+-      WARN_ON(!hash_entry);
+-
+-      return 0;
+-}
+-
+-int dtsec_set_promiscuous(struct fman_mac *dtsec, bool new_val)
+-{
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      /* Set unicast promiscuous */
+-      tmp = ioread32be(&regs->rctrl);
+-      if (new_val)
+-              tmp |= RCTRL_UPROM;
+-      else
+-              tmp &= ~RCTRL_UPROM;
+-
+-      iowrite32be(tmp, &regs->rctrl);
+-
+-      /* Set multicast promiscuous */
+-      tmp = ioread32be(&regs->rctrl);
+-      if (new_val)
+-              tmp |= RCTRL_MPROM;
+-      else
+-              tmp &= ~RCTRL_MPROM;
+-
+-      iowrite32be(tmp, &regs->rctrl);
+-
+-      return 0;
+-}
+-
+-int dtsec_adjust_link(struct fman_mac *dtsec, u16 speed)
+-{
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->maccfg2);
+-
+-      /* Full Duplex */
+-      tmp |= MACCFG2_FULL_DUPLEX;
+-
+-      tmp &= ~(MACCFG2_NIBBLE_MODE | MACCFG2_BYTE_MODE);
+-      if (speed < SPEED_1000)
+-              tmp |= MACCFG2_NIBBLE_MODE;
+-      else if (speed == SPEED_1000)
+-              tmp |= MACCFG2_BYTE_MODE;
+-      iowrite32be(tmp, &regs->maccfg2);
+-
+-      tmp = ioread32be(&regs->ecntrl);
+-      if (speed == SPEED_100)
+-              tmp |= DTSEC_ECNTRL_R100M;
+-      else
+-              tmp &= ~DTSEC_ECNTRL_R100M;
+-      iowrite32be(tmp, &regs->ecntrl);
+-
+-      return 0;
+-}
+-
+-int dtsec_restart_autoneg(struct fman_mac *dtsec)
+-{
+-      u16 tmp_reg16;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      tmp_reg16 = phy_read(dtsec->tbiphy, MII_BMCR);
+-
+-      tmp_reg16 &= ~(BMCR_SPEED100 | BMCR_SPEED1000);
+-      tmp_reg16 |= (BMCR_ANENABLE | BMCR_ANRESTART |
+-                    BMCR_FULLDPLX | BMCR_SPEED1000);
+-
+-      phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16);
+-
+-      return 0;
+-}
+-
+-int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version)
+-{
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      *mac_version = ioread32be(&regs->tsec_id);
+-
+-      return 0;
+-}
+-
+-int dtsec_set_exception(struct fman_mac *dtsec,
+-                      enum fman_mac_exceptions exception, bool enable)
+-{
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      u32 bit_mask = 0;
+-
+-      if (!is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      if (exception != FM_MAC_EX_1G_1588_TS_RX_ERR) {
+-              bit_mask = get_exception_flag(exception);
+-              if (bit_mask) {
+-                      if (enable)
+-                              dtsec->exceptions |= bit_mask;
+-                      else
+-                              dtsec->exceptions &= ~bit_mask;
+-              } else {
+-                      pr_err("Undefined exception\n");
+-                      return -EINVAL;
+-              }
+-              if (enable)
+-                      iowrite32be(ioread32be(&regs->imask) | bit_mask,
+-                                  &regs->imask);
+-              else
+-                      iowrite32be(ioread32be(&regs->imask) & ~bit_mask,
+-                                  &regs->imask);
+-      } else {
+-              if (!dtsec->ptp_tsu_enabled) {
+-                      pr_err("Exception valid for 1588 only\n");
+-                      return -EINVAL;
+-              }
+-              switch (exception) {
+-              case FM_MAC_EX_1G_1588_TS_RX_ERR:
+-                      if (enable) {
+-                              dtsec->en_tsu_err_exeption = true;
+-                              iowrite32be(ioread32be(&regs->tmr_pemask) |
+-                                          TMR_PEMASK_TSREEN,
+-                                          &regs->tmr_pemask);
+-                      } else {
+-                              dtsec->en_tsu_err_exeption = false;
+-                              iowrite32be(ioread32be(&regs->tmr_pemask) &
+-                                          ~TMR_PEMASK_TSREEN,
+-                                          &regs->tmr_pemask);
+-                      }
+-                      break;
+-              default:
+-                      pr_err("Undefined exception\n");
+-                      return -EINVAL;
+-              }
+-      }
+-
+-      return 0;
+-}
+-
+-int dtsec_init(struct fman_mac *dtsec)
+-{
+-      struct dtsec_regs __iomem *regs = dtsec->regs;
+-      struct dtsec_cfg *dtsec_drv_param;
+-      int err;
+-      u16 max_frm_ln;
+-      enet_addr_t eth_addr;
+-
+-      if (is_init_done(dtsec->dtsec_drv_param))
+-              return -EINVAL;
+-
+-      if (DEFAULT_RESET_ON_INIT &&
+-          (fman_reset_mac(dtsec->fm, dtsec->mac_id) != 0)) {
+-              pr_err("Can't reset MAC!\n");
+-              return -EINVAL;
+-      }
+-
+-      err = check_init_parameters(dtsec);
+-      if (err)
+-              return err;
+-
+-      dtsec_drv_param = dtsec->dtsec_drv_param;
+-
+-      MAKE_ENET_ADDR_FROM_UINT64(dtsec->addr, eth_addr);
+-
+-      err = init(dtsec->regs, dtsec_drv_param, dtsec->phy_if,
+-                 dtsec->max_speed, (u8 *)eth_addr, dtsec->exceptions,
+-                 dtsec->tbiphy->mdio.addr);
+-      if (err) {
+-              free_init_resources(dtsec);
+-              pr_err("DTSEC version doesn't support this i/f mode\n");
+-              return err;
+-      }
+-
+-      if (dtsec->phy_if == PHY_INTERFACE_MODE_SGMII) {
+-              u16 tmp_reg16;
+-
+-              /* Configure the TBI PHY Control Register */
+-              tmp_reg16 = TBICON_CLK_SELECT | TBICON_SOFT_RESET;
+-              phy_write(dtsec->tbiphy, MII_TBICON, tmp_reg16);
+-
+-              tmp_reg16 = TBICON_CLK_SELECT;
+-              phy_write(dtsec->tbiphy, MII_TBICON, tmp_reg16);
+-
+-              tmp_reg16 = (BMCR_RESET | BMCR_ANENABLE |
+-                           BMCR_FULLDPLX | BMCR_SPEED1000);
+-              phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16);
+-
+-              if (dtsec->basex_if)
+-                      tmp_reg16 = TBIANA_1000X;
+-              else
+-                      tmp_reg16 = TBIANA_SGMII;
+-              phy_write(dtsec->tbiphy, MII_ADVERTISE, tmp_reg16);
+-
+-              tmp_reg16 = (BMCR_ANENABLE | BMCR_ANRESTART |
+-                           BMCR_FULLDPLX | BMCR_SPEED1000);
+-
+-              phy_write(dtsec->tbiphy, MII_BMCR, tmp_reg16);
+-      }
+-
+-      /* Max Frame Length */
+-      max_frm_ln = (u16)ioread32be(&regs->maxfrm);
+-      err = fman_set_mac_max_frame(dtsec->fm, dtsec->mac_id, max_frm_ln);
+-      if (err) {
+-              pr_err("Setting max frame length failed\n");
+-              free_init_resources(dtsec);
+-              return -EINVAL;
+-      }
+-
+-      dtsec->multicast_addr_hash =
+-      alloc_hash_table(EXTENDED_HASH_TABLE_SIZE);
+-      if (!dtsec->multicast_addr_hash) {
+-              free_init_resources(dtsec);
+-              pr_err("MC hash table is failed\n");
+-              return -ENOMEM;
+-      }
+-
+-      dtsec->unicast_addr_hash = alloc_hash_table(DTSEC_HASH_TABLE_SIZE);
+-      if (!dtsec->unicast_addr_hash) {
+-              free_init_resources(dtsec);
+-              pr_err("UC hash table is failed\n");
+-              return -ENOMEM;
+-      }
+-
+-      /* register err intr handler for dtsec to FPM (err) */
+-      fman_register_intr(dtsec->fm, FMAN_MOD_MAC, dtsec->mac_id,
+-                         FMAN_INTR_TYPE_ERR, dtsec_isr, dtsec);
+-      /* register 1588 intr handler for TMR to FPM (normal) */
+-      fman_register_intr(dtsec->fm, FMAN_MOD_MAC, dtsec->mac_id,
+-                         FMAN_INTR_TYPE_NORMAL, dtsec_1588_isr, dtsec);
+-
+-      kfree(dtsec_drv_param);
+-      dtsec->dtsec_drv_param = NULL;
+-
+-      return 0;
+-}
+-
+-int dtsec_free(struct fman_mac *dtsec)
+-{
+-      free_init_resources(dtsec);
+-
+-      kfree(dtsec->dtsec_drv_param);
+-      dtsec->dtsec_drv_param = NULL;
+-      kfree(dtsec);
+-
+-      return 0;
+-}
+-
+-struct fman_mac *dtsec_config(struct fman_mac_params *params)
+-{
+-      struct fman_mac *dtsec;
+-      struct dtsec_cfg *dtsec_drv_param;
+-      void __iomem *base_addr;
+-
+-      base_addr = params->base_addr;
+-
+-      /* allocate memory for the UCC GETH data structure. */
+-      dtsec = kzalloc(sizeof(*dtsec), GFP_KERNEL);
+-      if (!dtsec)
+-              return NULL;
+-
+-      /* allocate memory for the d_tsec driver parameters data structure. */
+-      dtsec_drv_param = kzalloc(sizeof(*dtsec_drv_param), GFP_KERNEL);
+-      if (!dtsec_drv_param)
+-              goto err_dtsec;
+-
+-      /* Plant parameter structure pointer */
+-      dtsec->dtsec_drv_param = dtsec_drv_param;
+-
+-      set_dflts(dtsec_drv_param);
+-
+-      dtsec->regs = base_addr;
+-      dtsec->addr = ENET_ADDR_TO_UINT64(params->addr);
+-      dtsec->max_speed = params->max_speed;
+-      dtsec->phy_if = params->phy_if;
+-      dtsec->mac_id = params->mac_id;
+-      dtsec->exceptions = (DTSEC_IMASK_BREN   |
+-                           DTSEC_IMASK_RXCEN  |
+-                           DTSEC_IMASK_BTEN   |
+-                           DTSEC_IMASK_TXCEN  |
+-                           DTSEC_IMASK_TXEEN  |
+-                           DTSEC_IMASK_ABRTEN |
+-                           DTSEC_IMASK_LCEN   |
+-                           DTSEC_IMASK_CRLEN  |
+-                           DTSEC_IMASK_XFUNEN |
+-                           DTSEC_IMASK_IFERREN |
+-                           DTSEC_IMASK_MAGEN  |
+-                           DTSEC_IMASK_TDPEEN |
+-                           DTSEC_IMASK_RDPEEN);
+-      dtsec->exception_cb = params->exception_cb;
+-      dtsec->event_cb = params->event_cb;
+-      dtsec->dev_id = params->dev_id;
+-      dtsec->ptp_tsu_enabled = dtsec->dtsec_drv_param->ptp_tsu_en;
+-      dtsec->en_tsu_err_exeption = dtsec->dtsec_drv_param->ptp_exception_en;
+-
+-      dtsec->fm = params->fm;
+-      dtsec->basex_if = params->basex_if;
+-
+-      if (!params->internal_phy_node) {
+-              pr_err("TBI PHY node is not available\n");
+-              goto err_dtsec_drv_param;
+-      }
+-
+-      dtsec->tbiphy = of_phy_find_device(params->internal_phy_node);
+-      if (!dtsec->tbiphy) {
+-              pr_err("of_phy_find_device (TBI PHY) failed\n");
+-              goto err_dtsec_drv_param;
+-      }
+-
+-      put_device(&dtsec->tbiphy->mdio.dev);
+-
+-      /* Save FMan revision */
+-      fman_get_revision(dtsec->fm, &dtsec->fm_rev_info);
+-
+-      return dtsec;
+-
+-err_dtsec_drv_param:
+-      kfree(dtsec_drv_param);
+-err_dtsec:
+-      kfree(dtsec);
+-      return NULL;
+-}
+diff --git a/drivers/net/ethernet/freescale/fman/fman_dtsec.h b/drivers/net/ethernet/freescale/fman/fman_dtsec.h
+deleted file mode 100644
+index c4467c0..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman_dtsec.h
++++ /dev/null
+@@ -1,59 +0,0 @@
+-/*
+- * Copyright 2008-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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#ifndef __DTSEC_H
+-#define __DTSEC_H
+-
+-#include "fman_mac.h"
+-
+-struct fman_mac *dtsec_config(struct fman_mac_params *params);
+-int dtsec_set_promiscuous(struct fman_mac *dtsec, bool new_val);
+-int dtsec_modify_mac_address(struct fman_mac *dtsec, enet_addr_t *enet_addr);
+-int dtsec_adjust_link(struct fman_mac *dtsec,
+-                    u16 speed);
+-int dtsec_restart_autoneg(struct fman_mac *dtsec);
+-int dtsec_cfg_max_frame_len(struct fman_mac *dtsec, u16 new_val);
+-int dtsec_cfg_pad_and_crc(struct fman_mac *dtsec, bool new_val);
+-int dtsec_enable(struct fman_mac *dtsec, enum comm_mode mode);
+-int dtsec_disable(struct fman_mac *dtsec, enum comm_mode mode);
+-int dtsec_init(struct fman_mac *dtsec);
+-int dtsec_free(struct fman_mac *dtsec);
+-int dtsec_accept_rx_pause_frames(struct fman_mac *dtsec, bool en);
+-int dtsec_set_tx_pause_frames(struct fman_mac *dtsec, u8 priority,
+-                            u16 pause_time, u16 thresh_time);
+-int dtsec_set_exception(struct fman_mac *dtsec,
+-                      enum fman_mac_exceptions exception, bool enable);
+-int dtsec_add_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
+-int dtsec_del_hash_mac_address(struct fman_mac *dtsec, enet_addr_t *eth_addr);
+-int dtsec_get_version(struct fman_mac *dtsec, u32 *mac_version);
+-
+-#endif /* __DTSEC_H */
+diff --git a/drivers/net/ethernet/freescale/fman/fman_mac.h b/drivers/net/ethernet/freescale/fman/fman_mac.h
+deleted file mode 100644
+index dd6d052..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman_mac.h
++++ /dev/null
+@@ -1,274 +0,0 @@
+-/*
+- * Copyright 2008-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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-/* FM MAC ... */
+-#ifndef __FM_MAC_H
+-#define __FM_MAC_H
+-
+-#include "fman.h"
+-
+-#include <linux/slab.h>
+-#include <linux/phy.h>
+-#include <linux/if_ether.h>
+-
+-struct fman_mac;
+-
+-/* Ethernet Address */
+-typedef u8 enet_addr_t[ETH_ALEN];
+-
+-#define ENET_ADDR_TO_UINT64(_enet_addr)               \
+-      (u64)(((u64)(_enet_addr)[0] << 40) |            \
+-            ((u64)(_enet_addr)[1] << 32) |            \
+-            ((u64)(_enet_addr)[2] << 24) |            \
+-            ((u64)(_enet_addr)[3] << 16) |            \
+-            ((u64)(_enet_addr)[4] << 8) |             \
+-            ((u64)(_enet_addr)[5]))
+-
+-#define MAKE_ENET_ADDR_FROM_UINT64(_addr64, _enet_addr) \
+-      do { \
+-              int i; \
+-              for (i = 0; i < ETH_ALEN; i++) \
+-                      (_enet_addr)[i] = \
+-                      (u8)((_addr64) >> ((5 - i) * 8)); \
+-      } while (0)
+-
+-/* defaults */
+-#define DEFAULT_RESET_ON_INIT                 false
+-
+-/* PFC defines */
+-#define FSL_FM_PAUSE_TIME_ENABLE      0xf000
+-#define FSL_FM_PAUSE_TIME_DISABLE     0
+-#define FSL_FM_PAUSE_THRESH_DEFAULT   0
+-
+-#define FM_MAC_NO_PFC   0xff
+-
+-/* HASH defines */
+-#define ETH_HASH_ENTRY_OBJ(ptr)       \
+-      hlist_entry_safe(ptr, struct eth_hash_entry, node)
+-
+-/* Enumeration (bit flags) of communication modes (Transmit,
+- * receive or both).
+- */
+-enum comm_mode {
+-      COMM_MODE_NONE = 0,     /* No transmit/receive communication */
+-      COMM_MODE_RX = 1,       /* Only receive communication */
+-      COMM_MODE_TX = 2,       /* Only transmit communication */
+-      COMM_MODE_RX_AND_TX = 3 /* Both transmit and receive communication */
+-};
+-
+-/* FM MAC Exceptions */
+-enum fman_mac_exceptions {
+-      FM_MAC_EX_10G_MDIO_SCAN_EVENT = 0
+-      /* 10GEC MDIO scan event interrupt */
+-      , FM_MAC_EX_10G_MDIO_CMD_CMPL
+-      /* 10GEC MDIO command completion interrupt */
+-      , FM_MAC_EX_10G_REM_FAULT
+-      /* 10GEC, mEMAC Remote fault interrupt */
+-      , FM_MAC_EX_10G_LOC_FAULT
+-      /* 10GEC, mEMAC Local fault interrupt */
+-      , FM_MAC_EX_10G_TX_ECC_ER
+-      /* 10GEC, mEMAC Transmit frame ECC error interrupt */
+-      , FM_MAC_EX_10G_TX_FIFO_UNFL
+-      /* 10GEC, mEMAC Transmit FIFO underflow interrupt */
+-      , FM_MAC_EX_10G_TX_FIFO_OVFL
+-      /* 10GEC, mEMAC Transmit FIFO overflow interrupt */
+-      , FM_MAC_EX_10G_TX_ER
+-      /* 10GEC Transmit frame error interrupt */
+-      , FM_MAC_EX_10G_RX_FIFO_OVFL
+-      /* 10GEC, mEMAC Receive FIFO overflow interrupt */
+-      , FM_MAC_EX_10G_RX_ECC_ER
+-      /* 10GEC, mEMAC Receive frame ECC error interrupt */
+-      , FM_MAC_EX_10G_RX_JAB_FRM
+-      /* 10GEC Receive jabber frame interrupt */
+-      , FM_MAC_EX_10G_RX_OVRSZ_FRM
+-      /* 10GEC Receive oversized frame interrupt */
+-      , FM_MAC_EX_10G_RX_RUNT_FRM
+-      /* 10GEC Receive runt frame interrupt */
+-      , FM_MAC_EX_10G_RX_FRAG_FRM
+-      /* 10GEC Receive fragment frame interrupt */
+-      , FM_MAC_EX_10G_RX_LEN_ER
+-      /* 10GEC Receive payload length error interrupt */
+-      , FM_MAC_EX_10G_RX_CRC_ER
+-      /* 10GEC Receive CRC error interrupt */
+-      , FM_MAC_EX_10G_RX_ALIGN_ER
+-      /* 10GEC Receive alignment error interrupt */
+-      , FM_MAC_EX_1G_BAB_RX
+-      /* dTSEC Babbling receive error */
+-      , FM_MAC_EX_1G_RX_CTL
+-      /* dTSEC Receive control (pause frame) interrupt */
+-      , FM_MAC_EX_1G_GRATEFUL_TX_STP_COMPLET
+-      /* dTSEC Graceful transmit stop complete */
+-      , FM_MAC_EX_1G_BAB_TX
+-      /* dTSEC Babbling transmit error */
+-      , FM_MAC_EX_1G_TX_CTL
+-      /* dTSEC Transmit control (pause frame) interrupt */
+-      , FM_MAC_EX_1G_TX_ERR
+-      /* dTSEC Transmit error */
+-      , FM_MAC_EX_1G_LATE_COL
+-      /* dTSEC Late collision */
+-      , FM_MAC_EX_1G_COL_RET_LMT
+-      /* dTSEC Collision retry limit */
+-      , FM_MAC_EX_1G_TX_FIFO_UNDRN
+-      /* dTSEC Transmit FIFO underrun */
+-      , FM_MAC_EX_1G_MAG_PCKT
+-      /* dTSEC Magic Packet detection */
+-      , FM_MAC_EX_1G_MII_MNG_RD_COMPLET
+-      /* dTSEC MII management read completion */
+-      , FM_MAC_EX_1G_MII_MNG_WR_COMPLET
+-      /* dTSEC MII management write completion */
+-      , FM_MAC_EX_1G_GRATEFUL_RX_STP_COMPLET
+-      /* dTSEC Graceful receive stop complete */
+-      , FM_MAC_EX_1G_DATA_ERR
+-      /* dTSEC Internal data error on transmit */
+-      , FM_MAC_1G_RX_DATA_ERR
+-      /* dTSEC Internal data error on receive */
+-      , FM_MAC_EX_1G_1588_TS_RX_ERR
+-      /* dTSEC Time-Stamp Receive Error */
+-      , FM_MAC_EX_1G_RX_MIB_CNT_OVFL
+-      /* dTSEC MIB counter overflow */
+-      , FM_MAC_EX_TS_FIFO_ECC_ERR
+-      /* mEMAC Time-stamp FIFO ECC error interrupt;
+-       * not supported on T4240/B4860 rev1 chips
+-       */
+-      , FM_MAC_EX_MAGIC_PACKET_INDICATION = FM_MAC_EX_1G_MAG_PCKT
+-      /* mEMAC Magic Packet Indication Interrupt */
+-};
+-
+-struct eth_hash_entry {
+-      u64 addr;               /* Ethernet Address  */
+-      struct list_head node;
+-};
+-
+-typedef void (fman_mac_exception_cb)(void *dev_id,
+-                                  enum fman_mac_exceptions exceptions);
+-
+-/* FMan MAC config input */
+-struct fman_mac_params {
+-      /* Base of memory mapped FM MAC registers */
+-      void __iomem *base_addr;
+-      /* MAC address of device; First octet is sent first */
+-      enet_addr_t addr;
+-      /* MAC ID; numbering of dTSEC and 1G-mEMAC:
+-       * 0 - FM_MAX_NUM_OF_1G_MACS;
+-       * numbering of 10G-MAC (TGEC) and 10G-mEMAC:
+-       * 0 - FM_MAX_NUM_OF_10G_MACS
+-       */
+-      u8 mac_id;
+-      /* PHY interface */
+-      phy_interface_t  phy_if;
+-      /* Note that the speed should indicate the maximum rate that
+-       * this MAC should support rather than the actual speed;
+-       */
+-      u16 max_speed;
+-      /* A handle to the FM object this port related to */
+-      void *fm;
+-      void *dev_id; /* device cookie used by the exception cbs */
+-      fman_mac_exception_cb *event_cb;    /* MDIO Events Callback Routine */
+-      fman_mac_exception_cb *exception_cb;/* Exception Callback Routine */
+-      /* SGMII/QSGII interface with 1000BaseX auto-negotiation between MAC
+-       * and phy or backplane; Note: 1000BaseX auto-negotiation relates only
+-       * to interface between MAC and phy/backplane, SGMII phy can still
+-       * synchronize with far-end phy at 10Mbps, 100Mbps or 1000Mbps
+-      */
+-      bool basex_if;
+-      /* Pointer to TBI/PCS PHY node, used for TBI/PCS PHY access */
+-      struct device_node *internal_phy_node;
+-};
+-
+-struct eth_hash_t {
+-      u16 size;
+-      struct list_head *lsts;
+-};
+-
+-static inline struct eth_hash_entry
+-*dequeue_addr_from_hash_entry(struct list_head *addr_lst)
+-{
+-      struct eth_hash_entry *hash_entry = NULL;
+-
+-      if (!list_empty(addr_lst)) {
+-              hash_entry = ETH_HASH_ENTRY_OBJ(addr_lst->next);
+-              list_del_init(&hash_entry->node);
+-      }
+-      return hash_entry;
+-}
+-
+-static inline void free_hash_table(struct eth_hash_t *hash)
+-{
+-      struct eth_hash_entry *hash_entry;
+-      int i = 0;
+-
+-      if (hash) {
+-              if (hash->lsts) {
+-                      for (i = 0; i < hash->size; i++) {
+-                              hash_entry =
+-                              dequeue_addr_from_hash_entry(&hash->lsts[i]);
+-                              while (hash_entry) {
+-                                      kfree(hash_entry);
+-                                      hash_entry =
+-                                      dequeue_addr_from_hash_entry(&hash->
+-                                                                   lsts[i]);
+-                              }
+-                      }
+-
+-                      kfree(hash->lsts);
+-              }
+-
+-              kfree(hash);
+-      }
+-}
+-
+-static inline struct eth_hash_t *alloc_hash_table(u16 size)
+-{
+-      u32 i;
+-      struct eth_hash_t *hash;
+-
+-      /* Allocate address hash table */
+-      hash = kmalloc_array(size, sizeof(struct eth_hash_t *), GFP_KERNEL);
+-      if (!hash)
+-              return NULL;
+-
+-      hash->size = size;
+-
+-      hash->lsts = kmalloc_array(hash->size, sizeof(struct list_head),
+-                                 GFP_KERNEL);
+-      if (!hash->lsts) {
+-              kfree(hash);
+-              return NULL;
+-      }
+-
+-      for (i = 0; i < hash->size; i++)
+-              INIT_LIST_HEAD(&hash->lsts[i]);
+-
+-      return hash;
+-}
+-
+-#endif /* __FM_MAC_H */
+diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.c b/drivers/net/ethernet/freescale/fman/fman_memac.c
+deleted file mode 100644
+index 71a5ded..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman_memac.c
++++ /dev/null
+@@ -1,1177 +0,0 @@
+-/*
+- * Copyright 2008-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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+-
+-#include "fman_memac.h"
+-#include "fman.h"
+-
+-#include <linux/slab.h>
+-#include <linux/io.h>
+-#include <linux/phy.h>
+-#include <linux/of_mdio.h>
+-
+-/* PCS registers */
+-#define MDIO_SGMII_CR                 0x00
+-#define MDIO_SGMII_DEV_ABIL_SGMII     0x04
+-#define MDIO_SGMII_LINK_TMR_L         0x12
+-#define MDIO_SGMII_LINK_TMR_H         0x13
+-#define MDIO_SGMII_IF_MODE            0x14
+-
+-/* SGMII Control defines */
+-#define SGMII_CR_AN_EN                        0x1000
+-#define SGMII_CR_RESTART_AN           0x0200
+-#define SGMII_CR_FD                   0x0100
+-#define SGMII_CR_SPEED_SEL1_1G                0x0040
+-#define SGMII_CR_DEF_VAL              (SGMII_CR_AN_EN | SGMII_CR_FD | \
+-                                       SGMII_CR_SPEED_SEL1_1G)
+-
+-/* SGMII Device Ability for SGMII defines */
+-#define MDIO_SGMII_DEV_ABIL_SGMII_MODE        0x4001
+-#define MDIO_SGMII_DEV_ABIL_BASEX_MODE        0x01A0
+-
+-/* Link timer define */
+-#define LINK_TMR_L                    0xa120
+-#define LINK_TMR_H                    0x0007
+-#define LINK_TMR_L_BASEX              0xaf08
+-#define LINK_TMR_H_BASEX              0x002f
+-
+-/* SGMII IF Mode defines */
+-#define IF_MODE_USE_SGMII_AN          0x0002
+-#define IF_MODE_SGMII_EN              0x0001
+-#define IF_MODE_SGMII_SPEED_100M      0x0004
+-#define IF_MODE_SGMII_SPEED_1G                0x0008
+-#define IF_MODE_SGMII_DUPLEX_HALF     0x0010
+-
+-/* Num of additional exact match MAC adr regs */
+-#define MEMAC_NUM_OF_PADDRS 7
+-
+-/* Control and Configuration Register (COMMAND_CONFIG) */
+-#define CMD_CFG_REG_LOWP_RXETY        0x01000000 /* 07 Rx low power indication */
+-#define CMD_CFG_TX_LOWP_ENA   0x00800000 /* 08 Tx Low Power Idle Enable */
+-#define CMD_CFG_PFC_MODE      0x00080000 /* 12 Enable PFC */
+-#define CMD_CFG_NO_LEN_CHK    0x00020000 /* 14 Payload length check disable */
+-#define CMD_CFG_SW_RESET      0x00001000 /* 19 S/W Reset, self clearing bit */
+-#define CMD_CFG_TX_PAD_EN     0x00000800 /* 20 Enable Tx padding of frames */
+-#define CMD_CFG_PAUSE_IGNORE  0x00000100 /* 23 Ignore Pause frame quanta */
+-#define CMD_CFG_CRC_FWD               0x00000040 /* 25 Terminate/frwd CRC of frames */
+-#define CMD_CFG_PAD_EN                0x00000020 /* 26 Frame padding removal */
+-#define CMD_CFG_PROMIS_EN     0x00000010 /* 27 Promiscuous operation enable */
+-#define CMD_CFG_RX_EN         0x00000002 /* 30 MAC receive path enable */
+-#define CMD_CFG_TX_EN         0x00000001 /* 31 MAC transmit path enable */
+-
+-/* Transmit FIFO Sections Register (TX_FIFO_SECTIONS) */
+-#define TX_FIFO_SECTIONS_TX_EMPTY_MASK                        0xFFFF0000
+-#define TX_FIFO_SECTIONS_TX_AVAIL_MASK                        0x0000FFFF
+-#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G         0x00400000
+-#define TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G          0x00100000
+-#define TX_FIFO_SECTIONS_TX_AVAIL_10G                 0x00000019
+-#define TX_FIFO_SECTIONS_TX_AVAIL_1G                  0x00000020
+-#define TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G            0x00000060
+-
+-#define GET_TX_EMPTY_DEFAULT_VALUE(_val)                              \
+-do {                                                                  \
+-      _val &= ~TX_FIFO_SECTIONS_TX_EMPTY_MASK;                        \
+-      ((_val == TX_FIFO_SECTIONS_TX_AVAIL_10G) ?                      \
+-                      (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G) :\
+-                      (_val |= TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G));\
+-} while (0)
+-
+-/* Interface Mode Register (IF_MODE) */
+-
+-#define IF_MODE_MASK          0x00000003 /* 30-31 Mask on i/f mode bits */
+-#define IF_MODE_XGMII         0x00000000 /* 30-31 XGMII (10G) interface */
+-#define IF_MODE_GMII          0x00000002 /* 30-31 GMII (1G) interface */
+-#define IF_MODE_RGMII         0x00000004
+-#define IF_MODE_RGMII_AUTO    0x00008000
+-#define IF_MODE_RGMII_1000    0x00004000 /* 10 - 1000Mbps RGMII */
+-#define IF_MODE_RGMII_100     0x00000000 /* 00 - 100Mbps RGMII */
+-#define IF_MODE_RGMII_10      0x00002000 /* 01 - 10Mbps RGMII */
+-#define IF_MODE_RGMII_SP_MASK 0x00006000 /* Setsp mask bits */
+-#define IF_MODE_RGMII_FD      0x00001000 /* Full duplex RGMII */
+-#define IF_MODE_HD            0x00000040 /* Half duplex operation */
+-
+-/* Hash table Control Register (HASHTABLE_CTRL) */
+-#define HASH_CTRL_MCAST_EN    0x00000100
+-/* 26-31 Hash table address code */
+-#define HASH_CTRL_ADDR_MASK   0x0000003F
+-/* MAC mcast indication */
+-#define GROUP_ADDRESS         0x0000010000000000LL
+-#define HASH_TABLE_SIZE               64      /* Hash tbl size */
+-
+-/* Interrupt Mask Register (IMASK) */
+-#define MEMAC_IMASK_MGI               0x40000000 /* 1 Magic pkt detect indication */
+-#define MEMAC_IMASK_TSECC_ER  0x20000000 /* 2 Timestamp FIFO ECC error evnt */
+-#define MEMAC_IMASK_TECC_ER   0x02000000 /* 6 Transmit frame ECC error evnt */
+-#define MEMAC_IMASK_RECC_ER   0x01000000 /* 7 Receive frame ECC error evnt */
+-
+-#define MEMAC_ALL_ERRS_IMASK                                  \
+-              ((u32)(MEMAC_IMASK_TSECC_ER     |       \
+-                     MEMAC_IMASK_TECC_ER              |       \
+-                     MEMAC_IMASK_RECC_ER              |       \
+-                     MEMAC_IMASK_MGI))
+-
+-#define MEMAC_IEVNT_PCS                       0x80000000 /* PCS (XG). Link sync (G) */
+-#define MEMAC_IEVNT_AN                        0x40000000 /* Auto-negotiation */
+-#define MEMAC_IEVNT_LT                        0x20000000 /* Link Training/New page */
+-#define MEMAC_IEVNT_MGI                       0x00004000 /* Magic pkt detection */
+-#define MEMAC_IEVNT_TS_ECC_ER         0x00002000 /* Timestamp FIFO ECC error*/
+-#define MEMAC_IEVNT_RX_FIFO_OVFL      0x00001000 /* Rx FIFO overflow */
+-#define MEMAC_IEVNT_TX_FIFO_UNFL      0x00000800 /* Tx FIFO underflow */
+-#define MEMAC_IEVNT_TX_FIFO_OVFL      0x00000400 /* Tx FIFO overflow */
+-#define MEMAC_IEVNT_TX_ECC_ER         0x00000200 /* Tx frame ECC error */
+-#define MEMAC_IEVNT_RX_ECC_ER         0x00000100 /* Rx frame ECC error */
+-#define MEMAC_IEVNT_LI_FAULT          0x00000080 /* Link Interruption flt */
+-#define MEMAC_IEVNT_RX_EMPTY          0x00000040 /* Rx FIFO empty */
+-#define MEMAC_IEVNT_TX_EMPTY          0x00000020 /* Tx FIFO empty */
+-#define MEMAC_IEVNT_RX_LOWP           0x00000010 /* Low Power Idle */
+-#define MEMAC_IEVNT_PHY_LOS           0x00000004 /* Phy loss of signal */
+-#define MEMAC_IEVNT_REM_FAULT         0x00000002 /* Remote fault (XGMII) */
+-#define MEMAC_IEVNT_LOC_FAULT         0x00000001 /* Local fault (XGMII) */
+-
+-#define DEFAULT_PAUSE_QUANTA  0xf000
+-#define DEFAULT_FRAME_LENGTH  0x600
+-#define DEFAULT_TX_IPG_LENGTH 12
+-
+-#define CLXY_PAUSE_QUANTA_CLX_PQNT    0x0000FFFF
+-#define CLXY_PAUSE_QUANTA_CLY_PQNT    0xFFFF0000
+-#define CLXY_PAUSE_THRESH_CLX_QTH     0x0000FFFF
+-#define CLXY_PAUSE_THRESH_CLY_QTH     0xFFFF0000
+-
+-struct mac_addr {
+-      /* Lower 32 bits of 48-bit MAC address */
+-      u32 mac_addr_l;
+-      /* Upper 16 bits of 48-bit MAC address */
+-      u32 mac_addr_u;
+-};
+-
+-/* memory map */
+-struct memac_regs {
+-      u32 res0000[2];                 /* General Control and Status */
+-      u32 command_config;             /* 0x008 Ctrl and cfg */
+-      struct mac_addr mac_addr0;      /* 0x00C-0x010 MAC_ADDR_0...1 */
+-      u32 maxfrm;                     /* 0x014 Max frame length */
+-      u32 res0018[1];
+-      u32 rx_fifo_sections;           /* Receive FIFO configuration reg */
+-      u32 tx_fifo_sections;           /* Transmit FIFO configuration reg */
+-      u32 res0024[2];
+-      u32 hashtable_ctrl;             /* 0x02C Hash table control */
+-      u32 res0030[4];
+-      u32 ievent;                     /* 0x040 Interrupt event */
+-      u32 tx_ipg_length;              /* 0x044 Transmitter inter-packet-gap */
+-      u32 res0048;
+-      u32 imask;                      /* 0x04C Interrupt mask */
+-      u32 res0050;
+-      u32 pause_quanta[4];            /* 0x054 Pause quanta */
+-      u32 pause_thresh[4];            /* 0x064 Pause quanta threshold */
+-      u32 rx_pause_status;            /* 0x074 Receive pause status */
+-      u32 res0078[2];
+-      struct mac_addr mac_addr[MEMAC_NUM_OF_PADDRS];/* 0x80-0x0B4 mac padr */
+-      u32 lpwake_timer;               /* 0x0B8 Low Power Wakeup Timer */
+-      u32 sleep_timer;                /* 0x0BC Transmit EEE Low Power Timer */
+-      u32 res00c0[8];
+-      u32 statn_config;               /* 0x0E0 Statistics configuration */
+-      u32 res00e4[7];
+-      /* Rx Statistics Counter */
+-      u32 reoct_l;
+-      u32 reoct_u;
+-      u32 roct_l;
+-      u32 roct_u;
+-      u32 raln_l;
+-      u32 raln_u;
+-      u32 rxpf_l;
+-      u32 rxpf_u;
+-      u32 rfrm_l;
+-      u32 rfrm_u;
+-      u32 rfcs_l;
+-      u32 rfcs_u;
+-      u32 rvlan_l;
+-      u32 rvlan_u;
+-      u32 rerr_l;
+-      u32 rerr_u;
+-      u32 ruca_l;
+-      u32 ruca_u;
+-      u32 rmca_l;
+-      u32 rmca_u;
+-      u32 rbca_l;
+-      u32 rbca_u;
+-      u32 rdrp_l;
+-      u32 rdrp_u;
+-      u32 rpkt_l;
+-      u32 rpkt_u;
+-      u32 rund_l;
+-      u32 rund_u;
+-      u32 r64_l;
+-      u32 r64_u;
+-      u32 r127_l;
+-      u32 r127_u;
+-      u32 r255_l;
+-      u32 r255_u;
+-      u32 r511_l;
+-      u32 r511_u;
+-      u32 r1023_l;
+-      u32 r1023_u;
+-      u32 r1518_l;
+-      u32 r1518_u;
+-      u32 r1519x_l;
+-      u32 r1519x_u;
+-      u32 rovr_l;
+-      u32 rovr_u;
+-      u32 rjbr_l;
+-      u32 rjbr_u;
+-      u32 rfrg_l;
+-      u32 rfrg_u;
+-      u32 rcnp_l;
+-      u32 rcnp_u;
+-      u32 rdrntp_l;
+-      u32 rdrntp_u;
+-      u32 res01d0[12];
+-      /* Tx Statistics Counter */
+-      u32 teoct_l;
+-      u32 teoct_u;
+-      u32 toct_l;
+-      u32 toct_u;
+-      u32 res0210[2];
+-      u32 txpf_l;
+-      u32 txpf_u;
+-      u32 tfrm_l;
+-      u32 tfrm_u;
+-      u32 tfcs_l;
+-      u32 tfcs_u;
+-      u32 tvlan_l;
+-      u32 tvlan_u;
+-      u32 terr_l;
+-      u32 terr_u;
+-      u32 tuca_l;
+-      u32 tuca_u;
+-      u32 tmca_l;
+-      u32 tmca_u;
+-      u32 tbca_l;
+-      u32 tbca_u;
+-      u32 res0258[2];
+-      u32 tpkt_l;
+-      u32 tpkt_u;
+-      u32 tund_l;
+-      u32 tund_u;
+-      u32 t64_l;
+-      u32 t64_u;
+-      u32 t127_l;
+-      u32 t127_u;
+-      u32 t255_l;
+-      u32 t255_u;
+-      u32 t511_l;
+-      u32 t511_u;
+-      u32 t1023_l;
+-      u32 t1023_u;
+-      u32 t1518_l;
+-      u32 t1518_u;
+-      u32 t1519x_l;
+-      u32 t1519x_u;
+-      u32 res02a8[6];
+-      u32 tcnp_l;
+-      u32 tcnp_u;
+-      u32 res02c8[14];
+-      /* Line Interface Control */
+-      u32 if_mode;            /* 0x300 Interface Mode Control */
+-      u32 if_status;          /* 0x304 Interface Status */
+-      u32 res0308[14];
+-      /* HiGig/2 */
+-      u32 hg_config;          /* 0x340 Control and cfg */
+-      u32 res0344[3];
+-      u32 hg_pause_quanta;    /* 0x350 Pause quanta */
+-      u32 res0354[3];
+-      u32 hg_pause_thresh;    /* 0x360 Pause quanta threshold */
+-      u32 res0364[3];
+-      u32 hgrx_pause_status;  /* 0x370 Receive pause status */
+-      u32 hg_fifos_status;    /* 0x374 fifos status */
+-      u32 rhm;                /* 0x378 rx messages counter */
+-      u32 thm;                /* 0x37C tx messages counter */
+-};
+-
+-struct memac_cfg {
+-      bool reset_on_init;
+-      bool pause_ignore;
+-      bool promiscuous_mode_enable;
+-      struct fixed_phy_status *fixed_link;
+-      u16 max_frame_length;
+-      u16 pause_quanta;
+-      u32 tx_ipg_length;
+-};
+-
+-struct fman_mac {
+-      /* Pointer to MAC memory mapped registers */
+-      struct memac_regs __iomem *regs;
+-      /* MAC address of device */
+-      u64 addr;
+-      /* Ethernet physical interface */
+-      phy_interface_t phy_if;
+-      u16 max_speed;
+-      void *dev_id; /* device cookie used by the exception cbs */
+-      fman_mac_exception_cb *exception_cb;
+-      fman_mac_exception_cb *event_cb;
+-      /* Pointer to driver's global address hash table  */
+-      struct eth_hash_t *multicast_addr_hash;
+-      /* Pointer to driver's individual address hash table  */
+-      struct eth_hash_t *unicast_addr_hash;
+-      u8 mac_id;
+-      u32 exceptions;
+-      struct memac_cfg *memac_drv_param;
+-      void *fm;
+-      struct fman_rev_info fm_rev_info;
+-      bool basex_if;
+-      struct phy_device *pcsphy;
+-};
+-
+-static void add_addr_in_paddr(struct memac_regs __iomem *regs, u8 *adr,
+-                            u8 paddr_num)
+-{
+-      u32 tmp0, tmp1;
+-
+-      tmp0 = (u32)(adr[0] | adr[1] << 8 | adr[2] << 16 | adr[3] << 24);
+-      tmp1 = (u32)(adr[4] | adr[5] << 8);
+-
+-      if (paddr_num == 0) {
+-              iowrite32be(tmp0, &regs->mac_addr0.mac_addr_l);
+-              iowrite32be(tmp1, &regs->mac_addr0.mac_addr_u);
+-      } else {
+-              iowrite32be(tmp0, &regs->mac_addr[paddr_num - 1].mac_addr_l);
+-              iowrite32be(tmp1, &regs->mac_addr[paddr_num - 1].mac_addr_u);
+-      }
+-}
+-
+-static int reset(struct memac_regs __iomem *regs)
+-{
+-      u32 tmp;
+-      int count;
+-
+-      tmp = ioread32be(&regs->command_config);
+-
+-      tmp |= CMD_CFG_SW_RESET;
+-
+-      iowrite32be(tmp, &regs->command_config);
+-
+-      count = 100;
+-      do {
+-              udelay(1);
+-      } while ((ioread32be(&regs->command_config) & CMD_CFG_SW_RESET) &&
+-               --count);
+-
+-      if (count == 0)
+-              return -EBUSY;
+-
+-      return 0;
+-}
+-
+-static void set_exception(struct memac_regs __iomem *regs, u32 val,
+-                        bool enable)
+-{
+-      u32 tmp;
+-
+-      tmp = ioread32be(&regs->imask);
+-      if (enable)
+-              tmp |= val;
+-      else
+-              tmp &= ~val;
+-
+-      iowrite32be(tmp, &regs->imask);
+-}
+-
+-static int init(struct memac_regs __iomem *regs, struct memac_cfg *cfg,
+-              phy_interface_t phy_if, u16 speed, bool slow_10g_if,
+-              u32 exceptions)
+-{
+-      u32 tmp;
+-
+-      /* Config */
+-      tmp = 0;
+-      if (cfg->promiscuous_mode_enable)
+-              tmp |= CMD_CFG_PROMIS_EN;
+-      if (cfg->pause_ignore)
+-              tmp |= CMD_CFG_PAUSE_IGNORE;
+-
+-      /* Payload length check disable */
+-      tmp |= CMD_CFG_NO_LEN_CHK;
+-      /* Enable padding of frames in transmit direction */
+-      tmp |= CMD_CFG_TX_PAD_EN;
+-
+-      tmp |= CMD_CFG_CRC_FWD;
+-
+-      iowrite32be(tmp, &regs->command_config);
+-
+-      /* Max Frame Length */
+-      iowrite32be((u32)cfg->max_frame_length, &regs->maxfrm);
+-
+-      /* Pause Time */
+-      iowrite32be((u32)cfg->pause_quanta, &regs->pause_quanta[0]);
+-      iowrite32be((u32)0, &regs->pause_thresh[0]);
+-
+-      /* IF_MODE */
+-      tmp = 0;
+-      switch (phy_if) {
+-      case PHY_INTERFACE_MODE_XGMII:
+-              tmp |= IF_MODE_XGMII;
+-              break;
+-      default:
+-              tmp |= IF_MODE_GMII;
+-              if (phy_if == PHY_INTERFACE_MODE_RGMII)
+-                      tmp |= IF_MODE_RGMII | IF_MODE_RGMII_AUTO;
+-      }
+-      iowrite32be(tmp, &regs->if_mode);
+-
+-      /* TX_FIFO_SECTIONS */
+-      tmp = 0;
+-      if (phy_if == PHY_INTERFACE_MODE_XGMII) {
+-              if (slow_10g_if) {
+-                      tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_SLOW_10G |
+-                              TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
+-              } else {
+-                      tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_10G |
+-                              TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_10G);
+-              }
+-      } else {
+-              tmp |= (TX_FIFO_SECTIONS_TX_AVAIL_1G |
+-                      TX_FIFO_SECTIONS_TX_EMPTY_DEFAULT_1G);
+-      }
+-      iowrite32be(tmp, &regs->tx_fifo_sections);
+-
+-      /* clear all pending events and set-up interrupts */
+-      iowrite32be(0xffffffff, &regs->ievent);
+-      set_exception(regs, exceptions, true);
+-
+-      return 0;
+-}
+-
+-static void set_dflts(struct memac_cfg *cfg)
+-{
+-      cfg->reset_on_init = false;
+-      cfg->promiscuous_mode_enable = false;
+-      cfg->pause_ignore = false;
+-      cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
+-      cfg->max_frame_length = DEFAULT_FRAME_LENGTH;
+-      cfg->pause_quanta = DEFAULT_PAUSE_QUANTA;
+-}
+-
+-static u32 get_mac_addr_hash_code(u64 eth_addr)
+-{
+-      u64 mask1, mask2;
+-      u32 xor_val = 0;
+-      u8 i, j;
+-
+-      for (i = 0; i < 6; i++) {
+-              mask1 = eth_addr & (u64)0x01;
+-              eth_addr >>= 1;
+-
+-              for (j = 0; j < 7; j++) {
+-                      mask2 = eth_addr & (u64)0x01;
+-                      mask1 ^= mask2;
+-                      eth_addr >>= 1;
+-              }
+-
+-              xor_val |= (mask1 << (5 - i));
+-      }
+-
+-      return xor_val;
+-}
+-
+-static void setup_sgmii_internal_phy(struct fman_mac *memac,
+-                                   struct fixed_phy_status *fixed_link)
+-{
+-      u16 tmp_reg16;
+-
+-      if (WARN_ON(!memac->pcsphy))
+-              return;
+-
+-      /* SGMII mode */
+-      tmp_reg16 = IF_MODE_SGMII_EN;
+-      if (!fixed_link)
+-              /* AN enable */
+-              tmp_reg16 |= IF_MODE_USE_SGMII_AN;
+-      else {
+-              switch (fixed_link->speed) {
+-              case 10:
+-                      /* For 10M: IF_MODE[SPEED_10M] = 0 */
+-              break;
+-              case 100:
+-                      tmp_reg16 |= IF_MODE_SGMII_SPEED_100M;
+-              break;
+-              case 1000: /* fallthrough */
+-              default:
+-                      tmp_reg16 |= IF_MODE_SGMII_SPEED_1G;
+-              break;
+-              }
+-              if (!fixed_link->duplex)
+-                      tmp_reg16 |= IF_MODE_SGMII_DUPLEX_HALF;
+-      }
+-      phy_write(memac->pcsphy, MDIO_SGMII_IF_MODE, tmp_reg16);
+-
+-      /* Device ability according to SGMII specification */
+-      tmp_reg16 = MDIO_SGMII_DEV_ABIL_SGMII_MODE;
+-      phy_write(memac->pcsphy, MDIO_SGMII_DEV_ABIL_SGMII, tmp_reg16);
+-
+-      /* Adjust link timer for SGMII  -
+-       * According to Cisco SGMII specification the timer should be 1.6 ms.
+-       * The link_timer register is configured in units of the clock.
+-       * - When running as 1G SGMII, Serdes clock is 125 MHz, so
+-       * unit = 1 / (125*10^6 Hz) = 8 ns.
+-       * 1.6 ms in units of 8 ns = 1.6ms / 8ns = 2*10^5 = 0x30d40
+-       * - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
+-       * unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
+-       * 1.6 ms in units of 3.2 ns = 1.6ms / 3.2ns = 5*10^5 = 0x7a120.
+-       * Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
+-       * we always set up here a value of 2.5 SGMII.
+-       */
+-      phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_H, LINK_TMR_H);
+-      phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_L, LINK_TMR_L);
+-
+-      if (!fixed_link)
+-              /* Restart AN */
+-              tmp_reg16 = SGMII_CR_DEF_VAL | SGMII_CR_RESTART_AN;
+-      else
+-              /* AN disabled */
+-              tmp_reg16 = SGMII_CR_DEF_VAL & ~SGMII_CR_AN_EN;
+-      phy_write(memac->pcsphy, 0x0, tmp_reg16);
+-}
+-
+-static void setup_sgmii_internal_phy_base_x(struct fman_mac *memac)
+-{
+-      u16 tmp_reg16;
+-
+-      /* AN Device capability  */
+-      tmp_reg16 = MDIO_SGMII_DEV_ABIL_BASEX_MODE;
+-      phy_write(memac->pcsphy, MDIO_SGMII_DEV_ABIL_SGMII, tmp_reg16);
+-
+-      /* Adjust link timer for SGMII  -
+-       * For Serdes 1000BaseX auto-negotiation the timer should be 10 ms.
+-       * The link_timer register is configured in units of the clock.
+-       * - When running as 1G SGMII, Serdes clock is 125 MHz, so
+-       * unit = 1 / (125*10^6 Hz) = 8 ns.
+-       * 10 ms in units of 8 ns = 10ms / 8ns = 1250000 = 0x1312d0
+-       * - When running as 2.5G SGMII, Serdes clock is 312.5 MHz, so
+-       * unit = 1 / (312.5*10^6 Hz) = 3.2 ns.
+-       * 10 ms in units of 3.2 ns = 10ms / 3.2ns = 3125000 = 0x2faf08.
+-       * Since link_timer value of 1G SGMII will be too short for 2.5 SGMII,
+-       * we always set up here a value of 2.5 SGMII.
+-       */
+-      phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_H, LINK_TMR_H_BASEX);
+-      phy_write(memac->pcsphy, MDIO_SGMII_LINK_TMR_L, LINK_TMR_L_BASEX);
+-
+-      /* Restart AN */
+-      tmp_reg16 = SGMII_CR_DEF_VAL | SGMII_CR_RESTART_AN;
+-      phy_write(memac->pcsphy, 0x0, tmp_reg16);
+-}
+-
+-static int check_init_parameters(struct fman_mac *memac)
+-{
+-      if (memac->addr == 0) {
+-              pr_err("Ethernet MAC must have a valid MAC address\n");
+-              return -EINVAL;
+-      }
+-      if (!memac->exception_cb) {
+-              pr_err("Uninitialized exception handler\n");
+-              return -EINVAL;
+-      }
+-      if (!memac->event_cb) {
+-              pr_warn("Uninitialize event handler\n");
+-              return -EINVAL;
+-      }
+-
+-      return 0;
+-}
+-
+-static int get_exception_flag(enum fman_mac_exceptions exception)
+-{
+-      u32 bit_mask;
+-
+-      switch (exception) {
+-      case FM_MAC_EX_10G_TX_ECC_ER:
+-              bit_mask = MEMAC_IMASK_TECC_ER;
+-              break;
+-      case FM_MAC_EX_10G_RX_ECC_ER:
+-              bit_mask = MEMAC_IMASK_RECC_ER;
+-              break;
+-      case FM_MAC_EX_TS_FIFO_ECC_ERR:
+-              bit_mask = MEMAC_IMASK_TSECC_ER;
+-              break;
+-      case FM_MAC_EX_MAGIC_PACKET_INDICATION:
+-              bit_mask = MEMAC_IMASK_MGI;
+-              break;
+-      default:
+-              bit_mask = 0;
+-              break;
+-      }
+-
+-      return bit_mask;
+-}
+-
+-static void memac_err_exception(void *handle)
+-{
+-      struct fman_mac *memac = (struct fman_mac *)handle;
+-      struct memac_regs __iomem *regs = memac->regs;
+-      u32 event, imask;
+-
+-      event = ioread32be(&regs->ievent);
+-      imask = ioread32be(&regs->imask);
+-
+-      /* Imask include both error and notification/event bits.
+-       * Leaving only error bits enabled by imask.
+-       * The imask error bits are shifted by 16 bits offset from
+-       * their corresponding location in the ievent - hence the >> 16
+-       */
+-      event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
+-
+-      iowrite32be(event, &regs->ievent);
+-
+-      if (event & MEMAC_IEVNT_TS_ECC_ER)
+-              memac->exception_cb(memac->dev_id, FM_MAC_EX_TS_FIFO_ECC_ERR);
+-      if (event & MEMAC_IEVNT_TX_ECC_ER)
+-              memac->exception_cb(memac->dev_id, FM_MAC_EX_10G_TX_ECC_ER);
+-      if (event & MEMAC_IEVNT_RX_ECC_ER)
+-              memac->exception_cb(memac->dev_id, FM_MAC_EX_10G_RX_ECC_ER);
+-}
+-
+-static void memac_exception(void *handle)
+-{
+-      struct fman_mac *memac = (struct fman_mac *)handle;
+-      struct memac_regs __iomem *regs = memac->regs;
+-      u32 event, imask;
+-
+-      event = ioread32be(&regs->ievent);
+-      imask = ioread32be(&regs->imask);
+-
+-      /* Imask include both error and notification/event bits.
+-       * Leaving only error bits enabled by imask.
+-       * The imask error bits are shifted by 16 bits offset from
+-       * their corresponding location in the ievent - hence the >> 16
+-       */
+-      event &= ((imask & MEMAC_ALL_ERRS_IMASK) >> 16);
+-
+-      iowrite32be(event, &regs->ievent);
+-
+-      if (event & MEMAC_IEVNT_MGI)
+-              memac->exception_cb(memac->dev_id,
+-                                  FM_MAC_EX_MAGIC_PACKET_INDICATION);
+-}
+-
+-static void free_init_resources(struct fman_mac *memac)
+-{
+-      fman_unregister_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id,
+-                           FMAN_INTR_TYPE_ERR);
+-
+-      fman_unregister_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id,
+-                           FMAN_INTR_TYPE_NORMAL);
+-
+-      /* release the driver's group hash table */
+-      free_hash_table(memac->multicast_addr_hash);
+-      memac->multicast_addr_hash = NULL;
+-
+-      /* release the driver's individual hash table */
+-      free_hash_table(memac->unicast_addr_hash);
+-      memac->unicast_addr_hash = NULL;
+-}
+-
+-static bool is_init_done(struct memac_cfg *memac_drv_params)
+-{
+-      /* Checks if mEMAC driver parameters were initialized */
+-      if (!memac_drv_params)
+-              return true;
+-
+-      return false;
+-}
+-
+-int memac_enable(struct fman_mac *memac, enum comm_mode mode)
+-{
+-      struct memac_regs __iomem *regs = memac->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->command_config);
+-      if (mode & COMM_MODE_RX)
+-              tmp |= CMD_CFG_RX_EN;
+-      if (mode & COMM_MODE_TX)
+-              tmp |= CMD_CFG_TX_EN;
+-
+-      iowrite32be(tmp, &regs->command_config);
+-
+-      return 0;
+-}
+-
+-int memac_disable(struct fman_mac *memac, enum comm_mode mode)
+-{
+-      struct memac_regs __iomem *regs = memac->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->command_config);
+-      if (mode & COMM_MODE_RX)
+-              tmp &= ~CMD_CFG_RX_EN;
+-      if (mode & COMM_MODE_TX)
+-              tmp &= ~CMD_CFG_TX_EN;
+-
+-      iowrite32be(tmp, &regs->command_config);
+-
+-      return 0;
+-}
+-
+-int memac_set_promiscuous(struct fman_mac *memac, bool new_val)
+-{
+-      struct memac_regs __iomem *regs = memac->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->command_config);
+-      if (new_val)
+-              tmp |= CMD_CFG_PROMIS_EN;
+-      else
+-              tmp &= ~CMD_CFG_PROMIS_EN;
+-
+-      iowrite32be(tmp, &regs->command_config);
+-
+-      return 0;
+-}
+-
+-int memac_adjust_link(struct fman_mac *memac, u16 speed)
+-{
+-      struct memac_regs __iomem *regs = memac->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->if_mode);
+-
+-      /* Set full duplex */
+-      tmp &= ~IF_MODE_HD;
+-
+-      if (memac->phy_if == PHY_INTERFACE_MODE_RGMII) {
+-              /* Configure RGMII in manual mode */
+-              tmp &= ~IF_MODE_RGMII_AUTO;
+-              tmp &= ~IF_MODE_RGMII_SP_MASK;
+-              /* Full duplex */
+-              tmp |= IF_MODE_RGMII_FD;
+-
+-              switch (speed) {
+-              case SPEED_1000:
+-                      tmp |= IF_MODE_RGMII_1000;
+-                      break;
+-              case SPEED_100:
+-                      tmp |= IF_MODE_RGMII_100;
+-                      break;
+-              case SPEED_10:
+-                      tmp |= IF_MODE_RGMII_10;
+-                      break;
+-              default:
+-                      break;
+-              }
+-      }
+-
+-      iowrite32be(tmp, &regs->if_mode);
+-
+-      return 0;
+-}
+-
+-int memac_cfg_max_frame_len(struct fman_mac *memac, u16 new_val)
+-{
+-      if (is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      memac->memac_drv_param->max_frame_length = new_val;
+-
+-      return 0;
+-}
+-
+-int memac_cfg_reset_on_init(struct fman_mac *memac, bool enable)
+-{
+-      if (is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      memac->memac_drv_param->reset_on_init = enable;
+-
+-      return 0;
+-}
+-
+-int memac_cfg_fixed_link(struct fman_mac *memac,
+-                       struct fixed_phy_status *fixed_link)
+-{
+-      if (is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      memac->memac_drv_param->fixed_link = fixed_link;
+-
+-      return 0;
+-}
+-
+-int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority,
+-                            u16 pause_time, u16 thresh_time)
+-{
+-      struct memac_regs __iomem *regs = memac->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->tx_fifo_sections);
+-
+-      GET_TX_EMPTY_DEFAULT_VALUE(tmp);
+-      iowrite32be(tmp, &regs->tx_fifo_sections);
+-
+-      tmp = ioread32be(&regs->command_config);
+-      tmp &= ~CMD_CFG_PFC_MODE;
+-      priority = 0;
+-
+-      iowrite32be(tmp, &regs->command_config);
+-
+-      tmp = ioread32be(&regs->pause_quanta[priority / 2]);
+-      if (priority % 2)
+-              tmp &= CLXY_PAUSE_QUANTA_CLX_PQNT;
+-      else
+-              tmp &= CLXY_PAUSE_QUANTA_CLY_PQNT;
+-      tmp |= ((u32)pause_time << (16 * (priority % 2)));
+-      iowrite32be(tmp, &regs->pause_quanta[priority / 2]);
+-
+-      tmp = ioread32be(&regs->pause_thresh[priority / 2]);
+-      if (priority % 2)
+-              tmp &= CLXY_PAUSE_THRESH_CLX_QTH;
+-      else
+-              tmp &= CLXY_PAUSE_THRESH_CLY_QTH;
+-      tmp |= ((u32)thresh_time << (16 * (priority % 2)));
+-      iowrite32be(tmp, &regs->pause_thresh[priority / 2]);
+-
+-      return 0;
+-}
+-
+-int memac_accept_rx_pause_frames(struct fman_mac *memac, bool en)
+-{
+-      struct memac_regs __iomem *regs = memac->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->command_config);
+-      if (en)
+-              tmp &= ~CMD_CFG_PAUSE_IGNORE;
+-      else
+-              tmp |= CMD_CFG_PAUSE_IGNORE;
+-
+-      iowrite32be(tmp, &regs->command_config);
+-
+-      return 0;
+-}
+-
+-int memac_modify_mac_address(struct fman_mac *memac, enet_addr_t *enet_addr)
+-{
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      add_addr_in_paddr(memac->regs, (u8 *)(*enet_addr), 0);
+-
+-      return 0;
+-}
+-
+-int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
+-{
+-      struct memac_regs __iomem *regs = memac->regs;
+-      struct eth_hash_entry *hash_entry;
+-      u32 hash;
+-      u64 addr;
+-
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      addr = ENET_ADDR_TO_UINT64(*eth_addr);
+-
+-      if (!(addr & GROUP_ADDRESS)) {
+-              /* Unicast addresses not supported in hash */
+-              pr_err("Unicast Address\n");
+-              return -EINVAL;
+-      }
+-      hash = get_mac_addr_hash_code(addr) & HASH_CTRL_ADDR_MASK;
+-
+-      /* Create element to be added to the driver hash table */
+-      hash_entry = kmalloc(sizeof(*hash_entry), GFP_KERNEL);
+-      if (!hash_entry)
+-              return -ENOMEM;
+-      hash_entry->addr = addr;
+-      INIT_LIST_HEAD(&hash_entry->node);
+-
+-      list_add_tail(&hash_entry->node,
+-                    &memac->multicast_addr_hash->lsts[hash]);
+-      iowrite32be(hash | HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
+-
+-      return 0;
+-}
+-
+-int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr)
+-{
+-      struct memac_regs __iomem *regs = memac->regs;
+-      struct eth_hash_entry *hash_entry = NULL;
+-      struct list_head *pos;
+-      u32 hash;
+-      u64 addr;
+-
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      addr = ENET_ADDR_TO_UINT64(*eth_addr);
+-
+-      hash = get_mac_addr_hash_code(addr) & HASH_CTRL_ADDR_MASK;
+-
+-      list_for_each(pos, &memac->multicast_addr_hash->lsts[hash]) {
+-              hash_entry = ETH_HASH_ENTRY_OBJ(pos);
+-              if (hash_entry->addr == addr) {
+-                      list_del_init(&hash_entry->node);
+-                      kfree(hash_entry);
+-                      break;
+-              }
+-      }
+-      if (list_empty(&memac->multicast_addr_hash->lsts[hash]))
+-              iowrite32be(hash & ~HASH_CTRL_MCAST_EN, &regs->hashtable_ctrl);
+-
+-      return 0;
+-}
+-
+-int memac_set_exception(struct fman_mac *memac,
+-                      enum fman_mac_exceptions exception, bool enable)
+-{
+-      u32 bit_mask = 0;
+-
+-      if (!is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      bit_mask = get_exception_flag(exception);
+-      if (bit_mask) {
+-              if (enable)
+-                      memac->exceptions |= bit_mask;
+-              else
+-                      memac->exceptions &= ~bit_mask;
+-      } else {
+-              pr_err("Undefined exception\n");
+-              return -EINVAL;
+-      }
+-      set_exception(memac->regs, bit_mask, enable);
+-
+-      return 0;
+-}
+-
+-int memac_init(struct fman_mac *memac)
+-{
+-      struct memac_cfg *memac_drv_param;
+-      u8 i;
+-      enet_addr_t eth_addr;
+-      bool slow_10g_if = false;
+-      struct fixed_phy_status *fixed_link;
+-      int err;
+-      u32 reg32 = 0;
+-
+-      if (is_init_done(memac->memac_drv_param))
+-              return -EINVAL;
+-
+-      err = check_init_parameters(memac);
+-      if (err)
+-              return err;
+-
+-      memac_drv_param = memac->memac_drv_param;
+-
+-      if (memac->fm_rev_info.major == 6 && memac->fm_rev_info.minor == 4)
+-              slow_10g_if = true;
+-
+-      /* First, reset the MAC if desired. */
+-      if (memac_drv_param->reset_on_init) {
+-              err = reset(memac->regs);
+-              if (err) {
+-                      pr_err("mEMAC reset failed\n");
+-                      return err;
+-              }
+-      }
+-
+-      /* MAC Address */
+-      MAKE_ENET_ADDR_FROM_UINT64(memac->addr, eth_addr);
+-      add_addr_in_paddr(memac->regs, (u8 *)eth_addr, 0);
+-
+-      fixed_link = memac_drv_param->fixed_link;
+-
+-      init(memac->regs, memac->memac_drv_param, memac->phy_if,
+-           memac->max_speed, slow_10g_if, memac->exceptions);
+-
+-      /* FM_RX_FIFO_CORRUPT_ERRATA_10GMAC_A006320 errata workaround
+-       * Exists only in FMan 6.0 and 6.3.
+-       */
+-      if ((memac->fm_rev_info.major == 6) &&
+-          ((memac->fm_rev_info.minor == 0) ||
+-          (memac->fm_rev_info.minor == 3))) {
+-              /* MAC strips CRC from received frames - this workaround
+-               * should decrease the likelihood of bug appearance
+-               */
+-              reg32 = ioread32be(&memac->regs->command_config);
+-              reg32 &= ~CMD_CFG_CRC_FWD;
+-              iowrite32be(reg32, &memac->regs->command_config);
+-      }
+-
+-      if (memac->phy_if == PHY_INTERFACE_MODE_SGMII) {
+-              /* Configure internal SGMII PHY */
+-              if (memac->basex_if)
+-                      setup_sgmii_internal_phy_base_x(memac);
+-              else
+-                      setup_sgmii_internal_phy(memac, fixed_link);
+-      } else if (memac->phy_if == PHY_INTERFACE_MODE_QSGMII) {
+-              /* Configure 4 internal SGMII PHYs */
+-              for (i = 0; i < 4; i++) {
+-                      u8 qsmgii_phy_addr, phy_addr;
+-                      /* QSGMII PHY address occupies 3 upper bits of 5-bit
+-                       * phy_address; the lower 2 bits are used to extend
+-                       * register address space and access each one of 4
+-                       * ports inside QSGMII.
+-                       */
+-                      phy_addr = memac->pcsphy->mdio.addr;
+-                      qsmgii_phy_addr = (u8)((phy_addr << 2) | i);
+-                      memac->pcsphy->mdio.addr = qsmgii_phy_addr;
+-                      if (memac->basex_if)
+-                              setup_sgmii_internal_phy_base_x(memac);
+-                      else
+-                              setup_sgmii_internal_phy(memac, fixed_link);
+-
+-                      memac->pcsphy->mdio.addr = phy_addr;
+-              }
+-      }
+-
+-      /* Max Frame Length */
+-      err = fman_set_mac_max_frame(memac->fm, memac->mac_id,
+-                                   memac_drv_param->max_frame_length);
+-      if (err) {
+-              pr_err("settings Mac max frame length is FAILED\n");
+-              return err;
+-      }
+-
+-      memac->multicast_addr_hash = alloc_hash_table(HASH_TABLE_SIZE);
+-      if (!memac->multicast_addr_hash) {
+-              free_init_resources(memac);
+-              pr_err("allocation hash table is FAILED\n");
+-              return -ENOMEM;
+-      }
+-
+-      memac->unicast_addr_hash = alloc_hash_table(HASH_TABLE_SIZE);
+-      if (!memac->unicast_addr_hash) {
+-              free_init_resources(memac);
+-              pr_err("allocation hash table is FAILED\n");
+-              return -ENOMEM;
+-      }
+-
+-      fman_register_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id,
+-                         FMAN_INTR_TYPE_ERR, memac_err_exception, memac);
+-
+-      fman_register_intr(memac->fm, FMAN_MOD_MAC, memac->mac_id,
+-                         FMAN_INTR_TYPE_NORMAL, memac_exception, memac);
+-
+-      kfree(memac_drv_param);
+-      memac->memac_drv_param = NULL;
+-
+-      return 0;
+-}
+-
+-int memac_free(struct fman_mac *memac)
+-{
+-      free_init_resources(memac);
+-
+-      if (memac->pcsphy)
+-              put_device(&memac->pcsphy->mdio.dev);
+-
+-      kfree(memac->memac_drv_param);
+-      kfree(memac);
+-
+-      return 0;
+-}
+-
+-struct fman_mac *memac_config(struct fman_mac_params *params)
+-{
+-      struct fman_mac *memac;
+-      struct memac_cfg *memac_drv_param;
+-      void __iomem *base_addr;
+-
+-      base_addr = params->base_addr;
+-      /* allocate memory for the m_emac data structure */
+-      memac = kzalloc(sizeof(*memac), GFP_KERNEL);
+-      if (!memac)
+-              return NULL;
+-
+-      /* allocate memory for the m_emac driver parameters data structure */
+-      memac_drv_param = kzalloc(sizeof(*memac_drv_param), GFP_KERNEL);
+-      if (!memac_drv_param) {
+-              memac_free(memac);
+-              return NULL;
+-      }
+-
+-      /* Plant parameter structure pointer */
+-      memac->memac_drv_param = memac_drv_param;
+-
+-      set_dflts(memac_drv_param);
+-
+-      memac->addr = ENET_ADDR_TO_UINT64(params->addr);
+-
+-      memac->regs = base_addr;
+-      memac->max_speed = params->max_speed;
+-      memac->phy_if = params->phy_if;
+-      memac->mac_id = params->mac_id;
+-      memac->exceptions = (MEMAC_IMASK_TSECC_ER | MEMAC_IMASK_TECC_ER |
+-                           MEMAC_IMASK_RECC_ER | MEMAC_IMASK_MGI);
+-      memac->exception_cb = params->exception_cb;
+-      memac->event_cb = params->event_cb;
+-      memac->dev_id = params->dev_id;
+-      memac->fm = params->fm;
+-      memac->basex_if = params->basex_if;
+-
+-      /* Save FMan revision */
+-      fman_get_revision(memac->fm, &memac->fm_rev_info);
+-
+-      if (memac->phy_if == PHY_INTERFACE_MODE_SGMII ||
+-          memac->phy_if == PHY_INTERFACE_MODE_QSGMII) {
+-              if (!params->internal_phy_node) {
+-                      pr_err("PCS PHY node is not available\n");
+-                      memac_free(memac);
+-                      return NULL;
+-              }
+-
+-              memac->pcsphy = of_phy_find_device(params->internal_phy_node);
+-              if (!memac->pcsphy) {
+-                      pr_err("of_phy_find_device (PCS PHY) failed\n");
+-                      memac_free(memac);
+-                      return NULL;
+-              }
+-      }
+-
+-      return memac;
+-}
+diff --git a/drivers/net/ethernet/freescale/fman/fman_memac.h b/drivers/net/ethernet/freescale/fman/fman_memac.h
+deleted file mode 100644
+index 173d8e0..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman_memac.h
++++ /dev/null
+@@ -1,60 +0,0 @@
+-/*
+- * Copyright 2008-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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#ifndef __MEMAC_H
+-#define __MEMAC_H
+-
+-#include "fman_mac.h"
+-
+-#include <linux/netdevice.h>
+-
+-struct fman_mac *memac_config(struct fman_mac_params *params);
+-int memac_set_promiscuous(struct fman_mac *memac, bool new_val);
+-int memac_modify_mac_address(struct fman_mac *memac, enet_addr_t *enet_addr);
+-int memac_adjust_link(struct fman_mac *memac, u16 speed);
+-int memac_cfg_max_frame_len(struct fman_mac *memac, u16 new_val);
+-int memac_cfg_reset_on_init(struct fman_mac *memac, bool enable);
+-int memac_cfg_fixed_link(struct fman_mac *memac,
+-                       struct fixed_phy_status *fixed_link);
+-int memac_enable(struct fman_mac *memac, enum comm_mode mode);
+-int memac_disable(struct fman_mac *memac, enum comm_mode mode);
+-int memac_init(struct fman_mac *memac);
+-int memac_free(struct fman_mac *memac);
+-int memac_accept_rx_pause_frames(struct fman_mac *memac, bool en);
+-int memac_set_tx_pause_frames(struct fman_mac *memac, u8 priority,
+-                            u16 pause_time, u16 thresh_time);
+-int memac_set_exception(struct fman_mac *memac,
+-                      enum fman_mac_exceptions exception, bool enable);
+-int memac_add_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
+-int memac_del_hash_mac_address(struct fman_mac *memac, enet_addr_t *eth_addr);
+-
+-#endif /* __MEMAC_H */
+diff --git a/drivers/net/ethernet/freescale/fman/fman_muram.c b/drivers/net/ethernet/freescale/fman/fman_muram.c
+deleted file mode 100644
+index 5ec94d2..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman_muram.c
++++ /dev/null
+@@ -1,159 +0,0 @@
+-/*
+- * Copyright 2008-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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#include "fman_muram.h"
+-
+-#include <linux/io.h>
+-#include <linux/slab.h>
+-#include <linux/genalloc.h>
+-
+-struct muram_info {
+-      struct gen_pool *pool;
+-      void __iomem *vbase;
+-      size_t size;
+-      phys_addr_t pbase;
+-};
+-
+-static unsigned long fman_muram_vbase_to_offset(struct muram_info *muram,
+-                                              unsigned long vaddr)
+-{
+-      return vaddr - (unsigned long)muram->vbase;
+-}
+-
+-/**
+- * fman_muram_init
+- * @base:     Pointer to base of memory mapped FM-MURAM.
+- * @size:     Size of the FM-MURAM partition.
+- *
+- * Creates partition in the MURAM.
+- * The routine returns a pointer to the MURAM partition.
+- * This pointer must be passed as to all other FM-MURAM function calls.
+- * No actual initialization or configuration of FM_MURAM hardware is done by
+- * this routine.
+- *
+- * Return: pointer to FM-MURAM object, or NULL for Failure.
+- */
+-struct muram_info *fman_muram_init(phys_addr_t base, size_t size)
+-{
+-      struct muram_info *muram;
+-      void __iomem *vaddr;
+-      int ret;
+-
+-      muram = kzalloc(sizeof(*muram), GFP_KERNEL);
+-      if (!muram)
+-              return NULL;
+-
+-      muram->pool = gen_pool_create(ilog2(64), -1);
+-      if (!muram->pool) {
+-              pr_err("%s(): MURAM pool create failed\n", __func__);
+-              goto  muram_free;
+-      }
+-
+-      vaddr = ioremap(base, size);
+-      if (!vaddr) {
+-              pr_err("%s(): MURAM ioremap failed\n", __func__);
+-              goto pool_destroy;
+-      }
+-
+-      ret = gen_pool_add_virt(muram->pool, (unsigned long)vaddr,
+-                              base, size, -1);
+-      if (ret < 0) {
+-              pr_err("%s(): MURAM pool add failed\n", __func__);
+-              iounmap(vaddr);
+-              goto pool_destroy;
+-      }
+-
+-      memset_io(vaddr, 0, (int)size);
+-
+-      muram->vbase = vaddr;
+-      muram->pbase = base;
+-      return muram;
+-
+-pool_destroy:
+-      gen_pool_destroy(muram->pool);
+-muram_free:
+-      kfree(muram);
+-      return NULL;
+-}
+-
+-/**
+- * fman_muram_offset_to_vbase
+- * @muram:    FM-MURAM module pointer.
+- * @offset:   the offset of the memory block
+- *
+- * Gives the address of the memory region from specific offset
+- *
+- * Return: The address of the memory block
+- */
+-unsigned long fman_muram_offset_to_vbase(struct muram_info *muram,
+-                                       unsigned long offset)
+-{
+-      return offset + (unsigned long)muram->vbase;
+-}
+-
+-/**
+- * fman_muram_alloc
+- * @muram:    FM-MURAM module pointer.
+- * @size:     Size of the memory to be allocated.
+- *
+- * Allocate some memory from FM-MURAM partition.
+- *
+- * Return: address of the allocated memory; NULL otherwise.
+- */
+-unsigned long fman_muram_alloc(struct muram_info *muram, size_t size)
+-{
+-      unsigned long vaddr;
+-
+-      vaddr = gen_pool_alloc(muram->pool, size);
+-      if (!vaddr)
+-              return -ENOMEM;
+-
+-      memset_io((void __iomem *)vaddr, 0, size);
+-
+-      return fman_muram_vbase_to_offset(muram, vaddr);
+-}
+-
+-/**
+- * fman_muram_free_mem
+- * muram:     FM-MURAM module pointer.
+- * offset:    offset of the memory region to be freed.
+- * size:      size of the memory to be freed.
+- *
+- * Free an allocated memory from FM-MURAM partition.
+- */
+-void fman_muram_free_mem(struct muram_info *muram, unsigned long offset,
+-                       size_t size)
+-{
+-      unsigned long addr = fman_muram_offset_to_vbase(muram, offset);
+-
+-      gen_pool_free(muram->pool, addr, size);
+-}
+diff --git a/drivers/net/ethernet/freescale/fman/fman_muram.h b/drivers/net/ethernet/freescale/fman/fman_muram.h
+deleted file mode 100644
+index 453bf84..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman_muram.h
++++ /dev/null
+@@ -1,52 +0,0 @@
+-/*
+- * Copyright 2008-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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-#ifndef __FM_MURAM_EXT
+-#define __FM_MURAM_EXT
+-
+-#include <linux/types.h>
+-
+-#define FM_MURAM_INVALID_ALLOCATION   -1
+-
+-/* Structure for FM MURAM information */
+-struct muram_info;
+-
+-struct muram_info *fman_muram_init(phys_addr_t base, size_t size);
+-
+-unsigned long fman_muram_offset_to_vbase(struct muram_info *muram,
+-                                       unsigned long offset);
+-
+-unsigned long fman_muram_alloc(struct muram_info *muram, size_t size);
+-
+-void fman_muram_free_mem(struct muram_info *muram, unsigned long offset,
+-                       size_t size);
+-
+-#endif /* __FM_MURAM_EXT */
+diff --git a/drivers/net/ethernet/freescale/fman/fman_port.c b/drivers/net/ethernet/freescale/fman/fman_port.c
+deleted file mode 100644
+index 9f3bb50..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman_port.c
++++ /dev/null
+@@ -1,1791 +0,0 @@
+-/*
+- * Copyright 2008 - 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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+-
+-#include "fman_port.h"
+-#include "fman.h"
+-#include "fman_sp.h"
+-
+-#include <linux/io.h>
+-#include <linux/slab.h>
+-#include <linux/module.h>
+-#include <linux/interrupt.h>
+-#include <linux/of_platform.h>
+-#include <linux/of_address.h>
+-#include <linux/delay.h>
+-#include <linux/libfdt_env.h>
+-
+-/* Queue ID */
+-#define DFLT_FQ_ID            0x00FFFFFF
+-
+-/* General defines */
+-#define PORT_BMI_FIFO_UNITS           0x100
+-
+-#define MAX_PORT_FIFO_SIZE(bmi_max_fifo_size) \
+-      min((u32)bmi_max_fifo_size, (u32)1024 * FMAN_BMI_FIFO_UNITS)
+-
+-#define PORT_CG_MAP_NUM                       8
+-#define PORT_PRS_RESULT_WORDS_NUM     8
+-#define PORT_IC_OFFSET_UNITS          0x10
+-
+-#define MIN_EXT_BUF_SIZE              64
+-
+-#define BMI_PORT_REGS_OFFSET                          0
+-#define QMI_PORT_REGS_OFFSET                          0x400
+-
+-/* Default values */
+-#define DFLT_PORT_BUFFER_PREFIX_CONTEXT_DATA_ALIGN            \
+-      DFLT_FM_SP_BUFFER_PREFIX_CONTEXT_DATA_ALIGN
+-
+-#define DFLT_PORT_CUT_BYTES_FROM_END          4
+-
+-#define DFLT_PORT_ERRORS_TO_DISCARD           FM_PORT_FRM_ERR_CLS_DISCARD
+-#define DFLT_PORT_MAX_FRAME_LENGTH            9600
+-
+-#define DFLT_PORT_RX_FIFO_PRI_ELEVATION_LEV(bmi_max_fifo_size)        \
+-      MAX_PORT_FIFO_SIZE(bmi_max_fifo_size)
+-
+-#define DFLT_PORT_RX_FIFO_THRESHOLD(major, bmi_max_fifo_size) \
+-      (major == 6 ?                                           \
+-      MAX_PORT_FIFO_SIZE(bmi_max_fifo_size) :         \
+-      (MAX_PORT_FIFO_SIZE(bmi_max_fifo_size) * 3 / 4))        \
+-
+-#define DFLT_PORT_EXTRA_NUM_OF_FIFO_BUFS              0
+-
+-/* QMI defines */
+-#define QMI_DEQ_CFG_SUBPORTAL_MASK            0x1f
+-
+-#define QMI_PORT_CFG_EN                               0x80000000
+-#define QMI_PORT_STATUS_DEQ_FD_BSY            0x20000000
+-
+-#define QMI_DEQ_CFG_PRI                               0x80000000
+-#define QMI_DEQ_CFG_TYPE1                     0x10000000
+-#define QMI_DEQ_CFG_TYPE2                     0x20000000
+-#define QMI_DEQ_CFG_TYPE3                     0x30000000
+-#define QMI_DEQ_CFG_PREFETCH_PARTIAL          0x01000000
+-#define QMI_DEQ_CFG_PREFETCH_FULL             0x03000000
+-#define QMI_DEQ_CFG_SP_MASK                   0xf
+-#define QMI_DEQ_CFG_SP_SHIFT                  20
+-
+-#define QMI_BYTE_COUNT_LEVEL_CONTROL(_type)   \
+-      (_type == FMAN_PORT_TYPE_TX ? 0x1400 : 0x400)
+-
+-/* BMI defins */
+-#define BMI_EBD_EN                            0x80000000
+-
+-#define BMI_PORT_CFG_EN                               0x80000000
+-
+-#define BMI_PORT_STATUS_BSY                   0x80000000
+-
+-#define BMI_DMA_ATTR_SWP_SHIFT                        FMAN_SP_DMA_ATTR_SWP_SHIFT
+-#define BMI_DMA_ATTR_WRITE_OPTIMIZE           FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE
+-
+-#define BMI_RX_FIFO_PRI_ELEVATION_SHIFT       16
+-#define BMI_RX_FIFO_THRESHOLD_ETHE            0x80000000
+-
+-#define BMI_FRAME_END_CS_IGNORE_SHIFT         24
+-#define BMI_FRAME_END_CS_IGNORE_MASK          0x0000001f
+-
+-#define BMI_RX_FRAME_END_CUT_SHIFT            16
+-#define BMI_RX_FRAME_END_CUT_MASK             0x0000001f
+-
+-#define BMI_IC_TO_EXT_SHIFT                   FMAN_SP_IC_TO_EXT_SHIFT
+-#define BMI_IC_TO_EXT_MASK                    0x0000001f
+-#define BMI_IC_FROM_INT_SHIFT                 FMAN_SP_IC_FROM_INT_SHIFT
+-#define BMI_IC_FROM_INT_MASK                  0x0000000f
+-#define BMI_IC_SIZE_MASK                      0x0000001f
+-
+-#define BMI_INT_BUF_MARG_SHIFT                        28
+-#define BMI_INT_BUF_MARG_MASK                 0x0000000f
+-#define BMI_EXT_BUF_MARG_START_SHIFT          FMAN_SP_EXT_BUF_MARG_START_SHIFT
+-#define BMI_EXT_BUF_MARG_START_MASK           0x000001ff
+-#define BMI_EXT_BUF_MARG_END_MASK             0x000001ff
+-
+-#define BMI_CMD_MR_LEAC                               0x00200000
+-#define BMI_CMD_MR_SLEAC                      0x00100000
+-#define BMI_CMD_MR_MA                         0x00080000
+-#define BMI_CMD_MR_DEAS                               0x00040000
+-#define BMI_CMD_RX_MR_DEF                     (BMI_CMD_MR_LEAC | \
+-                                              BMI_CMD_MR_SLEAC | \
+-                                              BMI_CMD_MR_MA | \
+-                                              BMI_CMD_MR_DEAS)
+-#define BMI_CMD_TX_MR_DEF                     0
+-
+-#define BMI_CMD_ATTR_ORDER                    0x80000000
+-#define BMI_CMD_ATTR_SYNC                     0x02000000
+-#define BMI_CMD_ATTR_COLOR_SHIFT              26
+-
+-#define BMI_FIFO_PIPELINE_DEPTH_SHIFT         12
+-#define BMI_FIFO_PIPELINE_DEPTH_MASK          0x0000000f
+-#define BMI_NEXT_ENG_FD_BITS_SHIFT            24
+-
+-#define BMI_EXT_BUF_POOL_VALID                        FMAN_SP_EXT_BUF_POOL_VALID
+-#define BMI_EXT_BUF_POOL_EN_COUNTER           FMAN_SP_EXT_BUF_POOL_EN_COUNTER
+-#define BMI_EXT_BUF_POOL_BACKUP               FMAN_SP_EXT_BUF_POOL_BACKUP
+-#define BMI_EXT_BUF_POOL_ID_SHIFT             16
+-#define BMI_EXT_BUF_POOL_ID_MASK              0x003F0000
+-#define BMI_POOL_DEP_NUM_OF_POOLS_SHIFT       16
+-
+-#define BMI_TX_FIFO_MIN_FILL_SHIFT            16
+-
+-#define BMI_PRIORITY_ELEVATION_LEVEL ((0x3FF + 1) * PORT_BMI_FIFO_UNITS)
+-#define BMI_FIFO_THRESHOLD          ((0x3FF + 1) * PORT_BMI_FIFO_UNITS)
+-
+-#define BMI_DEQUEUE_PIPELINE_DEPTH(_type, _speed)             \
+-      ((_type == FMAN_PORT_TYPE_TX && _speed == 10000) ? 4 : 1)
+-
+-#define RX_ERRS_TO_ENQ                                  \
+-      (FM_PORT_FRM_ERR_DMA                    | \
+-      FM_PORT_FRM_ERR_PHYSICAL                | \
+-      FM_PORT_FRM_ERR_SIZE                    | \
+-      FM_PORT_FRM_ERR_EXTRACTION              | \
+-      FM_PORT_FRM_ERR_NO_SCHEME               | \
+-      FM_PORT_FRM_ERR_PRS_TIMEOUT             | \
+-      FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT        | \
+-      FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED    | \
+-      FM_PORT_FRM_ERR_PRS_HDR_ERR             | \
+-      FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW        | \
+-      FM_PORT_FRM_ERR_IPRE)
+-
+-/* NIA defines */
+-#define NIA_ORDER_RESTOR                              0x00800000
+-#define NIA_ENG_BMI                                   0x00500000
+-#define NIA_ENG_QMI_ENQ                                       0x00540000
+-#define NIA_ENG_QMI_DEQ                                       0x00580000
+-
+-#define NIA_BMI_AC_ENQ_FRAME                          0x00000002
+-#define NIA_BMI_AC_TX_RELEASE                         0x000002C0
+-#define NIA_BMI_AC_RELEASE                            0x000000C0
+-#define NIA_BMI_AC_TX                                 0x00000274
+-#define NIA_BMI_AC_FETCH_ALL_FRAME                    0x0000020c
+-
+-/* Port IDs */
+-#define TX_10G_PORT_BASE              0x30
+-#define RX_10G_PORT_BASE              0x10
+-
+-/* BMI Rx port register map */
+-struct fman_port_rx_bmi_regs {
+-      u32 fmbm_rcfg;          /* Rx Configuration */
+-      u32 fmbm_rst;           /* Rx Status */
+-      u32 fmbm_rda;           /* Rx DMA attributes */
+-      u32 fmbm_rfp;           /* Rx FIFO Parameters */
+-      u32 fmbm_rfed;          /* Rx Frame End Data */
+-      u32 fmbm_ricp;          /* Rx Internal Context Parameters */
+-      u32 fmbm_rim;           /* Rx Internal Buffer Margins */
+-      u32 fmbm_rebm;          /* Rx External Buffer Margins */
+-      u32 fmbm_rfne;          /* Rx Frame Next Engine */
+-      u32 fmbm_rfca;          /* Rx Frame Command Attributes. */
+-      u32 fmbm_rfpne;         /* Rx Frame Parser Next Engine */
+-      u32 fmbm_rpso;          /* Rx Parse Start Offset */
+-      u32 fmbm_rpp;           /* Rx Policer Profile  */
+-      u32 fmbm_rccb;          /* Rx Coarse Classification Base */
+-      u32 fmbm_reth;          /* Rx Excessive Threshold */
+-      u32 reserved003c[1];    /* (0x03C 0x03F) */
+-      u32 fmbm_rprai[PORT_PRS_RESULT_WORDS_NUM];
+-      /* Rx Parse Results Array Init */
+-      u32 fmbm_rfqid;         /* Rx Frame Queue ID */
+-      u32 fmbm_refqid;        /* Rx Error Frame Queue ID */
+-      u32 fmbm_rfsdm;         /* Rx Frame Status Discard Mask */
+-      u32 fmbm_rfsem;         /* Rx Frame Status Error Mask */
+-      u32 fmbm_rfene;         /* Rx Frame Enqueue Next Engine */
+-      u32 reserved0074[0x2];  /* (0x074-0x07C)  */
+-      u32 fmbm_rcmne;         /* Rx Frame Continuous Mode Next Engine */
+-      u32 reserved0080[0x20]; /* (0x080 0x0FF)  */
+-      u32 fmbm_ebmpi[FMAN_PORT_MAX_EXT_POOLS_NUM];
+-      /* Buffer Manager pool Information- */
+-      u32 fmbm_acnt[FMAN_PORT_MAX_EXT_POOLS_NUM];     /* Allocate Counter- */
+-      u32 reserved0130[8];    /* 0x130/0x140 - 0x15F reserved - */
+-      u32 fmbm_rcgm[PORT_CG_MAP_NUM]; /* Congestion Group Map */
+-      u32 fmbm_mpd;           /* BM Pool Depletion  */
+-      u32 reserved0184[0x1F]; /* (0x184 0x1FF) */
+-      u32 fmbm_rstc;          /* Rx Statistics Counters */
+-      u32 fmbm_rfrc;          /* Rx Frame Counter */
+-      u32 fmbm_rfbc;          /* Rx Bad Frames Counter */
+-      u32 fmbm_rlfc;          /* Rx Large Frames Counter */
+-      u32 fmbm_rffc;          /* Rx Filter Frames Counter */
+-      u32 fmbm_rfdc;          /* Rx Frame Discard Counter */
+-      u32 fmbm_rfldec;                /* Rx Frames List DMA Error Counter */
+-      u32 fmbm_rodc;          /* Rx Out of Buffers Discard nntr */
+-      u32 fmbm_rbdc;          /* Rx Buffers Deallocate Counter */
+-      u32 fmbm_rpec;          /* RX Prepare to enqueue Counte */
+-      u32 reserved0224[0x16]; /* (0x224 0x27F) */
+-      u32 fmbm_rpc;           /* Rx Performance Counters */
+-      u32 fmbm_rpcp;          /* Rx Performance Count Parameters */
+-      u32 fmbm_rccn;          /* Rx Cycle Counter */
+-      u32 fmbm_rtuc;          /* Rx Tasks Utilization Counter */
+-      u32 fmbm_rrquc;         /* Rx Receive Queue Utilization cntr */
+-      u32 fmbm_rduc;          /* Rx DMA Utilization Counter */
+-      u32 fmbm_rfuc;          /* Rx FIFO Utilization Counter */
+-      u32 fmbm_rpac;          /* Rx Pause Activation Counter */
+-      u32 reserved02a0[0x18]; /* (0x2A0 0x2FF) */
+-      u32 fmbm_rdcfg[0x3];    /* Rx Debug Configuration */
+-      u32 fmbm_rgpr;          /* Rx General Purpose Register */
+-      u32 reserved0310[0x3a];
+-};
+-
+-/* BMI Tx port register map */
+-struct fman_port_tx_bmi_regs {
+-      u32 fmbm_tcfg;          /* Tx Configuration */
+-      u32 fmbm_tst;           /* Tx Status */
+-      u32 fmbm_tda;           /* Tx DMA attributes */
+-      u32 fmbm_tfp;           /* Tx FIFO Parameters */
+-      u32 fmbm_tfed;          /* Tx Frame End Data */
+-      u32 fmbm_ticp;          /* Tx Internal Context Parameters */
+-      u32 fmbm_tfdne;         /* Tx Frame Dequeue Next Engine. */
+-      u32 fmbm_tfca;          /* Tx Frame Command attribute. */
+-      u32 fmbm_tcfqid;        /* Tx Confirmation Frame Queue ID. */
+-      u32 fmbm_tefqid;        /* Tx Frame Error Queue ID */
+-      u32 fmbm_tfene;         /* Tx Frame Enqueue Next Engine */
+-      u32 fmbm_trlmts;        /* Tx Rate Limiter Scale */
+-      u32 fmbm_trlmt;         /* Tx Rate Limiter */
+-      u32 reserved0034[0x0e]; /* (0x034-0x6c) */
+-      u32 fmbm_tccb;          /* Tx Coarse Classification base */
+-      u32 fmbm_tfne;          /* Tx Frame Next Engine */
+-      u32 fmbm_tpfcm[0x02];
+-      /* Tx Priority based Flow Control (PFC) Mapping */
+-      u32 fmbm_tcmne;         /* Tx Frame Continuous Mode Next Engine */
+-      u32 reserved0080[0x60]; /* (0x080-0x200) */
+-      u32 fmbm_tstc;          /* Tx Statistics Counters */
+-      u32 fmbm_tfrc;          /* Tx Frame Counter */
+-      u32 fmbm_tfdc;          /* Tx Frames Discard Counter */
+-      u32 fmbm_tfledc;        /* Tx Frame len error discard cntr */
+-      u32 fmbm_tfufdc;        /* Tx Frame unsprt frmt discard cntr */
+-      u32 fmbm_tbdc;          /* Tx Buffers Deallocate Counter */
+-      u32 reserved0218[0x1A]; /* (0x218-0x280) */
+-      u32 fmbm_tpc;           /* Tx Performance Counters */
+-      u32 fmbm_tpcp;          /* Tx Performance Count Parameters */
+-      u32 fmbm_tccn;          /* Tx Cycle Counter */
+-      u32 fmbm_ttuc;          /* Tx Tasks Utilization Counter */
+-      u32 fmbm_ttcquc;        /* Tx Transmit conf Q util Counter */
+-      u32 fmbm_tduc;          /* Tx DMA Utilization Counter */
+-      u32 fmbm_tfuc;          /* Tx FIFO Utilization Counter */
+-      u32 reserved029c[16];   /* (0x29C-0x2FF) */
+-      u32 fmbm_tdcfg[0x3];    /* Tx Debug Configuration */
+-      u32 fmbm_tgpr;          /* Tx General Purpose Register */
+-      u32 reserved0310[0x3a]; /* (0x310-0x3FF) */
+-};
+-
+-/* BMI port register map */
+-union fman_port_bmi_regs {
+-      struct fman_port_rx_bmi_regs rx;
+-      struct fman_port_tx_bmi_regs tx;
+-};
+-
+-/* QMI port register map */
+-struct fman_port_qmi_regs {
+-      u32 fmqm_pnc;           /* PortID n Configuration Register */
+-      u32 fmqm_pns;           /* PortID n Status Register */
+-      u32 fmqm_pnts;          /* PortID n Task Status Register */
+-      u32 reserved00c[4];     /* 0xn00C - 0xn01B */
+-      u32 fmqm_pnen;          /* PortID n Enqueue NIA Register */
+-      u32 fmqm_pnetfc;                /* PortID n Enq Total Frame Counter */
+-      u32 reserved024[2];     /* 0xn024 - 0x02B */
+-      u32 fmqm_pndn;          /* PortID n Dequeue NIA Register */
+-      u32 fmqm_pndc;          /* PortID n Dequeue Config Register */
+-      u32 fmqm_pndtfc;                /* PortID n Dequeue tot Frame cntr */
+-      u32 fmqm_pndfdc;                /* PortID n Dequeue FQID Dflt Cntr */
+-      u32 fmqm_pndcc;         /* PortID n Dequeue Confirm Counter */
+-};
+-
+-/* QMI dequeue prefetch modes */
+-enum fman_port_deq_prefetch {
+-      FMAN_PORT_DEQ_NO_PREFETCH, /* No prefetch mode */
+-      FMAN_PORT_DEQ_PART_PREFETCH, /* Partial prefetch mode */
+-      FMAN_PORT_DEQ_FULL_PREFETCH /* Full prefetch mode */
+-};
+-
+-/* A structure for defining FM port resources */
+-struct fman_port_rsrc {
+-      u32 num; /* Committed required resource */
+-      u32 extra; /* Extra (not committed) required resource */
+-};
+-
+-enum fman_port_dma_swap {
+-      FMAN_PORT_DMA_NO_SWAP,  /* No swap, transfer data as is */
+-      FMAN_PORT_DMA_SWAP_LE,
+-      /* The transferred data should be swapped in PPC Little Endian mode */
+-      FMAN_PORT_DMA_SWAP_BE
+-      /* The transferred data should be swapped in Big Endian mode */
+-};
+-
+-/* Default port color */
+-enum fman_port_color {
+-      FMAN_PORT_COLOR_GREEN,  /* Default port color is green */
+-      FMAN_PORT_COLOR_YELLOW, /* Default port color is yellow */
+-      FMAN_PORT_COLOR_RED,            /* Default port color is red */
+-      FMAN_PORT_COLOR_OVERRIDE        /* Ignore color */
+-};
+-
+-/* QMI dequeue from the SP channel - types */
+-enum fman_port_deq_type {
+-      FMAN_PORT_DEQ_BY_PRI,
+-      /* Priority precedence and Intra-Class scheduling */
+-      FMAN_PORT_DEQ_ACTIVE_FQ,
+-      /* Active FQ precedence and Intra-Class scheduling */
+-      FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS
+-      /* Active FQ precedence and override Intra-Class scheduling */
+-};
+-
+-/* External buffer pools configuration */
+-struct fman_port_bpools {
+-      u8 count;                       /* Num of pools to set up */
+-      bool counters_enable;           /* Enable allocate counters */
+-      u8 grp_bp_depleted_num;
+-      /* Number of depleted pools - if reached the BMI indicates
+-       * the MAC to send a pause frame
+-       */
+-      struct {
+-              u8 bpid;                /* BM pool ID */
+-              u16 size;
+-              /* Pool's size - must be in ascending order */
+-              bool is_backup;
+-              /* If this is a backup pool */
+-              bool grp_bp_depleted;
+-              /* Consider this buffer in multiple pools depletion criteria */
+-              bool single_bp_depleted;
+-              /* Consider this buffer in single pool depletion criteria */
+-      } bpool[FMAN_PORT_MAX_EXT_POOLS_NUM];
+-};
+-
+-struct fman_port_cfg {
+-      u32 dflt_fqid;
+-      u32 err_fqid;
+-      u8 deq_sp;
+-      bool deq_high_priority;
+-      enum fman_port_deq_type deq_type;
+-      enum fman_port_deq_prefetch deq_prefetch_option;
+-      u16 deq_byte_cnt;
+-      u8 cheksum_last_bytes_ignore;
+-      u8 rx_cut_end_bytes;
+-      struct fman_buf_pool_depletion buf_pool_depletion;
+-      struct fman_ext_pools ext_buf_pools;
+-      u32 tx_fifo_min_level;
+-      u32 tx_fifo_low_comf_level;
+-      u32 rx_pri_elevation;
+-      u32 rx_fifo_thr;
+-      struct fman_sp_buf_margins buf_margins;
+-      u32 int_buf_start_margin;
+-      struct fman_sp_int_context_data_copy int_context;
+-      u32 discard_mask;
+-      u32 err_mask;
+-      struct fman_buffer_prefix_content buffer_prefix_content;
+-      bool dont_release_buf;
+-
+-      u8 rx_fd_bits;
+-      u32 tx_fifo_deq_pipeline_depth;
+-      bool errata_A006320;
+-      bool excessive_threshold_register;
+-      bool fmbm_tfne_has_features;
+-
+-      enum fman_port_dma_swap dma_swap_data;
+-      enum fman_port_color color;
+-};
+-
+-struct fman_port_rx_pools_params {
+-      u8 num_of_pools;
+-      u16 second_largest_buf_size;
+-      u16 largest_buf_size;
+-};
+-
+-struct fman_port_dts_params {
+-      void __iomem *base_addr;        /* FMan port virtual memory */
+-      enum fman_port_type type;       /* Port type */
+-      u16 speed;                      /* Port speed */
+-      u8 id;                          /* HW Port Id */
+-      u32 qman_channel_id;            /* QMan channel id (non RX only) */
+-      struct fman *fman;              /* FMan Handle */
+-};
+-
+-struct fman_port {
+-      void *fm;
+-      struct device *dev;
+-      struct fman_rev_info rev_info;
+-      u8 port_id;
+-      enum fman_port_type port_type;
+-      u16 port_speed;
+-
+-      union fman_port_bmi_regs __iomem *bmi_regs;
+-      struct fman_port_qmi_regs __iomem *qmi_regs;
+-
+-      struct fman_sp_buffer_offsets buffer_offsets;
+-
+-      u8 internal_buf_offset;
+-      struct fman_ext_pools ext_buf_pools;
+-
+-      u16 max_frame_length;
+-      struct fman_port_rsrc open_dmas;
+-      struct fman_port_rsrc tasks;
+-      struct fman_port_rsrc fifo_bufs;
+-      struct fman_port_rx_pools_params rx_pools_params;
+-
+-      struct fman_port_cfg *cfg;
+-      struct fman_port_dts_params dts_params;
+-
+-      u8 ext_pools_num;
+-      u32 max_port_fifo_size;
+-      u32 max_num_of_ext_pools;
+-      u32 max_num_of_sub_portals;
+-      u32 bm_max_num_of_pools;
+-};
+-
+-static int init_bmi_rx(struct fman_port *port)
+-{
+-      struct fman_port_rx_bmi_regs __iomem *regs = &port->bmi_regs->rx;
+-      struct fman_port_cfg *cfg = port->cfg;
+-      u32 tmp;
+-
+-      /* DMA attributes */
+-      tmp = (u32)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
+-      /* Enable write optimization */
+-      tmp |= BMI_DMA_ATTR_WRITE_OPTIMIZE;
+-      iowrite32be(tmp, &regs->fmbm_rda);
+-
+-      /* Rx FIFO parameters */
+-      tmp = (cfg->rx_pri_elevation / PORT_BMI_FIFO_UNITS - 1) <<
+-              BMI_RX_FIFO_PRI_ELEVATION_SHIFT;
+-      tmp |= cfg->rx_fifo_thr / PORT_BMI_FIFO_UNITS - 1;
+-      iowrite32be(tmp, &regs->fmbm_rfp);
+-
+-      if (cfg->excessive_threshold_register)
+-              /* always allow access to the extra resources */
+-              iowrite32be(BMI_RX_FIFO_THRESHOLD_ETHE, &regs->fmbm_reth);
+-
+-      /* Frame end data */
+-      tmp = (cfg->cheksum_last_bytes_ignore & BMI_FRAME_END_CS_IGNORE_MASK) <<
+-              BMI_FRAME_END_CS_IGNORE_SHIFT;
+-      tmp |= (cfg->rx_cut_end_bytes & BMI_RX_FRAME_END_CUT_MASK) <<
+-              BMI_RX_FRAME_END_CUT_SHIFT;
+-      if (cfg->errata_A006320)
+-              tmp &= 0xffe0ffff;
+-      iowrite32be(tmp, &regs->fmbm_rfed);
+-
+-      /* Internal context parameters */
+-      tmp = ((cfg->int_context.ext_buf_offset / PORT_IC_OFFSET_UNITS) &
+-              BMI_IC_TO_EXT_MASK) << BMI_IC_TO_EXT_SHIFT;
+-      tmp |= ((cfg->int_context.int_context_offset / PORT_IC_OFFSET_UNITS) &
+-              BMI_IC_FROM_INT_MASK) << BMI_IC_FROM_INT_SHIFT;
+-      tmp |= (cfg->int_context.size / PORT_IC_OFFSET_UNITS) &
+-              BMI_IC_SIZE_MASK;
+-      iowrite32be(tmp, &regs->fmbm_ricp);
+-
+-      /* Internal buffer offset */
+-      tmp = ((cfg->int_buf_start_margin / PORT_IC_OFFSET_UNITS) &
+-              BMI_INT_BUF_MARG_MASK) << BMI_INT_BUF_MARG_SHIFT;
+-      iowrite32be(tmp, &regs->fmbm_rim);
+-
+-      /* External buffer margins */
+-      tmp = (cfg->buf_margins.start_margins & BMI_EXT_BUF_MARG_START_MASK) <<
+-              BMI_EXT_BUF_MARG_START_SHIFT;
+-      tmp |= cfg->buf_margins.end_margins & BMI_EXT_BUF_MARG_END_MASK;
+-      iowrite32be(tmp, &regs->fmbm_rebm);
+-
+-      /* Frame attributes */
+-      tmp = BMI_CMD_RX_MR_DEF;
+-      tmp |= BMI_CMD_ATTR_ORDER;
+-      tmp |= (u32)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
+-      /* Synchronization request */
+-      tmp |= BMI_CMD_ATTR_SYNC;
+-
+-      iowrite32be(tmp, &regs->fmbm_rfca);
+-
+-      /* NIA */
+-      tmp = (u32)cfg->rx_fd_bits << BMI_NEXT_ENG_FD_BITS_SHIFT;
+-
+-      tmp |= NIA_ENG_BMI | NIA_BMI_AC_ENQ_FRAME;
+-      iowrite32be(tmp, &regs->fmbm_rfne);
+-
+-      /* Enqueue NIA */
+-      iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_rfene);
+-
+-      /* Default/error queues */
+-      iowrite32be((cfg->dflt_fqid & DFLT_FQ_ID), &regs->fmbm_rfqid);
+-      iowrite32be((cfg->err_fqid & DFLT_FQ_ID), &regs->fmbm_refqid);
+-
+-      /* Discard/error masks */
+-      iowrite32be(cfg->discard_mask, &regs->fmbm_rfsdm);
+-      iowrite32be(cfg->err_mask, &regs->fmbm_rfsem);
+-
+-      return 0;
+-}
+-
+-static int init_bmi_tx(struct fman_port *port)
+-{
+-      struct fman_port_tx_bmi_regs __iomem *regs = &port->bmi_regs->tx;
+-      struct fman_port_cfg *cfg = port->cfg;
+-      u32 tmp;
+-
+-      /* Tx Configuration register */
+-      tmp = 0;
+-      iowrite32be(tmp, &regs->fmbm_tcfg);
+-
+-      /* DMA attributes */
+-      tmp = (u32)cfg->dma_swap_data << BMI_DMA_ATTR_SWP_SHIFT;
+-      iowrite32be(tmp, &regs->fmbm_tda);
+-
+-      /* Tx FIFO parameters */
+-      tmp = (cfg->tx_fifo_min_level / PORT_BMI_FIFO_UNITS) <<
+-              BMI_TX_FIFO_MIN_FILL_SHIFT;
+-      tmp |= ((cfg->tx_fifo_deq_pipeline_depth - 1) &
+-              BMI_FIFO_PIPELINE_DEPTH_MASK) << BMI_FIFO_PIPELINE_DEPTH_SHIFT;
+-      tmp |= (cfg->tx_fifo_low_comf_level / PORT_BMI_FIFO_UNITS) - 1;
+-      iowrite32be(tmp, &regs->fmbm_tfp);
+-
+-      /* Frame end data */
+-      tmp = (cfg->cheksum_last_bytes_ignore & BMI_FRAME_END_CS_IGNORE_MASK) <<
+-              BMI_FRAME_END_CS_IGNORE_SHIFT;
+-      iowrite32be(tmp, &regs->fmbm_tfed);
+-
+-      /* Internal context parameters */
+-      tmp = ((cfg->int_context.ext_buf_offset / PORT_IC_OFFSET_UNITS) &
+-              BMI_IC_TO_EXT_MASK) << BMI_IC_TO_EXT_SHIFT;
+-      tmp |= ((cfg->int_context.int_context_offset / PORT_IC_OFFSET_UNITS) &
+-              BMI_IC_FROM_INT_MASK) << BMI_IC_FROM_INT_SHIFT;
+-      tmp |= (cfg->int_context.size / PORT_IC_OFFSET_UNITS) &
+-              BMI_IC_SIZE_MASK;
+-      iowrite32be(tmp, &regs->fmbm_ticp);
+-
+-      /* Frame attributes */
+-      tmp = BMI_CMD_TX_MR_DEF;
+-      tmp |= BMI_CMD_ATTR_ORDER;
+-      tmp |= (u32)cfg->color << BMI_CMD_ATTR_COLOR_SHIFT;
+-      iowrite32be(tmp, &regs->fmbm_tfca);
+-
+-      /* Dequeue NIA + enqueue NIA */
+-      iowrite32be(NIA_ENG_QMI_DEQ, &regs->fmbm_tfdne);
+-      iowrite32be(NIA_ENG_QMI_ENQ | NIA_ORDER_RESTOR, &regs->fmbm_tfene);
+-      if (cfg->fmbm_tfne_has_features)
+-              iowrite32be(!cfg->dflt_fqid ?
+-                          BMI_EBD_EN | NIA_BMI_AC_FETCH_ALL_FRAME :
+-                          NIA_BMI_AC_FETCH_ALL_FRAME, &regs->fmbm_tfne);
+-      if (!cfg->dflt_fqid && cfg->dont_release_buf) {
+-              iowrite32be(DFLT_FQ_ID, &regs->fmbm_tcfqid);
+-              iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
+-                          &regs->fmbm_tfene);
+-              if (cfg->fmbm_tfne_has_features)
+-                      iowrite32be(ioread32be(&regs->fmbm_tfne) & ~BMI_EBD_EN,
+-                                  &regs->fmbm_tfne);
+-      }
+-
+-      /* Confirmation/error queues */
+-      if (cfg->dflt_fqid || !cfg->dont_release_buf)
+-              iowrite32be(cfg->dflt_fqid & DFLT_FQ_ID, &regs->fmbm_tcfqid);
+-      iowrite32be((cfg->err_fqid & DFLT_FQ_ID), &regs->fmbm_tefqid);
+-
+-      return 0;
+-}
+-
+-static int init_qmi(struct fman_port *port)
+-{
+-      struct fman_port_qmi_regs __iomem *regs = port->qmi_regs;
+-      struct fman_port_cfg *cfg = port->cfg;
+-      u32 tmp;
+-
+-      /* Rx port configuration */
+-      if (port->port_type == FMAN_PORT_TYPE_RX) {
+-              /* Enqueue NIA */
+-              iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_RELEASE, &regs->fmqm_pnen);
+-              return 0;
+-      }
+-
+-      /* Continue with Tx port configuration */
+-      if (port->port_type == FMAN_PORT_TYPE_TX) {
+-              /* Enqueue NIA */
+-              iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
+-                          &regs->fmqm_pnen);
+-              /* Dequeue NIA */
+-              iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX, &regs->fmqm_pndn);
+-      }
+-
+-      /* Dequeue Configuration register */
+-      tmp = 0;
+-      if (cfg->deq_high_priority)
+-              tmp |= QMI_DEQ_CFG_PRI;
+-
+-      switch (cfg->deq_type) {
+-      case FMAN_PORT_DEQ_BY_PRI:
+-              tmp |= QMI_DEQ_CFG_TYPE1;
+-              break;
+-      case FMAN_PORT_DEQ_ACTIVE_FQ:
+-              tmp |= QMI_DEQ_CFG_TYPE2;
+-              break;
+-      case FMAN_PORT_DEQ_ACTIVE_FQ_NO_ICS:
+-              tmp |= QMI_DEQ_CFG_TYPE3;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-
+-      switch (cfg->deq_prefetch_option) {
+-      case FMAN_PORT_DEQ_NO_PREFETCH:
+-              break;
+-      case FMAN_PORT_DEQ_PART_PREFETCH:
+-              tmp |= QMI_DEQ_CFG_PREFETCH_PARTIAL;
+-              break;
+-      case FMAN_PORT_DEQ_FULL_PREFETCH:
+-              tmp |= QMI_DEQ_CFG_PREFETCH_FULL;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-
+-      tmp |= (cfg->deq_sp & QMI_DEQ_CFG_SP_MASK) << QMI_DEQ_CFG_SP_SHIFT;
+-      tmp |= cfg->deq_byte_cnt;
+-      iowrite32be(tmp, &regs->fmqm_pndc);
+-
+-      return 0;
+-}
+-
+-static int init(struct fman_port *port)
+-{
+-      int err;
+-
+-      /* Init BMI registers */
+-      switch (port->port_type) {
+-      case FMAN_PORT_TYPE_RX:
+-              err = init_bmi_rx(port);
+-              break;
+-      case FMAN_PORT_TYPE_TX:
+-              err = init_bmi_tx(port);
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-
+-      if (err)
+-              return err;
+-
+-      /* Init QMI registers */
+-      err = init_qmi(port);
+-      return err;
+-
+-      return 0;
+-}
+-
+-static int set_bpools(const struct fman_port *port,
+-                    const struct fman_port_bpools *bp)
+-{
+-      u32 __iomem *bp_reg, *bp_depl_reg;
+-      u32 tmp;
+-      u8 i, max_bp_num;
+-      bool grp_depl_used = false, rx_port;
+-
+-      switch (port->port_type) {
+-      case FMAN_PORT_TYPE_RX:
+-              max_bp_num = port->ext_pools_num;
+-              rx_port = true;
+-              bp_reg = port->bmi_regs->rx.fmbm_ebmpi;
+-              bp_depl_reg = &port->bmi_regs->rx.fmbm_mpd;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-
+-      if (rx_port) {
+-              /* Check buffers are provided in ascending order */
+-              for (i = 0; (i < (bp->count - 1) &&
+-                           (i < FMAN_PORT_MAX_EXT_POOLS_NUM - 1)); i++) {
+-                      if (bp->bpool[i].size > bp->bpool[i + 1].size)
+-                              return -EINVAL;
+-              }
+-      }
+-
+-      /* Set up external buffers pools */
+-      for (i = 0; i < bp->count; i++) {
+-              tmp = BMI_EXT_BUF_POOL_VALID;
+-              tmp |= ((u32)bp->bpool[i].bpid <<
+-                      BMI_EXT_BUF_POOL_ID_SHIFT) & BMI_EXT_BUF_POOL_ID_MASK;
+-
+-              if (rx_port) {
+-                      if (bp->counters_enable)
+-                              tmp |= BMI_EXT_BUF_POOL_EN_COUNTER;
+-
+-                      if (bp->bpool[i].is_backup)
+-                              tmp |= BMI_EXT_BUF_POOL_BACKUP;
+-
+-                      tmp |= (u32)bp->bpool[i].size;
+-              }
+-
+-              iowrite32be(tmp, &bp_reg[i]);
+-      }
+-
+-      /* Clear unused pools */
+-      for (i = bp->count; i < max_bp_num; i++)
+-              iowrite32be(0, &bp_reg[i]);
+-
+-      /* Pools depletion */
+-      tmp = 0;
+-      for (i = 0; i < FMAN_PORT_MAX_EXT_POOLS_NUM; i++) {
+-              if (bp->bpool[i].grp_bp_depleted) {
+-                      grp_depl_used = true;
+-                      tmp |= 0x80000000 >> i;
+-              }
+-
+-              if (bp->bpool[i].single_bp_depleted)
+-                      tmp |= 0x80 >> i;
+-      }
+-
+-      if (grp_depl_used)
+-              tmp |= ((u32)bp->grp_bp_depleted_num - 1) <<
+-                  BMI_POOL_DEP_NUM_OF_POOLS_SHIFT;
+-
+-      iowrite32be(tmp, bp_depl_reg);
+-      return 0;
+-}
+-
+-static bool is_init_done(struct fman_port_cfg *cfg)
+-{
+-      /* Checks if FMan port driver parameters were initialized */
+-      if (!cfg)
+-              return true;
+-
+-      return false;
+-}
+-
+-static int verify_size_of_fifo(struct fman_port *port)
+-{
+-      u32 min_fifo_size_required = 0, opt_fifo_size_for_b2b = 0;
+-
+-      /* TX Ports */
+-      if (port->port_type == FMAN_PORT_TYPE_TX) {
+-              min_fifo_size_required = (u32)
+-                  (roundup(port->max_frame_length,
+-                           FMAN_BMI_FIFO_UNITS) + (3 * FMAN_BMI_FIFO_UNITS));
+-
+-              min_fifo_size_required +=
+-                  port->cfg->tx_fifo_deq_pipeline_depth *
+-                  FMAN_BMI_FIFO_UNITS;
+-
+-              opt_fifo_size_for_b2b = min_fifo_size_required;
+-
+-              /* Add some margin for back-to-back capability to improve
+-               * performance, allows the hardware to pipeline new frame dma
+-               * while the previous frame not yet transmitted.
+-               */
+-              if (port->port_speed == 10000)
+-                      opt_fifo_size_for_b2b += 3 * FMAN_BMI_FIFO_UNITS;
+-              else
+-                      opt_fifo_size_for_b2b += 2 * FMAN_BMI_FIFO_UNITS;
+-      }
+-
+-      /* RX Ports */
+-      else if (port->port_type == FMAN_PORT_TYPE_RX) {
+-              if (port->rev_info.major >= 6)
+-                      min_fifo_size_required = (u32)
+-                      (roundup(port->max_frame_length,
+-                               FMAN_BMI_FIFO_UNITS) +
+-                               (5 * FMAN_BMI_FIFO_UNITS));
+-                      /* 4 according to spec + 1 for FOF>0 */
+-              else
+-                      min_fifo_size_required = (u32)
+-                      (roundup(min(port->max_frame_length,
+-                                   port->rx_pools_params.largest_buf_size),
+-                                   FMAN_BMI_FIFO_UNITS) +
+-                                   (7 * FMAN_BMI_FIFO_UNITS));
+-
+-              opt_fifo_size_for_b2b = min_fifo_size_required;
+-
+-              /* Add some margin for back-to-back capability to improve
+-               * performance,allows the hardware to pipeline new frame dma
+-               * while the previous frame not yet transmitted.
+-               */
+-              if (port->port_speed == 10000)
+-                      opt_fifo_size_for_b2b += 8 * FMAN_BMI_FIFO_UNITS;
+-              else
+-                      opt_fifo_size_for_b2b += 3 * FMAN_BMI_FIFO_UNITS;
+-      }
+-
+-      WARN_ON(min_fifo_size_required <= 0);
+-      WARN_ON(opt_fifo_size_for_b2b < min_fifo_size_required);
+-
+-      /* Verify the size  */
+-      if (port->fifo_bufs.num < min_fifo_size_required)
+-              dev_dbg(port->dev, "%s: FIFO size should be enlarged to %d bytes\n",
+-                      __func__, min_fifo_size_required);
+-      else if (port->fifo_bufs.num < opt_fifo_size_for_b2b)
+-              dev_dbg(port->dev, "%s: For b2b processing,FIFO may be enlarged to %d bytes\n",
+-                      __func__, opt_fifo_size_for_b2b);
+-
+-      return 0;
+-}
+-
+-static int set_ext_buffer_pools(struct fman_port *port)
+-{
+-      struct fman_ext_pools *ext_buf_pools = &port->cfg->ext_buf_pools;
+-      struct fman_buf_pool_depletion *buf_pool_depletion =
+-      &port->cfg->buf_pool_depletion;
+-      u8 ordered_array[FMAN_PORT_MAX_EXT_POOLS_NUM];
+-      u16 sizes_array[BM_MAX_NUM_OF_POOLS];
+-      int i = 0, j = 0, err;
+-      struct fman_port_bpools bpools;
+-
+-      memset(&ordered_array, 0, sizeof(u8) * FMAN_PORT_MAX_EXT_POOLS_NUM);
+-      memset(&sizes_array, 0, sizeof(u16) * BM_MAX_NUM_OF_POOLS);
+-      memcpy(&port->ext_buf_pools, ext_buf_pools,
+-             sizeof(struct fman_ext_pools));
+-
+-      fman_sp_set_buf_pools_in_asc_order_of_buf_sizes(ext_buf_pools,
+-                                                      ordered_array,
+-                                                      sizes_array);
+-
+-      memset(&bpools, 0, sizeof(struct fman_port_bpools));
+-      bpools.count = ext_buf_pools->num_of_pools_used;
+-      bpools.counters_enable = true;
+-      for (i = 0; i < ext_buf_pools->num_of_pools_used; i++) {
+-              bpools.bpool[i].bpid = ordered_array[i];
+-              bpools.bpool[i].size = sizes_array[ordered_array[i]];
+-      }
+-
+-      /* save pools parameters for later use */
+-      port->rx_pools_params.num_of_pools = ext_buf_pools->num_of_pools_used;
+-      port->rx_pools_params.largest_buf_size =
+-          sizes_array[ordered_array[ext_buf_pools->num_of_pools_used - 1]];
+-      port->rx_pools_params.second_largest_buf_size =
+-          sizes_array[ordered_array[ext_buf_pools->num_of_pools_used - 2]];
+-
+-      /* FMBM_RMPD reg. - pool depletion */
+-      if (buf_pool_depletion->pools_grp_mode_enable) {
+-              bpools.grp_bp_depleted_num = buf_pool_depletion->num_of_pools;
+-              for (i = 0; i < port->bm_max_num_of_pools; i++) {
+-                      if (buf_pool_depletion->pools_to_consider[i]) {
+-                              for (j = 0; j < ext_buf_pools->
+-                                   num_of_pools_used; j++) {
+-                                      if (i == ordered_array[j]) {
+-                                              bpools.bpool[j].
+-                                                  grp_bp_depleted = true;
+-                                              break;
+-                                      }
+-                              }
+-                      }
+-              }
+-      }
+-
+-      if (buf_pool_depletion->single_pool_mode_enable) {
+-              for (i = 0; i < port->bm_max_num_of_pools; i++) {
+-                      if (buf_pool_depletion->
+-                          pools_to_consider_for_single_mode[i]) {
+-                              for (j = 0; j < ext_buf_pools->
+-                                   num_of_pools_used; j++) {
+-                                      if (i == ordered_array[j]) {
+-                                              bpools.bpool[j].
+-                                                  single_bp_depleted = true;
+-                                              break;
+-                                      }
+-                              }
+-                      }
+-              }
+-      }
+-
+-      err = set_bpools(port, &bpools);
+-      if (err != 0) {
+-              dev_err(port->dev, "%s: set_bpools() failed\n", __func__);
+-              return -EINVAL;
+-      }
+-
+-      return 0;
+-}
+-
+-static int init_low_level_driver(struct fman_port *port)
+-{
+-      struct fman_port_cfg *cfg = port->cfg;
+-      u32 tmp_val;
+-
+-      switch (port->port_type) {
+-      case FMAN_PORT_TYPE_RX:
+-              cfg->err_mask = (RX_ERRS_TO_ENQ & ~cfg->discard_mask);
+-              break;
+-      default:
+-              break;
+-      }
+-
+-      tmp_val = (u32)((port->internal_buf_offset % OFFSET_UNITS) ?
+-              (port->internal_buf_offset / OFFSET_UNITS + 1) :
+-              (port->internal_buf_offset / OFFSET_UNITS));
+-      port->internal_buf_offset = (u8)(tmp_val * OFFSET_UNITS);
+-      port->cfg->int_buf_start_margin = port->internal_buf_offset;
+-
+-      if (init(port) != 0) {
+-              dev_err(port->dev, "%s: fman port initialization failed\n",
+-                      __func__);
+-              return -ENODEV;
+-      }
+-
+-      /* The code bellow is a trick so the FM will not release the buffer
+-       * to BM nor will try to enqueue the frame to QM
+-       */
+-      if (port->port_type == FMAN_PORT_TYPE_TX) {
+-              if (!cfg->dflt_fqid && cfg->dont_release_buf) {
+-                      /* override fmbm_tcfqid 0 with a false non-0 value.
+-                       * This will force FM to act according to tfene.
+-                       * Otherwise, if fmbm_tcfqid is 0 the FM will release
+-                       * buffers to BM regardless of fmbm_tfene
+-                       */
+-                      iowrite32be(0xFFFFFF, &port->bmi_regs->tx.fmbm_tcfqid);
+-                      iowrite32be(NIA_ENG_BMI | NIA_BMI_AC_TX_RELEASE,
+-                                  &port->bmi_regs->tx.fmbm_tfene);
+-              }
+-      }
+-
+-      return 0;
+-}
+-
+-static int fill_soc_specific_params(struct fman_port *port)
+-{
+-      u32 bmi_max_fifo_size;
+-
+-      bmi_max_fifo_size = fman_get_bmi_max_fifo_size(port->fm);
+-      port->max_port_fifo_size = MAX_PORT_FIFO_SIZE(bmi_max_fifo_size);
+-      port->bm_max_num_of_pools = 64;
+-
+-      /* P4080 - Major 2
+-       * P2041/P3041/P5020/P5040 - Major 3
+-       * Tx/Bx - Major 6
+-       */
+-      switch (port->rev_info.major) {
+-      case 2:
+-      case 3:
+-              port->max_num_of_ext_pools              = 4;
+-              port->max_num_of_sub_portals            = 12;
+-              break;
+-
+-      case 6:
+-              port->max_num_of_ext_pools              = 8;
+-              port->max_num_of_sub_portals            = 16;
+-              break;
+-
+-      default:
+-              dev_err(port->dev, "%s: Unsupported FMan version\n", __func__);
+-              return -EINVAL;
+-      }
+-
+-      return 0;
+-}
+-
+-static int get_dflt_fifo_deq_pipeline_depth(u8 major, enum fman_port_type type,
+-                                          u16 speed)
+-{
+-      switch (type) {
+-      case FMAN_PORT_TYPE_RX:
+-      case FMAN_PORT_TYPE_TX:
+-              switch (speed) {
+-              case 10000:
+-                      return 4;
+-              case 1000:
+-                      if (major >= 6)
+-                              return 2;
+-                      else
+-                              return 1;
+-              default:
+-                      return 0;
+-              }
+-      default:
+-              return 0;
+-      }
+-}
+-
+-static int get_dflt_num_of_tasks(u8 major, enum fman_port_type type,
+-                               u16 speed)
+-{
+-      switch (type) {
+-      case FMAN_PORT_TYPE_RX:
+-      case FMAN_PORT_TYPE_TX:
+-              switch (speed) {
+-              case 10000:
+-                      return 16;
+-              case 1000:
+-                      if (major >= 6)
+-                              return 4;
+-                      else
+-                              return 3;
+-              default:
+-                      return 0;
+-              }
+-      default:
+-              return 0;
+-      }
+-}
+-
+-static int get_dflt_extra_num_of_tasks(u8 major, enum fman_port_type type,
+-                                     u16 speed)
+-{
+-      switch (type) {
+-      case FMAN_PORT_TYPE_RX:
+-              /* FMan V3 */
+-              if (major >= 6)
+-                      return 0;
+-
+-              /* FMan V2 */
+-              if (speed == 10000)
+-                      return 8;
+-              else
+-                      return 2;
+-      case FMAN_PORT_TYPE_TX:
+-      default:
+-              return 0;
+-      }
+-}
+-
+-static int get_dflt_num_of_open_dmas(u8 major, enum fman_port_type type,
+-                                   u16 speed)
+-{
+-      int val;
+-
+-      if (major >= 6) {
+-              switch (type) {
+-              case FMAN_PORT_TYPE_TX:
+-                      if (speed == 10000)
+-                              val = 12;
+-                      else
+-                              val = 3;
+-                      break;
+-              case FMAN_PORT_TYPE_RX:
+-                      if (speed == 10000)
+-                              val = 8;
+-                      else
+-                              val = 2;
+-                      break;
+-              default:
+-                      return 0;
+-              }
+-      } else {
+-              switch (type) {
+-              case FMAN_PORT_TYPE_TX:
+-              case FMAN_PORT_TYPE_RX:
+-                      if (speed == 10000)
+-                              val = 8;
+-                      else
+-                              val = 1;
+-                      break;
+-              default:
+-                      val = 0;
+-              }
+-      }
+-
+-      return val;
+-}
+-
+-static int get_dflt_extra_num_of_open_dmas(u8 major, enum fman_port_type type,
+-                                         u16 speed)
+-{
+-      /* FMan V3 */
+-      if (major >= 6)
+-              return 0;
+-
+-      /* FMan V2 */
+-      switch (type) {
+-      case FMAN_PORT_TYPE_RX:
+-      case FMAN_PORT_TYPE_TX:
+-              if (speed == 10000)
+-                      return 8;
+-              else
+-                      return 1;
+-      default:
+-              return 0;
+-      }
+-}
+-
+-static int get_dflt_num_of_fifo_bufs(u8 major, enum fman_port_type type,
+-                                   u16 speed)
+-{
+-      int val;
+-
+-      if (major >= 6) {
+-              switch (type) {
+-              case FMAN_PORT_TYPE_TX:
+-                      if (speed == 10000)
+-                              val = 64;
+-                      else
+-                              val = 50;
+-                      break;
+-              case FMAN_PORT_TYPE_RX:
+-                      if (speed == 10000)
+-                              val = 96;
+-                      else
+-                              val = 50;
+-                      break;
+-              default:
+-                      val = 0;
+-              }
+-      } else {
+-              switch (type) {
+-              case FMAN_PORT_TYPE_TX:
+-                      if (speed == 10000)
+-                              val = 48;
+-                      else
+-                              val = 44;
+-                      break;
+-              case FMAN_PORT_TYPE_RX:
+-                      if (speed == 10000)
+-                              val = 48;
+-                      else
+-                              val = 45;
+-                      break;
+-              default:
+-                      val = 0;
+-              }
+-      }
+-
+-      return val;
+-}
+-
+-static void set_dflt_cfg(struct fman_port *port,
+-                       struct fman_port_params *port_params)
+-{
+-      struct fman_port_cfg *cfg = port->cfg;
+-
+-      cfg->dma_swap_data = FMAN_PORT_DMA_NO_SWAP;
+-      cfg->color = FMAN_PORT_COLOR_GREEN;
+-      cfg->rx_cut_end_bytes = DFLT_PORT_CUT_BYTES_FROM_END;
+-      cfg->rx_pri_elevation = BMI_PRIORITY_ELEVATION_LEVEL;
+-      cfg->rx_fifo_thr = BMI_FIFO_THRESHOLD;
+-      cfg->tx_fifo_low_comf_level = (5 * 1024);
+-      cfg->deq_type = FMAN_PORT_DEQ_BY_PRI;
+-      cfg->deq_prefetch_option = FMAN_PORT_DEQ_FULL_PREFETCH;
+-      cfg->tx_fifo_deq_pipeline_depth =
+-              BMI_DEQUEUE_PIPELINE_DEPTH(port->port_type, port->port_speed);
+-      cfg->deq_byte_cnt = QMI_BYTE_COUNT_LEVEL_CONTROL(port->port_type);
+-
+-      cfg->rx_pri_elevation =
+-              DFLT_PORT_RX_FIFO_PRI_ELEVATION_LEV(port->max_port_fifo_size);
+-      port->cfg->rx_fifo_thr =
+-              DFLT_PORT_RX_FIFO_THRESHOLD(port->rev_info.major,
+-                                          port->max_port_fifo_size);
+-
+-      if ((port->rev_info.major == 6) &&
+-          ((port->rev_info.minor == 0) || (port->rev_info.minor == 3)))
+-              cfg->errata_A006320 = true;
+-
+-      /* Excessive Threshold register - exists for pre-FMv3 chips only */
+-      if (port->rev_info.major < 6)
+-              cfg->excessive_threshold_register = true;
+-      else
+-              cfg->fmbm_tfne_has_features = true;
+-
+-      cfg->buffer_prefix_content.data_align =
+-              DFLT_PORT_BUFFER_PREFIX_CONTEXT_DATA_ALIGN;
+-}
+-
+-static void set_rx_dflt_cfg(struct fman_port *port,
+-                          struct fman_port_params *port_params)
+-{
+-      port->cfg->discard_mask = DFLT_PORT_ERRORS_TO_DISCARD;
+-
+-      memcpy(&port->cfg->ext_buf_pools,
+-             &port_params->specific_params.rx_params.ext_buf_pools,
+-             sizeof(struct fman_ext_pools));
+-      port->cfg->err_fqid =
+-              port_params->specific_params.rx_params.err_fqid;
+-      port->cfg->dflt_fqid =
+-              port_params->specific_params.rx_params.dflt_fqid;
+-}
+-
+-static void set_tx_dflt_cfg(struct fman_port *port,
+-                          struct fman_port_params *port_params,
+-                          struct fman_port_dts_params *dts_params)
+-{
+-      port->cfg->tx_fifo_deq_pipeline_depth =
+-              get_dflt_fifo_deq_pipeline_depth(port->rev_info.major,
+-                                               port->port_type,
+-                                               port->port_speed);
+-      port->cfg->err_fqid =
+-              port_params->specific_params.non_rx_params.err_fqid;
+-      port->cfg->deq_sp =
+-              (u8)(dts_params->qman_channel_id & QMI_DEQ_CFG_SUBPORTAL_MASK);
+-      port->cfg->dflt_fqid =
+-              port_params->specific_params.non_rx_params.dflt_fqid;
+-      port->cfg->deq_high_priority = true;
+-}
+-
+-/**
+- * fman_port_config
+- * @port:     Pointer to the port structure
+- * @params:   Pointer to data structure of parameters
+- *
+- * Creates a descriptor for the FM PORT module.
+- * The routine returns a pointer to the FM PORT object.
+- * This descriptor must be passed as first parameter to all other FM PORT
+- * function calls.
+- * No actual initialization or configuration of FM hardware is done by this
+- * routine.
+- *
+- * Return: 0 on success; Error code otherwise.
+- */
+-int fman_port_config(struct fman_port *port, struct fman_port_params *params)
+-{
+-      void __iomem *base_addr = port->dts_params.base_addr;
+-      int err;
+-
+-      /* Allocate the FM driver's parameters structure */
+-      port->cfg = kzalloc(sizeof(*port->cfg), GFP_KERNEL);
+-      if (!port->cfg)
+-              goto err_params;
+-
+-      /* Initialize FM port parameters which will be kept by the driver */
+-      port->port_type = port->dts_params.type;
+-      port->port_speed = port->dts_params.speed;
+-      port->port_id = port->dts_params.id;
+-      port->fm = port->dts_params.fman;
+-      port->ext_pools_num = (u8)8;
+-
+-      /* get FM revision */
+-      fman_get_revision(port->fm, &port->rev_info);
+-
+-      err = fill_soc_specific_params(port);
+-      if (err)
+-              goto err_port_cfg;
+-
+-      switch (port->port_type) {
+-      case FMAN_PORT_TYPE_RX:
+-              set_rx_dflt_cfg(port, params);
+-      case FMAN_PORT_TYPE_TX:
+-              set_tx_dflt_cfg(port, params, &port->dts_params);
+-      default:
+-              set_dflt_cfg(port, params);
+-      }
+-
+-      /* Continue with other parameters */
+-      /* set memory map pointers */
+-      port->bmi_regs = base_addr + BMI_PORT_REGS_OFFSET;
+-      port->qmi_regs = base_addr + QMI_PORT_REGS_OFFSET;
+-
+-      port->max_frame_length = DFLT_PORT_MAX_FRAME_LENGTH;
+-      /* resource distribution. */
+-
+-      port->fifo_bufs.num =
+-      get_dflt_num_of_fifo_bufs(port->rev_info.major, port->port_type,
+-                                port->port_speed) * FMAN_BMI_FIFO_UNITS;
+-      port->fifo_bufs.extra =
+-      DFLT_PORT_EXTRA_NUM_OF_FIFO_BUFS * FMAN_BMI_FIFO_UNITS;
+-
+-      port->open_dmas.num =
+-      get_dflt_num_of_open_dmas(port->rev_info.major,
+-                                port->port_type, port->port_speed);
+-      port->open_dmas.extra =
+-      get_dflt_extra_num_of_open_dmas(port->rev_info.major,
+-                                      port->port_type, port->port_speed);
+-      port->tasks.num =
+-      get_dflt_num_of_tasks(port->rev_info.major,
+-                            port->port_type, port->port_speed);
+-      port->tasks.extra =
+-      get_dflt_extra_num_of_tasks(port->rev_info.major,
+-                                  port->port_type, port->port_speed);
+-
+-      /* FM_HEAVY_TRAFFIC_SEQUENCER_HANG_ERRATA_FMAN_A006981 errata
+-       * workaround
+-       */
+-      if ((port->rev_info.major == 6) && (port->rev_info.minor == 0) &&
+-          (((port->port_type == FMAN_PORT_TYPE_TX) &&
+-          (port->port_speed == 1000)))) {
+-              port->open_dmas.num = 16;
+-              port->open_dmas.extra = 0;
+-      }
+-
+-      if (port->rev_info.major >= 6 &&
+-          port->port_type == FMAN_PORT_TYPE_TX &&
+-          port->port_speed == 1000) {
+-              /* FM_WRONG_RESET_VALUES_ERRATA_FMAN_A005127 Errata
+-               * workaround
+-               */
+-              if (port->rev_info.major >= 6) {
+-                      u32 reg;
+-
+-                      reg = 0x00001013;
+-                      iowrite32be(reg, &port->bmi_regs->tx.fmbm_tfp);
+-              }
+-      }
+-
+-      return 0;
+-
+-err_port_cfg:
+-      kfree(port->cfg);
+-err_params:
+-      kfree(port);
+-      return -EINVAL;
+-}
+-EXPORT_SYMBOL(fman_port_config);
+-
+-/**
+- * fman_port_init
+- * port:      A pointer to a FM Port module.
+- * Initializes the FM PORT module by defining the software structure and
+- * configuring the hardware registers.
+- *
+- * Return: 0 on success; Error code otherwise.
+- */
+-int fman_port_init(struct fman_port *port)
+-{
+-      struct fman_port_cfg *cfg;
+-      int err;
+-      struct fman_port_init_params params;
+-
+-      if (is_init_done(port->cfg))
+-              return -EINVAL;
+-
+-      err = fman_sp_build_buffer_struct(&port->cfg->int_context,
+-                                        &port->cfg->buffer_prefix_content,
+-                                        &port->cfg->buf_margins,
+-                                        &port->buffer_offsets,
+-                                        &port->internal_buf_offset);
+-      if (err)
+-              return err;
+-
+-      cfg = port->cfg;
+-
+-      if (port->port_type == FMAN_PORT_TYPE_RX) {
+-              /* Call the external Buffer routine which also checks fifo
+-               * size and updates it if necessary
+-               */
+-              /* define external buffer pools and pool depletion */
+-              err = set_ext_buffer_pools(port);
+-              if (err)
+-                      return err;
+-              /* check if the largest external buffer pool is large enough */
+-              if (cfg->buf_margins.start_margins + MIN_EXT_BUF_SIZE +
+-                  cfg->buf_margins.end_margins >
+-                  port->rx_pools_params.largest_buf_size) {
+-                      dev_err(port->dev, "%s: buf_margins.start_margins (%d) + minimum buf size (64) + buf_margins.end_margins (%d) is larger than maximum external buffer size (%d)\n",
+-                              __func__, cfg->buf_margins.start_margins,
+-                              cfg->buf_margins.end_margins,
+-                              port->rx_pools_params.largest_buf_size);
+-                      return -EINVAL;
+-              }
+-      }
+-
+-      /* Call FM module routine for communicating parameters */
+-      memset(&params, 0, sizeof(params));
+-      params.port_id = port->port_id;
+-      params.port_type = port->port_type;
+-      params.port_speed = port->port_speed;
+-      params.num_of_tasks = (u8)port->tasks.num;
+-      params.num_of_extra_tasks = (u8)port->tasks.extra;
+-      params.num_of_open_dmas = (u8)port->open_dmas.num;
+-      params.num_of_extra_open_dmas = (u8)port->open_dmas.extra;
+-
+-      if (port->fifo_bufs.num) {
+-              err = verify_size_of_fifo(port);
+-              if (err)
+-                      return err;
+-      }
+-      params.size_of_fifo = port->fifo_bufs.num;
+-      params.extra_size_of_fifo = port->fifo_bufs.extra;
+-      params.deq_pipeline_depth = port->cfg->tx_fifo_deq_pipeline_depth;
+-      params.max_frame_length = port->max_frame_length;
+-
+-      err = fman_set_port_params(port->fm, &params);
+-      if (err)
+-              return err;
+-
+-      err = init_low_level_driver(port);
+-      if (err)
+-              return err;
+-
+-      kfree(port->cfg);
+-      port->cfg = NULL;
+-
+-      return 0;
+-}
+-EXPORT_SYMBOL(fman_port_init);
+-
+-/**
+- * fman_port_cfg_buf_prefix_content
+- * @port                      A pointer to a FM Port module.
+- * @buffer_prefix_content     A structure of parameters describing
+- *                            the structure of the buffer.
+- *                            Out parameter:
+- *                            Start margin - offset of data from
+- *                            start of external buffer.
+- * Defines the structure, size and content of the application buffer.
+- * The prefix, in Tx ports, if 'pass_prs_result', the application should set
+- * a value to their offsets in the prefix of the FM will save the first
+- * 'priv_data_size', than, depending on 'pass_prs_result' and
+- * 'pass_time_stamp', copy parse result and timeStamp, and the packet itself
+- * (in this order), to the application buffer, and to offset.
+- * Calling this routine changes the buffer margins definitions in the internal
+- * driver data base from its default configuration:
+- * Data size:  [DEFAULT_PORT_BUFFER_PREFIX_CONTENT_PRIV_DATA_SIZE]
+- * Pass Parser result: [DEFAULT_PORT_BUFFER_PREFIX_CONTENT_PASS_PRS_RESULT].
+- * Pass timestamp: [DEFAULT_PORT_BUFFER_PREFIX_CONTENT_PASS_TIME_STAMP].
+- * May be used for all ports
+- *
+- * Allowed only following fman_port_config() and before fman_port_init().
+- *
+- * Return: 0 on success; Error code otherwise.
+- */
+-int fman_port_cfg_buf_prefix_content(struct fman_port *port,
+-                                   struct fman_buffer_prefix_content *
+-                                   buffer_prefix_content)
+-{
+-      if (is_init_done(port->cfg))
+-              return -EINVAL;
+-
+-      memcpy(&port->cfg->buffer_prefix_content,
+-             buffer_prefix_content,
+-             sizeof(struct fman_buffer_prefix_content));
+-      /* if data_align was not initialized by user,
+-       * we return to driver's default
+-       */
+-      if (!port->cfg->buffer_prefix_content.data_align)
+-              port->cfg->buffer_prefix_content.data_align =
+-              DFLT_PORT_BUFFER_PREFIX_CONTEXT_DATA_ALIGN;
+-
+-      return 0;
+-}
+-EXPORT_SYMBOL(fman_port_cfg_buf_prefix_content);
+-
+-/**
+- * fman_port_disable
+- * port:      A pointer to a FM Port module.
+- *
+- * Gracefully disable an FM port. The port will not start new tasks after all
+- * tasks associated with the port are terminated.
+- *
+- * This is a blocking routine, it returns after port is gracefully stopped,
+- * i.e. the port will not except new frames, but it will finish all frames
+- * or tasks which were already began.
+- * Allowed only following fman_port_init().
+- *
+- * Return: 0 on success; Error code otherwise.
+- */
+-int fman_port_disable(struct fman_port *port)
+-{
+-      u32 __iomem *bmi_cfg_reg, *bmi_status_reg;
+-      u32 tmp;
+-      bool rx_port, failure = false;
+-      int count;
+-
+-      if (!is_init_done(port->cfg))
+-              return -EINVAL;
+-
+-      switch (port->port_type) {
+-      case FMAN_PORT_TYPE_RX:
+-              bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
+-              bmi_status_reg = &port->bmi_regs->rx.fmbm_rst;
+-              rx_port = true;
+-              break;
+-      case FMAN_PORT_TYPE_TX:
+-              bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
+-              bmi_status_reg = &port->bmi_regs->tx.fmbm_tst;
+-              rx_port = false;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-
+-      /* Disable QMI */
+-      if (!rx_port) {
+-              tmp = ioread32be(&port->qmi_regs->fmqm_pnc) & ~QMI_PORT_CFG_EN;
+-              iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
+-
+-              /* Wait for QMI to finish FD handling */
+-              count = 100;
+-              do {
+-                      udelay(10);
+-                      tmp = ioread32be(&port->qmi_regs->fmqm_pns);
+-              } while ((tmp & QMI_PORT_STATUS_DEQ_FD_BSY) && --count);
+-
+-              if (count == 0) {
+-                      /* Timeout */
+-                      failure = true;
+-              }
+-      }
+-
+-      /* Disable BMI */
+-      tmp = ioread32be(bmi_cfg_reg) & ~BMI_PORT_CFG_EN;
+-      iowrite32be(tmp, bmi_cfg_reg);
+-
+-      /* Wait for graceful stop end */
+-      count = 500;
+-      do {
+-              udelay(10);
+-              tmp = ioread32be(bmi_status_reg);
+-      } while ((tmp & BMI_PORT_STATUS_BSY) && --count);
+-
+-      if (count == 0) {
+-              /* Timeout */
+-              failure = true;
+-      }
+-
+-      if (failure)
+-              dev_dbg(port->dev, "%s: FMan Port[%d]: BMI or QMI is Busy. Port forced down\n",
+-                      __func__,  port->port_id);
+-
+-      return 0;
+-}
+-EXPORT_SYMBOL(fman_port_disable);
+-
+-/**
+- * fman_port_enable
+- * port:      A pointer to a FM Port module.
+- *
+- * A runtime routine provided to allow disable/enable of port.
+- *
+- * Allowed only following fman_port_init().
+- *
+- * Return: 0 on success; Error code otherwise.
+- */
+-int fman_port_enable(struct fman_port *port)
+-{
+-      u32 __iomem *bmi_cfg_reg;
+-      u32 tmp;
+-      bool rx_port;
+-
+-      if (!is_init_done(port->cfg))
+-              return -EINVAL;
+-
+-      switch (port->port_type) {
+-      case FMAN_PORT_TYPE_RX:
+-              bmi_cfg_reg = &port->bmi_regs->rx.fmbm_rcfg;
+-              rx_port = true;
+-              break;
+-      case FMAN_PORT_TYPE_TX:
+-              bmi_cfg_reg = &port->bmi_regs->tx.fmbm_tcfg;
+-              rx_port = false;
+-              break;
+-      default:
+-              return -EINVAL;
+-      }
+-
+-      /* Enable QMI */
+-      if (!rx_port) {
+-              tmp = ioread32be(&port->qmi_regs->fmqm_pnc) | QMI_PORT_CFG_EN;
+-              iowrite32be(tmp, &port->qmi_regs->fmqm_pnc);
+-      }
+-
+-      /* Enable BMI */
+-      tmp = ioread32be(bmi_cfg_reg) | BMI_PORT_CFG_EN;
+-      iowrite32be(tmp, bmi_cfg_reg);
+-
+-      return 0;
+-}
+-EXPORT_SYMBOL(fman_port_enable);
+-
+-/**
+- * fman_port_bind
+- * dev:               FMan Port OF device pointer
+- *
+- * Bind to a specific FMan Port.
+- *
+- * Allowed only after the port was created.
+- *
+- * Return: A pointer to the FMan port device.
+- */
+-struct fman_port *fman_port_bind(struct device *dev)
+-{
+-      return (struct fman_port *)(dev_get_drvdata(get_device(dev)));
+-}
+-EXPORT_SYMBOL(fman_port_bind);
+-
+-/**
+- * fman_port_get_qman_channel_id
+- * port:      Pointer to the FMan port devuce
+- *
+- * Get the QMan channel ID for the specific port
+- *
+- * Return: QMan channel ID
+- */
+-u32 fman_port_get_qman_channel_id(struct fman_port *port)
+-{
+-      return port->dts_params.qman_channel_id;
+-}
+-EXPORT_SYMBOL(fman_port_get_qman_channel_id);
+-
+-static int fman_port_probe(struct platform_device *of_dev)
+-{
+-      struct fman_port *port;
+-      struct fman *fman;
+-      struct device_node *fm_node, *port_node;
+-      struct resource res;
+-      struct resource *dev_res;
+-      u32 val;
+-      int err = 0, lenp;
+-      enum fman_port_type port_type;
+-      u16 port_speed;
+-      u8 port_id;
+-
+-      port = kzalloc(sizeof(*port), GFP_KERNEL);
+-      if (!port)
+-              return -ENOMEM;
+-
+-      port->dev = &of_dev->dev;
+-
+-      port_node = of_node_get(of_dev->dev.of_node);
+-
+-      /* Get the FM node */
+-      fm_node = of_get_parent(port_node);
+-      if (!fm_node) {
+-              dev_err(port->dev, "%s: of_get_parent() failed\n", __func__);
+-              err = -ENODEV;
+-              goto return_err;
+-      }
+-
+-      fman = dev_get_drvdata(&of_find_device_by_node(fm_node)->dev);
+-      of_node_put(fm_node);
+-      if (!fman) {
+-              err = -EINVAL;
+-              goto return_err;
+-      }
+-
+-      err = of_property_read_u32(port_node, "cell-index", &val);
+-      if (err) {
+-              dev_err(port->dev, "%s: reading cell-index for %s failed\n",
+-                      __func__, port_node->full_name);
+-              err = -EINVAL;
+-              goto return_err;
+-      }
+-      port_id = (u8)val;
+-      port->dts_params.id = port_id;
+-
+-      if (of_device_is_compatible(port_node, "fsl,fman-v3-port-tx")) {
+-              port_type = FMAN_PORT_TYPE_TX;
+-              port_speed = 1000;
+-              if (of_find_property(port_node, "fsl,fman-10g-port", &lenp))
+-                      port_speed = 10000;
+-
+-      } else if (of_device_is_compatible(port_node, "fsl,fman-v2-port-tx")) {
+-              if (port_id >= TX_10G_PORT_BASE)
+-                      port_speed = 10000;
+-              else
+-                      port_speed = 1000;
+-              port_type = FMAN_PORT_TYPE_TX;
+-
+-      } else if (of_device_is_compatible(port_node, "fsl,fman-v3-port-rx")) {
+-              port_type = FMAN_PORT_TYPE_RX;
+-              port_speed = 1000;
+-              if (of_find_property(port_node, "fsl,fman-10g-port", &lenp))
+-                      port_speed = 10000;
+-
+-      } else if (of_device_is_compatible(port_node, "fsl,fman-v2-port-rx")) {
+-              if (port_id >= RX_10G_PORT_BASE)
+-                      port_speed = 10000;
+-              else
+-                      port_speed = 1000;
+-              port_type = FMAN_PORT_TYPE_RX;
+-
+-      }  else {
+-              dev_err(port->dev, "%s: Illegal port type\n", __func__);
+-              err = -EINVAL;
+-              goto return_err;
+-      }
+-
+-      port->dts_params.type = port_type;
+-      port->dts_params.speed = port_speed;
+-
+-      if (port_type == FMAN_PORT_TYPE_TX) {
+-              u32 qman_channel_id;
+-
+-              qman_channel_id = fman_get_qman_channel_id(fman, port_id);
+-              if (qman_channel_id == 0) {
+-                      dev_err(port->dev, "%s: incorrect qman-channel-id\n",
+-                              __func__);
+-                      err = -EINVAL;
+-                      goto return_err;
+-              }
+-              port->dts_params.qman_channel_id = qman_channel_id;
+-      }
+-
+-      err = of_address_to_resource(port_node, 0, &res);
+-      if (err < 0) {
+-              dev_err(port->dev, "%s: of_address_to_resource() failed\n",
+-                      __func__);
+-              err = -ENOMEM;
+-              goto return_err;
+-      }
+-
+-      port->dts_params.fman = fman;
+-
+-      of_node_put(port_node);
+-
+-      dev_res = __devm_request_region(port->dev, &res, res.start,
+-                                      resource_size(&res), "fman-port");
+-      if (!dev_res) {
+-              dev_err(port->dev, "%s: __devm_request_region() failed\n",
+-                      __func__);
+-              err = -EINVAL;
+-              goto free_port;
+-      }
+-
+-      port->dts_params.base_addr = devm_ioremap(port->dev, res.start,
+-                                                resource_size(&res));
+-      if (!port->dts_params.base_addr)
+-              dev_err(port->dev, "%s: devm_ioremap() failed\n", __func__);
+-
+-      dev_set_drvdata(&of_dev->dev, port);
+-
+-      return 0;
+-
+-return_err:
+-      of_node_put(port_node);
+-free_port:
+-      kfree(port);
+-      return err;
+-}
+-
+-static const struct of_device_id fman_port_match[] = {
+-      {.compatible = "fsl,fman-v3-port-rx"},
+-      {.compatible = "fsl,fman-v2-port-rx"},
+-      {.compatible = "fsl,fman-v3-port-tx"},
+-      {.compatible = "fsl,fman-v2-port-tx"},
+-      {}
+-};
+-
+-MODULE_DEVICE_TABLE(of, fman_port_match);
+-
+-static struct platform_driver fman_port_driver = {
+-      .driver = {
+-              .name = "fsl-fman-port",
+-              .of_match_table = fman_port_match,
+-      },
+-      .probe = fman_port_probe,
+-};
+-
+-static int __init fman_port_load(void)
+-{
+-      int err;
+-
+-      pr_debug("FSL DPAA FMan driver\n");
+-
+-      err = platform_driver_register(&fman_port_driver);
+-      if (err < 0)
+-              pr_err("Error, platform_driver_register() = %d\n", err);
+-
+-      return err;
+-}
+-module_init(fman_port_load);
+-
+-static void __exit fman_port_unload(void)
+-{
+-      platform_driver_unregister(&fman_port_driver);
+-}
+-module_exit(fman_port_unload);
+-
+-MODULE_LICENSE("Dual BSD/GPL");
+-MODULE_DESCRIPTION("Freescale DPAA Frame Manager Port driver");
+diff --git a/drivers/net/ethernet/freescale/fman/fman_port.h b/drivers/net/ethernet/freescale/fman/fman_port.h
+deleted file mode 100644
+index 8ba9017..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman_port.h
++++ /dev/null
+@@ -1,151 +0,0 @@
+-/*
+- * Copyright 2008 - 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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#ifndef __FMAN_PORT_H
+-#define __FMAN_PORT_H
+-
+-#include "fman.h"
+-
+-/* FM Port API
+- * The FM uses a general module called "port" to represent a Tx port (MAC),
+- * an Rx port (MAC).
+- * The number of ports in an FM varies between SOCs.
+- * The SW driver manages these ports as sub-modules of the FM,i.e. after an
+- * FM is initialized, its ports may be initialized and operated upon.
+- * The port is initialized aware of its type, but other functions on a port
+- * may be indifferent to its type. When necessary, the driver verifies
+- * coherence and returns error if applicable.
+- * On initialization, user specifies the port type and it's index (relative
+- * to the port's type) - always starting at 0.
+- */
+-
+-/* FM Frame error */
+-/* Frame Descriptor errors */
+-/* Not for Rx-Port! Unsupported Format */
+-#define FM_PORT_FRM_ERR_UNSUPPORTED_FORMAT    FM_FD_ERR_UNSUPPORTED_FORMAT
+-/* Not for Rx-Port! Length Error */
+-#define FM_PORT_FRM_ERR_LENGTH                        FM_FD_ERR_LENGTH
+-/* DMA Data error */
+-#define FM_PORT_FRM_ERR_DMA                   FM_FD_ERR_DMA
+-/* non Frame-Manager error; probably come from SEC that was chained to FM */
+-#define FM_PORT_FRM_ERR_NON_FM                        FM_FD_RX_STATUS_ERR_NON_FM
+- /* IPR error */
+-#define FM_PORT_FRM_ERR_IPRE                  (FM_FD_ERR_IPR & ~FM_FD_IPR)
+-/* IPR non-consistent-sp */
+-#define FM_PORT_FRM_ERR_IPR_NCSP              (FM_FD_ERR_IPR_NCSP &   \
+-                                              ~FM_FD_IPR)
+-
+-/* Rx FIFO overflow, FCS error, code error, running disparity
+- * error (SGMII and TBI modes), FIFO parity error.
+- * PHY Sequence error, PHY error control character detected.
+- */
+-#define FM_PORT_FRM_ERR_PHYSICAL                FM_FD_ERR_PHYSICAL
+-/* Frame too long OR Frame size exceeds max_length_frame  */
+-#define FM_PORT_FRM_ERR_SIZE                    FM_FD_ERR_SIZE
+-/* indicates a classifier "drop" operation */
+-#define FM_PORT_FRM_ERR_CLS_DISCARD             FM_FD_ERR_CLS_DISCARD
+-/* Extract Out of Frame */
+-#define FM_PORT_FRM_ERR_EXTRACTION              FM_FD_ERR_EXTRACTION
+-/* No Scheme Selected */
+-#define FM_PORT_FRM_ERR_NO_SCHEME               FM_FD_ERR_NO_SCHEME
+-/* Keysize Overflow */
+-#define FM_PORT_FRM_ERR_KEYSIZE_OVERFLOW        FM_FD_ERR_KEYSIZE_OVERFLOW
+-/* Frame color is red */
+-#define FM_PORT_FRM_ERR_COLOR_RED               FM_FD_ERR_COLOR_RED
+-/* Frame color is yellow */
+-#define FM_PORT_FRM_ERR_COLOR_YELLOW            FM_FD_ERR_COLOR_YELLOW
+-/* Parser Time out Exceed */
+-#define FM_PORT_FRM_ERR_PRS_TIMEOUT             FM_FD_ERR_PRS_TIMEOUT
+-/* Invalid Soft Parser instruction */
+-#define FM_PORT_FRM_ERR_PRS_ILL_INSTRUCT        FM_FD_ERR_PRS_ILL_INSTRUCT
+-/* Header error was identified during parsing */
+-#define FM_PORT_FRM_ERR_PRS_HDR_ERR             FM_FD_ERR_PRS_HDR_ERR
+-/* Frame parsed beyind 256 first bytes */
+-#define FM_PORT_FRM_ERR_BLOCK_LIMIT_EXCEEDED    FM_FD_ERR_BLOCK_LIMIT_EXCEEDED
+-/* FPM Frame Processing Timeout Exceeded */
+-#define FM_PORT_FRM_ERR_PROCESS_TIMEOUT         0x00000001
+-
+-struct fman_port;
+-
+-/* A structure for additional Rx port parameters */
+-struct fman_port_rx_params {
+-      u32 err_fqid;                   /* Error Queue Id. */
+-      u32 dflt_fqid;                  /* Default Queue Id. */
+-      /* Which external buffer pools are used
+-       * (up to FMAN_PORT_MAX_EXT_POOLS_NUM), and their sizes.
+-       */
+-      struct fman_ext_pools ext_buf_pools;
+-};
+-
+-/* A structure for additional non-Rx port parameters */
+-struct fman_port_non_rx_params {
+-      /* Error Queue Id. */
+-      u32 err_fqid;
+-      /* For Tx - Default Confirmation queue, 0 means no Tx confirmation
+-       * for processed frames. For OP port - default Rx queue.
+-       */
+-      u32 dflt_fqid;
+-};
+-
+-/* A union for additional parameters depending on port type */
+-union fman_port_specific_params {
+-      /* Rx port parameters structure */
+-      struct fman_port_rx_params rx_params;
+-      /* Non-Rx port parameters structure */
+-      struct fman_port_non_rx_params non_rx_params;
+-};
+-
+-/* A structure representing FM initialization parameters */
+-struct fman_port_params {
+-      /* Virtual Address of memory mapped FM Port registers. */
+-      void *fm;
+-      union fman_port_specific_params specific_params;
+-      /* Additional parameters depending on port type. */
+-};
+-
+-int fman_port_config(struct fman_port *port, struct fman_port_params *params);
+-
+-int fman_port_init(struct fman_port *port);
+-
+-int fman_port_cfg_buf_prefix_content(struct fman_port *port,
+-                                   struct fman_buffer_prefix_content
+-                                   *buffer_prefix_content);
+-
+-int fman_port_disable(struct fman_port *port);
+-
+-int fman_port_enable(struct fman_port *port);
+-
+-u32 fman_port_get_qman_channel_id(struct fman_port *port);
+-
+-struct fman_port *fman_port_bind(struct device *dev);
+-
+-#endif /* __FMAN_PORT_H */
+diff --git a/drivers/net/ethernet/freescale/fman/fman_sp.c b/drivers/net/ethernet/freescale/fman/fman_sp.c
+deleted file mode 100644
+index 248f5bc..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman_sp.c
++++ /dev/null
+@@ -1,169 +0,0 @@
+-/*
+- * Copyright 2008 - 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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#include "fman_sp.h"
+-#include "fman.h"
+-
+-void fman_sp_set_buf_pools_in_asc_order_of_buf_sizes(struct fman_ext_pools
+-                                                   *fm_ext_pools,
+-                                                   u8 *ordered_array,
+-                                                   u16 *sizes_array)
+-{
+-      u16 buf_size = 0;
+-      int i = 0, j = 0, k = 0;
+-
+-      /* First we copy the external buffers pools information
+-       * to an ordered local array
+-       */
+-      for (i = 0; i < fm_ext_pools->num_of_pools_used; i++) {
+-              /* get pool size */
+-              buf_size = fm_ext_pools->ext_buf_pool[i].size;
+-
+-              /* keep sizes in an array according to poolId
+-               * for direct access
+-               */
+-              sizes_array[fm_ext_pools->ext_buf_pool[i].id] = buf_size;
+-
+-              /* save poolId in an ordered array according to size */
+-              for (j = 0; j <= i; j++) {
+-                      /* this is the next free place in the array */
+-                      if (j == i)
+-                              ordered_array[i] =
+-                                  fm_ext_pools->ext_buf_pool[i].id;
+-                      else {
+-                              /* find the right place for this poolId */
+-                              if (buf_size < sizes_array[ordered_array[j]]) {
+-                                      /* move the pool_ids one place ahead
+-                                       * to make room for this poolId
+-                                       */
+-                                      for (k = i; k > j; k--)
+-                                              ordered_array[k] =
+-                                                  ordered_array[k - 1];
+-
+-                                      /* now k==j, this is the place for
+-                                       * the new size
+-                                       */
+-                                      ordered_array[k] =
+-                                          fm_ext_pools->ext_buf_pool[i].id;
+-                                      break;
+-                              }
+-                      }
+-              }
+-      }
+-}
+-EXPORT_SYMBOL(fman_sp_set_buf_pools_in_asc_order_of_buf_sizes);
+-
+-int fman_sp_build_buffer_struct(struct fman_sp_int_context_data_copy *
+-                              int_context_data_copy,
+-                              struct fman_buffer_prefix_content *
+-                              buffer_prefix_content,
+-                              struct fman_sp_buf_margins *buf_margins,
+-                              struct fman_sp_buffer_offsets *buffer_offsets,
+-                              u8 *internal_buf_offset)
+-{
+-      u32 tmp;
+-
+-      /* Align start of internal context data to 16 byte */
+-      int_context_data_copy->ext_buf_offset = (u16)
+-              ((buffer_prefix_content->priv_data_size & (OFFSET_UNITS - 1)) ?
+-              ((buffer_prefix_content->priv_data_size + OFFSET_UNITS) &
+-                      ~(u16)(OFFSET_UNITS - 1)) :
+-              buffer_prefix_content->priv_data_size);
+-
+-      /* Translate margin and int_context params to FM parameters */
+-      /* Initialize with illegal value. Later we'll set legal values. */
+-      buffer_offsets->prs_result_offset = (u32)ILLEGAL_BASE;
+-      buffer_offsets->time_stamp_offset = (u32)ILLEGAL_BASE;
+-      buffer_offsets->hash_result_offset = (u32)ILLEGAL_BASE;
+-
+-      /* Internally the driver supports 4 options
+-       * 1. prsResult/timestamp/hashResult selection (in fact 8 options,
+-       * but for simplicity we'll
+-       * relate to it as 1).
+-       * 2. All IC context (from AD) not including debug.
+-       */
+-
+-      /* This case covers the options under 1 */
+-      /* Copy size must be in 16-byte granularity. */
+-      int_context_data_copy->size =
+-          (u16)((buffer_prefix_content->pass_prs_result ? 32 : 0) +
+-                ((buffer_prefix_content->pass_time_stamp ||
+-                buffer_prefix_content->pass_hash_result) ? 16 : 0));
+-
+-      /* Align start of internal context data to 16 byte */
+-      int_context_data_copy->int_context_offset =
+-          (u8)(buffer_prefix_content->pass_prs_result ? 32 :
+-               ((buffer_prefix_content->pass_time_stamp ||
+-               buffer_prefix_content->pass_hash_result) ? 64 : 0));
+-
+-      if (buffer_prefix_content->pass_prs_result)
+-              buffer_offsets->prs_result_offset =
+-                  int_context_data_copy->ext_buf_offset;
+-      if (buffer_prefix_content->pass_time_stamp)
+-              buffer_offsets->time_stamp_offset =
+-                  buffer_prefix_content->pass_prs_result ?
+-                  (int_context_data_copy->ext_buf_offset +
+-                      sizeof(struct fman_prs_result)) :
+-                  int_context_data_copy->ext_buf_offset;
+-      if (buffer_prefix_content->pass_hash_result)
+-              /* If PR is not requested, whether TS is
+-               * requested or not, IC will be copied from TS
+-                       */
+-              buffer_offsets->hash_result_offset =
+-              buffer_prefix_content->pass_prs_result ?
+-                      (int_context_data_copy->ext_buf_offset +
+-                              sizeof(struct fman_prs_result) + 8) :
+-                      int_context_data_copy->ext_buf_offset + 8;
+-
+-      if (int_context_data_copy->size)
+-              buf_margins->start_margins =
+-                  (u16)(int_context_data_copy->ext_buf_offset +
+-                        int_context_data_copy->size);
+-      else
+-              /* No Internal Context passing, STartMargin is
+-               * immediately after private_info
+-               */
+-              buf_margins->start_margins =
+-                  buffer_prefix_content->priv_data_size;
+-
+-      /* align data start */
+-      tmp = (u32)(buf_margins->start_margins %
+-                  buffer_prefix_content->data_align);
+-      if (tmp)
+-              buf_margins->start_margins +=
+-                  (buffer_prefix_content->data_align - tmp);
+-      buffer_offsets->data_offset = buf_margins->start_margins;
+-
+-      return 0;
+-}
+-EXPORT_SYMBOL(fman_sp_build_buffer_struct);
+-
+diff --git a/drivers/net/ethernet/freescale/fman/fman_sp.h b/drivers/net/ethernet/freescale/fman/fman_sp.h
+deleted file mode 100644
+index 820b7f6..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman_sp.h
++++ /dev/null
+@@ -1,103 +0,0 @@
+-/*
+- * Copyright 2008 - 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 Freescale Semiconductor nor the
+- *     names of its contributors may be used to endorse or promote products
+- *     derived from this software without specific prior written permission.
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#ifndef __FM_SP_H
+-#define __FM_SP_H
+-
+-#include "fman.h"
+-#include <linux/types.h>
+-
+-#define ILLEGAL_BASE    (~0)
+-
+-/* defaults */
+-#define DFLT_FM_SP_BUFFER_PREFIX_CONTEXT_DATA_ALIGN   64
+-
+-/* Registers bit fields */
+-#define FMAN_SP_EXT_BUF_POOL_EN_COUNTER               0x40000000
+-#define FMAN_SP_EXT_BUF_POOL_VALID                    0x80000000
+-#define FMAN_SP_EXT_BUF_POOL_BACKUP                   0x20000000
+-#define FMAN_SP_DMA_ATTR_WRITE_OPTIMIZE               0x00100000
+-#define FMAN_SP_SG_DISABLE                            0x80000000
+-
+-/* shifts */
+-#define FMAN_SP_EXT_BUF_MARG_START_SHIFT              16
+-#define FMAN_SP_DMA_ATTR_SWP_SHIFT                    30
+-#define FMAN_SP_IC_TO_EXT_SHIFT                       16
+-#define FMAN_SP_IC_FROM_INT_SHIFT                     8
+-
+-/* structure for defining internal context copying */
+-struct fman_sp_int_context_data_copy {
+-      /* < Offset in External buffer to which internal
+-       *  context is copied to (Rx) or taken from (Tx, Op).
+-       */
+-      u16 ext_buf_offset;
+-      /* Offset within internal context to copy from
+-       * (Rx) or to copy to (Tx, Op).
+-       */
+-      u8 int_context_offset;
+-      /* Internal offset size to be copied */
+-      u16 size;
+-};
+-
+-/*  struct for defining external buffer margins */
+-struct fman_sp_buf_margins {
+-      /* Number of bytes to be left at the beginning
+-       * of the external buffer (must be divisible by 16)
+-       */
+-      u16 start_margins;
+-      /* number of bytes to be left at the end
+-       * of the external buffer(must be divisible by 16)
+-       */
+-      u16 end_margins;
+-};
+-
+-struct fman_sp_buffer_offsets {
+-      u32 data_offset;
+-      u32 prs_result_offset;
+-      u32 time_stamp_offset;
+-      u32 hash_result_offset;
+-};
+-
+-int fman_sp_build_buffer_struct(struct fman_sp_int_context_data_copy
+-                              *int_context_data_copy,
+-                              struct fman_buffer_prefix_content
+-                              *buffer_prefix_content,
+-                              struct fman_sp_buf_margins *buf_margins,
+-                              struct fman_sp_buffer_offsets
+-                              *buffer_offsets,
+-                              u8 *internal_buf_offset);
+-
+-void fman_sp_set_buf_pools_in_asc_order_of_buf_sizes(struct fman_ext_pools
+-                                                   *fm_ext_pools,
+-                                                   u8 *ordered_array,
+-                                                   u16 *sizes_array);
+-
+-#endif        /* __FM_SP_H */
+diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.c b/drivers/net/ethernet/freescale/fman/fman_tgec.c
+deleted file mode 100644
+index 4b0f3a5..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman_tgec.c
++++ /dev/null
+@@ -1,783 +0,0 @@
+-/*
+- * Copyright 2008-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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+-
+-#include "fman_tgec.h"
+-#include "fman.h"
+-
+-#include <linux/slab.h>
+-#include <linux/bitrev.h>
+-#include <linux/io.h>
+-#include <linux/crc32.h>
+-
+-/* Transmit Inter-Packet Gap Length Register (TX_IPG_LENGTH) */
+-#define TGEC_TX_IPG_LENGTH_MASK       0x000003ff
+-
+-/* Command and Configuration Register (COMMAND_CONFIG) */
+-#define CMD_CFG_NO_LEN_CHK            0x00020000
+-#define CMD_CFG_PAUSE_IGNORE          0x00000100
+-#define CMF_CFG_CRC_FWD                       0x00000040
+-#define CMD_CFG_PROMIS_EN             0x00000010
+-#define CMD_CFG_RX_EN                 0x00000002
+-#define CMD_CFG_TX_EN                 0x00000001
+-
+-/* Interrupt Mask Register (IMASK) */
+-#define TGEC_IMASK_MDIO_SCAN_EVENT    0x00010000
+-#define TGEC_IMASK_MDIO_CMD_CMPL      0x00008000
+-#define TGEC_IMASK_REM_FAULT          0x00004000
+-#define TGEC_IMASK_LOC_FAULT          0x00002000
+-#define TGEC_IMASK_TX_ECC_ER          0x00001000
+-#define TGEC_IMASK_TX_FIFO_UNFL       0x00000800
+-#define TGEC_IMASK_TX_FIFO_OVFL       0x00000400
+-#define TGEC_IMASK_TX_ER              0x00000200
+-#define TGEC_IMASK_RX_FIFO_OVFL       0x00000100
+-#define TGEC_IMASK_RX_ECC_ER          0x00000080
+-#define TGEC_IMASK_RX_JAB_FRM         0x00000040
+-#define TGEC_IMASK_RX_OVRSZ_FRM       0x00000020
+-#define TGEC_IMASK_RX_RUNT_FRM                0x00000010
+-#define TGEC_IMASK_RX_FRAG_FRM                0x00000008
+-#define TGEC_IMASK_RX_LEN_ER          0x00000004
+-#define TGEC_IMASK_RX_CRC_ER          0x00000002
+-#define TGEC_IMASK_RX_ALIGN_ER                0x00000001
+-
+-/* Hashtable Control Register (HASHTABLE_CTRL) */
+-#define TGEC_HASH_MCAST_SHIFT         23
+-#define TGEC_HASH_MCAST_EN            0x00000200
+-#define TGEC_HASH_ADR_MSK             0x000001ff
+-
+-#define DEFAULT_TX_IPG_LENGTH                 12
+-#define DEFAULT_MAX_FRAME_LENGTH              0x600
+-#define DEFAULT_PAUSE_QUANT                   0xf000
+-
+-/* number of pattern match registers (entries) */
+-#define TGEC_NUM_OF_PADDRS          1
+-
+-/* Group address bit indication */
+-#define GROUP_ADDRESS               0x0000010000000000LL
+-
+-/* Hash table size (= 32 bits*8 regs) */
+-#define TGEC_HASH_TABLE_SIZE             512
+-
+-/* tGEC memory map */
+-struct tgec_regs {
+-      u32 tgec_id;            /* 0x000 Controller ID */
+-      u32 reserved001[1];     /* 0x004 */
+-      u32 command_config;     /* 0x008 Control and configuration */
+-      u32 mac_addr_0;         /* 0x00c Lower 32 bits of the MAC adr */
+-      u32 mac_addr_1;         /* 0x010 Upper 16 bits of the MAC adr */
+-      u32 maxfrm;             /* 0x014 Maximum frame length */
+-      u32 pause_quant;        /* 0x018 Pause quanta */
+-      u32 rx_fifo_sections;   /* 0x01c  */
+-      u32 tx_fifo_sections;   /* 0x020  */
+-      u32 rx_fifo_almost_f_e; /* 0x024  */
+-      u32 tx_fifo_almost_f_e; /* 0x028  */
+-      u32 hashtable_ctrl;     /* 0x02c Hash table control */
+-      u32 mdio_cfg_status;    /* 0x030  */
+-      u32 mdio_command;       /* 0x034  */
+-      u32 mdio_data;          /* 0x038  */
+-      u32 mdio_regaddr;       /* 0x03c  */
+-      u32 status;             /* 0x040  */
+-      u32 tx_ipg_len;         /* 0x044 Transmitter inter-packet-gap */
+-      u32 mac_addr_2;         /* 0x048 Lower 32 bits of 2nd MAC adr */
+-      u32 mac_addr_3;         /* 0x04c Upper 16 bits of 2nd MAC adr */
+-      u32 rx_fifo_ptr_rd;     /* 0x050  */
+-      u32 rx_fifo_ptr_wr;     /* 0x054  */
+-      u32 tx_fifo_ptr_rd;     /* 0x058  */
+-      u32 tx_fifo_ptr_wr;     /* 0x05c  */
+-      u32 imask;              /* 0x060 Interrupt mask */
+-      u32 ievent;             /* 0x064 Interrupt event */
+-      u32 udp_port;           /* 0x068 Defines a UDP Port number */
+-      u32 type_1588v2;        /* 0x06c Type field for 1588v2 */
+-      u32 reserved070[4];     /* 0x070 */
+-      /* 10Ge Statistics Counter */
+-      u32 tfrm_u;             /* 80 aFramesTransmittedOK */
+-      u32 tfrm_l;             /* 84 aFramesTransmittedOK */
+-      u32 rfrm_u;             /* 88 aFramesReceivedOK */
+-      u32 rfrm_l;             /* 8c aFramesReceivedOK */
+-      u32 rfcs_u;             /* 90 aFrameCheckSequenceErrors */
+-      u32 rfcs_l;             /* 94 aFrameCheckSequenceErrors */
+-      u32 raln_u;             /* 98 aAlignmentErrors */
+-      u32 raln_l;             /* 9c aAlignmentErrors */
+-      u32 txpf_u;             /* A0 aPAUSEMACCtrlFramesTransmitted */
+-      u32 txpf_l;             /* A4 aPAUSEMACCtrlFramesTransmitted */
+-      u32 rxpf_u;             /* A8 aPAUSEMACCtrlFramesReceived */
+-      u32 rxpf_l;             /* Ac aPAUSEMACCtrlFramesReceived */
+-      u32 rlong_u;            /* B0 aFrameTooLongErrors */
+-      u32 rlong_l;            /* B4 aFrameTooLongErrors */
+-      u32 rflr_u;             /* B8 aInRangeLengthErrors */
+-      u32 rflr_l;             /* Bc aInRangeLengthErrors */
+-      u32 tvlan_u;            /* C0 VLANTransmittedOK */
+-      u32 tvlan_l;            /* C4 VLANTransmittedOK */
+-      u32 rvlan_u;            /* C8 VLANReceivedOK */
+-      u32 rvlan_l;            /* Cc VLANReceivedOK */
+-      u32 toct_u;             /* D0 if_out_octets */
+-      u32 toct_l;             /* D4 if_out_octets */
+-      u32 roct_u;             /* D8 if_in_octets */
+-      u32 roct_l;             /* Dc if_in_octets */
+-      u32 ruca_u;             /* E0 if_in_ucast_pkts */
+-      u32 ruca_l;             /* E4 if_in_ucast_pkts */
+-      u32 rmca_u;             /* E8 ifInMulticastPkts */
+-      u32 rmca_l;             /* Ec ifInMulticastPkts */
+-      u32 rbca_u;             /* F0 ifInBroadcastPkts */
+-      u32 rbca_l;             /* F4 ifInBroadcastPkts */
+-      u32 terr_u;             /* F8 if_out_errors */
+-      u32 terr_l;             /* Fc if_out_errors */
+-      u32 reserved100[2];     /* 100-108 */
+-      u32 tuca_u;             /* 108 if_out_ucast_pkts */
+-      u32 tuca_l;             /* 10c if_out_ucast_pkts */
+-      u32 tmca_u;             /* 110 ifOutMulticastPkts */
+-      u32 tmca_l;             /* 114 ifOutMulticastPkts */
+-      u32 tbca_u;             /* 118 ifOutBroadcastPkts */
+-      u32 tbca_l;             /* 11c ifOutBroadcastPkts */
+-      u32 rdrp_u;             /* 120 etherStatsDropEvents */
+-      u32 rdrp_l;             /* 124 etherStatsDropEvents */
+-      u32 reoct_u;            /* 128 etherStatsOctets */
+-      u32 reoct_l;            /* 12c etherStatsOctets */
+-      u32 rpkt_u;             /* 130 etherStatsPkts */
+-      u32 rpkt_l;             /* 134 etherStatsPkts */
+-      u32 trund_u;            /* 138 etherStatsUndersizePkts */
+-      u32 trund_l;            /* 13c etherStatsUndersizePkts */
+-      u32 r64_u;              /* 140 etherStatsPkts64Octets */
+-      u32 r64_l;              /* 144 etherStatsPkts64Octets */
+-      u32 r127_u;             /* 148 etherStatsPkts65to127Octets */
+-      u32 r127_l;             /* 14c etherStatsPkts65to127Octets */
+-      u32 r255_u;             /* 150 etherStatsPkts128to255Octets */
+-      u32 r255_l;             /* 154 etherStatsPkts128to255Octets */
+-      u32 r511_u;             /* 158 etherStatsPkts256to511Octets */
+-      u32 r511_l;             /* 15c etherStatsPkts256to511Octets */
+-      u32 r1023_u;            /* 160 etherStatsPkts512to1023Octets */
+-      u32 r1023_l;            /* 164 etherStatsPkts512to1023Octets */
+-      u32 r1518_u;            /* 168 etherStatsPkts1024to1518Octets */
+-      u32 r1518_l;            /* 16c etherStatsPkts1024to1518Octets */
+-      u32 r1519x_u;           /* 170 etherStatsPkts1519toX */
+-      u32 r1519x_l;           /* 174 etherStatsPkts1519toX */
+-      u32 trovr_u;            /* 178 etherStatsOversizePkts */
+-      u32 trovr_l;            /* 17c etherStatsOversizePkts */
+-      u32 trjbr_u;            /* 180 etherStatsJabbers */
+-      u32 trjbr_l;            /* 184 etherStatsJabbers */
+-      u32 trfrg_u;            /* 188 etherStatsFragments */
+-      u32 trfrg_l;            /* 18C etherStatsFragments */
+-      u32 rerr_u;             /* 190 if_in_errors */
+-      u32 rerr_l;             /* 194 if_in_errors */
+-};
+-
+-struct tgec_cfg {
+-      bool pause_ignore;
+-      bool promiscuous_mode_enable;
+-      u16 max_frame_length;
+-      u16 pause_quant;
+-      u32 tx_ipg_length;
+-};
+-
+-struct fman_mac {
+-      /* Pointer to the memory mapped registers. */
+-      struct tgec_regs __iomem *regs;
+-      /* MAC address of device; */
+-      u64 addr;
+-      u16 max_speed;
+-      void *dev_id; /* device cookie used by the exception cbs */
+-      fman_mac_exception_cb *exception_cb;
+-      fman_mac_exception_cb *event_cb;
+-      /* pointer to driver's global address hash table  */
+-      struct eth_hash_t *multicast_addr_hash;
+-      /* pointer to driver's individual address hash table  */
+-      struct eth_hash_t *unicast_addr_hash;
+-      u8 mac_id;
+-      u32 exceptions;
+-      struct tgec_cfg *cfg;
+-      void *fm;
+-      struct fman_rev_info fm_rev_info;
+-};
+-
+-static void set_mac_address(struct tgec_regs __iomem *regs, u8 *adr)
+-{
+-      u32 tmp0, tmp1;
+-
+-      tmp0 = (u32)(adr[0] | adr[1] << 8 | adr[2] << 16 | adr[3] << 24);
+-      tmp1 = (u32)(adr[4] | adr[5] << 8);
+-      iowrite32be(tmp0, &regs->mac_addr_0);
+-      iowrite32be(tmp1, &regs->mac_addr_1);
+-}
+-
+-static void set_dflts(struct tgec_cfg *cfg)
+-{
+-      cfg->promiscuous_mode_enable = false;
+-      cfg->pause_ignore = false;
+-      cfg->tx_ipg_length = DEFAULT_TX_IPG_LENGTH;
+-      cfg->max_frame_length = DEFAULT_MAX_FRAME_LENGTH;
+-      cfg->pause_quant = DEFAULT_PAUSE_QUANT;
+-}
+-
+-static int init(struct tgec_regs __iomem *regs, struct tgec_cfg *cfg,
+-              u32 exception_mask)
+-{
+-      u32 tmp;
+-
+-      /* Config */
+-      tmp = CMF_CFG_CRC_FWD;
+-      if (cfg->promiscuous_mode_enable)
+-              tmp |= CMD_CFG_PROMIS_EN;
+-      if (cfg->pause_ignore)
+-              tmp |= CMD_CFG_PAUSE_IGNORE;
+-      /* Payload length check disable */
+-      tmp |= CMD_CFG_NO_LEN_CHK;
+-      iowrite32be(tmp, &regs->command_config);
+-
+-      /* Max Frame Length */
+-      iowrite32be((u32)cfg->max_frame_length, &regs->maxfrm);
+-      /* Pause Time */
+-      iowrite32be(cfg->pause_quant, &regs->pause_quant);
+-
+-      /* clear all pending events and set-up interrupts */
+-      iowrite32be(0xffffffff, &regs->ievent);
+-      iowrite32be(ioread32be(&regs->imask) | exception_mask, &regs->imask);
+-
+-      return 0;
+-}
+-
+-static int check_init_parameters(struct fman_mac *tgec)
+-{
+-      if (tgec->max_speed < SPEED_10000) {
+-              pr_err("10G MAC driver only support 10G speed\n");
+-              return -EINVAL;
+-      }
+-      if (tgec->addr == 0) {
+-              pr_err("Ethernet 10G MAC Must have valid MAC Address\n");
+-              return -EINVAL;
+-      }
+-      if (!tgec->exception_cb) {
+-              pr_err("uninitialized exception_cb\n");
+-              return -EINVAL;
+-      }
+-      if (!tgec->event_cb) {
+-              pr_err("uninitialized event_cb\n");
+-              return -EINVAL;
+-      }
+-
+-      return 0;
+-}
+-
+-static int get_exception_flag(enum fman_mac_exceptions exception)
+-{
+-      u32 bit_mask;
+-
+-      switch (exception) {
+-      case FM_MAC_EX_10G_MDIO_SCAN_EVENT:
+-              bit_mask = TGEC_IMASK_MDIO_SCAN_EVENT;
+-              break;
+-      case FM_MAC_EX_10G_MDIO_CMD_CMPL:
+-              bit_mask = TGEC_IMASK_MDIO_CMD_CMPL;
+-              break;
+-      case FM_MAC_EX_10G_REM_FAULT:
+-              bit_mask = TGEC_IMASK_REM_FAULT;
+-              break;
+-      case FM_MAC_EX_10G_LOC_FAULT:
+-              bit_mask = TGEC_IMASK_LOC_FAULT;
+-              break;
+-      case FM_MAC_EX_10G_TX_ECC_ER:
+-              bit_mask = TGEC_IMASK_TX_ECC_ER;
+-              break;
+-      case FM_MAC_EX_10G_TX_FIFO_UNFL:
+-              bit_mask = TGEC_IMASK_TX_FIFO_UNFL;
+-              break;
+-      case FM_MAC_EX_10G_TX_FIFO_OVFL:
+-              bit_mask = TGEC_IMASK_TX_FIFO_OVFL;
+-              break;
+-      case FM_MAC_EX_10G_TX_ER:
+-              bit_mask = TGEC_IMASK_TX_ER;
+-              break;
+-      case FM_MAC_EX_10G_RX_FIFO_OVFL:
+-              bit_mask = TGEC_IMASK_RX_FIFO_OVFL;
+-              break;
+-      case FM_MAC_EX_10G_RX_ECC_ER:
+-              bit_mask = TGEC_IMASK_RX_ECC_ER;
+-              break;
+-      case FM_MAC_EX_10G_RX_JAB_FRM:
+-              bit_mask = TGEC_IMASK_RX_JAB_FRM;
+-              break;
+-      case FM_MAC_EX_10G_RX_OVRSZ_FRM:
+-              bit_mask = TGEC_IMASK_RX_OVRSZ_FRM;
+-              break;
+-      case FM_MAC_EX_10G_RX_RUNT_FRM:
+-              bit_mask = TGEC_IMASK_RX_RUNT_FRM;
+-              break;
+-      case FM_MAC_EX_10G_RX_FRAG_FRM:
+-              bit_mask = TGEC_IMASK_RX_FRAG_FRM;
+-              break;
+-      case FM_MAC_EX_10G_RX_LEN_ER:
+-              bit_mask = TGEC_IMASK_RX_LEN_ER;
+-              break;
+-      case FM_MAC_EX_10G_RX_CRC_ER:
+-              bit_mask = TGEC_IMASK_RX_CRC_ER;
+-              break;
+-      case FM_MAC_EX_10G_RX_ALIGN_ER:
+-              bit_mask = TGEC_IMASK_RX_ALIGN_ER;
+-              break;
+-      default:
+-              bit_mask = 0;
+-              break;
+-      }
+-
+-      return bit_mask;
+-}
+-
+-static void tgec_err_exception(void *handle)
+-{
+-      struct fman_mac *tgec = (struct fman_mac *)handle;
+-      struct tgec_regs __iomem *regs = tgec->regs;
+-      u32 event;
+-
+-      /* do not handle MDIO events */
+-      event = ioread32be(&regs->ievent) &
+-                         ~(TGEC_IMASK_MDIO_SCAN_EVENT |
+-                         TGEC_IMASK_MDIO_CMD_CMPL);
+-
+-      event &= ioread32be(&regs->imask);
+-
+-      iowrite32be(event, &regs->ievent);
+-
+-      if (event & TGEC_IMASK_REM_FAULT)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_REM_FAULT);
+-      if (event & TGEC_IMASK_LOC_FAULT)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_LOC_FAULT);
+-      if (event & TGEC_IMASK_TX_ECC_ER)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_TX_ECC_ER);
+-      if (event & TGEC_IMASK_TX_FIFO_UNFL)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_TX_FIFO_UNFL);
+-      if (event & TGEC_IMASK_TX_FIFO_OVFL)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_TX_FIFO_OVFL);
+-      if (event & TGEC_IMASK_TX_ER)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_TX_ER);
+-      if (event & TGEC_IMASK_RX_FIFO_OVFL)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_FIFO_OVFL);
+-      if (event & TGEC_IMASK_RX_ECC_ER)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_ECC_ER);
+-      if (event & TGEC_IMASK_RX_JAB_FRM)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_JAB_FRM);
+-      if (event & TGEC_IMASK_RX_OVRSZ_FRM)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_OVRSZ_FRM);
+-      if (event & TGEC_IMASK_RX_RUNT_FRM)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_RUNT_FRM);
+-      if (event & TGEC_IMASK_RX_FRAG_FRM)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_FRAG_FRM);
+-      if (event & TGEC_IMASK_RX_LEN_ER)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_LEN_ER);
+-      if (event & TGEC_IMASK_RX_CRC_ER)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_CRC_ER);
+-      if (event & TGEC_IMASK_RX_ALIGN_ER)
+-              tgec->exception_cb(tgec->dev_id, FM_MAC_EX_10G_RX_ALIGN_ER);
+-}
+-
+-static void free_init_resources(struct fman_mac *tgec)
+-{
+-      fman_unregister_intr(tgec->fm, FMAN_MOD_MAC, tgec->mac_id,
+-                           FMAN_INTR_TYPE_ERR);
+-
+-      /* release the driver's group hash table */
+-      free_hash_table(tgec->multicast_addr_hash);
+-      tgec->multicast_addr_hash = NULL;
+-
+-      /* release the driver's individual hash table */
+-      free_hash_table(tgec->unicast_addr_hash);
+-      tgec->unicast_addr_hash = NULL;
+-}
+-
+-static bool is_init_done(struct tgec_cfg *cfg)
+-{
+-      /* Checks if tGEC driver parameters were initialized */
+-      if (!cfg)
+-              return true;
+-
+-      return false;
+-}
+-
+-int tgec_enable(struct fman_mac *tgec, enum comm_mode mode)
+-{
+-      struct tgec_regs __iomem *regs = tgec->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->command_config);
+-      if (mode & COMM_MODE_RX)
+-              tmp |= CMD_CFG_RX_EN;
+-      if (mode & COMM_MODE_TX)
+-              tmp |= CMD_CFG_TX_EN;
+-      iowrite32be(tmp, &regs->command_config);
+-
+-      return 0;
+-}
+-
+-int tgec_disable(struct fman_mac *tgec, enum comm_mode mode)
+-{
+-      struct tgec_regs __iomem *regs = tgec->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->command_config);
+-      if (mode & COMM_MODE_RX)
+-              tmp &= ~CMD_CFG_RX_EN;
+-      if (mode & COMM_MODE_TX)
+-              tmp &= ~CMD_CFG_TX_EN;
+-      iowrite32be(tmp, &regs->command_config);
+-
+-      return 0;
+-}
+-
+-int tgec_set_promiscuous(struct fman_mac *tgec, bool new_val)
+-{
+-      struct tgec_regs __iomem *regs = tgec->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->command_config);
+-      if (new_val)
+-              tmp |= CMD_CFG_PROMIS_EN;
+-      else
+-              tmp &= ~CMD_CFG_PROMIS_EN;
+-      iowrite32be(tmp, &regs->command_config);
+-
+-      return 0;
+-}
+-
+-int tgec_cfg_max_frame_len(struct fman_mac *tgec, u16 new_val)
+-{
+-      if (is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+-      tgec->cfg->max_frame_length = new_val;
+-
+-      return 0;
+-}
+-
+-int tgec_set_tx_pause_frames(struct fman_mac *tgec, u8 __maybe_unused priority,
+-                           u16 pause_time, u16 __maybe_unused thresh_time)
+-{
+-      struct tgec_regs __iomem *regs = tgec->regs;
+-
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+-      iowrite32be((u32)pause_time, &regs->pause_quant);
+-
+-      return 0;
+-}
+-
+-int tgec_accept_rx_pause_frames(struct fman_mac *tgec, bool en)
+-{
+-      struct tgec_regs __iomem *regs = tgec->regs;
+-      u32 tmp;
+-
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+-      tmp = ioread32be(&regs->command_config);
+-      if (!en)
+-              tmp |= CMD_CFG_PAUSE_IGNORE;
+-      else
+-              tmp &= ~CMD_CFG_PAUSE_IGNORE;
+-      iowrite32be(tmp, &regs->command_config);
+-
+-      return 0;
+-}
+-
+-int tgec_modify_mac_address(struct fman_mac *tgec, enet_addr_t *p_enet_addr)
+-{
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+-      tgec->addr = ENET_ADDR_TO_UINT64(*p_enet_addr);
+-      set_mac_address(tgec->regs, (u8 *)(*p_enet_addr));
+-
+-      return 0;
+-}
+-
+-int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
+-{
+-      struct tgec_regs __iomem *regs = tgec->regs;
+-      struct eth_hash_entry *hash_entry;
+-      u32 crc = 0xFFFFFFFF, hash;
+-      u64 addr;
+-
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+-      addr = ENET_ADDR_TO_UINT64(*eth_addr);
+-
+-      if (!(addr & GROUP_ADDRESS)) {
+-              /* Unicast addresses not supported in hash */
+-              pr_err("Unicast Address\n");
+-              return -EINVAL;
+-      }
+-      /* CRC calculation */
+-      crc = crc32_le(crc, (u8 *)eth_addr, ETH_ALEN);
+-      crc = bitrev32(crc);
+-      /* Take 9 MSB bits */
+-      hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK;
+-
+-      /* Create element to be added to the driver hash table */
+-      hash_entry = kmalloc(sizeof(*hash_entry), GFP_KERNEL);
+-      if (!hash_entry)
+-              return -ENOMEM;
+-      hash_entry->addr = addr;
+-      INIT_LIST_HEAD(&hash_entry->node);
+-
+-      list_add_tail(&hash_entry->node,
+-                    &tgec->multicast_addr_hash->lsts[hash]);
+-      iowrite32be((hash | TGEC_HASH_MCAST_EN), &regs->hashtable_ctrl);
+-
+-      return 0;
+-}
+-
+-int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr)
+-{
+-      struct tgec_regs __iomem *regs = tgec->regs;
+-      struct eth_hash_entry *hash_entry = NULL;
+-      struct list_head *pos;
+-      u32 crc = 0xFFFFFFFF, hash;
+-      u64 addr;
+-
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+-      addr = ((*(u64 *)eth_addr) >> 16);
+-
+-      /* CRC calculation */
+-      crc = crc32_le(crc, (u8 *)eth_addr, ETH_ALEN);
+-      crc = bitrev32(crc);
+-      /* Take 9 MSB bits */
+-      hash = (crc >> TGEC_HASH_MCAST_SHIFT) & TGEC_HASH_ADR_MSK;
+-
+-      list_for_each(pos, &tgec->multicast_addr_hash->lsts[hash]) {
+-              hash_entry = ETH_HASH_ENTRY_OBJ(pos);
+-              if (hash_entry->addr == addr) {
+-                      list_del_init(&hash_entry->node);
+-                      kfree(hash_entry);
+-                      break;
+-              }
+-      }
+-      if (list_empty(&tgec->multicast_addr_hash->lsts[hash]))
+-              iowrite32be((hash & ~TGEC_HASH_MCAST_EN),
+-                          &regs->hashtable_ctrl);
+-
+-      return 0;
+-}
+-
+-int tgec_get_version(struct fman_mac *tgec, u32 *mac_version)
+-{
+-      struct tgec_regs __iomem *regs = tgec->regs;
+-
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+-      *mac_version = ioread32be(&regs->tgec_id);
+-
+-      return 0;
+-}
+-
+-int tgec_set_exception(struct fman_mac *tgec,
+-                     enum fman_mac_exceptions exception, bool enable)
+-{
+-      struct tgec_regs __iomem *regs = tgec->regs;
+-      u32 bit_mask = 0;
+-
+-      if (!is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+-      bit_mask = get_exception_flag(exception);
+-      if (bit_mask) {
+-              if (enable)
+-                      tgec->exceptions |= bit_mask;
+-              else
+-                      tgec->exceptions &= ~bit_mask;
+-      } else {
+-              pr_err("Undefined exception\n");
+-              return -EINVAL;
+-      }
+-      if (enable)
+-              iowrite32be(ioread32be(&regs->imask) | bit_mask, &regs->imask);
+-      else
+-              iowrite32be(ioread32be(&regs->imask) & ~bit_mask, &regs->imask);
+-
+-      return 0;
+-}
+-
+-int tgec_init(struct fman_mac *tgec)
+-{
+-      struct tgec_cfg *cfg;
+-      enet_addr_t eth_addr;
+-      int err;
+-
+-      if (is_init_done(tgec->cfg))
+-              return -EINVAL;
+-
+-      if (DEFAULT_RESET_ON_INIT &&
+-          (fman_reset_mac(tgec->fm, tgec->mac_id) != 0)) {
+-              pr_err("Can't reset MAC!\n");
+-              return -EINVAL;
+-      }
+-
+-      err = check_init_parameters(tgec);
+-      if (err)
+-              return err;
+-
+-      cfg = tgec->cfg;
+-
+-      MAKE_ENET_ADDR_FROM_UINT64(tgec->addr, eth_addr);
+-      set_mac_address(tgec->regs, (u8 *)eth_addr);
+-
+-      /* interrupts */
+-      /* FM_10G_REM_N_LCL_FLT_EX_10GMAC_ERRATA_SW005 Errata workaround */
+-      if (tgec->fm_rev_info.major <= 2)
+-              tgec->exceptions &= ~(TGEC_IMASK_REM_FAULT |
+-                                    TGEC_IMASK_LOC_FAULT);
+-
+-      err = init(tgec->regs, cfg, tgec->exceptions);
+-      if (err) {
+-              free_init_resources(tgec);
+-              pr_err("TGEC version doesn't support this i/f mode\n");
+-              return err;
+-      }
+-
+-      /* Max Frame Length */
+-      err = fman_set_mac_max_frame(tgec->fm, tgec->mac_id,
+-                                   cfg->max_frame_length);
+-      if (err) {
+-              pr_err("Setting max frame length FAILED\n");
+-              free_init_resources(tgec);
+-              return -EINVAL;
+-      }
+-
+-      /* FM_TX_FIFO_CORRUPTION_ERRATA_10GMAC_A007 Errata workaround */
+-      if (tgec->fm_rev_info.major == 2) {
+-              struct tgec_regs __iomem *regs = tgec->regs;
+-              u32 tmp;
+-
+-              /* restore the default tx ipg Length */
+-              tmp = (ioread32be(&regs->tx_ipg_len) &
+-                     ~TGEC_TX_IPG_LENGTH_MASK) | 12;
+-
+-              iowrite32be(tmp, &regs->tx_ipg_len);
+-      }
+-
+-      tgec->multicast_addr_hash = alloc_hash_table(TGEC_HASH_TABLE_SIZE);
+-      if (!tgec->multicast_addr_hash) {
+-              free_init_resources(tgec);
+-              pr_err("allocation hash table is FAILED\n");
+-              return -ENOMEM;
+-      }
+-
+-      tgec->unicast_addr_hash = alloc_hash_table(TGEC_HASH_TABLE_SIZE);
+-      if (!tgec->unicast_addr_hash) {
+-              free_init_resources(tgec);
+-              pr_err("allocation hash table is FAILED\n");
+-              return -ENOMEM;
+-      }
+-
+-      fman_register_intr(tgec->fm, FMAN_MOD_MAC, tgec->mac_id,
+-                         FMAN_INTR_TYPE_ERR, tgec_err_exception, tgec);
+-
+-      kfree(cfg);
+-      tgec->cfg = NULL;
+-
+-      return 0;
+-}
+-
+-int tgec_free(struct fman_mac *tgec)
+-{
+-      free_init_resources(tgec);
+-
+-      kfree(tgec->cfg);
+-      kfree(tgec);
+-
+-      return 0;
+-}
+-
+-struct fman_mac *tgec_config(struct fman_mac_params *params)
+-{
+-      struct fman_mac *tgec;
+-      struct tgec_cfg *cfg;
+-      void __iomem *base_addr;
+-
+-      base_addr = params->base_addr;
+-      /* allocate memory for the UCC GETH data structure. */
+-      tgec = kzalloc(sizeof(*tgec), GFP_KERNEL);
+-      if (!tgec)
+-              return NULL;
+-
+-      /* allocate memory for the 10G MAC driver parameters data structure. */
+-      cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
+-      if (!cfg) {
+-              tgec_free(tgec);
+-              return NULL;
+-      }
+-
+-      /* Plant parameter structure pointer */
+-      tgec->cfg = cfg;
+-
+-      set_dflts(cfg);
+-
+-      tgec->regs = base_addr;
+-      tgec->addr = ENET_ADDR_TO_UINT64(params->addr);
+-      tgec->max_speed = params->max_speed;
+-      tgec->mac_id = params->mac_id;
+-      tgec->exceptions = (TGEC_IMASK_MDIO_SCAN_EVENT  |
+-                          TGEC_IMASK_REM_FAULT        |
+-                          TGEC_IMASK_LOC_FAULT        |
+-                          TGEC_IMASK_TX_ECC_ER        |
+-                          TGEC_IMASK_TX_FIFO_UNFL     |
+-                          TGEC_IMASK_TX_FIFO_OVFL     |
+-                          TGEC_IMASK_TX_ER            |
+-                          TGEC_IMASK_RX_FIFO_OVFL     |
+-                          TGEC_IMASK_RX_ECC_ER        |
+-                          TGEC_IMASK_RX_JAB_FRM       |
+-                          TGEC_IMASK_RX_OVRSZ_FRM     |
+-                          TGEC_IMASK_RX_RUNT_FRM      |
+-                          TGEC_IMASK_RX_FRAG_FRM      |
+-                          TGEC_IMASK_RX_CRC_ER        |
+-                          TGEC_IMASK_RX_ALIGN_ER);
+-      tgec->exception_cb = params->exception_cb;
+-      tgec->event_cb = params->event_cb;
+-      tgec->dev_id = params->dev_id;
+-      tgec->fm = params->fm;
+-
+-      /* Save FMan revision */
+-      fman_get_revision(tgec->fm, &tgec->fm_rev_info);
+-
+-      return tgec;
+-}
+diff --git a/drivers/net/ethernet/freescale/fman/fman_tgec.h b/drivers/net/ethernet/freescale/fman/fman_tgec.h
+deleted file mode 100644
+index 514bba9..0000000
+--- a/drivers/net/ethernet/freescale/fman/fman_tgec.h
++++ /dev/null
+@@ -1,55 +0,0 @@
+-/*
+- * Copyright 2008-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 Freescale Semiconductor nor the
+- *       names of its contributors may be used to endorse or promote products
+- *       derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#ifndef __TGEC_H
+-#define __TGEC_H
+-
+-#include "fman_mac.h"
+-
+-struct fman_mac *tgec_config(struct fman_mac_params *params);
+-int tgec_set_promiscuous(struct fman_mac *tgec, bool new_val);
+-int tgec_modify_mac_address(struct fman_mac *tgec, enet_addr_t *enet_addr);
+-int tgec_cfg_max_frame_len(struct fman_mac *tgec, u16 new_val);
+-int tgec_enable(struct fman_mac *tgec, enum comm_mode mode);
+-int tgec_disable(struct fman_mac *tgec, enum comm_mode mode);
+-int tgec_init(struct fman_mac *tgec);
+-int tgec_free(struct fman_mac *tgec);
+-int tgec_accept_rx_pause_frames(struct fman_mac *tgec, bool en);
+-int tgec_set_tx_pause_frames(struct fman_mac *tgec, u8 priority,
+-                           u16 pause_time, u16 thresh_time);
+-int tgec_set_exception(struct fman_mac *tgec,
+-                     enum fman_mac_exceptions exception, bool enable);
+-int tgec_add_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr);
+-int tgec_del_hash_mac_address(struct fman_mac *tgec, enet_addr_t *eth_addr);
+-int tgec_get_version(struct fman_mac *tgec, u32 *mac_version);
+-
+-#endif /* __TGEC_H */
+diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c
+deleted file mode 100644
+index 736db9d..0000000
+--- a/drivers/net/ethernet/freescale/fman/mac.c
++++ /dev/null
+@@ -1,950 +0,0 @@
+-/* Copyright 2008-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 Freescale Semiconductor nor the
+- *     names of its contributors may be used to endorse or promote products
+- *     derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+-
+-#include <linux/init.h>
+-#include <linux/module.h>
+-#include <linux/of_address.h>
+-#include <linux/of_platform.h>
+-#include <linux/of_net.h>
+-#include <linux/of_mdio.h>
+-#include <linux/device.h>
+-#include <linux/phy.h>
+-#include <linux/netdevice.h>
+-#include <linux/phy_fixed.h>
+-#include <linux/etherdevice.h>
+-#include <linux/libfdt_env.h>
+-
+-#include "mac.h"
+-#include "fman_mac.h"
+-#include "fman_dtsec.h"
+-#include "fman_tgec.h"
+-#include "fman_memac.h"
+-
+-MODULE_LICENSE("Dual BSD/GPL");
+-MODULE_DESCRIPTION("FSL FMan MAC API based driver");
+-
+-struct mac_priv_s {
+-      struct device                   *dev;
+-      void __iomem                    *vaddr;
+-      u8                              cell_index;
+-      phy_interface_t                 phy_if;
+-      struct fman                     *fman;
+-      struct device_node              *phy_node;
+-      struct device_node              *internal_phy_node;
+-      /* List of multicast addresses */
+-      struct list_head                mc_addr_list;
+-      struct platform_device          *eth_dev;
+-      struct fixed_phy_status         *fixed_link;
+-      u16                             speed;
+-      u16                             max_speed;
+-
+-      int (*enable)(struct fman_mac *mac_dev, enum comm_mode mode);
+-      int (*disable)(struct fman_mac *mac_dev, enum comm_mode mode);
+-};
+-
+-struct mac_address {
+-      u8 addr[ETH_ALEN];
+-      struct list_head list;
+-};
+-
+-static void mac_exception(void *handle, enum fman_mac_exceptions ex)
+-{
+-      struct mac_device       *mac_dev;
+-      struct mac_priv_s       *priv;
+-
+-      mac_dev = handle;
+-      priv = mac_dev->priv;
+-
+-      if (ex == FM_MAC_EX_10G_RX_FIFO_OVFL) {
+-              /* don't flag RX FIFO after the first */
+-              mac_dev->set_exception(mac_dev->fman_mac,
+-                                     FM_MAC_EX_10G_RX_FIFO_OVFL, false);
+-              dev_err(priv->dev, "10G MAC got RX FIFO Error = %x\n", ex);
+-      }
+-
+-      dev_dbg(priv->dev, "%s:%s() -> %d\n", KBUILD_BASENAME ".c",
+-              __func__, ex);
+-}
+-
+-static void set_fman_mac_params(struct mac_device *mac_dev,
+-                              struct fman_mac_params *params)
+-{
+-      struct mac_priv_s *priv = mac_dev->priv;
+-
+-      params->base_addr = (typeof(params->base_addr))
+-              devm_ioremap(priv->dev, mac_dev->res->start,
+-                           resource_size(mac_dev->res));
+-      memcpy(&params->addr, mac_dev->addr, sizeof(mac_dev->addr));
+-      params->max_speed       = priv->max_speed;
+-      params->phy_if          = priv->phy_if;
+-      params->basex_if        = false;
+-      params->mac_id          = priv->cell_index;
+-      params->fm              = (void *)priv->fman;
+-      params->exception_cb    = mac_exception;
+-      params->event_cb        = mac_exception;
+-      params->dev_id          = mac_dev;
+-      params->internal_phy_node = priv->internal_phy_node;
+-}
+-
+-static int tgec_initialization(struct mac_device *mac_dev)
+-{
+-      int err;
+-      struct mac_priv_s       *priv;
+-      struct fman_mac_params  params;
+-      u32                     version;
+-
+-      priv = mac_dev->priv;
+-
+-      set_fman_mac_params(mac_dev, &params);
+-
+-      mac_dev->fman_mac = tgec_config(&params);
+-      if (!mac_dev->fman_mac) {
+-              err = -EINVAL;
+-              goto _return;
+-      }
+-
+-      err = tgec_cfg_max_frame_len(mac_dev->fman_mac, fman_get_max_frm());
+-      if (err < 0)
+-              goto _return_fm_mac_free;
+-
+-      err = tgec_init(mac_dev->fman_mac);
+-      if (err < 0)
+-              goto _return_fm_mac_free;
+-
+-      /* For 10G MAC, disable Tx ECC exception */
+-      err = mac_dev->set_exception(mac_dev->fman_mac,
+-                                   FM_MAC_EX_10G_TX_ECC_ER, false);
+-      if (err < 0)
+-              goto _return_fm_mac_free;
+-
+-      err = tgec_get_version(mac_dev->fman_mac, &version);
+-      if (err < 0)
+-              goto _return_fm_mac_free;
+-
+-      dev_info(priv->dev, "FMan XGEC version: 0x%08x\n", version);
+-
+-      goto _return;
+-
+-_return_fm_mac_free:
+-      tgec_free(mac_dev->fman_mac);
+-
+-_return:
+-      return err;
+-}
+-
+-static int dtsec_initialization(struct mac_device *mac_dev)
+-{
+-      int                     err;
+-      struct mac_priv_s       *priv;
+-      struct fman_mac_params  params;
+-      u32                     version;
+-
+-      priv = mac_dev->priv;
+-
+-      set_fman_mac_params(mac_dev, &params);
+-
+-      mac_dev->fman_mac = dtsec_config(&params);
+-      if (!mac_dev->fman_mac) {
+-              err = -EINVAL;
+-              goto _return;
+-      }
+-
+-      err = dtsec_cfg_max_frame_len(mac_dev->fman_mac, fman_get_max_frm());
+-      if (err < 0)
+-              goto _return_fm_mac_free;
+-
+-      err = dtsec_cfg_pad_and_crc(mac_dev->fman_mac, true);
+-      if (err < 0)
+-              goto _return_fm_mac_free;
+-
+-      err = dtsec_init(mac_dev->fman_mac);
+-      if (err < 0)
+-              goto _return_fm_mac_free;
+-
+-      /* For 1G MAC, disable by default the MIB counters overflow interrupt */
+-      err = mac_dev->set_exception(mac_dev->fman_mac,
+-                                   FM_MAC_EX_1G_RX_MIB_CNT_OVFL, false);
+-      if (err < 0)
+-              goto _return_fm_mac_free;
+-
+-      err = dtsec_get_version(mac_dev->fman_mac, &version);
+-      if (err < 0)
+-              goto _return_fm_mac_free;
+-
+-      dev_info(priv->dev, "FMan dTSEC version: 0x%08x\n", version);
+-
+-      goto _return;
+-
+-_return_fm_mac_free:
+-      dtsec_free(mac_dev->fman_mac);
+-
+-_return:
+-      return err;
+-}
+-
+-static int memac_initialization(struct mac_device *mac_dev)
+-{
+-      int                      err;
+-      struct mac_priv_s       *priv;
+-      struct fman_mac_params   params;
+-
+-      priv = mac_dev->priv;
+-
+-      set_fman_mac_params(mac_dev, &params);
+-
+-      if (priv->max_speed == SPEED_10000)
+-              params.phy_if = PHY_INTERFACE_MODE_XGMII;
+-
+-      mac_dev->fman_mac = memac_config(&params);
+-      if (!mac_dev->fman_mac) {
+-              err = -EINVAL;
+-              goto _return;
+-      }
+-
+-      err = memac_cfg_max_frame_len(mac_dev->fman_mac, fman_get_max_frm());
+-      if (err < 0)
+-              goto _return_fm_mac_free;
+-
+-      err = memac_cfg_reset_on_init(mac_dev->fman_mac, true);
+-      if (err < 0)
+-              goto _return_fm_mac_free;
+-
+-      err = memac_cfg_fixed_link(mac_dev->fman_mac, priv->fixed_link);
+-      if (err < 0)
+-              goto _return_fm_mac_free;
+-
+-      err = memac_init(mac_dev->fman_mac);
+-      if (err < 0)
+-              goto _return_fm_mac_free;
+-
+-      dev_info(priv->dev, "FMan MEMAC\n");
+-
+-      goto _return;
+-
+-_return_fm_mac_free:
+-      memac_free(mac_dev->fman_mac);
+-
+-_return:
+-      return err;
+-}
+-
+-static int start(struct mac_device *mac_dev)
+-{
+-      int      err;
+-      struct phy_device *phy_dev = mac_dev->phy_dev;
+-      struct mac_priv_s *priv = mac_dev->priv;
+-
+-      err = priv->enable(mac_dev->fman_mac, COMM_MODE_RX_AND_TX);
+-      if (!err && phy_dev)
+-              phy_start(phy_dev);
+-
+-      return err;
+-}
+-
+-static int stop(struct mac_device *mac_dev)
+-{
+-      struct mac_priv_s *priv = mac_dev->priv;
+-
+-      if (mac_dev->phy_dev)
+-              phy_stop(mac_dev->phy_dev);
+-
+-      return priv->disable(mac_dev->fman_mac, COMM_MODE_RX_AND_TX);
+-}
+-
+-static int set_multi(struct net_device *net_dev, struct mac_device *mac_dev)
+-{
+-      struct mac_priv_s       *priv;
+-      struct mac_address      *old_addr, *tmp;
+-      struct netdev_hw_addr   *ha;
+-      int                     err;
+-      enet_addr_t             *addr;
+-
+-      priv = mac_dev->priv;
+-
+-      /* Clear previous address list */
+-      list_for_each_entry_safe(old_addr, tmp, &priv->mc_addr_list, list) {
+-              addr = (enet_addr_t *)old_addr->addr;
+-              err = mac_dev->remove_hash_mac_addr(mac_dev->fman_mac, addr);
+-              if (err < 0)
+-                      return err;
+-
+-              list_del(&old_addr->list);
+-              kfree(old_addr);
+-      }
+-
+-      /* Add all the addresses from the new list */
+-      netdev_for_each_mc_addr(ha, net_dev) {
+-              addr = (enet_addr_t *)ha->addr;
+-              err = mac_dev->add_hash_mac_addr(mac_dev->fman_mac, addr);
+-              if (err < 0)
+-                      return err;
+-
+-              tmp = kmalloc(sizeof(*tmp), GFP_ATOMIC);
+-              if (!tmp)
+-                      return -ENOMEM;
+-
+-              ether_addr_copy(tmp->addr, ha->addr);
+-              list_add(&tmp->list, &priv->mc_addr_list);
+-      }
+-      return 0;
+-}
+-
+-/**
+- * fman_set_mac_active_pause
+- * @mac_dev:  A pointer to the MAC device
+- * @rx:               Pause frame setting for RX
+- * @tx:               Pause frame setting for TX
+- *
+- * Set the MAC RX/TX PAUSE frames settings
+- *
+- * Avoid redundant calls to FMD, if the MAC driver already contains the desired
+- * active PAUSE settings. Otherwise, the new active settings should be reflected
+- * in FMan.
+- *
+- * Return: 0 on success; Error code otherwise.
+- */
+-int fman_set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx)
+-{
+-      struct fman_mac *fman_mac = mac_dev->fman_mac;
+-      int err = 0;
+-
+-      if (rx != mac_dev->rx_pause_active) {
+-              err = mac_dev->set_rx_pause(fman_mac, rx);
+-              if (likely(err == 0))
+-                      mac_dev->rx_pause_active = rx;
+-      }
+-
+-      if (tx != mac_dev->tx_pause_active) {
+-              u16 pause_time = (tx ? FSL_FM_PAUSE_TIME_ENABLE :
+-                                       FSL_FM_PAUSE_TIME_DISABLE);
+-
+-              err = mac_dev->set_tx_pause(fman_mac, 0, pause_time, 0);
+-
+-              if (likely(err == 0))
+-                      mac_dev->tx_pause_active = tx;
+-      }
+-
+-      return err;
+-}
+-EXPORT_SYMBOL(fman_set_mac_active_pause);
+-
+-/**
+- * fman_get_pause_cfg
+- * @mac_dev:  A pointer to the MAC device
+- * @rx:               Return value for RX setting
+- * @tx:               Return value for TX setting
+- *
+- * Determine the MAC RX/TX PAUSE frames settings based on PHY
+- * autonegotiation or values set by eththool.
+- *
+- * Return: Pointer to FMan device.
+- */
+-void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause,
+-                      bool *tx_pause)
+-{
+-      struct phy_device *phy_dev = mac_dev->phy_dev;
+-      u16 lcl_adv, rmt_adv;
+-      u8 flowctrl;
+-
+-      *rx_pause = *tx_pause = false;
+-
+-      if (!phy_dev->duplex)
+-              return;
+-
+-      /* If PAUSE autonegotiation is disabled, the TX/RX PAUSE settings
+-       * are those set by ethtool.
+-       */
+-      if (!mac_dev->autoneg_pause) {
+-              *rx_pause = mac_dev->rx_pause_req;
+-              *tx_pause = mac_dev->tx_pause_req;
+-              return;
+-      }
+-
+-      /* Else if PAUSE autonegotiation is enabled, the TX/RX PAUSE
+-       * settings depend on the result of the link negotiation.
+-       */
+-
+-      /* get local capabilities */
+-      lcl_adv = 0;
+-      if (phy_dev->advertising & ADVERTISED_Pause)
+-              lcl_adv |= ADVERTISE_PAUSE_CAP;
+-      if (phy_dev->advertising & ADVERTISED_Asym_Pause)
+-              lcl_adv |= ADVERTISE_PAUSE_ASYM;
+-
+-      /* get link partner capabilities */
+-      rmt_adv = 0;
+-      if (phy_dev->pause)
+-              rmt_adv |= LPA_PAUSE_CAP;
+-      if (phy_dev->asym_pause)
+-              rmt_adv |= LPA_PAUSE_ASYM;
+-
+-      /* Calculate TX/RX settings based on local and peer advertised
+-       * symmetric/asymmetric PAUSE capabilities.
+-       */
+-      flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv);
+-      if (flowctrl & FLOW_CTRL_RX)
+-              *rx_pause = true;
+-      if (flowctrl & FLOW_CTRL_TX)
+-              *tx_pause = true;
+-}
+-EXPORT_SYMBOL(fman_get_pause_cfg);
+-
+-static void adjust_link_void(struct net_device *net_dev)
+-{
+-}
+-
+-static void adjust_link_dtsec(struct net_device *net_dev)
+-{
+-      struct device *dev = net_dev->dev.parent;
+-      struct dpaa_eth_data *eth_data = dev->platform_data;
+-      struct mac_device *mac_dev = eth_data->mac_dev;
+-      struct phy_device *phy_dev = mac_dev->phy_dev;
+-      struct fman_mac *fman_mac;
+-      bool rx_pause, tx_pause;
+-      int err;
+-
+-      fman_mac = mac_dev->fman_mac;
+-      if (!phy_dev->link) {
+-              dtsec_restart_autoneg(fman_mac);
+-
+-              return;
+-      }
+-
+-      dtsec_adjust_link(fman_mac, phy_dev->speed);
+-      fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
+-      err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
+-      if (err < 0)
+-              netdev_err(net_dev, "fman_set_mac_active_pause() = %d\n", err);
+-}
+-
+-static void adjust_link_memac(struct net_device *net_dev)
+-{
+-      struct device *dev = net_dev->dev.parent;
+-      struct dpaa_eth_data *eth_data = dev->platform_data;
+-      struct mac_device *mac_dev = eth_data->mac_dev;
+-      struct phy_device *phy_dev = mac_dev->phy_dev;
+-      struct fman_mac *fman_mac;
+-      bool rx_pause, tx_pause;
+-      int err;
+-
+-      fman_mac = mac_dev->fman_mac;
+-      memac_adjust_link(fman_mac, phy_dev->speed);
+-
+-      fman_get_pause_cfg(mac_dev, &rx_pause, &tx_pause);
+-      err = fman_set_mac_active_pause(mac_dev, rx_pause, tx_pause);
+-      if (err < 0)
+-              netdev_err(net_dev, "fman_set_mac_active_pause() = %d\n", err);
+-}
+-
+-/* Initializes driver's PHY state, and attaches to the PHY.
+- * Returns 0 on success.
+- */
+-static struct phy_device *init_phy(struct net_device *net_dev,
+-                                 struct mac_device *mac_dev,
+-                                 void (*adj_lnk)(struct net_device *))
+-{
+-      struct phy_device       *phy_dev;
+-      struct mac_priv_s       *priv = mac_dev->priv;
+-
+-      phy_dev = of_phy_connect(net_dev, priv->phy_node, adj_lnk, 0,
+-                               priv->phy_if);
+-      if (!phy_dev) {
+-              netdev_err(net_dev, "Could not connect to PHY\n");
+-              return NULL;
+-      }
+-
+-      /* Remove any features not supported by the controller */
+-      phy_dev->supported &= mac_dev->if_support;
+-      /* Enable the symmetric and asymmetric PAUSE frame advertisements,
+-       * as most of the PHY drivers do not enable them by default.
+-       */
+-      phy_dev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
+-      phy_dev->advertising = phy_dev->supported;
+-
+-      mac_dev->phy_dev = phy_dev;
+-
+-      return phy_dev;
+-}
+-
+-static struct phy_device *dtsec_init_phy(struct net_device *net_dev,
+-                                       struct mac_device *mac_dev)
+-{
+-      return init_phy(net_dev, mac_dev, &adjust_link_dtsec);
+-}
+-
+-static struct phy_device *tgec_init_phy(struct net_device *net_dev,
+-                                      struct mac_device *mac_dev)
+-{
+-      return init_phy(net_dev, mac_dev, adjust_link_void);
+-}
+-
+-static struct phy_device *memac_init_phy(struct net_device *net_dev,
+-                                       struct mac_device *mac_dev)
+-{
+-      return init_phy(net_dev, mac_dev, &adjust_link_memac);
+-}
+-
+-static void setup_dtsec(struct mac_device *mac_dev)
+-{
+-      mac_dev->init_phy               = dtsec_init_phy;
+-      mac_dev->init                   = dtsec_initialization;
+-      mac_dev->set_promisc            = dtsec_set_promiscuous;
+-      mac_dev->change_addr            = dtsec_modify_mac_address;
+-      mac_dev->add_hash_mac_addr      = dtsec_add_hash_mac_address;
+-      mac_dev->remove_hash_mac_addr   = dtsec_del_hash_mac_address;
+-      mac_dev->set_tx_pause           = dtsec_set_tx_pause_frames;
+-      mac_dev->set_rx_pause           = dtsec_accept_rx_pause_frames;
+-      mac_dev->set_exception          = dtsec_set_exception;
+-      mac_dev->set_multi              = set_multi;
+-      mac_dev->start                  = start;
+-      mac_dev->stop                   = stop;
+-
+-      mac_dev->priv->enable           = dtsec_enable;
+-      mac_dev->priv->disable          = dtsec_disable;
+-}
+-
+-static void setup_tgec(struct mac_device *mac_dev)
+-{
+-      mac_dev->init_phy               = tgec_init_phy;
+-      mac_dev->init                   = tgec_initialization;
+-      mac_dev->set_promisc            = tgec_set_promiscuous;
+-      mac_dev->change_addr            = tgec_modify_mac_address;
+-      mac_dev->add_hash_mac_addr      = tgec_add_hash_mac_address;
+-      mac_dev->remove_hash_mac_addr   = tgec_del_hash_mac_address;
+-      mac_dev->set_tx_pause           = tgec_set_tx_pause_frames;
+-      mac_dev->set_rx_pause           = tgec_accept_rx_pause_frames;
+-      mac_dev->set_exception          = tgec_set_exception;
+-      mac_dev->set_multi              = set_multi;
+-      mac_dev->start                  = start;
+-      mac_dev->stop                   = stop;
+-
+-      mac_dev->priv->enable           = tgec_enable;
+-      mac_dev->priv->disable          = tgec_disable;
+-}
+-
+-static void setup_memac(struct mac_device *mac_dev)
+-{
+-      mac_dev->init_phy               = memac_init_phy;
+-      mac_dev->init                   = memac_initialization;
+-      mac_dev->set_promisc            = memac_set_promiscuous;
+-      mac_dev->change_addr            = memac_modify_mac_address;
+-      mac_dev->add_hash_mac_addr      = memac_add_hash_mac_address;
+-      mac_dev->remove_hash_mac_addr   = memac_del_hash_mac_address;
+-      mac_dev->set_tx_pause           = memac_set_tx_pause_frames;
+-      mac_dev->set_rx_pause           = memac_accept_rx_pause_frames;
+-      mac_dev->set_exception          = memac_set_exception;
+-      mac_dev->set_multi              = set_multi;
+-      mac_dev->start                  = start;
+-      mac_dev->stop                   = stop;
+-
+-      mac_dev->priv->enable           = memac_enable;
+-      mac_dev->priv->disable          = memac_disable;
+-}
+-
+-#define DTSEC_SUPPORTED \
+-      (SUPPORTED_10baseT_Half \
+-      | SUPPORTED_10baseT_Full \
+-      | SUPPORTED_100baseT_Half \
+-      | SUPPORTED_100baseT_Full \
+-      | SUPPORTED_Autoneg \
+-      | SUPPORTED_Pause \
+-      | SUPPORTED_Asym_Pause \
+-      | SUPPORTED_MII)
+-
+-static DEFINE_MUTEX(eth_lock);
+-
+-static const u16 phy2speed[] = {
+-      [PHY_INTERFACE_MODE_MII]                = SPEED_100,
+-      [PHY_INTERFACE_MODE_GMII]               = SPEED_1000,
+-      [PHY_INTERFACE_MODE_SGMII]              = SPEED_1000,
+-      [PHY_INTERFACE_MODE_TBI]                = SPEED_1000,
+-      [PHY_INTERFACE_MODE_RMII]               = SPEED_100,
+-      [PHY_INTERFACE_MODE_RGMII]              = SPEED_1000,
+-      [PHY_INTERFACE_MODE_RGMII_ID]           = SPEED_1000,
+-      [PHY_INTERFACE_MODE_RGMII_RXID] = SPEED_1000,
+-      [PHY_INTERFACE_MODE_RGMII_TXID] = SPEED_1000,
+-      [PHY_INTERFACE_MODE_RTBI]               = SPEED_1000,
+-      [PHY_INTERFACE_MODE_XGMII]              = SPEED_10000
+-};
+-
+-static struct platform_device *dpaa_eth_add_device(int fman_id,
+-                                                 struct mac_device *mac_dev,
+-                                                 struct device_node *node)
+-{
+-      struct platform_device *pdev;
+-      struct dpaa_eth_data data;
+-      struct mac_priv_s       *priv;
+-      static int dpaa_eth_dev_cnt;
+-      int ret;
+-
+-      priv = mac_dev->priv;
+-
+-      data.mac_dev = mac_dev;
+-      data.mac_hw_id = priv->cell_index;
+-      data.fman_hw_id = fman_id;
+-      data.mac_node = node;
+-
+-      mutex_lock(&eth_lock);
+-
+-      pdev = platform_device_alloc("dpaa-ethernet", dpaa_eth_dev_cnt);
+-      if (!pdev) {
+-              ret = -ENOMEM;
+-              goto no_mem;
+-      }
+-
+-      ret = platform_device_add_data(pdev, &data, sizeof(data));
+-      if (ret)
+-              goto err;
+-
+-      ret = platform_device_add(pdev);
+-      if (ret)
+-              goto err;
+-
+-      dpaa_eth_dev_cnt++;
+-      mutex_unlock(&eth_lock);
+-
+-      return pdev;
+-
+-err:
+-      platform_device_put(pdev);
+-no_mem:
+-      mutex_unlock(&eth_lock);
+-
+-      return ERR_PTR(ret);
+-}
+-
+-static const struct of_device_id mac_match[] = {
+-      { .compatible   = "fsl,fman-dtsec" },
+-      { .compatible   = "fsl,fman-xgec" },
+-      { .compatible   = "fsl,fman-memac" },
+-      {}
+-};
+-MODULE_DEVICE_TABLE(of, mac_match);
+-
+-static int mac_probe(struct platform_device *_of_dev)
+-{
+-      int                      err, i, nph;
+-      struct device           *dev;
+-      struct device_node      *mac_node, *dev_node;
+-      struct mac_device       *mac_dev;
+-      struct platform_device  *of_dev;
+-      struct resource          res;
+-      struct mac_priv_s       *priv;
+-      const u8                *mac_addr;
+-      u32                      val;
+-      u8                      fman_id;
+-      int                     phy_if;
+-
+-      dev = &_of_dev->dev;
+-      mac_node = dev->of_node;
+-
+-      mac_dev = devm_kzalloc(dev, sizeof(*mac_dev), GFP_KERNEL);
+-      if (!mac_dev) {
+-              err = -ENOMEM;
+-              dev_err(dev, "devm_kzalloc() = %d\n", err);
+-              goto _return;
+-      }
+-      priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
+-      if (!priv) {
+-              err = -ENOMEM;
+-              goto _return;
+-      }
+-
+-      /* Save private information */
+-      mac_dev->priv = priv;
+-      priv->dev = dev;
+-
+-      if (of_device_is_compatible(mac_node, "fsl,fman-dtsec")) {
+-              setup_dtsec(mac_dev);
+-              priv->internal_phy_node = of_parse_phandle(mac_node,
+-                                                        "tbi-handle", 0);
+-      } else if (of_device_is_compatible(mac_node, "fsl,fman-xgec")) {
+-              setup_tgec(mac_dev);
+-      } else if (of_device_is_compatible(mac_node, "fsl,fman-memac")) {
+-              setup_memac(mac_dev);
+-              priv->internal_phy_node = of_parse_phandle(mac_node,
+-                                                        "pcsphy-handle", 0);
+-      } else {
+-              dev_err(dev, "MAC node (%s) contains unsupported MAC\n",
+-                      mac_node->full_name);
+-              err = -EINVAL;
+-              goto _return;
+-      }
+-
+-      /* Register mac_dev */
+-      dev_set_drvdata(dev, mac_dev);
+-
+-      INIT_LIST_HEAD(&priv->mc_addr_list);
+-
+-      /* Get the FM node */
+-      dev_node = of_get_parent(mac_node);
+-      if (!dev_node) {
+-              dev_err(dev, "of_get_parent(%s) failed\n",
+-                      mac_node->full_name);
+-              err = -EINVAL;
+-              goto _return_dev_set_drvdata;
+-      }
+-
+-      of_dev = of_find_device_by_node(dev_node);
+-      if (!of_dev) {
+-              dev_err(dev, "of_find_device_by_node(%s) failed\n",
+-                      dev_node->full_name);
+-              err = -EINVAL;
+-              goto _return_of_node_put;
+-      }
+-
+-      /* Get the FMan cell-index */
+-      err = of_property_read_u32(dev_node, "cell-index", &val);
+-      if (err) {
+-              dev_err(dev, "failed to read cell-index for %s\n",
+-                      dev_node->full_name);
+-              err = -EINVAL;
+-              goto _return_of_node_put;
+-      }
+-      /* cell-index 0 => FMan id 1 */
+-      fman_id = (u8)(val + 1);
+-
+-      priv->fman = fman_bind(&of_dev->dev);
+-      if (!priv->fman) {
+-              dev_err(dev, "fman_bind(%s) failed\n", dev_node->full_name);
+-              err = -ENODEV;
+-              goto _return_of_node_put;
+-      }
+-
+-      of_node_put(dev_node);
+-
+-      /* Get the address of the memory mapped registers */
+-      err = of_address_to_resource(mac_node, 0, &res);
+-      if (err < 0) {
+-              dev_err(dev, "of_address_to_resource(%s) = %d\n",
+-                      mac_node->full_name, err);
+-              goto _return_dev_set_drvdata;
+-      }
+-
+-      mac_dev->res = __devm_request_region(dev,
+-                                           fman_get_mem_region(priv->fman),
+-                                           res.start, res.end + 1 - res.start,
+-                                           "mac");
+-      if (!mac_dev->res) {
+-              dev_err(dev, "__devm_request_mem_region(mac) failed\n");
+-              err = -EBUSY;
+-              goto _return_dev_set_drvdata;
+-      }
+-
+-      priv->vaddr = devm_ioremap(dev, mac_dev->res->start,
+-                                 mac_dev->res->end + 1 - mac_dev->res->start);
+-      if (!priv->vaddr) {
+-              dev_err(dev, "devm_ioremap() failed\n");
+-              err = -EIO;
+-              goto _return_dev_set_drvdata;
+-      }
+-
+-      if (!of_device_is_available(mac_node)) {
+-              devm_iounmap(dev, priv->vaddr);
+-              __devm_release_region(dev, fman_get_mem_region(priv->fman),
+-                                    res.start, res.end + 1 - res.start);
+-              devm_kfree(dev, mac_dev);
+-              dev_set_drvdata(dev, NULL);
+-              return -ENODEV;
+-      }
+-
+-      /* Get the cell-index */
+-      err = of_property_read_u32(mac_node, "cell-index", &val);
+-      if (err) {
+-              dev_err(dev, "failed to read cell-index for %s\n",
+-                      mac_node->full_name);
+-              err = -EINVAL;
+-              goto _return_dev_set_drvdata;
+-      }
+-      priv->cell_index = (u8)val;
+-
+-      /* Get the MAC address */
+-      mac_addr = of_get_mac_address(mac_node);
+-      if (!mac_addr) {
+-              dev_err(dev, "of_get_mac_address(%s) failed\n",
+-                      mac_node->full_name);
+-              err = -EINVAL;
+-              goto _return_dev_set_drvdata;
+-      }
+-      memcpy(mac_dev->addr, mac_addr, sizeof(mac_dev->addr));
+-
+-      /* Get the port handles */
+-      nph = of_count_phandle_with_args(mac_node, "fsl,fman-ports", NULL);
+-      if (unlikely(nph < 0)) {
+-              dev_err(dev, "of_count_phandle_with_args(%s, fsl,fman-ports) failed\n",
+-                      mac_node->full_name);
+-              err = nph;
+-              goto _return_dev_set_drvdata;
+-      }
+-
+-      if (nph != ARRAY_SIZE(mac_dev->port)) {
+-              dev_err(dev, "Not supported number of fman-ports handles of mac node %s from device tree\n",
+-                      mac_node->full_name);
+-              err = -EINVAL;
+-              goto _return_dev_set_drvdata;
+-      }
+-
+-      for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) {
+-              /* Find the port node */
+-              dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i);
+-              if (!dev_node) {
+-                      dev_err(dev, "of_parse_phandle(%s, fsl,fman-ports) failed\n",
+-                              mac_node->full_name);
+-                      err = -EINVAL;
+-                      goto _return_of_node_put;
+-              }
+-
+-              of_dev = of_find_device_by_node(dev_node);
+-              if (!of_dev) {
+-                      dev_err(dev, "of_find_device_by_node(%s) failed\n",
+-                              dev_node->full_name);
+-                      err = -EINVAL;
+-                      goto _return_of_node_put;
+-              }
+-
+-              mac_dev->port[i] = fman_port_bind(&of_dev->dev);
+-              if (!mac_dev->port[i]) {
+-                      dev_err(dev, "dev_get_drvdata(%s) failed\n",
+-                              dev_node->full_name);
+-                      err = -EINVAL;
+-                      goto _return_of_node_put;
+-              }
+-              of_node_put(dev_node);
+-      }
+-
+-      /* Get the PHY connection type */
+-      phy_if = of_get_phy_mode(mac_node);
+-      if (phy_if < 0) {
+-              dev_warn(dev,
+-                       "of_get_phy_mode() for %s failed. Defaulting to SGMII\n",
+-                       mac_node->full_name);
+-              phy_if = PHY_INTERFACE_MODE_SGMII;
+-      }
+-      priv->phy_if = phy_if;
+-
+-      priv->speed             = phy2speed[priv->phy_if];
+-      priv->max_speed         = priv->speed;
+-      mac_dev->if_support     = DTSEC_SUPPORTED;
+-      /* We don't support half-duplex in SGMII mode */
+-      if (priv->phy_if == PHY_INTERFACE_MODE_SGMII)
+-              mac_dev->if_support &= ~(SUPPORTED_10baseT_Half |
+-                                      SUPPORTED_100baseT_Half);
+-
+-      /* Gigabit support (no half-duplex) */
+-      if (priv->max_speed == 1000)
+-              mac_dev->if_support |= SUPPORTED_1000baseT_Full;
+-
+-      /* The 10G interface only supports one mode */
+-      if (priv->phy_if == PHY_INTERFACE_MODE_XGMII)
+-              mac_dev->if_support = SUPPORTED_10000baseT_Full;
+-
+-      /* Get the rest of the PHY information */
+-      priv->phy_node = of_parse_phandle(mac_node, "phy-handle", 0);
+-      if (!priv->phy_node && of_phy_is_fixed_link(mac_node)) {
+-              struct phy_device *phy;
+-
+-              err = of_phy_register_fixed_link(mac_node);
+-              if (err)
+-                      goto _return_dev_set_drvdata;
+-
+-              priv->fixed_link = kzalloc(sizeof(*priv->fixed_link),
+-                                         GFP_KERNEL);
+-              if (!priv->fixed_link)
+-                      goto _return_dev_set_drvdata;
+-
+-              priv->phy_node = of_node_get(mac_node);
+-              phy = of_phy_find_device(priv->phy_node);
+-              if (!phy)
+-                      goto _return_dev_set_drvdata;
+-
+-              priv->fixed_link->link = phy->link;
+-              priv->fixed_link->speed = phy->speed;
+-              priv->fixed_link->duplex = phy->duplex;
+-              priv->fixed_link->pause = phy->pause;
+-              priv->fixed_link->asym_pause = phy->asym_pause;
+-
+-              put_device(&phy->mdio.dev);
+-      }
+-
+-      err = mac_dev->init(mac_dev);
+-      if (err < 0) {
+-              dev_err(dev, "mac_dev->init() = %d\n", err);
+-              of_node_put(priv->phy_node);
+-              goto _return_dev_set_drvdata;
+-      }
+-
+-      /* pause frame autonegotiation enabled */
+-      mac_dev->autoneg_pause = true;
+-
+-      /* By intializing the values to false, force FMD to enable PAUSE frames
+-       * on RX and TX
+-       */
+-      mac_dev->rx_pause_req = true;
+-      mac_dev->tx_pause_req = true;
+-      mac_dev->rx_pause_active = false;
+-      mac_dev->tx_pause_active = false;
+-      err = fman_set_mac_active_pause(mac_dev, true, true);
+-      if (err < 0)
+-              dev_err(dev, "fman_set_mac_active_pause() = %d\n", err);
+-
+-      dev_info(dev, "FMan MAC address: %02hx:%02hx:%02hx:%02hx:%02hx:%02hx\n",
+-               mac_dev->addr[0], mac_dev->addr[1], mac_dev->addr[2],
+-               mac_dev->addr[3], mac_dev->addr[4], mac_dev->addr[5]);
+-
+-      priv->eth_dev = dpaa_eth_add_device(fman_id, mac_dev, mac_node);
+-      if (IS_ERR(priv->eth_dev)) {
+-              dev_err(dev, "failed to add Ethernet platform device for MAC %d\n",
+-                      priv->cell_index);
+-              priv->eth_dev = NULL;
+-      }
+-
+-      goto _return;
+-
+-_return_of_node_put:
+-      of_node_put(dev_node);
+-_return_dev_set_drvdata:
+-      kfree(priv->fixed_link);
+-      dev_set_drvdata(dev, NULL);
+-_return:
+-      return err;
+-}
+-
+-static struct platform_driver mac_driver = {
+-      .driver = {
+-              .name           = KBUILD_MODNAME,
+-              .of_match_table = mac_match,
+-      },
+-      .probe          = mac_probe,
+-};
+-
+-builtin_platform_driver(mac_driver);
+diff --git a/drivers/net/ethernet/freescale/fman/mac.h b/drivers/net/ethernet/freescale/fman/mac.h
+deleted file mode 100644
+index d7313f0..0000000
+--- a/drivers/net/ethernet/freescale/fman/mac.h
++++ /dev/null
+@@ -1,98 +0,0 @@
+-/* Copyright 2008-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 Freescale Semiconductor nor the
+- *     names of its contributors may be used to endorse or promote products
+- *     derived from this software without specific prior written permission.
+- *
+- *
+- * ALTERNATIVELY, this software may be distributed under the terms of the
+- * GNU General Public License ("GPL") as published by the Free Software
+- * Foundation, either version 2 of that License or (at your option) any
+- * later version.
+- *
+- * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``AS IS'' AND ANY
+- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+- * DISCLAIMED. IN NO EVENT SHALL Freescale Semiconductor BE LIABLE FOR ANY
+- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+- */
+-
+-#ifndef __MAC_H
+-#define __MAC_H
+-
+-#include <linux/device.h>
+-#include <linux/if_ether.h>
+-#include <linux/phy.h>
+-#include <linux/list.h>
+-
+-#include "fman_port.h"
+-#include "fman.h"
+-#include "fman_mac.h"
+-
+-struct fman_mac;
+-struct mac_priv_s;
+-
+-struct mac_device {
+-      struct resource         *res;
+-      u8                       addr[ETH_ALEN];
+-      struct fman_port        *port[2];
+-      u32                      if_support;
+-      struct phy_device       *phy_dev;
+-
+-      bool autoneg_pause;
+-      bool rx_pause_req;
+-      bool tx_pause_req;
+-      bool rx_pause_active;
+-      bool tx_pause_active;
+-      bool promisc;
+-
+-      struct phy_device *(*init_phy)(struct net_device *net_dev,
+-                                     struct mac_device *mac_dev);
+-      int (*init)(struct mac_device *mac_dev);
+-      int (*start)(struct mac_device *mac_dev);
+-      int (*stop)(struct mac_device *mac_dev);
+-      int (*set_promisc)(struct fman_mac *mac_dev, bool enable);
+-      int (*change_addr)(struct fman_mac *mac_dev, enet_addr_t *enet_addr);
+-      int (*set_multi)(struct net_device *net_dev,
+-                       struct mac_device *mac_dev);
+-      int (*set_rx_pause)(struct fman_mac *mac_dev, bool en);
+-      int (*set_tx_pause)(struct fman_mac *mac_dev, u8 priority,
+-                          u16 pause_time, u16 thresh_time);
+-      int (*set_exception)(struct fman_mac *mac_dev,
+-                           enum fman_mac_exceptions exception, bool enable);
+-      int (*add_hash_mac_addr)(struct fman_mac *mac_dev,
+-                               enet_addr_t *eth_addr);
+-      int (*remove_hash_mac_addr)(struct fman_mac *mac_dev,
+-                                  enet_addr_t *eth_addr);
+-
+-      struct fman_mac         *fman_mac;
+-      struct mac_priv_s       *priv;
+-};
+-
+-struct dpaa_eth_data {
+-      struct device_node *mac_node;
+-      struct mac_device *mac_dev;
+-      int mac_hw_id;
+-      int fman_hw_id;
+-};
+-
+-extern const char     *mac_driver_description;
+-
+-int fman_set_mac_active_pause(struct mac_device *mac_dev, bool rx, bool tx);
+-
+-void fman_get_pause_cfg(struct mac_device *mac_dev, bool *rx_pause,
+-                      bool *tx_pause);
+-
+-#endif        /* __MAC_H */
+diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+index 4b86260..9b3639e 100644
+--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
++++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c
+@@ -60,9 +60,6 @@ module_param(fs_enet_debug, int, 0);
+ MODULE_PARM_DESC(fs_enet_debug,
+                "Freescale bitmapped debugging message enable value");
+-#define RX_RING_SIZE  32
+-#define TX_RING_SIZE  64
+-
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+ static void fs_enet_netpoll(struct net_device *dev);
+ #endif
+@@ -82,113 +79,20 @@ static void skb_align(struct sk_buff *skb, int align)
+               skb_reserve(skb, align - off);
+ }
+-/* NAPI function */
+-static int fs_enet_napi(struct napi_struct *napi, int budget)
++/* NAPI receive function */
++static int fs_enet_rx_napi(struct napi_struct *napi, int budget)
+ {
+       struct fs_enet_private *fep = container_of(napi, struct fs_enet_private, napi);
+       struct net_device *dev = fep->ndev;
+       const struct fs_platform_info *fpi = fep->fpi;
+       cbd_t __iomem *bdp;
+-      struct sk_buff *skb, *skbn;
++      struct sk_buff *skb, *skbn, *skbt;
+       int received = 0;
+       u16 pkt_len, sc;
+       int curidx;
+-      int dirtyidx, do_wake, do_restart;
+-      int tx_left = TX_RING_SIZE;
+-
+-      spin_lock(&fep->tx_lock);
+-      bdp = fep->dirty_tx;
+-
+-      /* clear status bits for napi*/
+-      (*fep->ops->napi_clear_event)(dev);
+-
+-      do_wake = do_restart = 0;
+-      while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0 && tx_left) {
+-              dirtyidx = bdp - fep->tx_bd_base;
+-
+-              if (fep->tx_free == fep->tx_ring)
+-                      break;
+-
+-              skb = fep->tx_skbuff[dirtyidx];
+-
+-              /*
+-               * Check for errors.
+-               */
+-              if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC |
+-                        BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) {
+-
+-                      if (sc & BD_ENET_TX_HB) /* No heartbeat */
+-                              fep->stats.tx_heartbeat_errors++;
+-                      if (sc & BD_ENET_TX_LC) /* Late collision */
+-                              fep->stats.tx_window_errors++;
+-                      if (sc & BD_ENET_TX_RL) /* Retrans limit */
+-                              fep->stats.tx_aborted_errors++;
+-                      if (sc & BD_ENET_TX_UN) /* Underrun */
+-                              fep->stats.tx_fifo_errors++;
+-                      if (sc & BD_ENET_TX_CSL)        /* Carrier lost */
+-                              fep->stats.tx_carrier_errors++;
+-
+-                      if (sc & (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
+-                              fep->stats.tx_errors++;
+-                              do_restart = 1;
+-                      }
+-              } else
+-                      fep->stats.tx_packets++;
+-
+-              if (sc & BD_ENET_TX_READY) {
+-                      dev_warn(fep->dev,
+-                               "HEY! Enet xmit interrupt and TX_READY.\n");
+-              }
+-
+-              /*
+-               * Deferred means some collisions occurred during transmit,
+-               * but we eventually sent the packet OK.
+-               */
+-              if (sc & BD_ENET_TX_DEF)
+-                      fep->stats.collisions++;
+-
+-              /* unmap */
+-              if (fep->mapped_as_page[dirtyidx])
+-                      dma_unmap_page(fep->dev, CBDR_BUFADDR(bdp),
+-                                     CBDR_DATLEN(bdp), DMA_TO_DEVICE);
+-              else
+-                      dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
+-                                       CBDR_DATLEN(bdp), DMA_TO_DEVICE);
+-              /*
+-               * Free the sk buffer associated with this last transmit.
+-               */
+-              if (skb) {
+-                      dev_kfree_skb(skb);
+-                      fep->tx_skbuff[dirtyidx] = NULL;
+-              }
+-
+-              /*
+-               * Update pointer to next buffer descriptor to be transmitted.
+-               */
+-              if ((sc & BD_ENET_TX_WRAP) == 0)
+-                      bdp++;
+-              else
+-                      bdp = fep->tx_bd_base;
+-
+-              /*
+-               * Since we have freed up a buffer, the ring is no longer
+-               * full.
+-               */
+-              if (++fep->tx_free == MAX_SKB_FRAGS)
+-                      do_wake = 1;
+-              tx_left--;
+-      }
+-
+-      fep->dirty_tx = bdp;
+-
+-      if (do_restart)
+-              (*fep->ops->tx_restart)(dev);
+-
+-      spin_unlock(&fep->tx_lock);
+-
+-      if (do_wake)
+-              netif_wake_queue(dev);
++      if (budget <= 0)
++              return received;
+       /*
+        * First, grab all of the stats for the incoming packet.
+@@ -196,8 +100,10 @@ static int fs_enet_napi(struct napi_struct *napi, int budget)
+        */
+       bdp = fep->cur_rx;
+-      while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0 &&
+-             received < budget) {
++      /* clear RX status bits for napi*/
++      (*fep->ops->napi_clear_rx_event)(dev);
++
++      while (((sc = CBDR_SC(bdp)) & BD_ENET_RX_EMPTY) == 0) {
+               curidx = bdp - fep->rx_bd_base;
+               /*
+@@ -226,10 +132,21 @@ static int fs_enet_napi(struct napi_struct *napi, int budget)
+                       if (sc & BD_ENET_RX_OV)
+                               fep->stats.rx_crc_errors++;
+-                      skbn = fep->rx_skbuff[curidx];
++                      skb = fep->rx_skbuff[curidx];
++
++                      dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
++                              L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
++                              DMA_FROM_DEVICE);
++
++                      skbn = skb;
++
+               } else {
+                       skb = fep->rx_skbuff[curidx];
++                      dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
++                              L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
++                              DMA_FROM_DEVICE);
++
+                       /*
+                        * Process the incoming frame.
+                        */
+@@ -244,31 +161,16 @@ static int fs_enet_napi(struct napi_struct *napi, int budget)
+                                       skb_reserve(skbn, 2);   /* align IP header */
+                                       skb_copy_from_linear_data(skb,
+                                                     skbn->data, pkt_len);
+-                                      swap(skb, skbn);
+-                                      dma_sync_single_for_cpu(fep->dev,
+-                                              CBDR_BUFADDR(bdp),
+-                                              L1_CACHE_ALIGN(pkt_len),
+-                                              DMA_FROM_DEVICE);
++                                      /* swap */
++                                      skbt = skb;
++                                      skb = skbn;
++                                      skbn = skbt;
+                               }
+                       } else {
+                               skbn = netdev_alloc_skb(dev, ENET_RX_FRSIZE);
+-                              if (skbn) {
+-                                      dma_addr_t dma;
+-
++                              if (skbn)
+                                       skb_align(skbn, ENET_RX_ALIGN);
+-
+-                                      dma_unmap_single(fep->dev,
+-                                              CBDR_BUFADDR(bdp),
+-                                              L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+-                                              DMA_FROM_DEVICE);
+-
+-                                      dma = dma_map_single(fep->dev,
+-                                              skbn->data,
+-                                              L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
+-                                              DMA_FROM_DEVICE);
+-                                      CBDW_BUFADDR(bdp, dma);
+-                              }
+                       }
+                       if (skbn != NULL) {
+@@ -283,6 +185,9 @@ static int fs_enet_napi(struct napi_struct *napi, int budget)
+               }
+               fep->rx_skbuff[curidx] = skbn;
++              CBDW_BUFADDR(bdp, dma_map_single(fep->dev, skbn->data,
++                           L1_CACHE_ALIGN(PKT_MAXBUF_SIZE),
++                           DMA_FROM_DEVICE));
+               CBDW_DATLEN(bdp, 0);
+               CBDW_SC(bdp, (sc & ~BD_ENET_RX_STATS) | BD_ENET_RX_EMPTY);
+@@ -295,19 +200,134 @@ static int fs_enet_napi(struct napi_struct *napi, int budget)
+                       bdp = fep->rx_bd_base;
+               (*fep->ops->rx_bd_done)(dev);
++
++              if (received >= budget)
++                      break;
+       }
+       fep->cur_rx = bdp;
+-      if (received < budget && tx_left) {
++      if (received < budget) {
+               /* done */
+               napi_complete(napi);
+-              (*fep->ops->napi_enable)(dev);
++              (*fep->ops->napi_enable_rx)(dev);
++      }
++      return received;
++}
+-              return received;
++static int fs_enet_tx_napi(struct napi_struct *napi, int budget)
++{
++      struct fs_enet_private *fep = container_of(napi, struct fs_enet_private,
++                                                 napi_tx);
++      struct net_device *dev = fep->ndev;
++      cbd_t __iomem *bdp;
++      struct sk_buff *skb;
++      int dirtyidx, do_wake, do_restart;
++      u16 sc;
++      int has_tx_work = 0;
++
++      spin_lock(&fep->tx_lock);
++      bdp = fep->dirty_tx;
++
++      /* clear TX status bits for napi*/
++      (*fep->ops->napi_clear_tx_event)(dev);
++
++      do_wake = do_restart = 0;
++      while (((sc = CBDR_SC(bdp)) & BD_ENET_TX_READY) == 0) {
++              dirtyidx = bdp - fep->tx_bd_base;
++
++              if (fep->tx_free == fep->tx_ring)
++                      break;
++
++              skb = fep->tx_skbuff[dirtyidx];
++
++              /*
++               * Check for errors.
++               */
++              if (sc & (BD_ENET_TX_HB | BD_ENET_TX_LC |
++                        BD_ENET_TX_RL | BD_ENET_TX_UN | BD_ENET_TX_CSL)) {
++
++                      if (sc & BD_ENET_TX_HB) /* No heartbeat */
++                              fep->stats.tx_heartbeat_errors++;
++                      if (sc & BD_ENET_TX_LC) /* Late collision */
++                              fep->stats.tx_window_errors++;
++                      if (sc & BD_ENET_TX_RL) /* Retrans limit */
++                              fep->stats.tx_aborted_errors++;
++                      if (sc & BD_ENET_TX_UN) /* Underrun */
++                              fep->stats.tx_fifo_errors++;
++                      if (sc & BD_ENET_TX_CSL)        /* Carrier lost */
++                              fep->stats.tx_carrier_errors++;
++
++                      if (sc & (BD_ENET_TX_LC | BD_ENET_TX_RL | BD_ENET_TX_UN)) {
++                              fep->stats.tx_errors++;
++                              do_restart = 1;
++                      }
++              } else
++                      fep->stats.tx_packets++;
++
++              if (sc & BD_ENET_TX_READY) {
++                      dev_warn(fep->dev,
++                               "HEY! Enet xmit interrupt and TX_READY.\n");
++              }
++
++              /*
++               * Deferred means some collisions occurred during transmit,
++               * but we eventually sent the packet OK.
++               */
++              if (sc & BD_ENET_TX_DEF)
++                      fep->stats.collisions++;
++
++              /* unmap */
++              if (fep->mapped_as_page[dirtyidx])
++                      dma_unmap_page(fep->dev, CBDR_BUFADDR(bdp),
++                                     CBDR_DATLEN(bdp), DMA_TO_DEVICE);
++              else
++                      dma_unmap_single(fep->dev, CBDR_BUFADDR(bdp),
++                                       CBDR_DATLEN(bdp), DMA_TO_DEVICE);
++
++              /*
++               * Free the sk buffer associated with this last transmit.
++               */
++              if (skb) {
++                      dev_kfree_skb(skb);
++                      fep->tx_skbuff[dirtyidx] = NULL;
++              }
++
++              /*
++               * Update pointer to next buffer descriptor to be transmitted.
++               */
++              if ((sc & BD_ENET_TX_WRAP) == 0)
++                      bdp++;
++              else
++                      bdp = fep->tx_bd_base;
++
++              /*
++               * Since we have freed up a buffer, the ring is no longer
++               * full.
++               */
++              if (++fep->tx_free >= MAX_SKB_FRAGS)
++                      do_wake = 1;
++              has_tx_work = 1;
++      }
++
++      fep->dirty_tx = bdp;
++
++      if (do_restart)
++              (*fep->ops->tx_restart)(dev);
++
++      if (!has_tx_work) {
++              napi_complete(napi);
++              (*fep->ops->napi_enable_tx)(dev);
+       }
+-      return budget;
++      spin_unlock(&fep->tx_lock);
++
++      if (do_wake)
++              netif_wake_queue(dev);
++
++      if (has_tx_work)
++              return budget;
++      return 0;
+ }
+ /*
+@@ -333,18 +353,18 @@ fs_enet_interrupt(int irq, void *dev_id)
+               nr++;
+               int_clr_events = int_events;
+-              int_clr_events &= ~fep->ev_napi;
++              int_clr_events &= ~fep->ev_napi_rx;
+               (*fep->ops->clear_int_events)(dev, int_clr_events);
+               if (int_events & fep->ev_err)
+                       (*fep->ops->ev_error)(dev, int_events);
+-              if (int_events & fep->ev) {
++              if (int_events & fep->ev_rx) {
+                       napi_ok = napi_schedule_prep(&fep->napi);
+-                      (*fep->ops->napi_disable)(dev);
+-                      (*fep->ops->clear_int_events)(dev, fep->ev_napi);
++                      (*fep->ops->napi_disable_rx)(dev);
++                      (*fep->ops->clear_int_events)(dev, fep->ev_napi_rx);
+                       /* NOTE: it is possible for FCCs in NAPI mode    */
+                       /* to submit a spurious interrupt while in poll  */
+@@ -352,6 +372,17 @@ fs_enet_interrupt(int irq, void *dev_id)
+                               __napi_schedule(&fep->napi);
+               }
++              if (int_events & fep->ev_tx) {
++                      napi_ok = napi_schedule_prep(&fep->napi_tx);
++
++                      (*fep->ops->napi_disable_tx)(dev);
++                      (*fep->ops->clear_int_events)(dev, fep->ev_napi_tx);
++
++                      /* NOTE: it is possible for FCCs in NAPI mode    */
++                      /* to submit a spurious interrupt while in poll  */
++                      if (napi_ok)
++                              __napi_schedule(&fep->napi_tx);
++              }
+       }
+       handled = nr > 0;
+@@ -459,9 +490,6 @@ static struct sk_buff *tx_skb_align_workaround(struct net_device *dev,
+ {
+       struct sk_buff *new_skb;
+-      if (skb_linearize(skb))
+-              return NULL;
+-
+       /* Alloc new skb */
+       new_skb = netdev_alloc_skb(dev, skb->len + 4);
+       if (!new_skb)
+@@ -487,27 +515,12 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+       cbd_t __iomem *bdp;
+       int curidx;
+       u16 sc;
+-      int nr_frags;
++      int nr_frags = skb_shinfo(skb)->nr_frags;
+       skb_frag_t *frag;
+       int len;
+-#ifdef CONFIG_FS_ENET_MPC5121_FEC
+-      int is_aligned = 1;
+-      int i;
+-
+-      if (!IS_ALIGNED((unsigned long)skb->data, 4)) {
+-              is_aligned = 0;
+-      } else {
+-              nr_frags = skb_shinfo(skb)->nr_frags;
+-              frag = skb_shinfo(skb)->frags;
+-              for (i = 0; i < nr_frags; i++, frag++) {
+-                      if (!IS_ALIGNED(frag->page_offset, 4)) {
+-                              is_aligned = 0;
+-                              break;
+-                      }
+-              }
+-      }
+-      if (!is_aligned) {
++#ifdef CONFIG_FS_ENET_MPC5121_FEC
++      if (((unsigned long)skb->data) & 0x3) {
+               skb = tx_skb_align_workaround(dev, skb);
+               if (!skb) {
+                       /*
+@@ -519,7 +532,6 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+               }
+       }
+ #endif
+-
+       spin_lock(&fep->tx_lock);
+       /*
+@@ -527,7 +539,6 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+        */
+       bdp = fep->cur_tx;
+-      nr_frags = skb_shinfo(skb)->nr_frags;
+       if (fep->tx_free <= nr_frags || (CBDR_SC(bdp) & BD_ENET_TX_READY)) {
+               netif_stop_queue(dev);
+               spin_unlock(&fep->tx_lock);
+@@ -558,8 +569,7 @@ static int fs_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
+       frag = skb_shinfo(skb)->frags;
+       while (nr_frags) {
+               CBDC_SC(bdp,
+-                      BD_ENET_TX_STATS | BD_ENET_TX_INTR | BD_ENET_TX_LAST |
+-                      BD_ENET_TX_TC);
++                      BD_ENET_TX_STATS | BD_ENET_TX_LAST | BD_ENET_TX_TC);
+               CBDS_SC(bdp, BD_ENET_TX_READY);
+               if ((CBDR_SC(bdp) & BD_ENET_TX_WRAP) == 0)
+@@ -624,15 +634,14 @@ static void fs_timeout(struct net_device *dev)
+       spin_lock_irqsave(&fep->lock, flags);
+       if (dev->flags & IFF_UP) {
+-              phy_stop(dev->phydev);
++              phy_stop(fep->phydev);
+               (*fep->ops->stop)(dev);
+               (*fep->ops->restart)(dev);
+-              phy_start(dev->phydev);
++              phy_start(fep->phydev);
+       }
+-      phy_start(dev->phydev);
+-      wake = fep->tx_free >= MAX_SKB_FRAGS &&
+-             !(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY);
++      phy_start(fep->phydev);
++      wake = fep->tx_free && !(CBDR_SC(fep->cur_tx) & BD_ENET_TX_READY);
+       spin_unlock_irqrestore(&fep->lock, flags);
+       if (wake)
+@@ -645,7 +654,7 @@ static void fs_timeout(struct net_device *dev)
+ static void generic_adjust_link(struct  net_device *dev)
+ {
+       struct fs_enet_private *fep = netdev_priv(dev);
+-      struct phy_device *phydev = dev->phydev;
++      struct phy_device *phydev = fep->phydev;
+       int new_state = 0;
+       if (phydev->link) {
+@@ -714,6 +723,8 @@ static int fs_init_phy(struct net_device *dev)
+               return -ENODEV;
+       }
++      fep->phydev = phydev;
++
+       return 0;
+ }
+@@ -724,10 +735,11 @@ static int fs_enet_open(struct net_device *dev)
+       int err;
+       /* to initialize the fep->cur_rx,... */
+-      /* not doing this, will cause a crash in fs_enet_napi */
++      /* not doing this, will cause a crash in fs_enet_rx_napi */
+       fs_init_bds(fep->ndev);
+       napi_enable(&fep->napi);
++      napi_enable(&fep->napi_tx);
+       /* Install our interrupt handler. */
+       r = request_irq(fep->interrupt, fs_enet_interrupt, IRQF_SHARED,
+@@ -735,6 +747,7 @@ static int fs_enet_open(struct net_device *dev)
+       if (r != 0) {
+               dev_err(fep->dev, "Could not allocate FS_ENET IRQ!");
+               napi_disable(&fep->napi);
++              napi_disable(&fep->napi_tx);
+               return -EINVAL;
+       }
+@@ -742,9 +755,10 @@ static int fs_enet_open(struct net_device *dev)
+       if (err) {
+               free_irq(fep->interrupt, dev);
+               napi_disable(&fep->napi);
++              napi_disable(&fep->napi_tx);
+               return err;
+       }
+-      phy_start(dev->phydev);
++      phy_start(fep->phydev);
+       netif_start_queue(dev);
+@@ -759,7 +773,8 @@ static int fs_enet_close(struct net_device *dev)
+       netif_stop_queue(dev);
+       netif_carrier_off(dev);
+       napi_disable(&fep->napi);
+-      phy_stop(dev->phydev);
++      napi_disable(&fep->napi_tx);
++      phy_stop(fep->phydev);
+       spin_lock_irqsave(&fep->lock, flags);
+       spin_lock(&fep->tx_lock);
+@@ -768,7 +783,8 @@ static int fs_enet_close(struct net_device *dev)
+       spin_unlock_irqrestore(&fep->lock, flags);
+       /* release any irqs */
+-      phy_disconnect(dev->phydev);
++      phy_disconnect(fep->phydev);
++      fep->phydev = NULL;
+       free_irq(fep->interrupt, dev);
+       return 0;
+@@ -813,82 +829,64 @@ static void fs_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+               regs->version = 0;
+ }
+-static int fs_nway_reset(struct net_device *dev)
++static int fs_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+ {
+-      return 0;
++      struct fs_enet_private *fep = netdev_priv(dev);
++
++      if (!fep->phydev)
++              return -ENODEV;
++
++      return phy_ethtool_gset(fep->phydev, cmd);
+ }
+-static u32 fs_get_msglevel(struct net_device *dev)
++static int fs_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+ {
+       struct fs_enet_private *fep = netdev_priv(dev);
+-      return fep->msg_enable;
++
++      if (!fep->phydev)
++              return -ENODEV;
++
++      return phy_ethtool_sset(fep->phydev, cmd);
+ }
+-static void fs_set_msglevel(struct net_device *dev, u32 value)
++static int fs_nway_reset(struct net_device *dev)
+ {
+-      struct fs_enet_private *fep = netdev_priv(dev);
+-      fep->msg_enable = value;
++      return 0;
+ }
+-static int fs_get_tunable(struct net_device *dev,
+-                        const struct ethtool_tunable *tuna, void *data)
++static u32 fs_get_msglevel(struct net_device *dev)
+ {
+       struct fs_enet_private *fep = netdev_priv(dev);
+-      struct fs_platform_info *fpi = fep->fpi;
+-      int ret = 0;
+-
+-      switch (tuna->id) {
+-      case ETHTOOL_RX_COPYBREAK:
+-              *(u32 *)data = fpi->rx_copybreak;
+-              break;
+-      default:
+-              ret = -EINVAL;
+-              break;
+-      }
+-
+-      return ret;
++      return fep->msg_enable;
+ }
+-static int fs_set_tunable(struct net_device *dev,
+-                        const struct ethtool_tunable *tuna, const void *data)
++static void fs_set_msglevel(struct net_device *dev, u32 value)
+ {
+       struct fs_enet_private *fep = netdev_priv(dev);
+-      struct fs_platform_info *fpi = fep->fpi;
+-      int ret = 0;
+-
+-      switch (tuna->id) {
+-      case ETHTOOL_RX_COPYBREAK:
+-              fpi->rx_copybreak = *(u32 *)data;
+-              break;
+-      default:
+-              ret = -EINVAL;
+-              break;
+-      }
+-
+-      return ret;
++      fep->msg_enable = value;
+ }
+ static const struct ethtool_ops fs_ethtool_ops = {
+       .get_drvinfo = fs_get_drvinfo,
+       .get_regs_len = fs_get_regs_len,
++      .get_settings = fs_get_settings,
++      .set_settings = fs_set_settings,
+       .nway_reset = fs_nway_reset,
+       .get_link = ethtool_op_get_link,
+       .get_msglevel = fs_get_msglevel,
+       .set_msglevel = fs_set_msglevel,
+       .get_regs = fs_get_regs,
+       .get_ts_info = ethtool_op_get_ts_info,
+-      .get_link_ksettings = phy_ethtool_get_link_ksettings,
+-      .set_link_ksettings = phy_ethtool_set_link_ksettings,
+-      .get_tunable = fs_get_tunable,
+-      .set_tunable = fs_set_tunable,
+ };
+ static int fs_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ {
++      struct fs_enet_private *fep = netdev_priv(dev);
++
+       if (!netif_running(dev))
+               return -EINVAL;
+-      return phy_mii_ioctl(dev->phydev, rq, cmd);
++      return phy_mii_ioctl(fep->phydev, rq, cmd);
+ }
+ extern int fs_mii_connect(struct net_device *dev);
+@@ -948,8 +946,8 @@ static int fs_enet_probe(struct platform_device *ofdev)
+               fpi->cp_command = *data;
+       }
+-      fpi->rx_ring = RX_RING_SIZE;
+-      fpi->tx_ring = TX_RING_SIZE;
++      fpi->rx_ring = 32;
++      fpi->tx_ring = 64;
+       fpi->rx_copybreak = 240;
+       fpi->napi_weight = 17;
+       fpi->phy_node = of_parse_phandle(ofdev->dev.of_node, "phy-handle", 0);
+@@ -980,7 +978,7 @@ static int fs_enet_probe(struct platform_device *ofdev)
+               err = clk_prepare_enable(clk);
+               if (err) {
+                       ret = err;
+-                      goto out_deregister_fixed_link;
++                      goto out_free_fpi;
+               }
+               fpi->clk_per = clk;
+       }
+@@ -1033,7 +1031,8 @@ static int fs_enet_probe(struct platform_device *ofdev)
+       ndev->netdev_ops = &fs_enet_netdev_ops;
+       ndev->watchdog_timeo = 2 * HZ;
+-      netif_napi_add(ndev, &fep->napi, fs_enet_napi, fpi->napi_weight);
++      netif_napi_add(ndev, &fep->napi, fs_enet_rx_napi, fpi->napi_weight);
++      netif_napi_add(ndev, &fep->napi_tx, fs_enet_tx_napi, 2);
+       ndev->ethtool_ops = &fs_ethtool_ops;
+@@ -1061,9 +1060,6 @@ static int fs_enet_probe(struct platform_device *ofdev)
+       of_node_put(fpi->phy_node);
+       if (fpi->clk_per)
+               clk_disable_unprepare(fpi->clk_per);
+-out_deregister_fixed_link:
+-      if (of_phy_is_fixed_link(ofdev->dev.of_node))
+-              of_phy_deregister_fixed_link(ofdev->dev.of_node);
+ out_free_fpi:
+       kfree(fpi);
+       return ret;
+@@ -1082,8 +1078,6 @@ static int fs_enet_remove(struct platform_device *ofdev)
+       of_node_put(fep->fpi->phy_node);
+       if (fep->fpi->clk_per)
+               clk_disable_unprepare(fep->fpi->clk_per);
+-      if (of_phy_is_fixed_link(ofdev->dev.of_node))
+-              of_phy_deregister_fixed_link(ofdev->dev.of_node);
+       free_netdev(ndev);
+       return 0;
+ }
+diff --git a/drivers/net/ethernet/freescale/fs_enet/fs_enet.h b/drivers/net/ethernet/freescale/fs_enet/fs_enet.h
+index fee24c8..f184d8f 100644
+--- a/drivers/net/ethernet/freescale/fs_enet/fs_enet.h
++++ b/drivers/net/ethernet/freescale/fs_enet/fs_enet.h
+@@ -81,9 +81,12 @@ struct fs_ops {
+       void (*adjust_link)(struct net_device *dev);
+       void (*restart)(struct net_device *dev);
+       void (*stop)(struct net_device *dev);
+-      void (*napi_clear_event)(struct net_device *dev);
+-      void (*napi_enable)(struct net_device *dev);
+-      void (*napi_disable)(struct net_device *dev);
++      void (*napi_clear_rx_event)(struct net_device *dev);
++      void (*napi_enable_rx)(struct net_device *dev);
++      void (*napi_disable_rx)(struct net_device *dev);
++      void (*napi_clear_tx_event)(struct net_device *dev);
++      void (*napi_enable_tx)(struct net_device *dev);
++      void (*napi_disable_tx)(struct net_device *dev);
+       void (*rx_bd_done)(struct net_device *dev);
+       void (*tx_kickstart)(struct net_device *dev);
+       u32 (*get_int_events)(struct net_device *dev);
+@@ -119,6 +122,7 @@ struct phy_info {
+ struct fs_enet_private {
+       struct napi_struct napi;
++      struct napi_struct napi_tx;
+       struct device *dev;     /* pointer back to the device (must be initialized first) */
+       struct net_device *ndev;
+       spinlock_t lock;        /* during all ops except TX pckt processing */
+@@ -145,11 +149,14 @@ struct fs_enet_private {
+       unsigned int last_mii_status;
+       int interrupt;
++      struct phy_device *phydev;
+       int oldduplex, oldspeed, oldlink;       /* current settings */
+       /* event masks */
+-      u32 ev_napi;            /* mask of NAPI events */
+-      u32 ev;                 /* event mask          */
++      u32 ev_napi_rx;         /* mask of NAPI rx events */
++      u32 ev_napi_tx;         /* mask of NAPI rx events */
++      u32 ev_rx;              /* rx event mask          */
++      u32 ev_tx;              /* tx event mask          */
+       u32 ev_err;             /* error event mask       */
+       u16 bd_rx_empty;        /* mask of BD rx empty    */
+diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c b/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c
+index 120c758..08f5b91 100644
+--- a/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c
++++ b/drivers/net/ethernet/freescale/fs_enet/mac-fcc.c
+@@ -90,7 +90,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
+       int ret = -EINVAL;
+       fep->interrupt = irq_of_parse_and_map(ofdev->dev.of_node, 0);
+-      if (!fep->interrupt)
++      if (fep->interrupt == NO_IRQ)
+               goto out;
+       fep->fcc.fccp = of_iomap(ofdev->dev.of_node, 0);
+@@ -124,8 +124,10 @@ static int do_pd_setup(struct fs_enet_private *fep)
+       return ret;
+ }
+-#define FCC_NAPI_EVENT_MSK    (FCC_ENET_RXF | FCC_ENET_RXB | FCC_ENET_TXB)
+-#define FCC_EVENT             (FCC_ENET_RXF | FCC_ENET_TXB)
++#define FCC_NAPI_RX_EVENT_MSK (FCC_ENET_RXF | FCC_ENET_RXB)
++#define FCC_NAPI_TX_EVENT_MSK (FCC_ENET_TXB)
++#define FCC_RX_EVENT          (FCC_ENET_RXF)
++#define FCC_TX_EVENT          (FCC_ENET_TXB)
+ #define FCC_ERR_EVENT_MSK     (FCC_ENET_TXE)
+ static int setup_data(struct net_device *dev)
+@@ -135,8 +137,10 @@ static int setup_data(struct net_device *dev)
+       if (do_pd_setup(fep) != 0)
+               return -EINVAL;
+-      fep->ev_napi = FCC_NAPI_EVENT_MSK;
+-      fep->ev = FCC_EVENT;
++      fep->ev_napi_rx = FCC_NAPI_RX_EVENT_MSK;
++      fep->ev_napi_tx = FCC_NAPI_TX_EVENT_MSK;
++      fep->ev_rx = FCC_RX_EVENT;
++      fep->ev_tx = FCC_TX_EVENT;
+       fep->ev_err = FCC_ERR_EVENT_MSK;
+       return 0;
+@@ -366,7 +370,7 @@ static void restart(struct net_device *dev)
+       /* adjust to speed (for RMII mode) */
+       if (fpi->use_rmii) {
+-              if (dev->phydev->speed == 100)
++              if (fep->phydev->speed == 100)
+                       C8(fcccp, fcc_gfemr, 0x20);
+               else
+                       S8(fcccp, fcc_gfemr, 0x20);
+@@ -392,7 +396,7 @@ static void restart(struct net_device *dev)
+               S32(fccp, fcc_fpsmr, FCC_PSMR_RMII);
+       /* adjust to duplex mode */
+-      if (dev->phydev->duplex)
++      if (fep->phydev->duplex)
+               S32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB);
+       else
+               C32(fccp, fcc_fpsmr, FCC_PSMR_FDE | FCC_PSMR_LPB);
+@@ -420,28 +424,52 @@ static void stop(struct net_device *dev)
+       fs_cleanup_bds(dev);
+ }
+-static void napi_clear_event_fs(struct net_device *dev)
++static void napi_clear_rx_event(struct net_device *dev)
+ {
+       struct fs_enet_private *fep = netdev_priv(dev);
+       fcc_t __iomem *fccp = fep->fcc.fccp;
+-      W16(fccp, fcc_fcce, FCC_NAPI_EVENT_MSK);
++      W16(fccp, fcc_fcce, FCC_NAPI_RX_EVENT_MSK);
+ }
+-static void napi_enable_fs(struct net_device *dev)
++static void napi_enable_rx(struct net_device *dev)
+ {
+       struct fs_enet_private *fep = netdev_priv(dev);
+       fcc_t __iomem *fccp = fep->fcc.fccp;
+-      S16(fccp, fcc_fccm, FCC_NAPI_EVENT_MSK);
++      S16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
+ }
+-static void napi_disable_fs(struct net_device *dev)
++static void napi_disable_rx(struct net_device *dev)
+ {
+       struct fs_enet_private *fep = netdev_priv(dev);
+       fcc_t __iomem *fccp = fep->fcc.fccp;
+-      C16(fccp, fcc_fccm, FCC_NAPI_EVENT_MSK);
++      C16(fccp, fcc_fccm, FCC_NAPI_RX_EVENT_MSK);
++}
++
++static void napi_clear_tx_event(struct net_device *dev)
++{
++      struct fs_enet_private *fep = netdev_priv(dev);
++      fcc_t __iomem *fccp = fep->fcc.fccp;
++
++      W16(fccp, fcc_fcce, FCC_NAPI_TX_EVENT_MSK);
++}
++
++static void napi_enable_tx(struct net_device *dev)
++{
++      struct fs_enet_private *fep = netdev_priv(dev);
++      fcc_t __iomem *fccp = fep->fcc.fccp;
++
++      S16(fccp, fcc_fccm, FCC_NAPI_TX_EVENT_MSK);
++}
++
++static void napi_disable_tx(struct net_device *dev)
++{
++      struct fs_enet_private *fep = netdev_priv(dev);
++      fcc_t __iomem *fccp = fep->fcc.fccp;
++
++      C16(fccp, fcc_fccm, FCC_NAPI_TX_EVENT_MSK);
+ }
+ static void rx_bd_done(struct net_device *dev)
+@@ -524,7 +552,7 @@ static void tx_restart(struct net_device *dev)
+       cbd_t __iomem *prev_bd;
+       cbd_t __iomem *last_tx_bd;
+-      last_tx_bd = fep->tx_bd_base + (fpi->tx_ring - 1);
++      last_tx_bd = fep->tx_bd_base + (fpi->tx_ring * sizeof(cbd_t));
+       /* get the current bd held in TBPTR  and scan back from this point */
+       recheck_bd = curr_tbptr = (cbd_t __iomem *)
+@@ -567,9 +595,12 @@ const struct fs_ops fs_fcc_ops = {
+       .set_multicast_list     = set_multicast_list,
+       .restart                = restart,
+       .stop                   = stop,
+-      .napi_clear_event       = napi_clear_event_fs,
+-      .napi_enable            = napi_enable_fs,
+-      .napi_disable           = napi_disable_fs,
++      .napi_clear_rx_event    = napi_clear_rx_event,
++      .napi_enable_rx         = napi_enable_rx,
++      .napi_disable_rx        = napi_disable_rx,
++      .napi_clear_tx_event    = napi_clear_tx_event,
++      .napi_enable_tx         = napi_enable_tx,
++      .napi_disable_tx        = napi_disable_tx,
+       .rx_bd_done             = rx_bd_done,
+       .tx_kickstart           = tx_kickstart,
+       .get_int_events         = get_int_events,
+diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
+index 777beff..b34214e 100644
+--- a/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
++++ b/drivers/net/ethernet/freescale/fs_enet/mac-fec.c
+@@ -99,7 +99,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
+       struct platform_device *ofdev = to_platform_device(fep->dev);
+       fep->interrupt = irq_of_parse_and_map(ofdev->dev.of_node, 0);
+-      if (!fep->interrupt)
++      if (fep->interrupt == NO_IRQ)
+               return -EINVAL;
+       fep->fec.fecp = of_iomap(ofdev->dev.of_node, 0);
+@@ -109,8 +109,10 @@ static int do_pd_setup(struct fs_enet_private *fep)
+       return 0;
+ }
+-#define FEC_NAPI_EVENT_MSK    (FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_TXF)
+-#define FEC_EVENT             (FEC_ENET_RXF | FEC_ENET_TXF)
++#define FEC_NAPI_RX_EVENT_MSK (FEC_ENET_RXF | FEC_ENET_RXB)
++#define FEC_NAPI_TX_EVENT_MSK (FEC_ENET_TXF | FEC_ENET_TXB)
++#define FEC_RX_EVENT          (FEC_ENET_RXF)
++#define FEC_TX_EVENT          (FEC_ENET_TXF)
+ #define FEC_ERR_EVENT_MSK     (FEC_ENET_HBERR | FEC_ENET_BABR | \
+                                FEC_ENET_BABT | FEC_ENET_EBERR)
+@@ -124,8 +126,10 @@ static int setup_data(struct net_device *dev)
+       fep->fec.hthi = 0;
+       fep->fec.htlo = 0;
+-      fep->ev_napi = FEC_NAPI_EVENT_MSK;
+-      fep->ev = FEC_EVENT;
++      fep->ev_napi_rx = FEC_NAPI_RX_EVENT_MSK;
++      fep->ev_napi_tx = FEC_NAPI_TX_EVENT_MSK;
++      fep->ev_rx = FEC_RX_EVENT;
++      fep->ev_tx = FEC_TX_EVENT;
+       fep->ev_err = FEC_ERR_EVENT_MSK;
+       return 0;
+@@ -250,7 +254,7 @@ static void restart(struct net_device *dev)
+       int r;
+       u32 addrhi, addrlo;
+-      struct mii_bus *mii = dev->phydev->mdio.bus;
++      struct mii_bus* mii = fep->phydev->bus;
+       struct fec_info* fec_inf = mii->priv;
+       r = whack_reset(fep->fec.fecp);
+@@ -329,7 +333,7 @@ static void restart(struct net_device *dev)
+       /*
+        * adjust to duplex mode
+        */
+-      if (dev->phydev->duplex) {
++      if (fep->phydev->duplex) {
+               FC(fecp, r_cntrl, FEC_RCNTRL_DRT);
+               FS(fecp, x_cntrl, FEC_TCNTRL_FDEN);     /* FD enable */
+       } else {
+@@ -359,7 +363,7 @@ static void stop(struct net_device *dev)
+       const struct fs_platform_info *fpi = fep->fpi;
+       struct fec __iomem *fecp = fep->fec.fecp;
+-      struct fec_info *feci = dev->phydev->mdio.bus->priv;
++      struct fec_info* feci= fep->phydev->bus->priv;
+       int i;
+@@ -392,28 +396,52 @@ static void stop(struct net_device *dev)
+       }
+ }
+-static void napi_clear_event_fs(struct net_device *dev)
++static void napi_clear_rx_event(struct net_device *dev)
+ {
+       struct fs_enet_private *fep = netdev_priv(dev);
+       struct fec __iomem *fecp = fep->fec.fecp;
+-      FW(fecp, ievent, FEC_NAPI_EVENT_MSK);
++      FW(fecp, ievent, FEC_NAPI_RX_EVENT_MSK);
+ }
+-static void napi_enable_fs(struct net_device *dev)
++static void napi_enable_rx(struct net_device *dev)
+ {
+       struct fs_enet_private *fep = netdev_priv(dev);
+       struct fec __iomem *fecp = fep->fec.fecp;
+-      FS(fecp, imask, FEC_NAPI_EVENT_MSK);
++      FS(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
+ }
+-static void napi_disable_fs(struct net_device *dev)
++static void napi_disable_rx(struct net_device *dev)
+ {
+       struct fs_enet_private *fep = netdev_priv(dev);
+       struct fec __iomem *fecp = fep->fec.fecp;
+-      FC(fecp, imask, FEC_NAPI_EVENT_MSK);
++      FC(fecp, imask, FEC_NAPI_RX_EVENT_MSK);
++}
++
++static void napi_clear_tx_event(struct net_device *dev)
++{
++      struct fs_enet_private *fep = netdev_priv(dev);
++      struct fec __iomem *fecp = fep->fec.fecp;
++
++      FW(fecp, ievent, FEC_NAPI_TX_EVENT_MSK);
++}
++
++static void napi_enable_tx(struct net_device *dev)
++{
++      struct fs_enet_private *fep = netdev_priv(dev);
++      struct fec __iomem *fecp = fep->fec.fecp;
++
++      FS(fecp, imask, FEC_NAPI_TX_EVENT_MSK);
++}
++
++static void napi_disable_tx(struct net_device *dev)
++{
++      struct fs_enet_private *fep = netdev_priv(dev);
++      struct fec __iomem *fecp = fep->fec.fecp;
++
++      FC(fecp, imask, FEC_NAPI_TX_EVENT_MSK);
+ }
+ static void rx_bd_done(struct net_device *dev)
+@@ -485,9 +513,12 @@ const struct fs_ops fs_fec_ops = {
+       .set_multicast_list     = set_multicast_list,
+       .restart                = restart,
+       .stop                   = stop,
+-      .napi_clear_event       = napi_clear_event_fs,
+-      .napi_enable            = napi_enable_fs,
+-      .napi_disable           = napi_disable_fs,
++      .napi_clear_rx_event    = napi_clear_rx_event,
++      .napi_enable_rx         = napi_enable_rx,
++      .napi_disable_rx        = napi_disable_rx,
++      .napi_clear_tx_event    = napi_clear_tx_event,
++      .napi_enable_tx         = napi_enable_tx,
++      .napi_disable_tx        = napi_disable_tx,
+       .rx_bd_done             = rx_bd_done,
+       .tx_kickstart           = tx_kickstart,
+       .get_int_events         = get_int_events,
+diff --git a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
+index 15abd37..7a184e8 100644
+--- a/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
++++ b/drivers/net/ethernet/freescale/fs_enet/mac-scc.c
+@@ -99,7 +99,7 @@ static int do_pd_setup(struct fs_enet_private *fep)
+       struct platform_device *ofdev = to_platform_device(fep->dev);
+       fep->interrupt = irq_of_parse_and_map(ofdev->dev.of_node, 0);
+-      if (!fep->interrupt)
++      if (fep->interrupt == NO_IRQ)
+               return -EINVAL;
+       fep->scc.sccp = of_iomap(ofdev->dev.of_node, 0);
+@@ -115,8 +115,10 @@ static int do_pd_setup(struct fs_enet_private *fep)
+       return 0;
+ }
+-#define SCC_NAPI_EVENT_MSK    (SCCE_ENET_RXF | SCCE_ENET_RXB | SCCE_ENET_TXB)
+-#define SCC_EVENT             (SCCE_ENET_RXF | SCCE_ENET_TXB)
++#define SCC_NAPI_RX_EVENT_MSK (SCCE_ENET_RXF | SCCE_ENET_RXB)
++#define SCC_NAPI_TX_EVENT_MSK (SCCE_ENET_TXB)
++#define SCC_RX_EVENT          (SCCE_ENET_RXF)
++#define SCC_TX_EVENT          (SCCE_ENET_TXB)
+ #define SCC_ERR_EVENT_MSK     (SCCE_ENET_TXE | SCCE_ENET_BSY)
+ static int setup_data(struct net_device *dev)
+@@ -128,8 +130,10 @@ static int setup_data(struct net_device *dev)
+       fep->scc.hthi = 0;
+       fep->scc.htlo = 0;
+-      fep->ev_napi = SCC_NAPI_EVENT_MSK;
+-      fep->ev = SCC_EVENT | SCCE_ENET_TXE;
++      fep->ev_napi_rx = SCC_NAPI_RX_EVENT_MSK;
++      fep->ev_napi_tx = SCC_NAPI_TX_EVENT_MSK;
++      fep->ev_rx = SCC_RX_EVENT;
++      fep->ev_tx = SCC_TX_EVENT | SCCE_ENET_TXE;
+       fep->ev_err = SCC_ERR_EVENT_MSK;
+       return 0;
+@@ -348,7 +352,7 @@ static void restart(struct net_device *dev)
+       W16(sccp, scc_psmr, SCC_PSMR_ENCRC | SCC_PSMR_NIB22);
+       /* Set full duplex mode if needed */
+-      if (dev->phydev->duplex)
++      if (fep->phydev->duplex)
+               S16(sccp, scc_psmr, SCC_PSMR_LPB | SCC_PSMR_FDE);
+       /* Restore multicast and promiscuous settings */
+@@ -375,28 +379,52 @@ static void stop(struct net_device *dev)
+       fs_cleanup_bds(dev);
+ }
+-static void napi_clear_event_fs(struct net_device *dev)
++static void napi_clear_rx_event(struct net_device *dev)
+ {
+       struct fs_enet_private *fep = netdev_priv(dev);
+       scc_t __iomem *sccp = fep->scc.sccp;
+-      W16(sccp, scc_scce, SCC_NAPI_EVENT_MSK);
++      W16(sccp, scc_scce, SCC_NAPI_RX_EVENT_MSK);
+ }
+-static void napi_enable_fs(struct net_device *dev)
++static void napi_enable_rx(struct net_device *dev)
+ {
+       struct fs_enet_private *fep = netdev_priv(dev);
+       scc_t __iomem *sccp = fep->scc.sccp;
+-      S16(sccp, scc_sccm, SCC_NAPI_EVENT_MSK);
++      S16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
+ }
+-static void napi_disable_fs(struct net_device *dev)
++static void napi_disable_rx(struct net_device *dev)
+ {
+       struct fs_enet_private *fep = netdev_priv(dev);
+       scc_t __iomem *sccp = fep->scc.sccp;
+-      C16(sccp, scc_sccm, SCC_NAPI_EVENT_MSK);
++      C16(sccp, scc_sccm, SCC_NAPI_RX_EVENT_MSK);
++}
++
++static void napi_clear_tx_event(struct net_device *dev)
++{
++      struct fs_enet_private *fep = netdev_priv(dev);
++      scc_t __iomem *sccp = fep->scc.sccp;
++
++      W16(sccp, scc_scce, SCC_NAPI_TX_EVENT_MSK);
++}
++
++static void napi_enable_tx(struct net_device *dev)
++{
++      struct fs_enet_private *fep = netdev_priv(dev);
++      scc_t __iomem *sccp = fep->scc.sccp;
++
++      S16(sccp, scc_sccm, SCC_NAPI_TX_EVENT_MSK);
++}
++
++static void napi_disable_tx(struct net_device *dev)
++{
++      struct fs_enet_private *fep = netdev_priv(dev);
++      scc_t __iomem *sccp = fep->scc.sccp;
++
++      C16(sccp, scc_sccm, SCC_NAPI_TX_EVENT_MSK);
+ }
+ static void rx_bd_done(struct net_device *dev)
+@@ -469,9 +497,12 @@ const struct fs_ops fs_scc_ops = {
+       .set_multicast_list     = set_multicast_list,
+       .restart                = restart,
+       .stop                   = stop,
+-      .napi_clear_event       = napi_clear_event_fs,
+-      .napi_enable            = napi_enable_fs,
+-      .napi_disable           = napi_disable_fs,
++      .napi_clear_rx_event    = napi_clear_rx_event,
++      .napi_enable_rx         = napi_enable_rx,
++      .napi_disable_rx        = napi_disable_rx,
++      .napi_clear_tx_event    = napi_clear_tx_event,
++      .napi_enable_tx         = napi_enable_tx,
++      .napi_disable_tx        = napi_disable_tx,
+       .rx_bd_done             = rx_bd_done,
+       .tx_kickstart           = tx_kickstart,
+       .get_int_events         = get_int_events,
+diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
+index 1f015ed..68a428d 100644
+--- a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
++++ b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c
+@@ -172,16 +172,23 @@ static int fs_enet_mdio_probe(struct platform_device *ofdev)
+               goto out_free_bus;
+       new_bus->phy_mask = ~0;
++      new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
++      if (!new_bus->irq) {
++              ret = -ENOMEM;
++              goto out_unmap_regs;
++      }
+       new_bus->parent = &ofdev->dev;
+       platform_set_drvdata(ofdev, new_bus);
+       ret = of_mdiobus_register(new_bus, ofdev->dev.of_node);
+       if (ret)
+-              goto out_unmap_regs;
++              goto out_free_irqs;
+       return 0;
++out_free_irqs:
++      kfree(new_bus->irq);
+ out_unmap_regs:
+       iounmap(bitbang->dir);
+ out_free_bus:
+@@ -198,6 +205,7 @@ static int fs_enet_mdio_remove(struct platform_device *ofdev)
+       struct bb_info *bitbang = bus->priv;
+       mdiobus_unregister(bus);
++      kfree(bus->irq);
+       free_mdio_bitbang(bus);
+       iounmap(bitbang->dir);
+       kfree(bitbang);
+diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
+index a89267b..2be383e 100644
+--- a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
++++ b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c
+@@ -166,16 +166,23 @@ static int fs_enet_mdio_probe(struct platform_device *ofdev)
+       clrsetbits_be32(&fec->fecp->fec_mii_speed, 0x7E, fec->mii_speed);
+       new_bus->phy_mask = ~0;
++      new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
++      if (!new_bus->irq) {
++              ret = -ENOMEM;
++              goto out_unmap_regs;
++      }
+       new_bus->parent = &ofdev->dev;
+       platform_set_drvdata(ofdev, new_bus);
+       ret = of_mdiobus_register(new_bus, ofdev->dev.of_node);
+       if (ret)
+-              goto out_unmap_regs;
++              goto out_free_irqs;
+       return 0;
++out_free_irqs:
++      kfree(new_bus->irq);
+ out_unmap_regs:
+       iounmap(fec->fecp);
+ out_res:
+@@ -193,6 +200,7 @@ static int fs_enet_mdio_remove(struct platform_device *ofdev)
+       struct fec_info *fec = bus->priv;
+       mdiobus_unregister(bus);
++      kfree(bus->irq);
+       iounmap(fec->fecp);
+       kfree(fec);
+       mdiobus_free(bus);
+diff --git a/drivers/net/ethernet/freescale/fsl_pq_mdio.c b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
+index 446c7b3..3c40f6b 100644
+--- a/drivers/net/ethernet/freescale/fsl_pq_mdio.c
++++ b/drivers/net/ethernet/freescale/fsl_pq_mdio.c
+@@ -29,7 +29,7 @@
+ #include <asm/io.h>
+ #if IS_ENABLED(CONFIG_UCC_GETH)
+-#include <soc/fsl/qe/ucc.h>
++#include <asm/ucc.h>  /* for ucc_set_qe_mux_mii_mng() */
+ #endif
+ #include "gianfar.h"
+@@ -69,6 +69,7 @@ struct fsl_pq_mdio {
+ struct fsl_pq_mdio_priv {
+       void __iomem *map;
+       struct fsl_pq_mii __iomem *regs;
++      int irqs[PHY_MAX_ADDR];
+ };
+ /*
+@@ -195,15 +196,13 @@ static int fsl_pq_mdio_reset(struct mii_bus *bus)
+       return 0;
+ }
+-#if IS_ENABLED(CONFIG_GIANFAR)
++#if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE)
+ /*
+- * Return the TBIPA address, starting from the address
+- * of the mapped GFAR MDIO registers (struct gfar)
+  * This is mildly evil, but so is our hardware for doing this.
+  * Also, we have to cast back to struct gfar because of
+  * definition weirdness done in gianfar.h.
+  */
+-static uint32_t __iomem *get_gfar_tbipa_from_mdio(void __iomem *p)
++static uint32_t __iomem *get_gfar_tbipa(void __iomem *p)
+ {
+       struct gfar __iomem *enet_regs = p;
+@@ -211,15 +210,6 @@ static uint32_t __iomem *get_gfar_tbipa_from_mdio(void __iomem *p)
+ }
+ /*
+- * Return the TBIPA address, starting from the address
+- * of the mapped GFAR MII registers (gfar_mii_regs[] within struct gfar)
+- */
+-static uint32_t __iomem *get_gfar_tbipa_from_mii(void __iomem *p)
+-{
+-      return get_gfar_tbipa_from_mdio(container_of(p, struct gfar, gfar_mii_regs));
+-}
+-
+-/*
+  * Return the TBIPAR address for an eTSEC2 node
+  */
+ static uint32_t __iomem *get_etsec_tbipa(void __iomem *p)
+@@ -228,14 +218,13 @@ static uint32_t __iomem *get_etsec_tbipa(void __iomem *p)
+ }
+ #endif
+-#if IS_ENABLED(CONFIG_UCC_GETH)
++#if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE)
+ /*
+- * Return the TBIPAR address for a QE MDIO node, starting from the address
+- * of the mapped MII registers (struct fsl_pq_mii)
++ * Return the TBIPAR address for a QE MDIO node
+  */
+ static uint32_t __iomem *get_ucc_tbipa(void __iomem *p)
+ {
+-      struct fsl_pq_mdio __iomem *mdio = container_of(p, struct fsl_pq_mdio, mii);
++      struct fsl_pq_mdio __iomem *mdio = p;
+       return &mdio->utbipar;
+ }
+@@ -306,19 +295,19 @@ static void ucc_configure(phys_addr_t start, phys_addr_t end)
+ #endif
+ static const struct of_device_id fsl_pq_mdio_match[] = {
+-#if IS_ENABLED(CONFIG_GIANFAR)
++#if defined(CONFIG_GIANFAR) || defined(CONFIG_GIANFAR_MODULE)
+       {
+               .compatible = "fsl,gianfar-tbi",
+               .data = &(struct fsl_pq_mdio_data) {
+                       .mii_offset = 0,
+-                      .get_tbipa = get_gfar_tbipa_from_mii,
++                      .get_tbipa = get_gfar_tbipa,
+               },
+       },
+       {
+               .compatible = "fsl,gianfar-mdio",
+               .data = &(struct fsl_pq_mdio_data) {
+                       .mii_offset = 0,
+-                      .get_tbipa = get_gfar_tbipa_from_mii,
++                      .get_tbipa = get_gfar_tbipa,
+               },
+       },
+       {
+@@ -326,7 +315,7 @@ static const struct of_device_id fsl_pq_mdio_match[] = {
+               .compatible = "gianfar",
+               .data = &(struct fsl_pq_mdio_data) {
+                       .mii_offset = offsetof(struct fsl_pq_mdio, mii),
+-                      .get_tbipa = get_gfar_tbipa_from_mdio,
++                      .get_tbipa = get_gfar_tbipa,
+               },
+       },
+       {
+@@ -344,7 +333,7 @@ static const struct of_device_id fsl_pq_mdio_match[] = {
+               },
+       },
+ #endif
+-#if IS_ENABLED(CONFIG_UCC_GETH)
++#if defined(CONFIG_UCC_GETH) || defined(CONFIG_UCC_GETH_MODULE)
+       {
+               .compatible = "fsl,ucc-mdio",
+               .data = &(struct fsl_pq_mdio_data) {
+@@ -400,6 +389,7 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev)
+       new_bus->read = &fsl_pq_mdio_read;
+       new_bus->write = &fsl_pq_mdio_write;
+       new_bus->reset = &fsl_pq_mdio_reset;
++      new_bus->irq = priv->irqs;
+       err = of_address_to_resource(np, 0, &res);
+       if (err < 0) {
+@@ -455,16 +445,6 @@ static int fsl_pq_mdio_probe(struct platform_device *pdev)
+                       tbipa = data->get_tbipa(priv->map);
+-                      /*
+-                       * Add consistency check to make sure TBI is contained
+-                       * within the mapped range (not because we would get a
+-                       * segfault, rather to catch bugs in computing TBI
+-                       * address). Print error message but continue anyway.
+-                       */
+-                      if ((void *)tbipa > priv->map + resource_size(&res) - 4)
+-                              dev_err(&pdev->dev, "invalid register map (should be at least 0x%04zx to contain TBI address)\n",
+-                                      ((void *)tbipa - priv->map) + 4);
+-
+                       iowrite32be(be32_to_cpup(prop), tbipa);
+               }
+       }
+diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
+index 9061c2f..4ee080d 100644
+--- a/drivers/net/ethernet/freescale/gianfar.c
++++ b/drivers/net/ethernet/freescale/gianfar.c
+@@ -107,17 +107,17 @@
+ #include "gianfar.h"
+-#define TX_TIMEOUT      (5*HZ)
++#define TX_TIMEOUT      (1*HZ)
+-const char gfar_driver_version[] = "2.0";
++const char gfar_driver_version[] = "1.3";
+ static int gfar_enet_open(struct net_device *dev);
+ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev);
+ static void gfar_reset_task(struct work_struct *work);
+ static void gfar_timeout(struct net_device *dev);
+ static int gfar_close(struct net_device *dev);
+-static void gfar_alloc_rx_buffs(struct gfar_priv_rx_q *rx_queue,
+-                              int alloc_cnt);
++static struct sk_buff *gfar_new_skb(struct net_device *dev,
++                                  dma_addr_t *bufaddr);
+ static int gfar_set_mac_address(struct net_device *dev);
+ static int gfar_change_mtu(struct net_device *dev, int new_mtu);
+ static irqreturn_t gfar_error(int irq, void *dev_id);
+@@ -141,7 +141,8 @@ static void gfar_netpoll(struct net_device *dev);
+ #endif
+ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit);
+ static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue);
+-static void gfar_process_frame(struct net_device *ndev, struct sk_buff *skb);
++static void gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
++                             int amount_pull, struct napi_struct *napi);
+ static void gfar_halt_nodisable(struct gfar_private *priv);
+ static void gfar_clear_exact_match(struct net_device *dev);
+ static void gfar_set_mac_for_addr(struct net_device *dev, int num,
+@@ -168,15 +169,17 @@ static void gfar_init_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp,
+       bdp->lstatus = cpu_to_be32(lstatus);
+ }
+-static void gfar_init_bds(struct net_device *ndev)
++static int gfar_init_bds(struct net_device *ndev)
+ {
+       struct gfar_private *priv = netdev_priv(ndev);
+       struct gfar __iomem *regs = priv->gfargrp[0].regs;
+       struct gfar_priv_tx_q *tx_queue = NULL;
+       struct gfar_priv_rx_q *rx_queue = NULL;
+       struct txbd8 *txbdp;
++      struct rxbd8 *rxbdp;
+       u32 __iomem *rfbptr;
+       int i, j;
++      dma_addr_t bufaddr;
+       for (i = 0; i < priv->num_tx_queues; i++) {
+               tx_queue = priv->tx_queue[i];
+@@ -204,26 +207,40 @@ static void gfar_init_bds(struct net_device *ndev)
+       rfbptr = &regs->rfbptr0;
+       for (i = 0; i < priv->num_rx_queues; i++) {
+               rx_queue = priv->rx_queue[i];
++              rx_queue->cur_rx = rx_queue->rx_bd_base;
++              rx_queue->skb_currx = 0;
++              rxbdp = rx_queue->rx_bd_base;
+-              rx_queue->next_to_clean = 0;
+-              rx_queue->next_to_use = 0;
+-              rx_queue->next_to_alloc = 0;
++              for (j = 0; j < rx_queue->rx_ring_size; j++) {
++                      struct sk_buff *skb = rx_queue->rx_skbuff[j];
+-              /* make sure next_to_clean != next_to_use after this
+-               * by leaving at least 1 unused descriptor
+-               */
+-              gfar_alloc_rx_buffs(rx_queue, gfar_rxbd_unused(rx_queue));
++                      if (skb) {
++                              bufaddr = be32_to_cpu(rxbdp->bufPtr);
++                      } else {
++                              skb = gfar_new_skb(ndev, &bufaddr);
++                              if (!skb) {
++                                      netdev_err(ndev, "Can't allocate RX buffers\n");
++                                      return -ENOMEM;
++                              }
++                              rx_queue->rx_skbuff[j] = skb;
++                      }
++
++                      gfar_init_rxbdp(rx_queue, rxbdp, bufaddr);
++                      rxbdp++;
++              }
+               rx_queue->rfbptr = rfbptr;
+               rfbptr += 2;
+       }
++
++      return 0;
+ }
+ static int gfar_alloc_skb_resources(struct net_device *ndev)
+ {
+       void *vaddr;
+       dma_addr_t addr;
+-      int i, j;
++      int i, j, k;
+       struct gfar_private *priv = netdev_priv(ndev);
+       struct device *dev = priv->dev;
+       struct gfar_priv_tx_q *tx_queue = NULL;
+@@ -262,8 +279,7 @@ static int gfar_alloc_skb_resources(struct net_device *ndev)
+               rx_queue = priv->rx_queue[i];
+               rx_queue->rx_bd_base = vaddr;
+               rx_queue->rx_bd_dma_base = addr;
+-              rx_queue->ndev = ndev;
+-              rx_queue->dev = dev;
++              rx_queue->dev = ndev;
+               addr  += sizeof(struct rxbd8) * rx_queue->rx_ring_size;
+               vaddr += sizeof(struct rxbd8) * rx_queue->rx_ring_size;
+       }
+@@ -278,20 +294,25 @@ static int gfar_alloc_skb_resources(struct net_device *ndev)
+               if (!tx_queue->tx_skbuff)
+                       goto cleanup;
+-              for (j = 0; j < tx_queue->tx_ring_size; j++)
+-                      tx_queue->tx_skbuff[j] = NULL;
++              for (k = 0; k < tx_queue->tx_ring_size; k++)
++                      tx_queue->tx_skbuff[k] = NULL;
+       }
+       for (i = 0; i < priv->num_rx_queues; i++) {
+               rx_queue = priv->rx_queue[i];
+-              rx_queue->rx_buff = kcalloc(rx_queue->rx_ring_size,
+-                                          sizeof(*rx_queue->rx_buff),
+-                                          GFP_KERNEL);
+-              if (!rx_queue->rx_buff)
++              rx_queue->rx_skbuff =
++                      kmalloc_array(rx_queue->rx_ring_size,
++                                    sizeof(*rx_queue->rx_skbuff),
++                                    GFP_KERNEL);
++              if (!rx_queue->rx_skbuff)
+                       goto cleanup;
++
++              for (j = 0; j < rx_queue->rx_ring_size; j++)
++                      rx_queue->rx_skbuff[j] = NULL;
+       }
+-      gfar_init_bds(ndev);
++      if (gfar_init_bds(ndev))
++              goto cleanup;
+       return 0;
+@@ -333,16 +354,28 @@ static void gfar_init_rqprm(struct gfar_private *priv)
+       }
+ }
+-static void gfar_rx_offload_en(struct gfar_private *priv)
++static void gfar_rx_buff_size_config(struct gfar_private *priv)
+ {
++      int frame_size = priv->ndev->mtu + ETH_HLEN + ETH_FCS_LEN;
++
+       /* set this when rx hw offload (TOE) functions are being used */
+       priv->uses_rxfcb = 0;
+       if (priv->ndev->features & (NETIF_F_RXCSUM | NETIF_F_HW_VLAN_CTAG_RX))
+               priv->uses_rxfcb = 1;
+-      if (priv->hwts_rx_en || priv->rx_filer_enable)
++      if (priv->hwts_rx_en)
+               priv->uses_rxfcb = 1;
++
++      if (priv->uses_rxfcb)
++              frame_size += GMAC_FCB_LEN;
++
++      frame_size += priv->padding;
++
++      frame_size = (frame_size & ~(INCREMENTAL_BUFFER_SIZE - 1)) +
++                   INCREMENTAL_BUFFER_SIZE;
++
++      priv->rx_buffer_size = frame_size;
+ }
+ static void gfar_mac_rx_config(struct gfar_private *priv)
+@@ -351,7 +384,7 @@ static void gfar_mac_rx_config(struct gfar_private *priv)
+       u32 rctrl = 0;
+       if (priv->rx_filer_enable) {
+-              rctrl |= RCTRL_FILREN | RCTRL_PRSDEP_INIT;
++              rctrl |= RCTRL_FILREN;
+               /* Program the RIR0 reg with the required distribution */
+               if (priv->poll_mode == GFAR_SQ_POLLING)
+                       gfar_write(&regs->rir0, DEFAULT_2RXQ_RIR0);
+@@ -483,15 +516,6 @@ static struct net_device_stats *gfar_get_stats(struct net_device *dev)
+       return &dev->stats;
+ }
+-static int gfar_set_mac_addr(struct net_device *dev, void *p)
+-{
+-      eth_mac_addr(dev, p);
+-
+-      gfar_set_mac_for_addr(dev, 0, dev->dev_addr);
+-
+-      return 0;
+-}
+-
+ static const struct net_device_ops gfar_netdev_ops = {
+       .ndo_open = gfar_enet_open,
+       .ndo_start_xmit = gfar_start_xmit,
+@@ -502,7 +526,7 @@ static const struct net_device_ops gfar_netdev_ops = {
+       .ndo_tx_timeout = gfar_timeout,
+       .ndo_do_ioctl = gfar_ioctl,
+       .ndo_get_stats = gfar_get_stats,
+-      .ndo_set_mac_address = gfar_set_mac_addr,
++      .ndo_set_mac_address = eth_mac_addr,
+       .ndo_validate_addr = eth_validate_addr,
+ #ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller = gfar_netpoll,
+@@ -532,6 +556,22 @@ static void gfar_ints_enable(struct gfar_private *priv)
+       }
+ }
++static void lock_tx_qs(struct gfar_private *priv)
++{
++      int i;
++
++      for (i = 0; i < priv->num_tx_queues; i++)
++              spin_lock(&priv->tx_queue[i]->txlock);
++}
++
++static void unlock_tx_qs(struct gfar_private *priv)
++{
++      int i;
++
++      for (i = 0; i < priv->num_tx_queues; i++)
++              spin_unlock(&priv->tx_queue[i]->txlock);
++}
++
+ static int gfar_alloc_tx_queues(struct gfar_private *priv)
+ {
+       int i;
+@@ -560,8 +600,9 @@ static int gfar_alloc_rx_queues(struct gfar_private *priv)
+               if (!priv->rx_queue[i])
+                       return -ENOMEM;
++              priv->rx_queue[i]->rx_skbuff = NULL;
+               priv->rx_queue[i]->qindex = i;
+-              priv->rx_queue[i]->ndev = priv->ndev;
++              priv->rx_queue[i]->dev = priv->ndev;
+       }
+       return 0;
+ }
+@@ -647,9 +688,9 @@ static int gfar_parse_group(struct device_node *np,
+       if (model && strcasecmp(model, "FEC")) {
+               gfar_irq(grp, RX)->irq = irq_of_parse_and_map(np, 1);
+               gfar_irq(grp, ER)->irq = irq_of_parse_and_map(np, 2);
+-              if (!gfar_irq(grp, TX)->irq ||
+-                  !gfar_irq(grp, RX)->irq ||
+-                  !gfar_irq(grp, ER)->irq)
++              if (gfar_irq(grp, TX)->irq == NO_IRQ ||
++                  gfar_irq(grp, RX)->irq == NO_IRQ ||
++                  gfar_irq(grp, ER)->irq == NO_IRQ)
+                       return -EINVAL;
+       }
+@@ -738,6 +779,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
+       struct gfar_private *priv = NULL;
+       struct device_node *np = ofdev->dev.of_node;
+       struct device_node *child = NULL;
++      struct property *stash;
+       u32 stash_len = 0;
+       u32 stash_idx = 0;
+       unsigned int num_tx_qs, num_rx_qs;
+@@ -853,7 +895,9 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
+                       goto err_grp_init;
+       }
+-      if (of_property_read_bool(np, "bd-stash")) {
++      stash = of_find_property(np, "bd-stash", NULL);
++
++      if (stash) {
+               priv->device_flags |= FSL_GIANFAR_DEV_HAS_BD_STASHING;
+               priv->bd_stash_en = 1;
+       }
+@@ -891,8 +935,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
+                                    FSL_GIANFAR_DEV_HAS_VLAN |
+                                    FSL_GIANFAR_DEV_HAS_MAGIC_PACKET |
+                                    FSL_GIANFAR_DEV_HAS_EXTENDED_HASH |
+-                                   FSL_GIANFAR_DEV_HAS_TIMER |
+-                                   FSL_GIANFAR_DEV_HAS_RX_FILER;
++                                   FSL_GIANFAR_DEV_HAS_TIMER;
+       err = of_property_read_string(np, "phy-connection-type", &ctype);
+@@ -905,9 +948,6 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
+       if (of_find_property(np, "fsl,magic-packet", NULL))
+               priv->device_flags |= FSL_GIANFAR_DEV_HAS_MAGIC_PACKET;
+-      if (of_get_property(np, "fsl,wake-on-filer", NULL))
+-              priv->device_flags |= FSL_GIANFAR_DEV_HAS_WAKE_ON_FILER;
+-
+       priv->phy_node = of_parse_phandle(np, "phy-handle", 0);
+       /* In the case of a fixed PHY, the DT node associated
+@@ -999,7 +1039,7 @@ static int gfar_hwtstamp_get(struct net_device *netdev, struct ifreq *ifr)
+ static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+ {
+-      struct phy_device *phydev = dev->phydev;
++      struct gfar_private *priv = netdev_priv(dev);
+       if (!netif_running(dev))
+               return -EINVAL;
+@@ -1009,10 +1049,10 @@ static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+       if (cmd == SIOCGHWTSTAMP)
+               return gfar_hwtstamp_get(dev, rq);
+-      if (!phydev)
++      if (!priv->phydev)
+               return -ENODEV;
+-      return phy_mii_ioctl(phydev, rq, cmd);
++      return phy_mii_ioctl(priv->phydev, rq, cmd);
+ }
+ static u32 cluster_entry_per_class(struct gfar_private *priv, u32 rqfar,
+@@ -1111,10 +1151,8 @@ static void __gfar_detect_errata_85xx(struct gfar_private *priv)
+       if ((SVR_SOC_VER(svr) == SVR_8548) && (SVR_REV(svr) == 0x20))
+               priv->errata |= GFAR_ERRATA_12;
+-      /* P2020/P1010 Rev 1; MPC8548 Rev 2 */
+       if (((SVR_SOC_VER(svr) == SVR_P2020) && (SVR_REV(svr) < 0x20)) ||
+-          ((SVR_SOC_VER(svr) == SVR_P2010) && (SVR_REV(svr) < 0x20)) ||
+-          ((SVR_SOC_VER(svr) == SVR_8548) && (SVR_REV(svr) < 0x31)))
++          ((SVR_SOC_VER(svr) == SVR_P2010) && (SVR_REV(svr) < 0x20)))
+               priv->errata |= GFAR_ERRATA_76; /* aka eTSEC 20 */
+ }
+ #endif
+@@ -1156,11 +1194,12 @@ void gfar_mac_reset(struct gfar_private *priv)
+       udelay(3);
+-      gfar_rx_offload_en(priv);
++      /* Compute rx_buff_size based on config flags */
++      gfar_rx_buff_size_config(priv);
+       /* Initialize the max receive frame/buffer lengths */
+-      gfar_write(&regs->maxfrm, GFAR_JUMBO_FRAME_SIZE);
+-      gfar_write(&regs->mrblr, GFAR_RXB_SIZE);
++      gfar_write(&regs->maxfrm, priv->rx_buffer_size);
++      gfar_write(&regs->mrblr, priv->rx_buffer_size);
+       /* Initialize the Minimum Frame Length Register */
+       gfar_write(&regs->minflr, MINFLR_INIT_SETTINGS);
+@@ -1168,11 +1207,12 @@ void gfar_mac_reset(struct gfar_private *priv)
+       /* Initialize MACCFG2. */
+       tempval = MACCFG2_INIT_SETTINGS;
+-      /* eTSEC74 erratum: Rx frames of length MAXFRM or MAXFRM-1
+-       * are marked as truncated.  Avoid this by MACCFG2[Huge Frame]=1,
+-       * and by checking RxBD[LG] and discarding larger than MAXFRM.
++      /* If the mtu is larger than the max size for standard
++       * ethernet frames (ie, a jumbo frame), then set maccfg2
++       * to allow huge frames, and to check the length
+        */
+-      if (gfar_has_errata(priv, GFAR_ERRATA_74))
++      if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE ||
++          gfar_has_errata(priv, GFAR_ERRATA_74))
+               tempval |= MACCFG2_HUGEFRAME | MACCFG2_LENGTHCHECK;
+       gfar_write(&regs->maccfg2, tempval);
+@@ -1312,7 +1352,6 @@ static void gfar_init_addr_hash_table(struct gfar_private *priv)
+  */
+ static int gfar_probe(struct platform_device *ofdev)
+ {
+-      struct device_node *np = ofdev->dev.of_node;
+       struct net_device *dev = NULL;
+       struct gfar_private *priv = NULL;
+       int err = 0, i;
+@@ -1328,6 +1367,7 @@ static int gfar_probe(struct platform_device *ofdev)
+       priv->dev = &ofdev->dev;
+       SET_NETDEV_DEV(dev, &ofdev->dev);
++      spin_lock_init(&priv->bflock);
+       INIT_WORK(&priv->reset_task, gfar_reset_task);
+       platform_set_drvdata(ofdev, priv);
+@@ -1348,12 +1388,12 @@ static int gfar_probe(struct platform_device *ofdev)
+               if (priv->poll_mode == GFAR_SQ_POLLING) {
+                       netif_napi_add(dev, &priv->gfargrp[i].napi_rx,
+                                      gfar_poll_rx_sq, GFAR_DEV_WEIGHT);
+-                      netif_tx_napi_add(dev, &priv->gfargrp[i].napi_tx,
++                      netif_napi_add(dev, &priv->gfargrp[i].napi_tx,
+                                      gfar_poll_tx_sq, 2);
+               } else {
+                       netif_napi_add(dev, &priv->gfargrp[i].napi_rx,
+                                      gfar_poll_rx, GFAR_DEV_WEIGHT);
+-                      netif_tx_napi_add(dev, &priv->gfargrp[i].napi_tx,
++                      netif_napi_add(dev, &priv->gfargrp[i].napi_tx,
+                                      gfar_poll_tx, 2);
+               }
+       }
+@@ -1371,8 +1411,6 @@ static int gfar_probe(struct platform_device *ofdev)
+               dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
+       }
+-      dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+-
+       gfar_init_addr_hash_table(priv);
+       /* Insert receive time stamps into padding alignment bytes */
+@@ -1383,6 +1421,8 @@ static int gfar_probe(struct platform_device *ofdev)
+           priv->device_flags & FSL_GIANFAR_DEV_HAS_TIMER)
+               dev->needed_headroom = GMAC_FCB_LEN;
++      priv->rx_buffer_size = DEFAULT_RX_BUFFER_SIZE;
++
+       /* Initializing some of the rx/tx queue level parameters */
+       for (i = 0; i < priv->num_tx_queues; i++) {
+               priv->tx_queue[i]->tx_ring_size = DEFAULT_TX_RING_SIZE;
+@@ -1397,9 +1437,8 @@ static int gfar_probe(struct platform_device *ofdev)
+               priv->rx_queue[i]->rxic = DEFAULT_RXIC;
+       }
+-      /* Always enable rx filer if available */
+-      priv->rx_filer_enable =
+-          (priv->device_flags & FSL_GIANFAR_DEV_HAS_RX_FILER) ? 1 : 0;
++      /* always enable rx filer */
++      priv->rx_filer_enable = 1;
+       /* Enable most messages by default */
+       priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
+       /* use pritority h/w tx queue scheduling for single queue devices */
+@@ -1420,14 +1459,9 @@ static int gfar_probe(struct platform_device *ofdev)
+               goto register_fail;
+       }
+-      if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET)
+-              priv->wol_supported |= GFAR_WOL_MAGIC;
+-
+-      if ((priv->device_flags & FSL_GIANFAR_DEV_HAS_WAKE_ON_FILER) &&
+-          priv->rx_filer_enable)
+-              priv->wol_supported |= GFAR_WOL_FILER_UCAST;
+-
+-      device_set_wakeup_capable(&ofdev->dev, priv->wol_supported);
++      device_init_wakeup(&dev->dev,
++                         priv->device_flags &
++                         FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+       /* fill out IRQ number and name fields */
+       for (i = 0; i < priv->num_grps; i++) {
+@@ -1463,8 +1497,6 @@ static int gfar_probe(struct platform_device *ofdev)
+       return 0;
+ register_fail:
+-      if (of_phy_is_fixed_link(np))
+-              of_phy_deregister_fixed_link(np);
+       unmap_group_regs(priv);
+       gfar_free_rx_queues(priv);
+       gfar_free_tx_queues(priv);
+@@ -1477,16 +1509,11 @@ static int gfar_probe(struct platform_device *ofdev)
+ static int gfar_remove(struct platform_device *ofdev)
+ {
+       struct gfar_private *priv = platform_get_drvdata(ofdev);
+-      struct device_node *np = ofdev->dev.of_node;
+       of_node_put(priv->phy_node);
+       of_node_put(priv->tbi_node);
+       unregister_netdev(priv->ndev);
+-
+-      if (of_phy_is_fixed_link(np))
+-              of_phy_deregister_fixed_link(np);
+-
+       unmap_group_regs(priv);
+       gfar_free_rx_queues(priv);
+       gfar_free_tx_queues(priv);
+@@ -1497,153 +1524,53 @@ static int gfar_remove(struct platform_device *ofdev)
+ #ifdef CONFIG_PM
+-static void __gfar_filer_disable(struct gfar_private *priv)
+-{
+-      struct gfar __iomem *regs = priv->gfargrp[0].regs;
+-      u32 temp;
+-
+-      temp = gfar_read(&regs->rctrl);
+-      temp &= ~(RCTRL_FILREN | RCTRL_PRSDEP_INIT);
+-      gfar_write(&regs->rctrl, temp);
+-}
+-
+-static void __gfar_filer_enable(struct gfar_private *priv)
+-{
+-      struct gfar __iomem *regs = priv->gfargrp[0].regs;
+-      u32 temp;
+-
+-      temp = gfar_read(&regs->rctrl);
+-      temp |= RCTRL_FILREN | RCTRL_PRSDEP_INIT;
+-      gfar_write(&regs->rctrl, temp);
+-}
+-
+-/* Filer rules implementing wol capabilities */
+-static void gfar_filer_config_wol(struct gfar_private *priv)
+-{
+-      unsigned int i;
+-      u32 rqfcr;
+-
+-      __gfar_filer_disable(priv);
+-
+-      /* clear the filer table, reject any packet by default */
+-      rqfcr = RQFCR_RJE | RQFCR_CMP_MATCH;
+-      for (i = 0; i <= MAX_FILER_IDX; i++)
+-              gfar_write_filer(priv, i, rqfcr, 0);
+-
+-      i = 0;
+-      if (priv->wol_opts & GFAR_WOL_FILER_UCAST) {
+-              /* unicast packet, accept it */
+-              struct net_device *ndev = priv->ndev;
+-              /* get the default rx queue index */
+-              u8 qindex = (u8)priv->gfargrp[0].rx_queue->qindex;
+-              u32 dest_mac_addr = (ndev->dev_addr[0] << 16) |
+-                                  (ndev->dev_addr[1] << 8) |
+-                                   ndev->dev_addr[2];
+-
+-              rqfcr = (qindex << 10) | RQFCR_AND |
+-                      RQFCR_CMP_EXACT | RQFCR_PID_DAH;
+-
+-              gfar_write_filer(priv, i++, rqfcr, dest_mac_addr);
+-
+-              dest_mac_addr = (ndev->dev_addr[3] << 16) |
+-                              (ndev->dev_addr[4] << 8) |
+-                               ndev->dev_addr[5];
+-              rqfcr = (qindex << 10) | RQFCR_GPI |
+-                      RQFCR_CMP_EXACT | RQFCR_PID_DAL;
+-              gfar_write_filer(priv, i++, rqfcr, dest_mac_addr);
+-      }
+-
+-      __gfar_filer_enable(priv);
+-}
+-
+-static void gfar_filer_restore_table(struct gfar_private *priv)
+-{
+-      u32 rqfcr, rqfpr;
+-      unsigned int i;
+-
+-      __gfar_filer_disable(priv);
+-
+-      for (i = 0; i <= MAX_FILER_IDX; i++) {
+-              rqfcr = priv->ftp_rqfcr[i];
+-              rqfpr = priv->ftp_rqfpr[i];
+-              gfar_write_filer(priv, i, rqfcr, rqfpr);
+-      }
+-
+-      __gfar_filer_enable(priv);
+-}
+-
+-/* gfar_start() for Rx only and with the FGPI filer interrupt enabled */
+-static void gfar_start_wol_filer(struct gfar_private *priv)
+-{
+-      struct gfar __iomem *regs = priv->gfargrp[0].regs;
+-      u32 tempval;
+-      int i = 0;
+-
+-      /* Enable Rx hw queues */
+-      gfar_write(&regs->rqueue, priv->rqueue);
+-
+-      /* Initialize DMACTRL to have WWR and WOP */
+-      tempval = gfar_read(&regs->dmactrl);
+-      tempval |= DMACTRL_INIT_SETTINGS;
+-      gfar_write(&regs->dmactrl, tempval);
+-
+-      /* Make sure we aren't stopped */
+-      tempval = gfar_read(&regs->dmactrl);
+-      tempval &= ~DMACTRL_GRS;
+-      gfar_write(&regs->dmactrl, tempval);
+-
+-      for (i = 0; i < priv->num_grps; i++) {
+-              regs = priv->gfargrp[i].regs;
+-              /* Clear RHLT, so that the DMA starts polling now */
+-              gfar_write(&regs->rstat, priv->gfargrp[i].rstat);
+-              /* enable the Filer General Purpose Interrupt */
+-              gfar_write(&regs->imask, IMASK_FGPI);
+-      }
+-
+-      /* Enable Rx DMA */
+-      tempval = gfar_read(&regs->maccfg1);
+-      tempval |= MACCFG1_RX_EN;
+-      gfar_write(&regs->maccfg1, tempval);
+-}
+-
+ static int gfar_suspend(struct device *dev)
+ {
+       struct gfar_private *priv = dev_get_drvdata(dev);
+       struct net_device *ndev = priv->ndev;
+       struct gfar __iomem *regs = priv->gfargrp[0].regs;
++      unsigned long flags;
+       u32 tempval;
+-      u16 wol = priv->wol_opts;
+-      if (!netif_running(ndev))
+-              return 0;
++      int magic_packet = priv->wol_en &&
++                         (priv->device_flags &
++                          FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+-      disable_napi(priv);
+-      netif_tx_lock(ndev);
+       netif_device_detach(ndev);
+-      netif_tx_unlock(ndev);
+-      gfar_halt(priv);
++      if (netif_running(ndev)) {
+-      if (wol & GFAR_WOL_MAGIC) {
+-              /* Enable interrupt on Magic Packet */
+-              gfar_write(&regs->imask, IMASK_MAG);
++              local_irq_save(flags);
++              lock_tx_qs(priv);
+-              /* Enable Magic Packet mode */
+-              tempval = gfar_read(&regs->maccfg2);
+-              tempval |= MACCFG2_MPEN;
+-              gfar_write(&regs->maccfg2, tempval);
++              gfar_halt_nodisable(priv);
+-              /* re-enable the Rx block */
++              /* Disable Tx, and Rx if wake-on-LAN is disabled. */
+               tempval = gfar_read(&regs->maccfg1);
+-              tempval |= MACCFG1_RX_EN;
++
++              tempval &= ~MACCFG1_TX_EN;
++
++              if (!magic_packet)
++                      tempval &= ~MACCFG1_RX_EN;
++
+               gfar_write(&regs->maccfg1, tempval);
+-      } else if (wol & GFAR_WOL_FILER_UCAST) {
+-              gfar_filer_config_wol(priv);
+-              gfar_start_wol_filer(priv);
++              unlock_tx_qs(priv);
++              local_irq_restore(flags);
+-      } else {
+-              phy_stop(ndev->phydev);
++              disable_napi(priv);
++
++              if (magic_packet) {
++                      /* Enable interrupt on Magic Packet */
++                      gfar_write(&regs->imask, IMASK_MAG);
++
++                      /* Enable Magic Packet mode */
++                      tempval = gfar_read(&regs->maccfg2);
++                      tempval |= MACCFG2_MPEN;
++                      gfar_write(&regs->maccfg2, tempval);
++              } else {
++                      phy_stop(priv->phydev);
++              }
+       }
+       return 0;
+@@ -1654,30 +1581,37 @@ static int gfar_resume(struct device *dev)
+       struct gfar_private *priv = dev_get_drvdata(dev);
+       struct net_device *ndev = priv->ndev;
+       struct gfar __iomem *regs = priv->gfargrp[0].regs;
++      unsigned long flags;
+       u32 tempval;
+-      u16 wol = priv->wol_opts;
++      int magic_packet = priv->wol_en &&
++                         (priv->device_flags &
++                          FSL_GIANFAR_DEV_HAS_MAGIC_PACKET);
+-      if (!netif_running(ndev))
++      if (!netif_running(ndev)) {
++              netif_device_attach(ndev);
+               return 0;
++      }
+-      if (wol & GFAR_WOL_MAGIC) {
+-              /* Disable Magic Packet mode */
+-              tempval = gfar_read(&regs->maccfg2);
+-              tempval &= ~MACCFG2_MPEN;
+-              gfar_write(&regs->maccfg2, tempval);
++      if (!magic_packet && priv->phydev)
++              phy_start(priv->phydev);
+-      } else if (wol & GFAR_WOL_FILER_UCAST) {
+-              /* need to stop rx only, tx is already down */
+-              gfar_halt(priv);
+-              gfar_filer_restore_table(priv);
++      /* Disable Magic Packet mode, in case something
++       * else woke us up.
++       */
++      local_irq_save(flags);
++      lock_tx_qs(priv);
+-      } else {
+-              phy_start(ndev->phydev);
+-      }
++      tempval = gfar_read(&regs->maccfg2);
++      tempval &= ~MACCFG2_MPEN;
++      gfar_write(&regs->maccfg2, tempval);
+       gfar_start(priv);
++      unlock_tx_qs(priv);
++      local_irq_restore(flags);
++
+       netif_device_attach(ndev);
++
+       enable_napi(priv);
+       return 0;
+@@ -1694,7 +1628,10 @@ static int gfar_restore(struct device *dev)
+               return 0;
+       }
+-      gfar_init_bds(ndev);
++      if (gfar_init_bds(ndev)) {
++              free_skb_resources(priv);
++              return -ENOMEM;
++      }
+       gfar_mac_reset(priv);
+@@ -1706,8 +1643,8 @@ static int gfar_restore(struct device *dev)
+       priv->oldspeed = 0;
+       priv->oldduplex = -1;
+-      if (ndev->phydev)
+-              phy_start(ndev->phydev);
++      if (priv->phydev)
++              phy_start(priv->phydev);
+       netif_device_attach(ndev);
+       enable_napi(priv);
+@@ -1786,7 +1723,6 @@ static int init_phy(struct net_device *dev)
+               priv->device_flags & FSL_GIANFAR_DEV_HAS_GIGABIT ?
+               GFAR_SUPPORTED_GBIT : 0;
+       phy_interface_t interface;
+-      struct phy_device *phydev;
+       priv->oldlink = 0;
+       priv->oldspeed = 0;
+@@ -1794,9 +1730,9 @@ static int init_phy(struct net_device *dev)
+       interface = gfar_get_interface(dev);
+-      phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, 0,
+-                              interface);
+-      if (!phydev) {
++      priv->phydev = of_phy_connect(dev, priv->phy_node, &adjust_link, 0,
++                                    interface);
++      if (!priv->phydev) {
+               dev_err(&dev->dev, "could not attach to PHY\n");
+               return -ENODEV;
+       }
+@@ -1805,11 +1741,11 @@ static int init_phy(struct net_device *dev)
+               gfar_configure_serdes(dev);
+       /* Remove any features not supported by the controller */
+-      phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
+-      phydev->advertising = phydev->supported;
++      priv->phydev->supported &= (GFAR_SUPPORTED | gigabit_support);
++      priv->phydev->advertising = priv->phydev->supported;
+       /* Add support for flow control, but don't advertise it by default */
+-      phydev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
++      priv->phydev->supported |= (SUPPORTED_Pause | SUPPORTED_Asym_Pause);
+       return 0;
+ }
+@@ -1844,10 +1780,8 @@ static void gfar_configure_serdes(struct net_device *dev)
+        * everything for us?  Resetting it takes the link down and requires
+        * several seconds for it to come back.
+        */
+-      if (phy_read(tbiphy, MII_BMSR) & BMSR_LSTATUS) {
+-              put_device(&tbiphy->mdio.dev);
++      if (phy_read(tbiphy, MII_BMSR) & BMSR_LSTATUS)
+               return;
+-      }
+       /* Single clk mode, mii mode off(for serdes communication) */
+       phy_write(tbiphy, MII_TBICON, TBICON_CLK_SELECT);
+@@ -1859,8 +1793,6 @@ static void gfar_configure_serdes(struct net_device *dev)
+       phy_write(tbiphy, MII_BMCR,
+                 BMCR_ANENABLE | BMCR_ANRESTART | BMCR_FULLDPLX |
+                 BMCR_SPEED1000);
+-
+-      put_device(&tbiphy->mdio.dev);
+ }
+ static int __gfar_is_rx_idle(struct gfar_private *priv)
+@@ -1953,7 +1885,7 @@ void stop_gfar(struct net_device *dev)
+       /* disable ints and gracefully shut down Rx/Tx DMA */
+       gfar_halt(priv);
+-      phy_stop(dev->phydev);
++      phy_stop(priv->phydev);
+       free_skb_resources(priv);
+ }
+@@ -1990,32 +1922,26 @@ static void free_skb_tx_queue(struct gfar_priv_tx_q *tx_queue)
+ static void free_skb_rx_queue(struct gfar_priv_rx_q *rx_queue)
+ {
++      struct rxbd8 *rxbdp;
++      struct gfar_private *priv = netdev_priv(rx_queue->dev);
+       int i;
+-      struct rxbd8 *rxbdp = rx_queue->rx_bd_base;
+-
+-      if (rx_queue->skb)
+-              dev_kfree_skb(rx_queue->skb);
++      rxbdp = rx_queue->rx_bd_base;
+       for (i = 0; i < rx_queue->rx_ring_size; i++) {
+-              struct  gfar_rx_buff *rxb = &rx_queue->rx_buff[i];
+-
++              if (rx_queue->rx_skbuff[i]) {
++                      dma_unmap_single(priv->dev, be32_to_cpu(rxbdp->bufPtr),
++                                       priv->rx_buffer_size,
++                                       DMA_FROM_DEVICE);
++                      dev_kfree_skb_any(rx_queue->rx_skbuff[i]);
++                      rx_queue->rx_skbuff[i] = NULL;
++              }
+               rxbdp->lstatus = 0;
+               rxbdp->bufPtr = 0;
+               rxbdp++;
+-
+-              if (!rxb->page)
+-                      continue;
+-
+-              dma_unmap_single(rx_queue->dev, rxb->dma,
+-                               PAGE_SIZE, DMA_FROM_DEVICE);
+-              __free_page(rxb->page);
+-
+-              rxb->page = NULL;
+       }
+-
+-      kfree(rx_queue->rx_buff);
+-      rx_queue->rx_buff = NULL;
++      kfree(rx_queue->rx_skbuff);
++      rx_queue->rx_skbuff = NULL;
+ }
+ /* If there are any tx skbs or rx skbs still around, free them.
+@@ -2040,7 +1966,7 @@ static void free_skb_resources(struct gfar_private *priv)
+       for (i = 0; i < priv->num_rx_queues; i++) {
+               rx_queue = priv->rx_queue[i];
+-              if (rx_queue->rx_buff)
++              if (rx_queue->rx_skbuff)
+                       free_skb_rx_queue(rx_queue);
+       }
+@@ -2085,7 +2011,7 @@ void gfar_start(struct gfar_private *priv)
+       gfar_ints_enable(priv);
+-      netif_trans_update(priv->ndev); /* prevent tx timeout */
++      priv->ndev->trans_start = jiffies; /* prevent tx timeout */
+ }
+ static void free_grp_irqs(struct gfar_priv_grp *grp)
+@@ -2116,8 +2042,6 @@ static int register_grp_irqs(struct gfar_priv_grp *grp)
+                       goto err_irq_fail;
+               }
+-              enable_irq_wake(gfar_irq(grp, ER)->irq);
+-
+               err = request_irq(gfar_irq(grp, TX)->irq, gfar_transmit, 0,
+                                 gfar_irq(grp, TX)->name, grp);
+               if (err < 0) {
+@@ -2132,8 +2056,6 @@ static int register_grp_irqs(struct gfar_priv_grp *grp)
+                                 gfar_irq(grp, RX)->irq);
+                       goto rx_irq_fail;
+               }
+-              enable_irq_wake(gfar_irq(grp, RX)->irq);
+-
+       } else {
+               err = request_irq(gfar_irq(grp, TX)->irq, gfar_interrupt, 0,
+                                 gfar_irq(grp, TX)->name, grp);
+@@ -2142,7 +2064,6 @@ static int register_grp_irqs(struct gfar_priv_grp *grp)
+                                 gfar_irq(grp, TX)->irq);
+                       goto err_irq_fail;
+               }
+-              enable_irq_wake(gfar_irq(grp, TX)->irq);
+       }
+       return 0;
+@@ -2208,12 +2129,7 @@ int startup_gfar(struct net_device *ndev)
+       /* Start Rx/Tx DMA and enable the interrupts */
+       gfar_start(priv);
+-      /* force link state update after mac reset */
+-      priv->oldlink = 0;
+-      priv->oldspeed = 0;
+-      priv->oldduplex = -1;
+-
+-      phy_start(ndev->phydev);
++      phy_start(priv->phydev);
+       enable_napi(priv);
+@@ -2242,6 +2158,8 @@ static int gfar_enet_open(struct net_device *dev)
+       if (err)
+               return err;
++      device_set_wakeup_enable(&dev->dev, priv->wol_en);
++
+       return err;
+ }
+@@ -2283,7 +2201,7 @@ static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb,
+       fcb->flags = flags;
+ }
+-static inline void gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb)
++void inline gfar_tx_vlan(struct sk_buff *skb, struct txfcb *fcb)
+ {
+       fcb->flags |= TXFCB_VLN;
+       fcb->vlctl = cpu_to_be16(skb_vlan_tag_get(skb));
+@@ -2333,10 +2251,10 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
+       struct txfcb *fcb = NULL;
+       struct txbd8 *txbdp, *txbdp_start, *base, *txbdp_tstamp = NULL;
+       u32 lstatus;
+-      skb_frag_t *frag;
+       int i, rq = 0;
+       int do_tstamp, do_csum, do_vlan;
+       u32 bufaddr;
++      unsigned long flags;
+       unsigned int nr_frags, nr_txbds, bytes_sent, fcb_len = 0;
+       rq = skb->queue_mapping;
+@@ -2401,6 +2319,52 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
+       txbdp = txbdp_start = tx_queue->cur_tx;
+       lstatus = be32_to_cpu(txbdp->lstatus);
++      /* Time stamp insertion requires one additional TxBD */
++      if (unlikely(do_tstamp))
++              txbdp_tstamp = txbdp = next_txbd(txbdp, base,
++                                               tx_queue->tx_ring_size);
++
++      if (nr_frags == 0) {
++              if (unlikely(do_tstamp)) {
++                      u32 lstatus_ts = be32_to_cpu(txbdp_tstamp->lstatus);
++
++                      lstatus_ts |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
++                      txbdp_tstamp->lstatus = cpu_to_be32(lstatus_ts);
++              } else {
++                      lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
++              }
++      } else {
++              /* Place the fragment addresses and lengths into the TxBDs */
++              for (i = 0; i < nr_frags; i++) {
++                      unsigned int frag_len;
++                      /* Point at the next BD, wrapping as needed */
++                      txbdp = next_txbd(txbdp, base, tx_queue->tx_ring_size);
++
++                      frag_len = skb_shinfo(skb)->frags[i].size;
++
++                      lstatus = be32_to_cpu(txbdp->lstatus) | frag_len |
++                                BD_LFLAG(TXBD_READY);
++
++                      /* Handle the last BD specially */
++                      if (i == nr_frags - 1)
++                              lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
++
++                      bufaddr = skb_frag_dma_map(priv->dev,
++                                                 &skb_shinfo(skb)->frags[i],
++                                                 0,
++                                                 frag_len,
++                                                 DMA_TO_DEVICE);
++                      if (unlikely(dma_mapping_error(priv->dev, bufaddr)))
++                              goto dma_map_err;
++
++                      /* set the TxBD length and buffer pointer */
++                      txbdp->bufPtr = cpu_to_be32(bufaddr);
++                      txbdp->lstatus = cpu_to_be32(lstatus);
++              }
++
++              lstatus = be32_to_cpu(txbdp_start->lstatus);
++      }
++
+       /* Add TxPAL between FCB and frame if required */
+       if (unlikely(do_tstamp)) {
+               skb_push(skb, GMAC_TXPAL_LEN);
+@@ -2435,6 +2399,12 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
+       if (do_vlan)
+               gfar_tx_vlan(skb, fcb);
++      /* Setup tx hardware time stamping if requested */
++      if (unlikely(do_tstamp)) {
++              skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
++              fcb->ptp = 1;
++      }
++
+       bufaddr = dma_map_single(priv->dev, skb->data, skb_headlen(skb),
+                                DMA_TO_DEVICE);
+       if (unlikely(dma_mapping_error(priv->dev, bufaddr)))
+@@ -2442,47 +2412,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
+       txbdp_start->bufPtr = cpu_to_be32(bufaddr);
+-      /* Time stamp insertion requires one additional TxBD */
+-      if (unlikely(do_tstamp))
+-              txbdp_tstamp = txbdp = next_txbd(txbdp, base,
+-                                               tx_queue->tx_ring_size);
+-
+-      if (likely(!nr_frags)) {
+-              if (likely(!do_tstamp))
+-                      lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
+-      } else {
+-              u32 lstatus_start = lstatus;
+-
+-              /* Place the fragment addresses and lengths into the TxBDs */
+-              frag = &skb_shinfo(skb)->frags[0];
+-              for (i = 0; i < nr_frags; i++, frag++) {
+-                      unsigned int size;
+-
+-                      /* Point at the next BD, wrapping as needed */
+-                      txbdp = next_txbd(txbdp, base, tx_queue->tx_ring_size);
+-
+-                      size = skb_frag_size(frag);
+-
+-                      lstatus = be32_to_cpu(txbdp->lstatus) | size |
+-                                BD_LFLAG(TXBD_READY);
+-
+-                      /* Handle the last BD specially */
+-                      if (i == nr_frags - 1)
+-                              lstatus |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
+-
+-                      bufaddr = skb_frag_dma_map(priv->dev, frag, 0,
+-                                                 size, DMA_TO_DEVICE);
+-                      if (unlikely(dma_mapping_error(priv->dev, bufaddr)))
+-                              goto dma_map_err;
+-
+-                      /* set the TxBD length and buffer pointer */
+-                      txbdp->bufPtr = cpu_to_be32(bufaddr);
+-                      txbdp->lstatus = cpu_to_be32(lstatus);
+-              }
+-
+-              lstatus = lstatus_start;
+-      }
+-
+       /* If time stamping is requested one additional TxBD must be set up. The
+        * first TxBD points to the FCB and must have a data length of
+        * GMAC_FCB_LEN. The second TxBD points to the actual frame data with
+@@ -2493,25 +2422,31 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
+               bufaddr = be32_to_cpu(txbdp_start->bufPtr);
+               bufaddr += fcb_len;
+-
+               lstatus_ts |= BD_LFLAG(TXBD_READY) |
+                             (skb_headlen(skb) - fcb_len);
+-              if (!nr_frags)
+-                      lstatus_ts |= BD_LFLAG(TXBD_LAST | TXBD_INTERRUPT);
+               txbdp_tstamp->bufPtr = cpu_to_be32(bufaddr);
+               txbdp_tstamp->lstatus = cpu_to_be32(lstatus_ts);
+               lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | GMAC_FCB_LEN;
+-
+-              /* Setup tx hardware time stamping */
+-              skb_shinfo(skb)->tx_flags |= SKBTX_IN_PROGRESS;
+-              fcb->ptp = 1;
+       } else {
+               lstatus |= BD_LFLAG(TXBD_CRC | TXBD_READY) | skb_headlen(skb);
+       }
+       netdev_tx_sent_queue(txq, bytes_sent);
++      /* We can work in parallel with gfar_clean_tx_ring(), except
++       * when modifying num_txbdfree. Note that we didn't grab the lock
++       * when we were reading the num_txbdfree and checking for available
++       * space, that's because outside of this function it can only grow,
++       * and once we've got needed space, it cannot suddenly disappear.
++       *
++       * The lock also protects us from gfar_error(), which can modify
++       * regs->tstat and thus retrigger the transfers, which is why we
++       * also must grab the lock before setting ready bit for the first
++       * to be transmitted BD.
++       */
++      spin_lock_irqsave(&tx_queue->txlock, flags);
++
+       gfar_wmb();
+       txbdp_start->lstatus = cpu_to_be32(lstatus);
+@@ -2528,15 +2463,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
+       tx_queue->cur_tx = next_txbd(txbdp, base, tx_queue->tx_ring_size);
+-      /* We can work in parallel with gfar_clean_tx_ring(), except
+-       * when modifying num_txbdfree. Note that we didn't grab the lock
+-       * when we were reading the num_txbdfree and checking for available
+-       * space, that's because outside of this function it can only grow.
+-       */
+-      spin_lock_bh(&tx_queue->txlock);
+       /* reduce TxBD free count */
+       tx_queue->num_txbdfree -= (nr_txbds);
+-      spin_unlock_bh(&tx_queue->txlock);
+       /* If the next BD still needs to be cleaned up, then the bds
+        * are full.  We need to tell the kernel to stop sending us stuff.
+@@ -2550,6 +2478,9 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
+       /* Tell the DMA to go go go */
+       gfar_write(&regs->tstat, TSTAT_CLEAR_THALT >> tx_queue->qindex);
++      /* Unlock priv */
++      spin_unlock_irqrestore(&tx_queue->txlock, flags);
++
+       return NETDEV_TX_OK;
+ dma_map_err:
+@@ -2582,7 +2513,8 @@ static int gfar_close(struct net_device *dev)
+       stop_gfar(dev);
+       /* Disconnect from the PHY */
+-      phy_disconnect(dev->phydev);
++      phy_disconnect(priv->phydev);
++      priv->phydev = NULL;
+       gfar_free_irq(priv);
+@@ -2602,7 +2534,7 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
+       struct gfar_private *priv = netdev_priv(dev);
+       int frame_size = new_mtu + ETH_HLEN;
+-      if ((frame_size < 64) || (frame_size > GFAR_JUMBO_FRAME_SIZE)) {
++      if ((frame_size < 64) || (frame_size > JUMBO_FRAME_SIZE)) {
+               netif_err(priv, drv, dev, "Invalid MTU setting\n");
+               return -EINVAL;
+       }
+@@ -2656,6 +2588,15 @@ static void gfar_timeout(struct net_device *dev)
+       schedule_work(&priv->reset_task);
+ }
++static void gfar_align_skb(struct sk_buff *skb)
++{
++      /* We need the data buffer to be aligned properly.  We will reserve
++       * as many bytes as needed to align the data properly
++       */
++      skb_reserve(skb, RXBUF_ALIGNMENT -
++                  (((unsigned long) skb->data) & (RXBUF_ALIGNMENT - 1)));
++}
++
+ /* Interrupt Handler for Transmit complete */
+ static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
+ {
+@@ -2681,6 +2622,7 @@ static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
+       skb_dirtytx = tx_queue->skb_dirtytx;
+       while ((skb = tx_queue->tx_skbuff[skb_dirtytx])) {
++              unsigned long flags;
+               frags = skb_shinfo(skb)->nr_frags;
+@@ -2713,11 +2655,10 @@ static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
+               if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS)) {
+                       struct skb_shared_hwtstamps shhwtstamps;
+-                      u64 *ns = (u64 *)(((uintptr_t)skb->data + 0x10) &
+-                                        ~0x7UL);
++                      u64 *ns = (u64*) (((u32)skb->data + 0x10) & ~0x7);
+                       memset(&shhwtstamps, 0, sizeof(shhwtstamps));
+-                      shhwtstamps.hwtstamp = ns_to_ktime(be64_to_cpu(*ns));
++                      shhwtstamps.hwtstamp = ns_to_ktime(*ns);
+                       skb_pull(skb, GMAC_FCB_LEN + GMAC_TXPAL_LEN);
+                       skb_tstamp_tx(skb, &shhwtstamps);
+                       gfar_clear_txbd_status(bdp);
+@@ -2745,9 +2686,9 @@ static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
+                             TX_RING_MOD_MASK(tx_ring_size);
+               howmany++;
+-              spin_lock(&tx_queue->txlock);
++              spin_lock_irqsave(&tx_queue->txlock, flags);
+               tx_queue->num_txbdfree += nr_txbds;
+-              spin_unlock(&tx_queue->txlock);
++              spin_unlock_irqrestore(&tx_queue->txlock, flags);
+       }
+       /* If we freed a buffer, we can restart transmission, if necessary */
+@@ -2763,85 +2704,49 @@ static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
+       netdev_tx_completed_queue(txq, howmany, bytes_sent);
+ }
+-static bool gfar_new_page(struct gfar_priv_rx_q *rxq, struct gfar_rx_buff *rxb)
++static struct sk_buff *gfar_alloc_skb(struct net_device *dev)
+ {
+-      struct page *page;
+-      dma_addr_t addr;
+-
+-      page = dev_alloc_page();
+-      if (unlikely(!page))
+-              return false;
+-
+-      addr = dma_map_page(rxq->dev, page, 0, PAGE_SIZE, DMA_FROM_DEVICE);
+-      if (unlikely(dma_mapping_error(rxq->dev, addr))) {
+-              __free_page(page);
+-
+-              return false;
+-      }
++      struct gfar_private *priv = netdev_priv(dev);
++      struct sk_buff *skb;
+-      rxb->dma = addr;
+-      rxb->page = page;
+-      rxb->page_offset = 0;
++      skb = netdev_alloc_skb(dev, priv->rx_buffer_size + RXBUF_ALIGNMENT);
++      if (!skb)
++              return NULL;
+-      return true;
+-}
++      gfar_align_skb(skb);
+-static void gfar_rx_alloc_err(struct gfar_priv_rx_q *rx_queue)
+-{
+-      struct gfar_private *priv = netdev_priv(rx_queue->ndev);
+-      struct gfar_extra_stats *estats = &priv->extra_stats;
+-
+-      netdev_err(rx_queue->ndev, "Can't alloc RX buffers\n");
+-      atomic64_inc(&estats->rx_alloc_err);
++      return skb;
+ }
+-static void gfar_alloc_rx_buffs(struct gfar_priv_rx_q *rx_queue,
+-                              int alloc_cnt)
++static struct sk_buff *gfar_new_skb(struct net_device *dev, dma_addr_t *bufaddr)
+ {
+-      struct rxbd8 *bdp;
+-      struct gfar_rx_buff *rxb;
+-      int i;
+-
+-      i = rx_queue->next_to_use;
+-      bdp = &rx_queue->rx_bd_base[i];
+-      rxb = &rx_queue->rx_buff[i];
+-
+-      while (alloc_cnt--) {
+-              /* try reuse page */
+-              if (unlikely(!rxb->page)) {
+-                      if (unlikely(!gfar_new_page(rx_queue, rxb))) {
+-                              gfar_rx_alloc_err(rx_queue);
+-                              break;
+-                      }
+-              }
++      struct gfar_private *priv = netdev_priv(dev);
++      struct sk_buff *skb;
++      dma_addr_t addr;
+-              /* Setup the new RxBD */
+-              gfar_init_rxbdp(rx_queue, bdp,
+-                              rxb->dma + rxb->page_offset + RXBUF_ALIGNMENT);
++      skb = gfar_alloc_skb(dev);
++      if (!skb)
++              return NULL;
+-              /* Update to the next pointer */
+-              bdp++;
+-              rxb++;
+-
+-              if (unlikely(++i == rx_queue->rx_ring_size)) {
+-                      i = 0;
+-                      bdp = rx_queue->rx_bd_base;
+-                      rxb = rx_queue->rx_buff;
+-              }
++      addr = dma_map_single(priv->dev, skb->data,
++                            priv->rx_buffer_size, DMA_FROM_DEVICE);
++      if (unlikely(dma_mapping_error(priv->dev, addr))) {
++              dev_kfree_skb_any(skb);
++              return NULL;
+       }
+-      rx_queue->next_to_use = i;
+-      rx_queue->next_to_alloc = i;
++      *bufaddr = addr;
++      return skb;
+ }
+-static void count_errors(u32 lstatus, struct net_device *ndev)
++static inline void count_errors(unsigned short status, struct net_device *dev)
+ {
+-      struct gfar_private *priv = netdev_priv(ndev);
+-      struct net_device_stats *stats = &ndev->stats;
++      struct gfar_private *priv = netdev_priv(dev);
++      struct net_device_stats *stats = &dev->stats;
+       struct gfar_extra_stats *estats = &priv->extra_stats;
+       /* If the packet was truncated, none of the other errors matter */
+-      if (lstatus & BD_LFLAG(RXBD_TRUNCATED)) {
++      if (status & RXBD_TRUNCATED) {
+               stats->rx_length_errors++;
+               atomic64_inc(&estats->rx_trunc);
+@@ -2849,25 +2754,25 @@ static void count_errors(u32 lstatus, struct net_device *ndev)
+               return;
+       }
+       /* Count the errors, if there were any */
+-      if (lstatus & BD_LFLAG(RXBD_LARGE | RXBD_SHORT)) {
++      if (status & (RXBD_LARGE | RXBD_SHORT)) {
+               stats->rx_length_errors++;
+-              if (lstatus & BD_LFLAG(RXBD_LARGE))
++              if (status & RXBD_LARGE)
+                       atomic64_inc(&estats->rx_large);
+               else
+                       atomic64_inc(&estats->rx_short);
+       }
+-      if (lstatus & BD_LFLAG(RXBD_NONOCTET)) {
++      if (status & RXBD_NONOCTET) {
+               stats->rx_frame_errors++;
+               atomic64_inc(&estats->rx_nonoctet);
+       }
+-      if (lstatus & BD_LFLAG(RXBD_CRCERR)) {
++      if (status & RXBD_CRCERR) {
+               atomic64_inc(&estats->rx_crcerr);
+               stats->rx_crc_errors++;
+       }
+-      if (lstatus & BD_LFLAG(RXBD_OVERRUN)) {
++      if (status & RXBD_OVERRUN) {
+               atomic64_inc(&estats->rx_overrun);
+-              stats->rx_over_errors++;
++              stats->rx_crc_errors++;
+       }
+ }
+@@ -2875,14 +2780,7 @@ irqreturn_t gfar_receive(int irq, void *grp_id)
+ {
+       struct gfar_priv_grp *grp = (struct gfar_priv_grp *)grp_id;
+       unsigned long flags;
+-      u32 imask, ievent;
+-
+-      ievent = gfar_read(&grp->regs->ievent);
+-
+-      if (unlikely(ievent & IEVENT_FGPI)) {
+-              gfar_write(&grp->regs->ievent, IEVENT_FGPI);
+-              return IRQ_HANDLED;
+-      }
++      u32 imask;
+       if (likely(napi_schedule_prep(&grp->napi_rx))) {
+               spin_lock_irqsave(&grp->grplock, flags);
+@@ -2925,101 +2823,6 @@ static irqreturn_t gfar_transmit(int irq, void *grp_id)
+       return IRQ_HANDLED;
+ }
+-static bool gfar_add_rx_frag(struct gfar_rx_buff *rxb, u32 lstatus,
+-                           struct sk_buff *skb, bool first)
+-{
+-      unsigned int size = lstatus & BD_LENGTH_MASK;
+-      struct page *page = rxb->page;
+-      bool last = !!(lstatus & BD_LFLAG(RXBD_LAST));
+-
+-      /* Remove the FCS from the packet length */
+-      if (last)
+-              size -= ETH_FCS_LEN;
+-
+-      if (likely(first)) {
+-              skb_put(skb, size);
+-      } else {
+-              /* the last fragments' length contains the full frame length */
+-              if (last)
+-                      size -= skb->len;
+-
+-              /* in case the last fragment consisted only of the FCS */
+-              if (size > 0)
+-                      skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, page,
+-                                      rxb->page_offset + RXBUF_ALIGNMENT,
+-                                      size, GFAR_RXB_TRUESIZE);
+-      }
+-
+-      /* try reuse page */
+-      if (unlikely(page_count(page) != 1))
+-              return false;
+-
+-      /* change offset to the other half */
+-      rxb->page_offset ^= GFAR_RXB_TRUESIZE;
+-
+-      page_ref_inc(page);
+-
+-      return true;
+-}
+-
+-static void gfar_reuse_rx_page(struct gfar_priv_rx_q *rxq,
+-                             struct gfar_rx_buff *old_rxb)
+-{
+-      struct gfar_rx_buff *new_rxb;
+-      u16 nta = rxq->next_to_alloc;
+-
+-      new_rxb = &rxq->rx_buff[nta];
+-
+-      /* find next buf that can reuse a page */
+-      nta++;
+-      rxq->next_to_alloc = (nta < rxq->rx_ring_size) ? nta : 0;
+-
+-      /* copy page reference */
+-      *new_rxb = *old_rxb;
+-
+-      /* sync for use by the device */
+-      dma_sync_single_range_for_device(rxq->dev, old_rxb->dma,
+-                                       old_rxb->page_offset,
+-                                       GFAR_RXB_TRUESIZE, DMA_FROM_DEVICE);
+-}
+-
+-static struct sk_buff *gfar_get_next_rxbuff(struct gfar_priv_rx_q *rx_queue,
+-                                          u32 lstatus, struct sk_buff *skb)
+-{
+-      struct gfar_rx_buff *rxb = &rx_queue->rx_buff[rx_queue->next_to_clean];
+-      struct page *page = rxb->page;
+-      bool first = false;
+-
+-      if (likely(!skb)) {
+-              void *buff_addr = page_address(page) + rxb->page_offset;
+-
+-              skb = build_skb(buff_addr, GFAR_SKBFRAG_SIZE);
+-              if (unlikely(!skb)) {
+-                      gfar_rx_alloc_err(rx_queue);
+-                      return NULL;
+-              }
+-              skb_reserve(skb, RXBUF_ALIGNMENT);
+-              first = true;
+-      }
+-
+-      dma_sync_single_range_for_cpu(rx_queue->dev, rxb->dma, rxb->page_offset,
+-                                    GFAR_RXB_TRUESIZE, DMA_FROM_DEVICE);
+-
+-      if (gfar_add_rx_frag(rxb, lstatus, skb, first)) {
+-              /* reuse the free half of the page */
+-              gfar_reuse_rx_page(rx_queue, rxb);
+-      } else {
+-              /* page cannot be reused, unmap it */
+-              dma_unmap_page(rx_queue->dev, rxb->dma,
+-                             PAGE_SIZE, DMA_FROM_DEVICE);
+-      }
+-
+-      /* clear rxb content */
+-      rxb->page = NULL;
+-
+-      return skb;
+-}
+-
+ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb)
+ {
+       /* If valid headers were found, and valid sums
+@@ -3034,9 +2837,10 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb)
+ }
+ /* gfar_process_frame() -- handle one incoming packet if skb isn't NULL. */
+-static void gfar_process_frame(struct net_device *ndev, struct sk_buff *skb)
++static void gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
++                             int amount_pull, struct napi_struct *napi)
+ {
+-      struct gfar_private *priv = netdev_priv(ndev);
++      struct gfar_private *priv = netdev_priv(dev);
+       struct rxfcb *fcb = NULL;
+       /* fcb is at the beginning if exists */
+@@ -3045,8 +2849,10 @@ static void gfar_process_frame(struct net_device *ndev, struct sk_buff *skb)
+       /* Remove the FCB from the skb
+        * Remove the padded bytes, if there are any
+        */
+-      if (priv->uses_rxfcb)
+-              skb_pull(skb, GMAC_FCB_LEN);
++      if (amount_pull) {
++              skb_record_rx_queue(skb, fcb->rq);
++              skb_pull(skb, amount_pull);
++      }
+       /* Get receive timestamp from the skb */
+       if (priv->hwts_rx_en) {
+@@ -3054,26 +2860,30 @@ static void gfar_process_frame(struct net_device *ndev, struct sk_buff *skb)
+               u64 *ns = (u64 *) skb->data;
+               memset(shhwtstamps, 0, sizeof(*shhwtstamps));
+-              shhwtstamps->hwtstamp = ns_to_ktime(be64_to_cpu(*ns));
++              shhwtstamps->hwtstamp = ns_to_ktime(*ns);
+       }
+       if (priv->padding)
+               skb_pull(skb, priv->padding);
+-      if (ndev->features & NETIF_F_RXCSUM)
++      if (dev->features & NETIF_F_RXCSUM)
+               gfar_rx_checksum(skb, fcb);
+       /* Tell the skb what kind of packet this is */
+-      skb->protocol = eth_type_trans(skb, ndev);
++      skb->protocol = eth_type_trans(skb, dev);
+       /* There's need to check for NETIF_F_HW_VLAN_CTAG_RX here.
+        * Even if vlan rx accel is disabled, on some chips
+        * RXFCB_VLN is pseudo randomly set.
+        */
+-      if (ndev->features & NETIF_F_HW_VLAN_CTAG_RX &&
++      if (dev->features & NETIF_F_HW_VLAN_CTAG_RX &&
+           be16_to_cpu(fcb->flags) & RXFCB_VLN)
+               __vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
+                                      be16_to_cpu(fcb->vlctl));
++
++      /* Send the packet up the stack */
++      napi_gro_receive(napi, skb);
++
+ }
+ /* gfar_clean_rx_ring() -- Processes each frame in the rx ring
+@@ -3082,89 +2892,91 @@ static void gfar_process_frame(struct net_device *ndev, struct sk_buff *skb)
+  */
+ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)
+ {
+-      struct net_device *ndev = rx_queue->ndev;
+-      struct gfar_private *priv = netdev_priv(ndev);
+-      struct rxbd8 *bdp;
+-      int i, howmany = 0;
+-      struct sk_buff *skb = rx_queue->skb;
+-      int cleaned_cnt = gfar_rxbd_unused(rx_queue);
+-      unsigned int total_bytes = 0, total_pkts = 0;
++      struct net_device *dev = rx_queue->dev;
++      struct rxbd8 *bdp, *base;
++      struct sk_buff *skb;
++      int pkt_len;
++      int amount_pull;
++      int howmany = 0;
++      struct gfar_private *priv = netdev_priv(dev);
+       /* Get the first full descriptor */
+-      i = rx_queue->next_to_clean;
++      bdp = rx_queue->cur_rx;
++      base = rx_queue->rx_bd_base;
+-      while (rx_work_limit--) {
+-              u32 lstatus;
++      amount_pull = priv->uses_rxfcb ? GMAC_FCB_LEN : 0;
+-              if (cleaned_cnt >= GFAR_RX_BUFF_ALLOC) {
+-                      gfar_alloc_rx_buffs(rx_queue, cleaned_cnt);
+-                      cleaned_cnt = 0;
+-              }
+-
+-              bdp = &rx_queue->rx_bd_base[i];
+-              lstatus = be32_to_cpu(bdp->lstatus);
+-              if (lstatus & BD_LFLAG(RXBD_EMPTY))
+-                      break;
++      while (!(be16_to_cpu(bdp->status) & RXBD_EMPTY) && rx_work_limit--) {
++              struct sk_buff *newskb;
++              dma_addr_t bufaddr;
+-              /* order rx buffer descriptor reads */
+               rmb();
+-              /* fetch next to clean buffer from the ring */
+-              skb = gfar_get_next_rxbuff(rx_queue, lstatus, skb);
+-              if (unlikely(!skb))
+-                      break;
+-
+-              cleaned_cnt++;
+-              howmany++;
++              /* Add another skb for the future */
++              newskb = gfar_new_skb(dev, &bufaddr);
+-              if (unlikely(++i == rx_queue->rx_ring_size))
+-                      i = 0;
++              skb = rx_queue->rx_skbuff[rx_queue->skb_currx];
+-              rx_queue->next_to_clean = i;
+-
+-              /* fetch next buffer if not the last in frame */
+-              if (!(lstatus & BD_LFLAG(RXBD_LAST)))
+-                      continue;
++              dma_unmap_single(priv->dev, be32_to_cpu(bdp->bufPtr),
++                               priv->rx_buffer_size, DMA_FROM_DEVICE);
++
++              if (unlikely(!(be16_to_cpu(bdp->status) & RXBD_ERR) &&
++                           be16_to_cpu(bdp->length) > priv->rx_buffer_size))
++                      bdp->status = cpu_to_be16(RXBD_LARGE);
++
++              /* We drop the frame if we failed to allocate a new buffer */
++              if (unlikely(!newskb ||
++                           !(be16_to_cpu(bdp->status) & RXBD_LAST) ||
++                           be16_to_cpu(bdp->status) & RXBD_ERR)) {
++                      count_errors(be16_to_cpu(bdp->status), dev);
++
++                      if (unlikely(!newskb)) {
++                              newskb = skb;
++                              bufaddr = be32_to_cpu(bdp->bufPtr);
++                      } else if (skb)
++                              dev_kfree_skb(skb);
++              } else {
++                      /* Increment the number of packets */
++                      rx_queue->stats.rx_packets++;
++                      howmany++;
++
++                      if (likely(skb)) {
++                              pkt_len = be16_to_cpu(bdp->length) -
++                                        ETH_FCS_LEN;
++                              /* Remove the FCS from the packet length */
++                              skb_put(skb, pkt_len);
++                              rx_queue->stats.rx_bytes += pkt_len;
++                              skb_record_rx_queue(skb, rx_queue->qindex);
++                              gfar_process_frame(dev, skb, amount_pull,
++                                                 &rx_queue->grp->napi_rx);
+-              if (unlikely(lstatus & BD_LFLAG(RXBD_ERR))) {
+-                      count_errors(lstatus, ndev);
++                      } else {
++                              netif_warn(priv, rx_err, dev, "Missing skb!\n");
++                              rx_queue->stats.rx_dropped++;
++                              atomic64_inc(&priv->extra_stats.rx_skbmissing);
++                      }
+-                      /* discard faulty buffer */
+-                      dev_kfree_skb(skb);
+-                      skb = NULL;
+-                      rx_queue->stats.rx_dropped++;
+-                      continue;
+               }
+-              /* Increment the number of packets */
+-              total_pkts++;
+-              total_bytes += skb->len;
++              rx_queue->rx_skbuff[rx_queue->skb_currx] = newskb;
+-              skb_record_rx_queue(skb, rx_queue->qindex);
++              /* Setup the new bdp */
++              gfar_init_rxbdp(rx_queue, bdp, bufaddr);
+-              gfar_process_frame(ndev, skb);
++              /* Update Last Free RxBD pointer for LFC */
++              if (unlikely(rx_queue->rfbptr && priv->tx_actual_en))
++                      gfar_write(rx_queue->rfbptr, (u32)bdp);
+-              /* Send the packet up the stack */
+-              napi_gro_receive(&rx_queue->grp->napi_rx, skb);
++              /* Update to the next pointer */
++              bdp = next_bd(bdp, base, rx_queue->rx_ring_size);
+-              skb = NULL;
++              /* update to point at the next skb */
++              rx_queue->skb_currx = (rx_queue->skb_currx + 1) &
++                                    RX_RING_MOD_MASK(rx_queue->rx_ring_size);
+       }
+-      /* Store incomplete frames for completion */
+-      rx_queue->skb = skb;
+-
+-      rx_queue->stats.rx_packets += total_pkts;
+-      rx_queue->stats.rx_bytes += total_bytes;
+-
+-      if (cleaned_cnt)
+-              gfar_alloc_rx_buffs(rx_queue, cleaned_cnt);
+-
+-      /* Update Last Free RxBD pointer for LFC */
+-      if (unlikely(priv->tx_actual_en)) {
+-              u32 bdp_dma = gfar_rxbd_dma_lastfree(rx_queue);
+-
+-              gfar_write(rx_queue->rfbptr, bdp_dma);
+-      }
++      /* Update the current rxbd pointer to be the next one */
++      rx_queue->cur_rx = bdp;
+       return howmany;
+ }
+@@ -3396,7 +3208,7 @@ static irqreturn_t gfar_interrupt(int irq, void *grp_id)
+ static void adjust_link(struct net_device *dev)
+ {
+       struct gfar_private *priv = netdev_priv(dev);
+-      struct phy_device *phydev = dev->phydev;
++      struct phy_device *phydev = priv->phydev;
+       if (unlikely(phydev->link != priv->oldlink ||
+                    (phydev->link && (phydev->duplex != priv->oldduplex ||
+@@ -3599,19 +3411,30 @@ static irqreturn_t gfar_error(int irq, void *grp_id)
+               if (events & IEVENT_CRL)
+                       dev->stats.tx_aborted_errors++;
+               if (events & IEVENT_XFUN) {
++                      unsigned long flags;
++
+                       netif_dbg(priv, tx_err, dev,
+                                 "TX FIFO underrun, packet dropped\n");
+                       dev->stats.tx_dropped++;
+                       atomic64_inc(&priv->extra_stats.tx_underrun);
+-                      schedule_work(&priv->reset_task);
++                      local_irq_save(flags);
++                      lock_tx_qs(priv);
++
++                      /* Reactivate the Tx Queues */
++                      gfar_write(&regs->tstat, gfargrp->tstat);
++
++                      unlock_tx_qs(priv);
++                      local_irq_restore(flags);
+               }
+               netif_dbg(priv, tx_err, dev, "Transmit Error\n");
+       }
+       if (events & IEVENT_BSY) {
+-              dev->stats.rx_over_errors++;
++              dev->stats.rx_errors++;
+               atomic64_inc(&priv->extra_stats.rx_bsy);
++              gfar_receive(irq, grp_id);
++
+               netif_dbg(priv, rx_err, dev, "busy error (rstat: %x)\n",
+                         gfar_read(&regs->rstat));
+       }
+@@ -3637,8 +3460,7 @@ static irqreturn_t gfar_error(int irq, void *grp_id)
+ static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv)
+ {
+-      struct net_device *ndev = priv->ndev;
+-      struct phy_device *phydev = ndev->phydev;
++      struct phy_device *phydev = priv->phydev;
+       u32 val = 0;
+       if (!phydev->duplex)
+@@ -3678,10 +3500,10 @@ static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv)
+ static noinline void gfar_update_link_state(struct gfar_private *priv)
+ {
+       struct gfar __iomem *regs = priv->gfargrp[0].regs;
+-      struct net_device *ndev = priv->ndev;
+-      struct phy_device *phydev = ndev->phydev;
++      struct phy_device *phydev = priv->phydev;
+       struct gfar_priv_rx_q *rx_queue = NULL;
+       int i;
++      struct rxbd8 *bdp;
+       if (unlikely(test_bit(GFAR_RESETTING, &priv->state)))
+               return;
+@@ -3738,11 +3560,15 @@ static noinline void gfar_update_link_state(struct gfar_private *priv)
+               /* Turn last free buffer recording on */
+               if ((tempval1 & MACCFG1_TX_FLOW) && !tx_flow_oldval) {
+                       for (i = 0; i < priv->num_rx_queues; i++) {
+-                              u32 bdp_dma;
+-
+                               rx_queue = priv->rx_queue[i];
+-                              bdp_dma = gfar_rxbd_dma_lastfree(rx_queue);
+-                              gfar_write(rx_queue->rfbptr, bdp_dma);
++                              bdp = rx_queue->cur_rx;
++                              /* skip to previous bd */
++                              bdp = skip_bd(bdp, rx_queue->rx_ring_size - 1,
++                                            rx_queue->rx_bd_base,
++                                            rx_queue->rx_ring_size);
++
++                              if (rx_queue->rfbptr)
++                                      gfar_write(rx_queue->rfbptr, (u32)bdp);
+                       }
+                       priv->tx_actual_en = 1;
+diff --git a/drivers/net/ethernet/freescale/gianfar.h b/drivers/net/ethernet/freescale/gianfar.h
+index 6e8a9c8..daa1d37 100644
+--- a/drivers/net/ethernet/freescale/gianfar.h
++++ b/drivers/net/ethernet/freescale/gianfar.h
+@@ -71,6 +71,11 @@ struct ethtool_rx_list {
+ /* Number of bytes to align the rx bufs to */
+ #define RXBUF_ALIGNMENT 64
++/* The number of bytes which composes a unit for the purpose of
++ * allocating data buffers.  ie-for any given MTU, the data buffer
++ * will be the next highest multiple of 512 bytes. */
++#define INCREMENTAL_BUFFER_SIZE 512
++
+ #define PHY_INIT_TIMEOUT 100000
+ #define DRV_NAME "gfar-enet"
+@@ -87,8 +92,6 @@ extern const char gfar_driver_version[];
+ #define DEFAULT_TX_RING_SIZE  256
+ #define DEFAULT_RX_RING_SIZE  256
+-#define GFAR_RX_BUFF_ALLOC    16
+-
+ #define GFAR_RX_MAX_RING_SIZE   256
+ #define GFAR_TX_MAX_RING_SIZE   256
+@@ -100,15 +103,11 @@ extern const char gfar_driver_version[];
+ #define DEFAULT_RX_LFC_THR  16
+ #define DEFAULT_LFC_PTVVAL  4
+-/* prevent fragmenation by HW in DSA environments */
+-#define GFAR_RXB_SIZE roundup(1536 + 8, 64)
+-#define GFAR_SKBFRAG_SIZE (RXBUF_ALIGNMENT + GFAR_RXB_SIZE \
+-                        + SKB_DATA_ALIGN(sizeof(struct skb_shared_info)))
+-#define GFAR_RXB_TRUESIZE 2048
+-
++#define DEFAULT_RX_BUFFER_SIZE  1536
+ #define TX_RING_MOD_MASK(size) (size-1)
+ #define RX_RING_MOD_MASK(size) (size-1)
+-#define GFAR_JUMBO_FRAME_SIZE 9600
++#define JUMBO_BUFFER_SIZE 9728
++#define JUMBO_FRAME_SIZE 9600
+ #define DEFAULT_FIFO_TX_THR 0x100
+ #define DEFAULT_FIFO_TX_STARVE 0x40
+@@ -341,7 +340,6 @@ extern const char gfar_driver_version[];
+ #define IEVENT_MAG            0x00000800
+ #define IEVENT_GRSC           0x00000100
+ #define IEVENT_RXF0           0x00000080
+-#define IEVENT_FGPI           0x00000010
+ #define IEVENT_FIR            0x00000008
+ #define IEVENT_FIQ            0x00000004
+ #define IEVENT_DPE            0x00000002
+@@ -374,7 +372,6 @@ extern const char gfar_driver_version[];
+ #define IMASK_MAG             0x00000800
+ #define IMASK_GRSC              0x00000100
+ #define IMASK_RXFEN0          0x00000080
+-#define IMASK_FGPI            0x00000010
+ #define IMASK_FIR             0x00000008
+ #define IMASK_FIQ             0x00000004
+ #define IMASK_DPE             0x00000002
+@@ -543,9 +540,6 @@ extern const char gfar_driver_version[];
+ #define GFAR_INT_NAME_MAX     (IFNAMSIZ + 6)  /* '_g#_xx' */
+-#define GFAR_WOL_MAGIC                0x00000001
+-#define GFAR_WOL_FILER_UCAST  0x00000002
+-
+ struct txbd8
+ {
+       union {
+@@ -646,7 +640,6 @@ struct rmon_mib
+ };
+ struct gfar_extra_stats {
+-      atomic64_t rx_alloc_err;
+       atomic64_t rx_large;
+       atomic64_t rx_short;
+       atomic64_t rx_nonoctet;
+@@ -658,6 +651,7 @@ struct gfar_extra_stats {
+       atomic64_t eberr;
+       atomic64_t tx_babt;
+       atomic64_t tx_underrun;
++      atomic64_t rx_skbmissing;
+       atomic64_t tx_timeout;
+ };
+@@ -923,8 +917,6 @@ struct gfar {
+ #define FSL_GIANFAR_DEV_HAS_BD_STASHING               0x00000200
+ #define FSL_GIANFAR_DEV_HAS_BUF_STASHING      0x00000400
+ #define FSL_GIANFAR_DEV_HAS_TIMER             0x00000800
+-#define FSL_GIANFAR_DEV_HAS_WAKE_ON_FILER     0x00001000
+-#define FSL_GIANFAR_DEV_HAS_RX_FILER          0x00002000
+ #if (MAXGROUPS == 2)
+ #define DEFAULT_MAPPING       0xAA
+@@ -1020,42 +1012,34 @@ struct rx_q_stats {
+       unsigned long rx_dropped;
+ };
+-struct gfar_rx_buff {
+-      dma_addr_t dma;
+-      struct page *page;
+-      unsigned int page_offset;
+-};
+-
+ /**
+  *    struct gfar_priv_rx_q - per rx queue structure
+- *    @rx_buff: Array of buffer info metadata structs
++ *    @rx_skbuff: skb pointers
++ *    @skb_currx: currently use skb pointer
+  *    @rx_bd_base: First rx buffer descriptor
+- *    @next_to_use: index of the next buffer to be alloc'd
+- *    @next_to_clean: index of the next buffer to be cleaned
++ *    @cur_rx: Next free rx ring entry
+  *    @qindex: index of this queue
+- *    @ndev: back pointer to net_device
++ *    @dev: back pointer to the dev structure
+  *    @rx_ring_size: Rx ring size
+  *    @rxcoalescing: enable/disable rx-coalescing
+  *    @rxic: receive interrupt coalescing vlaue
+  */
+ struct gfar_priv_rx_q {
+-      struct  gfar_rx_buff *rx_buff __aligned(SMP_CACHE_BYTES);
++      struct  sk_buff **rx_skbuff __aligned(SMP_CACHE_BYTES);
++      dma_addr_t rx_bd_dma_base;
+       struct  rxbd8 *rx_bd_base;
+-      struct  net_device *ndev;
+-      struct  device *dev;
+-      u16 rx_ring_size;
+-      u16 qindex;
+-      struct  gfar_priv_grp *grp;
+-      u16 next_to_clean;
+-      u16 next_to_use;
+-      u16 next_to_alloc;
+-      struct  sk_buff *skb;
++      struct  rxbd8 *cur_rx;
++      struct  net_device *dev;
++      struct gfar_priv_grp *grp;
+       struct rx_q_stats stats;
+-      u32 __iomem *rfbptr;
++      u16     skb_currx;
++      u16     qindex;
++      unsigned int    rx_ring_size;
++      /* RX Coalescing values */
+       unsigned char rxcoalescing;
+       unsigned long rxic;
+-      dma_addr_t rx_bd_dma_base;
++      u32 __iomem *rfbptr;
+ };
+ enum gfar_irqinfo_id {
+@@ -1125,6 +1109,7 @@ struct gfar_private {
+       struct device *dev;
+       struct net_device *ndev;
+       enum gfar_errata errata;
++      unsigned int rx_buffer_size;
+       u16 uses_rxfcb;
+       u16 padding;
+@@ -1154,11 +1139,15 @@ struct gfar_private {
+       phy_interface_t interface;
+       struct device_node *phy_node;
+       struct device_node *tbi_node;
++      struct phy_device *phydev;
+       struct mii_bus *mii_bus;
+       int oldspeed;
+       int oldduplex;
+       int oldlink;
++      /* Bitfield update lock */
++      spinlock_t bflock;
++
+       uint32_t msg_enable;
+       struct work_struct reset_task;
+@@ -1168,6 +1157,8 @@ struct gfar_private {
+               extended_hash:1,
+               bd_stash_en:1,
+               rx_filer_enable:1,
++              /* Wake-on-LAN enabled */
++              wol_en:1,
+               /* Enable priorty based Tx scheduling in Hw */
+               prio_sched_en:1,
+               /* Flow control flags */
+@@ -1196,10 +1187,6 @@ struct gfar_private {
+       u32 __iomem *hash_regs[16];
+       int hash_width;
+-      /* wake-on-lan settings */
+-      u16 wol_opts;
+-      u16 wol_supported;
+-
+       /*Filer table*/
+       unsigned int ftp_rqfpr[MAX_FILER_IDX + 1];
+       unsigned int ftp_rqfcr[MAX_FILER_IDX + 1];
+@@ -1308,28 +1295,6 @@ static inline void gfar_clear_txbd_status(struct txbd8 *bdp)
+       bdp->lstatus = cpu_to_be32(lstatus);
+ }
+-static inline int gfar_rxbd_unused(struct gfar_priv_rx_q *rxq)
+-{
+-      if (rxq->next_to_clean > rxq->next_to_use)
+-              return rxq->next_to_clean - rxq->next_to_use - 1;
+-
+-      return rxq->rx_ring_size + rxq->next_to_clean - rxq->next_to_use - 1;
+-}
+-
+-static inline u32 gfar_rxbd_dma_lastfree(struct gfar_priv_rx_q *rxq)
+-{
+-      struct rxbd8 *bdp;
+-      u32 bdp_dma;
+-      int i;
+-
+-      i = rxq->next_to_use ? rxq->next_to_use - 1 : rxq->rx_ring_size - 1;
+-      bdp = &rxq->rx_bd_base[i];
+-      bdp_dma = lower_32_bits(rxq->rx_bd_dma_base);
+-      bdp_dma += (uintptr_t)bdp - (uintptr_t)rxq->rx_bd_base;
+-
+-      return bdp_dma;
+-}
+-
+ irqreturn_t gfar_receive(int irq, void *dev_id);
+ int startup_gfar(struct net_device *dev);
+ void stop_gfar(struct net_device *dev);
+diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c
+index 56588f2..fda12fb 100644
+--- a/drivers/net/ethernet/freescale/gianfar_ethtool.c
++++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c
+@@ -61,8 +61,6 @@ static void gfar_gdrvinfo(struct net_device *dev,
+                         struct ethtool_drvinfo *drvinfo);
+ static const char stat_gstrings[][ETH_GSTRING_LEN] = {
+-      /* extra stats */
+-      "rx-allocation-errors",
+       "rx-large-frame-errors",
+       "rx-short-frame-errors",
+       "rx-non-octet-errors",
+@@ -74,8 +72,8 @@ static const char stat_gstrings[][ETH_GSTRING_LEN] = {
+       "ethernet-bus-error",
+       "tx-babbling-errors",
+       "tx-underrun-errors",
++      "rx-skb-missing-errors",
+       "tx-timeout-errors",
+-      /* rmon stats */
+       "tx-rx-64-frames",
+       "tx-rx-65-127-frames",
+       "tx-rx-128-255-frames",
+@@ -182,6 +180,42 @@ static void gfar_gdrvinfo(struct net_device *dev,
+               sizeof(drvinfo->version));
+       strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+       strlcpy(drvinfo->bus_info, "N/A", sizeof(drvinfo->bus_info));
++      drvinfo->regdump_len = 0;
++      drvinfo->eedump_len = 0;
++}
++
++
++static int gfar_ssettings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++      struct gfar_private *priv = netdev_priv(dev);
++      struct phy_device *phydev = priv->phydev;
++
++      if (NULL == phydev)
++              return -ENODEV;
++
++      return phy_ethtool_sset(phydev, cmd);
++}
++
++
++/* Return the current settings in the ethtool_cmd structure */
++static int gfar_gsettings(struct net_device *dev, struct ethtool_cmd *cmd)
++{
++      struct gfar_private *priv = netdev_priv(dev);
++      struct phy_device *phydev = priv->phydev;
++      struct gfar_priv_rx_q *rx_queue = NULL;
++      struct gfar_priv_tx_q *tx_queue = NULL;
++
++      if (NULL == phydev)
++              return -ENODEV;
++      tx_queue = priv->tx_queue[0];
++      rx_queue = priv->rx_queue[0];
++
++      /* etsec-1.7 and older versions have only one txic
++       * and rxic regs although they support multiple queues */
++      cmd->maxtxpkt = get_icft_value(tx_queue->txic);
++      cmd->maxrxpkt = get_icft_value(rx_queue->rxic);
++
++      return phy_ethtool_gset(phydev, cmd);
+ }
+ /* Return the length of the register structure */
+@@ -208,12 +242,10 @@ static void gfar_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+ static unsigned int gfar_usecs2ticks(struct gfar_private *priv,
+                                    unsigned int usecs)
+ {
+-      struct net_device *ndev = priv->ndev;
+-      struct phy_device *phydev = ndev->phydev;
+       unsigned int count;
+       /* The timer is different, depending on the interface speed */
+-      switch (phydev->speed) {
++      switch (priv->phydev->speed) {
+       case SPEED_1000:
+               count = GFAR_GBIT_TIME;
+               break;
+@@ -235,12 +267,10 @@ static unsigned int gfar_usecs2ticks(struct gfar_private *priv,
+ static unsigned int gfar_ticks2usecs(struct gfar_private *priv,
+                                    unsigned int ticks)
+ {
+-      struct net_device *ndev = priv->ndev;
+-      struct phy_device *phydev = ndev->phydev;
+       unsigned int count;
+       /* The timer is different, depending on the interface speed */
+-      switch (phydev->speed) {
++      switch (priv->phydev->speed) {
+       case SPEED_1000:
+               count = GFAR_GBIT_TIME;
+               break;
+@@ -274,7 +304,7 @@ static int gfar_gcoalesce(struct net_device *dev,
+       if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
+               return -EOPNOTSUPP;
+-      if (!dev->phydev)
++      if (NULL == priv->phydev)
+               return -ENODEV;
+       rx_queue = priv->rx_queue[0];
+@@ -335,7 +365,7 @@ static int gfar_scoalesce(struct net_device *dev,
+       if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_COALESCE))
+               return -EOPNOTSUPP;
+-      if (!dev->phydev)
++      if (NULL == priv->phydev)
+               return -ENODEV;
+       /* Check the bounds of the values */
+@@ -499,7 +529,7 @@ static int gfar_spauseparam(struct net_device *dev,
+                           struct ethtool_pauseparam *epause)
+ {
+       struct gfar_private *priv = netdev_priv(dev);
+-      struct phy_device *phydev = dev->phydev;
++      struct phy_device *phydev = priv->phydev;
+       struct gfar __iomem *regs = priv->gfargrp[0].regs;
+       u32 oldadv, newadv;
+@@ -612,49 +642,31 @@ static void gfar_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+ {
+       struct gfar_private *priv = netdev_priv(dev);
+-      wol->supported = 0;
+-      wol->wolopts = 0;
+-
+-      if (priv->wol_supported & GFAR_WOL_MAGIC)
+-              wol->supported |= WAKE_MAGIC;
+-
+-      if (priv->wol_supported & GFAR_WOL_FILER_UCAST)
+-              wol->supported |= WAKE_UCAST;
+-
+-      if (priv->wol_opts & GFAR_WOL_MAGIC)
+-              wol->wolopts |= WAKE_MAGIC;
+-
+-      if (priv->wol_opts & GFAR_WOL_FILER_UCAST)
+-              wol->wolopts |= WAKE_UCAST;
++      if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) {
++              wol->supported = WAKE_MAGIC;
++              wol->wolopts = priv->wol_en ? WAKE_MAGIC : 0;
++      } else {
++              wol->supported = wol->wolopts = 0;
++      }
+ }
+ static int gfar_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+ {
+       struct gfar_private *priv = netdev_priv(dev);
+-      u16 wol_opts = 0;
+-      int err;
++      unsigned long flags;
+-      if (!priv->wol_supported && wol->wolopts)
++      if (!(priv->device_flags & FSL_GIANFAR_DEV_HAS_MAGIC_PACKET) &&
++          wol->wolopts != 0)
+               return -EINVAL;
+-      if (wol->wolopts & ~(WAKE_MAGIC | WAKE_UCAST))
++      if (wol->wolopts & ~WAKE_MAGIC)
+               return -EINVAL;
+-      if (wol->wolopts & WAKE_MAGIC) {
+-              wol_opts |= GFAR_WOL_MAGIC;
+-      } else {
+-              if (wol->wolopts & WAKE_UCAST)
+-                      wol_opts |= GFAR_WOL_FILER_UCAST;
+-      }
+-
+-      wol_opts &= priv->wol_supported;
+-      priv->wol_opts = 0;
+-
+-      err = device_set_wakeup_enable(priv->dev, wol_opts);
+-      if (err)
+-              return err;
++      device_set_wakeup_enable(&dev->dev, wol->wolopts & WAKE_MAGIC);
+-      priv->wol_opts = wol_opts;
++      spin_lock_irqsave(&priv->bflock, flags);
++      priv->wol_en =  !!device_may_wakeup(&dev->dev);
++      spin_unlock_irqrestore(&priv->bflock, flags);
+       return 0;
+ }
+@@ -665,14 +677,14 @@ static void ethflow_to_filer_rules (struct gfar_private *priv, u64 ethflow)
+       u32 fcr = 0x0, fpr = FPR_FILER_MASK;
+       if (ethflow & RXH_L2DA) {
+-              fcr = RQFCR_PID_DAH | RQFCR_CMP_NOMATCH |
++              fcr = RQFCR_PID_DAH |RQFCR_CMP_NOMATCH |
+                     RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
+               priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
+               priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
+               gfar_write_filer(priv, priv->cur_filer_idx, fcr, fpr);
+               priv->cur_filer_idx = priv->cur_filer_idx - 1;
+-              fcr = RQFCR_PID_DAL | RQFCR_CMP_NOMATCH |
++              fcr = RQFCR_PID_DAL | RQFCR_AND | RQFCR_CMP_NOMATCH |
+                     RQFCR_HASH | RQFCR_AND | RQFCR_HASHTBL_0;
+               priv->ftp_rqfpr[priv->cur_filer_idx] = fpr;
+               priv->ftp_rqfcr[priv->cur_filer_idx] = fcr;
+@@ -891,6 +903,27 @@ static int gfar_check_filer_hardware(struct gfar_private *priv)
+       return 0;
+ }
++static int gfar_comp_asc(const void *a, const void *b)
++{
++      return memcmp(a, b, 4);
++}
++
++static int gfar_comp_desc(const void *a, const void *b)
++{
++      return -memcmp(a, b, 4);
++}
++
++static void gfar_swap(void *a, void *b, int size)
++{
++      u32 *_a = a;
++      u32 *_b = b;
++
++      swap(_a[0], _b[0]);
++      swap(_a[1], _b[1]);
++      swap(_a[2], _b[2]);
++      swap(_a[3], _b[3]);
++}
++
+ /* Write a mask to filer cache */
+ static void gfar_set_mask(u32 mask, struct filer_table *tab)
+ {
+@@ -1240,6 +1273,310 @@ static int gfar_convert_to_filer(struct ethtool_rx_flow_spec *rule,
+       return 0;
+ }
++/* Copy size filer entries */
++static void gfar_copy_filer_entries(struct gfar_filer_entry dst[0],
++                                  struct gfar_filer_entry src[0], s32 size)
++{
++      while (size > 0) {
++              size--;
++              dst[size].ctrl = src[size].ctrl;
++              dst[size].prop = src[size].prop;
++      }
++}
++
++/* Delete the contents of the filer-table between start and end
++ * and collapse them
++ */
++static int gfar_trim_filer_entries(u32 begin, u32 end, struct filer_table *tab)
++{
++      int length;
++
++      if (end > MAX_FILER_CACHE_IDX || end < begin)
++              return -EINVAL;
++
++      end++;
++      length = end - begin;
++
++      /* Copy */
++      while (end < tab->index) {
++              tab->fe[begin].ctrl = tab->fe[end].ctrl;
++              tab->fe[begin++].prop = tab->fe[end++].prop;
++
++      }
++      /* Fill up with don't cares */
++      while (begin < tab->index) {
++              tab->fe[begin].ctrl = 0x60;
++              tab->fe[begin].prop = 0xFFFFFFFF;
++              begin++;
++      }
++
++      tab->index -= length;
++      return 0;
++}
++
++/* Make space on the wanted location */
++static int gfar_expand_filer_entries(u32 begin, u32 length,
++                                   struct filer_table *tab)
++{
++      if (length == 0 || length + tab->index > MAX_FILER_CACHE_IDX ||
++          begin > MAX_FILER_CACHE_IDX)
++              return -EINVAL;
++
++      gfar_copy_filer_entries(&(tab->fe[begin + length]), &(tab->fe[begin]),
++                              tab->index - length + 1);
++
++      tab->index += length;
++      return 0;
++}
++
++static int gfar_get_next_cluster_start(int start, struct filer_table *tab)
++{
++      for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1);
++           start++) {
++              if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) ==
++                  (RQFCR_AND | RQFCR_CLE))
++                      return start;
++      }
++      return -1;
++}
++
++static int gfar_get_next_cluster_end(int start, struct filer_table *tab)
++{
++      for (; (start < tab->index) && (start < MAX_FILER_CACHE_IDX - 1);
++           start++) {
++              if ((tab->fe[start].ctrl & (RQFCR_AND | RQFCR_CLE)) ==
++                  (RQFCR_CLE))
++                      return start;
++      }
++      return -1;
++}
++
++/* Uses hardwares clustering option to reduce
++ * the number of filer table entries
++ */
++static void gfar_cluster_filer(struct filer_table *tab)
++{
++      s32 i = -1, j, iend, jend;
++
++      while ((i = gfar_get_next_cluster_start(++i, tab)) != -1) {
++              j = i;
++              while ((j = gfar_get_next_cluster_start(++j, tab)) != -1) {
++                      /* The cluster entries self and the previous one
++                       * (a mask) must be identical!
++                       */
++                      if (tab->fe[i].ctrl != tab->fe[j].ctrl)
++                              break;
++                      if (tab->fe[i].prop != tab->fe[j].prop)
++                              break;
++                      if (tab->fe[i - 1].ctrl != tab->fe[j - 1].ctrl)
++                              break;
++                      if (tab->fe[i - 1].prop != tab->fe[j - 1].prop)
++                              break;
++                      iend = gfar_get_next_cluster_end(i, tab);
++                      jend = gfar_get_next_cluster_end(j, tab);
++                      if (jend == -1 || iend == -1)
++                              break;
++
++                      /* First we make some free space, where our cluster
++                       * element should be. Then we copy it there and finally
++                       * delete in from its old location.
++                       */
++                      if (gfar_expand_filer_entries(iend, (jend - j), tab) ==
++                          -EINVAL)
++                              break;
++
++                      gfar_copy_filer_entries(&(tab->fe[iend + 1]),
++                                              &(tab->fe[jend + 1]), jend - j);
++
++                      if (gfar_trim_filer_entries(jend - 1,
++                                                  jend + (jend - j),
++                                                  tab) == -EINVAL)
++                              return;
++
++                      /* Mask out cluster bit */
++                      tab->fe[iend].ctrl &= ~(RQFCR_CLE);
++              }
++      }
++}
++
++/* Swaps the masked bits of a1<>a2 and b1<>b2 */
++static void gfar_swap_bits(struct gfar_filer_entry *a1,
++                         struct gfar_filer_entry *a2,
++                         struct gfar_filer_entry *b1,
++                         struct gfar_filer_entry *b2, u32 mask)
++{
++      u32 temp[4];
++      temp[0] = a1->ctrl & mask;
++      temp[1] = a2->ctrl & mask;
++      temp[2] = b1->ctrl & mask;
++      temp[3] = b2->ctrl & mask;
++
++      a1->ctrl &= ~mask;
++      a2->ctrl &= ~mask;
++      b1->ctrl &= ~mask;
++      b2->ctrl &= ~mask;
++
++      a1->ctrl |= temp[1];
++      a2->ctrl |= temp[0];
++      b1->ctrl |= temp[3];
++      b2->ctrl |= temp[2];
++}
++
++/* Generate a list consisting of masks values with their start and
++ * end of validity and block as indicator for parts belonging
++ * together (glued by ANDs) in mask_table
++ */
++static u32 gfar_generate_mask_table(struct gfar_mask_entry *mask_table,
++                                  struct filer_table *tab)
++{
++      u32 i, and_index = 0, block_index = 1;
++
++      for (i = 0; i < tab->index; i++) {
++
++              /* LSByte of control = 0 sets a mask */
++              if (!(tab->fe[i].ctrl & 0xF)) {
++                      mask_table[and_index].mask = tab->fe[i].prop;
++                      mask_table[and_index].start = i;
++                      mask_table[and_index].block = block_index;
++                      if (and_index >= 1)
++                              mask_table[and_index - 1].end = i - 1;
++                      and_index++;
++              }
++              /* cluster starts and ends will be separated because they should
++               * hold their position
++               */
++              if (tab->fe[i].ctrl & RQFCR_CLE)
++                      block_index++;
++              /* A not set AND indicates the end of a depended block */
++              if (!(tab->fe[i].ctrl & RQFCR_AND))
++                      block_index++;
++      }
++
++      mask_table[and_index - 1].end = i - 1;
++
++      return and_index;
++}
++
++/* Sorts the entries of mask_table by the values of the masks.
++ * Important: The 0xFF80 flags of the first and last entry of a
++ * block must hold their position (which queue, CLusterEnable, ReJEct,
++ * AND)
++ */
++static void gfar_sort_mask_table(struct gfar_mask_entry *mask_table,
++                               struct filer_table *temp_table, u32 and_index)
++{
++      /* Pointer to compare function (_asc or _desc) */
++      int (*gfar_comp)(const void *, const void *);
++
++      u32 i, size = 0, start = 0, prev = 1;
++      u32 old_first, old_last, new_first, new_last;
++
++      gfar_comp = &gfar_comp_desc;
++
++      for (i = 0; i < and_index; i++) {
++              if (prev != mask_table[i].block) {
++                      old_first = mask_table[start].start + 1;
++                      old_last = mask_table[i - 1].end;
++                      sort(mask_table + start, size,
++                           sizeof(struct gfar_mask_entry),
++                           gfar_comp, &gfar_swap);
++
++                      /* Toggle order for every block. This makes the
++                       * thing more efficient!
++                       */
++                      if (gfar_comp == gfar_comp_desc)
++                              gfar_comp = &gfar_comp_asc;
++                      else
++                              gfar_comp = &gfar_comp_desc;
++
++                      new_first = mask_table[start].start + 1;
++                      new_last = mask_table[i - 1].end;
++
++                      gfar_swap_bits(&temp_table->fe[new_first],
++                                     &temp_table->fe[old_first],
++                                     &temp_table->fe[new_last],
++                                     &temp_table->fe[old_last],
++                                     RQFCR_QUEUE | RQFCR_CLE |
++                                     RQFCR_RJE | RQFCR_AND);
++
++                      start = i;
++                      size = 0;
++              }
++              size++;
++              prev = mask_table[i].block;
++      }
++}
++
++/* Reduces the number of masks needed in the filer table to save entries
++ * This is done by sorting the masks of a depended block. A depended block is
++ * identified by gluing ANDs or CLE. The sorting order toggles after every
++ * block. Of course entries in scope of a mask must change their location with
++ * it.
++ */
++static int gfar_optimize_filer_masks(struct filer_table *tab)
++{
++      struct filer_table *temp_table;
++      struct gfar_mask_entry *mask_table;
++
++      u32 and_index = 0, previous_mask = 0, i = 0, j = 0, size = 0;
++      s32 ret = 0;
++
++      /* We need a copy of the filer table because
++       * we want to change its order
++       */
++      temp_table = kmemdup(tab, sizeof(*temp_table), GFP_KERNEL);
++      if (temp_table == NULL)
++              return -ENOMEM;
++
++      mask_table = kcalloc(MAX_FILER_CACHE_IDX / 2 + 1,
++                           sizeof(struct gfar_mask_entry), GFP_KERNEL);
++
++      if (mask_table == NULL) {
++              ret = -ENOMEM;
++              goto end;
++      }
++
++      and_index = gfar_generate_mask_table(mask_table, tab);
++
++      gfar_sort_mask_table(mask_table, temp_table, and_index);
++
++      /* Now we can copy the data from our duplicated filer table to
++       * the real one in the order the mask table says
++       */
++      for (i = 0; i < and_index; i++) {
++              size = mask_table[i].end - mask_table[i].start + 1;
++              gfar_copy_filer_entries(&(tab->fe[j]),
++                              &(temp_table->fe[mask_table[i].start]), size);
++              j += size;
++      }
++
++      /* And finally we just have to check for duplicated masks and drop the
++       * second ones
++       */
++      for (i = 0; i < tab->index && i < MAX_FILER_CACHE_IDX; i++) {
++              if (tab->fe[i].ctrl == 0x80) {
++                      previous_mask = i++;
++                      break;
++              }
++      }
++      for (; i < tab->index && i < MAX_FILER_CACHE_IDX; i++) {
++              if (tab->fe[i].ctrl == 0x80) {
++                      if (tab->fe[i].prop == tab->fe[previous_mask].prop) {
++                              /* Two identical ones found!
++                               * So drop the second one!
++                               */
++                              gfar_trim_filer_entries(i, i, tab);
++                      } else
++                              /* Not identical! */
++                              previous_mask = i;
++              }
++      }
++
++      kfree(mask_table);
++end:  kfree(temp_table);
++      return ret;
++}
++
+ /* Write the bit-pattern from software's buffer to hardware registers */
+ static int gfar_write_filer_table(struct gfar_private *priv,
+                                 struct filer_table *tab)
+@@ -1249,10 +1586,11 @@ static int gfar_write_filer_table(struct gfar_private *priv,
+               return -EBUSY;
+       /* Fill regular entries */
+-      for (; i < MAX_FILER_IDX && (tab->fe[i].ctrl | tab->fe[i].prop); i++)
++      for (; i < MAX_FILER_IDX - 1 && (tab->fe[i].ctrl | tab->fe[i].prop);
++           i++)
+               gfar_write_filer(priv, i, tab->fe[i].ctrl, tab->fe[i].prop);
+       /* Fill the rest with fall-troughs */
+-      for (; i < MAX_FILER_IDX; i++)
++      for (; i < MAX_FILER_IDX - 1; i++)
+               gfar_write_filer(priv, i, 0x60, 0xFFFFFFFF);
+       /* Last entry must be default accept
+        * because that's what people expect
+@@ -1286,6 +1624,7 @@ static int gfar_process_filer_changes(struct gfar_private *priv)
+ {
+       struct ethtool_flow_spec_container *j;
+       struct filer_table *tab;
++      s32 i = 0;
+       s32 ret = 0;
+       /* So index is set to zero, too! */
+@@ -1310,6 +1649,17 @@ static int gfar_process_filer_changes(struct gfar_private *priv)
+               }
+       }
++      i = tab->index;
++
++      /* Optimizations to save entries */
++      gfar_cluster_filer(tab);
++      gfar_optimize_filer_masks(tab);
++
++      pr_debug("\tSummary:\n"
++               "\tData on hardware: %d\n"
++               "\tCompression rate: %d%%\n",
++               tab->index, 100 - (100 * tab->index) / i);
++
+       /* Write everything to hardware */
+       ret = gfar_write_filer_table(priv, tab);
+       if (ret == -EBUSY) {
+@@ -1375,14 +1725,13 @@ static int gfar_add_cls(struct gfar_private *priv,
+       }
+ process:
+-      priv->rx_list.count++;
+       ret = gfar_process_filer_changes(priv);
+       if (ret)
+               goto clean_list;
++      priv->rx_list.count++;
+       return ret;
+ clean_list:
+-      priv->rx_list.count--;
+       list_del(&temp->list);
+ clean_mem:
+       kfree(temp);
+@@ -1535,6 +1884,8 @@ static int gfar_get_ts_info(struct net_device *dev,
+ }
+ const struct ethtool_ops gfar_ethtool_ops = {
++      .get_settings = gfar_gsettings,
++      .set_settings = gfar_ssettings,
+       .get_drvinfo = gfar_gdrvinfo,
+       .get_regs_len = gfar_reglen,
+       .get_regs = gfar_get_regs,
+@@ -1557,6 +1908,4 @@ const struct ethtool_ops gfar_ethtool_ops = {
+       .set_rxnfc = gfar_set_nfc,
+       .get_rxnfc = gfar_get_nfc,
+       .get_ts_info = gfar_get_ts_info,
+-      .get_link_ksettings = phy_ethtool_get_link_ksettings,
+-      .set_link_ksettings = phy_ethtool_set_link_ksettings,
+ };
+diff --git a/drivers/net/ethernet/freescale/gianfar_ptp.c b/drivers/net/ethernet/freescale/gianfar_ptp.c
+index 5779881..8e3cd77 100644
+--- a/drivers/net/ethernet/freescale/gianfar_ptp.c
++++ b/drivers/net/ethernet/freescale/gianfar_ptp.c
+@@ -422,6 +422,19 @@ static struct ptp_clock_info ptp_gianfar_caps = {
+       .enable         = ptp_gianfar_enable,
+ };
++/* OF device tree */
++
++static int get_of_u32(struct device_node *node, char *str, u32 *val)
++{
++      int plen;
++      const u32 *prop = of_get_property(node, str, &plen);
++
++      if (!prop || plen != sizeof(*prop))
++              return -1;
++      *val = *prop;
++      return 0;
++}
++
+ static int gianfar_ptp_probe(struct platform_device *dev)
+ {
+       struct device_node *node = dev->dev.of_node;
+@@ -439,28 +452,22 @@ static int gianfar_ptp_probe(struct platform_device *dev)
+       etsects->caps = ptp_gianfar_caps;
+-      if (of_property_read_u32(node, "fsl,cksel", &etsects->cksel))
++      if (get_of_u32(node, "fsl,cksel", &etsects->cksel))
+               etsects->cksel = DEFAULT_CKSEL;
+-      if (of_property_read_u32(node,
+-                               "fsl,tclk-period", &etsects->tclk_period) ||
+-          of_property_read_u32(node,
+-                               "fsl,tmr-prsc", &etsects->tmr_prsc) ||
+-          of_property_read_u32(node,
+-                               "fsl,tmr-add", &etsects->tmr_add) ||
+-          of_property_read_u32(node,
+-                               "fsl,tmr-fiper1", &etsects->tmr_fiper1) ||
+-          of_property_read_u32(node,
+-                               "fsl,tmr-fiper2", &etsects->tmr_fiper2) ||
+-          of_property_read_u32(node,
+-                               "fsl,max-adj", &etsects->caps.max_adj)) {
++      if (get_of_u32(node, "fsl,tclk-period", &etsects->tclk_period) ||
++          get_of_u32(node, "fsl,tmr-prsc", &etsects->tmr_prsc) ||
++          get_of_u32(node, "fsl,tmr-add", &etsects->tmr_add) ||
++          get_of_u32(node, "fsl,tmr-fiper1", &etsects->tmr_fiper1) ||
++          get_of_u32(node, "fsl,tmr-fiper2", &etsects->tmr_fiper2) ||
++          get_of_u32(node, "fsl,max-adj", &etsects->caps.max_adj)) {
+               pr_err("device tree node missing required elements\n");
+               goto no_node;
+       }
+       etsects->irq = platform_get_irq(dev, 0);
+-      if (etsects->irq < 0) {
++      if (etsects->irq == NO_IRQ) {
+               pr_err("irq not in device tree\n");
+               goto no_node;
+       }
+@@ -550,7 +557,6 @@ static const struct of_device_id match_table[] = {
+       { .compatible = "fsl,etsec-ptp" },
+       {},
+ };
+-MODULE_DEVICE_TABLE(of, match_table);
+ static struct platform_driver gianfar_ptp_driver = {
+       .driver = {
+diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c
+index f76d332..4dd40e0 100644
+--- a/drivers/net/ethernet/freescale/ucc_geth.c
++++ b/drivers/net/ethernet/freescale/ucc_geth.c
+@@ -40,10 +40,10 @@
+ #include <asm/uaccess.h>
+ #include <asm/irq.h>
+ #include <asm/io.h>
+-#include <soc/fsl/qe/immap_qe.h>
+-#include <soc/fsl/qe/qe.h>
+-#include <soc/fsl/qe/ucc.h>
+-#include <soc/fsl/qe/ucc_fast.h>
++#include <asm/immap_qe.h>
++#include <asm/qe.h>
++#include <asm/ucc.h>
++#include <asm/ucc_fast.h>
+ #include <asm/machdep.h>
+ #include "ucc_geth.h"
+@@ -1384,8 +1384,6 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
+               value = phy_read(tbiphy, ENET_TBI_MII_CR);
+               value &= ~0x1000;       /* Turn off autonegotiation */
+               phy_write(tbiphy, ENET_TBI_MII_CR, value);
+-
+-              put_device(&tbiphy->mdio.dev);
+       }
+       init_check_frame_length_mode(ug_info->lengthCheckRx, &ug_regs->maccfg2);
+@@ -1704,10 +1702,8 @@ static void uec_configure_serdes(struct net_device *dev)
+        * everything for us?  Resetting it takes the link down and requires
+        * several seconds for it to come back.
+        */
+-      if (phy_read(tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS) {
+-              put_device(&tbiphy->mdio.dev);
++      if (phy_read(tbiphy, ENET_TBI_MII_SR) & TBISR_LSTATUS)
+               return;
+-      }
+       /* Single clk mode, mii mode off(for serdes communication) */
+       phy_write(tbiphy, ENET_TBI_MII_ANA, TBIANA_SETTINGS);
+@@ -1715,8 +1711,6 @@ static void uec_configure_serdes(struct net_device *dev)
+       phy_write(tbiphy, ENET_TBI_MII_TBICON, TBICON_CLK_SELECT);
+       phy_write(tbiphy, ENET_TBI_MII_CR, TBICR_SETTINGS);
+-
+-      put_device(&tbiphy->mdio.dev);
+ }
+ /* Configure the PHY for dev.
+@@ -3756,7 +3750,7 @@ static int ucc_geth_probe(struct platform_device* ofdev)
+                       return -EINVAL;
+               }
+               if ((*prop < QE_CLK_NONE) || (*prop > QE_CLK24)) {
+-                      pr_err("invalid rx-clock property\n");
++                      pr_err("invalid rx-clock propperty\n");
+                       return -EINVAL;
+               }
+               ug_info->uf_info.rx_clock = *prop;
+@@ -3868,8 +3862,9 @@ static int ucc_geth_probe(struct platform_device* ofdev)
+       dev = alloc_etherdev(sizeof(*ugeth));
+       if (dev == NULL) {
+-              err = -ENOMEM;
+-              goto err_deregister_fixed_link;
++              of_node_put(ug_info->tbi_node);
++              of_node_put(ug_info->phy_node);
++              return -ENOMEM;
+       }
+       ugeth = netdev_priv(dev);
+@@ -3906,7 +3901,10 @@ static int ucc_geth_probe(struct platform_device* ofdev)
+               if (netif_msg_probe(ugeth))
+                       pr_err("%s: Cannot register net device, aborting\n",
+                              dev->name);
+-              goto err_free_netdev;
++              free_netdev(dev);
++              of_node_put(ug_info->tbi_node);
++              of_node_put(ug_info->phy_node);
++              return err;
+       }
+       mac_addr = of_get_mac_address(np);
+@@ -3919,29 +3917,16 @@ static int ucc_geth_probe(struct platform_device* ofdev)
+       ugeth->node = np;
+       return 0;
+-
+-err_free_netdev:
+-      free_netdev(dev);
+-err_deregister_fixed_link:
+-      if (of_phy_is_fixed_link(np))
+-              of_phy_deregister_fixed_link(np);
+-      of_node_put(ug_info->tbi_node);
+-      of_node_put(ug_info->phy_node);
+-
+-      return err;
+ }
+ static int ucc_geth_remove(struct platform_device* ofdev)
+ {
+       struct net_device *dev = platform_get_drvdata(ofdev);
+       struct ucc_geth_private *ugeth = netdev_priv(dev);
+-      struct device_node *np = ofdev->dev.of_node;
+       unregister_netdev(dev);
+       free_netdev(dev);
+       ucc_geth_memclean(ugeth);
+-      if (of_phy_is_fixed_link(np))
+-              of_phy_deregister_fixed_link(np);
+       of_node_put(ugeth->ug_info->tbi_node);
+       of_node_put(ugeth->ug_info->phy_node);
+diff --git a/drivers/net/ethernet/freescale/ucc_geth.h b/drivers/net/ethernet/freescale/ucc_geth.h
+index 5da19b4..75f3371 100644
+--- a/drivers/net/ethernet/freescale/ucc_geth.h
++++ b/drivers/net/ethernet/freescale/ucc_geth.h
+@@ -22,11 +22,11 @@
+ #include <linux/list.h>
+ #include <linux/if_ether.h>
+-#include <soc/fsl/qe/immap_qe.h>
+-#include <soc/fsl/qe/qe.h>
++#include <asm/immap_qe.h>
++#include <asm/qe.h>
+-#include <soc/fsl/qe/ucc.h>
+-#include <soc/fsl/qe/ucc_fast.h>
++#include <asm/ucc.h>
++#include <asm/ucc_fast.h>
+ #define DRV_DESC "QE UCC Gigabit Ethernet Controller"
+ #define DRV_NAME "ucc_geth"
+diff --git a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
+index 812a968..cc83350 100644
+--- a/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
++++ b/drivers/net/ethernet/freescale/ucc_geth_ethtool.c
+@@ -105,20 +105,23 @@ static const char rx_fw_stat_gstrings[][ETH_GSTRING_LEN] = {
+ #define UEC_RX_FW_STATS_LEN ARRAY_SIZE(rx_fw_stat_gstrings)
+ static int
+-uec_get_ksettings(struct net_device *netdev, struct ethtool_link_ksettings *cmd)
++uec_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ {
+       struct ucc_geth_private *ugeth = netdev_priv(netdev);
+       struct phy_device *phydev = ugeth->phydev;
++      struct ucc_geth_info *ug_info = ugeth->ug_info;
+       if (!phydev)
+               return -ENODEV;
+-      return phy_ethtool_ksettings_get(phydev, cmd);
++      ecmd->maxtxpkt = 1;
++      ecmd->maxrxpkt = ug_info->interruptcoalescingmaxvalue[0];
++
++      return phy_ethtool_gset(phydev, ecmd);
+ }
+ static int
+-uec_set_ksettings(struct net_device *netdev,
+-                const struct ethtool_link_ksettings *cmd)
++uec_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
+ {
+       struct ucc_geth_private *ugeth = netdev_priv(netdev);
+       struct phy_device *phydev = ugeth->phydev;
+@@ -126,7 +129,7 @@ uec_set_ksettings(struct net_device *netdev,
+       if (!phydev)
+               return -ENODEV;
+-      return phy_ethtool_ksettings_set(phydev, cmd);
++      return phy_ethtool_sset(phydev, ecmd);
+ }
+ static void
+@@ -348,6 +351,8 @@ uec_get_drvinfo(struct net_device *netdev,
+       strlcpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version));
+       strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+       strlcpy(drvinfo->bus_info, "QUICC ENGINE", sizeof(drvinfo->bus_info));
++      drvinfo->eedump_len = 0;
++      drvinfo->regdump_len = uec_get_regs_len(netdev);
+ }
+ #ifdef CONFIG_PM
+@@ -389,6 +394,8 @@ static int uec_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
+ #endif /* CONFIG_PM */
+ static const struct ethtool_ops uec_ethtool_ops = {
++      .get_settings           = uec_get_settings,
++      .set_settings           = uec_set_settings,
+       .get_drvinfo            = uec_get_drvinfo,
+       .get_regs_len           = uec_get_regs_len,
+       .get_regs               = uec_get_regs,
+@@ -406,8 +413,6 @@ static const struct ethtool_ops uec_ethtool_ops = {
+       .get_wol                = uec_get_wol,
+       .set_wol                = uec_set_wol,
+       .get_ts_info            = ethtool_op_get_ts_info,
+-      .get_link_ksettings     = uec_get_ksettings,
+-      .set_link_ksettings     = uec_set_ksettings,
+ };
+ void uec_set_ethtool_ops(struct net_device *netdev)
+diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c
+index e03b30c..7b8fe86 100644
+--- a/drivers/net/ethernet/freescale/xgmac_mdio.c
++++ b/drivers/net/ethernet/freescale/xgmac_mdio.c
+@@ -271,8 +271,11 @@ static int xgmac_mdio_probe(struct platform_device *pdev)
+               goto err_ioremap;
+       }
+-      priv->is_little_endian = of_property_read_bool(pdev->dev.of_node,
+-                                                     "little-endian");
++      if (of_get_property(pdev->dev.of_node,
++                          "little-endian", NULL))
++              priv->is_little_endian = true;
++      else
++              priv->is_little_endian = false;
+       ret = of_mdiobus_register(bus, np);
+       if (ret) {
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/gpu-viv_gcc6_indent_warning_error_fix.patch b/recipes-kernel/linux/linux-karo-4.9.11/gpu-viv_gcc6_indent_warning_error_fix.patch
new file mode 100755 (executable)
index 0000000..b48606c
--- /dev/null
@@ -0,0 +1,30 @@
+From 8d0142efbfcfe4e3998f748496ceba62890c47f0 Mon Sep 17 00:00:00 2001
+From: Lauren Post <lauren.post@nxp.com>
+Date: Wed, 13 Jul 2016 03:07:23 -0500
+Subject: [PATCH] gpu-viv:  Fix gcc 6.0 indent warning error in gc_hal_kernel_platform_imx6ql4.c
+
+Upstream-Status: Pending
+
+Signed-off-by: Lauren Post <lauren.post@nxp.com>
+---
+ .../linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c  | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c
+index e436ada..d98c2f8 100644
+--- a/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c
++++ b/drivers/mxc/gpu-viv/hal/os/linux/kernel/platform/freescale/gc_hal_kernel_platform_imx6q14.c
+@@ -475,8 +475,8 @@ gckPLATFORM_AdjustParam(
+     Args->gpu3DMinClock = initgpu3DMinClock;
+-  if(Args->physSize == 0)
+-    Args->physSize = 0x80000000;
++    if(Args->physSize == 0)
++        Args->physSize = 0x80000000;
+     return gcvSTATUS_OK;
+ }
+-- 
+1.9.1
+
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/reset-phy-minimal.patch b/recipes-kernel/linux/linux-karo-4.9.11/reset-phy-minimal.patch
new file mode 100644 (file)
index 0000000..8a35d74
--- /dev/null
@@ -0,0 +1,30 @@
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index 41a31f2..c062438 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -1875,6 +1875,8 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+       return ret;
+ }
++static int fec_reset_phy(struct platform_device *pdev);
++
+ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
+ {
+       struct fec_enet_private *fep = netdev_priv(ndev);
+@@ -1885,6 +1887,7 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
+                       ret = clk_prepare_enable(fep->clk_enet_out);
+                       if (ret)
+                               return ret;
++                      fec_reset_phy(fep->pdev);
+               }
+               if (fep->clk_ptp) {
+                       mutex_lock(&fep->ptp_clk_mutex);
+@@ -3367,6 +3370,8 @@ static int fec_reset_phy(struct platform_device *pdev)
+       gpio_set_value_cansleep(phy_reset, !active_high);
++      devm_gpio_free(&pdev->dev, phy_reset);
++
+       return 0;
+ }
+ #else /* CONFIG_OF */
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/reset_ethernet_phy_whenever_the_enet_out_clock_is_being_enabled.patch b/recipes-kernel/linux/linux-karo-4.9.11/reset_ethernet_phy_whenever_the_enet_out_clock_is_being_enabled.patch
new file mode 100644 (file)
index 0000000..d0233dd
--- /dev/null
@@ -0,0 +1,203 @@
+From fac8dc6a300ced21494cba76af18cb4197c699c6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Lothar=20Wa=C3=9Fmann?= <LW@KARO-electronics.de>
+Date: Tue, 10 Oct 2017 14:05:36 +0200
+Subject: [PATCH] net: fec: reset PHY whenever enet out clock has been
+ re-enabled
+
+---
+ drivers/net/ethernet/freescale/fec.h      |   5 ++
+ drivers/net/ethernet/freescale/fec_main.c | 124 +++++++++++++++++++-----------
+ 2 files changed, 82 insertions(+), 47 deletions(-)
+
+diff --git a/drivers/net/ethernet/freescale/fec.h b/drivers/net/ethernet/freescale/fec.h
+index 38c7b21e5d63..4c2de04fe0aa 100644
+--- a/drivers/net/ethernet/freescale/fec.h
++++ b/drivers/net/ethernet/freescale/fec.h
+@@ -523,6 +523,11 @@ struct fec_enet_private {
+       int     dev_id;
++      int     reset_gpio;
++      int     phy_reset_duration;
++      int     phy_post_delay;
++      int     reset_active_high;
++
+       /* Phylib and MDIO interface */
+       struct  mii_bus *mii_bus;
+       int     mii_timeout;
+diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
+index c1160ae22f94..3c2cff867704 100644
+--- a/drivers/net/ethernet/freescale/fec_main.c
++++ b/drivers/net/ethernet/freescale/fec_main.c
+@@ -1836,6 +1836,8 @@ static int fec_enet_mdio_write(struct mii_bus *bus, int mii_id, int regnum,
+       return ret;
+ }
++static void fec_reset_phy(struct fec_enet_private *fep);
++
+ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
+ {
+       struct fec_enet_private *fep = netdev_priv(ndev);
+@@ -1846,9 +1848,13 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
+               if (ret)
+                       return ret;
+-              ret = clk_prepare_enable(fep->clk_enet_out);
+-              if (ret)
+-                      goto failed_clk_enet_out;
++              if (fep->clk_enet_out) {
++                      ret = clk_prepare_enable(fep->clk_enet_out);
++                      if (ret)
++                              goto failed_clk_enet_out;
++
++                      fec_reset_phy(fep);
++              }
+               if (fep->clk_ptp) {
+                       mutex_lock(&fep->ptp_clk_mutex);
+@@ -3213,67 +3219,90 @@ static int fec_enet_init(struct net_device *ndev)
+ }
+ #ifdef CONFIG_OF
+-static int fec_reset_phy(struct platform_device *pdev)
++static void fec_reset_phy(struct fec_enet_private *fep)
+ {
+-      int err, phy_reset;
+-      bool active_high = false;
+-      int msec = 1, phy_post_delay = 0;
+-      struct device_node *np = pdev->dev.of_node;
++      if (!gpio_is_valid(fep->reset_gpio))
++              return;
+-      if (!np)
+-              return 0;
++      gpio_set_value_cansleep(fep->reset_gpio, fep->reset_active_high);
+-      err = of_property_read_u32(np, "phy-reset-duration", &msec);
+-      /* A sane reset duration should not be longer than 1s */
+-      if (!err && msec > 1000)
+-              msec = 1;
++      if (fep->phy_reset_duration > 20)
++              msleep(fep->phy_reset_duration);
++      else
++              usleep_range(fep->phy_reset_duration * 1000,
++                           fep->phy_reset_duration * 1000 + 1000);
+-      phy_reset = of_get_named_gpio(np, "phy-reset-gpios", 0);
+-      if (phy_reset == -EPROBE_DEFER)
+-              return phy_reset;
+-      else if (!gpio_is_valid(phy_reset))
+-              return 0;
++      gpio_set_value_cansleep(fep->reset_gpio, !fep->reset_active_high);
+-      err = of_property_read_u32(np, "phy-reset-post-delay", &phy_post_delay);
+-      /* valid reset duration should be less than 1s */
+-      if (!err && phy_post_delay > 1000)
+-              return -EINVAL;
++      if (!fep->phy_post_delay)
++              return;
++      if (fep->phy_post_delay > 20)
++              msleep(fep->phy_post_delay);
++      else
++              usleep_range(fep->phy_post_delay * 1000,
++                           fep->phy_post_delay * 1000 + 1000);
++}
++
++static int fec_get_reset_gpio(struct platform_device *pdev)
++{
++      int err;
++      struct device_node *np = pdev->dev.of_node;
++      struct net_device *ndev = platform_get_drvdata(pdev);
++      struct fec_enet_private *fep = netdev_priv(ndev);
+-      active_high = of_property_read_bool(np, "phy-reset-active-high");
++      /* Most DT files do not specify the correct polarity
++       * of the phy-reset GPIO.
++       * So use this special property to signal the actual
++       * signal polarity.
++       */
++      fep->reset_gpio = of_get_named_gpio(np, "phy-reset-gpios", 0);
++      if (fep->reset_gpio == -EPROBE_DEFER)
++              return -EPROBE_DEFER;
++      if (!gpio_is_valid(fep->reset_gpio))
++              return 0;
++
++      fep->reset_active_high = of_property_read_bool(np,
++                                                     "phy-reset-active-high");
+-      err = devm_gpio_request_one(&pdev->dev, phy_reset,
+-                      active_high ? GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
+-                      "phy-reset");
++      err = devm_gpio_request_one(&pdev->dev, fep->reset_gpio,
++                                  fep->reset_active_high ?
++                                  GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH,
++                                  "phy-reset");
+       if (err) {
+               dev_err(&pdev->dev, "failed to get phy-reset-gpios: %d\n", err);
+               return err;
+       }
+-      if (msec > 20)
+-              msleep(msec);
+-      else
+-              usleep_range(msec * 1000, msec * 1000 + 1000);
+-
+-      gpio_set_value_cansleep(phy_reset, !active_high);
+-
+-      if (!phy_post_delay)
+-              return 0;
++      err = of_property_read_u32(np, "phy-reset-duration",
++                                 &fep->phy_reset_duration);
++      /* A sane reset duration should not be longer than 1s */
++      if (err || fep->phy_reset_duration > 1000)
++              fep->phy_reset_duration = 1;
+-      if (phy_post_delay > 20)
+-              msleep(phy_post_delay);
+-      else
+-              usleep_range(phy_post_delay * 1000,
+-                           phy_post_delay * 1000 + 1000);
++      err = of_property_read_u32(np, "phy-reset-post-delay",
++                                 &fep->phy_post_delay);
++      /* valid post reset delay should be less than 1s */
++      if (err)
++              fep->phy_post_delay = 0;
++      else if (fep->phy_post_delay > 1000)
++              return -EINVAL;
+       return 0;
+ }
+ #else /* CONFIG_OF */
+-static int fec_reset_phy(struct platform_device *pdev)
++/* In case of platform probe, the reset has been done
++ * by machine code.
++ */
++static inline void fec_reset_phy(struct fec_enet_private *fep)
+ {
+-      /*
+-       * In case of platform probe, the reset has been done
+-       * by machine code.
+-       */
++}
++
++static int fec_get_reset_gpio(struct platform_device *pdev)
++{
++      struct net_device *ndev = platform_get_drvdata(pdev);
++      struct fec_enet_private *fep = netdev_priv(ndev);
++
++      fep->reset_gpio = -EINVAL;
+       return 0;
+ }
+ #endif /* CONFIG_OF */
+@@ -3455,9 +3484,10 @@ fec_probe(struct platform_device *pdev)
+       pm_runtime_set_active(&pdev->dev);
+       pm_runtime_enable(&pdev->dev);
+-      ret = fec_reset_phy(pdev);
++      ret = fec_get_reset_gpio(pdev);
+       if (ret)
+               goto failed_reset;
++      fec_reset_phy(fep);
+       if (fep->bufdesc_ex)
+               fec_ptp_init(pdev);
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/set-enet_ref_clk-to-50-mhz.patch b/recipes-kernel/linux/linux-karo-4.9.11/set-enet_ref_clk-to-50-mhz.patch
new file mode 100755 (executable)
index 0000000..088e9bb
--- /dev/null
@@ -0,0 +1,25 @@
+diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
+index f45de65..3845ab3 100644
+--- a/drivers/clk/imx/clk-imx6q.c
++++ b/drivers/clk/imx/clk-imx6q.c
+@@ -882,6 +882,20 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
+        /*Set enet_ref clock to 125M to supply for RGMII tx_clk */
+        clk_set_rate(clk[IMX6QDL_CLK_ENET_REF], 125000000);
++       np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-fec");
++       if (np) {
++               u32 clock_frequency;
++               int ret;
++
++               ret = of_property_read_u32(np, "ref-clock", &clock_frequency);
++               if (ret == 0) {
++                       printk("fec ref-clock: %d\n", clock_frequency);
++                       imx_clk_set_rate(clk[IMX6QDL_CLK_ENET_REF], clock_frequency);
++               }
++       }
++       // This clock may be needed very early on
++       imx_clk_prepare_enable(clk[IMX6QDL_CLK_ENET_REF]);
++
+ #ifdef CONFIG_MX6_VPU_352M
+        /*
+         * If VPU 352M is enabled, then PLL2_PDF2 need to be
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/tx6/defconfig b/recipes-kernel/linux/linux-karo-4.9.11/tx6/defconfig
new file mode 100644 (file)
index 0000000..68aeadb
--- /dev/null
@@ -0,0 +1,461 @@
+CONFIG_LOCALVERSION="-1.0.0"
+CONFIG_KERNEL_LZO=y
+CONFIG_SYSVIPC=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=18
+CONFIG_CGROUPS=y
+CONFIG_MEMCG=y
+CONFIG_MEMCG_SWAP=y
+CONFIG_BLK_CGROUP=y
+CONFIG_CGROUP_SCHED=y
+CONFIG_CFS_BANDWIDTH=y
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_CGROUP_PIDS=y
+CONFIG_CGROUP_FREEZER=y
+CONFIG_CPUSETS=y
+CONFIG_CGROUP_DEVICE=y
+CONFIG_CGROUP_CPUACCT=y
+CONFIG_CGROUP_PERF=y
+CONFIG_NAMESPACES=y
+CONFIG_RELAY=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_EXPERT=y
+CONFIG_KALLSYMS_ALL=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_SLUB_DEBUG is not set
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+CONFIG_MODULE_SRCVERSION_ALL=y
+CONFIG_BLK_DEV_BSGLIB=y
+CONFIG_BLK_DEV_INTEGRITY=y
+CONFIG_BLK_DEV_THROTTLING=y
+CONFIG_CFQ_GROUP_IOSCHED=y
+CONFIG_ARCH_MXC=y
+CONFIG_SOC_IMX50=y
+CONFIG_SOC_IMX53=y
+CONFIG_SOC_IMX6Q=y
+CONFIG_SOC_IMX6SL=y
+CONFIG_SOC_IMX6SX=y
+CONFIG_SOC_IMX6ULL=y
+CONFIG_SOC_IMX7D=y
+CONFIG_SOC_IMX6SLL=y
+CONFIG_SOC_VF610=y
+CONFIG_ARM_THUMBEE=y
+CONFIG_SMP=y
+CONFIG_VMSPLIT_2G=y
+CONFIG_PREEMPT=y
+CONFIG_AEABI=y
+CONFIG_HIGHMEM=y
+CONFIG_CMA=y
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0,115200"
+CONFIG_CPU_FREQ=y
+CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
+CONFIG_ARM_IMX6Q_CPUFREQ=y
+CONFIG_CPU_IDLE=y
+CONFIG_VFP=y
+CONFIG_NEON=y
+CONFIG_BINFMT_MISC=m
+CONFIG_PM_DEBUG=y
+CONFIG_PM_TEST_SUSPEND=y
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_PACKET_DIAG=m
+CONFIG_UNIX=y
+CONFIG_UNIX_DIAG=m
+CONFIG_XFRM_USER=y
+CONFIG_XFRM_SUB_POLICY=y
+CONFIG_XFRM_MIGRATE=y
+CONFIG_XFRM_STATISTICS=y
+CONFIG_INET=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_INET_AH=m
+CONFIG_INET_ESP=m
+CONFIG_INET_XFRM_MODE_TRANSPORT=m
+CONFIG_INET_XFRM_MODE_TUNNEL=m
+CONFIG_INET_XFRM_MODE_BEET=m
+CONFIG_NETFILTER=y
+CONFIG_BRIDGE_NETFILTER=y
+CONFIG_NF_CONNTRACK=y
+CONFIG_NF_CONNTRACK_FTP=m
+CONFIG_NF_CONNTRACK_IRC=m
+CONFIG_NF_CONNTRACK_SIP=m
+CONFIG_NF_CT_NETLINK=m
+CONFIG_NETFILTER_XT_MARK=m
+CONFIG_NETFILTER_XT_TARGET_LOG=m
+CONFIG_NETFILTER_XT_TARGET_NFLOG=m
+CONFIG_NETFILTER_XT_TARGET_TCPMSS=m
+CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=m
+CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
+CONFIG_NETFILTER_XT_MATCH_IPVS=m
+CONFIG_NETFILTER_XT_MATCH_POLICY=m
+CONFIG_NETFILTER_XT_MATCH_STATE=m
+CONFIG_IP_VS=m
+CONFIG_NF_CONNTRACK_IPV4=y
+CONFIG_NF_LOG_ARP=m
+CONFIG_NF_NAT_IPV4=y
+CONFIG_IP_NF_IPTABLES=m
+CONFIG_IP_NF_MATCH_AH=m
+CONFIG_IP_NF_MATCH_ECN=m
+CONFIG_IP_NF_MATCH_RPFILTER=m
+CONFIG_IP_NF_MATCH_TTL=m
+CONFIG_IP_NF_FILTER=m
+CONFIG_IP_NF_TARGET_REJECT=m
+CONFIG_IP_NF_NAT=m
+CONFIG_IP_NF_TARGET_MASQUERADE=m
+CONFIG_IP_NF_MANGLE=m
+CONFIG_NF_CONNTRACK_IPV6=m
+CONFIG_IP6_NF_IPTABLES=m
+CONFIG_IP6_NF_MATCH_AH=m
+CONFIG_IP6_NF_MATCH_EUI64=m
+CONFIG_IP6_NF_MATCH_FRAG=m
+CONFIG_IP6_NF_MATCH_OPTS=m
+CONFIG_IP6_NF_MATCH_HL=m
+CONFIG_IP6_NF_MATCH_IPV6HEADER=m
+CONFIG_IP6_NF_MATCH_RPFILTER=m
+CONFIG_IP6_NF_MATCH_RT=m
+CONFIG_IP6_NF_TARGET_HL=m
+CONFIG_IP6_NF_FILTER=m
+CONFIG_IP6_NF_TARGET_REJECT=m
+CONFIG_IP6_NF_MANGLE=m
+CONFIG_BRIDGE_NF_EBTABLES=m
+CONFIG_BRIDGE_EBT_BROUTE=m
+CONFIG_BRIDGE_EBT_T_FILTER=m
+CONFIG_BRIDGE_EBT_T_NAT=m
+CONFIG_BRIDGE_EBT_802_3=m
+CONFIG_BRIDGE_EBT_AMONG=m
+CONFIG_BRIDGE_EBT_ARP=m
+CONFIG_BRIDGE_EBT_IP=m
+CONFIG_BRIDGE_EBT_IP6=m
+CONFIG_BRIDGE_EBT_LIMIT=m
+CONFIG_BRIDGE_EBT_MARK=m
+CONFIG_BRIDGE_EBT_PKTTYPE=m
+CONFIG_BRIDGE_EBT_STP=m
+CONFIG_BRIDGE_EBT_VLAN=m
+CONFIG_BRIDGE_EBT_ARPREPLY=m
+CONFIG_BRIDGE_EBT_DNAT=m
+CONFIG_BRIDGE_EBT_MARK_T=m
+CONFIG_BRIDGE_EBT_REDIRECT=m
+CONFIG_BRIDGE_EBT_SNAT=m
+CONFIG_BRIDGE_EBT_LOG=m
+CONFIG_BRIDGE_EBT_NFLOG=m
+CONFIG_BRIDGE=y
+CONFIG_VLAN_8021Q=y
+CONFIG_LLC2=y
+CONFIG_NETLINK_DIAG=y
+CONFIG_CGROUP_NET_PRIO=y
+CONFIG_CGROUP_NET_CLASSID=y
+CONFIG_CAN=y
+CONFIG_CAN_FLEXCAN=y
+CONFIG_CAN_M_CAN=y
+CONFIG_BT=y
+CONFIG_BT_RFCOMM=y
+CONFIG_BT_RFCOMM_TTY=y
+CONFIG_BT_BNEP=y
+CONFIG_BT_BNEP_MC_FILTER=y
+CONFIG_BT_BNEP_PROTO_FILTER=y
+CONFIG_BT_HIDP=y
+CONFIG_BT_HCIBTUSB=y
+CONFIG_BT_HCIUART=y
+CONFIG_BT_HCIUART_BCSP=y
+CONFIG_BT_HCIUART_ATH3K=y
+CONFIG_BT_HCIBCM203X=y
+CONFIG_BT_ATH3K=y
+CONFIG_CFG80211=y
+CONFIG_MAC80211=y
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_DMA_CMA=y
+CONFIG_CMA_SIZE_MBYTES=0
+CONFIG_IMX_WEIM=y
+CONFIG_CONNECTOR=y
+CONFIG_MTD=y
+CONFIG_MTD_TESTS=m
+CONFIG_MTD_CMDLINE_PARTS=y
+CONFIG_MTD_BLOCK=y
+CONFIG_NFTL=y
+CONFIG_NFTL_RW=y
+CONFIG_MTD_NAND=y
+CONFIG_MTD_NAND_GPMI_NAND=y
+CONFIG_MTD_NAND_MXC=y
+CONFIG_MTD_UBI=y
+CONFIG_MTD_UBI_FASTMAP=y
+CONFIG_MTD_UBI_GLUEBI=y
+CONFIG_MTD_UBI_BLOCK=y
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_VIRTIO_BLK=y
+CONFIG_EEPROM_AT24=y
+CONFIG_EEPROM_AT25=y
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=y
+CONFIG_SCSI_CONSTANTS=y
+CONFIG_SCSI_LOGGING=y
+CONFIG_SCSI_SCAN_ASYNC=y
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_ATA=y
+CONFIG_SATA_AHCI_PLATFORM=y
+CONFIG_AHCI_IMX=y
+CONFIG_PATA_IMX=y
+CONFIG_NETDEVICES=y
+CONFIG_VXLAN=y
+CONFIG_TUN=m
+CONFIG_VETH=m
+CONFIG_VIRTIO_NET=m
+CONFIG_NLMON=m
+# CONFIG_NET_VENDOR_BROADCOM is not set
+CONFIG_CS89x0=y
+CONFIG_CS89x0_PLATFORM=y
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_MICROCHIP is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMC91X=y
+CONFIG_SMC911X=y
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_STMICRO is not set
+CONFIG_SMSC_PHY=y
+CONFIG_USB_PEGASUS=m
+CONFIG_USB_RTL8150=m
+CONFIG_USB_RTL8152=m
+CONFIG_USB_USBNET=m
+CONFIG_USB_NET_CDC_EEM=m
+# CONFIG_RTL_CARDS is not set
+CONFIG_INPUT_EVDEV=y
+CONFIG_INPUT_EVBUG=m
+CONFIG_KEYBOARD_GPIO=y
+CONFIG_KEYBOARD_IMX=y
+CONFIG_MOUSE_PS2=m
+CONFIG_MOUSE_PS2_ELANTECH=y
+CONFIG_INPUT_TOUCHSCREEN=y
+CONFIG_TOUCHSCREEN_EGALAX=y
+CONFIG_TOUCHSCREEN_IMX6UL_TSC=y
+CONFIG_TOUCHSCREEN_EDT_FT5X06=y
+CONFIG_TOUCHSCREEN_USB_COMPOSITE=y
+CONFIG_TOUCHSCREEN_TSC2007=y
+CONFIG_TOUCHSCREEN_STMPE=y
+CONFIG_INPUT_MISC=y
+CONFIG_INPUT_MMA8450=y
+CONFIG_SERIO_SERPORT=m
+# CONFIG_LEGACY_PTYS is not set
+CONFIG_SERIAL_IMX=y
+CONFIG_SERIAL_IMX_CONSOLE=y
+CONFIG_SERIAL_FSL_LPUART=y
+CONFIG_SERIAL_FSL_LPUART_CONSOLE=y
+# CONFIG_I2C_COMPAT is not set
+CONFIG_I2C_CHARDEV=y
+# CONFIG_I2C_HELPER_AUTO is not set
+CONFIG_I2C_ALGOPCF=m
+CONFIG_I2C_ALGOPCA=m
+CONFIG_I2C_IMX=y
+CONFIG_SPI=y
+CONFIG_SPI_GPIO=y
+CONFIG_SPI_IMX=y
+CONFIG_GPIO_SYSFS=y
+CONFIG_GPIO_MAX732X=y
+CONFIG_GPIO_PCA953X=y
+CONFIG_GPIO_74X164=y
+CONFIG_POWER_RESET=y
+CONFIG_POWER_RESET_SYSCON_POWEROFF=y
+CONFIG_POWER_SUPPLY=y
+CONFIG_THERMAL=y
+CONFIG_CPU_THERMAL=y
+CONFIG_IMX_THERMAL=y
+CONFIG_WATCHDOG=y
+CONFIG_IMX2_WDT=y
+CONFIG_MFD_DA9052_I2C=y
+CONFIG_MFD_MC13XXX_SPI=y
+CONFIG_MFD_MC13XXX_I2C=y
+CONFIG_MFD_SI476X_CORE=y
+CONFIG_MFD_STMPE=y
+CONFIG_REGULATOR=y
+CONFIG_REGULATOR_FIXED_VOLTAGE=y
+CONFIG_REGULATOR_ANATOP=y
+CONFIG_REGULATOR_DA9052=y
+CONFIG_REGULATOR_GPIO=y
+CONFIG_REGULATOR_MC13783=y
+CONFIG_REGULATOR_MC13892=y
+CONFIG_REGULATOR_PFUZE100=y
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_MEDIA_CAMERA_SUPPORT=y
+CONFIG_MEDIA_RADIO_SUPPORT=y
+CONFIG_MEDIA_USB_SUPPORT=y
+CONFIG_USB_VIDEO_CLASS=m
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_V4L_MEM2MEM_DRIVERS=y
+CONFIG_VIDEO_CODA=y
+CONFIG_RADIO_SI476X=y
+CONFIG_DRM=y
+CONFIG_DRM_VIVANTE=y
+CONFIG_DRM_PANEL_SIMPLE=y
+CONFIG_DRM_IMX=y
+CONFIG_DRM_IMX_PARALLEL_DISPLAY=y
+CONFIG_DRM_IMX_LDB=y
+CONFIG_FB_MXS=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+CONFIG_FB_MXC_OVERLAY=y
+CONFIG_FB_MXC_LDB=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_L4F00242T03=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_PWM=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+CONFIG_LOGO=y
+CONFIG_SOUND=y
+CONFIG_SND=y
+CONFIG_SND_USB_AUDIO=m
+CONFIG_SND_SOC=y
+CONFIG_SND_IMX_SOC=y
+CONFIG_SND_SOC_EUKREA_TLV320=y
+CONFIG_SND_SOC_IMX_WM8962=y
+CONFIG_SND_SOC_IMX_SGTL5000=y
+CONFIG_SND_SOC_IMX_SPDIF=y
+CONFIG_SND_SOC_IMX_MC13783=y
+CONFIG_HID_MULTITOUCH=y
+CONFIG_USB_OTG_WHITELIST=y
+CONFIG_USB_EHCI_HCD=y
+CONFIG_USB_EHCI_MXC=y
+CONFIG_USB_HCD_TEST_MODE=y
+CONFIG_USB_ACM=m
+CONFIG_USB_STORAGE=y
+CONFIG_USB_CHIPIDEA=y
+CONFIG_USB_CHIPIDEA_UDC=y
+CONFIG_USB_CHIPIDEA_HOST=y
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_GENERIC=y
+CONFIG_USB_SERIAL_FTDI_SIO=m
+CONFIG_USB_SERIAL_OPTION=m
+CONFIG_USB_EHSET_TEST_FIXTURE=y
+CONFIG_NOP_USB_XCEIV=y
+CONFIG_USB_MXS_PHY=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_CONFIGFS=m
+CONFIG_USB_CONFIGFS_SERIAL=y
+CONFIG_USB_CONFIGFS_ACM=y
+CONFIG_USB_CONFIGFS_OBEX=y
+CONFIG_USB_CONFIGFS_NCM=y
+CONFIG_USB_CONFIGFS_ECM=y
+CONFIG_USB_CONFIGFS_ECM_SUBSET=y
+CONFIG_USB_CONFIGFS_RNDIS=y
+CONFIG_USB_CONFIGFS_EEM=y
+CONFIG_USB_CONFIGFS_MASS_STORAGE=y
+CONFIG_USB_CONFIGFS_F_LB_SS=y
+CONFIG_USB_CONFIGFS_F_FS=y
+CONFIG_USB_ZERO=m
+CONFIG_USB_ETH=m
+CONFIG_USB_G_NCM=m
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_MASS_STORAGE=m
+CONFIG_USB_G_SERIAL=m
+CONFIG_MMC=y
+CONFIG_MMC_SDHCI=y
+CONFIG_MMC_SDHCI_PLTFM=y
+CONFIG_MMC_SDHCI_ESDHC_IMX=y
+CONFIG_MXC_IPU=y
+CONFIG_MXC_IPU_V3_PRE=y
+CONFIG_MXC_GPU_VIV=y
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+CONFIG_LEDS_GPIO=y
+CONFIG_LEDS_TRIGGERS=y
+CONFIG_LEDS_TRIGGER_TIMER=y
+CONFIG_LEDS_TRIGGER_ONESHOT=y
+CONFIG_LEDS_TRIGGER_HEARTBEAT=y
+CONFIG_LEDS_TRIGGER_BACKLIGHT=y
+CONFIG_LEDS_TRIGGER_GPIO=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+CONFIG_RTC_DRV_DS1307=y
+CONFIG_DMADEVICES=y
+CONFIG_IMX_SDMA=y
+CONFIG_MXS_DMA=y
+CONFIG_DMATEST=m
+CONFIG_STAGING=y
+CONFIG_STAGING_MEDIA=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_IIO=y
+CONFIG_IMX7D_ADC=y
+CONFIG_VF610_ADC=y
+CONFIG_PWM=y
+CONFIG_PWM_IMX=y
+CONFIG_EXT4_FS=y
+CONFIG_EXT4_FS_POSIX_ACL=y
+CONFIG_EXT4_FS_SECURITY=y
+CONFIG_BTRFS_FS=m
+CONFIG_BTRFS_FS_POSIX_ACL=y
+CONFIG_QUOTA=y
+CONFIG_QUOTA_NETLINK_INTERFACE=y
+# CONFIG_PRINT_QUOTA_WARNING is not set
+CONFIG_AUTOFS4_FS=y
+CONFIG_FUSE_FS=y
+CONFIG_OVERLAY_FS=y
+CONFIG_ISO9660_FS=m
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+CONFIG_UDF_FS=m
+CONFIG_MSDOS_FS=m
+CONFIG_VFAT_FS=y
+CONFIG_TMPFS=y
+CONFIG_UBIFS_FS=y
+CONFIG_UBIFS_FS_ADVANCED_COMPR=y
+CONFIG_CRAMFS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3_ACL=y
+CONFIG_NFS_V4=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_DEFAULT="cp437"
+CONFIG_NLS_CODEPAGE_437=y
+CONFIG_NLS_ASCII=y
+CONFIG_NLS_ISO8859_1=y
+CONFIG_NLS_ISO8859_15=m
+CONFIG_NLS_UTF8=y
+CONFIG_DEBUG_FS=y
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+# CONFIG_FTRACE is not set
+CONFIG_SECURITYFS=y
+CONFIG_CRYPTO_USER=y
+CONFIG_CRYPTO_TEST=m
+CONFIG_CRYPTO_CBC=y
+CONFIG_CRYPTO_CTS=y
+CONFIG_CRYPTO_LRW=y
+CONFIG_CRYPTO_XTS=y
+CONFIG_CRYPTO_MD4=y
+CONFIG_CRYPTO_MD5=y
+CONFIG_CRYPTO_MICHAEL_MIC=y
+CONFIG_CRYPTO_RMD128=y
+CONFIG_CRYPTO_RMD160=y
+CONFIG_CRYPTO_RMD256=y
+CONFIG_CRYPTO_RMD320=y
+CONFIG_CRYPTO_SHA1=y
+CONFIG_CRYPTO_SHA512=y
+CONFIG_CRYPTO_TGR192=y
+CONFIG_CRYPTO_WP512=y
+CONFIG_CRYPTO_BLOWFISH=y
+CONFIG_CRYPTO_CAMELLIA=y
+CONFIG_CRYPTO_TWOFISH=y
+CONFIG_CRYPTO_DEV_FSL_CAAM=y
+CONFIG_CRC_CCITT=m
+CONFIG_CRC_T10DIF=y
+CONFIG_CRC7=m
+CONFIG_LIBCRC32C=m
+CONFIG_FONTS=y
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/tx6/imx6qdl-tx6-gpio.h b/recipes-kernel/linux/linux-karo-4.9.11/tx6/imx6qdl-tx6-gpio.h
new file mode 100755 (executable)
index 0000000..2ee5c86
--- /dev/null
@@ -0,0 +1,338 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __DTS_TX6QDL_GPIO_H
+#define __DTS_TX6QDL_GPIO_H
+
+#define TX_GPIO_PIN15  &gpio7 12
+#define TX_GPIO_PIN27  &gpio3 31
+#define TX_GPIO_PIN28  &gpio3 30
+#define TX_GPIO_PIN33  &gpio3 23
+#define TX_GPIO_PIN34  &gpio1 7
+#define TX_GPIO_PIN36  &gpio1 8
+#define TX_GPIO_PIN40  &gpio1 6
+#define TX_GPIO_PIN41  &gpio1 3
+#define TX_GPIO_PIN42  &gpio1 1
+#define TX_GPIO_PIN43  &gpio7 13
+#define TX_GPIO_PIN44  &gpio2 30
+#define TX_GPIO_PIN45  &gpio3 19
+#define TX_GPIO_PIN46  &gpio3 18
+#define TX_GPIO_PIN47  &gpio3 17
+#define TX_GPIO_PIN48  &gpio3 16
+#define TX_GPIO_PIN49  &gpio4 5
+#define TX_GPIO_PIN51  &gpio7 2
+#define TX_GPIO_PIN52  &gpio1 16
+#define TX_GPIO_PIN53  &gpio1 17
+#define TX_GPIO_PIN54  &gpio1 19
+#define TX_GPIO_PIN55  &gpio1 21
+#define TX_GPIO_PIN56  &gpio1 18
+#define TX_GPIO_PIN57  &gpio1 20
+#define TX_GPIO_PIN59  &gpio6 17
+#define TX_GPIO_PIN60  &gpio6 18
+#define TX_GPIO_PIN61  &gpio7 5
+#define TX_GPIO_PIN62  &gpio7 4
+#define TX_GPIO_PIN63  &gpio2 15
+#define TX_GPIO_PIN64  &gpio2 12
+#define TX_GPIO_PIN65  &gpio2 13
+#define TX_GPIO_PIN66  &gpio2 14
+#define TX_GPIO_PIN67  &gpio3 24
+#define TX_GPIO_PIN68  &gpio3 25
+#define TX_GPIO_PIN69  &gpio7 8
+#define TX_GPIO_PIN70  &gpio7 7
+#define TX_GPIO_PIN72  &gpio1 9
+#define TX_GPIO_PIN73  &gpio1 4
+#define TX_GPIO_PIN74  &gpio4 10
+#define TX_GPIO_PIN75  &gpio4 12
+#define TX_GPIO_PIN76  &gpio4 14
+#define TX_GPIO_PIN77  &gpio1 2
+#define TX_GPIO_PIN78  &gpio1 5
+#define TX_GPIO_PIN79  &gpio4 11
+#define TX_GPIO_PIN80  &gpio4 13
+#define TX_GPIO_PIN81  &gpio4 15
+#define TX_GPIO_PIN83  &gpio3 26
+#define TX_GPIO_PIN84  &gpio4 9
+#define TX_GPIO_PIN85  &gpio4 7
+#define TX_GPIO_PIN86  &gpio4 6
+#define TX_GPIO_PIN87  &gpio4 8
+#define TX_GPIO_PIN89  &gpio3 27
+#define TX_GPIO_PIN90  &gpio5 25
+#define TX_GPIO_PIN91  &gpio5 23
+#define TX_GPIO_PIN92  &gpio5 22
+#define TX_GPIO_PIN93  &gpio5 24
+#define TX_GPIO_PIN95  &gpio7 3
+#define TX_GPIO_PIN96  &gpio1 15
+#define TX_GPIO_PIN97  &gpio1 14
+#define TX_GPIO_PIN98  &gpio1 13
+#define TX_GPIO_PIN99  &gpio1 12
+#define TX_GPIO_PIN100 &gpio1 11
+#define TX_GPIO_PIN101 &gpio1 10
+#define TX_GPIO_PIN103 &gpio5 30
+#define TX_GPIO_PIN104 &gpio5 31
+#define TX_GPIO_PIN105 &gpio6 0
+#define TX_GPIO_PIN106 &gpio6 1
+#define TX_GPIO_PIN107 &gpio6 2
+#define TX_GPIO_PIN108 &gpio6 3
+#define TX_GPIO_PIN109 &gpio6 4
+#define TX_GPIO_PIN110 &gpio6 5
+#define TX_GPIO_PIN112 &gpio5 19
+#define TX_GPIO_PIN113 &gpio5 21
+#define TX_GPIO_PIN114 &gpio5 18
+#define TX_GPIO_PIN115 &gpio1 0
+#define TX_GPIO_PIN117 &gpio4 21
+#define TX_GPIO_PIN118 &gpio4 22
+#define TX_GPIO_PIN119 &gpio4 23
+#define TX_GPIO_PIN120 &gpio4 24
+#define TX_GPIO_PIN121 &gpio4 25
+#define TX_GPIO_PIN122 &gpio4 26
+#define TX_GPIO_PIN123 &gpio4 27
+#define TX_GPIO_PIN124 &gpio4 28
+#define TX_GPIO_PIN125 &gpio4 29
+#define TX_GPIO_PIN126 &gpio4 30
+#define TX_GPIO_PIN127 &gpio4 31
+#define TX_GPIO_PIN128 &gpio5 5
+#define TX_GPIO_PIN130 &gpio5 6
+#define TX_GPIO_PIN131 &gpio5 7
+#define TX_GPIO_PIN132 &gpio5 8
+#define TX_GPIO_PIN133 &gpio5 9
+#define TX_GPIO_PIN134 &gpio5 10
+#define TX_GPIO_PIN135 &gpio5 11
+#define TX_GPIO_PIN136 &gpio5 12
+#define TX_GPIO_PIN137 &gpio5 13
+#define TX_GPIO_PIN138 &gpio5 14
+#define TX_GPIO_PIN139 &gpio5 15
+#define TX_GPIO_PIN140 &gpio5 16
+#define TX_GPIO_PIN141 &gpio5 17
+#define TX_GPIO_PIN143 &gpio4 18
+#define TX_GPIO_PIN144 &gpio4 19
+#define TX_GPIO_PIN145 &gpio4 17
+#define TX_GPIO_PIN146 &gpio4 16
+#define TX_GPIO_PIN148 &gpio6 15
+#define TX_GPIO_PIN149 &gpio2 22
+#define TX_GPIO_PIN150 &gpio3 29
+#define TX_GPIO_PIN151 &gpio2 31
+#define TX_GPIO_PIN152 &gpio2 21
+#define TX_GPIO_PIN153 &gpio2 20
+#define TX_GPIO_PIN154 &gpio2 19
+#define TX_GPIO_PIN155 &gpio2 18
+#define TX_GPIO_PIN156 &gpio2 17
+#define TX_GPIO_PIN157 &gpio2 16
+#define TX_GPIO_PIN158 &gpio6 6
+#define TX_GPIO_PIN159 &gpio5 4
+#define TX_GPIO_PIN161 &gpio5 26
+#define TX_GPIO_PIN162 &gpio5 27
+#define TX_GPIO_PIN163 &gpio5 28
+#define TX_GPIO_PIN164 &gpio5 29
+#define TX_GPIO_PIN165 &gpio3 22
+#define TX_GPIO_PIN173 &gpio2 23
+#define TX_GPIO_PIN174 &gpio2 24
+#define TX_GPIO_PIN175 &gpio5 20
+#define TX_GPIO_PIN176 &gpio5 0
+#define TX_GPIO_PIN177 &gpio2 28
+#define TX_GPIO_PIN178 &gpio2 29
+#define TX_GPIO_PIN179 &gpio2 25
+#define TX_GPIO_PIN180 &gpio2 27
+#define TX_GPIO_PIN181 &gpio2 26
+#define TX_GPIO_PIN182 &gpio6 31
+#define TX_GPIO_PIN184 &gpio3 0
+#define TX_GPIO_PIN185 &gpio3 1
+#define TX_GPIO_PIN186 &gpio3 2
+#define TX_GPIO_PIN187 &gpio3 3
+#define TX_GPIO_PIN188 &gpio3 4
+#define TX_GPIO_PIN189 &gpio3 5
+#define TX_GPIO_PIN190 &gpio3 6
+#define TX_GPIO_PIN191 &gpio3 7
+#define TX_GPIO_PIN192 &gpio3 8
+#define TX_GPIO_PIN193 &gpio3 9
+#define TX_GPIO_PIN194 &gpio3 10
+#define TX_GPIO_PIN195 &gpio3 11
+#define TX_GPIO_PIN196 &gpio3 12
+#define TX_GPIO_PIN197 &gpio3 13
+#define TX_GPIO_PIN198 &gpio3 14
+#define TX_GPIO_PIN199 &gpio3 15
+
+#define TX_GPIO_PAD15  MX6QDL_PAD_GPIO_17__GPIO7_IO12          0x1b0b0
+#define TX_GPIO_PAD27  MX6QDL_PAD_EIM_D31__GPIO3_IO31          0x1b0b0
+#define TX_GPIO_PAD28  MX6QDL_PAD_EIM_D30__GPIO3_IO30          0x1b0b0
+#define TX_GPIO_PAD33  MX6QDL_PAD_EIM_D23__GPIO3_IO23          0x1b0b0
+#define TX_GPIO_PAD34  MX6QDL_PAD_GPIO_7__GPIO1_IO07           0x1b0b0
+#define TX_GPIO_PAD36  MX6QDL_PAD_GPIO_8__GPIO1_IO08           0x1b0b0
+#define TX_GPIO_PAD40  MX6QDL_PAD_GPIO_6__GPIO1_IO06           0x1b0b0
+#define TX_GPIO_PAD41  MX6QDL_PAD_GPIO_3__GPIO1_IO03           0x1b0b0
+#define TX_GPIO_PAD42  MX6QDL_PAD_GPIO_1__GPIO1_IO01           0x1b0b0
+#define TX_GPIO_PAD43  MX6QDL_PAD_GPIO_18__GPIO7_IO13          0x1b0b0
+#define TX_GPIO_PAD44  MX6QDL_PAD_EIM_EB2__GPIO2_IO30          0x1b0b0
+#define TX_GPIO_PAD45  MX6QDL_PAD_EIM_D19__GPIO3_IO19          0x1b0b0
+#define TX_GPIO_PAD46  MX6QDL_PAD_EIM_D18__GPIO3_IO18          0x1b0b0
+#define TX_GPIO_PAD47  MX6QDL_PAD_EIM_D17__GPIO3_IO17          0x1b0b0
+#define TX_GPIO_PAD48  MX6QDL_PAD_EIM_D16__GPIO3_IO16          0x1b0b0
+#define TX_GPIO_PAD49  MX6QDL_PAD_GPIO_19__GPIO4_IO05          0x1b0b0
+#define TX_GPIO_PAD51  MX6QDL_PAD_SD3_CMD__GPIO7_IO02          0x1b0b0
+#define TX_GPIO_PAD52  MX6QDL_PAD_SD1_DAT0__GPIO1_IO16         0x1b0b0
+#define TX_GPIO_PAD53  MX6QDL_PAD_SD1_DAT1__GPIO1_IO17         0x1b0b0
+#define TX_GPIO_PAD54  MX6QDL_PAD_SD1_DAT2__GPIO1_IO19         0x1b0b0
+#define TX_GPIO_PAD55  MX6QDL_PAD_SD1_DAT3__GPIO1_IO21         0x1b0b0
+#define TX_GPIO_PAD56  MX6QDL_PAD_SD1_CMD__GPIO1_IO18          0x1b0b0
+#define TX_GPIO_PAD57  MX6QDL_PAD_SD1_CLK__GPIO1_IO20          0x1b0b0
+#define TX_GPIO_PAD59  MX6QDL_PAD_SD3_DAT7__GPIO6_IO17         0x1b0b0
+#define TX_GPIO_PAD60  MX6QDL_PAD_SD3_DAT6__GPIO6_IO18         0x1b0b0
+#define TX_GPIO_PAD61  MX6QDL_PAD_SD3_DAT1__GPIO7_IO05         0x1b0b0
+#define TX_GPIO_PAD62  MX6QDL_PAD_SD3_DAT0__GPIO7_IO04         0x1b0b0
+#define TX_GPIO_PAD63  MX6QDL_PAD_SD4_DAT7__GPIO2_IO15         0x1b0b0
+#define TX_GPIO_PAD64  MX6QDL_PAD_SD4_DAT4__GPIO2_IO12         0x1b0b0
+#define TX_GPIO_PAD65  MX6QDL_PAD_SD4_DAT5__GPIO2_IO13         0x1b0b0
+#define TX_GPIO_PAD66  MX6QDL_PAD_SD4_DAT6__GPIO2_IO14         0x1b0b0
+#define TX_GPIO_PAD67  MX6QDL_PAD_EIM_D24__GPIO3_IO24          0x1b0b0
+#define TX_GPIO_PAD68  MX6QDL_PAD_EIM_D25__GPIO3_IO25          0x1b0b0
+#define TX_GPIO_PAD69  MX6QDL_PAD_SD3_RST__GPIO7_IO08          0x1b0b0
+#define TX_GPIO_PAD70  MX6QDL_PAD_SD3_DAT3__GPIO7_IO07         0x1b0b0
+#define TX_GPIO_PAD72  MX6QDL_PAD_GPIO_9__GPIO1_IO09           0x1b0b0
+#define TX_GPIO_PAD73  MX6QDL_PAD_GPIO_4__GPIO1_IO04           0x1b0b0
+#define TX_GPIO_PAD74  MX6QDL_PAD_KEY_COL2__GPIO4_IO10         0x1b0b0
+#define TX_GPIO_PAD75  MX6QDL_PAD_KEY_COL3__GPIO4_IO12         0x1b0b0
+#define TX_GPIO_PAD76  MX6QDL_PAD_KEY_COL4__GPIO4_IO14         0x1b0b0
+#define TX_GPIO_PAD77  MX6QDL_PAD_GPIO_2__GPIO1_IO02           0x1b0b0
+#define TX_GPIO_PAD78  MX6QDL_PAD_GPIO_5__GPIO1_IO05           0x1b0b0
+#define TX_GPIO_PAD79  MX6QDL_PAD_KEY_ROW2__GPIO4_IO11         0x1b0b0
+#define TX_GPIO_PAD80  MX6QDL_PAD_KEY_ROW3__GPIO4_IO13         0x1b0b0
+#define TX_GPIO_PAD81  MX6QDL_PAD_KEY_ROW4__GPIO4_IO15         0x1b0b0
+#define TX_GPIO_PAD83  MX6QDL_PAD_EIM_D26__GPIO3_IO26          0x1b0b0
+#define TX_GPIO_PAD84  MX6QDL_PAD_KEY_ROW1 __GPIO4_IO09        0x1b0b0
+#define TX_GPIO_PAD85  MX6QDL_PAD_KEY_ROW0__GPIO4_IO07         0x1b0b0
+#define TX_GPIO_PAD86  MX6QDL_PAD_KEY_COL0__GPIO4_IO06         0x1b0b0
+#define TX_GPIO_PAD87  MX6QDL_PAD_KEY_COL1__GPIO4_IO08         0x1b0b0
+#define TX_GPIO_PAD89  MX6QDL_PAD_EIM_D27__GPIO3_IO27          0x1b0b0
+#define TX_GPIO_PAD90  MX6QDL_PAD_CSI0_DAT7__GPIO5_IO25        0x1b0b0
+#define TX_GPIO_PAD91  MX6QDL_PAD_CSI0_DAT5 __GPIO5_IO23       0x1b0b0
+#define TX_GPIO_PAD92  MX6QDL_PAD_CSI0_DAT4__GPIO5_IO22        0x1b0b0
+#define TX_GPIO_PAD93  MX6QDL_PAD_CSI0_DAT6 __GPIO5_IO24       0x1b0b0
+#define TX_GPIO_PAD95  MX6QDL_PAD_SD3_CLK__GPIO7_IO03          0x1b0b0
+#define TX_GPIO_PAD96  MX6QDL_PAD_SD2_DAT0__GPIO1_IO15         0x1b0b0
+#define TX_GPIO_PAD97  MX6QDL_PAD_SD2_DAT1__GPIO1_IO14         0x1b0b0
+#define TX_GPIO_PAD98  MX6QDL_PAD_SD2_DAT2__GPIO1_IO13         0x1b0b0
+#define TX_GPIO_PAD99  MX6QDL_PAD_SD2_DAT3__GPIO1_IO12         0x1b0b0
+#define TX_GPIO_PAD100 MX6QDL_PAD_SD2_CMD__GPIO1_IO11          0x1b0b0
+#define TX_GPIO_PAD101 MX6QDL_PAD_SD2_CLK__GPIO1_IO10          0x1b0b0
+#define TX_GPIO_PAD103 MX6QDL_PAD_CSI0_DAT12__GPIO5_IO30       0x1b0b0
+#define TX_GPIO_PAD104 MX6QDL_PAD_CSI0_DAT13__GPIO5_IO31       0x1b0b0
+#define TX_GPIO_PAD105 MX6QDL_PAD_CSI0_DAT14__GPIO6_IO00       0x1b0b0
+#define TX_GPIO_PAD106 MX6QDL_PAD_CSI0_DAT15__GPIO6_IO01       0x1b0b0
+#define TX_GPIO_PAD107 MX6QDL_PAD_CSI0_DAT16__GPIO6_IO02       0x1b0b0
+#define TX_GPIO_PAD108 MX6QDL_PAD_CSI0_DAT17__GPIO6_IO03       0x1b0b0
+#define TX_GPIO_PAD109 MX6QDL_PAD_CSI0_DAT18__GPIO6_IO04       0x1b0b0
+#define TX_GPIO_PAD110 MX6QDL_PAD_CSI0_DAT19__GPIO6_IO05       0x1b0b0
+#define TX_GPIO_PAD112 MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19        0x1b0b0
+#define TX_GPIO_PAD113 MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21       0x1b0b0
+#define TX_GPIO_PAD114 MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18      0x1b0b0
+#define TX_GPIO_PAD115 MX6QDL_PAD_GPIO_0__GPIO1_IO00           0x1b0b0
+#define TX_GPIO_PAD117 MX6QDL_PAD_DISP0_DAT0__GPIO4_IO21       0x1b0b0
+#define TX_GPIO_PAD118 MX6QDL_PAD_DISP0_DAT1__GPIO4_IO22       0x1b0b0
+#define TX_GPIO_PAD119 MX6QDL_PAD_DISP0_DAT2__GPIO4_IO23       0x1b0b0
+#define TX_GPIO_PAD120 MX6QDL_PAD_DISP0_DAT3__GPIO4_IO24       0x1b0b0
+#define TX_GPIO_PAD121 MX6QDL_PAD_DISP0_DAT4__GPIO4_IO25       0x1b0b0
+#define TX_GPIO_PAD122 MX6QDL_PAD_DISP0_DAT5__GPIO4_IO26       0x1b0b0
+#define TX_GPIO_PAD123 MX6QDL_PAD_DISP0_DAT6__GPIO4_IO27       0x1b0b0
+#define TX_GPIO_PAD124 MX6QDL_PAD_DISP0_DAT7__GPIO4_IO28       0x1b0b0
+#define TX_GPIO_PAD125 MX6QDL_PAD_DISP0_DAT8__GPIO4_IO29       0x1b0b0
+#define TX_GPIO_PAD126 MX6QDL_PAD_DISP0_DAT9__GPIO4_IO30       0x1b0b0
+#define TX_GPIO_PAD127 MX6QDL_PAD_DISP0_DAT10__GPIO4_IO31      0x1b0b0
+#define TX_GPIO_PAD128 MX6QDL_PAD_DISP0_DAT11__GPIO5_IO05      0x1b0b0
+#define TX_GPIO_PAD130 MX6QDL_PAD_DISP0_DAT12__GPIO5_IO06      0x1b0b0
+#define TX_GPIO_PAD131 MX6QDL_PAD_DISP0_DAT13__GPIO5_IO07      0x1b0b0
+#define TX_GPIO_PAD132 MX6QDL_PAD_DISP0_DAT14__GPIO5_IO08      0x1b0b0
+#define TX_GPIO_PAD133 MX6QDL_PAD_DISP0_DAT15__GPIO5_IO09      0x1b0b0
+#define TX_GPIO_PAD134 MX6QDL_PAD_DISP0_DAT16__GPIO5_IO10      0x1b0b0
+#define TX_GPIO_PAD135 MX6QDL_PAD_DISP0_DAT17__GPIO5_IO11      0x1b0b0
+#define TX_GPIO_PAD136 MX6QDL_PAD_DISP0_DAT18__GPIO5_IO12      0x1b0b0
+#define TX_GPIO_PAD137 MX6QDL_PAD_DISP0_DAT19__GPIO5_IO13      0x1b0b0
+#define TX_GPIO_PAD138 MX6QDL_PAD_DISP0_DAT20__GPIO5_IO14      0x1b0b0
+#define TX_GPIO_PAD139 MX6QDL_PAD_DISP0_DAT21__GPIO5_IO15      0x1b0b0
+#define TX_GPIO_PAD140 MX6QDL_PAD_DISP0_DAT22__GPIO5_IO16      0x1b0b0
+#define TX_GPIO_PAD141 MX6QDL_PAD_DISP0_DAT23__GPIO5_IO17      0x1b0b0
+#define TX_GPIO_PAD143 MX6QDL_PAD_DI0_PIN2__GPIO4_IO18         0x1b0b0
+#define TX_GPIO_PAD144 MX6QDL_PAD_DI0_PIN3__GPIO4_IO19         0x1b0b0
+#define TX_GPIO_PAD145 MX6QDL_PAD_DI0_PIN15__GPIO4_IO17        0x1b0b0
+#define TX_GPIO_PAD146 MX6QDL_PAD_DI0_DISP_CLK__GPIO4_IO16     0x1b0b0
+#define TX_GPIO_PAD148 MX6QDL_PAD_NANDF_CS2__GPIO6_IO15        0x1b0b0
+#define TX_GPIO_PAD149 MX6QDL_PAD_EIM_A16__GPIO2_IO22          0x1b0b0
+#define TX_GPIO_PAD150 MX6QDL_PAD_EIM_D29__GPIO3_IO29          0x1b0b0
+#define TX_GPIO_PAD151 MX6QDL_PAD_EIM_EB3__GPIO2_IO31          0x1b0b0
+#define TX_GPIO_PAD152 MX6QDL_PAD_EIM_A17__GPIO2_IO21          0x1b0b0
+#define TX_GPIO_PAD153 MX6QDL_PAD_EIM_A18__GPIO2_IO20          0x1b0b0
+#define TX_GPIO_PAD154 MX6QDL_PAD_EIM_A19__GPIO2_IO19          0x1b0b0
+#define TX_GPIO_PAD155 MX6QDL_PAD_EIM_A20__GPIO2_IO18          0x1b0b0
+#define TX_GPIO_PAD156 MX6QDL_PAD_EIM_A21__GPIO2_IO17          0x1b0b0
+#define TX_GPIO_PAD157 MX6QDL_PAD_EIM_A22__GPIO2_IO16          0x1b0b0
+#define TX_GPIO_PAD158 MX6QDL_PAD_EIM_A23__GPIO6_IO06          0x1b0b0
+#define TX_GPIO_PAD159 MX6QDL_PAD_EIM_A24__GPIO5_IO04          0x1b0b0
+#define TX_GPIO_PAD161 MX6QDL_PAD_CSI0_DAT8__GPIO5_IO26        0x1b0b0
+#define TX_GPIO_PAD162 MX6QDL_PAD_CSI0_DAT9 __GPIO5_IO27       0x1b0b0
+#define TX_GPIO_PAD163 MX6QDL_PAD_CSI0_DAT10__GPIO5_IO28       0x1b0b0
+#define TX_GPIO_PAD164 MX6QDL_PAD_CSI0_DAT11__GPIO5_IO29       0x1b0b0
+#define TX_GPIO_PAD165 MX6QDL_PAD_EIM_D22__GPIO3_IO22          0x1b0b0
+#define TX_GPIO_PAD173 MX6QDL_PAD_EIM_CS0__GPIO2_IO23          0x1b0b0
+#define TX_GPIO_PAD174 MX6QDL_PAD_EIM_CS1__GPIO2_IO24          0x1b0b0
+#define TX_GPIO_PAD175 MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20     0x1b0b0
+#define TX_GPIO_PAD176 MX6QDL_PAD_EIM_WAIT__GPIO5_IO00         0x1b0b0
+#define TX_GPIO_PAD177 MX6QDL_PAD_EIM_EB0__GPIO2_IO28          0x1b0b0
+#define TX_GPIO_PAD178 MX6QDL_PAD_EIM_EB1__GPIO2_IO29          0x1b0b0
+#define TX_GPIO_PAD179 MX6QDL_PAD_EIM_OE__GPIO2_IO25           0x1b0b0
+#define TX_GPIO_PAD180 MX6QDL_PAD_EIM_LBA__GPIO2_IO27          0x1b0b0
+#define TX_GPIO_PAD181 MX6QDL_PAD_EIM_RW__GPIO2_IO26           0x1b0b0
+#define TX_GPIO_PAD182 MX6QDL_PAD_EIM_BCLK__GPIO6_IO31         0x1b0b0
+#define TX_GPIO_PAD184 MX6QDL_PAD_EIM_DA0__GPIO3_IO00          0x1b0b0
+#define TX_GPIO_PAD185 MX6QDL_PAD_EIM_DA1__GPIO3_IO01          0x1b0b0
+#define TX_GPIO_PAD186 MX6QDL_PAD_EIM_DA2__GPIO3_IO02          0x1b0b0
+#define TX_GPIO_PAD187 MX6QDL_PAD_EIM_DA3__GPIO3_IO03          0x1b0b0
+#define TX_GPIO_PAD188 MX6QDL_PAD_EIM_DA4__GPIO3_IO04          0x1b0b0
+#define TX_GPIO_PAD189 MX6QDL_PAD_EIM_DA5__GPIO3_IO05          0x1b0b0
+#define TX_GPIO_PAD190 MX6QDL_PAD_EIM_DA6__GPIO3_IO06          0x1b0b0
+#define TX_GPIO_PAD191 MX6QDL_PAD_EIM_DA7__GPIO3_IO07          0x1b0b0
+#define TX_GPIO_PAD192 MX6QDL_PAD_EIM_DA8__GPIO3_IO08          0x1b0b0
+#define TX_GPIO_PAD193 MX6QDL_PAD_EIM_DA9__GPIO3_IO09          0x1b0b0
+#define TX_GPIO_PAD194 MX6QDL_PAD_EIM_DA10__GPIO3_IO10         0x1b0b0
+#define TX_GPIO_PAD195 MX6QDL_PAD_EIM_DA11__GPIO3_IO11         0x1b0b0
+#define TX_GPIO_PAD196 MX6QDL_PAD_EIM_DA12__GPIO3_IO12         0x1b0b0
+#define TX_GPIO_PAD197 MX6QDL_PAD_EIM_DA13__GPIO3_IO13         0x1b0b0
+#define TX_GPIO_PAD198 MX6QDL_PAD_EIM_DA14__GPIO3_IO14         0x1b0b0
+#define TX_GPIO_PAD199 MX6QDL_PAD_EIM_DA15__GPIO3_IO15         0x1b0b0
+
+#endif /* __DTS_TX6QDL_GPIO_H */
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/tx6/imx6qdl-tx6.dtsi b/recipes-kernel/linux/linux-karo-4.9.11/tx6/imx6qdl-tx6.dtsi
new file mode 100755 (executable)
index 0000000..6f61150
--- /dev/null
@@ -0,0 +1,647 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+#include <dt-bindings/gpio/gpio.h>
+#include <dt-bindings/gpio/imx6qdl-tx6-gpio.h>
+#include <dt-bindings/input/input.h>
+#include <dt-bindings/pwm/pwm.h>
+
+/*
+ * Definitions for simpler referencing of TX's standard nodes
+ */
+
+/* On-board NVMe */
+#define TX_EMMC                &usdhc4
+#define TX_NAND                &gpmi
+/* bus connectors */
+#define TX_I2C         &i2c3
+#define TX_CAN1                &can2
+#define TX_CAN2                &can1
+/* video & display */
+#define TX_LCD         &lcd
+#define TX_LCD_FB      &mxcfb0
+#define TX_LDB         &ldb
+#define TX_LDB_FB1     &mxcfb1
+#define TX_LDB_FB2     &mxcfb2
+#define TX_PWM         &pwm2
+#define TX_PWM1                &pwm2   /* First  (1st) PWM used (TX's default) */
+#define TX_PWM2                &pwm1   /* Second (2nd) PWM used */
+/* NVM */
+#define TX_SD1         &usdhc1
+#define TX_SD2         &usdhc2
+#define TX_SPI         &ecspi1
+#define TX_SSI1                &audmux
+#define TX_SSI_PIN     &pinctrl_ssi1
+/* UART */
+#define TX_UART1       &uart1
+#define TX_UART2       &uart2
+#define TX_UART3       &uart3
+/* USB */
+#define TX_USBH                &usbh1
+#define TX_USBOTG      &usbotg
+
+/ {
+       aliases {
+               can0 = &can2;
+               can1 = &can1;
+               emmc = &usdhc4;
+               ethernet0 = &fec;
+               sdhc0 = &usdhc1;
+               sdhc1 = &usdhc2;
+               usbh = &usbh1;
+               usbotg = &usbotg;
+       };
+
+       memory {
+               reg = <0 0>; /* will be filled by U-Boot */
+       };
+
+       /* override imx6dl.dtsi gpu clock definition bug */
+
+       clocks {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               mclk: clock {
+                       compatible = "fixed-clock";
+                       #clock-cells = <0>;
+                       clock-frequency = <26000000>;
+               };
+       };
+
+       chosen {
+               stdout-path = TX_UART1;
+       };
+
+       regulators {
+               compatible = "simple-bus";
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               reg_3v3_etn: regulator-3v3etn {
+                       compatible = "regulator-fixed";
+                       regulator-name = "3V3_ETN";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_etnphy_power>;
+                       gpio = <&gpio3 20 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+               };
+
+               reg_usbh1_vbus: regulator-usbh1vbus {
+                       compatible = "regulator-fixed";
+                       regulator-name = "usbh1_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usbh1_vbus>;
+                       gpio = <TX_GPIO_PIN27 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+               };
+
+               reg_usbotg_vbus: regulator-usbotgvbus {
+                       compatible = "regulator-fixed";
+                       regulator-name = "usbotg_vbus";
+                       regulator-min-microvolt = <5000000>;
+                       regulator-max-microvolt = <5000000>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_usbotg_vbus>;
+                       gpio = <TX_GPIO_PIN34 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+               };
+       };
+
+       lcd: lcd@0 {
+               status = "disabled";
+       };
+
+       mxcfb0: fb@0 {
+               compatible = "fsl,mxc_sdc_fb";
+               disp_dev = "lcd";
+               interface_pix_fmt = "RGB24";
+               default_bpp = <16>;
+               int_clk = <0>;
+               late_init = <0>;
+               status = "disabled";
+       };
+
+       mxcfb1: fb@1 {
+               compatible = "fsl,mxc_sdc_fb";
+               disp_dev = "ldb";
+               interface_pix_fmt = "RGB666";
+               default_bpp = <16>;
+               int_clk = <0>;
+               late_init = <0>;
+               status = "disabled";
+       };
+
+       mxcfb2: fb@2 {
+               compatible = "fsl,mxc_sdc_fb";
+               disp_dev = "ldb";
+               interface_pix_fmt = "RGB666";
+               default_bpp = <16>;
+               int_clk = <0>;
+               late_init = <0>;
+               status = "disabled";
+       };
+
+       v4l2_cap_0 {
+               compatible = "fsl,imx6q-v4l2-capture";
+               ipu_id = <0>;
+               csi_id = <0>;
+               mclk_source = <0>;
+               status = "disabled";
+       };
+
+       v4l2_cap_1 {
+               compatible = "fsl,imx6q-v4l2-capture";
+               ipu_id = <0>;
+               csi_id = <1>;
+               mclk_source = <0>;
+               status = "disabled";
+       };
+
+       v4l2_out {
+               compatible = "fsl,mxc_v4l2_output";
+               status = "disabled";
+       };
+};
+
+&can1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan1>;
+       status = "disabled";
+};
+
+&can2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_flexcan2>;
+       status = "disabled";
+};
+
+&clks {
+       fsl,ldb-di0-parent = <&clks IMX6QDL_CLK_PLL2_PFD0_352M>;
+       fsl,ldb-di1-parent = <&clks IMX6QDL_CLK_PLL2_PFD0_352M>;
+};
+
+&dcic2 {
+       dcic_id = <1>;
+       dcic_mux = "dcic-lvds1";
+       status = "okay";
+};
+
+&ecspi1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ecspi1>;
+       fsl,spi-num-chipselects = <2>;
+       cs-gpios = <
+               TX_GPIO_PIN44 GPIO_ACTIVE_HIGH
+               TX_GPIO_PIN45 GPIO_ACTIVE_HIGH
+       >;
+       status = "disabled";
+
+       spidev0: spi@0 {
+               compatible = "spidev";
+               reg = <0>;
+               spi-max-frequency = <54000000>;
+       };
+
+       spidev1: spi@1 {
+               compatible = "spidev";
+               reg = <1>;
+               spi-max-frequency = <54000000>;
+       };
+};
+
+&fec {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_enet>;
+       clocks = <&clks IMX6QDL_CLK_ENET>,
+                <&clks IMX6QDL_CLK_ENET>,
+                <&clks IMX6QDL_CLK_ENET_REF>,
+                <&clks IMX6QDL_CLK_ENET_REF>;
+       clock-names = "ipg", "ahb", "ptp", "enet_out";
+       ref-clock = <50000000>;
+       phy-mode = "rmii";
+       phy-reset-gpios = <&gpio7 6 GPIO_ACTIVE_HIGH>;
+       phy-handle = <&etnphy>;
+       phy-supply = <&reg_3v3_etn>;
+        fsl,magic-packet;
+        fsl,err006687-workaround-present;
+       status = "okay";
+
+       mdio {
+               #address-cells = <1>;
+               #size-cells = <0>;
+
+               etnphy: ethernet-phy@0 {
+                       compatible = "ethernet-phy-ieee802.3-c22";
+                       reg = <0>;
+                       interrupts-extended  = <&gpio7 1 IRQ_TYPE_EDGE_FALLING>;
+                       status = "okay";
+               };
+       };
+};
+
+&gpmi {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_gpmi_nand>;
+       nand-on-flash-bbt;
+       fsl,no-blockmark-swap;
+       status = "disabled";
+};
+
+&i2c3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_i2c3>;
+       clock-frequency = <400000>;
+       status = "disabled";
+};
+
+&pwm1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm1>;
+       status = "disabled";
+};
+
+&pwm2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_pwm2>;
+       status = "disabled";
+};
+
+&reg_arm {
+       /delete-property/ regulator-allow-bypass;
+};
+
+&reg_pu {
+       /delete-property/ regulator-allow-bypass;
+};
+
+&reg_soc {
+       /delete-property/ regulator-allow-bypass;
+};
+
+&snvs_poweroff {
+       status = "okay";
+};
+
+&ssi1 {
+       status = "okay";
+};
+
+&ssi2 {
+       status = "okay";
+};
+
+&uart1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart1 &pinctrl_uart1_rtscts>;
+       status = "disabled";
+};
+
+&uart2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart2 &pinctrl_uart2_rtscts>;
+       status = "disabled";
+};
+
+&uart3 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_uart3 &pinctrl_uart3_rtscts>;
+       status = "disabled";
+};
+
+&usbotg {
+       vbus-supply = <&reg_usbotg_vbus>;
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usbotg>;
+       dr_mode = "peripheral";
+       disable-over-current;
+       status = "disabled";
+};
+
+&usbh1 {
+       vbus-supply = <&reg_usbh1_vbus>;
+       dr_mode = "host";
+       disable-over-current;
+       status = "disabled";
+};
+
+&usdhc1 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc1>;
+       bus-width = <4>;
+       no-1-8-v;
+       cd-gpios = <&gpio7 2 GPIO_ACTIVE_LOW>;
+       fsl,wp-controller;
+       status = "disabled";
+};
+
+&usdhc2 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc2>;
+       bus-width = <4>;
+       no-1-8-v;
+       cd-gpios = <&gpio7 3 GPIO_ACTIVE_LOW>;
+       fsl,wp-controller;
+       status = "disabled";
+};
+
+&usdhc4 {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_usdhc4>;
+       bus-width = <4>;
+       non-removable;
+       no-1-8-v;
+       fsl,wp-controller;
+       status = "disabled";
+};
+
+&iomuxc {
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_hog>;
+
+       tx6 {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_DAT2__GPIO7_IO06         0x1b0b1 /* ETN PHY RESET */
+                               MX6QDL_PAD_SD3_DAT4__GPIO7_IO01         0x1b0b1 /* ETN PHY INT */
+                       >;
+               };
+
+               pinctrl_ssi1: audmuxgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_ROW1__AUD5_RXD           0x130b0 /* SSI1_RXD */
+                               MX6QDL_PAD_KEY_ROW0__AUD5_TXD           0x110b0 /* SSI1_TXD */
+                               MX6QDL_PAD_KEY_COL0__AUD5_TXC           0x130b0 /* SSI1_CLK */
+                               MX6QDL_PAD_KEY_COL1__AUD5_TXFS          0x130b0 /* SSI1_FS */
+                       >;
+               };
+
+               pinctrl_ecspi1: ecspi1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D18__ECSPI1_MOSI         0x0b0b0
+                               MX6QDL_PAD_EIM_D17__ECSPI1_MISO         0x0b0b0
+                               MX6QDL_PAD_EIM_D16__ECSPI1_SCLK         0x0b0b0
+                               MX6QDL_PAD_GPIO_19__ECSPI1_RDY          0x0b0b0
+                               MX6QDL_PAD_EIM_EB2__GPIO2_IO30          0x0b0b0 /* SPI CS0 */
+                               MX6QDL_PAD_EIM_D19__GPIO3_IO19          0x0b0b0 /* SPI CS1 */
+                       >;
+               };
+
+               pinctrl_enet: enetgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_ENET_MDC__ENET_MDC           0x1b0b0
+                               MX6QDL_PAD_ENET_MDIO__ENET_MDIO         0x1b0b0
+                               MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0     0x1b0b0
+                               MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1     0x1b0b0
+                               MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER       0x1b0b0
+                               MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN       0x1b0b0
+                               MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0     0x1b0b0
+                               MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1     0x1b0b0
+                               MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN      0x1b0b0
+                       >;
+               };
+
+               pinctrl_etnphy_power: etnphy-pwrgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D20__GPIO3_IO20          0x1b0b1 /* ETN PHY POWER */
+                       >;
+               };
+
+               pinctrl_flexcan1: flexcan1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_7__FLEXCAN1_TX          0x1b0b0
+                               MX6QDL_PAD_GPIO_8__FLEXCAN1_RX          0x1b0b0
+                       >;
+               };
+
+               pinctrl_flexcan2: flexcan2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_KEY_COL4__FLEXCAN2_TX        0x1b0b0
+                               MX6QDL_PAD_KEY_ROW4__FLEXCAN2_RX        0x1b0b0
+                       >;
+               };
+
+               pinctrl_gpmi_nand: gpminandgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_NANDF_CLE__NAND_CLE          0x0b0b1
+                               MX6QDL_PAD_NANDF_ALE__NAND_ALE          0x0b0b1
+                               MX6QDL_PAD_NANDF_WP_B__NAND_WP_B        0x0b0b1
+                               MX6QDL_PAD_NANDF_RB0__NAND_READY_B      0x0b000
+                               MX6QDL_PAD_NANDF_CS0__NAND_CE0_B        0x0b0b1
+                               MX6QDL_PAD_SD4_CMD__NAND_RE_B           0x0b0b1
+                               MX6QDL_PAD_SD4_CLK__NAND_WE_B           0x0b0b1
+                               MX6QDL_PAD_NANDF_D0__NAND_DATA00        0x0b0b1
+                               MX6QDL_PAD_NANDF_D1__NAND_DATA01        0x0b0b1
+                               MX6QDL_PAD_NANDF_D2__NAND_DATA02        0x0b0b1
+                               MX6QDL_PAD_NANDF_D3__NAND_DATA03        0x0b0b1
+                               MX6QDL_PAD_NANDF_D4__NAND_DATA04        0x0b0b1
+                               MX6QDL_PAD_NANDF_D5__NAND_DATA05        0x0b0b1
+                               MX6QDL_PAD_NANDF_D6__NAND_DATA06        0x0b0b1
+                               MX6QDL_PAD_NANDF_D7__NAND_DATA07        0x0b0b1
+                       >;
+               };
+
+               pinctrl_i2c3: i2c3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_3__I2C3_SCL             0x4001b8b1
+                               MX6QDL_PAD_GPIO_6__I2C3_SDA             0x4001b8b1
+                       >;
+               };
+
+               pinctrl_ipu1: ipu1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK      0x10
+                               MX6QDL_PAD_DI0_PIN15__IPU1_DI0_PIN15            0x10
+                               MX6QDL_PAD_DI0_PIN2__IPU1_DI0_PIN02             0x10
+                               MX6QDL_PAD_DI0_PIN3__IPU1_DI0_PIN03             0x10
+                               MX6QDL_PAD_DI0_PIN4__IPU1_DI0_PIN04             0x80000000
+                               MX6QDL_PAD_DISP0_DAT0__IPU1_DISP0_DATA00        0x10
+                               MX6QDL_PAD_DISP0_DAT1__IPU1_DISP0_DATA01        0x10
+                               MX6QDL_PAD_DISP0_DAT2__IPU1_DISP0_DATA02        0x10
+                               MX6QDL_PAD_DISP0_DAT3__IPU1_DISP0_DATA03        0x10
+                               MX6QDL_PAD_DISP0_DAT4__IPU1_DISP0_DATA04        0x10
+                               MX6QDL_PAD_DISP0_DAT5__IPU1_DISP0_DATA05        0x10
+                               MX6QDL_PAD_DISP0_DAT6__IPU1_DISP0_DATA06        0x10
+                               MX6QDL_PAD_DISP0_DAT7__IPU1_DISP0_DATA07        0x10
+                               MX6QDL_PAD_DISP0_DAT8__IPU1_DISP0_DATA08        0x10
+                               MX6QDL_PAD_DISP0_DAT9__IPU1_DISP0_DATA09        0x10
+                               MX6QDL_PAD_DISP0_DAT10__IPU1_DISP0_DATA10       0x10
+                               MX6QDL_PAD_DISP0_DAT11__IPU1_DISP0_DATA11       0x10
+                               MX6QDL_PAD_DISP0_DAT12__IPU1_DISP0_DATA12       0x10
+                               MX6QDL_PAD_DISP0_DAT13__IPU1_DISP0_DATA13       0x10
+                               MX6QDL_PAD_DISP0_DAT14__IPU1_DISP0_DATA14       0x10
+                               MX6QDL_PAD_DISP0_DAT15__IPU1_DISP0_DATA15       0x10
+                               MX6QDL_PAD_DISP0_DAT16__IPU1_DISP0_DATA16       0x10
+                               MX6QDL_PAD_DISP0_DAT17__IPU1_DISP0_DATA17       0x10
+                               MX6QDL_PAD_DISP0_DAT18__IPU1_DISP0_DATA18       0x10
+                               MX6QDL_PAD_DISP0_DAT19__IPU1_DISP0_DATA19       0x10
+                               MX6QDL_PAD_DISP0_DAT20__IPU1_DISP0_DATA20       0x10
+                               MX6QDL_PAD_DISP0_DAT21__IPU1_DISP0_DATA21       0x10
+                               MX6QDL_PAD_DISP0_DAT22__IPU1_DISP0_DATA22       0x10
+                               MX6QDL_PAD_DISP0_DAT23__IPU1_DISP0_DATA23       0x10
+                       >;
+               };
+
+               pinctrl_pwm1: pwm1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_9__PWM1_OUT             0x1b0b1
+                       >;
+               };
+
+               pinctrl_pwm2: pwm2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_1__PWM2_OUT             0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart1: uart1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_DAT7__UART1_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD3_DAT6__UART1_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart1_rtscts: uart1_rtsctsgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_DAT1__UART1_RTS_B        0x1b0b1
+                               MX6QDL_PAD_SD3_DAT0__UART1_CTS_B        0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart2: uart2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT7__UART2_TX_DATA      0x1b0b1
+                               MX6QDL_PAD_SD4_DAT4__UART2_RX_DATA      0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart2_rtscts: uart2_rtsctsgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_DAT5__UART2_RTS_B        0x1b0b1
+                               MX6QDL_PAD_SD4_DAT6__UART2_CTS_B        0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart3: uart3grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D24__UART3_TX_DATA       0x1b0b1
+                               MX6QDL_PAD_EIM_D25__UART3_RX_DATA       0x1b0b1
+                       >;
+               };
+
+               pinctrl_uart3_rtscts: uart3_rtsctsgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD3_DAT3__UART3_CTS_B        0x1b0b1
+                               MX6QDL_PAD_SD3_RST__UART3_RTS_B         0x1b0b1
+                       >;
+               };
+
+               pinctrl_usbh1_vbus: usbh1-vbusgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D31__GPIO3_IO31          0x1b0b0 /* USBH1_VBUSEN */
+                       >;
+               };
+
+               pinctrl_usbotg: usbotggrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_EIM_D23__GPIO3_IO23          0x17059
+                       >;
+               };
+
+               pinctrl_usbotg_vbus: usbotg-vbusgrp {
+                       fsl,pins = <
+                               MX6QDL_PAD_GPIO_7__GPIO1_IO07           0x1b0b0 /* USBOTG_VBUSEN */
+                       >;
+               };
+
+               pinctrl_usdhc1: usdhc1grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD1_CMD__SD1_CMD             0x070b1
+                               MX6QDL_PAD_SD1_CLK__SD1_CLK             0x070b1
+                               MX6QDL_PAD_SD1_DAT0__SD1_DATA0          0x070b1
+                               MX6QDL_PAD_SD1_DAT1__SD1_DATA1          0x070b1
+                               MX6QDL_PAD_SD1_DAT2__SD1_DATA2          0x070b1
+                               MX6QDL_PAD_SD1_DAT3__SD1_DATA3          0x070b1
+                               MX6QDL_PAD_SD3_CMD__GPIO7_IO02          0x170b0 /* SD1 CD */
+                       >;
+               };
+
+               pinctrl_usdhc2: usdhc2grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD2_CMD__SD2_CMD             0x070b1
+                               MX6QDL_PAD_SD2_CLK__SD2_CLK             0x070b1
+                               MX6QDL_PAD_SD2_DAT0__SD2_DATA0          0x070b1
+                               MX6QDL_PAD_SD2_DAT1__SD2_DATA1          0x070b1
+                               MX6QDL_PAD_SD2_DAT2__SD2_DATA2          0x070b1
+                               MX6QDL_PAD_SD2_DAT3__SD2_DATA3          0x070b1
+                               MX6QDL_PAD_SD3_CLK__GPIO7_IO03          0x170b0 /* SD2 CD */
+                       >;
+               };
+
+               pinctrl_usdhc4: usdhc4grp {
+                       fsl,pins = <
+                               MX6QDL_PAD_SD4_CMD__SD4_CMD             0x070b1
+                               MX6QDL_PAD_SD4_CLK__SD4_CLK             0x070b1
+                               MX6QDL_PAD_SD4_DAT0__SD4_DATA0          0x070b1
+                               MX6QDL_PAD_SD4_DAT1__SD4_DATA1          0x070b1
+                               MX6QDL_PAD_SD4_DAT2__SD4_DATA2          0x070b1
+                               MX6QDL_PAD_SD4_DAT3__SD4_DATA3          0x070b1
+                               MX6QDL_PAD_NANDF_ALE__SD4_RESET         0x0b0b1
+                       >;
+               };
+       };
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6dl-tx6-emmc-aclavis-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6dl-tx6-emmc-aclavis-lvds.dts
new file mode 100755 (executable)
index 0000000..23e60e9
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6U Module";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom timing here, therewith
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom timing here, therewith
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6dl-tx6-nand-aclavis-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6dl-tx6-nand-aclavis-lvds.dts
new file mode 100755 (executable)
index 0000000..da02e27
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6U Module";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6q-tx6-emmc-aclavis-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6q-tx6-emmc-aclavis-lvds.dts
new file mode 100755 (executable)
index 0000000..19332de
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (eMMC & LVDS)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom timing here, therewith
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom timing here, therewith
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6q-tx6-nand-aclavis-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6q-tx6-nand-aclavis-lvds.dts
new file mode 100755 (executable)
index 0000000..34858ae
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (NAND & LVDS)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6qp-tx6-emmc-aclavis-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6qp-tx6-emmc-aclavis-lvds.dts
new file mode 100755 (executable)
index 0000000..1f02434
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qp.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (eMMC & LVDS)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom timing here, therewith
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom timing here, therewith
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6s-tx6-emmc-aclavis-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6s-tx6-emmc-aclavis-lvds.dts
new file mode 100755 (executable)
index 0000000..e6e3436
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6S Module (eMMC & LVDS)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+       cpus {
+               /delete-node/ cpu@1;
+       };
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom timing here, therewith
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6s-tx6-nand-aclavis-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/imx6s-tx6-nand-aclavis-lvds.dts
new file mode 100755 (executable)
index 0000000..a5f890b
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6S Module (NAND & LVDS)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+       cpus {
+               /delete-node/ cpu@1;
+       };
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/txbase-aclavis-lvds.dtsi b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis-lvds/txbase-aclavis-lvds.dtsi
new file mode 100755 (executable)
index 0000000..52abdcd
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/ {
+       aliases {
+               backlight = &backlight0;
+               backlight0 = &backlight0;
+               /*
+                * The node/alias 'display' is needed for U-Boot to be able to
+                * show a logo/splash image at boot time. It needs to include
+                * 'display-timings' as direct sub-node.
+                */
+               display = &lvds0;
+               lvds0 = &lvds0;
+               lvds1 = &lvds1;
+               mxcfb0 = TX_LDB_FB1;
+               mxcfb1 = TX_LDB_FB2;
+       };
+
+       backlight0: backlight0 {
+               compatible = "pwm-backlight";
+               pwms = <TX_PWM 0 500000>;
+               power-supply = <&reg_lcd0_pwr>;
+               enable-gpios = <TX_GPIO_PIN154 GPIO_ACTIVE_HIGH>;
+               /*
+               * a poor man's way to create a 1:1 relationship between
+               * the PWM value and the actual duty cycle
+               */
+               brightness-levels = < 0  1  2  3  4  5  6  7  8  9
+                                    10 11 12 13 14 15 16 17 18 19
+                                    20 21 22 23 24 25 26 27 28 29
+                                    30 31 32 33 34 35 36 37 38 39
+                                    40 41 42 43 44 45 46 47 48 49
+                                    50 51 52 53 54 55 56 57 58 59
+                                    60 61 62 63 64 65 66 67 68 69
+                                    70 71 72 73 74 75 76 77 78 79
+                                    80 81 82 83 84 85 86 87 88 89
+                                    90 91 92 93 94 95 96 97 98 99
+                                   100>;
+               default-brightness-level = <50>;
+               status = "disabled";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               user_led: user {
+                       label = "Heartbeat";
+                       gpios = <TX_GPIO_PIN153 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       regulators {
+               reg_lcd0_pwr: regulator-lcd0-power {
+                       compatible = "regulator-fixed";
+                       regulator-name = "LCD0 RESET";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_lcd0_pwr>;
+                       gpio = <TX_GPIO_PIN150 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+       };
+};
+
+TX_CAN1 {
+       status = "okay";
+};
+
+TX_I2C {
+       status = "okay";
+
+       ds1339: rtc@68 {
+               compatible = "dallas,ds1339";
+               reg = <0x68>;
+       };
+};
+
+TX_LDB {
+/*
+ * The node/alias 'display' is needed for U-Boot to be able to show a
+ * logo/splash image at boot time. It needs to include 'display-timings'
+ * as direct sub-node.
+ *
+ * Other naming is only needed for the NXP/Freescale non-mainline
+ * compliant/proprietary display driver in their Yocto 4.1 Kernel
+ * implementation.
+ */
+       lvds0: lvds-channel@0 {
+               crtc = "ipu1-di0";
+               fsl,data-mapping = "spwg";
+               fsl,data-width = <24>;
+               primary;
+               status = "disabled";
+
+               display-timings {
+                       /*
+                        * The naitive mode has to be named seperately between
+                        * lvds0 & lvds1, otherwise it will be overwritten.
+                        */
+                       native-mode = <&timing0>;
+                       timing0: ETML101001DKA {
+                               clock-frequency = <0x043b5fc0>;
+                               hactive = <0x00000500>;
+                               vactive = <0x00000320>;
+                               hback-porch = <0x00000032>;
+                               hsync-len = <0x0000003c>;
+                               hfront-porch = <0x00000032>;
+                               vback-porch = <0x00000005>;
+                               vsync-len = <0x0000000d>;
+                               vfront-porch = <0x00000005>;
+                       };
+               };
+       };
+
+       lvds1: lvds-channel@1 {
+               crtc = "ipu1-di1";
+               fsl,data-mapping = "spwg";
+               fsl,data-width = <18>;
+               status = "disabled";
+
+               display-timings {
+                       /*
+                        * The naitive mode has to be named seperately between
+                        * lvds0 & lvds1, otherwise it will be overwritten.
+                        */
+                       native-mode = <&timing1>;
+                       timing1: ETML101001DKA {
+                               clock-frequency = <0x043b5fc0>;
+                               hactive = <0x00000500>;
+                               vactive = <0x00000320>;
+                               hback-porch = <0x00000032>;
+                               hsync-len = <0x0000003c>;
+                               hfront-porch = <0x00000032>;
+                               vback-porch = <0x00000005>;
+                               vsync-len = <0x0000000d>;
+                               vfront-porch = <0x00000005>;
+                       };
+               };
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "okay";
+};
+
+TX_PWM {
+       status = "okay";
+};
+
+TX_SD1 {
+       status = "okay";
+};
+
+TX_UART1 {
+       status = "okay";
+};
+
+TX_UART2 {
+       status = "okay";
+       fsl,uart-has-rtscts;
+       uart-has-rtscts;
+};
+
+TX_USBH {
+       status = "okay";
+};
+
+TX_USBOTG {
+       status = "okay";
+};
+
+&iomuxc {
+       tx6 {
+               pinctrl_hog: hoggrp {
+                       fsl,pins = <
+                               TX_GPIO_PAD148          /* OPTO IN */
+                               TX_GPIO_PAD149          /* OPTO IN */
+                               TX_GPIO_PAD151          /* OPTO OUT */
+                               TX_GPIO_PAD152          /* OPTO OUT */
+                               TX_GPIO_PAD154          /* Backlight enable */
+                       >;
+               };
+
+               pinctrl_gpio_leds: gpioledsgrp {
+                       fsl,pins = <
+                               TX_GPIO_PAD153          /* LED Heartbeat */
+                       >;
+               };
+
+               pinctrl_lcd0_pwr: lcd0-pwrgrp {
+                       fsl,pins = <
+                               TX_GPIO_PAD150          /* LCD Reset */
+                       >;
+               };
+       };
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6dl-tx6-emmc-aclavis.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6dl-tx6-emmc-aclavis.dts
new file mode 100755 (executable)
index 0000000..d26a69a
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6U Module (eMMC & RGB)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6dl-tx6-nand-aclavis.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6dl-tx6-nand-aclavis.dts
new file mode 100755 (executable)
index 0000000..14cab69
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6U Module (NAND & RGB)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6q-tx6-emmc-aclavis.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6q-tx6-emmc-aclavis.dts
new file mode 100755 (executable)
index 0000000..f17cf72
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (eMMC & RGB)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6q-tx6-nand-aclavis.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6q-tx6-nand-aclavis.dts
new file mode 100755 (executable)
index 0000000..dff34a1
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (NAND & RGB)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6qp-tx6-emmc-aclavis.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6qp-tx6-emmc-aclavis.dts
new file mode 100755 (executable)
index 0000000..7ede121
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qp.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (eMMC & RGB)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6s-tx6-emmc-aclavis.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6s-tx6-emmc-aclavis.dts
new file mode 100755 (executable)
index 0000000..d80dbdc
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6S Module (eMMC & RGB)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+       cpus {
+               /delete-node/ cpu@1;
+       };
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6s-tx6-nand-aclavis.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/imx6s-tx6-nand-aclavis.dts
new file mode 100755 (executable)
index 0000000..4d1dbb9
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-aclavis.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6S Module (NAND & RGB)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+       cpus {
+               /delete-node/ cpu@1;
+       };
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/txbase-aclavis.dtsi b/recipes-kernel/linux/linux-karo-4.9.11/txbase/aclavis/txbase-aclavis.dtsi
new file mode 100755 (executable)
index 0000000..d3fa888
--- /dev/null
@@ -0,0 +1,332 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2017 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/ {
+       aliases {
+               backlight = &backlight0;
+               backlight0 = &backlight0;
+               /*
+                * The node/alias 'display' is needed for U-Boot to be able to
+                * show a logo/splash image at boot time. It needs to include
+                * 'display-timings' as direct sub-node.
+                */
+               display = TX_LCD;
+               mxcfb0 = TX_LCD_FB;
+       };
+
+       backlight0: backlight0 {
+               compatible = "pwm-backlight";
+               pwms = <TX_PWM 0 500000>;
+               power-supply = <&reg_lcd0_pwr>;
+               /*
+               * a poor man's way to create a 1:1 relationship between
+               * the PWM value and the actual duty cycle
+               */
+               brightness-levels = < 0  1  2  3  4  5  6  7  8  9
+                                    10 11 12 13 14 15 16 17 18 19
+                                    20 21 22 23 24 25 26 27 28 29
+                                    30 31 32 33 34 35 36 37 38 39
+                                    40 41 42 43 44 45 46 47 48 49
+                                    50 51 52 53 54 55 56 57 58 59
+                                    60 61 62 63 64 65 66 67 68 69
+                                    70 71 72 73 74 75 76 77 78 79
+                                    80 81 82 83 84 85 86 87 88 89
+                                    90 91 92 93 94 95 96 97 98 99
+                                   100>;
+               default-brightness-level = <50>;
+               status = "disabled";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               user_led: user {
+                       label = "Heartbeat";
+                       gpios = <TX_GPIO_PIN153 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       regulators {
+               reg_lcd0_pwr: regulator-lcd-power {
+                       compatible = "regulator-fixed";
+                       regulator-name = "LCD0 RESET";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_lcd0_pwr>;
+                       gpio = <TX_GPIO_PIN150 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+       };
+};
+
+TX_CAN1 {
+       status = "okay";
+};
+
+TX_I2C {
+       status = "okay";
+
+       polytouch: edt-ft5x06@38 {
+               compatible = "edt,edt-ft5x06";
+               reg = <0x38>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_edt_ft5x06>;
+               interrupts-extended = <TX_GPIO_PIN148 0>;
+               reset-gpios = <TX_GPIO_PIN149 GPIO_ACTIVE_LOW>;
+               wake-gpios = <TX_GPIO_PIN152 GPIO_ACTIVE_HIGH>;
+               linux,wakeup;
+       };
+};
+
+TX_LCD {
+/*
+ * The node/alias 'display' is needed for U-Boot to be able to show a
+ * logo/splash image at boot time. It needs to include 'display-timings'
+ * as direct sub-node.
+ *
+ * Other naming is only needed for the NXP/Freescale non-mainline
+ * compliant/proprietary display driver in their Yocto 4.1 Kernel
+ * implementation.
+ */
+       compatible = "fsl,lcd";
+       ipu_id = <0>;
+       disp_id = <0>;
+       default_ifmt = "RGB565";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ipu1>;
+       status = "disabled";
+       display-timings {
+               VGA {
+                       clock-frequency = <25200000>;
+                       hactive = <640>;
+                       vactive = <480>;
+                       hback-porch = <48>;
+                       hsync-len = <96>;
+                       hfront-porch = <16>;
+                       vback-porch = <31>;
+                       vsync-len = <2>;
+                       vfront-porch = <12>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ETV570 {
+                       clock-frequency = <25200000>;
+                       hactive = <640>;
+                       vactive = <480>;
+                       hback-porch = <114>;
+                       hsync-len = <30>;
+                       hfront-porch = <16>;
+                       vback-porch = <32>;
+                       vsync-len = <3>;
+                       vfront-porch = <10>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ET0350 {
+                       clock-frequency = <6413760>;
+                       hactive = <320>;
+                       vactive = <240>;
+                       hback-porch = <34>;
+                       hsync-len = <34>;
+                       hfront-porch = <20>;
+                       vback-porch = <15>;
+                       vsync-len = <3>;
+                       vfront-porch = <4>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ET0430 {
+                       clock-frequency = <9009000>;
+                       hactive = <480>;
+                       vactive = <272>;
+                       hback-porch = <2>;
+                       hsync-len = <41>;
+                       hfront-porch = <2>;
+                       vback-porch = <2>;
+                       vsync-len = <10>;
+                       vfront-porch = <2>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <1>;
+               };
+
+               ET0500 {
+                       clock-frequency = <33264000>;
+                       hactive = <800>;
+                       vactive = <480>;
+                       hback-porch = <88>;
+                       hsync-len = <128>;
+                       hfront-porch = <40>;
+                       vback-porch = <33>;
+                       vsync-len = <2>;
+                       vfront-porch = <10>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ET0700 { /* same as ET0500 */
+                       clock-frequency = <33264000>;
+                       hactive = <800>;
+                       vactive = <480>;
+                       hback-porch = <88>;
+                       hsync-len = <128>;
+                       hfront-porch = <40>;
+                       vback-porch = <33>;
+                       vsync-len = <2>;
+                       vfront-porch = <10>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ETQ570 {
+                       clock-frequency = <6596040>;
+                       hactive = <320>;
+                       vactive = <240>;
+                       hback-porch = <38>;
+                       hsync-len = <30>;
+                       hfront-porch = <30>;
+                       vback-porch = <16>;
+                       vsync-len = <3>;
+                       vfront-porch = <4>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+       };
+};
+
+TX_LCD_FB {
+       compatible = "fsl,mxc_sdc_fb";
+       disp_dev = "lcd";
+       interface_pix_fmt = "RGB24";
+       default_bpp = <16>;
+       int_clk = <0>;
+       late_init = <0>;
+       status = "disabled";
+};
+
+TX_PWM {
+       status = "okay";
+};
+
+TX_SD1 {
+       status = "okay";
+};
+
+TX_UART1 {
+       status = "okay";
+};
+
+TX_UART2 {
+       status = "okay";
+       fsl,uart-has-rtscts;
+       uart-has-rtscts;
+};
+
+TX_USBH {
+       status = "okay";
+};
+
+TX_USBOTG {
+       status = "okay";
+};
+
+&iomuxc {
+       tx6 {
+               pinctrl_edt_ft5x06: edt-ft5x06grp {
+                       fsl,pins = <
+                               TX_GPIO_PAD148          /* Interrupt */
+                               TX_GPIO_PAD149          /* Reset */
+                               TX_GPIO_PAD152          /* Wake */
+                       >;
+               };
+
+               pinctrl_gpio_leds: gpioledsgrp {
+                       fsl,pins = <
+                               TX_GPIO_PAD153          /* LED Heartbeat */
+                       >;
+               };
+
+               pinctrl_lcd0_pwr: lcd0-pwrgrp {
+                       fsl,pins = <
+                               TX_GPIO_PAD150          /* LCD Reset */
+                       >;
+               };
+       };
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6dl-tx6-emmc-evalkit.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6dl-tx6-emmc-evalkit.dts
new file mode 100755 (executable)
index 0000000..a172448
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-evalkit.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6U Module (eMMC & RGB)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6dl-tx6-nand-evalkit.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6dl-tx6-nand-evalkit.dts
new file mode 100755 (executable)
index 0000000..bbff2b3
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-evalkit.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6U Module (NAND & RGB)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6q-tx6-emmc-evalkit.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6q-tx6-emmc-evalkit.dts
new file mode 100755 (executable)
index 0000000..1d63db1
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-evalkit.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (eMMC & RGB)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6q-tx6-nand-evalkit.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6q-tx6-nand-evalkit.dts
new file mode 100755 (executable)
index 0000000..639fb2a
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-evalkit.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (NAND & RGB)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6qp-tx6-emmc-evalkit.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6qp-tx6-emmc-evalkit.dts
new file mode 100755 (executable)
index 0000000..1819691
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qp.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-evalkit.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (eMMC & RGB)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6s-tx6-emmc-evalkit.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6s-tx6-emmc-evalkit.dts
new file mode 100755 (executable)
index 0000000..ab7e70b
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-evalkit.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6S Module (eMMC & RGB)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+       cpus {
+               /delete-node/ cpu@1;
+       };
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * therewith overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6s-tx6-nand-evalkit.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/imx6s-tx6-nand-evalkit.dts
new file mode 100755 (executable)
index 0000000..0a46f7a
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-evalkit.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6S Module (NAND & RGB)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+       cpus {
+               /delete-node/ cpu@1;
+       };
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/txbase-evalkit.dtsi b/recipes-kernel/linux/linux-karo-4.9.11/txbase/evalkit/txbase-evalkit.dtsi
new file mode 100755 (executable)
index 0000000..d8c5987
--- /dev/null
@@ -0,0 +1,197 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/ {
+       aliases {
+               backlight0 = &backlight0;
+               /*
+                * The node/alias 'display' is needed for U-Boot to be able to
+                * show a logo/splash image at boot time. It needs to include
+                * 'display-timings' as direct sub-node.
+                */
+               display = TX_LCD;
+               mxcfb0 = TX_LCD_FB;
+       };
+
+       backlight0: backlight0 {
+               compatible = "pwm-backlight";
+               pwms = <TX_PWM 0 500000>;
+               power-supply = <&reg_lcd0_pwr>;
+               /*
+               * a poor man's way to create a 1:1 relationship between
+               * the PWM value and the actual duty cycle
+               */
+               brightness-levels = < 0  1  2  3  4  5  6  7  8  9
+                                    10 11 12 13 14 15 16 17 18 19
+                                    20 21 22 23 24 25 26 27 28 29
+                                    30 31 32 33 34 35 36 37 38 39
+                                    40 41 42 43 44 45 46 47 48 49
+                                    50 51 52 53 54 55 56 57 58 59
+                                    60 61 62 63 64 65 66 67 68 69
+                                    70 71 72 73 74 75 76 77 78 79
+                                    80 81 82 83 84 85 86 87 88 89
+                                    90 91 92 93 94 95 96 97 98 99
+                                   100>;
+               default-brightness-level = <50>;
+               status = "disabled";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+               
+               user_led: user {
+                       label = "Heartbeat";
+                       gpios = <TX_GPIO_PIN153 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       reg_lcd0_pwr: regulator-lcd0-power {
+               compatible = "regulator-fixed";
+               regulator-name = "LCD0 RESET";
+               regulator-min-microvolt = <3300000>;
+               regulator-max-microvolt = <3300000>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_lcd0_pwr>;
+               gpio = <TX_GPIO_PIN150 GPIO_ACTIVE_HIGH>;
+               enable-active-high;
+               regulator-boot-on;
+               regulator-always-on;
+       };
+};
+
+&iomuxc {
+       tx6 {
+               pinctrl_edt_ft5x06: edt-ft5x06grp {
+                       fsl,pins = <
+                               TX_GPIO_PAD148          /* Interrupt */
+                               TX_GPIO_PAD149          /* Reset */
+                               TX_GPIO_PAD152          /* Wake */
+                       >;
+               };
+
+               pinctrl_gpio_leds: gpioledsgrp {
+                       fsl,pins = <
+                               TX_GPIO_PAD153          /* LED Heartbeat */
+                       >;
+               };
+
+               pinctrl_lcd0_pwr: lcd0-pwrgrp {
+                       fsl,pins = <
+                               TX_GPIO_PAD150          /* LCD Reset */
+                       >;
+               };
+       };
+};
+
+/*
+ * Ka-Ro device references in alphabetical order
+ */
+
+TX_CAN1 {
+       status = "okay";
+};
+
+TX_I2C {
+       ds1339: rtc@68 {
+               compatible = "dallas,ds1339";
+               reg = <0x68>;
+       };
+
+       polytouch: edt-ft5x06@38 {
+               compatible = "edt,edt-ft5x06";
+               reg = <0x38>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_edt_ft5x06>;
+               interrupt-extended = <TX_GPIO_PIN148 0>;
+               reset-gpios = <TX_GPIO_PIN149 GPIO_ACTIVE_LOW>;
+               wake-gpios = <TX_GPIO_PIN152 GPIO_ACTIVE_HIGH>;
+               linux,wakeup;
+       };
+};
+
+TX_LCD {
+       status = "okay";
+};
+
+TX_PWM {
+       status = "okay";
+};
+
+TX_UART1 {
+       status = "okay";
+};
+
+TX_UART2 {
+       status = "okay";
+};
+
+TX_UART3 {
+       status = "okay";
+};
+
+TX_USBH {
+       status = "okay";
+};
+
+TX_USBOTG {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6dl-tx6-emmc-mb7-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6dl-tx6-emmc-mb7-lvds.dts
new file mode 100755 (executable)
index 0000000..0fbc8b2
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6U Module (eMMC & LVDS)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * therewith overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * therewith overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6dl-tx6-nand-mb7-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6dl-tx6-nand-mb7-lvds.dts
new file mode 100755 (executable)
index 0000000..e3372eb
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6U Module (NAND & LVDS)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom timing here, therewith
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom timing here, therewith
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6q-tx6-emmc-mb7-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6q-tx6-emmc-mb7-lvds.dts
new file mode 100755 (executable)
index 0000000..3dced74
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (eMMC & LVDS)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * therewith overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * therewith overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6q-tx6-nand-mb7-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6q-tx6-nand-mb7-lvds.dts
new file mode 100755 (executable)
index 0000000..b482354
--- /dev/null
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (NAND & LVDS)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom timing here, therewith
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom timing here, therewith
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6qp-tx6-emmc-mb7-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6qp-tx6-emmc-mb7-lvds.dts
new file mode 100755 (executable)
index 0000000..aa16aa0
--- /dev/null
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qp.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (eMMC & LVDS)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * therewith overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * therewith overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6s-tx6-emmc-mb7-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6s-tx6-emmc-mb7-lvds.dts
new file mode 100755 (executable)
index 0000000..762f6b8
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6S Module (eMMC & LVDS)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+       cpus {
+               /delete-node/ cpu@1;
+       };
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * therewith overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom (U-Boot) timing here,
+                * therewith overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6s-tx6-nand-mb7-lvds.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/imx6s-tx6-nand-mb7-lvds.dts
new file mode 100755 (executable)
index 0000000..b627111
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7-lvds.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6S Module (NAND & LVDS)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+       cpus {
+               /delete-node/ cpu@1;
+       };
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LDB {
+       status = "okay";
+
+       lvds0: lvds-channel@0 {
+               status = "okay";
+               /*
+                * Users should add their custom timing here, therewith
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+
+       lvds1: lvds-channel@1 {
+               status = "disabled";
+               /*
+                * Users should add their custom timing here, therewith
+                * overwriting the default/pre-defined timings. For more see:
+                *
+                * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+                *
+                * e.g.:
+                * txbase/mb7-lvds/txbase-aclavis.dtsi
+                */
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "disabled";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/txbase-mb7-lvds.dtsi b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7-lvds/txbase-mb7-lvds.dtsi
new file mode 100755 (executable)
index 0000000..151e6db
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/ {
+       aliases {
+               backlight = &backlight0;
+               backlight0 = &backlight0;
+               /*
+               * The node/alias 'display' is needed for U-Boot to be able to
+               * show a logo/splash image at boot time. It needs to include
+               * 'display-timings' as direct sub-node.
+               */
+               display = &lvds0;
+               lvds0 = &lvds0;
+               lvds1 = &lvds1;
+               mxcfb0 = TX_LDB_FB1;
+               mxcfb1 = TX_LDB_FB2;
+       };
+
+       backlight0: backlight0 {
+               compatible = "pwm-backlight";
+               pwms = <TX_PWM 0 500000>;
+               power-supply = <&reg_lcd0_pwr>;
+               /*
+               * a poor man's way to create a 1:1 relationship between
+               * the PWM value and the actual duty cycle
+               */
+               brightness-levels = < 0  1  2  3  4  5  6  7  8  9
+                                    10 11 12 13 14 15 16 17 18 19
+                                    20 21 22 23 24 25 26 27 28 29
+                                    30 31 32 33 34 35 36 37 38 39
+                                    40 41 42 43 44 45 46 47 48 49
+                                    50 51 52 53 54 55 56 57 58 59
+                                    60 61 62 63 64 65 66 67 68 69
+                                    70 71 72 73 74 75 76 77 78 79
+                                    80 81 82 83 84 85 86 87 88 89
+                                    90 91 92 93 94 95 96 97 98 99
+                                   100>;
+               default-brightness-level = <50>;
+               status = "disabled";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               user_led: user {
+                       label = "Heartbeat";
+                       gpios = <TX_GPIO_PIN153 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       regulators {
+               reg_2v5: regulator {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "2V5";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+                       regulator-always-on;
+               };
+
+               reg_3v3: regulator {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "3V3";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_lcd0_pwr: regulator-lcd0-power {
+                       compatible = "regulator-fixed";
+                       regulator-name = "LCD0 RESET";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_lcd0_pwr>;
+                       gpio = <TX_GPIO_PIN150 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx-audio-sgtl5000";
+               model = "sgtl5000-audio";
+               pinctrl-names = "default";
+               pinctrl-0 = <TX_SSI_PIN>;
+               ssi-controller = <&ssi1>;
+               audio-codec = <&sgtl5000>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <5>;
+       };
+};
+
+TX_CAN1 {
+       status = "okay";
+};
+
+TX_I2C {
+       status = "okay";
+
+       sgtl5000: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               VDDA-supply = <&reg_2v5>;
+               VDDIO-supply = <&reg_3v3>;
+               clocks = <&mclk>;
+       };
+};
+
+TX_LDB {
+/*
+ * The node/alias 'display' is needed for U-Boot to be able to show a
+ * logo/splash image at boot time. It needs to include 'display-timings'
+ * as direct sub-node.
+ *
+ * Other naming is only needed for the NXP/Freescale non-mainline
+ * compliant/proprietary display driver in their Yocto 4.1 Kernel
+ * implementation.
+ */
+       lvds0: lvds-channel@0 {
+               crtc = "ipu1-di0";
+               fsl,data-mapping = "spwg";
+               fsl,data-width = <18>;
+               primary;
+               status = "disabled";
+
+               display-timings {
+                       /*
+                        * The naitive mode has to be named seperately between
+                        * lvds0 & lvds1, otherwise it will be overwritten.
+                        */
+                       native-mode = <&timing0>;
+                       timing0: hsd100pxn1 {
+                               clock-frequency = <65000000>;
+                               hactive = <1024>;
+                               vactive = <768>;
+                               hback-porch = <220>;
+                               hfront-porch = <40>;
+                               vback-porch = <21>;
+                               vfront-porch = <7>;
+                               hsync-len = <60>;
+                               vsync-len = <10>;
+                       };
+               };
+       };
+
+       lvds1: lvds-channel@1 {
+               crtc = "ipu1-di1";
+               fsl,data-mapping = "spwg";
+               fsl,data-width = <18>;
+               status = "disabled";
+
+               display-timings {
+                       /*
+                        * The naitive mode has to be named seperately between
+                        * lvds0 & lvds1, otherwise it will be overwritten.
+                        */
+                       native-mode = <&timing1>;
+                       timing1: hsd100pxn1 {
+                               clock-frequency = <65000000>;
+                               hactive = <1024>;
+                               vactive = <768>;
+                               hback-porch = <220>;
+                               hfront-porch = <40>;
+                               vback-porch = <21>;
+                               vfront-porch = <7>;
+                               hsync-len = <60>;
+                               vsync-len = <10>;
+                       };
+               };
+       };
+};
+
+TX_LDB_FB1 {
+       status = "okay";
+};
+
+TX_LDB_FB2 {
+       status = "okay";
+};
+
+TX_PWM {
+       status = "okay";
+};
+
+TX_SD1 {
+       status = "okay";
+};
+
+TX_SSI1 {
+       status = "okay";
+};
+
+TX_UART1 {
+       status = "okay";
+};
+
+TX_UART2 {
+       status = "okay";
+       fsl,uart-has-rtscts;
+       uart-has-rtscts;
+};
+
+TX_UART3 {
+       status = "okay";
+};
+
+TX_USBH {
+       status = "okay";
+};
+
+TX_USBOTG {
+       status = "okay";
+};
+
+&iomuxc {
+       tx6 {
+               pinctrl_gpio_leds: gpioledsgrp {
+                       fsl,pins = <
+                               TX_GPIO_PAD153          /* LED Heartbeat */
+                       >;
+               };
+
+               pinctrl_lcd0_pwr: lcd0-pwrgrp {
+                       fsl,pins = <
+                               TX_GPIO_PAD150          /* LCD Reset */
+                       >;
+               };
+       };
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6dl-tx6-emmc-mb7.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6dl-tx6-emmc-mb7.dts
new file mode 100755 (executable)
index 0000000..b978516
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6U Module (eMMC & RGB)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * therewith overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6dl-tx6-nand-mb7.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6dl-tx6-nand-mb7.dts
new file mode 100755 (executable)
index 0000000..01dda19
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6U Module (NAND & RGB)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6q-tx6-emmc-mb7.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6q-tx6-emmc-mb7.dts
new file mode 100755 (executable)
index 0000000..5020ecb
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (eMMC & RGB)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6q-tx6-nand-mb7.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6q-tx6-nand-mb7.dts
new file mode 100755 (executable)
index 0000000..ec2a67c
--- /dev/null
@@ -0,0 +1,107 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6Q Module (NAND & RGB)";
+       compatible = "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6qp-tx6-emmc-mb7.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6qp-tx6-emmc-mb7.dts
new file mode 100755 (executable)
index 0000000..4988ac5
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6q.dtsi"
+#include "imx6qp.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6QP Module (eMMC & RGB)";
+       compatible = "karo,imx6qp-tx6qp", "karo,imx6q-tx6q", "fsl,imx6q";
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6s-tx6-emmc-mb7.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6s-tx6-emmc-mb7.dts
new file mode 100755 (executable)
index 0000000..394890a
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6S Module (eMMC & RGB)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+       cpus {
+               /delete-node/ cpu@1;
+       };
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6s-tx6-nand-mb7.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/imx6s-tx6-nand-mb7.dts
new file mode 100755 (executable)
index 0000000..9e4ff16
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6S Module (NAND & RGB)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+       cpus {
+               /delete-node/ cpu@1;
+       };
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_NAND {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see:
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/txbase-mb7.dtsi b/recipes-kernel/linux/linux-karo-4.9.11/txbase/mb7/txbase-mb7.dtsi
new file mode 100755 (executable)
index 0000000..582bd35
--- /dev/null
@@ -0,0 +1,382 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/ {
+       aliases {
+               backlight = &backlight0;
+               backlight0 = &backlight0;
+               /*
+               * The node/alias 'display' is needed for U-Boot to be able to
+               * show a logo/splash image at boot time. It needs to include
+               * 'display-timings' as direct sub-node.
+               */
+               display = TX_LCD;
+               mxcfb0 = TX_LCD_FB;
+       };
+
+       backlight0: backlight0 {
+               compatible = "pwm-backlight";
+               pwms = <TX_PWM 0 500000>;
+               power-supply = <&reg_lcd0_pwr>;
+               /*
+               * a poor man's way to create a 1:1 relationship between
+               * the PWM value and the actual duty cycle
+               */
+               brightness-levels = < 0  1  2  3  4  5  6  7  8  9
+                                    10 11 12 13 14 15 16 17 18 19
+                                    20 21 22 23 24 25 26 27 28 29
+                                    30 31 32 33 34 35 36 37 38 39
+                                    40 41 42 43 44 45 46 47 48 49
+                                    50 51 52 53 54 55 56 57 58 59
+                                    60 61 62 63 64 65 66 67 68 69
+                                    70 71 72 73 74 75 76 77 78 79
+                                    80 81 82 83 84 85 86 87 88 89
+                                    90 91 92 93 94 95 96 97 98 99
+                                   100>;
+               default-brightness-level = <50>;
+               status = "disabled";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               user_led: user {
+                       label = "Heartbeat";
+                       gpios = <TX_GPIO_PIN153 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       regulators {
+               reg_2v5: regulator {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "2V5";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+                       regulator-always-on;
+               };
+
+               reg_3v3: regulator {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "3V3";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_lcd0_pwr: regulator-lcd-power {
+                       compatible = "regulator-fixed";
+                       regulator-name = "LCD0 RESET";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_lcd0_pwr>;
+                       gpio = <TX_GPIO_PIN150 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx-audio-sgtl5000";
+               model = "sgtl5000-audio";
+               pinctrl-names = "default";
+               pinctrl-0 = <TX_SSI_PIN>;
+               ssi-controller = <&ssi1>;
+               audio-codec = <&sgtl5000>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <5>;
+               status = "okay";
+       };
+};
+
+TX_CAN1 {
+       status = "okay";
+};
+
+TX_I2C {
+       status = "okay";
+
+       sgtl5000: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               VDDA-supply = <&reg_2v5>;
+               VDDIO-supply = <&reg_3v3>;
+               clocks = <&mclk>;
+       };
+
+       polytouch: edt-ft5x06@38 {
+               compatible = "edt,edt-ft5x06";
+               reg = <0x38>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_edt_ft5x06>;
+               interrupts-extended = <TX_GPIO_PIN148 0>;
+               reset-gpios = <TX_GPIO_PIN149 GPIO_ACTIVE_LOW>;
+               wake-gpios = <TX_GPIO_PIN152 GPIO_ACTIVE_HIGH>;
+               linux,wakeup;
+       };
+};
+
+TX_LCD {
+/*
+ * The node/alias 'display' is needed for U-Boot to be able to show a
+ * logo/splash image at boot time. It needs to include 'display-timings'
+ * as direct sub-node.
+ *
+ * Other naming is only needed for the NXP/Freescale non-mainline
+ * compliant/proprietary display driver in their Yocto 4.1 Kernel
+ * implementation.
+ */
+       compatible = "fsl,lcd";
+       ipu_id = <0>;
+       disp_id = <0>;
+       default_ifmt = "RGB565";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ipu1>;
+       status = "disabled";
+       display-timings {
+               VGA {
+                       clock-frequency = <25200000>;
+                       hactive = <640>;
+                       vactive = <480>;
+                       hback-porch = <48>;
+                       hsync-len = <96>;
+                       hfront-porch = <16>;
+                       vback-porch = <31>;
+                       vsync-len = <2>;
+                       vfront-porch = <12>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ETV570 {
+                       clock-frequency = <25200000>;
+                       hactive = <640>;
+                       vactive = <480>;
+                       hback-porch = <114>;
+                       hsync-len = <30>;
+                       hfront-porch = <16>;
+                       vback-porch = <32>;
+                       vsync-len = <3>;
+                       vfront-porch = <10>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ET0350 {
+                       clock-frequency = <6413760>;
+                       hactive = <320>;
+                       vactive = <240>;
+                       hback-porch = <34>;
+                       hsync-len = <34>;
+                       hfront-porch = <20>;
+                       vback-porch = <15>;
+                       vsync-len = <3>;
+                       vfront-porch = <4>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ET0430 {
+                       clock-frequency = <9009000>;
+                       hactive = <480>;
+                       vactive = <272>;
+                       hback-porch = <2>;
+                       hsync-len = <41>;
+                       hfront-porch = <2>;
+                       vback-porch = <2>;
+                       vsync-len = <10>;
+                       vfront-porch = <2>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <1>;
+               };
+
+               ET0500 {
+                       clock-frequency = <33264000>;
+                       hactive = <800>;
+                       vactive = <480>;
+                       hback-porch = <88>;
+                       hsync-len = <128>;
+                       hfront-porch = <40>;
+                       vback-porch = <33>;
+                       vsync-len = <2>;
+                       vfront-porch = <10>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ET0700 { /* same as ET0500 */
+                       clock-frequency = <33264000>;
+                       hactive = <800>;
+                       vactive = <480>;
+                       hback-porch = <88>;
+                       hsync-len = <128>;
+                       hfront-porch = <40>;
+                       vback-porch = <33>;
+                       vsync-len = <2>;
+                       vfront-porch = <10>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ETQ570 {
+                       clock-frequency = <6596040>;
+                       hactive = <320>;
+                       vactive = <240>;
+                       hback-porch = <38>;
+                       hsync-len = <30>;
+                       hfront-porch = <30>;
+                       vback-porch = <16>;
+                       vsync-len = <3>;
+                       vfront-porch = <4>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+       };
+};
+
+TX_LCD_FB {
+       compatible = "fsl,mxc_sdc_fb";
+       disp_dev = "lcd";
+       interface_pix_fmt = "RGB24";
+       default_bpp = <16>;
+       int_clk = <0>;
+       late_init = <0>;
+       status = "disabled";
+};
+
+TX_PWM {
+       status = "okay";
+};
+
+TX_SD1 {
+       status = "okay";
+};
+
+TX_SSI1 {
+       status = "okay";
+};
+
+TX_UART1 {
+       status = "okay";
+};
+
+TX_UART2 {
+       status = "okay";
+       fsl,uart-has-rtscts;
+       uart-has-rtscts;
+};
+
+TX_UART3 {
+       status = "okay";
+};
+
+TX_USBH {
+       status = "okay";
+};
+
+TX_USBOTG {
+       status = "okay";
+};
+
+&iomuxc {
+       tx6 {
+               pinctrl_edt_ft5x06: edt-ft5x06grp {
+                       fsl,pins = <
+                               TX_GPIO_PAD148          /* Interrupt */
+                               TX_GPIO_PAD149          /* Reset */
+                               TX_GPIO_PAD152          /* Wake */
+                       >;
+               };
+
+               pinctrl_gpio_leds: gpioledsgrp {
+                       fsl,pins = <
+                               TX_GPIO_PAD153          /* LED Heartbeat */
+                       >;
+               };
+
+               pinctrl_lcd0_pwr: lcd0-pwrgrp {
+                       fsl,pins = <
+                               TX_GPIO_PAD150          /* LCD Reset */
+                       >;
+               };
+       };
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/myboard/imx6s-tx6-emmc-myboard.dts b/recipes-kernel/linux/linux-karo-4.9.11/txbase/myboard/imx6s-tx6-emmc-myboard.dts
new file mode 100755 (executable)
index 0000000..10b1570
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that - in general - DTSI file(s) are include files that
+ * are for more than one purpose (usually bound to a SoC) and as such shouldn't
+ * be edited. For end-user products it should be the DTS file(s) that choose
+ * which devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation to the mainline Linux kernel.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/dts-v1/;
+
+#include "imx6dl.dtsi"
+#include "imx6qdl-tx6.dtsi"
+#include "txbase-mb7.dtsi"
+
+/ {
+       model = "Ka-Ro electronics TX6S Module (eMMC & RGB)";
+       compatible = "karo,imx6dl-tx6dl", "fsl,imx6dl";
+
+       cpus {
+               /delete-node/ cpu@1;
+       };
+};
+
+/*
+ * Every VOU is multi parted: backlight, device, framebuffer, pwm
+ * Thus all parts have to be enabled before a display can be used on the
+ * specific port.
+ */
+
+&backlight0 {
+       status = "okay";
+};
+
+/*
+ * NVM setup
+ */
+
+TX_EMMC {
+       status = "okay";
+};
+
+/*
+ * Remaining device references in alphabetical order
+ */
+
+TX_LCD {
+       status = "okay";
+       /*
+        * Users should add their custom timing here, therewith
+        * overwriting the default/pre-defined timings. For more see
+        *
+        * txbase/{BASEBOARD}-{DISPLAY-IF}/txbase-{BASEBOARD}-{DISPLAY-IF}.dtsi
+        *
+        * e.g.:
+        * txbase/mb7-lvds/txbase-aclavis.dtsi
+        */
+};
+
+TX_LCD_FB {
+       status = "okay";
+};
diff --git a/recipes-kernel/linux/linux-karo-4.9.11/txbase/myboard/txbase-myboard.dtsi b/recipes-kernel/linux/linux-karo-4.9.11/txbase/myboard/txbase-myboard.dtsi
new file mode 100755 (executable)
index 0000000..04337e5
--- /dev/null
@@ -0,0 +1,383 @@
+/*
+ * Copyright 2016 Lothar Waßmann <LW@KARO-electronics.de>
+ * Copyright 2016-2017 Oliver Wendt <OW@KARO-electronics.de>
+ * Copyright 2016 Michael Vyskocil <MV@KARO-electronics.de>
+ *
+ * This file is dual-licensed: you can use it either under the terms
+ * of the GPL or the X11 license, at your option. Note that this dual
+ * licensing only applies to this file, and not this project as a
+ * whole.
+ *
+ *  a) This file is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License
+ *     version 2 as published by the Free Software Foundation.
+ *
+ *     This file is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ * Or, alternatively,
+ *
+ *  b) Permission is hereby granted, free of charge, to any person
+ *     obtaining a copy of this software and associated documentation
+ *     files (the "Software"), to deal in the Software without
+ *     restriction, including without limitation the rights to use,
+ *     copy, modify, merge, publish, distribute, sublicense, and/or
+ *     sell copies of the Software, and to permit persons to whom the
+ *     Software is furnished to do so, subject to the following
+ *     conditions:
+ *
+ *     The above copyright notice and this permission notice shall be
+ *     included in all copies or substantial portions of the Software.
+ *
+ *     THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ *     EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ *     OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ *     NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ *     HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ *     WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ *     FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ *     OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Please be reminded that in general DTSI file(s) are include files that are
+ * for more than one purpose (usually bound to a SoC) and as such shouldn't be
+ * edited. For end-user products it should be the DTS file(s) that choose which
+ * devices and pins are active and setup.
+ *
+ * The setup of DT files for Ka-Ro TX COM Modules under Yocto follow a
+ * different, non-standard, implementation, which can make it necessary.
+ */
+
+/*
+ * Please see the imx6*-tx6-gpio.h && imx6*-tx6.dtsi in "linux-karo-x.y.ab/tx6"
+ * for the definitions like TX_NAND or TX_EMMC, etc.
+ */
+
+/ {
+       aliases {
+               backlight = &backlight0;
+               backlight0 = &backlight0;
+               /*
+               * The node/alias 'display' is needed for U-Boot to be able to
+               * show a logo/splash image at boot time. It needs to include
+               * 'display-timings' as direct sub-node.
+               */
+               display = TX_LCD;
+               mxcfb0 = TX_LCD_FB;
+       };
+
+       backlight0: backlight0 {
+               compatible = "pwm-backlight";
+               pwms = <TX_PWM 0 500000>;
+               power-supply = <&reg_lcd0_pwr>;
+               /*
+               * a poor man's way to create a 1:1 relationship between
+               * the PWM value and the actual duty cycle
+               */
+               brightness-levels = < 0  1  2  3  4  5  6  7  8  9
+                                    10 11 12 13 14 15 16 17 18 19
+                                    20 21 22 23 24 25 26 27 28 29
+                                    30 31 32 33 34 35 36 37 38 39
+                                    40 41 42 43 44 45 46 47 48 49
+                                    50 51 52 53 54 55 56 57 58 59
+                                    60 61 62 63 64 65 66 67 68 69
+                                    70 71 72 73 74 75 76 77 78 79
+                                    80 81 82 83 84 85 86 87 88 89
+                                    90 91 92 93 94 95 96 97 98 99
+                                   100>;
+               default-brightness-level = <50>;
+               status = "disabled";
+       };
+
+       leds {
+               compatible = "gpio-leds";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_gpio_leds>;
+
+               user_led: user {
+                       label = "Heartbeat";
+                       gpios = <TX_GPIO_PIN153 GPIO_ACTIVE_HIGH>;
+                       linux,default-trigger = "heartbeat";
+               };
+       };
+
+       regulators {
+               reg_2v5: regulator {
+                       compatible = "regulator-fixed";
+                       reg = <1>;
+                       regulator-name = "2V5";
+                       regulator-min-microvolt = <2500000>;
+                       regulator-max-microvolt = <2500000>;
+                       regulator-always-on;
+               };
+
+               reg_3v3: regulator {
+                       compatible = "regulator-fixed";
+                       reg = <2>;
+                       regulator-name = "3V3";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       regulator-always-on;
+               };
+
+               reg_lcd0_pwr: regulator-lcd0-power {
+                       compatible = "regulator-fixed";
+                       regulator-name = "LCD0 RESET";
+                       regulator-min-microvolt = <3300000>;
+                       regulator-max-microvolt = <3300000>;
+                       pinctrl-names = "default";
+                       pinctrl-0 = <&pinctrl_lcd0_pwr>;
+                       gpio = <TX_GPIO_PIN150 GPIO_ACTIVE_HIGH>;
+                       enable-active-high;
+                       regulator-boot-on;
+                       regulator-always-on;
+               };
+       };
+
+       sound {
+               compatible = "fsl,imx-audio-sgtl5000";
+               model = "sgtl5000-audio";
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_ssi1>;
+               ssi-controller = <&ssi1>;
+               audio-codec = <&sgtl5000>;
+               audio-routing =
+                       "MIC_IN", "Mic Jack",
+                       "Mic Jack", "Mic Bias",
+                       "Headphone Jack", "HP_OUT";
+               mux-int-port = <1>;
+               mux-ext-port = <5>;
+               status = "okay";
+       };
+};
+
+TX_LCD {
+/*
+ * The node/alias 'display' is needed for U-Boot to be able to show a
+ * logo/splash image at boot time. It needs to include 'display-timings'
+ * as direct sub-node.
+ *
+ * Other naming is only needed for the NXP/Freescale non-mainline
+ * compliant/proprietary display driver in their Yocto 4.1 Kernel
+ * implementation.
+ */
+       compatible = "fsl,lcd";
+       ipu_id = <0>;
+       disp_id = <0>;
+       default_ifmt = "RGB565";
+       pinctrl-names = "default";
+       pinctrl-0 = <&pinctrl_ipu1>;
+       status = "disabled";
+       display-timings {
+               VGA {
+                       clock-frequency = <25200000>;
+                       hactive = <640>;
+                       vactive = <480>;
+                       hback-porch = <48>;
+                       hsync-len = <96>;
+                       hfront-porch = <16>;
+                       vback-porch = <31>;
+                       vsync-len = <2>;
+                       vfront-porch = <12>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ETV570 {
+                       clock-frequency = <25200000>;
+                       hactive = <640>;
+                       vactive = <480>;
+                       hback-porch = <114>;
+                       hsync-len = <30>;
+                       hfront-porch = <16>;
+                       vback-porch = <32>;
+                       vsync-len = <3>;
+                       vfront-porch = <10>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ET0350 {
+                       clock-frequency = <6413760>;
+                       hactive = <320>;
+                       vactive = <240>;
+                       hback-porch = <34>;
+                       hsync-len = <34>;
+                       hfront-porch = <20>;
+                       vback-porch = <15>;
+                       vsync-len = <3>;
+                       vfront-porch = <4>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ET0430 {
+                       clock-frequency = <9009000>;
+                       hactive = <480>;
+                       vactive = <272>;
+                       hback-porch = <2>;
+                       hsync-len = <41>;
+                       hfront-porch = <2>;
+                       vback-porch = <2>;
+                       vsync-len = <10>;
+                       vfront-porch = <2>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <1>;
+               };
+
+               ET0500 {
+                       clock-frequency = <33264000>;
+                       hactive = <800>;
+                       vactive = <480>;
+                       hback-porch = <88>;
+                       hsync-len = <128>;
+                       hfront-porch = <40>;
+                       vback-porch = <33>;
+                       vsync-len = <2>;
+                       vfront-porch = <10>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ET0700 { /* same as ET0500 */
+                       clock-frequency = <33264000>;
+                       hactive = <800>;
+                       vactive = <480>;
+                       hback-porch = <88>;
+                       hsync-len = <128>;
+                       hfront-porch = <40>;
+                       vback-porch = <33>;
+                       vsync-len = <2>;
+                       vfront-porch = <10>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+
+               ETQ570 {
+                       clock-frequency = <6596040>;
+                       hactive = <320>;
+                       vactive = <240>;
+                       hback-porch = <38>;
+                       hsync-len = <30>;
+                       hfront-porch = <30>;
+                       vback-porch = <16>;
+                       vsync-len = <3>;
+                       vfront-porch = <4>;
+                       hsync-active = <0>;
+                       vsync-active = <0>;
+                       de-active = <1>;
+                       pixelclk-active = <0>;
+               };
+       };
+};
+
+TX_LCD_FB {
+       compatible = "fsl,mxc_sdc_fb";
+       disp_dev = "lcd";
+       interface_pix_fmt = "RGB24";
+       default_bpp = <16>;
+       int_clk = <0>;
+       late_init = <0>;
+       status = "disabled";
+};
+
+TX_I2C {
+       status = "okay";
+
+       sgtl5000: sgtl5000@0a {
+               compatible = "fsl,sgtl5000";
+               reg = <0x0a>;
+               VDDA-supply = <&reg_2v5>;
+               VDDIO-supply = <&reg_3v3>;
+               clocks = <&mclk>;
+       };
+
+       polytouch: edt-ft5x06@38 {
+               compatible = "edt,edt-ft5x06";
+               reg = <0x38>;
+               pinctrl-names = "default";
+               pinctrl-0 = <&pinctrl_edt_ft5x06>;
+               interrupts-extended = <TX_GPIO_PIN148 0>;
+               reset-gpios = <TX_GPIO_PIN149 GPIO_ACTIVE_LOW>;
+               wake-gpios = <TX_GPIO_PIN152 GPIO_ACTIVE_HIGH>;
+               linux,wakeup;
+       };
+};
+
+TX_CAN1 {
+       status = "okay";
+};
+
+
+TX_PWM {
+       status = "okay";
+};
+
+TX_SD1 {
+       status = "okay";
+};
+
+TX_SSI1 {
+       status = "okay";
+};
+
+TX_UART1 {
+       status = "okay";
+};
+
+TX_UART2 {
+       status = "okay";
+       fsl,uart-has-rtscts;
+       uart-has-rtscts;
+};
+
+TX_UART3 {
+       status = "okay";
+};
+
+TX_USBOTG {
+       status = "okay";
+};
+
+TX_USBH {
+       status = "okay";
+};
+
+&iomuxc {
+       tx6 {
+               pinctrl_edt_ft5x06: edt-ft5x06grp {
+                       fsl,pins = <
+                               TX_GPIO_PAD148          /* Interrupt */
+                               TX_GPIO_PAD149          /* Reset */
+                               TX_GPIO_PAD152          /* Wake */
+                       >;
+               };
+
+               pinctrl_gpio_leds: gpioledsgrp {
+                       fsl,pins = <
+                               TX_GPIO_PAD153          /* LED Heartbeat */
+                       >;
+               };
+
+               pinctrl_lcd0_pwr: lcd0-pwrgrp {
+                       fsl,pins = <
+                               TX_GPIO_PAD150          /* LCD Reset */
+                       >;
+               };
+       };
+};
diff --git a/recipes-kernel/linux/linux-karo_4.9.11.bb b/recipes-kernel/linux/linux-karo_4.9.11.bb
new file mode 100644 (file)
index 0000000..0fad9fb
--- /dev/null
@@ -0,0 +1,63 @@
+# Copyright (C) 2013-2016 Freescale Semiconductor
+# Copyright 2017 NXP
+# Copyright 2018 kernel concepts GmbH
+# Released under the MIT license (see COPYING.MIT for the terms)
+
+SUMMARY = "Linux Kernel provided and supported by NXP"
+DESCRIPTION = "Linux Kernel provided and supported by NXP with focus on \
+i.MX Family Reference Boards. It includes support for many IPs such as GPU, VPU and IPU."
+
+require recipes-kernel/linux/linux-imx.inc
+
+SRC_URI = "git://source.codeaurora.org/external/imx/linux-imx;protocol=https;branch=${SRCBRANCH} \
+           file://set-enet_ref_clk-to-50-mhz.patch \
+           file://edt-ft5x06-make-distinction-between.patch \
+           file://edt-ft5x06-fixes.patch \
+           file://add-support-for-edt-m12-touch.patch \
+           file://ethernet-update-driver.patch \
+           file://defconfig \
+"
+
+DEPENDS += "lzop-native bc-native"
+
+SRCBRANCH = "imx_4.9.11_1.0.0_ga"
+LOCALVERSION = "-1.0.0"
+SRCREV = "c27010d99a3d91703ea2d1a3f9630a9dedc3f86f"
+
+KERNEL_EXTRA_ARGS += "LOADADDR=${UBOOT_ENTRYPOINT}"
+
+COMPATIBLE_MACHINE  = "(tx6[qus]-.*)"
+
+FILESEXTRAPATHS_prepend = "${THISDIR}/${P}/txbase/${TXBASE}:"
+
+KERNEL_IMAGETYPE = "uImage"
+
+# Add NXP binary blob driver for the Vivante GPU to the kernel image.
+# Otherwise settings in the Kernel defconfig are actively delete or ignored and
+# the required external LKM ([RFS]/lib/modules/<kernel-version>/extra) is not
+# available at all ( exception being if specific images are being "bitbaked"
+# like: fsl-image-multimedia-full )
+
+# Add Vivante GPU driver support
+# Handle Vivante kernel driver setting:
+#   0 - machine does not have Vivante GPU driver support
+#   1 - machine has Vivante GPU driver support
+MACHINE_HAS_VIVANTE_KERNEL_DRIVER_SUPPORT ?= "1"
+
+# Use Vivante kernel driver module:
+#   0 - enable the builtin kernel driver module
+#   1 - enable the external kernel module
+MACHINE_USES_VIVANTE_KERNEL_DRIVER_MODULE ?= "0"
+
+# Add TX6 module specific DT file(s)
+SRC_URI += "file://imx6qdl-tx6.dtsi;subdir=git/arch/arm/boot/dts \
+           file://imx6qdl-tx6-gpio.h;subdir=git/include/dt-bindings/gpio \
+          "
+
+# Add baseboard dtsi file(s)
+SRC_URI += "file://txbase-${TXBASE}.dtsi;subdir=git/arch/arm/boot/dts"
+
+# Add TX6 (machine) specific DTS file(s)
+SRC_URI += "file://${TXTYPE}-${TXNVM}-${TXBASE}.dts;subdir=git/arch/arm/boot/dts"
+
+KERNEL_DEVICETREE = "${TXTYPE}-${TXNVM}-${TXBASE}.dtb"