socfpga ethernet/MMC support for 3.8

Pavel Machek pavel at denx.de
Mon Mar 4 15:43:35 EST 2013


Hi!

Below are changes that get MMC/ethernet working for me. Probably not
everything is strictly neccessary, I'll try to prune them some more.

Strange thing is that enh_desc.c (disabling checksumming AFAICT) seems
to be neccessary for NFS to work.

In the meantime... does it make sense to split simple changes and
submit them upstream?

arch/arm/boot/dts/Makefile -- dtb files should be build, this can be
probably considered bugfix.

socfpga.c: socfpga_cyclone5_restart() -- this is self-contained reset
function marked with "TODO".

(patches are originally from Altera).
Signed-off-by: Pavel Machek <pavel at denx.de>
(but not for merge for now).

Thanks,
								Pavel

diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index 5ebb44f..d675c986 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -124,6 +124,9 @@ dtb-$(CONFIG_ARCH_SHMOBILE) += emev2-kzm9d.dtb \
 	r8a7740-armadillo800eva.dtb \
 	sh73a0-kzm9g.dtb \
 	sh7372-mackerel.dtb
+dtb-$(CONFIG_ARCH_SOCFPGA) += socfpga_cyclone5.dtb\
+	socfpga_ice.dtb\
+	socfpga_vt.dtb
 dtb-$(CONFIG_ARCH_SPEAR13XX) += spear1310-evb.dtb \
 	spear1340-evb.dtb
 dtb-$(CONFIG_ARCH_SPEAR3XX)+= spear300-evb.dtb \
diff --git a/arch/arm/boot/dts/socfpga.dtsi b/arch/arm/boot/dts/socfpga.dtsi
index 19aec42..c59ca7d 100644
--- a/arch/arm/boot/dts/socfpga.dtsi
+++ b/arch/arm/boot/dts/socfpga.dtsi
@@ -23,8 +23,13 @@
 
 	aliases {
 		ethernet0 = &gmac0;
+		ethernet1 = &gmac1;
 		serial0 = &uart0;
 		serial1 = &uart1;
+		timer0 = &timer0;
+		timer1 = &timer1;
+		timer2 = &timer2;
+		timer3 = &timer3;
 	};
 
 	cpus {
@@ -61,6 +66,21 @@
 		interrupt-parent = <&intc>;
 		ranges;
 
+		agpio0: gpio at 0xc0000000 {
+			compatible = "altr,pio-1.0";
+			/* Register base 0xff200000 is for a light-weight bridge */
+			reg = <0xff200000 0x10>;
+			width = <32>;
+			/* There are 64 interrupts from the FPGA start at 72, so 45 has to be wrong */
+			interrupts = <0 45 4>;
+			interrupt-controller;
+			#interrupt-cells = <1>;
+			gpio-controller;
+			#gpio-cells = <2>;
+			level_trigger = <0>;
+		};
+
+
 		amba {
 			compatible = "arm,amba-bus";
 			#address-cells = <1>;
@@ -74,13 +94,62 @@
 			};
 		};
 
-		gmac0: stmmac at ff700000 {
+		clkmgr at ffd04000 {
+				compatible = "altr,clk-mgr";
+				reg = <0xffd04000 0x1000>;
+			};
+
+
+		gmac0: ethernet at ff700000 {
 			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac";
 			reg = <0xff700000 0x2000>;
 			interrupts = <0 115 4>;
 			interrupt-names = "macirq";
 			mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
-			phy-mode = "gmii";
+		};
+
+		gmac1: ethernet at ff702000 {
+			compatible = "altr,socfpga-stmmac", "snps,dwmac-3.70a", "snps,dwmac";
+			reg = <0xff702000 0x2000>;
+			interrupts = <0 120 4>;
+			interrupt-names = "macirq";
+			mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
+		};
+
+		gpio0: gpio at ff708000 {
+			compatible = "snps,dw-gpio";
+			reg = <0xff708000 0x1000>;
+			interrupts = <0 164 4>;
+			width = <29>;
+			virtual_irq_start = <257>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpio1: gpio at ff709000 {
+			compatible = "snps,dw-gpio";
+			reg = <0xff709000 0x1000>;
+			interrupts = <0 165 4>;
+			width = <29>;
+			virtual_irq_start = <286>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			gpio-controller;
+			#gpio-cells = <2>;
+		};
+
+		gpio2: gpio at ff70a000 {
+			compatible = "snps,dw-gpio";
+			reg = <0xff70a000 0x1000>;
+			interrupts = <0 166 4>;
+			width = <27>;
+			virtual_irq_start = <315>;
+			interrupt-controller;
+			#interrupt-cells = <2>;
+			gpio-controller;
+			#gpio-cells = <2>;
 		};
 
 		L2: l2-cache at fffef000 {
@@ -89,6 +158,83 @@
 			interrupts = <0 38 0x04>;
 			cache-unified;
 			cache-level = <2>;
+			arm,tag-latency = <1 1 1>;
+			arm,data-latency = <2 1 1>;
+		};
+
+		mmc: dwmmc0 at ff704000 {
+			compatible = "snps,dw-mshc";
+			reg = <0xff704000 0x1000>;
+			interrupts = <0 139 4>;
+			bus-hz = <12500000>; /*12.5 MHz*/
+			#address-cells = <1>;
+			#size-cells = <0>;
+			num-slots = <1>;
+			supports-highspeed;
+			broken-cd;
+			fifo-depth = <0x400>;
+			slot at 0 {
+				reg = <0>;
+				bus-width = <4>;
+			};
+		};
+
+		nand: nand at ff900000 {
+			#address-cells = <1>;
+			#size-cells = <1>;
+			compatible = "denali,denali-nand-dt";
+			reg = <0xff900000 0x100000>, <0xffb80000 0x10000>;
+			reg-names = "nand_data", "denali_reg";
+			interrupts = <0 144 4>;
+			dma-mask = <0xffffffff>;
+			};
+
+		rstmgr at ffd05000 {
+			compatible = "altr,rst-mgr";
+			reg = <0xffd05000 0x1000>;
+		};
+
+		spi0: spi at fff00000 {
+			compatible = "snps,dw-spi-mmio";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xfff00000 0x1000>;
+			interrupts = <0 154 4>;
+			num-chipselect = <4>;
+			bus-num = <0>;
+			tx-dma-channel = <&pdma 16>;
+			rx-dma-channel = <&pdma 17>;
+
+			spidev at 0 {
+				compatible = "spidev";
+				reg = <0>;	/* chip select */
+				spi-max-frequency = <100000000>;
+				enable-dma = <1>;
+			};
+		};
+
+		spi1: spi at fff01000 {
+			compatible = "snps,dw-spi-mmio";
+			#address-cells = <1>;
+			#size-cells = <0>;
+			reg = <0xfff01000 0x1000>;
+			interrupts = <0 156 4>;
+			num-chipselect = <4>;
+			bus-num = <1>;
+			tx-dma-channel = <&pdma 20>;
+			rx-dma-channel = <&pdma 21>;
+
+			spidev at 0 {
+				compatible = "spidev";
+				reg = <0>;
+				spi-max-frequency = <100000000>;
+				enable-dma = <1>;
+			};
+		};
+		
+		sysmgr at ffd08000 {
+			compatible = "altr,sys-mgr";
+			reg = <0xffd08000 0x4000>;
 		};
 
 		/* Local timer */
@@ -98,60 +244,44 @@
 			interrupts = <1 13 0xf04>;
 		};
 
-		timer0: timer at ffc08000 {
+		timer0: timer0 at ffc08000 {
 			compatible = "snps,dw-apb-timer-sp";
 			interrupts = <0 167 4>;
-			clock-frequency = <200000000>;
 			reg = <0xffc08000 0x1000>;
 		};
 
-		timer1: timer at ffc09000 {
+		timer1: timer1 at ffc09000 {
 			compatible = "snps,dw-apb-timer-sp";
 			interrupts = <0 168 4>;
-			clock-frequency = <200000000>;
 			reg = <0xffc09000 0x1000>;
 		};
 
-		timer2: timer at ffd00000 {
+		timer2: timer2 at ffd00000 {
 			compatible = "snps,dw-apb-timer-osc";
 			interrupts = <0 169 4>;
-			clock-frequency = <200000000>;
 			reg = <0xffd00000 0x1000>;
 		};
 
-		timer3: timer at ffd01000 {
+		timer3: timer3 at ffd01000 {
 			compatible = "snps,dw-apb-timer-osc";
 			interrupts = <0 170 4>;
-			clock-frequency = <200000000>;
 			reg = <0xffd01000 0x1000>;
 		};
 
-		uart0: uart at ffc02000 {
+		uart0: serial0 at ffc02000 {
 			compatible = "snps,dw-apb-uart";
 			reg = <0xffc02000 0x1000>;
-			clock-frequency = <7372800>;
 			interrupts = <0 162 4>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
 		};
 
-		uart1: uart at ffc03000 {
+		uart1: serial1 at ffc03000 {
 			compatible = "snps,dw-apb-uart";
 			reg = <0xffc03000 0x1000>;
-			clock-frequency = <7372800>;
 			interrupts = <0 163 4>;
 			reg-shift = <2>;
 			reg-io-width = <4>;
 		};
-
-		rstmgr at ffd05000 {
-				compatible = "altr,rst-mgr";
-				reg = <0xffd05000 0x1000>;
-			};
-
-		sysmgr at ffd08000 {
-				compatible = "altr,sys-mgr";
-				reg = <0xffd08000 0x4000>;
-			};
 	};
 };
diff --git a/arch/arm/boot/dts/socfpga_cyclone5.dts b/arch/arm/boot/dts/socfpga_cyclone5.dts
index ab7e4a9..d29addc 100644
--- a/arch/arm/boot/dts/socfpga_cyclone5.dts
+++ b/arch/arm/boot/dts/socfpga_cyclone5.dts
@@ -26,9 +26,169 @@
 		bootargs = "console=ttyS0,57600";
 	};
 
-	memory {
-		name = "memory";
-		device_type = "memory";
-		reg = <0x0 0x10000000>; /* 256MB */
+	aliases {
+		/* this allow the ethaddr uboot environmnet variable contents
+		 * to be added to the gmac1 device tree blob.
+		 */
+		ethernet0 = &gmac1;
+	};
+
+	soc {
+		ethernet at ff700000 {
+			status = "disabled";
+		};
+
+		ethernet at ff702000 {
+			phy-mode = "rgmii";
+			phy-addr = <0xffffffff>; /* probe for phy addr */
+		};
+
+		qspi: spi at ff705000 {
+				compatible = "cadence,qspi";
+				#address-cells = <1>;
+				#size-cells = <0>;
+				reg = <0xff705000 0x1000>,
+					<0xffa00000 0x1000>;
+				interrupts = <0 151 4>;
+				master-ref-clk = <400000000>;
+				ext-decoder = <0>;  /* external decoder */
+				num-chipselect = <4>;
+				fifo-depth = <128>;
+				bus-num = <2>;
+
+				flash0: n25q128 at 0 {
+					#address-cells = <1>;
+					#size-cells = <1>;
+					compatible = "n25q128";
+					reg = <0>;	/* chip select */
+					spi-max-frequency = <100000000>;
+					page-size = <256>;
+					block-size = <16>; /* 2^16, 64KB */
+					quad = <1>;	   /* 1-support quad */
+					tshsl-ns = <200>;
+					tsd2d-ns = <255>;
+					tchsh-ns = <20>;
+					tslch-ns = <20>;
+
+					partition at 0 {
+						/* 8MB for raw data. */
+						label = "Flash 0 Raw Data";
+						reg = <0x0 0x800000>;
+					};
+					partition at 800000 {
+						/* 8MB for jffs2 data. */
+						label = "Flash 0 jffs2 Filesystem";
+						reg = <0x800000 0x800000>;
+					};
+				};
+
+				flash1: n25q128 at 1 {
+					#address-cells = <1>;
+					#size-cells = <1>;
+					compatible = "n25q128";
+					reg = <1>;	/* chip select */
+					spi-max-frequency = <100000000>;
+					page-size = <256>;
+					block-size = <16>; /* 2^16, 64KB */
+					quad = <1>;
+					tshsl-ns = <200>;
+					tsd2d-ns = <255>;
+					tchsh-ns = <20>;
+					tslch-ns = <20>;
+
+					partition at 0 {
+						/* 16MB for user data. */
+						label = "Flash 1 User Data";
+						reg = <0x0 0x1000000>;
+					};
+				};
+			};
+
+		timer0 at ffc08000 {
+			clock-frequency = <100000000>;
+		};
+
+		timer1 at ffc09000 {
+			clock-frequency = <100000000>;
+		};
+
+		timer2 at ffd00000 {
+			clock-frequency = <25000000>;
+		};
+
+		timer3 at ffd01000 {
+			clock-frequency = <25000000>;
+		};
+
+		serial0 at ffc02000 {
+			clock-frequency = <100000000>;
+		};
+
+		serial1 at ffc03000 {
+			clock-frequency = <100000000>;
+		};
+
+		i2c0: i2c at ffc04000 {
+			speed-mode = <0>;
+		};
+
+		leds {
+			compatible = "gpio-leds";
+			fpga0 {
+				label = "fpga_led0";
+				gpios = <&agpio0 0 1>;
+			};
+
+			fpga1 {
+				label = "fpga_led1";
+				gpios = <&agpio0 1 1>;
+			};
+
+			fpga2 {
+				label = "fpga_led2";
+				gpios = <&agpio0 2 1>;
+			};
+
+			fpga3 {
+				label = "fpga_led3";
+				gpios = <&agpio0 3 1>;
+			};
+
+			hps0 {
+				label = "hps_led0";
+				gpios = <&gpio1 15 1>;
+			};
+
+			hps1 {
+				label = "hps_led1";
+				gpios = <&gpio1 14 1>;
+			};
+
+			hps2 {
+				label = "hps_led2";
+				gpios = <&gpio1 13 1>;
+			};
+
+			hps3 {
+				label = "hps_led3";
+				gpios = <&gpio1 12 1>;
+			};
+		};
+	};
+};
+
+&i2c0 {
+	lcd: lcd at 28 {
+		compatible = "newhaven,nhd-0216k3z-nsw-bbw";
+		reg = <0x28>;
+		height = <2>;
+		width = <16>;
+		brightness = <8>;
+	};
+
+	eeprom at 51 {
+		compatible = "atmel,24c32";
+		reg = <0x51>;
+		pagesize = <32>;
 	};
 };
diff --git a/arch/arm/mach-socfpga/core.h b/arch/arm/mach-socfpga/core.h
index 9941caa..e297307 100644
--- a/arch/arm/mach-socfpga/core.h
+++ b/arch/arm/mach-socfpga/core.h
@@ -24,11 +24,34 @@ extern void secondary_startup(void);
 extern void __iomem *socfpga_scu_base_addr;
 
 extern void socfpga_init_clocks(void);
-extern void socfpga_sysmgr_init(void);
+//extern void socfpga_sysmgr_init(void);
 
 extern struct smp_operations socfpga_smp_ops;
 extern char secondary_trampoline, secondary_trampoline_end;
 
 #define SOCFPGA_SCU_VIRT_BASE   0xfffec000
 
+
+#define SOCFPGA_RSTMGR_CTRL	0x04
+#define SOCFPGA_RSTMGR_MODPERRST	0x14
+#define SOCFPGA_RSTMGR_BRGMODRST	0x1c
+
+/* System Manager bits */
+#define RSTMGR_CTRL_SWCOLDRSTREQ	0x1	/* Cold Reset */
+#define RSTMGR_CTRL_SWWARMRSTREQ	0x2	/* Warm Reset */
+/*MPU Module Reset Register */
+ #define RSTMGR_MPUMODRST_CPU0	0x1	/*CPU0 Reset*/
+ #define RSTMGR_MPUMODRST_CPU1	0x2	/*CPU1 Reset*/
+ #define RSTMGR_MPUMODRST_WDS		0x4	/*Watchdog Reset*/
+ #define RSTMGR_MPUMODRST_SCUPER	0x8	/*SCU and periphs reset*/
+ #define RSTMGR_MPUMODRST_L2		0x10	/*L2 Cache reset*/
+
+#define SYSMGR_EMACGRP_CTRL_OFFSET 0x60
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII 0x0
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII 0x1
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RMII 0x2
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_WIDTH 2
+
+#define SYSMGR_EMACGRP_CTRL_PHYSEL_MASK 0x00000003
+
 #endif
diff --git a/arch/arm/mach-socfpga/socfpga.c b/arch/arm/mach-socfpga/socfpga.c
index 6732924..4d41642 100644
--- a/arch/arm/mach-socfpga/socfpga.c
+++ b/arch/arm/mach-socfpga/socfpga.c
@@ -17,12 +17,19 @@
 #include <linux/dw_apb_timer.h>
 #include <linux/of_address.h>
 #include <linux/of_irq.h>
+#include <linux/of_address.h>
 #include <linux/of_platform.h>
+#include <linux/of_net.h>
+#include <linux/stmmac.h>
+#include <linux/phy.h>
+#include <linux/micrel_phy.h>
+
 
 #include <asm/hardware/cache-l2x0.h>
 #include <asm/hardware/gic.h>
 #include <asm/mach/arch.h>
 #include <asm/mach/map.h>
+#include <asm/smp_twd.h>
 
 #include "core.h"
 
@@ -30,6 +37,29 @@ void __iomem *socfpga_scu_base_addr = ((void __iomem *)(SOCFPGA_SCU_VIRT_BASE));
 void __iomem *sys_manager_base_addr;
 void __iomem *rst_manager_base_addr;
 
+static int socfpga_phy_reset_mii(struct mii_bus *bus, int phyaddr);
+static int stmmac_plat_init(struct platform_device *pdev);
+
+static struct stmmac_mdio_bus_data stmmacenet_mdio_bus_data = {
+	.phy_reset_mii = socfpga_phy_reset_mii,
+};
+
+static struct plat_stmmacenet_data stmmacenet0_data = {
+	.mdio_bus_data = &stmmacenet_mdio_bus_data,
+	.init = &stmmac_plat_init,
+};
+
+static struct plat_stmmacenet_data stmmacenet1_data = {
+	.mdio_bus_data = &stmmacenet_mdio_bus_data,
+	.init = &stmmac_plat_init,
+};
+
+static const struct of_dev_auxdata socfpga_auxdata_lookup[] __initconst = {
+	OF_DEV_AUXDATA("snps,dwmac-3.70a", 0xff700000, NULL, &stmmacenet0_data),
+	OF_DEV_AUXDATA("snps,dwmac-3.70a", 0xff702000, NULL, &stmmacenet1_data),
+	{ /* sentinel */ }
+};
+ 
 static struct map_desc scu_io_desc __initdata = {
 	.virtual	= SOCFPGA_SCU_VIRT_BASE,
 	.pfn		= 0, /* run-time */
@@ -55,19 +85,126 @@ static void __init socfpga_scu_map_io(void)
 	iotable_init(&scu_io_desc, 1);
 }
 
-static void __init socfpga_map_io(void)
+static void __init enable_periphs(void)
 {
-	socfpga_scu_map_io();
-	iotable_init(&uart_io_desc, 1);
-	early_printk("Early printk initialized\n");
+	/* Release all peripherals from reset.*/
+	__raw_writel(0, rst_manager_base_addr + SOCFPGA_RSTMGR_MODPERRST);
+
+	/* Release all FPGA bridges from reset.*/
+	__raw_writel(0, rst_manager_base_addr + SOCFPGA_RSTMGR_BRGMODRST);
 }
 
-const static struct of_device_id irq_match[] = {
-	{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
-	{}
-};
+static int stmmac_mdio_write_null(struct mii_bus *bus, int phyaddr, int phyreg,
+			     u16 phydata)
+{
+	return 0;
+}
+
+#define MICREL_KSZ9021_EXTREG_CTRL 11
+#define MICREL_KSZ9021_EXTREG_DATA_WRITE 12
+#define MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW 260
+#define MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW 261
 
-void __init socfpga_sysmgr_init(void)
+static int stmmac_emdio_write(struct mii_bus *bus, int phyaddr, int phyreg,
+			     u16 phydata)
+{
+	int ret = (bus->write)(bus, phyaddr,
+		MICREL_KSZ9021_EXTREG_CTRL, 0x8000|phyreg);
+	if (ret) {
+		pr_warn("stmmac_emdio_write write1 failed %d\n", ret);
+		return ret;
+	}
+
+	ret = (bus->write)(bus, phyaddr,
+		MICREL_KSZ9021_EXTREG_DATA_WRITE, phydata);
+	if (ret) {
+		pr_warn("stmmac_emdio_write write2 failed %d\n", ret);
+		return ret;
+	}
+
+	return ret;
+}
+
+static int socfpga_phy_reset_mii(struct mii_bus *bus, int phyaddr)
+{
+	struct phy_device *phydev;
+
+	if (of_machine_is_compatible("altr,socfpga-vt"))
+		return 0;
+
+	phydev = bus->phy_map[phyaddr];
+
+	if (NULL == phydev) {
+		pr_err("%s no phydev found\n", __func__);
+		return -EINVAL;
+	}
+
+	if (PHY_ID_KSZ9021RLRN != phydev->phy_id) {
+		pr_err("%s unexpected PHY ID %08x\n", __func__, phydev->phy_id);
+		return -EINVAL;
+	}
+
+	pr_info("%s writing extended registers to phyaddr %d\n",
+		__func__, phyaddr);
+
+	/* add 2 ns of RXC PAD Skew and 2.6 ns of TXC PAD Skew */
+	stmmac_emdio_write(bus, phyaddr,
+		MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW, 0xa0d0);
+
+	/* set no PAD skew for data */
+	stmmac_emdio_write(bus, phyaddr,
+		MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW, 0x0000);
+
+	bus->write = &stmmac_mdio_write_null;
+	return 0;
+}
+
+static int stmmac_plat_init(struct platform_device *pdev)
+{
+	u32 ctrl, val, shift;
+	int phymode;
+
+	if (of_machine_is_compatible("altr,socfpga-vt"))
+		return 0;
+
+	phymode = of_get_phy_mode(pdev->dev.of_node);
+
+	switch (phymode) {
+	case PHY_INTERFACE_MODE_RGMII:
+		val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_RGMII;
+		break;
+	case PHY_INTERFACE_MODE_MII:
+	case PHY_INTERFACE_MODE_GMII:
+		val = SYSMGR_EMACGRP_CTRL_PHYSEL_ENUM_GMII_MII;
+		break;
+	default:
+		pr_err("%s bad phy mode %d", __func__, phymode);
+		return -EINVAL;
+	}
+
+	if (&stmmacenet1_data == pdev->dev.platform_data)
+		shift = SYSMGR_EMACGRP_CTRL_PHYSEL_WIDTH;
+	else if (&stmmacenet0_data == pdev->dev.platform_data)
+		shift = 0;
+	else {
+		pr_err("%s unexpected platform data pointer\n", __func__);
+		return -EINVAL;
+	}
+
+	ctrl =  __raw_readl(sys_manager_base_addr +
+		SYSMGR_EMACGRP_CTRL_OFFSET);
+
+	ctrl &= ~(SYSMGR_EMACGRP_CTRL_PHYSEL_MASK << shift);
+
+	ctrl |= (val << shift);
+
+	__raw_writel(ctrl, (sys_manager_base_addr +
+		SYSMGR_EMACGRP_CTRL_OFFSET));
+
+	return 0;
+}
+
+static void __init socfpga_sysmgr_init(void)
 {
 	struct device_node *np;
 
@@ -78,27 +215,58 @@ void __init socfpga_sysmgr_init(void)
 	rst_manager_base_addr = of_iomap(np, 0);
 }
 
+static void __init socfpga_map_io(void)
+{
+	socfpga_scu_map_io();
+	iotable_init(&uart_io_desc, 1);
+	early_printk("Early printk initialized\n");
+}
+
+const static struct of_device_id irq_match[] = {
+	{ .compatible = "arm,cortex-a9-gic", .data = gic_of_init, },
+	{}
+};
+
 static void __init gic_init_irq(void)
 {
 	of_irq_init(irq_match);
 	socfpga_sysmgr_init();
+	socfpga_init_clocks();
+	twd_local_timer_of_register();
 }
 
 static void socfpga_cyclone5_restart(char mode, const char *cmd)
 {
-	/* TODO: */
+	u32 temp;
+
+	temp = __raw_readl(rst_manager_base_addr + SOCFPGA_RSTMGR_CTRL);
+
+	if (mode == 'h')
+		temp |= RSTMGR_CTRL_SWCOLDRSTREQ;
+	else
+		temp |= RSTMGR_CTRL_SWWARMRSTREQ;
+	__raw_writel(temp, rst_manager_base_addr + SOCFPGA_RSTMGR_CTRL);
 }
 
 static void __init socfpga_cyclone5_init(void)
 {
-	l2x0_of_init(0, ~0UL);
-	of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-	socfpga_init_clocks();
+#ifdef CONFIG_CACHE_L2X0
+	u32 aux_ctrl = 0;
+	aux_ctrl |= (1 << L2X0_AUX_CTRL_DATA_PREFETCH_SHIFT) |
+			(1 << L2X0_AUX_CTRL_INSTR_PREFETCH_SHIFT);
+	l2x0_of_init(aux_ctrl, ~0UL);
+#endif
+	of_platform_populate(NULL, of_default_bus_match_table,
+		socfpga_auxdata_lookup, NULL);
+
+	enable_periphs();
 }
 
 static const char *altera_dt_match[] = {
 	"altr,socfpga",
 	"altr,socfpga-cyclone5",
+	"altr,socfpga-vt",
+	"altr,socfpga-ice",
 	NULL
 };
 
diff --git a/drivers/clk/socfpga/clk.c b/drivers/clk/socfpga/clk.c
index 2c855a6..30c76c4 100644
--- a/drivers/clk/socfpga/clk.c
+++ b/drivers/clk/socfpga/clk.c
@@ -17,6 +17,11 @@
 #include <linux/clk.h>
 #include <linux/clkdev.h>
 #include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+
+static DEFINE_SPINLOCK(_lock);
 
 #define SOCFPGA_OSC1_CLK	10000000
 #define SOCFPGA_MPU_CLK		800000000
@@ -24,28 +29,124 @@
 #define SOCFPGA_MAIN_NAND_SDMMC_CLK	250000000
 #define SOCFPGA_S2F_USR_CLK		125000000
 
+#define SOCFPGA_MAIN_PLL_CLK		1200000000
+#define SOCFPGA_PER_PLL_CLK		900000000
+#define SOCFPGA_SDRAM_PLL_CLK		800000000
+
+#define CLKMGR_PERPLLGRP_EN	0xA0
+
+#define CLKMGR_QSPI_CLK_EN				11
+#define CLKMGR_NAND_CLK_EN				10
+#define CLKMGR_NAND_X_CLK_EN			9
+#define CLKMGR_SDMMC_CLK_EN			8
+#define CLKMGR_S2FUSR_CLK_EN			7
+#define CLKMGR_GPIO_CLK_EN				6
+#define CLKMGR_CAN1_CLK_EN				5
+#define CLKMGR_CAN0_CLK_EN				4
+#define CLKMGR_SPI_M_CLK_EN			3
+#define CLKMGR_USB_MP_CLK_EN			2
+#define CLKMGR_EMAC1_CLK_EN			1
+#define CLKMGR_EMAC0_CLK_EN			0
+
+void __iomem *clk_mgr_base_addr;
+
 void __init socfpga_init_clocks(void)
 {
 	struct clk *clk;
+	struct device_node *np;
 
-	clk = clk_register_fixed_rate(NULL, "osc1_clk", NULL, CLK_IS_ROOT, SOCFPGA_OSC1_CLK);
+	np = of_find_compatible_node(NULL, NULL, "altr,clk-mgr");
+	clk_mgr_base_addr = of_iomap(np, 0);
+
+	clk = clk_register_fixed_rate(NULL, "main_pll_clk", NULL, CLK_IS_ROOT,
+			SOCFPGA_MAIN_PLL_CLK);
+	clk_register_clkdev(clk, "main_pll_clk", NULL);
+
+	clk = clk_register_fixed_rate(NULL, "per_pll_clk", NULL, CLK_IS_ROOT,
+			SOCFPGA_PER_PLL_CLK);
+	clk_register_clkdev(clk, "per_pll_clk", NULL);
+
+	clk = clk_register_fixed_rate(NULL, "sdram_pll_clk", NULL, CLK_IS_ROOT,
+			SOCFPGA_SDRAM_PLL_CLK);
+	clk_register_clkdev(clk, "sdram_pll_clk", NULL);
+
+	clk = clk_register_fixed_rate(NULL, "osc1_clk", NULL, CLK_IS_ROOT,
+			SOCFPGA_OSC1_CLK);
 	clk_register_clkdev(clk, "osc1_clk", NULL);
 
-	clk = clk_register_fixed_rate(NULL, "mpu_clk", NULL, CLK_IS_ROOT, SOCFPGA_MPU_CLK);
+	clk = clk_register_fixed_rate(NULL, "mpu_clk", NULL, CLK_IS_ROOT,
+			SOCFPGA_MPU_CLK);
 	clk_register_clkdev(clk, "mpu_clk", NULL);
 
-	clk = clk_register_fixed_rate(NULL, "main_clk", NULL, CLK_IS_ROOT, SOCFPGA_MPU_CLK/2);
+	clk = clk_register_fixed_rate(NULL, "main_clk", NULL, CLK_IS_ROOT,
+			SOCFPGA_MPU_CLK/2);
 	clk_register_clkdev(clk, "main_clk", NULL);
 
-	clk = clk_register_fixed_rate(NULL, "dbg_base_clk", NULL, CLK_IS_ROOT, SOCFPGA_MPU_CLK/2);
+	clk = clk_register_fixed_rate(NULL, "dbg_base_clk", NULL, CLK_IS_ROOT,
+			SOCFPGA_MPU_CLK/2);
 	clk_register_clkdev(clk, "dbg_base_clk", NULL);
 
-	clk = clk_register_fixed_rate(NULL, "main_qspi_clk", NULL, CLK_IS_ROOT, SOCFPGA_MAIN_QSPI_CLK);
+	clk = clk_register_fixed_rate(NULL, "smp_twd", NULL, CLK_IS_ROOT,
+			SOCFPGA_MPU_CLK/4);
+	clk_register_clkdev(clk, NULL, "smp_twd");
+
+	clk = clk_register_fixed_rate(NULL, "main_qspi_clk", NULL, CLK_IS_ROOT,
+			SOCFPGA_MAIN_QSPI_CLK);
 	clk_register_clkdev(clk, "main_qspi_clk", NULL);
 
-	clk = clk_register_fixed_rate(NULL, "main_nand_sdmmc_clk", NULL, CLK_IS_ROOT, SOCFPGA_MAIN_NAND_SDMMC_CLK);
+	clk = clk_register_fixed_rate(NULL, "main_nand_sdmmc_clk", NULL,
+			CLK_IS_ROOT, SOCFPGA_MAIN_NAND_SDMMC_CLK);
 	clk_register_clkdev(clk, "main_nand_sdmmc_clk", NULL);
 
-	clk = clk_register_fixed_rate(NULL, "s2f_usr_clk", NULL, CLK_IS_ROOT, SOCFPGA_S2F_USR_CLK);
+	clk = clk_register_fixed_rate(NULL, "s2f_usr_clk", NULL, CLK_IS_ROOT,
+			SOCFPGA_S2F_USR_CLK);
 	clk_register_clkdev(clk, "s2f_usr_clk", NULL);
+
+	clk = clk_register_fixed_rate(NULL, "i2c0_clk", NULL, CLK_IS_ROOT,
+			SOCFPGA_PER_PLL_CLK);
+	clk_register_clkdev(clk, NULL, "ffc04000.i2c");
+
+	clk = clk_register_fixed_rate(NULL, "i2c1_clk", NULL, CLK_IS_ROOT,
+			SOCFPGA_PER_PLL_CLK);
+	clk_register_clkdev(clk, NULL, "ffc05000.i2c");
+
+	clk = clk_register_gate(NULL, "gmac0_clk", "per_pll_clk", 0,
+			clk_mgr_base_addr + CLKMGR_PERPLLGRP_EN,
+			CLKMGR_EMAC0_CLK_EN, 0, &_lock);
+	clk_register_clkdev(clk, NULL, "ff700000.ethernet");
+
+	clk = clk_register_gate(NULL, "gmac1_clk", "per_pll_clk", 0,
+			clk_mgr_base_addr + CLKMGR_PERPLLGRP_EN,
+			CLKMGR_EMAC1_CLK_EN, 0, &_lock);
+	clk_register_clkdev(clk, NULL, "ff702000.ethernet");
+
+	clk = clk_register_gate(NULL, "spi0_clk", "per_pll_clk", 0,
+			clk_mgr_base_addr + CLKMGR_PERPLLGRP_EN,
+			CLKMGR_SPI_M_CLK_EN, 0, &_lock);
+	clk_register_clkdev(clk, NULL, "fff00000.spi");
+
+	clk = clk_register_gate(NULL, "spi1_clk", "per_pll_clk", 0,
+			clk_mgr_base_addr + CLKMGR_PERPLLGRP_EN,
+			CLKMGR_SPI_M_CLK_EN, 0, &_lock);
+	clk_register_clkdev(clk, NULL, "fff01000.spi");
+
+	clk = clk_register_gate(NULL, "gpio0_clk", "per_pll_clk", 0,
+			clk_mgr_base_addr + CLKMGR_PERPLLGRP_EN,
+			CLKMGR_GPIO_CLK_EN, 0, &_lock);
+	clk_register_clkdev(clk, NULL, "ff708000.gpio");
+
+	clk = clk_register_gate(NULL, "gpio1_clk", "per_pll_clk", 0,
+			clk_mgr_base_addr + CLKMGR_PERPLLGRP_EN,
+			CLKMGR_GPIO_CLK_EN, 0, &_lock);
+	clk_register_clkdev(clk, NULL, "ff709000.gpio");
+
+	clk = clk_register_gate(NULL, "gpio2_clk", "per_pll_clk", 0,
+			clk_mgr_base_addr + CLKMGR_PERPLLGRP_EN,
+			CLKMGR_GPIO_CLK_EN, 0, &_lock);
+	clk_register_clkdev(clk, NULL, "ff70a000.gpio");
+
+	clk = clk_register_gate(NULL, "nand_clk", "main_nand_sdmmc_clk", 0,
+			clk_mgr_base_addr + CLKMGR_PERPLLGRP_EN,
+			CLKMGR_NAND_CLK_EN, 0, &_lock);
+	clk_register_clkdev(clk, NULL, "ff900000.nand");
 }
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c
index 323c502..c199847 100644
--- a/drivers/mmc/host/dw_mmc.c
+++ b/drivers/mmc/host/dw_mmc.c
@@ -38,9 +38,14 @@
 #include "dw_mmc.h"
 
 /* Common flag combinations */
-#define DW_MCI_DATA_ERROR_FLAGS	(SDMMC_INT_DTO | SDMMC_INT_DCRC | \
-				 SDMMC_INT_HTO | SDMMC_INT_SBE  | \
-				 SDMMC_INT_EBE)
+
+/* According to Synopsys, the data starvation interrupt (HTO) should not treat
+ * as error. Software should continue the data transfer. We have verified this
+ * in Virtual Target. The same is applied to FIFO under/overrun (FRUN) as well.
+ */
+#define DW_MCI_DATA_ERROR_FLAGS (SDMMC_INT_DTO | SDMMC_INT_DCRC | \
+				 SDMMC_INT_HTO | SDMMC_INT_FRUN | SDMMC_INT_SBE | SDMMC_INT_EBE)
+
 #define DW_MCI_CMD_ERROR_FLAGS	(SDMMC_INT_RTO | SDMMC_INT_RCRC | \
 				 SDMMC_INT_RESP_ERR)
 #define DW_MCI_ERROR_FLAGS	(DW_MCI_DATA_ERROR_FLAGS | \
@@ -265,6 +270,9 @@ static u32 dw_mci_prepare_command(struct mmc_host *mmc, struct mmc_command *cmd)
 	if (drv_data && drv_data->prepare_command)
 		drv_data->prepare_command(slot->host, &cmdr);
 
+	if (slot->host->use_hold_reg)
+		cmdr |= SDMMC_CMD_USE_HOLD_REG;
+
 	return cmdr;
 }
 
@@ -2047,6 +2055,16 @@ static struct dw_mci_board *dw_mci_parse_dt(struct dw_mci *host)
 		return ERR_PTR(-ENOMEM);
 	}
 
+	if (of_property_read_u32(dev->of_node, "bus-hz", &pdata->bus_hz)) {
+		dev_err(dev, "couldn't determine bus-hz\n");
+		pdata->bus_hz = 50000000;
+	}
+
+	if (of_property_read_u32(dev->of_node, "pwr-en", &pdata->pwr_en)) {
+		dev_info(dev, "couldn't determine pwr-en, assuming pwr-en = 0\n");
+		pdata->pwr_en = 0;
+	}
+
 	/* find out number of slots supported */
 	if (of_property_read_u32(dev->of_node, "num-slots",
 				&pdata->num_slots)) {
@@ -2183,6 +2201,9 @@ int dw_mci_probe(struct dw_mci *host)
 		host->data_shift = 2;
 	}
 
+	/* Get the USE_HOLD_REG */
+	host->use_hold_reg = mci_readl(host, CMD) & SDMMC_CMD_USE_HOLD_REG;
+
 	/* Reset all blocks */
 	if (!mci_wait_reset(host->dev, host))
 		return -ENODEV;
@@ -2194,6 +2215,9 @@ int dw_mci_probe(struct dw_mci *host)
 	mci_writel(host, RINTSTS, 0xFFFFFFFF);
 	mci_writel(host, INTMASK, 0); /* disable all mmc interrupt first */
 
+	/* Set PWREN bit */
+	mci_writel(host, PWREN, host->pdata->pwr_en);
+
 	/* Put in max timeout */
 	mci_writel(host, TMOUT, 0xFFFFFFFF);
 
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h
index 53b8fd9..6172900 100644
--- a/drivers/mmc/host/dw_mmc.h
+++ b/drivers/mmc/host/dw_mmc.h
@@ -111,6 +111,7 @@
 #define SDMMC_INT_ERROR			0xbfc2
 /* Command register defines */
 #define SDMMC_CMD_START			BIT(31)
+#define SDMMC_CMD_USE_HOLD_REG		BIT(29)
 #define SDMMC_CMD_CCS_EXP		BIT(23)
 #define SDMMC_CMD_CEATA_RD		BIT(22)
 #define SDMMC_CMD_UPD_CLK		BIT(21)
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
index 7ad56af..03846dc 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000.h
@@ -228,6 +228,9 @@ enum rtc_control {
 #define GMAC_MMC_CTRL      0x100
 #define GMAC_MMC_RX_INTR   0x104
 #define GMAC_MMC_TX_INTR   0x108
+#define GMAC_MMC_INTR_MASK_RX		  0x10C
+#define GMAC_MMC_INTR_MASK_TX		  0x110
+#define GMAC_MMC_IPC_INTR_MASK_RX  0x200
 #define GMAC_MMC_RX_CSUM_OFFLOAD   0x208
 
 extern const struct stmmac_dma_ops dwmac1000_dma_ops;
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
index bfe0226..ade7bfb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c
@@ -40,6 +40,11 @@ static void dwmac1000_core_init(void __iomem *ioaddr)
 	/* Mask GMAC interrupts */
 	writel(0x207, ioaddr + GMAC_INT_MASK);
 
+	/* mask out interrupts because we don't handle them yet */
+	writel(~0UL, ioaddr + GMAC_MMC_INTR_MASK_RX);
+	writel(~0UL, ioaddr + GMAC_MMC_INTR_MASK_TX);
+	writel(~0UL, ioaddr + GMAC_MMC_IPC_INTR_MASK_RX);
+
 #ifdef STMMAC_VLAN_TAG_USED
 	/* Tag detection without filtering */
 	writel(0x0, ioaddr + GMAC_VLAN_TAG);
@@ -198,6 +203,7 @@ static int dwmac1000_irq_status(void __iomem *ioaddr)
 {
 	u32 intr_status = readl(ioaddr + GMAC_INT_STATUS);
 	int status = 0;
+	u32 value;
 
 	/* Not used events (e.g. MMC interrupts) are not handled. */
 	if ((intr_status & mmc_tx_irq)) {
@@ -222,6 +228,11 @@ static int dwmac1000_irq_status(void __iomem *ioaddr)
 		readl(ioaddr + GMAC_PMT);
 		status |= core_irq_receive_pmt_irq;
 	}
+	if (unlikely(intr_status & rgmii_irq)) {
+		CHIP_DBG(KERN_INFO "GMAC: Interrupt Status\n");
+		/* clear this link change interrupt because we are not handling it yet. */
+		value = readl(ioaddr + GMAC_GMII_STATUS);
+	}
 	/* MAC trx/rx EEE LPI entry/exit interrupts */
 	if (intr_status & lpiis_irq) {
 		/* Clean LPI interrupt by reading the Reg 12 */
diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
index 2fc8ef9..6996b2e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
+++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c
@@ -145,7 +145,11 @@ static int enh_desc_coe_rdes0(int ipc_err, int type, int payload_err)
 		ret = discard_frame;
 	} else if (status == 0x3) {
 		CHIP_DBG(KERN_ERR "RX Des0 status: No IPv4, IPv6 frame.\n");
+#ifdef CONFIG_ARCH_SOCFPGA
+		ret = csum_none;
+#else
 		ret = discard_frame;
+#endif
 	}
 	return ret;
 }
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index 0b9829f..294060e 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -242,6 +242,11 @@ int stmmac_mdio_register(struct net_device *ndev)
 		return -ENODEV;
 	}
 
+	if (priv->plat->mdio_bus_data->phy_reset_mii) {
+		priv->plat->mdio_bus_data->phy_reset_mii(new_bus,
+			priv->plat->phy_addr);
+	}
+
 	priv->mii = new_bus;
 
 	return 0;
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index b43d68b..e7b455a 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -34,15 +34,18 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
 				  const char **mac)
 {
 	struct device_node *np = pdev->dev.of_node;
+	u32 phyaddr;
 
 	if (!np)
 		return -ENODEV;
 
 	*mac = of_get_mac_address(np);
 	plat->interface = of_get_phy_mode(np);
-	plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
+	if (NULL == plat->mdio_bus_data) {
+		plat->mdio_bus_data = devm_kzalloc(&pdev->dev,
 					   sizeof(struct stmmac_mdio_bus_data),
 					   GFP_KERNEL);
+	}
 
 	/*
 	 * Currently only the properties needed on SPEAr600
@@ -56,6 +59,17 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
 		plat->pmt = 1;
 	}
 
+	if (0 == of_property_read_u32(np, "phy-addr", &phyaddr)) {
+		if ((-1 == phyaddr) ||
+			((phyaddr >= 0) && (phyaddr < PHY_MAX_ADDR))) {
+			plat->phy_addr = phyaddr;
+		} else {
+			pr_err("%s: ERROR: bad phy address: %d\n",
+				__func__, phyaddr);
+			return -EINVAL;
+		}
+	}
+
 	return 0;
 }
 #else
@@ -94,10 +108,14 @@ static int stmmac_pltfr_probe(struct platform_device *pdev)
 		return -ENOMEM;
 	}
 
+	plat_dat = pdev->dev.platform_data;
+
 	if (pdev->dev.of_node) {
-		plat_dat = devm_kzalloc(&pdev->dev,
+		if (NULL == plat_dat) {
+			plat_dat = devm_kzalloc(&pdev->dev,
 					sizeof(struct plat_stmmacenet_data),
 					GFP_KERNEL);
+		}
 		if (!plat_dat) {
 			pr_err("%s: ERROR: no memory", __func__);
 			return  -ENOMEM;
@@ -108,8 +126,6 @@ static int stmmac_pltfr_probe(struct platform_device *pdev)
 			pr_err("%s: main dt probe failed", __func__);
 			return ret;
 		}
-	} else {
-		plat_dat = pdev->dev.platform_data;
 	}
 
 	/* Custom initialisation (if needed)*/
diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h
index adfe8c0..f699596 100644
--- a/include/linux/micrel_phy.h
+++ b/include/linux/micrel_phy.h
@@ -17,6 +17,7 @@
 
 #define PHY_ID_KSZ8873MLL	0x000e7237
 #define PHY_ID_KSZ9021		0x00221610
+#define PHY_ID_KSZ9021RLRN	0x00221611
 #define PHY_ID_KS8737		0x00221720
 #define PHY_ID_KSZ8021		0x00221555
 #define PHY_ID_KSZ8041		0x00221510
diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h
index 34be4f4..cf22d32 100644
--- a/include/linux/mmc/dw_mmc.h
+++ b/include/linux/mmc/dw_mmc.h
@@ -187,6 +187,11 @@ struct dw_mci {
 	struct regulator	*vmmc;	/* Power regulator */
 	unsigned long		irq_flags; /* IRQ flags */
 	int			irq;
+
+	/* Set to one for SDR12 and SDR25 */
+	unsigned int use_hold_reg;
+	/*Card needs power enable bit */
+	u32 pwr_en;
 };
 
 /* DMA ops for Internal/External DMAC interface */
@@ -228,6 +233,8 @@ struct dw_mci_board {
 
 	u32 quirks; /* Workaround / Quirk flags */
 	unsigned int bus_hz; /* Clock speed at the cclk_in pad */
+	/*Card needs power enable bit */
+	u32 pwr_en;
 
 	u32 caps;	/* Capabilities */
 	u32 caps2;	/* More capabilities */
diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h
index c1b3ed3..3666be2 100644
--- a/include/linux/stmmac.h
+++ b/include/linux/stmmac.h
@@ -27,6 +27,8 @@
 #define __STMMAC_PLATFORM_DATA
 
 #include <linux/platform_device.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
 
 #define STMMAC_RX_COE_NONE	0
 #define STMMAC_RX_COE_TYPE1	1
@@ -77,6 +79,7 @@
 
 struct stmmac_mdio_bus_data {
 	int (*phy_reset)(void *priv);
+	int (*phy_reset_mii)(struct mii_bus *bus, int phyaddr);
 	unsigned int phy_mask;
 	int *irqs;
 	int probed_phy_irq;

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html



More information about the linux-arm-kernel mailing list