summaryrefslogtreecommitdiff
path: root/arch/hexagon/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/hexagon/kernel')
-rw-r--r--arch/hexagon/kernel/.gitignore1
-rw-r--r--arch/hexagon/kernel/Makefile5
-rw-r--r--arch/hexagon/kernel/dma.c59
-rw-r--r--arch/hexagon/kernel/hexagon_ksyms.c11
-rw-r--r--arch/hexagon/kernel/module.c2
-rw-r--r--arch/hexagon/kernel/process.c45
-rw-r--r--arch/hexagon/kernel/ptrace.c74
-rw-r--r--arch/hexagon/kernel/reset.c1
-rw-r--r--arch/hexagon/kernel/screen_info.c3
-rw-r--r--arch/hexagon/kernel/setup.c6
-rw-r--r--arch/hexagon/kernel/signal.c5
-rw-r--r--arch/hexagon/kernel/smp.c37
-rw-r--r--arch/hexagon/kernel/stacktrace.c4
-rw-r--r--arch/hexagon/kernel/time.c27
-rw-r--r--arch/hexagon/kernel/traps.c48
-rw-r--r--arch/hexagon/kernel/vdso.c5
-rw-r--r--arch/hexagon/kernel/vm_entry.S8
-rw-r--r--arch/hexagon/kernel/vm_events.c7
-rw-r--r--arch/hexagon/kernel/vmlinux.lds.S11
19 files changed, 129 insertions, 230 deletions
diff --git a/arch/hexagon/kernel/.gitignore b/arch/hexagon/kernel/.gitignore
new file mode 100644
index 000000000000..c5f676c3c224
--- /dev/null
+++ b/arch/hexagon/kernel/.gitignore
@@ -0,0 +1 @@
+vmlinux.lds
diff --git a/arch/hexagon/kernel/Makefile b/arch/hexagon/kernel/Makefile
index fae3dce32fde..3fdf937eb572 100644
--- a/arch/hexagon/kernel/Makefile
+++ b/arch/hexagon/kernel/Makefile
@@ -1,6 +1,7 @@
# SPDX-License-Identifier: GPL-2.0
-extra-y := head.o vmlinux.lds
+extra-y := vmlinux.lds
+obj-y += head.o
obj-$(CONFIG_SMP) += smp.o
obj-y += setup.o irq_cpu.o traps.o syscalltab.o signal.o time.o
@@ -16,5 +17,3 @@ obj-y += vm_vectors.o
obj-$(CONFIG_HAS_DMA) += dma.o
obj-$(CONFIG_STACKTRACE) += stacktrace.o
-
-obj-$(CONFIG_VGA_CONSOLE) += screen_info.o
diff --git a/arch/hexagon/kernel/dma.c b/arch/hexagon/kernel/dma.c
index 25f388d9cfcc..882680e81a30 100644
--- a/arch/hexagon/kernel/dma.c
+++ b/arch/hexagon/kernel/dma.c
@@ -5,56 +5,10 @@
* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
*/
-#include <linux/dma-noncoherent.h>
+#include <linux/dma-map-ops.h>
#include <linux/memblock.h>
-#include <linux/genalloc.h>
-#include <linux/module.h>
#include <asm/page.h>
-static struct gen_pool *coherent_pool;
-
-
-/* Allocates from a pool of uncached memory that was reserved at boot time */
-
-void *arch_dma_alloc(struct device *dev, size_t size, dma_addr_t *dma_addr,
- gfp_t flag, unsigned long attrs)
-{
- void *ret;
-
- /*
- * Our max_low_pfn should have been backed off by 16MB in
- * mm/init.c to create DMA coherent space. Use that as the VA
- * for the pool.
- */
-
- if (coherent_pool == NULL) {
- coherent_pool = gen_pool_create(PAGE_SHIFT, -1);
-
- if (coherent_pool == NULL)
- panic("Can't create %s() memory pool!", __func__);
- else
- gen_pool_add(coherent_pool,
- (unsigned long)pfn_to_virt(max_low_pfn),
- hexagon_coherent_pool_size, -1);
- }
-
- ret = (void *) gen_pool_alloc(coherent_pool, size);
-
- if (ret) {
- memset(ret, 0, size);
- *dma_addr = (dma_addr_t) virt_to_phys(ret);
- } else
- *dma_addr = ~0;
-
- return ret;
-}
-
-void arch_dma_free(struct device *dev, size_t size, void *vaddr,
- dma_addr_t dma_addr, unsigned long attrs)
-{
- gen_pool_free(coherent_pool, (unsigned long) vaddr, size);
-}
-
void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
enum dma_data_direction dir)
{
@@ -77,3 +31,14 @@ void arch_sync_dma_for_device(phys_addr_t paddr, size_t size,
BUG();
}
}
+
+/*
+ * Our max_low_pfn should have been backed off by 16MB in mm/init.c to create
+ * DMA coherent space. Use that for the pool.
+ */
+static int __init hexagon_dma_init(void)
+{
+ return dma_init_global_coherent(PFN_PHYS(max_low_pfn),
+ hexagon_coherent_pool_size);
+}
+core_initcall(hexagon_dma_init);
diff --git a/arch/hexagon/kernel/hexagon_ksyms.c b/arch/hexagon/kernel/hexagon_ksyms.c
index 6fb1aaab1c29..36a80e31d187 100644
--- a/arch/hexagon/kernel/hexagon_ksyms.c
+++ b/arch/hexagon/kernel/hexagon_ksyms.c
@@ -14,13 +14,10 @@
EXPORT_SYMBOL(__clear_user_hexagon);
EXPORT_SYMBOL(raw_copy_from_user);
EXPORT_SYMBOL(raw_copy_to_user);
-EXPORT_SYMBOL(iounmap);
-EXPORT_SYMBOL(__strnlen_user);
EXPORT_SYMBOL(__vmgetie);
EXPORT_SYMBOL(__vmsetie);
EXPORT_SYMBOL(__vmyield);
EXPORT_SYMBOL(empty_zero_page);
-EXPORT_SYMBOL(ioremap);
EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memset);
@@ -35,8 +32,8 @@ EXPORT_SYMBOL(_dflt_cache_att);
DECLARE_EXPORT(__hexagon_memcpy_likely_aligned_min32bytes_mult8bytes);
/* Additional functions */
-DECLARE_EXPORT(__divsi3);
-DECLARE_EXPORT(__modsi3);
-DECLARE_EXPORT(__udivsi3);
-DECLARE_EXPORT(__umodsi3);
+DECLARE_EXPORT(__hexagon_divsi3);
+DECLARE_EXPORT(__hexagon_modsi3);
+DECLARE_EXPORT(__hexagon_udivsi3);
+DECLARE_EXPORT(__hexagon_umodsi3);
DECLARE_EXPORT(csum_tcpudp_magic);
diff --git a/arch/hexagon/kernel/module.c b/arch/hexagon/kernel/module.c
index cf99fb79a124..cb3bf19b0640 100644
--- a/arch/hexagon/kernel/module.c
+++ b/arch/hexagon/kernel/module.c
@@ -120,7 +120,7 @@ int apply_relocate_add(Elf_Shdr *sechdrs, const char *strtab,
}
case R_HEXAGON_HI16:
value = (value>>16) & 0xffff;
- /* fallthrough */
+ fallthrough;
case R_HEXAGON_LO16:
*location &= ~0x00c03fff;
*location |= value & 0x3fff;
diff --git a/arch/hexagon/kernel/process.c b/arch/hexagon/kernel/process.c
index ac07f5f4b76b..2a77bfd75694 100644
--- a/arch/hexagon/kernel/process.c
+++ b/arch/hexagon/kernel/process.c
@@ -5,6 +5,7 @@
* Copyright (c) 2010-2012, The Linux Foundation. All rights reserved.
*/
+#include <linux/cpu.h>
#include <linux/sched.h>
#include <linux/sched/debug.h>
#include <linux/sched/task.h>
@@ -14,7 +15,7 @@
#include <linux/tick.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
-#include <linux/tracehook.h>
+#include <linux/resume_user_mode.h>
/*
* Program thread launch. Often defined as a macro in processor.h,
@@ -44,15 +45,16 @@ void arch_cpu_idle(void)
{
__vmwait();
/* interrupts wake us up, but irqs are still disabled */
- local_irq_enable();
}
/*
* Copy architecture-specific thread state
*/
-int copy_thread(unsigned long clone_flags, unsigned long usp,
- unsigned long arg, struct task_struct *p)
+int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
{
+ unsigned long clone_flags = args->flags;
+ unsigned long usp = args->stack;
+ unsigned long tls = args->tls;
struct thread_info *ti = task_thread_info(p);
struct hexagon_switch_stack *ss;
struct pt_regs *childregs;
@@ -73,11 +75,11 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
sizeof(*ss));
ss->lr = (unsigned long)ret_from_fork;
p->thread.switch_sp = ss;
- if (unlikely(p->flags & PF_KTHREAD)) {
+ if (unlikely(args->fn)) {
memset(childregs, 0, sizeof(struct pt_regs));
/* r24 <- fn, r25 <- arg */
- ss->r24 = usp;
- ss->r25 = arg;
+ ss->r24 = (unsigned long)args->fn;
+ ss->r25 = (unsigned long)args->fn_arg;
pt_set_kmode(childregs);
return 0;
}
@@ -100,25 +102,17 @@ int copy_thread(unsigned long clone_flags, unsigned long usp,
* ugp is used to provide TLS support.
*/
if (clone_flags & CLONE_SETTLS)
- childregs->ugp = childregs->r04;
+ childregs->ugp = tls;
/*
* Parent sees new pid -- not necessary, not even possible at
* this point in the fork process
- * Might also want to set things like ti->addr_limit
*/
return 0;
}
/*
- * Release any architecture-specific resources locked by thread
- */
-void release_thread(struct task_struct *dead_task)
-{
-}
-
-/*
* Some archs flush debug and FPU info here
*/
void flush_thread(void)
@@ -130,13 +124,11 @@ void flush_thread(void)
* is an identification of the point at which the scheduler
* was invoked by a blocked thread.
*/
-unsigned long get_wchan(struct task_struct *p)
+unsigned long __get_wchan(struct task_struct *p)
{
unsigned long fp, pc;
unsigned long stack_page;
int count = 0;
- if (!p || p == current || p->state == TASK_RUNNING)
- return 0;
stack_page = (unsigned long)task_stack_page(p);
fp = ((struct hexagon_switch_stack *)p->thread.switch_sp)->fp;
@@ -154,15 +146,6 @@ unsigned long get_wchan(struct task_struct *p)
}
/*
- * Required placeholder.
- */
-int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
-{
- return 0;
-}
-
-
-/*
* Called on the exit path of event entry; see vm_entry.S
*
* Interrupts will already be disabled.
@@ -170,6 +153,7 @@ int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
* Returns 0 if there's no need to re-check for more work.
*/
+int do_work_pending(struct pt_regs *regs, u32 thread_info_flags);
int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
{
if (!(thread_info_flags & _TIF_WORK_MASK)) {
@@ -183,14 +167,13 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
return 1;
}
- if (thread_info_flags & _TIF_SIGPENDING) {
+ if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
do_signal(regs);
return 1;
}
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
- clear_thread_flag(TIF_NOTIFY_RESUME);
- tracehook_notify_resume(regs);
+ resume_user_mode_work(regs);
return 1;
}
diff --git a/arch/hexagon/kernel/ptrace.c b/arch/hexagon/kernel/ptrace.c
index dcbf7ea960cc..905b06790ab7 100644
--- a/arch/hexagon/kernel/ptrace.c
+++ b/arch/hexagon/kernel/ptrace.c
@@ -35,58 +35,38 @@ void user_disable_single_step(struct task_struct *child)
static int genregs_get(struct task_struct *target,
const struct user_regset *regset,
- unsigned int pos, unsigned int count,
- void *kbuf, void __user *ubuf)
+ struct membuf to)
{
- int ret;
- unsigned int dummy;
struct pt_regs *regs = task_pt_regs(target);
-
- if (!regs)
- return -EIO;
-
/* The general idea here is that the copyout must happen in
* exactly the same order in which the userspace expects these
* regs. Now, the sequence in userspace does not match the
* sequence in the kernel, so everything past the 32 gprs
* happens one at a time.
*/
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
- &regs->r00, 0, 32*sizeof(unsigned long));
-
-#define ONEXT(KPT_REG, USR_REG) \
- if (!ret) \
- ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, \
- KPT_REG, offsetof(struct user_regs_struct, USR_REG), \
- offsetof(struct user_regs_struct, USR_REG) + \
- sizeof(unsigned long));
-
+ membuf_write(&to, &regs->r00, 32*sizeof(unsigned long));
/* Must be exactly same sequence as struct user_regs_struct */
- ONEXT(&regs->sa0, sa0);
- ONEXT(&regs->lc0, lc0);
- ONEXT(&regs->sa1, sa1);
- ONEXT(&regs->lc1, lc1);
- ONEXT(&regs->m0, m0);
- ONEXT(&regs->m1, m1);
- ONEXT(&regs->usr, usr);
- ONEXT(&regs->preds, p3_0);
- ONEXT(&regs->gp, gp);
- ONEXT(&regs->ugp, ugp);
- ONEXT(&pt_elr(regs), pc);
- dummy = pt_cause(regs);
- ONEXT(&dummy, cause);
- ONEXT(&pt_badva(regs), badva);
+ membuf_store(&to, regs->sa0);
+ membuf_store(&to, regs->lc0);
+ membuf_store(&to, regs->sa1);
+ membuf_store(&to, regs->lc1);
+ membuf_store(&to, regs->m0);
+ membuf_store(&to, regs->m1);
+ membuf_store(&to, regs->usr);
+ membuf_store(&to, regs->preds);
+ membuf_store(&to, regs->gp);
+ membuf_store(&to, regs->ugp);
+ membuf_store(&to, pt_elr(regs)); // pc
+ membuf_store(&to, (unsigned long)pt_cause(regs)); // cause
+ membuf_store(&to, pt_badva(regs)); // badva
#if CONFIG_HEXAGON_ARCH_VERSION >=4
- ONEXT(&regs->cs0, cs0);
- ONEXT(&regs->cs1, cs1);
+ membuf_store(&to, regs->cs0);
+ membuf_store(&to, regs->cs1);
+ return membuf_zero(&to, sizeof(unsigned long));
+#else
+ return membuf_zero(&to, 3 * sizeof(unsigned long));
#endif
-
- /* Pad the rest with zeros, if needed */
- if (!ret)
- ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
- offsetof(struct user_regs_struct, pad1), -1);
- return ret;
}
static int genregs_set(struct task_struct *target,
@@ -94,7 +74,7 @@ static int genregs_set(struct task_struct *target,
unsigned int pos, unsigned int count,
const void *kbuf, const void __user *ubuf)
{
- int ret;
+ int ret, ignore_offset;
unsigned long bucket;
struct pt_regs *regs = task_pt_regs(target);
@@ -131,14 +111,16 @@ static int genregs_set(struct task_struct *target,
#if CONFIG_HEXAGON_ARCH_VERSION >=4
INEXT(&regs->cs0, cs0);
INEXT(&regs->cs1, cs1);
+ ignore_offset = offsetof(struct user_regs_struct, pad1);
+#else
+ ignore_offset = offsetof(struct user_regs_struct, cs0);
#endif
/* Ignore the rest, if needed */
if (!ret)
- ret = user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
- offsetof(struct user_regs_struct, pad1), -1);
-
- if (ret)
+ user_regset_copyin_ignore(&pos, &count, &kbuf, &ubuf,
+ ignore_offset, -1);
+ else
return ret;
/*
@@ -159,7 +141,7 @@ static const struct user_regset hexagon_regsets[] = {
.n = ELF_NGREG,
.size = sizeof(unsigned long),
.align = sizeof(unsigned long),
- .get = genregs_get,
+ .regset_get = genregs_get,
.set = genregs_set,
},
};
diff --git a/arch/hexagon/kernel/reset.c b/arch/hexagon/kernel/reset.c
index da36114d928f..efd70a8d2526 100644
--- a/arch/hexagon/kernel/reset.c
+++ b/arch/hexagon/kernel/reset.c
@@ -3,6 +3,7 @@
* Copyright (c) 2010-2011, The Linux Foundation. All rights reserved.
*/
+#include <linux/reboot.h>
#include <linux/smp.h>
#include <asm/hexagon_vm.h>
diff --git a/arch/hexagon/kernel/screen_info.c b/arch/hexagon/kernel/screen_info.c
deleted file mode 100644
index 1e1ceb18bafe..000000000000
--- a/arch/hexagon/kernel/screen_info.c
+++ /dev/null
@@ -1,3 +0,0 @@
-#include <linux/screen_info.h>
-
-struct screen_info screen_info;
diff --git a/arch/hexagon/kernel/setup.c b/arch/hexagon/kernel/setup.c
index 1880d9beaf2b..621674e86232 100644
--- a/arch/hexagon/kernel/setup.c
+++ b/arch/hexagon/kernel/setup.c
@@ -66,9 +66,9 @@ void __init setup_arch(char **cmdline_p)
on_simulator = 0;
if (p[0] != '\0')
- strlcpy(boot_command_line, p, COMMAND_LINE_SIZE);
+ strscpy(boot_command_line, p, COMMAND_LINE_SIZE);
else
- strlcpy(boot_command_line, default_command_line,
+ strscpy(boot_command_line, default_command_line,
COMMAND_LINE_SIZE);
/*
@@ -76,7 +76,7 @@ void __init setup_arch(char **cmdline_p)
* are both picked up by the init code. If no reason to
* make them different, pass the same pointer back.
*/
- strlcpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
+ strscpy(cmd_line, boot_command_line, COMMAND_LINE_SIZE);
*cmdline_p = cmd_line;
parse_early_param();
diff --git a/arch/hexagon/kernel/signal.c b/arch/hexagon/kernel/signal.c
index d48864c48e5a..d301f4621553 100644
--- a/arch/hexagon/kernel/signal.c
+++ b/arch/hexagon/kernel/signal.c
@@ -7,7 +7,6 @@
#include <linux/linkage.h>
#include <linux/syscalls.h>
-#include <linux/tracehook.h>
#include <linux/sched/task_stack.h>
#include <asm/registers.h>
@@ -155,7 +154,7 @@ static void handle_signal(struct ksignal *ksig, struct pt_regs *regs)
regs->r00 = -EINTR;
break;
}
- /* Fall through */
+ fallthrough;
case -ERESTARTNOINTR:
regs->r06 = regs->syscall_nr;
pt_set_elr(regs, pt_elr(regs) - 4);
@@ -221,7 +220,7 @@ no_restart:
* Architecture-specific wrappers for signal-related system calls
*/
-asmlinkage int sys_rt_sigreturn(void)
+SYSCALL_DEFINE0(rt_sigreturn)
{
struct pt_regs *regs = current_pt_regs();
struct rt_sigframe __user *frame;
diff --git a/arch/hexagon/kernel/smp.c b/arch/hexagon/kernel/smp.c
index 0bbbe652a513..65e1fdf9fdb2 100644
--- a/arch/hexagon/kernel/smp.c
+++ b/arch/hexagon/kernel/smp.c
@@ -79,7 +79,7 @@ void smp_vm_unmask_irq(void *info)
* Specifically, first arg is irq, second is the irq_desc.
*/
-irqreturn_t handle_ipi(int irq, void *desc)
+static irqreturn_t handle_ipi(int irq, void *desc)
{
int cpu = smp_processor_id();
struct ipi_data *ipi = &per_cpu(ipi_data, cpu);
@@ -114,26 +114,16 @@ void send_ipi(const struct cpumask *cpumask, enum ipi_message_type msg)
local_irq_restore(flags);
}
-static struct irqaction ipi_intdesc = {
- .handler = handle_ipi,
- .flags = IRQF_TRIGGER_RISING,
- .name = "ipi_handler"
-};
-
-void __init smp_prepare_boot_cpu(void)
-{
-}
-
/*
* interrupts should already be disabled from the VM
* SP should already be correct; need to set THREADINFO_REG
* to point to current thread info
*/
-void start_secondary(void)
+static void start_secondary(void)
{
- unsigned int cpu;
unsigned long thread_ptr;
+ unsigned int cpu, irq;
/* Calculate thread_info pointer from stack pointer */
__asm__ __volatile__(
@@ -155,7 +145,10 @@ void start_secondary(void)
cpu = smp_processor_id();
- setup_irq(BASE_IPI_IRQ + cpu, &ipi_intdesc);
+ irq = BASE_IPI_IRQ + cpu;
+ if (request_irq(irq, handle_ipi, IRQF_TRIGGER_RISING, "ipi_handler",
+ NULL))
+ pr_err("Failed to request irq %u (ipi_handler)\n", irq);
/* Register the clock_event dummy */
setup_percpu_clockdev();
@@ -201,7 +194,7 @@ void __init smp_cpus_done(unsigned int max_cpus)
void __init smp_prepare_cpus(unsigned int max_cpus)
{
- int i;
+ int i, irq = BASE_IPI_IRQ;
/*
* should eventually have some sort of machine
@@ -213,11 +206,14 @@ void __init smp_prepare_cpus(unsigned int max_cpus)
set_cpu_present(i, true);
/* Also need to register the interrupts for IPI */
- if (max_cpus > 1)
- setup_irq(BASE_IPI_IRQ, &ipi_intdesc);
+ if (max_cpus > 1) {
+ if (request_irq(irq, handle_ipi, IRQF_TRIGGER_RISING,
+ "ipi_handler", NULL))
+ pr_err("Failed to request irq %d (ipi_handler)\n", irq);
+ }
}
-void smp_send_reschedule(int cpu)
+void arch_smp_send_reschedule(int cpu)
{
send_ipi(cpumask_of(cpu), IPI_RESCHEDULE);
}
@@ -240,11 +236,6 @@ void arch_send_call_function_ipi_mask(const struct cpumask *mask)
send_ipi(mask, IPI_CALL_FUNC);
}
-int setup_profiling_timer(unsigned int multiplier)
-{
- return -EINVAL;
-}
-
void smp_start_cpus(void)
{
int i;
diff --git a/arch/hexagon/kernel/stacktrace.c b/arch/hexagon/kernel/stacktrace.c
index 35f29423fda8..5ed02f699479 100644
--- a/arch/hexagon/kernel/stacktrace.c
+++ b/arch/hexagon/kernel/stacktrace.c
@@ -11,8 +11,6 @@
#include <linux/thread_info.h>
#include <linux/module.h>
-register unsigned long current_frame_pointer asm("r30");
-
struct stackframe {
unsigned long fp;
unsigned long rets;
@@ -30,7 +28,7 @@ void save_stack_trace(struct stack_trace *trace)
low = (unsigned long)task_stack_page(current);
high = low + THREAD_SIZE;
- fp = current_frame_pointer;
+ fp = (unsigned long)__builtin_frame_address(0);
while (fp >= low && fp <= (high - sizeof(*frame))) {
frame = (struct stackframe *)fp;
diff --git a/arch/hexagon/kernel/time.c b/arch/hexagon/kernel/time.c
index f99e9257bed4..f0f207e2a694 100644
--- a/arch/hexagon/kernel/time.c
+++ b/arch/hexagon/kernel/time.c
@@ -17,8 +17,11 @@
#include <linux/of_irq.h>
#include <linux/module.h>
-#include <asm/timer-regs.h>
+#include <asm/delay.h>
#include <asm/hexagon_vm.h>
+#include <asm/time.h>
+
+#define TIMER_ENABLE BIT(0)
/*
* For the clocksource we need:
@@ -33,6 +36,13 @@ cycles_t pcycle_freq_mhz;
cycles_t thread_freq_mhz;
cycles_t sleep_clk_freq;
+/*
+ * 8x50 HDD Specs 5-8. Simulator co-sim not fixed until
+ * release 1.1, and then it's "adjustable" and probably not defaulted.
+ */
+#define RTOS_TIMER_INT 3
+#define RTOS_TIMER_REGS_ADDR 0xAB000000UL
+
static struct resource rtos_timer_resources[] = {
{
.start = RTOS_TIMER_REGS_ADDR,
@@ -80,7 +90,7 @@ static int set_next_event(unsigned long delta, struct clock_event_device *evt)
iowrite32(0, &rtos_timer->clear);
iowrite32(delta, &rtos_timer->match);
- iowrite32(1 << TIMER_ENABLE, &rtos_timer->enable);
+ iowrite32(TIMER_ENABLE, &rtos_timer->enable);
return 0;
}
@@ -143,13 +153,6 @@ static irqreturn_t timer_interrupt(int irq, void *devid)
return IRQ_HANDLED;
}
-/* This should also be pulled from devtree */
-static struct irqaction rtos_timer_intdesc = {
- .handler = timer_interrupt,
- .flags = IRQF_TIMER | IRQF_TRIGGER_RISING,
- .name = "rtos_timer"
-};
-
/*
* time_init_deferred - called by start_kernel to set up timer/clock source
*
@@ -159,10 +162,11 @@ static struct irqaction rtos_timer_intdesc = {
* This runs just before the delay loop is calibrated, and
* is used for delay calibration.
*/
-void __init time_init_deferred(void)
+static void __init time_init_deferred(void)
{
struct resource *resource = NULL;
struct clock_event_device *ce_dev = &hexagon_clockevent_dev;
+ unsigned long flag = IRQF_TIMER | IRQF_TRIGGER_RISING;
ce_dev->cpumask = cpu_all_mask;
@@ -195,7 +199,8 @@ void __init time_init_deferred(void)
#endif
clockevents_register_device(ce_dev);
- setup_irq(ce_dev->irq, &rtos_timer_intdesc);
+ if (request_irq(ce_dev->irq, timer_interrupt, flag, "rtos_timer", NULL))
+ pr_err("Failed to register rtos_timer interrupt\n");
}
void __init time_init(void)
diff --git a/arch/hexagon/kernel/traps.c b/arch/hexagon/kernel/traps.c
index 69c623b14ddd..75e062722d28 100644
--- a/arch/hexagon/kernel/traps.c
+++ b/arch/hexagon/kernel/traps.c
@@ -14,7 +14,7 @@
#include <linux/kdebug.h>
#include <linux/syscalls.h>
#include <linux/signal.h>
-#include <linux/tracehook.h>
+#include <linux/ptrace.h>
#include <asm/traps.h>
#include <asm/vm_fault.h>
#include <asm/syscall.h>
@@ -28,10 +28,6 @@
#define TRAP_SYSCALL 1
#define TRAP_DEBUG 0xdb
-void __init trap_init(void)
-{
-}
-
#ifdef CONFIG_GENERIC_BUG
/* Maybe should resemble arch/sh/kernel/traps.c ?? */
int is_valid_bugaddr(unsigned long addr)
@@ -79,7 +75,7 @@ static const char *ex_name(int ex)
}
static void do_show_stack(struct task_struct *task, unsigned long *fp,
- unsigned long ip)
+ unsigned long ip, const char *loglvl)
{
int kstack_depth_to_print = 24;
unsigned long offset, size;
@@ -93,9 +89,8 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp,
if (task == NULL)
task = current;
- printk(KERN_INFO "CPU#%d, %s/%d, Call Trace:\n",
- raw_smp_processor_id(), task->comm,
- task_pid_nr(task));
+ printk("%sCPU#%d, %s/%d, Call Trace:\n", loglvl, raw_smp_processor_id(),
+ task->comm, task_pid_nr(task));
if (fp == NULL) {
if (task == current) {
@@ -108,7 +103,7 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp,
}
if ((((unsigned long) fp) & 0x3) || ((unsigned long) fp < 0x1000)) {
- printk(KERN_INFO "-- Corrupt frame pointer %p\n", fp);
+ printk("%s-- Corrupt frame pointer %p\n", loglvl, fp);
return;
}
@@ -125,8 +120,7 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp,
name = kallsyms_lookup(ip, &size, &offset, &modname, tmpstr);
- printk(KERN_INFO "[%p] 0x%lx: %s + 0x%lx", fp, ip, name,
- offset);
+ printk("%s[%p] 0x%lx: %s + 0x%lx", loglvl, fp, ip, name, offset);
if (((unsigned long) fp < low) || (high < (unsigned long) fp))
printk(KERN_CONT " (FP out of bounds!)");
if (modname)
@@ -136,8 +130,7 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp,
newfp = (unsigned long *) *fp;
if (((unsigned long) newfp) & 0x3) {
- printk(KERN_INFO "-- Corrupt frame pointer %p\n",
- newfp);
+ printk("%s-- Corrupt frame pointer %p\n", loglvl, newfp);
break;
}
@@ -147,7 +140,7 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp,
+ 8);
if (regs->syscall_nr != -1) {
- printk(KERN_INFO "-- trap0 -- syscall_nr: %ld",
+ printk("%s-- trap0 -- syscall_nr: %ld", loglvl,
regs->syscall_nr);
printk(KERN_CONT " psp: %lx elr: %lx\n",
pt_psp(regs), pt_elr(regs));
@@ -155,7 +148,7 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp,
} else {
/* really want to see more ... */
kstack_depth_to_print += 6;
- printk(KERN_INFO "-- %s (0x%lx) badva: %lx\n",
+ printk("%s-- %s (0x%lx) badva: %lx\n", loglvl,
ex_name(pt_cause(regs)), pt_cause(regs),
pt_badva(regs));
}
@@ -178,10 +171,10 @@ static void do_show_stack(struct task_struct *task, unsigned long *fp,
}
}
-void show_stack(struct task_struct *task, unsigned long *fp)
+void show_stack(struct task_struct *task, unsigned long *fp, const char *loglvl)
{
/* Saved link reg is one word above FP */
- do_show_stack(task, fp, 0);
+ do_show_stack(task, fp, 0, loglvl);
}
int die(const char *str, struct pt_regs *regs, long err)
@@ -207,7 +200,7 @@ int die(const char *str, struct pt_regs *regs, long err)
print_modules();
show_regs(regs);
- do_show_stack(current, &regs->r30, pt_elr(regs));
+ do_show_stack(current, &regs->r30, pt_elr(regs), KERN_EMERG);
bust_spinlocks(0);
add_taint(TAINT_DIE, LOCKDEP_NOW_UNRELIABLE);
@@ -221,7 +214,7 @@ int die(const char *str, struct pt_regs *regs, long err)
panic("Fatal exception");
oops_exit();
- do_exit(err);
+ make_task_dead(err);
return 0;
}
@@ -288,6 +281,7 @@ static void cache_error(struct pt_regs *regs)
/*
* General exception handler
*/
+void do_genex(struct pt_regs *regs);
void do_genex(struct pt_regs *regs)
{
/*
@@ -338,13 +332,7 @@ void do_genex(struct pt_regs *regs)
}
}
-/* Indirect system call dispatch */
-long sys_syscall(void)
-{
- printk(KERN_ERR "sys_syscall invoked!\n");
- return -ENOSYS;
-}
-
+void do_trap0(struct pt_regs *regs);
void do_trap0(struct pt_regs *regs)
{
syscall_fn syscall;
@@ -355,7 +343,7 @@ void do_trap0(struct pt_regs *regs)
/* allow strace to catch syscall args */
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE) &&
- tracehook_report_syscall_entry(regs)))
+ ptrace_report_syscall_entry(regs)))
return; /* return -ENOSYS somewhere? */
/* Interrupts should be re-enabled for syscall processing */
@@ -393,7 +381,7 @@ void do_trap0(struct pt_regs *regs)
/* allow strace to get the syscall return state */
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE)))
- tracehook_report_syscall_exit(regs, 0);
+ ptrace_report_syscall_exit(regs, 0);
break;
case TRAP_DEBUG:
@@ -422,6 +410,7 @@ void do_trap0(struct pt_regs *regs)
/*
* Machine check exception handler
*/
+void do_machcheck(struct pt_regs *regs);
void do_machcheck(struct pt_regs *regs)
{
/* Halt and catch fire */
@@ -432,6 +421,7 @@ void do_machcheck(struct pt_regs *regs)
* Treat this like the old 0xdb trap.
*/
+void do_debug_exception(struct pt_regs *regs);
void do_debug_exception(struct pt_regs *regs)
{
regs->hvmer.vmest &= ~HVM_VMEST_CAUSE_MSK;
diff --git a/arch/hexagon/kernel/vdso.c b/arch/hexagon/kernel/vdso.c
index 25a1d9cfd4cc..2e4872d62124 100644
--- a/arch/hexagon/kernel/vdso.c
+++ b/arch/hexagon/kernel/vdso.c
@@ -10,6 +10,7 @@
#include <linux/vmalloc.h>
#include <linux/binfmts.h>
+#include <asm/elf.h>
#include <asm/vdso.h>
static struct page *vdso_page;
@@ -52,7 +53,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
unsigned long vdso_base;
struct mm_struct *mm = current->mm;
- if (down_write_killable(&mm->mmap_sem))
+ if (mmap_write_lock_killable(mm))
return -EINTR;
/* Try to get it loaded right near ld.so/glibc. */
@@ -76,7 +77,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
mm->context.vdso = (void *)vdso_base;
up_fail:
- up_write(&mm->mmap_sem);
+ mmap_write_unlock(mm);
return ret;
}
diff --git a/arch/hexagon/kernel/vm_entry.S b/arch/hexagon/kernel/vm_entry.S
index 12242c27e2df..554371d92bed 100644
--- a/arch/hexagon/kernel/vm_entry.S
+++ b/arch/hexagon/kernel/vm_entry.S
@@ -265,12 +265,12 @@ event_dispatch:
* should be in the designated register (usually R19)
*
* If we were in kernel mode, we don't need to check scheduler
- * or signals if CONFIG_PREEMPT is not set. If set, then it has
+ * or signals if CONFIG_PREEMPTION is not set. If set, then it has
* to jump to a need_resched kind of block.
- * BTW, CONFIG_PREEMPT is not supported yet.
+ * BTW, CONFIG_PREEMPTION is not supported yet.
*/
-#ifdef CONFIG_PREEMPT
+#ifdef CONFIG_PREEMPTION
R0 = #VM_INT_DISABLE
trap1(#HVM_TRAP1_VMSETIE)
#endif
@@ -369,7 +369,7 @@ ret_from_fork:
R26.L = #LO(do_work_pending);
R0 = #VM_INT_DISABLE;
}
- if P0 jump check_work_pending
+ if (P0) jump check_work_pending
{
R0 = R25;
callr R24
diff --git a/arch/hexagon/kernel/vm_events.c b/arch/hexagon/kernel/vm_events.c
index 59ef72e4a4e5..2b881a89b206 100644
--- a/arch/hexagon/kernel/vm_events.c
+++ b/arch/hexagon/kernel/vm_events.c
@@ -73,13 +73,6 @@ void show_regs(struct pt_regs *regs)
pt_psp(regs), pt_badva(regs), ints_enabled(regs));
}
-void dummy_handler(struct pt_regs *regs)
-{
- unsigned int elr = pt_elr(regs);
- printk(KERN_ERR "Unimplemented handler; ELR=0x%08x\n", elr);
-}
-
-
void arch_do_IRQ(struct pt_regs *regs)
{
int irq = pt_cause(regs);
diff --git a/arch/hexagon/kernel/vmlinux.lds.S b/arch/hexagon/kernel/vmlinux.lds.S
index 0ca2471ddb9f..1140051a0c45 100644
--- a/arch/hexagon/kernel/vmlinux.lds.S
+++ b/arch/hexagon/kernel/vmlinux.lds.S
@@ -38,8 +38,9 @@ SECTIONS
.text : AT(ADDR(.text)) {
_text = .;
TEXT_TEXT
+ IRQENTRY_TEXT
+ SOFTIRQENTRY_TEXT
SCHED_TEXT
- CPUIDLE_TEXT
LOCK_TEXT
KPROBES_TEXT
*(.fixup)
@@ -59,13 +60,9 @@ SECTIONS
_end = .;
- /DISCARD/ : {
- EXIT_TEXT
- EXIT_DATA
- EXIT_CALL
- }
-
STABS_DEBUG
DWARF_DEBUG
+ ELF_DETAILS
+ DISCARDS
}