v4.19.13 snapshot.
diff --git a/arch/m68k/sun3x/Makefile b/arch/m68k/sun3x/Makefile
new file mode 100644
index 0000000..be5776d
--- /dev/null
+++ b/arch/m68k/sun3x/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for Linux arch/m68k/sun3x source directory
+#
+
+obj-y		:= config.o time.o dvma.o prom.o
diff --git a/arch/m68k/sun3x/config.c b/arch/m68k/sun3x/config.c
new file mode 100644
index 0000000..33d3a1c
--- /dev/null
+++ b/arch/m68k/sun3x/config.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Setup kernel for a Sun3x machine
+ *
+ * (C) 1999 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ *
+ * based on code from Oliver Jowett <oliver@jowett.manawatu.gen.nz>
+ */
+
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/seq_file.h>
+#include <linux/console.h>
+#include <linux/init.h>
+
+#include <asm/machdep.h>
+#include <asm/irq.h>
+#include <asm/sun3xprom.h>
+#include <asm/sun3ints.h>
+#include <asm/setup.h>
+#include <asm/oplib.h>
+
+#include "time.h"
+
+volatile char *clock_va;
+
+extern void sun3_get_model(char *model);
+
+void sun3_leds(unsigned int i)
+{
+
+}
+
+static void sun3x_get_hardware_list(struct seq_file *m)
+{
+	seq_printf(m, "PROM Revision:\t%s\n", romvec->pv_monid);
+}
+
+/*
+ *  Setup the sun3x configuration info
+ */
+void __init config_sun3x(void)
+{
+
+	sun3x_prom_init();
+
+	mach_max_dma_address = 0xffffffff; /* we can DMA anywhere, whee */
+
+	mach_sched_init      = sun3x_sched_init;
+	mach_init_IRQ        = sun3_init_IRQ;
+
+	arch_gettimeoffset   = sun3x_gettimeoffset;
+	mach_reset           = sun3x_reboot;
+
+	mach_hwclk           = sun3x_hwclk;
+	mach_get_model       = sun3_get_model;
+	mach_get_hardware_list = sun3x_get_hardware_list;
+
+	sun3_intreg = (unsigned char *)SUN3X_INTREG;
+
+	/* only the serial console is known to work anyway... */
+#if 0
+	switch (*(unsigned char *)SUN3X_EEPROM_CONS) {
+	case 0x10:
+		serial_console = 1;
+		conswitchp = NULL;
+		break;
+	case 0x11:
+		serial_console = 2;
+		conswitchp = NULL;
+		break;
+	default:
+		serial_console = 0;
+		conswitchp = &dummy_con;
+		break;
+	}
+#endif
+
+}
+
diff --git a/arch/m68k/sun3x/dvma.c b/arch/m68k/sun3x/dvma.c
new file mode 100644
index 0000000..b2acbc8
--- /dev/null
+++ b/arch/m68k/sun3x/dvma.c
@@ -0,0 +1,199 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Virtual DMA allocation
+ *
+ * (C) 1999 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
+ *
+ * 11/26/2000 -- disabled the existing code because it didn't work for
+ * me in 2.4.  Replaced with a significantly more primitive version
+ * similar to the sun3 code.  the old functionality was probably more
+ * desirable, but....   -- Sam Creasey (sammy@oh.verio.com)
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/mm.h>
+#include <linux/bootmem.h>
+#include <linux/vmalloc.h>
+
+#include <asm/sun3x.h>
+#include <asm/dvma.h>
+#include <asm/io.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+
+/* IOMMU support */
+
+#define IOMMU_ADDR_MASK            0x03ffe000
+#define IOMMU_CACHE_INHIBIT        0x00000040
+#define IOMMU_FULL_BLOCK           0x00000020
+#define IOMMU_MODIFIED             0x00000010
+#define IOMMU_USED                 0x00000008
+#define IOMMU_WRITE_PROTECT        0x00000004
+#define IOMMU_DT_MASK              0x00000003
+#define IOMMU_DT_INVALID           0x00000000
+#define IOMMU_DT_VALID             0x00000001
+#define IOMMU_DT_BAD               0x00000002
+
+
+static volatile unsigned long *iommu_pte = (unsigned long *)SUN3X_IOMMU;
+
+
+#define dvma_entry_paddr(index)		(iommu_pte[index] & IOMMU_ADDR_MASK)
+#define dvma_entry_vaddr(index,paddr)	((index << DVMA_PAGE_SHIFT) |  \
+					 (paddr & (DVMA_PAGE_SIZE-1)))
+#if 0
+#define dvma_entry_set(index,addr)	(iommu_pte[index] =            \
+					    (addr & IOMMU_ADDR_MASK) | \
+				             IOMMU_DT_VALID | IOMMU_CACHE_INHIBIT)
+#else
+#define dvma_entry_set(index,addr)	(iommu_pte[index] =            \
+					    (addr & IOMMU_ADDR_MASK) | \
+				             IOMMU_DT_VALID)
+#endif
+#define dvma_entry_clr(index)		(iommu_pte[index] = IOMMU_DT_INVALID)
+#define dvma_entry_hash(addr)		((addr >> DVMA_PAGE_SHIFT) ^ \
+					 ((addr & 0x03c00000) >>     \
+						(DVMA_PAGE_SHIFT+4)))
+
+#ifdef DEBUG
+/* code to print out a dvma mapping for debugging purposes */
+void dvma_print (unsigned long dvma_addr)
+{
+
+	unsigned long index;
+
+	index = dvma_addr >> DVMA_PAGE_SHIFT;
+
+	pr_info("idx %lx dvma_addr %08lx paddr %08lx\n", index, dvma_addr,
+		dvma_entry_paddr(index));
+}
+#endif
+
+
+/* create a virtual mapping for a page assigned within the IOMMU
+   so that the cpu can reach it easily */
+inline int dvma_map_cpu(unsigned long kaddr,
+			       unsigned long vaddr, int len)
+{
+	pgd_t *pgd;
+	unsigned long end;
+	int ret = 0;
+
+	kaddr &= PAGE_MASK;
+	vaddr &= PAGE_MASK;
+
+	end = PAGE_ALIGN(vaddr + len);
+
+	pr_debug("dvma: mapping kern %08lx to virt %08lx\n", kaddr, vaddr);
+	pgd = pgd_offset_k(vaddr);
+
+	do {
+		pmd_t *pmd;
+		unsigned long end2;
+
+		if((pmd = pmd_alloc(&init_mm, pgd, vaddr)) == NULL) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		if((end & PGDIR_MASK) > (vaddr & PGDIR_MASK))
+			end2 = (vaddr + (PGDIR_SIZE-1)) & PGDIR_MASK;
+		else
+			end2 = end;
+
+		do {
+			pte_t *pte;
+			unsigned long end3;
+
+			if((pte = pte_alloc_kernel(pmd, vaddr)) == NULL) {
+				ret = -ENOMEM;
+				goto out;
+			}
+
+			if((end2 & PMD_MASK) > (vaddr & PMD_MASK))
+				end3 = (vaddr + (PMD_SIZE-1)) & PMD_MASK;
+			else
+				end3 = end2;
+
+			do {
+				pr_debug("mapping %08lx phys to %08lx\n",
+					 __pa(kaddr), vaddr);
+				set_pte(pte, pfn_pte(virt_to_pfn(kaddr),
+						     PAGE_KERNEL));
+				pte++;
+				kaddr += PAGE_SIZE;
+				vaddr += PAGE_SIZE;
+			} while(vaddr < end3);
+
+		} while(vaddr < end2);
+
+	} while(vaddr < end);
+
+	flush_tlb_all();
+
+ out:
+	return ret;
+}
+
+
+inline int dvma_map_iommu(unsigned long kaddr, unsigned long baddr,
+				 int len)
+{
+	unsigned long end, index;
+
+	index = baddr >> DVMA_PAGE_SHIFT;
+	end = ((baddr+len) >> DVMA_PAGE_SHIFT);
+
+	if(len & ~DVMA_PAGE_MASK)
+		end++;
+
+	for(; index < end ; index++) {
+//		if(dvma_entry_use(index))
+//			BUG();
+//		pr_info("mapping pa %lx to ba %lx\n", __pa(kaddr),
+//			index << DVMA_PAGE_SHIFT);
+
+		dvma_entry_set(index, __pa(kaddr));
+
+		iommu_pte[index] |= IOMMU_FULL_BLOCK;
+//		dvma_entry_inc(index);
+
+		kaddr += DVMA_PAGE_SIZE;
+	}
+
+#ifdef DEBUG
+	for(index = (baddr >> DVMA_PAGE_SHIFT); index < end; index++)
+		dvma_print(index << DVMA_PAGE_SHIFT);
+#endif
+	return 0;
+
+}
+
+void dvma_unmap_iommu(unsigned long baddr, int len)
+{
+
+	int index, end;
+
+
+	index = baddr >> DVMA_PAGE_SHIFT;
+	end = (DVMA_PAGE_ALIGN(baddr+len) >> DVMA_PAGE_SHIFT);
+
+	for(; index < end ; index++) {
+		pr_debug("freeing bus mapping %08x\n",
+			 index << DVMA_PAGE_SHIFT);
+#if 0
+		if(!dvma_entry_use(index))
+			pr_info("dvma_unmap freeing unused entry %04x\n",
+				index);
+		else
+			dvma_entry_dec(index);
+#endif
+		dvma_entry_clr(index);
+	}
+
+}
+
diff --git a/arch/m68k/sun3x/prom.c b/arch/m68k/sun3x/prom.c
new file mode 100644
index 0000000..be14c89
--- /dev/null
+++ b/arch/m68k/sun3x/prom.c
@@ -0,0 +1,166 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Prom access routines for the sun3x */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/setup.h>
+#include <asm/traps.h>
+#include <asm/sun3xprom.h>
+#include <asm/idprom.h>
+#include <asm/segment.h>
+#include <asm/sun3ints.h>
+#include <asm/openprom.h>
+#include <asm/machines.h>
+
+void (*sun3x_putchar)(int);
+int (*sun3x_getchar)(void);
+int (*sun3x_mayget)(void);
+int (*sun3x_mayput)(int);
+void (*sun3x_prom_reboot)(void);
+e_vector sun3x_prom_abort;
+struct linux_romvec *romvec;
+
+/* prom vector table */
+e_vector *sun3x_prom_vbr;
+
+/* Handle returning to the prom */
+void sun3x_halt(void)
+{
+	unsigned long flags;
+
+	/* Disable interrupts while we mess with things */
+	local_irq_save(flags);
+
+	/* Restore prom vbr */
+	asm volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr));
+
+	/* Restore prom NMI clock */
+//	sun3x_disable_intreg(5);
+	sun3_enable_irq(7);
+
+	/* Let 'er rip */
+	asm volatile ("trap #14");
+
+	/* Restore everything */
+	sun3_disable_irq(7);
+	sun3_enable_irq(5);
+
+	asm volatile ("movec %0,%%vbr" : : "r" ((void*)vectors));
+	local_irq_restore(flags);
+}
+
+void sun3x_reboot(void)
+{
+	/* This never returns, don't bother saving things */
+	local_irq_disable();
+
+	/* Restore prom vbr */
+	asm volatile ("movec %0,%%vbr" : : "r" ((void*)sun3x_prom_vbr));
+
+	/* Restore prom NMI clock */
+	sun3_disable_irq(5);
+	sun3_enable_irq(7);
+
+	/* Let 'er rip */
+	(*romvec->pv_reboot)("vmlinux");
+}
+
+static void sun3x_prom_write(struct console *co, const char *s,
+                             unsigned int count)
+{
+	while (count--) {
+		if (*s == '\n')
+			sun3x_putchar('\r');
+		sun3x_putchar(*s++);
+	}
+}
+
+/* debug console - write-only */
+
+static struct console sun3x_debug = {
+	.name	= "debug",
+	.write	= sun3x_prom_write,
+	.flags	= CON_PRINTBUFFER,
+	.index	= -1,
+};
+
+void __init sun3x_prom_init(void)
+{
+	/* Read the vector table */
+
+	sun3x_putchar = *(void (**)(int)) (SUN3X_P_PUTCHAR);
+	sun3x_getchar = *(int (**)(void)) (SUN3X_P_GETCHAR);
+	sun3x_mayget = *(int (**)(void))  (SUN3X_P_MAYGET);
+	sun3x_mayput = *(int (**)(int))   (SUN3X_P_MAYPUT);
+	sun3x_prom_reboot = *(void (**)(void)) (SUN3X_P_REBOOT);
+	sun3x_prom_abort = *(e_vector *)  (SUN3X_P_ABORT);
+	romvec = (struct linux_romvec *)SUN3X_PROM_BASE;
+
+	idprom_init();
+
+	if (!((idprom->id_machtype & SM_ARCH_MASK) == SM_SUN3X)) {
+		pr_warn("Machine reports strange type %02x\n",
+			idprom->id_machtype);
+		pr_warn("Pretending it's a 3/80, but very afraid...\n");
+		idprom->id_machtype = SM_SUN3X | SM_3_80;
+	}
+
+	/* point trap #14 at abort.
+	 * XXX this is futile since we restore the vbr first - oops
+	 */
+	vectors[VEC_TRAP14] = sun3x_prom_abort;
+}
+
+static int __init sun3x_debug_setup(char *arg)
+{
+	/* If debug=prom was specified, start the debug console */
+	if (MACH_IS_SUN3X && !strcmp(arg, "prom"))
+		register_console(&sun3x_debug);
+	return 0;
+}
+
+early_param("debug", sun3x_debug_setup);
+
+/* some prom functions to export */
+int prom_getintdefault(int node, char *property, int deflt)
+{
+	return deflt;
+}
+
+int prom_getbool (int node, char *prop)
+{
+	return 1;
+}
+
+void prom_printf(char *fmt, ...)
+{
+}
+
+void prom_halt (void)
+{
+	sun3x_halt();
+}
+
+/* Get the idprom and stuff it into buffer 'idbuf'.  Returns the
+ * format type.  'num_bytes' is the number of bytes that your idbuf
+ * has space for.  Returns 0xff on error.
+ */
+unsigned char
+prom_get_idprom(char *idbuf, int num_bytes)
+{
+        int i;
+
+	/* make a copy of the idprom structure */
+	for (i = 0; i < num_bytes; i++)
+		idbuf[i] = ((char *)SUN3X_IDPROM)[i];
+
+        return idbuf[0];
+}
diff --git a/arch/m68k/sun3x/time.c b/arch/m68k/sun3x/time.c
new file mode 100644
index 0000000..047e2bc
--- /dev/null
+++ b/arch/m68k/sun3x/time.c
@@ -0,0 +1,105 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ *  linux/arch/m68k/sun3x/time.c
+ *
+ *  Sun3x-specific time handling
+ */
+
+#include <linux/types.h>
+#include <linux/kd.h>
+#include <linux/init.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/interrupt.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+
+#include <asm/irq.h>
+#include <asm/io.h>
+#include <asm/machdep.h>
+#include <asm/traps.h>
+#include <asm/sun3x.h>
+#include <asm/sun3ints.h>
+
+#include "time.h"
+
+#define M_CONTROL 0xf8
+#define M_SEC     0xf9
+#define M_MIN     0xfa
+#define M_HOUR    0xfb
+#define M_DAY     0xfc
+#define M_DATE    0xfd
+#define M_MONTH   0xfe
+#define M_YEAR    0xff
+
+#define C_WRITE   0x80
+#define C_READ    0x40
+#define C_SIGN    0x20
+#define C_CALIB   0x1f
+
+int sun3x_hwclk(int set, struct rtc_time *t)
+{
+	volatile struct mostek_dt *h =
+		(struct mostek_dt *)(SUN3X_EEPROM+M_CONTROL);
+	unsigned long flags;
+
+	local_irq_save(flags);
+
+	if(set) {
+		h->csr |= C_WRITE;
+		h->sec = bin2bcd(t->tm_sec);
+		h->min = bin2bcd(t->tm_min);
+		h->hour = bin2bcd(t->tm_hour);
+		h->wday = bin2bcd(t->tm_wday);
+		h->mday = bin2bcd(t->tm_mday);
+		h->month = bin2bcd(t->tm_mon + 1);
+		h->year = bin2bcd(t->tm_year % 100);
+		h->csr &= ~C_WRITE;
+	} else {
+		h->csr |= C_READ;
+		t->tm_sec = bcd2bin(h->sec);
+		t->tm_min = bcd2bin(h->min);
+		t->tm_hour = bcd2bin(h->hour);
+		t->tm_wday = bcd2bin(h->wday);
+		t->tm_mday = bcd2bin(h->mday);
+		t->tm_mon = bcd2bin(h->month) - 1;
+		t->tm_year = bcd2bin(h->year);
+		h->csr &= ~C_READ;
+		if (t->tm_year < 70)
+			t->tm_year += 100;
+	}
+
+	local_irq_restore(flags);
+
+	return 0;
+}
+/* Not much we can do here */
+u32 sun3x_gettimeoffset(void)
+{
+    return 0L;
+}
+
+#if 0
+static void sun3x_timer_tick(int irq, void *dev_id, struct pt_regs *regs)
+{
+    void (*vector)(int, void *, struct pt_regs *) = dev_id;
+
+    /* Clear the pending interrupt - pulse the enable line low */
+    disable_irq(5);
+    enable_irq(5);
+
+    vector(irq, NULL, regs);
+}
+#endif
+
+void __init sun3x_sched_init(irq_handler_t vector)
+{
+
+	sun3_disable_interrupts();
+
+
+    /* Pulse enable low to get the clock started */
+	sun3_disable_irq(5);
+	sun3_enable_irq(5);
+	sun3_enable_interrupts();
+}
diff --git a/arch/m68k/sun3x/time.h b/arch/m68k/sun3x/time.h
new file mode 100644
index 0000000..496f406
--- /dev/null
+++ b/arch/m68k/sun3x/time.h
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef SUN3X_TIME_H
+#define SUN3X_TIME_H
+
+extern int sun3x_hwclk(int set, struct rtc_time *t);
+u32 sun3x_gettimeoffset(void);
+void sun3x_sched_init(irq_handler_t vector);
+
+struct mostek_dt {
+	volatile unsigned char csr;
+	volatile unsigned char sec;
+	volatile unsigned char min;
+	volatile unsigned char hour;
+	volatile unsigned char wday;
+	volatile unsigned char mday;
+	volatile unsigned char month;
+	volatile unsigned char year;
+};
+
+#endif