aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips')
-rw-r--r--arch/mips/include/asm/bootinfo.h5
-rw-r--r--arch/mips/include/asm/mach-loongson/boot_param.h44
-rw-r--r--arch/mips/include/asm/mach-loongson/loongson.h2
-rw-r--r--arch/mips/include/asm/mach-loongson/loongson_hwmon.h55
-rw-r--r--arch/mips/include/asm/mach-loongson/machine.h2
-rw-r--r--arch/mips/include/asm/mach-loongson/workarounds.h7
-rw-r--r--arch/mips/loongson/common/early_printk.c2
-rw-r--r--arch/mips/loongson/common/env.c26
-rw-r--r--arch/mips/loongson/common/machtype.c5
-rw-r--r--arch/mips/loongson/common/serial.c48
-rw-r--r--arch/mips/loongson/common/uart_base.c30
-rw-r--r--arch/mips/loongson/loongson-3/Makefile2
-rw-r--r--arch/mips/loongson/loongson-3/platform.c43
-rw-r--r--arch/mips/loongson/loongson-3/smp.c5
14 files changed, 234 insertions, 42 deletions
diff --git a/arch/mips/include/asm/bootinfo.h b/arch/mips/include/asm/bootinfo.h
index 1f7ca8b00404..8b2eaa155d18 100644
--- a/arch/mips/include/asm/bootinfo.h
+++ b/arch/mips/include/asm/bootinfo.h
@@ -70,10 +70,7 @@ enum loongson_machine_type {
70 MACH_DEXXON_GDIUM2F10, 70 MACH_DEXXON_GDIUM2F10,
71 MACH_LEMOTE_NAS, 71 MACH_LEMOTE_NAS,
72 MACH_LEMOTE_LL2F, 72 MACH_LEMOTE_LL2F,
73 MACH_LEMOTE_A1004, 73 MACH_LOONGSON_GENERIC,
74 MACH_LEMOTE_A1101,
75 MACH_LEMOTE_A1201,
76 MACH_LEMOTE_A1205,
77 MACH_LOONGSON_END 74 MACH_LOONGSON_END
78}; 75};
79 76
diff --git a/arch/mips/include/asm/mach-loongson/boot_param.h b/arch/mips/include/asm/mach-loongson/boot_param.h
index 11ebf4ca2b41..fa802926523f 100644
--- a/arch/mips/include/asm/mach-loongson/boot_param.h
+++ b/arch/mips/include/asm/mach-loongson/boot_param.h
@@ -10,7 +10,8 @@
10#define VIDEO_ROM 7 10#define VIDEO_ROM 7
11#define ADAPTER_ROM 8 11#define ADAPTER_ROM 8
12#define ACPI_TABLE 9 12#define ACPI_TABLE 9
13#define MAX_MEMORY_TYPE 10 13#define SMBIOS_TABLE 10
14#define MAX_MEMORY_TYPE 11
14 15
15#define LOONGSON3_BOOT_MEM_MAP_MAX 128 16#define LOONGSON3_BOOT_MEM_MAP_MAX 128
16struct efi_memory_map_loongson { 17struct efi_memory_map_loongson {
@@ -48,10 +49,43 @@ struct efi_cpuinfo_loongson {
48 u32 nr_cpus; 49 u32 nr_cpus;
49} __packed; 50} __packed;
50 51
52#define MAX_UARTS 64
53struct uart_device {
54 u32 iotype; /* see include/linux/serial_core.h */
55 u32 uartclk;
56 u32 int_offset;
57 u64 uart_base;
58} __packed;
59
60#define MAX_SENSORS 64
61#define SENSOR_TEMPER 0x00000001
62#define SENSOR_VOLTAGE 0x00000002
63#define SENSOR_FAN 0x00000004
64struct sensor_device {
65 char name[32]; /* a formal name */
66 char label[64]; /* a flexible description */
67 u32 type; /* SENSOR_* */
68 u32 id; /* instance id of a sensor-class */
69 u32 fan_policy; /* see loongson_hwmon.h */
70 u32 fan_percent;/* only for constant speed policy */
71 u64 base_addr; /* base address of device registers */
72} __packed;
73
51struct system_loongson { 74struct system_loongson {
52 u16 vers; /* version of system_loongson */ 75 u16 vers; /* version of system_loongson */
53 u32 ccnuma_smp; /* 0: no numa; 1: has numa */ 76 u32 ccnuma_smp; /* 0: no numa; 1: has numa */
54 u32 sing_double_channel; /* 1:single; 2:double */ 77 u32 sing_double_channel; /* 1:single; 2:double */
78 u32 nr_uarts;
79 struct uart_device uarts[MAX_UARTS];
80 u32 nr_sensors;
81 struct sensor_device sensors[MAX_SENSORS];
82 char has_ec;
83 char ec_name[32];
84 u64 ec_base_addr;
85 char has_tcm;
86 char tcm_name[32];
87 u64 tcm_base_addr;
88 u64 workarounds; /* see workarounds.h */
55} __packed; 89} __packed;
56 90
57struct irq_source_routing_table { 91struct irq_source_routing_table {
@@ -162,9 +196,15 @@ struct loongson_system_configuration {
162 u64 suspend_addr; 196 u64 suspend_addr;
163 u64 vgabios_addr; 197 u64 vgabios_addr;
164 u32 dma_mask_bits; 198 u32 dma_mask_bits;
199 char ecname[32];
200 u32 nr_uarts;
201 struct uart_device uarts[MAX_UARTS];
202 u32 nr_sensors;
203 struct sensor_device sensors[MAX_SENSORS];
204 u64 workarounds;
165}; 205};
166 206
167extern struct efi_memory_map_loongson *loongson_memmap; 207extern struct efi_memory_map_loongson *loongson_memmap;
168extern struct loongson_system_configuration loongson_sysconf; 208extern struct loongson_system_configuration loongson_sysconf;
169extern int cpuhotplug_workaround; 209
170#endif 210#endif
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h
index 92bf76c21441..5459ac09679f 100644
--- a/arch/mips/include/asm/mach-loongson/loongson.h
+++ b/arch/mips/include/asm/mach-loongson/loongson.h
@@ -35,7 +35,7 @@ extern void __init prom_init_cmdline(void);
35extern void __init prom_init_machtype(void); 35extern void __init prom_init_machtype(void);
36extern void __init prom_init_env(void); 36extern void __init prom_init_env(void);
37#ifdef CONFIG_LOONGSON_UART_BASE 37#ifdef CONFIG_LOONGSON_UART_BASE
38extern unsigned long _loongson_uart_base, loongson_uart_base; 38extern unsigned long _loongson_uart_base[], loongson_uart_base[];
39extern void prom_init_loongson_uart_base(void); 39extern void prom_init_loongson_uart_base(void);
40#endif 40#endif
41 41
diff --git a/arch/mips/include/asm/mach-loongson/loongson_hwmon.h b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h
new file mode 100644
index 000000000000..4431fc54a36c
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/loongson_hwmon.h
@@ -0,0 +1,55 @@
1#ifndef __LOONGSON_HWMON_H_
2#define __LOONGSON_HWMON_H_
3
4#include <linux/types.h>
5
6#define MIN_TEMP 0
7#define MAX_TEMP 255
8#define NOT_VALID_TEMP 999
9
10typedef int (*get_temp_fun)(int);
11extern int loongson3_cpu_temp(int);
12
13/* 0:Max speed, 1:Manual, 2:Auto */
14enum fan_control_mode {
15 FAN_FULL_MODE = 0,
16 FAN_MANUAL_MODE = 1,
17 FAN_AUTO_MODE = 2,
18 FAN_MODE_END
19};
20
21struct temp_range {
22 u8 low;
23 u8 high;
24 u8 level;
25};
26
27#define CONSTANT_SPEED_POLICY 0 /* at constent speed */
28#define STEP_SPEED_POLICY 1 /* use up/down arrays to describe policy */
29#define KERNEL_HELPER_POLICY 2 /* kernel as a helper to fan control */
30
31#define MAX_STEP_NUM 16
32#define MAX_FAN_LEVEL 255
33
34/* loongson_fan_policy works when fan work at FAN_AUTO_MODE */
35struct loongson_fan_policy {
36 u8 type;
37
38 /* percent only used when type is CONSTANT_SPEED_POLICY */
39 u8 percent;
40
41 /* period between two check. (Unit: S) */
42 u8 adjust_period;
43
44 /* fan adjust usually depend on a temprature input */
45 get_temp_fun depend_temp;
46
47 /* up_step/down_step used when type is STEP_SPEED_POLICY */
48 u8 up_step_num;
49 u8 down_step_num;
50 struct temp_range up_step[MAX_STEP_NUM];
51 struct temp_range down_step[MAX_STEP_NUM];
52 struct delayed_work work;
53};
54
55#endif /* __LOONGSON_HWMON_H_*/
diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h
index 228e37847a36..cb2b60249cd2 100644
--- a/arch/mips/include/asm/mach-loongson/machine.h
+++ b/arch/mips/include/asm/mach-loongson/machine.h
@@ -26,7 +26,7 @@
26 26
27#ifdef CONFIG_LOONGSON_MACH3X 27#ifdef CONFIG_LOONGSON_MACH3X
28 28
29#define LOONGSON_MACHTYPE MACH_LEMOTE_A1101 29#define LOONGSON_MACHTYPE MACH_LOONGSON_GENERIC
30 30
31#endif /* CONFIG_LOONGSON_MACH3X */ 31#endif /* CONFIG_LOONGSON_MACH3X */
32 32
diff --git a/arch/mips/include/asm/mach-loongson/workarounds.h b/arch/mips/include/asm/mach-loongson/workarounds.h
new file mode 100644
index 000000000000..e180c1422eae
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson/workarounds.h
@@ -0,0 +1,7 @@
1#ifndef __ASM_MACH_LOONGSON_WORKAROUNDS_H_
2#define __ASM_MACH_LOONGSON_WORKAROUNDS_H_
3
4#define WORKAROUND_CPUFREQ 0x00000001
5#define WORKAROUND_CPUHOTPLUG 0x00000002
6
7#endif
diff --git a/arch/mips/loongson/common/early_printk.c b/arch/mips/loongson/common/early_printk.c
index ced461b39069..6ca632e529dc 100644
--- a/arch/mips/loongson/common/early_printk.c
+++ b/arch/mips/loongson/common/early_printk.c
@@ -30,7 +30,7 @@ void prom_putchar(char c)
30 int timeout; 30 int timeout;
31 unsigned char *uart_base; 31 unsigned char *uart_base;
32 32
33 uart_base = (unsigned char *)_loongson_uart_base; 33 uart_base = (unsigned char *)_loongson_uart_base[0];
34 timeout = 1024; 34 timeout = 1024;
35 35
36 while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) && 36 while (((serial_in(uart_base, UART_LSR) & UART_LSR_THRE) == 0) &&
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c
index d8be5398105c..045ea3d47c87 100644
--- a/arch/mips/loongson/common/env.c
+++ b/arch/mips/loongson/common/env.c
@@ -21,6 +21,7 @@
21#include <asm/bootinfo.h> 21#include <asm/bootinfo.h>
22#include <loongson.h> 22#include <loongson.h>
23#include <boot_param.h> 23#include <boot_param.h>
24#include <workarounds.h>
24 25
25u32 cpu_clock_freq; 26u32 cpu_clock_freq;
26EXPORT_SYMBOL(cpu_clock_freq); 27EXPORT_SYMBOL(cpu_clock_freq);
@@ -31,7 +32,6 @@ u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180};
31u64 loongson_freqctrl[MAX_PACKAGES]; 32u64 loongson_freqctrl[MAX_PACKAGES];
32 33
33unsigned long long smp_group[4]; 34unsigned long long smp_group[4];
34int cpuhotplug_workaround = 0;
35 35
36#define parse_even_earlier(res, option, p) \ 36#define parse_even_earlier(res, option, p) \
37do { \ 37do { \
@@ -67,6 +67,7 @@ void __init prom_init_env(void)
67#else 67#else
68 struct boot_params *boot_p; 68 struct boot_params *boot_p;
69 struct loongson_params *loongson_p; 69 struct loongson_params *loongson_p;
70 struct system_loongson *esys;
70 struct efi_cpuinfo_loongson *ecpu; 71 struct efi_cpuinfo_loongson *ecpu;
71 struct irq_source_routing_table *eirq_source; 72 struct irq_source_routing_table *eirq_source;
72 73
@@ -74,6 +75,8 @@ void __init prom_init_env(void)
74 boot_p = (struct boot_params *)fw_arg2; 75 boot_p = (struct boot_params *)fw_arg2;
75 loongson_p = &(boot_p->efi.smbios.lp); 76 loongson_p = &(boot_p->efi.smbios.lp);
76 77
78 esys = (struct system_loongson *)
79 ((u64)loongson_p + loongson_p->system_offset);
77 ecpu = (struct efi_cpuinfo_loongson *) 80 ecpu = (struct efi_cpuinfo_loongson *)
78 ((u64)loongson_p + loongson_p->cpu_offset); 81 ((u64)loongson_p + loongson_p->cpu_offset);
79 eirq_source = (struct irq_source_routing_table *) 82 eirq_source = (struct irq_source_routing_table *)
@@ -95,6 +98,7 @@ void __init prom_init_env(void)
95 loongson_chipcfg[2] = 0x900020001fe00180; 98 loongson_chipcfg[2] = 0x900020001fe00180;
96 loongson_chipcfg[3] = 0x900030001fe00180; 99 loongson_chipcfg[3] = 0x900030001fe00180;
97 loongson_sysconf.ht_control_base = 0x90000EFDFB000000; 100 loongson_sysconf.ht_control_base = 0x90000EFDFB000000;
101 loongson_sysconf.workarounds = WORKAROUND_CPUFREQ;
98 } else if (ecpu->cputype == Loongson_3B) { 102 } else if (ecpu->cputype == Loongson_3B) {
99 loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ 103 loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */
100 loongson_sysconf.cores_per_package = 8; 104 loongson_sysconf.cores_per_package = 8;
@@ -111,7 +115,7 @@ void __init prom_init_env(void)
111 loongson_freqctrl[2] = 0x900040001fe001d0; 115 loongson_freqctrl[2] = 0x900040001fe001d0;
112 loongson_freqctrl[3] = 0x900060001fe001d0; 116 loongson_freqctrl[3] = 0x900060001fe001d0;
113 loongson_sysconf.ht_control_base = 0x90001EFDFB000000; 117 loongson_sysconf.ht_control_base = 0x90001EFDFB000000;
114 cpuhotplug_workaround = 1; 118 loongson_sysconf.workarounds = WORKAROUND_CPUHOTPLUG;
115 } else { 119 } else {
116 loongson_sysconf.cores_per_node = 1; 120 loongson_sysconf.cores_per_node = 1;
117 loongson_sysconf.cores_per_package = 1; 121 loongson_sysconf.cores_per_package = 1;
@@ -143,6 +147,24 @@ void __init prom_init_env(void)
143 pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", 147 pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n",
144 loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, 148 loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr,
145 loongson_sysconf.vgabios_addr); 149 loongson_sysconf.vgabios_addr);
150
151 memset(loongson_sysconf.ecname, 0, 32);
152 if (esys->has_ec)
153 memcpy(loongson_sysconf.ecname, esys->ec_name, 32);
154 loongson_sysconf.workarounds |= esys->workarounds;
155
156 loongson_sysconf.nr_uarts = esys->nr_uarts;
157 if (esys->nr_uarts < 1 || esys->nr_uarts > MAX_UARTS)
158 loongson_sysconf.nr_uarts = 1;
159 memcpy(loongson_sysconf.uarts, esys->uarts,
160 sizeof(struct uart_device) * loongson_sysconf.nr_uarts);
161
162 loongson_sysconf.nr_sensors = esys->nr_sensors;
163 if (loongson_sysconf.nr_sensors > MAX_SENSORS)
164 loongson_sysconf.nr_sensors = 0;
165 if (loongson_sysconf.nr_sensors)
166 memcpy(loongson_sysconf.sensors, esys->sensors,
167 sizeof(struct sensor_device) * loongson_sysconf.nr_sensors);
146#endif 168#endif
147 if (cpu_clock_freq == 0) { 169 if (cpu_clock_freq == 0) {
148 processor_id = (&current_cpu_data)->processor_id; 170 processor_id = (&current_cpu_data)->processor_id;
diff --git a/arch/mips/loongson/common/machtype.c b/arch/mips/loongson/common/machtype.c
index 1a4797984b8d..26629abe3f1f 100644
--- a/arch/mips/loongson/common/machtype.c
+++ b/arch/mips/loongson/common/machtype.c
@@ -27,10 +27,7 @@ static const char *system_types[] = {
27 [MACH_DEXXON_GDIUM2F10] "dexxon-gdium-2f", 27 [MACH_DEXXON_GDIUM2F10] "dexxon-gdium-2f",
28 [MACH_LEMOTE_NAS] "lemote-nas-2f", 28 [MACH_LEMOTE_NAS] "lemote-nas-2f",
29 [MACH_LEMOTE_LL2F] "lemote-lynloong-2f", 29 [MACH_LEMOTE_LL2F] "lemote-lynloong-2f",
30 [MACH_LEMOTE_A1004] "lemote-3a-notebook-a1004", 30 [MACH_LOONGSON_GENERIC] "generic-loongson-machine",
31 [MACH_LEMOTE_A1101] "lemote-3a-itx-a1101",
32 [MACH_LEMOTE_A1201] "lemote-2gq-notebook-a1201",
33 [MACH_LEMOTE_A1205] "lemote-2gq-aio-a1205",
34 [MACH_LOONGSON_END] NULL, 31 [MACH_LOONGSON_END] NULL,
35}; 32};
36 33
diff --git a/arch/mips/loongson/common/serial.c b/arch/mips/loongson/common/serial.c
index bd2b7095b6dc..d2f4817a4b45 100644
--- a/arch/mips/loongson/common/serial.c
+++ b/arch/mips/loongson/common/serial.c
@@ -38,7 +38,7 @@
38 .regshift = 0, \ 38 .regshift = 0, \
39} 39}
40 40
41static struct plat_serial8250_port uart8250_data[][2] = { 41static struct plat_serial8250_port uart8250_data[][MAX_UARTS + 1] = {
42 [MACH_LOONGSON_UNKNOWN] {}, 42 [MACH_LOONGSON_UNKNOWN] {},
43 [MACH_LEMOTE_FL2E] {PORT(4, 1843200), {} }, 43 [MACH_LEMOTE_FL2E] {PORT(4, 1843200), {} },
44 [MACH_LEMOTE_FL2F] {PORT(3, 1843200), {} }, 44 [MACH_LEMOTE_FL2F] {PORT(3, 1843200), {} },
@@ -47,10 +47,7 @@ static struct plat_serial8250_port uart8250_data[][2] = {
47 [MACH_DEXXON_GDIUM2F10] {PORT_M(3, 3686400), {} }, 47 [MACH_DEXXON_GDIUM2F10] {PORT_M(3, 3686400), {} },
48 [MACH_LEMOTE_NAS] {PORT_M(3, 3686400), {} }, 48 [MACH_LEMOTE_NAS] {PORT_M(3, 3686400), {} },
49 [MACH_LEMOTE_LL2F] {PORT(3, 1843200), {} }, 49 [MACH_LEMOTE_LL2F] {PORT(3, 1843200), {} },
50 [MACH_LEMOTE_A1004] {PORT_M(2, 33177600), {} }, 50 [MACH_LOONGSON_GENERIC] {PORT_M(2, 25000000), {} },
51 [MACH_LEMOTE_A1101] {PORT_M(2, 25000000), {} },
52 [MACH_LEMOTE_A1201] {PORT_M(2, 25000000), {} },
53 [MACH_LEMOTE_A1205] {PORT_M(2, 25000000), {} },
54 [MACH_LOONGSON_END] {}, 51 [MACH_LOONGSON_END] {},
55}; 52};
56 53
@@ -61,17 +58,52 @@ static struct platform_device uart8250_device = {
61 58
62static int __init serial_init(void) 59static int __init serial_init(void)
63{ 60{
61 int i;
64 unsigned char iotype; 62 unsigned char iotype;
65 63
66 iotype = uart8250_data[mips_machtype][0].iotype; 64 iotype = uart8250_data[mips_machtype][0].iotype;
67 65
68 if (UPIO_MEM == iotype) 66 if (UPIO_MEM == iotype) {
67 uart8250_data[mips_machtype][0].mapbase =
68 loongson_uart_base[0];
69 uart8250_data[mips_machtype][0].membase = 69 uart8250_data[mips_machtype][0].membase =
70 (void __iomem *)_loongson_uart_base; 70 (void __iomem *)_loongson_uart_base[0];
71 }
71 else if (UPIO_PORT == iotype) 72 else if (UPIO_PORT == iotype)
72 uart8250_data[mips_machtype][0].iobase = 73 uart8250_data[mips_machtype][0].iobase =
73 loongson_uart_base - LOONGSON_PCIIO_BASE; 74 loongson_uart_base[0] - LOONGSON_PCIIO_BASE;
74 75
76 if (loongson_sysconf.uarts[0].uartclk)
77 uart8250_data[mips_machtype][0].uartclk =
78 loongson_sysconf.uarts[0].uartclk;
79
80 for (i = 1; i < loongson_sysconf.nr_uarts; i++) {
81 iotype = loongson_sysconf.uarts[i].iotype;
82 uart8250_data[mips_machtype][i].iotype = iotype;
83 loongson_uart_base[i] = loongson_sysconf.uarts[i].uart_base;
84
85 if (UPIO_MEM == iotype) {
86 uart8250_data[mips_machtype][i].irq =
87 MIPS_CPU_IRQ_BASE + loongson_sysconf.uarts[i].int_offset;
88 uart8250_data[mips_machtype][i].mapbase =
89 loongson_uart_base[i];
90 uart8250_data[mips_machtype][i].membase =
91 ioremap_nocache(loongson_uart_base[i], 8);
92 } else if (UPIO_PORT == iotype) {
93 uart8250_data[mips_machtype][i].irq =
94 loongson_sysconf.uarts[i].int_offset;
95 uart8250_data[mips_machtype][i].iobase =
96 loongson_uart_base[i] - LOONGSON_PCIIO_BASE;
97 }
98
99 uart8250_data[mips_machtype][i].uartclk =
100 loongson_sysconf.uarts[i].uartclk;
101 uart8250_data[mips_machtype][i].flags =
102 UPF_BOOT_AUTOCONF | UPF_SKIP_TEST;
103 }
104
105 memset(&uart8250_data[mips_machtype][loongson_sysconf.nr_uarts],
106 0, sizeof(struct plat_serial8250_port));
75 uart8250_device.dev.platform_data = uart8250_data[mips_machtype]; 107 uart8250_device.dev.platform_data = uart8250_data[mips_machtype];
76 108
77 return platform_device_register(&uart8250_device); 109 return platform_device_register(&uart8250_device);
diff --git a/arch/mips/loongson/common/uart_base.c b/arch/mips/loongson/common/uart_base.c
index 1e1eeea73fde..9de559d58e1f 100644
--- a/arch/mips/loongson/common/uart_base.c
+++ b/arch/mips/loongson/common/uart_base.c
@@ -13,22 +13,27 @@
13 13
14#include <loongson.h> 14#include <loongson.h>
15 15
16/* ioremapped */
17unsigned long _loongson_uart_base;
18EXPORT_SYMBOL(_loongson_uart_base);
19/* raw */ 16/* raw */
20unsigned long loongson_uart_base; 17unsigned long loongson_uart_base[MAX_UARTS] = {};
18/* ioremapped */
19unsigned long _loongson_uart_base[MAX_UARTS] = {};
20
21EXPORT_SYMBOL(loongson_uart_base); 21EXPORT_SYMBOL(loongson_uart_base);
22EXPORT_SYMBOL(_loongson_uart_base);
22 23
23void prom_init_loongson_uart_base(void) 24void prom_init_loongson_uart_base(void)
24{ 25{
25 switch (mips_machtype) { 26 switch (mips_machtype) {
27 case MACH_LOONGSON_GENERIC:
28 /* The CPU provided serial port (CPU) */
29 loongson_uart_base[0] = LOONGSON_REG_BASE + 0x1e0;
30 break;
26 case MACH_LEMOTE_FL2E: 31 case MACH_LEMOTE_FL2E:
27 loongson_uart_base = LOONGSON_PCIIO_BASE + 0x3f8; 32 loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x3f8;
28 break; 33 break;
29 case MACH_LEMOTE_FL2F: 34 case MACH_LEMOTE_FL2F:
30 case MACH_LEMOTE_LL2F: 35 case MACH_LEMOTE_LL2F:
31 loongson_uart_base = LOONGSON_PCIIO_BASE + 0x2f8; 36 loongson_uart_base[0] = LOONGSON_PCIIO_BASE + 0x2f8;
32 break; 37 break;
33 case MACH_LEMOTE_ML2F7: 38 case MACH_LEMOTE_ML2F7:
34 case MACH_LEMOTE_YL2F89: 39 case MACH_LEMOTE_YL2F89:
@@ -36,17 +41,10 @@ void prom_init_loongson_uart_base(void)
36 case MACH_LEMOTE_NAS: 41 case MACH_LEMOTE_NAS:
37 default: 42 default:
38 /* The CPU provided serial port (LPC) */ 43 /* The CPU provided serial port (LPC) */
39 loongson_uart_base = LOONGSON_LIO1_BASE + 0x3f8; 44 loongson_uart_base[0] = LOONGSON_LIO1_BASE + 0x3f8;
40 break;
41 case MACH_LEMOTE_A1004:
42 case MACH_LEMOTE_A1101:
43 case MACH_LEMOTE_A1201:
44 case MACH_LEMOTE_A1205:
45 /* The CPU provided serial port (CPU) */
46 loongson_uart_base = LOONGSON_REG_BASE + 0x1e0;
47 break; 45 break;
48 } 46 }
49 47
50 _loongson_uart_base = 48 _loongson_uart_base[0] =
51 (unsigned long)ioremap_nocache(loongson_uart_base, 8); 49 (unsigned long)ioremap_nocache(loongson_uart_base[0], 8);
52} 50}
diff --git a/arch/mips/loongson/loongson-3/Makefile b/arch/mips/loongson/loongson-3/Makefile
index b4df775b9f30..69809a3d8f34 100644
--- a/arch/mips/loongson/loongson-3/Makefile
+++ b/arch/mips/loongson/loongson-3/Makefile
@@ -1,7 +1,7 @@
1# 1#
2# Makefile for Loongson-3 family machines 2# Makefile for Loongson-3 family machines
3# 3#
4obj-y += irq.o cop2-ex.o 4obj-y += irq.o cop2-ex.o platform.o
5 5
6obj-$(CONFIG_SMP) += smp.o 6obj-$(CONFIG_SMP) += smp.o
7 7
diff --git a/arch/mips/loongson/loongson-3/platform.c b/arch/mips/loongson/loongson-3/platform.c
new file mode 100644
index 000000000000..25a97cc0ee33
--- /dev/null
+++ b/arch/mips/loongson/loongson-3/platform.c
@@ -0,0 +1,43 @@
1/*
2 * Copyright (C) 2009 Lemote Inc.
3 * Author: Wu Zhangjin, wuzhangjin@gmail.com
4 * Xiang Yu, xiangy@lemote.com
5 * Chen Huacai, chenhc@lemote.com
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13#include <linux/err.h>
14#include <linux/slab.h>
15#include <linux/platform_device.h>
16#include <asm/bootinfo.h>
17#include <boot_param.h>
18#include <loongson_hwmon.h>
19#include <workarounds.h>
20
21static int __init loongson3_platform_init(void)
22{
23 int i;
24 struct platform_device *pdev;
25
26 if (loongson_sysconf.ecname[0] != '\0')
27 platform_device_register_simple(loongson_sysconf.ecname, -1, NULL, 0);
28
29 for (i = 0; i < loongson_sysconf.nr_sensors; i++) {
30 if (loongson_sysconf.sensors[i].type > SENSOR_FAN)
31 continue;
32
33 pdev = kzalloc(sizeof(struct platform_device), GFP_KERNEL);
34 pdev->name = loongson_sysconf.sensors[i].name;
35 pdev->id = loongson_sysconf.sensors[i].id;
36 pdev->dev.platform_data = &loongson_sysconf.sensors[i];
37 platform_device_register(pdev);
38 }
39
40 return 0;
41}
42
43arch_initcall(loongson3_platform_init);
diff --git a/arch/mips/loongson/loongson-3/smp.c b/arch/mips/loongson/loongson-3/smp.c
index 94ed8a57353c..e2eb688b5434 100644
--- a/arch/mips/loongson/loongson-3/smp.c
+++ b/arch/mips/loongson/loongson-3/smp.c
@@ -25,6 +25,7 @@
25#include <asm/tlbflush.h> 25#include <asm/tlbflush.h>
26#include <asm/cacheflush.h> 26#include <asm/cacheflush.h>
27#include <loongson.h> 27#include <loongson.h>
28#include <workarounds.h>
28 29
29#include "smp.h" 30#include "smp.h"
30 31
@@ -587,7 +588,7 @@ void loongson3_disable_clock(int cpu)
587 if (loongson_sysconf.cputype == Loongson_3A) { 588 if (loongson_sysconf.cputype == Loongson_3A) {
588 LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); 589 LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id));
589 } else if (loongson_sysconf.cputype == Loongson_3B) { 590 } else if (loongson_sysconf.cputype == Loongson_3B) {
590 if (!cpuhotplug_workaround) 591 if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
591 LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3)); 592 LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3));
592 } 593 }
593} 594}
@@ -600,7 +601,7 @@ void loongson3_enable_clock(int cpu)
600 if (loongson_sysconf.cputype == Loongson_3A) { 601 if (loongson_sysconf.cputype == Loongson_3A) {
601 LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); 602 LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id);
602 } else if (loongson_sysconf.cputype == Loongson_3B) { 603 } else if (loongson_sysconf.cputype == Loongson_3B) {
603 if (!cpuhotplug_workaround) 604 if (!(loongson_sysconf.workarounds & WORKAROUND_CPUHOTPLUG))
604 LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3); 605 LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3);
605 } 606 }
606} 607}