All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V2 00/12] MIPS: Loongson: new features and improvements
@ 2018-01-27  3:12 Huacai Chen
  2018-01-27  3:12 ` [PATCH V2 01/12] MIPS: Loongson: Add Loongson-3A R3.1 basic support Huacai Chen
                   ` (8 more replies)
  0 siblings, 9 replies; 42+ messages in thread
From: Huacai Chen @ 2018-01-27  3:12 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen

This patchset is prepared for the next 4.16 release for Linux/MIPS. It
add Loongson-3A R3.1 support, enable Loongson-3's SFB at runtime, adds
"model name" and "CPU MHz" knobs in /proc/cpuinfo which is needed by
some userspace tools, adds Loongson-3 kexec/kdump and CPUFreq support,
fixes CPU UART irq delivery problem, and introduces WAR_LLSC_MB to
improve stability.

V1 -> V2:
1, Add Loongson-3A R3.1 basic support.
2, Fix CPU UART irq delivery problem.
3, Improve code and descriptions (Thank James Hogan).
4, Sync the code to upstream.

Huacai Chen(12):
 MIPS: Loongson: Add Loongson-3A R3.1 basic support.
 MIPS: Loongson-3: Define and use some CP0 registers.
 MIPS: Loongson-3: Enable Store Fill Buffer at runtime.
 MIPS: c-r4k: Add r4k_blast_scache_node for Loongson-3.
 MIPS: Loongson fix name confict - MEM_RESERVED.
 MIPS: Ensure pmd_present() returns false after pmd_mknotpresent().
 MIPS: Add __cpu_full_name[] to make CPU names more human-readable.
 MIPS: Align kernel load address to 64KB.
 MIPS: Loongson: Add kexec/kdump support.
 MIPS: Loongson: Make CPUFreq usable for Loongson-3.
 MIPS: Loongson-3: Fix CPU UART irq delivery problem.
 MIPS: Loongson: Introduce and use WAR_LLSC_MB.

Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/boot/compressed/calc_vmlinuz_load_addr.c |   5 +-
 arch/mips/include/asm/atomic.h                     |  18 +-
 arch/mips/include/asm/barrier.h                    |   6 +
 arch/mips/include/asm/bitops.h                     |  15 ++
 arch/mips/include/asm/cmpxchg.h                    |   9 +-
 arch/mips/include/asm/cpu-info.h                   |   2 +
 arch/mips/include/asm/cpu.h                        |  51 ++---
 arch/mips/include/asm/edac.h                       |   5 +-
 arch/mips/include/asm/futex.h                      |  18 +-
 arch/mips/include/asm/io.h                         |   2 +-
 arch/mips/include/asm/local.h                      |  10 +-
 arch/mips/include/asm/mach-loongson64/boot_param.h |   3 +-
 .../asm/mach-loongson64/kernel-entry-init.h        |  38 ++--
 arch/mips/include/asm/mach-loongson64/loongson.h   |   1 +
 arch/mips/include/asm/mipsregs.h                   |   2 +
 arch/mips/include/asm/pgtable-64.h                 |   5 +
 arch/mips/include/asm/pgtable.h                    |   5 +-
 arch/mips/include/asm/r4kcache.h                   |  34 +++
 arch/mips/include/asm/time.h                       |   2 +
 arch/mips/kernel/cpu-probe.c                       |  28 ++-
 arch/mips/kernel/proc.c                            |   7 +
 arch/mips/kernel/relocate_kernel.S                 |  30 +++
 arch/mips/kernel/smp.c                             |   3 +-
 arch/mips/kernel/syscall.c                         |   2 +
 arch/mips/kernel/time.c                            |   2 +
 arch/mips/loongson64/Kconfig                       |   1 +
 arch/mips/loongson64/Platform                      |   3 +
 arch/mips/loongson64/common/env.c                  |  24 ++-
 arch/mips/loongson64/common/mem.c                  |   2 +-
 arch/mips/loongson64/common/platform.c             |  13 +-
 arch/mips/loongson64/common/reset.c                | 119 +++++++++++
 arch/mips/loongson64/loongson-3/Makefile           |   2 +-
 arch/mips/loongson64/loongson-3/clock.c            | 191 +++++++++++++++++
 arch/mips/loongson64/loongson-3/irq.c              |  41 +---
 arch/mips/loongson64/loongson-3/numa.c             |   2 +-
 arch/mips/loongson64/loongson-3/smp.c              |   8 +-
 arch/mips/loongson64/loongson-3/smp.h              |   1 +
 arch/mips/mm/c-r4k.c                               |  42 +++-
 arch/mips/mm/tlbex.c                               |  11 +
 drivers/cpufreq/Kconfig                            |  13 ++
 drivers/cpufreq/Makefile                           |   1 +
 drivers/cpufreq/loongson3_cpufreq.c                | 236 +++++++++++++++++++++
 drivers/platform/mips/cpu_hwmon.c                  |   3 +-
 43 files changed, 893 insertions(+), 123 deletions(-)
 create mode 100644 arch/mips/loongson64/loongson-3/clock.c
 create mode 100644 drivers/cpufreq/loongson3_cpufreq.c
--
2.7.0

^ permalink raw reply	[flat|nested] 42+ messages in thread

* [PATCH V2 01/12] MIPS: Loongson: Add Loongson-3A R3.1 basic support
  2018-01-27  3:12 [PATCH V2 00/12] MIPS: Loongson: new features and improvements Huacai Chen
@ 2018-01-27  3:12 ` Huacai Chen
  2018-01-27  3:12 ` [PATCH V2 02/12] MIPS: Loongson64: Define and use some CP0 registers Huacai Chen
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 42+ messages in thread
From: Huacai Chen @ 2018-01-27  3:12 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen

Loongson-3A R3.1 is the bugfix revision of Loongson-3A R3.

All Loongson-3 CPU family:

Code-name         Brand-name       PRId
Loongson-3A R1    Loongson-3A1000  0x6305
Loongson-3A R2    Loongson-3A2000  0x6308
Loongson-3A R3    Loongson-3A3000  0x6309
Loongson-3A R3.1  Loongson-3A3000  0x630d
Loongson-3B R1    Loongson-3B1000  0x6306
Loongson-3B R2    Loongson-3B1500  0x6307

Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/include/asm/cpu.h           | 51 ++++++++++++++++++-----------------
 arch/mips/kernel/cpu-probe.c          |  3 ++-
 arch/mips/loongson64/common/env.c     |  3 ++-
 arch/mips/loongson64/loongson-3/smp.c |  3 ++-
 drivers/platform/mips/cpu_hwmon.c     |  3 ++-
 5 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index d39324c..4fbb069 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -225,31 +225,32 @@
  * Definitions for 7:0 on legacy processors
  */
 
-#define PRID_REV_TX4927		0x0022
-#define PRID_REV_TX4937		0x0030
-#define PRID_REV_R4400		0x0040
-#define PRID_REV_R3000A		0x0030
-#define PRID_REV_R3000		0x0020
-#define PRID_REV_R2000A		0x0010
-#define PRID_REV_TX3912		0x0010
-#define PRID_REV_TX3922		0x0030
-#define PRID_REV_TX3927		0x0040
-#define PRID_REV_VR4111		0x0050
-#define PRID_REV_VR4181		0x0050	/* Same as VR4111 */
-#define PRID_REV_VR4121		0x0060
-#define PRID_REV_VR4122		0x0070
-#define PRID_REV_VR4181A	0x0070	/* Same as VR4122 */
-#define PRID_REV_VR4130		0x0080
-#define PRID_REV_34K_V1_0_2	0x0022
-#define PRID_REV_LOONGSON1B	0x0020
-#define PRID_REV_LOONGSON1C	0x0020	/* Same as Loongson-1B */
-#define PRID_REV_LOONGSON2E	0x0002
-#define PRID_REV_LOONGSON2F	0x0003
-#define PRID_REV_LOONGSON3A_R1	0x0005
-#define PRID_REV_LOONGSON3B_R1	0x0006
-#define PRID_REV_LOONGSON3B_R2	0x0007
-#define PRID_REV_LOONGSON3A_R2	0x0008
-#define PRID_REV_LOONGSON3A_R3	0x0009
+#define PRID_REV_TX4927			0x0022
+#define PRID_REV_TX4937			0x0030
+#define PRID_REV_R4400			0x0040
+#define PRID_REV_R3000A			0x0030
+#define PRID_REV_R3000			0x0020
+#define PRID_REV_R2000A			0x0010
+#define PRID_REV_TX3912			0x0010
+#define PRID_REV_TX3922			0x0030
+#define PRID_REV_TX3927			0x0040
+#define PRID_REV_VR4111			0x0050
+#define PRID_REV_VR4181			0x0050	/* Same as VR4111 */
+#define PRID_REV_VR4121			0x0060
+#define PRID_REV_VR4122			0x0070
+#define PRID_REV_VR4181A		0x0070	/* Same as VR4122 */
+#define PRID_REV_VR4130			0x0080
+#define PRID_REV_34K_V1_0_2		0x0022
+#define PRID_REV_LOONGSON1B		0x0020
+#define PRID_REV_LOONGSON1C		0x0020	/* Same as Loongson-1B */
+#define PRID_REV_LOONGSON2E		0x0002
+#define PRID_REV_LOONGSON2F		0x0003
+#define PRID_REV_LOONGSON3A_R1		0x0005
+#define PRID_REV_LOONGSON3B_R1		0x0006
+#define PRID_REV_LOONGSON3B_R2		0x0007
+#define PRID_REV_LOONGSON3A_R2		0x0008
+#define PRID_REV_LOONGSON3A_R3_0	0x0009
+#define PRID_REV_LOONGSON3A_R3_1	0x000d
 
 /*
  * Older processors used to encode processor version and revision in two
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index cf3fd54..83317d6 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -1834,7 +1834,8 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
 			set_elf_platform(cpu, "loongson3a");
 			set_isa(c, MIPS_CPU_ISA_M64R2);
 			break;
-		case PRID_REV_LOONGSON3A_R3:
+		case PRID_REV_LOONGSON3A_R3_0:
+		case PRID_REV_LOONGSON3A_R3_1:
 			c->cputype = CPU_LOONGSON3;
 			__cpu_name[cpu] = "ICT Loongson-3";
 			set_elf_platform(cpu, "loongson3a");
diff --git a/arch/mips/loongson64/common/env.c b/arch/mips/loongson64/common/env.c
index 1e8a955..8f68ee0 100644
--- a/arch/mips/loongson64/common/env.c
+++ b/arch/mips/loongson64/common/env.c
@@ -198,7 +198,8 @@ void __init prom_init_env(void)
 			break;
 		case PRID_REV_LOONGSON3A_R1:
 		case PRID_REV_LOONGSON3A_R2:
-		case PRID_REV_LOONGSON3A_R3:
+		case PRID_REV_LOONGSON3A_R3_0:
+		case PRID_REV_LOONGSON3A_R3_1:
 			cpu_clock_freq = 900000000;
 			break;
 		case PRID_REV_LOONGSON3B_R1:
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c
index 8501109..fea95d0 100644
--- a/arch/mips/loongson64/loongson-3/smp.c
+++ b/arch/mips/loongson64/loongson-3/smp.c
@@ -682,7 +682,8 @@ void play_dead(void)
 			(void *)CKSEG1ADDR((unsigned long)loongson3a_r1_play_dead);
 		break;
 	case PRID_REV_LOONGSON3A_R2:
-	case PRID_REV_LOONGSON3A_R3:
+	case PRID_REV_LOONGSON3A_R3_0:
+	case PRID_REV_LOONGSON3A_R3_1:
 		play_dead_at_ckseg1 =
 			(void *)CKSEG1ADDR((unsigned long)loongson3a_r2r3_play_dead);
 		break;
diff --git a/drivers/platform/mips/cpu_hwmon.c b/drivers/platform/mips/cpu_hwmon.c
index 322de58..f66521c 100644
--- a/drivers/platform/mips/cpu_hwmon.c
+++ b/drivers/platform/mips/cpu_hwmon.c
@@ -30,7 +30,8 @@ int loongson3_cpu_temp(int cpu)
 	case PRID_REV_LOONGSON3B_R2:
 		reg = ((reg >> 8) & 0xff) - 100;
 		break;
-	case PRID_REV_LOONGSON3A_R3:
+	case PRID_REV_LOONGSON3A_R3_0:
+	case PRID_REV_LOONGSON3A_R3_1:
 		reg = (reg & 0xffff)*731/0x4000 - 273;
 		break;
 	}
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH V2 02/12] MIPS: Loongson64: Define and use some CP0 registers
  2018-01-27  3:12 [PATCH V2 00/12] MIPS: Loongson: new features and improvements Huacai Chen
  2018-01-27  3:12 ` [PATCH V2 01/12] MIPS: Loongson: Add Loongson-3A R3.1 basic support Huacai Chen
@ 2018-01-27  3:12 ` Huacai Chen
  2018-02-15 11:36   ` James Hogan
  2018-01-27  3:12 ` [PATCH V2 03/12] MIPS: Loongson-3: Enable Store Fill Buffer at runtime Huacai Chen
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 42+ messages in thread
From: Huacai Chen @ 2018-01-27  3:12 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen

This patche defines CP0_CONFIG3, CP0_CONFIG6, CP0_PAGEGRAIN and uses
them in kernel-entry-init.h for Loongson64.

Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 .../asm/mach-loongson64/kernel-entry-init.h        | 24 +++++++++++-----------
 arch/mips/include/asm/mipsregs.h                   |  2 ++
 2 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h
index 8393bc54..3127391 100644
--- a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h
+++ b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h
@@ -19,18 +19,18 @@
 	.set	push
 	.set	mips64
 	/* Set LPA on LOONGSON3 config3 */
-	mfc0	t0, $16, 3
+	mfc0	t0, CP0_CONFIG3
 	or	t0, (0x1 << 7)
-	mtc0	t0, $16, 3
+	mtc0	t0, CP0_CONFIG3
 	/* Set ELPA on LOONGSON3 pagegrain */
-	mfc0	t0, $5, 1
+	mfc0	t0, CP0_PAGEGRAIN
 	or	t0, (0x1 << 29)
-	mtc0	t0, $5, 1
+	mtc0	t0, CP0_PAGEGRAIN
 #ifdef CONFIG_LOONGSON3_ENHANCEMENT
 	/* Enable STFill Buffer */
-	mfc0	t0, $16, 6
+	mfc0	t0, CP0_CONFIG6
 	or	t0, 0x100
-	mtc0	t0, $16, 6
+	mtc0	t0, CP0_CONFIG6
 #endif
 	_ehb
 	.set	pop
@@ -45,18 +45,18 @@
 	.set	push
 	.set	mips64
 	/* Set LPA on LOONGSON3 config3 */
-	mfc0	t0, $16, 3
+	mfc0	t0, CP0_CONFIG3
 	or	t0, (0x1 << 7)
-	mtc0	t0, $16, 3
+	mtc0	t0, CP0_CONFIG3
 	/* Set ELPA on LOONGSON3 pagegrain */
-	mfc0	t0, $5, 1
+	mfc0	t0, CP0_PAGEGRAIN
 	or	t0, (0x1 << 29)
-	mtc0	t0, $5, 1
+	mtc0	t0, CP0_PAGEGRAIN
 #ifdef CONFIG_LOONGSON3_ENHANCEMENT
 	/* Enable STFill Buffer */
-	mfc0	t0, $16, 6
+	mfc0	t0, CP0_CONFIG6
 	or	t0, 0x100
-	mtc0	t0, $16, 6
+	mtc0	t0, CP0_CONFIG6
 #endif
 	_ehb
 	.set	pop
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 0b58864..69307b3 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -51,6 +51,7 @@
 #define CP0_GLOBALNUMBER $3, 1
 #define CP0_CONTEXT $4
 #define CP0_PAGEMASK $5
+#define CP0_PAGEGRAIN $5, 1
 #define CP0_SEGCTL0 $5, 2
 #define CP0_SEGCTL1 $5, 3
 #define CP0_SEGCTL2 $5, 4
@@ -77,6 +78,7 @@
 #define CP0_CONFIG $16
 #define CP0_CONFIG3 $16, 3
 #define CP0_CONFIG5 $16, 5
+#define CP0_CONFIG6 $16, 6
 #define CP0_LLADDR $17
 #define CP0_WATCHLO $18
 #define CP0_WATCHHI $19
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH V2 03/12] MIPS: Loongson-3: Enable Store Fill Buffer at runtime
  2018-01-27  3:12 [PATCH V2 00/12] MIPS: Loongson: new features and improvements Huacai Chen
  2018-01-27  3:12 ` [PATCH V2 01/12] MIPS: Loongson: Add Loongson-3A R3.1 basic support Huacai Chen
  2018-01-27  3:12 ` [PATCH V2 02/12] MIPS: Loongson64: Define and use some CP0 registers Huacai Chen
@ 2018-01-27  3:12 ` Huacai Chen
  2018-02-15 12:43   ` James Hogan
  2018-01-27  3:19 ` [PATCH V2 04/12] MIPS: c-r4k: Add r4k_blast_scache_node for Loongson-3 Huacai Chen
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 42+ messages in thread
From: Huacai Chen @ 2018-01-27  3:12 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen

New Loongson-3 (Loongson-3A R2, Loongson-3A R3, and newer) has SFB
(Store Fill Buffer) which can improve the performance of memory access.
Now, SFB enablement is controlled by CONFIG_LOONGSON3_ENHANCEMENT, and
the generic kernel has no benefit from SFB (even it is running on a new
Loongson-3 machine). With this patch, we can enable SFB at runtime by
detecting the CPU type (the expense is war_io_reorder_wmb() will always
be a 'sync', which will hurt the performance of old Loongson-3).

Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/include/asm/io.h                                |  2 +-
 arch/mips/include/asm/mach-loongson64/kernel-entry-init.h | 14 ++++++++++----
 2 files changed, 11 insertions(+), 5 deletions(-)

diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 0cbf3af..5146efa 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -304,7 +304,7 @@ static inline void iounmap(const volatile void __iomem *addr)
 #undef __IS_KSEG1
 }
 
-#if defined(CONFIG_CPU_CAVIUM_OCTEON) || defined(CONFIG_LOONGSON3_ENHANCEMENT)
+#if defined(CONFIG_CPU_CAVIUM_OCTEON) || defined(CONFIG_CPU_LOONGSON3)
 #define war_io_reorder_wmb()		wmb()
 #else
 #define war_io_reorder_wmb()		do { } while (0)
diff --git a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h
index 3127391..4b7f58a 100644
--- a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h
+++ b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h
@@ -26,12 +26,15 @@
 	mfc0	t0, CP0_PAGEGRAIN
 	or	t0, (0x1 << 29)
 	mtc0	t0, CP0_PAGEGRAIN
-#ifdef CONFIG_LOONGSON3_ENHANCEMENT
 	/* Enable STFill Buffer */
+	mfc0	t0, CP0_PRID
+	andi	t0, 0xffff
+	slti	t0, 0x6308
+	bnez	t0, 1f
 	mfc0	t0, CP0_CONFIG6
 	or	t0, 0x100
 	mtc0	t0, CP0_CONFIG6
-#endif
+1:
 	_ehb
 	.set	pop
 #endif
@@ -52,12 +55,15 @@
 	mfc0	t0, CP0_PAGEGRAIN
 	or	t0, (0x1 << 29)
 	mtc0	t0, CP0_PAGEGRAIN
-#ifdef CONFIG_LOONGSON3_ENHANCEMENT
 	/* Enable STFill Buffer */
+	mfc0	t0, CP0_PRID
+	andi	t0, 0xffff
+	slti	t0, 0x6308
+	bnez	t0, 1f
 	mfc0	t0, CP0_CONFIG6
 	or	t0, 0x100
 	mtc0	t0, CP0_CONFIG6
-#endif
+1:
 	_ehb
 	.set	pop
 #endif
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH V2 04/12] MIPS: c-r4k: Add r4k_blast_scache_node for Loongson-3
  2018-01-27  3:12 [PATCH V2 00/12] MIPS: Loongson: new features and improvements Huacai Chen
                   ` (2 preceding siblings ...)
  2018-01-27  3:12 ` [PATCH V2 03/12] MIPS: Loongson-3: Enable Store Fill Buffer at runtime Huacai Chen
@ 2018-01-27  3:19 ` Huacai Chen
  2018-02-19 22:19   ` James Hogan
  2018-01-27  3:20 ` [PATCH V2 05/12] MIPS: Loongson fix name confict - MEM_RESERVED Huacai Chen
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 42+ messages in thread
From: Huacai Chen @ 2018-01-27  3:19 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen, # 3 . 15+

For multi-node Loongson-3 (NUMA configuration), r4k_blast_scache() can
only flush Node-0's scache. So we add r4k_blast_scache_node() by using
(CAC_BASE | (node_id << NODE_ADDRSPACE_SHIFT)) instead of CKSEG0 as the
start address.

Cc: <stable@vger.kernel.org> # 3.15+
Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/include/asm/r4kcache.h | 34 ++++++++++++++++++++++++++++++++
 arch/mips/mm/c-r4k.c             | 42 +++++++++++++++++++++++++++++++++-------
 2 files changed, 69 insertions(+), 7 deletions(-)

diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h
index 7f12d7e..c1f2806 100644
--- a/arch/mips/include/asm/r4kcache.h
+++ b/arch/mips/include/asm/r4kcache.h
@@ -747,4 +747,38 @@ __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, , )
 __BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, , )
 __BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, , )
 
+#ifndef pa_to_nid
+#define pa_to_nid(addr) 0
+#endif
+
+#ifndef NODE_ADDRSPACE_SHIFT
+#define nid_to_addrbase(nid) 0
+#else
+#define nid_to_addrbase(nid) (nid << NODE_ADDRSPACE_SHIFT)
+#endif
+
+#define __BUILD_BLAST_CACHE_NODE(pfx, desc, indexop, hitop, lsize)	\
+static inline void blast_##pfx##cache##lsize##_node(long node)		\
+{									\
+	unsigned long start = CAC_BASE | nid_to_addrbase(node);		\
+	unsigned long end = start + current_cpu_data.desc.waysize;	\
+	unsigned long ws_inc = 1UL << current_cpu_data.desc.waybit;	\
+	unsigned long ws_end = current_cpu_data.desc.ways <<		\
+			       current_cpu_data.desc.waybit;		\
+	unsigned long ws, addr;						\
+									\
+	__##pfx##flush_prologue						\
+									\
+	for (ws = 0; ws < ws_end; ws += ws_inc)				\
+		for (addr = start; addr < end; addr += lsize * 32)	\
+			cache##lsize##_unroll32(addr|ws, indexop);	\
+									\
+	__##pfx##flush_epilogue						\
+}
+
+__BUILD_BLAST_CACHE_NODE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 16)
+__BUILD_BLAST_CACHE_NODE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 32)
+__BUILD_BLAST_CACHE_NODE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 64)
+__BUILD_BLAST_CACHE_NODE(s, scache, Index_Writeback_Inv_SD, Hit_Writeback_Inv_SD, 128)
+
 #endif /* _ASM_R4KCACHE_H */
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
index 6f534b20..155f5f5 100644
--- a/arch/mips/mm/c-r4k.c
+++ b/arch/mips/mm/c-r4k.c
@@ -459,11 +459,28 @@ static void r4k_blast_scache_setup(void)
 		r4k_blast_scache = blast_scache128;
 }
 
+static void (*r4k_blast_scache_node)(long node);
+
+static void r4k_blast_scache_node_setup(void)
+{
+	unsigned long sc_lsize = cpu_scache_line_size();
+
+	if (current_cpu_type() != CPU_LOONGSON3)
+		r4k_blast_scache_node = (void *)cache_noop;
+	else if (sc_lsize == 16)
+		r4k_blast_scache_node = blast_scache16_node;
+	else if (sc_lsize == 32)
+		r4k_blast_scache_node = blast_scache32_node;
+	else if (sc_lsize == 64)
+		r4k_blast_scache_node = blast_scache64_node;
+	else if (sc_lsize == 128)
+		r4k_blast_scache_node = blast_scache128_node;
+}
+
 static inline void local_r4k___flush_cache_all(void * args)
 {
 	switch (current_cpu_type()) {
 	case CPU_LOONGSON2:
-	case CPU_LOONGSON3:
 	case CPU_R4000SC:
 	case CPU_R4000MC:
 	case CPU_R4400SC:
@@ -480,6 +497,10 @@ static inline void local_r4k___flush_cache_all(void * args)
 		r4k_blast_scache();
 		break;
 
+	case CPU_LOONGSON3:
+		r4k_blast_scache_node(get_ebase_cpunum() >> 2);
+		break;
+
 	case CPU_BMIPS5000:
 		r4k_blast_scache();
 		__sync();
@@ -839,9 +860,12 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
 
 	preempt_disable();
 	if (cpu_has_inclusive_pcaches) {
-		if (size >= scache_size)
-			r4k_blast_scache();
-		else
+		if (size >= scache_size) {
+			if (current_cpu_type() != CPU_LOONGSON3)
+				r4k_blast_scache();
+			else
+				r4k_blast_scache_node(pa_to_nid(addr));
+		} else
 			blast_scache_range(addr, addr + size);
 		preempt_enable();
 		__sync();
@@ -872,9 +896,12 @@ static void r4k_dma_cache_inv(unsigned long addr, unsigned long size)
 
 	preempt_disable();
 	if (cpu_has_inclusive_pcaches) {
-		if (size >= scache_size)
-			r4k_blast_scache();
-		else {
+		if (size >= scache_size) {
+			if (current_cpu_type() != CPU_LOONGSON3)
+				r4k_blast_scache();
+			else
+				r4k_blast_scache_node(pa_to_nid(addr));
+		} else {
 			/*
 			 * There is no clearly documented alignment requirement
 			 * for the cache instruction on MIPS processors and
@@ -1905,6 +1932,7 @@ void r4k_cache_init(void)
 	r4k_blast_scache_page_setup();
 	r4k_blast_scache_page_indexed_setup();
 	r4k_blast_scache_setup();
+	r4k_blast_scache_node_setup();
 #ifdef CONFIG_EVA
 	r4k_blast_dcache_user_page_setup();
 	r4k_blast_icache_user_page_setup();
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH V2 05/12] MIPS: Loongson fix name confict - MEM_RESERVED
  2018-01-27  3:12 [PATCH V2 00/12] MIPS: Loongson: new features and improvements Huacai Chen
                   ` (3 preceding siblings ...)
  2018-01-27  3:19 ` [PATCH V2 04/12] MIPS: c-r4k: Add r4k_blast_scache_node for Loongson-3 Huacai Chen
@ 2018-01-27  3:20 ` Huacai Chen
  2018-01-27  3:21 ` [PATCH V2 06/12] MIPS: Ensure pmd_present() returns false after pmd_mknotpresent() Huacai Chen
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 42+ messages in thread
From: Huacai Chen @ 2018-01-27  3:20 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen, # 3 . 15+,
	YunQiang Su

MEM_RESERVED is used as a value of enum mem_type in include/linux/
edac.h. This will make failure to build for Loongson in some case:
for example with CONFIG_RAS enabled.

So here rename MEM_RESERVED to SYSTEM_RAM_RESERVED in Loongson code.

Cc: <stable@vger.kernel.org> # 3.15+
Reviewed-by: James Hogan <jhogan@kernel.org>
Signed-off-by: YunQiang Su <yunqiang.su@imgtec.com>
Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/include/asm/mach-loongson64/boot_param.h | 2 +-
 arch/mips/loongson64/common/mem.c                  | 2 +-
 arch/mips/loongson64/loongson-3/numa.c             | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h
index 4f69f08..8c286be 100644
--- a/arch/mips/include/asm/mach-loongson64/boot_param.h
+++ b/arch/mips/include/asm/mach-loongson64/boot_param.h
@@ -4,7 +4,7 @@
 
 #define SYSTEM_RAM_LOW		1
 #define SYSTEM_RAM_HIGH		2
-#define MEM_RESERVED		3
+#define SYSTEM_RAM_RESERVED	3
 #define PCI_IO			4
 #define PCI_MEM			5
 #define LOONGSON_CFG_REG	6
diff --git a/arch/mips/loongson64/common/mem.c b/arch/mips/loongson64/common/mem.c
index b01d524..c549e52 100644
--- a/arch/mips/loongson64/common/mem.c
+++ b/arch/mips/loongson64/common/mem.c
@@ -79,7 +79,7 @@ void __init prom_init_memory(void)
 					(u64)loongson_memmap->map[i].mem_size << 20,
 					BOOT_MEM_RAM);
 				break;
-			case MEM_RESERVED:
+			case SYSTEM_RAM_RESERVED:
 				add_memory_region(loongson_memmap->map[i].mem_start,
 					(u64)loongson_memmap->map[i].mem_size << 20,
 					BOOT_MEM_RESERVED);
diff --git a/arch/mips/loongson64/loongson-3/numa.c b/arch/mips/loongson64/loongson-3/numa.c
index f17ef52..9717106 100644
--- a/arch/mips/loongson64/loongson-3/numa.c
+++ b/arch/mips/loongson64/loongson-3/numa.c
@@ -166,7 +166,7 @@ static void __init szmem(unsigned int node)
 			memblock_add_node(PFN_PHYS(start_pfn),
 				PFN_PHYS(end_pfn - start_pfn), node);
 			break;
-		case MEM_RESERVED:
+		case SYSTEM_RAM_RESERVED:
 			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);
 			add_memory_region((node_id << 44) + mem_start,
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH V2 06/12] MIPS: Ensure pmd_present() returns false after pmd_mknotpresent()
  2018-01-27  3:12 [PATCH V2 00/12] MIPS: Loongson: new features and improvements Huacai Chen
                   ` (4 preceding siblings ...)
  2018-01-27  3:20 ` [PATCH V2 05/12] MIPS: Loongson fix name confict - MEM_RESERVED Huacai Chen
@ 2018-01-27  3:21 ` Huacai Chen
  2018-01-27  3:22 ` [PATCH V2 07/12] MIPS: Add __cpu_full_name[] to make CPU names more human-readable Huacai Chen
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 42+ messages in thread
From: Huacai Chen @ 2018-01-27  3:21 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen, # 3 . 8+

This patch is borrowed from ARM64 to ensure pmd_present() returns false
after pmd_mknotpresent(). This is needed for THP.

Cc: <stable@vger.kernel.org> # 3.8+
References: 5bb1cc0ff9a6 ("arm64: Ensure pmd_present() returns false after pmd_mknotpresent()")
Reviewed-by: James Hogan <jhogan@kernel.org>
Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/include/asm/pgtable-64.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/mips/include/asm/pgtable-64.h b/arch/mips/include/asm/pgtable-64.h
index 0036ea0..93a9dce 100644
--- a/arch/mips/include/asm/pgtable-64.h
+++ b/arch/mips/include/asm/pgtable-64.h
@@ -265,6 +265,11 @@ static inline int pmd_bad(pmd_t pmd)
 
 static inline int pmd_present(pmd_t pmd)
 {
+#ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT
+	if (unlikely(pmd_val(pmd) & _PAGE_HUGE))
+		return pmd_val(pmd) & _PAGE_PRESENT;
+#endif
+
 	return pmd_val(pmd) != (unsigned long) invalid_pte_table;
 }
 
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH V2 07/12] MIPS: Add __cpu_full_name[] to make CPU names more human-readable
  2018-01-27  3:12 [PATCH V2 00/12] MIPS: Loongson: new features and improvements Huacai Chen
                   ` (5 preceding siblings ...)
  2018-01-27  3:21 ` [PATCH V2 06/12] MIPS: Ensure pmd_present() returns false after pmd_mknotpresent() Huacai Chen
@ 2018-01-27  3:22 ` Huacai Chen
  2018-01-27  3:22   ` [PATCH V2 08/12] MIPS: Align kernel load address to 64KB Huacai Chen
  2018-01-27  3:22   ` [PATCH V2 09/12] MIPS: Loongson: Add kexec/kdump support Huacai Chen
  2018-01-27  3:22 ` [PATCH V2 10/12] MIPS: Loongson: Make CPUFreq usable for Loongson-3 Huacai Chen
  2018-02-15 11:05 ` [PATCH V2 00/12] MIPS: Loongson: new features and improvements James Hogan
  8 siblings, 2 replies; 42+ messages in thread
From: Huacai Chen @ 2018-01-27  3:22 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen

In /proc/cpuinfo, we keep "cpu model" as is, since GCC should use it
for -march=native. Besides, we add __cpu_full_name[] to describe the
processor in a more human-readable manner. The full name is displayed
as "model name" in cpuinfo, which is needed by some userspace tools
such as gnome-system-monitor.

The CPU frequency in "model name" is the default value (highest), and
there is also a "CPU MHz" whose value can be changed by cpufreq.

This is only used by Loongson now (ICT is dropped in cpu name, and cpu
name can be overwritten by BIOS).

Reviewed-by: James Hogan <jhogan@kernel.org>
Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/include/asm/cpu-info.h                   |  2 ++
 arch/mips/include/asm/mach-loongson64/boot_param.h |  1 +
 arch/mips/include/asm/time.h                       |  2 ++
 arch/mips/kernel/cpu-probe.c                       | 25 ++++++++++++++++------
 arch/mips/kernel/proc.c                            |  7 ++++++
 arch/mips/kernel/time.c                            |  2 ++
 arch/mips/loongson64/common/env.c                  | 13 +++++++++++
 arch/mips/loongson64/loongson-3/smp.c              |  1 +
 arch/mips/loongson64/loongson-3/smp.h              |  1 +
 9 files changed, 48 insertions(+), 6 deletions(-)

diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h
index a41059d..6128a37 100644
--- a/arch/mips/include/asm/cpu-info.h
+++ b/arch/mips/include/asm/cpu-info.h
@@ -116,7 +116,9 @@ extern void cpu_probe(void);
 extern void cpu_report(void);
 
 extern const char *__cpu_name[];
+extern const char *__cpu_full_name[];
 #define cpu_name_string()	__cpu_name[raw_smp_processor_id()]
+#define cpu_full_name_string()	__cpu_full_name[raw_smp_processor_id()]
 
 struct seq_file;
 struct notifier_block;
diff --git a/arch/mips/include/asm/mach-loongson64/boot_param.h b/arch/mips/include/asm/mach-loongson64/boot_param.h
index 8c286be..1d69e4c 100644
--- a/arch/mips/include/asm/mach-loongson64/boot_param.h
+++ b/arch/mips/include/asm/mach-loongson64/boot_param.h
@@ -58,6 +58,7 @@ struct efi_cpuinfo_loongson {
 	u16 reserved_cores_mask;
 	u32 cpu_clock_freq; /* cpu_clock */
 	u32 nr_cpus;
+	char cpuname[64];
 } __packed;
 
 #define MAX_UARTS 64
diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h
index 17d4cd2..efbfc48 100644
--- a/arch/mips/include/asm/time.h
+++ b/arch/mips/include/asm/time.h
@@ -35,6 +35,8 @@ extern int rtc_mips_set_mmss(unsigned long);
  */
 extern void plat_time_init(void);
 
+extern unsigned int mips_cpu_frequency;
+
 /*
  * mips_hpt_frequency - must be set if you intend to use an R4k-compatible
  * counter as a timer interrupt source.
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index 83317d6..b7acf35 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -1461,30 +1461,40 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
 		switch (c->processor_id & PRID_REV_MASK) {
 		case PRID_REV_LOONGSON2E:
 			c->cputype = CPU_LOONGSON2;
-			__cpu_name[cpu] = "ICT Loongson-2";
+			__cpu_name[cpu] = "Loongson-2";
 			set_elf_platform(cpu, "loongson2e");
 			set_isa(c, MIPS_CPU_ISA_III);
 			c->fpu_msk31 |= FPU_CSR_CONDX;
+			__cpu_full_name[cpu] = "Loongson-2E";
 			break;
 		case PRID_REV_LOONGSON2F:
 			c->cputype = CPU_LOONGSON2;
-			__cpu_name[cpu] = "ICT Loongson-2";
+			__cpu_name[cpu] = "Loongson-2";
 			set_elf_platform(cpu, "loongson2f");
 			set_isa(c, MIPS_CPU_ISA_III);
 			c->fpu_msk31 |= FPU_CSR_CONDX;
+			__cpu_full_name[cpu] = "Loongson-2F";
 			break;
 		case PRID_REV_LOONGSON3A_R1:
 			c->cputype = CPU_LOONGSON3;
-			__cpu_name[cpu] = "ICT Loongson-3";
+			__cpu_name[cpu] = "Loongson-3";
 			set_elf_platform(cpu, "loongson3a");
 			set_isa(c, MIPS_CPU_ISA_M64R1);
+			__cpu_full_name[cpu] = "Loongson-3A R1 (Loongson-3A1000)";
 			break;
 		case PRID_REV_LOONGSON3B_R1:
+			c->cputype = CPU_LOONGSON3;
+			__cpu_name[cpu] = "Loongson-3";
+			set_elf_platform(cpu, "loongson3b");
+			set_isa(c, MIPS_CPU_ISA_M64R1);
+			__cpu_full_name[cpu] = "Loongson-3B R1 (Loongson-3B1000)";
+			break;
 		case PRID_REV_LOONGSON3B_R2:
 			c->cputype = CPU_LOONGSON3;
-			__cpu_name[cpu] = "ICT Loongson-3";
+			__cpu_name[cpu] = "Loongson-3";
 			set_elf_platform(cpu, "loongson3b");
 			set_isa(c, MIPS_CPU_ISA_M64R1);
+			__cpu_full_name[cpu] = "Loongson-3B R2 (Loongson-3B1500)";
 			break;
 		}
 
@@ -1830,16 +1840,18 @@ static inline void cpu_probe_loongson(struct cpuinfo_mips *c, unsigned int cpu)
 		switch (c->processor_id & PRID_REV_MASK) {
 		case PRID_REV_LOONGSON3A_R2:
 			c->cputype = CPU_LOONGSON3;
-			__cpu_name[cpu] = "ICT Loongson-3";
+			__cpu_name[cpu] = "Loongson-3";
 			set_elf_platform(cpu, "loongson3a");
 			set_isa(c, MIPS_CPU_ISA_M64R2);
+			__cpu_full_name[cpu] = "Loongson-3A R2 (Loongson-3A2000)";
 			break;
 		case PRID_REV_LOONGSON3A_R3_0:
 		case PRID_REV_LOONGSON3A_R3_1:
 			c->cputype = CPU_LOONGSON3;
-			__cpu_name[cpu] = "ICT Loongson-3";
+			__cpu_name[cpu] = "Loongson-3";
 			set_elf_platform(cpu, "loongson3a");
 			set_isa(c, MIPS_CPU_ISA_M64R2);
+			__cpu_full_name[cpu] = "Loongson-3A R3 (Loongson-3A3000)";
 			break;
 		}
 
@@ -1959,6 +1971,7 @@ EXPORT_SYMBOL(__ua_limit);
 #endif
 
 const char *__cpu_name[NR_CPUS];
+const char *__cpu_full_name[NR_CPUS];
 const char *__elf_platform;
 
 void cpu_probe(void)
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c
index b2de408..b4c31b0 100644
--- a/arch/mips/kernel/proc.c
+++ b/arch/mips/kernel/proc.c
@@ -15,6 +15,7 @@
 #include <asm/mipsregs.h>
 #include <asm/processor.h>
 #include <asm/prom.h>
+#include <asm/time.h>
 
 unsigned int vced_count, vcei_count;
 
@@ -63,6 +64,12 @@ static int show_cpuinfo(struct seq_file *m, void *v)
 	seq_printf(m, fmt, __cpu_name[n],
 		      (version >> 4) & 0x0f, version & 0x0f,
 		      (fp_vers >> 4) & 0x0f, fp_vers & 0x0f);
+	if (__cpu_full_name[n])
+		seq_printf(m, "model name\t\t: %s\n", __cpu_full_name[n]);
+	if (mips_cpu_frequency)
+		seq_printf(m, "CPU MHz\t\t\t: %u.%02u\n",
+			      mips_cpu_frequency / 1000000,
+			      (mips_cpu_frequency / 10000) % 100);
 	seq_printf(m, "BogoMIPS\t\t: %u.%02u\n",
 		      cpu_data[n].udelay_val / (500000/HZ),
 		      (cpu_data[n].udelay_val / (5000/HZ)) % 100);
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c
index a6ebc81..5c096c2 100644
--- a/arch/mips/kernel/time.c
+++ b/arch/mips/kernel/time.c
@@ -69,6 +69,8 @@ EXPORT_SYMBOL(perf_irq);
  * 2) calculate a couple of cached variables for later usage
  */
 
+unsigned int mips_cpu_frequency;
+EXPORT_SYMBOL_GPL(mips_cpu_frequency);
 unsigned int mips_hpt_frequency;
 EXPORT_SYMBOL_GPL(mips_hpt_frequency);
 
diff --git a/arch/mips/loongson64/common/env.c b/arch/mips/loongson64/common/env.c
index 8f68ee0..2928ac5 100644
--- a/arch/mips/loongson64/common/env.c
+++ b/arch/mips/loongson64/common/env.c
@@ -18,6 +18,7 @@
  * option) any later version.
  */
 #include <linux/export.h>
+#include <asm/time.h>
 #include <asm/bootinfo.h>
 #include <loongson.h>
 #include <boot_param.h>
@@ -25,6 +26,7 @@
 
 u32 cpu_clock_freq;
 EXPORT_SYMBOL(cpu_clock_freq);
+char cpu_full_name[64];
 struct efi_memory_map_loongson *loongson_memmap;
 struct loongson_system_configuration loongson_sysconf;
 
@@ -45,6 +47,7 @@ do {									\
 void __init prom_init_env(void)
 {
 	/* pmon passes arguments in 32bit pointers */
+	char freq[12];
 	unsigned int processor_id;
 
 #ifndef CONFIG_LEFI_FIRMWARE_INTERFACE
@@ -151,6 +154,10 @@ void __init prom_init_env(void)
 	loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus +
 		loongson_sysconf.cores_per_node - 1) /
 		loongson_sysconf.cores_per_node;
+	if (!strncmp(ecpu->cpuname, "Loongson", 8))
+		strncpy(cpu_full_name, ecpu->cpuname, sizeof(cpu_full_name));
+	if (cpu_full_name[0] == 0)
+		strncpy(cpu_full_name, __cpu_full_name[0], sizeof(cpu_full_name));
 
 	loongson_sysconf.pci_mem_start_addr = eirq_source->pci_mem_start_addr;
 	loongson_sysconf.pci_mem_end_addr = eirq_source->pci_mem_end_addr;
@@ -211,5 +218,11 @@ void __init prom_init_env(void)
 			break;
 		}
 	}
+	mips_cpu_frequency = cpu_clock_freq;
 	pr_info("CpuClock = %u\n", cpu_clock_freq);
+
+	/* Append default cpu frequency with round-off */
+	sprintf(freq, " @ %uMHz", (cpu_clock_freq + 500000) / 1000000);
+	strncat(cpu_full_name, freq, sizeof(cpu_full_name));
+	__cpu_full_name[0] = cpu_full_name;
 }
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c
index fea95d0..470e9c1 100644
--- a/arch/mips/loongson64/loongson-3/smp.c
+++ b/arch/mips/loongson64/loongson-3/smp.c
@@ -340,6 +340,7 @@ static void loongson3_init_secondary(void)
 		initcount = core0_c0count[cpu] + i/2;
 
 	write_c0_count(initcount);
+	__cpu_full_name[cpu] = cpu_full_name;
 }
 
 static void loongson3_smp_finish(void)
diff --git a/arch/mips/loongson64/loongson-3/smp.h b/arch/mips/loongson64/loongson-3/smp.h
index 957bde8..6112d9d 100644
--- a/arch/mips/loongson64/loongson-3/smp.h
+++ b/arch/mips/loongson64/loongson-3/smp.h
@@ -3,6 +3,7 @@
 #define __LOONGSON_SMP_H_
 
 /* for Loongson-3 smp support */
+extern char cpu_full_name[64];
 extern unsigned long long smp_group[4];
 
 /* 4 groups(nodes) in maximum in numa case */
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
  2018-01-27  3:22 ` [PATCH V2 07/12] MIPS: Add __cpu_full_name[] to make CPU names more human-readable Huacai Chen
@ 2018-01-27  3:22   ` Huacai Chen
  2018-02-19 23:07     ` James Hogan
  2018-01-27  3:22   ` [PATCH V2 09/12] MIPS: Loongson: Add kexec/kdump support Huacai Chen
  1 sibling, 1 reply; 42+ messages in thread
From: Huacai Chen @ 2018-01-27  3:22 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen

KEXEC assume kernel align to PAGE_SIZE, and 64KB is the largest
PAGE_SIZE.

Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/boot/compressed/calc_vmlinuz_load_addr.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c b/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c
index 37fe58c..1dcaef4 100644
--- a/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c
+++ b/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c
@@ -45,11 +45,10 @@ int main(int argc, char *argv[])
 	vmlinuz_load_addr = vmlinux_load_addr + vmlinux_size;
 
 	/*
-	 * Align with 16 bytes: "greater than that used for any standard data
-	 * types by a MIPS compiler." -- See MIPS Run Linux (Second Edition).
+	 * Align with 64KB: KEXEC assume kernel align to PAGE_SIZE
 	 */
 
-	vmlinuz_load_addr += (16 - vmlinux_size % 16);
+	vmlinuz_load_addr += (65536 - vmlinux_size % 65536);
 
 	printf("0x%llx\n", vmlinuz_load_addr);
 
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH V2 09/12] MIPS: Loongson: Add kexec/kdump support
  2018-01-27  3:22 ` [PATCH V2 07/12] MIPS: Add __cpu_full_name[] to make CPU names more human-readable Huacai Chen
  2018-01-27  3:22   ` [PATCH V2 08/12] MIPS: Align kernel load address to 64KB Huacai Chen
@ 2018-01-27  3:22   ` Huacai Chen
  2018-02-19 23:54     ` James Hogan
  1 sibling, 1 reply; 42+ messages in thread
From: Huacai Chen @ 2018-01-27  3:22 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen

Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/kernel/relocate_kernel.S    |  30 +++++++++
 arch/mips/loongson64/common/env.c     |   8 +++
 arch/mips/loongson64/common/reset.c   | 119 ++++++++++++++++++++++++++++++++++
 arch/mips/loongson64/loongson-3/smp.c |   4 ++
 4 files changed, 161 insertions(+)

diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S
index c6bbf21..e73edc7 100644
--- a/arch/mips/kernel/relocate_kernel.S
+++ b/arch/mips/kernel/relocate_kernel.S
@@ -135,6 +135,36 @@ LEAF(kexec_smp_wait)
 #else
 	sync
 #endif
+
+#ifdef CONFIG_CPU_LOONGSON3
+	/* s0:prid s1:initfn */
+	/* t0:base t1:cpuid t2:node t3:core t9:count */
+	mfc0  t1, $15, 1
+	andi  t1, 0x3ff
+	dli   t0, 0x900000003ff01000
+	andi  t3, t1, 0x3
+	sll   t3, 8               /* get core id */
+	or    t0, t0, t3
+	andi  t2, t1, 0xc
+	dsll  t2, 42              /* get node id */
+	or    t0, t0, t2
+	mfc0  s0, $15, 0
+	andi  s0, s0, 0xf
+	blt   s0, 0x6, 1f         /* Loongson-3A1000 */
+	bgt   s0, 0x7, 1f         /* Loongson-3A2000/3A3000 */
+	dsrl  t2, 30              /* Loongson-3B1000/3B1500 need bit15:14 */
+	or    t0, t0, t2
+1:	li    t9, 0x100           /* wait for init loop */
+2:	addiu t9, -1              /* limit mailbox access */
+	bnez  t9, 2b
+	ld    s1, 0x20(t0)        /* get PC via mailbox */
+	beqz  s1, 1b
+	ld    sp, 0x28(t0)        /* get SP via mailbox */
+	ld    gp, 0x30(t0)        /* get GP via mailbox */
+	ld    a1, 0x38(t0)
+	jr    s1                  /* jump to initial PC */
+#endif
+
 	j		s1
 	END(kexec_smp_wait)
 #endif
diff --git a/arch/mips/loongson64/common/env.c b/arch/mips/loongson64/common/env.c
index 2928ac5..990a2d69 100644
--- a/arch/mips/loongson64/common/env.c
+++ b/arch/mips/loongson64/common/env.c
@@ -72,6 +72,7 @@ void __init prom_init_env(void)
 
 	pr_info("memsize=%u, highmemsize=%u\n", memsize, highmemsize);
 #else
+	int i;
 	struct boot_params *boot_p;
 	struct loongson_params *loongson_p;
 	struct system_loongson *esys;
@@ -149,6 +150,13 @@ void __init prom_init_env(void)
 	loongson_sysconf.nr_cpus = ecpu->nr_cpus;
 	loongson_sysconf.boot_cpu_id = ecpu->cpu_startup_core_id;
 	loongson_sysconf.reserved_cpus_mask = ecpu->reserved_cores_mask;
+#ifdef CONFIG_KEXEC
+	loongson_sysconf.boot_cpu_id = get_ebase_cpunum();
+	for (i = 0; i < loongson_sysconf.boot_cpu_id; i++)
+		loongson_sysconf.reserved_cpus_mask |= (1<<i);
+	pr_info("Boot CPU ID is being fixed from %d to %d\n",
+		ecpu->cpu_startup_core_id, loongson_sysconf.boot_cpu_id);
+#endif
 	if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0)
 		loongson_sysconf.nr_cpus = NR_CPUS;
 	loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus +
diff --git a/arch/mips/loongson64/common/reset.c b/arch/mips/loongson64/common/reset.c
index a60715e..5f65a4e 100644
--- a/arch/mips/loongson64/common/reset.c
+++ b/arch/mips/loongson64/common/reset.c
@@ -11,9 +11,14 @@
  */
 #include <linux/init.h>
 #include <linux/pm.h>
+#include <linux/cpu.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include <linux/kexec.h>
 
 #include <asm/idle.h>
 #include <asm/reboot.h>
+#include <asm/bootinfo.h>
 
 #include <loongson.h>
 #include <boot_param.h>
@@ -80,12 +85,126 @@ static void loongson_halt(void)
 	}
 }
 
+#ifdef CONFIG_KEXEC
+
+/* 0X80000000~0X80200000 is safe */
+#define MAX_ARGS	64
+#define KEXEC_CTRL_CODE	0XFFFFFFFF80100000UL
+#define KEXEC_ARGV_ADDR	0XFFFFFFFF80108000UL
+#define KEXEC_ARGV_SIZE	3060
+#define KEXEC_ENVP_SIZE	4500
+
+void *kexec_argv;
+void *kexec_envp;
+extern const size_t relocate_new_kernel_size;
+
+static int loongson_kexec_prepare(struct kimage *image)
+{
+	int i, argc = 0;
+	unsigned int *argv;
+	char *str, *ptr, *bootloader = "kexec";
+
+	/* argv at offset 0, argv[] at offset KEXEC_ARGV_SIZE/2 */
+	argv = (unsigned int *)kexec_argv;
+	argv[argc++] = (unsigned int)(KEXEC_ARGV_ADDR + KEXEC_ARGV_SIZE/2);
+
+	for (i = 0; i < image->nr_segments; i++) {
+		if (!strncmp(bootloader, (char *)image->segment[i].buf,
+				strlen(bootloader))) {
+			/*
+			 * convert command line string to array
+			 * of parameters (as bootloader does).
+			 */
+			int offt;
+			memcpy(kexec_argv + KEXEC_ARGV_SIZE/2, image->segment[i].buf, KEXEC_ARGV_SIZE/2);
+			str = (char *)kexec_argv + KEXEC_ARGV_SIZE/2;
+			ptr = strchr(str, ' ');
+
+			while (ptr && (argc < MAX_ARGS)) {
+				*ptr = '\0';
+				if (ptr[1] != ' ') {
+					offt = (int)(ptr - str + 1);
+					argv[argc] = KEXEC_ARGV_ADDR + KEXEC_ARGV_SIZE/2 + offt;
+					argc++;
+				}
+				ptr = strchr(ptr + 1, ' ');
+			}
+			break;
+		}
+	}
+
+	kexec_args[0] = argc;
+	kexec_args[1] = fw_arg1;
+	kexec_args[2] = fw_arg2;
+	image->control_code_page = virt_to_page((void *)KEXEC_CTRL_CODE);
+
+	return 0;
+}
+
+#ifdef CONFIG_SMP
+static void kexec_smp_down(void *ignored)
+{
+	int cpu = smp_processor_id();
+
+	local_irq_disable();
+	set_cpu_online(cpu, false);
+	while (!atomic_read(&kexec_ready_to_reboot))
+		cpu_relax();
+
+	asm volatile (
+	"	sync					\n"
+	"	synci	($0)				\n");
+
+	relocated_kexec_smp_wait(NULL);
+}
+#endif
+
+static void loongson_kexec_shutdown(void)
+{
+#ifdef CONFIG_SMP
+	int cpu;
+
+	for_each_possible_cpu(cpu)
+		if (!cpu_online(cpu))
+			cpu_up(cpu); /* Everyone should go to reboot_code_buffer */
+
+	smp_call_function(kexec_smp_down, NULL, 0);
+	smp_wmb();
+	while (num_online_cpus() > 1) {
+		mdelay(1);
+		cpu_relax();
+	}
+#endif
+	memcpy((void *)fw_arg1, kexec_argv, KEXEC_ARGV_SIZE);
+	memcpy((void *)fw_arg2, kexec_envp, KEXEC_ENVP_SIZE);
+}
+
+static void loongson_crash_shutdown(struct pt_regs *regs)
+{
+	default_machine_crash_shutdown(regs);
+	memcpy((void *)fw_arg1, kexec_argv, KEXEC_ARGV_SIZE);
+	memcpy((void *)fw_arg2, kexec_envp, KEXEC_ENVP_SIZE);
+}
+
+#endif
+
 static int __init mips_reboot_setup(void)
 {
 	_machine_restart = loongson_restart;
 	_machine_halt = loongson_halt;
 	pm_power_off = loongson_poweroff;
 
+#ifdef CONFIG_KEXEC
+	kexec_argv = kmalloc(KEXEC_ARGV_SIZE, GFP_KERNEL);
+	kexec_envp = kmalloc(KEXEC_ENVP_SIZE, GFP_KERNEL);
+	fw_arg1 = KEXEC_ARGV_ADDR;
+	memcpy(kexec_envp, (void *)fw_arg2, KEXEC_ENVP_SIZE);
+
+	_machine_kexec_prepare = loongson_kexec_prepare;
+	_machine_kexec_shutdown = loongson_kexec_shutdown;
+	_machine_crash_shutdown = loongson_crash_shutdown;
+#endif
+
 	return 0;
 }
 
diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c
index 470e9c1..1e21ac4 100644
--- a/arch/mips/loongson64/loongson-3/smp.c
+++ b/arch/mips/loongson64/loongson-3/smp.c
@@ -387,6 +387,10 @@ static void __init loongson3_smp_setup(void)
 	ipi_status0_regs_init();
 	ipi_en0_regs_init();
 	ipi_mailbox_buf_init();
+
+	for (i = 0; i < loongson_sysconf.nr_cpus; i++)
+		loongson3_ipi_write64(0, (void *)(ipi_mailbox_buf[i]+0x0));
+
 	cpu_set_core(&cpu_data[0],
 		     cpu_logical_map(0) % loongson_sysconf.cores_per_package);
 	cpu_data[0].package = cpu_logical_map(0) / loongson_sysconf.cores_per_package;
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH V2 10/12] MIPS: Loongson: Make CPUFreq usable for Loongson-3
  2018-01-27  3:12 [PATCH V2 00/12] MIPS: Loongson: new features and improvements Huacai Chen
                   ` (6 preceding siblings ...)
  2018-01-27  3:22 ` [PATCH V2 07/12] MIPS: Add __cpu_full_name[] to make CPU names more human-readable Huacai Chen
@ 2018-01-27  3:22 ` Huacai Chen
  2018-01-27  3:23   ` [PATCH V2 11/12] MIPS: Loongson-3: Fix CPU UART irq delivery problem Huacai Chen
                     ` (2 more replies)
  2018-02-15 11:05 ` [PATCH V2 00/12] MIPS: Loongson: new features and improvements James Hogan
  8 siblings, 3 replies; 42+ messages in thread
From: Huacai Chen @ 2018-01-27  3:22 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen

Loongson-3A/3B support frequency scaling. But due to hardware
limitation, Loongson-3A's frequency scaling is not independent for
each core, we suggest enable Loongson-3A's CPUFreq only when there is
one core online. Loongson-3B can adjust frequency independently for
each core, so it can be always enabled.

Each package has only one register (ChipConfig or FreqCtrl) to control
frequency, so we need spinlocks to protect register access for multi-
cores. However, we cannot use spinlock when a core becomes into "wait"
status (frequency = 0), so we only enable "wait" when there is one core
in a package online.

arch/mips/kernel/smp.c is modified to guarantee udelay_val has the
correct value while both CPU hotplug and CPUFreq are enabled.

Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/include/asm/mach-loongson64/loongson.h |   1 +
 arch/mips/kernel/smp.c                           |   3 +-
 arch/mips/loongson64/Kconfig                     |   1 +
 arch/mips/loongson64/common/platform.c           |  13 +-
 arch/mips/loongson64/loongson-3/Makefile         |   2 +-
 arch/mips/loongson64/loongson-3/clock.c          | 191 ++++++++++++++++++
 drivers/cpufreq/Kconfig                          |  13 ++
 drivers/cpufreq/Makefile                         |   1 +
 drivers/cpufreq/loongson3_cpufreq.c              | 236 +++++++++++++++++++++++
 9 files changed, 456 insertions(+), 5 deletions(-)
 create mode 100644 arch/mips/loongson64/loongson-3/clock.c
 create mode 100644 drivers/cpufreq/loongson3_cpufreq.c

diff --git a/arch/mips/include/asm/mach-loongson64/loongson.h b/arch/mips/include/asm/mach-loongson64/loongson.h
index d0ae5d5..845f6dd 100644
--- a/arch/mips/include/asm/mach-loongson64/loongson.h
+++ b/arch/mips/include/asm/mach-loongson64/loongson.h
@@ -277,6 +277,7 @@ extern u64 loongson_freqctrl[MAX_PACKAGES];
 #ifdef CONFIG_CPU_SUPPORTS_CPUFREQ
 #include <linux/cpufreq.h>
 extern struct cpufreq_frequency_table loongson2_clockmod_table[];
+extern struct cpufreq_frequency_table loongson3_clockmod_table[];
 #endif
 
 /*
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index d84b906..915eba5 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -370,7 +370,8 @@ asmlinkage void start_secondary(void)
 	calibrate_delay();
 	preempt_disable();
 	cpu = smp_processor_id();
-	cpu_data[cpu].udelay_val = loops_per_jiffy;
+	if (!cpu_data[cpu].udelay_val)
+		cpu_data[cpu].udelay_val = loops_per_jiffy;
 
 	cpumask_set_cpu(cpu, &cpu_coherent_mask);
 	notify_cpu_starting(cpu);
diff --git a/arch/mips/loongson64/Kconfig b/arch/mips/loongson64/Kconfig
index 0d249fc..e6b28ff 100644
--- a/arch/mips/loongson64/Kconfig
+++ b/arch/mips/loongson64/Kconfig
@@ -70,6 +70,7 @@ config LOONGSON_MACH3X
 	select CSRC_R4K
 	select CEVT_R4K
 	select CPU_HAS_WB
+	select HAVE_CLK
 	select HW_HAS_PCI
 	select ISA
 	select HT_PCI
diff --git a/arch/mips/loongson64/common/platform.c b/arch/mips/loongson64/common/platform.c
index 0ed3832..733a13f 100644
--- a/arch/mips/loongson64/common/platform.c
+++ b/arch/mips/loongson64/common/platform.c
@@ -17,15 +17,22 @@ static struct platform_device loongson2_cpufreq_device = {
 	.id = -1,
 };
 
-static int __init loongson2_cpufreq_init(void)
+static struct platform_device loongson3_cpufreq_device = {
+	.name = "loongson3_cpufreq",
+	.id = -1,
+};
+
+static int __init loongson_cpufreq_init(void)
 {
 	struct cpuinfo_mips *c = &current_cpu_data;
 
 	/* Only 2F revision and it's successors support CPUFreq */
-	if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_LOONGSON2F)
+	if ((c->processor_id & PRID_REV_MASK) == PRID_REV_LOONGSON2F)
 		return platform_device_register(&loongson2_cpufreq_device);
+	if ((c->processor_id & PRID_REV_MASK) >= PRID_REV_LOONGSON3A_R1)
+		return platform_device_register(&loongson3_cpufreq_device);
 
 	return -ENODEV;
 }
 
-arch_initcall(loongson2_cpufreq_init);
+arch_initcall(loongson_cpufreq_init);
diff --git a/arch/mips/loongson64/loongson-3/Makefile b/arch/mips/loongson64/loongson-3/Makefile
index 44bc148..7b035b7 100644
--- a/arch/mips/loongson64/loongson-3/Makefile
+++ b/arch/mips/loongson64/loongson-3/Makefile
@@ -1,7 +1,7 @@
 #
 # Makefile for Loongson-3 family machines
 #
-obj-y			+= irq.o cop2-ex.o platform.o acpi_init.o
+obj-y			+= irq.o cop2-ex.o platform.o acpi_init.o clock.o
 
 obj-$(CONFIG_SMP)	+= smp.o
 
diff --git a/arch/mips/loongson64/loongson-3/clock.c b/arch/mips/loongson64/loongson-3/clock.c
new file mode 100644
index 0000000..5b7edc5
--- /dev/null
+++ b/arch/mips/loongson64/loongson-3/clock.c
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2008 - 2014 Lemote Inc.
+ * Author: Yan Hua, yanh@lemote.com
+ *         Chen Huacai, chenhc@lemote.com
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/cpufreq.h>
+#include <linux/platform_device.h>
+
+#include <asm/clock.h>
+
+#include <loongson.h>
+
+static LIST_HEAD(clock_list);
+static DEFINE_SPINLOCK(clock_lock);
+static DEFINE_MUTEX(clock_list_sem);
+
+/* Minimum CLK support */
+enum {
+	DC_ZERO, DC_25PT = 2, DC_37PT, DC_50PT, DC_62PT, DC_75PT,
+	DC_87PT, DC_DISABLE, DC_RESV
+};
+
+struct cpufreq_frequency_table loongson3_clockmod_table[] = {
+	{0, DC_RESV, CPUFREQ_ENTRY_INVALID},
+	{0, DC_ZERO, CPUFREQ_ENTRY_INVALID},
+	{0, DC_25PT, 0},
+	{0, DC_37PT, 0},
+	{0, DC_50PT, 0},
+	{0, DC_62PT, 0},
+	{0, DC_75PT, 0},
+	{0, DC_87PT, 0},
+	{0, DC_DISABLE, 0},
+	{0, DC_RESV, CPUFREQ_TABLE_END},
+};
+EXPORT_SYMBOL_GPL(loongson3_clockmod_table);
+
+static struct clk cpu_clks[NR_CPUS];
+static char clk_names[NR_CPUS][10];
+
+struct clk *cpu_clk_get(int cpu)
+{
+	return &cpu_clks[cpu];
+}
+
+struct clk *clk_get(struct device *dev, const char *id)
+{
+	int i;
+	struct clk *clk;
+
+	if (!id)
+		return NULL;
+
+	for_each_possible_cpu(i) {
+		clk = &cpu_clks[i];
+		if (strcmp(clk->name, id) == 0)
+			return clk;
+	}
+
+	return NULL;
+}
+EXPORT_SYMBOL(clk_get);
+
+static void propagate_rate(struct clk *clk)
+{
+	struct clk *clkp;
+
+	list_for_each_entry(clkp, &clock_list, node) {
+		if (likely(clkp->parent != clk))
+			continue;
+		if (likely(clkp->ops && clkp->ops->recalc))
+			clkp->ops->recalc(clkp);
+		if (unlikely(clkp->flags & CLK_RATE_PROPAGATES))
+			propagate_rate(clkp);
+	}
+}
+
+int clk_enable(struct clk *clk)
+{
+	return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+	if (!clk)
+		return 0;
+
+	return (unsigned long)clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+	int regval, ret = 0;
+	struct cpufreq_frequency_table *pos;
+	int cpu = clk - cpu_clks;
+	uint64_t core_id = cpu_core(&cpu_data[cpu]);
+	uint64_t package_id = cpu_data[cpu].package;
+
+	if (likely(clk->ops && clk->ops->set_rate)) {
+		unsigned long flags;
+
+		spin_lock_irqsave(&clock_lock, flags);
+		ret = clk->ops->set_rate(clk, rate, 0);
+		spin_unlock_irqrestore(&clock_lock, flags);
+	}
+
+	if (unlikely(clk->flags & CLK_RATE_PROPAGATES))
+		propagate_rate(clk);
+
+	cpufreq_for_each_valid_entry(pos, loongson3_clockmod_table)
+		if (rate == pos->frequency)
+			break;
+	if (rate != pos->frequency)
+		return -ENOTSUPP;
+
+	clk->rate = rate;
+
+	if ((read_c0_prid() & 0xf) == PRID_REV_LOONGSON3A_R1) {
+		regval = LOONGSON_CHIPCFG(package_id);
+		regval = (regval & ~0x7) | (pos->driver_data - 1);
+		LOONGSON_CHIPCFG(package_id) = regval;
+	} else {
+		regval = LOONGSON_FREQCTRL(package_id);
+		regval = (regval & ~(0x7 << (core_id*4))) |
+			((pos->driver_data - 1) << (core_id*4));
+		LOONGSON_FREQCTRL(package_id) = regval;
+	}
+
+	return ret;
+}
+EXPORT_SYMBOL_GPL(clk_set_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+	if (likely(clk->ops && clk->ops->round_rate)) {
+		unsigned long flags, rounded;
+
+		spin_lock_irqsave(&clock_lock, flags);
+		rounded = clk->ops->round_rate(clk, rate);
+		spin_unlock_irqrestore(&clock_lock, flags);
+
+		return rounded;
+	}
+
+	return rate;
+}
+EXPORT_SYMBOL_GPL(clk_round_rate);
+
+static int loongson3_clock_init(void)
+{
+	int i;
+
+	for_each_possible_cpu(i) {
+		sprintf(clk_names[i], "cpu%d_clk", i);
+		cpu_clks[i].name = clk_names[i];
+		cpu_clks[i].flags = CLK_ALWAYS_ENABLED | CLK_RATE_PROPAGATES;
+		cpu_clks[i].rate = cpu_clock_freq / 1000;
+	}
+
+	/* clock table init */
+	for (i = 2;
+	     (loongson3_clockmod_table[i].frequency != CPUFREQ_TABLE_END);
+	     i++)
+		loongson3_clockmod_table[i].frequency = ((cpu_clock_freq / 1000) * i) / 8;
+
+	return 0;
+}
+arch_initcall(loongson3_clock_init);
+
+MODULE_AUTHOR("Huacai Chen <chenhc@lemote.com>");
+MODULE_DESCRIPTION("CPUFreq driver for Loongson 3A/3B");
+MODULE_LICENSE("GPL");
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig
index d8addbc..ea89910c 100644
--- a/drivers/cpufreq/Kconfig
+++ b/drivers/cpufreq/Kconfig
@@ -286,6 +286,19 @@ config LOONGSON2_CPUFREQ
 
 	  If in doubt, say N.
 
+config LOONGSON3_CPUFREQ
+	tristate "Loongson3 CPUFreq Driver"
+	depends on LOONGSON_MACH3X
+	help
+	  This option adds a CPUFreq driver for loongson processors which
+	  support software configurable cpu frequency.
+
+	  Loongson-3A and it's successors support this feature.
+
+	  For details, take a look at <file:Documentation/cpu-freq/>.
+
+	  If in doubt, say N.
+
 config LOONGSON1_CPUFREQ
 	tristate "Loongson1 CPUFreq Driver"
 	depends on LOONGSON1_LS1B
diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile
index 812f9e0..52e52c4 100644
--- a/drivers/cpufreq/Makefile
+++ b/drivers/cpufreq/Makefile
@@ -106,6 +106,7 @@ obj-$(CONFIG_CRIS_MACH_ARTPEC3)		+= cris-artpec3-cpufreq.o
 obj-$(CONFIG_ETRAXFS)			+= cris-etraxfs-cpufreq.o
 obj-$(CONFIG_IA64_ACPI_CPUFREQ)		+= ia64-acpi-cpufreq.o
 obj-$(CONFIG_LOONGSON2_CPUFREQ)		+= loongson2_cpufreq.o
+obj-$(CONFIG_LOONGSON3_CPUFREQ)		+= loongson3_cpufreq.o
 obj-$(CONFIG_LOONGSON1_CPUFREQ)		+= loongson1-cpufreq.o
 obj-$(CONFIG_SH_CPU_FREQ)		+= sh-cpufreq.o
 obj-$(CONFIG_SPARC_US2E_CPUFREQ)	+= sparc-us2e-cpufreq.o
diff --git a/drivers/cpufreq/loongson3_cpufreq.c b/drivers/cpufreq/loongson3_cpufreq.c
new file mode 100644
index 0000000..fecbe3f
--- /dev/null
+++ b/drivers/cpufreq/loongson3_cpufreq.c
@@ -0,0 +1,236 @@
+/*
+ * CPUFreq driver for the loongson-3 processors
+ *
+ * All revisions of Loongson-3 processor support this feature.
+ *
+ * Copyright (C) 2008 - 2014 Lemote Inc.
+ * Author: Yan Hua, yanh@lemote.com
+ *         Chen Huacai, chenhc@lemote.com
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License.  See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/delay.h>
+#include <linux/cpufreq.h>
+#include <linux/platform_device.h>
+#include <asm/idle.h>
+#include <asm/clock.h>
+#include <asm/cevt-r4k.h>
+
+#include <loongson.h>
+
+static uint nowait = 1;
+static spinlock_t cpufreq_reg_lock[MAX_PACKAGES];
+
+static void (*saved_cpu_wait)(void);
+extern struct clk *cpu_clk_get(int cpu);
+
+static int loongson3_cpu_freq_notifier(struct notifier_block *nb,
+					unsigned long val, void *data);
+
+static struct notifier_block loongson3_cpufreq_notifier_block = {
+	.notifier_call = loongson3_cpu_freq_notifier
+};
+
+#ifdef CONFIG_SMP
+static int loongson3_cpu_freq_notifier(struct notifier_block *nb,
+					unsigned long val, void *data)
+{
+	struct cpufreq_freqs *freqs = (struct cpufreq_freqs *)data;
+	unsigned long cpu = freqs->cpu;
+	struct clock_event_device *cd = &per_cpu(mips_clockevent_device, cpu);
+
+	if (val == CPUFREQ_POSTCHANGE) {
+		if (cpu == smp_processor_id())
+			clockevents_update_freq(cd, freqs->new * 1000 / 2);
+		else {
+			clockevents_calc_mult_shift(cd, freqs->new * 1000 / 2, 4);
+			cd->min_delta_ns = clockevent_delta2ns(cd->min_delta_ticks, cd);
+			cd->max_delta_ns = clockevent_delta2ns(cd->max_delta_ticks, cd);
+		}
+		cpu_data[cpu].udelay_val =
+			cpufreq_scale(loops_per_jiffy, cpu_clock_freq / 1000, freqs->new);
+	}
+
+	return 0;
+}
+#else
+static int loongson3_cpu_freq_notifier(struct notifier_block *nb,
+					unsigned long val, void *data)
+{
+	struct cpufreq_freqs *freqs = (struct cpufreq_freqs *)data;
+	struct clock_event_device *cd = &per_cpu(mips_clockevent_device, 0);
+
+	if (val == CPUFREQ_POSTCHANGE) {
+		clockevents_update_freq(cd, freqs->new * 1000 / 2);
+		current_cpu_data.udelay_val = loops_per_jiffy;
+	}
+
+	return 0;
+}
+#endif
+
+static unsigned int loongson3_cpufreq_get(unsigned int cpu)
+{
+	return clk_get_rate(cpu_clk_get(cpu));
+}
+
+/*
+ * Here we notify other drivers of the proposed change and the final change.
+ */
+static int loongson3_cpufreq_target(struct cpufreq_policy *policy,
+				     unsigned int index)
+{
+	unsigned int freq;
+	unsigned int cpu = policy->cpu;
+	unsigned int package = cpu_data[cpu].package;
+
+	if (!cpu_online(cpu))
+		return -ENODEV;
+
+	freq =
+	    ((cpu_clock_freq / 1000) *
+	     loongson3_clockmod_table[index].driver_data) / 8;
+
+	/* setting the cpu frequency */
+	spin_lock(&cpufreq_reg_lock[package]);
+	clk_set_rate(policy->clk, freq);
+	spin_unlock(&cpufreq_reg_lock[package]);
+
+	return 0;
+}
+
+static int loongson3_cpufreq_cpu_init(struct cpufreq_policy *policy)
+{
+	if (!cpu_online(policy->cpu))
+		return -ENODEV;
+
+	policy->clk = cpu_clk_get(policy->cpu);
+	policy->cur = loongson3_cpufreq_get(policy->cpu);
+
+	policy->cpuinfo.transition_latency = 1000;
+
+	/* Loongson-3A R1: all cores in a package share one clock */
+	if ((read_c0_prid() & 0xf) == PRID_REV_LOONGSON3A_R1)
+		cpumask_copy(policy->cpus, topology_core_cpumask(policy->cpu));
+
+	return cpufreq_table_validate_and_show(policy,
+			&loongson3_clockmod_table[0]);
+}
+
+static int loongson3_cpufreq_exit(struct cpufreq_policy *policy)
+{
+	return 0;
+}
+
+static struct cpufreq_driver loongson3_cpufreq_driver = {
+	.name = "loongson3",
+	.init = loongson3_cpufreq_cpu_init,
+	.verify = cpufreq_generic_frequency_table_verify,
+	.target_index = loongson3_cpufreq_target,
+	.get = loongson3_cpufreq_get,
+	.exit = loongson3_cpufreq_exit,
+	.attr = cpufreq_generic_attr,
+};
+
+static struct platform_device_id platform_device_ids[] = {
+	{
+		.name = "loongson3_cpufreq",
+	},
+	{}
+};
+
+MODULE_DEVICE_TABLE(platform, platform_device_ids);
+
+static struct platform_driver platform_driver = {
+	.driver = {
+		.name = "loongson3_cpufreq",
+		.owner = THIS_MODULE,
+	},
+	.id_table = platform_device_ids,
+};
+
+/*
+ * This is the simple version of Loongson-3 wait, Maybe we need do this in
+ * interrupt disabled content
+ */
+
+void loongson3_cpu_wait(void)
+{
+	u32 cpu_freq, shared_cpus = 0;
+	int i, cpu = smp_processor_id();
+	uint64_t core_id = cpu_core(&cpu_data[cpu]);
+	uint64_t package_id = cpu_data[cpu].package;
+
+	for_each_online_cpu(i)
+		if (cpu_data[i].package == package_id)
+			shared_cpus++;
+
+	if (shared_cpus > 1)
+		goto out;
+
+	if ((read_c0_prid() & 0xf) == PRID_REV_LOONGSON3A_R1) {
+		cpu_freq = LOONGSON_CHIPCFG(package_id);
+		LOONGSON_CHIPCFG(package_id) &= ~0x7;    /* Put CPU into wait mode */
+		LOONGSON_CHIPCFG(package_id) = cpu_freq; /* Restore CPU state */
+	} else {
+		cpu_freq = LOONGSON_FREQCTRL(package_id);
+		LOONGSON_FREQCTRL(package_id) &= ~(0x7 << (core_id*4)); /* Put CPU into wait mode */
+		LOONGSON_FREQCTRL(package_id) = cpu_freq;               /* Restore CPU state */
+	}
+
+out:
+	local_irq_enable();
+}
+EXPORT_SYMBOL_GPL(loongson3_cpu_wait);
+
+static int __init cpufreq_init(void)
+{
+	int i, ret;
+
+	/* Register platform stuff */
+	ret = platform_driver_register(&platform_driver);
+	if (ret)
+		return ret;
+
+	pr_info("cpufreq: Loongson-3 CPU frequency driver.\n");
+
+	for (i = 0; i < MAX_PACKAGES; i++)
+		spin_lock_init(&cpufreq_reg_lock[i]);
+
+	cpufreq_register_notifier(&loongson3_cpufreq_notifier_block,
+				  CPUFREQ_TRANSITION_NOTIFIER);
+
+	ret = cpufreq_register_driver(&loongson3_cpufreq_driver);
+
+	if (!ret && !nowait) {
+		saved_cpu_wait = cpu_wait;
+		cpu_wait = loongson3_cpu_wait;
+	}
+
+	return ret;
+}
+
+static void __exit cpufreq_exit(void)
+{
+	if (!nowait && saved_cpu_wait)
+		cpu_wait = saved_cpu_wait;
+	cpufreq_unregister_driver(&loongson3_cpufreq_driver);
+	cpufreq_unregister_notifier(&loongson3_cpufreq_notifier_block,
+				    CPUFREQ_TRANSITION_NOTIFIER);
+
+	platform_driver_unregister(&platform_driver);
+}
+
+module_init(cpufreq_init);
+module_exit(cpufreq_exit);
+
+module_param(nowait, uint, 0644);
+MODULE_PARM_DESC(nowait, "Disable Loongson-3A/3B specific wait");
+
+MODULE_AUTHOR("Huacai Chen <chenhc@lemote.com>");
+MODULE_DESCRIPTION("CPUFreq driver for Loongson-3A/3B");
+MODULE_LICENSE("GPL");
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH V2 11/12] MIPS: Loongson-3: Fix CPU UART irq delivery problem
  2018-01-27  3:22 ` [PATCH V2 10/12] MIPS: Loongson: Make CPUFreq usable for Loongson-3 Huacai Chen
@ 2018-01-27  3:23   ` Huacai Chen
  2018-02-20 21:49     ` James Hogan
  2018-01-27  3:23   ` [PATCH V2 12/12] MIPS: Loongson: Introduce and use WAR_LLSC_MB Huacai Chen
  2018-02-20 21:42   ` [PATCH V2 10/12] MIPS: Loongson: Make CPUFreq usable for Loongson-3 James Hogan
  2 siblings, 1 reply; 42+ messages in thread
From: Huacai Chen @ 2018-01-27  3:23 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen, stable

Masking/unmasking the CPU UART irq in CP0_Status (and redirecting it to
other CPUs) may cause interrupts be lost, especially in multi-package
machines (Package-0's UART irq cannot be delivered to others). So make
mask_loongson_irq() and unmask_loongson_irq() be no-ops.

Cc: stable@vger.kernel.org
Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/loongson64/loongson-3/irq.c | 41 ++---------------------------------
 1 file changed, 2 insertions(+), 39 deletions(-)

diff --git a/arch/mips/loongson64/loongson-3/irq.c b/arch/mips/loongson64/loongson-3/irq.c
index cbeb20f..e8381ec 100644
--- a/arch/mips/loongson64/loongson-3/irq.c
+++ b/arch/mips/loongson64/loongson-3/irq.c
@@ -102,45 +102,8 @@ static struct irqaction cascade_irqaction = {
 	.name = "cascade",
 };
 
-static inline void mask_loongson_irq(struct irq_data *d)
-{
-	clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
-	irq_disable_hazard();
-
-	/* Workaround: UART IRQ may deliver to any core */
-	if (d->irq == LOONGSON_UART_IRQ) {
-		int cpu = smp_processor_id();
-		int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node;
-		int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node;
-		u64 intenclr_addr = smp_group[node_id] |
-			(u64)(&LOONGSON_INT_ROUTER_INTENCLR);
-		u64 introuter_lpc_addr = smp_group[node_id] |
-			(u64)(&LOONGSON_INT_ROUTER_LPC);
-
-		*(volatile u32 *)intenclr_addr = 1 << 10;
-		*(volatile u8 *)introuter_lpc_addr = 0x10 + (1<<core_id);
-	}
-}
-
-static inline void unmask_loongson_irq(struct irq_data *d)
-{
-	/* Workaround: UART IRQ may deliver to any core */
-	if (d->irq == LOONGSON_UART_IRQ) {
-		int cpu = smp_processor_id();
-		int node_id = cpu_logical_map(cpu) / loongson_sysconf.cores_per_node;
-		int core_id = cpu_logical_map(cpu) % loongson_sysconf.cores_per_node;
-		u64 intenset_addr = smp_group[node_id] |
-			(u64)(&LOONGSON_INT_ROUTER_INTENSET);
-		u64 introuter_lpc_addr = smp_group[node_id] |
-			(u64)(&LOONGSON_INT_ROUTER_LPC);
-
-		*(volatile u32 *)intenset_addr = 1 << 10;
-		*(volatile u8 *)introuter_lpc_addr = 0x10 + (1<<core_id);
-	}
-
-	set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
-	irq_enable_hazard();
-}
+static inline void mask_loongson_irq(struct irq_data *d) { }
+static inline void unmask_loongson_irq(struct irq_data *d) { }
 
  /* For MIPS IRQs which shared by all cores */
 static struct irq_chip loongson_irq_chip = {
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* [PATCH V2 12/12] MIPS: Loongson: Introduce and use WAR_LLSC_MB
  2018-01-27  3:22 ` [PATCH V2 10/12] MIPS: Loongson: Make CPUFreq usable for Loongson-3 Huacai Chen
  2018-01-27  3:23   ` [PATCH V2 11/12] MIPS: Loongson-3: Fix CPU UART irq delivery problem Huacai Chen
@ 2018-01-27  3:23   ` Huacai Chen
  2018-02-20 22:21     ` James Hogan
  2018-02-20 21:42   ` [PATCH V2 10/12] MIPS: Loongson: Make CPUFreq usable for Loongson-3 James Hogan
  2 siblings, 1 reply; 42+ messages in thread
From: Huacai Chen @ 2018-01-27  3:23 UTC (permalink / raw)
  To: Ralf Baechle
  Cc: James Hogan, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, Huacai Chen

On the Loongson-2G/2H/3A/3B there is a hardware flaw that ll/sc and
lld/scd is very weak ordering. We should add sync instructions before
each ll/lld and after the last sc/scd to workaround. Otherwise, this
flaw will cause deadlock occationally (e.g. when doing heavy load test
with LTP).

Signed-off-by: Huacai Chen <chenhc@lemote.com>
---
 arch/mips/include/asm/atomic.h  | 18 ++++++++++++++++--
 arch/mips/include/asm/barrier.h |  6 ++++++
 arch/mips/include/asm/bitops.h  | 15 +++++++++++++++
 arch/mips/include/asm/cmpxchg.h |  9 +++++++--
 arch/mips/include/asm/edac.h    |  5 ++++-
 arch/mips/include/asm/futex.h   | 18 ++++++++++++------
 arch/mips/include/asm/local.h   | 10 ++++++++--
 arch/mips/include/asm/pgtable.h |  5 ++++-
 arch/mips/kernel/syscall.c      |  2 ++
 arch/mips/loongson64/Platform   |  3 +++
 arch/mips/mm/tlbex.c            | 11 +++++++++++
 11 files changed, 88 insertions(+), 14 deletions(-)

diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
index 0ab176b..99a6d01 100644
--- a/arch/mips/include/asm/atomic.h
+++ b/arch/mips/include/asm/atomic.h
@@ -62,6 +62,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v)			      \
 		do {							      \
 			__asm__ __volatile__(				      \
 			"	.set	"MIPS_ISA_LEVEL"		\n"   \
+			__WAR_LLSC_MB					      \
 			"	ll	%0, %1		# atomic_" #op "\n"   \
 			"	" #asm_op " %0, %2			\n"   \
 			"	sc	%0, %1				\n"   \
@@ -69,6 +70,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v)			      \
 			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter)  \
 			: "Ir" (i));					      \
 		} while (unlikely(!temp));				      \
+		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");	      \
 	} else {							      \
 		unsigned long flags;					      \
 									      \
@@ -103,6 +105,7 @@ static __inline__ int atomic_##op##_return_relaxed(int i, atomic_t * v)	      \
 		do {							      \
 			__asm__ __volatile__(				      \
 			"	.set	"MIPS_ISA_LEVEL"		\n"   \
+			__WAR_LLSC_MB					      \
 			"	ll	%1, %2	# atomic_" #op "_return	\n"   \
 			"	" #asm_op " %0, %1, %3			\n"   \
 			"	sc	%0, %2				\n"   \
@@ -151,6 +154,7 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v)	      \
 		do {							      \
 			__asm__ __volatile__(				      \
 			"	.set	"MIPS_ISA_LEVEL"		\n"   \
+			__WAR_LLSC_MB					      \
 			"	ll	%1, %2	# atomic_fetch_" #op "	\n"   \
 			"	" #asm_op " %0, %1, %3			\n"   \
 			"	sc	%0, %2				\n"   \
@@ -159,6 +163,7 @@ static __inline__ int atomic_fetch_##op##_relaxed(int i, atomic_t * v)	      \
 			  "+" GCC_OFF_SMALL_ASM() (v->counter)		      \
 			: "Ir" (i));					      \
 		} while (unlikely(!result));				      \
+		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");	      \
 									      \
 		result = temp;						      \
 	} else {							      \
@@ -242,7 +247,9 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
 
 		__asm__ __volatile__(
 		"	.set	"MIPS_ISA_LEVEL"			\n"
-		"1:	ll	%1, %2		# atomic_sub_if_positive\n"
+		"1:			# atomic_sub_if_positive	\n"
+		__WAR_LLSC_MB
+		"	ll	%1, %2					\n"
 		"	subu	%0, %1, %3				\n"
 		"	bltz	%0, 1f					\n"
 		"	sc	%0, %2					\n"
@@ -404,6 +411,7 @@ static __inline__ void atomic64_##op(long i, atomic64_t * v)		      \
 		do {							      \
 			__asm__ __volatile__(				      \
 			"	.set	"MIPS_ISA_LEVEL"		\n"   \
+			__WAR_LLSC_MB					      \
 			"	lld	%0, %1		# atomic64_" #op "\n" \
 			"	" #asm_op " %0, %2			\n"   \
 			"	scd	%0, %1				\n"   \
@@ -411,6 +419,7 @@ static __inline__ void atomic64_##op(long i, atomic64_t * v)		      \
 			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter)      \
 			: "Ir" (i));					      \
 		} while (unlikely(!temp));				      \
+		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");	      \
 	} else {							      \
 		unsigned long flags;					      \
 									      \
@@ -445,6 +454,7 @@ static __inline__ long atomic64_##op##_return_relaxed(long i, atomic64_t * v) \
 		do {							      \
 			__asm__ __volatile__(				      \
 			"	.set	"MIPS_ISA_LEVEL"		\n"   \
+			__WAR_LLSC_MB					      \
 			"	lld	%1, %2	# atomic64_" #op "_return\n"  \
 			"	" #asm_op " %0, %1, %3			\n"   \
 			"	scd	%0, %2				\n"   \
@@ -494,6 +504,7 @@ static __inline__ long atomic64_fetch_##op##_relaxed(long i, atomic64_t * v)  \
 		do {							      \
 			__asm__ __volatile__(				      \
 			"	.set	"MIPS_ISA_LEVEL"		\n"   \
+			__WAR_LLSC_MB					      \
 			"	lld	%1, %2	# atomic64_fetch_" #op "\n"   \
 			"	" #asm_op " %0, %1, %3			\n"   \
 			"	scd	%0, %2				\n"   \
@@ -503,6 +514,7 @@ static __inline__ long atomic64_fetch_##op##_relaxed(long i, atomic64_t * v)  \
 			: "Ir" (i), GCC_OFF_SMALL_ASM() (v->counter)	      \
 			: "memory");					      \
 		} while (unlikely(!result));				      \
+		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");	      \
 									      \
 		result = temp;						      \
 	} else {							      \
@@ -587,7 +599,9 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
 
 		__asm__ __volatile__(
 		"	.set	"MIPS_ISA_LEVEL"			\n"
-		"1:	lld	%1, %2		# atomic64_sub_if_positive\n"
+		"1:			# atomic64_sub_if_positive	\n"
+		__WAR_LLSC_MB
+		"	lld	%1, %2					\n"
 		"	dsubu	%0, %1, %3				\n"
 		"	bltz	%0, 1f					\n"
 		"	scd	%0, %2					\n"
diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h
index 0e8e6af..268d921 100644
--- a/arch/mips/include/asm/barrier.h
+++ b/arch/mips/include/asm/barrier.h
@@ -203,6 +203,12 @@
 #define __WEAK_LLSC_MB		"		\n"
 #endif
 
+#if defined(CONFIG_LOONGSON3) && defined(CONFIG_SMP) /* Loongson-3's LLSC workaround */
+#define __WAR_LLSC_MB		"	sync	\n"
+#else
+#define __WAR_LLSC_MB		"		\n"
+#endif
+
 #define smp_llsc_mb()	__asm__ __volatile__(__WEAK_LLSC_MB : : :"memory")
 
 #ifdef CONFIG_CPU_CAVIUM_OCTEON
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h
index da1b871..0612cff 100644
--- a/arch/mips/include/asm/bitops.h
+++ b/arch/mips/include/asm/bitops.h
@@ -70,17 +70,20 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
 	} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
 		do {
 			__asm__ __volatile__(
+			__WAR_LLSC_MB
 			"	" __LL "%0, %1		# set_bit	\n"
 			"	" __INS "%0, %3, %2, 1			\n"
 			"	" __SC "%0, %1				\n"
 			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
 			: "ir" (bit), "r" (~0));
 		} while (unlikely(!temp));
+		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
 #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
 	} else if (kernel_uses_llsc) {
 		do {
 			__asm__ __volatile__(
 			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
+			__WAR_LLSC_MB
 			"	" __LL "%0, %1		# set_bit	\n"
 			"	or	%0, %2				\n"
 			"	" __SC	"%0, %1				\n"
@@ -88,6 +91,7 @@ static inline void set_bit(unsigned long nr, volatile unsigned long *addr)
 			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
 			: "ir" (1UL << bit));
 		} while (unlikely(!temp));
+		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
 	} else
 		__mips_set_bit(nr, addr);
 }
@@ -122,17 +126,20 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
 	} else if (kernel_uses_llsc && __builtin_constant_p(bit)) {
 		do {
 			__asm__ __volatile__(
+			__WAR_LLSC_MB
 			"	" __LL "%0, %1		# clear_bit	\n"
 			"	" __INS "%0, $0, %2, 1			\n"
 			"	" __SC "%0, %1				\n"
 			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
 			: "ir" (bit));
 		} while (unlikely(!temp));
+		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
 #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */
 	} else if (kernel_uses_llsc) {
 		do {
 			__asm__ __volatile__(
 			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
+			__WAR_LLSC_MB
 			"	" __LL "%0, %1		# clear_bit	\n"
 			"	and	%0, %2				\n"
 			"	" __SC "%0, %1				\n"
@@ -140,6 +147,7 @@ static inline void clear_bit(unsigned long nr, volatile unsigned long *addr)
 			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
 			: "ir" (~(1UL << bit)));
 		} while (unlikely(!temp));
+		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
 	} else
 		__mips_clear_bit(nr, addr);
 }
@@ -191,6 +199,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
 		do {
 			__asm__ __volatile__(
 			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
+			__WAR_LLSC_MB
 			"	" __LL "%0, %1		# change_bit	\n"
 			"	xor	%0, %2				\n"
 			"	" __SC	"%0, %1				\n"
@@ -198,6 +207,7 @@ static inline void change_bit(unsigned long nr, volatile unsigned long *addr)
 			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (*m)
 			: "ir" (1UL << bit));
 		} while (unlikely(!temp));
+		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
 	} else
 		__mips_change_bit(nr, addr);
 }
@@ -240,6 +250,7 @@ static inline int test_and_set_bit(unsigned long nr,
 		do {
 			__asm__ __volatile__(
 			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
+			__WAR_LLSC_MB
 			"	" __LL "%0, %1	# test_and_set_bit	\n"
 			"	or	%2, %0, %3			\n"
 			"	" __SC	"%2, %1				\n"
@@ -294,6 +305,7 @@ static inline int test_and_set_bit_lock(unsigned long nr,
 		do {
 			__asm__ __volatile__(
 			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
+			__WAR_LLSC_MB
 			"	" __LL "%0, %1	# test_and_set_bit	\n"
 			"	or	%2, %0, %3			\n"
 			"	" __SC	"%2, %1				\n"
@@ -350,6 +362,7 @@ static inline int test_and_clear_bit(unsigned long nr,
 
 		do {
 			__asm__ __volatile__(
+			__WAR_LLSC_MB
 			"	" __LL	"%0, %1 # test_and_clear_bit	\n"
 			"	" __EXT "%2, %0, %3, 1			\n"
 			"	" __INS "%0, $0, %3, 1			\n"
@@ -366,6 +379,7 @@ static inline int test_and_clear_bit(unsigned long nr,
 		do {
 			__asm__ __volatile__(
 			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
+			__WAR_LLSC_MB
 			"	" __LL	"%0, %1 # test_and_clear_bit	\n"
 			"	or	%2, %0, %3			\n"
 			"	xor	%2, %3				\n"
@@ -423,6 +437,7 @@ static inline int test_and_change_bit(unsigned long nr,
 		do {
 			__asm__ __volatile__(
 			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
+			__WAR_LLSC_MB
 			"	" __LL	"%0, %1 # test_and_change_bit	\n"
 			"	xor	%2, %0, %3			\n"
 			"	" __SC	"\t%2, %1			\n"
diff --git a/arch/mips/include/asm/cmpxchg.h b/arch/mips/include/asm/cmpxchg.h
index 89e9fb7..1f9c091 100644
--- a/arch/mips/include/asm/cmpxchg.h
+++ b/arch/mips/include/asm/cmpxchg.h
@@ -48,7 +48,9 @@ extern unsigned long __xchg_called_with_bad_pointer(void)
 		"	.set	push				\n"	\
 		"	.set	noat				\n"	\
 		"	.set	" MIPS_ISA_ARCH_LEVEL "		\n"	\
-		"1:	" ld "	%0, %2		# __xchg_asm	\n"	\
+		"1:				# __xchg_asm	\n"	\
+		__WAR_LLSC_MB						\
+		"	" ld "	%0, %2				\n"	\
 		"	.set	mips0				\n"	\
 		"	move	$1, %z3				\n"	\
 		"	.set	" MIPS_ISA_ARCH_LEVEL "		\n"	\
@@ -118,7 +120,9 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
 		"	.set	push				\n"	\
 		"	.set	noat				\n"	\
 		"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"	\
-		"1:	" ld "	%0, %2		# __cmpxchg_asm \n"	\
+		"1:				# __cmpxchg_asm \n"	\
+		__WAR_LLSC_MB						\
+		"	" ld "	%0, %2				\n"	\
 		"	bne	%0, %z3, 2f			\n"	\
 		"	.set	mips0				\n"	\
 		"	move	$1, %z4				\n"	\
@@ -127,6 +131,7 @@ static inline unsigned long __xchg(volatile void *ptr, unsigned long x,
 		"\t" __scbeqz "	$1, 1b				\n"	\
 		"	.set	pop				\n"	\
 		"2:						\n"	\
+		__WAR_LLSC_MB						\
 		: "=&r" (__ret), "=" GCC_OFF_SMALL_ASM() (*m)		\
 		: GCC_OFF_SMALL_ASM() (*m), "Jr" (old), "Jr" (new)		\
 		: "memory");						\
diff --git a/arch/mips/include/asm/edac.h b/arch/mips/include/asm/edac.h
index fc46776..b07a3a9 100644
--- a/arch/mips/include/asm/edac.h
+++ b/arch/mips/include/asm/edac.h
@@ -22,13 +22,16 @@ static inline void edac_atomic_scrub(void *va, u32 size)
 
 		__asm__ __volatile__ (
 		"	.set	mips2					\n"
-		"1:	ll	%0, %1		# edac_atomic_scrub	\n"
+		"1:				# edac_atomic_scrub	\n"
+		__WAR_LLSC_MB
+		"	ll	%0, %1					\n"
 		"	addu	%0, $0					\n"
 		"	sc	%0, %1					\n"
 		"	beqz	%0, 1b					\n"
 		"	.set	mips0					\n"
 		: "=&r" (temp), "=" GCC_OFF_SMALL_ASM() (*virt_addr)
 		: GCC_OFF_SMALL_ASM() (*virt_addr));
+		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
 
 		virt_addr++;
 	}
diff --git a/arch/mips/include/asm/futex.h b/arch/mips/include/asm/futex.h
index a9e61ea..d497ee9 100644
--- a/arch/mips/include/asm/futex.h
+++ b/arch/mips/include/asm/futex.h
@@ -54,7 +54,9 @@
 		"	.set	push				\n"	\
 		"	.set	noat				\n"	\
 		"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"	\
-		"1:	"user_ll("%1", "%4")" # __futex_atomic_op\n"	\
+		"1:				 # __futex_atomic_op\n"	\
+		__WAR_LLSC_MB						\
+		"	"user_ll("%1", "%4")"			\n"	\
 		"	.set	mips0				\n"	\
 		"	" insn	"				\n"	\
 		"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"	\
@@ -70,8 +72,9 @@
 		"	j	3b				\n"	\
 		"	.previous				\n"	\
 		"	.section __ex_table,\"a\"		\n"	\
-		"	"__UA_ADDR "\t1b, 4b			\n"	\
-		"	"__UA_ADDR "\t2b, 4b			\n"	\
+		"	"__UA_ADDR "\t(1b + 0), 4b		\n"	\
+		"	"__UA_ADDR "\t(1b + 4), 4b		\n"	\
+		"	"__UA_ADDR "\t(2b + 0), 4b		\n"	\
 		"	.previous				\n"	\
 		: "=r" (ret), "=&r" (oldval),				\
 		  "=" GCC_OFF_SMALL_ASM() (*uaddr)				\
@@ -167,7 +170,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 		"	.set	push					\n"
 		"	.set	noat					\n"
 		"	.set	"MIPS_ISA_ARCH_LEVEL"			\n"
-		"1:	"user_ll("%1", "%3")"				\n"
+		"1:							\n"
+		__WAR_LLSC_MB
+		"	"user_ll("%1", "%3")"				\n"
 		"	bne	%1, %z4, 3f				\n"
 		"	.set	mips0					\n"
 		"	move	$1, %z5					\n"
@@ -183,8 +188,9 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr,
 		"	j	3b					\n"
 		"	.previous					\n"
 		"	.section __ex_table,\"a\"			\n"
-		"	"__UA_ADDR "\t1b, 4b				\n"
-		"	"__UA_ADDR "\t2b, 4b				\n"
+		"	"__UA_ADDR "\t(1b + 0), 4b			\n"
+		"	"__UA_ADDR "\t(1b + 4), 4b			\n"
+		"	"__UA_ADDR "\t(2b + 0), 4b			\n"
 		"	.previous					\n"
 		: "+r" (ret), "=&r" (val), "=" GCC_OFF_SMALL_ASM() (*uaddr)
 		: GCC_OFF_SMALL_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval),
diff --git a/arch/mips/include/asm/local.h b/arch/mips/include/asm/local.h
index ac8264e..4105b7a 100644
--- a/arch/mips/include/asm/local.h
+++ b/arch/mips/include/asm/local.h
@@ -50,7 +50,9 @@ static __inline__ long local_add_return(long i, local_t * l)
 
 		__asm__ __volatile__(
 		"	.set	"MIPS_ISA_ARCH_LEVEL"			\n"
-		"1:"	__LL	"%1, %2		# local_add_return	\n"
+		"1:				# local_add_return	\n"
+			__WAR_LLSC_MB
+			__LL	"%1, %2					\n"
 		"	addu	%0, %1, %3				\n"
 			__SC	"%0, %2					\n"
 		"	beqz	%0, 1b					\n"
@@ -59,6 +61,7 @@ static __inline__ long local_add_return(long i, local_t * l)
 		: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
 		: "Ir" (i), "m" (l->a.counter)
 		: "memory");
+		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
 	} else {
 		unsigned long flags;
 
@@ -95,7 +98,9 @@ static __inline__ long local_sub_return(long i, local_t * l)
 
 		__asm__ __volatile__(
 		"	.set	"MIPS_ISA_ARCH_LEVEL"			\n"
-		"1:"	__LL	"%1, %2		# local_sub_return	\n"
+		"1:				# local_sub_return	\n"
+			__WAR_LLSC_MB
+			__LL	"%1, %2					\n"
 		"	subu	%0, %1, %3				\n"
 			__SC	"%0, %2					\n"
 		"	beqz	%0, 1b					\n"
@@ -104,6 +109,7 @@ static __inline__ long local_sub_return(long i, local_t * l)
 		: "=&r" (result), "=&r" (temp), "=m" (l->a.counter)
 		: "Ir" (i), "m" (l->a.counter)
 		: "memory");
+		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
 	} else {
 		unsigned long flags;
 
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h
index 1a508a7..729e001 100644
--- a/arch/mips/include/asm/pgtable.h
+++ b/arch/mips/include/asm/pgtable.h
@@ -233,7 +233,9 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
 			"	.set	"MIPS_ISA_ARCH_LEVEL"		\n"
 			"	.set	push				\n"
 			"	.set	noreorder			\n"
-			"1:"	__LL	"%[tmp], %[buddy]		\n"
+			"1:						\n"
+				__WAR_LLSC_MB
+				__LL	"%[tmp], %[buddy]		\n"
 			"	bnez	%[tmp], 2f			\n"
 			"	 or	%[tmp], %[tmp], %[global]	\n"
 				__SC	"%[tmp], %[buddy]		\n"
@@ -244,6 +246,7 @@ static inline void set_pte(pte_t *ptep, pte_t pteval)
 			"	.set	mips0				\n"
 			: [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp)
 			: [global] "r" (page_global));
+			__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
 		}
 #else /* !CONFIG_SMP */
 		if (pte_none(*buddy))
diff --git a/arch/mips/kernel/syscall.c b/arch/mips/kernel/syscall.c
index 58c6f63..342fbff 100644
--- a/arch/mips/kernel/syscall.c
+++ b/arch/mips/kernel/syscall.c
@@ -133,6 +133,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new)
 		"	.set	"MIPS_ISA_ARCH_LEVEL"			\n"
 		"	li	%[err], 0				\n"
 		"1:							\n"
+		__WAR_LLSC_MB
 		user_ll("%[old]", "(%[addr])")
 		"	move	%[tmp], %[new]				\n"
 		"2:							\n"
@@ -156,6 +157,7 @@ static inline int mips_atomic_set(unsigned long addr, unsigned long new)
 		  [new] "r" (new),
 		  [efault] "i" (-EFAULT)
 		: "memory");
+		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");
 	} else {
 		do {
 			preempt_disable();
diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform
index 0fce460..3700dcf 100644
--- a/arch/mips/loongson64/Platform
+++ b/arch/mips/loongson64/Platform
@@ -23,6 +23,9 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
 endif
 
 cflags-$(CONFIG_CPU_LOONGSON3)	+= -Wa,--trap
+ifneq ($(call as-option,-Wa$(comma)-mfix-loongson3-llsc,),)
+  cflags-$(CONFIG_CPU_LOONGSON3) += -Wa$(comma)-mno-fix-loongson3-llsc
+endif
 #
 # binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a
 # as MIPS64 R2; older versions as just R1.  This leaves the possibility open
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 3d3dfba..a507ba7 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -919,6 +919,8 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
 		 * to mimic that here by taking a load/istream page
 		 * fault.
 		 */
+		if (current_cpu_type() == CPU_LOONGSON3)
+			uasm_i_sync(p, 0);
 		UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0);
 		uasm_i_jr(p, ptr);
 
@@ -1545,6 +1547,7 @@ static void build_loongson3_tlb_refill_handler(void)
 
 	if (check_for_high_segbits) {
 		uasm_l_large_segbits_fault(&l, p);
+		uasm_i_sync(&p, 0);
 		UASM_i_LA(&p, K1, (unsigned long)tlb_do_page_fault_0);
 		uasm_i_jr(&p, K1);
 		uasm_i_nop(&p);
@@ -1645,6 +1648,8 @@ static void
 iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr)
 {
 #ifdef CONFIG_SMP
+	if (current_cpu_type() == CPU_LOONGSON3)
+		uasm_i_sync(p, 0);
 # ifdef CONFIG_PHYS_ADDR_T_64BIT
 	if (cpu_has_64bits)
 		uasm_i_lld(p, pte, 0, ptr);
@@ -2262,6 +2267,8 @@ static void build_r4000_tlb_load_handler(void)
 #endif
 
 	uasm_l_nopage_tlbl(&l, p);
+	if (current_cpu_type() == CPU_LOONGSON3)
+		uasm_i_sync(&p, 0);
 	build_restore_work_registers(&p);
 #ifdef CONFIG_CPU_MICROMIPS
 	if ((unsigned long)tlb_do_page_fault_0 & 1) {
@@ -2317,6 +2324,8 @@ static void build_r4000_tlb_store_handler(void)
 #endif
 
 	uasm_l_nopage_tlbs(&l, p);
+	if (current_cpu_type() == CPU_LOONGSON3)
+		uasm_i_sync(&p, 0);
 	build_restore_work_registers(&p);
 #ifdef CONFIG_CPU_MICROMIPS
 	if ((unsigned long)tlb_do_page_fault_1 & 1) {
@@ -2373,6 +2382,8 @@ static void build_r4000_tlb_modify_handler(void)
 #endif
 
 	uasm_l_nopage_tlbm(&l, p);
+	if (current_cpu_type() == CPU_LOONGSON3)
+		uasm_i_sync(&p, 0);
 	build_restore_work_registers(&p);
 #ifdef CONFIG_CPU_MICROMIPS
 	if ((unsigned long)tlb_do_page_fault_1 & 1) {
-- 
2.7.0

^ permalink raw reply related	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 00/12] MIPS: Loongson: new features and improvements
  2018-01-27  3:12 [PATCH V2 00/12] MIPS: Loongson: new features and improvements Huacai Chen
                   ` (7 preceding siblings ...)
  2018-01-27  3:22 ` [PATCH V2 10/12] MIPS: Loongson: Make CPUFreq usable for Loongson-3 Huacai Chen
@ 2018-02-15 11:05 ` James Hogan
  2018-02-28  2:23   ` Huacai Chen
  8 siblings, 1 reply; 42+ messages in thread
From: James Hogan @ 2018-02-15 11:05 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Ralf Baechle, Steven J . Hill, linux-mips, Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 2886 bytes --]

On Sat, Jan 27, 2018 at 11:12:20AM +0800, Huacai Chen wrote:
> This patchset is prepared for the next 4.16 release for Linux/MIPS. It
> add Loongson-3A R3.1 support, enable Loongson-3's SFB at runtime, adds
> "model name" and "CPU MHz" knobs in /proc/cpuinfo which is needed by
> some userspace tools, adds Loongson-3 kexec/kdump and CPUFreq support,
> fixes CPU UART irq delivery problem, and introduces WAR_LLSC_MB to
> improve stability.
> 
> V1 -> V2:
> 1, Add Loongson-3A R3.1 basic support.
> 2, Fix CPU UART irq delivery problem.
> 3, Improve code and descriptions (Thank James Hogan).
> 4, Sync the code to upstream.

I few general suggestions that I hope will help you to get your patches
applied quicker:

- Please have a separate series for each group of related changes in
  future. It makes them more manageable, makes dependencies clearer, and
  avoids unchanged resends of unrelated patches when you respin the
  whole series. Series are mainly to group tightly related patches, or
  because of dependencies of later patches on earlier ones (and even if
  you have a series of 30 dependent patches, you can still sometimes
  split it into groups and mention in the cover letters which other
  pending series each series depends on).

- More importantly, avoid moving patches between series or adding
  unrelated patches to a series if possible (so probably best not to
  split this series now). It makes it harder to see what has changed,
  whether past feedback has been addressed, and whether new/removed
  patches are new/abandoned or simply moved from/to a different series.

- Please don't resend a series without changes, ping it if you are
  concerned. It clutters patchwork for no good reason and makes it
  harder to see if past feedback has been addressed.

- Please run checkpatch on all patches before submission, and fix any
  reasonable warnings and errors (i.e. there are various lines exceeding
  80 characters in this series which should be split, but some are
  acceptable where its to keep a string together).

- Please include Fixes tags where appropriate, especially where you've
  Cc'd stable.

- If you Cc stable, please state how far back it should be backported
  wherever possible,
  E.g. Cc: <stable@vger.kernel.org> # 4.14+
  This may help finding what version a commit is first included in:
  https://www.linux-mips.org/archives/linux-mips/2017-07/msg00149.html

- Please run get_maintainer.pl on each patch to make sure you cc the
  appropriate maintainers and lists (and Cc them on the cover letter
  too). Its fine to skip LKML for lots of MIPS patches, but don't miss
  out the appropriate subsystem maintainers and lists for patches
  touching drivers/ or they'll never get acked and never get applied.

- Split arch/mips/ and drivers/ patches wherever possible.

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 02/12] MIPS: Loongson64: Define and use some CP0 registers
  2018-01-27  3:12 ` [PATCH V2 02/12] MIPS: Loongson64: Define and use some CP0 registers Huacai Chen
@ 2018-02-15 11:36   ` James Hogan
  0 siblings, 0 replies; 42+ messages in thread
From: James Hogan @ 2018-02-15 11:36 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Ralf Baechle, Steven J . Hill, linux-mips, Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 530 bytes --]

On Sat, Jan 27, 2018 at 11:12:22AM +0800, Huacai Chen wrote:
> This patche defines CP0_CONFIG3, CP0_CONFIG6, CP0_PAGEGRAIN and uses
> them in kernel-entry-init.h for Loongson64.

Please write commit messages in the imerative mood (i.e. like you're
telling the code how to change), and without referring to the patch
itself, E.g.
> Define CP0_CONFIG3, CP0_CONFIG6, CP0_PAGEGRAIN and use them in
> kernel-entry-init.h for Loongson64.

Thanks for splitting this patch out.

Reviewed-by: James Hogan <jhogan@kernel.org>

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 03/12] MIPS: Loongson-3: Enable Store Fill Buffer at runtime
  2018-01-27  3:12 ` [PATCH V2 03/12] MIPS: Loongson-3: Enable Store Fill Buffer at runtime Huacai Chen
@ 2018-02-15 12:43   ` James Hogan
  0 siblings, 0 replies; 42+ messages in thread
From: James Hogan @ 2018-02-15 12:43 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Ralf Baechle, Steven J . Hill, linux-mips, Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 856 bytes --]

On Sat, Jan 27, 2018 at 11:12:23AM +0800, Huacai Chen wrote:
> diff --git a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h
> index 3127391..4b7f58a 100644
> --- a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h
> +++ b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h
> @@ -26,12 +26,15 @@
>  	mfc0	t0, CP0_PAGEGRAIN
>  	or	t0, (0x1 << 29)
>  	mtc0	t0, CP0_PAGEGRAIN
> -#ifdef CONFIG_LOONGSON3_ENHANCEMENT
>  	/* Enable STFill Buffer */
> +	mfc0	t0, CP0_PRID
> +	andi	t0, 0xffff

Maybe worth including <asm/cpu.h and doing:
	andi	t0, (PRID_IMP_MASK | PRID_REV_MASK)

> +	slti	t0, 0x6308

and:
	slti	t0, (PRID_IMP_LOONGSON_64 | PRID_REV_LOONGSON3A_R2)

With something like that here and in the other place:

Reviewed-by: James Hogan <jhogan@kernel.org>

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 04/12] MIPS: c-r4k: Add r4k_blast_scache_node for Loongson-3
  2018-01-27  3:19 ` [PATCH V2 04/12] MIPS: c-r4k: Add r4k_blast_scache_node for Loongson-3 Huacai Chen
@ 2018-02-19 22:19   ` James Hogan
  0 siblings, 0 replies; 42+ messages in thread
From: James Hogan @ 2018-02-19 22:19 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Ralf Baechle, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, # 3 . 15+

[-- Attachment #1: Type: text/plain, Size: 3534 bytes --]

On Sat, Jan 27, 2018 at 11:19:05AM +0800, Huacai Chen wrote:
> For multi-node Loongson-3 (NUMA configuration), r4k_blast_scache() can
> only flush Node-0's scache. So we add r4k_blast_scache_node() by using
> (CAC_BASE | (node_id << NODE_ADDRSPACE_SHIFT)) instead of CKSEG0 as the
> start address.
> 
> Cc: <stable@vger.kernel.org> # 3.15+
> Signed-off-by: Huacai Chen <chenhc@lemote.com>
> ---
>  arch/mips/include/asm/r4kcache.h | 34 ++++++++++++++++++++++++++++++++
>  arch/mips/mm/c-r4k.c             | 42 +++++++++++++++++++++++++++++++++-------
>  2 files changed, 69 insertions(+), 7 deletions(-)
> 
> diff --git a/arch/mips/include/asm/r4kcache.h b/arch/mips/include/asm/r4kcache.h
> index 7f12d7e..c1f2806 100644
> --- a/arch/mips/include/asm/r4kcache.h
> +++ b/arch/mips/include/asm/r4kcache.h
> @@ -747,4 +747,38 @@ __BUILD_BLAST_CACHE_RANGE(s, scache, Hit_Writeback_Inv_SD, , )
>  __BUILD_BLAST_CACHE_RANGE(inv_d, dcache, Hit_Invalidate_D, , )
>  __BUILD_BLAST_CACHE_RANGE(inv_s, scache, Hit_Invalidate_SD, , )
>  
> +#ifndef pa_to_nid
> +#define pa_to_nid(addr) 0
> +#endif
> +
> +#ifndef NODE_ADDRSPACE_SHIFT

To be sure you get the right definition of both of these if they exist,
and wherever this header is included, we should explicitly #include the
appropriate header (asm/mmzone.h?) from this header.

> +#define nid_to_addrbase(nid) 0
> +#else
> +#define nid_to_addrbase(nid) (nid << NODE_ADDRSPACE_SHIFT)

Technically this should have parentheses around nid.

It seems slightly inconsistent to have pa_to_nid() defined in mmzone.h,
but not the reverse nid_to_addrbase(). NODE_ADDRSPACE_SHIFT is very
loongson specific afterall.

Would it make sense to move it into
arch/mips/include/asm/mach-loongson64/mmzone.h and put the 0 definition
in #ifndef nid_to_addrbase?

> +#endif
> +
> +#define __BUILD_BLAST_CACHE_NODE(pfx, desc, indexop, hitop, lsize)	\

I think this is worthy of a quick comment to explain that this is very
specific to Loongson3.

>  #endif /* _ASM_R4KCACHE_H */
> diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c
> index 6f534b20..155f5f5 100644
> --- a/arch/mips/mm/c-r4k.c
> +++ b/arch/mips/mm/c-r4k.c

...

> @@ -480,6 +497,10 @@ static inline void local_r4k___flush_cache_all(void * args)
>  		r4k_blast_scache();
>  		break;
>  
> +	case CPU_LOONGSON3:
> +		r4k_blast_scache_node(get_ebase_cpunum() >> 2);

I assume this can't use cpu_to_node() because it needs to work even when
NUMA=n? If so, I think it deserves a brief comment to explain that.

> +		break;
> +
>  	case CPU_BMIPS5000:
>  		r4k_blast_scache();
>  		__sync();
> @@ -839,9 +860,12 @@ static void r4k_dma_cache_wback_inv(unsigned long addr, unsigned long size)
>  
>  	preempt_disable();
>  	if (cpu_has_inclusive_pcaches) {
> -		if (size >= scache_size)
> -			r4k_blast_scache();
> -		else
> +		if (size >= scache_size) {
> +			if (current_cpu_type() != CPU_LOONGSON3)
> +				r4k_blast_scache();
> +			else
> +				r4k_blast_scache_node(pa_to_nid(addr));

If I read this right, addr is a virtual address so this feels a bit
hacky, but I suppose its harmless since it'll probably always be memory
in xkphys space where pa_to_nid() will do the right thing. Perhaps a
comment along the lines of:
/* This assumes that addr is in XKPhys */

> +		} else

Please keep braces consistent, i.e. add to the trailing else statement
too.

Other than those niggles, the actual mechanism looks reasonable to me.

Thanks
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
  2018-01-27  3:22   ` [PATCH V2 08/12] MIPS: Align kernel load address to 64KB Huacai Chen
@ 2018-02-19 23:07     ` James Hogan
  2018-02-20 22:14         ` Maciej W. Rozycki
  0 siblings, 1 reply; 42+ messages in thread
From: James Hogan @ 2018-02-19 23:07 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Ralf Baechle, Steven J . Hill, linux-mips, Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 1917 bytes --]

On Sat, Jan 27, 2018 at 11:22:15AM +0800, Huacai Chen wrote:
> KEXEC assume kernel align to PAGE_SIZE, and 64KB is the largest
> PAGE_SIZE.

Please expand, maybe referring to sanity_check_segment_list() which does
the actual check. Maybe something like this:

 Kexec needs the new kernel's load address to be aligned on a page
 boundary (see sanity_check_segment_list()), but on MIPS the default
 vmlinuz load address is only explicitly aligned to 16 bytes.

 Since the largest PAGE_SIZE supported by MIPS kernels is 64KB, increase
 the alignment calculated by calc_vmlinuz_load_addr to 64KB.


I suppose it'd be a bit ugly for the kexec userland code to increase the
size of the load segment downwards to make it page aligned...

> 
> Signed-off-by: Huacai Chen <chenhc@lemote.com>
> ---
>  arch/mips/boot/compressed/calc_vmlinuz_load_addr.c | 5 ++---
>  1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c b/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c
> index 37fe58c..1dcaef4 100644
> --- a/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c
> +++ b/arch/mips/boot/compressed/calc_vmlinuz_load_addr.c
> @@ -45,11 +45,10 @@ int main(int argc, char *argv[])
>  	vmlinuz_load_addr = vmlinux_load_addr + vmlinux_size;
>  
>  	/*
> -	 * Align with 16 bytes: "greater than that used for any standard data
> -	 * types by a MIPS compiler." -- See MIPS Run Linux (Second Edition).
> +	 * Align with 64KB: KEXEC assume kernel align to PAGE_SIZE

"Align to 64KB: kexec needs load sections to be aligned to PAGE_SIZE,
which may be as large as 64KB depending on the kernel configuration".

>  	 */
>  
> -	vmlinuz_load_addr += (16 - vmlinux_size % 16);
> +	vmlinuz_load_addr += (65536 - vmlinux_size % 65536);

Personally I find (64 * 1024) (or even SZ_64K) easier to read, but no
big deal.

Thanks
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 09/12] MIPS: Loongson: Add kexec/kdump support
  2018-01-27  3:22   ` [PATCH V2 09/12] MIPS: Loongson: Add kexec/kdump support Huacai Chen
@ 2018-02-19 23:54     ` James Hogan
  0 siblings, 0 replies; 42+ messages in thread
From: James Hogan @ 2018-02-19 23:54 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Ralf Baechle, Steven J . Hill, linux-mips, Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 7845 bytes --]

On Sat, Jan 27, 2018 at 11:22:16AM +0800, Huacai Chen wrote:
> Signed-off-by: Huacai Chen <chenhc@lemote.com>

Please add a commit message.

Worth Cc'ing kexec maintainers?

> ---
>  arch/mips/kernel/relocate_kernel.S    |  30 +++++++++
>  arch/mips/loongson64/common/env.c     |   8 +++
>  arch/mips/loongson64/common/reset.c   | 119 ++++++++++++++++++++++++++++++++++
>  arch/mips/loongson64/loongson-3/smp.c |   4 ++
>  4 files changed, 161 insertions(+)
> 
> diff --git a/arch/mips/kernel/relocate_kernel.S b/arch/mips/kernel/relocate_kernel.S
> index c6bbf21..e73edc7 100644
> --- a/arch/mips/kernel/relocate_kernel.S
> +++ b/arch/mips/kernel/relocate_kernel.S
> @@ -135,6 +135,36 @@ LEAF(kexec_smp_wait)
>  #else
>  	sync
>  #endif
> +
> +#ifdef CONFIG_CPU_LOONGSON3
> +	/* s0:prid s1:initfn */
> +	/* t0:base t1:cpuid t2:node t3:core t9:count */
> +	mfc0  t1, $15, 1

Can you use CP0_EBASE from mipsregs.h?

> +	andi  t1, 0x3ff

MIPS_EBASE_CPUNUM

> +	dli   t0, 0x900000003ff01000

Whats that?

> +	andi  t3, t1, 0x3
> +	sll   t3, 8               /* get core id */
> +	or    t0, t0, t3

Do you have the INS instruction on loongson? Does it make sense to do
this, even if only for readability?
	dins	t0, t1, 8, 2

> +	andi  t2, t1, 0xc
> +	dsll  t2, 42              /* get node id */
> +	or    t0, t0, t2

Does it make sense to do this, especially for readability (44 vs 42)?
	dext	t2, t1, 2, 2
	dins	t0, t2, 44, 2

> +	mfc0  s0, $15, 0

CP0_PRID

> +	andi  s0, s0, 0xf
> +	blt   s0, 0x6, 1f         /* Loongson-3A1000 */
> +	bgt   s0, 0x7, 1f         /* Loongson-3A2000/3A3000 */

> +	dsrl  t2, 30              /* Loongson-3B1000/3B1500 need bit15:14 */
> +	or    t0, t0, t2

maybe:
	dins	t0, t2, 14, 2

> +1:	li    t9, 0x100           /* wait for init loop */
> +2:	addiu t9, -1              /* limit mailbox access */
> +	bnez  t9, 2b
> +	ld    s1, 0x20(t0)        /* get PC via mailbox */
> +	beqz  s1, 1b
> +	ld    sp, 0x28(t0)        /* get SP via mailbox */
> +	ld    gp, 0x30(t0)        /* get GP via mailbox */
> +	ld    a1, 0x38(t0)
> +	jr    s1                  /* jump to initial PC */
> +#endif
> +
>  	j		s1
>  	END(kexec_smp_wait)
>  #endif
> diff --git a/arch/mips/loongson64/common/env.c b/arch/mips/loongson64/common/env.c
> index 2928ac5..990a2d69 100644
> --- a/arch/mips/loongson64/common/env.c
> +++ b/arch/mips/loongson64/common/env.c
> @@ -72,6 +72,7 @@ void __init prom_init_env(void)
>  
>  	pr_info("memsize=%u, highmemsize=%u\n", memsize, highmemsize);
>  #else
> +	int i;
>  	struct boot_params *boot_p;
>  	struct loongson_params *loongson_p;
>  	struct system_loongson *esys;
> @@ -149,6 +150,13 @@ void __init prom_init_env(void)
>  	loongson_sysconf.nr_cpus = ecpu->nr_cpus;
>  	loongson_sysconf.boot_cpu_id = ecpu->cpu_startup_core_id;
>  	loongson_sysconf.reserved_cpus_mask = ecpu->reserved_cores_mask;
> +#ifdef CONFIG_KEXEC
> +	loongson_sysconf.boot_cpu_id = get_ebase_cpunum();
> +	for (i = 0; i < loongson_sysconf.boot_cpu_id; i++)
> +		loongson_sysconf.reserved_cpus_mask |= (1<<i);

maybe this?
	loongson_sysconf.reserved_cpus_mask |=
		(1 << loongson_sysconf.boot_cpu_id) - 1;

> +	pr_info("Boot CPU ID is being fixed from %d to %d\n",
> +		ecpu->cpu_startup_core_id, loongson_sysconf.boot_cpu_id);
> +#endif
>  	if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0)
>  		loongson_sysconf.nr_cpus = NR_CPUS;
>  	loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus +
> diff --git a/arch/mips/loongson64/common/reset.c b/arch/mips/loongson64/common/reset.c
> index a60715e..5f65a4e 100644
> --- a/arch/mips/loongson64/common/reset.c
> +++ b/arch/mips/loongson64/common/reset.c
> @@ -11,9 +11,14 @@
>   */
>  #include <linux/init.h>
>  #include <linux/pm.h>
> +#include <linux/cpu.h>
> +#include <linux/slab.h>
> +#include <linux/delay.h>
> +#include <linux/kexec.h>
>  
>  #include <asm/idle.h>
>  #include <asm/reboot.h>
> +#include <asm/bootinfo.h>

alphabetical ordering wherever possible please.

>  
>  #include <loongson.h>
>  #include <boot_param.h>
> @@ -80,12 +85,126 @@ static void loongson_halt(void)
>  	}
>  }
>  
> +#ifdef CONFIG_KEXEC
> +
> +/* 0X80000000~0X80200000 is safe */
> +#define MAX_ARGS	64
> +#define KEXEC_CTRL_CODE	0XFFFFFFFF80100000UL
> +#define KEXEC_ARGV_ADDR	0XFFFFFFFF80108000UL

lower case 0x please.

> +#define KEXEC_ARGV_SIZE	3060
> +#define KEXEC_ENVP_SIZE	4500
> +
> +void *kexec_argv;
> +void *kexec_envp;
> +extern const size_t relocate_new_kernel_size;

A couple of other architectures have moved this declaration to
asm/kexec.h.

> +
> +static int loongson_kexec_prepare(struct kimage *image)
> +{
> +	int i, argc = 0;
> +	unsigned int *argv;
> +	char *str, *ptr, *bootloader = "kexec";
> +
> +	/* argv at offset 0, argv[] at offset KEXEC_ARGV_SIZE/2 */
> +	argv = (unsigned int *)kexec_argv;

the cast is redundant as kexec_argv is void *.

> +	argv[argc++] = (unsigned int)(KEXEC_ARGV_ADDR + KEXEC_ARGV_SIZE/2);
> +
> +	for (i = 0; i < image->nr_segments; i++) {
> +		if (!strncmp(bootloader, (char *)image->segment[i].buf,
> +				strlen(bootloader))) {
> +			/*
> +			 * convert command line string to array
> +			 * of parameters (as bootloader does).
> +			 */
> +			int offt;
> +			memcpy(kexec_argv + KEXEC_ARGV_SIZE/2, image->segment[i].buf, KEXEC_ARGV_SIZE/2);
> +			str = (char *)kexec_argv + KEXEC_ARGV_SIZE/2;
> +			ptr = strchr(str, ' ');
> +
> +			while (ptr && (argc < MAX_ARGS)) {
> +				*ptr = '\0';
> +				if (ptr[1] != ' ') {
> +					offt = (int)(ptr - str + 1);
> +					argv[argc] = KEXEC_ARGV_ADDR + KEXEC_ARGV_SIZE/2 + offt;
> +					argc++;
> +				}
> +				ptr = strchr(ptr + 1, ' ');
> +			}
> +			break;
> +		}
> +	}
> +
> +	kexec_args[0] = argc;
> +	kexec_args[1] = fw_arg1;
> +	kexec_args[2] = fw_arg2;
> +	image->control_code_page = virt_to_page((void *)KEXEC_CTRL_CODE);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_SMP
> +static void kexec_smp_down(void *ignored)
> +{
> +	int cpu = smp_processor_id();
> +
> +	local_irq_disable();
> +	set_cpu_online(cpu, false);
> +	while (!atomic_read(&kexec_ready_to_reboot))
> +		cpu_relax();
> +
> +	asm volatile (
> +	"	sync					\n"
> +	"	synci	($0)				\n");

The intermediate assembly looks nicer, and you'd get fewer checkpatch
complaints, if you do something more like this:
	asm volatile ("sync\n\t"
		      "synci ($0)");

> +
> +	relocated_kexec_smp_wait(NULL);
> +}
> +#endif
> +
> +static void loongson_kexec_shutdown(void)
> +{
> +#ifdef CONFIG_SMP
> +	int cpu;
> +
> +	for_each_possible_cpu(cpu)
> +		if (!cpu_online(cpu))
> +			cpu_up(cpu); /* Everyone should go to reboot_code_buffer */

long line 

> +
> +	smp_call_function(kexec_smp_down, NULL, 0);
> +	smp_wmb();

This probably needs a comment to explain what smp_rmb() it pairs with,
or what writes need a barrier between them and why. It certainly isn't
clear from reading the code.

> +	while (num_online_cpus() > 1) {
> +		mdelay(1);
> +		cpu_relax();
> +	}
> +#endif
> +	memcpy((void *)fw_arg1, kexec_argv, KEXEC_ARGV_SIZE);
> +	memcpy((void *)fw_arg2, kexec_envp, KEXEC_ENVP_SIZE);
> +}

> diff --git a/arch/mips/loongson64/loongson-3/smp.c b/arch/mips/loongson64/loongson-3/smp.c
> index 470e9c1..1e21ac4 100644
> --- a/arch/mips/loongson64/loongson-3/smp.c
> +++ b/arch/mips/loongson64/loongson-3/smp.c
> @@ -387,6 +387,10 @@ static void __init loongson3_smp_setup(void)
>  	ipi_status0_regs_init();
>  	ipi_en0_regs_init();
>  	ipi_mailbox_buf_init();
> +
> +	for (i = 0; i < loongson_sysconf.nr_cpus; i++)
> +		loongson3_ipi_write64(0, (void *)(ipi_mailbox_buf[i]+0x0));

what does that do? Please consider adding a comment.

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 10/12] MIPS: Loongson: Make CPUFreq usable for Loongson-3
  2018-01-27  3:22 ` [PATCH V2 10/12] MIPS: Loongson: Make CPUFreq usable for Loongson-3 Huacai Chen
  2018-01-27  3:23   ` [PATCH V2 11/12] MIPS: Loongson-3: Fix CPU UART irq delivery problem Huacai Chen
  2018-01-27  3:23   ` [PATCH V2 12/12] MIPS: Loongson: Introduce and use WAR_LLSC_MB Huacai Chen
@ 2018-02-20 21:42   ` James Hogan
  2 siblings, 0 replies; 42+ messages in thread
From: James Hogan @ 2018-02-20 21:42 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Ralf Baechle, Steven J . Hill, linux-mips, Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 1422 bytes --]

On Sat, Jan 27, 2018 at 11:22:59AM +0800, Huacai Chen wrote:
> Loongson-3A/3B support frequency scaling. But due to hardware
> limitation, Loongson-3A's frequency scaling is not independent for
> each core, we suggest enable Loongson-3A's CPUFreq only when there is
> one core online.

Does the code do anything to enforce that?

If not, should it?

Will it just work suboptimally if you tried?

>  arch/mips/include/asm/mach-loongson64/loongson.h |   1 +
>  arch/mips/kernel/smp.c                           |   3 +-
>  arch/mips/loongson64/Kconfig                     |   1 +
>  arch/mips/loongson64/common/platform.c           |  13 +-
>  arch/mips/loongson64/loongson-3/Makefile         |   2 +-
>  arch/mips/loongson64/loongson-3/clock.c          | 191 ++++++++++++++++++
>  drivers/cpufreq/Kconfig                          |  13 ++
>  drivers/cpufreq/Makefile                         |   1 +
>  drivers/cpufreq/loongson3_cpufreq.c              | 236 +++++++++++++++++++++++

This could presumably be fairly neatly divided into 3 separate changes:
- New clocks driver
- New cpufreq driver
- Minimal platform changes in arch/mips to instantiate the drivers

Please can you use the common clock framework i.e. a driver in
drivers/clk/, rather than adding yet another implementation of the clk
api in arch/mips/.

Each change needs the appropriate maintainers on Cc or you'll never get
the required review.

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 11/12] MIPS: Loongson-3: Fix CPU UART irq delivery problem
  2018-01-27  3:23   ` [PATCH V2 11/12] MIPS: Loongson-3: Fix CPU UART irq delivery problem Huacai Chen
@ 2018-02-20 21:49     ` James Hogan
  0 siblings, 0 replies; 42+ messages in thread
From: James Hogan @ 2018-02-20 21:49 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Ralf Baechle, Steven J . Hill, linux-mips, Fuxin Zhang,
	Zhangjin Wu, stable

[-- Attachment #1: Type: text/plain, Size: 842 bytes --]

On Sat, Jan 27, 2018 at 11:23:00AM +0800, Huacai Chen wrote:
> Masking/unmasking the CPU UART irq in CP0_Status (and redirecting it to
> other CPUs) may cause interrupts be lost, especially in multi-package
> machines (Package-0's UART irq cannot be delivered to others). So make
> mask_loongson_irq() and unmask_loongson_irq() be no-ops.
> 
> Cc: stable@vger.kernel.org

...

> -static inline void mask_loongson_irq(struct irq_data *d)
> -{
> -	clear_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE));
> -	irq_disable_hazard();
> -
> -	/* Workaround: UART IRQ may deliver to any core */

Wouldn't removing this self-described "workaround" bring back the
original problem?

At the very least you need a much better explanation of why these
workarounds are no longer applicable and can be safely removed.

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-20 22:14         ` Maciej W. Rozycki
  0 siblings, 0 replies; 42+ messages in thread
From: Maciej W. Rozycki @ 2018-02-20 22:14 UTC (permalink / raw)
  To: James Hogan
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

On Mon, 19 Feb 2018, James Hogan wrote:

> > KEXEC assume kernel align to PAGE_SIZE, and 64KB is the largest
> > PAGE_SIZE.
> 
> Please expand, maybe referring to sanity_check_segment_list() which does
> the actual check. Maybe something like this:
> 
>  Kexec needs the new kernel's load address to be aligned on a page
>  boundary (see sanity_check_segment_list()), but on MIPS the default
>  vmlinuz load address is only explicitly aligned to 16 bytes.
> 
>  Since the largest PAGE_SIZE supported by MIPS kernels is 64KB, increase
>  the alignment calculated by calc_vmlinuz_load_addr to 64KB.

 But why does it have to be hardcoded?  Shouldn't it be inherited from 
the image being loaded?  I'm missing bits of context here, but that 
would be either CONFIG_PAGE_SIZE_* settings or the ELF program header's 
`p_align' value, depending on how this code operates.  Wasting say 60kB 
of memory on smaller systems due to excessive alignment might not be a 
good idea.

  Maciej

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-20 22:14         ` Maciej W. Rozycki
  0 siblings, 0 replies; 42+ messages in thread
From: Maciej W. Rozycki @ 2018-02-20 22:14 UTC (permalink / raw)
  To: James Hogan
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

On Mon, 19 Feb 2018, James Hogan wrote:

> > KEXEC assume kernel align to PAGE_SIZE, and 64KB is the largest
> > PAGE_SIZE.
> 
> Please expand, maybe referring to sanity_check_segment_list() which does
> the actual check. Maybe something like this:
> 
>  Kexec needs the new kernel's load address to be aligned on a page
>  boundary (see sanity_check_segment_list()), but on MIPS the default
>  vmlinuz load address is only explicitly aligned to 16 bytes.
> 
>  Since the largest PAGE_SIZE supported by MIPS kernels is 64KB, increase
>  the alignment calculated by calc_vmlinuz_load_addr to 64KB.

 But why does it have to be hardcoded?  Shouldn't it be inherited from 
the image being loaded?  I'm missing bits of context here, but that 
would be either CONFIG_PAGE_SIZE_* settings or the ELF program header's 
`p_align' value, depending on how this code operates.  Wasting say 60kB 
of memory on smaller systems due to excessive alignment might not be a 
good idea.

  Maciej

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 12/12] MIPS: Loongson: Introduce and use WAR_LLSC_MB
  2018-01-27  3:23   ` [PATCH V2 12/12] MIPS: Loongson: Introduce and use WAR_LLSC_MB Huacai Chen
@ 2018-02-20 22:21     ` James Hogan
  2018-02-21 10:09         ` Maciej W. Rozycki
  0 siblings, 1 reply; 42+ messages in thread
From: James Hogan @ 2018-02-20 22:21 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Ralf Baechle, Steven J . Hill, linux-mips, Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 3369 bytes --]

On Sat, Jan 27, 2018 at 11:23:01AM +0800, Huacai Chen wrote:
> On the Loongson-2G/2H/3A/3B there is a hardware flaw that ll/sc and
> lld/scd is very weak ordering. We should add sync instructions before
> each ll/lld and after the last sc/scd to workaround. Otherwise, this
> flaw will cause deadlock occationally (e.g. when doing heavy load test
> with LTP).

How confident are you that this is the minimal change required to fix
the issue? Is the problem well understood?

It'd be helpful to have some more details about the flaw if you have
them.

I.e. does it really have to be done on every loop iteration (such that
using WEAK_REORDERING_BEYOND_LLSC is insufficient)?

> diff --git a/arch/mips/include/asm/atomic.h b/arch/mips/include/asm/atomic.h
> index 0ab176b..99a6d01 100644
> --- a/arch/mips/include/asm/atomic.h
> +++ b/arch/mips/include/asm/atomic.h
> @@ -62,6 +62,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v)			      \
>  		do {							      \
>  			__asm__ __volatile__(				      \
>  			"	.set	"MIPS_ISA_LEVEL"		\n"   \
> +			__WAR_LLSC_MB					      \
>  			"	ll	%0, %1		# atomic_" #op "\n"   \
>  			"	" #asm_op " %0, %2			\n"   \
>  			"	sc	%0, %1				\n"   \
> @@ -69,6 +70,7 @@ static __inline__ void atomic_##op(int i, atomic_t * v)			      \
>  			: "=&r" (temp), "+" GCC_OFF_SMALL_ASM() (v->counter)  \
>  			: "Ir" (i));					      \
>  		} while (unlikely(!temp));				      \
> +		__asm__ __volatile__(__WAR_LLSC_MB : : :"memory");	      \

This still results in an additional compiler barrier on other platforms,
so if it must remain it needs abstracting.

> diff --git a/arch/mips/include/asm/barrier.h b/arch/mips/include/asm/barrier.h
> index 0e8e6af..268d921 100644
> --- a/arch/mips/include/asm/barrier.h
> +++ b/arch/mips/include/asm/barrier.h
> @@ -203,6 +203,12 @@
>  #define __WEAK_LLSC_MB		"		\n"
>  #endif
>  
> +#if defined(CONFIG_LOONGSON3) && defined(CONFIG_SMP) /* Loongson-3's LLSC workaround */
> +#define __WAR_LLSC_MB		"	sync	\n"
> +#else
> +#define __WAR_LLSC_MB		"		\n"
> +#endif

A comment explaining the whole issue would be helpful for others trying
to decipher this.

> diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform
> index 0fce460..3700dcf 100644
> --- a/arch/mips/loongson64/Platform
> +++ b/arch/mips/loongson64/Platform
> @@ -23,6 +23,9 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
>  endif
>  
>  cflags-$(CONFIG_CPU_LOONGSON3)	+= -Wa,--trap
> +ifneq ($(call as-option,-Wa$(comma)-mfix-loongson3-llsc,),)
> +  cflags-$(CONFIG_CPU_LOONGSON3) += -Wa$(comma)-mno-fix-loongson3-llsc
> +endif

Could this be a separate patch?

This needs more explanation.
- What does this do exactly?
- Why are you turning *OFF* the compiler fix?
- Was some fix we don't want already in use by default?

> diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
> index 3d3dfba..a507ba7 100644
> --- a/arch/mips/mm/tlbex.c
> +++ b/arch/mips/mm/tlbex.c
> @@ -919,6 +919,8 @@ build_get_pgd_vmalloc64(u32 **p, struct uasm_label **l, struct uasm_reloc **r,
>  		 * to mimic that here by taking a load/istream page
>  		 * fault.
>  		 */
> +		if (current_cpu_type() == CPU_LOONGSON3)
> +			uasm_i_sync(p, 0);

I suggest abstracting this out with a nice comment explaining why it is
necessary.

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-20 22:25           ` James Hogan
  0 siblings, 0 replies; 42+ messages in thread
From: James Hogan @ 2018-02-20 22:25 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 1307 bytes --]

On Tue, Feb 20, 2018 at 10:14:39PM +0000, Maciej W. Rozycki wrote:
> On Mon, 19 Feb 2018, James Hogan wrote:
> 
> > > KEXEC assume kernel align to PAGE_SIZE, and 64KB is the largest
> > > PAGE_SIZE.
> > 
> > Please expand, maybe referring to sanity_check_segment_list() which does
> > the actual check. Maybe something like this:
> > 
> >  Kexec needs the new kernel's load address to be aligned on a page
> >  boundary (see sanity_check_segment_list()), but on MIPS the default
> >  vmlinuz load address is only explicitly aligned to 16 bytes.
> > 
> >  Since the largest PAGE_SIZE supported by MIPS kernels is 64KB, increase
> >  the alignment calculated by calc_vmlinuz_load_addr to 64KB.
> 
>  But why does it have to be hardcoded?  Shouldn't it be inherited from 
> the image being loaded?  I'm missing bits of context here, but that 
> would be either CONFIG_PAGE_SIZE_* settings or the ELF program header's 
> `p_align' value, depending on how this code operates.  Wasting say 60kB 
> of memory on smaller systems due to excessive alignment might not be a 
> good idea.

I presume there's nothing to stop a kernel with 64KB pages (and hence
requiring 64KB alignment of load sections) loading a new kernel with 4KB
pages (which is the one we're looking at).

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-20 22:25           ` James Hogan
  0 siblings, 0 replies; 42+ messages in thread
From: James Hogan @ 2018-02-20 22:25 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 1307 bytes --]

On Tue, Feb 20, 2018 at 10:14:39PM +0000, Maciej W. Rozycki wrote:
> On Mon, 19 Feb 2018, James Hogan wrote:
> 
> > > KEXEC assume kernel align to PAGE_SIZE, and 64KB is the largest
> > > PAGE_SIZE.
> > 
> > Please expand, maybe referring to sanity_check_segment_list() which does
> > the actual check. Maybe something like this:
> > 
> >  Kexec needs the new kernel's load address to be aligned on a page
> >  boundary (see sanity_check_segment_list()), but on MIPS the default
> >  vmlinuz load address is only explicitly aligned to 16 bytes.
> > 
> >  Since the largest PAGE_SIZE supported by MIPS kernels is 64KB, increase
> >  the alignment calculated by calc_vmlinuz_load_addr to 64KB.
> 
>  But why does it have to be hardcoded?  Shouldn't it be inherited from 
> the image being loaded?  I'm missing bits of context here, but that 
> would be either CONFIG_PAGE_SIZE_* settings or the ELF program header's 
> `p_align' value, depending on how this code operates.  Wasting say 60kB 
> of memory on smaller systems due to excessive alignment might not be a 
> good idea.

I presume there's nothing to stop a kernel with 64KB pages (and hence
requiring 64KB alignment of load sections) loading a new kernel with 4KB
pages (which is the one we're looking at).

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-20 22:53             ` Maciej W. Rozycki
  0 siblings, 0 replies; 42+ messages in thread
From: Maciej W. Rozycki @ 2018-02-20 22:53 UTC (permalink / raw)
  To: James Hogan
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

On Tue, 20 Feb 2018, James Hogan wrote:

> > >  Since the largest PAGE_SIZE supported by MIPS kernels is 64KB, increase
> > >  the alignment calculated by calc_vmlinuz_load_addr to 64KB.
> > 
> >  But why does it have to be hardcoded?  Shouldn't it be inherited from 
> > the image being loaded?  I'm missing bits of context here, but that 
> > would be either CONFIG_PAGE_SIZE_* settings or the ELF program header's 
> > `p_align' value, depending on how this code operates.  Wasting say 60kB 
> > of memory on smaller systems due to excessive alignment might not be a 
> > good idea.
> 
> I presume there's nothing to stop a kernel with 64KB pages (and hence
> requiring 64KB alignment of load sections) loading a new kernel with 4KB
> pages (which is the one we're looking at).

 As I say, I'm missing bits of context.  If you say that a 64kiB-page 
kernel loads a 4kiB-page kernel, then the alignment for the latter is 
obviously 4kiB.  So I repeat my question: why hardcode the alignment to 
64kiB while we only need 4kiB in this case?

  Maciej

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-20 22:53             ` Maciej W. Rozycki
  0 siblings, 0 replies; 42+ messages in thread
From: Maciej W. Rozycki @ 2018-02-20 22:53 UTC (permalink / raw)
  To: James Hogan
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

On Tue, 20 Feb 2018, James Hogan wrote:

> > >  Since the largest PAGE_SIZE supported by MIPS kernels is 64KB, increase
> > >  the alignment calculated by calc_vmlinuz_load_addr to 64KB.
> > 
> >  But why does it have to be hardcoded?  Shouldn't it be inherited from 
> > the image being loaded?  I'm missing bits of context here, but that 
> > would be either CONFIG_PAGE_SIZE_* settings or the ELF program header's 
> > `p_align' value, depending on how this code operates.  Wasting say 60kB 
> > of memory on smaller systems due to excessive alignment might not be a 
> > good idea.
> 
> I presume there's nothing to stop a kernel with 64KB pages (and hence
> requiring 64KB alignment of load sections) loading a new kernel with 4KB
> pages (which is the one we're looking at).

 As I say, I'm missing bits of context.  If you say that a 64kiB-page 
kernel loads a 4kiB-page kernel, then the alignment for the latter is 
obviously 4kiB.  So I repeat my question: why hardcode the alignment to 
64kiB while we only need 4kiB in this case?

  Maciej

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-20 22:58               ` James Hogan
  0 siblings, 0 replies; 42+ messages in thread
From: James Hogan @ 2018-02-20 22:58 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 1607 bytes --]

On Tue, Feb 20, 2018 at 10:53:19PM +0000, Maciej W. Rozycki wrote:
> On Tue, 20 Feb 2018, James Hogan wrote:
> 
> > > >  Since the largest PAGE_SIZE supported by MIPS kernels is 64KB, increase
> > > >  the alignment calculated by calc_vmlinuz_load_addr to 64KB.
> > > 
> > >  But why does it have to be hardcoded?  Shouldn't it be inherited from 
> > > the image being loaded?  I'm missing bits of context here, but that 
> > > would be either CONFIG_PAGE_SIZE_* settings or the ELF program header's 
> > > `p_align' value, depending on how this code operates.  Wasting say 60kB 
> > > of memory on smaller systems due to excessive alignment might not be a 
> > > good idea.
> > 
> > I presume there's nothing to stop a kernel with 64KB pages (and hence
> > requiring 64KB alignment of load sections) loading a new kernel with 4KB
> > pages (which is the one we're looking at).
> 
>  As I say, I'm missing bits of context.  If you say that a 64kiB-page 
> kernel loads a 4kiB-page kernel, then the alignment for the latter is 
> obviously 4kiB.  So I repeat my question: why hardcode the alignment to 
> 64kiB while we only need 4kiB in this case?

Because its the 1st kernel which is doing the kexec'ing of the 2nd
kernel. The 2nd kernel might not even have kexec enabled, but you still
might want to boot it using kexec.

The only alternative is for the kexec userland tools to be able to
automatically adjust the load segments to load a bit more before the
start of the kernel image so that its aligned, and i'm not sure how
universally safe that would be.

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-20 22:58               ` James Hogan
  0 siblings, 0 replies; 42+ messages in thread
From: James Hogan @ 2018-02-20 22:58 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 1607 bytes --]

On Tue, Feb 20, 2018 at 10:53:19PM +0000, Maciej W. Rozycki wrote:
> On Tue, 20 Feb 2018, James Hogan wrote:
> 
> > > >  Since the largest PAGE_SIZE supported by MIPS kernels is 64KB, increase
> > > >  the alignment calculated by calc_vmlinuz_load_addr to 64KB.
> > > 
> > >  But why does it have to be hardcoded?  Shouldn't it be inherited from 
> > > the image being loaded?  I'm missing bits of context here, but that 
> > > would be either CONFIG_PAGE_SIZE_* settings or the ELF program header's 
> > > `p_align' value, depending on how this code operates.  Wasting say 60kB 
> > > of memory on smaller systems due to excessive alignment might not be a 
> > > good idea.
> > 
> > I presume there's nothing to stop a kernel with 64KB pages (and hence
> > requiring 64KB alignment of load sections) loading a new kernel with 4KB
> > pages (which is the one we're looking at).
> 
>  As I say, I'm missing bits of context.  If you say that a 64kiB-page 
> kernel loads a 4kiB-page kernel, then the alignment for the latter is 
> obviously 4kiB.  So I repeat my question: why hardcode the alignment to 
> 64kiB while we only need 4kiB in this case?

Because its the 1st kernel which is doing the kexec'ing of the 2nd
kernel. The 2nd kernel might not even have kexec enabled, but you still
might want to boot it using kexec.

The only alternative is for the kexec userland tools to be able to
automatically adjust the load segments to load a bit more before the
start of the kernel image so that its aligned, and i'm not sure how
universally safe that would be.

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-20 23:38                 ` Maciej W. Rozycki
  0 siblings, 0 replies; 42+ messages in thread
From: Maciej W. Rozycki @ 2018-02-20 23:38 UTC (permalink / raw)
  To: James Hogan
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

On Tue, 20 Feb 2018, James Hogan wrote:

> >  As I say, I'm missing bits of context.  If you say that a 64kiB-page 
> > kernel loads a 4kiB-page kernel, then the alignment for the latter is 
> > obviously 4kiB.  So I repeat my question: why hardcode the alignment to 
> > 64kiB while we only need 4kiB in this case?
> 
> Because its the 1st kernel which is doing the kexec'ing of the 2nd
> kernel. The 2nd kernel might not even have kexec enabled, but you still
> might want to boot it using kexec.

 Forgive my dumbness, but I don't understand what's preventing the 1st 
kernel from getting the alignment of the 2nd kernel (regardless of 
whether the 2nd kernel has kexec enabled).  What prevents the 1st kernel 
from interpreting the `p_align' value from the relevant program header 
of the 2nd kernel before loading the segment the header describes?  It 
has to load the header anyway or it wouldn't know how much data to load 
and where from into the file, and how much BSS space to initialise.

 Here's an example program header dump from `vmlinux':

$ readelf -l vmlinux

Elf file type is EXEC (Executable file)
Entry point 0x80506e70
There are 3 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  ABIFLAGS       0x4b02e8 0x805ac2e8 0x805ac2e8 0x00018 0x00018 R   0x8
  LOAD           0x004000 0x80100000 0x80100000 0x534650 0x569710 RWE 0x4000
  NOTE           0x4145a8 0x805105a8 0x805105a8 0x00024 0x00024 R   0x4

 Section to Segment mapping:
  Segment Sections...
   00     .MIPS.abiflags
   01     .text __ex_table .notes .rodata .MIPS.abiflags .pci_fixup __ksymtab __ksymtab_gpl __kcrctab __kcrctab_gpl __ksymtab_strings __param __modver .data .init.text .init.data .exit.text .bss
   02     .notes
$ 

As you can see there's only one loadable segment (the usual case) and 
its alignment is 0x4000, that is 16kiB.  So this kernel uses a page size 
of 16kiB.

  Maciej

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-20 23:38                 ` Maciej W. Rozycki
  0 siblings, 0 replies; 42+ messages in thread
From: Maciej W. Rozycki @ 2018-02-20 23:38 UTC (permalink / raw)
  To: James Hogan
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

On Tue, 20 Feb 2018, James Hogan wrote:

> >  As I say, I'm missing bits of context.  If you say that a 64kiB-page 
> > kernel loads a 4kiB-page kernel, then the alignment for the latter is 
> > obviously 4kiB.  So I repeat my question: why hardcode the alignment to 
> > 64kiB while we only need 4kiB in this case?
> 
> Because its the 1st kernel which is doing the kexec'ing of the 2nd
> kernel. The 2nd kernel might not even have kexec enabled, but you still
> might want to boot it using kexec.

 Forgive my dumbness, but I don't understand what's preventing the 1st 
kernel from getting the alignment of the 2nd kernel (regardless of 
whether the 2nd kernel has kexec enabled).  What prevents the 1st kernel 
from interpreting the `p_align' value from the relevant program header 
of the 2nd kernel before loading the segment the header describes?  It 
has to load the header anyway or it wouldn't know how much data to load 
and where from into the file, and how much BSS space to initialise.

 Here's an example program header dump from `vmlinux':

$ readelf -l vmlinux

Elf file type is EXEC (Executable file)
Entry point 0x80506e70
There are 3 program headers, starting at offset 52

Program Headers:
  Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
  ABIFLAGS       0x4b02e8 0x805ac2e8 0x805ac2e8 0x00018 0x00018 R   0x8
  LOAD           0x004000 0x80100000 0x80100000 0x534650 0x569710 RWE 0x4000
  NOTE           0x4145a8 0x805105a8 0x805105a8 0x00024 0x00024 R   0x4

 Section to Segment mapping:
  Segment Sections...
   00     .MIPS.abiflags
   01     .text __ex_table .notes .rodata .MIPS.abiflags .pci_fixup __ksymtab __ksymtab_gpl __kcrctab __kcrctab_gpl __ksymtab_strings __param __modver .data .init.text .init.data .exit.text .bss
   02     .notes
$ 

As you can see there's only one loadable segment (the usual case) and 
its alignment is 0x4000, that is 16kiB.  So this kernel uses a page size 
of 16kiB.

  Maciej

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 12/12] MIPS: Loongson: Introduce and use WAR_LLSC_MB
@ 2018-02-21 10:09         ` Maciej W. Rozycki
  0 siblings, 0 replies; 42+ messages in thread
From: Maciej W. Rozycki @ 2018-02-21 10:09 UTC (permalink / raw)
  To: James Hogan
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

On Tue, 20 Feb 2018, James Hogan wrote:

> > diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform
> > index 0fce460..3700dcf 100644
> > --- a/arch/mips/loongson64/Platform
> > +++ b/arch/mips/loongson64/Platform
> > @@ -23,6 +23,9 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
> >  endif
> >  
> >  cflags-$(CONFIG_CPU_LOONGSON3)	+= -Wa,--trap
> > +ifneq ($(call as-option,-Wa$(comma)-mfix-loongson3-llsc,),)
> > +  cflags-$(CONFIG_CPU_LOONGSON3) += -Wa$(comma)-mno-fix-loongson3-llsc
> > +endif
> 
> Could this be a separate patch?
> 
> This needs more explanation.
> - What does this do exactly?
> - Why are you turning *OFF* the compiler fix?
> - Was some fix we don't want already in use by default?

 FYI, support for `-mfix-loongson3-llsc' in GAS has only recently been 
proposed: <https://sourceware.org/ml/binutils/2018-01/msg00303.html> and 
is still pending review.

  Maciej

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 12/12] MIPS: Loongson: Introduce and use WAR_LLSC_MB
@ 2018-02-21 10:09         ` Maciej W. Rozycki
  0 siblings, 0 replies; 42+ messages in thread
From: Maciej W. Rozycki @ 2018-02-21 10:09 UTC (permalink / raw)
  To: James Hogan
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

On Tue, 20 Feb 2018, James Hogan wrote:

> > diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform
> > index 0fce460..3700dcf 100644
> > --- a/arch/mips/loongson64/Platform
> > +++ b/arch/mips/loongson64/Platform
> > @@ -23,6 +23,9 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
> >  endif
> >  
> >  cflags-$(CONFIG_CPU_LOONGSON3)	+= -Wa,--trap
> > +ifneq ($(call as-option,-Wa$(comma)-mfix-loongson3-llsc,),)
> > +  cflags-$(CONFIG_CPU_LOONGSON3) += -Wa$(comma)-mno-fix-loongson3-llsc
> > +endif
> 
> Could this be a separate patch?
> 
> This needs more explanation.
> - What does this do exactly?
> - Why are you turning *OFF* the compiler fix?
> - Was some fix we don't want already in use by default?

 FYI, support for `-mfix-loongson3-llsc' in GAS has only recently been 
proposed: <https://sourceware.org/ml/binutils/2018-01/msg00303.html> and 
is still pending review.

  Maciej

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-21 11:13                   ` James Hogan
  0 siblings, 0 replies; 42+ messages in thread
From: James Hogan @ 2018-02-21 11:13 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 2901 bytes --]

On Tue, Feb 20, 2018 at 11:38:26PM +0000, Maciej W. Rozycki wrote:
> On Tue, 20 Feb 2018, James Hogan wrote:
> 
> > >  As I say, I'm missing bits of context.  If you say that a 64kiB-page 
> > > kernel loads a 4kiB-page kernel, then the alignment for the latter is 
> > > obviously 4kiB.  So I repeat my question: why hardcode the alignment to 
> > > 64kiB while we only need 4kiB in this case?
> > 
> > Because its the 1st kernel which is doing the kexec'ing of the 2nd
> > kernel. The 2nd kernel might not even have kexec enabled, but you still
> > might want to boot it using kexec.
> 
>  Forgive my dumbness, but I don't understand what's preventing the 1st 
> kernel from getting the alignment of the 2nd kernel (regardless of 
> whether the 2nd kernel has kexec enabled).  What prevents the 1st kernel 
> from interpreting the `p_align' value from the relevant program header 
> of the 2nd kernel before loading the segment the header describes?  It 
> has to load the header anyway or it wouldn't know how much data to load 
> and where from into the file, and how much BSS space to initialise.

The kernel doesn't always get an elf through kexec_load(2), but rather a
list of load segments. In any case though its not about knowing the
page size of 2nd kernel, its about kexec working with page size chunks.
See the comment in sanity_check_segment_list().

> 
>  Here's an example program header dump from `vmlinux':
> 
> $ readelf -l vmlinux

Yeh but its not a vmlinux, its a vmlinuz. Thats the whole point. Though
it sounds like you'd have the same problem with vmlinux too if you tried
reducing the page size, so perhaps its fine for compressed kernels to
just align to the page size of the 2nd kernel, so they're no worse than
vmlinux.

> 
> Elf file type is EXEC (Executable file)
> Entry point 0x80506e70
> There are 3 program headers, starting at offset 52
> 
> Program Headers:
>   Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
>   ABIFLAGS       0x4b02e8 0x805ac2e8 0x805ac2e8 0x00018 0x00018 R   0x8
>   LOAD           0x004000 0x80100000 0x80100000 0x534650 0x569710 RWE 0x4000
>   NOTE           0x4145a8 0x805105a8 0x805105a8 0x00024 0x00024 R   0x4
> 
>  Section to Segment mapping:
>   Segment Sections...
>    00     .MIPS.abiflags
>    01     .text __ex_table .notes .rodata .MIPS.abiflags .pci_fixup __ksymtab __ksymtab_gpl __kcrctab __kcrctab_gpl __ksymtab_strings __param __modver .data .init.text .init.data .exit.text .bss
>    02     .notes
> $ 
> 
> As you can see there's only one loadable segment (the usual case) and 
> its alignment is 0x4000, that is 16kiB.  So this kernel uses a page size 
> of 16kiB.

For malta_defconfig *vmlinuz* however (CONFIG_PAGE_SIZE_16KB=y), I get
this:
  LOAD           0x008320 0x80828320 0x80828320 0x35e580 0x8605a0 RWE 0x10000

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-21 11:13                   ` James Hogan
  0 siblings, 0 replies; 42+ messages in thread
From: James Hogan @ 2018-02-21 11:13 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 2901 bytes --]

On Tue, Feb 20, 2018 at 11:38:26PM +0000, Maciej W. Rozycki wrote:
> On Tue, 20 Feb 2018, James Hogan wrote:
> 
> > >  As I say, I'm missing bits of context.  If you say that a 64kiB-page 
> > > kernel loads a 4kiB-page kernel, then the alignment for the latter is 
> > > obviously 4kiB.  So I repeat my question: why hardcode the alignment to 
> > > 64kiB while we only need 4kiB in this case?
> > 
> > Because its the 1st kernel which is doing the kexec'ing of the 2nd
> > kernel. The 2nd kernel might not even have kexec enabled, but you still
> > might want to boot it using kexec.
> 
>  Forgive my dumbness, but I don't understand what's preventing the 1st 
> kernel from getting the alignment of the 2nd kernel (regardless of 
> whether the 2nd kernel has kexec enabled).  What prevents the 1st kernel 
> from interpreting the `p_align' value from the relevant program header 
> of the 2nd kernel before loading the segment the header describes?  It 
> has to load the header anyway or it wouldn't know how much data to load 
> and where from into the file, and how much BSS space to initialise.

The kernel doesn't always get an elf through kexec_load(2), but rather a
list of load segments. In any case though its not about knowing the
page size of 2nd kernel, its about kexec working with page size chunks.
See the comment in sanity_check_segment_list().

> 
>  Here's an example program header dump from `vmlinux':
> 
> $ readelf -l vmlinux

Yeh but its not a vmlinux, its a vmlinuz. Thats the whole point. Though
it sounds like you'd have the same problem with vmlinux too if you tried
reducing the page size, so perhaps its fine for compressed kernels to
just align to the page size of the 2nd kernel, so they're no worse than
vmlinux.

> 
> Elf file type is EXEC (Executable file)
> Entry point 0x80506e70
> There are 3 program headers, starting at offset 52
> 
> Program Headers:
>   Type           Offset   VirtAddr   PhysAddr   FileSiz MemSiz  Flg Align
>   ABIFLAGS       0x4b02e8 0x805ac2e8 0x805ac2e8 0x00018 0x00018 R   0x8
>   LOAD           0x004000 0x80100000 0x80100000 0x534650 0x569710 RWE 0x4000
>   NOTE           0x4145a8 0x805105a8 0x805105a8 0x00024 0x00024 R   0x4
> 
>  Section to Segment mapping:
>   Segment Sections...
>    00     .MIPS.abiflags
>    01     .text __ex_table .notes .rodata .MIPS.abiflags .pci_fixup __ksymtab __ksymtab_gpl __kcrctab __kcrctab_gpl __ksymtab_strings __param __modver .data .init.text .init.data .exit.text .bss
>    02     .notes
> $ 
> 
> As you can see there's only one loadable segment (the usual case) and 
> its alignment is 0x4000, that is 16kiB.  So this kernel uses a page size 
> of 16kiB.

For malta_defconfig *vmlinuz* however (CONFIG_PAGE_SIZE_16KB=y), I get
this:
  LOAD           0x008320 0x80828320 0x80828320 0x35e580 0x8605a0 RWE 0x10000

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 12/12] MIPS: Loongson: Introduce and use WAR_LLSC_MB
  2018-02-21 10:09         ` Maciej W. Rozycki
  (?)
@ 2018-02-21 11:43         ` James Hogan
  -1 siblings, 0 replies; 42+ messages in thread
From: James Hogan @ 2018-02-21 11:43 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 1390 bytes --]

On Wed, Feb 21, 2018 at 10:09:06AM +0000, Maciej W. Rozycki wrote:
> On Tue, 20 Feb 2018, James Hogan wrote:
> 
> > > diff --git a/arch/mips/loongson64/Platform b/arch/mips/loongson64/Platform
> > > index 0fce460..3700dcf 100644
> > > --- a/arch/mips/loongson64/Platform
> > > +++ b/arch/mips/loongson64/Platform
> > > @@ -23,6 +23,9 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS
> > >  endif
> > >  
> > >  cflags-$(CONFIG_CPU_LOONGSON3)	+= -Wa,--trap
> > > +ifneq ($(call as-option,-Wa$(comma)-mfix-loongson3-llsc,),)
> > > +  cflags-$(CONFIG_CPU_LOONGSON3) += -Wa$(comma)-mno-fix-loongson3-llsc
> > > +endif
> > 
> > Could this be a separate patch?
> > 
> > This needs more explanation.
> > - What does this do exactly?
> > - Why are you turning *OFF* the compiler fix?
> > - Was some fix we don't want already in use by default?
> 
>  FYI, support for `-mfix-loongson3-llsc' in GAS has only recently been 
> proposed: <https://sourceware.org/ml/binutils/2018-01/msg00303.html> and 
> is still pending review.

Thanks for that link Maciej. GNU changelogs are useless, so this is the
interesting bit:
> +@item -mfix-loongson3-llsc
> +@itemx -mno-fix-loongson3-llsc
> +Insert @code{sync} instruction before @samp{ll} or @samp{lld} instrction
> +to work around Loongson3 @samp{LL}/@samp{SC} errata.
> +This issue exists in all Loongson3 CPUs.

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-26 12:41                     ` Maciej W. Rozycki
  0 siblings, 0 replies; 42+ messages in thread
From: Maciej W. Rozycki @ 2018-02-26 12:41 UTC (permalink / raw)
  To: James Hogan
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

On Wed, 21 Feb 2018, James Hogan wrote:

> >  Forgive my dumbness, but I don't understand what's preventing the 1st 
> > kernel from getting the alignment of the 2nd kernel (regardless of 
> > whether the 2nd kernel has kexec enabled).  What prevents the 1st kernel 
> > from interpreting the `p_align' value from the relevant program header 
> > of the 2nd kernel before loading the segment the header describes?  It 
> > has to load the header anyway or it wouldn't know how much data to load 
> > and where from into the file, and how much BSS space to initialise.
> 
> The kernel doesn't always get an elf through kexec_load(2), but rather a
> list of load segments. In any case though its not about knowing the
> page size of 2nd kernel, its about kexec working with page size chunks.
> See the comment in sanity_check_segment_list().

 So this is 1st kernel's page size AFAICT.  And I can see `struct 
kexec_segment' drops ELF program header information, sigh.

> >  Here's an example program header dump from `vmlinux':
> > 
> > $ readelf -l vmlinux
> 
> Yeh but its not a vmlinux, its a vmlinuz. Thats the whole point. Though
> it sounds like you'd have the same problem with vmlinux too if you tried
> reducing the page size, so perhaps its fine for compressed kernels to
> just align to the page size of the 2nd kernel, so they're no worse than
> vmlinux.

 Well, even if compressed you need to preserve the original structures 
somehow so that once uncompressed the memory image is the same as if 
`vmlinux' was loaded directly.

> > As you can see there's only one loadable segment (the usual case) and 
> > its alignment is 0x4000, that is 16kiB.  So this kernel uses a page size 
> > of 16kiB.
> 
> For malta_defconfig *vmlinuz* however (CONFIG_PAGE_SIZE_16KB=y), I get
> this:
>   LOAD           0x008320 0x80828320 0x80828320 0x35e580 0x8605a0 RWE 0x10000

 Hmm, now you've left me stumped, so I'll shut up.

  Maciej

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 08/12] MIPS: Align kernel load address to 64KB
@ 2018-02-26 12:41                     ` Maciej W. Rozycki
  0 siblings, 0 replies; 42+ messages in thread
From: Maciej W. Rozycki @ 2018-02-26 12:41 UTC (permalink / raw)
  To: James Hogan
  Cc: Huacai Chen, Ralf Baechle, Steven J . Hill, linux-mips,
	Fuxin Zhang, Zhangjin Wu

On Wed, 21 Feb 2018, James Hogan wrote:

> >  Forgive my dumbness, but I don't understand what's preventing the 1st 
> > kernel from getting the alignment of the 2nd kernel (regardless of 
> > whether the 2nd kernel has kexec enabled).  What prevents the 1st kernel 
> > from interpreting the `p_align' value from the relevant program header 
> > of the 2nd kernel before loading the segment the header describes?  It 
> > has to load the header anyway or it wouldn't know how much data to load 
> > and where from into the file, and how much BSS space to initialise.
> 
> The kernel doesn't always get an elf through kexec_load(2), but rather a
> list of load segments. In any case though its not about knowing the
> page size of 2nd kernel, its about kexec working with page size chunks.
> See the comment in sanity_check_segment_list().

 So this is 1st kernel's page size AFAICT.  And I can see `struct 
kexec_segment' drops ELF program header information, sigh.

> >  Here's an example program header dump from `vmlinux':
> > 
> > $ readelf -l vmlinux
> 
> Yeh but its not a vmlinux, its a vmlinuz. Thats the whole point. Though
> it sounds like you'd have the same problem with vmlinux too if you tried
> reducing the page size, so perhaps its fine for compressed kernels to
> just align to the page size of the 2nd kernel, so they're no worse than
> vmlinux.

 Well, even if compressed you need to preserve the original structures 
somehow so that once uncompressed the memory image is the same as if 
`vmlinux' was loaded directly.

> > As you can see there's only one loadable segment (the usual case) and 
> > its alignment is 0x4000, that is 16kiB.  So this kernel uses a page size 
> > of 16kiB.
> 
> For malta_defconfig *vmlinuz* however (CONFIG_PAGE_SIZE_16KB=y), I get
> this:
>   LOAD           0x008320 0x80828320 0x80828320 0x35e580 0x8605a0 RWE 0x10000

 Hmm, now you've left me stumped, so I'll shut up.

  Maciej

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 00/12] MIPS: Loongson: new features and improvements
  2018-02-15 11:05 ` [PATCH V2 00/12] MIPS: Loongson: new features and improvements James Hogan
@ 2018-02-28  2:23   ` Huacai Chen
  2018-02-28 10:03     ` James Hogan
  0 siblings, 1 reply; 42+ messages in thread
From: Huacai Chen @ 2018-02-28  2:23 UTC (permalink / raw)
  To: James Hogan
  Cc: Ralf Baechle, Steven J . Hill, Linux MIPS Mailing List,
	Fuxin Zhang, Zhangjin Wu

Hi, James,

I really don't want send many patches in a seris. But in practise, my
single patch in linux-mips usually be ignored (even they are very
simple and well described)....

For example:
https://patchwork.linux-mips.org/patch/17723/
https://patchwork.linux-mips.org/patch/18587/
https://patchwork.linux-mips.org/patch/18682/

Anyway, thank you for your susggestions, I will rework other patches.

Huacai

On Thu, Feb 15, 2018 at 7:05 PM, James Hogan <jhogan@kernel.org> wrote:
> On Sat, Jan 27, 2018 at 11:12:20AM +0800, Huacai Chen wrote:
>> This patchset is prepared for the next 4.16 release for Linux/MIPS. It
>> add Loongson-3A R3.1 support, enable Loongson-3's SFB at runtime, adds
>> "model name" and "CPU MHz" knobs in /proc/cpuinfo which is needed by
>> some userspace tools, adds Loongson-3 kexec/kdump and CPUFreq support,
>> fixes CPU UART irq delivery problem, and introduces WAR_LLSC_MB to
>> improve stability.
>>
>> V1 -> V2:
>> 1, Add Loongson-3A R3.1 basic support.
>> 2, Fix CPU UART irq delivery problem.
>> 3, Improve code and descriptions (Thank James Hogan).
>> 4, Sync the code to upstream.
>
> I few general suggestions that I hope will help you to get your patches
> applied quicker:
>
> - Please have a separate series for each group of related changes in
>   future. It makes them more manageable, makes dependencies clearer, and
>   avoids unchanged resends of unrelated patches when you respin the
>   whole series. Series are mainly to group tightly related patches, or
>   because of dependencies of later patches on earlier ones (and even if
>   you have a series of 30 dependent patches, you can still sometimes
>   split it into groups and mention in the cover letters which other
>   pending series each series depends on).
>
> - More importantly, avoid moving patches between series or adding
>   unrelated patches to a series if possible (so probably best not to
>   split this series now). It makes it harder to see what has changed,
>   whether past feedback has been addressed, and whether new/removed
>   patches are new/abandoned or simply moved from/to a different series.
>
> - Please don't resend a series without changes, ping it if you are
>   concerned. It clutters patchwork for no good reason and makes it
>   harder to see if past feedback has been addressed.
>
> - Please run checkpatch on all patches before submission, and fix any
>   reasonable warnings and errors (i.e. there are various lines exceeding
>   80 characters in this series which should be split, but some are
>   acceptable where its to keep a string together).
>
> - Please include Fixes tags where appropriate, especially where you've
>   Cc'd stable.
>
> - If you Cc stable, please state how far back it should be backported
>   wherever possible,
>   E.g. Cc: <stable@vger.kernel.org> # 4.14+
>   This may help finding what version a commit is first included in:
>   https://www.linux-mips.org/archives/linux-mips/2017-07/msg00149.html
>
> - Please run get_maintainer.pl on each patch to make sure you cc the
>   appropriate maintainers and lists (and Cc them on the cover letter
>   too). Its fine to skip LKML for lots of MIPS patches, but don't miss
>   out the appropriate subsystem maintainers and lists for patches
>   touching drivers/ or they'll never get acked and never get applied.
>
> - Split arch/mips/ and drivers/ patches wherever possible.
>
> Cheers
> James

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 00/12] MIPS: Loongson: new features and improvements
  2018-02-28  2:23   ` Huacai Chen
@ 2018-02-28 10:03     ` James Hogan
  2018-03-01  2:35       ` Huacai Chen
  0 siblings, 1 reply; 42+ messages in thread
From: James Hogan @ 2018-02-28 10:03 UTC (permalink / raw)
  To: Huacai Chen
  Cc: Ralf Baechle, Steven J . Hill, Linux MIPS Mailing List,
	Fuxin Zhang, Zhangjin Wu

[-- Attachment #1: Type: text/plain, Size: 1640 bytes --]

On Wed, Feb 28, 2018 at 10:23:09AM +0800, Huacai Chen wrote:
> Hi, James,
> 
> I really don't want send many patches in a seris. But in practise, my
> single patch in linux-mips usually be ignored (even they are very
> simple and well described)....

Then please feel free to reply to the patch and ask if anybody has
feedback, stating how important the patch is for you, so it can be
prioritised. Resends as part of other series just adds to the noise.

> 
> For example:
> https://patchwork.linux-mips.org/patch/17723/

Yes, that one needs a proper look.

> https://patchwork.linux-mips.org/patch/18587/

This one apparently knowingly breaks the feature on other platforms, so
can't really be applied as is. I think Matt Redfearn & I were thinking
his single IPI stuff could potentially be helpful there too.

> https://patchwork.linux-mips.org/patch/18682/

You sent that this morning so its hardly had time to be ignored, and I
had already spotted it on my phone and intended to apply it today. Also
I disagree that "Commit x breaks Loongson64 platforms, so fix it" counts
as well described, even if it is simple, and obvious (to me at least)
what you're talking about.

E.g. a better description would along the lines of:

Commit 7a407aa5e0d3 ("MIPS: Push ARCH_MIGHT_HAVE_PC_SERIO down to
platform level") moves the global MIPS ARCH_MIGHT_HAVE_PC_SERIO select
down to various platforms, but doesn't add it to Loongson64 platforms
which need it, so add the selects to these platforms too.

> 
> Anyway, thank you for your susggestions, I will rework other patches.

Thank you.

Cheers
James

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply	[flat|nested] 42+ messages in thread

* Re: [PATCH V2 00/12] MIPS: Loongson: new features and improvements
  2018-02-28 10:03     ` James Hogan
@ 2018-03-01  2:35       ` Huacai Chen
  0 siblings, 0 replies; 42+ messages in thread
From: Huacai Chen @ 2018-03-01  2:35 UTC (permalink / raw)
  To: James Hogan
  Cc: Ralf Baechle, Steven J . Hill, Linux MIPS Mailing List,
	Fuxin Zhang, Zhangjin Wu

On Wed, Feb 28, 2018 at 6:03 PM, James Hogan <jhogan@kernel.org> wrote:
> On Wed, Feb 28, 2018 at 10:23:09AM +0800, Huacai Chen wrote:
>> Hi, James,
>>
>> I really don't want send many patches in a seris. But in practise, my
>> single patch in linux-mips usually be ignored (even they are very
>> simple and well described)....
>
> Then please feel free to reply to the patch and ask if anybody has
> feedback, stating how important the patch is for you, so it can be
> prioritised. Resends as part of other series just adds to the noise.
>
>>
>> For example:
>> https://patchwork.linux-mips.org/patch/17723/
>
> Yes, that one needs a proper look.
>
>> https://patchwork.linux-mips.org/patch/18587/
>
> This one apparently knowingly breaks the feature on other platforms, so
> can't really be applied as is. I think Matt Redfearn & I were thinking
> his single IPI stuff could potentially be helpful there too.
I think this does't break other platforms, because:
1, arch_trigger_cpumask_backtrace() will not be called in normal cases;
2, If arch_trigger_cpumask_backtrace() really be called, the old code
also doesn't work (deadlock).

>
>> https://patchwork.linux-mips.org/patch/18682/
>
> You sent that this morning so its hardly had time to be ignored, and I
> had already spotted it on my phone and intended to apply it today. Also
> I disagree that "Commit x breaks Loongson64 platforms, so fix it" counts
> as well described, even if it is simple, and obvious (to me at least)
> what you're talking about.
>
> E.g. a better description would along the lines of:
>
> Commit 7a407aa5e0d3 ("MIPS: Push ARCH_MIGHT_HAVE_PC_SERIO down to
> platform level") moves the global MIPS ARCH_MIGHT_HAVE_PC_SERIO select
> down to various platforms, but doesn't add it to Loongson64 platforms
> which need it, so add the selects to these platforms too.
I'll update my commit messages.

>
>>
>> Anyway, thank you for your susggestions, I will rework other patches.
>
> Thank you.
>
> Cheers
> James

^ permalink raw reply	[flat|nested] 42+ messages in thread

end of thread, other threads:[~2018-03-01  2:35 UTC | newest]

Thread overview: 42+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-01-27  3:12 [PATCH V2 00/12] MIPS: Loongson: new features and improvements Huacai Chen
2018-01-27  3:12 ` [PATCH V2 01/12] MIPS: Loongson: Add Loongson-3A R3.1 basic support Huacai Chen
2018-01-27  3:12 ` [PATCH V2 02/12] MIPS: Loongson64: Define and use some CP0 registers Huacai Chen
2018-02-15 11:36   ` James Hogan
2018-01-27  3:12 ` [PATCH V2 03/12] MIPS: Loongson-3: Enable Store Fill Buffer at runtime Huacai Chen
2018-02-15 12:43   ` James Hogan
2018-01-27  3:19 ` [PATCH V2 04/12] MIPS: c-r4k: Add r4k_blast_scache_node for Loongson-3 Huacai Chen
2018-02-19 22:19   ` James Hogan
2018-01-27  3:20 ` [PATCH V2 05/12] MIPS: Loongson fix name confict - MEM_RESERVED Huacai Chen
2018-01-27  3:21 ` [PATCH V2 06/12] MIPS: Ensure pmd_present() returns false after pmd_mknotpresent() Huacai Chen
2018-01-27  3:22 ` [PATCH V2 07/12] MIPS: Add __cpu_full_name[] to make CPU names more human-readable Huacai Chen
2018-01-27  3:22   ` [PATCH V2 08/12] MIPS: Align kernel load address to 64KB Huacai Chen
2018-02-19 23:07     ` James Hogan
2018-02-20 22:14       ` Maciej W. Rozycki
2018-02-20 22:14         ` Maciej W. Rozycki
2018-02-20 22:25         ` James Hogan
2018-02-20 22:25           ` James Hogan
2018-02-20 22:53           ` Maciej W. Rozycki
2018-02-20 22:53             ` Maciej W. Rozycki
2018-02-20 22:58             ` James Hogan
2018-02-20 22:58               ` James Hogan
2018-02-20 23:38               ` Maciej W. Rozycki
2018-02-20 23:38                 ` Maciej W. Rozycki
2018-02-21 11:13                 ` James Hogan
2018-02-21 11:13                   ` James Hogan
2018-02-26 12:41                   ` Maciej W. Rozycki
2018-02-26 12:41                     ` Maciej W. Rozycki
2018-01-27  3:22   ` [PATCH V2 09/12] MIPS: Loongson: Add kexec/kdump support Huacai Chen
2018-02-19 23:54     ` James Hogan
2018-01-27  3:22 ` [PATCH V2 10/12] MIPS: Loongson: Make CPUFreq usable for Loongson-3 Huacai Chen
2018-01-27  3:23   ` [PATCH V2 11/12] MIPS: Loongson-3: Fix CPU UART irq delivery problem Huacai Chen
2018-02-20 21:49     ` James Hogan
2018-01-27  3:23   ` [PATCH V2 12/12] MIPS: Loongson: Introduce and use WAR_LLSC_MB Huacai Chen
2018-02-20 22:21     ` James Hogan
2018-02-21 10:09       ` Maciej W. Rozycki
2018-02-21 10:09         ` Maciej W. Rozycki
2018-02-21 11:43         ` James Hogan
2018-02-20 21:42   ` [PATCH V2 10/12] MIPS: Loongson: Make CPUFreq usable for Loongson-3 James Hogan
2018-02-15 11:05 ` [PATCH V2 00/12] MIPS: Loongson: new features and improvements James Hogan
2018-02-28  2:23   ` Huacai Chen
2018-02-28 10:03     ` James Hogan
2018-03-01  2:35       ` Huacai Chen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.