summaryrefslogtreecommitdiff
path: root/arch/mips/dec
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/dec')
-rw-r--r--arch/mips/dec/Makefile3
-rw-r--r--arch/mips/dec/Platform1
-rw-r--r--arch/mips/dec/ecc-berr.c7
-rw-r--r--arch/mips/dec/int-handler.S42
-rw-r--r--arch/mips/dec/ioasic-irq.c53
-rw-r--r--arch/mips/dec/kn01-berr.c8
-rw-r--r--arch/mips/dec/kn02-irq.c6
-rw-r--r--arch/mips/dec/kn02xa-berr.c7
-rw-r--r--arch/mips/dec/platform.c40
-rw-r--r--arch/mips/dec/prom/Makefile4
-rw-r--r--arch/mips/dec/prom/call_o32.S89
-rw-r--r--arch/mips/dec/prom/cmdline.c1
-rw-r--r--arch/mips/dec/prom/console.c6
-rw-r--r--arch/mips/dec/prom/dectypes.h1
-rw-r--r--arch/mips/dec/prom/identify.c3
-rw-r--r--arch/mips/dec/prom/init.c14
-rw-r--r--arch/mips/dec/prom/locore.S1
-rw-r--r--arch/mips/dec/prom/memory.c17
-rw-r--r--arch/mips/dec/reset.c1
-rw-r--r--arch/mips/dec/setup.c103
-rw-r--r--arch/mips/dec/tc.c2
-rw-r--r--arch/mips/dec/time.c40
-rw-r--r--arch/mips/dec/wbflush.c4
23 files changed, 238 insertions, 215 deletions
diff --git a/arch/mips/dec/Makefile b/arch/mips/dec/Makefile
index 3d5d2c56de8d..c9f62f1da31d 100644
--- a/arch/mips/dec/Makefile
+++ b/arch/mips/dec/Makefile
@@ -1,9 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for the DECstation family specific parts of the kernel
#
obj-y := ecc-berr.o int-handler.o ioasic-irq.o kn01-berr.o \
- kn02-irq.o kn02xa-berr.o reset.o setup.o time.o
+ kn02-irq.o kn02xa-berr.o platform.o reset.o setup.o time.o
obj-$(CONFIG_TC) += tc.o
obj-$(CONFIG_CPU_HAS_WB) += wbflush.o
diff --git a/arch/mips/dec/Platform b/arch/mips/dec/Platform
index cf55a6f4e720..c82391e832f9 100644
--- a/arch/mips/dec/Platform
+++ b/arch/mips/dec/Platform
@@ -1,7 +1,6 @@
#
# DECstation family
#
-platform-$(CONFIG_MACH_DECSTATION) += dec/
cflags-$(CONFIG_MACH_DECSTATION) += \
-I$(srctree)/arch/mips/include/asm/mach-dec
libs-$(CONFIG_MACH_DECSTATION) += arch/mips/dec/prom/
diff --git a/arch/mips/dec/ecc-berr.c b/arch/mips/dec/ecc-berr.c
index 5abf4e894216..1eb356fdd832 100644
--- a/arch/mips/dec/ecc-berr.c
+++ b/arch/mips/dec/ecc-berr.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Bus error event handling code for systems equipped with ECC
* handling logic, i.e. DECstation/DECsystem 5000/200 (KN02),
@@ -5,11 +6,6 @@
* 5900/260 (KN05) systems.
*
* Copyright (c) 2003, 2005 Maciej W. Rozycki
- *
- * 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/init.h>
@@ -21,6 +17,7 @@
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
+#include <asm/cpu-type.h>
#include <asm/irq_regs.h>
#include <asm/processor.h>
#include <asm/ptrace.h>
diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S
index 22afed16ccde..011d1d678840 100644
--- a/arch/mips/dec/int-handler.S
+++ b/arch/mips/dec/int-handler.S
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 1995, 1996, 1997 Paul M. Antoine and Harald Koerfgen
* Copyright (C) 2000, 2001, 2002, 2003, 2005 Maciej W. Rozycki
@@ -5,7 +6,7 @@
* Written by Ralf Baechle and Andreas Busse, modified for DECstation
* support by Paul Antoine and Harald Koerfgen.
*
- * completly rewritten:
+ * completely rewritten:
* Copyright (C) 1998 Harald Koerfgen
*
* Rewritten extensively for controller-driven IRQ support
@@ -118,7 +119,7 @@
* 7 FPU/R4k timer
*
* We handle the IRQ according to _our_ priority (see setup.c),
- * then we just return. If multiple IRQs are pending then we will
+ * then we just return. If multiple IRQs are pending then we will
* just take another exception, big deal.
*/
.align 5
@@ -130,7 +131,7 @@
*/
mfc0 t0,CP0_CAUSE # get pending interrupts
mfc0 t1,CP0_STATUS
-#ifdef CONFIG_32BIT
+#if defined(CONFIG_32BIT) && defined(CONFIG_MIPS_FP_SUPPORT)
lw t2,cpu_fpu_mask
#endif
andi t0,ST0_IM # CAUSE.CE may be non-zero!
@@ -138,7 +139,7 @@
beqz t0,spurious
-#ifdef CONFIG_32BIT
+#if defined(CONFIG_32BIT) && defined(CONFIG_MIPS_FP_SUPPORT)
and t2,t0
bnez t2,fpu # handle FPU immediately
#endif
@@ -146,7 +147,14 @@
/*
* Find irq with highest priority
*/
- PTR_LA t1,cpu_mask_nr_tbl
+ # open coded PTR_LA t1, cpu_mask_nr_tbl
+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
+ # open coded la t1, cpu_mask_nr_tbl
+ lui t1, %hi(cpu_mask_nr_tbl)
+ addiu t1, %lo(cpu_mask_nr_tbl)
+#else
+#error GCC `-msym32' option required for 64-bit DECstation builds
+#endif
1: lw t2,(t1)
nop
and t2,t0
@@ -195,7 +203,14 @@
/*
* Find irq with highest priority
*/
- PTR_LA t1,asic_mask_nr_tbl
+ # open coded PTR_LA t1,asic_mask_nr_tbl
+#if defined(CONFIG_32BIT) || defined(KBUILD_64BIT_SYM32)
+ # open coded la t1, asic_mask_nr_tbl
+ lui t1, %hi(asic_mask_nr_tbl)
+ addiu t1, %lo(asic_mask_nr_tbl)
+#else
+#error GCC `-msym32' option required for 64-bit DECstation builds
+#endif
2: lw t2,(t1)
nop
and t2,t0
@@ -221,7 +236,7 @@
FEXPORT(cpu_all_int) # HALT, timers, software junk
li a0,DEC_CPU_IRQ_BASE
srl t0,CAUSEB_IP
- li t1,CAUSEF_IP>>CAUSEB_IP # mask
+ li t1,CAUSEF_IP>>CAUSEB_IP # mask
b 1f
li t2,4 # nr of bits / 2
@@ -265,10 +280,15 @@ handle_it:
j dec_irq_dispatch
nop
-#ifdef CONFIG_32BIT
+#if defined(CONFIG_32BIT) && defined(CONFIG_MIPS_FP_SUPPORT)
fpu:
+ lw t0,fpu_kstat_irq
+ nop
+ lw t1,(t0)
+ nop
+ addu t1,1
j handle_fpe_int
- nop
+ sw t1,(t0)
#endif
spurious:
@@ -284,8 +304,8 @@ spurious:
*/
FEXPORT(dec_intr_unimplemented)
move a1,t0 # cheats way of printing an arg!
- PANIC("Unimplemented cpu interrupt! CP0_CAUSE: 0x%08x");
+ ASM_PANIC("Unimplemented cpu interrupt! CP0_CAUSE: 0x%08x");
FEXPORT(asic_intr_unimplemented)
move a1,t0 # cheats way of printing an arg!
- PANIC("Unimplemented asic interrupt! ASIC ISR: 0x%08x");
+ ASM_PANIC("Unimplemented asic interrupt! ASIC ISR: 0x%08x");
diff --git a/arch/mips/dec/ioasic-irq.c b/arch/mips/dec/ioasic-irq.c
index 824e08c73798..971f7b46759b 100644
--- a/arch/mips/dec/ioasic-irq.c
+++ b/arch/mips/dec/ioasic-irq.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* DEC I/O ASIC interrupts.
*
- * Copyright (c) 2002, 2003 Maciej W. Rozycki
- *
- * 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.
+ * Copyright (c) 2002, 2003, 2013 Maciej W. Rozycki
*/
#include <linux/init.h>
@@ -51,14 +47,51 @@ static struct irq_chip ioasic_irq_type = {
.irq_unmask = unmask_ioasic_irq,
};
+static void clear_ioasic_dma_irq(struct irq_data *d)
+{
+ u32 sir;
+
+ sir = ~(1 << (d->irq - ioasic_irq_base));
+ ioasic_write(IO_REG_SIR, sir);
+ fast_iob();
+}
+
static struct irq_chip ioasic_dma_irq_type = {
.name = "IO-ASIC-DMA",
- .irq_ack = ack_ioasic_irq,
+ .irq_ack = clear_ioasic_dma_irq,
.irq_mask = mask_ioasic_irq,
- .irq_mask_ack = ack_ioasic_irq,
.irq_unmask = unmask_ioasic_irq,
+ .irq_eoi = clear_ioasic_dma_irq,
};
+/*
+ * I/O ASIC implements two kinds of DMA interrupts, informational and
+ * error interrupts.
+ *
+ * The former do not stop DMA and should be cleared as soon as possible
+ * so that if they retrigger before the handler has completed, usually as
+ * a side effect of actions taken by the handler, then they are reissued.
+ * These use the `handle_edge_irq' handler that clears the request right
+ * away.
+ *
+ * The latter stop DMA and do not resume it until the interrupt has been
+ * cleared. This cannot be done until after a corrective action has been
+ * taken and this also means they will not retrigger. Therefore they use
+ * the `handle_fasteoi_irq' handler that only clears the request on the
+ * way out. Because MIPS processor interrupt inputs, one of which the I/O
+ * ASIC is cascaded to, are level-triggered it is recommended that error
+ * DMA interrupt action handlers are registered with the IRQF_ONESHOT flag
+ * set so that they are run with the interrupt line masked.
+ *
+ * This mask has `1' bits in the positions of informational interrupts.
+ */
+#define IO_IRQ_DMA_INFO \
+ (IO_IRQ_MASK(IO_INR_SCC0A_RXDMA) | \
+ IO_IRQ_MASK(IO_INR_SCC1A_RXDMA) | \
+ IO_IRQ_MASK(IO_INR_ISDN_TXDMA) | \
+ IO_IRQ_MASK(IO_INR_ISDN_RXDMA) | \
+ IO_IRQ_MASK(IO_INR_ASC_DMA))
+
void __init init_ioasic_irqs(int base)
{
int i;
@@ -71,7 +104,9 @@ void __init init_ioasic_irqs(int base)
irq_set_chip_and_handler(i, &ioasic_irq_type,
handle_level_irq);
for (; i < base + IO_IRQ_LINES; i++)
- irq_set_chip(i, &ioasic_dma_irq_type);
+ irq_set_chip_and_handler(i, &ioasic_dma_irq_type,
+ 1 << (i - base) & IO_IRQ_DMA_INFO ?
+ handle_edge_irq : handle_fasteoi_irq);
ioasic_irq_base = base;
}
diff --git a/arch/mips/dec/kn01-berr.c b/arch/mips/dec/kn01-berr.c
index 44d8a87a8a68..76efed7bc9f3 100644
--- a/arch/mips/dec/kn01-berr.c
+++ b/arch/mips/dec/kn01-berr.c
@@ -1,14 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Bus error event handling code for DECstation/DECsystem 3100
* and 2100 (KN01) systems equipped with parity error detection
* logic.
*
* Copyright (c) 2005 Maciej W. Rozycki
- *
- * 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/init.h>
@@ -23,7 +19,7 @@
#include <asm/page.h>
#include <asm/ptrace.h>
#include <asm/traps.h>
-#include <asm/uaccess.h>
+#include <linux/uaccess.h>
#include <asm/dec/kn01.h>
diff --git a/arch/mips/dec/kn02-irq.c b/arch/mips/dec/kn02-irq.c
index 37199f742c45..7e18de5743bf 100644
--- a/arch/mips/dec/kn02-irq.c
+++ b/arch/mips/dec/kn02-irq.c
@@ -1,13 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* DECstation 5000/200 (KN02) Control and Status Register
* interrupts.
*
* Copyright (c) 2002, 2003, 2005 Maciej W. Rozycki
- *
- * 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/init.h>
diff --git a/arch/mips/dec/kn02xa-berr.c b/arch/mips/dec/kn02xa-berr.c
index f434b759e3b9..9699fc4e6eb1 100644
--- a/arch/mips/dec/kn02xa-berr.c
+++ b/arch/mips/dec/kn02xa-berr.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Bus error event handling code for 5000-series systems equipped
* with parity error detection logic, i.e. DECstation/DECsystem
@@ -6,11 +7,6 @@
* (KN04-CA) systems.
*
* Copyright (c) 2005 Maciej W. Rozycki
- *
- * 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/init.h>
@@ -19,6 +15,7 @@
#include <linux/types.h>
#include <asm/addrspace.h>
+#include <asm/cpu-type.h>
#include <asm/irq_regs.h>
#include <asm/ptrace.h>
#include <asm/traps.h>
diff --git a/arch/mips/dec/platform.c b/arch/mips/dec/platform.c
new file mode 100644
index 000000000000..c4fcb8c58e01
--- /dev/null
+++ b/arch/mips/dec/platform.c
@@ -0,0 +1,40 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * DEC platform devices.
+ *
+ * Copyright (c) 2014 Maciej W. Rozycki
+ */
+
+#include <linux/ioport.h>
+#include <linux/kernel.h>
+#include <linux/mc146818rtc.h>
+#include <linux/platform_device.h>
+
+static struct resource dec_rtc_resources[] = {
+ {
+ .name = "rtc",
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct cmos_rtc_board_info dec_rtc_info = {
+ .flags = CMOS_RTC_FLAGS_NOFREQ,
+ .address_space = 64,
+};
+
+static struct platform_device dec_rtc_device = {
+ .name = "rtc_cmos",
+ .id = PLATFORM_DEVID_NONE,
+ .dev.platform_data = &dec_rtc_info,
+ .resource = dec_rtc_resources,
+ .num_resources = ARRAY_SIZE(dec_rtc_resources),
+};
+
+static int __init dec_add_devices(void)
+{
+ dec_rtc_resources[0].start = RTC_PORT(0);
+ dec_rtc_resources[0].end = RTC_PORT(0) + dec_kn_slot_size - 1;
+ return platform_device_register(&dec_rtc_device);
+}
+
+device_initcall(dec_add_devices);
diff --git a/arch/mips/dec/prom/Makefile b/arch/mips/dec/prom/Makefile
index 064ae7a76bdc..2bad87551203 100644
--- a/arch/mips/dec/prom/Makefile
+++ b/arch/mips/dec/prom/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0-only
#
# Makefile for the DECstation prom monitor library routines
# under Linux.
@@ -5,5 +6,4 @@
lib-y += init.o memory.o cmdline.o identify.o console.o
-lib-$(CONFIG_32BIT) += locore.o
-lib-$(CONFIG_64BIT) += call_o32.o
+lib-$(CONFIG_CPU_R3000) += locore.o
diff --git a/arch/mips/dec/prom/call_o32.S b/arch/mips/dec/prom/call_o32.S
deleted file mode 100644
index c0d1522d448f..000000000000
--- a/arch/mips/dec/prom/call_o32.S
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * O32 interface for the 64 (or N32) ABI.
- *
- * Copyright (C) 2002 Maciej W. Rozycki
- *
- * 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 <asm/asm.h>
-#include <asm/regdef.h>
-
-/* Maximum number of arguments supported. Must be even! */
-#define O32_ARGC 32
-/* Number of static registers we save. */
-#define O32_STATC 11
-/* Frame size for both of the above. */
-#define O32_FRAMESZ (4 * O32_ARGC + SZREG * O32_STATC)
-
- .text
-
-/*
- * O32 function call dispatcher, for interfacing 32-bit ROM routines.
- *
- * The standard 64 (N32) calling sequence is supported, with a0
- * holding a function pointer, a1-a7 -- its first seven arguments
- * and the stack -- remaining ones (up to O32_ARGC, including a1-a7).
- * Static registers, gp and fp are preserved, v0 holds a result.
- * This code relies on the called o32 function for sp and ra
- * restoration and thus both this dispatcher and the current stack
- * have to be placed in a KSEGx (or KUSEG) address space. Any
- * pointers passed have to point to addresses within one of these
- * spaces as well.
- */
-NESTED(call_o32, O32_FRAMESZ, ra)
- REG_SUBU sp,O32_FRAMESZ
-
- REG_S ra,O32_FRAMESZ-1*SZREG(sp)
- REG_S fp,O32_FRAMESZ-2*SZREG(sp)
- REG_S gp,O32_FRAMESZ-3*SZREG(sp)
- REG_S s7,O32_FRAMESZ-4*SZREG(sp)
- REG_S s6,O32_FRAMESZ-5*SZREG(sp)
- REG_S s5,O32_FRAMESZ-6*SZREG(sp)
- REG_S s4,O32_FRAMESZ-7*SZREG(sp)
- REG_S s3,O32_FRAMESZ-8*SZREG(sp)
- REG_S s2,O32_FRAMESZ-9*SZREG(sp)
- REG_S s1,O32_FRAMESZ-10*SZREG(sp)
- REG_S s0,O32_FRAMESZ-11*SZREG(sp)
-
- move jp,a0
-
- sll a0,a1,zero
- sll a1,a2,zero
- sll a2,a3,zero
- sll a3,a4,zero
- sw a5,0x10(sp)
- sw a6,0x14(sp)
- sw a7,0x18(sp)
-
- PTR_LA t0,O32_FRAMESZ(sp)
- PTR_LA t1,0x1c(sp)
- li t2,O32_ARGC-7
-1:
- lw t3,(t0)
- REG_ADDU t0,SZREG
- sw t3,(t1)
- REG_SUBU t2,1
- REG_ADDU t1,4
- bnez t2,1b
-
- jalr jp
-
- REG_L s0,O32_FRAMESZ-11*SZREG(sp)
- REG_L s1,O32_FRAMESZ-10*SZREG(sp)
- REG_L s2,O32_FRAMESZ-9*SZREG(sp)
- REG_L s3,O32_FRAMESZ-8*SZREG(sp)
- REG_L s4,O32_FRAMESZ-7*SZREG(sp)
- REG_L s5,O32_FRAMESZ-6*SZREG(sp)
- REG_L s6,O32_FRAMESZ-5*SZREG(sp)
- REG_L s7,O32_FRAMESZ-4*SZREG(sp)
- REG_L gp,O32_FRAMESZ-3*SZREG(sp)
- REG_L fp,O32_FRAMESZ-2*SZREG(sp)
- REG_L ra,O32_FRAMESZ-1*SZREG(sp)
-
- REG_ADDU sp,O32_FRAMESZ
- jr ra
-END(call_o32)
diff --git a/arch/mips/dec/prom/cmdline.c b/arch/mips/dec/prom/cmdline.c
index c3490bebbc5d..3ed63280ae29 100644
--- a/arch/mips/dec/prom/cmdline.c
+++ b/arch/mips/dec/prom/cmdline.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* cmdline.c: read the command line passed to us by the PROM.
*
diff --git a/arch/mips/dec/prom/console.c b/arch/mips/dec/prom/console.c
index caa6e047caf1..31a8441d8431 100644
--- a/arch/mips/dec/prom/console.c
+++ b/arch/mips/dec/prom/console.c
@@ -1,12 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* DECstation PROM-based early console support.
*
* Copyright (C) 2004, 2007 Maciej W. Rozycki
- *
- * 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/console.h>
#include <linux/init.h>
diff --git a/arch/mips/dec/prom/dectypes.h b/arch/mips/dec/prom/dectypes.h
index 69ea5b9c8190..9fcbcc7cdbd3 100644
--- a/arch/mips/dec/prom/dectypes.h
+++ b/arch/mips/dec/prom/dectypes.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef DECTYPES
#define DECTYPES
diff --git a/arch/mips/dec/prom/identify.c b/arch/mips/dec/prom/identify.c
index 95e26f4bb38f..80cd14cd1a63 100644
--- a/arch/mips/dec/prom/identify.c
+++ b/arch/mips/dec/prom/identify.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* identify.c: machine identification code.
*
@@ -7,7 +8,7 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mc146818rtc.h>
-#include <linux/module.h>
+#include <linux/export.h>
#include <linux/string.h>
#include <linux/types.h>
diff --git a/arch/mips/dec/prom/init.c b/arch/mips/dec/prom/init.c
index ab169046e442..8d74d7d6c05b 100644
--- a/arch/mips/dec/prom/init.c
+++ b/arch/mips/dec/prom/init.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* init.c: PROM library initialisation code.
*
@@ -13,6 +14,7 @@
#include <asm/bootinfo.h>
#include <asm/cpu.h>
+#include <asm/cpu-type.h>
#include <asm/processor.h>
#include <asm/dec/prom.h>
@@ -40,7 +42,7 @@ int (*__pmax_close)(int);
* Detect which PROM the DECSTATION has, and set the callback vectors
* appropriately.
*/
-void __init which_prom(s32 magic, s32 *prom_vec)
+static void __init which_prom(s32 magic, s32 *prom_vec)
{
/*
* No sign of the REX PROM's magic number means we assume a non-REX
@@ -87,7 +89,7 @@ void __init which_prom(s32 magic, s32 *prom_vec)
void __init prom_init(void)
{
extern void dec_machine_halt(void);
- static char cpu_msg[] __initdata =
+ static const char cpu_msg[] __initconst =
"Sorry, this kernel is compiled for a wrong CPU type!\n";
s32 argc = fw_arg0;
s32 *argv = (void *)fw_arg1;
@@ -103,15 +105,15 @@ void __init prom_init(void)
if (prom_is_rex(magic))
rex_clear_cache();
- /* Register the early console. */
+ /* Register the early console. */
register_prom_console();
/* Were we compiled with the right CPU option? */
#if defined(CONFIG_CPU_R3000)
if ((current_cpu_type() == CPU_R4000SC) ||
(current_cpu_type() == CPU_R4400SC)) {
- static char r4k_msg[] __initdata =
- "Please recompile with \"CONFIG_CPU_R4x00 = y\".\n";
+ static const char r4k_msg[] __initconst =
+ "Please recompile with \"CONFIG_CPU_R4X00 = y\".\n";
printk(cpu_msg);
printk(r4k_msg);
dec_machine_halt();
@@ -121,7 +123,7 @@ void __init prom_init(void)
#if defined(CONFIG_CPU_R4X00)
if ((current_cpu_type() == CPU_R3000) ||
(current_cpu_type() == CPU_R3000A)) {
- static char r3k_msg[] __initdata =
+ static const char r3k_msg[] __initconst =
"Please recompile with \"CONFIG_CPU_R3000 = y\".\n";
printk(cpu_msg);
printk(r3k_msg);
diff --git a/arch/mips/dec/prom/locore.S b/arch/mips/dec/prom/locore.S
index f72b5741025f..0eb8fab62ab0 100644
--- a/arch/mips/dec/prom/locore.S
+++ b/arch/mips/dec/prom/locore.S
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
/*
* locore.S
*/
diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c
index 0aadac742900..44490c30d63b 100644
--- a/arch/mips/dec/prom/memory.c
+++ b/arch/mips/dec/prom/memory.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* memory.c: memory initialisation code.
*
@@ -7,11 +8,10 @@
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/mm.h>
-#include <linux/bootmem.h>
+#include <linux/memblock.h>
#include <linux/types.h>
#include <asm/addrspace.h>
-#include <asm/bootinfo.h>
#include <asm/dec/machtype.h>
#include <asm/dec/prom.h>
#include <asm/page.h>
@@ -22,12 +22,12 @@ volatile unsigned long mem_err; /* So we know an error occurred */
/*
* Probe memory in 4MB chunks, waiting for an error to tell us we've fallen
- * off the end of real memory. Only suitable for the 2100/3100's (PMAX).
+ * off the end of real memory. Only suitable for the 2100/3100's (PMAX).
*/
#define CHUNK_SIZE 0x400000
-static inline void pmax_setup_memory_region(void)
+static __init void pmax_setup_memory_region(void)
{
volatile unsigned char *memory_page, dummy;
char old_handler[0x80];
@@ -49,15 +49,14 @@ static inline void pmax_setup_memory_region(void)
}
memcpy((void *)(CKSEG0 + 0x80), &old_handler, 0x80);
- add_memory_region(0, (unsigned long)memory_page - CKSEG1 - CHUNK_SIZE,
- BOOT_MEM_RAM);
+ memblock_add(0, (unsigned long)memory_page - CKSEG1 - CHUNK_SIZE);
}
/*
* Use the REX prom calls to get hold of the memory bitmap, and thence
* determine memory size.
*/
-static inline void rex_setup_memory_region(void)
+static __init void rex_setup_memory_region(void)
{
int i, bitmap_size;
unsigned long mem_start = 0, mem_size = 0;
@@ -75,13 +74,13 @@ static inline void rex_setup_memory_region(void)
else if (!mem_size)
mem_start += (8 * bm->pagesize);
else {
- add_memory_region(mem_start, mem_size, BOOT_MEM_RAM);
+ memblock_add(mem_start, mem_size);
mem_start += mem_size + (8 * bm->pagesize);
mem_size = 0;
}
}
if (mem_size)
- add_memory_region(mem_start, mem_size, BOOT_MEM_RAM);
+ memblock_add(mem_start, mem_size);
}
void __init prom_meminit(u32 magic)
diff --git a/arch/mips/dec/reset.c b/arch/mips/dec/reset.c
index c15a879046e5..3df01f1da347 100644
--- a/arch/mips/dec/reset.c
+++ b/arch/mips/dec/reset.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Reset a DECstation machine.
*
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c
index 741cb4235bde..87f0a1436bf9 100644
--- a/arch/mips/dec/setup.c
+++ b/arch/mips/dec/setup.c
@@ -6,27 +6,34 @@
* for more details.
*
* Copyright (C) 1998 Harald Koerfgen
- * Copyright (C) 2000, 2001, 2002, 2003, 2005 Maciej W. Rozycki
+ * Copyright (C) 2000, 2001, 2002, 2003, 2005, 2020 Maciej W. Rozycki
*/
#include <linux/console.h>
+#include <linux/export.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
-#include <linux/module.h>
+#include <linux/irq.h>
+#include <linux/irqnr.h>
+#include <linux/memblock.h>
#include <linux/param.h>
+#include <linux/percpu-defs.h>
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/pm.h>
-#include <linux/irq.h>
+#include <asm/addrspace.h>
#include <asm/bootinfo.h>
#include <asm/cpu.h>
#include <asm/cpu-features.h>
+#include <asm/cpu-type.h>
#include <asm/irq.h>
#include <asm/irq_cpu.h>
#include <asm/mipsregs.h>
+#include <asm/page.h>
#include <asm/reboot.h>
+#include <asm/sections.h>
#include <asm/time.h>
#include <asm/traps.h>
#include <asm/wbflush.h>
@@ -57,15 +64,16 @@ EXPORT_SYMBOL(dec_kn_slot_size);
int dec_tc_bus;
DEFINE_SPINLOCK(ioasic_ssr_lock);
+EXPORT_SYMBOL(ioasic_ssr_lock);
volatile u32 *ioasic_base;
EXPORT_SYMBOL(ioasic_base);
/*
- * IRQ routing and priority tables. Priorites are set as follows:
+ * IRQ routing and priority tables. Priorities are set as follows:
*
- * KN01 KN230 KN02 KN02-BA KN02-CA KN03
+ * KN01 KN230 KN02 KN02-BA KN02-CA KN03
*
* MEMORY CPU CPU CPU ASIC CPU CPU
* RTC CPU CPU CPU ASIC CPU CPU
@@ -97,29 +105,10 @@ int_ptr asic_mask_nr_tbl[DEC_MAX_ASIC_INTS][2] = {
{ { .i = ~0 }, { .p = asic_intr_unimplemented } },
};
int cpu_fpu_mask = DEC_CPU_IRQ_MASK(DEC_CPU_INR_FPU);
+int *fpu_kstat_irq;
-static struct irqaction ioirq = {
- .handler = no_action,
- .name = "cascade",
- .flags = IRQF_NO_THREAD,
-};
-static struct irqaction fpuirq = {
- .handler = no_action,
- .name = "fpu",
- .flags = IRQF_NO_THREAD,
-};
-
-static struct irqaction busirq = {
- .name = "bus error",
- .flags = IRQF_NO_THREAD,
-};
-
-static struct irqaction haltirq = {
- .handler = dec_intr_halt,
- .name = "halt",
- .flags = IRQF_NO_THREAD,
-};
-
+static irq_handler_t busirq_handler;
+static unsigned int busirq_flags = IRQF_NO_THREAD;
/*
* Bus error (DBE/IBE exceptions and bus interrupts) handling setup.
@@ -128,22 +117,22 @@ static void __init dec_be_init(void)
{
switch (mips_machtype) {
case MACH_DS23100: /* DS2100/DS3100 Pmin/Pmax */
- board_be_handler = dec_kn01_be_handler;
- busirq.handler = dec_kn01_be_interrupt;
- busirq.flags |= IRQF_SHARED;
+ mips_set_be_handler(dec_kn01_be_handler);
+ busirq_handler = dec_kn01_be_interrupt;
+ busirq_flags |= IRQF_SHARED;
dec_kn01_be_init();
break;
case MACH_DS5000_1XX: /* DS5000/1xx 3min */
case MACH_DS5000_XX: /* DS5000/xx Maxine */
- board_be_handler = dec_kn02xa_be_handler;
- busirq.handler = dec_kn02xa_be_interrupt;
+ mips_set_be_handler(dec_kn02xa_be_handler);
+ busirq_handler = dec_kn02xa_be_interrupt;
dec_kn02xa_be_init();
break;
case MACH_DS5000_200: /* DS5000/200 3max */
case MACH_DS5000_2X0: /* DS5000/240 3max+ */
case MACH_DS5900: /* DS5900 bigmax */
- board_be_handler = dec_ecc_be_handler;
- busirq.handler = dec_ecc_be_interrupt;
+ mips_set_be_handler(dec_ecc_be_handler);
+ busirq_handler = dec_ecc_be_interrupt;
dec_ecc_be_init();
break;
}
@@ -161,6 +150,9 @@ void __init plat_mem_setup(void)
ioport_resource.start = ~0UL;
ioport_resource.end = 0UL;
+
+ /* Stay away from the firmware working memory area for now. */
+ memblock_reserve(PHYS_OFFSET, __pa_symbol(&_text) - PHYS_OFFSET);
}
/*
@@ -413,7 +405,7 @@ static void __init dec_init_kn02(void)
/*
* Machine-specific initialisation for KN02-BA, aka DS5000/1xx
- * (xx = 20, 25, 33), aka 3min. Also applies to KN04(-BA), aka
+ * (xx = 20, 25, 33), aka 3min. Also applies to KN04(-BA), aka
* DS5000/150, aka 4min.
*/
static int kn02ba_interrupt[DEC_NR_INTS] __initdata = {
@@ -748,20 +740,41 @@ void __init arch_init_irq(void)
cpu_fpu_mask = 0;
dec_interrupt[DEC_IRQ_FPU] = -1;
}
+ /* Free the halt interrupt unused on R4k systems. */
+ if (current_cpu_type() == CPU_R4000SC ||
+ current_cpu_type() == CPU_R4400SC)
+ dec_interrupt[DEC_IRQ_HALT] = -1;
/* Register board interrupts: FPU and cascade. */
- if (dec_interrupt[DEC_IRQ_FPU] >= 0)
- setup_irq(dec_interrupt[DEC_IRQ_FPU], &fpuirq);
- if (dec_interrupt[DEC_IRQ_CASCADE] >= 0)
- setup_irq(dec_interrupt[DEC_IRQ_CASCADE], &ioirq);
-
+ if (IS_ENABLED(CONFIG_MIPS_FP_SUPPORT) &&
+ dec_interrupt[DEC_IRQ_FPU] >= 0 && cpu_has_fpu) {
+ struct irq_desc *desc_fpu;
+ int irq_fpu;
+
+ irq_fpu = dec_interrupt[DEC_IRQ_FPU];
+ if (request_irq(irq_fpu, no_action, IRQF_NO_THREAD, "fpu",
+ NULL))
+ pr_err("Failed to register fpu interrupt\n");
+ desc_fpu = irq_to_desc(irq_fpu);
+ fpu_kstat_irq = this_cpu_ptr(&desc_fpu->kstat_irqs->cnt);
+ }
+ if (dec_interrupt[DEC_IRQ_CASCADE] >= 0) {
+ if (request_irq(dec_interrupt[DEC_IRQ_CASCADE], no_action,
+ IRQF_NO_THREAD, "cascade", NULL))
+ pr_err("Failed to register cascade interrupt\n");
+ }
/* Register the bus error interrupt. */
- if (dec_interrupt[DEC_IRQ_BUS] >= 0 && busirq.handler)
- setup_irq(dec_interrupt[DEC_IRQ_BUS], &busirq);
-
+ if (dec_interrupt[DEC_IRQ_BUS] >= 0 && busirq_handler) {
+ if (request_irq(dec_interrupt[DEC_IRQ_BUS], busirq_handler,
+ busirq_flags, "bus error", busirq_handler))
+ pr_err("Failed to register bus error interrupt\n");
+ }
/* Register the HALT interrupt. */
- if (dec_interrupt[DEC_IRQ_HALT] >= 0)
- setup_irq(dec_interrupt[DEC_IRQ_HALT], &haltirq);
+ if (dec_interrupt[DEC_IRQ_HALT] >= 0) {
+ if (request_irq(dec_interrupt[DEC_IRQ_HALT], dec_intr_halt,
+ IRQF_NO_THREAD, "halt", NULL))
+ pr_err("Failed to register halt interrupt\n");
+ }
}
asmlinkage unsigned int dec_irq_dispatch(unsigned int irq)
diff --git a/arch/mips/dec/tc.c b/arch/mips/dec/tc.c
index 732027c79834..dba58397668e 100644
--- a/arch/mips/dec/tc.c
+++ b/arch/mips/dec/tc.c
@@ -52,7 +52,7 @@ int __init tc_bus_get_info(struct tc_bus *tbus)
case MACH_DS5900:
tbus->ext_slot_base = 0x20000000;
tbus->ext_slot_size = 0x20000000;
- /* fall through */
+ fallthrough;
case MACH_DS5000_1XX:
tbus->num_tcslots = 3;
break;
diff --git a/arch/mips/dec/time.c b/arch/mips/dec/time.c
index ea57f39e6736..c38686f89a18 100644
--- a/arch/mips/dec/time.c
+++ b/arch/mips/dec/time.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 1991, 1992, 1995 Linus Torvalds
* Copyright (C) 2000, 2003 Maciej W. Rozycki
@@ -18,7 +19,7 @@
#include <asm/dec/ioasic.h>
#include <asm/dec/machtype.h>
-void read_persistent_clock(struct timespec *ts)
+void read_persistent_clock64(struct timespec64 *ts)
{
unsigned int year, mon, day, hour, min, sec, real_year;
unsigned long flags;
@@ -53,19 +54,20 @@ void read_persistent_clock(struct timespec *ts)
year += real_year - 72 + 2000;
- ts->tv_sec = mktime(year, mon, day, hour, min, sec);
+ ts->tv_sec = mktime64(year, mon, day, hour, min, sec);
ts->tv_nsec = 0;
}
/*
- * In order to set the CMOS clock precisely, rtc_mips_set_mmss has to
+ * In order to set the CMOS clock precisely, update_persistent_clock64 has to
* be called 500 ms after the second nowtime has started, because when
* nowtime is written into the registers of the CMOS clock, it will
* jump to the next second precisely 500 ms later. Check the Dallas
* DS1287 data sheet for details.
*/
-int rtc_mips_set_mmss(unsigned long nowtime)
+int update_persistent_clock64(struct timespec64 now)
{
+ time64_t nowtime = now.tv_sec;
int retval = 0;
int real_seconds, real_minutes, cmos_minutes;
unsigned char save_control, save_freq_select;
@@ -90,8 +92,7 @@ int rtc_mips_set_mmss(unsigned long nowtime)
* messing with unknown time zones but requires your
* RTC not to be off by more than 15 minutes
*/
- real_seconds = nowtime % 60;
- real_minutes = nowtime / 60;
+ real_minutes = div_s64_rem(nowtime, 60, &real_seconds);
if (((abs(real_minutes - cmos_minutes) + 15) / 30) & 1)
real_minutes += 30; /* correct for half hour time zone */
real_minutes %= 60;
@@ -125,13 +126,18 @@ int rtc_mips_set_mmss(unsigned long nowtime)
void __init plat_time_init(void)
{
+ int ioasic_clock = 0;
u32 start, end;
- int i = HZ / 10;
+ int i = HZ / 8;
/* Set up the rate of periodic DS1287 interrupts. */
ds1287_set_base_clock(HZ);
+ /* On some I/O ASIC systems we have the I/O ASIC's counter. */
+ if (IOASIC)
+ ioasic_clock = dec_ioasic_clocksource_init() == 0;
if (cpu_has_counter) {
+ ds1287_timer_state();
while (!ds1287_timer_state())
;
@@ -143,12 +149,24 @@ void __init plat_time_init(void)
end = read_c0_count();
- mips_hpt_frequency = (end - start) * 10;
+ mips_hpt_frequency = (end - start) * 8;
printk(KERN_INFO "MIPS counter frequency %dHz\n",
mips_hpt_frequency);
- } else if (IOASIC)
- /* For pre-R4k systems we use the I/O ASIC's counter. */
- dec_ioasic_clocksource_init();
+
+ /*
+ * All R4k DECstations suffer from the CP0 Count erratum,
+ * so we can't use the timer as a clock source, and a clock
+ * event both at a time. An accurate wall clock is more
+ * important than a high-precision interval timer so only
+ * use the timer as a clock source, and not a clock event
+ * if there's no I/O ASIC counter available to serve as a
+ * clock source.
+ */
+ if (!ioasic_clock) {
+ init_r4k_clocksource();
+ mips_hpt_frequency = 0;
+ }
+ }
ds1287_clockevent_init(dec_interrupt[DEC_IRQ_RTC]);
}
diff --git a/arch/mips/dec/wbflush.c b/arch/mips/dec/wbflush.c
index 56bda4a396b5..dad64d1789b2 100644
--- a/arch/mips/dec/wbflush.c
+++ b/arch/mips/dec/wbflush.c
@@ -14,6 +14,7 @@
* Copyright (C) 2002 Maciej W. Rozycki
*/
+#include <linux/export.h>
#include <linux/init.h>
#include <asm/bootinfo.h>
@@ -88,7 +89,4 @@ static void wbflush_mips(void)
{
__fast_iob();
}
-
-#include <linux/module.h>
-
EXPORT_SYMBOL(__wbflush);