summaryrefslogtreecommitdiff
path: root/arch/metag/kernel/irq.c
diff options
context:
space:
mode:
authorJames Hogan <jhogan@kernel.org>2017-10-24 13:07:54 +0100
committerJames Hogan <jhogan@kernel.org>2018-02-22 11:07:21 +0000
commitbb6fb6dfcc17cddac11ac295861f7608194447a7 (patch)
tree47ee071a415546dd01adbf628f61acb80473d476 /arch/metag/kernel/irq.c
parent91ab883eb21325ad80f3473633f794c78ac87f51 (diff)
metag: Remove arch/metag/
The earliest Meta architecture port of Linux I have a record of was an import of a Meta port of Linux v2.4.1 in February 2004, which was worked on significantly over the next few years by Graham Whaley, Will Newton, Matt Fleming, myself and others. Eventually the port was merged into mainline in v3.9 in March 2013, not long after Imagination Technologies bought MIPS Technologies and shifted its CPU focus over to the MIPS architecture. As a result, though the port was maintained for a while, kept on life support for a while longer, and useful for testing a few specific drivers for which I don't have ready access to the equivalent MIPS hardware, it is now essentially dead with no users. It is also stuck using an out-of-tree toolchain based on GCC 4.2.4 which is no longer maintained, now struggles to build modern kernels due to toolchain bugs, and doesn't itself build with a modern GCC. The latest buildroot port is still using an old uClibc snapshot which is no longer served, and the latest uClibc doesn't build with GCC 4.2.4. So lets call it a day and drop the Meta architecture port from the kernel. RIP Meta. Signed-off-by: James Hogan <jhogan@kernel.org> Link: https://lkml.kernel.org/r/95906b76-6ce1-3f84-eaba-c29b4ae952eb@roeck-us.net Reviewed-by: Guenter Roeck <linux@roeck-us.net> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Acked-by: Graham Whaley <graham.whaley@gmail.com> Cc: linux-metag@vger.kernel.org
Diffstat (limited to 'arch/metag/kernel/irq.c')
-rw-r--r--arch/metag/kernel/irq.c293
1 files changed, 0 insertions, 293 deletions
diff --git a/arch/metag/kernel/irq.c b/arch/metag/kernel/irq.c
deleted file mode 100644
index 704cf17f8370..000000000000
--- a/arch/metag/kernel/irq.c
+++ /dev/null
@@ -1,293 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0
-/*
- * Linux/Meta general interrupt handling code
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/irqchip/metag-ext.h>
-#include <linux/irqchip/metag.h>
-#include <linux/irqdomain.h>
-#include <linux/ratelimit.h>
-
-#include <asm/core_reg.h>
-#include <asm/mach/arch.h>
-#include <linux/uaccess.h>
-
-#ifdef CONFIG_4KSTACKS
-union irq_ctx {
- struct thread_info tinfo;
- u32 stack[THREAD_SIZE/sizeof(u32)];
-};
-
-static union irq_ctx *hardirq_ctx[NR_CPUS] __read_mostly;
-static union irq_ctx *softirq_ctx[NR_CPUS] __read_mostly;
-#endif
-
-static struct irq_domain *root_domain;
-
-static unsigned int startup_meta_irq(struct irq_data *data)
-{
- tbi_startup_interrupt(data->hwirq);
- return 0;
-}
-
-static void shutdown_meta_irq(struct irq_data *data)
-{
- tbi_shutdown_interrupt(data->hwirq);
-}
-
-void do_IRQ(int irq, struct pt_regs *regs)
-{
- struct pt_regs *old_regs = set_irq_regs(regs);
-#ifdef CONFIG_4KSTACKS
- struct irq_desc *desc;
- union irq_ctx *curctx, *irqctx;
- u32 *isp;
-#endif
-
- irq_enter();
-
- irq = irq_linear_revmap(root_domain, irq);
-
-#ifdef CONFIG_DEBUG_STACKOVERFLOW
- /* Debugging check for stack overflow: is there less than 1KB free? */
- {
- unsigned long sp;
-
- sp = __core_reg_get(A0StP);
- sp &= THREAD_SIZE - 1;
-
- if (unlikely(sp > (THREAD_SIZE - 1024)))
- pr_err("Stack overflow in do_IRQ: %ld\n", sp);
- }
-#endif
-
-
-#ifdef CONFIG_4KSTACKS
- curctx = (union irq_ctx *) current_thread_info();
- irqctx = hardirq_ctx[smp_processor_id()];
-
- /*
- * this is where we switch to the IRQ stack. However, if we are
- * already using the IRQ stack (because we interrupted a hardirq
- * handler) we can't do that and just have to keep using the
- * current stack (which is the irq stack already after all)
- */
- if (curctx != irqctx) {
- /* build the stack frame on the IRQ stack */
- isp = (u32 *) ((char *)irqctx + sizeof(struct thread_info));
- irqctx->tinfo.task = curctx->tinfo.task;
-
- /*
- * Copy the softirq bits in preempt_count so that the
- * softirq checks work in the hardirq context.
- */
- irqctx->tinfo.preempt_count =
- (irqctx->tinfo.preempt_count & ~SOFTIRQ_MASK) |
- (curctx->tinfo.preempt_count & SOFTIRQ_MASK);
-
- desc = irq_to_desc(irq);
-
- asm volatile (
- "MOV D0.5,%0\n"
- "MOV D1Ar1,%1\n"
- "MOV D1RtP,%2\n"
- "SWAP A0StP,D0.5\n"
- "SWAP PC,D1RtP\n"
- "MOV A0StP,D0.5\n"
- :
- : "r" (isp), "r" (desc), "r" (desc->handle_irq)
- : "memory", "cc", "D1Ar1", "D0Ar2", "D1Ar3", "D0Ar4",
- "D1Ar5", "D0Ar6", "D0Re0", "D1Re0", "D0.4", "D1RtP",
- "D0.5"
- );
- } else
-#endif
- generic_handle_irq(irq);
-
- irq_exit();
-
- set_irq_regs(old_regs);
-}
-
-#ifdef CONFIG_4KSTACKS
-
-static char softirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss;
-
-static char hardirq_stack[NR_CPUS * THREAD_SIZE] __page_aligned_bss;
-
-/*
- * allocate per-cpu stacks for hardirq and for softirq processing
- */
-void irq_ctx_init(int cpu)
-{
- union irq_ctx *irqctx;
-
- if (hardirq_ctx[cpu])
- return;
-
- irqctx = (union irq_ctx *) &hardirq_stack[cpu * THREAD_SIZE];
- irqctx->tinfo.task = NULL;
- irqctx->tinfo.cpu = cpu;
- irqctx->tinfo.preempt_count = HARDIRQ_OFFSET;
- irqctx->tinfo.addr_limit = MAKE_MM_SEG(0);
-
- hardirq_ctx[cpu] = irqctx;
-
- irqctx = (union irq_ctx *) &softirq_stack[cpu * THREAD_SIZE];
- irqctx->tinfo.task = NULL;
- irqctx->tinfo.cpu = cpu;
- irqctx->tinfo.preempt_count = 0;
- irqctx->tinfo.addr_limit = MAKE_MM_SEG(0);
-
- softirq_ctx[cpu] = irqctx;
-
- pr_info("CPU %u irqstacks, hard=%p soft=%p\n",
- cpu, hardirq_ctx[cpu], softirq_ctx[cpu]);
-}
-
-void irq_ctx_exit(int cpu)
-{
- hardirq_ctx[smp_processor_id()] = NULL;
-}
-
-extern asmlinkage void __do_softirq(void);
-
-void do_softirq_own_stack(void)
-{
- struct thread_info *curctx;
- union irq_ctx *irqctx;
- u32 *isp;
-
- curctx = current_thread_info();
- irqctx = softirq_ctx[smp_processor_id()];
- irqctx->tinfo.task = curctx->task;
-
- /* build the stack frame on the softirq stack */
- isp = (u32 *) ((char *)irqctx + sizeof(struct thread_info));
-
- asm volatile (
- "MOV D0.5,%0\n"
- "SWAP A0StP,D0.5\n"
- "CALLR D1RtP,___do_softirq\n"
- "MOV A0StP,D0.5\n"
- :
- : "r" (isp)
- : "memory", "cc", "D1Ar1", "D0Ar2", "D1Ar3", "D0Ar4",
- "D1Ar5", "D0Ar6", "D0Re0", "D1Re0", "D0.4", "D1RtP",
- "D0.5"
- );
-}
-#endif
-
-static struct irq_chip meta_irq_type = {
- .name = "META-IRQ",
- .irq_startup = startup_meta_irq,
- .irq_shutdown = shutdown_meta_irq,
-};
-
-/**
- * tbisig_map() - Map a TBI signal number to a virtual IRQ number.
- * @hw: Number of the TBI signal. Must be in range.
- *
- * Returns: The virtual IRQ number of the TBI signal number IRQ specified by
- * @hw.
- */
-int tbisig_map(unsigned int hw)
-{
- return irq_create_mapping(root_domain, hw);
-}
-
-/**
- * metag_tbisig_map() - map a tbi signal to a Linux virtual IRQ number
- * @d: root irq domain
- * @irq: virtual irq number
- * @hw: hardware irq number (TBI signal number)
- *
- * This sets up a virtual irq for a specified TBI signal number.
- */
-static int metag_tbisig_map(struct irq_domain *d, unsigned int irq,
- irq_hw_number_t hw)
-{
-#ifdef CONFIG_SMP
- irq_set_chip_and_handler(irq, &meta_irq_type, handle_percpu_irq);
-#else
- irq_set_chip_and_handler(irq, &meta_irq_type, handle_simple_irq);
-#endif
- return 0;
-}
-
-static const struct irq_domain_ops metag_tbisig_domain_ops = {
- .map = metag_tbisig_map,
-};
-
-/*
- * void init_IRQ(void)
- *
- * Parameters: None
- *
- * Returns: Nothing
- *
- * This function should be called during kernel startup to initialize
- * the IRQ handling routines.
- */
-void __init init_IRQ(void)
-{
- root_domain = irq_domain_add_linear(NULL, 32,
- &metag_tbisig_domain_ops, NULL);
- if (unlikely(!root_domain))
- panic("init_IRQ: cannot add root IRQ domain");
-
- irq_ctx_init(smp_processor_id());
-
- init_internal_IRQ();
- init_external_IRQ();
-
- if (machine_desc->init_irq)
- machine_desc->init_irq();
-}
-
-int __init arch_probe_nr_irqs(void)
-{
- if (machine_desc->nr_irqs)
- nr_irqs = machine_desc->nr_irqs;
- return 0;
-}
-
-#ifdef CONFIG_HOTPLUG_CPU
-/*
- * The CPU has been marked offline. Migrate IRQs off this CPU. If
- * the affinity settings do not allow other CPUs, force them onto any
- * available CPU.
- */
-void migrate_irqs(void)
-{
- unsigned int i, cpu = smp_processor_id();
-
- for_each_active_irq(i) {
- struct irq_data *data = irq_get_irq_data(i);
- struct cpumask *mask;
- unsigned int newcpu;
-
- if (irqd_is_per_cpu(data))
- continue;
-
- mask = irq_data_get_affinity_mask(data);
- if (!cpumask_test_cpu(cpu, mask))
- continue;
-
- newcpu = cpumask_any_and(mask, cpu_online_mask);
-
- if (newcpu >= nr_cpu_ids) {
- pr_info_ratelimited("IRQ%u no longer affine to CPU%u\n",
- i, cpu);
-
- cpumask_setall(mask);
- }
- irq_set_affinity(i, mask);
- }
-}
-#endif /* CONFIG_HOTPLUG_CPU */