Commit 9830afca authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'riscv-for-linus-4.21-mw1' of...

Merge tag 'riscv-for-linus-4.21-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/palmer/riscv-linux

Pull RISC-V updates from Palmer Dabbelt:
 "We don't have many patches for this merge window, probably because
  everything has been a bit busy with the holidays and conferences. The
  only big user-visible change is to move over to an SBI-based earlycon
  instead of our arch-specific early printk support.

  The only outstanding patch set I know of is the audit patch set, which
  I've managed to make a mess of and will attempt to clean up"

* tag 'riscv-for-linus-4.21-mw1' of git://git.kernel.org/pub/scm/linux/kernel/git/palmer/riscv-linux:
  RISC-V: Select GENERIC_SCHED_CLOCK for clocksource drivers
  RISC-V: lib: minor asm cleanup
  RISC-V: Update Kconfig to better handle CMDLINE
  riscv: remove unused variable in ftrace
  RISC-V: add of_node_put()
  RISC-V: Fix of_node_* refcount
  riscv, atomic: Add #define's for the atomic_{cmp,}xchg_*() variants
  RISC-V: Remove EARLY_PRINTK support
  RISC-V: defconfig: Enable RISC-V SBI earlycon support
parents 30807ef2 9b9afe4a
...@@ -24,6 +24,7 @@ config RISCV ...@@ -24,6 +24,7 @@ config RISCV
select GENERIC_CPU_DEVICES select GENERIC_CPU_DEVICES
select GENERIC_IRQ_SHOW select GENERIC_IRQ_SHOW
select GENERIC_PCI_IOMAP select GENERIC_PCI_IOMAP
select GENERIC_SCHED_CLOCK
select GENERIC_STRNCPY_FROM_USER select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER select GENERIC_STRNLEN_USER
select GENERIC_SMP_IDLE_THREAD select GENERIC_SMP_IDLE_THREAD
...@@ -227,39 +228,48 @@ endmenu ...@@ -227,39 +228,48 @@ endmenu
menu "Boot options" menu "Boot options"
config CMDLINE_BOOL config CMDLINE
bool "Built-in kernel command line" string "Built-in kernel command line"
help help
For most platforms, it is firmware or second stage bootloader For most platforms, the arguments for the kernel's command line
that by default specifies the kernel command line options. are provided at run-time, during boot. However, there are cases
However, it might be necessary or advantageous to either override where either no arguments are being provided or the provided
the default kernel command line or add a few extra options to it. arguments are insufficient or even invalid.
For such cases, this option allows hardcoding command line options
directly into the kernel.
For that, choose 'Y' here and fill in the extra boot parameters When that occurs, it is possible to define a built-in command
in CONFIG_CMDLINE. line here and choose how the kernel should use it later on.
The built-in options will be concatenated to the default command choice
line if CMDLINE_FORCE is set to 'N'. Otherwise, the default prompt "Built-in command line usage" if CMDLINE != ""
command line will be ignored and replaced by the built-in string. default CMDLINE_FALLBACK
help
Choose how the kernel will handle the provided built-in command
line.
config CMDLINE config CMDLINE_FALLBACK
string "Built-in kernel command string" bool "Use bootloader kernel arguments if available"
depends on CMDLINE_BOOL
default ""
help help
Supply command-line options at build time by entering them here. Use the built-in command line as fallback in case we get nothing
during boot. This is the default behaviour.
config CMDLINE_EXTEND
bool "Extend bootloader kernel arguments"
help
The command-line arguments provided during boot will be
appended to the built-in command line. This is useful in
cases where the provided arguments are insufficient and
you don't want to or cannot modify them.
config CMDLINE_FORCE config CMDLINE_FORCE
bool "Built-in command line overrides bootloader arguments" bool "Always use the default kernel command string"
depends on CMDLINE_BOOL
help help
Set this option to 'Y' to have the kernel ignore the bootloader Always use the built-in command line, even if we get one during
or firmware command line. Instead, the built-in command line boot. This is useful in case you need to override the provided
will be used exclusively. command line on systems where you don't have or want control
over it.
If you don't know what to do here, say N. endchoice
endmenu endmenu
......
...@@ -46,6 +46,7 @@ CONFIG_INPUT_MOUSEDEV=y ...@@ -46,6 +46,7 @@ CONFIG_INPUT_MOUSEDEV=y
CONFIG_SERIAL_8250=y CONFIG_SERIAL_8250=y
CONFIG_SERIAL_8250_CONSOLE=y CONFIG_SERIAL_8250_CONSOLE=y
CONFIG_SERIAL_OF_PLATFORM=y CONFIG_SERIAL_OF_PLATFORM=y
CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
CONFIG_HVC_RISCV_SBI=y CONFIG_HVC_RISCV_SBI=y
# CONFIG_PTP_1588_CLOCK is not set # CONFIG_PTP_1588_CLOCK is not set
CONFIG_DRM=y CONFIG_DRM=y
......
...@@ -303,6 +303,15 @@ c_t atomic##prefix##_cmpxchg(atomic##prefix##_t *v, c_t o, c_t n) \ ...@@ -303,6 +303,15 @@ c_t atomic##prefix##_cmpxchg(atomic##prefix##_t *v, c_t o, c_t n) \
ATOMIC_OPS() ATOMIC_OPS()
#define atomic_xchg_relaxed atomic_xchg_relaxed
#define atomic_xchg_acquire atomic_xchg_acquire
#define atomic_xchg_release atomic_xchg_release
#define atomic_xchg atomic_xchg
#define atomic_cmpxchg_relaxed atomic_cmpxchg_relaxed
#define atomic_cmpxchg_acquire atomic_cmpxchg_acquire
#define atomic_cmpxchg_release atomic_cmpxchg_release
#define atomic_cmpxchg atomic_cmpxchg
#undef ATOMIC_OPS #undef ATOMIC_OPS
#undef ATOMIC_OP #undef ATOMIC_OP
......
...@@ -28,6 +28,7 @@ static int __init_cache_level(unsigned int cpu) ...@@ -28,6 +28,7 @@ static int __init_cache_level(unsigned int cpu)
{ {
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
struct device_node *np = of_cpu_device_node_get(cpu); struct device_node *np = of_cpu_device_node_get(cpu);
struct device_node *prev = NULL;
int levels = 0, leaves = 0, level; int levels = 0, leaves = 0, level;
if (of_property_read_bool(np, "cache-size")) if (of_property_read_bool(np, "cache-size"))
...@@ -39,7 +40,10 @@ static int __init_cache_level(unsigned int cpu) ...@@ -39,7 +40,10 @@ static int __init_cache_level(unsigned int cpu)
if (leaves > 0) if (leaves > 0)
levels = 1; levels = 1;
prev = np;
while ((np = of_find_next_cache_node(np))) { while ((np = of_find_next_cache_node(np))) {
of_node_put(prev);
prev = np;
if (!of_device_is_compatible(np, "cache")) if (!of_device_is_compatible(np, "cache"))
break; break;
if (of_property_read_u32(np, "cache-level", &level)) if (of_property_read_u32(np, "cache-level", &level))
...@@ -55,8 +59,10 @@ static int __init_cache_level(unsigned int cpu) ...@@ -55,8 +59,10 @@ static int __init_cache_level(unsigned int cpu)
levels = level; levels = level;
} }
of_node_put(np);
this_cpu_ci->num_levels = levels; this_cpu_ci->num_levels = levels;
this_cpu_ci->num_leaves = leaves; this_cpu_ci->num_leaves = leaves;
return 0; return 0;
} }
...@@ -65,6 +71,7 @@ static int __populate_cache_leaves(unsigned int cpu) ...@@ -65,6 +71,7 @@ static int __populate_cache_leaves(unsigned int cpu)
struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu);
struct cacheinfo *this_leaf = this_cpu_ci->info_list; struct cacheinfo *this_leaf = this_cpu_ci->info_list;
struct device_node *np = of_cpu_device_node_get(cpu); struct device_node *np = of_cpu_device_node_get(cpu);
struct device_node *prev = NULL;
int levels = 1, level = 1; int levels = 1, level = 1;
if (of_property_read_bool(np, "cache-size")) if (of_property_read_bool(np, "cache-size"))
...@@ -74,7 +81,10 @@ static int __populate_cache_leaves(unsigned int cpu) ...@@ -74,7 +81,10 @@ static int __populate_cache_leaves(unsigned int cpu)
if (of_property_read_bool(np, "d-cache-size")) if (of_property_read_bool(np, "d-cache-size"))
ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level); ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
prev = np;
while ((np = of_find_next_cache_node(np))) { while ((np = of_find_next_cache_node(np))) {
of_node_put(prev);
prev = np;
if (!of_device_is_compatible(np, "cache")) if (!of_device_is_compatible(np, "cache"))
break; break;
if (of_property_read_u32(np, "cache-level", &level)) if (of_property_read_u32(np, "cache-level", &level))
...@@ -89,6 +99,7 @@ static int __populate_cache_leaves(unsigned int cpu) ...@@ -89,6 +99,7 @@ static int __populate_cache_leaves(unsigned int cpu)
ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level); ci_leaf_init(this_leaf++, np, CACHE_TYPE_DATA, level);
levels = level; levels = level;
} }
of_node_put(np);
return 0; return 0;
} }
......
...@@ -158,6 +158,7 @@ static int c_show(struct seq_file *m, void *v) ...@@ -158,6 +158,7 @@ static int c_show(struct seq_file *m, void *v)
&& strcmp(compat, "riscv")) && strcmp(compat, "riscv"))
seq_printf(m, "uarch\t\t: %s\n", compat); seq_printf(m, "uarch\t\t: %s\n", compat);
seq_puts(m, "\n"); seq_puts(m, "\n");
of_node_put(node);
return 0; return 0;
} }
......
...@@ -56,8 +56,10 @@ void riscv_fill_hwcap(void) ...@@ -56,8 +56,10 @@ void riscv_fill_hwcap(void)
if (of_property_read_string(node, "riscv,isa", &isa)) { if (of_property_read_string(node, "riscv,isa", &isa)) {
pr_warning("Unable to find \"riscv,isa\" devicetree entry"); pr_warning("Unable to find \"riscv,isa\" devicetree entry");
of_node_put(node);
return; return;
} }
of_node_put(node);
for (i = 0; i < strlen(isa); ++i) for (i = 0; i < strlen(isa); ++i)
elf_hwcap |= isa2hwcap[(unsigned char)(isa[i])]; elf_hwcap |= isa2hwcap[(unsigned char)(isa[i])];
......
...@@ -132,7 +132,6 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr, ...@@ -132,7 +132,6 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
{ {
unsigned long return_hooker = (unsigned long)&return_to_handler; unsigned long return_hooker = (unsigned long)&return_to_handler;
unsigned long old; unsigned long old;
int err;
if (unlikely(atomic_read(&current->tracing_graph_pause))) if (unlikely(atomic_read(&current->tracing_graph_pause)))
return; return;
......
...@@ -476,6 +476,7 @@ int __init init_hw_perf_events(void) ...@@ -476,6 +476,7 @@ int __init init_hw_perf_events(void)
if (of_id) if (of_id)
riscv_pmu = of_id->data; riscv_pmu = of_id->data;
of_node_put(node);
} }
perf_pmu_register(riscv_pmu->pmu, "cpu", PERF_TYPE_RAW); perf_pmu_register(riscv_pmu->pmu, "cpu", PERF_TYPE_RAW);
......
...@@ -35,31 +35,9 @@ ...@@ -35,31 +35,9 @@
#include <asm/sections.h> #include <asm/sections.h>
#include <asm/pgtable.h> #include <asm/pgtable.h>
#include <asm/smp.h> #include <asm/smp.h>
#include <asm/sbi.h>
#include <asm/tlbflush.h> #include <asm/tlbflush.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
#ifdef CONFIG_EARLY_PRINTK
static void sbi_console_write(struct console *co, const char *buf,
unsigned int n)
{
int i;
for (i = 0; i < n; ++i) {
if (buf[i] == '\n')
sbi_console_putchar('\r');
sbi_console_putchar(buf[i]);
}
}
struct console riscv_sbi_early_console_dev __initdata = {
.name = "early",
.write = sbi_console_write,
.flags = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME,
.index = -1
};
#endif
#ifdef CONFIG_DUMMY_CONSOLE #ifdef CONFIG_DUMMY_CONSOLE
struct screen_info screen_info = { struct screen_info screen_info = {
.orig_video_lines = 30, .orig_video_lines = 30,
...@@ -219,12 +197,6 @@ static void __init setup_bootmem(void) ...@@ -219,12 +197,6 @@ static void __init setup_bootmem(void)
void __init setup_arch(char **cmdline_p) void __init setup_arch(char **cmdline_p)
{ {
#if defined(CONFIG_EARLY_PRINTK)
if (likely(early_console == NULL)) {
early_console = &riscv_sbi_early_console_dev;
register_console(early_console);
}
#endif
*cmdline_p = boot_command_line; *cmdline_p = boot_command_line;
parse_early_param(); parse_early_param();
......
...@@ -57,12 +57,15 @@ void __init setup_smp(void) ...@@ -57,12 +57,15 @@ void __init setup_smp(void)
while ((dn = of_find_node_by_type(dn, "cpu"))) { while ((dn = of_find_node_by_type(dn, "cpu"))) {
hart = riscv_of_processor_hartid(dn); hart = riscv_of_processor_hartid(dn);
if (hart < 0) if (hart < 0) {
of_node_put(dn);
continue; continue;
}
if (hart == cpuid_to_hartid_map(0)) { if (hart == cpuid_to_hartid_map(0)) {
BUG_ON(found_boot_cpu); BUG_ON(found_boot_cpu);
found_boot_cpu = 1; found_boot_cpu = 1;
of_node_put(dn);
continue; continue;
} }
...@@ -70,6 +73,7 @@ void __init setup_smp(void) ...@@ -70,6 +73,7 @@ void __init setup_smp(void)
set_cpu_possible(cpuid, true); set_cpu_possible(cpuid, true);
set_cpu_present(cpuid, true); set_cpu_present(cpuid, true);
cpuid++; cpuid++;
of_node_put(dn);
} }
BUG_ON(!found_boot_cpu); BUG_ON(!found_boot_cpu);
......
...@@ -26,6 +26,7 @@ void __init time_init(void) ...@@ -26,6 +26,7 @@ void __init time_init(void)
cpu = of_find_node_by_path("/cpus"); cpu = of_find_node_by_path("/cpus");
if (!cpu || of_property_read_u32(cpu, "timebase-frequency", &prop)) if (!cpu || of_property_read_u32(cpu, "timebase-frequency", &prop))
panic(KERN_WARNING "RISC-V system with no 'timebase-frequency' in DTS\n"); panic(KERN_WARNING "RISC-V system with no 'timebase-frequency' in DTS\n");
of_node_put(cpu);
riscv_timebase = prop; riscv_timebase = prop;
lpj_fine = riscv_timebase / HZ; lpj_fine = riscv_timebase / HZ;
......
...@@ -10,8 +10,10 @@ ...@@ -10,8 +10,10 @@
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
.globl __lshrti3
__lshrti3: #include <linux/linkage.h>
ENTRY(__lshrti3)
beqz a2, .L1 beqz a2, .L1
li a5,64 li a5,64
sub a5,a5,a2 sub a5,a5,a2
...@@ -40,3 +42,4 @@ __lshrti3: ...@@ -40,3 +42,4 @@ __lshrti3:
ld a1,8(sp) ld a1,8(sp)
addi sp,sp,16 addi sp,sp,16
ret ret
ENDPROC(__lshrti3)
...@@ -11,8 +11,9 @@ ...@@ -11,8 +11,9 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
.globl __udivdi3 #include <linux/linkage.h>
__udivdi3:
ENTRY(__udivdi3)
mv a2, a1 mv a2, a1
mv a1, a0 mv a1, a0
li a0, -1 li a0, -1
...@@ -36,3 +37,4 @@ __udivdi3: ...@@ -36,3 +37,4 @@ __udivdi3:
bnez a3, .L3 bnez a3, .L3
.L5: .L5:
ret ret
ENDPROC(__udivdi3)
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