MIPS: Loongson64: Drop legacy IRQ code
authorJiaxun Yang <jiaxun.yang@flygoat.com>
Wed, 25 Mar 2020 03:55:00 +0000 (11:55 +0800)
committerThomas Bogendoerfer <tsbogend@alpha.franken.de>
Wed, 25 Mar 2020 15:07:11 +0000 (16:07 +0100)
We've made generic irqchip drivers for Loongson-3 platform, it's time
to say goodbye to these legacy code.

Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
Co-developed-by: Huacai Chen <chenhc@lemote.com>
Signed-off-by: Huacai Chen <chenhc@lemote.com>
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
arch/mips/include/asm/mach-loongson64/boot_param.h
arch/mips/include/asm/mach-loongson64/irq.h
arch/mips/loongson64/Makefile
arch/mips/loongson64/init.c
arch/mips/loongson64/irq.c [deleted file]
arch/mips/loongson64/smp.c

index 8c286be..2ed483e 100644 (file)
@@ -2,6 +2,8 @@
 #ifndef __ASM_MACH_LOONGSON64_BOOT_PARAM_H_
 #define __ASM_MACH_LOONGSON64_BOOT_PARAM_H_
 
+#include <linux/types.h>
+
 #define SYSTEM_RAM_LOW         1
 #define SYSTEM_RAM_HIGH                2
 #define SYSTEM_RAM_RESERVED    3
index 0d39556..d41dc4a 100644 (file)
@@ -7,34 +7,6 @@
 /* cpu core interrupt numbers */
 #define MIPS_CPU_IRQ_BASE 56
 
-#define LOONGSON_UART_IRQ   (MIPS_CPU_IRQ_BASE + 2) /* UART */
-#define LOONGSON_BRIDGE_IRQ (MIPS_CPU_IRQ_BASE + 3) /* CASCADE */
-#define LOONGSON_TIMER_IRQ  (MIPS_CPU_IRQ_BASE + 7) /* CPU Timer */
-
-#define LOONGSON_HT1_CFG_BASE          loongson_sysconf.ht_control_base
-#define LOONGSON_HT1_INT_VECTOR_BASE   (LOONGSON_HT1_CFG_BASE + 0x80)
-#define LOONGSON_HT1_INT_EN_BASE       (LOONGSON_HT1_CFG_BASE + 0xa0)
-#define LOONGSON_HT1_INT_VECTOR(n)     \
-               LOONGSON3_REG32(LOONGSON_HT1_INT_VECTOR_BASE, 4 * (n))
-#define LOONGSON_HT1_INTN_EN(n)                \
-               LOONGSON3_REG32(LOONGSON_HT1_INT_EN_BASE, 4 * (n))
-
-#define LOONGSON_INT_ROUTER_OFFSET     0x1400
-#define LOONGSON_INT_ROUTER_INTEN      \
-         LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x24)
-#define LOONGSON_INT_ROUTER_INTENSET   \
-         LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x28)
-#define LOONGSON_INT_ROUTER_INTENCLR   \
-         LOONGSON3_REG32(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + 0x2c)
-#define LOONGSON_INT_ROUTER_ENTRY(n)   \
-         LOONGSON3_REG8(LOONGSON3_REG_BASE, LOONGSON_INT_ROUTER_OFFSET + n)
-#define LOONGSON_INT_ROUTER_LPC                LOONGSON_INT_ROUTER_ENTRY(0x0a)
-#define LOONGSON_INT_ROUTER_HT1(n)     LOONGSON_INT_ROUTER_ENTRY(n + 0x18)
-
-#define LOONGSON_INT_COREx_INTy(x, y)  (1<<(x) | 1<<(y+4))     /* route to int y of core x */
-
-extern void fixup_irqs(void);
-extern void loongson3_ipi_interrupt(struct pt_regs *regs);
-
 #include <asm/mach-generic/irq.h>
+
 #endif /* __ASM_MACH_LOONGSON64_IRQ_H_ */
index 7821891..b7f40b1 100644 (file)
@@ -2,7 +2,7 @@
 #
 # Makefile for Loongson-3 family machines
 #
-obj-$(CONFIG_MACH_LOONGSON64) += irq.o cop2-ex.o platform.o acpi_init.o dma.o \
+obj-$(CONFIG_MACH_LOONGSON64) += cop2-ex.o platform.o acpi_init.o dma.o \
                                setup.o init.o env.o time.o reset.o \
 
 obj-$(CONFIG_SMP)      += smp.o
index 5ac1a0f..da38944 100644 (file)
@@ -4,6 +4,7 @@
  * Author: Wu Zhangjin, wuzhangjin@gmail.com
  */
 
+#include <linux/irqchip.h>
 #include <linux/memblock.h>
 #include <asm/bootinfo.h>
 #include <asm/traps.h>
@@ -44,3 +45,8 @@ void __init prom_init(void)
 void __init prom_free_prom_memory(void)
 {
 }
+
+void __init arch_init_irq(void)
+{
+       irqchip_init();
+}
diff --git a/arch/mips/loongson64/irq.c b/arch/mips/loongson64/irq.c
deleted file mode 100644 (file)
index 79ad797..0000000
+++ /dev/null
@@ -1,162 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-#include <loongson.h>
-#include <irq.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-
-#include <asm/irq_cpu.h>
-#include <asm/i8259.h>
-#include <asm/mipsregs.h>
-
-#include "smp.h"
-
-extern void loongson3_send_irq_by_ipi(int cpu, int irqs);
-
-unsigned int irq_cpu[16] = {[0 ... 15] = -1};
-unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15};
-unsigned int local_irq = 1<<0 | 1<<1 | 1<<2 | 1<<7 | 1<<8 | 1<<12;
-
-int plat_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity,
-                         bool force)
-{
-       unsigned int cpu;
-       struct cpumask new_affinity;
-
-       /* I/O devices are connected on package-0 */
-       cpumask_copy(&new_affinity, affinity);
-       for_each_cpu(cpu, affinity)
-               if (cpu_data[cpu].package > 0)
-                       cpumask_clear_cpu(cpu, &new_affinity);
-
-       if (cpumask_empty(&new_affinity))
-               return -EINVAL;
-
-       cpumask_copy(d->common->affinity, &new_affinity);
-
-       return IRQ_SET_MASK_OK_NOCOPY;
-}
-
-static void ht_irqdispatch(void)
-{
-       unsigned int i, irq;
-       struct irq_data *irqd;
-       struct cpumask affinity;
-
-       irq = LOONGSON_HT1_INT_VECTOR(0);
-       LOONGSON_HT1_INT_VECTOR(0) = irq; /* Acknowledge the IRQs */
-
-       for (i = 0; i < ARRAY_SIZE(ht_irq); i++) {
-               if (!(irq & (0x1 << ht_irq[i])))
-                       continue;
-
-               /* handled by local core */
-               if (local_irq & (0x1 << ht_irq[i])) {
-                       do_IRQ(ht_irq[i]);
-                       continue;
-               }
-
-               irqd = irq_get_irq_data(ht_irq[i]);
-               cpumask_and(&affinity, irqd->common->affinity, cpu_active_mask);
-               if (cpumask_empty(&affinity)) {
-                       do_IRQ(ht_irq[i]);
-                       continue;
-               }
-
-               irq_cpu[ht_irq[i]] = cpumask_next(irq_cpu[ht_irq[i]], &affinity);
-               if (irq_cpu[ht_irq[i]] >= nr_cpu_ids)
-                       irq_cpu[ht_irq[i]] = cpumask_first(&affinity);
-
-               if (irq_cpu[ht_irq[i]] == 0) {
-                       do_IRQ(ht_irq[i]);
-                       continue;
-               }
-
-               /* balanced by other cores */
-               loongson3_send_irq_by_ipi(irq_cpu[ht_irq[i]], (0x1 << ht_irq[i]));
-       }
-}
-
-#define UNUSED_IPS (CAUSEF_IP5 | CAUSEF_IP4 | CAUSEF_IP1 | CAUSEF_IP0)
-
-asmlinkage void plat_irq_dispatch(void)
-{
-       unsigned int pending;
-
-       pending = read_c0_cause() & read_c0_status() & ST0_IM;
-
-       if (pending & CAUSEF_IP7)
-               do_IRQ(LOONGSON_TIMER_IRQ);
-#if defined(CONFIG_SMP)
-       if (pending & CAUSEF_IP6)
-               loongson3_ipi_interrupt(NULL);
-#endif
-       if (pending & CAUSEF_IP3)
-               ht_irqdispatch();
-       if (pending & CAUSEF_IP2)
-               do_IRQ(LOONGSON_UART_IRQ);
-       if (pending & UNUSED_IPS) {
-               pr_err("%s : spurious interrupt\n", __func__);
-               spurious_interrupt();
-       }
-}
-
-static inline void mask_loongson_irq(struct irq_data *d) { }
-static inline void unmask_loongson_irq(struct irq_data *d) { }
-
- /* For MIPS IRQs which shared by all cores */
-static struct irq_chip loongson_irq_chip = {
-       .name           = "Loongson",
-       .irq_ack        = mask_loongson_irq,
-       .irq_mask       = mask_loongson_irq,
-       .irq_mask_ack   = mask_loongson_irq,
-       .irq_unmask     = unmask_loongson_irq,
-       .irq_eoi        = unmask_loongson_irq,
-};
-
-void irq_router_init(void)
-{
-       int i;
-
-       /* route LPC int to cpu core0 int 0 */
-       LOONGSON_INT_ROUTER_LPC =
-               LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 0);
-       /* route HT1 int0 ~ int7 to cpu core0 INT1*/
-       for (i = 0; i < 8; i++)
-               LOONGSON_INT_ROUTER_HT1(i) =
-                       LOONGSON_INT_COREx_INTy(loongson_sysconf.boot_cpu_id, 1);
-       /* enable HT1 interrupt */
-       LOONGSON_HT1_INTN_EN(0) = 0xffffffff;
-       /* enable router interrupt intenset */
-       LOONGSON_INT_ROUTER_INTENSET =
-               LOONGSON_INT_ROUTER_INTEN | (0xffff << 16) | 0x1 << 10;
-}
-
-void __init arch_init_irq(void)
-{
-       struct irq_chip *chip;
-
-       clear_c0_status(ST0_IM | ST0_BEV);
-
-       irq_router_init();
-       mips_cpu_irq_init();
-       init_i8259_irqs();
-       chip = irq_get_chip(I8259A_IRQ_BASE);
-       chip->irq_set_affinity = plat_set_irq_affinity;
-
-       irq_set_chip_and_handler(LOONGSON_UART_IRQ,
-                       &loongson_irq_chip, handle_percpu_irq);
-       irq_set_chip_and_handler(LOONGSON_BRIDGE_IRQ,
-                       &loongson_irq_chip, handle_percpu_irq);
-
-       set_c0_status(STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP6);
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-
-void fixup_irqs(void)
-{
-       irq_cpu_offline();
-       clear_c0_status(ST0_IM);
-}
-
-#endif
index de8e074..e1fe8bb 100644 (file)
@@ -4,6 +4,7 @@
  * Author: Chen Huacai, chenhc@lemote.com
  */
 
+#include <irq.h>
 #include <linux/init.h>
 #include <linux/cpu.h>
 #include <linux/sched.h>
@@ -25,6 +26,8 @@
 
 DEFINE_PER_CPU(int, cpu_state);
 
+#define LS_IPI_IRQ (MIPS_CPU_IRQ_BASE + 6)
+
 static void *ipi_set0_regs[16];
 static void *ipi_clear0_regs[16];
 static void *ipi_status0_regs[16];
@@ -302,20 +305,13 @@ loongson3_send_ipi_mask(const struct cpumask *mask, unsigned int action)
                ipi_write_action(cpu_logical_map(i), (u32)action);
 }
 
-#define IPI_IRQ_OFFSET 6
-
-void loongson3_send_irq_by_ipi(int cpu, int irqs)
-{
-       ipi_write_action(cpu_logical_map(cpu), irqs << IPI_IRQ_OFFSET);
-}
 
-void loongson3_ipi_interrupt(struct pt_regs *regs)
+static irqreturn_t loongson3_ipi_interrupt(int irq, void *dev_id)
 {
        int i, cpu = smp_processor_id();
-       unsigned int action, c0count, irqs;
+       unsigned int action, c0count;
 
        action = ipi_read_clear(cpu);
-       irqs = action >> IPI_IRQ_OFFSET;
 
        if (action & SMP_RESCHEDULE_YOURSELF)
                scheduler_ipi();
@@ -335,13 +331,7 @@ void loongson3_ipi_interrupt(struct pt_regs *regs)
                __wbflush(); /* Let others see the result ASAP */
        }
 
-       if (irqs) {
-               int irq;
-               while ((irq = ffs(irqs))) {
-                       do_IRQ(irq-1);
-                       irqs &= ~(1<<(irq-1));
-               }
-       }
+       return IRQ_HANDLED;
 }
 
 #define MAX_LOOPS 800
@@ -438,6 +428,9 @@ static void __init loongson3_smp_setup(void)
 
 static void __init loongson3_prepare_cpus(unsigned int max_cpus)
 {
+       if (request_irq(LS_IPI_IRQ, loongson3_ipi_interrupt,
+                       IRQF_PERCPU | IRQF_NO_SUSPEND, "SMP_IPI", NULL))
+               pr_err("Failed to request IPI IRQ\n");
        init_cpu_present(cpu_possible_mask);
        per_cpu(cpu_state, smp_processor_id()) = CPU_ONLINE;
 }
@@ -484,7 +477,8 @@ static int loongson3_cpu_disable(void)
        set_cpu_online(cpu, false);
        calculate_cpu_foreign_map();
        local_irq_save(flags);
-       fixup_irqs();
+       irq_cpu_offline();
+       clear_c0_status(ST0_IM);
        local_irq_restore(flags);
        local_flush_tlb_all();