Unverified Commit 849fa86c authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files

!12491 LoongArch: fix some 3C6000&LS7A related problems

Merge Pull Request from: @ci-robot 
 
PR sync from: Hongchen Zhang <zhanghongchen@loongson.cn>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/LB4X6RBPX2AHNRTLGERH6RYUI4UCXJ3U/ 
Haowei Zheng (1):
  acpi: mcfg quirk: Increased multi-chip support for the 3C6000

gaojuxin (1):
  LoongArch: Add workaround for 3C6000 about io wr/rd

wusheng (1):
  pci/quirks: LS7A2000 enable msi

zhangtianyang (1):
  Loongarch: Dynamic enable writecombine


-- 
2.33.0
 
https://gitee.com/openeuler/kernel/issues/IAZ38J 
 
Link:https://gitee.com/openeuler/kernel/pulls/12491

 

Reviewed-by: default avatarZhang Peng <zhangpeng362@huawei.com>
Signed-off-by: default avatarZhang Peng <zhangpeng362@huawei.com>
parents 1dafb29c fcf5d35b
Loading
Loading
Loading
Loading
+149 −0
Original line number Diff line number Diff line
@@ -79,6 +79,155 @@ extern void __memcpy_fromio(void *to, const volatile void __iomem *from, size_t

#define __io_aw() mmiowb()

#include <linux/spinlock.h>
extern spinlock_t lcl_node_lock[16];
#define __raw_readb __raw_readb
static inline u8 __raw_readb(const volatile void __iomem *addr)
{
	unsigned long dst_node, node;
	unsigned long irq_flag;
	u8 val;

	dst_node = ((unsigned long)addr >> 44) & 0xf;
	node = get_csr_cpuid() / 32;
	if (node != dst_node)
		spin_lock_irqsave(&lcl_node_lock[node + 8], irq_flag);
	val = *(const volatile u8 __force *)addr;
	if (node != dst_node)
		spin_unlock_irqrestore(&lcl_node_lock[node + 8], irq_flag);
	/* read barrier */
	rmb();
	return val;
}

#define __raw_readw __raw_readw
static inline u16 __raw_readw(const volatile void __iomem *addr)
{
	unsigned long dst_node, node;
	unsigned long irq_flag;
	u16 val;

	dst_node = ((unsigned long)addr >> 44) & 0xf;
	node = get_csr_cpuid() / 32;
	if (node != dst_node)
		spin_lock_irqsave(&lcl_node_lock[node + 8], irq_flag);
	val = *(const volatile u16 __force *)addr;
	if (node != dst_node)
		spin_unlock_irqrestore(&lcl_node_lock[node + 8], irq_flag);
	/* read barrier */
	rmb();
	return val;
}

#define __raw_readl __raw_readl
static inline u32 __raw_readl(const volatile void __iomem *addr)
{
	unsigned long dst_node, node;
	unsigned long irq_flag;
	u32 val;

	dst_node = ((unsigned long)addr >> 44) & 0xf;
	node = get_csr_cpuid() / 32;
	if (node != dst_node)
		spin_lock_irqsave(&lcl_node_lock[node + 8], irq_flag);
	val = *(const volatile u32 __force *)addr;
	if (node != dst_node)
		spin_unlock_irqrestore(&lcl_node_lock[node + 8], irq_flag);
	/* read barrier */
	rmb();
	return val;
}

#ifdef CONFIG_64BIT
#define __raw_readq __raw_readq
static inline u64 __raw_readq(const volatile void __iomem *addr)
{
	unsigned long dst_node, node;
	unsigned long irq_flag;
	u64 val;

	dst_node = ((unsigned long)addr >> 44) & 0xf;
	node = get_csr_cpuid() / 32;
	if (node != dst_node)
		spin_lock_irqsave(&lcl_node_lock[node + 8], irq_flag);
	val = *(const volatile u64 __force *)addr;
	if (node != dst_node)
		spin_unlock_irqrestore(&lcl_node_lock[node + 8], irq_flag);
	/* read barrier */
	rmb();
	return val;
}
#endif /* CONFIG_64BIT */

#define __raw_writeb __raw_writeb
static inline void __raw_writeb(u8 value, volatile void __iomem *addr)
{
	unsigned long dst_node, node;
	unsigned long irq_flag;

	/* write barrier */
	wmb();
	dst_node = ((unsigned long)addr >> 44) & 0xf;
	node = get_csr_cpuid() / 32;
	if (node != dst_node)
		spin_lock_irqsave(&lcl_node_lock[node], irq_flag);
	*(volatile u8 __force *)addr = value;
	if (node != dst_node)
		spin_unlock_irqrestore(&lcl_node_lock[node], irq_flag);
}

#define __raw_writew __raw_writew
static inline void __raw_writew(u16 value, volatile void __iomem *addr)
{
	unsigned long dst_node, node;
	unsigned long irq_flag;

	/* write barrier */
	wmb();
	dst_node = ((unsigned long)addr >> 44) & 0xf;
	node = get_csr_cpuid() / 32;
	if (node != dst_node)
		spin_lock_irqsave(&lcl_node_lock[node], irq_flag);
	*(volatile u16 __force *)addr = value;
	if (node != dst_node)
		spin_unlock_irqrestore(&lcl_node_lock[node], irq_flag);
}

#define __raw_writel __raw_writel
static inline void __raw_writel(u32 value, volatile void __iomem *addr)
{
	unsigned long dst_node, node;
	unsigned long irq_flag;

	/* write barrier */
	wmb();
	dst_node = ((unsigned long)addr >> 44) & 0xf;
	node = get_csr_cpuid() / 32;
	if (node != dst_node)
		spin_lock_irqsave(&lcl_node_lock[node], irq_flag);
	*(volatile u32 __force *)addr = value;
	if (node != dst_node)
		spin_unlock_irqrestore(&lcl_node_lock[node], irq_flag);
}

#ifdef CONFIG_64BIT
#define __raw_writeq __raw_writeq
static inline void __raw_writeq(u64 value, volatile void __iomem *addr)
{
	unsigned long dst_node, node;
	unsigned long irq_flag;

	/* write barrier */
	wmb();
	dst_node = ((unsigned long)addr >> 44) & 0xf;
	node = get_csr_cpuid() / 32;
	if (node != dst_node)
		spin_lock_irqsave(&lcl_node_lock[node], irq_flag);
	*(volatile u64 __force *)addr = value;
	if (node != dst_node)
		spin_unlock_irqrestore(&lcl_node_lock[node], irq_flag);
}
#endif /* CONFIG_64BIT */
#include <asm-generic/io.h>

#define ARCH_HAS_VALID_PHYS_ADDR_RANGE
+2 −2
Original line number Diff line number Diff line
@@ -43,8 +43,8 @@ void spurious_interrupt(void);
extern bool arch_trigger_cpumask_backtrace(const cpumask_t *mask,
					   int exclude_cpu);

#define MAX_IO_PICS 2
#define NR_IRQS	(64 + (256 * MAX_IO_PICS))
#define MAX_IO_PICS  16
#define NR_IRQS	(64 + NR_VECTORS * (NR_CPUS + MAX_IO_PICS))

struct acpi_vector_group {
	int node;
+26 −2
Original line number Diff line number Diff line
@@ -184,12 +184,14 @@ bool wc_enabled = false;

EXPORT_SYMBOL(wc_enabled);

static int wc_arg = -1;

static int __init setup_writecombine(char *p)
{
	if (!strcmp(p, "on"))
		wc_enabled = true;
		wc_arg = true;
	else if (!strcmp(p, "off"))
		wc_enabled = false;
		wc_arg = false;
	else
		pr_warn("Unknown writecombine setting \"%s\".\n", p);

@@ -371,6 +373,26 @@ static void __init bootcmdline_init(char **cmdline_p)
	*cmdline_p = boot_command_line;
}

static void __init writecombine_detect(void)
{
	u64 cpuname;

	if (wc_arg >= 0) {
		wc_enabled = wc_arg;
		return;
	}

	cpuname = iocsr_read64(LOONGARCH_IOCSR_CPUNAME);

	switch (cpuname) {
	case 0x0000303030364333:
		wc_enabled = true;
		break;
	default:
		break;
	}
}

void __init platform_init(void)
{
	arch_reserve_vmcore();
@@ -394,6 +416,8 @@ void __init platform_init(void)
	smbios_parse();
	pr_info("The BIOS Version: %s\n", b_info.bios_version);

	writecombine_detect();
	pr_info("WriteCombine: %s\n", wc_enabled ? "on":"off");
	efi_runtime_init();
}

+19 −1
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@
#include <asm/time.h>
#include "legacy_boot.h"

spinlock_t lcl_node_lock[16];
EXPORT_SYMBOL(lcl_node_lock);
int __cpu_number_map[NR_CPUS];   /* Map physical to logical */
EXPORT_SYMBOL(__cpu_number_map);

@@ -196,7 +198,19 @@ static void ipi_write_action(int cpu, u32 action)

static void loongson_send_ipi_single(int cpu, unsigned int action)
{
	unsigned int curr_cpu = cpu_logical_map(smp_processor_id());
	unsigned int t_cpu = cpu_logical_map(cpu);
	int flag = -1;
	unsigned long irq_flag;

	if ((curr_cpu / 32) != (t_cpu / 32)) {
		flag = curr_cpu / 32;
		spin_lock_irqsave(&lcl_node_lock[flag], irq_flag);
		asm ("dbar 0x0");
	}
	ipi_write_action(cpu_logical_map(cpu), (u32)action);
	if (flag >= 0)
		spin_unlock_irqrestore(&lcl_node_lock[flag], irq_flag);
}

static void loongson_send_ipi_mask(const struct cpumask *mask, unsigned int action)
@@ -204,7 +218,7 @@ static void loongson_send_ipi_mask(const struct cpumask *mask, unsigned int acti
	unsigned int i;

	for_each_cpu(i, mask)
		ipi_write_action(cpu_logical_map(i), (u32)action);
		loongson_send_ipi_single(i, (u32)action);
}

void arch_send_call_function_single_ipi(int cpu)
@@ -305,6 +319,10 @@ static void __init fdt_smp_setup(void)

void __init loongson_smp_setup(void)
{
	int i;

	for (i = 0; i < 16; i++)
		spin_lock_init(&lcl_node_lock[i]);
	fdt_smp_setup();

	cpu_data[0].core = cpu_logical_map(0) % loongson_sysconf.cores_per_package;
+13 −0
Original line number Diff line number Diff line
@@ -185,6 +185,19 @@ static struct mcfg_fixup mcfg_quirks[] = {
	LOONGSON_ECAM_MCFG("LOONGSON", 0),
	LOONGSON_ECAM_MCFG("\0", 1),
	LOONGSON_ECAM_MCFG("LOONGSON", 1),
	LOONGSON_ECAM_MCFG("\0", 2),
	LOONGSON_ECAM_MCFG("LOONGSON", 2),
	LOONGSON_ECAM_MCFG("\0", 3),
	LOONGSON_ECAM_MCFG("LOONGSON", 3),
	LOONGSON_ECAM_MCFG("\0", 4),
	LOONGSON_ECAM_MCFG("LOONGSON", 4),
	LOONGSON_ECAM_MCFG("\0", 5),
	LOONGSON_ECAM_MCFG("LOONGSON", 5),
	LOONGSON_ECAM_MCFG("\0", 6),
	LOONGSON_ECAM_MCFG("LOONGSON", 6),
	LOONGSON_ECAM_MCFG("\0", 7),
	LOONGSON_ECAM_MCFG("LOONGSON", 7),

#endif /* LOONGARCH */

#ifdef CONFIG_SW64
Loading