Commit b8503b21 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'mips-fixes_6.7_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux

Pull MIPS fixes from Thomas Bogendoerfer:

 - Fixes for broken Loongson firmware

 - Fix lockdep splat

 - Fix FPU states when creating kernel threads

* tag 'mips-fixes_6.7_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux:
  MIPS: kernel: Clear FPU states when setting up kernel threads
  MIPS: Loongson64: Handle more memory types passed from firmware
  MIPS: Loongson64: Enable DMA noncoherent support
  MIPS: Loongson64: Reserve vgabios memory on boot
  mips/smp: Call rcutree_report_cpu_starting() earlier
parents 9d3bc457 a58a1734
...@@ -460,6 +460,7 @@ config MACH_LOONGSON2EF ...@@ -460,6 +460,7 @@ config MACH_LOONGSON2EF
config MACH_LOONGSON64 config MACH_LOONGSON64
bool "Loongson 64-bit family of machines" bool "Loongson 64-bit family of machines"
select ARCH_DMA_DEFAULT_COHERENT
select ARCH_SPARSEMEM_ENABLE select ARCH_SPARSEMEM_ENABLE
select ARCH_MIGHT_HAVE_PC_PARPORT select ARCH_MIGHT_HAVE_PC_PARPORT
select ARCH_MIGHT_HAVE_PC_SERIO select ARCH_MIGHT_HAVE_PC_SERIO
...@@ -1251,6 +1252,7 @@ config CPU_LOONGSON64 ...@@ -1251,6 +1252,7 @@ config CPU_LOONGSON64
select CPU_SUPPORTS_MSA select CPU_SUPPORTS_MSA
select CPU_DIEI_BROKEN if !LOONGSON3_ENHANCEMENT select CPU_DIEI_BROKEN if !LOONGSON3_ENHANCEMENT
select CPU_MIPSR2_IRQ_VI select CPU_MIPSR2_IRQ_VI
select DMA_NONCOHERENT
select WEAK_ORDERING select WEAK_ORDERING
select WEAK_REORDERING_BEYOND_LLSC select WEAK_REORDERING_BEYOND_LLSC
select MIPS_ASID_BITS_VARIABLE select MIPS_ASID_BITS_VARIABLE
......
...@@ -14,7 +14,11 @@ ...@@ -14,7 +14,11 @@
#define ADAPTER_ROM 8 #define ADAPTER_ROM 8
#define ACPI_TABLE 9 #define ACPI_TABLE 9
#define SMBIOS_TABLE 10 #define SMBIOS_TABLE 10
#define MAX_MEMORY_TYPE 11 #define UMA_VIDEO_RAM 11
#define VUMA_VIDEO_RAM 12
#define MAX_MEMORY_TYPE 13
#define MEM_SIZE_IS_IN_BYTES (1 << 31)
#define LOONGSON3_BOOT_MEM_MAP_MAX 128 #define LOONGSON3_BOOT_MEM_MAP_MAX 128
struct efi_memory_map_loongson { struct efi_memory_map_loongson {
...@@ -117,7 +121,8 @@ struct irq_source_routing_table { ...@@ -117,7 +121,8 @@ struct irq_source_routing_table {
u64 pci_io_start_addr; u64 pci_io_start_addr;
u64 pci_io_end_addr; u64 pci_io_end_addr;
u64 pci_config_addr; u64 pci_config_addr;
u32 dma_mask_bits; u16 dma_mask_bits;
u16 dma_noncoherent;
} __packed; } __packed;
struct interface_info { struct interface_info {
......
...@@ -121,6 +121,19 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) ...@@ -121,6 +121,19 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
/* Put the stack after the struct pt_regs. */ /* Put the stack after the struct pt_regs. */
childksp = (unsigned long) childregs; childksp = (unsigned long) childregs;
p->thread.cp0_status = (read_c0_status() & ~(ST0_CU2|ST0_CU1)) | ST0_KERNEL_CUMASK; p->thread.cp0_status = (read_c0_status() & ~(ST0_CU2|ST0_CU1)) | ST0_KERNEL_CUMASK;
/*
* New tasks lose permission to use the fpu. This accelerates context
* switching for most programs since they don't use the fpu.
*/
clear_tsk_thread_flag(p, TIF_USEDFPU);
clear_tsk_thread_flag(p, TIF_USEDMSA);
clear_tsk_thread_flag(p, TIF_MSA_CTX_LIVE);
#ifdef CONFIG_MIPS_MT_FPAFF
clear_tsk_thread_flag(p, TIF_FPUBOUND);
#endif /* CONFIG_MIPS_MT_FPAFF */
if (unlikely(args->fn)) { if (unlikely(args->fn)) {
/* kernel thread */ /* kernel thread */
unsigned long status = p->thread.cp0_status; unsigned long status = p->thread.cp0_status;
...@@ -149,20 +162,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) ...@@ -149,20 +162,8 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
p->thread.reg29 = (unsigned long) childregs; p->thread.reg29 = (unsigned long) childregs;
p->thread.reg31 = (unsigned long) ret_from_fork; p->thread.reg31 = (unsigned long) ret_from_fork;
/*
* New tasks lose permission to use the fpu. This accelerates context
* switching for most programs since they don't use the fpu.
*/
childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); childregs->cp0_status &= ~(ST0_CU2|ST0_CU1);
clear_tsk_thread_flag(p, TIF_USEDFPU);
clear_tsk_thread_flag(p, TIF_USEDMSA);
clear_tsk_thread_flag(p, TIF_MSA_CTX_LIVE);
#ifdef CONFIG_MIPS_MT_FPAFF
clear_tsk_thread_flag(p, TIF_FPUBOUND);
#endif /* CONFIG_MIPS_MT_FPAFF */
#ifdef CONFIG_MIPS_FP_SUPPORT #ifdef CONFIG_MIPS_FP_SUPPORT
atomic_set(&p->thread.bd_emu_frame, BD_EMUFRAME_NONE); atomic_set(&p->thread.bd_emu_frame, BD_EMUFRAME_NONE);
#endif #endif
......
...@@ -351,10 +351,11 @@ early_initcall(mips_smp_ipi_init); ...@@ -351,10 +351,11 @@ early_initcall(mips_smp_ipi_init);
*/ */
asmlinkage void start_secondary(void) asmlinkage void start_secondary(void)
{ {
unsigned int cpu; unsigned int cpu = raw_smp_processor_id();
cpu_probe(); cpu_probe();
per_cpu_trap_init(false); per_cpu_trap_init(false);
rcutree_report_cpu_starting(cpu);
mips_clockevent_init(); mips_clockevent_init();
mp_ops->init_secondary(); mp_ops->init_secondary();
cpu_report(); cpu_report();
...@@ -366,7 +367,6 @@ asmlinkage void start_secondary(void) ...@@ -366,7 +367,6 @@ asmlinkage void start_secondary(void)
*/ */
calibrate_delay(); calibrate_delay();
cpu = smp_processor_id();
cpu_data[cpu].udelay_val = loops_per_jiffy; cpu_data[cpu].udelay_val = loops_per_jiffy;
set_cpu_sibling_map(cpu); set_cpu_sibling_map(cpu);
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
* Copyright (C) 2009 Lemote Inc. * Copyright (C) 2009 Lemote Inc.
* Author: Wu Zhangjin, wuzhangjin@gmail.com * Author: Wu Zhangjin, wuzhangjin@gmail.com
*/ */
#include <linux/dma-map-ops.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/pci_ids.h> #include <linux/pci_ids.h>
#include <asm/bootinfo.h> #include <asm/bootinfo.h>
...@@ -147,8 +149,14 @@ void __init prom_lefi_init_env(void) ...@@ -147,8 +149,14 @@ void __init prom_lefi_init_env(void)
loongson_sysconf.dma_mask_bits = eirq_source->dma_mask_bits; loongson_sysconf.dma_mask_bits = eirq_source->dma_mask_bits;
if (loongson_sysconf.dma_mask_bits < 32 || if (loongson_sysconf.dma_mask_bits < 32 ||
loongson_sysconf.dma_mask_bits > 64) loongson_sysconf.dma_mask_bits > 64) {
loongson_sysconf.dma_mask_bits = 32; loongson_sysconf.dma_mask_bits = 32;
dma_default_coherent = true;
} else {
dma_default_coherent = !eirq_source->dma_noncoherent;
}
pr_info("Firmware: Coherent DMA: %s\n", dma_default_coherent ? "on" : "off");
loongson_sysconf.restart_addr = boot_p->reset_system.ResetWarm; loongson_sysconf.restart_addr = boot_p->reset_system.ResetWarm;
loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown; loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown;
......
...@@ -49,8 +49,7 @@ void virtual_early_config(void) ...@@ -49,8 +49,7 @@ void virtual_early_config(void)
void __init szmem(unsigned int node) void __init szmem(unsigned int node)
{ {
u32 i, mem_type; u32 i, mem_type;
static unsigned long num_physpages; phys_addr_t node_id, mem_start, mem_size;
u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size;
/* Otherwise come from DTB */ /* Otherwise come from DTB */
if (loongson_sysconf.fw_interface != LOONGSON_LEFI) if (loongson_sysconf.fw_interface != LOONGSON_LEFI)
...@@ -64,30 +63,46 @@ void __init szmem(unsigned int node) ...@@ -64,30 +63,46 @@ void __init szmem(unsigned int node)
mem_type = loongson_memmap->map[i].mem_type; mem_type = loongson_memmap->map[i].mem_type;
mem_size = loongson_memmap->map[i].mem_size; mem_size = loongson_memmap->map[i].mem_size;
mem_start = loongson_memmap->map[i].mem_start;
/* Memory size comes in MB if MEM_SIZE_IS_IN_BYTES not set */
if (mem_size & MEM_SIZE_IS_IN_BYTES)
mem_size &= ~MEM_SIZE_IS_IN_BYTES;
else
mem_size = mem_size << 20;
mem_start = (node_id << 44) | loongson_memmap->map[i].mem_start;
switch (mem_type) { switch (mem_type) {
case SYSTEM_RAM_LOW: case SYSTEM_RAM_LOW:
case SYSTEM_RAM_HIGH: case SYSTEM_RAM_HIGH:
start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; case UMA_VIDEO_RAM:
node_psize = (mem_size << 20) >> PAGE_SHIFT; pr_info("Node %d, mem_type:%d\t[%pa], %pa bytes usable\n",
end_pfn = start_pfn + node_psize; (u32)node_id, mem_type, &mem_start, &mem_size);
num_physpages += node_psize; memblock_add_node(mem_start, mem_size, node,
pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n",
(u32)node_id, mem_type, mem_start, mem_size);
pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n",
start_pfn, end_pfn, num_physpages);
memblock_add_node(PFN_PHYS(start_pfn),
PFN_PHYS(node_psize), node,
MEMBLOCK_NONE); MEMBLOCK_NONE);
break; break;
case SYSTEM_RAM_RESERVED: case SYSTEM_RAM_RESERVED:
pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", case VIDEO_ROM:
(u32)node_id, mem_type, mem_start, mem_size); case ADAPTER_ROM:
memblock_reserve(((node_id << 44) + mem_start), mem_size << 20); case ACPI_TABLE:
case SMBIOS_TABLE:
pr_info("Node %d, mem_type:%d\t[%pa], %pa bytes reserved\n",
(u32)node_id, mem_type, &mem_start, &mem_size);
memblock_reserve(mem_start, mem_size);
break;
/* We should not reserve VUMA_VIDEO_RAM as it overlaps with MMIO */
case VUMA_VIDEO_RAM:
default:
pr_info("Node %d, mem_type:%d\t[%pa], %pa bytes unhandled\n",
(u32)node_id, mem_type, &mem_start, &mem_size);
break; break;
} }
} }
/* Reserve vgabios if it comes from firmware */
if (loongson_sysconf.vgabios_addr)
memblock_reserve(virt_to_phys((void *)loongson_sysconf.vgabios_addr),
SZ_256K);
} }
#ifndef CONFIG_NUMA #ifndef CONFIG_NUMA
......
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