[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/Makefile b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/Makefile
new file mode 100644
index 0000000..b3263ec
--- /dev/null
+++ b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/Makefile
@@ -0,0 +1,12 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+obj-y   := unit-init.o leds.o irq-fpga.o
+
+obj-$(CONFIG_SMSC911X) += smsc911x.o
diff --git a/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/clock.h b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/clock.h
new file mode 100644
index 0000000..d34ac9a
--- /dev/null
+++ b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/clock.h
@@ -0,0 +1,29 @@
+/* clock.h: unit-specific clocks
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * Modified by Matsushita Electric Industrial Co., Ltd.
+ * Modifications:
+ *	23-Feb-2007 MEI Add define for watchdog timer.
+ *
+ * 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.
+ */
+
+#ifndef _ASM_UNIT_CLOCK_H
+#define _ASM_UNIT_CLOCK_H
+
+#ifndef __ASSEMBLY__
+
+#define MN10300_IOCLK		100000000UL		/* for DDR800 */
+/*#define MN10300_IOCLK		83333333UL */		/* for DDR667 */
+#define MN10300_IOBCLK		MN10300_IOCLK		/* IOBCLK is equal to IOCLK */
+
+#endif /* !__ASSEMBLY__ */
+
+#define MN10300_WDCLK		27000000UL
+
+#endif /* _ASM_UNIT_CLOCK_H */
diff --git a/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/fpga-regs.h b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/fpga-regs.h
new file mode 100644
index 0000000..2901ed3
--- /dev/null
+++ b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/fpga-regs.h
@@ -0,0 +1,53 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* ASB2364 FPGA registers
+ */
+
+#ifndef _ASM_UNIT_FPGA_REGS_H
+#define _ASM_UNIT_FPGA_REGS_H
+
+#include <asm/cpu-regs.h>
+
+#ifdef __KERNEL__
+
+#define ASB2364_FPGA_REG_RESET_LAN	__SYSREG(0xa9001300, u16)
+#define ASB2364_FPGA_REG_RESET_UART	__SYSREG(0xa9001304, u16)
+#define ASB2364_FPGA_REG_RESET_I2C	__SYSREG(0xa9001308, u16)
+#define ASB2364_FPGA_REG_RESET_USB	__SYSREG(0xa900130c, u16)
+#define ASB2364_FPGA_REG_RESET_AV	__SYSREG(0xa9001310, u16)
+
+#define ASB2364_FPGA_REG_IRQ(X)		__SYSREG(0xa9001510+((X)*4), u16)
+#define ASB2364_FPGA_REG_IRQ_LAN	ASB2364_FPGA_REG_IRQ(0)
+#define ASB2364_FPGA_REG_IRQ_UART	ASB2364_FPGA_REG_IRQ(1)
+#define ASB2364_FPGA_REG_IRQ_I2C	ASB2364_FPGA_REG_IRQ(2)
+#define ASB2364_FPGA_REG_IRQ_USB	ASB2364_FPGA_REG_IRQ(3)
+#define ASB2364_FPGA_REG_IRQ_FPGA	ASB2364_FPGA_REG_IRQ(5)
+
+#define ASB2364_FPGA_REG_MASK(X)	__SYSREG(0xa9001590+((X)*4), u16)
+#define ASB2364_FPGA_REG_MASK_LAN	ASB2364_FPGA_REG_MASK(0)
+#define ASB2364_FPGA_REG_MASK_UART	ASB2364_FPGA_REG_MASK(1)
+#define ASB2364_FPGA_REG_MASK_I2C	ASB2364_FPGA_REG_MASK(2)
+#define ASB2364_FPGA_REG_MASK_USB	ASB2364_FPGA_REG_MASK(3)
+#define ASB2364_FPGA_REG_MASK_FPGA	ASB2364_FPGA_REG_MASK(5)
+
+#define ASB2364_FPGA_REG_CPLD5_SET1	__SYSREG(0xa9002500, u16)
+#define ASB2364_FPGA_REG_CPLD5_SET2	__SYSREG(0xa9002504, u16)
+#define ASB2364_FPGA_REG_CPLD6_SET1	__SYSREG(0xa9002600, u16)
+#define ASB2364_FPGA_REG_CPLD6_SET2	__SYSREG(0xa9002604, u16)
+#define ASB2364_FPGA_REG_CPLD7_SET1	__SYSREG(0xa9002700, u16)
+#define ASB2364_FPGA_REG_CPLD7_SET2	__SYSREG(0xa9002704, u16)
+#define ASB2364_FPGA_REG_CPLD8_SET1	__SYSREG(0xa9002800, u16)
+#define ASB2364_FPGA_REG_CPLD8_SET2	__SYSREG(0xa9002804, u16)
+#define ASB2364_FPGA_REG_CPLD9_SET1	__SYSREG(0xa9002900, u16)
+#define ASB2364_FPGA_REG_CPLD9_SET2	__SYSREG(0xa9002904, u16)
+#define ASB2364_FPGA_REG_CPLD10_SET1	__SYSREG(0xa9002a00, u16)
+#define ASB2364_FPGA_REG_CPLD10_SET2	__SYSREG(0xa9002a04, u16)
+
+#define SyncExBus()					\
+	do {						\
+		unsigned short w;			\
+		w = *(volatile short *)0xa9000000;	\
+	} while (0)
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_UNIT_FPGA_REGS_H */
diff --git a/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/irq.h b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/irq.h
new file mode 100644
index 0000000..786148e
--- /dev/null
+++ b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/irq.h
@@ -0,0 +1,35 @@
+/* ASB2364 FPGA irq numbers
+ *
+ * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+#ifndef _UNIT_IRQ_H
+#define _UNIT_IRQ_H
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_SMP
+#define NR_CPU_IRQS	GxICR_NUM_EXT_IRQS
+#else
+#define NR_CPU_IRQS	GxICR_NUM_IRQS
+#endif
+
+enum {
+	FPGA_LAN_IRQ	= NR_CPU_IRQS,
+	FPGA_UART_IRQ,
+	FPGA_I2C_IRQ,
+	FPGA_USB_IRQ,
+	FPGA_RESERVED_IRQ,
+	FPGA_FPGA_IRQ,
+	NR_IRQS
+};
+
+extern void __init irq_fpga_init(void);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _UNIT_IRQ_H */
diff --git a/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/leds.h b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/leds.h
new file mode 100644
index 0000000..03a3933
--- /dev/null
+++ b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/leds.h
@@ -0,0 +1,54 @@
+/* Unit-specific leds
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _ASM_UNIT_LEDS_H
+#define _ASM_UNIT_LEDS_H
+
+#include <asm/pio-regs.h>
+#include <asm/cpu-regs.h>
+#include <asm/exceptions.h>
+
+#define MN10300_USE_7SEGLEDS	0
+
+#define ASB2364_7SEGLEDS	__SYSREG(0xA9001630, u32)
+
+/*
+ * use the 7-segment LEDs to indicate states
+ */
+
+#if MN10300_USE_7SEGLEDS
+/* flip the 7-segment LEDs between "Gdb-" and "----" */
+#define mn10300_set_gdbleds(ONOFF)					\
+	do {								\
+		ASB2364_7SEGLEDS = (ONOFF) ? 0x8543077f : 0x7f7f7f7f;	\
+	} while (0)
+#else
+#define mn10300_set_gdbleds(ONOFF) do {} while (0)
+#endif
+
+#if MN10300_USE_7SEGLEDS
+/* indicate double-fault by displaying "db-f" on the LEDs */
+#define mn10300_set_dbfleds			\
+	mov	0x43077f1d,d0		;	\
+	mov	d0,(ASB2364_7SEGLEDS)
+#else
+#define mn10300_set_dbfleds
+#endif
+
+#ifndef __ASSEMBLY__
+extern void peripheral_leds_display_exception(enum exception_code);
+extern void peripheral_leds_led_chase(void);
+extern void peripheral_leds7x4_display_dec(unsigned int, unsigned int);
+extern void peripheral_leds7x4_display_hex(unsigned int, unsigned int);
+extern void debug_to_serial(const char *, int);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_UNIT_LEDS_H */
diff --git a/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/serial.h b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/serial.h
new file mode 100644
index 0000000..92f224a
--- /dev/null
+++ b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/serial.h
@@ -0,0 +1,151 @@
+/* Unit-specific 8250 serial ports
+ *
+ * Copyright (C) 2005 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+
+#ifndef _ASM_UNIT_SERIAL_H
+#define _ASM_UNIT_SERIAL_H
+
+#include <asm/cpu-regs.h>
+#include <proc/irq.h>
+#include <unit/fpga-regs.h>
+#include <linux/serial_reg.h>
+
+#define SERIAL_PORT0_BASE_ADDRESS	0xA8200000
+
+#define SERIAL_IRQ	XIRQ1	/* single serial (TL16C550C)	(Lo) */
+
+/*
+ * The ASB2364 has an 12.288 MHz clock
+ * for your UART.
+ *
+ * It'd be nice if someone built a serial card with a 24.576 MHz
+ * clock, since the 16550A is capable of handling a top speed of 1.5
+ * megabits/second; but this requires the faster clock.
+ */
+#define BASE_BAUD (12288000 / 16)
+
+/*
+ * dispose of the /dev/ttyS0 and /dev/ttyS1 serial ports
+ */
+#ifndef CONFIG_GDBSTUB_ON_TTYSx
+
+#define SERIAL_PORT_DFNS						\
+	{								\
+		.baud_base	= BASE_BAUD,				\
+		.irq		= SERIAL_IRQ,				\
+		.flags		= STD_COM_FLAGS,			\
+		.iomem_base	= (u8 *) SERIAL_PORT0_BASE_ADDRESS,	\
+		.iomem_reg_shift = 1,					\
+		.io_type	= SERIAL_IO_MEM,			\
+	},
+
+#ifndef __ASSEMBLY__
+
+static inline void __debug_to_serial(const char *p, int n)
+{
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#else /* CONFIG_GDBSTUB_ON_TTYSx */
+
+#define SERIAL_PORT_DFNS /* stolen by gdb-stub */
+
+#if defined(CONFIG_GDBSTUB_ON_TTYS0)
+#define GDBPORT_SERIAL_RX	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_RX  * 2, u8)
+#define GDBPORT_SERIAL_TX	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_TX  * 2, u8)
+#define GDBPORT_SERIAL_DLL	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLL * 2, u8)
+#define GDBPORT_SERIAL_DLM	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_DLM * 2, u8)
+#define GDBPORT_SERIAL_IER	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IER * 2, u8)
+#define GDBPORT_SERIAL_IIR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IIR * 2, u8)
+#define GDBPORT_SERIAL_FCR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_FCR * 2, u8)
+#define GDBPORT_SERIAL_LCR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LCR * 2, u8)
+#define GDBPORT_SERIAL_MCR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MCR * 2, u8)
+#define GDBPORT_SERIAL_LSR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_LSR * 2, u8)
+#define GDBPORT_SERIAL_MSR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_MSR * 2, u8)
+#define GDBPORT_SERIAL_SCR	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_SCR * 2, u8)
+#define GDBPORT_SERIAL_IRQ	SERIAL_IRQ
+
+#elif defined(CONFIG_GDBSTUB_ON_TTYS1)
+#error The ASB2364 does not have a /dev/ttyS1
+#endif
+
+#ifndef __ASSEMBLY__
+
+static inline void __debug_to_serial(const char *p, int n)
+{
+	char ch;
+
+#define LSR_WAIT_FOR(STATE)	\
+	do {} while (!(GDBPORT_SERIAL_LSR & UART_LSR_##STATE))
+#define FLOWCTL_QUERY(LINE)	\
+	({ GDBPORT_SERIAL_MSR & UART_MSR_##LINE; })
+#define FLOWCTL_WAIT_FOR(LINE)	\
+	do {} while (!(GDBPORT_SERIAL_MSR & UART_MSR_##LINE))
+#define FLOWCTL_CLEAR(LINE)	\
+	do { GDBPORT_SERIAL_MCR &= ~UART_MCR_##LINE; } while (0)
+#define FLOWCTL_SET(LINE)	\
+	do { GDBPORT_SERIAL_MCR |= UART_MCR_##LINE; } while (0)
+
+	FLOWCTL_SET(DTR);
+
+	for (; n > 0; n--) {
+		LSR_WAIT_FOR(THRE);
+		FLOWCTL_WAIT_FOR(CTS);
+
+		ch = *p++;
+		if (ch == 0x0a) {
+			GDBPORT_SERIAL_TX = 0x0d;
+			LSR_WAIT_FOR(THRE);
+			FLOWCTL_WAIT_FOR(CTS);
+		}
+		GDBPORT_SERIAL_TX = ch;
+	}
+
+	FLOWCTL_CLEAR(DTR);
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* CONFIG_GDBSTUB_ON_TTYSx */
+
+#define SERIAL_INITIALIZE					\
+do {								\
+	/* release reset */					\
+	ASB2364_FPGA_REG_RESET_UART = 0x0001;			\
+	SyncExBus();						\
+} while (0)
+
+#define SERIAL_CHECK_INTERRUPT					\
+do {								\
+	if ((ASB2364_FPGA_REG_IRQ_UART & 0x0001) == 0x0001) {	\
+		return IRQ_NONE;				\
+	}							\
+} while (0)
+
+#define SERIAL_CLEAR_INTERRUPT					\
+do {								\
+	ASB2364_FPGA_REG_IRQ_UART = 0x0001;			\
+	SyncExBus();						\
+} while (0)
+
+#define SERIAL_SET_INT_MASK					\
+do {								\
+	ASB2364_FPGA_REG_MASK_UART = 0x0001;			\
+	SyncExBus();						\
+} while (0)
+
+#define SERIAL_CLEAR_INT_MASK					\
+do {								\
+	ASB2364_FPGA_REG_MASK_UART = 0x0000;			\
+	SyncExBus();						\
+} while (0)
+
+#endif /* _ASM_UNIT_SERIAL_H */
diff --git a/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/smsc911x.h b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/smsc911x.h
new file mode 100644
index 0000000..4c1ede5
--- /dev/null
+++ b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/smsc911x.h
@@ -0,0 +1,171 @@
+/* Support for the SMSC911x NIC
+ *
+ * Copyright (C) 2006 Matsushita Electric Industrial Co., Ltd.
+ * All Rights Reserved.
+ *
+ * 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.
+ */
+#ifndef _ASM_UNIT_SMSC911X_H
+#define _ASM_UNIT_SMSC911X_H
+
+#include <linux/netdevice.h>
+#include <proc/irq.h>
+#include <unit/fpga-regs.h>
+
+#define MN10300_USE_EXT_EEPROM
+
+
+#define SMSC911X_BASE		0xA8000000UL
+#define SMSC911X_BASE_END	0xA8000100UL
+#define SMSC911X_IRQ		FPGA_LAN_IRQ
+
+/*
+ * Allow the FPGA to be initialised by the SMSC911x driver
+ */
+#undef SMSC_INITIALIZE
+#define SMSC_INITIALIZE()					\
+do {								\
+	/* release reset */					\
+	ASB2364_FPGA_REG_RESET_LAN = 0x0001;			\
+	SyncExBus();						\
+} while (0)
+
+#ifdef MN10300_USE_EXT_EEPROM
+#include <linux/delay.h>
+#include <unit/clock.h>
+
+#define EEPROM_ADDRESS	0xA0
+#define MAC_OFFSET	0x0008
+#define USE_IIC_CH	0	/* 0 or 1 */
+#define IIC_OFFSET	(0x80000 * USE_IIC_CH)
+#define IIC_DTRM	__SYSREG(0xd8400000 + IIC_OFFSET, u32)
+#define IIC_DREC	__SYSREG(0xd8400004 + IIC_OFFSET, u32)
+#define IIC_MYADD	__SYSREG(0xd8400008 + IIC_OFFSET, u32)
+#define IIC_CLK		__SYSREG(0xd840000c + IIC_OFFSET, u32)
+#define IIC_BRST	__SYSREG(0xd8400010 + IIC_OFFSET, u32)
+#define IIC_HOLD	__SYSREG(0xd8400014 + IIC_OFFSET, u32)
+#define IIC_BSTS	__SYSREG(0xd8400018 + IIC_OFFSET, u32)
+#define IIC_ICR		__SYSREG(0xd4000080 + 4 * USE_IIC_CH, u16)
+
+#define IIC_CLK_PLS	((unsigned short)(MN10300_IOCLK / 100000 - 1))
+#define IIC_CLK_LOW	((unsigned short)(IIC_CLK_PLS / 2))
+
+#define SYS_IIC_DTRM_Bit_STA	((unsigned short)0x0400)
+#define SYS_IIC_DTRM_Bit_STO	((unsigned short)0x0200)
+#define SYS_IIC_DTRM_Bit_ACK	((unsigned short)0x0100)
+#define SYS_IIC_DTRM_Bit_DATA	((unsigned short)0x00FF)
+
+static inline void POLL_INT_REQ(volatile u16 *icr)
+{
+	unsigned long flags;
+	u16 tmp;
+
+	while (!(*icr & GxICR_REQUEST))
+		;
+	flags = arch_local_cli_save();
+	tmp = *icr;
+	*icr = (tmp & GxICR_LEVEL) | GxICR_DETECT;
+	tmp = *icr;
+	arch_local_irq_restore(flags);
+}
+
+/*
+ * Implement the SMSC911x hook for MAC address retrieval
+ */
+#undef smsc_get_mac
+static inline int smsc_get_mac(struct net_device *dev)
+{
+	unsigned char *mac_buf = dev->dev_addr;
+	int i;
+	unsigned short value;
+	unsigned int data;
+	int mac_length = 6;
+	int check;
+	u16 orig_gicr, tmp;
+	unsigned long flags;
+
+	/* save original GnICR and clear GnICR.IE */
+	flags = arch_local_cli_save();
+	orig_gicr = IIC_ICR;
+	IIC_ICR = orig_gicr & GxICR_LEVEL;
+	tmp = IIC_ICR;
+	arch_local_irq_restore(flags);
+
+	IIC_MYADD = 0x00000008;
+	IIC_CLK = (IIC_CLK_LOW << 16) + (IIC_CLK_PLS);
+	/* bus hung recovery */
+
+	while (1) {
+		check = 0;
+		for (i = 0; i < 3; i++) {
+			if ((IIC_BSTS & 0x00000003) == 0x00000003)
+				check++;
+			udelay(3);
+		}
+
+		if (check == 3) {
+			IIC_BRST = 0x00000003;
+			break;
+		} else {
+			for (i = 0; i < 3; i++) {
+				IIC_BRST = 0x00000002;
+				udelay(8);
+				IIC_BRST = 0x00000003;
+				udelay(8);
+			}
+		}
+	}
+
+	IIC_BRST = 0x00000002;
+	IIC_BRST = 0x00000003;
+
+	value	=  SYS_IIC_DTRM_Bit_STA | SYS_IIC_DTRM_Bit_ACK;
+	value	|= (((unsigned short)EEPROM_ADDRESS & SYS_IIC_DTRM_Bit_DATA) |
+		    (unsigned short)0x0000);
+	IIC_DTRM = value;
+	POLL_INT_REQ(&IIC_ICR);
+
+	/** send offset of MAC address in EEPROM **/
+	IIC_DTRM = (unsigned char)((MAC_OFFSET & 0xFF00) >> 8);
+	POLL_INT_REQ(&IIC_ICR);
+
+	IIC_DTRM = (unsigned char)(MAC_OFFSET & 0x00FF);
+	POLL_INT_REQ(&IIC_ICR);
+
+	udelay(1000);
+
+	value	=  SYS_IIC_DTRM_Bit_STA;
+	value	|= (((unsigned short)EEPROM_ADDRESS & SYS_IIC_DTRM_Bit_DATA) |
+		    (unsigned short)0x0001);
+	IIC_DTRM = value;
+	POLL_INT_REQ(&IIC_ICR);
+
+	IIC_DTRM = 0x00000000;
+	while (mac_length > 0) {
+		POLL_INT_REQ(&IIC_ICR);
+
+		data = IIC_DREC;
+		mac_length--;
+		if (mac_length == 0)
+			value = 0x00000300;	/* stop IIC bus */
+		else if (mac_length == 1)
+			value = 0x00000100;	/* no ack */
+		else
+			value = 0x00000000;	/* ack */
+		IIC_DTRM = value;
+		*mac_buf++ = (unsigned char)(data & 0xff);
+	}
+
+	/* restore GnICR.LV and GnICR.IE */
+	flags = arch_local_cli_save();
+	IIC_ICR = (orig_gicr & (GxICR_LEVEL | GxICR_ENABLE));
+	tmp = IIC_ICR;
+	arch_local_irq_restore(flags);
+
+	return 0;
+}
+#endif /* MN10300_USE_EXT_EEPROM */
+#endif /* _ASM_UNIT_SMSC911X_H */
diff --git a/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/timex.h b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/timex.h
new file mode 100644
index 0000000..42f32db
--- /dev/null
+++ b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/include/unit/timex.h
@@ -0,0 +1,155 @@
+/* timex.h: MN2WS0038 architecture timer specifications
+ *
+ * Copyright (C) 2002, 2010 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * 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.
+ */
+#ifndef _ASM_UNIT_TIMEX_H
+#define _ASM_UNIT_TIMEX_H
+
+#include <asm/timer-regs.h>
+#include <unit/clock.h>
+#include <asm/param.h>
+
+/*
+ * jiffies counter specifications
+ */
+
+#define	TMJCBR_MAX		0xffffff	/* 24bit */
+#define	TMJCIRQ			TMTIRQ
+
+#ifndef __ASSEMBLY__
+
+#define MN10300_SRC_IOBCLK	MN10300_IOBCLK
+
+#ifndef HZ
+# error HZ undeclared.
+#endif /* !HZ */
+
+#define MN10300_JCCLK		(MN10300_SRC_IOBCLK)
+#define MN10300_TSCCLK		(MN10300_SRC_IOBCLK)
+
+#define MN10300_JC_PER_HZ	((MN10300_JCCLK + HZ / 2) / HZ)
+#define MN10300_TSC_PER_HZ	((MN10300_TSCCLK + HZ / 2) / HZ)
+
+/* Check bit width of MTM interval value that sets base register */
+#if (MN10300_JC_PER_HZ - 1) > TMJCBR_MAX
+# error MTM tick timer interval value is overflow.
+#endif
+
+static inline void stop_jiffies_counter(void)
+{
+	u16 tmp;
+	TMTMD = 0;
+	tmp = TMTMD;
+}
+
+static inline void reload_jiffies_counter(u32 cnt)
+{
+	u32 tmp;
+
+	TMTBR = cnt;
+	tmp = TMTBR;
+
+	TMTMD = TMTMD_TMTLDE;
+	TMTMD = TMTMD_TMTCNE;
+	tmp = TMTMD;
+}
+
+#if defined(CONFIG_SMP) && defined(CONFIG_GENERIC_CLOCKEVENTS) && \
+    !defined(CONFIG_GENERIC_CLOCKEVENTS_BROADCAST)
+/*
+ * If we aren't using broadcasting, each core needs its own event timer.
+ * Since CPU0 uses the tick timer which is 24-bits, we use timer 4 & 5
+ * cascaded to 32-bits for CPU1 (but only really use 24-bits to match
+ * CPU0).
+ */
+
+#define	TMJC1IRQ		TM5IRQ
+
+static inline void stop_jiffies_counter1(void)
+{
+	u8 tmp;
+	TM4MD = 0;
+	TM5MD = 0;
+	tmp = TM4MD;
+	tmp = TM5MD;
+}
+
+static inline void reload_jiffies_counter1(u32 cnt)
+{
+	u32 tmp;
+
+	TM45BR = cnt;
+	tmp = TM45BR;
+
+	TM4MD = TM4MD_INIT_COUNTER;
+	tmp = TM4MD;
+
+	TM5MD = TM5MD_SRC_TM4CASCADE | TM5MD_INIT_COUNTER;
+	TM5MD = TM5MD_SRC_TM4CASCADE | TM5MD_COUNT_ENABLE;
+	tmp = TM5MD;
+
+	TM4MD = TM4MD_COUNT_ENABLE;
+	tmp = TM4MD;
+}
+#endif /* CONFIG_SMP&GENERIC_CLOCKEVENTS&!GENERIC_CLOCKEVENTS_BROADCAST */
+
+#endif /* !__ASSEMBLY__ */
+
+
+/*
+ * timestamp counter specifications
+ */
+#define	TMTSCBR_MAX	0xffffffff
+
+#ifndef __ASSEMBLY__
+
+/* Use 32-bit timestamp counter */
+#define	TMTSCMD		TMSMD
+#define	TMTSCBR		TMSBR
+#define	TMTSCBC		TMSBC
+#define	TMTSCICR	TMSICR
+
+static inline void startup_timestamp_counter(void)
+{
+	u32 sync;
+
+	/* set up TMS(Timestamp) 32bit timer register to count real time
+	 * - count down from 4Gig-1 to 0 and wrap at IOBCLK rate
+	 */
+
+	TMTSCBR = TMTSCBR_MAX;
+	sync = TMTSCBR;
+
+	TMTSCICR = 0;
+	sync = TMTSCICR;
+
+	TMTSCMD = TMTMD_TMTLDE;
+	TMTSCMD = TMTMD_TMTCNE;
+	sync = TMTSCMD;
+}
+
+static inline void shutdown_timestamp_counter(void)
+{
+	TMTSCMD = 0;
+}
+
+/*
+ * we use a cascaded pair of 16-bit down-counting timers to count I/O
+ * clock cycles for the purposes of time keeping
+ */
+typedef unsigned long cycles_t;
+
+static inline cycles_t read_timestamp_counter(void)
+{
+	return (cycles_t)~TMTSCBC;
+}
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* _ASM_UNIT_TIMEX_H */
diff --git a/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/irq-fpga.c b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/irq-fpga.c
new file mode 100644
index 0000000..073e2cc
--- /dev/null
+++ b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/irq-fpga.c
@@ -0,0 +1,108 @@
+/* ASB2364 FPGA interrupt multiplexing
+ *
+ * Copyright (C) 2010 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+#include <unit/fpga-regs.h>
+
+/*
+ * FPGA PIC operations
+ */
+static void asb2364_fpga_mask(struct irq_data *d)
+{
+	ASB2364_FPGA_REG_MASK(d->irq - NR_CPU_IRQS) = 0x0001;
+	SyncExBus();
+}
+
+static void asb2364_fpga_ack(struct irq_data *d)
+{
+	ASB2364_FPGA_REG_IRQ(d->irq - NR_CPU_IRQS) = 0x0001;
+	SyncExBus();
+}
+
+static void asb2364_fpga_mask_ack(struct irq_data *d)
+{
+	ASB2364_FPGA_REG_MASK(d->irq - NR_CPU_IRQS) = 0x0001;
+	SyncExBus();
+	ASB2364_FPGA_REG_IRQ(d->irq - NR_CPU_IRQS) = 0x0001;
+	SyncExBus();
+}
+
+static void asb2364_fpga_unmask(struct irq_data *d)
+{
+	ASB2364_FPGA_REG_MASK(d->irq - NR_CPU_IRQS) = 0x0000;
+	SyncExBus();
+}
+
+static struct irq_chip asb2364_fpga_pic = {
+	.name		= "fpga",
+	.irq_ack	= asb2364_fpga_ack,
+	.irq_mask	= asb2364_fpga_mask,
+	.irq_mask_ack	= asb2364_fpga_mask_ack,
+	.irq_unmask	= asb2364_fpga_unmask,
+};
+
+/*
+ * FPGA PIC interrupt handler
+ */
+static irqreturn_t fpga_interrupt(int irq, void *_mask)
+{
+	if ((ASB2364_FPGA_REG_IRQ_LAN  & 0x0001) != 0x0001)
+		generic_handle_irq(FPGA_LAN_IRQ);
+	if ((ASB2364_FPGA_REG_IRQ_UART & 0x0001) != 0x0001)
+		generic_handle_irq(FPGA_UART_IRQ);
+	if ((ASB2364_FPGA_REG_IRQ_I2C  & 0x0001) != 0x0001)
+		generic_handle_irq(FPGA_I2C_IRQ);
+	if ((ASB2364_FPGA_REG_IRQ_USB  & 0x0001) != 0x0001)
+		generic_handle_irq(FPGA_USB_IRQ);
+	if ((ASB2364_FPGA_REG_IRQ_FPGA & 0x0001) != 0x0001)
+		generic_handle_irq(FPGA_FPGA_IRQ);
+
+	return IRQ_HANDLED;
+}
+
+/*
+ * Define an interrupt action for each FPGA PIC output
+ */
+static struct irqaction fpga_irq[]  = {
+	[0] = {
+		.handler	= fpga_interrupt,
+		.flags		= IRQF_SHARED,
+		.name		= "fpga",
+	},
+};
+
+/*
+ * Initialise the FPGA's PIC
+ */
+void __init irq_fpga_init(void)
+{
+	int irq;
+
+	ASB2364_FPGA_REG_MASK_LAN  = 0x0001;
+	SyncExBus();
+	ASB2364_FPGA_REG_MASK_UART = 0x0001;
+	SyncExBus();
+	ASB2364_FPGA_REG_MASK_I2C  = 0x0001;
+	SyncExBus();
+	ASB2364_FPGA_REG_MASK_USB  = 0x0001;
+	SyncExBus();
+	ASB2364_FPGA_REG_MASK_FPGA = 0x0001;
+	SyncExBus();
+
+	for (irq = NR_CPU_IRQS; irq < NR_IRQS; irq++)
+		irq_set_chip_and_handler(irq, &asb2364_fpga_pic,
+					 handle_level_irq);
+
+	/* the FPGA drives the XIRQ1 input on the CPU PIC */
+	setup_irq(XIRQ1, &fpga_irq[0]);
+}
diff --git a/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/leds.c b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/leds.c
new file mode 100644
index 0000000..1ff830c
--- /dev/null
+++ b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/leds.c
@@ -0,0 +1,98 @@
+/* leds.c: ASB2364 peripheral 7seg LEDs x4 support
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/processor.h>
+#include <asm/intctl-regs.h>
+#include <asm/rtc-regs.h>
+#include <unit/leds.h>
+
+#if MN10300_USE_7SEGLEDS
+static const u8 asb2364_led_hex_tbl[16] = {
+	0x80, 0xf2, 0x48, 0x60, 0x32, 0x24, 0x04, 0xf0,
+	0x00, 0x20, 0x10, 0x06, 0x8c, 0x42, 0x0c, 0x1c
+};
+
+static const u32 asb2364_led_chase_tbl[6] = {
+	~0x02020202,	/* top		- segA */
+	~0x04040404,	/* right top	- segB */
+	~0x08080808,	/* right bottom	- segC */
+	~0x10101010,	/* bottom	- segD */
+	~0x20202020,	/* left bottom	- segE */
+	~0x40404040,	/* left top	- segF */
+};
+
+static unsigned asb2364_led_chase;
+
+void peripheral_leds7x4_display_dec(unsigned int val, unsigned int points)
+{
+	u32 leds;
+
+	leds = asb2364_led_hex_tbl[(val/1000) % 10];
+	leds <<= 8;
+	leds |= asb2364_led_hex_tbl[(val/100) % 10];
+	leds <<= 8;
+	leds |= asb2364_led_hex_tbl[(val/10) % 10];
+	leds <<= 8;
+	leds |= asb2364_led_hex_tbl[val % 10];
+	leds |= points^0x01010101;
+
+	ASB2364_7SEGLEDS = leds;
+}
+
+void peripheral_leds7x4_display_hex(unsigned int val, unsigned int points)
+{
+	u32 leds;
+
+	leds = asb2364_led_hex_tbl[(val/1000) % 10];
+	leds <<= 8;
+	leds |= asb2364_led_hex_tbl[(val/100) % 10];
+	leds <<= 8;
+	leds |= asb2364_led_hex_tbl[(val/10) % 10];
+	leds <<= 8;
+	leds |= asb2364_led_hex_tbl[val % 10];
+	leds |= points^0x01010101;
+
+	ASB2364_7SEGLEDS = leds;
+}
+
+/* display triple horizontal bar and exception code */
+void peripheral_leds_display_exception(enum exception_code code)
+{
+	u32 leds;
+
+	leds = asb2364_led_hex_tbl[(code/0x100) % 0x10];
+	leds <<= 8;
+	leds |= asb2364_led_hex_tbl[(code/0x10) % 0x10];
+	leds <<= 8;
+	leds |= asb2364_led_hex_tbl[code % 0x10];
+	leds |= 0x6d010101;
+
+	ASB2364_7SEGLEDS = leds;
+}
+
+void peripheral_leds_led_chase(void)
+{
+	ASB2364_7SEGLEDS = asb2364_led_chase_tbl[asb2364_led_chase];
+	asb2364_led_chase++;
+	if (asb2364_led_chase >= 6)
+		asb2364_led_chase = 0;
+}
+#else  /* MN10300_USE_7SEGLEDS */
+void peripheral_leds7x4_display_dec(unsigned int val, unsigned int points) { }
+void peripheral_leds7x4_display_hex(unsigned int val, unsigned int points) { }
+void peripheral_leds_display_exception(enum exception_code code) { }
+void peripheral_leds_led_chase(void) { }
+#endif /* MN10300_USE_7SEGLEDS */
diff --git a/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/smsc911x.c b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/smsc911x.c
new file mode 100644
index 0000000..544a73e
--- /dev/null
+++ b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/smsc911x.c
@@ -0,0 +1,58 @@
+/* Specification for the SMSC911x NIC
+ *
+ * Copyright (C) 2006 Matsushita Electric Industrial Co., Ltd.
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/smsc911x.h>
+#include <unit/smsc911x.h>
+
+static struct smsc911x_platform_config smsc911x_config = {
+	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
+	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN,
+	.flags		= SMSC911X_USE_32BIT,
+};
+
+static struct resource smsc911x_resources[] = {
+	[0] = {
+		.start	= SMSC911X_BASE,
+		.end	= SMSC911X_BASE_END,
+		.flags	= IORESOURCE_MEM,
+	},
+	[1] = {
+		.start	= SMSC911X_IRQ,
+		.end	= SMSC911X_IRQ,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct platform_device smsc911x_device = {
+	.name		= "smsc911x",
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(smsc911x_resources),
+	.resource	= smsc911x_resources,
+	.dev		= {
+		.platform_data = &smsc911x_config,
+	}
+};
+
+/*
+ * add platform devices
+ */
+static int __init unit_device_init(void)
+{
+	platform_device_register(&smsc911x_device);
+	return 0;
+}
+
+device_initcall(unit_device_init);
diff --git a/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/unit-init.c b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/unit-init.c
new file mode 100644
index 0000000..6359b41
--- /dev/null
+++ b/src/kernel/linux/v4.14/arch/mn10300/unit-asb2364/unit-init.c
@@ -0,0 +1,132 @@
+/* ASB2364 initialisation
+ *
+ * Copyright (C) 2002 Red Hat, Inc. All Rights Reserved.
+ * Written by David Howells (dhowells@redhat.com)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+
+#include <asm/io.h>
+#include <asm/setup.h>
+#include <asm/processor.h>
+#include <asm/irq.h>
+#include <asm/intctl-regs.h>
+#include <asm/serial-regs.h>
+#include <unit/fpga-regs.h>
+#include <unit/serial.h>
+#include <unit/smsc911x.h>
+
+#define TTYS0_SERIAL_IER	__SYSREG(SERIAL_PORT0_BASE_ADDRESS + UART_IER * 2, u8)
+#define LAN_IRQ_CFG		__SYSREG(SMSC911X_BASE + 0x54, u32)
+#define LAN_INT_EN		__SYSREG(SMSC911X_BASE + 0x5c, u32)
+
+/*
+ * initialise some of the unit hardware before gdbstub is set up
+ */
+asmlinkage void __init unit_init(void)
+{
+	/* Make sure we aren't going to get unexpected interrupts */
+	TTYS0_SERIAL_IER = 0;
+	SC0RXICR = 0;
+	SC0TXICR = 0;
+	SC1RXICR = 0;
+	SC1TXICR = 0;
+	SC2RXICR = 0;
+	SC2TXICR = 0;
+
+	/* Attempt to reset the FPGA attached peripherals */
+	ASB2364_FPGA_REG_RESET_LAN = 0x0000;
+	SyncExBus();
+	ASB2364_FPGA_REG_RESET_UART = 0x0000;
+	SyncExBus();
+	ASB2364_FPGA_REG_RESET_I2C = 0x0000;
+	SyncExBus();
+	ASB2364_FPGA_REG_RESET_USB = 0x0000;
+	SyncExBus();
+	ASB2364_FPGA_REG_RESET_AV = 0x0000;
+	SyncExBus();
+
+	/* set up the external interrupts */
+
+	/* XIRQ[0]: NAND RXBY */
+	/* SET_XIRQ_TRIGGER(0, XIRQ_TRIGGER_LOWLEVEL); */
+
+	/* XIRQ[1]: LAN, UART, I2C, USB, PCI, FPGA */
+	SET_XIRQ_TRIGGER(1, XIRQ_TRIGGER_LOWLEVEL);
+
+	/* XIRQ[2]: Extend Slot 1-9 */
+	/* SET_XIRQ_TRIGGER(2, XIRQ_TRIGGER_LOWLEVEL); */
+
+#if defined(CONFIG_EXT_SERIAL_IRQ_LEVEL) &&	\
+    defined(CONFIG_ETHERNET_IRQ_LEVEL) &&	\
+    (CONFIG_EXT_SERIAL_IRQ_LEVEL != CONFIG_ETHERNET_IRQ_LEVEL)
+# error CONFIG_EXT_SERIAL_IRQ_LEVEL != CONFIG_ETHERNET_IRQ_LEVEL
+#endif
+
+#if defined(CONFIG_EXT_SERIAL_IRQ_LEVEL)
+	set_intr_level(XIRQ1, NUM2GxICR_LEVEL(CONFIG_EXT_SERIAL_IRQ_LEVEL));
+#elif defined(CONFIG_ETHERNET_IRQ_LEVEL)
+	set_intr_level(XIRQ1, NUM2GxICR_LEVEL(CONFIG_ETHERNET_IRQ_LEVEL));
+#endif
+}
+
+/*
+ * initialise the rest of the unit hardware after gdbstub is ready
+ */
+asmlinkage void __init unit_setup(void)
+{
+	/* Release the reset on the SMSC911X so that it is ready by the time we
+	 * need it */
+	ASB2364_FPGA_REG_RESET_LAN = 0x0001;
+	SyncExBus();
+	ASB2364_FPGA_REG_RESET_UART = 0x0001;
+	SyncExBus();
+	ASB2364_FPGA_REG_RESET_I2C = 0x0001;
+	SyncExBus();
+	ASB2364_FPGA_REG_RESET_USB = 0x0001;
+	SyncExBus();
+	ASB2364_FPGA_REG_RESET_AV = 0x0001;
+	SyncExBus();
+
+	/* Make sure the ethernet chipset isn't going to give us an interrupt
+	 * storm from stuff it was doing pre-reset */
+	LAN_IRQ_CFG = 0;
+	LAN_INT_EN = 0;
+}
+
+/*
+ * initialise the external interrupts used by a unit of this type
+ */
+void __init unit_init_IRQ(void)
+{
+	unsigned int extnum;
+
+	for (extnum = 0 ; extnum < NR_XIRQS ; extnum++) {
+		switch (GET_XIRQ_TRIGGER(extnum)) {
+			/* LEVEL triggered interrupts should be made
+			 * post-ACK'able as they hold their lines until
+			 * serviced
+			 */
+		case XIRQ_TRIGGER_HILEVEL:
+		case XIRQ_TRIGGER_LOWLEVEL:
+			mn10300_set_lateack_irq_type(XIRQ2IRQ(extnum));
+			break;
+		default:
+			break;
+		}
+	}
+
+#define IRQCTL	__SYSREG(0xd5000090, u32)
+	IRQCTL |= 0x02;
+
+	irq_fpga_init();
+}