[linux] 01/01: [mips{, 64}el/loongson-3] Add support for Loongson-3A/B 3000 CPUs

debian-kernel at lists.debian.org debian-kernel at lists.debian.org
Sun Sep 24 23:36:32 UTC 2017


This is an automated email from the git hooks/post-receive script.

benh pushed a commit to branch stretch
in repository linux.

commit 58dba0c32a0753be40e070fbc86dcf776f8cb33d
Author: Ben Hutchings <ben at decadent.org.uk>
Date:   Mon Sep 25 00:35:30 2017 +0100

    [mips{,64}el/loongson-3] Add support for Loongson-3A/B 3000 CPUs
    
    Thanks to YunQiang Su.
    
    Closes: #871701
    
    - Add Loongson-3A R3 basic support
    - Add NMI handler support
    - Support 4 packages in CPU Hwmon driver
    - IRQ balancing for PCI devices
    - support irq_set_affinity() in i8259 chip
    - Make enum loongson_cpu_type more clear
---
 debian/changelog                                   |   8 +
 ...on-make-enum-loongson_cpu_type-more-clear.patch |  88 ++++++++++
 ...-loongson-3-irq-balancing-for-pci-devices.patch | 101 +++++++++++
 ...on-3-support-4-packages-in-cpu-hwmon-driv.patch | 192 +++++++++++++++++++++
 ...on-3-support-irq_set_affinity-in-i8259-ch.patch | 123 +++++++++++++
 ...loongson-add-loongson-3a-r3-basic-support.patch | 120 +++++++++++++
 .../mips-loongson-add-nmi-handler-support.patch    |  54 ++++++
 debian/patches/series                              |   6 +
 8 files changed, 692 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index c88e123..e75e616 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -117,6 +117,14 @@ linux (4.9.51-1) UNRELEASED; urgency=medium
   * Fix regressions caused by fix for CVE-2016-7097 (Closes: #873026):
     - ext4: preserve i_mode if __ext4_set_acl() fails
     - ext4: Don't clear SGID when inheriting ACLs
+  * [mips{,64}el/loongson-3] Add support for Loongson-3A/B 3000 CPUs, thanks to
+    YunQiang Su (Closes: #871701):
+    - Add Loongson-3A R3 basic support
+    - Add NMI handler support
+    - Support 4 packages in CPU Hwmon driver
+    - IRQ balancing for PCI devices
+    - support irq_set_affinity() in i8259 chip
+    - Make enum loongson_cpu_type more clear
 
  -- Ben Hutchings <ben at decadent.org.uk>  Tue, 19 Sep 2017 00:38:28 +0100
 
diff --git a/debian/patches/features/mips/mips-loogson-make-enum-loongson_cpu_type-more-clear.patch b/debian/patches/features/mips/mips-loogson-make-enum-loongson_cpu_type-more-clear.patch
new file mode 100644
index 0000000..427a02e
--- /dev/null
+++ b/debian/patches/features/mips/mips-loogson-make-enum-loongson_cpu_type-more-clear.patch
@@ -0,0 +1,88 @@
+From: Huacai Chen <chenhc at lemote.com>
+Date: Thu, 22 Jun 2017 23:06:54 +0800
+Subject: [6/6] MIPS: Loogson: Make enum loongson_cpu_type more clear
+Origin: https://git.kernel.org/linus/b9c4dc2cf9af62bc0d2d8504c15175aeac49ad53
+Bug-Debian: https://bugs.debian.org/871701
+
+Sort enum loongson_cpu_type in a more reasonable manner, this makes the
+CPU names more clear and extensible. Those already defined enum values
+are renamed to Legacy_* for compatibility.
+
+Signed-off-by: Huacai Chen <chenhc at lemote.com>
+Cc: John Crispin <john at phrozen.org>
+Cc: Steven J . Hill <Steven.Hill at cavium.com>
+Cc: Fuxin Zhang <zhangfx at lemote.com>
+Cc: Zhangjin Wu <wuzhangjin at gmail.com>
+Cc: linux-mips at linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/16591/
+Signed-off-by: Ralf Baechle <ralf at linux-mips.org>
+---
+ arch/mips/include/asm/mach-loongson64/boot_param.h | 22 ++++++++++++++++------
+ arch/mips/loongson64/common/env.c                  | 11 ++++++++---
+ 2 files changed, 24 insertions(+), 9 deletions(-)
+
+--- a/arch/mips/include/asm/mach-loongson64/boot_param.h
++++ b/arch/mips/include/asm/mach-loongson64/boot_param.h
+@@ -27,12 +27,22 @@ struct efi_memory_map_loongson {
+ } __packed;
+ 
+ enum loongson_cpu_type {
+-	Loongson_2E = 0,
+-	Loongson_2F = 1,
+-	Loongson_3A = 2,
+-	Loongson_3B = 3,
+-	Loongson_1A = 4,
+-	Loongson_1B = 5
++	Legacy_2E = 0x0,
++	Legacy_2F = 0x1,
++	Legacy_3A = 0x2,
++	Legacy_3B = 0x3,
++	Legacy_1A = 0x4,
++	Legacy_1B = 0x5,
++	Legacy_2G = 0x6,
++	Legacy_2H = 0x7,
++	Loongson_1A = 0x100,
++	Loongson_1B = 0x101,
++	Loongson_2E = 0x200,
++	Loongson_2F = 0x201,
++	Loongson_2G = 0x202,
++	Loongson_2H = 0x203,
++	Loongson_3A = 0x300,
++	Loongson_3B = 0x301
+ };
+ 
+ /*
+--- a/arch/mips/loongson64/common/env.c
++++ b/arch/mips/loongson64/common/env.c
+@@ -90,7 +90,9 @@ void __init prom_init_env(void)
+ 
+ 	cpu_clock_freq = ecpu->cpu_clock_freq;
+ 	loongson_sysconf.cputype = ecpu->cputype;
+-	if (ecpu->cputype == Loongson_3A) {
++	switch (ecpu->cputype) {
++	case Legacy_3A:
++	case Loongson_3A:
+ 		loongson_sysconf.cores_per_node = 4;
+ 		loongson_sysconf.cores_per_package = 4;
+ 		smp_group[0] = 0x900000003ff01000;
+@@ -111,7 +113,9 @@ void __init prom_init_env(void)
+ 		loongson_freqctrl[3] = 0x900030001fe001d0;
+ 		loongson_sysconf.ht_control_base = 0x90000EFDFB000000;
+ 		loongson_sysconf.workarounds = WORKAROUND_CPUFREQ;
+-	} else if (ecpu->cputype == Loongson_3B) {
++		break;
++	case Legacy_3B:
++	case Loongson_3B:
+ 		loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */
+ 		loongson_sysconf.cores_per_package = 8;
+ 		smp_group[0] = 0x900000003ff01000;
+@@ -132,7 +136,8 @@ void __init prom_init_env(void)
+ 		loongson_freqctrl[3] = 0x900060001fe001d0;
+ 		loongson_sysconf.ht_control_base = 0x90001EFDFB000000;
+ 		loongson_sysconf.workarounds = WORKAROUND_CPUHOTPLUG;
+-	} else {
++		break;
++	default:
+ 		loongson_sysconf.cores_per_node = 1;
+ 		loongson_sysconf.cores_per_package = 1;
+ 		loongson_chipcfg[0] = 0x900000001fe00180;
diff --git a/debian/patches/features/mips/mips-loongson-3-irq-balancing-for-pci-devices.patch b/debian/patches/features/mips/mips-loongson-3-irq-balancing-for-pci-devices.patch
new file mode 100644
index 0000000..4c4478a
--- /dev/null
+++ b/debian/patches/features/mips/mips-loongson-3-irq-balancing-for-pci-devices.patch
@@ -0,0 +1,101 @@
+From: Huacai Chen <chenhc at lemote.com>
+Date: Thu, 22 Jun 2017 23:06:52 +0800
+Subject: [4/6] MIPS: Loongson-3: IRQ balancing for PCI devices
+Origin: https://git.kernel.org/linus/e1b88ca8d72193e48bac026b19b8c686cc7fea25
+Bug-Debian: https://bugs.debian.org/871701
+
+IRQ0 (HPET), IRQ1 (Keyboard), IRQ2 (Cascade), IRQ7 (SCI), IRQ8 (RTC)
+and IRQ12 (Mouse) are handled by core-0 locally. Other PCI IRQs (3, 4,
+5, 6, 14, 15) are balanced by all cores from Node-0. This can improve
+I/O performance significantly.
+
+Signed-off-by: Huacai Chen <chenhc at lemote.com>
+Cc: John Crispin <john at phrozen.org>
+Cc: Steven J . Hill <Steven.Hill at cavium.com>
+Cc: Fuxin Zhang <zhangfx at lemote.com>
+Cc: Zhangjin Wu <wuzhangjin at gmail.com>
+Cc: linux-mips at linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/16589/
+Signed-off-by: Ralf Baechle <ralf at linux-mips.org>
+---
+ arch/mips/loongson64/loongson-3/irq.c | 19 +++++++++++++++++--
+ arch/mips/loongson64/loongson-3/smp.c | 18 +++++++++++++++++-
+ 2 files changed, 34 insertions(+), 3 deletions(-)
+
+--- a/arch/mips/loongson64/loongson-3/irq.c
++++ b/arch/mips/loongson64/loongson-3/irq.c
+@@ -9,17 +9,32 @@
+ 
+ #include "smp.h"
+ 
++extern void loongson3_send_irq_by_ipi(int cpu, int irqs);
+ unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15};
++unsigned int local_irq = 1<<0 | 1<<1 | 1<<2 | 1<<7 | 1<<8 | 1<<12;
+ 
+ static void ht_irqdispatch(void)
+ {
+-	unsigned int i, irq;
++	unsigned int i, irq, irq0, irq1;
++	static unsigned int dest_cpu = 0;
+ 
+ 	irq = LOONGSON_HT1_INT_VECTOR(0);
+ 	LOONGSON_HT1_INT_VECTOR(0) = irq; /* Acknowledge the IRQs */
+ 
++	irq0 = irq & local_irq;  /* handled by local core */
++	irq1 = irq & ~local_irq; /* balanced by other cores */
++
++	if (dest_cpu == 0 || !cpu_online(dest_cpu))
++		irq0 |= irq1;
++	else
++		loongson3_send_irq_by_ipi(dest_cpu, irq1);
++
++	dest_cpu = dest_cpu + 1;
++	if (dest_cpu >= num_possible_cpus() || cpu_data[dest_cpu].package > 0)
++		dest_cpu = 0;
++
+ 	for (i = 0; i < ARRAY_SIZE(ht_irq); i++) {
+-		if (irq & (0x1 << ht_irq[i]))
++		if (irq0 & (0x1 << ht_irq[i]))
+ 			do_IRQ(ht_irq[i]);
+ 	}
+ }
+--- a/arch/mips/loongson64/loongson-3/smp.c
++++ b/arch/mips/loongson64/loongson-3/smp.c
+@@ -252,13 +252,21 @@ loongson3_send_ipi_mask(const struct cpu
+ 		loongson3_ipi_write32((u32)action, ipi_set0_regs[cpu_logical_map(i)]);
+ }
+ 
++#define IPI_IRQ_OFFSET 6
++
++void loongson3_send_irq_by_ipi(int cpu, int irqs)
++{
++	loongson3_ipi_write32(irqs << IPI_IRQ_OFFSET, ipi_set0_regs[cpu_logical_map(cpu)]);
++}
++
+ void loongson3_ipi_interrupt(struct pt_regs *regs)
+ {
+ 	int i, cpu = smp_processor_id();
+-	unsigned int action, c0count;
++	unsigned int action, c0count, irqs;
+ 
+ 	/* Load the ipi register to figure out what we're supposed to do */
+ 	action = loongson3_ipi_read32(ipi_status0_regs[cpu_logical_map(cpu)]);
++	irqs = action >> IPI_IRQ_OFFSET;
+ 
+ 	/* Clear the ipi register to clear the interrupt */
+ 	loongson3_ipi_write32((u32)action, ipi_clear0_regs[cpu_logical_map(cpu)]);
+@@ -280,6 +288,14 @@ void loongson3_ipi_interrupt(struct pt_r
+ 			core0_c0count[i] = c0count;
+ 		__wbflush(); /* Let others see the result ASAP */
+ 	}
++
++	if (irqs) {
++		int irq;
++		while ((irq = ffs(irqs))) {
++			do_IRQ(irq-1);
++			irqs &= ~(1<<(irq-1));
++		}
++	}
+ }
+ 
+ #define MAX_LOOPS 800
diff --git a/debian/patches/features/mips/mips-loongson-3-support-4-packages-in-cpu-hwmon-driv.patch b/debian/patches/features/mips/mips-loongson-3-support-4-packages-in-cpu-hwmon-driv.patch
new file mode 100644
index 0000000..d08dab5
--- /dev/null
+++ b/debian/patches/features/mips/mips-loongson-3-support-4-packages-in-cpu-hwmon-driv.patch
@@ -0,0 +1,192 @@
+From: Huacai Chen <chenhc at lemote.com>
+Date: Thu, 22 Jun 2017 23:06:51 +0800
+Subject: [3/6] MIPS: Loongson-3: Support 4 packages in CPU Hwmon driver
+Origin: https://git.kernel.org/linus/99b0b5a3a1e994247e7533de0fd7e4d13ead0ddd
+Bug-Debian: https://bugs.debian.org/871701
+
+Loongson-3 machines may have as many as 4 physical packages.
+
+Signed-off-by: Huacai Chen <chenhc at lemote.com>
+Cc: John Crispin <john at phrozen.org>
+Cc: Steven J . Hill <Steven.Hill at cavium.com>
+Cc: Fuxin Zhang <zhangfx at lemote.com>
+Cc: Zhangjin Wu <wuzhangjin at gmail.com>
+Cc: linux-mips at linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/16588/
+Signed-off-by: Ralf Baechle <ralf at linux-mips.org>
+---
+ drivers/platform/mips/cpu_hwmon.c | 119 +++++++++++++++++++-------------------
+ 1 file changed, 58 insertions(+), 61 deletions(-)
+
+--- a/drivers/platform/mips/cpu_hwmon.c
++++ b/drivers/platform/mips/cpu_hwmon.c
+@@ -37,6 +37,7 @@ int loongson3_cpu_temp(int cpu)
+ 	return (int)reg * 1000;
+ }
+ 
++static int nr_packages;
+ static struct device *cpu_hwmon_dev;
+ 
+ static ssize_t get_hwmon_name(struct device *dev,
+@@ -60,88 +61,74 @@ static ssize_t get_hwmon_name(struct dev
+ 	return sprintf(buf, "cpu-hwmon\n");
+ }
+ 
+-static ssize_t get_cpu0_temp(struct device *dev,
++static ssize_t get_cpu_temp(struct device *dev,
+ 			struct device_attribute *attr, char *buf);
+-static ssize_t get_cpu1_temp(struct device *dev,
+-			struct device_attribute *attr, char *buf);
+-static ssize_t cpu0_temp_label(struct device *dev,
+-			struct device_attribute *attr, char *buf);
+-static ssize_t cpu1_temp_label(struct device *dev,
++static ssize_t cpu_temp_label(struct device *dev,
+ 			struct device_attribute *attr, char *buf);
+ 
+-static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_cpu0_temp, NULL, 1);
+-static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, cpu0_temp_label, NULL, 1);
+-static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_cpu1_temp, NULL, 2);
+-static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, cpu1_temp_label, NULL, 2);
+-
+-static const struct attribute *hwmon_cputemp1[] = {
+-	&sensor_dev_attr_temp1_input.dev_attr.attr,
+-	&sensor_dev_attr_temp1_label.dev_attr.attr,
+-	NULL
+-};
+-
+-static const struct attribute *hwmon_cputemp2[] = {
+-	&sensor_dev_attr_temp2_input.dev_attr.attr,
+-	&sensor_dev_attr_temp2_label.dev_attr.attr,
+-	NULL
++static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, get_cpu_temp, NULL, 1);
++static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, cpu_temp_label, NULL, 1);
++static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, get_cpu_temp, NULL, 2);
++static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, cpu_temp_label, NULL, 2);
++static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, get_cpu_temp, NULL, 3);
++static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, cpu_temp_label, NULL, 3);
++static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, get_cpu_temp, NULL, 4);
++static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, cpu_temp_label, NULL, 4);
++
++static const struct attribute *hwmon_cputemp[4][3] = {
++	{
++		&sensor_dev_attr_temp1_input.dev_attr.attr,
++		&sensor_dev_attr_temp1_label.dev_attr.attr,
++		NULL
++	},
++	{
++		&sensor_dev_attr_temp2_input.dev_attr.attr,
++		&sensor_dev_attr_temp2_label.dev_attr.attr,
++		NULL
++	},
++	{
++		&sensor_dev_attr_temp3_input.dev_attr.attr,
++		&sensor_dev_attr_temp3_label.dev_attr.attr,
++		NULL
++	},
++	{
++		&sensor_dev_attr_temp4_input.dev_attr.attr,
++		&sensor_dev_attr_temp4_label.dev_attr.attr,
++		NULL
++	}
+ };
+ 
+-static ssize_t cpu0_temp_label(struct device *dev,
++static ssize_t cpu_temp_label(struct device *dev,
+ 			struct device_attribute *attr, char *buf)
+ {
+-	return sprintf(buf, "CPU 0 Temperature\n");
++	int id = (to_sensor_dev_attr(attr))->index - 1;
++	return sprintf(buf, "CPU %d Temperature\n", id);
+ }
+ 
+-static ssize_t cpu1_temp_label(struct device *dev,
++static ssize_t get_cpu_temp(struct device *dev,
+ 			struct device_attribute *attr, char *buf)
+ {
+-	return sprintf(buf, "CPU 1 Temperature\n");
+-}
+-
+-static ssize_t get_cpu0_temp(struct device *dev,
+-			struct device_attribute *attr, char *buf)
+-{
+-	int value = loongson3_cpu_temp(0);
+-	return sprintf(buf, "%d\n", value);
+-}
+-
+-static ssize_t get_cpu1_temp(struct device *dev,
+-			struct device_attribute *attr, char *buf)
+-{
+-	int value = loongson3_cpu_temp(1);
++	int id = (to_sensor_dev_attr(attr))->index - 1;
++	int value = loongson3_cpu_temp(id);
+ 	return sprintf(buf, "%d\n", value);
+ }
+ 
+ static int create_sysfs_cputemp_files(struct kobject *kobj)
+ {
+-	int ret;
+-
+-	ret = sysfs_create_files(kobj, hwmon_cputemp1);
+-	if (ret)
+-		goto sysfs_create_temp1_fail;
+-
+-	if (loongson_sysconf.nr_cpus <= loongson_sysconf.cores_per_package)
+-		return 0;
++	int i, ret = 0;
+ 
+-	ret = sysfs_create_files(kobj, hwmon_cputemp2);
+-	if (ret)
+-		goto sysfs_create_temp2_fail;
++	for (i=0; i<nr_packages; i++)
++		ret = sysfs_create_files(kobj, hwmon_cputemp[i]);
+ 
+-	return 0;
+-
+-sysfs_create_temp2_fail:
+-	sysfs_remove_files(kobj, hwmon_cputemp1);
+-
+-sysfs_create_temp1_fail:
+-	return -1;
++	return ret;
+ }
+ 
+ static void remove_sysfs_cputemp_files(struct kobject *kobj)
+ {
+-	sysfs_remove_files(&cpu_hwmon_dev->kobj, hwmon_cputemp1);
++	int i;
+ 
+-	if (loongson_sysconf.nr_cpus > loongson_sysconf.cores_per_package)
+-		sysfs_remove_files(&cpu_hwmon_dev->kobj, hwmon_cputemp2);
++	for (i=0; i<nr_packages; i++)
++		sysfs_remove_files(kobj, hwmon_cputemp[i]);
+ }
+ 
+ #define CPU_THERMAL_THRESHOLD 90000
+@@ -149,8 +136,15 @@ static struct delayed_work thermal_work;
+ 
+ static void do_thermal_timer(struct work_struct *work)
+ {
+-	int value = loongson3_cpu_temp(0);
+-	if (value <= CPU_THERMAL_THRESHOLD)
++	int i, value, temp_max = 0;
++
++	for (i=0; i<nr_packages; i++) {
++		value = loongson3_cpu_temp(i);
++		if (value > temp_max)
++			temp_max = value;
++	}
++
++	if (temp_max <= CPU_THERMAL_THRESHOLD)
+ 		schedule_delayed_work(&thermal_work, msecs_to_jiffies(5000));
+ 	else
+ 		orderly_poweroff(true);
+@@ -169,6 +163,9 @@ static int __init loongson_hwmon_init(vo
+ 		goto fail_hwmon_device_register;
+ 	}
+ 
++	nr_packages = loongson_sysconf.nr_cpus /
++		loongson_sysconf.cores_per_package;
++
+ 	ret = sysfs_create_group(&cpu_hwmon_dev->kobj,
+ 				&cpu_hwmon_attribute_group);
+ 	if (ret) {
diff --git a/debian/patches/features/mips/mips-loongson-3-support-irq_set_affinity-in-i8259-ch.patch b/debian/patches/features/mips/mips-loongson-3-support-irq_set_affinity-in-i8259-ch.patch
new file mode 100644
index 0000000..571b320
--- /dev/null
+++ b/debian/patches/features/mips/mips-loongson-3-support-irq_set_affinity-in-i8259-ch.patch
@@ -0,0 +1,123 @@
+From: Huacai Chen <chenhc at lemote.com>
+Date: Thu, 22 Jun 2017 23:06:53 +0800
+Subject: [5/6] MIPS: Loongson-3: support irq_set_affinity() in i8259 chip
+Origin: https://git.kernel.org/linus/ecc38a0968ec3e0605079e49d276d9a4186abdb7
+Bug-Debian: https://bugs.debian.org/871701
+
+With this patch we can set irq affinity via procfs, so as to improve
+network performance.
+
+Signed-off-by: Huacai Chen <chenhc at lemote.com>
+Cc: John Crispin <john at phrozen.org>
+Cc: Steven J . Hill <Steven.Hill at cavium.com>
+Cc: Fuxin Zhang <zhangfx at lemote.com>
+Cc: Zhangjin Wu <wuzhangjin at gmail.com>
+Cc: linux-mips at linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/16590/
+Signed-off-by: Ralf Baechle <ralf at linux-mips.org>
+---
+ arch/mips/loongson64/loongson-3/irq.c | 67 ++++++++++++++++++++++++++++-------
+ 1 file changed, 54 insertions(+), 13 deletions(-)
+
+--- a/arch/mips/loongson64/loongson-3/irq.c
++++ b/arch/mips/loongson64/loongson-3/irq.c
+@@ -10,32 +10,68 @@
+ #include "smp.h"
+ 
+ extern void loongson3_send_irq_by_ipi(int cpu, int irqs);
++
++unsigned int irq_cpu[16] = {[0 ... 15] = -1};
+ unsigned int ht_irq[] = {0, 1, 3, 4, 5, 6, 7, 8, 12, 14, 15};
+ unsigned int local_irq = 1<<0 | 1<<1 | 1<<2 | 1<<7 | 1<<8 | 1<<12;
+ 
++int plat_set_irq_affinity(struct irq_data *d, const struct cpumask *affinity,
++			  bool force)
++{
++	unsigned int cpu;
++	struct cpumask new_affinity;
++
++	/* I/O devices are connected on package-0 */
++	cpumask_copy(&new_affinity, affinity);
++	for_each_cpu(cpu, affinity)
++		if (cpu_data[cpu].package > 0)
++			cpumask_clear_cpu(cpu, &new_affinity);
++
++	if (cpumask_empty(&new_affinity))
++		return -EINVAL;
++
++	cpumask_copy(d->common->affinity, &new_affinity);
++
++	return IRQ_SET_MASK_OK_NOCOPY;
++}
++
+ static void ht_irqdispatch(void)
+ {
+-	unsigned int i, irq, irq0, irq1;
+-	static unsigned int dest_cpu = 0;
++	unsigned int i, irq;
++	struct irq_data *irqd;
++	struct cpumask affinity;
+ 
+ 	irq = LOONGSON_HT1_INT_VECTOR(0);
+ 	LOONGSON_HT1_INT_VECTOR(0) = irq; /* Acknowledge the IRQs */
+ 
+-	irq0 = irq & local_irq;  /* handled by local core */
+-	irq1 = irq & ~local_irq; /* balanced by other cores */
++	for (i = 0; i < ARRAY_SIZE(ht_irq); i++) {
++		if (!(irq & (0x1 << ht_irq[i])))
++			continue;
+ 
+-	if (dest_cpu == 0 || !cpu_online(dest_cpu))
+-		irq0 |= irq1;
+-	else
+-		loongson3_send_irq_by_ipi(dest_cpu, irq1);
+-
+-	dest_cpu = dest_cpu + 1;
+-	if (dest_cpu >= num_possible_cpus() || cpu_data[dest_cpu].package > 0)
+-		dest_cpu = 0;
++		/* handled by local core */
++		if (local_irq & (0x1 << ht_irq[i])) {
++			do_IRQ(ht_irq[i]);
++			continue;
++		}
+ 
+-	for (i = 0; i < ARRAY_SIZE(ht_irq); i++) {
+-		if (irq0 & (0x1 << ht_irq[i]))
++		irqd = irq_get_irq_data(ht_irq[i]);
++		cpumask_and(&affinity, irqd->common->affinity, cpu_active_mask);
++		if (cpumask_empty(&affinity)) {
++			do_IRQ(ht_irq[i]);
++			continue;
++		}
++
++		irq_cpu[ht_irq[i]] = cpumask_next(irq_cpu[ht_irq[i]], &affinity);
++		if (irq_cpu[ht_irq[i]] >= nr_cpu_ids)
++			irq_cpu[ht_irq[i]] = cpumask_first(&affinity);
++
++		if (irq_cpu[ht_irq[i]] == 0) {
+ 			do_IRQ(ht_irq[i]);
++			continue;
++		}
++
++		/* balanced by other cores */
++		loongson3_send_irq_by_ipi(irq_cpu[ht_irq[i]], (0x1 << ht_irq[i]));
+ 	}
+ }
+ 
+@@ -135,11 +171,16 @@ void irq_router_init(void)
+ 
+ void __init mach_init_irq(void)
+ {
++	struct irq_chip *chip;
++
+ 	clear_c0_status(ST0_IM | ST0_BEV);
+ 
+ 	irq_router_init();
+ 	mips_cpu_irq_init();
+ 	init_i8259_irqs();
++	chip = irq_get_chip(I8259A_IRQ_BASE);
++	chip->irq_set_affinity = plat_set_irq_affinity;
++
+ 	irq_set_chip_and_handler(LOONGSON_UART_IRQ,
+ 			&loongson_irq_chip, handle_level_irq);
+ 
diff --git a/debian/patches/features/mips/mips-loongson-add-loongson-3a-r3-basic-support.patch b/debian/patches/features/mips/mips-loongson-add-loongson-3a-r3-basic-support.patch
new file mode 100644
index 0000000..e2bc90f
--- /dev/null
+++ b/debian/patches/features/mips/mips-loongson-add-loongson-3a-r3-basic-support.patch
@@ -0,0 +1,120 @@
+From: Huacai Chen <chenhc at lemote.com>
+Date: Thu, 22 Jun 2017 23:06:48 +0800
+Subject: [1/6] MIPS: Loongson: Add Loongson-3A R3 basic support
+Origin: https://git.kernel.org/linus/0a00024d7a779b283db2a02130ffa46f47634d0c
+Bug-Debian: https://bugs.debian.org/871701
+
+Loongson-3A R3 is very similar to Loongson-3A R2.
+
+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-3B R1  Loongson-3B1000  0x6306
+Loongson-3B R2  Loongson-3B1500  0x6307
+
+Signed-off-by: Huacai Chen <chenhc at lemote.com>
+Cc: John Crispin <john at phrozen.org>
+Cc: Steven J . Hill <Steven.Hill at cavium.com>
+Cc: Fuxin Zhang <zhangfx at lemote.com>
+Cc: Zhangjin Wu <wuzhangjin at gmail.com>
+Cc: linux-mips at linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/16585/
+Signed-off-by: Ralf Baechle <ralf at linux-mips.org>
+---
+ arch/mips/include/asm/cpu.h           |  1 +
+ arch/mips/kernel/cpu-probe.c          |  6 ++++++
+ arch/mips/loongson64/common/env.c     |  1 +
+ arch/mips/loongson64/loongson-3/smp.c |  5 +++--
+ drivers/platform/mips/cpu_hwmon.c     | 17 +++++++++++++----
+ 5 files changed, 24 insertions(+), 6 deletions(-)
+
+--- a/arch/mips/include/asm/cpu.h
++++ b/arch/mips/include/asm/cpu.h
+@@ -247,6 +247,7 @@
+ #define PRID_REV_LOONGSON3B_R1	0x0006
+ #define PRID_REV_LOONGSON3B_R2	0x0007
+ #define PRID_REV_LOONGSON3A_R2	0x0008
++#define PRID_REV_LOONGSON3A_R3	0x0009
+ 
+ /*
+  * Older processors used to encode processor version and revision in two
+--- a/arch/mips/kernel/cpu-probe.c
++++ b/arch/mips/kernel/cpu-probe.c
+@@ -1821,6 +1821,12 @@ static inline void cpu_probe_loongson(st
+ 			set_elf_platform(cpu, "loongson3a");
+ 			set_isa(c, MIPS_CPU_ISA_M64R2);
+ 			break;
++		case PRID_REV_LOONGSON3A_R3:
++			c->cputype = CPU_LOONGSON3;
++			__cpu_name[cpu] = "ICT Loongson-3";
++			set_elf_platform(cpu, "loongson3a");
++			set_isa(c, MIPS_CPU_ISA_M64R2);
++			break;
+ 		}
+ 
+ 		decode_configs(c);
+--- a/arch/mips/loongson64/common/env.c
++++ b/arch/mips/loongson64/common/env.c
+@@ -193,6 +193,7 @@ void __init prom_init_env(void)
+ 			break;
+ 		case PRID_REV_LOONGSON3A_R1:
+ 		case PRID_REV_LOONGSON3A_R2:
++		case PRID_REV_LOONGSON3A_R3:
+ 			cpu_clock_freq = 900000000;
+ 			break;
+ 		case PRID_REV_LOONGSON3B_R1:
+--- a/arch/mips/loongson64/loongson-3/smp.c
++++ b/arch/mips/loongson64/loongson-3/smp.c
+@@ -502,7 +502,7 @@ static void loongson3a_r1_play_dead(int
+ 		: "a1");
+ }
+ 
+-static void loongson3a_r2_play_dead(int *state_addr)
++static void loongson3a_r2r3_play_dead(int *state_addr)
+ {
+ 	register int val;
+ 	register long cpuid, core, node, count;
+@@ -663,8 +663,9 @@ void play_dead(void)
+ 			(void *)CKSEG1ADDR((unsigned long)loongson3a_r1_play_dead);
+ 		break;
+ 	case PRID_REV_LOONGSON3A_R2:
++	case PRID_REV_LOONGSON3A_R3:
+ 		play_dead_at_ckseg1 =
+-			(void *)CKSEG1ADDR((unsigned long)loongson3a_r2_play_dead);
++			(void *)CKSEG1ADDR((unsigned long)loongson3a_r2r3_play_dead);
+ 		break;
+ 	case PRID_REV_LOONGSON3B_R1:
+ 	case PRID_REV_LOONGSON3B_R2:
+--- a/drivers/platform/mips/cpu_hwmon.c
++++ b/drivers/platform/mips/cpu_hwmon.c
+@@ -17,14 +17,23 @@
+  */
+ int loongson3_cpu_temp(int cpu)
+ {
+-	u32 reg;
++	u32 reg, prid_rev;
+ 
+ 	reg = LOONGSON_CHIPTEMP(cpu);
+-	if ((read_c0_prid() & PRID_REV_MASK) == PRID_REV_LOONGSON3A_R1)
++	prid_rev = read_c0_prid() & PRID_REV_MASK;
++	switch (prid_rev) {
++	case PRID_REV_LOONGSON3A_R1:
+ 		reg = (reg >> 8) & 0xff;
+-	else
++		break;
++	case PRID_REV_LOONGSON3A_R2:
++	case PRID_REV_LOONGSON3B_R1:
++	case PRID_REV_LOONGSON3B_R2:
+ 		reg = ((reg >> 8) & 0xff) - 100;
+-
++		break;
++	case PRID_REV_LOONGSON3A_R3:
++		reg = (reg & 0xffff)*731/0x4000 - 273;
++		break;
++	}
+ 	return (int)reg * 1000;
+ }
+ 
diff --git a/debian/patches/features/mips/mips-loongson-add-nmi-handler-support.patch b/debian/patches/features/mips/mips-loongson-add-nmi-handler-support.patch
new file mode 100644
index 0000000..3fd2ced
--- /dev/null
+++ b/debian/patches/features/mips/mips-loongson-add-nmi-handler-support.patch
@@ -0,0 +1,54 @@
+From: Huacai Chen <chenhc at lemote.com>
+Date: Thu, 22 Jun 2017 23:06:50 +0800
+Subject: [2/6] MIPS: Loongson: Add NMI handler support
+Origin: https://git.kernel.org/linus/b392ee07999aa1f19b3a845fad47ec4275341f71
+Bug-Debian: https://bugs.debian.org/871701
+
+Signed-off-by: Huacai Chen <chenhc at lemote.com>
+Cc: John Crispin <john at phrozen.org>
+Cc: Steven J . Hill <Steven.Hill at cavium.com>
+Cc: Fuxin Zhang <zhangfx at lemote.com>
+Cc: Zhangjin Wu <wuzhangjin at gmail.com>
+Cc: linux-mips at linux-mips.org
+Patchwork: https://patchwork.linux-mips.org/patch/16587/
+Signed-off-by: Ralf Baechle <ralf at linux-mips.org>
+---
+ arch/mips/loongson64/common/init.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+--- a/arch/mips/loongson64/common/init.c
++++ b/arch/mips/loongson64/common/init.c
+@@ -10,13 +10,25 @@
+ 
+ #include <linux/bootmem.h>
+ #include <asm/bootinfo.h>
++#include <asm/traps.h>
+ #include <asm/smp-ops.h>
++#include <asm/cacheflush.h>
+ 
+ #include <loongson.h>
+ 
+ /* Loongson CPU address windows config space base address */
+ unsigned long __maybe_unused _loongson_addrwincfg_base;
+ 
++static void __init mips_nmi_setup(void)
++{
++	void *base;
++	extern char except_vec_nmi;
++
++	base = (void *)(CAC_BASE + 0x380);
++	memcpy(base, &except_vec_nmi, 0x80);
++	flush_icache_range((unsigned long)base, (unsigned long)base + 0x80);
++}
++
+ void __init prom_init(void)
+ {
+ #ifdef CONFIG_CPU_SUPPORTS_ADDRWINCFG
+@@ -40,6 +52,7 @@ void __init prom_init(void)
+ 	/*init the uart base address */
+ 	prom_init_uart_base();
+ 	register_smp_ops(&loongson3_smp_ops);
++	board_nmi_handler_setup = mips_nmi_setup;
+ }
+ 
+ void __init prom_free_prom_memory(void)
diff --git a/debian/patches/series b/debian/patches/series
index a848e89..a960ecb 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -81,6 +81,12 @@ features/arm/arm-dts-rockchip-add-arm-mali-gpu-node-for-rk3288.patch
 features/arm/arm-dts-rockchip-enable-arm-mali-gpu-on-rk3288-rock2.patch
 features/arm/arm-dts-rockchip-enable-arm-mali-gpu-on-rk3288-firef.patch
 features/arm/arm-dts-rockchip-enable-arm-mali-gpu-on-rk3288-veyro.patch
+features/mips/mips-loongson-add-loongson-3a-r3-basic-support.patch
+features/mips/mips-loongson-add-nmi-handler-support.patch
+features/mips/mips-loongson-3-support-4-packages-in-cpu-hwmon-driv.patch
+features/mips/mips-loongson-3-irq-balancing-for-pci-devices.patch
+features/mips/mips-loongson-3-support-irq_set_affinity-in-i8259-ch.patch
+features/mips/mips-loogson-make-enum-loongson_cpu_type-more-clear.patch
 
 # Miscellaneous bug fixes
 bugfix/all/kbuild-use-nostdinc-in-compile-tests.patch

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/kernel/linux.git



More information about the Kernel-svn-changes mailing list