Commit bdcf11de authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'riscv-for-linus-5.9-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux

Pull RISC-V fixes from Palmer Dabbelt:

 - A fix for a lockdep issue to avoid an asserting triggering during
   early boot. There shouldn't be any incorrect behavior as the system
   isn't concurrent at the time.

 - The addition of a missing fence when installing early fixmap
   mappings.

 - A corretion to the K210 device tree's interrupt map.

 - A fix for M-mode timer handling on the K210.

* tag 'riscv-for-linus-5.9-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/riscv/linux:
  RISC-V: Resurrect the MMIO timer implementation for M-mode systems
  riscv: Fix Kendryte K210 device tree
  riscv: Add sfence.vma after early page table changes
  RISC-V: Take text_mutex in ftrace_init_nop()
parents d0373c14 d5be89a8
......@@ -32,6 +32,7 @@ config RISCV
select ARCH_WANT_FRAME_POINTERS
select ARCH_WANT_HUGE_PMD_SHARE if 64BIT
select CLONE_BACKWARDS
select CLINT_TIMER if !MMU
select COMMON_CLK
select EDAC_SUPPORT
select GENERIC_ARCH_TOPOLOGY if SMP
......
......@@ -95,10 +95,12 @@ sysctl: sysctl@50440000 {
#clock-cells = <1>;
};
clint0: interrupt-controller@2000000 {
clint0: clint@2000000 {
#interrupt-cells = <1>;
compatible = "riscv,clint0";
reg = <0x2000000 0xC000>;
interrupts-extended = <&cpu0_intc 3>, <&cpu1_intc 3>;
interrupts-extended = <&cpu0_intc 3 &cpu0_intc 7
&cpu1_intc 3 &cpu1_intc 7>;
clocks = <&sysctl K210_CLK_ACLK>;
};
......
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2020 Google, Inc
*/
#ifndef _ASM_RISCV_CLINT_H
#define _ASM_RISCV_CLINT_H
#include <linux/types.h>
#include <asm/mmio.h>
#ifdef CONFIG_RISCV_M_MODE
/*
* This lives in the CLINT driver, but is accessed directly by timex.h to avoid
* any overhead when accessing the MMIO timer.
*
* The ISA defines mtime as a 64-bit memory-mapped register that increments at
* a constant frequency, but it doesn't define some other constraints we depend
* on (most notably ordering constraints, but also some simpler stuff like the
* memory layout). Thus, this is called "clint_time_val" instead of something
* like "riscv_mtime", to signify that these non-ISA assumptions must hold.
*/
extern u64 __iomem *clint_time_val;
#endif
#endif
......@@ -66,6 +66,13 @@ do { \
* Let auipc+jalr be the basic *mcount unit*, so we make it 8 bytes here.
*/
#define MCOUNT_INSN_SIZE 8
#ifndef __ASSEMBLY__
struct dyn_ftrace;
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec);
#define ftrace_init_nop ftrace_init_nop
#endif
#endif
#endif /* _ASM_RISCV_FTRACE_H */
......@@ -10,6 +10,31 @@
typedef unsigned long cycles_t;
#ifdef CONFIG_RISCV_M_MODE
#include <asm/clint.h>
#ifdef CONFIG_64BIT
static inline cycles_t get_cycles(void)
{
return readq_relaxed(clint_time_val);
}
#else /* !CONFIG_64BIT */
static inline u32 get_cycles(void)
{
return readl_relaxed(((u32 *)clint_time_val));
}
#define get_cycles get_cycles
static inline u32 get_cycles_hi(void)
{
return readl_relaxed(((u32 *)clint_time_val) + 1);
}
#define get_cycles_hi get_cycles_hi
#endif /* CONFIG_64BIT */
#else /* CONFIG_RISCV_M_MODE */
static inline cycles_t get_cycles(void)
{
return csr_read(CSR_TIME);
......@@ -41,6 +66,8 @@ static inline u64 get_cycles64(void)
}
#endif /* CONFIG_64BIT */
#endif /* !CONFIG_RISCV_M_MODE */
#define ARCH_HAS_READ_CURRENT_TIMER
static inline int read_current_timer(unsigned long *timer_val)
{
......
......@@ -97,6 +97,25 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec,
return __ftrace_modify_call(rec->ip, addr, false);
}
/*
* This is called early on, and isn't wrapped by
* ftrace_arch_code_modify_{prepare,post_process}() and therefor doesn't hold
* text_mutex, which triggers a lockdep failure. SMP isn't running so we could
* just directly poke the text, but it's simpler to just take the lock
* ourselves.
*/
int ftrace_init_nop(struct module *mod, struct dyn_ftrace *rec)
{
int out;
ftrace_arch_code_modify_prepare();
out = ftrace_make_nop(mod, rec, MCOUNT_ADDR);
ftrace_arch_code_modify_post_process();
return out;
}
int ftrace_update_ftrace_func(ftrace_func_t func)
{
int ret = __ftrace_modify_call((unsigned long)&ftrace_call,
......
......@@ -226,12 +226,11 @@ void __set_fixmap(enum fixed_addresses idx, phys_addr_t phys, pgprot_t prot)
ptep = &fixmap_pte[pte_index(addr)];
if (pgprot_val(prot)) {
if (pgprot_val(prot))
set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot));
} else {
else
pte_clear(&init_mm, addr, ptep);
local_flush_tlb_page(addr);
}
}
static pte_t *__init get_pte_virt(phys_addr_t pa)
......
......@@ -19,6 +19,11 @@
#include <linux/interrupt.h>
#include <linux/of_irq.h>
#include <linux/smp.h>
#include <linux/timex.h>
#ifndef CONFIG_RISCV_M_MODE
#include <asm/clint.h>
#endif
#define CLINT_IPI_OFF 0
#define CLINT_TIMER_CMP_OFF 0x4000
......@@ -31,6 +36,10 @@ static u64 __iomem *clint_timer_val;
static unsigned long clint_timer_freq;
static unsigned int clint_timer_irq;
#ifdef CONFIG_RISCV_M_MODE
u64 __iomem *clint_time_val;
#endif
static void clint_send_ipi(const struct cpumask *target)
{
unsigned int cpu;
......@@ -184,6 +193,14 @@ static int __init clint_timer_init_dt(struct device_node *np)
clint_timer_val = base + CLINT_TIMER_VAL_OFF;
clint_timer_freq = riscv_timebase;
#ifdef CONFIG_RISCV_M_MODE
/*
* Yes, that's an odd naming scheme. time_val is public, but hopefully
* will die in favor of something cleaner.
*/
clint_time_val = clint_timer_val;
#endif
pr_info("%pOFP: timer running at %ld Hz\n", np, clint_timer_freq);
rc = clocksource_register_hz(&clint_clocksource, clint_timer_freq);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment