diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 11:47:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 11:47:00 -0400 |
commit | e669830526a0abaf301bf408df69cde33901ac63 (patch) | |
tree | 0b6043375006d1754bbd1ab2370b0a0536546cc9 /arch/mips | |
parent | ebb067d2f4e2db59b076f9c9cba0375a8ad1e07c (diff) | |
parent | 475d5928b79bb78326a645863d46ff95c5e25e5a (diff) |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle:
"This is the main pull request for 3.17. It contains:
- misc Cavium Octeon, BCM47xx, BCM63xx and Alchemy updates
- MIPS ptrace updates and cleanups
- various fixes that will also go to -stable
- a number of cleanups and small non-critical fixes.
- NUMA support for the Loongson 3.
- more support for MSA
- support for MAAR
- various FP enhancements and fixes"
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (139 commits)
MIPS: jz4740: remove unnecessary null test before debugfs_remove
MIPS: Octeon: remove unnecessary null test before debugfs_remove_recursive
MIPS: ZBOOT: implement stack protector in compressed boot phase
MIPS: mipsreg: remove duplicate MIPS_CONF4_FTLBSETS_SHIFT
MIPS: Bonito64: remove a duplicate define
MIPS: Malta: initialise MAARs
MIPS: Initialise MAARs
MIPS: detect presence of MAARs
MIPS: define MAAR register accessors & bits
MIPS: mark MSA experimental
MIPS: Don't build MSA support unless it can be used
MIPS: consistently clear MSA flags when starting & copying threads
MIPS: 16 byte align MSA vector context
MIPS: disable preemption whilst initialising MSA
MIPS: ensure MSA gets disabled during boot
MIPS: fix read_msa_* & write_msa_* functions on non-MSA toolchains
MIPS: fix MSA context for tasks which don't use FP first
MIPS: init upper 64b of vector registers when MSA is first used
MIPS: save/disable MSA in lose_fpu
MIPS: preserve scalar FP CSR when switching vector context
...
Diffstat (limited to 'arch/mips')
141 files changed, 4905 insertions, 2652 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 10f270bd3e25..900c7e5333b6 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -71,6 +71,7 @@ config MIPS_ALCHEMY | |||
71 | select SYS_SUPPORTS_APM_EMULATION | 71 | select SYS_SUPPORTS_APM_EMULATION |
72 | select ARCH_REQUIRE_GPIOLIB | 72 | select ARCH_REQUIRE_GPIOLIB |
73 | select SYS_SUPPORTS_ZBOOT | 73 | select SYS_SUPPORTS_ZBOOT |
74 | select COMMON_CLK | ||
74 | 75 | ||
75 | config AR7 | 76 | config AR7 |
76 | bool "Texas Instruments AR7" | 77 | bool "Texas Instruments AR7" |
@@ -129,6 +130,8 @@ config BCM47XX | |||
129 | select SYS_SUPPORTS_MIPS16 | 130 | select SYS_SUPPORTS_MIPS16 |
130 | select SYS_HAS_EARLY_PRINTK | 131 | select SYS_HAS_EARLY_PRINTK |
131 | select USE_GENERIC_EARLY_PRINTK_8250 | 132 | select USE_GENERIC_EARLY_PRINTK_8250 |
133 | select GPIOLIB | ||
134 | select LEDS_GPIO_REGISTER | ||
132 | help | 135 | help |
133 | Support for BCM47XX based boards | 136 | Support for BCM47XX based boards |
134 | 137 | ||
@@ -137,6 +140,7 @@ config BCM63XX | |||
137 | select BOOT_RAW | 140 | select BOOT_RAW |
138 | select CEVT_R4K | 141 | select CEVT_R4K |
139 | select CSRC_R4K | 142 | select CSRC_R4K |
143 | select SYNC_R4K | ||
140 | select DMA_NONCOHERENT | 144 | select DMA_NONCOHERENT |
141 | select IRQ_CPU | 145 | select IRQ_CPU |
142 | select SYS_SUPPORTS_32BIT_KERNEL | 146 | select SYS_SUPPORTS_32BIT_KERNEL |
@@ -2056,6 +2060,7 @@ config MIPS_CPS | |||
2056 | support is unavailable. | 2060 | support is unavailable. |
2057 | 2061 | ||
2058 | config MIPS_CPS_PM | 2062 | config MIPS_CPS_PM |
2063 | select MIPS_CPC | ||
2059 | bool | 2064 | bool |
2060 | 2065 | ||
2061 | config MIPS_GIC_IPI | 2066 | config MIPS_GIC_IPI |
@@ -2109,9 +2114,9 @@ config CPU_MICROMIPS | |||
2109 | microMIPS ISA | 2114 | microMIPS ISA |
2110 | 2115 | ||
2111 | config CPU_HAS_MSA | 2116 | config CPU_HAS_MSA |
2112 | bool "Support for the MIPS SIMD Architecture" | 2117 | bool "Support for the MIPS SIMD Architecture (EXPERIMENTAL)" |
2113 | depends on CPU_SUPPORTS_MSA | 2118 | depends on CPU_SUPPORTS_MSA |
2114 | default y | 2119 | depends on 64BIT || MIPS_O32_FP64_SUPPORT |
2115 | help | 2120 | help |
2116 | MIPS SIMD Architecture (MSA) introduces 128 bit wide vector registers | 2121 | MIPS SIMD Architecture (MSA) introduces 128 bit wide vector registers |
2117 | and a set of SIMD instructions to operate on them. When this option | 2122 | and a set of SIMD instructions to operate on them. When this option |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index a8521de14791..9336509f47ad 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -151,8 +151,10 @@ cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \ | |||
151 | -Wa,--trap | 151 | -Wa,--trap |
152 | cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \ | 152 | cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \ |
153 | -Wa,--trap | 153 | -Wa,--trap |
154 | cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1 -mno-mdmx -mno-mips3d,-march=r5000) \ | 154 | cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1,-march=r5000) \ |
155 | -Wa,--trap | 155 | -Wa,--trap |
156 | cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mdmx) | ||
157 | cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-mno-mips3d) | ||
156 | cflags-$(CONFIG_CPU_R8000) += -march=r8000 -Wa,--trap | 158 | cflags-$(CONFIG_CPU_R8000) += -march=r8000 -Wa,--trap |
157 | cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \ | 159 | cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \ |
158 | -Wa,--trap | 160 | -Wa,--trap |
diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c index 25a59a23547e..1e3b102389ef 100644 --- a/arch/mips/alchemy/board-mtx1.c +++ b/arch/mips/alchemy/board-mtx1.c | |||
@@ -85,10 +85,10 @@ void __init board_setup(void) | |||
85 | #endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */ | 85 | #endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */ |
86 | 86 | ||
87 | /* Initialize sys_pinfunc */ | 87 | /* Initialize sys_pinfunc */ |
88 | au_writel(SYS_PF_NI2, SYS_PINFUNC); | 88 | alchemy_wrsys(SYS_PF_NI2, AU1000_SYS_PINFUNC); |
89 | 89 | ||
90 | /* Initialize GPIO */ | 90 | /* Initialize GPIO */ |
91 | au_writel(~0, KSEG1ADDR(AU1000_SYS_PHYS_ADDR) + SYS_TRIOUTCLR); | 91 | alchemy_wrsys(~0, AU1000_SYS_TRIOUTCLR); |
92 | alchemy_gpio_direction_output(0, 0); /* Disable M66EN (PCI 66MHz) */ | 92 | alchemy_gpio_direction_output(0, 0); /* Disable M66EN (PCI 66MHz) */ |
93 | alchemy_gpio_direction_output(3, 1); /* Disable PCI CLKRUN# */ | 93 | alchemy_gpio_direction_output(3, 1); /* Disable PCI CLKRUN# */ |
94 | alchemy_gpio_direction_output(1, 1); /* Enable EXT_IO3 */ | 94 | alchemy_gpio_direction_output(1, 1); /* Enable EXT_IO3 */ |
diff --git a/arch/mips/alchemy/board-xxs1500.c b/arch/mips/alchemy/board-xxs1500.c index 3fb814be0e91..0fc53e08a894 100644 --- a/arch/mips/alchemy/board-xxs1500.c +++ b/arch/mips/alchemy/board-xxs1500.c | |||
@@ -87,9 +87,9 @@ void __init board_setup(void) | |||
87 | alchemy_gpio2_enable(); | 87 | alchemy_gpio2_enable(); |
88 | 88 | ||
89 | /* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */ | 89 | /* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */ |
90 | pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3; | 90 | pin_func = alchemy_rdsys(AU1000_SYS_PINFUNC) & ~SYS_PF_UR3; |
91 | pin_func |= SYS_PF_UR3; | 91 | pin_func |= SYS_PF_UR3; |
92 | au_writel(pin_func, SYS_PINFUNC); | 92 | alchemy_wrsys(pin_func, AU1000_SYS_PINFUNC); |
93 | 93 | ||
94 | /* Enable UART */ | 94 | /* Enable UART */ |
95 | alchemy_uart_enable(AU1000_UART3_PHYS_ADDR); | 95 | alchemy_uart_enable(AU1000_UART3_PHYS_ADDR); |
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile index cb83d8d21aef..f64744f3b59f 100644 --- a/arch/mips/alchemy/common/Makefile +++ b/arch/mips/alchemy/common/Makefile | |||
@@ -5,8 +5,8 @@ | |||
5 | # Makefile for the Alchemy Au1xx0 CPUs, generic files. | 5 | # Makefile for the Alchemy Au1xx0 CPUs, generic files. |
6 | # | 6 | # |
7 | 7 | ||
8 | obj-y += prom.o time.o clocks.o platform.o power.o setup.o \ | 8 | obj-y += prom.o time.o clock.o platform.o power.o \ |
9 | sleeper.o dma.o dbdma.o vss.o irq.o usb.o | 9 | setup.o sleeper.o dma.o dbdma.o vss.o irq.o usb.o |
10 | 10 | ||
11 | # optional gpiolib support | 11 | # optional gpiolib support |
12 | ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) | 12 | ifeq ($(CONFIG_ALCHEMY_GPIO_INDIRECT),) |
diff --git a/arch/mips/alchemy/common/clock.c b/arch/mips/alchemy/common/clock.c new file mode 100644 index 000000000000..d7557cde271a --- /dev/null +++ b/arch/mips/alchemy/common/clock.c | |||
@@ -0,0 +1,1094 @@ | |||
1 | /* | ||
2 | * Alchemy clocks. | ||
3 | * | ||
4 | * Exposes all configurable internal clock sources to the clk framework. | ||
5 | * | ||
6 | * We have: | ||
7 | * - Root source, usually 12MHz supplied by an external crystal | ||
8 | * - 3 PLLs which generate multiples of root rate [AUX, CPU, AUX2] | ||
9 | * | ||
10 | * Dividers: | ||
11 | * - 6 clock dividers with: | ||
12 | * * selectable source [one of the PLLs], | ||
13 | * * output divided between [2 .. 512 in steps of 2] (!Au1300) | ||
14 | * or [1 .. 256 in steps of 1] (Au1300), | ||
15 | * * can be enabled individually. | ||
16 | * | ||
17 | * - up to 6 "internal" (fixed) consumers which: | ||
18 | * * take either AUXPLL or one of the above 6 dividers as input, | ||
19 | * * divide this input by 1, 2, or 4 (and 3 on Au1300). | ||
20 | * * can be disabled separately. | ||
21 | * | ||
22 | * Misc clocks: | ||
23 | * - sysbus clock: CPU core clock (CPUPLL) divided by 2, 3 or 4. | ||
24 | * depends on board design and should be set by bootloader, read-only. | ||
25 | * - peripheral clock: half the rate of sysbus clock, source for a lot | ||
26 | * of peripheral blocks, read-only. | ||
27 | * - memory clock: clk rate to main memory chips, depends on board | ||
28 | * design and is read-only, | ||
29 | * - lrclk: the static bus clock signal for synchronous operation. | ||
30 | * depends on board design, must be set by bootloader, | ||
31 | * but may be required to correctly configure devices attached to | ||
32 | * the static bus. The Au1000/1500/1100 manuals call it LCLK, on | ||
33 | * later models it's called RCLK. | ||
34 | */ | ||
35 | |||
36 | #include <linux/init.h> | ||
37 | #include <linux/io.h> | ||
38 | #include <linux/clk-provider.h> | ||
39 | #include <linux/clkdev.h> | ||
40 | #include <linux/clk-private.h> | ||
41 | #include <linux/slab.h> | ||
42 | #include <linux/spinlock.h> | ||
43 | #include <linux/types.h> | ||
44 | #include <asm/mach-au1x00/au1000.h> | ||
45 | |||
46 | /* Base clock: 12MHz is the default in all databooks, and I haven't | ||
47 | * found any board yet which uses a different rate. | ||
48 | */ | ||
49 | #define ALCHEMY_ROOTCLK_RATE 12000000 | ||
50 | |||
51 | /* | ||
52 | * the internal sources which can be driven by the PLLs and dividers. | ||
53 | * Names taken from the databooks, refer to them for more information, | ||
54 | * especially which ones are share a clock line. | ||
55 | */ | ||
56 | static const char * const alchemy_au1300_intclknames[] = { | ||
57 | "lcd_intclk", "gpemgp_clk", "maempe_clk", "maebsa_clk", | ||
58 | "EXTCLK0", "EXTCLK1" | ||
59 | }; | ||
60 | |||
61 | static const char * const alchemy_au1200_intclknames[] = { | ||
62 | "lcd_intclk", NULL, NULL, NULL, "EXTCLK0", "EXTCLK1" | ||
63 | }; | ||
64 | |||
65 | static const char * const alchemy_au1550_intclknames[] = { | ||
66 | "usb_clk", "psc0_intclk", "psc1_intclk", "pci_clko", | ||
67 | "EXTCLK0", "EXTCLK1" | ||
68 | }; | ||
69 | |||
70 | static const char * const alchemy_au1100_intclknames[] = { | ||
71 | "usb_clk", "lcd_intclk", NULL, "i2s_clk", "EXTCLK0", "EXTCLK1" | ||
72 | }; | ||
73 | |||
74 | static const char * const alchemy_au1500_intclknames[] = { | ||
75 | NULL, "usbd_clk", "usbh_clk", "pci_clko", "EXTCLK0", "EXTCLK1" | ||
76 | }; | ||
77 | |||
78 | static const char * const alchemy_au1000_intclknames[] = { | ||
79 | "irda_clk", "usbd_clk", "usbh_clk", "i2s_clk", "EXTCLK0", | ||
80 | "EXTCLK1" | ||
81 | }; | ||
82 | |||
83 | /* aliases for a few on-chip sources which are either shared | ||
84 | * or have gone through name changes. | ||
85 | */ | ||
86 | static struct clk_aliastable { | ||
87 | char *alias; | ||
88 | char *base; | ||
89 | int cputype; | ||
90 | } alchemy_clk_aliases[] __initdata = { | ||
91 | { "usbh_clk", "usb_clk", ALCHEMY_CPU_AU1100 }, | ||
92 | { "usbd_clk", "usb_clk", ALCHEMY_CPU_AU1100 }, | ||
93 | { "irda_clk", "usb_clk", ALCHEMY_CPU_AU1100 }, | ||
94 | { "usbh_clk", "usb_clk", ALCHEMY_CPU_AU1550 }, | ||
95 | { "usbd_clk", "usb_clk", ALCHEMY_CPU_AU1550 }, | ||
96 | { "psc2_intclk", "usb_clk", ALCHEMY_CPU_AU1550 }, | ||
97 | { "psc3_intclk", "EXTCLK0", ALCHEMY_CPU_AU1550 }, | ||
98 | { "psc0_intclk", "EXTCLK0", ALCHEMY_CPU_AU1200 }, | ||
99 | { "psc1_intclk", "EXTCLK1", ALCHEMY_CPU_AU1200 }, | ||
100 | { "psc0_intclk", "EXTCLK0", ALCHEMY_CPU_AU1300 }, | ||
101 | { "psc2_intclk", "EXTCLK0", ALCHEMY_CPU_AU1300 }, | ||
102 | { "psc1_intclk", "EXTCLK1", ALCHEMY_CPU_AU1300 }, | ||
103 | { "psc3_intclk", "EXTCLK1", ALCHEMY_CPU_AU1300 }, | ||
104 | |||
105 | { NULL, NULL, 0 }, | ||
106 | }; | ||
107 | |||
108 | #define IOMEM(x) ((void __iomem *)(KSEG1ADDR(CPHYSADDR(x)))) | ||
109 | |||
110 | /* access locks to SYS_FREQCTRL0/1 and SYS_CLKSRC registers */ | ||
111 | static spinlock_t alchemy_clk_fg0_lock; | ||
112 | static spinlock_t alchemy_clk_fg1_lock; | ||
113 | static spinlock_t alchemy_clk_csrc_lock; | ||
114 | |||
115 | /* CPU Core clock *****************************************************/ | ||
116 | |||
117 | static unsigned long alchemy_clk_cpu_recalc(struct clk_hw *hw, | ||
118 | unsigned long parent_rate) | ||
119 | { | ||
120 | unsigned long t; | ||
121 | |||
122 | /* | ||
123 | * On early Au1000, sys_cpupll was write-only. Since these | ||
124 | * silicon versions of Au1000 are not sold, we don't bend | ||
125 | * over backwards trying to determine the frequency. | ||
126 | */ | ||
127 | if (unlikely(au1xxx_cpu_has_pll_wo())) | ||
128 | t = 396000000; | ||
129 | else { | ||
130 | t = alchemy_rdsys(AU1000_SYS_CPUPLL) & 0x7f; | ||
131 | t *= parent_rate; | ||
132 | } | ||
133 | |||
134 | return t; | ||
135 | } | ||
136 | |||
137 | static struct clk_ops alchemy_clkops_cpu = { | ||
138 | .recalc_rate = alchemy_clk_cpu_recalc, | ||
139 | }; | ||
140 | |||
141 | static struct clk __init *alchemy_clk_setup_cpu(const char *parent_name, | ||
142 | int ctype) | ||
143 | { | ||
144 | struct clk_init_data id; | ||
145 | struct clk_hw *h; | ||
146 | |||
147 | h = kzalloc(sizeof(*h), GFP_KERNEL); | ||
148 | if (!h) | ||
149 | return ERR_PTR(-ENOMEM); | ||
150 | |||
151 | id.name = ALCHEMY_CPU_CLK; | ||
152 | id.parent_names = &parent_name; | ||
153 | id.num_parents = 1; | ||
154 | id.flags = CLK_IS_BASIC; | ||
155 | id.ops = &alchemy_clkops_cpu; | ||
156 | h->init = &id; | ||
157 | |||
158 | return clk_register(NULL, h); | ||
159 | } | ||
160 | |||
161 | /* AUXPLLs ************************************************************/ | ||
162 | |||
163 | struct alchemy_auxpll_clk { | ||
164 | struct clk_hw hw; | ||
165 | unsigned long reg; /* au1300 has also AUXPLL2 */ | ||
166 | int maxmult; /* max multiplier */ | ||
167 | }; | ||
168 | #define to_auxpll_clk(x) container_of(x, struct alchemy_auxpll_clk, hw) | ||
169 | |||
170 | static unsigned long alchemy_clk_aux_recalc(struct clk_hw *hw, | ||
171 | unsigned long parent_rate) | ||
172 | { | ||
173 | struct alchemy_auxpll_clk *a = to_auxpll_clk(hw); | ||
174 | |||
175 | return (alchemy_rdsys(a->reg) & 0xff) * parent_rate; | ||
176 | } | ||
177 | |||
178 | static int alchemy_clk_aux_setr(struct clk_hw *hw, | ||
179 | unsigned long rate, | ||
180 | unsigned long parent_rate) | ||
181 | { | ||
182 | struct alchemy_auxpll_clk *a = to_auxpll_clk(hw); | ||
183 | unsigned long d = rate; | ||
184 | |||
185 | if (rate) | ||
186 | d /= parent_rate; | ||
187 | else | ||
188 | d = 0; | ||
189 | |||
190 | /* minimum is 84MHz, max is 756-1032 depending on variant */ | ||
191 | if (((d < 7) && (d != 0)) || (d > a->maxmult)) | ||
192 | return -EINVAL; | ||
193 | |||
194 | alchemy_wrsys(d, a->reg); | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static long alchemy_clk_aux_roundr(struct clk_hw *hw, | ||
199 | unsigned long rate, | ||
200 | unsigned long *parent_rate) | ||
201 | { | ||
202 | struct alchemy_auxpll_clk *a = to_auxpll_clk(hw); | ||
203 | unsigned long mult; | ||
204 | |||
205 | if (!rate || !*parent_rate) | ||
206 | return 0; | ||
207 | |||
208 | mult = rate / (*parent_rate); | ||
209 | |||
210 | if (mult && (mult < 7)) | ||
211 | mult = 7; | ||
212 | if (mult > a->maxmult) | ||
213 | mult = a->maxmult; | ||
214 | |||
215 | return (*parent_rate) * mult; | ||
216 | } | ||
217 | |||
218 | static struct clk_ops alchemy_clkops_aux = { | ||
219 | .recalc_rate = alchemy_clk_aux_recalc, | ||
220 | .set_rate = alchemy_clk_aux_setr, | ||
221 | .round_rate = alchemy_clk_aux_roundr, | ||
222 | }; | ||
223 | |||
224 | static struct clk __init *alchemy_clk_setup_aux(const char *parent_name, | ||
225 | char *name, int maxmult, | ||
226 | unsigned long reg) | ||
227 | { | ||
228 | struct clk_init_data id; | ||
229 | struct clk *c; | ||
230 | struct alchemy_auxpll_clk *a; | ||
231 | |||
232 | a = kzalloc(sizeof(*a), GFP_KERNEL); | ||
233 | if (!a) | ||
234 | return ERR_PTR(-ENOMEM); | ||
235 | |||
236 | id.name = name; | ||
237 | id.parent_names = &parent_name; | ||
238 | id.num_parents = 1; | ||
239 | id.flags = CLK_GET_RATE_NOCACHE; | ||
240 | id.ops = &alchemy_clkops_aux; | ||
241 | |||
242 | a->reg = reg; | ||
243 | a->maxmult = maxmult; | ||
244 | a->hw.init = &id; | ||
245 | |||
246 | c = clk_register(NULL, &a->hw); | ||
247 | if (!IS_ERR(c)) | ||
248 | clk_register_clkdev(c, name, NULL); | ||
249 | else | ||
250 | kfree(a); | ||
251 | |||
252 | return c; | ||
253 | } | ||
254 | |||
255 | /* sysbus_clk *********************************************************/ | ||
256 | |||
257 | static struct clk __init *alchemy_clk_setup_sysbus(const char *pn) | ||
258 | { | ||
259 | unsigned long v = (alchemy_rdsys(AU1000_SYS_POWERCTRL) & 3) + 2; | ||
260 | struct clk *c; | ||
261 | |||
262 | c = clk_register_fixed_factor(NULL, ALCHEMY_SYSBUS_CLK, | ||
263 | pn, 0, 1, v); | ||
264 | if (!IS_ERR(c)) | ||
265 | clk_register_clkdev(c, ALCHEMY_SYSBUS_CLK, NULL); | ||
266 | return c; | ||
267 | } | ||
268 | |||
269 | /* Peripheral Clock ***************************************************/ | ||
270 | |||
271 | static struct clk __init *alchemy_clk_setup_periph(const char *pn) | ||
272 | { | ||
273 | /* Peripheral clock runs at half the rate of sysbus clk */ | ||
274 | struct clk *c; | ||
275 | |||
276 | c = clk_register_fixed_factor(NULL, ALCHEMY_PERIPH_CLK, | ||
277 | pn, 0, 1, 2); | ||
278 | if (!IS_ERR(c)) | ||
279 | clk_register_clkdev(c, ALCHEMY_PERIPH_CLK, NULL); | ||
280 | return c; | ||
281 | } | ||
282 | |||
283 | /* mem clock **********************************************************/ | ||
284 | |||
285 | static struct clk __init *alchemy_clk_setup_mem(const char *pn, int ct) | ||
286 | { | ||
287 | void __iomem *addr = IOMEM(AU1000_MEM_PHYS_ADDR); | ||
288 | unsigned long v; | ||
289 | struct clk *c; | ||
290 | int div; | ||
291 | |||
292 | switch (ct) { | ||
293 | case ALCHEMY_CPU_AU1550: | ||
294 | case ALCHEMY_CPU_AU1200: | ||
295 | v = __raw_readl(addr + AU1550_MEM_SDCONFIGB); | ||
296 | div = (v & (1 << 15)) ? 1 : 2; | ||
297 | break; | ||
298 | case ALCHEMY_CPU_AU1300: | ||
299 | v = __raw_readl(addr + AU1550_MEM_SDCONFIGB); | ||
300 | div = (v & (1 << 31)) ? 1 : 2; | ||
301 | break; | ||
302 | case ALCHEMY_CPU_AU1000: | ||
303 | case ALCHEMY_CPU_AU1500: | ||
304 | case ALCHEMY_CPU_AU1100: | ||
305 | default: | ||
306 | div = 2; | ||
307 | break; | ||
308 | } | ||
309 | |||
310 | c = clk_register_fixed_factor(NULL, ALCHEMY_MEM_CLK, pn, | ||
311 | 0, 1, div); | ||
312 | if (!IS_ERR(c)) | ||
313 | clk_register_clkdev(c, ALCHEMY_MEM_CLK, NULL); | ||
314 | return c; | ||
315 | } | ||
316 | |||
317 | /* lrclk: external synchronous static bus clock ***********************/ | ||
318 | |||
319 | static struct clk __init *alchemy_clk_setup_lrclk(const char *pn) | ||
320 | { | ||
321 | /* MEM_STCFG0[15:13] = divisor. | ||
322 | * L/RCLK = periph_clk / (divisor + 1) | ||
323 | * On Au1000, Au1500, Au1100 it's called LCLK, | ||
324 | * on later models it's called RCLK, but it's the same thing. | ||
325 | */ | ||
326 | struct clk *c; | ||
327 | unsigned long v = alchemy_rdsmem(AU1000_MEM_STCFG0) >> 13; | ||
328 | |||
329 | v = (v & 7) + 1; | ||
330 | c = clk_register_fixed_factor(NULL, ALCHEMY_LR_CLK, | ||
331 | pn, 0, 1, v); | ||
332 | if (!IS_ERR(c)) | ||
333 | clk_register_clkdev(c, ALCHEMY_LR_CLK, NULL); | ||
334 | return c; | ||
335 | } | ||
336 | |||
337 | /* Clock dividers and muxes *******************************************/ | ||
338 | |||
339 | /* data for fgen and csrc mux-dividers */ | ||
340 | struct alchemy_fgcs_clk { | ||
341 | struct clk_hw hw; | ||
342 | spinlock_t *reglock; /* register lock */ | ||
343 | unsigned long reg; /* SYS_FREQCTRL0/1 */ | ||
344 | int shift; /* offset in register */ | ||
345 | int parent; /* parent before disable [Au1300] */ | ||
346 | int isen; /* is it enabled? */ | ||
347 | int *dt; /* dividertable for csrc */ | ||
348 | }; | ||
349 | #define to_fgcs_clk(x) container_of(x, struct alchemy_fgcs_clk, hw) | ||
350 | |||
351 | static long alchemy_calc_div(unsigned long rate, unsigned long prate, | ||
352 | int scale, int maxdiv, unsigned long *rv) | ||
353 | { | ||
354 | long div1, div2; | ||
355 | |||
356 | div1 = prate / rate; | ||
357 | if ((prate / div1) > rate) | ||
358 | div1++; | ||
359 | |||
360 | if (scale == 2) { /* only div-by-multiple-of-2 possible */ | ||
361 | if (div1 & 1) | ||
362 | div1++; /* stay <=prate */ | ||
363 | } | ||
364 | |||
365 | div2 = (div1 / scale) - 1; /* value to write to register */ | ||
366 | |||
367 | if (div2 > maxdiv) | ||
368 | div2 = maxdiv; | ||
369 | if (rv) | ||
370 | *rv = div2; | ||
371 | |||
372 | div1 = ((div2 + 1) * scale); | ||
373 | return div1; | ||
374 | } | ||
375 | |||
376 | static long alchemy_clk_fgcs_detr(struct clk_hw *hw, unsigned long rate, | ||
377 | unsigned long *best_parent_rate, | ||
378 | struct clk **best_parent_clk, | ||
379 | int scale, int maxdiv) | ||
380 | { | ||
381 | struct clk *pc, *bpc, *free; | ||
382 | long tdv, tpr, pr, nr, br, bpr, diff, lastdiff; | ||
383 | int j; | ||
384 | |||
385 | lastdiff = INT_MAX; | ||
386 | bpr = 0; | ||
387 | bpc = NULL; | ||
388 | br = -EINVAL; | ||
389 | free = NULL; | ||
390 | |||
391 | /* look at the rates each enabled parent supplies and select | ||
392 | * the one that gets closest to but not over the requested rate. | ||
393 | */ | ||
394 | for (j = 0; j < 7; j++) { | ||
395 | pc = clk_get_parent_by_index(hw->clk, j); | ||
396 | if (!pc) | ||
397 | break; | ||
398 | |||
399 | /* if this parent is currently unused, remember it. | ||
400 | * XXX: I know it's a layering violation, but it works | ||
401 | * so well.. (if (!clk_has_active_children(pc)) ) | ||
402 | */ | ||
403 | if (pc->prepare_count == 0) { | ||
404 | if (!free) | ||
405 | free = pc; | ||
406 | } | ||
407 | |||
408 | pr = clk_get_rate(pc); | ||
409 | if (pr < rate) | ||
410 | continue; | ||
411 | |||
412 | /* what can hardware actually provide */ | ||
413 | tdv = alchemy_calc_div(rate, pr, scale, maxdiv, NULL); | ||
414 | nr = pr / tdv; | ||
415 | diff = rate - nr; | ||
416 | if (nr > rate) | ||
417 | continue; | ||
418 | |||
419 | if (diff < lastdiff) { | ||
420 | lastdiff = diff; | ||
421 | bpr = pr; | ||
422 | bpc = pc; | ||
423 | br = nr; | ||
424 | } | ||
425 | if (diff == 0) | ||
426 | break; | ||
427 | } | ||
428 | |||
429 | /* if we couldn't get the exact rate we wanted from the enabled | ||
430 | * parents, maybe we can tell an available disabled/inactive one | ||
431 | * to give us a rate we can divide down to the requested rate. | ||
432 | */ | ||
433 | if (lastdiff && free) { | ||
434 | for (j = (maxdiv == 4) ? 1 : scale; j <= maxdiv; j += scale) { | ||
435 | tpr = rate * j; | ||
436 | if (tpr < 0) | ||
437 | break; | ||
438 | pr = clk_round_rate(free, tpr); | ||
439 | |||
440 | tdv = alchemy_calc_div(rate, pr, scale, maxdiv, NULL); | ||
441 | nr = pr / tdv; | ||
442 | diff = rate - nr; | ||
443 | if (nr > rate) | ||
444 | continue; | ||
445 | if (diff < lastdiff) { | ||
446 | lastdiff = diff; | ||
447 | bpr = pr; | ||
448 | bpc = free; | ||
449 | br = nr; | ||
450 | } | ||
451 | if (diff == 0) | ||
452 | break; | ||
453 | } | ||
454 | } | ||
455 | |||
456 | *best_parent_rate = bpr; | ||
457 | *best_parent_clk = bpc; | ||
458 | return br; | ||
459 | } | ||
460 | |||
461 | static int alchemy_clk_fgv1_en(struct clk_hw *hw) | ||
462 | { | ||
463 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
464 | unsigned long v, flags; | ||
465 | |||
466 | spin_lock_irqsave(c->reglock, flags); | ||
467 | v = alchemy_rdsys(c->reg); | ||
468 | v |= (1 << 1) << c->shift; | ||
469 | alchemy_wrsys(v, c->reg); | ||
470 | spin_unlock_irqrestore(c->reglock, flags); | ||
471 | |||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | static int alchemy_clk_fgv1_isen(struct clk_hw *hw) | ||
476 | { | ||
477 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
478 | unsigned long v = alchemy_rdsys(c->reg) >> (c->shift + 1); | ||
479 | |||
480 | return v & 1; | ||
481 | } | ||
482 | |||
483 | static void alchemy_clk_fgv1_dis(struct clk_hw *hw) | ||
484 | { | ||
485 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
486 | unsigned long v, flags; | ||
487 | |||
488 | spin_lock_irqsave(c->reglock, flags); | ||
489 | v = alchemy_rdsys(c->reg); | ||
490 | v &= ~((1 << 1) << c->shift); | ||
491 | alchemy_wrsys(v, c->reg); | ||
492 | spin_unlock_irqrestore(c->reglock, flags); | ||
493 | } | ||
494 | |||
495 | static int alchemy_clk_fgv1_setp(struct clk_hw *hw, u8 index) | ||
496 | { | ||
497 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
498 | unsigned long v, flags; | ||
499 | |||
500 | spin_lock_irqsave(c->reglock, flags); | ||
501 | v = alchemy_rdsys(c->reg); | ||
502 | if (index) | ||
503 | v |= (1 << c->shift); | ||
504 | else | ||
505 | v &= ~(1 << c->shift); | ||
506 | alchemy_wrsys(v, c->reg); | ||
507 | spin_unlock_irqrestore(c->reglock, flags); | ||
508 | |||
509 | return 0; | ||
510 | } | ||
511 | |||
512 | static u8 alchemy_clk_fgv1_getp(struct clk_hw *hw) | ||
513 | { | ||
514 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
515 | |||
516 | return (alchemy_rdsys(c->reg) >> c->shift) & 1; | ||
517 | } | ||
518 | |||
519 | static int alchemy_clk_fgv1_setr(struct clk_hw *hw, unsigned long rate, | ||
520 | unsigned long parent_rate) | ||
521 | { | ||
522 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
523 | unsigned long div, v, flags, ret; | ||
524 | int sh = c->shift + 2; | ||
525 | |||
526 | if (!rate || !parent_rate || rate > (parent_rate / 2)) | ||
527 | return -EINVAL; | ||
528 | ret = alchemy_calc_div(rate, parent_rate, 2, 512, &div); | ||
529 | spin_lock_irqsave(c->reglock, flags); | ||
530 | v = alchemy_rdsys(c->reg); | ||
531 | v &= ~(0xff << sh); | ||
532 | v |= div << sh; | ||
533 | alchemy_wrsys(v, c->reg); | ||
534 | spin_unlock_irqrestore(c->reglock, flags); | ||
535 | |||
536 | return 0; | ||
537 | } | ||
538 | |||
539 | static unsigned long alchemy_clk_fgv1_recalc(struct clk_hw *hw, | ||
540 | unsigned long parent_rate) | ||
541 | { | ||
542 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
543 | unsigned long v = alchemy_rdsys(c->reg) >> (c->shift + 2); | ||
544 | |||
545 | v = ((v & 0xff) + 1) * 2; | ||
546 | return parent_rate / v; | ||
547 | } | ||
548 | |||
549 | static long alchemy_clk_fgv1_detr(struct clk_hw *hw, unsigned long rate, | ||
550 | unsigned long *best_parent_rate, | ||
551 | struct clk **best_parent_clk) | ||
552 | { | ||
553 | return alchemy_clk_fgcs_detr(hw, rate, best_parent_rate, | ||
554 | best_parent_clk, 2, 512); | ||
555 | } | ||
556 | |||
557 | /* Au1000, Au1100, Au15x0, Au12x0 */ | ||
558 | static struct clk_ops alchemy_clkops_fgenv1 = { | ||
559 | .recalc_rate = alchemy_clk_fgv1_recalc, | ||
560 | .determine_rate = alchemy_clk_fgv1_detr, | ||
561 | .set_rate = alchemy_clk_fgv1_setr, | ||
562 | .set_parent = alchemy_clk_fgv1_setp, | ||
563 | .get_parent = alchemy_clk_fgv1_getp, | ||
564 | .enable = alchemy_clk_fgv1_en, | ||
565 | .disable = alchemy_clk_fgv1_dis, | ||
566 | .is_enabled = alchemy_clk_fgv1_isen, | ||
567 | }; | ||
568 | |||
569 | static void __alchemy_clk_fgv2_en(struct alchemy_fgcs_clk *c) | ||
570 | { | ||
571 | unsigned long v = alchemy_rdsys(c->reg); | ||
572 | |||
573 | v &= ~(3 << c->shift); | ||
574 | v |= (c->parent & 3) << c->shift; | ||
575 | alchemy_wrsys(v, c->reg); | ||
576 | c->isen = 1; | ||
577 | } | ||
578 | |||
579 | static int alchemy_clk_fgv2_en(struct clk_hw *hw) | ||
580 | { | ||
581 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
582 | unsigned long flags; | ||
583 | |||
584 | /* enable by setting the previous parent clock */ | ||
585 | spin_lock_irqsave(c->reglock, flags); | ||
586 | __alchemy_clk_fgv2_en(c); | ||
587 | spin_unlock_irqrestore(c->reglock, flags); | ||
588 | |||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | static int alchemy_clk_fgv2_isen(struct clk_hw *hw) | ||
593 | { | ||
594 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
595 | |||
596 | return ((alchemy_rdsys(c->reg) >> c->shift) & 3) != 0; | ||
597 | } | ||
598 | |||
599 | static void alchemy_clk_fgv2_dis(struct clk_hw *hw) | ||
600 | { | ||
601 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
602 | unsigned long v, flags; | ||
603 | |||
604 | spin_lock_irqsave(c->reglock, flags); | ||
605 | v = alchemy_rdsys(c->reg); | ||
606 | v &= ~(3 << c->shift); /* set input mux to "disabled" state */ | ||
607 | alchemy_wrsys(v, c->reg); | ||
608 | c->isen = 0; | ||
609 | spin_unlock_irqrestore(c->reglock, flags); | ||
610 | } | ||
611 | |||
612 | static int alchemy_clk_fgv2_setp(struct clk_hw *hw, u8 index) | ||
613 | { | ||
614 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
615 | unsigned long flags; | ||
616 | |||
617 | spin_lock_irqsave(c->reglock, flags); | ||
618 | c->parent = index + 1; /* value to write to register */ | ||
619 | if (c->isen) | ||
620 | __alchemy_clk_fgv2_en(c); | ||
621 | spin_unlock_irqrestore(c->reglock, flags); | ||
622 | |||
623 | return 0; | ||
624 | } | ||
625 | |||
626 | static u8 alchemy_clk_fgv2_getp(struct clk_hw *hw) | ||
627 | { | ||
628 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
629 | unsigned long flags, v; | ||
630 | |||
631 | spin_lock_irqsave(c->reglock, flags); | ||
632 | v = c->parent - 1; | ||
633 | spin_unlock_irqrestore(c->reglock, flags); | ||
634 | return v; | ||
635 | } | ||
636 | |||
637 | /* fg0-2 and fg4-6 share a "scale"-bit. With this bit cleared, the | ||
638 | * dividers behave exactly as on previous models (dividers are multiples | ||
639 | * of 2); with the bit set, dividers are multiples of 1, halving their | ||
640 | * range, but making them also much more flexible. | ||
641 | */ | ||
642 | static int alchemy_clk_fgv2_setr(struct clk_hw *hw, unsigned long rate, | ||
643 | unsigned long parent_rate) | ||
644 | { | ||
645 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
646 | int sh = c->shift + 2; | ||
647 | unsigned long div, v, flags, ret; | ||
648 | |||
649 | if (!rate || !parent_rate || rate > parent_rate) | ||
650 | return -EINVAL; | ||
651 | |||
652 | v = alchemy_rdsys(c->reg) & (1 << 30); /* test "scale" bit */ | ||
653 | ret = alchemy_calc_div(rate, parent_rate, v ? 1 : 2, | ||
654 | v ? 256 : 512, &div); | ||
655 | |||
656 | spin_lock_irqsave(c->reglock, flags); | ||
657 | v = alchemy_rdsys(c->reg); | ||
658 | v &= ~(0xff << sh); | ||
659 | v |= (div & 0xff) << sh; | ||
660 | alchemy_wrsys(v, c->reg); | ||
661 | spin_unlock_irqrestore(c->reglock, flags); | ||
662 | |||
663 | return 0; | ||
664 | } | ||
665 | |||
666 | static unsigned long alchemy_clk_fgv2_recalc(struct clk_hw *hw, | ||
667 | unsigned long parent_rate) | ||
668 | { | ||
669 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
670 | int sh = c->shift + 2; | ||
671 | unsigned long v, t; | ||
672 | |||
673 | v = alchemy_rdsys(c->reg); | ||
674 | t = parent_rate / (((v >> sh) & 0xff) + 1); | ||
675 | if ((v & (1 << 30)) == 0) /* test scale bit */ | ||
676 | t /= 2; | ||
677 | |||
678 | return t; | ||
679 | } | ||
680 | |||
681 | static long alchemy_clk_fgv2_detr(struct clk_hw *hw, unsigned long rate, | ||
682 | unsigned long *best_parent_rate, | ||
683 | struct clk **best_parent_clk) | ||
684 | { | ||
685 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
686 | int scale, maxdiv; | ||
687 | |||
688 | if (alchemy_rdsys(c->reg) & (1 << 30)) { | ||
689 | scale = 1; | ||
690 | maxdiv = 256; | ||
691 | } else { | ||
692 | scale = 2; | ||
693 | maxdiv = 512; | ||
694 | } | ||
695 | |||
696 | return alchemy_clk_fgcs_detr(hw, rate, best_parent_rate, | ||
697 | best_parent_clk, scale, maxdiv); | ||
698 | } | ||
699 | |||
700 | /* Au1300 larger input mux, no separate disable bit, flexible divider */ | ||
701 | static struct clk_ops alchemy_clkops_fgenv2 = { | ||
702 | .recalc_rate = alchemy_clk_fgv2_recalc, | ||
703 | .determine_rate = alchemy_clk_fgv2_detr, | ||
704 | .set_rate = alchemy_clk_fgv2_setr, | ||
705 | .set_parent = alchemy_clk_fgv2_setp, | ||
706 | .get_parent = alchemy_clk_fgv2_getp, | ||
707 | .enable = alchemy_clk_fgv2_en, | ||
708 | .disable = alchemy_clk_fgv2_dis, | ||
709 | .is_enabled = alchemy_clk_fgv2_isen, | ||
710 | }; | ||
711 | |||
712 | static const char * const alchemy_clk_fgv1_parents[] = { | ||
713 | ALCHEMY_CPU_CLK, ALCHEMY_AUXPLL_CLK | ||
714 | }; | ||
715 | |||
716 | static const char * const alchemy_clk_fgv2_parents[] = { | ||
717 | ALCHEMY_AUXPLL2_CLK, ALCHEMY_CPU_CLK, ALCHEMY_AUXPLL_CLK | ||
718 | }; | ||
719 | |||
720 | static const char * const alchemy_clk_fgen_names[] = { | ||
721 | ALCHEMY_FG0_CLK, ALCHEMY_FG1_CLK, ALCHEMY_FG2_CLK, | ||
722 | ALCHEMY_FG3_CLK, ALCHEMY_FG4_CLK, ALCHEMY_FG5_CLK }; | ||
723 | |||
724 | static int __init alchemy_clk_init_fgens(int ctype) | ||
725 | { | ||
726 | struct clk *c; | ||
727 | struct clk_init_data id; | ||
728 | struct alchemy_fgcs_clk *a; | ||
729 | unsigned long v; | ||
730 | int i, ret; | ||
731 | |||
732 | switch (ctype) { | ||
733 | case ALCHEMY_CPU_AU1000...ALCHEMY_CPU_AU1200: | ||
734 | id.ops = &alchemy_clkops_fgenv1; | ||
735 | id.parent_names = (const char **)alchemy_clk_fgv1_parents; | ||
736 | id.num_parents = 2; | ||
737 | break; | ||
738 | case ALCHEMY_CPU_AU1300: | ||
739 | id.ops = &alchemy_clkops_fgenv2; | ||
740 | id.parent_names = (const char **)alchemy_clk_fgv2_parents; | ||
741 | id.num_parents = 3; | ||
742 | break; | ||
743 | default: | ||
744 | return -ENODEV; | ||
745 | } | ||
746 | id.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE; | ||
747 | |||
748 | a = kzalloc((sizeof(*a)) * 6, GFP_KERNEL); | ||
749 | if (!a) | ||
750 | return -ENOMEM; | ||
751 | |||
752 | spin_lock_init(&alchemy_clk_fg0_lock); | ||
753 | spin_lock_init(&alchemy_clk_fg1_lock); | ||
754 | ret = 0; | ||
755 | for (i = 0; i < 6; i++) { | ||
756 | id.name = alchemy_clk_fgen_names[i]; | ||
757 | a->shift = 10 * (i < 3 ? i : i - 3); | ||
758 | if (i > 2) { | ||
759 | a->reg = AU1000_SYS_FREQCTRL1; | ||
760 | a->reglock = &alchemy_clk_fg1_lock; | ||
761 | } else { | ||
762 | a->reg = AU1000_SYS_FREQCTRL0; | ||
763 | a->reglock = &alchemy_clk_fg0_lock; | ||
764 | } | ||
765 | |||
766 | /* default to first parent if bootloader has set | ||
767 | * the mux to disabled state. | ||
768 | */ | ||
769 | if (ctype == ALCHEMY_CPU_AU1300) { | ||
770 | v = alchemy_rdsys(a->reg); | ||
771 | a->parent = (v >> a->shift) & 3; | ||
772 | if (!a->parent) { | ||
773 | a->parent = 1; | ||
774 | a->isen = 0; | ||
775 | } else | ||
776 | a->isen = 1; | ||
777 | } | ||
778 | |||
779 | a->hw.init = &id; | ||
780 | c = clk_register(NULL, &a->hw); | ||
781 | if (IS_ERR(c)) | ||
782 | ret++; | ||
783 | else | ||
784 | clk_register_clkdev(c, id.name, NULL); | ||
785 | a++; | ||
786 | } | ||
787 | |||
788 | return ret; | ||
789 | } | ||
790 | |||
791 | /* internal sources muxes *********************************************/ | ||
792 | |||
793 | static int alchemy_clk_csrc_isen(struct clk_hw *hw) | ||
794 | { | ||
795 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
796 | unsigned long v = alchemy_rdsys(c->reg); | ||
797 | |||
798 | return (((v >> c->shift) >> 2) & 7) != 0; | ||
799 | } | ||
800 | |||
801 | static void __alchemy_clk_csrc_en(struct alchemy_fgcs_clk *c) | ||
802 | { | ||
803 | unsigned long v = alchemy_rdsys(c->reg); | ||
804 | |||
805 | v &= ~((7 << 2) << c->shift); | ||
806 | v |= ((c->parent & 7) << 2) << c->shift; | ||
807 | alchemy_wrsys(v, c->reg); | ||
808 | c->isen = 1; | ||
809 | } | ||
810 | |||
811 | static int alchemy_clk_csrc_en(struct clk_hw *hw) | ||
812 | { | ||
813 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
814 | unsigned long flags; | ||
815 | |||
816 | /* enable by setting the previous parent clock */ | ||
817 | spin_lock_irqsave(c->reglock, flags); | ||
818 | __alchemy_clk_csrc_en(c); | ||
819 | spin_unlock_irqrestore(c->reglock, flags); | ||
820 | |||
821 | return 0; | ||
822 | } | ||
823 | |||
824 | static void alchemy_clk_csrc_dis(struct clk_hw *hw) | ||
825 | { | ||
826 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
827 | unsigned long v, flags; | ||
828 | |||
829 | spin_lock_irqsave(c->reglock, flags); | ||
830 | v = alchemy_rdsys(c->reg); | ||
831 | v &= ~((3 << 2) << c->shift); /* mux to "disabled" state */ | ||
832 | alchemy_wrsys(v, c->reg); | ||
833 | c->isen = 0; | ||
834 | spin_unlock_irqrestore(c->reglock, flags); | ||
835 | } | ||
836 | |||
837 | static int alchemy_clk_csrc_setp(struct clk_hw *hw, u8 index) | ||
838 | { | ||
839 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
840 | unsigned long flags; | ||
841 | |||
842 | spin_lock_irqsave(c->reglock, flags); | ||
843 | c->parent = index + 1; /* value to write to register */ | ||
844 | if (c->isen) | ||
845 | __alchemy_clk_csrc_en(c); | ||
846 | spin_unlock_irqrestore(c->reglock, flags); | ||
847 | |||
848 | return 0; | ||
849 | } | ||
850 | |||
851 | static u8 alchemy_clk_csrc_getp(struct clk_hw *hw) | ||
852 | { | ||
853 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
854 | |||
855 | return c->parent - 1; | ||
856 | } | ||
857 | |||
858 | static unsigned long alchemy_clk_csrc_recalc(struct clk_hw *hw, | ||
859 | unsigned long parent_rate) | ||
860 | { | ||
861 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
862 | unsigned long v = (alchemy_rdsys(c->reg) >> c->shift) & 3; | ||
863 | |||
864 | return parent_rate / c->dt[v]; | ||
865 | } | ||
866 | |||
867 | static int alchemy_clk_csrc_setr(struct clk_hw *hw, unsigned long rate, | ||
868 | unsigned long parent_rate) | ||
869 | { | ||
870 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
871 | unsigned long d, v, flags; | ||
872 | int i; | ||
873 | |||
874 | if (!rate || !parent_rate || rate > parent_rate) | ||
875 | return -EINVAL; | ||
876 | |||
877 | d = (parent_rate + (rate / 2)) / rate; | ||
878 | if (d > 4) | ||
879 | return -EINVAL; | ||
880 | if ((d == 3) && (c->dt[2] != 3)) | ||
881 | d = 4; | ||
882 | |||
883 | for (i = 0; i < 4; i++) | ||
884 | if (c->dt[i] == d) | ||
885 | break; | ||
886 | |||
887 | if (i >= 4) | ||
888 | return -EINVAL; /* oops */ | ||
889 | |||
890 | spin_lock_irqsave(c->reglock, flags); | ||
891 | v = alchemy_rdsys(c->reg); | ||
892 | v &= ~(3 << c->shift); | ||
893 | v |= (i & 3) << c->shift; | ||
894 | alchemy_wrsys(v, c->reg); | ||
895 | spin_unlock_irqrestore(c->reglock, flags); | ||
896 | |||
897 | return 0; | ||
898 | } | ||
899 | |||
900 | static long alchemy_clk_csrc_detr(struct clk_hw *hw, unsigned long rate, | ||
901 | unsigned long *best_parent_rate, | ||
902 | struct clk **best_parent_clk) | ||
903 | { | ||
904 | struct alchemy_fgcs_clk *c = to_fgcs_clk(hw); | ||
905 | int scale = c->dt[2] == 3 ? 1 : 2; /* au1300 check */ | ||
906 | |||
907 | return alchemy_clk_fgcs_detr(hw, rate, best_parent_rate, | ||
908 | best_parent_clk, scale, 4); | ||
909 | } | ||
910 | |||
911 | static struct clk_ops alchemy_clkops_csrc = { | ||
912 | .recalc_rate = alchemy_clk_csrc_recalc, | ||
913 | .determine_rate = alchemy_clk_csrc_detr, | ||
914 | .set_rate = alchemy_clk_csrc_setr, | ||
915 | .set_parent = alchemy_clk_csrc_setp, | ||
916 | .get_parent = alchemy_clk_csrc_getp, | ||
917 | .enable = alchemy_clk_csrc_en, | ||
918 | .disable = alchemy_clk_csrc_dis, | ||
919 | .is_enabled = alchemy_clk_csrc_isen, | ||
920 | }; | ||
921 | |||
922 | static const char * const alchemy_clk_csrc_parents[] = { | ||
923 | /* disabled at index 0 */ ALCHEMY_AUXPLL_CLK, | ||
924 | ALCHEMY_FG0_CLK, ALCHEMY_FG1_CLK, ALCHEMY_FG2_CLK, | ||
925 | ALCHEMY_FG3_CLK, ALCHEMY_FG4_CLK, ALCHEMY_FG5_CLK | ||
926 | }; | ||
927 | |||
928 | /* divider tables */ | ||
929 | static int alchemy_csrc_dt1[] = { 1, 4, 1, 2 }; /* rest */ | ||
930 | static int alchemy_csrc_dt2[] = { 1, 4, 3, 2 }; /* Au1300 */ | ||
931 | |||
932 | static int __init alchemy_clk_setup_imux(int ctype) | ||
933 | { | ||
934 | struct alchemy_fgcs_clk *a; | ||
935 | const char * const *names; | ||
936 | struct clk_init_data id; | ||
937 | unsigned long v; | ||
938 | int i, ret, *dt; | ||
939 | struct clk *c; | ||
940 | |||
941 | id.ops = &alchemy_clkops_csrc; | ||
942 | id.parent_names = (const char **)alchemy_clk_csrc_parents; | ||
943 | id.num_parents = 7; | ||
944 | id.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE; | ||
945 | |||
946 | dt = alchemy_csrc_dt1; | ||
947 | switch (ctype) { | ||
948 | case ALCHEMY_CPU_AU1000: | ||
949 | names = alchemy_au1000_intclknames; | ||
950 | break; | ||
951 | case ALCHEMY_CPU_AU1500: | ||
952 | names = alchemy_au1500_intclknames; | ||
953 | break; | ||
954 | case ALCHEMY_CPU_AU1100: | ||
955 | names = alchemy_au1100_intclknames; | ||
956 | break; | ||
957 | case ALCHEMY_CPU_AU1550: | ||
958 | names = alchemy_au1550_intclknames; | ||
959 | break; | ||
960 | case ALCHEMY_CPU_AU1200: | ||
961 | names = alchemy_au1200_intclknames; | ||
962 | break; | ||
963 | case ALCHEMY_CPU_AU1300: | ||
964 | dt = alchemy_csrc_dt2; | ||
965 | names = alchemy_au1300_intclknames; | ||
966 | break; | ||
967 | default: | ||
968 | return -ENODEV; | ||
969 | } | ||
970 | |||
971 | a = kzalloc((sizeof(*a)) * 6, GFP_KERNEL); | ||
972 | if (!a) | ||
973 | return -ENOMEM; | ||
974 | |||
975 | spin_lock_init(&alchemy_clk_csrc_lock); | ||
976 | ret = 0; | ||
977 | |||
978 | for (i = 0; i < 6; i++) { | ||
979 | id.name = names[i]; | ||
980 | if (!id.name) | ||
981 | goto next; | ||
982 | |||
983 | a->shift = i * 5; | ||
984 | a->reg = AU1000_SYS_CLKSRC; | ||
985 | a->reglock = &alchemy_clk_csrc_lock; | ||
986 | a->dt = dt; | ||
987 | |||
988 | /* default to first parent clock if mux is initially | ||
989 | * set to disabled state. | ||
990 | */ | ||
991 | v = alchemy_rdsys(a->reg); | ||
992 | a->parent = ((v >> a->shift) >> 2) & 7; | ||
993 | if (!a->parent) { | ||
994 | a->parent = 1; | ||
995 | a->isen = 0; | ||
996 | } else | ||
997 | a->isen = 1; | ||
998 | |||
999 | a->hw.init = &id; | ||
1000 | c = clk_register(NULL, &a->hw); | ||
1001 | if (IS_ERR(c)) | ||
1002 | ret++; | ||
1003 | else | ||
1004 | clk_register_clkdev(c, id.name, NULL); | ||
1005 | next: | ||
1006 | a++; | ||
1007 | } | ||
1008 | |||
1009 | return ret; | ||
1010 | } | ||
1011 | |||
1012 | |||
1013 | /**********************************************************************/ | ||
1014 | |||
1015 | |||
1016 | #define ERRCK(x) \ | ||
1017 | if (IS_ERR(x)) { \ | ||
1018 | ret = PTR_ERR(x); \ | ||
1019 | goto out; \ | ||
1020 | } | ||
1021 | |||
1022 | static int __init alchemy_clk_init(void) | ||
1023 | { | ||
1024 | int ctype = alchemy_get_cputype(), ret, i; | ||
1025 | struct clk_aliastable *t = alchemy_clk_aliases; | ||
1026 | struct clk *c; | ||
1027 | |||
1028 | /* Root of the Alchemy clock tree: external 12MHz crystal osc */ | ||
1029 | c = clk_register_fixed_rate(NULL, ALCHEMY_ROOT_CLK, NULL, | ||
1030 | CLK_IS_ROOT, | ||
1031 | ALCHEMY_ROOTCLK_RATE); | ||
1032 | ERRCK(c) | ||
1033 | |||
1034 | /* CPU core clock */ | ||
1035 | c = alchemy_clk_setup_cpu(ALCHEMY_ROOT_CLK, ctype); | ||
1036 | ERRCK(c) | ||
1037 | |||
1038 | /* AUXPLLs: max 1GHz on Au1300, 748MHz on older models */ | ||
1039 | i = (ctype == ALCHEMY_CPU_AU1300) ? 84 : 63; | ||
1040 | c = alchemy_clk_setup_aux(ALCHEMY_ROOT_CLK, ALCHEMY_AUXPLL_CLK, | ||
1041 | i, AU1000_SYS_AUXPLL); | ||
1042 | ERRCK(c) | ||
1043 | |||
1044 | if (ctype == ALCHEMY_CPU_AU1300) { | ||
1045 | c = alchemy_clk_setup_aux(ALCHEMY_ROOT_CLK, | ||
1046 | ALCHEMY_AUXPLL2_CLK, i, | ||
1047 | AU1300_SYS_AUXPLL2); | ||
1048 | ERRCK(c) | ||
1049 | } | ||
1050 | |||
1051 | /* sysbus clock: cpu core clock divided by 2, 3 or 4 */ | ||
1052 | c = alchemy_clk_setup_sysbus(ALCHEMY_CPU_CLK); | ||
1053 | ERRCK(c) | ||
1054 | |||
1055 | /* peripheral clock: runs at half rate of sysbus clk */ | ||
1056 | c = alchemy_clk_setup_periph(ALCHEMY_SYSBUS_CLK); | ||
1057 | ERRCK(c) | ||
1058 | |||
1059 | /* SDR/DDR memory clock */ | ||
1060 | c = alchemy_clk_setup_mem(ALCHEMY_SYSBUS_CLK, ctype); | ||
1061 | ERRCK(c) | ||
1062 | |||
1063 | /* L/RCLK: external static bus clock for synchronous mode */ | ||
1064 | c = alchemy_clk_setup_lrclk(ALCHEMY_PERIPH_CLK); | ||
1065 | ERRCK(c) | ||
1066 | |||
1067 | /* Frequency dividers 0-5 */ | ||
1068 | ret = alchemy_clk_init_fgens(ctype); | ||
1069 | if (ret) { | ||
1070 | ret = -ENODEV; | ||
1071 | goto out; | ||
1072 | } | ||
1073 | |||
1074 | /* diving muxes for internal sources */ | ||
1075 | ret = alchemy_clk_setup_imux(ctype); | ||
1076 | if (ret) { | ||
1077 | ret = -ENODEV; | ||
1078 | goto out; | ||
1079 | } | ||
1080 | |||
1081 | /* set up aliases drivers might look for */ | ||
1082 | while (t->base) { | ||
1083 | if (t->cputype == ctype) | ||
1084 | clk_add_alias(t->alias, NULL, t->base, NULL); | ||
1085 | t++; | ||
1086 | } | ||
1087 | |||
1088 | pr_info("Alchemy clocktree installed\n"); | ||
1089 | return 0; | ||
1090 | |||
1091 | out: | ||
1092 | return ret; | ||
1093 | } | ||
1094 | postcore_initcall(alchemy_clk_init); | ||
diff --git a/arch/mips/alchemy/common/clocks.c b/arch/mips/alchemy/common/clocks.c deleted file mode 100644 index f38298a8b98c..000000000000 --- a/arch/mips/alchemy/common/clocks.c +++ /dev/null | |||
@@ -1,105 +0,0 @@ | |||
1 | /* | ||
2 | * BRIEF MODULE DESCRIPTION | ||
3 | * Simple Au1xx0 clocks routines. | ||
4 | * | ||
5 | * Copyright 2001, 2008 MontaVista Software Inc. | ||
6 | * Author: MontaVista Software, Inc. <source@mvista.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
14 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
16 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
19 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #include <linux/module.h> | ||
30 | #include <linux/spinlock.h> | ||
31 | #include <asm/time.h> | ||
32 | #include <asm/mach-au1x00/au1000.h> | ||
33 | |||
34 | /* | ||
35 | * I haven't found anyone that doesn't use a 12 MHz source clock, | ||
36 | * but just in case..... | ||
37 | */ | ||
38 | #define AU1000_SRC_CLK 12000000 | ||
39 | |||
40 | static unsigned int au1x00_clock; /* Hz */ | ||
41 | static unsigned long uart_baud_base; | ||
42 | |||
43 | /* | ||
44 | * Set the au1000_clock | ||
45 | */ | ||
46 | void set_au1x00_speed(unsigned int new_freq) | ||
47 | { | ||
48 | au1x00_clock = new_freq; | ||
49 | } | ||
50 | |||
51 | unsigned int get_au1x00_speed(void) | ||
52 | { | ||
53 | return au1x00_clock; | ||
54 | } | ||
55 | EXPORT_SYMBOL(get_au1x00_speed); | ||
56 | |||
57 | /* | ||
58 | * The UART baud base is not known at compile time ... if | ||
59 | * we want to be able to use the same code on different | ||
60 | * speed CPUs. | ||
61 | */ | ||
62 | unsigned long get_au1x00_uart_baud_base(void) | ||
63 | { | ||
64 | return uart_baud_base; | ||
65 | } | ||
66 | |||
67 | void set_au1x00_uart_baud_base(unsigned long new_baud_base) | ||
68 | { | ||
69 | uart_baud_base = new_baud_base; | ||
70 | } | ||
71 | |||
72 | /* | ||
73 | * We read the real processor speed from the PLL. This is important | ||
74 | * because it is more accurate than computing it from the 32 KHz | ||
75 | * counter, if it exists. If we don't have an accurate processor | ||
76 | * speed, all of the peripherals that derive their clocks based on | ||
77 | * this advertised speed will introduce error and sometimes not work | ||
78 | * properly. This function is further convoluted to still allow configurations | ||
79 | * to do that in case they have really, really old silicon with a | ||
80 | * write-only PLL register. -- Dan | ||
81 | */ | ||
82 | unsigned long au1xxx_calc_clock(void) | ||
83 | { | ||
84 | unsigned long cpu_speed; | ||
85 | |||
86 | /* | ||
87 | * On early Au1000, sys_cpupll was write-only. Since these | ||
88 | * silicon versions of Au1000 are not sold by AMD, we don't bend | ||
89 | * over backwards trying to determine the frequency. | ||
90 | */ | ||
91 | if (au1xxx_cpu_has_pll_wo()) | ||
92 | cpu_speed = 396000000; | ||
93 | else | ||
94 | cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK; | ||
95 | |||
96 | /* On Alchemy CPU:counter ratio is 1:1 */ | ||
97 | mips_hpt_frequency = cpu_speed; | ||
98 | /* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */ | ||
99 | set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL) | ||
100 | & 0x03) + 2) * 16)); | ||
101 | |||
102 | set_au1x00_speed(cpu_speed); | ||
103 | |||
104 | return cpu_speed; | ||
105 | } | ||
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c index 19d5642c16d9..745695db5ba0 100644 --- a/arch/mips/alchemy/common/dbdma.c +++ b/arch/mips/alchemy/common/dbdma.c | |||
@@ -341,7 +341,7 @@ u32 au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid, | |||
341 | (dtp->dev_flags & DEV_FLAGS_SYNC)) | 341 | (dtp->dev_flags & DEV_FLAGS_SYNC)) |
342 | i |= DDMA_CFG_SYNC; | 342 | i |= DDMA_CFG_SYNC; |
343 | cp->ddma_cfg = i; | 343 | cp->ddma_cfg = i; |
344 | au_sync(); | 344 | wmb(); /* drain writebuffer */ |
345 | 345 | ||
346 | /* | 346 | /* |
347 | * Return a non-zero value that can be used to find the channel | 347 | * Return a non-zero value that can be used to find the channel |
@@ -631,7 +631,7 @@ u32 au1xxx_dbdma_put_source(u32 chanid, dma_addr_t buf, int nbytes, u32 flags) | |||
631 | */ | 631 | */ |
632 | dma_cache_wback_inv((unsigned long)buf, nbytes); | 632 | dma_cache_wback_inv((unsigned long)buf, nbytes); |
633 | dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ | 633 | dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ |
634 | au_sync(); | 634 | wmb(); /* drain writebuffer */ |
635 | dma_cache_wback_inv((unsigned long)dp, sizeof(*dp)); | 635 | dma_cache_wback_inv((unsigned long)dp, sizeof(*dp)); |
636 | ctp->chan_ptr->ddma_dbell = 0; | 636 | ctp->chan_ptr->ddma_dbell = 0; |
637 | 637 | ||
@@ -693,7 +693,7 @@ u32 au1xxx_dbdma_put_dest(u32 chanid, dma_addr_t buf, int nbytes, u32 flags) | |||
693 | */ | 693 | */ |
694 | dma_cache_inv((unsigned long)buf, nbytes); | 694 | dma_cache_inv((unsigned long)buf, nbytes); |
695 | dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ | 695 | dp->dscr_cmd0 |= DSCR_CMD0_V; /* Let it rip */ |
696 | au_sync(); | 696 | wmb(); /* drain writebuffer */ |
697 | dma_cache_wback_inv((unsigned long)dp, sizeof(*dp)); | 697 | dma_cache_wback_inv((unsigned long)dp, sizeof(*dp)); |
698 | ctp->chan_ptr->ddma_dbell = 0; | 698 | ctp->chan_ptr->ddma_dbell = 0; |
699 | 699 | ||
@@ -760,7 +760,7 @@ void au1xxx_dbdma_stop(u32 chanid) | |||
760 | 760 | ||
761 | cp = ctp->chan_ptr; | 761 | cp = ctp->chan_ptr; |
762 | cp->ddma_cfg &= ~DDMA_CFG_EN; /* Disable channel */ | 762 | cp->ddma_cfg &= ~DDMA_CFG_EN; /* Disable channel */ |
763 | au_sync(); | 763 | wmb(); /* drain writebuffer */ |
764 | while (!(cp->ddma_stat & DDMA_STAT_H)) { | 764 | while (!(cp->ddma_stat & DDMA_STAT_H)) { |
765 | udelay(1); | 765 | udelay(1); |
766 | halt_timeout++; | 766 | halt_timeout++; |
@@ -771,7 +771,7 @@ void au1xxx_dbdma_stop(u32 chanid) | |||
771 | } | 771 | } |
772 | /* clear current desc valid and doorbell */ | 772 | /* clear current desc valid and doorbell */ |
773 | cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V); | 773 | cp->ddma_stat |= (DDMA_STAT_DB | DDMA_STAT_V); |
774 | au_sync(); | 774 | wmb(); /* drain writebuffer */ |
775 | } | 775 | } |
776 | EXPORT_SYMBOL(au1xxx_dbdma_stop); | 776 | EXPORT_SYMBOL(au1xxx_dbdma_stop); |
777 | 777 | ||
@@ -789,9 +789,9 @@ void au1xxx_dbdma_start(u32 chanid) | |||
789 | cp = ctp->chan_ptr; | 789 | cp = ctp->chan_ptr; |
790 | cp->ddma_desptr = virt_to_phys(ctp->cur_ptr); | 790 | cp->ddma_desptr = virt_to_phys(ctp->cur_ptr); |
791 | cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */ | 791 | cp->ddma_cfg |= DDMA_CFG_EN; /* Enable channel */ |
792 | au_sync(); | 792 | wmb(); /* drain writebuffer */ |
793 | cp->ddma_dbell = 0; | 793 | cp->ddma_dbell = 0; |
794 | au_sync(); | 794 | wmb(); /* drain writebuffer */ |
795 | } | 795 | } |
796 | EXPORT_SYMBOL(au1xxx_dbdma_start); | 796 | EXPORT_SYMBOL(au1xxx_dbdma_start); |
797 | 797 | ||
@@ -832,7 +832,7 @@ u32 au1xxx_get_dma_residue(u32 chanid) | |||
832 | 832 | ||
833 | /* This is only valid if the channel is stopped. */ | 833 | /* This is only valid if the channel is stopped. */ |
834 | rv = cp->ddma_bytecnt; | 834 | rv = cp->ddma_bytecnt; |
835 | au_sync(); | 835 | wmb(); /* drain writebuffer */ |
836 | 836 | ||
837 | return rv; | 837 | return rv; |
838 | } | 838 | } |
@@ -868,7 +868,7 @@ static irqreturn_t dbdma_interrupt(int irq, void *dev_id) | |||
868 | au1x_dma_chan_t *cp; | 868 | au1x_dma_chan_t *cp; |
869 | 869 | ||
870 | intstat = dbdma_gptr->ddma_intstat; | 870 | intstat = dbdma_gptr->ddma_intstat; |
871 | au_sync(); | 871 | wmb(); /* drain writebuffer */ |
872 | chan_index = __ffs(intstat); | 872 | chan_index = __ffs(intstat); |
873 | 873 | ||
874 | ctp = chan_tab_ptr[chan_index]; | 874 | ctp = chan_tab_ptr[chan_index]; |
@@ -877,7 +877,7 @@ static irqreturn_t dbdma_interrupt(int irq, void *dev_id) | |||
877 | 877 | ||
878 | /* Reset interrupt. */ | 878 | /* Reset interrupt. */ |
879 | cp->ddma_irq = 0; | 879 | cp->ddma_irq = 0; |
880 | au_sync(); | 880 | wmb(); /* drain writebuffer */ |
881 | 881 | ||
882 | if (ctp->chan_callback) | 882 | if (ctp->chan_callback) |
883 | ctp->chan_callback(irq, ctp->chan_callparam); | 883 | ctp->chan_callback(irq, ctp->chan_callparam); |
@@ -1061,7 +1061,7 @@ static int __init dbdma_setup(unsigned int irq, dbdev_tab_t *idtable) | |||
1061 | dbdma_gptr->ddma_config = 0; | 1061 | dbdma_gptr->ddma_config = 0; |
1062 | dbdma_gptr->ddma_throttle = 0; | 1062 | dbdma_gptr->ddma_throttle = 0; |
1063 | dbdma_gptr->ddma_inten = 0xffff; | 1063 | dbdma_gptr->ddma_inten = 0xffff; |
1064 | au_sync(); | 1064 | wmb(); /* drain writebuffer */ |
1065 | 1065 | ||
1066 | ret = request_irq(irq, dbdma_interrupt, 0, "dbdma", (void *)dbdma_gptr); | 1066 | ret = request_irq(irq, dbdma_interrupt, 0, "dbdma", (void *)dbdma_gptr); |
1067 | if (ret) | 1067 | if (ret) |
diff --git a/arch/mips/alchemy/common/dma.c b/arch/mips/alchemy/common/dma.c index 9b624e2c0fcf..4fb6207b883b 100644 --- a/arch/mips/alchemy/common/dma.c +++ b/arch/mips/alchemy/common/dma.c | |||
@@ -141,17 +141,17 @@ void dump_au1000_dma_channel(unsigned int dmanr) | |||
141 | 141 | ||
142 | printk(KERN_INFO "Au1000 DMA%d Register Dump:\n", dmanr); | 142 | printk(KERN_INFO "Au1000 DMA%d Register Dump:\n", dmanr); |
143 | printk(KERN_INFO " mode = 0x%08x\n", | 143 | printk(KERN_INFO " mode = 0x%08x\n", |
144 | au_readl(chan->io + DMA_MODE_SET)); | 144 | __raw_readl(chan->io + DMA_MODE_SET)); |
145 | printk(KERN_INFO " addr = 0x%08x\n", | 145 | printk(KERN_INFO " addr = 0x%08x\n", |
146 | au_readl(chan->io + DMA_PERIPHERAL_ADDR)); | 146 | __raw_readl(chan->io + DMA_PERIPHERAL_ADDR)); |
147 | printk(KERN_INFO " start0 = 0x%08x\n", | 147 | printk(KERN_INFO " start0 = 0x%08x\n", |
148 | au_readl(chan->io + DMA_BUFFER0_START)); | 148 | __raw_readl(chan->io + DMA_BUFFER0_START)); |
149 | printk(KERN_INFO " start1 = 0x%08x\n", | 149 | printk(KERN_INFO " start1 = 0x%08x\n", |
150 | au_readl(chan->io + DMA_BUFFER1_START)); | 150 | __raw_readl(chan->io + DMA_BUFFER1_START)); |
151 | printk(KERN_INFO " count0 = 0x%08x\n", | 151 | printk(KERN_INFO " count0 = 0x%08x\n", |
152 | au_readl(chan->io + DMA_BUFFER0_COUNT)); | 152 | __raw_readl(chan->io + DMA_BUFFER0_COUNT)); |
153 | printk(KERN_INFO " count1 = 0x%08x\n", | 153 | printk(KERN_INFO " count1 = 0x%08x\n", |
154 | au_readl(chan->io + DMA_BUFFER1_COUNT)); | 154 | __raw_readl(chan->io + DMA_BUFFER1_COUNT)); |
155 | } | 155 | } |
156 | 156 | ||
157 | /* | 157 | /* |
@@ -204,7 +204,8 @@ int request_au1000_dma(int dev_id, const char *dev_str, | |||
204 | } | 204 | } |
205 | 205 | ||
206 | /* fill it in */ | 206 | /* fill it in */ |
207 | chan->io = KSEG1ADDR(AU1000_DMA_PHYS_ADDR) + i * DMA_CHANNEL_LEN; | 207 | chan->io = (void __iomem *)(KSEG1ADDR(AU1000_DMA_PHYS_ADDR) + |
208 | i * DMA_CHANNEL_LEN); | ||
208 | chan->dev_id = dev_id; | 209 | chan->dev_id = dev_id; |
209 | chan->dev_str = dev_str; | 210 | chan->dev_str = dev_str; |
210 | chan->fifo_addr = dev->fifo_addr; | 211 | chan->fifo_addr = dev->fifo_addr; |
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c index 63a71817a00c..6cb60abfdcc9 100644 --- a/arch/mips/alchemy/common/irq.c +++ b/arch/mips/alchemy/common/irq.c | |||
@@ -389,13 +389,12 @@ static int au1x_ic1_setwake(struct irq_data *d, unsigned int on) | |||
389 | return -EINVAL; | 389 | return -EINVAL; |
390 | 390 | ||
391 | local_irq_save(flags); | 391 | local_irq_save(flags); |
392 | wakemsk = __raw_readl((void __iomem *)SYS_WAKEMSK); | 392 | wakemsk = alchemy_rdsys(AU1000_SYS_WAKEMSK); |
393 | if (on) | 393 | if (on) |
394 | wakemsk |= 1 << bit; | 394 | wakemsk |= 1 << bit; |
395 | else | 395 | else |
396 | wakemsk &= ~(1 << bit); | 396 | wakemsk &= ~(1 << bit); |
397 | __raw_writel(wakemsk, (void __iomem *)SYS_WAKEMSK); | 397 | alchemy_wrsys(wakemsk, AU1000_SYS_WAKEMSK); |
398 | wmb(); | ||
399 | local_irq_restore(flags); | 398 | local_irq_restore(flags); |
400 | 399 | ||
401 | return 0; | 400 | return 0; |
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index 9837a134a6d6..d77a64f4c78b 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c | |||
@@ -11,6 +11,7 @@ | |||
11 | * warranty of any kind, whether express or implied. | 11 | * warranty of any kind, whether express or implied. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/clk.h> | ||
14 | #include <linux/dma-mapping.h> | 15 | #include <linux/dma-mapping.h> |
15 | #include <linux/etherdevice.h> | 16 | #include <linux/etherdevice.h> |
16 | #include <linux/init.h> | 17 | #include <linux/init.h> |
@@ -99,10 +100,20 @@ static struct platform_device au1xx0_uart_device = { | |||
99 | 100 | ||
100 | static void __init alchemy_setup_uarts(int ctype) | 101 | static void __init alchemy_setup_uarts(int ctype) |
101 | { | 102 | { |
102 | unsigned int uartclk = get_au1x00_uart_baud_base() * 16; | 103 | long uartclk; |
103 | int s = sizeof(struct plat_serial8250_port); | 104 | int s = sizeof(struct plat_serial8250_port); |
104 | int c = alchemy_get_uarts(ctype); | 105 | int c = alchemy_get_uarts(ctype); |
105 | struct plat_serial8250_port *ports; | 106 | struct plat_serial8250_port *ports; |
107 | struct clk *clk = clk_get(NULL, ALCHEMY_PERIPH_CLK); | ||
108 | |||
109 | if (IS_ERR(clk)) | ||
110 | return; | ||
111 | if (clk_prepare_enable(clk)) { | ||
112 | clk_put(clk); | ||
113 | return; | ||
114 | } | ||
115 | uartclk = clk_get_rate(clk); | ||
116 | clk_put(clk); | ||
106 | 117 | ||
107 | ports = kzalloc(s * (c + 1), GFP_KERNEL); | 118 | ports = kzalloc(s * (c + 1), GFP_KERNEL); |
108 | if (!ports) { | 119 | if (!ports) { |
@@ -420,7 +431,7 @@ static void __init alchemy_setup_macs(int ctype) | |||
420 | memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6); | 431 | memcpy(au1xxx_eth1_platform_data.mac, ethaddr, 6); |
421 | 432 | ||
422 | /* Register second MAC if enabled in pinfunc */ | 433 | /* Register second MAC if enabled in pinfunc */ |
423 | if (!(au_readl(SYS_PINFUNC) & (u32)SYS_PF_NI2)) { | 434 | if (!(alchemy_rdsys(AU1000_SYS_PINFUNC) & SYS_PF_NI2)) { |
424 | ret = platform_device_register(&au1xxx_eth1_device); | 435 | ret = platform_device_register(&au1xxx_eth1_device); |
425 | if (ret) | 436 | if (ret) |
426 | printk(KERN_INFO "Alchemy: failed to register MAC1\n"); | 437 | printk(KERN_INFO "Alchemy: failed to register MAC1\n"); |
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index bdb28dee8fdd..921ed30b440c 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c | |||
@@ -54,28 +54,28 @@ static unsigned int sleep_static_memctlr[4][3]; | |||
54 | static void save_core_regs(void) | 54 | static void save_core_regs(void) |
55 | { | 55 | { |
56 | /* Clocks and PLLs. */ | 56 | /* Clocks and PLLs. */ |
57 | sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0); | 57 | sleep_sys_clocks[0] = alchemy_rdsys(AU1000_SYS_FREQCTRL0); |
58 | sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1); | 58 | sleep_sys_clocks[1] = alchemy_rdsys(AU1000_SYS_FREQCTRL1); |
59 | sleep_sys_clocks[2] = au_readl(SYS_CLKSRC); | 59 | sleep_sys_clocks[2] = alchemy_rdsys(AU1000_SYS_CLKSRC); |
60 | sleep_sys_clocks[3] = au_readl(SYS_CPUPLL); | 60 | sleep_sys_clocks[3] = alchemy_rdsys(AU1000_SYS_CPUPLL); |
61 | sleep_sys_clocks[4] = au_readl(SYS_AUXPLL); | 61 | sleep_sys_clocks[4] = alchemy_rdsys(AU1000_SYS_AUXPLL); |
62 | 62 | ||
63 | /* pin mux config */ | 63 | /* pin mux config */ |
64 | sleep_sys_pinfunc = au_readl(SYS_PINFUNC); | 64 | sleep_sys_pinfunc = alchemy_rdsys(AU1000_SYS_PINFUNC); |
65 | 65 | ||
66 | /* Save the static memory controller configuration. */ | 66 | /* Save the static memory controller configuration. */ |
67 | sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0); | 67 | sleep_static_memctlr[0][0] = alchemy_rdsmem(AU1000_MEM_STCFG0); |
68 | sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0); | 68 | sleep_static_memctlr[0][1] = alchemy_rdsmem(AU1000_MEM_STTIME0); |
69 | sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0); | 69 | sleep_static_memctlr[0][2] = alchemy_rdsmem(AU1000_MEM_STADDR0); |
70 | sleep_static_memctlr[1][0] = au_readl(MEM_STCFG1); | 70 | sleep_static_memctlr[1][0] = alchemy_rdsmem(AU1000_MEM_STCFG1); |
71 | sleep_static_memctlr[1][1] = au_readl(MEM_STTIME1); | 71 | sleep_static_memctlr[1][1] = alchemy_rdsmem(AU1000_MEM_STTIME1); |
72 | sleep_static_memctlr[1][2] = au_readl(MEM_STADDR1); | 72 | sleep_static_memctlr[1][2] = alchemy_rdsmem(AU1000_MEM_STADDR1); |
73 | sleep_static_memctlr[2][0] = au_readl(MEM_STCFG2); | 73 | sleep_static_memctlr[2][0] = alchemy_rdsmem(AU1000_MEM_STCFG2); |
74 | sleep_static_memctlr[2][1] = au_readl(MEM_STTIME2); | 74 | sleep_static_memctlr[2][1] = alchemy_rdsmem(AU1000_MEM_STTIME2); |
75 | sleep_static_memctlr[2][2] = au_readl(MEM_STADDR2); | 75 | sleep_static_memctlr[2][2] = alchemy_rdsmem(AU1000_MEM_STADDR2); |
76 | sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3); | 76 | sleep_static_memctlr[3][0] = alchemy_rdsmem(AU1000_MEM_STCFG3); |
77 | sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3); | 77 | sleep_static_memctlr[3][1] = alchemy_rdsmem(AU1000_MEM_STTIME3); |
78 | sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3); | 78 | sleep_static_memctlr[3][2] = alchemy_rdsmem(AU1000_MEM_STADDR3); |
79 | } | 79 | } |
80 | 80 | ||
81 | static void restore_core_regs(void) | 81 | static void restore_core_regs(void) |
@@ -85,30 +85,28 @@ static void restore_core_regs(void) | |||
85 | * one of those Au1000 with a write-only PLL, where we dont | 85 | * one of those Au1000 with a write-only PLL, where we dont |
86 | * have a valid value) | 86 | * have a valid value) |
87 | */ | 87 | */ |
88 | au_writel(sleep_sys_clocks[0], SYS_FREQCTRL0); | 88 | alchemy_wrsys(sleep_sys_clocks[0], AU1000_SYS_FREQCTRL0); |
89 | au_writel(sleep_sys_clocks[1], SYS_FREQCTRL1); | 89 | alchemy_wrsys(sleep_sys_clocks[1], AU1000_SYS_FREQCTRL1); |
90 | au_writel(sleep_sys_clocks[2], SYS_CLKSRC); | 90 | alchemy_wrsys(sleep_sys_clocks[2], AU1000_SYS_CLKSRC); |
91 | au_writel(sleep_sys_clocks[4], SYS_AUXPLL); | 91 | alchemy_wrsys(sleep_sys_clocks[4], AU1000_SYS_AUXPLL); |
92 | if (!au1xxx_cpu_has_pll_wo()) | 92 | if (!au1xxx_cpu_has_pll_wo()) |
93 | au_writel(sleep_sys_clocks[3], SYS_CPUPLL); | 93 | alchemy_wrsys(sleep_sys_clocks[3], AU1000_SYS_CPUPLL); |
94 | au_sync(); | ||
95 | 94 | ||
96 | au_writel(sleep_sys_pinfunc, SYS_PINFUNC); | 95 | alchemy_wrsys(sleep_sys_pinfunc, AU1000_SYS_PINFUNC); |
97 | au_sync(); | ||
98 | 96 | ||
99 | /* Restore the static memory controller configuration. */ | 97 | /* Restore the static memory controller configuration. */ |
100 | au_writel(sleep_static_memctlr[0][0], MEM_STCFG0); | 98 | alchemy_wrsmem(sleep_static_memctlr[0][0], AU1000_MEM_STCFG0); |
101 | au_writel(sleep_static_memctlr[0][1], MEM_STTIME0); | 99 | alchemy_wrsmem(sleep_static_memctlr[0][1], AU1000_MEM_STTIME0); |
102 | au_writel(sleep_static_memctlr[0][2], MEM_STADDR0); | 100 | alchemy_wrsmem(sleep_static_memctlr[0][2], AU1000_MEM_STADDR0); |
103 | au_writel(sleep_static_memctlr[1][0], MEM_STCFG1); | 101 | alchemy_wrsmem(sleep_static_memctlr[1][0], AU1000_MEM_STCFG1); |
104 | au_writel(sleep_static_memctlr[1][1], MEM_STTIME1); | 102 | alchemy_wrsmem(sleep_static_memctlr[1][1], AU1000_MEM_STTIME1); |
105 | au_writel(sleep_static_memctlr[1][2], MEM_STADDR1); | 103 | alchemy_wrsmem(sleep_static_memctlr[1][2], AU1000_MEM_STADDR1); |
106 | au_writel(sleep_static_memctlr[2][0], MEM_STCFG2); | 104 | alchemy_wrsmem(sleep_static_memctlr[2][0], AU1000_MEM_STCFG2); |
107 | au_writel(sleep_static_memctlr[2][1], MEM_STTIME2); | 105 | alchemy_wrsmem(sleep_static_memctlr[2][1], AU1000_MEM_STTIME2); |
108 | au_writel(sleep_static_memctlr[2][2], MEM_STADDR2); | 106 | alchemy_wrsmem(sleep_static_memctlr[2][2], AU1000_MEM_STADDR2); |
109 | au_writel(sleep_static_memctlr[3][0], MEM_STCFG3); | 107 | alchemy_wrsmem(sleep_static_memctlr[3][0], AU1000_MEM_STCFG3); |
110 | au_writel(sleep_static_memctlr[3][1], MEM_STTIME3); | 108 | alchemy_wrsmem(sleep_static_memctlr[3][1], AU1000_MEM_STTIME3); |
111 | au_writel(sleep_static_memctlr[3][2], MEM_STADDR3); | 109 | alchemy_wrsmem(sleep_static_memctlr[3][2], AU1000_MEM_STADDR3); |
112 | } | 110 | } |
113 | 111 | ||
114 | void au_sleep(void) | 112 | void au_sleep(void) |
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c index 8267e3c97721..ea8f41869e56 100644 --- a/arch/mips/alchemy/common/setup.c +++ b/arch/mips/alchemy/common/setup.c | |||
@@ -27,12 +27,9 @@ | |||
27 | 27 | ||
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/ioport.h> | 29 | #include <linux/ioport.h> |
30 | #include <linux/jiffies.h> | ||
31 | #include <linux/module.h> | ||
32 | 30 | ||
33 | #include <asm/dma-coherence.h> | 31 | #include <asm/dma-coherence.h> |
34 | #include <asm/mipsregs.h> | 32 | #include <asm/mipsregs.h> |
35 | #include <asm/time.h> | ||
36 | 33 | ||
37 | #include <au1000.h> | 34 | #include <au1000.h> |
38 | 35 | ||
@@ -41,18 +38,6 @@ extern void set_cpuspec(void); | |||
41 | 38 | ||
42 | void __init plat_mem_setup(void) | 39 | void __init plat_mem_setup(void) |
43 | { | 40 | { |
44 | unsigned long est_freq; | ||
45 | |||
46 | /* determine core clock */ | ||
47 | est_freq = au1xxx_calc_clock(); | ||
48 | est_freq += 5000; /* round */ | ||
49 | est_freq -= est_freq % 10000; | ||
50 | printk(KERN_INFO "(PRId %08x) @ %lu.%02lu MHz\n", read_c0_prid(), | ||
51 | est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000); | ||
52 | |||
53 | /* this is faster than wasting cycles trying to approximate it */ | ||
54 | preset_lpj = (est_freq >> 1) / HZ; | ||
55 | |||
56 | if (au1xxx_cpu_needs_config_od()) | 41 | if (au1xxx_cpu_needs_config_od()) |
57 | /* Various early Au1xx0 errata corrected by this */ | 42 | /* Various early Au1xx0 errata corrected by this */ |
58 | set_c0_config(1 << 19); /* Set Config[OD] */ | 43 | set_c0_config(1 << 19); /* Set Config[OD] */ |
diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c index 93fa586d52e2..50e17e13c18b 100644 --- a/arch/mips/alchemy/common/time.c +++ b/arch/mips/alchemy/common/time.c | |||
@@ -46,7 +46,7 @@ | |||
46 | 46 | ||
47 | static cycle_t au1x_counter1_read(struct clocksource *cs) | 47 | static cycle_t au1x_counter1_read(struct clocksource *cs) |
48 | { | 48 | { |
49 | return au_readl(SYS_RTCREAD); | 49 | return alchemy_rdsys(AU1000_SYS_RTCREAD); |
50 | } | 50 | } |
51 | 51 | ||
52 | static struct clocksource au1x_counter1_clocksource = { | 52 | static struct clocksource au1x_counter1_clocksource = { |
@@ -60,12 +60,11 @@ static struct clocksource au1x_counter1_clocksource = { | |||
60 | static int au1x_rtcmatch2_set_next_event(unsigned long delta, | 60 | static int au1x_rtcmatch2_set_next_event(unsigned long delta, |
61 | struct clock_event_device *cd) | 61 | struct clock_event_device *cd) |
62 | { | 62 | { |
63 | delta += au_readl(SYS_RTCREAD); | 63 | delta += alchemy_rdsys(AU1000_SYS_RTCREAD); |
64 | /* wait for register access */ | 64 | /* wait for register access */ |
65 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M21) | 65 | while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_M21) |
66 | ; | 66 | ; |
67 | au_writel(delta, SYS_RTCMATCH2); | 67 | alchemy_wrsys(delta, AU1000_SYS_RTCMATCH2); |
68 | au_sync(); | ||
69 | 68 | ||
70 | return 0; | 69 | return 0; |
71 | } | 70 | } |
@@ -112,31 +111,29 @@ static int __init alchemy_time_init(unsigned int m2int) | |||
112 | * (the 32S bit seems to be stuck set to 1 once a single clock- | 111 | * (the 32S bit seems to be stuck set to 1 once a single clock- |
113 | * edge is detected, hence the timeouts). | 112 | * edge is detected, hence the timeouts). |
114 | */ | 113 | */ |
115 | if (CNTR_OK != (au_readl(SYS_COUNTER_CNTRL) & CNTR_OK)) | 114 | if (CNTR_OK != (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & CNTR_OK)) |
116 | goto cntr_err; | 115 | goto cntr_err; |
117 | 116 | ||
118 | /* | 117 | /* |
119 | * setup counter 1 (RTC) to tick at full speed | 118 | * setup counter 1 (RTC) to tick at full speed |
120 | */ | 119 | */ |
121 | t = 0xffffff; | 120 | t = 0xffffff; |
122 | while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S) && --t) | 121 | while ((alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_T1S) && --t) |
123 | asm volatile ("nop"); | 122 | asm volatile ("nop"); |
124 | if (!t) | 123 | if (!t) |
125 | goto cntr_err; | 124 | goto cntr_err; |
126 | 125 | ||
127 | au_writel(0, SYS_RTCTRIM); /* 32.768 kHz */ | 126 | alchemy_wrsys(0, AU1000_SYS_RTCTRIM); /* 32.768 kHz */ |
128 | au_sync(); | ||
129 | 127 | ||
130 | t = 0xffffff; | 128 | t = 0xffffff; |
131 | while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t) | 129 | while ((alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_C1S) && --t) |
132 | asm volatile ("nop"); | 130 | asm volatile ("nop"); |
133 | if (!t) | 131 | if (!t) |
134 | goto cntr_err; | 132 | goto cntr_err; |
135 | au_writel(0, SYS_RTCWRITE); | 133 | alchemy_wrsys(0, AU1000_SYS_RTCWRITE); |
136 | au_sync(); | ||
137 | 134 | ||
138 | t = 0xffffff; | 135 | t = 0xffffff; |
139 | while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && --t) | 136 | while ((alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_C1S) && --t) |
140 | asm volatile ("nop"); | 137 | asm volatile ("nop"); |
141 | if (!t) | 138 | if (!t) |
142 | goto cntr_err; | 139 | goto cntr_err; |
diff --git a/arch/mips/alchemy/common/usb.c b/arch/mips/alchemy/common/usb.c index d193dbea84a1..297805ade849 100644 --- a/arch/mips/alchemy/common/usb.c +++ b/arch/mips/alchemy/common/usb.c | |||
@@ -9,6 +9,7 @@ | |||
9 | * | 9 | * |
10 | */ | 10 | */ |
11 | 11 | ||
12 | #include <linux/clk.h> | ||
12 | #include <linux/init.h> | 13 | #include <linux/init.h> |
13 | #include <linux/io.h> | 14 | #include <linux/io.h> |
14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
@@ -387,10 +388,25 @@ static inline void au1200_usb_init(void) | |||
387 | udelay(1000); | 388 | udelay(1000); |
388 | } | 389 | } |
389 | 390 | ||
390 | static inline void au1000_usb_init(unsigned long rb, int reg) | 391 | static inline int au1000_usb_init(unsigned long rb, int reg) |
391 | { | 392 | { |
392 | void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg); | 393 | void __iomem *base = (void __iomem *)KSEG1ADDR(rb + reg); |
393 | unsigned long r = __raw_readl(base); | 394 | unsigned long r = __raw_readl(base); |
395 | struct clk *c; | ||
396 | |||
397 | /* 48MHz check. Don't init if no one can provide it */ | ||
398 | c = clk_get(NULL, "usbh_clk"); | ||
399 | if (IS_ERR(c)) | ||
400 | return -ENODEV; | ||
401 | if (clk_round_rate(c, 48000000) != 48000000) { | ||
402 | clk_put(c); | ||
403 | return -ENODEV; | ||
404 | } | ||
405 | if (clk_set_rate(c, 48000000)) { | ||
406 | clk_put(c); | ||
407 | return -ENODEV; | ||
408 | } | ||
409 | clk_put(c); | ||
394 | 410 | ||
395 | #if defined(__BIG_ENDIAN) | 411 | #if defined(__BIG_ENDIAN) |
396 | r |= USBHEN_BE; | 412 | r |= USBHEN_BE; |
@@ -400,6 +416,8 @@ static inline void au1000_usb_init(unsigned long rb, int reg) | |||
400 | __raw_writel(r, base); | 416 | __raw_writel(r, base); |
401 | wmb(); | 417 | wmb(); |
402 | udelay(1000); | 418 | udelay(1000); |
419 | |||
420 | return 0; | ||
403 | } | 421 | } |
404 | 422 | ||
405 | 423 | ||
@@ -407,8 +425,15 @@ static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg) | |||
407 | { | 425 | { |
408 | void __iomem *base = (void __iomem *)KSEG1ADDR(rb); | 426 | void __iomem *base = (void __iomem *)KSEG1ADDR(rb); |
409 | unsigned long r = __raw_readl(base + creg); | 427 | unsigned long r = __raw_readl(base + creg); |
428 | struct clk *c = clk_get(NULL, "usbh_clk"); | ||
429 | |||
430 | if (IS_ERR(c)) | ||
431 | return; | ||
410 | 432 | ||
411 | if (enable) { | 433 | if (enable) { |
434 | if (clk_prepare_enable(c)) | ||
435 | goto out; | ||
436 | |||
412 | __raw_writel(r | USBHEN_CE, base + creg); | 437 | __raw_writel(r | USBHEN_CE, base + creg); |
413 | wmb(); | 438 | wmb(); |
414 | udelay(1000); | 439 | udelay(1000); |
@@ -423,7 +448,10 @@ static inline void __au1xx0_ohci_control(int enable, unsigned long rb, int creg) | |||
423 | } else { | 448 | } else { |
424 | __raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg); | 449 | __raw_writel(r & ~(USBHEN_CE | USBHEN_E), base + creg); |
425 | wmb(); | 450 | wmb(); |
451 | clk_disable_unprepare(c); | ||
426 | } | 452 | } |
453 | out: | ||
454 | clk_put(c); | ||
427 | } | 455 | } |
428 | 456 | ||
429 | static inline int au1000_usb_control(int block, int enable, unsigned long rb, | 457 | static inline int au1000_usb_control(int block, int enable, unsigned long rb, |
@@ -457,11 +485,11 @@ int alchemy_usb_control(int block, int enable) | |||
457 | case ALCHEMY_CPU_AU1500: | 485 | case ALCHEMY_CPU_AU1500: |
458 | case ALCHEMY_CPU_AU1100: | 486 | case ALCHEMY_CPU_AU1100: |
459 | ret = au1000_usb_control(block, enable, | 487 | ret = au1000_usb_control(block, enable, |
460 | AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); | 488 | AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); |
461 | break; | 489 | break; |
462 | case ALCHEMY_CPU_AU1550: | 490 | case ALCHEMY_CPU_AU1550: |
463 | ret = au1000_usb_control(block, enable, | 491 | ret = au1000_usb_control(block, enable, |
464 | AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); | 492 | AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); |
465 | break; | 493 | break; |
466 | case ALCHEMY_CPU_AU1200: | 494 | case ALCHEMY_CPU_AU1200: |
467 | ret = au1200_usb_control(block, enable); | 495 | ret = au1200_usb_control(block, enable); |
@@ -569,14 +597,18 @@ static struct syscore_ops alchemy_usb_pm_ops = { | |||
569 | 597 | ||
570 | static int __init alchemy_usb_init(void) | 598 | static int __init alchemy_usb_init(void) |
571 | { | 599 | { |
600 | int ret = 0; | ||
601 | |||
572 | switch (alchemy_get_cputype()) { | 602 | switch (alchemy_get_cputype()) { |
573 | case ALCHEMY_CPU_AU1000: | 603 | case ALCHEMY_CPU_AU1000: |
574 | case ALCHEMY_CPU_AU1500: | 604 | case ALCHEMY_CPU_AU1500: |
575 | case ALCHEMY_CPU_AU1100: | 605 | case ALCHEMY_CPU_AU1100: |
576 | au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, AU1000_OHCICFG); | 606 | ret = au1000_usb_init(AU1000_USB_OHCI_PHYS_ADDR, |
607 | AU1000_OHCICFG); | ||
577 | break; | 608 | break; |
578 | case ALCHEMY_CPU_AU1550: | 609 | case ALCHEMY_CPU_AU1550: |
579 | au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, AU1550_OHCICFG); | 610 | ret = au1000_usb_init(AU1550_USB_OHCI_PHYS_ADDR, |
611 | AU1550_OHCICFG); | ||
580 | break; | 612 | break; |
581 | case ALCHEMY_CPU_AU1200: | 613 | case ALCHEMY_CPU_AU1200: |
582 | au1200_usb_init(); | 614 | au1200_usb_init(); |
@@ -586,8 +618,9 @@ static int __init alchemy_usb_init(void) | |||
586 | break; | 618 | break; |
587 | } | 619 | } |
588 | 620 | ||
589 | register_syscore_ops(&alchemy_usb_pm_ops); | 621 | if (!ret) |
622 | register_syscore_ops(&alchemy_usb_pm_ops); | ||
590 | 623 | ||
591 | return 0; | 624 | return ret; |
592 | } | 625 | } |
593 | arch_initcall(alchemy_usb_init); | 626 | arch_initcall(alchemy_usb_init); |
diff --git a/arch/mips/alchemy/devboards/db1000.c b/arch/mips/alchemy/devboards/db1000.c index 92dd929d4057..001102e197f1 100644 --- a/arch/mips/alchemy/devboards/db1000.c +++ b/arch/mips/alchemy/devboards/db1000.c | |||
@@ -19,6 +19,7 @@ | |||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/clk.h> | ||
22 | #include <linux/dma-mapping.h> | 23 | #include <linux/dma-mapping.h> |
23 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
24 | #include <linux/init.h> | 25 | #include <linux/init.h> |
@@ -496,6 +497,7 @@ int __init db1000_dev_setup(void) | |||
496 | int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); | 497 | int board = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); |
497 | int c0, c1, d0, d1, s0, s1, flashsize = 32, twosocks = 1; | 498 | int c0, c1, d0, d1, s0, s1, flashsize = 32, twosocks = 1; |
498 | unsigned long pfc; | 499 | unsigned long pfc; |
500 | struct clk *c, *p; | ||
499 | 501 | ||
500 | if (board == BCSR_WHOAMI_DB1500) { | 502 | if (board == BCSR_WHOAMI_DB1500) { |
501 | c0 = AU1500_GPIO2_INT; | 503 | c0 = AU1500_GPIO2_INT; |
@@ -518,14 +520,25 @@ int __init db1000_dev_setup(void) | |||
518 | gpio_direction_input(20); /* sd1 cd# */ | 520 | gpio_direction_input(20); /* sd1 cd# */ |
519 | 521 | ||
520 | /* spi_gpio on SSI0 pins */ | 522 | /* spi_gpio on SSI0 pins */ |
521 | pfc = __raw_readl((void __iomem *)SYS_PINFUNC); | 523 | pfc = alchemy_rdsys(AU1000_SYS_PINFUNC); |
522 | pfc |= (1 << 0); /* SSI0 pins as GPIOs */ | 524 | pfc |= (1 << 0); /* SSI0 pins as GPIOs */ |
523 | __raw_writel(pfc, (void __iomem *)SYS_PINFUNC); | 525 | alchemy_wrsys(pfc, AU1000_SYS_PINFUNC); |
524 | wmb(); | ||
525 | 526 | ||
526 | spi_register_board_info(db1100_spi_info, | 527 | spi_register_board_info(db1100_spi_info, |
527 | ARRAY_SIZE(db1100_spi_info)); | 528 | ARRAY_SIZE(db1100_spi_info)); |
528 | 529 | ||
530 | /* link LCD clock to AUXPLL */ | ||
531 | p = clk_get(NULL, "auxpll_clk"); | ||
532 | c = clk_get(NULL, "lcd_intclk"); | ||
533 | if (!IS_ERR(c) && !IS_ERR(p)) { | ||
534 | clk_set_parent(c, p); | ||
535 | clk_set_rate(c, clk_get_rate(p)); | ||
536 | } | ||
537 | if (!IS_ERR(c)) | ||
538 | clk_put(c); | ||
539 | if (!IS_ERR(p)) | ||
540 | clk_put(p); | ||
541 | |||
529 | platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs)); | 542 | platform_add_devices(db1100_devs, ARRAY_SIZE(db1100_devs)); |
530 | platform_device_register(&db1100_spi_dev); | 543 | platform_device_register(&db1100_spi_dev); |
531 | } else if (board == BCSR_WHOAMI_DB1000) { | 544 | } else if (board == BCSR_WHOAMI_DB1000) { |
diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c index 9e46667f2597..776188908dfc 100644 --- a/arch/mips/alchemy/devboards/db1200.c +++ b/arch/mips/alchemy/devboards/db1200.c | |||
@@ -18,6 +18,7 @@ | |||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/clk.h> | ||
21 | #include <linux/dma-mapping.h> | 22 | #include <linux/dma-mapping.h> |
22 | #include <linux/gpio.h> | 23 | #include <linux/gpio.h> |
23 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
@@ -129,7 +130,6 @@ static int __init db1200_detect_board(void) | |||
129 | 130 | ||
130 | int __init db1200_board_setup(void) | 131 | int __init db1200_board_setup(void) |
131 | { | 132 | { |
132 | unsigned long freq0, clksrc, div, pfc; | ||
133 | unsigned short whoami; | 133 | unsigned short whoami; |
134 | 134 | ||
135 | if (db1200_detect_board()) | 135 | if (db1200_detect_board()) |
@@ -149,34 +149,6 @@ int __init db1200_board_setup(void) | |||
149 | " Board-ID %d Daughtercard ID %d\n", get_system_type(), | 149 | " Board-ID %d Daughtercard ID %d\n", get_system_type(), |
150 | (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf); | 150 | (whoami >> 4) & 0xf, (whoami >> 8) & 0xf, whoami & 0xf); |
151 | 151 | ||
152 | /* SMBus/SPI on PSC0, Audio on PSC1 */ | ||
153 | pfc = __raw_readl((void __iomem *)SYS_PINFUNC); | ||
154 | pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B); | ||
155 | pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3); | ||
156 | pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */ | ||
157 | __raw_writel(pfc, (void __iomem *)SYS_PINFUNC); | ||
158 | wmb(); | ||
159 | |||
160 | /* Clock configurations: PSC0: ~50MHz via Clkgen0, derived from | ||
161 | * CPU clock; all other clock generators off/unused. | ||
162 | */ | ||
163 | div = (get_au1x00_speed() + 25000000) / 50000000; | ||
164 | if (div & 1) | ||
165 | div++; | ||
166 | div = ((div >> 1) - 1) & 0xff; | ||
167 | |||
168 | freq0 = div << SYS_FC_FRDIV0_BIT; | ||
169 | __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0); | ||
170 | wmb(); | ||
171 | freq0 |= SYS_FC_FE0; /* enable F0 */ | ||
172 | __raw_writel(freq0, (void __iomem *)SYS_FREQCTRL0); | ||
173 | wmb(); | ||
174 | |||
175 | /* psc0_intclk comes 1:1 from F0 */ | ||
176 | clksrc = SYS_CS_MUX_FQ0 << SYS_CS_ME0_BIT; | ||
177 | __raw_writel(clksrc, (void __iomem *)SYS_CLKSRC); | ||
178 | wmb(); | ||
179 | |||
180 | return 0; | 152 | return 0; |
181 | } | 153 | } |
182 | 154 | ||
@@ -250,7 +222,7 @@ static void au1200_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | |||
250 | 222 | ||
251 | static int au1200_nand_device_ready(struct mtd_info *mtd) | 223 | static int au1200_nand_device_ready(struct mtd_info *mtd) |
252 | { | 224 | { |
253 | return __raw_readl((void __iomem *)MEM_STSTAT) & 1; | 225 | return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1; |
254 | } | 226 | } |
255 | 227 | ||
256 | static struct mtd_partition db1200_nand_parts[] = { | 228 | static struct mtd_partition db1200_nand_parts[] = { |
@@ -847,6 +819,7 @@ int __init db1200_dev_setup(void) | |||
847 | unsigned long pfc; | 819 | unsigned long pfc; |
848 | unsigned short sw; | 820 | unsigned short sw; |
849 | int swapped, bid; | 821 | int swapped, bid; |
822 | struct clk *c; | ||
850 | 823 | ||
851 | bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); | 824 | bid = BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)); |
852 | if ((bid == BCSR_WHOAMI_PB1200_DDR1) || | 825 | if ((bid == BCSR_WHOAMI_PB1200_DDR1) || |
@@ -859,6 +832,24 @@ int __init db1200_dev_setup(void) | |||
859 | irq_set_irq_type(AU1200_GPIO7_INT, IRQ_TYPE_LEVEL_LOW); | 832 | irq_set_irq_type(AU1200_GPIO7_INT, IRQ_TYPE_LEVEL_LOW); |
860 | bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT); | 833 | bcsr_init_irq(DB1200_INT_BEGIN, DB1200_INT_END, AU1200_GPIO7_INT); |
861 | 834 | ||
835 | /* SMBus/SPI on PSC0, Audio on PSC1 */ | ||
836 | pfc = alchemy_rdsys(AU1000_SYS_PINFUNC); | ||
837 | pfc &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B); | ||
838 | pfc &= ~(SYS_PINFUNC_P1A | SYS_PINFUNC_P1B | SYS_PINFUNC_FS3); | ||
839 | pfc |= SYS_PINFUNC_P1C; /* SPI is configured later */ | ||
840 | alchemy_wrsys(pfc, AU1000_SYS_PINFUNC); | ||
841 | |||
842 | /* get 50MHz for I2C driver on PSC0 */ | ||
843 | c = clk_get(NULL, "psc0_intclk"); | ||
844 | if (!IS_ERR(c)) { | ||
845 | pfc = clk_round_rate(c, 50000000); | ||
846 | if ((pfc < 1) || (abs(50000000 - pfc) > 2500000)) | ||
847 | pr_warn("DB1200: cant get I2C close to 50MHz\n"); | ||
848 | else | ||
849 | clk_set_rate(c, pfc); | ||
850 | clk_put(c); | ||
851 | } | ||
852 | |||
862 | /* insert/eject pairs: one of both is always screaming. To avoid | 853 | /* insert/eject pairs: one of both is always screaming. To avoid |
863 | * issues they must not be automatically enabled when initially | 854 | * issues they must not be automatically enabled when initially |
864 | * requested. | 855 | * requested. |
@@ -886,7 +877,7 @@ int __init db1200_dev_setup(void) | |||
886 | * As a result, in SPI mode, OTG simply won't work (PSC0 uses | 877 | * As a result, in SPI mode, OTG simply won't work (PSC0 uses |
887 | * it as an input pin which is pulled high on the boards). | 878 | * it as an input pin which is pulled high on the boards). |
888 | */ | 879 | */ |
889 | pfc = __raw_readl((void __iomem *)SYS_PINFUNC) & ~SYS_PINFUNC_P0A; | 880 | pfc = alchemy_rdsys(AU1000_SYS_PINFUNC) & ~SYS_PINFUNC_P0A; |
890 | 881 | ||
891 | /* switch off OTG VBUS supply */ | 882 | /* switch off OTG VBUS supply */ |
892 | gpio_request(215, "otg-vbus"); | 883 | gpio_request(215, "otg-vbus"); |
@@ -912,8 +903,7 @@ int __init db1200_dev_setup(void) | |||
912 | printk(KERN_INFO " S6.8 ON : PSC0 mode SPI\n"); | 903 | printk(KERN_INFO " S6.8 ON : PSC0 mode SPI\n"); |
913 | printk(KERN_INFO " OTG port VBUS supply disabled\n"); | 904 | printk(KERN_INFO " OTG port VBUS supply disabled\n"); |
914 | } | 905 | } |
915 | __raw_writel(pfc, (void __iomem *)SYS_PINFUNC); | 906 | alchemy_wrsys(pfc, AU1000_SYS_PINFUNC); |
916 | wmb(); | ||
917 | 907 | ||
918 | /* Audio: DIP7 selects I2S(0)/AC97(1), but need I2C for I2S! | 908 | /* Audio: DIP7 selects I2S(0)/AC97(1), but need I2C for I2S! |
919 | * so: DIP7=1 || DIP8=0 => AC97, DIP7=0 && DIP8=1 => I2S | 909 | * so: DIP7=1 || DIP8=0 => AC97, DIP7=0 && DIP8=1 => I2S |
@@ -932,6 +922,11 @@ int __init db1200_dev_setup(void) | |||
932 | } | 922 | } |
933 | 923 | ||
934 | /* Audio PSC clock is supplied externally. (FIXME: platdata!!) */ | 924 | /* Audio PSC clock is supplied externally. (FIXME: platdata!!) */ |
925 | c = clk_get(NULL, "psc1_intclk"); | ||
926 | if (!IS_ERR(c)) { | ||
927 | clk_prepare_enable(c); | ||
928 | clk_put(c); | ||
929 | } | ||
935 | __raw_writel(PSC_SEL_CLK_SERCLK, | 930 | __raw_writel(PSC_SEL_CLK_SERCLK, |
936 | (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); | 931 | (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); |
937 | wmb(); | 932 | wmb(); |
diff --git a/arch/mips/alchemy/devboards/db1300.c b/arch/mips/alchemy/devboards/db1300.c index 1aed6be4de10..ef93ee3f6a2c 100644 --- a/arch/mips/alchemy/devboards/db1300.c +++ b/arch/mips/alchemy/devboards/db1300.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * (c) 2009 Manuel Lauss <manuel.lauss@googlemail.com> | 4 | * (c) 2009 Manuel Lauss <manuel.lauss@googlemail.com> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/clk.h> | ||
7 | #include <linux/dma-mapping.h> | 8 | #include <linux/dma-mapping.h> |
8 | #include <linux/gpio.h> | 9 | #include <linux/gpio.h> |
9 | #include <linux/gpio_keys.h> | 10 | #include <linux/gpio_keys.h> |
@@ -169,7 +170,7 @@ static void au1300_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | |||
169 | 170 | ||
170 | static int au1300_nand_device_ready(struct mtd_info *mtd) | 171 | static int au1300_nand_device_ready(struct mtd_info *mtd) |
171 | { | 172 | { |
172 | return __raw_readl((void __iomem *)MEM_STSTAT) & 1; | 173 | return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1; |
173 | } | 174 | } |
174 | 175 | ||
175 | static struct mtd_partition db1300_nand_parts[] = { | 176 | static struct mtd_partition db1300_nand_parts[] = { |
@@ -731,6 +732,7 @@ static struct platform_device *db1300_dev[] __initdata = { | |||
731 | int __init db1300_dev_setup(void) | 732 | int __init db1300_dev_setup(void) |
732 | { | 733 | { |
733 | int swapped, cpldirq; | 734 | int swapped, cpldirq; |
735 | struct clk *c; | ||
734 | 736 | ||
735 | /* setup CPLD IRQ muxer */ | 737 | /* setup CPLD IRQ muxer */ |
736 | cpldirq = au1300_gpio_to_irq(AU1300_PIN_EXTCLK1); | 738 | cpldirq = au1300_gpio_to_irq(AU1300_PIN_EXTCLK1); |
@@ -761,6 +763,11 @@ int __init db1300_dev_setup(void) | |||
761 | (void __iomem *)KSEG1ADDR(AU1300_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET); | 763 | (void __iomem *)KSEG1ADDR(AU1300_PSC2_PHYS_ADDR) + PSC_SEL_OFFSET); |
762 | wmb(); | 764 | wmb(); |
763 | /* I2C uses internal 48MHz EXTCLK1 */ | 765 | /* I2C uses internal 48MHz EXTCLK1 */ |
766 | c = clk_get(NULL, "psc3_intclk"); | ||
767 | if (!IS_ERR(c)) { | ||
768 | clk_prepare_enable(c); | ||
769 | clk_put(c); | ||
770 | } | ||
764 | __raw_writel(PSC_SEL_CLK_INTCLK, | 771 | __raw_writel(PSC_SEL_CLK_INTCLK, |
765 | (void __iomem *)KSEG1ADDR(AU1300_PSC3_PHYS_ADDR) + PSC_SEL_OFFSET); | 772 | (void __iomem *)KSEG1ADDR(AU1300_PSC3_PHYS_ADDR) + PSC_SEL_OFFSET); |
766 | wmb(); | 773 | wmb(); |
diff --git a/arch/mips/alchemy/devboards/db1550.c b/arch/mips/alchemy/devboards/db1550.c index bbd8d9884702..7e89936f763e 100644 --- a/arch/mips/alchemy/devboards/db1550.c +++ b/arch/mips/alchemy/devboards/db1550.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com> | 4 | * (c) 2011 Manuel Lauss <manuel.lauss@googlemail.com> |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <linux/clk.h> | ||
7 | #include <linux/dma-mapping.h> | 8 | #include <linux/dma-mapping.h> |
8 | #include <linux/gpio.h> | 9 | #include <linux/gpio.h> |
9 | #include <linux/i2c.h> | 10 | #include <linux/i2c.h> |
@@ -31,16 +32,16 @@ | |||
31 | static void __init db1550_hw_setup(void) | 32 | static void __init db1550_hw_setup(void) |
32 | { | 33 | { |
33 | void __iomem *base; | 34 | void __iomem *base; |
35 | unsigned long v; | ||
34 | 36 | ||
35 | /* complete SPI setup: link psc0_intclk to a 48MHz source, | 37 | /* complete SPI setup: link psc0_intclk to a 48MHz source, |
36 | * and assign GPIO16 to PSC0_SYNC1 (SPI cs# line) as well as PSC1_SYNC | 38 | * and assign GPIO16 to PSC0_SYNC1 (SPI cs# line) as well as PSC1_SYNC |
37 | * for AC97 on PB1550. | 39 | * for AC97 on PB1550. |
38 | */ | 40 | */ |
39 | base = (void __iomem *)SYS_CLKSRC; | 41 | v = alchemy_rdsys(AU1000_SYS_CLKSRC); |
40 | __raw_writel(__raw_readl(base) | 0x000001e0, base); | 42 | alchemy_wrsys(v | 0x000001e0, AU1000_SYS_CLKSRC); |
41 | base = (void __iomem *)SYS_PINFUNC; | 43 | v = alchemy_rdsys(AU1000_SYS_PINFUNC); |
42 | __raw_writel(__raw_readl(base) | 1 | SYS_PF_PSC1_S1, base); | 44 | alchemy_wrsys(v | 1 | SYS_PF_PSC1_S1, AU1000_SYS_PINFUNC); |
43 | wmb(); | ||
44 | 45 | ||
45 | /* reset the AC97 codec now, the reset time in the psc-ac97 driver | 46 | /* reset the AC97 codec now, the reset time in the psc-ac97 driver |
46 | * is apparently too short although it's ridiculous as it is. | 47 | * is apparently too short although it's ridiculous as it is. |
@@ -151,7 +152,7 @@ static void au1550_nand_cmd_ctrl(struct mtd_info *mtd, int cmd, | |||
151 | 152 | ||
152 | static int au1550_nand_device_ready(struct mtd_info *mtd) | 153 | static int au1550_nand_device_ready(struct mtd_info *mtd) |
153 | { | 154 | { |
154 | return __raw_readl((void __iomem *)MEM_STSTAT) & 1; | 155 | return alchemy_rdsmem(AU1000_MEM_STSTAT) & 1; |
155 | } | 156 | } |
156 | 157 | ||
157 | static struct mtd_partition db1550_nand_parts[] = { | 158 | static struct mtd_partition db1550_nand_parts[] = { |
@@ -217,7 +218,7 @@ static struct platform_device pb1550_nand_dev = { | |||
217 | 218 | ||
218 | static void __init pb1550_nand_setup(void) | 219 | static void __init pb1550_nand_setup(void) |
219 | { | 220 | { |
220 | int boot_swapboot = (au_readl(MEM_STSTAT) & (0x7 << 1)) | | 221 | int boot_swapboot = (alchemy_rdsmem(AU1000_MEM_STSTAT) & (0x7 << 1)) | |
221 | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1); | 222 | ((bcsr_read(BCSR_STATUS) >> 6) & 0x1); |
222 | 223 | ||
223 | gpio_direction_input(206); /* de-assert NAND CS# */ | 224 | gpio_direction_input(206); /* de-assert NAND CS# */ |
@@ -574,6 +575,7 @@ static void __init pb1550_devices(void) | |||
574 | int __init db1550_dev_setup(void) | 575 | int __init db1550_dev_setup(void) |
575 | { | 576 | { |
576 | int swapped, id; | 577 | int swapped, id; |
578 | struct clk *c; | ||
577 | 579 | ||
578 | id = (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) != BCSR_WHOAMI_DB1550); | 580 | id = (BCSR_WHOAMI_BOARD(bcsr_read(BCSR_WHOAMI)) != BCSR_WHOAMI_DB1550); |
579 | 581 | ||
@@ -582,6 +584,17 @@ int __init db1550_dev_setup(void) | |||
582 | spi_register_board_info(db1550_spi_devs, | 584 | spi_register_board_info(db1550_spi_devs, |
583 | ARRAY_SIZE(db1550_i2c_devs)); | 585 | ARRAY_SIZE(db1550_i2c_devs)); |
584 | 586 | ||
587 | c = clk_get(NULL, "psc0_intclk"); | ||
588 | if (!IS_ERR(c)) { | ||
589 | clk_prepare_enable(c); | ||
590 | clk_put(c); | ||
591 | } | ||
592 | c = clk_get(NULL, "psc2_intclk"); | ||
593 | if (!IS_ERR(c)) { | ||
594 | clk_prepare_enable(c); | ||
595 | clk_put(c); | ||
596 | } | ||
597 | |||
585 | /* Audio PSC clock is supplied by codecs (PSC1, 3) FIXME: platdata!! */ | 598 | /* Audio PSC clock is supplied by codecs (PSC1, 3) FIXME: platdata!! */ |
586 | __raw_writel(PSC_SEL_CLK_SERCLK, | 599 | __raw_writel(PSC_SEL_CLK_SERCLK, |
587 | (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); | 600 | (void __iomem *)KSEG1ADDR(AU1550_PSC1_PHYS_ADDR) + PSC_SEL_OFFSET); |
diff --git a/arch/mips/alchemy/devboards/pm.c b/arch/mips/alchemy/devboards/pm.c index 61e90fe9eab1..bfeb8f3c0be6 100644 --- a/arch/mips/alchemy/devboards/pm.c +++ b/arch/mips/alchemy/devboards/pm.c | |||
@@ -45,23 +45,20 @@ static int db1x_pm_enter(suspend_state_t state) | |||
45 | alchemy_gpio1_input_enable(); | 45 | alchemy_gpio1_input_enable(); |
46 | 46 | ||
47 | /* clear and setup wake cause and source */ | 47 | /* clear and setup wake cause and source */ |
48 | au_writel(0, SYS_WAKEMSK); | 48 | alchemy_wrsys(0, AU1000_SYS_WAKEMSK); |
49 | au_sync(); | 49 | alchemy_wrsys(0, AU1000_SYS_WAKESRC); |
50 | au_writel(0, SYS_WAKESRC); | ||
51 | au_sync(); | ||
52 | 50 | ||
53 | au_writel(db1x_pm_wakemsk, SYS_WAKEMSK); | 51 | alchemy_wrsys(db1x_pm_wakemsk, AU1000_SYS_WAKEMSK); |
54 | au_sync(); | ||
55 | 52 | ||
56 | /* setup 1Hz-timer-based wakeup: wait for reg access */ | 53 | /* setup 1Hz-timer-based wakeup: wait for reg access */ |
57 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) | 54 | while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_M20) |
58 | asm volatile ("nop"); | 55 | asm volatile ("nop"); |
59 | 56 | ||
60 | au_writel(au_readl(SYS_TOYREAD) + db1x_pm_sleep_secs, SYS_TOYMATCH2); | 57 | alchemy_wrsys(alchemy_rdsys(AU1000_SYS_TOYREAD) + db1x_pm_sleep_secs, |
61 | au_sync(); | 58 | AU1000_SYS_TOYMATCH2); |
62 | 59 | ||
63 | /* wait for value to really hit the register */ | 60 | /* wait for value to really hit the register */ |
64 | while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) | 61 | while (alchemy_rdsys(AU1000_SYS_CNTRCTRL) & SYS_CNTRL_M20) |
65 | asm volatile ("nop"); | 62 | asm volatile ("nop"); |
66 | 63 | ||
67 | /* ...and now the sandman can come! */ | 64 | /* ...and now the sandman can come! */ |
@@ -102,12 +99,10 @@ static void db1x_pm_end(void) | |||
102 | /* read and store wakeup source, the clear the register. To | 99 | /* read and store wakeup source, the clear the register. To |
103 | * be able to clear it, WAKEMSK must be cleared first. | 100 | * be able to clear it, WAKEMSK must be cleared first. |
104 | */ | 101 | */ |
105 | db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC); | 102 | db1x_pm_last_wakesrc = alchemy_rdsys(AU1000_SYS_WAKESRC); |
106 | |||
107 | au_writel(0, SYS_WAKEMSK); | ||
108 | au_writel(0, SYS_WAKESRC); | ||
109 | au_sync(); | ||
110 | 103 | ||
104 | alchemy_wrsys(0, AU1000_SYS_WAKEMSK); | ||
105 | alchemy_wrsys(0, AU1000_SYS_WAKESRC); | ||
111 | } | 106 | } |
112 | 107 | ||
113 | static const struct platform_suspend_ops db1x_pm_ops = { | 108 | static const struct platform_suspend_ops db1x_pm_ops = { |
@@ -242,17 +237,13 @@ static int __init pm_init(void) | |||
242 | * for confirmation since there's plenty of time from here to | 237 | * for confirmation since there's plenty of time from here to |
243 | * the next suspend cycle. | 238 | * the next suspend cycle. |
244 | */ | 239 | */ |
245 | if (au_readl(SYS_TOYTRIM) != 32767) { | 240 | if (alchemy_rdsys(AU1000_SYS_TOYTRIM) != 32767) |
246 | au_writel(32767, SYS_TOYTRIM); | 241 | alchemy_wrsys(32767, AU1000_SYS_TOYTRIM); |
247 | au_sync(); | ||
248 | } | ||
249 | 242 | ||
250 | db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC); | 243 | db1x_pm_last_wakesrc = alchemy_rdsys(AU1000_SYS_WAKESRC); |
251 | 244 | ||
252 | au_writel(0, SYS_WAKESRC); | 245 | alchemy_wrsys(0, AU1000_SYS_WAKESRC); |
253 | au_sync(); | 246 | alchemy_wrsys(0, AU1000_SYS_WAKEMSK); |
254 | au_writel(0, SYS_WAKEMSK); | ||
255 | au_sync(); | ||
256 | 247 | ||
257 | suspend_set_ops(&db1x_pm_ops); | 248 | suspend_set_ops(&db1x_pm_ops); |
258 | 249 | ||
diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig index 09cb6f7aa3db..fc21d3659fa0 100644 --- a/arch/mips/bcm47xx/Kconfig +++ b/arch/mips/bcm47xx/Kconfig | |||
@@ -11,8 +11,6 @@ config BCM47XX_SSB | |||
11 | select SSB_DRIVER_PCICORE if PCI | 11 | select SSB_DRIVER_PCICORE if PCI |
12 | select SSB_PCICORE_HOSTMODE if PCI | 12 | select SSB_PCICORE_HOSTMODE if PCI |
13 | select SSB_DRIVER_GPIO | 13 | select SSB_DRIVER_GPIO |
14 | select GPIOLIB | ||
15 | select LEDS_GPIO_REGISTER | ||
16 | default y | 14 | default y |
17 | help | 15 | help |
18 | Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support. | 16 | Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support. |
@@ -22,6 +20,7 @@ config BCM47XX_SSB | |||
22 | config BCM47XX_BCMA | 20 | config BCM47XX_BCMA |
23 | bool "BCMA Support for Broadcom BCM47XX" | 21 | bool "BCMA Support for Broadcom BCM47XX" |
24 | select SYS_HAS_CPU_MIPS32_R2 | 22 | select SYS_HAS_CPU_MIPS32_R2 |
23 | select SYS_SUPPORTS_HIGHMEM | ||
25 | select CPU_MIPSR2_IRQ_VI | 24 | select CPU_MIPSR2_IRQ_VI |
26 | select BCMA | 25 | select BCMA |
27 | select BCMA_HOST_SOC | 26 | select BCMA_HOST_SOC |
@@ -29,8 +28,6 @@ config BCM47XX_BCMA | |||
29 | select BCMA_HOST_PCI if PCI | 28 | select BCMA_HOST_PCI if PCI |
30 | select BCMA_DRIVER_PCI_HOSTMODE if PCI | 29 | select BCMA_DRIVER_PCI_HOSTMODE if PCI |
31 | select BCMA_DRIVER_GPIO | 30 | select BCMA_DRIVER_GPIO |
32 | select GPIOLIB | ||
33 | select LEDS_GPIO_REGISTER | ||
34 | default y | 31 | default y |
35 | help | 32 | help |
36 | Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus. | 33 | Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus. |
diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h index 0194c3b9a729..f1cc9d0495d8 100644 --- a/arch/mips/bcm47xx/bcm47xx_private.h +++ b/arch/mips/bcm47xx/bcm47xx_private.h | |||
@@ -3,6 +3,9 @@ | |||
3 | 3 | ||
4 | #include <linux/kernel.h> | 4 | #include <linux/kernel.h> |
5 | 5 | ||
6 | /* prom.c */ | ||
7 | void __init bcm47xx_prom_highmem_init(void); | ||
8 | |||
6 | /* buttons.c */ | 9 | /* buttons.c */ |
7 | int __init bcm47xx_buttons_register(void); | 10 | int __init bcm47xx_buttons_register(void); |
8 | 11 | ||
diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c index 44ab1be68c3c..b3ae068ca4fa 100644 --- a/arch/mips/bcm47xx/board.c +++ b/arch/mips/bcm47xx/board.c | |||
@@ -58,6 +58,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_machine_name[] __initconst = | |||
58 | static const | 58 | static const |
59 | struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initconst = { | 59 | struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initconst = { |
60 | {{BCM47XX_BOARD_ASUS_RTN10U, "Asus RT-N10U"}, "RTN10U"}, | 60 | {{BCM47XX_BOARD_ASUS_RTN10U, "Asus RT-N10U"}, "RTN10U"}, |
61 | {{BCM47XX_BOARD_ASUS_RTN10D, "Asus RT-N10D"}, "RTN10D"}, | ||
61 | {{BCM47XX_BOARD_ASUS_RTN12, "Asus RT-N12"}, "RT-N12"}, | 62 | {{BCM47XX_BOARD_ASUS_RTN12, "Asus RT-N12"}, "RT-N12"}, |
62 | {{BCM47XX_BOARD_ASUS_RTN12B1, "Asus RT-N12B1"}, "RTN12B1"}, | 63 | {{BCM47XX_BOARD_ASUS_RTN12B1, "Asus RT-N12B1"}, "RTN12B1"}, |
63 | {{BCM47XX_BOARD_ASUS_RTN12C1, "Asus RT-N12C1"}, "RTN12C1"}, | 64 | {{BCM47XX_BOARD_ASUS_RTN12C1, "Asus RT-N12C1"}, "RTN12C1"}, |
@@ -80,6 +81,14 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initcons | |||
80 | { {0}, NULL}, | 81 | { {0}, NULL}, |
81 | }; | 82 | }; |
82 | 83 | ||
84 | /* hardware_version, boardnum */ | ||
85 | static const | ||
86 | struct bcm47xx_board_type_list2 bcm47xx_board_list_hw_version_num[] __initconst = { | ||
87 | {{BCM47XX_BOARD_MICROSOFT_MN700, "Microsoft MN-700"}, "WL500-", "mn700"}, | ||
88 | {{BCM47XX_BOARD_ASUS_WL500G, "Asus WL500G"}, "WL500-", "asusX"}, | ||
89 | { {0}, NULL}, | ||
90 | }; | ||
91 | |||
83 | /* productid */ | 92 | /* productid */ |
84 | static const | 93 | static const |
85 | struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = { | 94 | struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = { |
@@ -98,7 +107,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = { | |||
98 | /* ModelId */ | 107 | /* ModelId */ |
99 | static const | 108 | static const |
100 | struct bcm47xx_board_type_list1 bcm47xx_board_list_ModelId[] __initconst = { | 109 | struct bcm47xx_board_type_list1 bcm47xx_board_list_ModelId[] __initconst = { |
101 | {{BCM47XX_BOARD_DELL_TM2300, "Dell WX-5565"}, "WX-5565"}, | 110 | {{BCM47XX_BOARD_DELL_TM2300, "Dell TrueMobile 2300"}, "WX-5565"}, |
102 | {{BCM47XX_BOARD_MOTOROLA_WE800G, "Motorola WE800G"}, "WE800G"}, | 111 | {{BCM47XX_BOARD_MOTOROLA_WE800G, "Motorola WE800G"}, "WE800G"}, |
103 | {{BCM47XX_BOARD_MOTOROLA_WR850GP, "Motorola WR850GP"}, "WR850GP"}, | 112 | {{BCM47XX_BOARD_MOTOROLA_WR850GP, "Motorola WR850GP"}, "WR850GP"}, |
104 | {{BCM47XX_BOARD_MOTOROLA_WR850GV2V3, "Motorola WR850G"}, "WR850G"}, | 113 | {{BCM47XX_BOARD_MOTOROLA_WR850GV2V3, "Motorola WR850G"}, "WR850G"}, |
@@ -180,9 +189,9 @@ struct bcm47xx_board_type_list3 bcm47xx_board_list_board[] __initconst = { | |||
180 | {{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"}, | 189 | {{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"}, |
181 | {{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"}, | 190 | {{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"}, |
182 | {{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "0x04CF", "3500", "02"}, | 191 | {{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "0x04CF", "3500", "02"}, |
183 | {{BCM47XX_BOARD_LINKSYS_WRT54G, "Linksys WRT54G/GS/GL"}, "0x0101", "42", "0x10"}, | 192 | {{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101, "Linksys WRT54G/GS/GL"}, "0x0101", "42", "0x10"}, |
184 | {{BCM47XX_BOARD_LINKSYS_WRT54G, "Linksys WRT54G/GS/GL"}, "0x0467", "42", "0x10"}, | 193 | {{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467, "Linksys WRT54G/GS/GL"}, "0x0467", "42", "0x10"}, |
185 | {{BCM47XX_BOARD_LINKSYS_WRT54G, "Linksys WRT54G/GS/GL"}, "0x0708", "42", "0x10"}, | 194 | {{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708, "Linksys WRT54G/GS/GL"}, "0x0708", "42", "0x10"}, |
186 | { {0}, NULL}, | 195 | { {0}, NULL}, |
187 | }; | 196 | }; |
188 | 197 | ||
@@ -237,6 +246,15 @@ static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void) | |||
237 | } | 246 | } |
238 | } | 247 | } |
239 | 248 | ||
249 | if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0 && | ||
250 | bcm47xx_nvram_getenv("boardtype", buf2, sizeof(buf2)) >= 0) { | ||
251 | for (e2 = bcm47xx_board_list_boot_hw; e2->value1; e2++) { | ||
252 | if (!strstarts(buf1, e2->value1) && | ||
253 | !strcmp(buf2, e2->value2)) | ||
254 | return &e2->board; | ||
255 | } | ||
256 | } | ||
257 | |||
240 | if (bcm47xx_nvram_getenv("productid", buf1, sizeof(buf1)) >= 0) { | 258 | if (bcm47xx_nvram_getenv("productid", buf1, sizeof(buf1)) >= 0) { |
241 | for (e1 = bcm47xx_board_list_productid; e1->value1; e1++) { | 259 | for (e1 = bcm47xx_board_list_productid; e1->value1; e1++) { |
242 | if (!strcmp(buf1, e1->value1)) | 260 | if (!strcmp(buf1, e1->value1)) |
diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c index 49a1ce06844b..913182bcafb8 100644 --- a/arch/mips/bcm47xx/buttons.c +++ b/arch/mips/bcm47xx/buttons.c | |||
@@ -56,6 +56,11 @@ bcm47xx_buttons_asus_wl330ge[] __initconst = { | |||
56 | }; | 56 | }; |
57 | 57 | ||
58 | static const struct gpio_keys_button | 58 | static const struct gpio_keys_button |
59 | bcm47xx_buttons_asus_wl500g[] __initconst = { | ||
60 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
61 | }; | ||
62 | |||
63 | static const struct gpio_keys_button | ||
59 | bcm47xx_buttons_asus_wl500gd[] __initconst = { | 64 | bcm47xx_buttons_asus_wl500gd[] __initconst = { |
60 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | 65 | BCM47XX_GPIO_KEY(6, KEY_RESTART), |
61 | }; | 66 | }; |
@@ -265,7 +270,7 @@ bcm47xx_buttons_linksys_wrt54g3gv2[] __initconst = { | |||
265 | }; | 270 | }; |
266 | 271 | ||
267 | static const struct gpio_keys_button | 272 | static const struct gpio_keys_button |
268 | bcm47xx_buttons_linksys_wrt54gsv1[] __initconst = { | 273 | bcm47xx_buttons_linksys_wrt54g_generic[] __initconst = { |
269 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | 274 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), |
270 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | 275 | BCM47XX_GPIO_KEY(6, KEY_RESTART), |
271 | }; | 276 | }; |
@@ -288,6 +293,13 @@ bcm47xx_buttons_linksys_wrtsl54gs[] __initconst = { | |||
288 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | 293 | BCM47XX_GPIO_KEY(6, KEY_RESTART), |
289 | }; | 294 | }; |
290 | 295 | ||
296 | /* Microsoft */ | ||
297 | |||
298 | static const struct gpio_keys_button | ||
299 | bcm47xx_buttons_microsoft_nm700[] __initconst = { | ||
300 | BCM47XX_GPIO_KEY(7, KEY_RESTART), | ||
301 | }; | ||
302 | |||
291 | /* Motorola */ | 303 | /* Motorola */ |
292 | 304 | ||
293 | static const struct gpio_keys_button | 305 | static const struct gpio_keys_button |
@@ -329,6 +341,12 @@ bcm47xx_buttons_netgear_wndr4500v1[] __initconst = { | |||
329 | }; | 341 | }; |
330 | 342 | ||
331 | static const struct gpio_keys_button | 343 | static const struct gpio_keys_button |
344 | bcm47xx_buttons_netgear_wnr3500lv1[] __initconst = { | ||
345 | BCM47XX_GPIO_KEY(4, KEY_RESTART), | ||
346 | BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON), | ||
347 | }; | ||
348 | |||
349 | static const struct gpio_keys_button | ||
332 | bcm47xx_buttons_netgear_wnr834bv2[] __initconst = { | 350 | bcm47xx_buttons_netgear_wnr834bv2[] __initconst = { |
333 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | 351 | BCM47XX_GPIO_KEY(6, KEY_RESTART), |
334 | }; | 352 | }; |
@@ -395,6 +413,9 @@ int __init bcm47xx_buttons_register(void) | |||
395 | case BCM47XX_BOARD_ASUS_WL330GE: | 413 | case BCM47XX_BOARD_ASUS_WL330GE: |
396 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl330ge); | 414 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl330ge); |
397 | break; | 415 | break; |
416 | case BCM47XX_BOARD_ASUS_WL500G: | ||
417 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500g); | ||
418 | break; | ||
398 | case BCM47XX_BOARD_ASUS_WL500GD: | 419 | case BCM47XX_BOARD_ASUS_WL500GD: |
399 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gd); | 420 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gd); |
400 | break; | 421 | break; |
@@ -501,12 +522,14 @@ int __init bcm47xx_buttons_register(void) | |||
501 | case BCM47XX_BOARD_LINKSYS_WRT310NV1: | 522 | case BCM47XX_BOARD_LINKSYS_WRT310NV1: |
502 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt310nv1); | 523 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt310nv1); |
503 | break; | 524 | break; |
504 | case BCM47XX_BOARD_LINKSYS_WRT54G: | ||
505 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54gsv1); | ||
506 | break; | ||
507 | case BCM47XX_BOARD_LINKSYS_WRT54G3GV2: | 525 | case BCM47XX_BOARD_LINKSYS_WRT54G3GV2: |
508 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g3gv2); | 526 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g3gv2); |
509 | break; | 527 | break; |
528 | case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101: | ||
529 | case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467: | ||
530 | case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708: | ||
531 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g_generic); | ||
532 | break; | ||
510 | case BCM47XX_BOARD_LINKSYS_WRT610NV1: | 533 | case BCM47XX_BOARD_LINKSYS_WRT610NV1: |
511 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv1); | 534 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv1); |
512 | break; | 535 | break; |
@@ -517,6 +540,10 @@ int __init bcm47xx_buttons_register(void) | |||
517 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrtsl54gs); | 540 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrtsl54gs); |
518 | break; | 541 | break; |
519 | 542 | ||
543 | case BCM47XX_BOARD_MICROSOFT_MN700: | ||
544 | err = bcm47xx_copy_bdata(bcm47xx_buttons_microsoft_nm700); | ||
545 | break; | ||
546 | |||
520 | case BCM47XX_BOARD_MOTOROLA_WE800G: | 547 | case BCM47XX_BOARD_MOTOROLA_WE800G: |
521 | err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_we800g); | 548 | err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_we800g); |
522 | break; | 549 | break; |
@@ -536,6 +563,9 @@ int __init bcm47xx_buttons_register(void) | |||
536 | case BCM47XX_BOARD_NETGEAR_WNDR4500V1: | 563 | case BCM47XX_BOARD_NETGEAR_WNDR4500V1: |
537 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500v1); | 564 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500v1); |
538 | break; | 565 | break; |
566 | case BCM47XX_BOARD_NETGEAR_WNR3500L: | ||
567 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr3500lv1); | ||
568 | break; | ||
539 | case BCM47XX_BOARD_NETGEAR_WNR834BV2: | 569 | case BCM47XX_BOARD_NETGEAR_WNR834BV2: |
540 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr834bv2); | 570 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr834bv2); |
541 | break; | 571 | break; |
diff --git a/arch/mips/bcm47xx/leds.c b/arch/mips/bcm47xx/leds.c index adcb547a91c3..903a656d4119 100644 --- a/arch/mips/bcm47xx/leds.c +++ b/arch/mips/bcm47xx/leds.c | |||
@@ -35,6 +35,15 @@ bcm47xx_leds_asus_rtn12[] __initconst = { | |||
35 | }; | 35 | }; |
36 | 36 | ||
37 | static const struct gpio_led | 37 | static const struct gpio_led |
38 | bcm47xx_leds_asus_rtn15u[] __initconst = { | ||
39 | /* TODO: Add "wlan" LED */ | ||
40 | BCM47XX_GPIO_LED(3, "blue", "wan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
41 | BCM47XX_GPIO_LED(4, "blue", "lan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
42 | BCM47XX_GPIO_LED(6, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
43 | BCM47XX_GPIO_LED(9, "blue", "usb", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
44 | }; | ||
45 | |||
46 | static const struct gpio_led | ||
38 | bcm47xx_leds_asus_rtn16[] __initconst = { | 47 | bcm47xx_leds_asus_rtn16[] __initconst = { |
39 | BCM47XX_GPIO_LED(1, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON), | 48 | BCM47XX_GPIO_LED(1, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON), |
40 | BCM47XX_GPIO_LED(7, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | 49 | BCM47XX_GPIO_LED(7, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), |
@@ -42,8 +51,8 @@ bcm47xx_leds_asus_rtn16[] __initconst = { | |||
42 | 51 | ||
43 | static const struct gpio_led | 52 | static const struct gpio_led |
44 | bcm47xx_leds_asus_rtn66u[] __initconst = { | 53 | bcm47xx_leds_asus_rtn66u[] __initconst = { |
45 | BCM47XX_GPIO_LED(12, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | 54 | BCM47XX_GPIO_LED(12, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON), |
46 | BCM47XX_GPIO_LED(15, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF), | 55 | BCM47XX_GPIO_LED(15, "blue", "usb", 1, LEDS_GPIO_DEFSTATE_OFF), |
47 | }; | 56 | }; |
48 | 57 | ||
49 | static const struct gpio_led | 58 | static const struct gpio_led |
@@ -64,6 +73,11 @@ bcm47xx_leds_asus_wl330ge[] __initconst = { | |||
64 | }; | 73 | }; |
65 | 74 | ||
66 | static const struct gpio_led | 75 | static const struct gpio_led |
76 | bcm47xx_leds_asus_wl500g[] __initconst = { | ||
77 | BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
78 | }; | ||
79 | |||
80 | static const struct gpio_led | ||
67 | bcm47xx_leds_asus_wl500gd[] __initconst = { | 81 | bcm47xx_leds_asus_wl500gd[] __initconst = { |
68 | BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | 82 | BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), |
69 | }; | 83 | }; |
@@ -216,8 +230,8 @@ bcm47xx_leds_linksys_e1000v1[] __initconst = { | |||
216 | 230 | ||
217 | static const struct gpio_led | 231 | static const struct gpio_led |
218 | bcm47xx_leds_linksys_e1000v21[] __initconst = { | 232 | bcm47xx_leds_linksys_e1000v21[] __initconst = { |
219 | BCM47XX_GPIO_LED(5, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | 233 | BCM47XX_GPIO_LED(5, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), |
220 | BCM47XX_GPIO_LED(6, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | 234 | BCM47XX_GPIO_LED(6, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON), |
221 | BCM47XX_GPIO_LED(7, "amber", "wps", 0, LEDS_GPIO_DEFSTATE_OFF), | 235 | BCM47XX_GPIO_LED(7, "amber", "wps", 0, LEDS_GPIO_DEFSTATE_OFF), |
222 | BCM47XX_GPIO_LED(8, "blue", "wps", 0, LEDS_GPIO_DEFSTATE_OFF), | 236 | BCM47XX_GPIO_LED(8, "blue", "wps", 0, LEDS_GPIO_DEFSTATE_OFF), |
223 | }; | 237 | }; |
@@ -292,7 +306,7 @@ bcm47xx_leds_linksys_wrt310nv1[] __initconst = { | |||
292 | }; | 306 | }; |
293 | 307 | ||
294 | static const struct gpio_led | 308 | static const struct gpio_led |
295 | bcm47xx_leds_linksys_wrt54gsv1[] __initconst = { | 309 | bcm47xx_leds_linksys_wrt54g_generic[] __initconst = { |
296 | BCM47XX_GPIO_LED(0, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | 310 | BCM47XX_GPIO_LED(0, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), |
297 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | 311 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), |
298 | BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | 312 | BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), |
@@ -306,6 +320,24 @@ bcm47xx_leds_linksys_wrt54g3gv2[] __initconst = { | |||
306 | BCM47XX_GPIO_LED(3, "blue", "3g", 0, LEDS_GPIO_DEFSTATE_OFF), | 320 | BCM47XX_GPIO_LED(3, "blue", "3g", 0, LEDS_GPIO_DEFSTATE_OFF), |
307 | }; | 321 | }; |
308 | 322 | ||
323 | /* Verified on: WRT54GS V1.0 */ | ||
324 | static const struct gpio_led | ||
325 | bcm47xx_leds_linksys_wrt54g_type_0101[] __initconst = { | ||
326 | BCM47XX_GPIO_LED(0, "green", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
327 | BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
328 | BCM47XX_GPIO_LED(7, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
329 | }; | ||
330 | |||
331 | /* Verified on: WRT54GL V1.1 */ | ||
332 | static const struct gpio_led | ||
333 | bcm47xx_leds_linksys_wrt54g_type_0467[] __initconst = { | ||
334 | BCM47XX_GPIO_LED(0, "green", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
335 | BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
336 | BCM47XX_GPIO_LED(2, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
337 | BCM47XX_GPIO_LED(3, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
338 | BCM47XX_GPIO_LED(7, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
339 | }; | ||
340 | |||
309 | static const struct gpio_led | 341 | static const struct gpio_led |
310 | bcm47xx_leds_linksys_wrt610nv1[] __initconst = { | 342 | bcm47xx_leds_linksys_wrt610nv1[] __initconst = { |
311 | BCM47XX_GPIO_LED(0, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF), | 343 | BCM47XX_GPIO_LED(0, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF), |
@@ -325,11 +357,17 @@ bcm47xx_leds_linksys_wrt610nv2[] __initconst = { | |||
325 | 357 | ||
326 | static const struct gpio_led | 358 | static const struct gpio_led |
327 | bcm47xx_leds_linksys_wrtsl54gs[] __initconst = { | 359 | bcm47xx_leds_linksys_wrtsl54gs[] __initconst = { |
328 | BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | 360 | BCM47XX_GPIO_LED(0, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), |
329 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | 361 | BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), |
330 | BCM47XX_GPIO_LED(2, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | 362 | BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), |
331 | BCM47XX_GPIO_LED(3, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | 363 | BCM47XX_GPIO_LED(7, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), |
332 | BCM47XX_GPIO_LED(7, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | 364 | }; |
365 | |||
366 | /* Microsoft */ | ||
367 | |||
368 | static const struct gpio_led | ||
369 | bcm47xx_leds_microsoft_nm700[] __initconst = { | ||
370 | BCM47XX_GPIO_LED(6, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
333 | }; | 371 | }; |
334 | 372 | ||
335 | /* Motorola */ | 373 | /* Motorola */ |
@@ -377,6 +415,15 @@ bcm47xx_leds_netgear_wndr4500v1[] __initconst = { | |||
377 | }; | 415 | }; |
378 | 416 | ||
379 | static const struct gpio_led | 417 | static const struct gpio_led |
418 | bcm47xx_leds_netgear_wnr3500lv1[] __initconst = { | ||
419 | BCM47XX_GPIO_LED(0, "blue", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
420 | BCM47XX_GPIO_LED(1, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
421 | BCM47XX_GPIO_LED(2, "green", "wan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
422 | BCM47XX_GPIO_LED(3, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
423 | BCM47XX_GPIO_LED(7, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
424 | }; | ||
425 | |||
426 | static const struct gpio_led | ||
380 | bcm47xx_leds_netgear_wnr834bv2[] __initconst = { | 427 | bcm47xx_leds_netgear_wnr834bv2[] __initconst = { |
381 | BCM47XX_GPIO_LED(2, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | 428 | BCM47XX_GPIO_LED(2, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), |
382 | BCM47XX_GPIO_LED(3, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF), | 429 | BCM47XX_GPIO_LED(3, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF), |
@@ -417,6 +464,9 @@ void __init bcm47xx_leds_register(void) | |||
417 | case BCM47XX_BOARD_ASUS_RTN12: | 464 | case BCM47XX_BOARD_ASUS_RTN12: |
418 | bcm47xx_set_pdata(bcm47xx_leds_asus_rtn12); | 465 | bcm47xx_set_pdata(bcm47xx_leds_asus_rtn12); |
419 | break; | 466 | break; |
467 | case BCM47XX_BOARD_ASUS_RTN15U: | ||
468 | bcm47xx_set_pdata(bcm47xx_leds_asus_rtn15u); | ||
469 | break; | ||
420 | case BCM47XX_BOARD_ASUS_RTN16: | 470 | case BCM47XX_BOARD_ASUS_RTN16: |
421 | bcm47xx_set_pdata(bcm47xx_leds_asus_rtn16); | 471 | bcm47xx_set_pdata(bcm47xx_leds_asus_rtn16); |
422 | break; | 472 | break; |
@@ -432,6 +482,9 @@ void __init bcm47xx_leds_register(void) | |||
432 | case BCM47XX_BOARD_ASUS_WL330GE: | 482 | case BCM47XX_BOARD_ASUS_WL330GE: |
433 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl330ge); | 483 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl330ge); |
434 | break; | 484 | break; |
485 | case BCM47XX_BOARD_ASUS_WL500G: | ||
486 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl500g); | ||
487 | break; | ||
435 | case BCM47XX_BOARD_ASUS_WL500GD: | 488 | case BCM47XX_BOARD_ASUS_WL500GD: |
436 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gd); | 489 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gd); |
437 | break; | 490 | break; |
@@ -538,12 +591,18 @@ void __init bcm47xx_leds_register(void) | |||
538 | case BCM47XX_BOARD_LINKSYS_WRT310NV1: | 591 | case BCM47XX_BOARD_LINKSYS_WRT310NV1: |
539 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt310nv1); | 592 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt310nv1); |
540 | break; | 593 | break; |
541 | case BCM47XX_BOARD_LINKSYS_WRT54G: | ||
542 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54gsv1); | ||
543 | break; | ||
544 | case BCM47XX_BOARD_LINKSYS_WRT54G3GV2: | 594 | case BCM47XX_BOARD_LINKSYS_WRT54G3GV2: |
545 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g3gv2); | 595 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g3gv2); |
546 | break; | 596 | break; |
597 | case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101: | ||
598 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_type_0101); | ||
599 | break; | ||
600 | case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467: | ||
601 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_type_0467); | ||
602 | break; | ||
603 | case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708: | ||
604 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_generic); | ||
605 | break; | ||
547 | case BCM47XX_BOARD_LINKSYS_WRT610NV1: | 606 | case BCM47XX_BOARD_LINKSYS_WRT610NV1: |
548 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv1); | 607 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv1); |
549 | break; | 608 | break; |
@@ -554,6 +613,10 @@ void __init bcm47xx_leds_register(void) | |||
554 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrtsl54gs); | 613 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrtsl54gs); |
555 | break; | 614 | break; |
556 | 615 | ||
616 | case BCM47XX_BOARD_MICROSOFT_MN700: | ||
617 | bcm47xx_set_pdata(bcm47xx_leds_microsoft_nm700); | ||
618 | break; | ||
619 | |||
557 | case BCM47XX_BOARD_MOTOROLA_WE800G: | 620 | case BCM47XX_BOARD_MOTOROLA_WE800G: |
558 | bcm47xx_set_pdata(bcm47xx_leds_motorola_we800g); | 621 | bcm47xx_set_pdata(bcm47xx_leds_motorola_we800g); |
559 | break; | 622 | break; |
@@ -570,6 +633,9 @@ void __init bcm47xx_leds_register(void) | |||
570 | case BCM47XX_BOARD_NETGEAR_WNDR4500V1: | 633 | case BCM47XX_BOARD_NETGEAR_WNDR4500V1: |
571 | bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr4500v1); | 634 | bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr4500v1); |
572 | break; | 635 | break; |
636 | case BCM47XX_BOARD_NETGEAR_WNR3500L: | ||
637 | bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr3500lv1); | ||
638 | break; | ||
573 | case BCM47XX_BOARD_NETGEAR_WNR834BV2: | 639 | case BCM47XX_BOARD_NETGEAR_WNR834BV2: |
574 | bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr834bv2); | 640 | bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr834bv2); |
575 | break; | 641 | break; |
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c index 1a03a2f43496..1b170bf5f7f0 100644 --- a/arch/mips/bcm47xx/prom.c +++ b/arch/mips/bcm47xx/prom.c | |||
@@ -51,6 +51,8 @@ __init void bcm47xx_set_system_type(u16 chip_id) | |||
51 | chip_id); | 51 | chip_id); |
52 | } | 52 | } |
53 | 53 | ||
54 | static unsigned long lowmem __initdata; | ||
55 | |||
54 | static __init void prom_init_mem(void) | 56 | static __init void prom_init_mem(void) |
55 | { | 57 | { |
56 | unsigned long mem; | 58 | unsigned long mem; |
@@ -87,6 +89,7 @@ static __init void prom_init_mem(void) | |||
87 | if (!memcmp(prom_init, prom_init + mem, 32)) | 89 | if (!memcmp(prom_init, prom_init + mem, 32)) |
88 | break; | 90 | break; |
89 | } | 91 | } |
92 | lowmem = mem; | ||
90 | 93 | ||
91 | /* Ignoring the last page when ddr size is 128M. Cached | 94 | /* Ignoring the last page when ddr size is 128M. Cached |
92 | * accesses to last page is causing the processor to prefetch | 95 | * accesses to last page is causing the processor to prefetch |
@@ -95,7 +98,6 @@ static __init void prom_init_mem(void) | |||
95 | */ | 98 | */ |
96 | if (c->cputype == CPU_74K && (mem == (128 << 20))) | 99 | if (c->cputype == CPU_74K && (mem == (128 << 20))) |
97 | mem -= 0x1000; | 100 | mem -= 0x1000; |
98 | |||
99 | add_memory_region(0, mem, BOOT_MEM_RAM); | 101 | add_memory_region(0, mem, BOOT_MEM_RAM); |
100 | } | 102 | } |
101 | 103 | ||
@@ -114,3 +116,67 @@ void __init prom_init(void) | |||
114 | void __init prom_free_prom_memory(void) | 116 | void __init prom_free_prom_memory(void) |
115 | { | 117 | { |
116 | } | 118 | } |
119 | |||
120 | #if defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) | ||
121 | |||
122 | #define EXTVBASE 0xc0000000 | ||
123 | #define ENTRYLO(x) ((pte_val(pfn_pte((x) >> _PFN_SHIFT, PAGE_KERNEL_UNCACHED)) >> 6) | 1) | ||
124 | |||
125 | #include <asm/tlbflush.h> | ||
126 | |||
127 | /* Stripped version of tlb_init, with the call to build_tlb_refill_handler | ||
128 | * dropped. Calling it at this stage causes a hang. | ||
129 | */ | ||
130 | void __cpuinit early_tlb_init(void) | ||
131 | { | ||
132 | write_c0_pagemask(PM_DEFAULT_MASK); | ||
133 | write_c0_wired(0); | ||
134 | temp_tlb_entry = current_cpu_data.tlbsize - 1; | ||
135 | local_flush_tlb_all(); | ||
136 | } | ||
137 | |||
138 | void __init bcm47xx_prom_highmem_init(void) | ||
139 | { | ||
140 | unsigned long off = (unsigned long)prom_init; | ||
141 | unsigned long extmem = 0; | ||
142 | bool highmem_region = false; | ||
143 | |||
144 | if (WARN_ON(bcm47xx_bus_type != BCM47XX_BUS_TYPE_BCMA)) | ||
145 | return; | ||
146 | |||
147 | if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706) | ||
148 | highmem_region = true; | ||
149 | |||
150 | if (lowmem != 128 << 20 || !highmem_region) | ||
151 | return; | ||
152 | |||
153 | early_tlb_init(); | ||
154 | |||
155 | /* Add one temporary TLB entry to map SDRAM Region 2. | ||
156 | * Physical Virtual | ||
157 | * 0x80000000 0xc0000000 (1st: 256MB) | ||
158 | * 0x90000000 0xd0000000 (2nd: 256MB) | ||
159 | */ | ||
160 | add_temporary_entry(ENTRYLO(0x80000000), | ||
161 | ENTRYLO(0x80000000 + (256 << 20)), | ||
162 | EXTVBASE, PM_256M); | ||
163 | |||
164 | off = EXTVBASE + __pa(off); | ||
165 | for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) { | ||
166 | if (!memcmp(prom_init, (void *)(off + extmem), 16)) | ||
167 | break; | ||
168 | } | ||
169 | extmem -= lowmem; | ||
170 | |||
171 | early_tlb_init(); | ||
172 | |||
173 | if (!extmem) | ||
174 | return; | ||
175 | |||
176 | pr_warn("Found %lu MiB of extra memory, but highmem is unsupported yet!\n", | ||
177 | extmem >> 20); | ||
178 | |||
179 | /* TODO: Register extra memory */ | ||
180 | } | ||
181 | |||
182 | #endif /* defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) */ | ||
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c index 63a4b0e915dc..2b63e7e7d3d3 100644 --- a/arch/mips/bcm47xx/setup.c +++ b/arch/mips/bcm47xx/setup.c | |||
@@ -59,12 +59,12 @@ static void bcm47xx_machine_restart(char *command) | |||
59 | switch (bcm47xx_bus_type) { | 59 | switch (bcm47xx_bus_type) { |
60 | #ifdef CONFIG_BCM47XX_SSB | 60 | #ifdef CONFIG_BCM47XX_SSB |
61 | case BCM47XX_BUS_TYPE_SSB: | 61 | case BCM47XX_BUS_TYPE_SSB: |
62 | ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1); | 62 | ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 3); |
63 | break; | 63 | break; |
64 | #endif | 64 | #endif |
65 | #ifdef CONFIG_BCM47XX_BCMA | 65 | #ifdef CONFIG_BCM47XX_BCMA |
66 | case BCM47XX_BUS_TYPE_BCMA: | 66 | case BCM47XX_BUS_TYPE_BCMA: |
67 | bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1); | 67 | bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 3); |
68 | break; | 68 | break; |
69 | #endif | 69 | #endif |
70 | } | 70 | } |
@@ -218,6 +218,9 @@ void __init plat_mem_setup(void) | |||
218 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; | 218 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; |
219 | bcm47xx_register_bcma(); | 219 | bcm47xx_register_bcma(); |
220 | bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); | 220 | bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); |
221 | #ifdef CONFIG_HIGHMEM | ||
222 | bcm47xx_prom_highmem_init(); | ||
223 | #endif | ||
221 | #endif | 224 | #endif |
222 | } else { | 225 | } else { |
223 | printk(KERN_INFO "bcm47xx: using ssb bus\n"); | 226 | printk(KERN_INFO "bcm47xx: using ssb bus\n"); |
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c index da4cdb16844e..41226b68de3d 100644 --- a/arch/mips/bcm47xx/sprom.c +++ b/arch/mips/bcm47xx/sprom.c | |||
@@ -28,6 +28,8 @@ | |||
28 | 28 | ||
29 | #include <bcm47xx.h> | 29 | #include <bcm47xx.h> |
30 | #include <bcm47xx_nvram.h> | 30 | #include <bcm47xx_nvram.h> |
31 | #include <linux/if_ether.h> | ||
32 | #include <linux/etherdevice.h> | ||
31 | 33 | ||
32 | static void create_key(const char *prefix, const char *postfix, | 34 | static void create_key(const char *prefix, const char *postfix, |
33 | const char *name, char *buf, int len) | 35 | const char *name, char *buf, int len) |
@@ -631,6 +633,33 @@ static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom, | |||
631 | } | 633 | } |
632 | } | 634 | } |
633 | 635 | ||
636 | static bool bcm47xx_is_valid_mac(u8 *mac) | ||
637 | { | ||
638 | return mac && !(mac[0] == 0x00 && mac[1] == 0x90 && mac[2] == 0x4c); | ||
639 | } | ||
640 | |||
641 | static int bcm47xx_increase_mac_addr(u8 *mac, u8 num) | ||
642 | { | ||
643 | u8 *oui = mac + ETH_ALEN/2 - 1; | ||
644 | u8 *p = mac + ETH_ALEN - 1; | ||
645 | |||
646 | do { | ||
647 | (*p) += num; | ||
648 | if (*p > num) | ||
649 | break; | ||
650 | p--; | ||
651 | num = 1; | ||
652 | } while (p != oui); | ||
653 | |||
654 | if (p == oui) { | ||
655 | pr_err("unable to fetch mac address\n"); | ||
656 | return -ENOENT; | ||
657 | } | ||
658 | return 0; | ||
659 | } | ||
660 | |||
661 | static int mac_addr_used = 2; | ||
662 | |||
634 | static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, | 663 | static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, |
635 | const char *prefix, bool fallback) | 664 | const char *prefix, bool fallback) |
636 | { | 665 | { |
@@ -648,6 +677,25 @@ static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, | |||
648 | 677 | ||
649 | nvram_read_macaddr(prefix, "macaddr", sprom->il0mac, fallback); | 678 | nvram_read_macaddr(prefix, "macaddr", sprom->il0mac, fallback); |
650 | nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback); | 679 | nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback); |
680 | |||
681 | /* The address prefix 00:90:4C is used by Broadcom in their initial | ||
682 | configuration. When a mac address with the prefix 00:90:4C is used | ||
683 | all devices from the same series are sharing the same mac address. | ||
684 | To prevent mac address collisions we replace them with a mac address | ||
685 | based on the base address. */ | ||
686 | if (!bcm47xx_is_valid_mac(sprom->il0mac)) { | ||
687 | u8 mac[6]; | ||
688 | |||
689 | nvram_read_macaddr(NULL, "et0macaddr", mac, false); | ||
690 | if (bcm47xx_is_valid_mac(mac)) { | ||
691 | int err = bcm47xx_increase_mac_addr(mac, mac_addr_used); | ||
692 | |||
693 | if (!err) { | ||
694 | ether_addr_copy(sprom->il0mac, mac); | ||
695 | mac_addr_used++; | ||
696 | } | ||
697 | } | ||
698 | } | ||
651 | } | 699 | } |
652 | 700 | ||
653 | static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix, | 701 | static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix, |
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c index fd4e76c00a42..536f64443031 100644 --- a/arch/mips/bcm63xx/cpu.c +++ b/arch/mips/bcm63xx/cpu.c | |||
@@ -24,7 +24,9 @@ EXPORT_SYMBOL(bcm63xx_regs_base); | |||
24 | const int *bcm63xx_irqs; | 24 | const int *bcm63xx_irqs; |
25 | EXPORT_SYMBOL(bcm63xx_irqs); | 25 | EXPORT_SYMBOL(bcm63xx_irqs); |
26 | 26 | ||
27 | static u16 bcm63xx_cpu_id; | 27 | u16 bcm63xx_cpu_id __read_mostly; |
28 | EXPORT_SYMBOL(bcm63xx_cpu_id); | ||
29 | |||
28 | static u8 bcm63xx_cpu_rev; | 30 | static u8 bcm63xx_cpu_rev; |
29 | static unsigned int bcm63xx_cpu_freq; | 31 | static unsigned int bcm63xx_cpu_freq; |
30 | static unsigned int bcm63xx_memory_size; | 32 | static unsigned int bcm63xx_memory_size; |
@@ -97,13 +99,6 @@ static const int bcm6368_irqs[] = { | |||
97 | 99 | ||
98 | }; | 100 | }; |
99 | 101 | ||
100 | u16 __bcm63xx_get_cpu_id(void) | ||
101 | { | ||
102 | return bcm63xx_cpu_id; | ||
103 | } | ||
104 | |||
105 | EXPORT_SYMBOL(__bcm63xx_get_cpu_id); | ||
106 | |||
107 | u8 bcm63xx_get_cpu_rev(void) | 102 | u8 bcm63xx_get_cpu_rev(void) |
108 | { | 103 | { |
109 | return bcm63xx_cpu_rev; | 104 | return bcm63xx_cpu_rev; |
diff --git a/arch/mips/bcm63xx/dev-enet.c b/arch/mips/bcm63xx/dev-enet.c index 52bc01df9bfe..e8284771d620 100644 --- a/arch/mips/bcm63xx/dev-enet.c +++ b/arch/mips/bcm63xx/dev-enet.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <bcm63xx_io.h> | 14 | #include <bcm63xx_io.h> |
15 | #include <bcm63xx_regs.h> | 15 | #include <bcm63xx_regs.h> |
16 | 16 | ||
17 | #ifdef BCMCPU_RUNTIME_DETECT | ||
18 | static const unsigned long bcm6348_regs_enetdmac[] = { | 17 | static const unsigned long bcm6348_regs_enetdmac[] = { |
19 | [ENETDMAC_CHANCFG] = ENETDMAC_CHANCFG_REG, | 18 | [ENETDMAC_CHANCFG] = ENETDMAC_CHANCFG_REG, |
20 | [ENETDMAC_IR] = ENETDMAC_IR_REG, | 19 | [ENETDMAC_IR] = ENETDMAC_IR_REG, |
@@ -43,9 +42,6 @@ static __init void bcm63xx_enetdmac_regs_init(void) | |||
43 | else | 42 | else |
44 | bcm63xx_regs_enetdmac = bcm6348_regs_enetdmac; | 43 | bcm63xx_regs_enetdmac = bcm6348_regs_enetdmac; |
45 | } | 44 | } |
46 | #else | ||
47 | static __init void bcm63xx_enetdmac_regs_init(void) { } | ||
48 | #endif | ||
49 | 45 | ||
50 | static struct resource shared_res[] = { | 46 | static struct resource shared_res[] = { |
51 | { | 47 | { |
diff --git a/arch/mips/bcm63xx/dev-spi.c b/arch/mips/bcm63xx/dev-spi.c index d12daed749bc..ad448e41e3bd 100644 --- a/arch/mips/bcm63xx/dev-spi.c +++ b/arch/mips/bcm63xx/dev-spi.c | |||
@@ -18,7 +18,6 @@ | |||
18 | #include <bcm63xx_dev_spi.h> | 18 | #include <bcm63xx_dev_spi.h> |
19 | #include <bcm63xx_regs.h> | 19 | #include <bcm63xx_regs.h> |
20 | 20 | ||
21 | #ifdef BCMCPU_RUNTIME_DETECT | ||
22 | /* | 21 | /* |
23 | * register offsets | 22 | * register offsets |
24 | */ | 23 | */ |
@@ -41,9 +40,6 @@ static __init void bcm63xx_spi_regs_init(void) | |||
41 | BCMCPU_IS_6362() || BCMCPU_IS_6368()) | 40 | BCMCPU_IS_6362() || BCMCPU_IS_6368()) |
42 | bcm63xx_regs_spi = bcm6358_regs_spi; | 41 | bcm63xx_regs_spi = bcm6358_regs_spi; |
43 | } | 42 | } |
44 | #else | ||
45 | static __init void bcm63xx_spi_regs_init(void) { } | ||
46 | #endif | ||
47 | 43 | ||
48 | static struct resource spi_resources[] = { | 44 | static struct resource spi_resources[] = { |
49 | { | 45 | { |
diff --git a/arch/mips/bcm63xx/gpio.c b/arch/mips/bcm63xx/gpio.c index a6c2135dbf38..468bc7b99cd3 100644 --- a/arch/mips/bcm63xx/gpio.c +++ b/arch/mips/bcm63xx/gpio.c | |||
@@ -18,19 +18,6 @@ | |||
18 | #include <bcm63xx_io.h> | 18 | #include <bcm63xx_io.h> |
19 | #include <bcm63xx_regs.h> | 19 | #include <bcm63xx_regs.h> |
20 | 20 | ||
21 | #ifndef BCMCPU_RUNTIME_DETECT | ||
22 | #define gpio_out_low_reg GPIO_DATA_LO_REG | ||
23 | #ifdef CONFIG_BCM63XX_CPU_6345 | ||
24 | #ifdef gpio_out_low_reg | ||
25 | #undef gpio_out_low_reg | ||
26 | #define gpio_out_low_reg GPIO_DATA_LO_REG_6345 | ||
27 | #endif /* gpio_out_low_reg */ | ||
28 | #endif /* CONFIG_BCM63XX_CPU_6345 */ | ||
29 | |||
30 | static inline void bcm63xx_gpio_out_low_reg_init(void) | ||
31 | { | ||
32 | } | ||
33 | #else /* ! BCMCPU_RUNTIME_DETECT */ | ||
34 | static u32 gpio_out_low_reg; | 21 | static u32 gpio_out_low_reg; |
35 | 22 | ||
36 | static void bcm63xx_gpio_out_low_reg_init(void) | 23 | static void bcm63xx_gpio_out_low_reg_init(void) |
@@ -44,7 +31,6 @@ static void bcm63xx_gpio_out_low_reg_init(void) | |||
44 | break; | 31 | break; |
45 | } | 32 | } |
46 | } | 33 | } |
47 | #endif /* ! BCMCPU_RUNTIME_DETECT */ | ||
48 | 34 | ||
49 | static DEFINE_SPINLOCK(bcm63xx_gpio_lock); | 35 | static DEFINE_SPINLOCK(bcm63xx_gpio_lock); |
50 | static u32 gpio_out_low, gpio_out_high; | 36 | static u32 gpio_out_low, gpio_out_high; |
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c index 1525f8a3841b..37eb2d1fa69a 100644 --- a/arch/mips/bcm63xx/irq.c +++ b/arch/mips/bcm63xx/irq.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/interrupt.h> | 12 | #include <linux/interrupt.h> |
13 | #include <linux/module.h> | 13 | #include <linux/module.h> |
14 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
15 | #include <linux/spinlock.h> | ||
15 | #include <asm/irq_cpu.h> | 16 | #include <asm/irq_cpu.h> |
16 | #include <asm/mipsregs.h> | 17 | #include <asm/mipsregs.h> |
17 | #include <bcm63xx_cpu.h> | 18 | #include <bcm63xx_cpu.h> |
@@ -19,222 +20,20 @@ | |||
19 | #include <bcm63xx_io.h> | 20 | #include <bcm63xx_io.h> |
20 | #include <bcm63xx_irq.h> | 21 | #include <bcm63xx_irq.h> |
21 | 22 | ||
22 | static void __dispatch_internal(void) __maybe_unused; | ||
23 | static void __dispatch_internal_64(void) __maybe_unused; | ||
24 | static void __internal_irq_mask_32(unsigned int irq) __maybe_unused; | ||
25 | static void __internal_irq_mask_64(unsigned int irq) __maybe_unused; | ||
26 | static void __internal_irq_unmask_32(unsigned int irq) __maybe_unused; | ||
27 | static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused; | ||
28 | |||
29 | #ifndef BCMCPU_RUNTIME_DETECT | ||
30 | #ifdef CONFIG_BCM63XX_CPU_3368 | ||
31 | #define irq_stat_reg PERF_IRQSTAT_3368_REG | ||
32 | #define irq_mask_reg PERF_IRQMASK_3368_REG | ||
33 | #define irq_bits 32 | ||
34 | #define is_ext_irq_cascaded 0 | ||
35 | #define ext_irq_start 0 | ||
36 | #define ext_irq_end 0 | ||
37 | #define ext_irq_count 4 | ||
38 | #define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_3368 | ||
39 | #define ext_irq_cfg_reg2 0 | ||
40 | #endif | ||
41 | #ifdef CONFIG_BCM63XX_CPU_6328 | ||
42 | #define irq_stat_reg PERF_IRQSTAT_6328_REG | ||
43 | #define irq_mask_reg PERF_IRQMASK_6328_REG | ||
44 | #define irq_bits 64 | ||
45 | #define is_ext_irq_cascaded 1 | ||
46 | #define ext_irq_start (BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE) | ||
47 | #define ext_irq_end (BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE) | ||
48 | #define ext_irq_count 4 | ||
49 | #define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6328 | ||
50 | #define ext_irq_cfg_reg2 0 | ||
51 | #endif | ||
52 | #ifdef CONFIG_BCM63XX_CPU_6338 | ||
53 | #define irq_stat_reg PERF_IRQSTAT_6338_REG | ||
54 | #define irq_mask_reg PERF_IRQMASK_6338_REG | ||
55 | #define irq_bits 32 | ||
56 | #define is_ext_irq_cascaded 0 | ||
57 | #define ext_irq_start 0 | ||
58 | #define ext_irq_end 0 | ||
59 | #define ext_irq_count 4 | ||
60 | #define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6338 | ||
61 | #define ext_irq_cfg_reg2 0 | ||
62 | #endif | ||
63 | #ifdef CONFIG_BCM63XX_CPU_6345 | ||
64 | #define irq_stat_reg PERF_IRQSTAT_6345_REG | ||
65 | #define irq_mask_reg PERF_IRQMASK_6345_REG | ||
66 | #define irq_bits 32 | ||
67 | #define is_ext_irq_cascaded 0 | ||
68 | #define ext_irq_start 0 | ||
69 | #define ext_irq_end 0 | ||
70 | #define ext_irq_count 4 | ||
71 | #define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6345 | ||
72 | #define ext_irq_cfg_reg2 0 | ||
73 | #endif | ||
74 | #ifdef CONFIG_BCM63XX_CPU_6348 | ||
75 | #define irq_stat_reg PERF_IRQSTAT_6348_REG | ||
76 | #define irq_mask_reg PERF_IRQMASK_6348_REG | ||
77 | #define irq_bits 32 | ||
78 | #define is_ext_irq_cascaded 0 | ||
79 | #define ext_irq_start 0 | ||
80 | #define ext_irq_end 0 | ||
81 | #define ext_irq_count 4 | ||
82 | #define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6348 | ||
83 | #define ext_irq_cfg_reg2 0 | ||
84 | #endif | ||
85 | #ifdef CONFIG_BCM63XX_CPU_6358 | ||
86 | #define irq_stat_reg PERF_IRQSTAT_6358_REG | ||
87 | #define irq_mask_reg PERF_IRQMASK_6358_REG | ||
88 | #define irq_bits 32 | ||
89 | #define is_ext_irq_cascaded 1 | ||
90 | #define ext_irq_start (BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE) | ||
91 | #define ext_irq_end (BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE) | ||
92 | #define ext_irq_count 4 | ||
93 | #define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6358 | ||
94 | #define ext_irq_cfg_reg2 0 | ||
95 | #endif | ||
96 | #ifdef CONFIG_BCM63XX_CPU_6362 | ||
97 | #define irq_stat_reg PERF_IRQSTAT_6362_REG | ||
98 | #define irq_mask_reg PERF_IRQMASK_6362_REG | ||
99 | #define irq_bits 64 | ||
100 | #define is_ext_irq_cascaded 1 | ||
101 | #define ext_irq_start (BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE) | ||
102 | #define ext_irq_end (BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE) | ||
103 | #define ext_irq_count 4 | ||
104 | #define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6362 | ||
105 | #define ext_irq_cfg_reg2 0 | ||
106 | #endif | ||
107 | #ifdef CONFIG_BCM63XX_CPU_6368 | ||
108 | #define irq_stat_reg PERF_IRQSTAT_6368_REG | ||
109 | #define irq_mask_reg PERF_IRQMASK_6368_REG | ||
110 | #define irq_bits 64 | ||
111 | #define is_ext_irq_cascaded 1 | ||
112 | #define ext_irq_start (BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE) | ||
113 | #define ext_irq_end (BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE) | ||
114 | #define ext_irq_count 6 | ||
115 | #define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6368 | ||
116 | #define ext_irq_cfg_reg2 PERF_EXTIRQ_CFG_REG2_6368 | ||
117 | #endif | ||
118 | |||
119 | #if irq_bits == 32 | ||
120 | #define dispatch_internal __dispatch_internal | ||
121 | #define internal_irq_mask __internal_irq_mask_32 | ||
122 | #define internal_irq_unmask __internal_irq_unmask_32 | ||
123 | #else | ||
124 | #define dispatch_internal __dispatch_internal_64 | ||
125 | #define internal_irq_mask __internal_irq_mask_64 | ||
126 | #define internal_irq_unmask __internal_irq_unmask_64 | ||
127 | #endif | ||
128 | 23 | ||
129 | #define irq_stat_addr (bcm63xx_regset_address(RSET_PERF) + irq_stat_reg) | 24 | static DEFINE_SPINLOCK(ipic_lock); |
130 | #define irq_mask_addr (bcm63xx_regset_address(RSET_PERF) + irq_mask_reg) | 25 | static DEFINE_SPINLOCK(epic_lock); |
131 | 26 | ||
132 | static inline void bcm63xx_init_irq(void) | 27 | static u32 irq_stat_addr[2]; |
133 | { | 28 | static u32 irq_mask_addr[2]; |
134 | } | 29 | static void (*dispatch_internal)(int cpu); |
135 | #else /* ! BCMCPU_RUNTIME_DETECT */ | ||
136 | |||
137 | static u32 irq_stat_addr, irq_mask_addr; | ||
138 | static void (*dispatch_internal)(void); | ||
139 | static int is_ext_irq_cascaded; | 30 | static int is_ext_irq_cascaded; |
140 | static unsigned int ext_irq_count; | 31 | static unsigned int ext_irq_count; |
141 | static unsigned int ext_irq_start, ext_irq_end; | 32 | static unsigned int ext_irq_start, ext_irq_end; |
142 | static unsigned int ext_irq_cfg_reg1, ext_irq_cfg_reg2; | 33 | static unsigned int ext_irq_cfg_reg1, ext_irq_cfg_reg2; |
143 | static void (*internal_irq_mask)(unsigned int irq); | 34 | static void (*internal_irq_mask)(struct irq_data *d); |
144 | static void (*internal_irq_unmask)(unsigned int irq); | 35 | static void (*internal_irq_unmask)(struct irq_data *d, const struct cpumask *m); |
145 | 36 | ||
146 | static void bcm63xx_init_irq(void) | ||
147 | { | ||
148 | int irq_bits; | ||
149 | |||
150 | irq_stat_addr = bcm63xx_regset_address(RSET_PERF); | ||
151 | irq_mask_addr = bcm63xx_regset_address(RSET_PERF); | ||
152 | |||
153 | switch (bcm63xx_get_cpu_id()) { | ||
154 | case BCM3368_CPU_ID: | ||
155 | irq_stat_addr += PERF_IRQSTAT_3368_REG; | ||
156 | irq_mask_addr += PERF_IRQMASK_3368_REG; | ||
157 | irq_bits = 32; | ||
158 | ext_irq_count = 4; | ||
159 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368; | ||
160 | break; | ||
161 | case BCM6328_CPU_ID: | ||
162 | irq_stat_addr += PERF_IRQSTAT_6328_REG; | ||
163 | irq_mask_addr += PERF_IRQMASK_6328_REG; | ||
164 | irq_bits = 64; | ||
165 | ext_irq_count = 4; | ||
166 | is_ext_irq_cascaded = 1; | ||
167 | ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE; | ||
168 | ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE; | ||
169 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328; | ||
170 | break; | ||
171 | case BCM6338_CPU_ID: | ||
172 | irq_stat_addr += PERF_IRQSTAT_6338_REG; | ||
173 | irq_mask_addr += PERF_IRQMASK_6338_REG; | ||
174 | irq_bits = 32; | ||
175 | ext_irq_count = 4; | ||
176 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338; | ||
177 | break; | ||
178 | case BCM6345_CPU_ID: | ||
179 | irq_stat_addr += PERF_IRQSTAT_6345_REG; | ||
180 | irq_mask_addr += PERF_IRQMASK_6345_REG; | ||
181 | irq_bits = 32; | ||
182 | ext_irq_count = 4; | ||
183 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345; | ||
184 | break; | ||
185 | case BCM6348_CPU_ID: | ||
186 | irq_stat_addr += PERF_IRQSTAT_6348_REG; | ||
187 | irq_mask_addr += PERF_IRQMASK_6348_REG; | ||
188 | irq_bits = 32; | ||
189 | ext_irq_count = 4; | ||
190 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348; | ||
191 | break; | ||
192 | case BCM6358_CPU_ID: | ||
193 | irq_stat_addr += PERF_IRQSTAT_6358_REG; | ||
194 | irq_mask_addr += PERF_IRQMASK_6358_REG; | ||
195 | irq_bits = 32; | ||
196 | ext_irq_count = 4; | ||
197 | is_ext_irq_cascaded = 1; | ||
198 | ext_irq_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE; | ||
199 | ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE; | ||
200 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358; | ||
201 | break; | ||
202 | case BCM6362_CPU_ID: | ||
203 | irq_stat_addr += PERF_IRQSTAT_6362_REG; | ||
204 | irq_mask_addr += PERF_IRQMASK_6362_REG; | ||
205 | irq_bits = 64; | ||
206 | ext_irq_count = 4; | ||
207 | is_ext_irq_cascaded = 1; | ||
208 | ext_irq_start = BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE; | ||
209 | ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE; | ||
210 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362; | ||
211 | break; | ||
212 | case BCM6368_CPU_ID: | ||
213 | irq_stat_addr += PERF_IRQSTAT_6368_REG; | ||
214 | irq_mask_addr += PERF_IRQMASK_6368_REG; | ||
215 | irq_bits = 64; | ||
216 | ext_irq_count = 6; | ||
217 | is_ext_irq_cascaded = 1; | ||
218 | ext_irq_start = BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE; | ||
219 | ext_irq_end = BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE; | ||
220 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6368; | ||
221 | ext_irq_cfg_reg2 = PERF_EXTIRQ_CFG_REG2_6368; | ||
222 | break; | ||
223 | default: | ||
224 | BUG(); | ||
225 | } | ||
226 | |||
227 | if (irq_bits == 32) { | ||
228 | dispatch_internal = __dispatch_internal; | ||
229 | internal_irq_mask = __internal_irq_mask_32; | ||
230 | internal_irq_unmask = __internal_irq_unmask_32; | ||
231 | } else { | ||
232 | dispatch_internal = __dispatch_internal_64; | ||
233 | internal_irq_mask = __internal_irq_mask_64; | ||
234 | internal_irq_unmask = __internal_irq_unmask_64; | ||
235 | } | ||
236 | } | ||
237 | #endif /* ! BCMCPU_RUNTIME_DETECT */ | ||
238 | 37 | ||
239 | static inline u32 get_ext_irq_perf_reg(int irq) | 38 | static inline u32 get_ext_irq_perf_reg(int irq) |
240 | { | 39 | { |
@@ -252,53 +51,113 @@ static inline void handle_internal(int intbit) | |||
252 | do_IRQ(intbit + IRQ_INTERNAL_BASE); | 51 | do_IRQ(intbit + IRQ_INTERNAL_BASE); |
253 | } | 52 | } |
254 | 53 | ||
54 | static inline int enable_irq_for_cpu(int cpu, struct irq_data *d, | ||
55 | const struct cpumask *m) | ||
56 | { | ||
57 | bool enable = cpu_online(cpu); | ||
58 | |||
59 | #ifdef CONFIG_SMP | ||
60 | if (m) | ||
61 | enable &= cpu_isset(cpu, *m); | ||
62 | else if (irqd_affinity_was_set(d)) | ||
63 | enable &= cpu_isset(cpu, *d->affinity); | ||
64 | #endif | ||
65 | return enable; | ||
66 | } | ||
67 | |||
255 | /* | 68 | /* |
256 | * dispatch internal devices IRQ (uart, enet, watchdog, ...). do not | 69 | * dispatch internal devices IRQ (uart, enet, watchdog, ...). do not |
257 | * prioritize any interrupt relatively to another. the static counter | 70 | * prioritize any interrupt relatively to another. the static counter |
258 | * will resume the loop where it ended the last time we left this | 71 | * will resume the loop where it ended the last time we left this |
259 | * function. | 72 | * function. |
260 | */ | 73 | */ |
261 | static void __dispatch_internal(void) | ||
262 | { | ||
263 | u32 pending; | ||
264 | static int i; | ||
265 | |||
266 | pending = bcm_readl(irq_stat_addr) & bcm_readl(irq_mask_addr); | ||
267 | 74 | ||
268 | if (!pending) | 75 | #define BUILD_IPIC_INTERNAL(width) \ |
269 | return ; | 76 | void __dispatch_internal_##width(int cpu) \ |
270 | 77 | { \ | |
271 | while (1) { | 78 | u32 pending[width / 32]; \ |
272 | int to_call = i; | 79 | unsigned int src, tgt; \ |
273 | 80 | bool irqs_pending = false; \ | |
274 | i = (i + 1) & 0x1f; | 81 | static unsigned int i[2]; \ |
275 | if (pending & (1 << to_call)) { | 82 | unsigned int *next = &i[cpu]; \ |
276 | handle_internal(to_call); | 83 | unsigned long flags; \ |
277 | break; | 84 | \ |
278 | } | 85 | /* read registers in reverse order */ \ |
279 | } | 86 | spin_lock_irqsave(&ipic_lock, flags); \ |
87 | for (src = 0, tgt = (width / 32); src < (width / 32); src++) { \ | ||
88 | u32 val; \ | ||
89 | \ | ||
90 | val = bcm_readl(irq_stat_addr[cpu] + src * sizeof(u32)); \ | ||
91 | val &= bcm_readl(irq_mask_addr[cpu] + src * sizeof(u32)); \ | ||
92 | pending[--tgt] = val; \ | ||
93 | \ | ||
94 | if (val) \ | ||
95 | irqs_pending = true; \ | ||
96 | } \ | ||
97 | spin_unlock_irqrestore(&ipic_lock, flags); \ | ||
98 | \ | ||
99 | if (!irqs_pending) \ | ||
100 | return; \ | ||
101 | \ | ||
102 | while (1) { \ | ||
103 | unsigned int to_call = *next; \ | ||
104 | \ | ||
105 | *next = (*next + 1) & (width - 1); \ | ||
106 | if (pending[to_call / 32] & (1 << (to_call & 0x1f))) { \ | ||
107 | handle_internal(to_call); \ | ||
108 | break; \ | ||
109 | } \ | ||
110 | } \ | ||
111 | } \ | ||
112 | \ | ||
113 | static void __internal_irq_mask_##width(struct irq_data *d) \ | ||
114 | { \ | ||
115 | u32 val; \ | ||
116 | unsigned irq = d->irq - IRQ_INTERNAL_BASE; \ | ||
117 | unsigned reg = (irq / 32) ^ (width/32 - 1); \ | ||
118 | unsigned bit = irq & 0x1f; \ | ||
119 | unsigned long flags; \ | ||
120 | int cpu; \ | ||
121 | \ | ||
122 | spin_lock_irqsave(&ipic_lock, flags); \ | ||
123 | for_each_present_cpu(cpu) { \ | ||
124 | if (!irq_mask_addr[cpu]) \ | ||
125 | break; \ | ||
126 | \ | ||
127 | val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\ | ||
128 | val &= ~(1 << bit); \ | ||
129 | bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\ | ||
130 | } \ | ||
131 | spin_unlock_irqrestore(&ipic_lock, flags); \ | ||
132 | } \ | ||
133 | \ | ||
134 | static void __internal_irq_unmask_##width(struct irq_data *d, \ | ||
135 | const struct cpumask *m) \ | ||
136 | { \ | ||
137 | u32 val; \ | ||
138 | unsigned irq = d->irq - IRQ_INTERNAL_BASE; \ | ||
139 | unsigned reg = (irq / 32) ^ (width/32 - 1); \ | ||
140 | unsigned bit = irq & 0x1f; \ | ||
141 | unsigned long flags; \ | ||
142 | int cpu; \ | ||
143 | \ | ||
144 | spin_lock_irqsave(&ipic_lock, flags); \ | ||
145 | for_each_present_cpu(cpu) { \ | ||
146 | if (!irq_mask_addr[cpu]) \ | ||
147 | break; \ | ||
148 | \ | ||
149 | val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\ | ||
150 | if (enable_irq_for_cpu(cpu, d, m)) \ | ||
151 | val |= (1 << bit); \ | ||
152 | else \ | ||
153 | val &= ~(1 << bit); \ | ||
154 | bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\ | ||
155 | } \ | ||
156 | spin_unlock_irqrestore(&ipic_lock, flags); \ | ||
280 | } | 157 | } |
281 | 158 | ||
282 | static void __dispatch_internal_64(void) | 159 | BUILD_IPIC_INTERNAL(32); |
283 | { | 160 | BUILD_IPIC_INTERNAL(64); |
284 | u64 pending; | ||
285 | static int i; | ||
286 | |||
287 | pending = bcm_readq(irq_stat_addr) & bcm_readq(irq_mask_addr); | ||
288 | |||
289 | if (!pending) | ||
290 | return ; | ||
291 | |||
292 | while (1) { | ||
293 | int to_call = i; | ||
294 | |||
295 | i = (i + 1) & 0x3f; | ||
296 | if (pending & (1ull << to_call)) { | ||
297 | handle_internal(to_call); | ||
298 | break; | ||
299 | } | ||
300 | } | ||
301 | } | ||
302 | 161 | ||
303 | asmlinkage void plat_irq_dispatch(void) | 162 | asmlinkage void plat_irq_dispatch(void) |
304 | { | 163 | { |
@@ -317,8 +176,11 @@ asmlinkage void plat_irq_dispatch(void) | |||
317 | if (cause & CAUSEF_IP1) | 176 | if (cause & CAUSEF_IP1) |
318 | do_IRQ(1); | 177 | do_IRQ(1); |
319 | if (cause & CAUSEF_IP2) | 178 | if (cause & CAUSEF_IP2) |
320 | dispatch_internal(); | 179 | dispatch_internal(0); |
321 | if (!is_ext_irq_cascaded) { | 180 | if (is_ext_irq_cascaded) { |
181 | if (cause & CAUSEF_IP3) | ||
182 | dispatch_internal(1); | ||
183 | } else { | ||
322 | if (cause & CAUSEF_IP3) | 184 | if (cause & CAUSEF_IP3) |
323 | do_IRQ(IRQ_EXT_0); | 185 | do_IRQ(IRQ_EXT_0); |
324 | if (cause & CAUSEF_IP4) | 186 | if (cause & CAUSEF_IP4) |
@@ -335,50 +197,14 @@ asmlinkage void plat_irq_dispatch(void) | |||
335 | * internal IRQs operations: only mask/unmask on PERF irq mask | 197 | * internal IRQs operations: only mask/unmask on PERF irq mask |
336 | * register. | 198 | * register. |
337 | */ | 199 | */ |
338 | static void __internal_irq_mask_32(unsigned int irq) | ||
339 | { | ||
340 | u32 mask; | ||
341 | |||
342 | mask = bcm_readl(irq_mask_addr); | ||
343 | mask &= ~(1 << irq); | ||
344 | bcm_writel(mask, irq_mask_addr); | ||
345 | } | ||
346 | |||
347 | static void __internal_irq_mask_64(unsigned int irq) | ||
348 | { | ||
349 | u64 mask; | ||
350 | |||
351 | mask = bcm_readq(irq_mask_addr); | ||
352 | mask &= ~(1ull << irq); | ||
353 | bcm_writeq(mask, irq_mask_addr); | ||
354 | } | ||
355 | |||
356 | static void __internal_irq_unmask_32(unsigned int irq) | ||
357 | { | ||
358 | u32 mask; | ||
359 | |||
360 | mask = bcm_readl(irq_mask_addr); | ||
361 | mask |= (1 << irq); | ||
362 | bcm_writel(mask, irq_mask_addr); | ||
363 | } | ||
364 | |||
365 | static void __internal_irq_unmask_64(unsigned int irq) | ||
366 | { | ||
367 | u64 mask; | ||
368 | |||
369 | mask = bcm_readq(irq_mask_addr); | ||
370 | mask |= (1ull << irq); | ||
371 | bcm_writeq(mask, irq_mask_addr); | ||
372 | } | ||
373 | |||
374 | static void bcm63xx_internal_irq_mask(struct irq_data *d) | 200 | static void bcm63xx_internal_irq_mask(struct irq_data *d) |
375 | { | 201 | { |
376 | internal_irq_mask(d->irq - IRQ_INTERNAL_BASE); | 202 | internal_irq_mask(d); |
377 | } | 203 | } |
378 | 204 | ||
379 | static void bcm63xx_internal_irq_unmask(struct irq_data *d) | 205 | static void bcm63xx_internal_irq_unmask(struct irq_data *d) |
380 | { | 206 | { |
381 | internal_irq_unmask(d->irq - IRQ_INTERNAL_BASE); | 207 | internal_irq_unmask(d, NULL); |
382 | } | 208 | } |
383 | 209 | ||
384 | /* | 210 | /* |
@@ -389,8 +215,10 @@ static void bcm63xx_external_irq_mask(struct irq_data *d) | |||
389 | { | 215 | { |
390 | unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; | 216 | unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; |
391 | u32 reg, regaddr; | 217 | u32 reg, regaddr; |
218 | unsigned long flags; | ||
392 | 219 | ||
393 | regaddr = get_ext_irq_perf_reg(irq); | 220 | regaddr = get_ext_irq_perf_reg(irq); |
221 | spin_lock_irqsave(&epic_lock, flags); | ||
394 | reg = bcm_perf_readl(regaddr); | 222 | reg = bcm_perf_readl(regaddr); |
395 | 223 | ||
396 | if (BCMCPU_IS_6348()) | 224 | if (BCMCPU_IS_6348()) |
@@ -399,16 +227,20 @@ static void bcm63xx_external_irq_mask(struct irq_data *d) | |||
399 | reg &= ~EXTIRQ_CFG_MASK(irq % 4); | 227 | reg &= ~EXTIRQ_CFG_MASK(irq % 4); |
400 | 228 | ||
401 | bcm_perf_writel(reg, regaddr); | 229 | bcm_perf_writel(reg, regaddr); |
230 | spin_unlock_irqrestore(&epic_lock, flags); | ||
231 | |||
402 | if (is_ext_irq_cascaded) | 232 | if (is_ext_irq_cascaded) |
403 | internal_irq_mask(irq + ext_irq_start); | 233 | internal_irq_mask(irq_get_irq_data(irq + ext_irq_start)); |
404 | } | 234 | } |
405 | 235 | ||
406 | static void bcm63xx_external_irq_unmask(struct irq_data *d) | 236 | static void bcm63xx_external_irq_unmask(struct irq_data *d) |
407 | { | 237 | { |
408 | unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; | 238 | unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; |
409 | u32 reg, regaddr; | 239 | u32 reg, regaddr; |
240 | unsigned long flags; | ||
410 | 241 | ||
411 | regaddr = get_ext_irq_perf_reg(irq); | 242 | regaddr = get_ext_irq_perf_reg(irq); |
243 | spin_lock_irqsave(&epic_lock, flags); | ||
412 | reg = bcm_perf_readl(regaddr); | 244 | reg = bcm_perf_readl(regaddr); |
413 | 245 | ||
414 | if (BCMCPU_IS_6348()) | 246 | if (BCMCPU_IS_6348()) |
@@ -417,17 +249,21 @@ static void bcm63xx_external_irq_unmask(struct irq_data *d) | |||
417 | reg |= EXTIRQ_CFG_MASK(irq % 4); | 249 | reg |= EXTIRQ_CFG_MASK(irq % 4); |
418 | 250 | ||
419 | bcm_perf_writel(reg, regaddr); | 251 | bcm_perf_writel(reg, regaddr); |
252 | spin_unlock_irqrestore(&epic_lock, flags); | ||
420 | 253 | ||
421 | if (is_ext_irq_cascaded) | 254 | if (is_ext_irq_cascaded) |
422 | internal_irq_unmask(irq + ext_irq_start); | 255 | internal_irq_unmask(irq_get_irq_data(irq + ext_irq_start), |
256 | NULL); | ||
423 | } | 257 | } |
424 | 258 | ||
425 | static void bcm63xx_external_irq_clear(struct irq_data *d) | 259 | static void bcm63xx_external_irq_clear(struct irq_data *d) |
426 | { | 260 | { |
427 | unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; | 261 | unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; |
428 | u32 reg, regaddr; | 262 | u32 reg, regaddr; |
263 | unsigned long flags; | ||
429 | 264 | ||
430 | regaddr = get_ext_irq_perf_reg(irq); | 265 | regaddr = get_ext_irq_perf_reg(irq); |
266 | spin_lock_irqsave(&epic_lock, flags); | ||
431 | reg = bcm_perf_readl(regaddr); | 267 | reg = bcm_perf_readl(regaddr); |
432 | 268 | ||
433 | if (BCMCPU_IS_6348()) | 269 | if (BCMCPU_IS_6348()) |
@@ -436,6 +272,7 @@ static void bcm63xx_external_irq_clear(struct irq_data *d) | |||
436 | reg |= EXTIRQ_CFG_CLEAR(irq % 4); | 272 | reg |= EXTIRQ_CFG_CLEAR(irq % 4); |
437 | 273 | ||
438 | bcm_perf_writel(reg, regaddr); | 274 | bcm_perf_writel(reg, regaddr); |
275 | spin_unlock_irqrestore(&epic_lock, flags); | ||
439 | } | 276 | } |
440 | 277 | ||
441 | static int bcm63xx_external_irq_set_type(struct irq_data *d, | 278 | static int bcm63xx_external_irq_set_type(struct irq_data *d, |
@@ -444,6 +281,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d, | |||
444 | unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; | 281 | unsigned int irq = d->irq - IRQ_EXTERNAL_BASE; |
445 | u32 reg, regaddr; | 282 | u32 reg, regaddr; |
446 | int levelsense, sense, bothedge; | 283 | int levelsense, sense, bothedge; |
284 | unsigned long flags; | ||
447 | 285 | ||
448 | flow_type &= IRQ_TYPE_SENSE_MASK; | 286 | flow_type &= IRQ_TYPE_SENSE_MASK; |
449 | 287 | ||
@@ -478,6 +316,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d, | |||
478 | } | 316 | } |
479 | 317 | ||
480 | regaddr = get_ext_irq_perf_reg(irq); | 318 | regaddr = get_ext_irq_perf_reg(irq); |
319 | spin_lock_irqsave(&epic_lock, flags); | ||
481 | reg = bcm_perf_readl(regaddr); | 320 | reg = bcm_perf_readl(regaddr); |
482 | irq %= 4; | 321 | irq %= 4; |
483 | 322 | ||
@@ -522,6 +361,7 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d, | |||
522 | } | 361 | } |
523 | 362 | ||
524 | bcm_perf_writel(reg, regaddr); | 363 | bcm_perf_writel(reg, regaddr); |
364 | spin_unlock_irqrestore(&epic_lock, flags); | ||
525 | 365 | ||
526 | irqd_set_trigger_type(d, flow_type); | 366 | irqd_set_trigger_type(d, flow_type); |
527 | if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) | 367 | if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) |
@@ -532,6 +372,18 @@ static int bcm63xx_external_irq_set_type(struct irq_data *d, | |||
532 | return IRQ_SET_MASK_OK_NOCOPY; | 372 | return IRQ_SET_MASK_OK_NOCOPY; |
533 | } | 373 | } |
534 | 374 | ||
375 | #ifdef CONFIG_SMP | ||
376 | static int bcm63xx_internal_set_affinity(struct irq_data *data, | ||
377 | const struct cpumask *dest, | ||
378 | bool force) | ||
379 | { | ||
380 | if (!irqd_irq_disabled(data)) | ||
381 | internal_irq_unmask(data, dest); | ||
382 | |||
383 | return 0; | ||
384 | } | ||
385 | #endif | ||
386 | |||
535 | static struct irq_chip bcm63xx_internal_irq_chip = { | 387 | static struct irq_chip bcm63xx_internal_irq_chip = { |
536 | .name = "bcm63xx_ipic", | 388 | .name = "bcm63xx_ipic", |
537 | .irq_mask = bcm63xx_internal_irq_mask, | 389 | .irq_mask = bcm63xx_internal_irq_mask, |
@@ -554,12 +406,130 @@ static struct irqaction cpu_ip2_cascade_action = { | |||
554 | .flags = IRQF_NO_THREAD, | 406 | .flags = IRQF_NO_THREAD, |
555 | }; | 407 | }; |
556 | 408 | ||
409 | #ifdef CONFIG_SMP | ||
410 | static struct irqaction cpu_ip3_cascade_action = { | ||
411 | .handler = no_action, | ||
412 | .name = "cascade_ip3", | ||
413 | .flags = IRQF_NO_THREAD, | ||
414 | }; | ||
415 | #endif | ||
416 | |||
557 | static struct irqaction cpu_ext_cascade_action = { | 417 | static struct irqaction cpu_ext_cascade_action = { |
558 | .handler = no_action, | 418 | .handler = no_action, |
559 | .name = "cascade_extirq", | 419 | .name = "cascade_extirq", |
560 | .flags = IRQF_NO_THREAD, | 420 | .flags = IRQF_NO_THREAD, |
561 | }; | 421 | }; |
562 | 422 | ||
423 | static void bcm63xx_init_irq(void) | ||
424 | { | ||
425 | int irq_bits; | ||
426 | |||
427 | irq_stat_addr[0] = bcm63xx_regset_address(RSET_PERF); | ||
428 | irq_mask_addr[0] = bcm63xx_regset_address(RSET_PERF); | ||
429 | irq_stat_addr[1] = bcm63xx_regset_address(RSET_PERF); | ||
430 | irq_mask_addr[1] = bcm63xx_regset_address(RSET_PERF); | ||
431 | |||
432 | switch (bcm63xx_get_cpu_id()) { | ||
433 | case BCM3368_CPU_ID: | ||
434 | irq_stat_addr[0] += PERF_IRQSTAT_3368_REG; | ||
435 | irq_mask_addr[0] += PERF_IRQMASK_3368_REG; | ||
436 | irq_stat_addr[1] = 0; | ||
437 | irq_stat_addr[1] = 0; | ||
438 | irq_bits = 32; | ||
439 | ext_irq_count = 4; | ||
440 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368; | ||
441 | break; | ||
442 | case BCM6328_CPU_ID: | ||
443 | irq_stat_addr[0] += PERF_IRQSTAT_6328_REG(0); | ||
444 | irq_mask_addr[0] += PERF_IRQMASK_6328_REG(0); | ||
445 | irq_stat_addr[1] += PERF_IRQSTAT_6328_REG(1); | ||
446 | irq_stat_addr[1] += PERF_IRQMASK_6328_REG(1); | ||
447 | irq_bits = 64; | ||
448 | ext_irq_count = 4; | ||
449 | is_ext_irq_cascaded = 1; | ||
450 | ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE; | ||
451 | ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE; | ||
452 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328; | ||
453 | break; | ||
454 | case BCM6338_CPU_ID: | ||
455 | irq_stat_addr[0] += PERF_IRQSTAT_6338_REG; | ||
456 | irq_mask_addr[0] += PERF_IRQMASK_6338_REG; | ||
457 | irq_stat_addr[1] = 0; | ||
458 | irq_mask_addr[1] = 0; | ||
459 | irq_bits = 32; | ||
460 | ext_irq_count = 4; | ||
461 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338; | ||
462 | break; | ||
463 | case BCM6345_CPU_ID: | ||
464 | irq_stat_addr[0] += PERF_IRQSTAT_6345_REG; | ||
465 | irq_mask_addr[0] += PERF_IRQMASK_6345_REG; | ||
466 | irq_stat_addr[1] = 0; | ||
467 | irq_mask_addr[1] = 0; | ||
468 | irq_bits = 32; | ||
469 | ext_irq_count = 4; | ||
470 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345; | ||
471 | break; | ||
472 | case BCM6348_CPU_ID: | ||
473 | irq_stat_addr[0] += PERF_IRQSTAT_6348_REG; | ||
474 | irq_mask_addr[0] += PERF_IRQMASK_6348_REG; | ||
475 | irq_stat_addr[1] = 0; | ||
476 | irq_mask_addr[1] = 0; | ||
477 | irq_bits = 32; | ||
478 | ext_irq_count = 4; | ||
479 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348; | ||
480 | break; | ||
481 | case BCM6358_CPU_ID: | ||
482 | irq_stat_addr[0] += PERF_IRQSTAT_6358_REG(0); | ||
483 | irq_mask_addr[0] += PERF_IRQMASK_6358_REG(0); | ||
484 | irq_stat_addr[1] += PERF_IRQSTAT_6358_REG(1); | ||
485 | irq_mask_addr[1] += PERF_IRQMASK_6358_REG(1); | ||
486 | irq_bits = 32; | ||
487 | ext_irq_count = 4; | ||
488 | is_ext_irq_cascaded = 1; | ||
489 | ext_irq_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE; | ||
490 | ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE; | ||
491 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358; | ||
492 | break; | ||
493 | case BCM6362_CPU_ID: | ||
494 | irq_stat_addr[0] += PERF_IRQSTAT_6362_REG(0); | ||
495 | irq_mask_addr[0] += PERF_IRQMASK_6362_REG(0); | ||
496 | irq_stat_addr[1] += PERF_IRQSTAT_6362_REG(1); | ||
497 | irq_mask_addr[1] += PERF_IRQMASK_6362_REG(1); | ||
498 | irq_bits = 64; | ||
499 | ext_irq_count = 4; | ||
500 | is_ext_irq_cascaded = 1; | ||
501 | ext_irq_start = BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE; | ||
502 | ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE; | ||
503 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362; | ||
504 | break; | ||
505 | case BCM6368_CPU_ID: | ||
506 | irq_stat_addr[0] += PERF_IRQSTAT_6368_REG(0); | ||
507 | irq_mask_addr[0] += PERF_IRQMASK_6368_REG(0); | ||
508 | irq_stat_addr[1] += PERF_IRQSTAT_6368_REG(1); | ||
509 | irq_mask_addr[1] += PERF_IRQMASK_6368_REG(1); | ||
510 | irq_bits = 64; | ||
511 | ext_irq_count = 6; | ||
512 | is_ext_irq_cascaded = 1; | ||
513 | ext_irq_start = BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE; | ||
514 | ext_irq_end = BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE; | ||
515 | ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6368; | ||
516 | ext_irq_cfg_reg2 = PERF_EXTIRQ_CFG_REG2_6368; | ||
517 | break; | ||
518 | default: | ||
519 | BUG(); | ||
520 | } | ||
521 | |||
522 | if (irq_bits == 32) { | ||
523 | dispatch_internal = __dispatch_internal_32; | ||
524 | internal_irq_mask = __internal_irq_mask_32; | ||
525 | internal_irq_unmask = __internal_irq_unmask_32; | ||
526 | } else { | ||
527 | dispatch_internal = __dispatch_internal_64; | ||
528 | internal_irq_mask = __internal_irq_mask_64; | ||
529 | internal_irq_unmask = __internal_irq_unmask_64; | ||
530 | } | ||
531 | } | ||
532 | |||
563 | void __init arch_init_irq(void) | 533 | void __init arch_init_irq(void) |
564 | { | 534 | { |
565 | int i; | 535 | int i; |
@@ -580,4 +550,14 @@ void __init arch_init_irq(void) | |||
580 | } | 550 | } |
581 | 551 | ||
582 | setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action); | 552 | setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action); |
553 | #ifdef CONFIG_SMP | ||
554 | if (is_ext_irq_cascaded) { | ||
555 | setup_irq(MIPS_CPU_IRQ_BASE + 3, &cpu_ip3_cascade_action); | ||
556 | bcm63xx_internal_irq_chip.irq_set_affinity = | ||
557 | bcm63xx_internal_set_affinity; | ||
558 | |||
559 | cpumask_clear(irq_default_affinity); | ||
560 | cpumask_set_cpu(smp_processor_id(), irq_default_affinity); | ||
561 | } | ||
562 | #endif | ||
583 | } | 563 | } |
diff --git a/arch/mips/bcm63xx/reset.c b/arch/mips/bcm63xx/reset.c index acbeb1fe7c57..d1fe51edf5e6 100644 --- a/arch/mips/bcm63xx/reset.c +++ b/arch/mips/bcm63xx/reset.c | |||
@@ -125,8 +125,6 @@ | |||
125 | #define BCM6368_RESET_PCIE 0 | 125 | #define BCM6368_RESET_PCIE 0 |
126 | #define BCM6368_RESET_PCIE_EXT 0 | 126 | #define BCM6368_RESET_PCIE_EXT 0 |
127 | 127 | ||
128 | #ifdef BCMCPU_RUNTIME_DETECT | ||
129 | |||
130 | /* | 128 | /* |
131 | * core reset bits | 129 | * core reset bits |
132 | */ | 130 | */ |
@@ -188,64 +186,6 @@ static int __init bcm63xx_reset_bits_init(void) | |||
188 | 186 | ||
189 | return 0; | 187 | return 0; |
190 | } | 188 | } |
191 | #else | ||
192 | |||
193 | #ifdef CONFIG_BCM63XX_CPU_3368 | ||
194 | static const u32 bcm63xx_reset_bits[] = { | ||
195 | __GEN_RESET_BITS_TABLE(3368) | ||
196 | }; | ||
197 | #define reset_reg PERF_SOFTRESET_6358_REG | ||
198 | #endif | ||
199 | |||
200 | #ifdef CONFIG_BCM63XX_CPU_6328 | ||
201 | static const u32 bcm63xx_reset_bits[] = { | ||
202 | __GEN_RESET_BITS_TABLE(6328) | ||
203 | }; | ||
204 | #define reset_reg PERF_SOFTRESET_6328_REG | ||
205 | #endif | ||
206 | |||
207 | #ifdef CONFIG_BCM63XX_CPU_6338 | ||
208 | static const u32 bcm63xx_reset_bits[] = { | ||
209 | __GEN_RESET_BITS_TABLE(6338) | ||
210 | }; | ||
211 | #define reset_reg PERF_SOFTRESET_REG | ||
212 | #endif | ||
213 | |||
214 | #ifdef CONFIG_BCM63XX_CPU_6345 | ||
215 | static const u32 bcm63xx_reset_bits[] = { }; | ||
216 | #define reset_reg 0 | ||
217 | #endif | ||
218 | |||
219 | #ifdef CONFIG_BCM63XX_CPU_6348 | ||
220 | static const u32 bcm63xx_reset_bits[] = { | ||
221 | __GEN_RESET_BITS_TABLE(6348) | ||
222 | }; | ||
223 | #define reset_reg PERF_SOFTRESET_REG | ||
224 | #endif | ||
225 | |||
226 | #ifdef CONFIG_BCM63XX_CPU_6358 | ||
227 | static const u32 bcm63xx_reset_bits[] = { | ||
228 | __GEN_RESET_BITS_TABLE(6358) | ||
229 | }; | ||
230 | #define reset_reg PERF_SOFTRESET_6358_REG | ||
231 | #endif | ||
232 | |||
233 | #ifdef CONFIG_BCM63XX_CPU_6362 | ||
234 | static const u32 bcm63xx_reset_bits[] = { | ||
235 | __GEN_RESET_BITS_TABLE(6362) | ||
236 | }; | ||
237 | #define reset_reg PERF_SOFTRESET_6362_REG | ||
238 | #endif | ||
239 | |||
240 | #ifdef CONFIG_BCM63XX_CPU_6368 | ||
241 | static const u32 bcm63xx_reset_bits[] = { | ||
242 | __GEN_RESET_BITS_TABLE(6368) | ||
243 | }; | ||
244 | #define reset_reg PERF_SOFTRESET_6368_REG | ||
245 | #endif | ||
246 | |||
247 | static int __init bcm63xx_reset_bits_init(void) { return 0; } | ||
248 | #endif | ||
249 | 189 | ||
250 | static DEFINE_SPINLOCK(reset_mutex); | 190 | static DEFINE_SPINLOCK(reset_mutex); |
251 | 191 | ||
diff --git a/arch/mips/boot/compressed/decompress.c b/arch/mips/boot/compressed/decompress.c index c00c4ddf4514..b49c7adbfa89 100644 --- a/arch/mips/boot/compressed/decompress.c +++ b/arch/mips/boot/compressed/decompress.c | |||
@@ -67,10 +67,24 @@ void error(char *x) | |||
67 | #include "../../../../lib/decompress_unxz.c" | 67 | #include "../../../../lib/decompress_unxz.c" |
68 | #endif | 68 | #endif |
69 | 69 | ||
70 | unsigned long __stack_chk_guard; | ||
71 | |||
72 | void __stack_chk_guard_setup(void) | ||
73 | { | ||
74 | __stack_chk_guard = 0x000a0dff; | ||
75 | } | ||
76 | |||
77 | void __stack_chk_fail(void) | ||
78 | { | ||
79 | error("stack-protector: Kernel stack is corrupted\n"); | ||
80 | } | ||
81 | |||
70 | void decompress_kernel(unsigned long boot_heap_start) | 82 | void decompress_kernel(unsigned long boot_heap_start) |
71 | { | 83 | { |
72 | unsigned long zimage_start, zimage_size; | 84 | unsigned long zimage_start, zimage_size; |
73 | 85 | ||
86 | __stack_chk_guard_setup(); | ||
87 | |||
74 | zimage_start = (unsigned long)(&__image_begin); | 88 | zimage_start = (unsigned long)(&__image_begin); |
75 | zimage_size = (unsigned long)(&__image_end) - | 89 | zimage_size = (unsigned long)(&__image_end) - |
76 | (unsigned long)(&__image_begin); | 90 | (unsigned long)(&__image_begin); |
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c index b764df64be40..5dfef84b9576 100644 --- a/arch/mips/cavium-octeon/executive/cvmx-helper-board.c +++ b/arch/mips/cavium-octeon/executive/cvmx-helper-board.c | |||
@@ -186,6 +186,15 @@ int cvmx_helper_board_get_mii_address(int ipd_port) | |||
186 | return 7 - ipd_port; | 186 | return 7 - ipd_port; |
187 | else | 187 | else |
188 | return -1; | 188 | return -1; |
189 | case CVMX_BOARD_TYPE_CUST_DSR1000N: | ||
190 | /* | ||
191 | * Port 2 connects to Broadcom PHY (B5081). Other ports (0-1) | ||
192 | * connect to a switch (BCM53115). | ||
193 | */ | ||
194 | if (ipd_port == 2) | ||
195 | return 8; | ||
196 | else | ||
197 | return -1; | ||
189 | } | 198 | } |
190 | 199 | ||
191 | /* Some unknown board. Somebody forgot to update this function... */ | 200 | /* Some unknown board. Somebody forgot to update this function... */ |
@@ -274,6 +283,18 @@ cvmx_helper_link_info_t __cvmx_helper_board_link_get(int ipd_port) | |||
274 | return result; | 283 | return result; |
275 | } | 284 | } |
276 | break; | 285 | break; |
286 | case CVMX_BOARD_TYPE_CUST_DSR1000N: | ||
287 | if (ipd_port == 0 || ipd_port == 1) { | ||
288 | /* Ports 0 and 1 connect to a switch (BCM53115). */ | ||
289 | result.s.link_up = 1; | ||
290 | result.s.full_duplex = 1; | ||
291 | result.s.speed = 1000; | ||
292 | return result; | ||
293 | } else { | ||
294 | /* Port 2 uses a Broadcom PHY (B5081). */ | ||
295 | is_broadcom_phy = 1; | ||
296 | } | ||
297 | break; | ||
277 | } | 298 | } |
278 | 299 | ||
279 | phy_addr = cvmx_helper_board_get_mii_address(ipd_port); | 300 | phy_addr = cvmx_helper_board_get_mii_address(ipd_port); |
@@ -738,6 +759,7 @@ enum cvmx_helper_board_usb_clock_types __cvmx_helper_board_usb_get_clock_type(vo | |||
738 | case CVMX_BOARD_TYPE_LANAI2_G: | 759 | case CVMX_BOARD_TYPE_LANAI2_G: |
739 | case CVMX_BOARD_TYPE_NIC10E_66: | 760 | case CVMX_BOARD_TYPE_NIC10E_66: |
740 | case CVMX_BOARD_TYPE_UBNT_E100: | 761 | case CVMX_BOARD_TYPE_UBNT_E100: |
762 | case CVMX_BOARD_TYPE_CUST_DSR1000N: | ||
741 | return USB_CLOCK_TYPE_CRYSTAL_12; | 763 | return USB_CLOCK_TYPE_CRYSTAL_12; |
742 | case CVMX_BOARD_TYPE_NIC10E: | 764 | case CVMX_BOARD_TYPE_NIC10E: |
743 | return USB_CLOCK_TYPE_REF_12; | 765 | return USB_CLOCK_TYPE_REF_12; |
diff --git a/arch/mips/cavium-octeon/oct_ilm.c b/arch/mips/cavium-octeon/oct_ilm.c index 71b213dbb621..2d68a39f1443 100644 --- a/arch/mips/cavium-octeon/oct_ilm.c +++ b/arch/mips/cavium-octeon/oct_ilm.c | |||
@@ -194,8 +194,7 @@ err_irq: | |||
194 | static __exit void oct_ilm_module_exit(void) | 194 | static __exit void oct_ilm_module_exit(void) |
195 | { | 195 | { |
196 | disable_timer(TIMER_NUM); | 196 | disable_timer(TIMER_NUM); |
197 | if (dir) | 197 | debugfs_remove_recursive(dir); |
198 | debugfs_remove_recursive(dir); | ||
199 | free_irq(OCTEON_IRQ_TIMER0 + TIMER_NUM, 0); | 198 | free_irq(OCTEON_IRQ_TIMER0 + TIMER_NUM, 0); |
200 | } | 199 | } |
201 | 200 | ||
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index a7b3ae104d8c..ecd903dd1c45 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c | |||
@@ -84,9 +84,14 @@ static void octeon_smp_hotplug_setup(void) | |||
84 | #ifdef CONFIG_HOTPLUG_CPU | 84 | #ifdef CONFIG_HOTPLUG_CPU |
85 | struct linux_app_boot_info *labi; | 85 | struct linux_app_boot_info *labi; |
86 | 86 | ||
87 | if (!setup_max_cpus) | ||
88 | return; | ||
89 | |||
87 | labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER); | 90 | labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER); |
88 | if (labi->labi_signature != LABI_SIGNATURE) | 91 | if (labi->labi_signature != LABI_SIGNATURE) { |
89 | panic("The bootloader version on this board is incorrect."); | 92 | pr_info("The bootloader on this board does not support HOTPLUG_CPU."); |
93 | return; | ||
94 | } | ||
90 | 95 | ||
91 | octeon_bootloader_entry_addr = labi->InitTLBStart_addr; | 96 | octeon_bootloader_entry_addr = labi->InitTLBStart_addr; |
92 | #endif | 97 | #endif |
@@ -129,7 +134,8 @@ static void octeon_smp_setup(void) | |||
129 | * will assign CPU numbers for possible cores as well. Cores | 134 | * will assign CPU numbers for possible cores as well. Cores |
130 | * are always consecutively numberd from 0. | 135 | * are always consecutively numberd from 0. |
131 | */ | 136 | */ |
132 | for (id = 0; id < num_cores && id < NR_CPUS; id++) { | 137 | for (id = 0; setup_max_cpus && octeon_bootloader_entry_addr && |
138 | id < num_cores && id < NR_CPUS; id++) { | ||
133 | if (!(core_mask & (1 << id))) { | 139 | if (!(core_mask & (1 << id))) { |
134 | set_cpu_possible(cpus, true); | 140 | set_cpu_possible(cpus, true); |
135 | __cpu_number_map[id] = cpus; | 141 | __cpu_number_map[id] = cpus; |
@@ -192,14 +198,6 @@ static void octeon_init_secondary(void) | |||
192 | */ | 198 | */ |
193 | void octeon_prepare_cpus(unsigned int max_cpus) | 199 | void octeon_prepare_cpus(unsigned int max_cpus) |
194 | { | 200 | { |
195 | #ifdef CONFIG_HOTPLUG_CPU | ||
196 | struct linux_app_boot_info *labi; | ||
197 | |||
198 | labi = (struct linux_app_boot_info *)PHYS_TO_XKSEG_CACHED(LABI_ADDR_IN_BOOTLOADER); | ||
199 | |||
200 | if (labi->labi_signature != LABI_SIGNATURE) | ||
201 | panic("The bootloader version on this board is incorrect."); | ||
202 | #endif | ||
203 | /* | 201 | /* |
204 | * Only the low order mailbox bits are used for IPIs, leave | 202 | * Only the low order mailbox bits are used for IPIs, leave |
205 | * the other bits alone. | 203 | * the other bits alone. |
@@ -237,6 +235,9 @@ static int octeon_cpu_disable(void) | |||
237 | if (cpu == 0) | 235 | if (cpu == 0) |
238 | return -EBUSY; | 236 | return -EBUSY; |
239 | 237 | ||
238 | if (!octeon_bootloader_entry_addr) | ||
239 | return -ENOTSUPP; | ||
240 | |||
240 | set_cpu_online(cpu, false); | 241 | set_cpu_online(cpu, false); |
241 | cpu_clear(cpu, cpu_callin_map); | 242 | cpu_clear(cpu, cpu_callin_map); |
242 | local_irq_disable(); | 243 | local_irq_disable(); |
diff --git a/arch/mips/configs/loongson3_defconfig b/arch/mips/configs/loongson3_defconfig index fca91a8c8ef4..4cb787ff273e 100644 --- a/arch/mips/configs/loongson3_defconfig +++ b/arch/mips/configs/loongson3_defconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | CONFIG_MACH_LOONGSON=y | 1 | CONFIG_MACH_LOONGSON=y |
2 | CONFIG_SWIOTLB=y | 2 | CONFIG_SWIOTLB=y |
3 | CONFIG_LEMOTE_MACH3A=y | 3 | CONFIG_LOONGSON_MACH3X=y |
4 | CONFIG_CPU_LOONGSON3=y | 4 | CONFIG_CPU_LOONGSON3=y |
5 | CONFIG_64BIT=y | 5 | CONFIG_64BIT=y |
6 | CONFIG_PAGE_SIZE_16KB=y | 6 | CONFIG_PAGE_SIZE_16KB=y |
diff --git a/arch/mips/include/asm/Kbuild b/arch/mips/include/asm/Kbuild index 05439187891d..335e5290ec75 100644 --- a/arch/mips/include/asm/Kbuild +++ b/arch/mips/include/asm/Kbuild | |||
@@ -15,4 +15,5 @@ generic-y += segment.h | |||
15 | generic-y += serial.h | 15 | generic-y += serial.h |
16 | generic-y += trace_clock.h | 16 | generic-y += trace_clock.h |
17 | generic-y += ucontext.h | 17 | generic-y += ucontext.h |
18 | generic-y += user.h | ||
18 | generic-y += xor.h | 19 | generic-y += xor.h |
diff --git a/arch/mips/include/asm/addrspace.h b/arch/mips/include/asm/addrspace.h index 3f745459fdb5..3b0e51d5a613 100644 --- a/arch/mips/include/asm/addrspace.h +++ b/arch/mips/include/asm/addrspace.h | |||
@@ -52,7 +52,7 @@ | |||
52 | */ | 52 | */ |
53 | #define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff) | 53 | #define CPHYSADDR(a) ((_ACAST32_(a)) & 0x1fffffff) |
54 | #define XPHYSADDR(a) ((_ACAST64_(a)) & \ | 54 | #define XPHYSADDR(a) ((_ACAST64_(a)) & \ |
55 | _CONST64_(0x000000ffffffffff)) | 55 | _CONST64_(0x0000ffffffffffff)) |
56 | 56 | ||
57 | #ifdef CONFIG_64BIT | 57 | #ifdef CONFIG_64BIT |
58 | 58 | ||
diff --git a/arch/mips/include/asm/asmmacro.h b/arch/mips/include/asm/asmmacro.h index 935543f14538..cd9a98bc8f60 100644 --- a/arch/mips/include/asm/asmmacro.h +++ b/arch/mips/include/asm/asmmacro.h | |||
@@ -10,6 +10,7 @@ | |||
10 | 10 | ||
11 | #include <asm/hazards.h> | 11 | #include <asm/hazards.h> |
12 | #include <asm/asm-offsets.h> | 12 | #include <asm/asm-offsets.h> |
13 | #include <asm/msa.h> | ||
13 | 14 | ||
14 | #ifdef CONFIG_32BIT | 15 | #ifdef CONFIG_32BIT |
15 | #include <asm/asmmacro-32.h> | 16 | #include <asm/asmmacro-32.h> |
@@ -378,9 +379,19 @@ | |||
378 | st_d 29, THREAD_FPR29, \thread | 379 | st_d 29, THREAD_FPR29, \thread |
379 | st_d 30, THREAD_FPR30, \thread | 380 | st_d 30, THREAD_FPR30, \thread |
380 | st_d 31, THREAD_FPR31, \thread | 381 | st_d 31, THREAD_FPR31, \thread |
382 | .set push | ||
383 | .set noat | ||
384 | cfcmsa $1, MSA_CSR | ||
385 | sw $1, THREAD_MSA_CSR(\thread) | ||
386 | .set pop | ||
381 | .endm | 387 | .endm |
382 | 388 | ||
383 | .macro msa_restore_all thread | 389 | .macro msa_restore_all thread |
390 | .set push | ||
391 | .set noat | ||
392 | lw $1, THREAD_MSA_CSR(\thread) | ||
393 | ctcmsa MSA_CSR, $1 | ||
394 | .set pop | ||
384 | ld_d 0, THREAD_FPR0, \thread | 395 | ld_d 0, THREAD_FPR0, \thread |
385 | ld_d 1, THREAD_FPR1, \thread | 396 | ld_d 1, THREAD_FPR1, \thread |
386 | ld_d 2, THREAD_FPR2, \thread | 397 | ld_d 2, THREAD_FPR2, \thread |
@@ -415,4 +426,24 @@ | |||
415 | ld_d 31, THREAD_FPR31, \thread | 426 | ld_d 31, THREAD_FPR31, \thread |
416 | .endm | 427 | .endm |
417 | 428 | ||
429 | .macro msa_init_upper wd | ||
430 | #ifdef CONFIG_64BIT | ||
431 | insert_d \wd, 1 | ||
432 | #else | ||
433 | insert_w \wd, 2 | ||
434 | insert_w \wd, 3 | ||
435 | #endif | ||
436 | .if 31-\wd | ||
437 | msa_init_upper (\wd+1) | ||
438 | .endif | ||
439 | .endm | ||
440 | |||
441 | .macro msa_init_all_upper | ||
442 | .set push | ||
443 | .set noat | ||
444 | not $1, zero | ||
445 | msa_init_upper 0 | ||
446 | .set pop | ||
447 | .endm | ||
448 | |||
418 | #endif /* _ASM_ASMMACRO_H */ | 449 | #endif /* _ASM_ASMMACRO_H */ |
diff --git a/arch/mips/include/asm/bitops.h b/arch/mips/include/asm/bitops.h index 7c8816f7b7c4..bae6b0fa8ab5 100644 --- a/arch/mips/include/asm/bitops.h +++ b/arch/mips/include/asm/bitops.h | |||
@@ -559,7 +559,13 @@ static inline int fls(int x) | |||
559 | int r; | 559 | int r; |
560 | 560 | ||
561 | if (__builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) { | 561 | if (__builtin_constant_p(cpu_has_clo_clz) && cpu_has_clo_clz) { |
562 | __asm__("clz %0, %1" : "=r" (x) : "r" (x)); | 562 | __asm__( |
563 | " .set push \n" | ||
564 | " .set mips32 \n" | ||
565 | " clz %0, %1 \n" | ||
566 | " .set pop \n" | ||
567 | : "=r" (x) | ||
568 | : "r" (x)); | ||
563 | 569 | ||
564 | return 32 - x; | 570 | return 32 - x; |
565 | } | 571 | } |
diff --git a/arch/mips/include/asm/cop2.h b/arch/mips/include/asm/cop2.h index c1516cc0285f..d0352983b94d 100644 --- a/arch/mips/include/asm/cop2.h +++ b/arch/mips/include/asm/cop2.h | |||
@@ -32,6 +32,14 @@ extern void nlm_cop2_restore(struct nlm_cop2_state *); | |||
32 | #define cop2_present 1 | 32 | #define cop2_present 1 |
33 | #define cop2_lazy_restore 0 | 33 | #define cop2_lazy_restore 0 |
34 | 34 | ||
35 | #elif defined(CONFIG_CPU_LOONGSON3) | ||
36 | |||
37 | #define cop2_save(r) | ||
38 | #define cop2_restore(r) | ||
39 | |||
40 | #define cop2_present 1 | ||
41 | #define cop2_lazy_restore 1 | ||
42 | |||
35 | #else | 43 | #else |
36 | 44 | ||
37 | #define cop2_present 0 | 45 | #define cop2_present 0 |
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h index c7d8c997d93e..e079598ae051 100644 --- a/arch/mips/include/asm/cpu-features.h +++ b/arch/mips/include/asm/cpu-features.h | |||
@@ -29,6 +29,15 @@ | |||
29 | #ifndef cpu_has_eva | 29 | #ifndef cpu_has_eva |
30 | #define cpu_has_eva (cpu_data[0].options & MIPS_CPU_EVA) | 30 | #define cpu_has_eva (cpu_data[0].options & MIPS_CPU_EVA) |
31 | #endif | 31 | #endif |
32 | #ifndef cpu_has_htw | ||
33 | #define cpu_has_htw (cpu_data[0].options & MIPS_CPU_HTW) | ||
34 | #endif | ||
35 | #ifndef cpu_has_rixiex | ||
36 | #define cpu_has_rixiex (cpu_data[0].options & MIPS_CPU_RIXIEX) | ||
37 | #endif | ||
38 | #ifndef cpu_has_maar | ||
39 | #define cpu_has_maar (cpu_data[0].options & MIPS_CPU_MAAR) | ||
40 | #endif | ||
32 | 41 | ||
33 | /* | 42 | /* |
34 | * For the moment we don't consider R6000 and R8000 so we can assume that | 43 | * For the moment we don't consider R6000 and R8000 so we can assume that |
diff --git a/arch/mips/include/asm/cpu-info.h b/arch/mips/include/asm/cpu-info.h index 47d5967ce7ef..d5f42c168001 100644 --- a/arch/mips/include/asm/cpu-info.h +++ b/arch/mips/include/asm/cpu-info.h | |||
@@ -44,8 +44,8 @@ struct cpuinfo_mips { | |||
44 | /* | 44 | /* |
45 | * Capability and feature descriptor structure for MIPS CPU | 45 | * Capability and feature descriptor structure for MIPS CPU |
46 | */ | 46 | */ |
47 | unsigned long options; | ||
48 | unsigned long ases; | 47 | unsigned long ases; |
48 | unsigned long long options; | ||
49 | unsigned int udelay_val; | 49 | unsigned int udelay_val; |
50 | unsigned int processor_id; | 50 | unsigned int processor_id; |
51 | unsigned int fpu_id; | 51 | unsigned int fpu_id; |
@@ -61,6 +61,7 @@ struct cpuinfo_mips { | |||
61 | struct cache_desc scache; /* Secondary cache */ | 61 | struct cache_desc scache; /* Secondary cache */ |
62 | struct cache_desc tcache; /* Tertiary/split secondary cache */ | 62 | struct cache_desc tcache; /* Tertiary/split secondary cache */ |
63 | int srsets; /* Shadow register sets */ | 63 | int srsets; /* Shadow register sets */ |
64 | int package;/* physical package number */ | ||
64 | int core; /* physical core number */ | 65 | int core; /* physical core number */ |
65 | #ifdef CONFIG_64BIT | 66 | #ifdef CONFIG_64BIT |
66 | int vmbits; /* Virtual memory size in bits */ | 67 | int vmbits; /* Virtual memory size in bits */ |
@@ -115,7 +116,7 @@ struct proc_cpuinfo_notifier_args { | |||
115 | #ifdef CONFIG_MIPS_MT_SMP | 116 | #ifdef CONFIG_MIPS_MT_SMP |
116 | # define cpu_vpe_id(cpuinfo) ((cpuinfo)->vpe_id) | 117 | # define cpu_vpe_id(cpuinfo) ((cpuinfo)->vpe_id) |
117 | #else | 118 | #else |
118 | # define cpu_vpe_id(cpuinfo) 0 | 119 | # define cpu_vpe_id(cpuinfo) ({ (void)cpuinfo; 0; }) |
119 | #endif | 120 | #endif |
120 | 121 | ||
121 | #endif /* __ASM_CPU_INFO_H */ | 122 | #endif /* __ASM_CPU_INFO_H */ |
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h index 129d08701e91..dfdc77ed1839 100644 --- a/arch/mips/include/asm/cpu.h +++ b/arch/mips/include/asm/cpu.h | |||
@@ -233,6 +233,8 @@ | |||
233 | #define PRID_REV_LOONGSON2E 0x0002 | 233 | #define PRID_REV_LOONGSON2E 0x0002 |
234 | #define PRID_REV_LOONGSON2F 0x0003 | 234 | #define PRID_REV_LOONGSON2F 0x0003 |
235 | #define PRID_REV_LOONGSON3A 0x0005 | 235 | #define PRID_REV_LOONGSON3A 0x0005 |
236 | #define PRID_REV_LOONGSON3B_R1 0x0006 | ||
237 | #define PRID_REV_LOONGSON3B_R2 0x0007 | ||
236 | 238 | ||
237 | /* | 239 | /* |
238 | * Older processors used to encode processor version and revision in two | 240 | * Older processors used to encode processor version and revision in two |
@@ -335,34 +337,37 @@ enum cpu_type_enum { | |||
335 | /* | 337 | /* |
336 | * CPU Option encodings | 338 | * CPU Option encodings |
337 | */ | 339 | */ |
338 | #define MIPS_CPU_TLB 0x00000001 /* CPU has TLB */ | 340 | #define MIPS_CPU_TLB 0x00000001ull /* CPU has TLB */ |
339 | #define MIPS_CPU_4KEX 0x00000002 /* "R4K" exception model */ | 341 | #define MIPS_CPU_4KEX 0x00000002ull /* "R4K" exception model */ |
340 | #define MIPS_CPU_3K_CACHE 0x00000004 /* R3000-style caches */ | 342 | #define MIPS_CPU_3K_CACHE 0x00000004ull /* R3000-style caches */ |
341 | #define MIPS_CPU_4K_CACHE 0x00000008 /* R4000-style caches */ | 343 | #define MIPS_CPU_4K_CACHE 0x00000008ull /* R4000-style caches */ |
342 | #define MIPS_CPU_TX39_CACHE 0x00000010 /* TX3900-style caches */ | 344 | #define MIPS_CPU_TX39_CACHE 0x00000010ull /* TX3900-style caches */ |
343 | #define MIPS_CPU_FPU 0x00000020 /* CPU has FPU */ | 345 | #define MIPS_CPU_FPU 0x00000020ull /* CPU has FPU */ |
344 | #define MIPS_CPU_32FPR 0x00000040 /* 32 dbl. prec. FP registers */ | 346 | #define MIPS_CPU_32FPR 0x00000040ull /* 32 dbl. prec. FP registers */ |
345 | #define MIPS_CPU_COUNTER 0x00000080 /* Cycle count/compare */ | 347 | #define MIPS_CPU_COUNTER 0x00000080ull /* Cycle count/compare */ |
346 | #define MIPS_CPU_WATCH 0x00000100 /* watchpoint registers */ | 348 | #define MIPS_CPU_WATCH 0x00000100ull /* watchpoint registers */ |
347 | #define MIPS_CPU_DIVEC 0x00000200 /* dedicated interrupt vector */ | 349 | #define MIPS_CPU_DIVEC 0x00000200ull /* dedicated interrupt vector */ |
348 | #define MIPS_CPU_VCE 0x00000400 /* virt. coherence conflict possible */ | 350 | #define MIPS_CPU_VCE 0x00000400ull /* virt. coherence conflict possible */ |
349 | #define MIPS_CPU_CACHE_CDEX_P 0x00000800 /* Create_Dirty_Exclusive CACHE op */ | 351 | #define MIPS_CPU_CACHE_CDEX_P 0x00000800ull /* Create_Dirty_Exclusive CACHE op */ |
350 | #define MIPS_CPU_CACHE_CDEX_S 0x00001000 /* ... same for seconary cache ... */ | 352 | #define MIPS_CPU_CACHE_CDEX_S 0x00001000ull /* ... same for seconary cache ... */ |
351 | #define MIPS_CPU_MCHECK 0x00002000 /* Machine check exception */ | 353 | #define MIPS_CPU_MCHECK 0x00002000ull /* Machine check exception */ |
352 | #define MIPS_CPU_EJTAG 0x00004000 /* EJTAG exception */ | 354 | #define MIPS_CPU_EJTAG 0x00004000ull /* EJTAG exception */ |
353 | #define MIPS_CPU_NOFPUEX 0x00008000 /* no FPU exception */ | 355 | #define MIPS_CPU_NOFPUEX 0x00008000ull /* no FPU exception */ |
354 | #define MIPS_CPU_LLSC 0x00010000 /* CPU has ll/sc instructions */ | 356 | #define MIPS_CPU_LLSC 0x00010000ull /* CPU has ll/sc instructions */ |
355 | #define MIPS_CPU_INCLUSIVE_CACHES 0x00020000 /* P-cache subset enforced */ | 357 | #define MIPS_CPU_INCLUSIVE_CACHES 0x00020000ull /* P-cache subset enforced */ |
356 | #define MIPS_CPU_PREFETCH 0x00040000 /* CPU has usable prefetch */ | 358 | #define MIPS_CPU_PREFETCH 0x00040000ull /* CPU has usable prefetch */ |
357 | #define MIPS_CPU_VINT 0x00080000 /* CPU supports MIPSR2 vectored interrupts */ | 359 | #define MIPS_CPU_VINT 0x00080000ull /* CPU supports MIPSR2 vectored interrupts */ |
358 | #define MIPS_CPU_VEIC 0x00100000 /* CPU supports MIPSR2 external interrupt controller mode */ | 360 | #define MIPS_CPU_VEIC 0x00100000ull /* CPU supports MIPSR2 external interrupt controller mode */ |
359 | #define MIPS_CPU_ULRI 0x00200000 /* CPU has ULRI feature */ | 361 | #define MIPS_CPU_ULRI 0x00200000ull /* CPU has ULRI feature */ |
360 | #define MIPS_CPU_PCI 0x00400000 /* CPU has Perf Ctr Int indicator */ | 362 | #define MIPS_CPU_PCI 0x00400000ull /* CPU has Perf Ctr Int indicator */ |
361 | #define MIPS_CPU_RIXI 0x00800000 /* CPU has TLB Read/eXec Inhibit */ | 363 | #define MIPS_CPU_RIXI 0x00800000ull /* CPU has TLB Read/eXec Inhibit */ |
362 | #define MIPS_CPU_MICROMIPS 0x01000000 /* CPU has microMIPS capability */ | 364 | #define MIPS_CPU_MICROMIPS 0x01000000ull /* CPU has microMIPS capability */ |
363 | #define MIPS_CPU_TLBINV 0x02000000 /* CPU supports TLBINV/F */ | 365 | #define MIPS_CPU_TLBINV 0x02000000ull /* CPU supports TLBINV/F */ |
364 | #define MIPS_CPU_SEGMENTS 0x04000000 /* CPU supports Segmentation Control registers */ | 366 | #define MIPS_CPU_SEGMENTS 0x04000000ull /* CPU supports Segmentation Control registers */ |
365 | #define MIPS_CPU_EVA 0x80000000 /* CPU supports Enhanced Virtual Addressing */ | 367 | #define MIPS_CPU_EVA 0x80000000ull /* CPU supports Enhanced Virtual Addressing */ |
368 | #define MIPS_CPU_HTW 0x100000000ull /* CPU support Hardware Page Table Walker */ | ||
369 | #define MIPS_CPU_RIXIEX 0x200000000ull /* CPU has unique exception codes for {Read, Execute}-Inhibit exceptions */ | ||
370 | #define MIPS_CPU_MAAR 0x400000000ull /* MAAR(I) registers are present */ | ||
366 | 371 | ||
367 | /* | 372 | /* |
368 | * CPU ASE encodings | 373 | * CPU ASE encodings |
diff --git a/arch/mips/include/asm/elf.h b/arch/mips/include/asm/elf.h index d4144056e928..1d38fe0edd2d 100644 --- a/arch/mips/include/asm/elf.h +++ b/arch/mips/include/asm/elf.h | |||
@@ -339,23 +339,6 @@ do { \ | |||
339 | 339 | ||
340 | #endif /* CONFIG_64BIT */ | 340 | #endif /* CONFIG_64BIT */ |
341 | 341 | ||
342 | struct pt_regs; | ||
343 | struct task_struct; | ||
344 | |||
345 | extern void elf_dump_regs(elf_greg_t *, struct pt_regs *regs); | ||
346 | extern int dump_task_regs(struct task_struct *, elf_gregset_t *); | ||
347 | extern int dump_task_fpu(struct task_struct *, elf_fpregset_t *); | ||
348 | |||
349 | #ifndef ELF_CORE_COPY_REGS | ||
350 | #define ELF_CORE_COPY_REGS(elf_regs, regs) \ | ||
351 | elf_dump_regs((elf_greg_t *)&(elf_regs), regs); | ||
352 | #endif | ||
353 | #ifndef ELF_CORE_COPY_TASK_REGS | ||
354 | #define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs) | ||
355 | #endif | ||
356 | #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) \ | ||
357 | dump_task_fpu(tsk, elf_fpregs) | ||
358 | |||
359 | #define CORE_DUMP_USE_REGSET | 342 | #define CORE_DUMP_USE_REGSET |
360 | #define ELF_EXEC_PAGESIZE PAGE_SIZE | 343 | #define ELF_EXEC_PAGESIZE PAGE_SIZE |
361 | 344 | ||
diff --git a/arch/mips/include/asm/fpu.h b/arch/mips/include/asm/fpu.h index a939574f8293..4d0aeda68397 100644 --- a/arch/mips/include/asm/fpu.h +++ b/arch/mips/include/asm/fpu.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/hazards.h> | 21 | #include <asm/hazards.h> |
22 | #include <asm/processor.h> | 22 | #include <asm/processor.h> |
23 | #include <asm/current.h> | 23 | #include <asm/current.h> |
24 | #include <asm/msa.h> | ||
24 | 25 | ||
25 | #ifdef CONFIG_MIPS_MT_FPAFF | 26 | #ifdef CONFIG_MIPS_MT_FPAFF |
26 | #include <asm/mips_mt.h> | 27 | #include <asm/mips_mt.h> |
@@ -141,13 +142,21 @@ static inline int own_fpu(int restore) | |||
141 | static inline void lose_fpu(int save) | 142 | static inline void lose_fpu(int save) |
142 | { | 143 | { |
143 | preempt_disable(); | 144 | preempt_disable(); |
144 | if (is_fpu_owner()) { | 145 | if (is_msa_enabled()) { |
146 | if (save) { | ||
147 | save_msa(current); | ||
148 | asm volatile("cfc1 %0, $31" | ||
149 | : "=r"(current->thread.fpu.fcr31)); | ||
150 | } | ||
151 | disable_msa(); | ||
152 | clear_thread_flag(TIF_USEDMSA); | ||
153 | } else if (is_fpu_owner()) { | ||
145 | if (save) | 154 | if (save) |
146 | _save_fp(current); | 155 | _save_fp(current); |
147 | KSTK_STATUS(current) &= ~ST0_CU1; | ||
148 | clear_thread_flag(TIF_USEDFPU); | ||
149 | __disable_fpu(); | 156 | __disable_fpu(); |
150 | } | 157 | } |
158 | KSTK_STATUS(current) &= ~ST0_CU1; | ||
159 | clear_thread_flag(TIF_USEDFPU); | ||
151 | preempt_enable(); | 160 | preempt_enable(); |
152 | } | 161 | } |
153 | 162 | ||
@@ -155,8 +164,6 @@ static inline int init_fpu(void) | |||
155 | { | 164 | { |
156 | int ret = 0; | 165 | int ret = 0; |
157 | 166 | ||
158 | preempt_disable(); | ||
159 | |||
160 | if (cpu_has_fpu) { | 167 | if (cpu_has_fpu) { |
161 | ret = __own_fpu(); | 168 | ret = __own_fpu(); |
162 | if (!ret) | 169 | if (!ret) |
@@ -164,8 +171,6 @@ static inline int init_fpu(void) | |||
164 | } else | 171 | } else |
165 | fpu_emulator_init_fpu(); | 172 | fpu_emulator_init_fpu(); |
166 | 173 | ||
167 | preempt_enable(); | ||
168 | |||
169 | return ret; | 174 | return ret; |
170 | } | 175 | } |
171 | 176 | ||
diff --git a/arch/mips/include/asm/gic.h b/arch/mips/include/asm/gic.h index 10f6a99f92c2..3f20b2111d56 100644 --- a/arch/mips/include/asm/gic.h +++ b/arch/mips/include/asm/gic.h | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/bitmap.h> | 14 | #include <linux/bitmap.h> |
15 | #include <linux/threads.h> | 15 | #include <linux/threads.h> |
16 | 16 | ||
17 | #include <irq.h> | ||
18 | |||
17 | #undef GICISBYTELITTLEENDIAN | 19 | #undef GICISBYTELITTLEENDIAN |
18 | 20 | ||
19 | /* Constants */ | 21 | /* Constants */ |
@@ -22,8 +24,6 @@ | |||
22 | #define GIC_TRIG_EDGE 1 | 24 | #define GIC_TRIG_EDGE 1 |
23 | #define GIC_TRIG_LEVEL 0 | 25 | #define GIC_TRIG_LEVEL 0 |
24 | 26 | ||
25 | #define GIC_NUM_INTRS (24 + NR_CPUS * 2) | ||
26 | |||
27 | #define MSK(n) ((1 << (n)) - 1) | 27 | #define MSK(n) ((1 << (n)) - 1) |
28 | #define REG32(addr) (*(volatile unsigned int *) (addr)) | 28 | #define REG32(addr) (*(volatile unsigned int *) (addr)) |
29 | #define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS) | 29 | #define REG(base, offs) REG32((unsigned long)(base) + offs##_##OFS) |
@@ -43,18 +43,17 @@ | |||
43 | #ifdef GICISBYTELITTLEENDIAN | 43 | #ifdef GICISBYTELITTLEENDIAN |
44 | #define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data)) | 44 | #define GICREAD(reg, data) ((data) = (reg), (data) = le32_to_cpu(data)) |
45 | #define GICWRITE(reg, data) ((reg) = cpu_to_le32(data)) | 45 | #define GICWRITE(reg, data) ((reg) = cpu_to_le32(data)) |
46 | #define GICBIS(reg, bits) \ | ||
47 | ({unsigned int data; \ | ||
48 | GICREAD(reg, data); \ | ||
49 | data |= bits; \ | ||
50 | GICWRITE(reg, data); \ | ||
51 | }) | ||
52 | |||
53 | #else | 46 | #else |
54 | #define GICREAD(reg, data) ((data) = (reg)) | 47 | #define GICREAD(reg, data) ((data) = (reg)) |
55 | #define GICWRITE(reg, data) ((reg) = (data)) | 48 | #define GICWRITE(reg, data) ((reg) = (data)) |
56 | #define GICBIS(reg, bits) ((reg) |= (bits)) | ||
57 | #endif | 49 | #endif |
50 | #define GICBIS(reg, mask, bits) \ | ||
51 | do { u32 data; \ | ||
52 | GICREAD((reg), data); \ | ||
53 | data &= ~(mask); \ | ||
54 | data |= ((bits) & (mask)); \ | ||
55 | GICWRITE((reg), data); \ | ||
56 | } while (0) | ||
58 | 57 | ||
59 | 58 | ||
60 | /* GIC Address Space */ | 59 | /* GIC Address Space */ |
@@ -170,13 +169,15 @@ | |||
170 | #define GIC_SH_SET_POLARITY_OFS 0x0100 | 169 | #define GIC_SH_SET_POLARITY_OFS 0x0100 |
171 | #define GIC_SET_POLARITY(intr, pol) \ | 170 | #define GIC_SET_POLARITY(intr, pol) \ |
172 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \ | 171 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_POLARITY_OFS + \ |
173 | GIC_INTR_OFS(intr)), (pol) << GIC_INTR_BIT(intr)) | 172 | GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ |
173 | (pol) << GIC_INTR_BIT(intr)) | ||
174 | 174 | ||
175 | /* Triggering : Reset Value is always 0 */ | 175 | /* Triggering : Reset Value is always 0 */ |
176 | #define GIC_SH_SET_TRIGGER_OFS 0x0180 | 176 | #define GIC_SH_SET_TRIGGER_OFS 0x0180 |
177 | #define GIC_SET_TRIGGER(intr, trig) \ | 177 | #define GIC_SET_TRIGGER(intr, trig) \ |
178 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \ | 178 | GICBIS(GIC_REG_ADDR(SHARED, GIC_SH_SET_TRIGGER_OFS + \ |
179 | GIC_INTR_OFS(intr)), (trig) << GIC_INTR_BIT(intr)) | 179 | GIC_INTR_OFS(intr)), (1 << GIC_INTR_BIT(intr)), \ |
180 | (trig) << GIC_INTR_BIT(intr)) | ||
180 | 181 | ||
181 | /* Mask manipulation */ | 182 | /* Mask manipulation */ |
182 | #define GIC_SH_SMASK_OFS 0x0380 | 183 | #define GIC_SH_SMASK_OFS 0x0380 |
@@ -306,18 +307,6 @@ | |||
306 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \ | 307 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_VPE_REG_OFF(intr, vpe)), \ |
307 | GIC_SH_MAP_TO_VPE_REG_BIT(vpe)) | 308 | GIC_SH_MAP_TO_VPE_REG_BIT(vpe)) |
308 | 309 | ||
309 | struct gic_pcpu_mask { | ||
310 | DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS); | ||
311 | }; | ||
312 | |||
313 | struct gic_pending_regs { | ||
314 | DECLARE_BITMAP(pending, GIC_NUM_INTRS); | ||
315 | }; | ||
316 | |||
317 | struct gic_intrmask_regs { | ||
318 | DECLARE_BITMAP(intrmask, GIC_NUM_INTRS); | ||
319 | }; | ||
320 | |||
321 | /* | 310 | /* |
322 | * Interrupt Meta-data specification. The ipiflag helps | 311 | * Interrupt Meta-data specification. The ipiflag helps |
323 | * in building ipi_map. | 312 | * in building ipi_map. |
@@ -329,8 +318,7 @@ struct gic_intr_map { | |||
329 | unsigned int polarity; /* Polarity : +/- */ | 318 | unsigned int polarity; /* Polarity : +/- */ |
330 | unsigned int trigtype; /* Trigger : Edge/Levl */ | 319 | unsigned int trigtype; /* Trigger : Edge/Levl */ |
331 | unsigned int flags; /* Misc flags */ | 320 | unsigned int flags; /* Misc flags */ |
332 | #define GIC_FLAG_IPI 0x01 | 321 | #define GIC_FLAG_TRANSPARENT 0x01 |
333 | #define GIC_FLAG_TRANSPARENT 0x02 | ||
334 | }; | 322 | }; |
335 | 323 | ||
336 | /* | 324 | /* |
@@ -386,6 +374,7 @@ extern unsigned int plat_ipi_call_int_xlate(unsigned int); | |||
386 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); | 374 | extern unsigned int plat_ipi_resched_int_xlate(unsigned int); |
387 | extern void gic_bind_eic_interrupt(int irq, int set); | 375 | extern void gic_bind_eic_interrupt(int irq, int set); |
388 | extern unsigned int gic_get_timer_pending(void); | 376 | extern unsigned int gic_get_timer_pending(void); |
377 | extern void gic_get_int_mask(unsigned long *dst, const unsigned long *src); | ||
389 | extern unsigned int gic_get_int(void); | 378 | extern unsigned int gic_get_int(void); |
390 | extern void gic_enable_interrupt(int irq_vec); | 379 | extern void gic_enable_interrupt(int irq_vec); |
391 | extern void gic_disable_interrupt(int irq_vec); | 380 | extern void gic_disable_interrupt(int irq_vec); |
diff --git a/arch/mips/include/asm/maar.h b/arch/mips/include/asm/maar.h new file mode 100644 index 000000000000..6c62b0f899c0 --- /dev/null +++ b/arch/mips/include/asm/maar.h | |||
@@ -0,0 +1,109 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2014 Imagination Technologies | ||
3 | * Author: Paul Burton <paul.burton@imgtec.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License as published by the | ||
7 | * Free Software Foundation; either version 2 of the License, or (at your | ||
8 | * option) any later version. | ||
9 | */ | ||
10 | |||
11 | #ifndef __MIPS_ASM_MIPS_MAAR_H__ | ||
12 | #define __MIPS_ASM_MIPS_MAAR_H__ | ||
13 | |||
14 | #include <asm/hazards.h> | ||
15 | #include <asm/mipsregs.h> | ||
16 | |||
17 | /** | ||
18 | * platform_maar_init() - perform platform-level MAAR configuration | ||
19 | * @num_pairs: The number of MAAR pairs present in the system. | ||
20 | * | ||
21 | * Platforms should implement this function such that it configures as many | ||
22 | * MAAR pairs as required, from 0 up to the maximum of num_pairs-1, and returns | ||
23 | * the number that were used. Any further MAARs will be configured to be | ||
24 | * invalid. The default implementation of this function will simply indicate | ||
25 | * that it has configured 0 MAAR pairs. | ||
26 | * | ||
27 | * Return: The number of MAAR pairs configured. | ||
28 | */ | ||
29 | unsigned __weak platform_maar_init(unsigned num_pairs); | ||
30 | |||
31 | /** | ||
32 | * write_maar_pair() - write to a pair of MAARs | ||
33 | * @idx: The index of the pair (ie. use MAARs idx*2 & (idx*2)+1). | ||
34 | * @lower: The lowest address that the MAAR pair will affect. Must be | ||
35 | * aligned to a 2^16 byte boundary. | ||
36 | * @upper: The highest address that the MAAR pair will affect. Must be | ||
37 | * aligned to one byte before a 2^16 byte boundary. | ||
38 | * @attrs: The accessibility attributes to program, eg. MIPS_MAAR_S. The | ||
39 | * MIPS_MAAR_V attribute will automatically be set. | ||
40 | * | ||
41 | * Program the pair of MAAR registers specified by idx to apply the attributes | ||
42 | * specified by attrs to the range of addresses from lower to higher. | ||
43 | */ | ||
44 | static inline void write_maar_pair(unsigned idx, phys_addr_t lower, | ||
45 | phys_addr_t upper, unsigned attrs) | ||
46 | { | ||
47 | /* Addresses begin at bit 16, but are shifted right 4 bits */ | ||
48 | BUG_ON(lower & (0xffff | ~(MIPS_MAAR_ADDR << 4))); | ||
49 | BUG_ON(((upper & 0xffff) != 0xffff) | ||
50 | || ((upper & ~0xffffull) & ~(MIPS_MAAR_ADDR << 4))); | ||
51 | |||
52 | /* Automatically set MIPS_MAAR_V */ | ||
53 | attrs |= MIPS_MAAR_V; | ||
54 | |||
55 | /* Write the upper address & attributes (only MIPS_MAAR_V matters) */ | ||
56 | write_c0_maari(idx << 1); | ||
57 | back_to_back_c0_hazard(); | ||
58 | write_c0_maar(((upper >> 4) & MIPS_MAAR_ADDR) | attrs); | ||
59 | back_to_back_c0_hazard(); | ||
60 | |||
61 | /* Write the lower address & attributes */ | ||
62 | write_c0_maari((idx << 1) | 0x1); | ||
63 | back_to_back_c0_hazard(); | ||
64 | write_c0_maar((lower >> 4) | attrs); | ||
65 | back_to_back_c0_hazard(); | ||
66 | } | ||
67 | |||
68 | /** | ||
69 | * struct maar_config - MAAR configuration data | ||
70 | * @lower: The lowest address that the MAAR pair will affect. Must be | ||
71 | * aligned to a 2^16 byte boundary. | ||
72 | * @upper: The highest address that the MAAR pair will affect. Must be | ||
73 | * aligned to one byte before a 2^16 byte boundary. | ||
74 | * @attrs: The accessibility attributes to program, eg. MIPS_MAAR_S. The | ||
75 | * MIPS_MAAR_V attribute will automatically be set. | ||
76 | * | ||
77 | * Describes the configuration of a pair of Memory Accessibility Attribute | ||
78 | * Registers - applying attributes from attrs to the range of physical | ||
79 | * addresses from lower to upper inclusive. | ||
80 | */ | ||
81 | struct maar_config { | ||
82 | phys_addr_t lower; | ||
83 | phys_addr_t upper; | ||
84 | unsigned attrs; | ||
85 | }; | ||
86 | |||
87 | /** | ||
88 | * maar_config() - configure MAARs according to provided data | ||
89 | * @cfg: Pointer to an array of struct maar_config. | ||
90 | * @num_cfg: The number of structs in the cfg array. | ||
91 | * @num_pairs: The number of MAAR pairs present in the system. | ||
92 | * | ||
93 | * Configures as many MAARs as are present and specified in the cfg | ||
94 | * array with the values taken from the cfg array. | ||
95 | * | ||
96 | * Return: The number of MAAR pairs configured. | ||
97 | */ | ||
98 | static inline unsigned maar_config(const struct maar_config *cfg, | ||
99 | unsigned num_cfg, unsigned num_pairs) | ||
100 | { | ||
101 | unsigned i; | ||
102 | |||
103 | for (i = 0; i < min(num_cfg, num_pairs); i++) | ||
104 | write_maar_pair(i, cfg[i].lower, cfg[i].upper, cfg[i].attrs); | ||
105 | |||
106 | return i; | ||
107 | } | ||
108 | |||
109 | #endif /* __MIPS_ASM_MIPS_MAAR_H__ */ | ||
diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h index b4c3ecb17d48..a7eec3364a64 100644 --- a/arch/mips/include/asm/mach-au1x00/au1000.h +++ b/arch/mips/include/asm/mach-au1x00/au1000.h | |||
@@ -34,6 +34,558 @@ | |||
34 | #ifndef _AU1000_H_ | 34 | #ifndef _AU1000_H_ |
35 | #define _AU1000_H_ | 35 | #define _AU1000_H_ |
36 | 36 | ||
37 | /* SOC Interrupt numbers */ | ||
38 | /* Au1000-style (IC0/1): 2 controllers with 32 sources each */ | ||
39 | #define AU1000_INTC0_INT_BASE (MIPS_CPU_IRQ_BASE + 8) | ||
40 | #define AU1000_INTC0_INT_LAST (AU1000_INTC0_INT_BASE + 31) | ||
41 | #define AU1000_INTC1_INT_BASE (AU1000_INTC0_INT_LAST + 1) | ||
42 | #define AU1000_INTC1_INT_LAST (AU1000_INTC1_INT_BASE + 31) | ||
43 | #define AU1000_MAX_INTR AU1000_INTC1_INT_LAST | ||
44 | |||
45 | /* Au1300-style (GPIC): 1 controller with up to 128 sources */ | ||
46 | #define ALCHEMY_GPIC_INT_BASE (MIPS_CPU_IRQ_BASE + 8) | ||
47 | #define ALCHEMY_GPIC_INT_NUM 128 | ||
48 | #define ALCHEMY_GPIC_INT_LAST (ALCHEMY_GPIC_INT_BASE + ALCHEMY_GPIC_INT_NUM - 1) | ||
49 | |||
50 | /* common clock names, shared among all variants. AUXPLL2 is Au1300 */ | ||
51 | #define ALCHEMY_ROOT_CLK "root_clk" | ||
52 | #define ALCHEMY_CPU_CLK "cpu_clk" | ||
53 | #define ALCHEMY_AUXPLL_CLK "auxpll_clk" | ||
54 | #define ALCHEMY_AUXPLL2_CLK "auxpll2_clk" | ||
55 | #define ALCHEMY_SYSBUS_CLK "sysbus_clk" | ||
56 | #define ALCHEMY_PERIPH_CLK "periph_clk" | ||
57 | #define ALCHEMY_MEM_CLK "mem_clk" | ||
58 | #define ALCHEMY_LR_CLK "lr_clk" | ||
59 | #define ALCHEMY_FG0_CLK "fg0_clk" | ||
60 | #define ALCHEMY_FG1_CLK "fg1_clk" | ||
61 | #define ALCHEMY_FG2_CLK "fg2_clk" | ||
62 | #define ALCHEMY_FG3_CLK "fg3_clk" | ||
63 | #define ALCHEMY_FG4_CLK "fg4_clk" | ||
64 | #define ALCHEMY_FG5_CLK "fg5_clk" | ||
65 | |||
66 | /* Au1300 peripheral interrupt numbers */ | ||
67 | #define AU1300_FIRST_INT (ALCHEMY_GPIC_INT_BASE) | ||
68 | #define AU1300_UART1_INT (AU1300_FIRST_INT + 17) | ||
69 | #define AU1300_UART2_INT (AU1300_FIRST_INT + 25) | ||
70 | #define AU1300_UART3_INT (AU1300_FIRST_INT + 27) | ||
71 | #define AU1300_SD1_INT (AU1300_FIRST_INT + 32) | ||
72 | #define AU1300_SD2_INT (AU1300_FIRST_INT + 38) | ||
73 | #define AU1300_PSC0_INT (AU1300_FIRST_INT + 48) | ||
74 | #define AU1300_PSC1_INT (AU1300_FIRST_INT + 52) | ||
75 | #define AU1300_PSC2_INT (AU1300_FIRST_INT + 56) | ||
76 | #define AU1300_PSC3_INT (AU1300_FIRST_INT + 60) | ||
77 | #define AU1300_NAND_INT (AU1300_FIRST_INT + 62) | ||
78 | #define AU1300_DDMA_INT (AU1300_FIRST_INT + 75) | ||
79 | #define AU1300_MMU_INT (AU1300_FIRST_INT + 76) | ||
80 | #define AU1300_MPU_INT (AU1300_FIRST_INT + 77) | ||
81 | #define AU1300_GPU_INT (AU1300_FIRST_INT + 78) | ||
82 | #define AU1300_UDMA_INT (AU1300_FIRST_INT + 79) | ||
83 | #define AU1300_TOY_INT (AU1300_FIRST_INT + 80) | ||
84 | #define AU1300_TOY_MATCH0_INT (AU1300_FIRST_INT + 81) | ||
85 | #define AU1300_TOY_MATCH1_INT (AU1300_FIRST_INT + 82) | ||
86 | #define AU1300_TOY_MATCH2_INT (AU1300_FIRST_INT + 83) | ||
87 | #define AU1300_RTC_INT (AU1300_FIRST_INT + 84) | ||
88 | #define AU1300_RTC_MATCH0_INT (AU1300_FIRST_INT + 85) | ||
89 | #define AU1300_RTC_MATCH1_INT (AU1300_FIRST_INT + 86) | ||
90 | #define AU1300_RTC_MATCH2_INT (AU1300_FIRST_INT + 87) | ||
91 | #define AU1300_UART0_INT (AU1300_FIRST_INT + 88) | ||
92 | #define AU1300_SD0_INT (AU1300_FIRST_INT + 89) | ||
93 | #define AU1300_USB_INT (AU1300_FIRST_INT + 90) | ||
94 | #define AU1300_LCD_INT (AU1300_FIRST_INT + 91) | ||
95 | #define AU1300_BSA_INT (AU1300_FIRST_INT + 92) | ||
96 | #define AU1300_MPE_INT (AU1300_FIRST_INT + 93) | ||
97 | #define AU1300_ITE_INT (AU1300_FIRST_INT + 94) | ||
98 | #define AU1300_AES_INT (AU1300_FIRST_INT + 95) | ||
99 | #define AU1300_CIM_INT (AU1300_FIRST_INT + 96) | ||
100 | |||
101 | /**********************************************************************/ | ||
102 | |||
103 | /* | ||
104 | * Physical base addresses for integrated peripherals | ||
105 | * 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200 5..au1300 | ||
106 | */ | ||
107 | |||
108 | #define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */ | ||
109 | #define AU1300_ROM_PHYS_ADDR 0x10000000 /* 5 */ | ||
110 | #define AU1300_OTP_PHYS_ADDR 0x10002000 /* 5 */ | ||
111 | #define AU1300_VSS_PHYS_ADDR 0x10003000 /* 5 */ | ||
112 | #define AU1300_UART0_PHYS_ADDR 0x10100000 /* 5 */ | ||
113 | #define AU1300_UART1_PHYS_ADDR 0x10101000 /* 5 */ | ||
114 | #define AU1300_UART2_PHYS_ADDR 0x10102000 /* 5 */ | ||
115 | #define AU1300_UART3_PHYS_ADDR 0x10103000 /* 5 */ | ||
116 | #define AU1000_USB_OHCI_PHYS_ADDR 0x10100000 /* 012 */ | ||
117 | #define AU1000_USB_UDC_PHYS_ADDR 0x10200000 /* 0123 */ | ||
118 | #define AU1300_GPIC_PHYS_ADDR 0x10200000 /* 5 */ | ||
119 | #define AU1000_IRDA_PHYS_ADDR 0x10300000 /* 02 */ | ||
120 | #define AU1200_AES_PHYS_ADDR 0x10300000 /* 45 */ | ||
121 | #define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */ | ||
122 | #define AU1300_GPU_PHYS_ADDR 0x10500000 /* 5 */ | ||
123 | #define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */ | ||
124 | #define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */ | ||
125 | #define AU1000_MACEN_PHYS_ADDR 0x10520000 /* 023 */ | ||
126 | #define AU1100_SD0_PHYS_ADDR 0x10600000 /* 245 */ | ||
127 | #define AU1300_SD1_PHYS_ADDR 0x10601000 /* 5 */ | ||
128 | #define AU1300_SD2_PHYS_ADDR 0x10602000 /* 5 */ | ||
129 | #define AU1100_SD1_PHYS_ADDR 0x10680000 /* 24 */ | ||
130 | #define AU1300_SYS_PHYS_ADDR 0x10900000 /* 5 */ | ||
131 | #define AU1550_PSC2_PHYS_ADDR 0x10A00000 /* 3 */ | ||
132 | #define AU1550_PSC3_PHYS_ADDR 0x10B00000 /* 3 */ | ||
133 | #define AU1300_PSC0_PHYS_ADDR 0x10A00000 /* 5 */ | ||
134 | #define AU1300_PSC1_PHYS_ADDR 0x10A01000 /* 5 */ | ||
135 | #define AU1300_PSC2_PHYS_ADDR 0x10A02000 /* 5 */ | ||
136 | #define AU1300_PSC3_PHYS_ADDR 0x10A03000 /* 5 */ | ||
137 | #define AU1000_I2S_PHYS_ADDR 0x11000000 /* 02 */ | ||
138 | #define AU1500_MAC0_PHYS_ADDR 0x11500000 /* 1 */ | ||
139 | #define AU1500_MAC1_PHYS_ADDR 0x11510000 /* 1 */ | ||
140 | #define AU1500_MACEN_PHYS_ADDR 0x11520000 /* 1 */ | ||
141 | #define AU1000_UART0_PHYS_ADDR 0x11100000 /* 01234 */ | ||
142 | #define AU1200_SWCNT_PHYS_ADDR 0x1110010C /* 4 */ | ||
143 | #define AU1000_UART1_PHYS_ADDR 0x11200000 /* 0234 */ | ||
144 | #define AU1000_UART2_PHYS_ADDR 0x11300000 /* 0 */ | ||
145 | #define AU1000_UART3_PHYS_ADDR 0x11400000 /* 0123 */ | ||
146 | #define AU1000_SSI0_PHYS_ADDR 0x11600000 /* 02 */ | ||
147 | #define AU1000_SSI1_PHYS_ADDR 0x11680000 /* 02 */ | ||
148 | #define AU1500_GPIO2_PHYS_ADDR 0x11700000 /* 1234 */ | ||
149 | #define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */ | ||
150 | #define AU1000_SYS_PHYS_ADDR 0x11900000 /* 012345 */ | ||
151 | #define AU1550_PSC0_PHYS_ADDR 0x11A00000 /* 34 */ | ||
152 | #define AU1550_PSC1_PHYS_ADDR 0x11B00000 /* 34 */ | ||
153 | #define AU1000_MEM_PHYS_ADDR 0x14000000 /* 01234 */ | ||
154 | #define AU1000_STATIC_MEM_PHYS_ADDR 0x14001000 /* 01234 */ | ||
155 | #define AU1300_UDMA_PHYS_ADDR 0x14001800 /* 5 */ | ||
156 | #define AU1000_DMA_PHYS_ADDR 0x14002000 /* 012 */ | ||
157 | #define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 345 */ | ||
158 | #define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 345 */ | ||
159 | #define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */ | ||
160 | #define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */ | ||
161 | #define AU1200_CIM_PHYS_ADDR 0x14004000 /* 45 */ | ||
162 | #define AU1500_PCI_PHYS_ADDR 0x14005000 /* 13 */ | ||
163 | #define AU1550_PE_PHYS_ADDR 0x14008000 /* 3 */ | ||
164 | #define AU1200_MAEBE_PHYS_ADDR 0x14010000 /* 4 */ | ||
165 | #define AU1200_MAEFE_PHYS_ADDR 0x14012000 /* 4 */ | ||
166 | #define AU1300_MAEITE_PHYS_ADDR 0x14010000 /* 5 */ | ||
167 | #define AU1300_MAEMPE_PHYS_ADDR 0x14014000 /* 5 */ | ||
168 | #define AU1550_USB_OHCI_PHYS_ADDR 0x14020000 /* 3 */ | ||
169 | #define AU1200_USB_CTL_PHYS_ADDR 0x14020000 /* 4 */ | ||
170 | #define AU1200_USB_OTG_PHYS_ADDR 0x14020020 /* 4 */ | ||
171 | #define AU1200_USB_OHCI_PHYS_ADDR 0x14020100 /* 4 */ | ||
172 | #define AU1200_USB_EHCI_PHYS_ADDR 0x14020200 /* 4 */ | ||
173 | #define AU1200_USB_UDC_PHYS_ADDR 0x14022000 /* 4 */ | ||
174 | #define AU1300_USB_EHCI_PHYS_ADDR 0x14020000 /* 5 */ | ||
175 | #define AU1300_USB_OHCI0_PHYS_ADDR 0x14020400 /* 5 */ | ||
176 | #define AU1300_USB_OHCI1_PHYS_ADDR 0x14020800 /* 5 */ | ||
177 | #define AU1300_USB_CTL_PHYS_ADDR 0x14021000 /* 5 */ | ||
178 | #define AU1300_USB_OTG_PHYS_ADDR 0x14022000 /* 5 */ | ||
179 | #define AU1300_MAEBSA_PHYS_ADDR 0x14030000 /* 5 */ | ||
180 | #define AU1100_LCD_PHYS_ADDR 0x15000000 /* 2 */ | ||
181 | #define AU1200_LCD_PHYS_ADDR 0x15000000 /* 45 */ | ||
182 | #define AU1500_PCI_MEM_PHYS_ADDR 0x400000000ULL /* 13 */ | ||
183 | #define AU1500_PCI_IO_PHYS_ADDR 0x500000000ULL /* 13 */ | ||
184 | #define AU1500_PCI_CONFIG0_PHYS_ADDR 0x600000000ULL /* 13 */ | ||
185 | #define AU1500_PCI_CONFIG1_PHYS_ADDR 0x680000000ULL /* 13 */ | ||
186 | #define AU1000_PCMCIA_IO_PHYS_ADDR 0xF00000000ULL /* 012345 */ | ||
187 | #define AU1000_PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL /* 012345 */ | ||
188 | #define AU1000_PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL /* 012345 */ | ||
189 | |||
190 | /**********************************************************************/ | ||
191 | |||
192 | |||
193 | /* | ||
194 | * Au1300 GPIO+INT controller (GPIC) register offsets and bits | ||
195 | * Registers are 128bits (0x10 bytes), divided into 4 "banks". | ||
196 | */ | ||
197 | #define AU1300_GPIC_PINVAL 0x0000 | ||
198 | #define AU1300_GPIC_PINVALCLR 0x0010 | ||
199 | #define AU1300_GPIC_IPEND 0x0020 | ||
200 | #define AU1300_GPIC_PRIENC 0x0030 | ||
201 | #define AU1300_GPIC_IEN 0x0040 /* int_mask in manual */ | ||
202 | #define AU1300_GPIC_IDIS 0x0050 /* int_maskclr in manual */ | ||
203 | #define AU1300_GPIC_DMASEL 0x0060 | ||
204 | #define AU1300_GPIC_DEVSEL 0x0080 | ||
205 | #define AU1300_GPIC_DEVCLR 0x0090 | ||
206 | #define AU1300_GPIC_RSTVAL 0x00a0 | ||
207 | /* pin configuration space. one 32bit register for up to 128 IRQs */ | ||
208 | #define AU1300_GPIC_PINCFG 0x1000 | ||
209 | |||
210 | #define GPIC_GPIO_TO_BIT(gpio) \ | ||
211 | (1 << ((gpio) & 0x1f)) | ||
212 | |||
213 | #define GPIC_GPIO_BANKOFF(gpio) \ | ||
214 | (((gpio) >> 5) * 4) | ||
215 | |||
216 | /* Pin Control bits: who owns the pin, what does it do */ | ||
217 | #define GPIC_CFG_PC_GPIN 0 | ||
218 | #define GPIC_CFG_PC_DEV 1 | ||
219 | #define GPIC_CFG_PC_GPOLOW 2 | ||
220 | #define GPIC_CFG_PC_GPOHIGH 3 | ||
221 | #define GPIC_CFG_PC_MASK 3 | ||
222 | |||
223 | /* assign pin to MIPS IRQ line */ | ||
224 | #define GPIC_CFG_IL_SET(x) (((x) & 3) << 2) | ||
225 | #define GPIC_CFG_IL_MASK (3 << 2) | ||
226 | |||
227 | /* pin interrupt type setup */ | ||
228 | #define GPIC_CFG_IC_OFF (0 << 4) | ||
229 | #define GPIC_CFG_IC_LEVEL_LOW (1 << 4) | ||
230 | #define GPIC_CFG_IC_LEVEL_HIGH (2 << 4) | ||
231 | #define GPIC_CFG_IC_EDGE_FALL (5 << 4) | ||
232 | #define GPIC_CFG_IC_EDGE_RISE (6 << 4) | ||
233 | #define GPIC_CFG_IC_EDGE_BOTH (7 << 4) | ||
234 | #define GPIC_CFG_IC_MASK (7 << 4) | ||
235 | |||
236 | /* allow interrupt to wake cpu from 'wait' */ | ||
237 | #define GPIC_CFG_IDLEWAKE (1 << 7) | ||
238 | |||
239 | /***********************************************************************/ | ||
240 | |||
241 | /* Au1000 SDRAM memory controller register offsets */ | ||
242 | #define AU1000_MEM_SDMODE0 0x0000 | ||
243 | #define AU1000_MEM_SDMODE1 0x0004 | ||
244 | #define AU1000_MEM_SDMODE2 0x0008 | ||
245 | #define AU1000_MEM_SDADDR0 0x000C | ||
246 | #define AU1000_MEM_SDADDR1 0x0010 | ||
247 | #define AU1000_MEM_SDADDR2 0x0014 | ||
248 | #define AU1000_MEM_SDREFCFG 0x0018 | ||
249 | #define AU1000_MEM_SDPRECMD 0x001C | ||
250 | #define AU1000_MEM_SDAUTOREF 0x0020 | ||
251 | #define AU1000_MEM_SDWRMD0 0x0024 | ||
252 | #define AU1000_MEM_SDWRMD1 0x0028 | ||
253 | #define AU1000_MEM_SDWRMD2 0x002C | ||
254 | #define AU1000_MEM_SDSLEEP 0x0030 | ||
255 | #define AU1000_MEM_SDSMCKE 0x0034 | ||
256 | |||
257 | /* MEM_SDMODE register content definitions */ | ||
258 | #define MEM_SDMODE_F (1 << 22) | ||
259 | #define MEM_SDMODE_SR (1 << 21) | ||
260 | #define MEM_SDMODE_BS (1 << 20) | ||
261 | #define MEM_SDMODE_RS (3 << 18) | ||
262 | #define MEM_SDMODE_CS (7 << 15) | ||
263 | #define MEM_SDMODE_TRAS (15 << 11) | ||
264 | #define MEM_SDMODE_TMRD (3 << 9) | ||
265 | #define MEM_SDMODE_TWR (3 << 7) | ||
266 | #define MEM_SDMODE_TRP (3 << 5) | ||
267 | #define MEM_SDMODE_TRCD (3 << 3) | ||
268 | #define MEM_SDMODE_TCL (7 << 0) | ||
269 | |||
270 | #define MEM_SDMODE_BS_2Bank (0 << 20) | ||
271 | #define MEM_SDMODE_BS_4Bank (1 << 20) | ||
272 | #define MEM_SDMODE_RS_11Row (0 << 18) | ||
273 | #define MEM_SDMODE_RS_12Row (1 << 18) | ||
274 | #define MEM_SDMODE_RS_13Row (2 << 18) | ||
275 | #define MEM_SDMODE_RS_N(N) ((N) << 18) | ||
276 | #define MEM_SDMODE_CS_7Col (0 << 15) | ||
277 | #define MEM_SDMODE_CS_8Col (1 << 15) | ||
278 | #define MEM_SDMODE_CS_9Col (2 << 15) | ||
279 | #define MEM_SDMODE_CS_10Col (3 << 15) | ||
280 | #define MEM_SDMODE_CS_11Col (4 << 15) | ||
281 | #define MEM_SDMODE_CS_N(N) ((N) << 15) | ||
282 | #define MEM_SDMODE_TRAS_N(N) ((N) << 11) | ||
283 | #define MEM_SDMODE_TMRD_N(N) ((N) << 9) | ||
284 | #define MEM_SDMODE_TWR_N(N) ((N) << 7) | ||
285 | #define MEM_SDMODE_TRP_N(N) ((N) << 5) | ||
286 | #define MEM_SDMODE_TRCD_N(N) ((N) << 3) | ||
287 | #define MEM_SDMODE_TCL_N(N) ((N) << 0) | ||
288 | |||
289 | /* MEM_SDADDR register contents definitions */ | ||
290 | #define MEM_SDADDR_E (1 << 20) | ||
291 | #define MEM_SDADDR_CSBA (0x03FF << 10) | ||
292 | #define MEM_SDADDR_CSMASK (0x03FF << 0) | ||
293 | #define MEM_SDADDR_CSBA_N(N) ((N) & (0x03FF << 22) >> 12) | ||
294 | #define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF << 22) >> 22) | ||
295 | |||
296 | /* MEM_SDREFCFG register content definitions */ | ||
297 | #define MEM_SDREFCFG_TRC (15 << 28) | ||
298 | #define MEM_SDREFCFG_TRPM (3 << 26) | ||
299 | #define MEM_SDREFCFG_E (1 << 25) | ||
300 | #define MEM_SDREFCFG_RE (0x1ffffff << 0) | ||
301 | #define MEM_SDREFCFG_TRC_N(N) ((N) << MEM_SDREFCFG_TRC) | ||
302 | #define MEM_SDREFCFG_TRPM_N(N) ((N) << MEM_SDREFCFG_TRPM) | ||
303 | #define MEM_SDREFCFG_REF_N(N) (N) | ||
304 | |||
305 | /* Au1550 SDRAM Register Offsets */ | ||
306 | #define AU1550_MEM_SDMODE0 0x0800 | ||
307 | #define AU1550_MEM_SDMODE1 0x0808 | ||
308 | #define AU1550_MEM_SDMODE2 0x0810 | ||
309 | #define AU1550_MEM_SDADDR0 0x0820 | ||
310 | #define AU1550_MEM_SDADDR1 0x0828 | ||
311 | #define AU1550_MEM_SDADDR2 0x0830 | ||
312 | #define AU1550_MEM_SDCONFIGA 0x0840 | ||
313 | #define AU1550_MEM_SDCONFIGB 0x0848 | ||
314 | #define AU1550_MEM_SDSTAT 0x0850 | ||
315 | #define AU1550_MEM_SDERRADDR 0x0858 | ||
316 | #define AU1550_MEM_SDSTRIDE0 0x0860 | ||
317 | #define AU1550_MEM_SDSTRIDE1 0x0868 | ||
318 | #define AU1550_MEM_SDSTRIDE2 0x0870 | ||
319 | #define AU1550_MEM_SDWRMD0 0x0880 | ||
320 | #define AU1550_MEM_SDWRMD1 0x0888 | ||
321 | #define AU1550_MEM_SDWRMD2 0x0890 | ||
322 | #define AU1550_MEM_SDPRECMD 0x08C0 | ||
323 | #define AU1550_MEM_SDAUTOREF 0x08C8 | ||
324 | #define AU1550_MEM_SDSREF 0x08D0 | ||
325 | #define AU1550_MEM_SDSLEEP MEM_SDSREF | ||
326 | |||
327 | /* Static Bus Controller register offsets */ | ||
328 | #define AU1000_MEM_STCFG0 0x000 | ||
329 | #define AU1000_MEM_STTIME0 0x004 | ||
330 | #define AU1000_MEM_STADDR0 0x008 | ||
331 | #define AU1000_MEM_STCFG1 0x010 | ||
332 | #define AU1000_MEM_STTIME1 0x014 | ||
333 | #define AU1000_MEM_STADDR1 0x018 | ||
334 | #define AU1000_MEM_STCFG2 0x020 | ||
335 | #define AU1000_MEM_STTIME2 0x024 | ||
336 | #define AU1000_MEM_STADDR2 0x028 | ||
337 | #define AU1000_MEM_STCFG3 0x030 | ||
338 | #define AU1000_MEM_STTIME3 0x034 | ||
339 | #define AU1000_MEM_STADDR3 0x038 | ||
340 | #define AU1000_MEM_STNDCTL 0x100 | ||
341 | #define AU1000_MEM_STSTAT 0x104 | ||
342 | |||
343 | #define MEM_STNAND_CMD 0x0 | ||
344 | #define MEM_STNAND_ADDR 0x4 | ||
345 | #define MEM_STNAND_DATA 0x20 | ||
346 | |||
347 | |||
348 | /* Programmable Counters 0 and 1 */ | ||
349 | #define AU1000_SYS_CNTRCTRL 0x14 | ||
350 | # define SYS_CNTRL_E1S (1 << 23) | ||
351 | # define SYS_CNTRL_T1S (1 << 20) | ||
352 | # define SYS_CNTRL_M21 (1 << 19) | ||
353 | # define SYS_CNTRL_M11 (1 << 18) | ||
354 | # define SYS_CNTRL_M01 (1 << 17) | ||
355 | # define SYS_CNTRL_C1S (1 << 16) | ||
356 | # define SYS_CNTRL_BP (1 << 14) | ||
357 | # define SYS_CNTRL_EN1 (1 << 13) | ||
358 | # define SYS_CNTRL_BT1 (1 << 12) | ||
359 | # define SYS_CNTRL_EN0 (1 << 11) | ||
360 | # define SYS_CNTRL_BT0 (1 << 10) | ||
361 | # define SYS_CNTRL_E0 (1 << 8) | ||
362 | # define SYS_CNTRL_E0S (1 << 7) | ||
363 | # define SYS_CNTRL_32S (1 << 5) | ||
364 | # define SYS_CNTRL_T0S (1 << 4) | ||
365 | # define SYS_CNTRL_M20 (1 << 3) | ||
366 | # define SYS_CNTRL_M10 (1 << 2) | ||
367 | # define SYS_CNTRL_M00 (1 << 1) | ||
368 | # define SYS_CNTRL_C0S (1 << 0) | ||
369 | |||
370 | /* Programmable Counter 0 Registers */ | ||
371 | #define AU1000_SYS_TOYTRIM 0x00 | ||
372 | #define AU1000_SYS_TOYWRITE 0x04 | ||
373 | #define AU1000_SYS_TOYMATCH0 0x08 | ||
374 | #define AU1000_SYS_TOYMATCH1 0x0c | ||
375 | #define AU1000_SYS_TOYMATCH2 0x10 | ||
376 | #define AU1000_SYS_TOYREAD 0x40 | ||
377 | |||
378 | /* Programmable Counter 1 Registers */ | ||
379 | #define AU1000_SYS_RTCTRIM 0x44 | ||
380 | #define AU1000_SYS_RTCWRITE 0x48 | ||
381 | #define AU1000_SYS_RTCMATCH0 0x4c | ||
382 | #define AU1000_SYS_RTCMATCH1 0x50 | ||
383 | #define AU1000_SYS_RTCMATCH2 0x54 | ||
384 | #define AU1000_SYS_RTCREAD 0x58 | ||
385 | |||
386 | |||
387 | /* GPIO */ | ||
388 | #define AU1000_SYS_PINFUNC 0x2C | ||
389 | # define SYS_PF_USB (1 << 15) /* 2nd USB device/host */ | ||
390 | # define SYS_PF_U3 (1 << 14) /* GPIO23/U3TXD */ | ||
391 | # define SYS_PF_U2 (1 << 13) /* GPIO22/U2TXD */ | ||
392 | # define SYS_PF_U1 (1 << 12) /* GPIO21/U1TXD */ | ||
393 | # define SYS_PF_SRC (1 << 11) /* GPIO6/SROMCKE */ | ||
394 | # define SYS_PF_CK5 (1 << 10) /* GPIO3/CLK5 */ | ||
395 | # define SYS_PF_CK4 (1 << 9) /* GPIO2/CLK4 */ | ||
396 | # define SYS_PF_IRF (1 << 8) /* GPIO15/IRFIRSEL */ | ||
397 | # define SYS_PF_UR3 (1 << 7) /* GPIO[14:9]/UART3 */ | ||
398 | # define SYS_PF_I2D (1 << 6) /* GPIO8/I2SDI */ | ||
399 | # define SYS_PF_I2S (1 << 5) /* I2S/GPIO[29:31] */ | ||
400 | # define SYS_PF_NI2 (1 << 4) /* NI2/GPIO[24:28] */ | ||
401 | # define SYS_PF_U0 (1 << 3) /* U0TXD/GPIO20 */ | ||
402 | # define SYS_PF_RD (1 << 2) /* IRTXD/GPIO19 */ | ||
403 | # define SYS_PF_A97 (1 << 1) /* AC97/SSL1 */ | ||
404 | # define SYS_PF_S0 (1 << 0) /* SSI_0/GPIO[16:18] */ | ||
405 | |||
406 | /* Au1100 only */ | ||
407 | # define SYS_PF_PC (1 << 18) /* PCMCIA/GPIO[207:204] */ | ||
408 | # define SYS_PF_LCD (1 << 17) /* extern lcd/GPIO[203:200] */ | ||
409 | # define SYS_PF_CS (1 << 16) /* EXTCLK0/32KHz to gpio2 */ | ||
410 | # define SYS_PF_EX0 (1 << 9) /* GPIO2/clock */ | ||
411 | |||
412 | /* Au1550 only. Redefines lots of pins */ | ||
413 | # define SYS_PF_PSC2_MASK (7 << 17) | ||
414 | # define SYS_PF_PSC2_AC97 0 | ||
415 | # define SYS_PF_PSC2_SPI 0 | ||
416 | # define SYS_PF_PSC2_I2S (1 << 17) | ||
417 | # define SYS_PF_PSC2_SMBUS (3 << 17) | ||
418 | # define SYS_PF_PSC2_GPIO (7 << 17) | ||
419 | # define SYS_PF_PSC3_MASK (7 << 20) | ||
420 | # define SYS_PF_PSC3_AC97 0 | ||
421 | # define SYS_PF_PSC3_SPI 0 | ||
422 | # define SYS_PF_PSC3_I2S (1 << 20) | ||
423 | # define SYS_PF_PSC3_SMBUS (3 << 20) | ||
424 | # define SYS_PF_PSC3_GPIO (7 << 20) | ||
425 | # define SYS_PF_PSC1_S1 (1 << 1) | ||
426 | # define SYS_PF_MUST_BE_SET ((1 << 5) | (1 << 2)) | ||
427 | |||
428 | /* Au1200 only */ | ||
429 | #define SYS_PINFUNC_DMA (1 << 31) | ||
430 | #define SYS_PINFUNC_S0A (1 << 30) | ||
431 | #define SYS_PINFUNC_S1A (1 << 29) | ||
432 | #define SYS_PINFUNC_LP0 (1 << 28) | ||
433 | #define SYS_PINFUNC_LP1 (1 << 27) | ||
434 | #define SYS_PINFUNC_LD16 (1 << 26) | ||
435 | #define SYS_PINFUNC_LD8 (1 << 25) | ||
436 | #define SYS_PINFUNC_LD1 (1 << 24) | ||
437 | #define SYS_PINFUNC_LD0 (1 << 23) | ||
438 | #define SYS_PINFUNC_P1A (3 << 21) | ||
439 | #define SYS_PINFUNC_P1B (1 << 20) | ||
440 | #define SYS_PINFUNC_FS3 (1 << 19) | ||
441 | #define SYS_PINFUNC_P0A (3 << 17) | ||
442 | #define SYS_PINFUNC_CS (1 << 16) | ||
443 | #define SYS_PINFUNC_CIM (1 << 15) | ||
444 | #define SYS_PINFUNC_P1C (1 << 14) | ||
445 | #define SYS_PINFUNC_U1T (1 << 12) | ||
446 | #define SYS_PINFUNC_U1R (1 << 11) | ||
447 | #define SYS_PINFUNC_EX1 (1 << 10) | ||
448 | #define SYS_PINFUNC_EX0 (1 << 9) | ||
449 | #define SYS_PINFUNC_U0R (1 << 8) | ||
450 | #define SYS_PINFUNC_MC (1 << 7) | ||
451 | #define SYS_PINFUNC_S0B (1 << 6) | ||
452 | #define SYS_PINFUNC_S0C (1 << 5) | ||
453 | #define SYS_PINFUNC_P0B (1 << 4) | ||
454 | #define SYS_PINFUNC_U0T (1 << 3) | ||
455 | #define SYS_PINFUNC_S1B (1 << 2) | ||
456 | |||
457 | /* Power Management */ | ||
458 | #define AU1000_SYS_SCRATCH0 0x18 | ||
459 | #define AU1000_SYS_SCRATCH1 0x1c | ||
460 | #define AU1000_SYS_WAKEMSK 0x34 | ||
461 | #define AU1000_SYS_ENDIAN 0x38 | ||
462 | #define AU1000_SYS_POWERCTRL 0x3c | ||
463 | #define AU1000_SYS_WAKESRC 0x5c | ||
464 | #define AU1000_SYS_SLPPWR 0x78 | ||
465 | #define AU1000_SYS_SLEEP 0x7c | ||
466 | |||
467 | #define SYS_WAKEMSK_D2 (1 << 9) | ||
468 | #define SYS_WAKEMSK_M2 (1 << 8) | ||
469 | #define SYS_WAKEMSK_GPIO(x) (1 << (x)) | ||
470 | |||
471 | /* Clock Controller */ | ||
472 | #define AU1000_SYS_FREQCTRL0 0x20 | ||
473 | #define AU1000_SYS_FREQCTRL1 0x24 | ||
474 | #define AU1000_SYS_CLKSRC 0x28 | ||
475 | #define AU1000_SYS_CPUPLL 0x60 | ||
476 | #define AU1000_SYS_AUXPLL 0x64 | ||
477 | #define AU1300_SYS_AUXPLL2 0x68 | ||
478 | |||
479 | |||
480 | /**********************************************************************/ | ||
481 | |||
482 | |||
483 | /* The PCI chip selects are outside the 32bit space, and since we can't | ||
484 | * just program the 36bit addresses into BARs, we have to take a chunk | ||
485 | * out of the 32bit space and reserve it for PCI. When these addresses | ||
486 | * are ioremap()ed, they'll be fixed up to the real 36bit address before | ||
487 | * being passed to the real ioremap function. | ||
488 | */ | ||
489 | #define ALCHEMY_PCI_MEMWIN_START (AU1500_PCI_MEM_PHYS_ADDR >> 4) | ||
490 | #define ALCHEMY_PCI_MEMWIN_END (ALCHEMY_PCI_MEMWIN_START + 0x0FFFFFFF) | ||
491 | |||
492 | /* for PCI IO it's simpler because we get to do the ioremap ourselves and then | ||
493 | * adjust the device's resources. | ||
494 | */ | ||
495 | #define ALCHEMY_PCI_IOWIN_START 0x00001000 | ||
496 | #define ALCHEMY_PCI_IOWIN_END 0x0000FFFF | ||
497 | |||
498 | #ifdef CONFIG_PCI | ||
499 | |||
500 | #define IOPORT_RESOURCE_START 0x00001000 /* skip legacy probing */ | ||
501 | #define IOPORT_RESOURCE_END 0xffffffff | ||
502 | #define IOMEM_RESOURCE_START 0x10000000 | ||
503 | #define IOMEM_RESOURCE_END 0xfffffffffULL | ||
504 | |||
505 | #else | ||
506 | |||
507 | /* Don't allow any legacy ports probing */ | ||
508 | #define IOPORT_RESOURCE_START 0x10000000 | ||
509 | #define IOPORT_RESOURCE_END 0xffffffff | ||
510 | #define IOMEM_RESOURCE_START 0x10000000 | ||
511 | #define IOMEM_RESOURCE_END 0xfffffffffULL | ||
512 | |||
513 | #endif | ||
514 | |||
515 | /* PCI controller block register offsets */ | ||
516 | #define PCI_REG_CMEM 0x0000 | ||
517 | #define PCI_REG_CONFIG 0x0004 | ||
518 | #define PCI_REG_B2BMASK_CCH 0x0008 | ||
519 | #define PCI_REG_B2BBASE0_VID 0x000C | ||
520 | #define PCI_REG_B2BBASE1_SID 0x0010 | ||
521 | #define PCI_REG_MWMASK_DEV 0x0014 | ||
522 | #define PCI_REG_MWBASE_REV_CCL 0x0018 | ||
523 | #define PCI_REG_ERR_ADDR 0x001C | ||
524 | #define PCI_REG_SPEC_INTACK 0x0020 | ||
525 | #define PCI_REG_ID 0x0100 | ||
526 | #define PCI_REG_STATCMD 0x0104 | ||
527 | #define PCI_REG_CLASSREV 0x0108 | ||
528 | #define PCI_REG_PARAM 0x010C | ||
529 | #define PCI_REG_MBAR 0x0110 | ||
530 | #define PCI_REG_TIMEOUT 0x0140 | ||
531 | |||
532 | /* PCI controller block register bits */ | ||
533 | #define PCI_CMEM_E (1 << 28) /* enable cacheable memory */ | ||
534 | #define PCI_CMEM_CMBASE(x) (((x) & 0x3fff) << 14) | ||
535 | #define PCI_CMEM_CMMASK(x) ((x) & 0x3fff) | ||
536 | #define PCI_CONFIG_ERD (1 << 27) /* pci error during R/W */ | ||
537 | #define PCI_CONFIG_ET (1 << 26) /* error in target mode */ | ||
538 | #define PCI_CONFIG_EF (1 << 25) /* fatal error */ | ||
539 | #define PCI_CONFIG_EP (1 << 24) /* parity error */ | ||
540 | #define PCI_CONFIG_EM (1 << 23) /* multiple errors */ | ||
541 | #define PCI_CONFIG_BM (1 << 22) /* bad master error */ | ||
542 | #define PCI_CONFIG_PD (1 << 20) /* PCI Disable */ | ||
543 | #define PCI_CONFIG_BME (1 << 19) /* Byte Mask Enable for reads */ | ||
544 | #define PCI_CONFIG_NC (1 << 16) /* mark mem access non-coherent */ | ||
545 | #define PCI_CONFIG_IA (1 << 15) /* INTA# enabled (target mode) */ | ||
546 | #define PCI_CONFIG_IP (1 << 13) /* int on PCI_PERR# */ | ||
547 | #define PCI_CONFIG_IS (1 << 12) /* int on PCI_SERR# */ | ||
548 | #define PCI_CONFIG_IMM (1 << 11) /* int on master abort */ | ||
549 | #define PCI_CONFIG_ITM (1 << 10) /* int on target abort (as master) */ | ||
550 | #define PCI_CONFIG_ITT (1 << 9) /* int on target abort (as target) */ | ||
551 | #define PCI_CONFIG_IPB (1 << 8) /* int on PERR# in bus master acc */ | ||
552 | #define PCI_CONFIG_SIC_NO (0 << 6) /* no byte mask changes */ | ||
553 | #define PCI_CONFIG_SIC_BA_ADR (1 << 6) /* on byte/hw acc, invert adr bits */ | ||
554 | #define PCI_CONFIG_SIC_HWA_DAT (2 << 6) /* on halfword acc, swap data */ | ||
555 | #define PCI_CONFIG_SIC_ALL (3 << 6) /* swap data bytes on all accesses */ | ||
556 | #define PCI_CONFIG_ST (1 << 5) /* swap data by target transactions */ | ||
557 | #define PCI_CONFIG_SM (1 << 4) /* swap data from PCI ctl */ | ||
558 | #define PCI_CONFIG_AEN (1 << 3) /* enable internal arbiter */ | ||
559 | #define PCI_CONFIG_R2H (1 << 2) /* REQ2# to hi-prio arbiter */ | ||
560 | #define PCI_CONFIG_R1H (1 << 1) /* REQ1# to hi-prio arbiter */ | ||
561 | #define PCI_CONFIG_CH (1 << 0) /* PCI ctl to hi-prio arbiter */ | ||
562 | #define PCI_B2BMASK_B2BMASK(x) (((x) & 0xffff) << 16) | ||
563 | #define PCI_B2BMASK_CCH(x) ((x) & 0xffff) /* 16 upper bits of class code */ | ||
564 | #define PCI_B2BBASE0_VID_B0(x) (((x) & 0xffff) << 16) | ||
565 | #define PCI_B2BBASE0_VID_SV(x) ((x) & 0xffff) | ||
566 | #define PCI_B2BBASE1_SID_B1(x) (((x) & 0xffff) << 16) | ||
567 | #define PCI_B2BBASE1_SID_SI(x) ((x) & 0xffff) | ||
568 | #define PCI_MWMASKDEV_MWMASK(x) (((x) & 0xffff) << 16) | ||
569 | #define PCI_MWMASKDEV_DEVID(x) ((x) & 0xffff) | ||
570 | #define PCI_MWBASEREVCCL_BASE(x) (((x) & 0xffff) << 16) | ||
571 | #define PCI_MWBASEREVCCL_REV(x) (((x) & 0xff) << 8) | ||
572 | #define PCI_MWBASEREVCCL_CCL(x) ((x) & 0xff) | ||
573 | #define PCI_ID_DID(x) (((x) & 0xffff) << 16) | ||
574 | #define PCI_ID_VID(x) ((x) & 0xffff) | ||
575 | #define PCI_STATCMD_STATUS(x) (((x) & 0xffff) << 16) | ||
576 | #define PCI_STATCMD_CMD(x) ((x) & 0xffff) | ||
577 | #define PCI_CLASSREV_CLASS(x) (((x) & 0x00ffffff) << 8) | ||
578 | #define PCI_CLASSREV_REV(x) ((x) & 0xff) | ||
579 | #define PCI_PARAM_BIST(x) (((x) & 0xff) << 24) | ||
580 | #define PCI_PARAM_HT(x) (((x) & 0xff) << 16) | ||
581 | #define PCI_PARAM_LT(x) (((x) & 0xff) << 8) | ||
582 | #define PCI_PARAM_CLS(x) ((x) & 0xff) | ||
583 | #define PCI_TIMEOUT_RETRIES(x) (((x) & 0xff) << 8) /* max retries */ | ||
584 | #define PCI_TIMEOUT_TO(x) ((x) & 0xff) /* target ready timeout */ | ||
585 | |||
586 | |||
587 | /**********************************************************************/ | ||
588 | |||
37 | 589 | ||
38 | #ifndef _LANGUAGE_ASSEMBLY | 590 | #ifndef _LANGUAGE_ASSEMBLY |
39 | 591 | ||
@@ -45,52 +597,36 @@ | |||
45 | 597 | ||
46 | #include <asm/cpu.h> | 598 | #include <asm/cpu.h> |
47 | 599 | ||
48 | /* cpu pipeline flush */ | 600 | /* helpers to access the SYS_* registers */ |
49 | void static inline au_sync(void) | 601 | static inline unsigned long alchemy_rdsys(int regofs) |
50 | { | 602 | { |
51 | __asm__ volatile ("sync"); | 603 | void __iomem *b = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); |
52 | } | ||
53 | 604 | ||
54 | void static inline au_sync_udelay(int us) | 605 | return __raw_readl(b + regofs); |
55 | { | ||
56 | __asm__ volatile ("sync"); | ||
57 | udelay(us); | ||
58 | } | 606 | } |
59 | 607 | ||
60 | void static inline au_sync_delay(int ms) | 608 | static inline void alchemy_wrsys(unsigned long v, int regofs) |
61 | { | 609 | { |
62 | __asm__ volatile ("sync"); | 610 | void __iomem *b = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); |
63 | mdelay(ms); | ||
64 | } | ||
65 | 611 | ||
66 | void static inline au_writeb(u8 val, unsigned long reg) | 612 | __raw_writel(v, b + regofs); |
67 | { | 613 | wmb(); /* drain writebuffer */ |
68 | *(volatile u8 *)reg = val; | ||
69 | } | 614 | } |
70 | 615 | ||
71 | void static inline au_writew(u16 val, unsigned long reg) | 616 | /* helpers to access static memctrl registers */ |
617 | static inline unsigned long alchemy_rdsmem(int regofs) | ||
72 | { | 618 | { |
73 | *(volatile u16 *)reg = val; | 619 | void __iomem *b = (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR); |
74 | } | ||
75 | 620 | ||
76 | void static inline au_writel(u32 val, unsigned long reg) | 621 | return __raw_readl(b + regofs); |
77 | { | ||
78 | *(volatile u32 *)reg = val; | ||
79 | } | 622 | } |
80 | 623 | ||
81 | static inline u8 au_readb(unsigned long reg) | 624 | static inline void alchemy_wrsmem(unsigned long v, int regofs) |
82 | { | 625 | { |
83 | return *(volatile u8 *)reg; | 626 | void __iomem *b = (void __iomem *)KSEG1ADDR(AU1000_STATIC_MEM_PHYS_ADDR); |
84 | } | ||
85 | 627 | ||
86 | static inline u16 au_readw(unsigned long reg) | 628 | __raw_writel(v, b + regofs); |
87 | { | 629 | wmb(); /* drain writebuffer */ |
88 | return *(volatile u16 *)reg; | ||
89 | } | ||
90 | |||
91 | static inline u32 au_readl(unsigned long reg) | ||
92 | { | ||
93 | return *(volatile u32 *)reg; | ||
94 | } | 630 | } |
95 | 631 | ||
96 | /* Early Au1000 have a write-only SYS_CPUPLL register. */ | 632 | /* Early Au1000 have a write-only SYS_CPUPLL register. */ |
@@ -192,19 +728,20 @@ static inline void alchemy_uart_enable(u32 uart_phys) | |||
192 | /* reset, enable clock, deassert reset */ | 728 | /* reset, enable clock, deassert reset */ |
193 | if ((__raw_readl(addr + 0x100) & 3) != 3) { | 729 | if ((__raw_readl(addr + 0x100) & 3) != 3) { |
194 | __raw_writel(0, addr + 0x100); | 730 | __raw_writel(0, addr + 0x100); |
195 | wmb(); | 731 | wmb(); /* drain writebuffer */ |
196 | __raw_writel(1, addr + 0x100); | 732 | __raw_writel(1, addr + 0x100); |
197 | wmb(); | 733 | wmb(); /* drain writebuffer */ |
198 | } | 734 | } |
199 | __raw_writel(3, addr + 0x100); | 735 | __raw_writel(3, addr + 0x100); |
200 | wmb(); | 736 | wmb(); /* drain writebuffer */ |
201 | } | 737 | } |
202 | 738 | ||
203 | static inline void alchemy_uart_disable(u32 uart_phys) | 739 | static inline void alchemy_uart_disable(u32 uart_phys) |
204 | { | 740 | { |
205 | void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys); | 741 | void __iomem *addr = (void __iomem *)KSEG1ADDR(uart_phys); |
742 | |||
206 | __raw_writel(0, addr + 0x100); /* UART_MOD_CNTRL */ | 743 | __raw_writel(0, addr + 0x100); /* UART_MOD_CNTRL */ |
207 | wmb(); | 744 | wmb(); /* drain writebuffer */ |
208 | } | 745 | } |
209 | 746 | ||
210 | static inline void alchemy_uart_putchar(u32 uart_phys, u8 c) | 747 | static inline void alchemy_uart_putchar(u32 uart_phys, u8 c) |
@@ -223,7 +760,7 @@ static inline void alchemy_uart_putchar(u32 uart_phys, u8 c) | |||
223 | } while (--timeout); | 760 | } while (--timeout); |
224 | 761 | ||
225 | __raw_writel(c, base + 0x04); /* tx */ | 762 | __raw_writel(c, base + 0x04); /* tx */ |
226 | wmb(); | 763 | wmb(); /* drain writebuffer */ |
227 | } | 764 | } |
228 | 765 | ||
229 | /* return number of ethernet MACs on a given cputype */ | 766 | /* return number of ethernet MACs on a given cputype */ |
@@ -240,20 +777,13 @@ static inline int alchemy_get_macs(int type) | |||
240 | return 0; | 777 | return 0; |
241 | } | 778 | } |
242 | 779 | ||
243 | /* arch/mips/au1000/common/clocks.c */ | ||
244 | extern void set_au1x00_speed(unsigned int new_freq); | ||
245 | extern unsigned int get_au1x00_speed(void); | ||
246 | extern void set_au1x00_uart_baud_base(unsigned long new_baud_base); | ||
247 | extern unsigned long get_au1x00_uart_baud_base(void); | ||
248 | extern unsigned long au1xxx_calc_clock(void); | ||
249 | |||
250 | /* PM: arch/mips/alchemy/common/sleeper.S, power.c, irq.c */ | 780 | /* PM: arch/mips/alchemy/common/sleeper.S, power.c, irq.c */ |
251 | void alchemy_sleep_au1000(void); | 781 | void alchemy_sleep_au1000(void); |
252 | void alchemy_sleep_au1550(void); | 782 | void alchemy_sleep_au1550(void); |
253 | void alchemy_sleep_au1300(void); | 783 | void alchemy_sleep_au1300(void); |
254 | void au_sleep(void); | 784 | void au_sleep(void); |
255 | 785 | ||
256 | /* USB: drivers/usb/host/alchemy-common.c */ | 786 | /* USB: arch/mips/alchemy/common/usb.c */ |
257 | enum alchemy_usb_block { | 787 | enum alchemy_usb_block { |
258 | ALCHEMY_USB_OHCI0, | 788 | ALCHEMY_USB_OHCI0, |
259 | ALCHEMY_USB_UDC0, | 789 | ALCHEMY_USB_UDC0, |
@@ -272,6 +802,20 @@ struct alchemy_pci_platdata { | |||
272 | unsigned long pci_cfg_clr; | 802 | unsigned long pci_cfg_clr; |
273 | }; | 803 | }; |
274 | 804 | ||
805 | /* The IrDA peripheral has an IRFIRSEL pin, but on the DB/PB boards it's | ||
806 | * not used to select FIR/SIR mode on the transceiver but as a GPIO. | ||
807 | * Instead a CPLD has to be told about the mode. The driver calls the | ||
808 | * set_phy_mode() function in addition to driving the IRFIRSEL pin. | ||
809 | */ | ||
810 | #define AU1000_IRDA_PHY_MODE_OFF 0 | ||
811 | #define AU1000_IRDA_PHY_MODE_SIR 1 | ||
812 | #define AU1000_IRDA_PHY_MODE_FIR 2 | ||
813 | |||
814 | struct au1k_irda_platform_data { | ||
815 | void (*set_phy_mode)(int mode); | ||
816 | }; | ||
817 | |||
818 | |||
275 | /* Multifunction pins: Each of these pins can either be assigned to the | 819 | /* Multifunction pins: Each of these pins can either be assigned to the |
276 | * GPIO controller or a on-chip peripheral. | 820 | * GPIO controller or a on-chip peripheral. |
277 | * Call "au1300_pinfunc_to_dev()" or "au1300_pinfunc_to_gpio()" to | 821 | * Call "au1300_pinfunc_to_dev()" or "au1300_pinfunc_to_gpio()" to |
@@ -344,20 +888,6 @@ enum au1300_vss_block { | |||
344 | 888 | ||
345 | extern void au1300_vss_block_control(int block, int enable); | 889 | extern void au1300_vss_block_control(int block, int enable); |
346 | 890 | ||
347 | |||
348 | /* SOC Interrupt numbers */ | ||
349 | /* Au1000-style (IC0/1): 2 controllers with 32 sources each */ | ||
350 | #define AU1000_INTC0_INT_BASE (MIPS_CPU_IRQ_BASE + 8) | ||
351 | #define AU1000_INTC0_INT_LAST (AU1000_INTC0_INT_BASE + 31) | ||
352 | #define AU1000_INTC1_INT_BASE (AU1000_INTC0_INT_LAST + 1) | ||
353 | #define AU1000_INTC1_INT_LAST (AU1000_INTC1_INT_BASE + 31) | ||
354 | #define AU1000_MAX_INTR AU1000_INTC1_INT_LAST | ||
355 | |||
356 | /* Au1300-style (GPIC): 1 controller with up to 128 sources */ | ||
357 | #define ALCHEMY_GPIC_INT_BASE (MIPS_CPU_IRQ_BASE + 8) | ||
358 | #define ALCHEMY_GPIC_INT_NUM 128 | ||
359 | #define ALCHEMY_GPIC_INT_LAST (ALCHEMY_GPIC_INT_BASE + ALCHEMY_GPIC_INT_NUM - 1) | ||
360 | |||
361 | enum soc_au1000_ints { | 891 | enum soc_au1000_ints { |
362 | AU1000_FIRST_INT = AU1000_INTC0_INT_BASE, | 892 | AU1000_FIRST_INT = AU1000_INTC0_INT_BASE, |
363 | AU1000_UART0_INT = AU1000_FIRST_INT, | 893 | AU1000_UART0_INT = AU1000_FIRST_INT, |
@@ -678,885 +1208,4 @@ enum soc_au1200_ints { | |||
678 | 1208 | ||
679 | #endif /* !defined (_LANGUAGE_ASSEMBLY) */ | 1209 | #endif /* !defined (_LANGUAGE_ASSEMBLY) */ |
680 | 1210 | ||
681 | /* Au1300 peripheral interrupt numbers */ | ||
682 | #define AU1300_FIRST_INT (ALCHEMY_GPIC_INT_BASE) | ||
683 | #define AU1300_UART1_INT (AU1300_FIRST_INT + 17) | ||
684 | #define AU1300_UART2_INT (AU1300_FIRST_INT + 25) | ||
685 | #define AU1300_UART3_INT (AU1300_FIRST_INT + 27) | ||
686 | #define AU1300_SD1_INT (AU1300_FIRST_INT + 32) | ||
687 | #define AU1300_SD2_INT (AU1300_FIRST_INT + 38) | ||
688 | #define AU1300_PSC0_INT (AU1300_FIRST_INT + 48) | ||
689 | #define AU1300_PSC1_INT (AU1300_FIRST_INT + 52) | ||
690 | #define AU1300_PSC2_INT (AU1300_FIRST_INT + 56) | ||
691 | #define AU1300_PSC3_INT (AU1300_FIRST_INT + 60) | ||
692 | #define AU1300_NAND_INT (AU1300_FIRST_INT + 62) | ||
693 | #define AU1300_DDMA_INT (AU1300_FIRST_INT + 75) | ||
694 | #define AU1300_MMU_INT (AU1300_FIRST_INT + 76) | ||
695 | #define AU1300_MPU_INT (AU1300_FIRST_INT + 77) | ||
696 | #define AU1300_GPU_INT (AU1300_FIRST_INT + 78) | ||
697 | #define AU1300_UDMA_INT (AU1300_FIRST_INT + 79) | ||
698 | #define AU1300_TOY_INT (AU1300_FIRST_INT + 80) | ||
699 | #define AU1300_TOY_MATCH0_INT (AU1300_FIRST_INT + 81) | ||
700 | #define AU1300_TOY_MATCH1_INT (AU1300_FIRST_INT + 82) | ||
701 | #define AU1300_TOY_MATCH2_INT (AU1300_FIRST_INT + 83) | ||
702 | #define AU1300_RTC_INT (AU1300_FIRST_INT + 84) | ||
703 | #define AU1300_RTC_MATCH0_INT (AU1300_FIRST_INT + 85) | ||
704 | #define AU1300_RTC_MATCH1_INT (AU1300_FIRST_INT + 86) | ||
705 | #define AU1300_RTC_MATCH2_INT (AU1300_FIRST_INT + 87) | ||
706 | #define AU1300_UART0_INT (AU1300_FIRST_INT + 88) | ||
707 | #define AU1300_SD0_INT (AU1300_FIRST_INT + 89) | ||
708 | #define AU1300_USB_INT (AU1300_FIRST_INT + 90) | ||
709 | #define AU1300_LCD_INT (AU1300_FIRST_INT + 91) | ||
710 | #define AU1300_BSA_INT (AU1300_FIRST_INT + 92) | ||
711 | #define AU1300_MPE_INT (AU1300_FIRST_INT + 93) | ||
712 | #define AU1300_ITE_INT (AU1300_FIRST_INT + 94) | ||
713 | #define AU1300_AES_INT (AU1300_FIRST_INT + 95) | ||
714 | #define AU1300_CIM_INT (AU1300_FIRST_INT + 96) | ||
715 | |||
716 | /**********************************************************************/ | ||
717 | |||
718 | /* | ||
719 | * Physical base addresses for integrated peripherals | ||
720 | * 0..au1000 1..au1500 2..au1100 3..au1550 4..au1200 5..au1300 | ||
721 | */ | ||
722 | |||
723 | #define AU1000_AC97_PHYS_ADDR 0x10000000 /* 012 */ | ||
724 | #define AU1300_ROM_PHYS_ADDR 0x10000000 /* 5 */ | ||
725 | #define AU1300_OTP_PHYS_ADDR 0x10002000 /* 5 */ | ||
726 | #define AU1300_VSS_PHYS_ADDR 0x10003000 /* 5 */ | ||
727 | #define AU1300_UART0_PHYS_ADDR 0x10100000 /* 5 */ | ||
728 | #define AU1300_UART1_PHYS_ADDR 0x10101000 /* 5 */ | ||
729 | #define AU1300_UART2_PHYS_ADDR 0x10102000 /* 5 */ | ||
730 | #define AU1300_UART3_PHYS_ADDR 0x10103000 /* 5 */ | ||
731 | #define AU1000_USB_OHCI_PHYS_ADDR 0x10100000 /* 012 */ | ||
732 | #define AU1000_USB_UDC_PHYS_ADDR 0x10200000 /* 0123 */ | ||
733 | #define AU1300_GPIC_PHYS_ADDR 0x10200000 /* 5 */ | ||
734 | #define AU1000_IRDA_PHYS_ADDR 0x10300000 /* 02 */ | ||
735 | #define AU1200_AES_PHYS_ADDR 0x10300000 /* 45 */ | ||
736 | #define AU1000_IC0_PHYS_ADDR 0x10400000 /* 01234 */ | ||
737 | #define AU1300_GPU_PHYS_ADDR 0x10500000 /* 5 */ | ||
738 | #define AU1000_MAC0_PHYS_ADDR 0x10500000 /* 023 */ | ||
739 | #define AU1000_MAC1_PHYS_ADDR 0x10510000 /* 023 */ | ||
740 | #define AU1000_MACEN_PHYS_ADDR 0x10520000 /* 023 */ | ||
741 | #define AU1100_SD0_PHYS_ADDR 0x10600000 /* 245 */ | ||
742 | #define AU1300_SD1_PHYS_ADDR 0x10601000 /* 5 */ | ||
743 | #define AU1300_SD2_PHYS_ADDR 0x10602000 /* 5 */ | ||
744 | #define AU1100_SD1_PHYS_ADDR 0x10680000 /* 24 */ | ||
745 | #define AU1300_SYS_PHYS_ADDR 0x10900000 /* 5 */ | ||
746 | #define AU1550_PSC2_PHYS_ADDR 0x10A00000 /* 3 */ | ||
747 | #define AU1550_PSC3_PHYS_ADDR 0x10B00000 /* 3 */ | ||
748 | #define AU1300_PSC0_PHYS_ADDR 0x10A00000 /* 5 */ | ||
749 | #define AU1300_PSC1_PHYS_ADDR 0x10A01000 /* 5 */ | ||
750 | #define AU1300_PSC2_PHYS_ADDR 0x10A02000 /* 5 */ | ||
751 | #define AU1300_PSC3_PHYS_ADDR 0x10A03000 /* 5 */ | ||
752 | #define AU1000_I2S_PHYS_ADDR 0x11000000 /* 02 */ | ||
753 | #define AU1500_MAC0_PHYS_ADDR 0x11500000 /* 1 */ | ||
754 | #define AU1500_MAC1_PHYS_ADDR 0x11510000 /* 1 */ | ||
755 | #define AU1500_MACEN_PHYS_ADDR 0x11520000 /* 1 */ | ||
756 | #define AU1000_UART0_PHYS_ADDR 0x11100000 /* 01234 */ | ||
757 | #define AU1200_SWCNT_PHYS_ADDR 0x1110010C /* 4 */ | ||
758 | #define AU1000_UART1_PHYS_ADDR 0x11200000 /* 0234 */ | ||
759 | #define AU1000_UART2_PHYS_ADDR 0x11300000 /* 0 */ | ||
760 | #define AU1000_UART3_PHYS_ADDR 0x11400000 /* 0123 */ | ||
761 | #define AU1000_SSI0_PHYS_ADDR 0x11600000 /* 02 */ | ||
762 | #define AU1000_SSI1_PHYS_ADDR 0x11680000 /* 02 */ | ||
763 | #define AU1500_GPIO2_PHYS_ADDR 0x11700000 /* 1234 */ | ||
764 | #define AU1000_IC1_PHYS_ADDR 0x11800000 /* 01234 */ | ||
765 | #define AU1000_SYS_PHYS_ADDR 0x11900000 /* 012345 */ | ||
766 | #define AU1550_PSC0_PHYS_ADDR 0x11A00000 /* 34 */ | ||
767 | #define AU1550_PSC1_PHYS_ADDR 0x11B00000 /* 34 */ | ||
768 | #define AU1000_MEM_PHYS_ADDR 0x14000000 /* 01234 */ | ||
769 | #define AU1000_STATIC_MEM_PHYS_ADDR 0x14001000 /* 01234 */ | ||
770 | #define AU1300_UDMA_PHYS_ADDR 0x14001800 /* 5 */ | ||
771 | #define AU1000_DMA_PHYS_ADDR 0x14002000 /* 012 */ | ||
772 | #define AU1550_DBDMA_PHYS_ADDR 0x14002000 /* 345 */ | ||
773 | #define AU1550_DBDMA_CONF_PHYS_ADDR 0x14003000 /* 345 */ | ||
774 | #define AU1000_MACDMA0_PHYS_ADDR 0x14004000 /* 0123 */ | ||
775 | #define AU1000_MACDMA1_PHYS_ADDR 0x14004200 /* 0123 */ | ||
776 | #define AU1200_CIM_PHYS_ADDR 0x14004000 /* 45 */ | ||
777 | #define AU1500_PCI_PHYS_ADDR 0x14005000 /* 13 */ | ||
778 | #define AU1550_PE_PHYS_ADDR 0x14008000 /* 3 */ | ||
779 | #define AU1200_MAEBE_PHYS_ADDR 0x14010000 /* 4 */ | ||
780 | #define AU1200_MAEFE_PHYS_ADDR 0x14012000 /* 4 */ | ||
781 | #define AU1300_MAEITE_PHYS_ADDR 0x14010000 /* 5 */ | ||
782 | #define AU1300_MAEMPE_PHYS_ADDR 0x14014000 /* 5 */ | ||
783 | #define AU1550_USB_OHCI_PHYS_ADDR 0x14020000 /* 3 */ | ||
784 | #define AU1200_USB_CTL_PHYS_ADDR 0x14020000 /* 4 */ | ||
785 | #define AU1200_USB_OTG_PHYS_ADDR 0x14020020 /* 4 */ | ||
786 | #define AU1200_USB_OHCI_PHYS_ADDR 0x14020100 /* 4 */ | ||
787 | #define AU1200_USB_EHCI_PHYS_ADDR 0x14020200 /* 4 */ | ||
788 | #define AU1200_USB_UDC_PHYS_ADDR 0x14022000 /* 4 */ | ||
789 | #define AU1300_USB_EHCI_PHYS_ADDR 0x14020000 /* 5 */ | ||
790 | #define AU1300_USB_OHCI0_PHYS_ADDR 0x14020400 /* 5 */ | ||
791 | #define AU1300_USB_OHCI1_PHYS_ADDR 0x14020800 /* 5 */ | ||
792 | #define AU1300_USB_CTL_PHYS_ADDR 0x14021000 /* 5 */ | ||
793 | #define AU1300_USB_OTG_PHYS_ADDR 0x14022000 /* 5 */ | ||
794 | #define AU1300_MAEBSA_PHYS_ADDR 0x14030000 /* 5 */ | ||
795 | #define AU1100_LCD_PHYS_ADDR 0x15000000 /* 2 */ | ||
796 | #define AU1200_LCD_PHYS_ADDR 0x15000000 /* 45 */ | ||
797 | #define AU1500_PCI_MEM_PHYS_ADDR 0x400000000ULL /* 13 */ | ||
798 | #define AU1500_PCI_IO_PHYS_ADDR 0x500000000ULL /* 13 */ | ||
799 | #define AU1500_PCI_CONFIG0_PHYS_ADDR 0x600000000ULL /* 13 */ | ||
800 | #define AU1500_PCI_CONFIG1_PHYS_ADDR 0x680000000ULL /* 13 */ | ||
801 | #define AU1000_PCMCIA_IO_PHYS_ADDR 0xF00000000ULL /* 012345 */ | ||
802 | #define AU1000_PCMCIA_ATTR_PHYS_ADDR 0xF40000000ULL /* 012345 */ | ||
803 | #define AU1000_PCMCIA_MEM_PHYS_ADDR 0xF80000000ULL /* 012345 */ | ||
804 | |||
805 | /**********************************************************************/ | ||
806 | |||
807 | |||
808 | /* | ||
809 | * Au1300 GPIO+INT controller (GPIC) register offsets and bits | ||
810 | * Registers are 128bits (0x10 bytes), divided into 4 "banks". | ||
811 | */ | ||
812 | #define AU1300_GPIC_PINVAL 0x0000 | ||
813 | #define AU1300_GPIC_PINVALCLR 0x0010 | ||
814 | #define AU1300_GPIC_IPEND 0x0020 | ||
815 | #define AU1300_GPIC_PRIENC 0x0030 | ||
816 | #define AU1300_GPIC_IEN 0x0040 /* int_mask in manual */ | ||
817 | #define AU1300_GPIC_IDIS 0x0050 /* int_maskclr in manual */ | ||
818 | #define AU1300_GPIC_DMASEL 0x0060 | ||
819 | #define AU1300_GPIC_DEVSEL 0x0080 | ||
820 | #define AU1300_GPIC_DEVCLR 0x0090 | ||
821 | #define AU1300_GPIC_RSTVAL 0x00a0 | ||
822 | /* pin configuration space. one 32bit register for up to 128 IRQs */ | ||
823 | #define AU1300_GPIC_PINCFG 0x1000 | ||
824 | |||
825 | #define GPIC_GPIO_TO_BIT(gpio) \ | ||
826 | (1 << ((gpio) & 0x1f)) | ||
827 | |||
828 | #define GPIC_GPIO_BANKOFF(gpio) \ | ||
829 | (((gpio) >> 5) * 4) | ||
830 | |||
831 | /* Pin Control bits: who owns the pin, what does it do */ | ||
832 | #define GPIC_CFG_PC_GPIN 0 | ||
833 | #define GPIC_CFG_PC_DEV 1 | ||
834 | #define GPIC_CFG_PC_GPOLOW 2 | ||
835 | #define GPIC_CFG_PC_GPOHIGH 3 | ||
836 | #define GPIC_CFG_PC_MASK 3 | ||
837 | |||
838 | /* assign pin to MIPS IRQ line */ | ||
839 | #define GPIC_CFG_IL_SET(x) (((x) & 3) << 2) | ||
840 | #define GPIC_CFG_IL_MASK (3 << 2) | ||
841 | |||
842 | /* pin interrupt type setup */ | ||
843 | #define GPIC_CFG_IC_OFF (0 << 4) | ||
844 | #define GPIC_CFG_IC_LEVEL_LOW (1 << 4) | ||
845 | #define GPIC_CFG_IC_LEVEL_HIGH (2 << 4) | ||
846 | #define GPIC_CFG_IC_EDGE_FALL (5 << 4) | ||
847 | #define GPIC_CFG_IC_EDGE_RISE (6 << 4) | ||
848 | #define GPIC_CFG_IC_EDGE_BOTH (7 << 4) | ||
849 | #define GPIC_CFG_IC_MASK (7 << 4) | ||
850 | |||
851 | /* allow interrupt to wake cpu from 'wait' */ | ||
852 | #define GPIC_CFG_IDLEWAKE (1 << 7) | ||
853 | |||
854 | /***********************************************************************/ | ||
855 | |||
856 | /* Au1000 SDRAM memory controller register offsets */ | ||
857 | #define AU1000_MEM_SDMODE0 0x0000 | ||
858 | #define AU1000_MEM_SDMODE1 0x0004 | ||
859 | #define AU1000_MEM_SDMODE2 0x0008 | ||
860 | #define AU1000_MEM_SDADDR0 0x000C | ||
861 | #define AU1000_MEM_SDADDR1 0x0010 | ||
862 | #define AU1000_MEM_SDADDR2 0x0014 | ||
863 | #define AU1000_MEM_SDREFCFG 0x0018 | ||
864 | #define AU1000_MEM_SDPRECMD 0x001C | ||
865 | #define AU1000_MEM_SDAUTOREF 0x0020 | ||
866 | #define AU1000_MEM_SDWRMD0 0x0024 | ||
867 | #define AU1000_MEM_SDWRMD1 0x0028 | ||
868 | #define AU1000_MEM_SDWRMD2 0x002C | ||
869 | #define AU1000_MEM_SDSLEEP 0x0030 | ||
870 | #define AU1000_MEM_SDSMCKE 0x0034 | ||
871 | |||
872 | /* MEM_SDMODE register content definitions */ | ||
873 | #define MEM_SDMODE_F (1 << 22) | ||
874 | #define MEM_SDMODE_SR (1 << 21) | ||
875 | #define MEM_SDMODE_BS (1 << 20) | ||
876 | #define MEM_SDMODE_RS (3 << 18) | ||
877 | #define MEM_SDMODE_CS (7 << 15) | ||
878 | #define MEM_SDMODE_TRAS (15 << 11) | ||
879 | #define MEM_SDMODE_TMRD (3 << 9) | ||
880 | #define MEM_SDMODE_TWR (3 << 7) | ||
881 | #define MEM_SDMODE_TRP (3 << 5) | ||
882 | #define MEM_SDMODE_TRCD (3 << 3) | ||
883 | #define MEM_SDMODE_TCL (7 << 0) | ||
884 | |||
885 | #define MEM_SDMODE_BS_2Bank (0 << 20) | ||
886 | #define MEM_SDMODE_BS_4Bank (1 << 20) | ||
887 | #define MEM_SDMODE_RS_11Row (0 << 18) | ||
888 | #define MEM_SDMODE_RS_12Row (1 << 18) | ||
889 | #define MEM_SDMODE_RS_13Row (2 << 18) | ||
890 | #define MEM_SDMODE_RS_N(N) ((N) << 18) | ||
891 | #define MEM_SDMODE_CS_7Col (0 << 15) | ||
892 | #define MEM_SDMODE_CS_8Col (1 << 15) | ||
893 | #define MEM_SDMODE_CS_9Col (2 << 15) | ||
894 | #define MEM_SDMODE_CS_10Col (3 << 15) | ||
895 | #define MEM_SDMODE_CS_11Col (4 << 15) | ||
896 | #define MEM_SDMODE_CS_N(N) ((N) << 15) | ||
897 | #define MEM_SDMODE_TRAS_N(N) ((N) << 11) | ||
898 | #define MEM_SDMODE_TMRD_N(N) ((N) << 9) | ||
899 | #define MEM_SDMODE_TWR_N(N) ((N) << 7) | ||
900 | #define MEM_SDMODE_TRP_N(N) ((N) << 5) | ||
901 | #define MEM_SDMODE_TRCD_N(N) ((N) << 3) | ||
902 | #define MEM_SDMODE_TCL_N(N) ((N) << 0) | ||
903 | |||
904 | /* MEM_SDADDR register contents definitions */ | ||
905 | #define MEM_SDADDR_E (1 << 20) | ||
906 | #define MEM_SDADDR_CSBA (0x03FF << 10) | ||
907 | #define MEM_SDADDR_CSMASK (0x03FF << 0) | ||
908 | #define MEM_SDADDR_CSBA_N(N) ((N) & (0x03FF << 22) >> 12) | ||
909 | #define MEM_SDADDR_CSMASK_N(N) ((N)&(0x03FF << 22) >> 22) | ||
910 | |||
911 | /* MEM_SDREFCFG register content definitions */ | ||
912 | #define MEM_SDREFCFG_TRC (15 << 28) | ||
913 | #define MEM_SDREFCFG_TRPM (3 << 26) | ||
914 | #define MEM_SDREFCFG_E (1 << 25) | ||
915 | #define MEM_SDREFCFG_RE (0x1ffffff << 0) | ||
916 | #define MEM_SDREFCFG_TRC_N(N) ((N) << MEM_SDREFCFG_TRC) | ||
917 | #define MEM_SDREFCFG_TRPM_N(N) ((N) << MEM_SDREFCFG_TRPM) | ||
918 | #define MEM_SDREFCFG_REF_N(N) (N) | ||
919 | |||
920 | /* Au1550 SDRAM Register Offsets */ | ||
921 | #define AU1550_MEM_SDMODE0 0x0800 | ||
922 | #define AU1550_MEM_SDMODE1 0x0808 | ||
923 | #define AU1550_MEM_SDMODE2 0x0810 | ||
924 | #define AU1550_MEM_SDADDR0 0x0820 | ||
925 | #define AU1550_MEM_SDADDR1 0x0828 | ||
926 | #define AU1550_MEM_SDADDR2 0x0830 | ||
927 | #define AU1550_MEM_SDCONFIGA 0x0840 | ||
928 | #define AU1550_MEM_SDCONFIGB 0x0848 | ||
929 | #define AU1550_MEM_SDSTAT 0x0850 | ||
930 | #define AU1550_MEM_SDERRADDR 0x0858 | ||
931 | #define AU1550_MEM_SDSTRIDE0 0x0860 | ||
932 | #define AU1550_MEM_SDSTRIDE1 0x0868 | ||
933 | #define AU1550_MEM_SDSTRIDE2 0x0870 | ||
934 | #define AU1550_MEM_SDWRMD0 0x0880 | ||
935 | #define AU1550_MEM_SDWRMD1 0x0888 | ||
936 | #define AU1550_MEM_SDWRMD2 0x0890 | ||
937 | #define AU1550_MEM_SDPRECMD 0x08C0 | ||
938 | #define AU1550_MEM_SDAUTOREF 0x08C8 | ||
939 | #define AU1550_MEM_SDSREF 0x08D0 | ||
940 | #define AU1550_MEM_SDSLEEP MEM_SDSREF | ||
941 | |||
942 | /* Static Bus Controller */ | ||
943 | #define MEM_STCFG0 0xB4001000 | ||
944 | #define MEM_STTIME0 0xB4001004 | ||
945 | #define MEM_STADDR0 0xB4001008 | ||
946 | |||
947 | #define MEM_STCFG1 0xB4001010 | ||
948 | #define MEM_STTIME1 0xB4001014 | ||
949 | #define MEM_STADDR1 0xB4001018 | ||
950 | |||
951 | #define MEM_STCFG2 0xB4001020 | ||
952 | #define MEM_STTIME2 0xB4001024 | ||
953 | #define MEM_STADDR2 0xB4001028 | ||
954 | |||
955 | #define MEM_STCFG3 0xB4001030 | ||
956 | #define MEM_STTIME3 0xB4001034 | ||
957 | #define MEM_STADDR3 0xB4001038 | ||
958 | |||
959 | #define MEM_STNDCTL 0xB4001100 | ||
960 | #define MEM_STSTAT 0xB4001104 | ||
961 | |||
962 | #define MEM_STNAND_CMD 0x0 | ||
963 | #define MEM_STNAND_ADDR 0x4 | ||
964 | #define MEM_STNAND_DATA 0x20 | ||
965 | |||
966 | |||
967 | /* Programmable Counters 0 and 1 */ | ||
968 | #define SYS_BASE 0xB1900000 | ||
969 | #define SYS_COUNTER_CNTRL (SYS_BASE + 0x14) | ||
970 | # define SYS_CNTRL_E1S (1 << 23) | ||
971 | # define SYS_CNTRL_T1S (1 << 20) | ||
972 | # define SYS_CNTRL_M21 (1 << 19) | ||
973 | # define SYS_CNTRL_M11 (1 << 18) | ||
974 | # define SYS_CNTRL_M01 (1 << 17) | ||
975 | # define SYS_CNTRL_C1S (1 << 16) | ||
976 | # define SYS_CNTRL_BP (1 << 14) | ||
977 | # define SYS_CNTRL_EN1 (1 << 13) | ||
978 | # define SYS_CNTRL_BT1 (1 << 12) | ||
979 | # define SYS_CNTRL_EN0 (1 << 11) | ||
980 | # define SYS_CNTRL_BT0 (1 << 10) | ||
981 | # define SYS_CNTRL_E0 (1 << 8) | ||
982 | # define SYS_CNTRL_E0S (1 << 7) | ||
983 | # define SYS_CNTRL_32S (1 << 5) | ||
984 | # define SYS_CNTRL_T0S (1 << 4) | ||
985 | # define SYS_CNTRL_M20 (1 << 3) | ||
986 | # define SYS_CNTRL_M10 (1 << 2) | ||
987 | # define SYS_CNTRL_M00 (1 << 1) | ||
988 | # define SYS_CNTRL_C0S (1 << 0) | ||
989 | |||
990 | /* Programmable Counter 0 Registers */ | ||
991 | #define SYS_TOYTRIM (SYS_BASE + 0) | ||
992 | #define SYS_TOYWRITE (SYS_BASE + 4) | ||
993 | #define SYS_TOYMATCH0 (SYS_BASE + 8) | ||
994 | #define SYS_TOYMATCH1 (SYS_BASE + 0xC) | ||
995 | #define SYS_TOYMATCH2 (SYS_BASE + 0x10) | ||
996 | #define SYS_TOYREAD (SYS_BASE + 0x40) | ||
997 | |||
998 | /* Programmable Counter 1 Registers */ | ||
999 | #define SYS_RTCTRIM (SYS_BASE + 0x44) | ||
1000 | #define SYS_RTCWRITE (SYS_BASE + 0x48) | ||
1001 | #define SYS_RTCMATCH0 (SYS_BASE + 0x4C) | ||
1002 | #define SYS_RTCMATCH1 (SYS_BASE + 0x50) | ||
1003 | #define SYS_RTCMATCH2 (SYS_BASE + 0x54) | ||
1004 | #define SYS_RTCREAD (SYS_BASE + 0x58) | ||
1005 | |||
1006 | /* I2S Controller */ | ||
1007 | #define I2S_DATA 0xB1000000 | ||
1008 | # define I2S_DATA_MASK 0xffffff | ||
1009 | #define I2S_CONFIG 0xB1000004 | ||
1010 | # define I2S_CONFIG_XU (1 << 25) | ||
1011 | # define I2S_CONFIG_XO (1 << 24) | ||
1012 | # define I2S_CONFIG_RU (1 << 23) | ||
1013 | # define I2S_CONFIG_RO (1 << 22) | ||
1014 | # define I2S_CONFIG_TR (1 << 21) | ||
1015 | # define I2S_CONFIG_TE (1 << 20) | ||
1016 | # define I2S_CONFIG_TF (1 << 19) | ||
1017 | # define I2S_CONFIG_RR (1 << 18) | ||
1018 | # define I2S_CONFIG_RE (1 << 17) | ||
1019 | # define I2S_CONFIG_RF (1 << 16) | ||
1020 | # define I2S_CONFIG_PD (1 << 11) | ||
1021 | # define I2S_CONFIG_LB (1 << 10) | ||
1022 | # define I2S_CONFIG_IC (1 << 9) | ||
1023 | # define I2S_CONFIG_FM_BIT 7 | ||
1024 | # define I2S_CONFIG_FM_MASK (0x3 << I2S_CONFIG_FM_BIT) | ||
1025 | # define I2S_CONFIG_FM_I2S (0x0 << I2S_CONFIG_FM_BIT) | ||
1026 | # define I2S_CONFIG_FM_LJ (0x1 << I2S_CONFIG_FM_BIT) | ||
1027 | # define I2S_CONFIG_FM_RJ (0x2 << I2S_CONFIG_FM_BIT) | ||
1028 | # define I2S_CONFIG_TN (1 << 6) | ||
1029 | # define I2S_CONFIG_RN (1 << 5) | ||
1030 | # define I2S_CONFIG_SZ_BIT 0 | ||
1031 | # define I2S_CONFIG_SZ_MASK (0x1F << I2S_CONFIG_SZ_BIT) | ||
1032 | |||
1033 | #define I2S_CONTROL 0xB1000008 | ||
1034 | # define I2S_CONTROL_D (1 << 1) | ||
1035 | # define I2S_CONTROL_CE (1 << 0) | ||
1036 | |||
1037 | |||
1038 | /* Ethernet Controllers */ | ||
1039 | |||
1040 | /* 4 byte offsets from AU1000_ETH_BASE */ | ||
1041 | #define MAC_CONTROL 0x0 | ||
1042 | # define MAC_RX_ENABLE (1 << 2) | ||
1043 | # define MAC_TX_ENABLE (1 << 3) | ||
1044 | # define MAC_DEF_CHECK (1 << 5) | ||
1045 | # define MAC_SET_BL(X) (((X) & 0x3) << 6) | ||
1046 | # define MAC_AUTO_PAD (1 << 8) | ||
1047 | # define MAC_DISABLE_RETRY (1 << 10) | ||
1048 | # define MAC_DISABLE_BCAST (1 << 11) | ||
1049 | # define MAC_LATE_COL (1 << 12) | ||
1050 | # define MAC_HASH_MODE (1 << 13) | ||
1051 | # define MAC_HASH_ONLY (1 << 15) | ||
1052 | # define MAC_PASS_ALL (1 << 16) | ||
1053 | # define MAC_INVERSE_FILTER (1 << 17) | ||
1054 | # define MAC_PROMISCUOUS (1 << 18) | ||
1055 | # define MAC_PASS_ALL_MULTI (1 << 19) | ||
1056 | # define MAC_FULL_DUPLEX (1 << 20) | ||
1057 | # define MAC_NORMAL_MODE 0 | ||
1058 | # define MAC_INT_LOOPBACK (1 << 21) | ||
1059 | # define MAC_EXT_LOOPBACK (1 << 22) | ||
1060 | # define MAC_DISABLE_RX_OWN (1 << 23) | ||
1061 | # define MAC_BIG_ENDIAN (1 << 30) | ||
1062 | # define MAC_RX_ALL (1 << 31) | ||
1063 | #define MAC_ADDRESS_HIGH 0x4 | ||
1064 | #define MAC_ADDRESS_LOW 0x8 | ||
1065 | #define MAC_MCAST_HIGH 0xC | ||
1066 | #define MAC_MCAST_LOW 0x10 | ||
1067 | #define MAC_MII_CNTRL 0x14 | ||
1068 | # define MAC_MII_BUSY (1 << 0) | ||
1069 | # define MAC_MII_READ 0 | ||
1070 | # define MAC_MII_WRITE (1 << 1) | ||
1071 | # define MAC_SET_MII_SELECT_REG(X) (((X) & 0x1f) << 6) | ||
1072 | # define MAC_SET_MII_SELECT_PHY(X) (((X) & 0x1f) << 11) | ||
1073 | #define MAC_MII_DATA 0x18 | ||
1074 | #define MAC_FLOW_CNTRL 0x1C | ||
1075 | # define MAC_FLOW_CNTRL_BUSY (1 << 0) | ||
1076 | # define MAC_FLOW_CNTRL_ENABLE (1 << 1) | ||
1077 | # define MAC_PASS_CONTROL (1 << 2) | ||
1078 | # define MAC_SET_PAUSE(X) (((X) & 0xffff) << 16) | ||
1079 | #define MAC_VLAN1_TAG 0x20 | ||
1080 | #define MAC_VLAN2_TAG 0x24 | ||
1081 | |||
1082 | /* Ethernet Controller Enable */ | ||
1083 | |||
1084 | # define MAC_EN_CLOCK_ENABLE (1 << 0) | ||
1085 | # define MAC_EN_RESET0 (1 << 1) | ||
1086 | # define MAC_EN_TOSS (0 << 2) | ||
1087 | # define MAC_EN_CACHEABLE (1 << 3) | ||
1088 | # define MAC_EN_RESET1 (1 << 4) | ||
1089 | # define MAC_EN_RESET2 (1 << 5) | ||
1090 | # define MAC_DMA_RESET (1 << 6) | ||
1091 | |||
1092 | /* Ethernet Controller DMA Channels */ | ||
1093 | |||
1094 | #define MAC0_TX_DMA_ADDR 0xB4004000 | ||
1095 | #define MAC1_TX_DMA_ADDR 0xB4004200 | ||
1096 | /* offsets from MAC_TX_RING_ADDR address */ | ||
1097 | #define MAC_TX_BUFF0_STATUS 0x0 | ||
1098 | # define TX_FRAME_ABORTED (1 << 0) | ||
1099 | # define TX_JAB_TIMEOUT (1 << 1) | ||
1100 | # define TX_NO_CARRIER (1 << 2) | ||
1101 | # define TX_LOSS_CARRIER (1 << 3) | ||
1102 | # define TX_EXC_DEF (1 << 4) | ||
1103 | # define TX_LATE_COLL_ABORT (1 << 5) | ||
1104 | # define TX_EXC_COLL (1 << 6) | ||
1105 | # define TX_UNDERRUN (1 << 7) | ||
1106 | # define TX_DEFERRED (1 << 8) | ||
1107 | # define TX_LATE_COLL (1 << 9) | ||
1108 | # define TX_COLL_CNT_MASK (0xF << 10) | ||
1109 | # define TX_PKT_RETRY (1 << 31) | ||
1110 | #define MAC_TX_BUFF0_ADDR 0x4 | ||
1111 | # define TX_DMA_ENABLE (1 << 0) | ||
1112 | # define TX_T_DONE (1 << 1) | ||
1113 | # define TX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3) | ||
1114 | #define MAC_TX_BUFF0_LEN 0x8 | ||
1115 | #define MAC_TX_BUFF1_STATUS 0x10 | ||
1116 | #define MAC_TX_BUFF1_ADDR 0x14 | ||
1117 | #define MAC_TX_BUFF1_LEN 0x18 | ||
1118 | #define MAC_TX_BUFF2_STATUS 0x20 | ||
1119 | #define MAC_TX_BUFF2_ADDR 0x24 | ||
1120 | #define MAC_TX_BUFF2_LEN 0x28 | ||
1121 | #define MAC_TX_BUFF3_STATUS 0x30 | ||
1122 | #define MAC_TX_BUFF3_ADDR 0x34 | ||
1123 | #define MAC_TX_BUFF3_LEN 0x38 | ||
1124 | |||
1125 | #define MAC0_RX_DMA_ADDR 0xB4004100 | ||
1126 | #define MAC1_RX_DMA_ADDR 0xB4004300 | ||
1127 | /* offsets from MAC_RX_RING_ADDR */ | ||
1128 | #define MAC_RX_BUFF0_STATUS 0x0 | ||
1129 | # define RX_FRAME_LEN_MASK 0x3fff | ||
1130 | # define RX_WDOG_TIMER (1 << 14) | ||
1131 | # define RX_RUNT (1 << 15) | ||
1132 | # define RX_OVERLEN (1 << 16) | ||
1133 | # define RX_COLL (1 << 17) | ||
1134 | # define RX_ETHER (1 << 18) | ||
1135 | # define RX_MII_ERROR (1 << 19) | ||
1136 | # define RX_DRIBBLING (1 << 20) | ||
1137 | # define RX_CRC_ERROR (1 << 21) | ||
1138 | # define RX_VLAN1 (1 << 22) | ||
1139 | # define RX_VLAN2 (1 << 23) | ||
1140 | # define RX_LEN_ERROR (1 << 24) | ||
1141 | # define RX_CNTRL_FRAME (1 << 25) | ||
1142 | # define RX_U_CNTRL_FRAME (1 << 26) | ||
1143 | # define RX_MCAST_FRAME (1 << 27) | ||
1144 | # define RX_BCAST_FRAME (1 << 28) | ||
1145 | # define RX_FILTER_FAIL (1 << 29) | ||
1146 | # define RX_PACKET_FILTER (1 << 30) | ||
1147 | # define RX_MISSED_FRAME (1 << 31) | ||
1148 | |||
1149 | # define RX_ERROR (RX_WDOG_TIMER | RX_RUNT | RX_OVERLEN | \ | ||
1150 | RX_COLL | RX_MII_ERROR | RX_CRC_ERROR | \ | ||
1151 | RX_LEN_ERROR | RX_U_CNTRL_FRAME | RX_MISSED_FRAME) | ||
1152 | #define MAC_RX_BUFF0_ADDR 0x4 | ||
1153 | # define RX_DMA_ENABLE (1 << 0) | ||
1154 | # define RX_T_DONE (1 << 1) | ||
1155 | # define RX_GET_DMA_BUFFER(X) (((X) >> 2) & 0x3) | ||
1156 | # define RX_SET_BUFF_ADDR(X) ((X) & 0xffffffc0) | ||
1157 | #define MAC_RX_BUFF1_STATUS 0x10 | ||
1158 | #define MAC_RX_BUFF1_ADDR 0x14 | ||
1159 | #define MAC_RX_BUFF2_STATUS 0x20 | ||
1160 | #define MAC_RX_BUFF2_ADDR 0x24 | ||
1161 | #define MAC_RX_BUFF3_STATUS 0x30 | ||
1162 | #define MAC_RX_BUFF3_ADDR 0x34 | ||
1163 | |||
1164 | /* SSIO */ | ||
1165 | #define SSI0_STATUS 0xB1600000 | ||
1166 | # define SSI_STATUS_BF (1 << 4) | ||
1167 | # define SSI_STATUS_OF (1 << 3) | ||
1168 | # define SSI_STATUS_UF (1 << 2) | ||
1169 | # define SSI_STATUS_D (1 << 1) | ||
1170 | # define SSI_STATUS_B (1 << 0) | ||
1171 | #define SSI0_INT 0xB1600004 | ||
1172 | # define SSI_INT_OI (1 << 3) | ||
1173 | # define SSI_INT_UI (1 << 2) | ||
1174 | # define SSI_INT_DI (1 << 1) | ||
1175 | #define SSI0_INT_ENABLE 0xB1600008 | ||
1176 | # define SSI_INTE_OIE (1 << 3) | ||
1177 | # define SSI_INTE_UIE (1 << 2) | ||
1178 | # define SSI_INTE_DIE (1 << 1) | ||
1179 | #define SSI0_CONFIG 0xB1600020 | ||
1180 | # define SSI_CONFIG_AO (1 << 24) | ||
1181 | # define SSI_CONFIG_DO (1 << 23) | ||
1182 | # define SSI_CONFIG_ALEN_BIT 20 | ||
1183 | # define SSI_CONFIG_ALEN_MASK (0x7 << 20) | ||
1184 | # define SSI_CONFIG_DLEN_BIT 16 | ||
1185 | # define SSI_CONFIG_DLEN_MASK (0x7 << 16) | ||
1186 | # define SSI_CONFIG_DD (1 << 11) | ||
1187 | # define SSI_CONFIG_AD (1 << 10) | ||
1188 | # define SSI_CONFIG_BM_BIT 8 | ||
1189 | # define SSI_CONFIG_BM_MASK (0x3 << 8) | ||
1190 | # define SSI_CONFIG_CE (1 << 7) | ||
1191 | # define SSI_CONFIG_DP (1 << 6) | ||
1192 | # define SSI_CONFIG_DL (1 << 5) | ||
1193 | # define SSI_CONFIG_EP (1 << 4) | ||
1194 | #define SSI0_ADATA 0xB1600024 | ||
1195 | # define SSI_AD_D (1 << 24) | ||
1196 | # define SSI_AD_ADDR_BIT 16 | ||
1197 | # define SSI_AD_ADDR_MASK (0xff << 16) | ||
1198 | # define SSI_AD_DATA_BIT 0 | ||
1199 | # define SSI_AD_DATA_MASK (0xfff << 0) | ||
1200 | #define SSI0_CLKDIV 0xB1600028 | ||
1201 | #define SSI0_CONTROL 0xB1600100 | ||
1202 | # define SSI_CONTROL_CD (1 << 1) | ||
1203 | # define SSI_CONTROL_E (1 << 0) | ||
1204 | |||
1205 | /* SSI1 */ | ||
1206 | #define SSI1_STATUS 0xB1680000 | ||
1207 | #define SSI1_INT 0xB1680004 | ||
1208 | #define SSI1_INT_ENABLE 0xB1680008 | ||
1209 | #define SSI1_CONFIG 0xB1680020 | ||
1210 | #define SSI1_ADATA 0xB1680024 | ||
1211 | #define SSI1_CLKDIV 0xB1680028 | ||
1212 | #define SSI1_ENABLE 0xB1680100 | ||
1213 | |||
1214 | /* | ||
1215 | * Register content definitions | ||
1216 | */ | ||
1217 | #define SSI_STATUS_BF (1 << 4) | ||
1218 | #define SSI_STATUS_OF (1 << 3) | ||
1219 | #define SSI_STATUS_UF (1 << 2) | ||
1220 | #define SSI_STATUS_D (1 << 1) | ||
1221 | #define SSI_STATUS_B (1 << 0) | ||
1222 | |||
1223 | /* SSI_INT */ | ||
1224 | #define SSI_INT_OI (1 << 3) | ||
1225 | #define SSI_INT_UI (1 << 2) | ||
1226 | #define SSI_INT_DI (1 << 1) | ||
1227 | |||
1228 | /* SSI_INTEN */ | ||
1229 | #define SSI_INTEN_OIE (1 << 3) | ||
1230 | #define SSI_INTEN_UIE (1 << 2) | ||
1231 | #define SSI_INTEN_DIE (1 << 1) | ||
1232 | |||
1233 | #define SSI_CONFIG_AO (1 << 24) | ||
1234 | #define SSI_CONFIG_DO (1 << 23) | ||
1235 | #define SSI_CONFIG_ALEN (7 << 20) | ||
1236 | #define SSI_CONFIG_DLEN (15 << 16) | ||
1237 | #define SSI_CONFIG_DD (1 << 11) | ||
1238 | #define SSI_CONFIG_AD (1 << 10) | ||
1239 | #define SSI_CONFIG_BM (3 << 8) | ||
1240 | #define SSI_CONFIG_CE (1 << 7) | ||
1241 | #define SSI_CONFIG_DP (1 << 6) | ||
1242 | #define SSI_CONFIG_DL (1 << 5) | ||
1243 | #define SSI_CONFIG_EP (1 << 4) | ||
1244 | #define SSI_CONFIG_ALEN_N(N) ((N-1) << 20) | ||
1245 | #define SSI_CONFIG_DLEN_N(N) ((N-1) << 16) | ||
1246 | #define SSI_CONFIG_BM_HI (0 << 8) | ||
1247 | #define SSI_CONFIG_BM_LO (1 << 8) | ||
1248 | #define SSI_CONFIG_BM_CY (2 << 8) | ||
1249 | |||
1250 | #define SSI_ADATA_D (1 << 24) | ||
1251 | #define SSI_ADATA_ADDR (0xFF << 16) | ||
1252 | #define SSI_ADATA_DATA 0x0FFF | ||
1253 | #define SSI_ADATA_ADDR_N(N) (N << 16) | ||
1254 | |||
1255 | #define SSI_ENABLE_CD (1 << 1) | ||
1256 | #define SSI_ENABLE_E (1 << 0) | ||
1257 | |||
1258 | |||
1259 | /* | ||
1260 | * The IrDA peripheral has an IRFIRSEL pin, but on the DB/PB boards it's not | ||
1261 | * used to select FIR/SIR mode on the transceiver but as a GPIO. Instead a | ||
1262 | * CPLD has to be told about the mode. | ||
1263 | */ | ||
1264 | #define AU1000_IRDA_PHY_MODE_OFF 0 | ||
1265 | #define AU1000_IRDA_PHY_MODE_SIR 1 | ||
1266 | #define AU1000_IRDA_PHY_MODE_FIR 2 | ||
1267 | |||
1268 | struct au1k_irda_platform_data { | ||
1269 | void(*set_phy_mode)(int mode); | ||
1270 | }; | ||
1271 | |||
1272 | |||
1273 | /* GPIO */ | ||
1274 | #define SYS_PINFUNC 0xB190002C | ||
1275 | # define SYS_PF_USB (1 << 15) /* 2nd USB device/host */ | ||
1276 | # define SYS_PF_U3 (1 << 14) /* GPIO23/U3TXD */ | ||
1277 | # define SYS_PF_U2 (1 << 13) /* GPIO22/U2TXD */ | ||
1278 | # define SYS_PF_U1 (1 << 12) /* GPIO21/U1TXD */ | ||
1279 | # define SYS_PF_SRC (1 << 11) /* GPIO6/SROMCKE */ | ||
1280 | # define SYS_PF_CK5 (1 << 10) /* GPIO3/CLK5 */ | ||
1281 | # define SYS_PF_CK4 (1 << 9) /* GPIO2/CLK4 */ | ||
1282 | # define SYS_PF_IRF (1 << 8) /* GPIO15/IRFIRSEL */ | ||
1283 | # define SYS_PF_UR3 (1 << 7) /* GPIO[14:9]/UART3 */ | ||
1284 | # define SYS_PF_I2D (1 << 6) /* GPIO8/I2SDI */ | ||
1285 | # define SYS_PF_I2S (1 << 5) /* I2S/GPIO[29:31] */ | ||
1286 | # define SYS_PF_NI2 (1 << 4) /* NI2/GPIO[24:28] */ | ||
1287 | # define SYS_PF_U0 (1 << 3) /* U0TXD/GPIO20 */ | ||
1288 | # define SYS_PF_RD (1 << 2) /* IRTXD/GPIO19 */ | ||
1289 | # define SYS_PF_A97 (1 << 1) /* AC97/SSL1 */ | ||
1290 | # define SYS_PF_S0 (1 << 0) /* SSI_0/GPIO[16:18] */ | ||
1291 | |||
1292 | /* Au1100 only */ | ||
1293 | # define SYS_PF_PC (1 << 18) /* PCMCIA/GPIO[207:204] */ | ||
1294 | # define SYS_PF_LCD (1 << 17) /* extern lcd/GPIO[203:200] */ | ||
1295 | # define SYS_PF_CS (1 << 16) /* EXTCLK0/32KHz to gpio2 */ | ||
1296 | # define SYS_PF_EX0 (1 << 9) /* GPIO2/clock */ | ||
1297 | |||
1298 | /* Au1550 only. Redefines lots of pins */ | ||
1299 | # define SYS_PF_PSC2_MASK (7 << 17) | ||
1300 | # define SYS_PF_PSC2_AC97 0 | ||
1301 | # define SYS_PF_PSC2_SPI 0 | ||
1302 | # define SYS_PF_PSC2_I2S (1 << 17) | ||
1303 | # define SYS_PF_PSC2_SMBUS (3 << 17) | ||
1304 | # define SYS_PF_PSC2_GPIO (7 << 17) | ||
1305 | # define SYS_PF_PSC3_MASK (7 << 20) | ||
1306 | # define SYS_PF_PSC3_AC97 0 | ||
1307 | # define SYS_PF_PSC3_SPI 0 | ||
1308 | # define SYS_PF_PSC3_I2S (1 << 20) | ||
1309 | # define SYS_PF_PSC3_SMBUS (3 << 20) | ||
1310 | # define SYS_PF_PSC3_GPIO (7 << 20) | ||
1311 | # define SYS_PF_PSC1_S1 (1 << 1) | ||
1312 | # define SYS_PF_MUST_BE_SET ((1 << 5) | (1 << 2)) | ||
1313 | |||
1314 | /* Au1200 only */ | ||
1315 | #define SYS_PINFUNC_DMA (1 << 31) | ||
1316 | #define SYS_PINFUNC_S0A (1 << 30) | ||
1317 | #define SYS_PINFUNC_S1A (1 << 29) | ||
1318 | #define SYS_PINFUNC_LP0 (1 << 28) | ||
1319 | #define SYS_PINFUNC_LP1 (1 << 27) | ||
1320 | #define SYS_PINFUNC_LD16 (1 << 26) | ||
1321 | #define SYS_PINFUNC_LD8 (1 << 25) | ||
1322 | #define SYS_PINFUNC_LD1 (1 << 24) | ||
1323 | #define SYS_PINFUNC_LD0 (1 << 23) | ||
1324 | #define SYS_PINFUNC_P1A (3 << 21) | ||
1325 | #define SYS_PINFUNC_P1B (1 << 20) | ||
1326 | #define SYS_PINFUNC_FS3 (1 << 19) | ||
1327 | #define SYS_PINFUNC_P0A (3 << 17) | ||
1328 | #define SYS_PINFUNC_CS (1 << 16) | ||
1329 | #define SYS_PINFUNC_CIM (1 << 15) | ||
1330 | #define SYS_PINFUNC_P1C (1 << 14) | ||
1331 | #define SYS_PINFUNC_U1T (1 << 12) | ||
1332 | #define SYS_PINFUNC_U1R (1 << 11) | ||
1333 | #define SYS_PINFUNC_EX1 (1 << 10) | ||
1334 | #define SYS_PINFUNC_EX0 (1 << 9) | ||
1335 | #define SYS_PINFUNC_U0R (1 << 8) | ||
1336 | #define SYS_PINFUNC_MC (1 << 7) | ||
1337 | #define SYS_PINFUNC_S0B (1 << 6) | ||
1338 | #define SYS_PINFUNC_S0C (1 << 5) | ||
1339 | #define SYS_PINFUNC_P0B (1 << 4) | ||
1340 | #define SYS_PINFUNC_U0T (1 << 3) | ||
1341 | #define SYS_PINFUNC_S1B (1 << 2) | ||
1342 | |||
1343 | /* Power Management */ | ||
1344 | #define SYS_SCRATCH0 0xB1900018 | ||
1345 | #define SYS_SCRATCH1 0xB190001C | ||
1346 | #define SYS_WAKEMSK 0xB1900034 | ||
1347 | #define SYS_ENDIAN 0xB1900038 | ||
1348 | #define SYS_POWERCTRL 0xB190003C | ||
1349 | #define SYS_WAKESRC 0xB190005C | ||
1350 | #define SYS_SLPPWR 0xB1900078 | ||
1351 | #define SYS_SLEEP 0xB190007C | ||
1352 | |||
1353 | #define SYS_WAKEMSK_D2 (1 << 9) | ||
1354 | #define SYS_WAKEMSK_M2 (1 << 8) | ||
1355 | #define SYS_WAKEMSK_GPIO(x) (1 << (x)) | ||
1356 | |||
1357 | /* Clock Controller */ | ||
1358 | #define SYS_FREQCTRL0 0xB1900020 | ||
1359 | # define SYS_FC_FRDIV2_BIT 22 | ||
1360 | # define SYS_FC_FRDIV2_MASK (0xff << SYS_FC_FRDIV2_BIT) | ||
1361 | # define SYS_FC_FE2 (1 << 21) | ||
1362 | # define SYS_FC_FS2 (1 << 20) | ||
1363 | # define SYS_FC_FRDIV1_BIT 12 | ||
1364 | # define SYS_FC_FRDIV1_MASK (0xff << SYS_FC_FRDIV1_BIT) | ||
1365 | # define SYS_FC_FE1 (1 << 11) | ||
1366 | # define SYS_FC_FS1 (1 << 10) | ||
1367 | # define SYS_FC_FRDIV0_BIT 2 | ||
1368 | # define SYS_FC_FRDIV0_MASK (0xff << SYS_FC_FRDIV0_BIT) | ||
1369 | # define SYS_FC_FE0 (1 << 1) | ||
1370 | # define SYS_FC_FS0 (1 << 0) | ||
1371 | #define SYS_FREQCTRL1 0xB1900024 | ||
1372 | # define SYS_FC_FRDIV5_BIT 22 | ||
1373 | # define SYS_FC_FRDIV5_MASK (0xff << SYS_FC_FRDIV5_BIT) | ||
1374 | # define SYS_FC_FE5 (1 << 21) | ||
1375 | # define SYS_FC_FS5 (1 << 20) | ||
1376 | # define SYS_FC_FRDIV4_BIT 12 | ||
1377 | # define SYS_FC_FRDIV4_MASK (0xff << SYS_FC_FRDIV4_BIT) | ||
1378 | # define SYS_FC_FE4 (1 << 11) | ||
1379 | # define SYS_FC_FS4 (1 << 10) | ||
1380 | # define SYS_FC_FRDIV3_BIT 2 | ||
1381 | # define SYS_FC_FRDIV3_MASK (0xff << SYS_FC_FRDIV3_BIT) | ||
1382 | # define SYS_FC_FE3 (1 << 1) | ||
1383 | # define SYS_FC_FS3 (1 << 0) | ||
1384 | #define SYS_CLKSRC 0xB1900028 | ||
1385 | # define SYS_CS_ME1_BIT 27 | ||
1386 | # define SYS_CS_ME1_MASK (0x7 << SYS_CS_ME1_BIT) | ||
1387 | # define SYS_CS_DE1 (1 << 26) | ||
1388 | # define SYS_CS_CE1 (1 << 25) | ||
1389 | # define SYS_CS_ME0_BIT 22 | ||
1390 | # define SYS_CS_ME0_MASK (0x7 << SYS_CS_ME0_BIT) | ||
1391 | # define SYS_CS_DE0 (1 << 21) | ||
1392 | # define SYS_CS_CE0 (1 << 20) | ||
1393 | # define SYS_CS_MI2_BIT 17 | ||
1394 | # define SYS_CS_MI2_MASK (0x7 << SYS_CS_MI2_BIT) | ||
1395 | # define SYS_CS_DI2 (1 << 16) | ||
1396 | # define SYS_CS_CI2 (1 << 15) | ||
1397 | |||
1398 | # define SYS_CS_ML_BIT 7 | ||
1399 | # define SYS_CS_ML_MASK (0x7 << SYS_CS_ML_BIT) | ||
1400 | # define SYS_CS_DL (1 << 6) | ||
1401 | # define SYS_CS_CL (1 << 5) | ||
1402 | |||
1403 | # define SYS_CS_MUH_BIT 12 | ||
1404 | # define SYS_CS_MUH_MASK (0x7 << SYS_CS_MUH_BIT) | ||
1405 | # define SYS_CS_DUH (1 << 11) | ||
1406 | # define SYS_CS_CUH (1 << 10) | ||
1407 | # define SYS_CS_MUD_BIT 7 | ||
1408 | # define SYS_CS_MUD_MASK (0x7 << SYS_CS_MUD_BIT) | ||
1409 | # define SYS_CS_DUD (1 << 6) | ||
1410 | # define SYS_CS_CUD (1 << 5) | ||
1411 | |||
1412 | # define SYS_CS_MIR_BIT 2 | ||
1413 | # define SYS_CS_MIR_MASK (0x7 << SYS_CS_MIR_BIT) | ||
1414 | # define SYS_CS_DIR (1 << 1) | ||
1415 | # define SYS_CS_CIR (1 << 0) | ||
1416 | |||
1417 | # define SYS_CS_MUX_AUX 0x1 | ||
1418 | # define SYS_CS_MUX_FQ0 0x2 | ||
1419 | # define SYS_CS_MUX_FQ1 0x3 | ||
1420 | # define SYS_CS_MUX_FQ2 0x4 | ||
1421 | # define SYS_CS_MUX_FQ3 0x5 | ||
1422 | # define SYS_CS_MUX_FQ4 0x6 | ||
1423 | # define SYS_CS_MUX_FQ5 0x7 | ||
1424 | #define SYS_CPUPLL 0xB1900060 | ||
1425 | #define SYS_AUXPLL 0xB1900064 | ||
1426 | |||
1427 | /* AC97 Controller */ | ||
1428 | #define AC97C_CONFIG 0xB0000000 | ||
1429 | # define AC97C_RECV_SLOTS_BIT 13 | ||
1430 | # define AC97C_RECV_SLOTS_MASK (0x3ff << AC97C_RECV_SLOTS_BIT) | ||
1431 | # define AC97C_XMIT_SLOTS_BIT 3 | ||
1432 | # define AC97C_XMIT_SLOTS_MASK (0x3ff << AC97C_XMIT_SLOTS_BIT) | ||
1433 | # define AC97C_SG (1 << 2) | ||
1434 | # define AC97C_SYNC (1 << 1) | ||
1435 | # define AC97C_RESET (1 << 0) | ||
1436 | #define AC97C_STATUS 0xB0000004 | ||
1437 | # define AC97C_XU (1 << 11) | ||
1438 | # define AC97C_XO (1 << 10) | ||
1439 | # define AC97C_RU (1 << 9) | ||
1440 | # define AC97C_RO (1 << 8) | ||
1441 | # define AC97C_READY (1 << 7) | ||
1442 | # define AC97C_CP (1 << 6) | ||
1443 | # define AC97C_TR (1 << 5) | ||
1444 | # define AC97C_TE (1 << 4) | ||
1445 | # define AC97C_TF (1 << 3) | ||
1446 | # define AC97C_RR (1 << 2) | ||
1447 | # define AC97C_RE (1 << 1) | ||
1448 | # define AC97C_RF (1 << 0) | ||
1449 | #define AC97C_DATA 0xB0000008 | ||
1450 | #define AC97C_CMD 0xB000000C | ||
1451 | # define AC97C_WD_BIT 16 | ||
1452 | # define AC97C_READ (1 << 7) | ||
1453 | # define AC97C_INDEX_MASK 0x7f | ||
1454 | #define AC97C_CNTRL 0xB0000010 | ||
1455 | # define AC97C_RS (1 << 1) | ||
1456 | # define AC97C_CE (1 << 0) | ||
1457 | |||
1458 | |||
1459 | /* The PCI chip selects are outside the 32bit space, and since we can't | ||
1460 | * just program the 36bit addresses into BARs, we have to take a chunk | ||
1461 | * out of the 32bit space and reserve it for PCI. When these addresses | ||
1462 | * are ioremap()ed, they'll be fixed up to the real 36bit address before | ||
1463 | * being passed to the real ioremap function. | ||
1464 | */ | ||
1465 | #define ALCHEMY_PCI_MEMWIN_START (AU1500_PCI_MEM_PHYS_ADDR >> 4) | ||
1466 | #define ALCHEMY_PCI_MEMWIN_END (ALCHEMY_PCI_MEMWIN_START + 0x0FFFFFFF) | ||
1467 | |||
1468 | /* for PCI IO it's simpler because we get to do the ioremap ourselves and then | ||
1469 | * adjust the device's resources. | ||
1470 | */ | ||
1471 | #define ALCHEMY_PCI_IOWIN_START 0x00001000 | ||
1472 | #define ALCHEMY_PCI_IOWIN_END 0x0000FFFF | ||
1473 | |||
1474 | #ifdef CONFIG_PCI | ||
1475 | |||
1476 | #define IOPORT_RESOURCE_START 0x00001000 /* skip legacy probing */ | ||
1477 | #define IOPORT_RESOURCE_END 0xffffffff | ||
1478 | #define IOMEM_RESOURCE_START 0x10000000 | ||
1479 | #define IOMEM_RESOURCE_END 0xfffffffffULL | ||
1480 | |||
1481 | #else | ||
1482 | |||
1483 | /* Don't allow any legacy ports probing */ | ||
1484 | #define IOPORT_RESOURCE_START 0x10000000 | ||
1485 | #define IOPORT_RESOURCE_END 0xffffffff | ||
1486 | #define IOMEM_RESOURCE_START 0x10000000 | ||
1487 | #define IOMEM_RESOURCE_END 0xfffffffffULL | ||
1488 | |||
1489 | #endif | ||
1490 | |||
1491 | /* PCI controller block register offsets */ | ||
1492 | #define PCI_REG_CMEM 0x0000 | ||
1493 | #define PCI_REG_CONFIG 0x0004 | ||
1494 | #define PCI_REG_B2BMASK_CCH 0x0008 | ||
1495 | #define PCI_REG_B2BBASE0_VID 0x000C | ||
1496 | #define PCI_REG_B2BBASE1_SID 0x0010 | ||
1497 | #define PCI_REG_MWMASK_DEV 0x0014 | ||
1498 | #define PCI_REG_MWBASE_REV_CCL 0x0018 | ||
1499 | #define PCI_REG_ERR_ADDR 0x001C | ||
1500 | #define PCI_REG_SPEC_INTACK 0x0020 | ||
1501 | #define PCI_REG_ID 0x0100 | ||
1502 | #define PCI_REG_STATCMD 0x0104 | ||
1503 | #define PCI_REG_CLASSREV 0x0108 | ||
1504 | #define PCI_REG_PARAM 0x010C | ||
1505 | #define PCI_REG_MBAR 0x0110 | ||
1506 | #define PCI_REG_TIMEOUT 0x0140 | ||
1507 | |||
1508 | /* PCI controller block register bits */ | ||
1509 | #define PCI_CMEM_E (1 << 28) /* enable cacheable memory */ | ||
1510 | #define PCI_CMEM_CMBASE(x) (((x) & 0x3fff) << 14) | ||
1511 | #define PCI_CMEM_CMMASK(x) ((x) & 0x3fff) | ||
1512 | #define PCI_CONFIG_ERD (1 << 27) /* pci error during R/W */ | ||
1513 | #define PCI_CONFIG_ET (1 << 26) /* error in target mode */ | ||
1514 | #define PCI_CONFIG_EF (1 << 25) /* fatal error */ | ||
1515 | #define PCI_CONFIG_EP (1 << 24) /* parity error */ | ||
1516 | #define PCI_CONFIG_EM (1 << 23) /* multiple errors */ | ||
1517 | #define PCI_CONFIG_BM (1 << 22) /* bad master error */ | ||
1518 | #define PCI_CONFIG_PD (1 << 20) /* PCI Disable */ | ||
1519 | #define PCI_CONFIG_BME (1 << 19) /* Byte Mask Enable for reads */ | ||
1520 | #define PCI_CONFIG_NC (1 << 16) /* mark mem access non-coherent */ | ||
1521 | #define PCI_CONFIG_IA (1 << 15) /* INTA# enabled (target mode) */ | ||
1522 | #define PCI_CONFIG_IP (1 << 13) /* int on PCI_PERR# */ | ||
1523 | #define PCI_CONFIG_IS (1 << 12) /* int on PCI_SERR# */ | ||
1524 | #define PCI_CONFIG_IMM (1 << 11) /* int on master abort */ | ||
1525 | #define PCI_CONFIG_ITM (1 << 10) /* int on target abort (as master) */ | ||
1526 | #define PCI_CONFIG_ITT (1 << 9) /* int on target abort (as target) */ | ||
1527 | #define PCI_CONFIG_IPB (1 << 8) /* int on PERR# in bus master acc */ | ||
1528 | #define PCI_CONFIG_SIC_NO (0 << 6) /* no byte mask changes */ | ||
1529 | #define PCI_CONFIG_SIC_BA_ADR (1 << 6) /* on byte/hw acc, invert adr bits */ | ||
1530 | #define PCI_CONFIG_SIC_HWA_DAT (2 << 6) /* on halfword acc, swap data */ | ||
1531 | #define PCI_CONFIG_SIC_ALL (3 << 6) /* swap data bytes on all accesses */ | ||
1532 | #define PCI_CONFIG_ST (1 << 5) /* swap data by target transactions */ | ||
1533 | #define PCI_CONFIG_SM (1 << 4) /* swap data from PCI ctl */ | ||
1534 | #define PCI_CONFIG_AEN (1 << 3) /* enable internal arbiter */ | ||
1535 | #define PCI_CONFIG_R2H (1 << 2) /* REQ2# to hi-prio arbiter */ | ||
1536 | #define PCI_CONFIG_R1H (1 << 1) /* REQ1# to hi-prio arbiter */ | ||
1537 | #define PCI_CONFIG_CH (1 << 0) /* PCI ctl to hi-prio arbiter */ | ||
1538 | #define PCI_B2BMASK_B2BMASK(x) (((x) & 0xffff) << 16) | ||
1539 | #define PCI_B2BMASK_CCH(x) ((x) & 0xffff) /* 16 upper bits of class code */ | ||
1540 | #define PCI_B2BBASE0_VID_B0(x) (((x) & 0xffff) << 16) | ||
1541 | #define PCI_B2BBASE0_VID_SV(x) ((x) & 0xffff) | ||
1542 | #define PCI_B2BBASE1_SID_B1(x) (((x) & 0xffff) << 16) | ||
1543 | #define PCI_B2BBASE1_SID_SI(x) ((x) & 0xffff) | ||
1544 | #define PCI_MWMASKDEV_MWMASK(x) (((x) & 0xffff) << 16) | ||
1545 | #define PCI_MWMASKDEV_DEVID(x) ((x) & 0xffff) | ||
1546 | #define PCI_MWBASEREVCCL_BASE(x) (((x) & 0xffff) << 16) | ||
1547 | #define PCI_MWBASEREVCCL_REV(x) (((x) & 0xff) << 8) | ||
1548 | #define PCI_MWBASEREVCCL_CCL(x) ((x) & 0xff) | ||
1549 | #define PCI_ID_DID(x) (((x) & 0xffff) << 16) | ||
1550 | #define PCI_ID_VID(x) ((x) & 0xffff) | ||
1551 | #define PCI_STATCMD_STATUS(x) (((x) & 0xffff) << 16) | ||
1552 | #define PCI_STATCMD_CMD(x) ((x) & 0xffff) | ||
1553 | #define PCI_CLASSREV_CLASS(x) (((x) & 0x00ffffff) << 8) | ||
1554 | #define PCI_CLASSREV_REV(x) ((x) & 0xff) | ||
1555 | #define PCI_PARAM_BIST(x) (((x) & 0xff) << 24) | ||
1556 | #define PCI_PARAM_HT(x) (((x) & 0xff) << 16) | ||
1557 | #define PCI_PARAM_LT(x) (((x) & 0xff) << 8) | ||
1558 | #define PCI_PARAM_CLS(x) ((x) & 0xff) | ||
1559 | #define PCI_TIMEOUT_RETRIES(x) (((x) & 0xff) << 8) /* max retries */ | ||
1560 | #define PCI_TIMEOUT_TO(x) ((x) & 0xff) /* target ready timeout */ | ||
1561 | |||
1562 | #endif | 1211 | #endif |
diff --git a/arch/mips/include/asm/mach-au1x00/au1000_dma.h b/arch/mips/include/asm/mach-au1x00/au1000_dma.h index 7cedca5a305c..0a0cd4270c6f 100644 --- a/arch/mips/include/asm/mach-au1x00/au1000_dma.h +++ b/arch/mips/include/asm/mach-au1x00/au1000_dma.h | |||
@@ -106,7 +106,7 @@ enum { | |||
106 | struct dma_chan { | 106 | struct dma_chan { |
107 | int dev_id; /* this channel is allocated if >= 0, */ | 107 | int dev_id; /* this channel is allocated if >= 0, */ |
108 | /* free otherwise */ | 108 | /* free otherwise */ |
109 | unsigned int io; | 109 | void __iomem *io; |
110 | const char *dev_str; | 110 | const char *dev_str; |
111 | int irq; | 111 | int irq; |
112 | void *irq_dev; | 112 | void *irq_dev; |
@@ -157,7 +157,7 @@ static inline void enable_dma_buffer0(unsigned int dmanr) | |||
157 | 157 | ||
158 | if (!chan) | 158 | if (!chan) |
159 | return; | 159 | return; |
160 | au_writel(DMA_BE0, chan->io + DMA_MODE_SET); | 160 | __raw_writel(DMA_BE0, chan->io + DMA_MODE_SET); |
161 | } | 161 | } |
162 | 162 | ||
163 | static inline void enable_dma_buffer1(unsigned int dmanr) | 163 | static inline void enable_dma_buffer1(unsigned int dmanr) |
@@ -166,7 +166,7 @@ static inline void enable_dma_buffer1(unsigned int dmanr) | |||
166 | 166 | ||
167 | if (!chan) | 167 | if (!chan) |
168 | return; | 168 | return; |
169 | au_writel(DMA_BE1, chan->io + DMA_MODE_SET); | 169 | __raw_writel(DMA_BE1, chan->io + DMA_MODE_SET); |
170 | } | 170 | } |
171 | static inline void enable_dma_buffers(unsigned int dmanr) | 171 | static inline void enable_dma_buffers(unsigned int dmanr) |
172 | { | 172 | { |
@@ -174,7 +174,7 @@ static inline void enable_dma_buffers(unsigned int dmanr) | |||
174 | 174 | ||
175 | if (!chan) | 175 | if (!chan) |
176 | return; | 176 | return; |
177 | au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET); | 177 | __raw_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET); |
178 | } | 178 | } |
179 | 179 | ||
180 | static inline void start_dma(unsigned int dmanr) | 180 | static inline void start_dma(unsigned int dmanr) |
@@ -183,7 +183,7 @@ static inline void start_dma(unsigned int dmanr) | |||
183 | 183 | ||
184 | if (!chan) | 184 | if (!chan) |
185 | return; | 185 | return; |
186 | au_writel(DMA_GO, chan->io + DMA_MODE_SET); | 186 | __raw_writel(DMA_GO, chan->io + DMA_MODE_SET); |
187 | } | 187 | } |
188 | 188 | ||
189 | #define DMA_HALT_POLL 0x5000 | 189 | #define DMA_HALT_POLL 0x5000 |
@@ -195,11 +195,11 @@ static inline void halt_dma(unsigned int dmanr) | |||
195 | 195 | ||
196 | if (!chan) | 196 | if (!chan) |
197 | return; | 197 | return; |
198 | au_writel(DMA_GO, chan->io + DMA_MODE_CLEAR); | 198 | __raw_writel(DMA_GO, chan->io + DMA_MODE_CLEAR); |
199 | 199 | ||
200 | /* Poll the halt bit */ | 200 | /* Poll the halt bit */ |
201 | for (i = 0; i < DMA_HALT_POLL; i++) | 201 | for (i = 0; i < DMA_HALT_POLL; i++) |
202 | if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) | 202 | if (__raw_readl(chan->io + DMA_MODE_READ) & DMA_HALT) |
203 | break; | 203 | break; |
204 | if (i == DMA_HALT_POLL) | 204 | if (i == DMA_HALT_POLL) |
205 | printk(KERN_INFO "halt_dma: HALT poll expired!\n"); | 205 | printk(KERN_INFO "halt_dma: HALT poll expired!\n"); |
@@ -215,7 +215,7 @@ static inline void disable_dma(unsigned int dmanr) | |||
215 | halt_dma(dmanr); | 215 | halt_dma(dmanr); |
216 | 216 | ||
217 | /* Now we can disable the buffers */ | 217 | /* Now we can disable the buffers */ |
218 | au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR); | 218 | __raw_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR); |
219 | } | 219 | } |
220 | 220 | ||
221 | static inline int dma_halted(unsigned int dmanr) | 221 | static inline int dma_halted(unsigned int dmanr) |
@@ -224,7 +224,7 @@ static inline int dma_halted(unsigned int dmanr) | |||
224 | 224 | ||
225 | if (!chan) | 225 | if (!chan) |
226 | return 1; | 226 | return 1; |
227 | return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0; | 227 | return (__raw_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0; |
228 | } | 228 | } |
229 | 229 | ||
230 | /* Initialize a DMA channel. */ | 230 | /* Initialize a DMA channel. */ |
@@ -239,14 +239,14 @@ static inline void init_dma(unsigned int dmanr) | |||
239 | disable_dma(dmanr); | 239 | disable_dma(dmanr); |
240 | 240 | ||
241 | /* Set device FIFO address */ | 241 | /* Set device FIFO address */ |
242 | au_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR); | 242 | __raw_writel(CPHYSADDR(chan->fifo_addr), chan->io + DMA_PERIPHERAL_ADDR); |
243 | 243 | ||
244 | mode = chan->mode | (chan->dev_id << DMA_DID_BIT); | 244 | mode = chan->mode | (chan->dev_id << DMA_DID_BIT); |
245 | if (chan->irq) | 245 | if (chan->irq) |
246 | mode |= DMA_IE; | 246 | mode |= DMA_IE; |
247 | 247 | ||
248 | au_writel(~mode, chan->io + DMA_MODE_CLEAR); | 248 | __raw_writel(~mode, chan->io + DMA_MODE_CLEAR); |
249 | au_writel(mode, chan->io + DMA_MODE_SET); | 249 | __raw_writel(mode, chan->io + DMA_MODE_SET); |
250 | } | 250 | } |
251 | 251 | ||
252 | /* | 252 | /* |
@@ -283,7 +283,7 @@ static inline int get_dma_active_buffer(unsigned int dmanr) | |||
283 | 283 | ||
284 | if (!chan) | 284 | if (!chan) |
285 | return -1; | 285 | return -1; |
286 | return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0; | 286 | return (__raw_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0; |
287 | } | 287 | } |
288 | 288 | ||
289 | /* | 289 | /* |
@@ -304,7 +304,7 @@ static inline void set_dma_fifo_addr(unsigned int dmanr, unsigned int a) | |||
304 | if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05) | 304 | if (chan->dev_id != DMA_ID_GP04 && chan->dev_id != DMA_ID_GP05) |
305 | return; | 305 | return; |
306 | 306 | ||
307 | au_writel(CPHYSADDR(a), chan->io + DMA_PERIPHERAL_ADDR); | 307 | __raw_writel(CPHYSADDR(a), chan->io + DMA_PERIPHERAL_ADDR); |
308 | } | 308 | } |
309 | 309 | ||
310 | /* | 310 | /* |
@@ -316,7 +316,7 @@ static inline void clear_dma_done0(unsigned int dmanr) | |||
316 | 316 | ||
317 | if (!chan) | 317 | if (!chan) |
318 | return; | 318 | return; |
319 | au_writel(DMA_D0, chan->io + DMA_MODE_CLEAR); | 319 | __raw_writel(DMA_D0, chan->io + DMA_MODE_CLEAR); |
320 | } | 320 | } |
321 | 321 | ||
322 | static inline void clear_dma_done1(unsigned int dmanr) | 322 | static inline void clear_dma_done1(unsigned int dmanr) |
@@ -325,7 +325,7 @@ static inline void clear_dma_done1(unsigned int dmanr) | |||
325 | 325 | ||
326 | if (!chan) | 326 | if (!chan) |
327 | return; | 327 | return; |
328 | au_writel(DMA_D1, chan->io + DMA_MODE_CLEAR); | 328 | __raw_writel(DMA_D1, chan->io + DMA_MODE_CLEAR); |
329 | } | 329 | } |
330 | 330 | ||
331 | /* | 331 | /* |
@@ -344,7 +344,7 @@ static inline void set_dma_addr0(unsigned int dmanr, unsigned int a) | |||
344 | 344 | ||
345 | if (!chan) | 345 | if (!chan) |
346 | return; | 346 | return; |
347 | au_writel(a, chan->io + DMA_BUFFER0_START); | 347 | __raw_writel(a, chan->io + DMA_BUFFER0_START); |
348 | } | 348 | } |
349 | 349 | ||
350 | /* | 350 | /* |
@@ -356,7 +356,7 @@ static inline void set_dma_addr1(unsigned int dmanr, unsigned int a) | |||
356 | 356 | ||
357 | if (!chan) | 357 | if (!chan) |
358 | return; | 358 | return; |
359 | au_writel(a, chan->io + DMA_BUFFER1_START); | 359 | __raw_writel(a, chan->io + DMA_BUFFER1_START); |
360 | } | 360 | } |
361 | 361 | ||
362 | 362 | ||
@@ -370,7 +370,7 @@ static inline void set_dma_count0(unsigned int dmanr, unsigned int count) | |||
370 | if (!chan) | 370 | if (!chan) |
371 | return; | 371 | return; |
372 | count &= DMA_COUNT_MASK; | 372 | count &= DMA_COUNT_MASK; |
373 | au_writel(count, chan->io + DMA_BUFFER0_COUNT); | 373 | __raw_writel(count, chan->io + DMA_BUFFER0_COUNT); |
374 | } | 374 | } |
375 | 375 | ||
376 | /* | 376 | /* |
@@ -383,7 +383,7 @@ static inline void set_dma_count1(unsigned int dmanr, unsigned int count) | |||
383 | if (!chan) | 383 | if (!chan) |
384 | return; | 384 | return; |
385 | count &= DMA_COUNT_MASK; | 385 | count &= DMA_COUNT_MASK; |
386 | au_writel(count, chan->io + DMA_BUFFER1_COUNT); | 386 | __raw_writel(count, chan->io + DMA_BUFFER1_COUNT); |
387 | } | 387 | } |
388 | 388 | ||
389 | /* | 389 | /* |
@@ -396,8 +396,8 @@ static inline void set_dma_count(unsigned int dmanr, unsigned int count) | |||
396 | if (!chan) | 396 | if (!chan) |
397 | return; | 397 | return; |
398 | count &= DMA_COUNT_MASK; | 398 | count &= DMA_COUNT_MASK; |
399 | au_writel(count, chan->io + DMA_BUFFER0_COUNT); | 399 | __raw_writel(count, chan->io + DMA_BUFFER0_COUNT); |
400 | au_writel(count, chan->io + DMA_BUFFER1_COUNT); | 400 | __raw_writel(count, chan->io + DMA_BUFFER1_COUNT); |
401 | } | 401 | } |
402 | 402 | ||
403 | /* | 403 | /* |
@@ -410,7 +410,7 @@ static inline unsigned int get_dma_buffer_done(unsigned int dmanr) | |||
410 | 410 | ||
411 | if (!chan) | 411 | if (!chan) |
412 | return 0; | 412 | return 0; |
413 | return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1); | 413 | return __raw_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1); |
414 | } | 414 | } |
415 | 415 | ||
416 | 416 | ||
@@ -437,10 +437,10 @@ static inline int get_dma_residue(unsigned int dmanr) | |||
437 | if (!chan) | 437 | if (!chan) |
438 | return 0; | 438 | return 0; |
439 | 439 | ||
440 | curBufCntReg = (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? | 440 | curBufCntReg = (__raw_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? |
441 | DMA_BUFFER1_COUNT : DMA_BUFFER0_COUNT; | 441 | DMA_BUFFER1_COUNT : DMA_BUFFER0_COUNT; |
442 | 442 | ||
443 | count = au_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK; | 443 | count = __raw_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK; |
444 | 444 | ||
445 | if ((chan->mode & DMA_DW_MASK) == DMA_DW16) | 445 | if ((chan->mode & DMA_DW_MASK) == DMA_DW16) |
446 | count <<= 1; | 446 | count <<= 1; |
diff --git a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h index 796afd051c35..9785e4ebb450 100644 --- a/arch/mips/include/asm/mach-au1x00/gpio-au1000.h +++ b/arch/mips/include/asm/mach-au1x00/gpio-au1000.h | |||
@@ -25,20 +25,20 @@ | |||
25 | #define MAKE_IRQ(intc, off) (AU1000_INTC##intc##_INT_BASE + (off)) | 25 | #define MAKE_IRQ(intc, off) (AU1000_INTC##intc##_INT_BASE + (off)) |
26 | 26 | ||
27 | /* GPIO1 registers within SYS_ area */ | 27 | /* GPIO1 registers within SYS_ area */ |
28 | #define SYS_TRIOUTRD 0x100 | 28 | #define AU1000_SYS_TRIOUTRD 0x100 |
29 | #define SYS_TRIOUTCLR 0x100 | 29 | #define AU1000_SYS_TRIOUTCLR 0x100 |
30 | #define SYS_OUTPUTRD 0x108 | 30 | #define AU1000_SYS_OUTPUTRD 0x108 |
31 | #define SYS_OUTPUTSET 0x108 | 31 | #define AU1000_SYS_OUTPUTSET 0x108 |
32 | #define SYS_OUTPUTCLR 0x10C | 32 | #define AU1000_SYS_OUTPUTCLR 0x10C |
33 | #define SYS_PINSTATERD 0x110 | 33 | #define AU1000_SYS_PINSTATERD 0x110 |
34 | #define SYS_PININPUTEN 0x110 | 34 | #define AU1000_SYS_PININPUTEN 0x110 |
35 | 35 | ||
36 | /* register offsets within GPIO2 block */ | 36 | /* register offsets within GPIO2 block */ |
37 | #define GPIO2_DIR 0x00 | 37 | #define AU1000_GPIO2_DIR 0x00 |
38 | #define GPIO2_OUTPUT 0x08 | 38 | #define AU1000_GPIO2_OUTPUT 0x08 |
39 | #define GPIO2_PINSTATE 0x0C | 39 | #define AU1000_GPIO2_PINSTATE 0x0C |
40 | #define GPIO2_INTENABLE 0x10 | 40 | #define AU1000_GPIO2_INTENABLE 0x10 |
41 | #define GPIO2_ENABLE 0x14 | 41 | #define AU1000_GPIO2_ENABLE 0x14 |
42 | 42 | ||
43 | struct gpio; | 43 | struct gpio; |
44 | 44 | ||
@@ -217,26 +217,21 @@ static inline int au1200_irq_to_gpio(int irq) | |||
217 | */ | 217 | */ |
218 | static inline void alchemy_gpio1_set_value(int gpio, int v) | 218 | static inline void alchemy_gpio1_set_value(int gpio, int v) |
219 | { | 219 | { |
220 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); | ||
221 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); | 220 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); |
222 | unsigned long r = v ? SYS_OUTPUTSET : SYS_OUTPUTCLR; | 221 | unsigned long r = v ? AU1000_SYS_OUTPUTSET : AU1000_SYS_OUTPUTCLR; |
223 | __raw_writel(mask, base + r); | 222 | alchemy_wrsys(mask, r); |
224 | wmb(); | ||
225 | } | 223 | } |
226 | 224 | ||
227 | static inline int alchemy_gpio1_get_value(int gpio) | 225 | static inline int alchemy_gpio1_get_value(int gpio) |
228 | { | 226 | { |
229 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); | ||
230 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); | 227 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); |
231 | return __raw_readl(base + SYS_PINSTATERD) & mask; | 228 | return alchemy_rdsys(AU1000_SYS_PINSTATERD) & mask; |
232 | } | 229 | } |
233 | 230 | ||
234 | static inline int alchemy_gpio1_direction_input(int gpio) | 231 | static inline int alchemy_gpio1_direction_input(int gpio) |
235 | { | 232 | { |
236 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1000_SYS_PHYS_ADDR); | ||
237 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); | 233 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO1_BASE); |
238 | __raw_writel(mask, base + SYS_TRIOUTCLR); | 234 | alchemy_wrsys(mask, AU1000_SYS_TRIOUTCLR); |
239 | wmb(); | ||
240 | return 0; | 235 | return 0; |
241 | } | 236 | } |
242 | 237 | ||
@@ -279,13 +274,13 @@ static inline void __alchemy_gpio2_mod_dir(int gpio, int to_out) | |||
279 | { | 274 | { |
280 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); | 275 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
281 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO2_BASE); | 276 | unsigned long mask = 1 << (gpio - ALCHEMY_GPIO2_BASE); |
282 | unsigned long d = __raw_readl(base + GPIO2_DIR); | 277 | unsigned long d = __raw_readl(base + AU1000_GPIO2_DIR); |
283 | 278 | ||
284 | if (to_out) | 279 | if (to_out) |
285 | d |= mask; | 280 | d |= mask; |
286 | else | 281 | else |
287 | d &= ~mask; | 282 | d &= ~mask; |
288 | __raw_writel(d, base + GPIO2_DIR); | 283 | __raw_writel(d, base + AU1000_GPIO2_DIR); |
289 | wmb(); | 284 | wmb(); |
290 | } | 285 | } |
291 | 286 | ||
@@ -294,14 +289,15 @@ static inline void alchemy_gpio2_set_value(int gpio, int v) | |||
294 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); | 289 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
295 | unsigned long mask; | 290 | unsigned long mask; |
296 | mask = ((v) ? 0x00010001 : 0x00010000) << (gpio - ALCHEMY_GPIO2_BASE); | 291 | mask = ((v) ? 0x00010001 : 0x00010000) << (gpio - ALCHEMY_GPIO2_BASE); |
297 | __raw_writel(mask, base + GPIO2_OUTPUT); | 292 | __raw_writel(mask, base + AU1000_GPIO2_OUTPUT); |
298 | wmb(); | 293 | wmb(); |
299 | } | 294 | } |
300 | 295 | ||
301 | static inline int alchemy_gpio2_get_value(int gpio) | 296 | static inline int alchemy_gpio2_get_value(int gpio) |
302 | { | 297 | { |
303 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); | 298 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
304 | return __raw_readl(base + GPIO2_PINSTATE) & (1 << (gpio - ALCHEMY_GPIO2_BASE)); | 299 | return __raw_readl(base + AU1000_GPIO2_PINSTATE) & |
300 | (1 << (gpio - ALCHEMY_GPIO2_BASE)); | ||
305 | } | 301 | } |
306 | 302 | ||
307 | static inline int alchemy_gpio2_direction_input(int gpio) | 303 | static inline int alchemy_gpio2_direction_input(int gpio) |
@@ -352,12 +348,12 @@ static inline int alchemy_gpio2_to_irq(int gpio) | |||
352 | static inline void __alchemy_gpio2_mod_int(int gpio2, int en) | 348 | static inline void __alchemy_gpio2_mod_int(int gpio2, int en) |
353 | { | 349 | { |
354 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); | 350 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
355 | unsigned long r = __raw_readl(base + GPIO2_INTENABLE); | 351 | unsigned long r = __raw_readl(base + AU1000_GPIO2_INTENABLE); |
356 | if (en) | 352 | if (en) |
357 | r |= 1 << gpio2; | 353 | r |= 1 << gpio2; |
358 | else | 354 | else |
359 | r &= ~(1 << gpio2); | 355 | r &= ~(1 << gpio2); |
360 | __raw_writel(r, base + GPIO2_INTENABLE); | 356 | __raw_writel(r, base + AU1000_GPIO2_INTENABLE); |
361 | wmb(); | 357 | wmb(); |
362 | } | 358 | } |
363 | 359 | ||
@@ -434,9 +430,9 @@ static inline void alchemy_gpio2_disable_int(int gpio2) | |||
434 | static inline void alchemy_gpio2_enable(void) | 430 | static inline void alchemy_gpio2_enable(void) |
435 | { | 431 | { |
436 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); | 432 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
437 | __raw_writel(3, base + GPIO2_ENABLE); /* reset, clock enabled */ | 433 | __raw_writel(3, base + AU1000_GPIO2_ENABLE); /* reset, clock enabled */ |
438 | wmb(); | 434 | wmb(); |
439 | __raw_writel(1, base + GPIO2_ENABLE); /* clock enabled */ | 435 | __raw_writel(1, base + AU1000_GPIO2_ENABLE); /* clock enabled */ |
440 | wmb(); | 436 | wmb(); |
441 | } | 437 | } |
442 | 438 | ||
@@ -448,7 +444,7 @@ static inline void alchemy_gpio2_enable(void) | |||
448 | static inline void alchemy_gpio2_disable(void) | 444 | static inline void alchemy_gpio2_disable(void) |
449 | { | 445 | { |
450 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); | 446 | void __iomem *base = (void __iomem *)KSEG1ADDR(AU1500_GPIO2_PHYS_ADDR); |
451 | __raw_writel(2, base + GPIO2_ENABLE); /* reset, clock disabled */ | 447 | __raw_writel(2, base + AU1000_GPIO2_ENABLE); /* reset, clock disabled */ |
452 | wmb(); | 448 | wmb(); |
453 | } | 449 | } |
454 | 450 | ||
diff --git a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h index bba7399a49a3..1f5643b89a91 100644 --- a/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h +++ b/arch/mips/include/asm/mach-bcm47xx/bcm47xx_board.h | |||
@@ -18,6 +18,7 @@ enum bcm47xx_board { | |||
18 | BCM47XX_BOARD_ASUS_WL300G, | 18 | BCM47XX_BOARD_ASUS_WL300G, |
19 | BCM47XX_BOARD_ASUS_WL320GE, | 19 | BCM47XX_BOARD_ASUS_WL320GE, |
20 | BCM47XX_BOARD_ASUS_WL330GE, | 20 | BCM47XX_BOARD_ASUS_WL330GE, |
21 | BCM47XX_BOARD_ASUS_WL500G, | ||
21 | BCM47XX_BOARD_ASUS_WL500GD, | 22 | BCM47XX_BOARD_ASUS_WL500GD, |
22 | BCM47XX_BOARD_ASUS_WL500GPV1, | 23 | BCM47XX_BOARD_ASUS_WL500GPV1, |
23 | BCM47XX_BOARD_ASUS_WL500GPV2, | 24 | BCM47XX_BOARD_ASUS_WL500GPV2, |
@@ -70,11 +71,15 @@ enum bcm47xx_board { | |||
70 | BCM47XX_BOARD_LINKSYS_WRT310NV1, | 71 | BCM47XX_BOARD_LINKSYS_WRT310NV1, |
71 | BCM47XX_BOARD_LINKSYS_WRT310NV2, | 72 | BCM47XX_BOARD_LINKSYS_WRT310NV2, |
72 | BCM47XX_BOARD_LINKSYS_WRT54G3GV2, | 73 | BCM47XX_BOARD_LINKSYS_WRT54G3GV2, |
73 | BCM47XX_BOARD_LINKSYS_WRT54G, | 74 | BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101, |
75 | BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467, | ||
76 | BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708, | ||
74 | BCM47XX_BOARD_LINKSYS_WRT610NV1, | 77 | BCM47XX_BOARD_LINKSYS_WRT610NV1, |
75 | BCM47XX_BOARD_LINKSYS_WRT610NV2, | 78 | BCM47XX_BOARD_LINKSYS_WRT610NV2, |
76 | BCM47XX_BOARD_LINKSYS_WRTSL54GS, | 79 | BCM47XX_BOARD_LINKSYS_WRTSL54GS, |
77 | 80 | ||
81 | BCM47XX_BOARD_MICROSOFT_MN700, | ||
82 | |||
78 | BCM47XX_BOARD_MOTOROLA_WE800G, | 83 | BCM47XX_BOARD_MOTOROLA_WE800G, |
79 | BCM47XX_BOARD_MOTOROLA_WR850GP, | 84 | BCM47XX_BOARD_MOTOROLA_WR850GP, |
80 | BCM47XX_BOARD_MOTOROLA_WR850GV2V3, | 85 | BCM47XX_BOARD_MOTOROLA_WR850GV2V3, |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h index 3112f08f0c72..56bb19219d48 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h | |||
@@ -19,118 +19,68 @@ | |||
19 | #define BCM6368_CPU_ID 0x6368 | 19 | #define BCM6368_CPU_ID 0x6368 |
20 | 20 | ||
21 | void __init bcm63xx_cpu_init(void); | 21 | void __init bcm63xx_cpu_init(void); |
22 | u16 __bcm63xx_get_cpu_id(void); | ||
23 | u8 bcm63xx_get_cpu_rev(void); | 22 | u8 bcm63xx_get_cpu_rev(void); |
24 | unsigned int bcm63xx_get_cpu_freq(void); | 23 | unsigned int bcm63xx_get_cpu_freq(void); |
25 | 24 | ||
25 | static inline u16 __pure __bcm63xx_get_cpu_id(const u16 cpu_id) | ||
26 | { | ||
27 | switch (cpu_id) { | ||
26 | #ifdef CONFIG_BCM63XX_CPU_3368 | 28 | #ifdef CONFIG_BCM63XX_CPU_3368 |
27 | # ifdef bcm63xx_get_cpu_id | 29 | case BCM3368_CPU_ID: |
28 | # undef bcm63xx_get_cpu_id | ||
29 | # define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | ||
30 | # define BCMCPU_RUNTIME_DETECT | ||
31 | # else | ||
32 | # define bcm63xx_get_cpu_id() BCM3368_CPU_ID | ||
33 | # endif | ||
34 | # define BCMCPU_IS_3368() (bcm63xx_get_cpu_id() == BCM3368_CPU_ID) | ||
35 | #else | ||
36 | # define BCMCPU_IS_3368() (0) | ||
37 | #endif | 30 | #endif |
38 | 31 | ||
39 | #ifdef CONFIG_BCM63XX_CPU_6328 | 32 | #ifdef CONFIG_BCM63XX_CPU_6328 |
40 | # ifdef bcm63xx_get_cpu_id | 33 | case BCM6328_CPU_ID: |
41 | # undef bcm63xx_get_cpu_id | ||
42 | # define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | ||
43 | # define BCMCPU_RUNTIME_DETECT | ||
44 | # else | ||
45 | # define bcm63xx_get_cpu_id() BCM6328_CPU_ID | ||
46 | # endif | ||
47 | # define BCMCPU_IS_6328() (bcm63xx_get_cpu_id() == BCM6328_CPU_ID) | ||
48 | #else | ||
49 | # define BCMCPU_IS_6328() (0) | ||
50 | #endif | 34 | #endif |
51 | 35 | ||
52 | #ifdef CONFIG_BCM63XX_CPU_6338 | 36 | #ifdef CONFIG_BCM63XX_CPU_6338 |
53 | # ifdef bcm63xx_get_cpu_id | 37 | case BCM6338_CPU_ID: |
54 | # undef bcm63xx_get_cpu_id | ||
55 | # define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | ||
56 | # define BCMCPU_RUNTIME_DETECT | ||
57 | # else | ||
58 | # define bcm63xx_get_cpu_id() BCM6338_CPU_ID | ||
59 | # endif | ||
60 | # define BCMCPU_IS_6338() (bcm63xx_get_cpu_id() == BCM6338_CPU_ID) | ||
61 | #else | ||
62 | # define BCMCPU_IS_6338() (0) | ||
63 | #endif | 38 | #endif |
64 | 39 | ||
65 | #ifdef CONFIG_BCM63XX_CPU_6345 | 40 | #ifdef CONFIG_BCM63XX_CPU_6345 |
66 | # ifdef bcm63xx_get_cpu_id | 41 | case BCM6345_CPU_ID: |
67 | # undef bcm63xx_get_cpu_id | ||
68 | # define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | ||
69 | # define BCMCPU_RUNTIME_DETECT | ||
70 | # else | ||
71 | # define bcm63xx_get_cpu_id() BCM6345_CPU_ID | ||
72 | # endif | ||
73 | # define BCMCPU_IS_6345() (bcm63xx_get_cpu_id() == BCM6345_CPU_ID) | ||
74 | #else | ||
75 | # define BCMCPU_IS_6345() (0) | ||
76 | #endif | 42 | #endif |
77 | 43 | ||
78 | #ifdef CONFIG_BCM63XX_CPU_6348 | 44 | #ifdef CONFIG_BCM63XX_CPU_6348 |
79 | # ifdef bcm63xx_get_cpu_id | 45 | case BCM6348_CPU_ID: |
80 | # undef bcm63xx_get_cpu_id | ||
81 | # define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | ||
82 | # define BCMCPU_RUNTIME_DETECT | ||
83 | # else | ||
84 | # define bcm63xx_get_cpu_id() BCM6348_CPU_ID | ||
85 | # endif | ||
86 | # define BCMCPU_IS_6348() (bcm63xx_get_cpu_id() == BCM6348_CPU_ID) | ||
87 | #else | ||
88 | # define BCMCPU_IS_6348() (0) | ||
89 | #endif | 46 | #endif |
90 | 47 | ||
91 | #ifdef CONFIG_BCM63XX_CPU_6358 | 48 | #ifdef CONFIG_BCM63XX_CPU_6358 |
92 | # ifdef bcm63xx_get_cpu_id | 49 | case BCM6358_CPU_ID: |
93 | # undef bcm63xx_get_cpu_id | ||
94 | # define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | ||
95 | # define BCMCPU_RUNTIME_DETECT | ||
96 | # else | ||
97 | # define bcm63xx_get_cpu_id() BCM6358_CPU_ID | ||
98 | # endif | ||
99 | # define BCMCPU_IS_6358() (bcm63xx_get_cpu_id() == BCM6358_CPU_ID) | ||
100 | #else | ||
101 | # define BCMCPU_IS_6358() (0) | ||
102 | #endif | 50 | #endif |
103 | 51 | ||
104 | #ifdef CONFIG_BCM63XX_CPU_6362 | 52 | #ifdef CONFIG_BCM63XX_CPU_6362 |
105 | # ifdef bcm63xx_get_cpu_id | 53 | case BCM6362_CPU_ID: |
106 | # undef bcm63xx_get_cpu_id | ||
107 | # define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | ||
108 | # define BCMCPU_RUNTIME_DETECT | ||
109 | # else | ||
110 | # define bcm63xx_get_cpu_id() BCM6362_CPU_ID | ||
111 | # endif | ||
112 | # define BCMCPU_IS_6362() (bcm63xx_get_cpu_id() == BCM6362_CPU_ID) | ||
113 | #else | ||
114 | # define BCMCPU_IS_6362() (0) | ||
115 | #endif | 54 | #endif |
116 | 55 | ||
117 | |||
118 | #ifdef CONFIG_BCM63XX_CPU_6368 | 56 | #ifdef CONFIG_BCM63XX_CPU_6368 |
119 | # ifdef bcm63xx_get_cpu_id | 57 | case BCM6368_CPU_ID: |
120 | # undef bcm63xx_get_cpu_id | ||
121 | # define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id() | ||
122 | # define BCMCPU_RUNTIME_DETECT | ||
123 | # else | ||
124 | # define bcm63xx_get_cpu_id() BCM6368_CPU_ID | ||
125 | # endif | ||
126 | # define BCMCPU_IS_6368() (bcm63xx_get_cpu_id() == BCM6368_CPU_ID) | ||
127 | #else | ||
128 | # define BCMCPU_IS_6368() (0) | ||
129 | #endif | 58 | #endif |
59 | break; | ||
60 | default: | ||
61 | unreachable(); | ||
62 | } | ||
130 | 63 | ||
131 | #ifndef bcm63xx_get_cpu_id | 64 | return cpu_id; |
132 | #error "No CPU support configured" | 65 | } |
133 | #endif | 66 | |
67 | extern u16 bcm63xx_cpu_id; | ||
68 | |||
69 | static inline u16 __pure bcm63xx_get_cpu_id(void) | ||
70 | { | ||
71 | const u16 cpu_id = bcm63xx_cpu_id; | ||
72 | |||
73 | return __bcm63xx_get_cpu_id(cpu_id); | ||
74 | } | ||
75 | |||
76 | #define BCMCPU_IS_3368() (bcm63xx_get_cpu_id() == BCM3368_CPU_ID) | ||
77 | #define BCMCPU_IS_6328() (bcm63xx_get_cpu_id() == BCM6328_CPU_ID) | ||
78 | #define BCMCPU_IS_6338() (bcm63xx_get_cpu_id() == BCM6338_CPU_ID) | ||
79 | #define BCMCPU_IS_6345() (bcm63xx_get_cpu_id() == BCM6345_CPU_ID) | ||
80 | #define BCMCPU_IS_6348() (bcm63xx_get_cpu_id() == BCM6348_CPU_ID) | ||
81 | #define BCMCPU_IS_6358() (bcm63xx_get_cpu_id() == BCM6358_CPU_ID) | ||
82 | #define BCMCPU_IS_6362() (bcm63xx_get_cpu_id() == BCM6362_CPU_ID) | ||
83 | #define BCMCPU_IS_6368() (bcm63xx_get_cpu_id() == BCM6368_CPU_ID) | ||
134 | 84 | ||
135 | /* | 85 | /* |
136 | * While registers sets are (mostly) the same across 63xx CPU, base | 86 | * While registers sets are (mostly) the same across 63xx CPU, base |
@@ -598,55 +548,6 @@ enum bcm63xx_regs_set { | |||
598 | 548 | ||
599 | extern const unsigned long *bcm63xx_regs_base; | 549 | extern const unsigned long *bcm63xx_regs_base; |
600 | 550 | ||
601 | #define __GEN_RSET_BASE(__cpu, __rset) \ | ||
602 | case RSET_## __rset : \ | ||
603 | return BCM_## __cpu ##_## __rset ##_BASE; | ||
604 | |||
605 | #define __GEN_RSET(__cpu) \ | ||
606 | switch (set) { \ | ||
607 | __GEN_RSET_BASE(__cpu, DSL_LMEM) \ | ||
608 | __GEN_RSET_BASE(__cpu, PERF) \ | ||
609 | __GEN_RSET_BASE(__cpu, TIMER) \ | ||
610 | __GEN_RSET_BASE(__cpu, WDT) \ | ||
611 | __GEN_RSET_BASE(__cpu, UART0) \ | ||
612 | __GEN_RSET_BASE(__cpu, UART1) \ | ||
613 | __GEN_RSET_BASE(__cpu, GPIO) \ | ||
614 | __GEN_RSET_BASE(__cpu, SPI) \ | ||
615 | __GEN_RSET_BASE(__cpu, HSSPI) \ | ||
616 | __GEN_RSET_BASE(__cpu, UDC0) \ | ||
617 | __GEN_RSET_BASE(__cpu, OHCI0) \ | ||
618 | __GEN_RSET_BASE(__cpu, OHCI_PRIV) \ | ||
619 | __GEN_RSET_BASE(__cpu, USBH_PRIV) \ | ||
620 | __GEN_RSET_BASE(__cpu, USBD) \ | ||
621 | __GEN_RSET_BASE(__cpu, USBDMA) \ | ||
622 | __GEN_RSET_BASE(__cpu, MPI) \ | ||
623 | __GEN_RSET_BASE(__cpu, PCMCIA) \ | ||
624 | __GEN_RSET_BASE(__cpu, PCIE) \ | ||
625 | __GEN_RSET_BASE(__cpu, DSL) \ | ||
626 | __GEN_RSET_BASE(__cpu, ENET0) \ | ||
627 | __GEN_RSET_BASE(__cpu, ENET1) \ | ||
628 | __GEN_RSET_BASE(__cpu, ENETDMA) \ | ||
629 | __GEN_RSET_BASE(__cpu, ENETDMAC) \ | ||
630 | __GEN_RSET_BASE(__cpu, ENETDMAS) \ | ||
631 | __GEN_RSET_BASE(__cpu, ENETSW) \ | ||
632 | __GEN_RSET_BASE(__cpu, EHCI0) \ | ||
633 | __GEN_RSET_BASE(__cpu, SDRAM) \ | ||
634 | __GEN_RSET_BASE(__cpu, MEMC) \ | ||
635 | __GEN_RSET_BASE(__cpu, DDR) \ | ||
636 | __GEN_RSET_BASE(__cpu, M2M) \ | ||
637 | __GEN_RSET_BASE(__cpu, ATM) \ | ||
638 | __GEN_RSET_BASE(__cpu, XTM) \ | ||
639 | __GEN_RSET_BASE(__cpu, XTMDMA) \ | ||
640 | __GEN_RSET_BASE(__cpu, XTMDMAC) \ | ||
641 | __GEN_RSET_BASE(__cpu, XTMDMAS) \ | ||
642 | __GEN_RSET_BASE(__cpu, PCM) \ | ||
643 | __GEN_RSET_BASE(__cpu, PCMDMA) \ | ||
644 | __GEN_RSET_BASE(__cpu, PCMDMAC) \ | ||
645 | __GEN_RSET_BASE(__cpu, PCMDMAS) \ | ||
646 | __GEN_RSET_BASE(__cpu, RNG) \ | ||
647 | __GEN_RSET_BASE(__cpu, MISC) \ | ||
648 | } | ||
649 | |||
650 | #define __GEN_CPU_REGS_TABLE(__cpu) \ | 551 | #define __GEN_CPU_REGS_TABLE(__cpu) \ |
651 | [RSET_DSL_LMEM] = BCM_## __cpu ##_DSL_LMEM_BASE, \ | 552 | [RSET_DSL_LMEM] = BCM_## __cpu ##_DSL_LMEM_BASE, \ |
652 | [RSET_PERF] = BCM_## __cpu ##_PERF_BASE, \ | 553 | [RSET_PERF] = BCM_## __cpu ##_PERF_BASE, \ |
@@ -693,36 +594,7 @@ extern const unsigned long *bcm63xx_regs_base; | |||
693 | 594 | ||
694 | static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) | 595 | static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set) |
695 | { | 596 | { |
696 | #ifdef BCMCPU_RUNTIME_DETECT | ||
697 | return bcm63xx_regs_base[set]; | 597 | return bcm63xx_regs_base[set]; |
698 | #else | ||
699 | #ifdef CONFIG_BCM63XX_CPU_3368 | ||
700 | __GEN_RSET(3368) | ||
701 | #endif | ||
702 | #ifdef CONFIG_BCM63XX_CPU_6328 | ||
703 | __GEN_RSET(6328) | ||
704 | #endif | ||
705 | #ifdef CONFIG_BCM63XX_CPU_6338 | ||
706 | __GEN_RSET(6338) | ||
707 | #endif | ||
708 | #ifdef CONFIG_BCM63XX_CPU_6345 | ||
709 | __GEN_RSET(6345) | ||
710 | #endif | ||
711 | #ifdef CONFIG_BCM63XX_CPU_6348 | ||
712 | __GEN_RSET(6348) | ||
713 | #endif | ||
714 | #ifdef CONFIG_BCM63XX_CPU_6358 | ||
715 | __GEN_RSET(6358) | ||
716 | #endif | ||
717 | #ifdef CONFIG_BCM63XX_CPU_6362 | ||
718 | __GEN_RSET(6362) | ||
719 | #endif | ||
720 | #ifdef CONFIG_BCM63XX_CPU_6368 | ||
721 | __GEN_RSET(6368) | ||
722 | #endif | ||
723 | #endif | ||
724 | /* unreached */ | ||
725 | return 0; | ||
726 | } | 598 | } |
727 | 599 | ||
728 | /* | 600 | /* |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h index 753953e86242..466fc85899f4 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_enet.h | |||
@@ -112,55 +112,9 @@ enum bcm63xx_regs_enetdmac { | |||
112 | 112 | ||
113 | static inline unsigned long bcm63xx_enetdmacreg(enum bcm63xx_regs_enetdmac reg) | 113 | static inline unsigned long bcm63xx_enetdmacreg(enum bcm63xx_regs_enetdmac reg) |
114 | { | 114 | { |
115 | #ifdef BCMCPU_RUNTIME_DETECT | ||
116 | extern const unsigned long *bcm63xx_regs_enetdmac; | 115 | extern const unsigned long *bcm63xx_regs_enetdmac; |
117 | 116 | ||
118 | return bcm63xx_regs_enetdmac[reg]; | 117 | return bcm63xx_regs_enetdmac[reg]; |
119 | #else | ||
120 | #ifdef CONFIG_BCM63XX_CPU_6345 | ||
121 | switch (reg) { | ||
122 | case ENETDMAC_CHANCFG: | ||
123 | return ENETDMA_6345_CHANCFG_REG; | ||
124 | case ENETDMAC_IR: | ||
125 | return ENETDMA_6345_IR_REG; | ||
126 | case ENETDMAC_IRMASK: | ||
127 | return ENETDMA_6345_IRMASK_REG; | ||
128 | case ENETDMAC_MAXBURST: | ||
129 | return ENETDMA_6345_MAXBURST_REG; | ||
130 | case ENETDMAC_BUFALLOC: | ||
131 | return ENETDMA_6345_BUFALLOC_REG; | ||
132 | case ENETDMAC_RSTART: | ||
133 | return ENETDMA_6345_RSTART_REG; | ||
134 | case ENETDMAC_FC: | ||
135 | return ENETDMA_6345_FC_REG; | ||
136 | case ENETDMAC_LEN: | ||
137 | return ENETDMA_6345_LEN_REG; | ||
138 | } | ||
139 | #endif | ||
140 | #if defined(CONFIG_BCM63XX_CPU_6328) || \ | ||
141 | defined(CONFIG_BCM63XX_CPU_6338) || \ | ||
142 | defined(CONFIG_BCM63XX_CPU_6348) || \ | ||
143 | defined(CONFIG_BCM63XX_CPU_6358) || \ | ||
144 | defined(CONFIG_BCM63XX_CPU_6362) || \ | ||
145 | defined(CONFIG_BCM63XX_CPU_6368) | ||
146 | switch (reg) { | ||
147 | case ENETDMAC_CHANCFG: | ||
148 | return ENETDMAC_CHANCFG_REG; | ||
149 | case ENETDMAC_IR: | ||
150 | return ENETDMAC_IR_REG; | ||
151 | case ENETDMAC_IRMASK: | ||
152 | return ENETDMAC_IRMASK_REG; | ||
153 | case ENETDMAC_MAXBURST: | ||
154 | return ENETDMAC_MAXBURST_REG; | ||
155 | case ENETDMAC_BUFALLOC: | ||
156 | case ENETDMAC_RSTART: | ||
157 | case ENETDMAC_FC: | ||
158 | case ENETDMAC_LEN: | ||
159 | return 0; | ||
160 | } | ||
161 | #endif | ||
162 | #endif | ||
163 | return 0; | ||
164 | } | 118 | } |
165 | 119 | ||
166 | 120 | ||
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h index c426cabc620a..25737655d141 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h | |||
@@ -30,26 +30,6 @@ enum bcm63xx_regs_spi { | |||
30 | SPI_RX_DATA, | 30 | SPI_RX_DATA, |
31 | }; | 31 | }; |
32 | 32 | ||
33 | #define __GEN_SPI_RSET_BASE(__cpu, __rset) \ | ||
34 | case SPI_## __rset: \ | ||
35 | return SPI_## __cpu ##_## __rset; | ||
36 | |||
37 | #define __GEN_SPI_RSET(__cpu) \ | ||
38 | switch (reg) { \ | ||
39 | __GEN_SPI_RSET_BASE(__cpu, CMD) \ | ||
40 | __GEN_SPI_RSET_BASE(__cpu, INT_STATUS) \ | ||
41 | __GEN_SPI_RSET_BASE(__cpu, INT_MASK_ST) \ | ||
42 | __GEN_SPI_RSET_BASE(__cpu, INT_MASK) \ | ||
43 | __GEN_SPI_RSET_BASE(__cpu, ST) \ | ||
44 | __GEN_SPI_RSET_BASE(__cpu, CLK_CFG) \ | ||
45 | __GEN_SPI_RSET_BASE(__cpu, FILL_BYTE) \ | ||
46 | __GEN_SPI_RSET_BASE(__cpu, MSG_TAIL) \ | ||
47 | __GEN_SPI_RSET_BASE(__cpu, RX_TAIL) \ | ||
48 | __GEN_SPI_RSET_BASE(__cpu, MSG_CTL) \ | ||
49 | __GEN_SPI_RSET_BASE(__cpu, MSG_DATA) \ | ||
50 | __GEN_SPI_RSET_BASE(__cpu, RX_DATA) \ | ||
51 | } | ||
52 | |||
53 | #define __GEN_SPI_REGS_TABLE(__cpu) \ | 33 | #define __GEN_SPI_REGS_TABLE(__cpu) \ |
54 | [SPI_CMD] = SPI_## __cpu ##_CMD, \ | 34 | [SPI_CMD] = SPI_## __cpu ##_CMD, \ |
55 | [SPI_INT_STATUS] = SPI_## __cpu ##_INT_STATUS, \ | 35 | [SPI_INT_STATUS] = SPI_## __cpu ##_INT_STATUS, \ |
@@ -66,20 +46,9 @@ enum bcm63xx_regs_spi { | |||
66 | 46 | ||
67 | static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg) | 47 | static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg) |
68 | { | 48 | { |
69 | #ifdef BCMCPU_RUNTIME_DETECT | ||
70 | extern const unsigned long *bcm63xx_regs_spi; | 49 | extern const unsigned long *bcm63xx_regs_spi; |
71 | 50 | ||
72 | return bcm63xx_regs_spi[reg]; | 51 | return bcm63xx_regs_spi[reg]; |
73 | #else | ||
74 | #if defined(CONFIG_BCM63XX_CPU_6338) || defined(CONFIG_BCM63XX_CPU_6348) | ||
75 | __GEN_SPI_RSET(6348) | ||
76 | #endif | ||
77 | #if defined(CONFIG_BCM63XX_CPU_6358) || defined(CONFIG_BCM63XX_CPU_6362) || \ | ||
78 | defined(CONFIG_BCM63XX_CPU_6368) | ||
79 | __GEN_SPI_RSET(6358) | ||
80 | #endif | ||
81 | #endif | ||
82 | return 0; | ||
83 | } | 52 | } |
84 | 53 | ||
85 | #endif /* BCM63XX_DEV_SPI_H */ | 54 | #endif /* BCM63XX_DEV_SPI_H */ |
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h index ab427f8814e6..4794067cb5a7 100644 --- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h +++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h | |||
@@ -215,23 +215,23 @@ | |||
215 | 215 | ||
216 | /* Interrupt Mask register */ | 216 | /* Interrupt Mask register */ |
217 | #define PERF_IRQMASK_3368_REG 0xc | 217 | #define PERF_IRQMASK_3368_REG 0xc |
218 | #define PERF_IRQMASK_6328_REG 0x20 | 218 | #define PERF_IRQMASK_6328_REG(x) (0x20 + (x) * 0x10) |
219 | #define PERF_IRQMASK_6338_REG 0xc | 219 | #define PERF_IRQMASK_6338_REG 0xc |
220 | #define PERF_IRQMASK_6345_REG 0xc | 220 | #define PERF_IRQMASK_6345_REG 0xc |
221 | #define PERF_IRQMASK_6348_REG 0xc | 221 | #define PERF_IRQMASK_6348_REG 0xc |
222 | #define PERF_IRQMASK_6358_REG 0xc | 222 | #define PERF_IRQMASK_6358_REG(x) (0xc + (x) * 0x2c) |
223 | #define PERF_IRQMASK_6362_REG 0x20 | 223 | #define PERF_IRQMASK_6362_REG(x) (0x20 + (x) * 0x10) |
224 | #define PERF_IRQMASK_6368_REG 0x20 | 224 | #define PERF_IRQMASK_6368_REG(x) (0x20 + (x) * 0x10) |
225 | 225 | ||
226 | /* Interrupt Status register */ | 226 | /* Interrupt Status register */ |
227 | #define PERF_IRQSTAT_3368_REG 0x10 | 227 | #define PERF_IRQSTAT_3368_REG 0x10 |
228 | #define PERF_IRQSTAT_6328_REG 0x28 | 228 | #define PERF_IRQSTAT_6328_REG(x) (0x28 + (x) * 0x10) |
229 | #define PERF_IRQSTAT_6338_REG 0x10 | 229 | #define PERF_IRQSTAT_6338_REG 0x10 |
230 | #define PERF_IRQSTAT_6345_REG 0x10 | 230 | #define PERF_IRQSTAT_6345_REG 0x10 |
231 | #define PERF_IRQSTAT_6348_REG 0x10 | 231 | #define PERF_IRQSTAT_6348_REG 0x10 |
232 | #define PERF_IRQSTAT_6358_REG 0x10 | 232 | #define PERF_IRQSTAT_6358_REG(x) (0x10 + (x) * 0x2c) |
233 | #define PERF_IRQSTAT_6362_REG 0x28 | 233 | #define PERF_IRQSTAT_6362_REG(x) (0x28 + (x) * 0x10) |
234 | #define PERF_IRQSTAT_6368_REG 0x28 | 234 | #define PERF_IRQSTAT_6368_REG(x) (0x28 + (x) * 0x10) |
235 | 235 | ||
236 | /* External Interrupt Configuration register */ | 236 | /* External Interrupt Configuration register */ |
237 | #define PERF_EXTIRQ_CFG_REG_3368 0x14 | 237 | #define PERF_EXTIRQ_CFG_REG_3368 0x14 |
diff --git a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h index e9c408e8ff4c..bc1167dbd4e3 100644 --- a/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h +++ b/arch/mips/include/asm/mach-bcm63xx/cpu-feature-overrides.h | |||
@@ -24,7 +24,7 @@ | |||
24 | #define cpu_has_smartmips 0 | 24 | #define cpu_has_smartmips 0 |
25 | #define cpu_has_vtag_icache 0 | 25 | #define cpu_has_vtag_icache 0 |
26 | 26 | ||
27 | #if !defined(BCMCPU_RUNTIME_DETECT) && (defined(CONFIG_BCM63XX_CPU_6348) || defined(CONFIG_BCM63XX_CPU_6345) || defined(CONFIG_BCM63XX_CPU_6338)) | 27 | #if !defined(CONFIG_SYS_HAS_CPU_BMIPS4350) |
28 | #define cpu_has_dc_aliases 0 | 28 | #define cpu_has_dc_aliases 0 |
29 | #endif | 29 | #endif |
30 | 30 | ||
diff --git a/arch/mips/include/asm/mach-loongson/boot_param.h b/arch/mips/include/asm/mach-loongson/boot_param.h index 829a7ec185fb..3388fc53599e 100644 --- a/arch/mips/include/asm/mach-loongson/boot_param.h +++ b/arch/mips/include/asm/mach-loongson/boot_param.h | |||
@@ -146,6 +146,9 @@ struct boot_params { | |||
146 | 146 | ||
147 | struct loongson_system_configuration { | 147 | struct loongson_system_configuration { |
148 | u32 nr_cpus; | 148 | u32 nr_cpus; |
149 | u32 nr_nodes; | ||
150 | int cores_per_node; | ||
151 | int cores_per_package; | ||
149 | enum loongson_cpu_type cputype; | 152 | enum loongson_cpu_type cputype; |
150 | u64 ht_control_base; | 153 | u64 ht_control_base; |
151 | u64 pci_mem_start_addr; | 154 | u64 pci_mem_start_addr; |
@@ -160,4 +163,5 @@ struct loongson_system_configuration { | |||
160 | 163 | ||
161 | extern struct efi_memory_map_loongson *loongson_memmap; | 164 | extern struct efi_memory_map_loongson *loongson_memmap; |
162 | extern struct loongson_system_configuration loongson_sysconf; | 165 | extern struct loongson_system_configuration loongson_sysconf; |
166 | extern int cpuhotplug_workaround; | ||
163 | #endif | 167 | #endif |
diff --git a/arch/mips/include/asm/mach-loongson/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson/kernel-entry-init.h new file mode 100644 index 000000000000..df5fca8eeb80 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/kernel-entry-init.h | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2005 Embedded Alley Solutions, Inc | ||
7 | * Copyright (C) 2005 Ralf Baechle (ralf@linux-mips.org) | ||
8 | * Copyright (C) 2009 Jiajie Chen (chenjiajie@cse.buaa.edu.cn) | ||
9 | * Copyright (C) 2012 Huacai Chen (chenhc@lemote.com) | ||
10 | */ | ||
11 | #ifndef __ASM_MACH_LOONGSON_KERNEL_ENTRY_H | ||
12 | #define __ASM_MACH_LOONGSON_KERNEL_ENTRY_H | ||
13 | |||
14 | /* | ||
15 | * Override macros used in arch/mips/kernel/head.S. | ||
16 | */ | ||
17 | .macro kernel_entry_setup | ||
18 | #ifdef CONFIG_CPU_LOONGSON3 | ||
19 | .set push | ||
20 | .set mips64 | ||
21 | /* Set LPA on LOONGSON3 config3 */ | ||
22 | mfc0 t0, $16, 3 | ||
23 | or t0, (0x1 << 7) | ||
24 | mtc0 t0, $16, 3 | ||
25 | /* Set ELPA on LOONGSON3 pagegrain */ | ||
26 | li t0, (0x1 << 29) | ||
27 | mtc0 t0, $5, 1 | ||
28 | _ehb | ||
29 | .set pop | ||
30 | #endif | ||
31 | .endm | ||
32 | |||
33 | /* | ||
34 | * Do SMP slave processor setup. | ||
35 | */ | ||
36 | .macro smp_slave_setup | ||
37 | #ifdef CONFIG_CPU_LOONGSON3 | ||
38 | .set push | ||
39 | .set mips64 | ||
40 | /* Set LPA on LOONGSON3 config3 */ | ||
41 | mfc0 t0, $16, 3 | ||
42 | or t0, (0x1 << 7) | ||
43 | mtc0 t0, $16, 3 | ||
44 | /* Set ELPA on LOONGSON3 pagegrain */ | ||
45 | li t0, (0x1 << 29) | ||
46 | mtc0 t0, $5, 1 | ||
47 | _ehb | ||
48 | .set pop | ||
49 | #endif | ||
50 | .endm | ||
51 | |||
52 | #endif /* __ASM_MACH_LOONGSON_KERNEL_ENTRY_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h index f3fd1eb8e3dd..92bf76c21441 100644 --- a/arch/mips/include/asm/mach-loongson/loongson.h +++ b/arch/mips/include/asm/mach-loongson/loongson.h | |||
@@ -249,8 +249,15 @@ static inline void do_perfcnt_IRQ(void) | |||
249 | #define LOONGSON_PXARB_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x68) | 249 | #define LOONGSON_PXARB_CFG LOONGSON_REG(LOONGSON_REGBASE + 0x68) |
250 | #define LOONGSON_PXARB_STATUS LOONGSON_REG(LOONGSON_REGBASE + 0x6c) | 250 | #define LOONGSON_PXARB_STATUS LOONGSON_REG(LOONGSON_REGBASE + 0x6c) |
251 | 251 | ||
252 | /* Chip Config */ | 252 | #define MAX_PACKAGES 4 |
253 | #define LOONGSON_CHIPCFG0 LOONGSON_REG(LOONGSON_REGBASE + 0x80) | 253 | |
254 | /* Chip Config registor of each physical cpu package, PRid >= Loongson-2F */ | ||
255 | extern u64 loongson_chipcfg[MAX_PACKAGES]; | ||
256 | #define LOONGSON_CHIPCFG(id) (*(volatile u32 *)(loongson_chipcfg[id])) | ||
257 | |||
258 | /* Freq Control register of each physical cpu package, PRid >= Loongson-3B */ | ||
259 | extern u64 loongson_freqctrl[MAX_PACKAGES]; | ||
260 | #define LOONGSON_FREQCTRL(id) (*(volatile u32 *)(loongson_freqctrl[id])) | ||
254 | 261 | ||
255 | /* pcimap */ | 262 | /* pcimap */ |
256 | 263 | ||
diff --git a/arch/mips/include/asm/mach-loongson/machine.h b/arch/mips/include/asm/mach-loongson/machine.h index 1b1f592fa2be..228e37847a36 100644 --- a/arch/mips/include/asm/mach-loongson/machine.h +++ b/arch/mips/include/asm/mach-loongson/machine.h | |||
@@ -24,10 +24,10 @@ | |||
24 | 24 | ||
25 | #endif | 25 | #endif |
26 | 26 | ||
27 | #ifdef CONFIG_LEMOTE_MACH3A | 27 | #ifdef CONFIG_LOONGSON_MACH3X |
28 | 28 | ||
29 | #define LOONGSON_MACHTYPE MACH_LEMOTE_A1101 | 29 | #define LOONGSON_MACHTYPE MACH_LEMOTE_A1101 |
30 | 30 | ||
31 | #endif /* CONFIG_LEMOTE_MACH3A */ | 31 | #endif /* CONFIG_LOONGSON_MACH3X */ |
32 | 32 | ||
33 | #endif /* __ASM_MACH_LOONGSON_MACHINE_H */ | 33 | #endif /* __ASM_MACH_LOONGSON_MACHINE_H */ |
diff --git a/arch/mips/include/asm/mach-loongson/mmzone.h b/arch/mips/include/asm/mach-loongson/mmzone.h new file mode 100644 index 000000000000..37c08a27b4f0 --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/mmzone.h | |||
@@ -0,0 +1,53 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Loongson Inc. & Lemote Inc. & | ||
3 | * Insititute of Computing Technology | ||
4 | * Author: Xiang Gao, gaoxiang@ict.ac.cn | ||
5 | * Huacai Chen, chenhc@lemote.com | ||
6 | * Xiaofu Meng, Shuangshuang Zhang | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | #ifndef _ASM_MACH_MMZONE_H | ||
14 | #define _ASM_MACH_MMZONE_H | ||
15 | |||
16 | #include <boot_param.h> | ||
17 | #define NODE_ADDRSPACE_SHIFT 44 | ||
18 | #define NODE0_ADDRSPACE_OFFSET 0x000000000000UL | ||
19 | #define NODE1_ADDRSPACE_OFFSET 0x100000000000UL | ||
20 | #define NODE2_ADDRSPACE_OFFSET 0x200000000000UL | ||
21 | #define NODE3_ADDRSPACE_OFFSET 0x300000000000UL | ||
22 | |||
23 | #define pa_to_nid(addr) (((addr) & 0xf00000000000) >> NODE_ADDRSPACE_SHIFT) | ||
24 | |||
25 | #define LEVELS_PER_SLICE 128 | ||
26 | |||
27 | struct slice_data { | ||
28 | unsigned long irq_enable_mask[2]; | ||
29 | int level_to_irq[LEVELS_PER_SLICE]; | ||
30 | }; | ||
31 | |||
32 | struct hub_data { | ||
33 | cpumask_t h_cpus; | ||
34 | unsigned long slice_map; | ||
35 | unsigned long irq_alloc_mask[2]; | ||
36 | struct slice_data slice[2]; | ||
37 | }; | ||
38 | |||
39 | struct node_data { | ||
40 | struct pglist_data pglist; | ||
41 | struct hub_data hub; | ||
42 | cpumask_t cpumask; | ||
43 | }; | ||
44 | |||
45 | extern struct node_data *__node_data[]; | ||
46 | |||
47 | #define NODE_DATA(n) (&__node_data[(n)]->pglist) | ||
48 | #define hub_data(n) (&__node_data[(n)]->hub) | ||
49 | |||
50 | extern void setup_zero_pages(void); | ||
51 | extern void __init prom_init_numa_memory(void); | ||
52 | |||
53 | #endif /* _ASM_MACH_MMZONE_H */ | ||
diff --git a/arch/mips/include/asm/mach-loongson/topology.h b/arch/mips/include/asm/mach-loongson/topology.h new file mode 100644 index 000000000000..5598ba77d2ef --- /dev/null +++ b/arch/mips/include/asm/mach-loongson/topology.h | |||
@@ -0,0 +1,23 @@ | |||
1 | #ifndef _ASM_MACH_TOPOLOGY_H | ||
2 | #define _ASM_MACH_TOPOLOGY_H | ||
3 | |||
4 | #ifdef CONFIG_NUMA | ||
5 | |||
6 | #define cpu_to_node(cpu) ((cpu) >> 2) | ||
7 | #define parent_node(node) (node) | ||
8 | #define cpumask_of_node(node) (&__node_data[(node)]->cpumask) | ||
9 | |||
10 | struct pci_bus; | ||
11 | extern int pcibus_to_node(struct pci_bus *); | ||
12 | |||
13 | #define cpumask_of_pcibus(bus) (cpu_online_mask) | ||
14 | |||
15 | extern unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES]; | ||
16 | |||
17 | #define node_distance(from, to) (__node_distances[(from)][(to)]) | ||
18 | |||
19 | #endif | ||
20 | |||
21 | #include <asm-generic/topology.h> | ||
22 | |||
23 | #endif /* _ASM_MACH_TOPOLOGY_H */ | ||
diff --git a/arch/mips/include/asm/mach-malta/irq.h b/arch/mips/include/asm/mach-malta/irq.h index 47cfe64efbb0..f2c13d211abb 100644 --- a/arch/mips/include/asm/mach-malta/irq.h +++ b/arch/mips/include/asm/mach-malta/irq.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define __ASM_MACH_MIPS_IRQ_H | 2 | #define __ASM_MACH_MIPS_IRQ_H |
3 | 3 | ||
4 | 4 | ||
5 | #define GIC_NUM_INTRS (24 + NR_CPUS * 2) | ||
5 | #define NR_IRQS 256 | 6 | #define NR_IRQS 256 |
6 | 7 | ||
7 | #include_next <irq.h> | 8 | #include_next <irq.h> |
diff --git a/arch/mips/include/asm/mach-sead3/irq.h b/arch/mips/include/asm/mach-sead3/irq.h index 5d154cfbcf4c..d8106f75b9af 100644 --- a/arch/mips/include/asm/mach-sead3/irq.h +++ b/arch/mips/include/asm/mach-sead3/irq.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #ifndef __ASM_MACH_MIPS_IRQ_H | 1 | #ifndef __ASM_MACH_MIPS_IRQ_H |
2 | #define __ASM_MACH_MIPS_IRQ_H | 2 | #define __ASM_MACH_MIPS_IRQ_H |
3 | 3 | ||
4 | #define GIC_NUM_INTRS (24 + NR_CPUS * 2) | ||
4 | #define NR_IRQS 256 | 5 | #define NR_IRQS 256 |
5 | 6 | ||
6 | 7 | ||
diff --git a/arch/mips/include/asm/mips-boards/bonito64.h b/arch/mips/include/asm/mips-boards/bonito64.h index b2048d1bcc1c..5368891d424b 100644 --- a/arch/mips/include/asm/mips-boards/bonito64.h +++ b/arch/mips/include/asm/mips-boards/bonito64.h | |||
@@ -414,7 +414,6 @@ extern unsigned long _pcictrl_bonito_pcicfg; | |||
414 | 414 | ||
415 | 415 | ||
416 | #define BONITO_PCIMEMBASECFG_ADDRMASK(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) | 416 | #define BONITO_PCIMEMBASECFG_ADDRMASK(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) |
417 | #define BONITO_PCIMEMBASECFG_ADDRMASK(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_MASK_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) | ||
418 | #define BONITO_PCIMEMBASECFG_ADDRTRANS(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) | 417 | #define BONITO_PCIMEMBASECFG_ADDRTRANS(WIN, CFG) ((((CFG) & BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS) >> BONITO_PCIMEMBASECFG_MEMBASE##WIN##_TRANS_SHIFT) << BONITO_PCIMEMBASECFG_ASHIFT) |
419 | 418 | ||
420 | #define BONITO_PCITOPHYS(WIN, ADDR, CFG) ( \ | 419 | #define BONITO_PCITOPHYS(WIN, ADDR, CFG) ( \ |
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h index 98e9754a4b6b..cf3b580c3df6 100644 --- a/arch/mips/include/asm/mipsregs.h +++ b/arch/mips/include/asm/mipsregs.h | |||
@@ -265,6 +265,7 @@ | |||
265 | #define PG_XIE (_ULCAST_(1) << 30) | 265 | #define PG_XIE (_ULCAST_(1) << 30) |
266 | #define PG_ELPA (_ULCAST_(1) << 29) | 266 | #define PG_ELPA (_ULCAST_(1) << 29) |
267 | #define PG_ESP (_ULCAST_(1) << 28) | 267 | #define PG_ESP (_ULCAST_(1) << 28) |
268 | #define PG_IEC (_ULCAST_(1) << 27) | ||
268 | 269 | ||
269 | /* | 270 | /* |
270 | * R4x00 interrupt enable / cause bits | 271 | * R4x00 interrupt enable / cause bits |
@@ -630,7 +631,6 @@ | |||
630 | #define MIPS_CONF4_MMUSIZEEXT_SHIFT (0) | 631 | #define MIPS_CONF4_MMUSIZEEXT_SHIFT (0) |
631 | #define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0) | 632 | #define MIPS_CONF4_MMUSIZEEXT (_ULCAST_(255) << 0) |
632 | #define MIPS_CONF4_FTLBSETS_SHIFT (0) | 633 | #define MIPS_CONF4_FTLBSETS_SHIFT (0) |
633 | #define MIPS_CONF4_FTLBSETS_SHIFT (0) | ||
634 | #define MIPS_CONF4_FTLBSETS (_ULCAST_(15) << MIPS_CONF4_FTLBSETS_SHIFT) | 634 | #define MIPS_CONF4_FTLBSETS (_ULCAST_(15) << MIPS_CONF4_FTLBSETS_SHIFT) |
635 | #define MIPS_CONF4_FTLBWAYS_SHIFT (4) | 635 | #define MIPS_CONF4_FTLBWAYS_SHIFT (4) |
636 | #define MIPS_CONF4_FTLBWAYS (_ULCAST_(15) << MIPS_CONF4_FTLBWAYS_SHIFT) | 636 | #define MIPS_CONF4_FTLBWAYS (_ULCAST_(15) << MIPS_CONF4_FTLBWAYS_SHIFT) |
@@ -652,6 +652,7 @@ | |||
652 | 652 | ||
653 | #define MIPS_CONF5_NF (_ULCAST_(1) << 0) | 653 | #define MIPS_CONF5_NF (_ULCAST_(1) << 0) |
654 | #define MIPS_CONF5_UFR (_ULCAST_(1) << 2) | 654 | #define MIPS_CONF5_UFR (_ULCAST_(1) << 2) |
655 | #define MIPS_CONF5_MRP (_ULCAST_(1) << 3) | ||
655 | #define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) | 656 | #define MIPS_CONF5_MSAEN (_ULCAST_(1) << 27) |
656 | #define MIPS_CONF5_EVA (_ULCAST_(1) << 28) | 657 | #define MIPS_CONF5_EVA (_ULCAST_(1) << 28) |
657 | #define MIPS_CONF5_CV (_ULCAST_(1) << 29) | 658 | #define MIPS_CONF5_CV (_ULCAST_(1) << 29) |
@@ -668,6 +669,12 @@ | |||
668 | #define MIPS_CONF7_IAR (_ULCAST_(1) << 10) | 669 | #define MIPS_CONF7_IAR (_ULCAST_(1) << 10) |
669 | #define MIPS_CONF7_AR (_ULCAST_(1) << 16) | 670 | #define MIPS_CONF7_AR (_ULCAST_(1) << 16) |
670 | 671 | ||
672 | /* MAAR bit definitions */ | ||
673 | #define MIPS_MAAR_ADDR ((BIT_ULL(BITS_PER_LONG - 12) - 1) << 12) | ||
674 | #define MIPS_MAAR_ADDR_SHIFT 12 | ||
675 | #define MIPS_MAAR_S (_ULCAST_(1) << 1) | ||
676 | #define MIPS_MAAR_V (_ULCAST_(1) << 0) | ||
677 | |||
671 | /* EntryHI bit definition */ | 678 | /* EntryHI bit definition */ |
672 | #define MIPS_ENTRYHI_EHINV (_ULCAST_(1) << 10) | 679 | #define MIPS_ENTRYHI_EHINV (_ULCAST_(1) << 10) |
673 | 680 | ||
@@ -706,6 +713,37 @@ | |||
706 | #define MIPS_SEGCFG_MK _ULCAST_(1) | 713 | #define MIPS_SEGCFG_MK _ULCAST_(1) |
707 | #define MIPS_SEGCFG_UK _ULCAST_(0) | 714 | #define MIPS_SEGCFG_UK _ULCAST_(0) |
708 | 715 | ||
716 | #define MIPS_PWFIELD_GDI_SHIFT 24 | ||
717 | #define MIPS_PWFIELD_GDI_MASK 0x3f000000 | ||
718 | #define MIPS_PWFIELD_UDI_SHIFT 18 | ||
719 | #define MIPS_PWFIELD_UDI_MASK 0x00fc0000 | ||
720 | #define MIPS_PWFIELD_MDI_SHIFT 12 | ||
721 | #define MIPS_PWFIELD_MDI_MASK 0x0003f000 | ||
722 | #define MIPS_PWFIELD_PTI_SHIFT 6 | ||
723 | #define MIPS_PWFIELD_PTI_MASK 0x00000fc0 | ||
724 | #define MIPS_PWFIELD_PTEI_SHIFT 0 | ||
725 | #define MIPS_PWFIELD_PTEI_MASK 0x0000003f | ||
726 | |||
727 | #define MIPS_PWSIZE_GDW_SHIFT 24 | ||
728 | #define MIPS_PWSIZE_GDW_MASK 0x3f000000 | ||
729 | #define MIPS_PWSIZE_UDW_SHIFT 18 | ||
730 | #define MIPS_PWSIZE_UDW_MASK 0x00fc0000 | ||
731 | #define MIPS_PWSIZE_MDW_SHIFT 12 | ||
732 | #define MIPS_PWSIZE_MDW_MASK 0x0003f000 | ||
733 | #define MIPS_PWSIZE_PTW_SHIFT 6 | ||
734 | #define MIPS_PWSIZE_PTW_MASK 0x00000fc0 | ||
735 | #define MIPS_PWSIZE_PTEW_SHIFT 0 | ||
736 | #define MIPS_PWSIZE_PTEW_MASK 0x0000003f | ||
737 | |||
738 | #define MIPS_PWCTL_PWEN_SHIFT 31 | ||
739 | #define MIPS_PWCTL_PWEN_MASK 0x80000000 | ||
740 | #define MIPS_PWCTL_DPH_SHIFT 7 | ||
741 | #define MIPS_PWCTL_DPH_MASK 0x00000080 | ||
742 | #define MIPS_PWCTL_HUGEPG_SHIFT 6 | ||
743 | #define MIPS_PWCTL_HUGEPG_MASK 0x00000060 | ||
744 | #define MIPS_PWCTL_PSN_SHIFT 0 | ||
745 | #define MIPS_PWCTL_PSN_MASK 0x0000003f | ||
746 | |||
709 | #ifndef __ASSEMBLY__ | 747 | #ifndef __ASSEMBLY__ |
710 | 748 | ||
711 | /* | 749 | /* |
@@ -1044,6 +1082,11 @@ do { \ | |||
1044 | #define write_c0_config6(val) __write_32bit_c0_register($16, 6, val) | 1082 | #define write_c0_config6(val) __write_32bit_c0_register($16, 6, val) |
1045 | #define write_c0_config7(val) __write_32bit_c0_register($16, 7, val) | 1083 | #define write_c0_config7(val) __write_32bit_c0_register($16, 7, val) |
1046 | 1084 | ||
1085 | #define read_c0_maar() __read_ulong_c0_register($17, 1) | ||
1086 | #define write_c0_maar(val) __write_ulong_c0_register($17, 1, val) | ||
1087 | #define read_c0_maari() __read_32bit_c0_register($17, 2) | ||
1088 | #define write_c0_maari(val) __write_32bit_c0_register($17, 2, val) | ||
1089 | |||
1047 | /* | 1090 | /* |
1048 | * The WatchLo register. There may be up to 8 of them. | 1091 | * The WatchLo register. There may be up to 8 of them. |
1049 | */ | 1092 | */ |
@@ -1201,6 +1244,19 @@ do { \ | |||
1201 | #define read_c0_segctl2() __read_32bit_c0_register($5, 4) | 1244 | #define read_c0_segctl2() __read_32bit_c0_register($5, 4) |
1202 | #define write_c0_segctl2(val) __write_32bit_c0_register($5, 4, val) | 1245 | #define write_c0_segctl2(val) __write_32bit_c0_register($5, 4, val) |
1203 | 1246 | ||
1247 | /* Hardware Page Table Walker */ | ||
1248 | #define read_c0_pwbase() __read_ulong_c0_register($5, 5) | ||
1249 | #define write_c0_pwbase(val) __write_ulong_c0_register($5, 5, val) | ||
1250 | |||
1251 | #define read_c0_pwfield() __read_ulong_c0_register($5, 6) | ||
1252 | #define write_c0_pwfield(val) __write_ulong_c0_register($5, 6, val) | ||
1253 | |||
1254 | #define read_c0_pwsize() __read_ulong_c0_register($5, 7) | ||
1255 | #define write_c0_pwsize(val) __write_ulong_c0_register($5, 7, val) | ||
1256 | |||
1257 | #define read_c0_pwctl() __read_32bit_c0_register($6, 6) | ||
1258 | #define write_c0_pwctl(val) __write_32bit_c0_register($6, 6, val) | ||
1259 | |||
1204 | /* Cavium OCTEON (cnMIPS) */ | 1260 | /* Cavium OCTEON (cnMIPS) */ |
1205 | #define read_c0_cvmcount() __read_ulong_c0_register($9, 6) | 1261 | #define read_c0_cvmcount() __read_ulong_c0_register($9, 6) |
1206 | #define write_c0_cvmcount(val) __write_ulong_c0_register($9, 6, val) | 1262 | #define write_c0_cvmcount(val) __write_ulong_c0_register($9, 6, val) |
diff --git a/arch/mips/include/asm/mmu_context.h b/arch/mips/include/asm/mmu_context.h index 2e373da5f8e9..2f82568a3ee4 100644 --- a/arch/mips/include/asm/mmu_context.h +++ b/arch/mips/include/asm/mmu_context.h | |||
@@ -20,10 +20,20 @@ | |||
20 | #include <asm/tlbflush.h> | 20 | #include <asm/tlbflush.h> |
21 | #include <asm-generic/mm_hooks.h> | 21 | #include <asm-generic/mm_hooks.h> |
22 | 22 | ||
23 | #define htw_set_pwbase(pgd) \ | ||
24 | do { \ | ||
25 | if (cpu_has_htw) { \ | ||
26 | write_c0_pwbase(pgd); \ | ||
27 | back_to_back_c0_hazard(); \ | ||
28 | htw_reset(); \ | ||
29 | } \ | ||
30 | } while (0) | ||
31 | |||
23 | #define TLBMISS_HANDLER_SETUP_PGD(pgd) \ | 32 | #define TLBMISS_HANDLER_SETUP_PGD(pgd) \ |
24 | do { \ | 33 | do { \ |
25 | extern void tlbmiss_handler_setup_pgd(unsigned long); \ | 34 | extern void tlbmiss_handler_setup_pgd(unsigned long); \ |
26 | tlbmiss_handler_setup_pgd((unsigned long)(pgd)); \ | 35 | tlbmiss_handler_setup_pgd((unsigned long)(pgd)); \ |
36 | htw_set_pwbase((unsigned long)pgd); \ | ||
27 | } while (0) | 37 | } while (0) |
28 | 38 | ||
29 | #ifdef CONFIG_MIPS_PGD_C0_CONTEXT | 39 | #ifdef CONFIG_MIPS_PGD_C0_CONTEXT |
diff --git a/arch/mips/include/asm/msa.h b/arch/mips/include/asm/msa.h index 538f6d482db8..af5638b12c75 100644 --- a/arch/mips/include/asm/msa.h +++ b/arch/mips/include/asm/msa.h | |||
@@ -12,8 +12,11 @@ | |||
12 | 12 | ||
13 | #include <asm/mipsregs.h> | 13 | #include <asm/mipsregs.h> |
14 | 14 | ||
15 | #ifndef __ASSEMBLY__ | ||
16 | |||
15 | extern void _save_msa(struct task_struct *); | 17 | extern void _save_msa(struct task_struct *); |
16 | extern void _restore_msa(struct task_struct *); | 18 | extern void _restore_msa(struct task_struct *); |
19 | extern void _init_msa_upper(void); | ||
17 | 20 | ||
18 | static inline void enable_msa(void) | 21 | static inline void enable_msa(void) |
19 | { | 22 | { |
@@ -112,10 +115,10 @@ static inline unsigned int read_msa_##name(void) \ | |||
112 | " .set push\n" \ | 115 | " .set push\n" \ |
113 | " .set noat\n" \ | 116 | " .set noat\n" \ |
114 | " .insn\n" \ | 117 | " .insn\n" \ |
115 | " .word #CFC_MSA_INSN | (" #cs " << 11)\n" \ | 118 | " .word %1 | (" #cs " << 11)\n" \ |
116 | " move %0, $1\n" \ | 119 | " move %0, $1\n" \ |
117 | " .set pop\n" \ | 120 | " .set pop\n" \ |
118 | : "=r"(reg)); \ | 121 | : "=r"(reg) : "i"(CFC_MSA_INSN)); \ |
119 | return reg; \ | 122 | return reg; \ |
120 | } \ | 123 | } \ |
121 | \ | 124 | \ |
@@ -126,22 +129,13 @@ static inline void write_msa_##name(unsigned int val) \ | |||
126 | " .set noat\n" \ | 129 | " .set noat\n" \ |
127 | " move $1, %0\n" \ | 130 | " move $1, %0\n" \ |
128 | " .insn\n" \ | 131 | " .insn\n" \ |
129 | " .word #CTC_MSA_INSN | (" #cs " << 6)\n" \ | 132 | " .word %1 | (" #cs " << 6)\n" \ |
130 | " .set pop\n" \ | 133 | " .set pop\n" \ |
131 | : : "r"(val)); \ | 134 | : : "r"(val), "i"(CTC_MSA_INSN)); \ |
132 | } | 135 | } |
133 | 136 | ||
134 | #endif /* !TOOLCHAIN_SUPPORTS_MSA */ | 137 | #endif /* !TOOLCHAIN_SUPPORTS_MSA */ |
135 | 138 | ||
136 | #define MSA_IR 0 | ||
137 | #define MSA_CSR 1 | ||
138 | #define MSA_ACCESS 2 | ||
139 | #define MSA_SAVE 3 | ||
140 | #define MSA_MODIFY 4 | ||
141 | #define MSA_REQUEST 5 | ||
142 | #define MSA_MAP 6 | ||
143 | #define MSA_UNMAP 7 | ||
144 | |||
145 | __BUILD_MSA_CTL_REG(ir, 0) | 139 | __BUILD_MSA_CTL_REG(ir, 0) |
146 | __BUILD_MSA_CTL_REG(csr, 1) | 140 | __BUILD_MSA_CTL_REG(csr, 1) |
147 | __BUILD_MSA_CTL_REG(access, 2) | 141 | __BUILD_MSA_CTL_REG(access, 2) |
@@ -151,6 +145,17 @@ __BUILD_MSA_CTL_REG(request, 5) | |||
151 | __BUILD_MSA_CTL_REG(map, 6) | 145 | __BUILD_MSA_CTL_REG(map, 6) |
152 | __BUILD_MSA_CTL_REG(unmap, 7) | 146 | __BUILD_MSA_CTL_REG(unmap, 7) |
153 | 147 | ||
148 | #endif /* !__ASSEMBLY__ */ | ||
149 | |||
150 | #define MSA_IR 0 | ||
151 | #define MSA_CSR 1 | ||
152 | #define MSA_ACCESS 2 | ||
153 | #define MSA_SAVE 3 | ||
154 | #define MSA_MODIFY 4 | ||
155 | #define MSA_REQUEST 5 | ||
156 | #define MSA_MAP 6 | ||
157 | #define MSA_UNMAP 7 | ||
158 | |||
154 | /* MSA Implementation Register (MSAIR) */ | 159 | /* MSA Implementation Register (MSAIR) */ |
155 | #define MSA_IR_REVB 0 | 160 | #define MSA_IR_REVB 0 |
156 | #define MSA_IR_REVF (_ULCAST_(0xff) << MSA_IR_REVB) | 161 | #define MSA_IR_REVF (_ULCAST_(0xff) << MSA_IR_REVB) |
diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h index 7b7818d1e4d5..2298199a287e 100644 --- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h +++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h | |||
@@ -228,6 +228,7 @@ enum cvmx_board_types_enum { | |||
228 | */ | 228 | */ |
229 | CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001, | 229 | CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001, |
230 | CVMX_BOARD_TYPE_UBNT_E100 = 20002, | 230 | CVMX_BOARD_TYPE_UBNT_E100 = 20002, |
231 | CVMX_BOARD_TYPE_CUST_DSR1000N = 20006, | ||
231 | CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000, | 232 | CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000, |
232 | 233 | ||
233 | /* The remaining range is reserved for future use. */ | 234 | /* The remaining range is reserved for future use. */ |
@@ -327,6 +328,7 @@ static inline const char *cvmx_board_type_to_string(enum | |||
327 | /* Customer private range */ | 328 | /* Customer private range */ |
328 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN) | 329 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN) |
329 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100) | 330 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_UBNT_E100) |
331 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DSR1000N) | ||
330 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX) | 332 | ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX) |
331 | } | 333 | } |
332 | return "Unsupported Board"; | 334 | return "Unsupported Board"; |
diff --git a/arch/mips/include/asm/pgtable-32.h b/arch/mips/include/asm/pgtable-32.h index b4204c179b97..cd7d6064bcbe 100644 --- a/arch/mips/include/asm/pgtable-32.h +++ b/arch/mips/include/asm/pgtable-32.h | |||
@@ -18,6 +18,18 @@ | |||
18 | 18 | ||
19 | #include <asm-generic/pgtable-nopmd.h> | 19 | #include <asm-generic/pgtable-nopmd.h> |
20 | 20 | ||
21 | extern int temp_tlb_entry __cpuinitdata; | ||
22 | |||
23 | /* | ||
24 | * - add_temporary_entry() add a temporary TLB entry. We use TLB entries | ||
25 | * starting at the top and working down. This is for populating the | ||
26 | * TLB before trap_init() puts the TLB miss handler in place. It | ||
27 | * should be used only for entries matching the actual page tables, | ||
28 | * to prevent inconsistencies. | ||
29 | */ | ||
30 | extern int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, | ||
31 | unsigned long entryhi, unsigned long pagemask); | ||
32 | |||
21 | /* | 33 | /* |
22 | * Basically we have the same two-level (which is the logical three level | 34 | * Basically we have the same two-level (which is the logical three level |
23 | * Linux page table layout folded) page tables as the i386. Some day | 35 | * Linux page table layout folded) page tables as the i386. Some day |
diff --git a/arch/mips/include/asm/pgtable.h b/arch/mips/include/asm/pgtable.h index 539ddd148bbb..027c74db13f9 100644 --- a/arch/mips/include/asm/pgtable.h +++ b/arch/mips/include/asm/pgtable.h | |||
@@ -97,6 +97,31 @@ extern void paging_init(void); | |||
97 | 97 | ||
98 | #define pmd_page_vaddr(pmd) pmd_val(pmd) | 98 | #define pmd_page_vaddr(pmd) pmd_val(pmd) |
99 | 99 | ||
100 | #define htw_stop() \ | ||
101 | do { \ | ||
102 | if (cpu_has_htw) \ | ||
103 | write_c0_pwctl(read_c0_pwctl() & \ | ||
104 | ~(1 << MIPS_PWCTL_PWEN_SHIFT)); \ | ||
105 | } while(0) | ||
106 | |||
107 | #define htw_start() \ | ||
108 | do { \ | ||
109 | if (cpu_has_htw) \ | ||
110 | write_c0_pwctl(read_c0_pwctl() | \ | ||
111 | (1 << MIPS_PWCTL_PWEN_SHIFT)); \ | ||
112 | } while(0) | ||
113 | |||
114 | |||
115 | #define htw_reset() \ | ||
116 | do { \ | ||
117 | if (cpu_has_htw) { \ | ||
118 | htw_stop(); \ | ||
119 | back_to_back_c0_hazard(); \ | ||
120 | htw_start(); \ | ||
121 | back_to_back_c0_hazard(); \ | ||
122 | } \ | ||
123 | } while(0) | ||
124 | |||
100 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) | 125 | #if defined(CONFIG_64BIT_PHYS_ADDR) && defined(CONFIG_CPU_MIPS32) |
101 | 126 | ||
102 | #define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) | 127 | #define pte_none(pte) (!(((pte).pte_low | (pte).pte_high) & ~_PAGE_GLOBAL)) |
@@ -131,6 +156,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt | |||
131 | null.pte_low = null.pte_high = _PAGE_GLOBAL; | 156 | null.pte_low = null.pte_high = _PAGE_GLOBAL; |
132 | 157 | ||
133 | set_pte_at(mm, addr, ptep, null); | 158 | set_pte_at(mm, addr, ptep, null); |
159 | htw_reset(); | ||
134 | } | 160 | } |
135 | #else | 161 | #else |
136 | 162 | ||
@@ -168,6 +194,7 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt | |||
168 | else | 194 | else |
169 | #endif | 195 | #endif |
170 | set_pte_at(mm, addr, ptep, __pte(0)); | 196 | set_pte_at(mm, addr, ptep, __pte(0)); |
197 | htw_reset(); | ||
171 | } | 198 | } |
172 | #endif | 199 | #endif |
173 | 200 | ||
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h index d5098bc554f4..05f08438a7c4 100644 --- a/arch/mips/include/asm/processor.h +++ b/arch/mips/include/asm/processor.h | |||
@@ -238,7 +238,13 @@ typedef struct { | |||
238 | unsigned long seg; | 238 | unsigned long seg; |
239 | } mm_segment_t; | 239 | } mm_segment_t; |
240 | 240 | ||
241 | #define ARCH_MIN_TASKALIGN 8 | 241 | #ifdef CONFIG_CPU_HAS_MSA |
242 | # define ARCH_MIN_TASKALIGN 16 | ||
243 | # define FPU_ALIGN __aligned(16) | ||
244 | #else | ||
245 | # define ARCH_MIN_TASKALIGN 8 | ||
246 | # define FPU_ALIGN | ||
247 | #endif | ||
242 | 248 | ||
243 | struct mips_abi; | 249 | struct mips_abi; |
244 | 250 | ||
@@ -255,7 +261,7 @@ struct thread_struct { | |||
255 | unsigned long cp0_status; | 261 | unsigned long cp0_status; |
256 | 262 | ||
257 | /* Saved fpu/fpu emulator stuff. */ | 263 | /* Saved fpu/fpu emulator stuff. */ |
258 | struct mips_fpu_struct fpu; | 264 | struct mips_fpu_struct fpu FPU_ALIGN; |
259 | #ifdef CONFIG_MIPS_MT_FPAFF | 265 | #ifdef CONFIG_MIPS_MT_FPAFF |
260 | /* Emulated instruction count */ | 266 | /* Emulated instruction count */ |
261 | unsigned long emulated_fp; | 267 | unsigned long emulated_fp; |
diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h index 7e6e682aece3..fc783f843bdc 100644 --- a/arch/mips/include/asm/ptrace.h +++ b/arch/mips/include/asm/ptrace.h | |||
@@ -23,7 +23,7 @@ | |||
23 | struct pt_regs { | 23 | struct pt_regs { |
24 | #ifdef CONFIG_32BIT | 24 | #ifdef CONFIG_32BIT |
25 | /* Pad bytes for argument save space on the stack. */ | 25 | /* Pad bytes for argument save space on the stack. */ |
26 | unsigned long pad0[6]; | 26 | unsigned long pad0[8]; |
27 | #endif | 27 | #endif |
28 | 28 | ||
29 | /* Saved main processor registers. */ | 29 | /* Saved main processor registers. */ |
@@ -47,8 +47,10 @@ struct pt_regs { | |||
47 | 47 | ||
48 | struct task_struct; | 48 | struct task_struct; |
49 | 49 | ||
50 | extern int ptrace_getregs(struct task_struct *child, __s64 __user *data); | 50 | extern int ptrace_getregs(struct task_struct *child, |
51 | extern int ptrace_setregs(struct task_struct *child, __s64 __user *data); | 51 | struct user_pt_regs __user *data); |
52 | extern int ptrace_setregs(struct task_struct *child, | ||
53 | struct user_pt_regs __user *data); | ||
52 | 54 | ||
53 | extern int ptrace_getfpregs(struct task_struct *child, __u32 __user *data); | 55 | extern int ptrace_getfpregs(struct task_struct *child, __u32 __user *data); |
54 | extern int ptrace_setfpregs(struct task_struct *child, __u32 __user *data); | 56 | extern int ptrace_setfpregs(struct task_struct *child, __u32 __user *data); |
diff --git a/arch/mips/include/asm/reg.h b/arch/mips/include/asm/reg.h index 910e71a12466..84dc7e2e27a8 100644 --- a/arch/mips/include/asm/reg.h +++ b/arch/mips/include/asm/reg.h | |||
@@ -1,128 +1 @@ | |||
1 | /* | #include <uapi/asm/reg.h> | |
2 | * Various register offset definitions for debuggers, core file | ||
3 | * examiners and whatnot. | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | * | ||
9 | * Copyright (C) 1995, 1999 Ralf Baechle | ||
10 | * Copyright (C) 1995, 1999 Silicon Graphics | ||
11 | */ | ||
12 | #ifndef __ASM_MIPS_REG_H | ||
13 | #define __ASM_MIPS_REG_H | ||
14 | |||
15 | |||
16 | #if defined(CONFIG_32BIT) || defined(WANT_COMPAT_REG_H) | ||
17 | |||
18 | #define EF_R0 6 | ||
19 | #define EF_R1 7 | ||
20 | #define EF_R2 8 | ||
21 | #define EF_R3 9 | ||
22 | #define EF_R4 10 | ||
23 | #define EF_R5 11 | ||
24 | #define EF_R6 12 | ||
25 | #define EF_R7 13 | ||
26 | #define EF_R8 14 | ||
27 | #define EF_R9 15 | ||
28 | #define EF_R10 16 | ||
29 | #define EF_R11 17 | ||
30 | #define EF_R12 18 | ||
31 | #define EF_R13 19 | ||
32 | #define EF_R14 20 | ||
33 | #define EF_R15 21 | ||
34 | #define EF_R16 22 | ||
35 | #define EF_R17 23 | ||
36 | #define EF_R18 24 | ||
37 | #define EF_R19 25 | ||
38 | #define EF_R20 26 | ||
39 | #define EF_R21 27 | ||
40 | #define EF_R22 28 | ||
41 | #define EF_R23 29 | ||
42 | #define EF_R24 30 | ||
43 | #define EF_R25 31 | ||
44 | |||
45 | /* | ||
46 | * k0/k1 unsaved | ||
47 | */ | ||
48 | #define EF_R26 32 | ||
49 | #define EF_R27 33 | ||
50 | |||
51 | #define EF_R28 34 | ||
52 | #define EF_R29 35 | ||
53 | #define EF_R30 36 | ||
54 | #define EF_R31 37 | ||
55 | |||
56 | /* | ||
57 | * Saved special registers | ||
58 | */ | ||
59 | #define EF_LO 38 | ||
60 | #define EF_HI 39 | ||
61 | |||
62 | #define EF_CP0_EPC 40 | ||
63 | #define EF_CP0_BADVADDR 41 | ||
64 | #define EF_CP0_STATUS 42 | ||
65 | #define EF_CP0_CAUSE 43 | ||
66 | #define EF_UNUSED0 44 | ||
67 | |||
68 | #define EF_SIZE 180 | ||
69 | |||
70 | #endif | ||
71 | |||
72 | #if defined(CONFIG_64BIT) && !defined(WANT_COMPAT_REG_H) | ||
73 | |||
74 | #define EF_R0 0 | ||
75 | #define EF_R1 1 | ||
76 | #define EF_R2 2 | ||
77 | #define EF_R3 3 | ||
78 | #define EF_R4 4 | ||
79 | #define EF_R5 5 | ||
80 | #define EF_R6 6 | ||
81 | #define EF_R7 7 | ||
82 | #define EF_R8 8 | ||
83 | #define EF_R9 9 | ||
84 | #define EF_R10 10 | ||
85 | #define EF_R11 11 | ||
86 | #define EF_R12 12 | ||
87 | #define EF_R13 13 | ||
88 | #define EF_R14 14 | ||
89 | #define EF_R15 15 | ||
90 | #define EF_R16 16 | ||
91 | #define EF_R17 17 | ||
92 | #define EF_R18 18 | ||
93 | #define EF_R19 19 | ||
94 | #define EF_R20 20 | ||
95 | #define EF_R21 21 | ||
96 | #define EF_R22 22 | ||
97 | #define EF_R23 23 | ||
98 | #define EF_R24 24 | ||
99 | #define EF_R25 25 | ||
100 | |||
101 | /* | ||
102 | * k0/k1 unsaved | ||
103 | */ | ||
104 | #define EF_R26 26 | ||
105 | #define EF_R27 27 | ||
106 | |||
107 | |||
108 | #define EF_R28 28 | ||
109 | #define EF_R29 29 | ||
110 | #define EF_R30 30 | ||
111 | #define EF_R31 31 | ||
112 | |||
113 | /* | ||
114 | * Saved special registers | ||
115 | */ | ||
116 | #define EF_LO 32 | ||
117 | #define EF_HI 33 | ||
118 | |||
119 | #define EF_CP0_EPC 34 | ||
120 | #define EF_CP0_BADVADDR 35 | ||
121 | #define EF_CP0_STATUS 36 | ||
122 | #define EF_CP0_CAUSE 37 | ||
123 | |||
124 | #define EF_SIZE 304 /* size in bytes */ | ||
125 | |||
126 | #endif /* CONFIG_64BIT */ | ||
127 | |||
128 | #endif /* __ASM_MIPS_REG_H */ | ||
diff --git a/arch/mips/include/asm/smp-cps.h b/arch/mips/include/asm/smp-cps.h index a06a08a9afc6..326c16ebd589 100644 --- a/arch/mips/include/asm/smp-cps.h +++ b/arch/mips/include/asm/smp-cps.h | |||
@@ -31,11 +31,19 @@ extern void mips_cps_core_init(void); | |||
31 | 31 | ||
32 | extern struct vpe_boot_config *mips_cps_boot_vpes(void); | 32 | extern struct vpe_boot_config *mips_cps_boot_vpes(void); |
33 | 33 | ||
34 | extern bool mips_cps_smp_in_use(void); | ||
35 | |||
36 | extern void mips_cps_pm_save(void); | 34 | extern void mips_cps_pm_save(void); |
37 | extern void mips_cps_pm_restore(void); | 35 | extern void mips_cps_pm_restore(void); |
38 | 36 | ||
37 | #ifdef CONFIG_MIPS_CPS | ||
38 | |||
39 | extern bool mips_cps_smp_in_use(void); | ||
40 | |||
41 | #else /* !CONFIG_MIPS_CPS */ | ||
42 | |||
43 | static inline bool mips_cps_smp_in_use(void) { return false; } | ||
44 | |||
45 | #endif /* !CONFIG_MIPS_CPS */ | ||
46 | |||
39 | #else /* __ASSEMBLY__ */ | 47 | #else /* __ASSEMBLY__ */ |
40 | 48 | ||
41 | .extern mips_cps_bootcfg; | 49 | .extern mips_cps_bootcfg; |
diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h index b037334fca22..1e0f20a9cdda 100644 --- a/arch/mips/include/asm/smp.h +++ b/arch/mips/include/asm/smp.h | |||
@@ -22,6 +22,7 @@ | |||
22 | 22 | ||
23 | extern int smp_num_siblings; | 23 | extern int smp_num_siblings; |
24 | extern cpumask_t cpu_sibling_map[]; | 24 | extern cpumask_t cpu_sibling_map[]; |
25 | extern cpumask_t cpu_core_map[]; | ||
25 | 26 | ||
26 | #define raw_smp_processor_id() (current_thread_info()->cpu) | 27 | #define raw_smp_processor_id() (current_thread_info()->cpu) |
27 | 28 | ||
@@ -36,6 +37,11 @@ extern int __cpu_logical_map[NR_CPUS]; | |||
36 | 37 | ||
37 | #define NO_PROC_ID (-1) | 38 | #define NO_PROC_ID (-1) |
38 | 39 | ||
40 | #define topology_physical_package_id(cpu) (cpu_data[cpu].package) | ||
41 | #define topology_core_id(cpu) (cpu_data[cpu].core) | ||
42 | #define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) | ||
43 | #define topology_thread_cpumask(cpu) (&cpu_sibling_map[cpu]) | ||
44 | |||
39 | #define SMP_RESCHEDULE_YOURSELF 0x1 /* XXX braindead */ | 45 | #define SMP_RESCHEDULE_YOURSELF 0x1 /* XXX braindead */ |
40 | #define SMP_CALL_FUNCTION 0x2 | 46 | #define SMP_CALL_FUNCTION 0x2 |
41 | /* Octeon - Tell another core to flush its icache */ | 47 | /* Octeon - Tell another core to flush its icache */ |
diff --git a/arch/mips/include/asm/sparsemem.h b/arch/mips/include/asm/sparsemem.h index d2da53c2c2f8..b1071c1e54f5 100644 --- a/arch/mips/include/asm/sparsemem.h +++ b/arch/mips/include/asm/sparsemem.h | |||
@@ -11,7 +11,7 @@ | |||
11 | #else | 11 | #else |
12 | # define SECTION_SIZE_BITS 28 | 12 | # define SECTION_SIZE_BITS 28 |
13 | #endif | 13 | #endif |
14 | #define MAX_PHYSMEM_BITS 35 | 14 | #define MAX_PHYSMEM_BITS 48 |
15 | 15 | ||
16 | #endif /* CONFIG_SPARSEMEM */ | 16 | #endif /* CONFIG_SPARSEMEM */ |
17 | #endif /* _MIPS_SPARSEMEM_H */ | 17 | #endif /* _MIPS_SPARSEMEM_H */ |
diff --git a/arch/mips/include/asm/user.h b/arch/mips/include/asm/user.h deleted file mode 100644 index 6bad61b0a53a..000000000000 --- a/arch/mips/include/asm/user.h +++ /dev/null | |||
@@ -1,58 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 1994, 1995, 1996, 1999 by Ralf Baechle | ||
7 | */ | ||
8 | #ifndef _ASM_USER_H | ||
9 | #define _ASM_USER_H | ||
10 | |||
11 | #include <asm/page.h> | ||
12 | #include <asm/reg.h> | ||
13 | |||
14 | /* | ||
15 | * Core file format: The core file is written in such a way that gdb | ||
16 | * can understand it and provide useful information to the user (under | ||
17 | * linux we use the `trad-core' bfd, NOT the irix-core). The file | ||
18 | * contents are as follows: | ||
19 | * | ||
20 | * upage: 1 page consisting of a user struct that tells gdb | ||
21 | * what is present in the file. Directly after this is a | ||
22 | * copy of the task_struct, which is currently not used by gdb, | ||
23 | * but it may come in handy at some point. All of the registers | ||
24 | * are stored as part of the upage. The upage should always be | ||
25 | * only one page long. | ||
26 | * data: The data segment follows next. We use current->end_text to | ||
27 | * current->brk to pick up all of the user variables, plus any memory | ||
28 | * that may have been sbrk'ed. No attempt is made to determine if a | ||
29 | * page is demand-zero or if a page is totally unused, we just cover | ||
30 | * the entire range. All of the addresses are rounded in such a way | ||
31 | * that an integral number of pages is written. | ||
32 | * stack: We need the stack information in order to get a meaningful | ||
33 | * backtrace. We need to write the data from usp to | ||
34 | * current->start_stack, so we round each of these in order to be able | ||
35 | * to write an integer number of pages. | ||
36 | */ | ||
37 | struct user { | ||
38 | unsigned long regs[EF_SIZE / /* integer and fp regs */ | ||
39 | sizeof(unsigned long) + 64]; | ||
40 | size_t u_tsize; /* text size (pages) */ | ||
41 | size_t u_dsize; /* data size (pages) */ | ||
42 | size_t u_ssize; /* stack size (pages) */ | ||
43 | unsigned long start_code; /* text starting address */ | ||
44 | unsigned long start_data; /* data starting address */ | ||
45 | unsigned long start_stack; /* stack starting address */ | ||
46 | long int signal; /* signal causing core dump */ | ||
47 | unsigned long u_ar0; /* help gdb find registers */ | ||
48 | unsigned long magic; /* identifies a core file */ | ||
49 | char u_comm[32]; /* user command name */ | ||
50 | }; | ||
51 | |||
52 | #define NBPG PAGE_SIZE | ||
53 | #define UPAGES 1 | ||
54 | #define HOST_TEXT_START_ADDR (u.start_code) | ||
55 | #define HOST_DATA_START_ADDR (u.start_data) | ||
56 | #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) | ||
57 | |||
58 | #endif /* _ASM_USER_H */ | ||
diff --git a/arch/mips/include/uapi/asm/ptrace.h b/arch/mips/include/uapi/asm/ptrace.h index b26f7e317279..bbcfb8ba8106 100644 --- a/arch/mips/include/uapi/asm/ptrace.h +++ b/arch/mips/include/uapi/asm/ptrace.h | |||
@@ -22,24 +22,27 @@ | |||
22 | #define DSP_CONTROL 77 | 22 | #define DSP_CONTROL 77 |
23 | #define ACX 78 | 23 | #define ACX 78 |
24 | 24 | ||
25 | #ifndef __KERNEL__ | ||
26 | /* | 25 | /* |
27 | * This struct defines the way the registers are stored on the stack during a | 26 | * This struct defines the registers as used by PTRACE_{GET,SET}REGS. The |
28 | * system call/exception. As usual the registers k0/k1 aren't being saved. | 27 | * format is the same for both 32- and 64-bit processes. Registers for 32-bit |
28 | * processes are sign extended. | ||
29 | */ | 29 | */ |
30 | #ifdef __KERNEL__ | ||
31 | struct user_pt_regs { | ||
32 | #else | ||
30 | struct pt_regs { | 33 | struct pt_regs { |
34 | #endif | ||
31 | /* Saved main processor registers. */ | 35 | /* Saved main processor registers. */ |
32 | unsigned long regs[32]; | 36 | __u64 regs[32]; |
33 | 37 | ||
34 | /* Saved special registers. */ | 38 | /* Saved special registers. */ |
35 | unsigned long cp0_status; | 39 | __u64 lo; |
36 | unsigned long hi; | 40 | __u64 hi; |
37 | unsigned long lo; | 41 | __u64 cp0_epc; |
38 | unsigned long cp0_badvaddr; | 42 | __u64 cp0_badvaddr; |
39 | unsigned long cp0_cause; | 43 | __u64 cp0_status; |
40 | unsigned long cp0_epc; | 44 | __u64 cp0_cause; |
41 | } __attribute__ ((aligned (8))); | 45 | } __attribute__ ((aligned (8))); |
42 | #endif /* __KERNEL__ */ | ||
43 | 46 | ||
44 | /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ | 47 | /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ |
45 | #define PTRACE_GETREGS 12 | 48 | #define PTRACE_GETREGS 12 |
diff --git a/arch/mips/include/uapi/asm/reg.h b/arch/mips/include/uapi/asm/reg.h new file mode 100644 index 000000000000..081e377f4f02 --- /dev/null +++ b/arch/mips/include/uapi/asm/reg.h | |||
@@ -0,0 +1,206 @@ | |||
1 | /* | ||
2 | * Various register offset definitions for debuggers, core file | ||
3 | * examiners and whatnot. | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | * | ||
9 | * Copyright (C) 1995, 1999 Ralf Baechle | ||
10 | * Copyright (C) 1995, 1999 Silicon Graphics | ||
11 | */ | ||
12 | #ifndef __UAPI_ASM_MIPS_REG_H | ||
13 | #define __UAPI_ASM_MIPS_REG_H | ||
14 | |||
15 | #define MIPS32_EF_R0 6 | ||
16 | #define MIPS32_EF_R1 7 | ||
17 | #define MIPS32_EF_R2 8 | ||
18 | #define MIPS32_EF_R3 9 | ||
19 | #define MIPS32_EF_R4 10 | ||
20 | #define MIPS32_EF_R5 11 | ||
21 | #define MIPS32_EF_R6 12 | ||
22 | #define MIPS32_EF_R7 13 | ||
23 | #define MIPS32_EF_R8 14 | ||
24 | #define MIPS32_EF_R9 15 | ||
25 | #define MIPS32_EF_R10 16 | ||
26 | #define MIPS32_EF_R11 17 | ||
27 | #define MIPS32_EF_R12 18 | ||
28 | #define MIPS32_EF_R13 19 | ||
29 | #define MIPS32_EF_R14 20 | ||
30 | #define MIPS32_EF_R15 21 | ||
31 | #define MIPS32_EF_R16 22 | ||
32 | #define MIPS32_EF_R17 23 | ||
33 | #define MIPS32_EF_R18 24 | ||
34 | #define MIPS32_EF_R19 25 | ||
35 | #define MIPS32_EF_R20 26 | ||
36 | #define MIPS32_EF_R21 27 | ||
37 | #define MIPS32_EF_R22 28 | ||
38 | #define MIPS32_EF_R23 29 | ||
39 | #define MIPS32_EF_R24 30 | ||
40 | #define MIPS32_EF_R25 31 | ||
41 | |||
42 | /* | ||
43 | * k0/k1 unsaved | ||
44 | */ | ||
45 | #define MIPS32_EF_R26 32 | ||
46 | #define MIPS32_EF_R27 33 | ||
47 | |||
48 | #define MIPS32_EF_R28 34 | ||
49 | #define MIPS32_EF_R29 35 | ||
50 | #define MIPS32_EF_R30 36 | ||
51 | #define MIPS32_EF_R31 37 | ||
52 | |||
53 | /* | ||
54 | * Saved special registers | ||
55 | */ | ||
56 | #define MIPS32_EF_LO 38 | ||
57 | #define MIPS32_EF_HI 39 | ||
58 | |||
59 | #define MIPS32_EF_CP0_EPC 40 | ||
60 | #define MIPS32_EF_CP0_BADVADDR 41 | ||
61 | #define MIPS32_EF_CP0_STATUS 42 | ||
62 | #define MIPS32_EF_CP0_CAUSE 43 | ||
63 | #define MIPS32_EF_UNUSED0 44 | ||
64 | |||
65 | #define MIPS32_EF_SIZE 180 | ||
66 | |||
67 | #define MIPS64_EF_R0 0 | ||
68 | #define MIPS64_EF_R1 1 | ||
69 | #define MIPS64_EF_R2 2 | ||
70 | #define MIPS64_EF_R3 3 | ||
71 | #define MIPS64_EF_R4 4 | ||
72 | #define MIPS64_EF_R5 5 | ||
73 | #define MIPS64_EF_R6 6 | ||
74 | #define MIPS64_EF_R7 7 | ||
75 | #define MIPS64_EF_R8 8 | ||
76 | #define MIPS64_EF_R9 9 | ||
77 | #define MIPS64_EF_R10 10 | ||
78 | #define MIPS64_EF_R11 11 | ||
79 | #define MIPS64_EF_R12 12 | ||
80 | #define MIPS64_EF_R13 13 | ||
81 | #define MIPS64_EF_R14 14 | ||
82 | #define MIPS64_EF_R15 15 | ||
83 | #define MIPS64_EF_R16 16 | ||
84 | #define MIPS64_EF_R17 17 | ||
85 | #define MIPS64_EF_R18 18 | ||
86 | #define MIPS64_EF_R19 19 | ||
87 | #define MIPS64_EF_R20 20 | ||
88 | #define MIPS64_EF_R21 21 | ||
89 | #define MIPS64_EF_R22 22 | ||
90 | #define MIPS64_EF_R23 23 | ||
91 | #define MIPS64_EF_R24 24 | ||
92 | #define MIPS64_EF_R25 25 | ||
93 | |||
94 | /* | ||
95 | * k0/k1 unsaved | ||
96 | */ | ||
97 | #define MIPS64_EF_R26 26 | ||
98 | #define MIPS64_EF_R27 27 | ||
99 | |||
100 | |||
101 | #define MIPS64_EF_R28 28 | ||
102 | #define MIPS64_EF_R29 29 | ||
103 | #define MIPS64_EF_R30 30 | ||
104 | #define MIPS64_EF_R31 31 | ||
105 | |||
106 | /* | ||
107 | * Saved special registers | ||
108 | */ | ||
109 | #define MIPS64_EF_LO 32 | ||
110 | #define MIPS64_EF_HI 33 | ||
111 | |||
112 | #define MIPS64_EF_CP0_EPC 34 | ||
113 | #define MIPS64_EF_CP0_BADVADDR 35 | ||
114 | #define MIPS64_EF_CP0_STATUS 36 | ||
115 | #define MIPS64_EF_CP0_CAUSE 37 | ||
116 | |||
117 | #define MIPS64_EF_SIZE 304 /* size in bytes */ | ||
118 | |||
119 | #if _MIPS_SIM == _MIPS_SIM_ABI32 | ||
120 | |||
121 | #define EF_R0 MIPS32_EF_R0 | ||
122 | #define EF_R1 MIPS32_EF_R1 | ||
123 | #define EF_R2 MIPS32_EF_R2 | ||
124 | #define EF_R3 MIPS32_EF_R3 | ||
125 | #define EF_R4 MIPS32_EF_R4 | ||
126 | #define EF_R5 MIPS32_EF_R5 | ||
127 | #define EF_R6 MIPS32_EF_R6 | ||
128 | #define EF_R7 MIPS32_EF_R7 | ||
129 | #define EF_R8 MIPS32_EF_R8 | ||
130 | #define EF_R9 MIPS32_EF_R9 | ||
131 | #define EF_R10 MIPS32_EF_R10 | ||
132 | #define EF_R11 MIPS32_EF_R11 | ||
133 | #define EF_R12 MIPS32_EF_R12 | ||
134 | #define EF_R13 MIPS32_EF_R13 | ||
135 | #define EF_R14 MIPS32_EF_R14 | ||
136 | #define EF_R15 MIPS32_EF_R15 | ||
137 | #define EF_R16 MIPS32_EF_R16 | ||
138 | #define EF_R17 MIPS32_EF_R17 | ||
139 | #define EF_R18 MIPS32_EF_R18 | ||
140 | #define EF_R19 MIPS32_EF_R19 | ||
141 | #define EF_R20 MIPS32_EF_R20 | ||
142 | #define EF_R21 MIPS32_EF_R21 | ||
143 | #define EF_R22 MIPS32_EF_R22 | ||
144 | #define EF_R23 MIPS32_EF_R23 | ||
145 | #define EF_R24 MIPS32_EF_R24 | ||
146 | #define EF_R25 MIPS32_EF_R25 | ||
147 | #define EF_R26 MIPS32_EF_R26 | ||
148 | #define EF_R27 MIPS32_EF_R27 | ||
149 | #define EF_R28 MIPS32_EF_R28 | ||
150 | #define EF_R29 MIPS32_EF_R29 | ||
151 | #define EF_R30 MIPS32_EF_R30 | ||
152 | #define EF_R31 MIPS32_EF_R31 | ||
153 | #define EF_LO MIPS32_EF_LO | ||
154 | #define EF_HI MIPS32_EF_HI | ||
155 | #define EF_CP0_EPC MIPS32_EF_CP0_EPC | ||
156 | #define EF_CP0_BADVADDR MIPS32_EF_CP0_BADVADDR | ||
157 | #define EF_CP0_STATUS MIPS32_EF_CP0_STATUS | ||
158 | #define EF_CP0_CAUSE MIPS32_EF_CP0_CAUSE | ||
159 | #define EF_UNUSED0 MIPS32_EF_UNUSED0 | ||
160 | #define EF_SIZE MIPS32_EF_SIZE | ||
161 | |||
162 | #elif _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 | ||
163 | |||
164 | #define EF_R0 MIPS64_EF_R0 | ||
165 | #define EF_R1 MIPS64_EF_R1 | ||
166 | #define EF_R2 MIPS64_EF_R2 | ||
167 | #define EF_R3 MIPS64_EF_R3 | ||
168 | #define EF_R4 MIPS64_EF_R4 | ||
169 | #define EF_R5 MIPS64_EF_R5 | ||
170 | #define EF_R6 MIPS64_EF_R6 | ||
171 | #define EF_R7 MIPS64_EF_R7 | ||
172 | #define EF_R8 MIPS64_EF_R8 | ||
173 | #define EF_R9 MIPS64_EF_R9 | ||
174 | #define EF_R10 MIPS64_EF_R10 | ||
175 | #define EF_R11 MIPS64_EF_R11 | ||
176 | #define EF_R12 MIPS64_EF_R12 | ||
177 | #define EF_R13 MIPS64_EF_R13 | ||
178 | #define EF_R14 MIPS64_EF_R14 | ||
179 | #define EF_R15 MIPS64_EF_R15 | ||
180 | #define EF_R16 MIPS64_EF_R16 | ||
181 | #define EF_R17 MIPS64_EF_R17 | ||
182 | #define EF_R18 MIPS64_EF_R18 | ||
183 | #define EF_R19 MIPS64_EF_R19 | ||
184 | #define EF_R20 MIPS64_EF_R20 | ||
185 | #define EF_R21 MIPS64_EF_R21 | ||
186 | #define EF_R22 MIPS64_EF_R22 | ||
187 | #define EF_R23 MIPS64_EF_R23 | ||
188 | #define EF_R24 MIPS64_EF_R24 | ||
189 | #define EF_R25 MIPS64_EF_R25 | ||
190 | #define EF_R26 MIPS64_EF_R26 | ||
191 | #define EF_R27 MIPS64_EF_R27 | ||
192 | #define EF_R28 MIPS64_EF_R28 | ||
193 | #define EF_R29 MIPS64_EF_R29 | ||
194 | #define EF_R30 MIPS64_EF_R30 | ||
195 | #define EF_R31 MIPS64_EF_R31 | ||
196 | #define EF_LO MIPS64_EF_LO | ||
197 | #define EF_HI MIPS64_EF_HI | ||
198 | #define EF_CP0_EPC MIPS64_EF_CP0_EPC | ||
199 | #define EF_CP0_BADVADDR MIPS64_EF_CP0_BADVADDR | ||
200 | #define EF_CP0_STATUS MIPS64_EF_CP0_STATUS | ||
201 | #define EF_CP0_CAUSE MIPS64_EF_CP0_CAUSE | ||
202 | #define EF_SIZE MIPS64_EF_SIZE | ||
203 | |||
204 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 || _MIPS_SIM == _MIPS_SIM_NABI32 */ | ||
205 | |||
206 | #endif /* __UAPI_ASM_MIPS_REG_H */ | ||
diff --git a/arch/mips/jz4740/clock-debugfs.c b/arch/mips/jz4740/clock-debugfs.c index a8acdeff267e..325422d0d453 100644 --- a/arch/mips/jz4740/clock-debugfs.c +++ b/arch/mips/jz4740/clock-debugfs.c | |||
@@ -87,8 +87,7 @@ void jz4740_clock_debugfs_add_clk(struct clk *clk) | |||
87 | /* TODO: Locking */ | 87 | /* TODO: Locking */ |
88 | void jz4740_clock_debugfs_update_parent(struct clk *clk) | 88 | void jz4740_clock_debugfs_update_parent(struct clk *clk) |
89 | { | 89 | { |
90 | if (clk->debugfs_parent_entry) | 90 | debugfs_remove(clk->debugfs_parent_entry); |
91 | debugfs_remove(clk->debugfs_parent_entry); | ||
92 | 91 | ||
93 | if (clk->parent) { | 92 | if (clk->parent) { |
94 | char parent_path[100]; | 93 | char parent_path[100]; |
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c index a447101cf9f1..0b12f273cb2e 100644 --- a/arch/mips/jz4740/platform.c +++ b/arch/mips/jz4740/platform.c | |||
@@ -59,7 +59,7 @@ struct platform_device jz4740_usb_ohci_device = { | |||
59 | 59 | ||
60 | /* USB Device Controller */ | 60 | /* USB Device Controller */ |
61 | struct platform_device jz4740_udc_xceiv_device = { | 61 | struct platform_device jz4740_udc_xceiv_device = { |
62 | .name = "usb_phy_gen_xceiv", | 62 | .name = "usb_phy_generic", |
63 | .id = 0, | 63 | .id = 0, |
64 | }; | 64 | }; |
65 | 65 | ||
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index 4bb5107511e2..b1d84bd4efb3 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c | |||
@@ -234,6 +234,7 @@ void output_thread_fpu_defines(void) | |||
234 | thread.fpu.fpr[31].val64[FPR_IDX(64, 0)]); | 234 | thread.fpu.fpr[31].val64[FPR_IDX(64, 0)]); |
235 | 235 | ||
236 | OFFSET(THREAD_FCR31, task_struct, thread.fpu.fcr31); | 236 | OFFSET(THREAD_FCR31, task_struct, thread.fpu.fcr31); |
237 | OFFSET(THREAD_MSA_CSR, task_struct, thread.fpu.msacsr); | ||
237 | BLANK(); | 238 | BLANK(); |
238 | } | 239 | } |
239 | 240 | ||
diff --git a/arch/mips/kernel/binfmt_elfo32.c b/arch/mips/kernel/binfmt_elfo32.c index 7faf5f2bee25..928767858b86 100644 --- a/arch/mips/kernel/binfmt_elfo32.c +++ b/arch/mips/kernel/binfmt_elfo32.c | |||
@@ -72,22 +72,6 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; | |||
72 | 72 | ||
73 | #include <asm/processor.h> | 73 | #include <asm/processor.h> |
74 | 74 | ||
75 | /* | ||
76 | * When this file is selected, we are definitely running a 64bit kernel. | ||
77 | * So using the right regs define in asm/reg.h | ||
78 | */ | ||
79 | #define WANT_COMPAT_REG_H | ||
80 | |||
81 | /* These MUST be defined before elf.h gets included */ | ||
82 | extern void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs); | ||
83 | #define ELF_CORE_COPY_REGS(_dest, _regs) elf32_core_copy_regs(_dest, _regs); | ||
84 | #define ELF_CORE_COPY_TASK_REGS(_tsk, _dest) \ | ||
85 | ({ \ | ||
86 | int __res = 1; \ | ||
87 | elf32_core_copy_regs(*(_dest), task_pt_regs(_tsk)); \ | ||
88 | __res; \ | ||
89 | }) | ||
90 | |||
91 | #include <linux/module.h> | 75 | #include <linux/module.h> |
92 | #include <linux/elfcore.h> | 76 | #include <linux/elfcore.h> |
93 | #include <linux/compat.h> | 77 | #include <linux/compat.h> |
@@ -145,28 +129,6 @@ jiffies_to_compat_timeval(unsigned long jiffies, struct compat_timeval *value) | |||
145 | value->tv_usec = rem / NSEC_PER_USEC; | 129 | value->tv_usec = rem / NSEC_PER_USEC; |
146 | } | 130 | } |
147 | 131 | ||
148 | void elf32_core_copy_regs(elf_gregset_t grp, struct pt_regs *regs) | ||
149 | { | ||
150 | int i; | ||
151 | |||
152 | for (i = 0; i < EF_R0; i++) | ||
153 | grp[i] = 0; | ||
154 | grp[EF_R0] = 0; | ||
155 | for (i = 1; i <= 31; i++) | ||
156 | grp[EF_R0 + i] = (elf_greg_t) regs->regs[i]; | ||
157 | grp[EF_R26] = 0; | ||
158 | grp[EF_R27] = 0; | ||
159 | grp[EF_LO] = (elf_greg_t) regs->lo; | ||
160 | grp[EF_HI] = (elf_greg_t) regs->hi; | ||
161 | grp[EF_CP0_EPC] = (elf_greg_t) regs->cp0_epc; | ||
162 | grp[EF_CP0_BADVADDR] = (elf_greg_t) regs->cp0_badvaddr; | ||
163 | grp[EF_CP0_STATUS] = (elf_greg_t) regs->cp0_status; | ||
164 | grp[EF_CP0_CAUSE] = (elf_greg_t) regs->cp0_cause; | ||
165 | #ifdef EF_UNUSED0 | ||
166 | grp[EF_UNUSED0] = 0; | ||
167 | #endif | ||
168 | } | ||
169 | |||
170 | MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries"); | 132 | MODULE_DESCRIPTION("Binary format loader for compatibility with o32 Linux/MIPS binaries"); |
171 | MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); | 133 | MODULE_AUTHOR("Ralf Baechle (ralf@linux-mips.org)"); |
172 | 134 | ||
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index d74f957c561e..e34b10be782e 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -54,6 +54,20 @@ static int __init dsp_disable(char *s) | |||
54 | 54 | ||
55 | __setup("nodsp", dsp_disable); | 55 | __setup("nodsp", dsp_disable); |
56 | 56 | ||
57 | static int mips_htw_disabled; | ||
58 | |||
59 | static int __init htw_disable(char *s) | ||
60 | { | ||
61 | mips_htw_disabled = 1; | ||
62 | cpu_data[0].options &= ~MIPS_CPU_HTW; | ||
63 | write_c0_pwctl(read_c0_pwctl() & | ||
64 | ~(1 << MIPS_PWCTL_PWEN_SHIFT)); | ||
65 | |||
66 | return 1; | ||
67 | } | ||
68 | |||
69 | __setup("nohtw", htw_disable); | ||
70 | |||
57 | static inline void check_errata(void) | 71 | static inline void check_errata(void) |
58 | { | 72 | { |
59 | struct cpuinfo_mips *c = ¤t_cpu_data; | 73 | struct cpuinfo_mips *c = ¤t_cpu_data; |
@@ -130,14 +144,13 @@ static inline int __cpu_has_fpu(void) | |||
130 | 144 | ||
131 | static inline unsigned long cpu_get_msa_id(void) | 145 | static inline unsigned long cpu_get_msa_id(void) |
132 | { | 146 | { |
133 | unsigned long status, conf5, msa_id; | 147 | unsigned long status, msa_id; |
134 | 148 | ||
135 | status = read_c0_status(); | 149 | status = read_c0_status(); |
136 | __enable_fpu(FPU_64BIT); | 150 | __enable_fpu(FPU_64BIT); |
137 | conf5 = read_c0_config5(); | ||
138 | enable_msa(); | 151 | enable_msa(); |
139 | msa_id = read_msa_ir(); | 152 | msa_id = read_msa_ir(); |
140 | write_c0_config5(conf5); | 153 | disable_msa(); |
141 | write_c0_status(status); | 154 | write_c0_status(status); |
142 | return msa_id; | 155 | return msa_id; |
143 | } | 156 | } |
@@ -321,6 +334,9 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) | |||
321 | c->options |= MIPS_CPU_SEGMENTS; | 334 | c->options |= MIPS_CPU_SEGMENTS; |
322 | if (config3 & MIPS_CONF3_MSA) | 335 | if (config3 & MIPS_CONF3_MSA) |
323 | c->ases |= MIPS_ASE_MSA; | 336 | c->ases |= MIPS_ASE_MSA; |
337 | /* Only tested on 32-bit cores */ | ||
338 | if ((config3 & MIPS_CONF3_PW) && config_enabled(CONFIG_32BIT)) | ||
339 | c->options |= MIPS_CPU_HTW; | ||
324 | 340 | ||
325 | return config3 & MIPS_CONF_M; | 341 | return config3 & MIPS_CONF_M; |
326 | } | 342 | } |
@@ -389,6 +405,8 @@ static inline unsigned int decode_config5(struct cpuinfo_mips *c) | |||
389 | 405 | ||
390 | if (config5 & MIPS_CONF5_EVA) | 406 | if (config5 & MIPS_CONF5_EVA) |
391 | c->options |= MIPS_CPU_EVA; | 407 | c->options |= MIPS_CPU_EVA; |
408 | if (config5 & MIPS_CONF5_MRP) | ||
409 | c->options |= MIPS_CPU_MAAR; | ||
392 | 410 | ||
393 | return config5 & MIPS_CONF_M; | 411 | return config5 & MIPS_CONF_M; |
394 | } | 412 | } |
@@ -421,6 +439,15 @@ static void decode_configs(struct cpuinfo_mips *c) | |||
421 | 439 | ||
422 | mips_probe_watch_registers(c); | 440 | mips_probe_watch_registers(c); |
423 | 441 | ||
442 | if (cpu_has_rixi) { | ||
443 | /* Enable the RIXI exceptions */ | ||
444 | write_c0_pagegrain(read_c0_pagegrain() | PG_IEC); | ||
445 | back_to_back_c0_hazard(); | ||
446 | /* Verify the IEC bit is set */ | ||
447 | if (read_c0_pagegrain() & PG_IEC) | ||
448 | c->options |= MIPS_CPU_RIXIEX; | ||
449 | } | ||
450 | |||
424 | #ifndef CONFIG_MIPS_CPS | 451 | #ifndef CONFIG_MIPS_CPS |
425 | if (cpu_has_mips_r2) { | 452 | if (cpu_has_mips_r2) { |
426 | c->core = get_ebase_cpunum(); | 453 | c->core = get_ebase_cpunum(); |
@@ -740,6 +767,12 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
740 | __cpu_name[cpu] = "ICT Loongson-3"; | 767 | __cpu_name[cpu] = "ICT Loongson-3"; |
741 | set_elf_platform(cpu, "loongson3a"); | 768 | set_elf_platform(cpu, "loongson3a"); |
742 | break; | 769 | break; |
770 | case PRID_REV_LOONGSON3B_R1: | ||
771 | case PRID_REV_LOONGSON3B_R2: | ||
772 | c->cputype = CPU_LOONGSON3; | ||
773 | __cpu_name[cpu] = "ICT Loongson-3"; | ||
774 | set_elf_platform(cpu, "loongson3b"); | ||
775 | break; | ||
743 | } | 776 | } |
744 | 777 | ||
745 | set_isa(c, MIPS_CPU_ISA_III); | 778 | set_isa(c, MIPS_CPU_ISA_III); |
@@ -1187,6 +1220,12 @@ void cpu_probe(void) | |||
1187 | if (mips_dsp_disabled) | 1220 | if (mips_dsp_disabled) |
1188 | c->ases &= ~(MIPS_ASE_DSP | MIPS_ASE_DSP2P); | 1221 | c->ases &= ~(MIPS_ASE_DSP | MIPS_ASE_DSP2P); |
1189 | 1222 | ||
1223 | if (mips_htw_disabled) { | ||
1224 | c->options &= ~MIPS_CPU_HTW; | ||
1225 | write_c0_pwctl(read_c0_pwctl() & | ||
1226 | ~(1 << MIPS_PWCTL_PWEN_SHIFT)); | ||
1227 | } | ||
1228 | |||
1190 | if (c->options & MIPS_CPU_FPU) { | 1229 | if (c->options & MIPS_CPU_FPU) { |
1191 | c->fpu_id = cpu_get_fpu_id(); | 1230 | c->fpu_id = cpu_get_fpu_id(); |
1192 | 1231 | ||
diff --git a/arch/mips/kernel/ftrace.c b/arch/mips/kernel/ftrace.c index 8b6538750fe1..937c54bc8ccc 100644 --- a/arch/mips/kernel/ftrace.c +++ b/arch/mips/kernel/ftrace.c | |||
@@ -63,7 +63,7 @@ static inline int in_kernel_space(unsigned long ip) | |||
63 | ((unsigned int)(JAL | (((addr) >> 2) & ADDR_MASK))) | 63 | ((unsigned int)(JAL | (((addr) >> 2) & ADDR_MASK))) |
64 | 64 | ||
65 | static unsigned int insn_jal_ftrace_caller __read_mostly; | 65 | static unsigned int insn_jal_ftrace_caller __read_mostly; |
66 | static unsigned int insn_lui_v1_hi16_mcount __read_mostly; | 66 | static unsigned int insn_la_mcount[2] __read_mostly; |
67 | static unsigned int insn_j_ftrace_graph_caller __maybe_unused __read_mostly; | 67 | static unsigned int insn_j_ftrace_graph_caller __maybe_unused __read_mostly; |
68 | 68 | ||
69 | static inline void ftrace_dyn_arch_init_insns(void) | 69 | static inline void ftrace_dyn_arch_init_insns(void) |
@@ -71,10 +71,10 @@ static inline void ftrace_dyn_arch_init_insns(void) | |||
71 | u32 *buf; | 71 | u32 *buf; |
72 | unsigned int v1; | 72 | unsigned int v1; |
73 | 73 | ||
74 | /* lui v1, hi16_mcount */ | 74 | /* la v1, _mcount */ |
75 | v1 = 3; | 75 | v1 = 3; |
76 | buf = (u32 *)&insn_lui_v1_hi16_mcount; | 76 | buf = (u32 *)&insn_la_mcount[0]; |
77 | UASM_i_LA_mostly(&buf, v1, MCOUNT_ADDR); | 77 | UASM_i_LA(&buf, v1, MCOUNT_ADDR); |
78 | 78 | ||
79 | /* jal (ftrace_caller + 8), jump over the first two instruction */ | 79 | /* jal (ftrace_caller + 8), jump over the first two instruction */ |
80 | buf = (u32 *)&insn_jal_ftrace_caller; | 80 | buf = (u32 *)&insn_jal_ftrace_caller; |
@@ -111,14 +111,47 @@ static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1, | |||
111 | unsigned int new_code2) | 111 | unsigned int new_code2) |
112 | { | 112 | { |
113 | int faulted; | 113 | int faulted; |
114 | mm_segment_t old_fs; | ||
114 | 115 | ||
115 | safe_store_code(new_code1, ip, faulted); | 116 | safe_store_code(new_code1, ip, faulted); |
116 | if (unlikely(faulted)) | 117 | if (unlikely(faulted)) |
117 | return -EFAULT; | 118 | return -EFAULT; |
118 | safe_store_code(new_code2, ip + 4, faulted); | 119 | |
120 | ip += 4; | ||
121 | safe_store_code(new_code2, ip, faulted); | ||
119 | if (unlikely(faulted)) | 122 | if (unlikely(faulted)) |
120 | return -EFAULT; | 123 | return -EFAULT; |
124 | |||
125 | ip -= 4; | ||
126 | old_fs = get_fs(); | ||
127 | set_fs(get_ds()); | ||
121 | flush_icache_range(ip, ip + 8); | 128 | flush_icache_range(ip, ip + 8); |
129 | set_fs(old_fs); | ||
130 | |||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | static int ftrace_modify_code_2r(unsigned long ip, unsigned int new_code1, | ||
135 | unsigned int new_code2) | ||
136 | { | ||
137 | int faulted; | ||
138 | mm_segment_t old_fs; | ||
139 | |||
140 | ip += 4; | ||
141 | safe_store_code(new_code2, ip, faulted); | ||
142 | if (unlikely(faulted)) | ||
143 | return -EFAULT; | ||
144 | |||
145 | ip -= 4; | ||
146 | safe_store_code(new_code1, ip, faulted); | ||
147 | if (unlikely(faulted)) | ||
148 | return -EFAULT; | ||
149 | |||
150 | old_fs = get_fs(); | ||
151 | set_fs(get_ds()); | ||
152 | flush_icache_range(ip, ip + 8); | ||
153 | set_fs(old_fs); | ||
154 | |||
122 | return 0; | 155 | return 0; |
123 | } | 156 | } |
124 | #endif | 157 | #endif |
@@ -130,13 +163,14 @@ static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1, | |||
130 | * | 163 | * |
131 | * move at, ra | 164 | * move at, ra |
132 | * jal _mcount --> nop | 165 | * jal _mcount --> nop |
166 | * sub sp, sp, 8 --> nop (CONFIG_32BIT) | ||
133 | * | 167 | * |
134 | * 2. For modules: | 168 | * 2. For modules: |
135 | * | 169 | * |
136 | * 2.1 For KBUILD_MCOUNT_RA_ADDRESS and CONFIG_32BIT | 170 | * 2.1 For KBUILD_MCOUNT_RA_ADDRESS and CONFIG_32BIT |
137 | * | 171 | * |
138 | * lui v1, hi_16bit_of_mcount --> b 1f (0x10000005) | 172 | * lui v1, hi_16bit_of_mcount --> b 1f (0x10000005) |
139 | * addiu v1, v1, low_16bit_of_mcount | 173 | * addiu v1, v1, low_16bit_of_mcount --> nop (CONFIG_32BIT) |
140 | * move at, ra | 174 | * move at, ra |
141 | * move $12, ra_address | 175 | * move $12, ra_address |
142 | * jalr v1 | 176 | * jalr v1 |
@@ -145,7 +179,7 @@ static int ftrace_modify_code_2(unsigned long ip, unsigned int new_code1, | |||
145 | * 2.2 For the Other situations | 179 | * 2.2 For the Other situations |
146 | * | 180 | * |
147 | * lui v1, hi_16bit_of_mcount --> b 1f (0x10000004) | 181 | * lui v1, hi_16bit_of_mcount --> b 1f (0x10000004) |
148 | * addiu v1, v1, low_16bit_of_mcount | 182 | * addiu v1, v1, low_16bit_of_mcount --> nop (CONFIG_32BIT) |
149 | * move at, ra | 183 | * move at, ra |
150 | * jalr v1 | 184 | * jalr v1 |
151 | * nop | move $12, ra_address | sub sp, sp, 8 | 185 | * nop | move $12, ra_address | sub sp, sp, 8 |
@@ -184,10 +218,14 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) | |||
184 | unsigned int new; | 218 | unsigned int new; |
185 | unsigned long ip = rec->ip; | 219 | unsigned long ip = rec->ip; |
186 | 220 | ||
187 | new = in_kernel_space(ip) ? insn_jal_ftrace_caller : | 221 | new = in_kernel_space(ip) ? insn_jal_ftrace_caller : insn_la_mcount[0]; |
188 | insn_lui_v1_hi16_mcount; | ||
189 | 222 | ||
223 | #ifdef CONFIG_64BIT | ||
190 | return ftrace_modify_code(ip, new); | 224 | return ftrace_modify_code(ip, new); |
225 | #else | ||
226 | return ftrace_modify_code_2r(ip, new, in_kernel_space(ip) ? | ||
227 | INSN_NOP : insn_la_mcount[1]); | ||
228 | #endif | ||
191 | } | 229 | } |
192 | 230 | ||
193 | #define FTRACE_CALL_IP ((unsigned long)(&ftrace_call)) | 231 | #define FTRACE_CALL_IP ((unsigned long)(&ftrace_call)) |
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c index 88e4c323382c..9e9d8b9a5b97 100644 --- a/arch/mips/kernel/irq-gic.c +++ b/arch/mips/kernel/irq-gic.c | |||
@@ -28,6 +28,18 @@ unsigned int gic_irq_flags[GIC_NUM_INTRS]; | |||
28 | /* The index into this array is the vector # of the interrupt. */ | 28 | /* The index into this array is the vector # of the interrupt. */ |
29 | struct gic_shared_intr_map gic_shared_intr_map[GIC_NUM_INTRS]; | 29 | struct gic_shared_intr_map gic_shared_intr_map[GIC_NUM_INTRS]; |
30 | 30 | ||
31 | struct gic_pcpu_mask { | ||
32 | DECLARE_BITMAP(pcpu_mask, GIC_NUM_INTRS); | ||
33 | }; | ||
34 | |||
35 | struct gic_pending_regs { | ||
36 | DECLARE_BITMAP(pending, GIC_NUM_INTRS); | ||
37 | }; | ||
38 | |||
39 | struct gic_intrmask_regs { | ||
40 | DECLARE_BITMAP(intrmask, GIC_NUM_INTRS); | ||
41 | }; | ||
42 | |||
31 | static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; | 43 | static struct gic_pcpu_mask pcpu_masks[NR_CPUS]; |
32 | static struct gic_pending_regs pending_regs[NR_CPUS]; | 44 | static struct gic_pending_regs pending_regs[NR_CPUS]; |
33 | static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; | 45 | static struct gic_intrmask_regs intrmask_regs[NR_CPUS]; |
@@ -177,7 +189,7 @@ unsigned int gic_compare_int(void) | |||
177 | return 0; | 189 | return 0; |
178 | } | 190 | } |
179 | 191 | ||
180 | unsigned int gic_get_int(void) | 192 | void gic_get_int_mask(unsigned long *dst, const unsigned long *src) |
181 | { | 193 | { |
182 | unsigned int i; | 194 | unsigned int i; |
183 | unsigned long *pending, *intrmask, *pcpu_mask; | 195 | unsigned long *pending, *intrmask, *pcpu_mask; |
@@ -202,8 +214,17 @@ unsigned int gic_get_int(void) | |||
202 | 214 | ||
203 | bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS); | 215 | bitmap_and(pending, pending, intrmask, GIC_NUM_INTRS); |
204 | bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS); | 216 | bitmap_and(pending, pending, pcpu_mask, GIC_NUM_INTRS); |
217 | bitmap_and(dst, src, pending, GIC_NUM_INTRS); | ||
218 | } | ||
205 | 219 | ||
206 | return find_first_bit(pending, GIC_NUM_INTRS); | 220 | unsigned int gic_get_int(void) |
221 | { | ||
222 | DECLARE_BITMAP(interrupts, GIC_NUM_INTRS); | ||
223 | |||
224 | bitmap_fill(interrupts, GIC_NUM_INTRS); | ||
225 | gic_get_int_mask(interrupts, interrupts); | ||
226 | |||
227 | return find_first_bit(interrupts, GIC_NUM_INTRS); | ||
207 | } | 228 | } |
208 | 229 | ||
209 | static void gic_mask_irq(struct irq_data *d) | 230 | static void gic_mask_irq(struct irq_data *d) |
@@ -269,11 +290,13 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, | |||
269 | 290 | ||
270 | /* Setup Intr to Pin mapping */ | 291 | /* Setup Intr to Pin mapping */ |
271 | if (pin & GIC_MAP_TO_NMI_MSK) { | 292 | if (pin & GIC_MAP_TO_NMI_MSK) { |
293 | int i; | ||
294 | |||
272 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin); | 295 | GICWRITE(GIC_REG_ADDR(SHARED, GIC_SH_MAP_TO_PIN(intr)), pin); |
273 | /* FIXME: hack to route NMI to all cpu's */ | 296 | /* FIXME: hack to route NMI to all cpu's */ |
274 | for (cpu = 0; cpu < NR_CPUS; cpu += 32) { | 297 | for (i = 0; i < NR_CPUS; i += 32) { |
275 | GICWRITE(GIC_REG_ADDR(SHARED, | 298 | GICWRITE(GIC_REG_ADDR(SHARED, |
276 | GIC_SH_MAP_TO_VPE_REG_OFF(intr, cpu)), | 299 | GIC_SH_MAP_TO_VPE_REG_OFF(intr, i)), |
277 | 0xffffffff); | 300 | 0xffffffff); |
278 | } | 301 | } |
279 | } else { | 302 | } else { |
@@ -299,9 +322,10 @@ static void __init gic_setup_intr(unsigned int intr, unsigned int cpu, | |||
299 | 322 | ||
300 | /* Init Intr Masks */ | 323 | /* Init Intr Masks */ |
301 | GIC_CLR_INTR_MASK(intr); | 324 | GIC_CLR_INTR_MASK(intr); |
325 | |||
302 | /* Initialise per-cpu Interrupt software masks */ | 326 | /* Initialise per-cpu Interrupt software masks */ |
303 | if (flags & GIC_FLAG_IPI) | 327 | set_bit(intr, pcpu_masks[cpu].pcpu_mask); |
304 | set_bit(intr, pcpu_masks[cpu].pcpu_mask); | 328 | |
305 | if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0)) | 329 | if ((flags & GIC_FLAG_TRANSPARENT) && (cpu_has_veic == 0)) |
306 | GIC_SET_INTR_MASK(intr); | 330 | GIC_SET_INTR_MASK(intr); |
307 | if (trigtype == GIC_TRIG_EDGE) | 331 | if (trigtype == GIC_TRIG_EDGE) |
@@ -340,8 +364,6 @@ static void __init gic_basic_init(int numintrs, int numvpes, | |||
340 | cpu = intrmap[i].cpunum; | 364 | cpu = intrmap[i].cpunum; |
341 | if (cpu == GIC_UNUSED) | 365 | if (cpu == GIC_UNUSED) |
342 | continue; | 366 | continue; |
343 | if (cpu == 0 && i != 0 && intrmap[i].flags == 0) | ||
344 | continue; | ||
345 | gic_setup_intr(i, | 367 | gic_setup_intr(i, |
346 | intrmap[i].cpunum, | 368 | intrmap[i].cpunum, |
347 | intrmap[i].pin + pin_offset, | 369 | intrmap[i].pin + pin_offset, |
diff --git a/arch/mips/kernel/mcount.S b/arch/mips/kernel/mcount.S index 00940d1d5c4f..5d25462de8a6 100644 --- a/arch/mips/kernel/mcount.S +++ b/arch/mips/kernel/mcount.S | |||
@@ -80,6 +80,19 @@ _mcount: | |||
80 | #endif | 80 | #endif |
81 | 81 | ||
82 | PTR_SUBU a0, ra, 8 /* arg1: self address */ | 82 | PTR_SUBU a0, ra, 8 /* arg1: self address */ |
83 | PTR_LA t1, _stext | ||
84 | sltu t2, a0, t1 /* t2 = (a0 < _stext) */ | ||
85 | PTR_LA t1, _etext | ||
86 | sltu t3, t1, a0 /* t3 = (a0 > _etext) */ | ||
87 | or t1, t2, t3 | ||
88 | beqz t1, ftrace_call | ||
89 | nop | ||
90 | #if defined(KBUILD_MCOUNT_RA_ADDRESS) && defined(CONFIG_32BIT) | ||
91 | PTR_SUBU a0, a0, 16 /* arg1: adjust to module's recorded callsite */ | ||
92 | #else | ||
93 | PTR_SUBU a0, a0, 12 | ||
94 | #endif | ||
95 | |||
83 | .globl ftrace_call | 96 | .globl ftrace_call |
84 | ftrace_call: | 97 | ftrace_call: |
85 | nop /* a placeholder for the call to a real tracing function */ | 98 | nop /* a placeholder for the call to a real tracing function */ |
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 4f2d9dece7ab..14bf74b0f51c 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c | |||
@@ -1386,6 +1386,9 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev) | |||
1386 | /* proAptiv */ | 1386 | /* proAptiv */ |
1387 | #define IS_BOTH_COUNTERS_PROAPTIV_EVENT(b) \ | 1387 | #define IS_BOTH_COUNTERS_PROAPTIV_EVENT(b) \ |
1388 | ((b) == 0 || (b) == 1) | 1388 | ((b) == 0 || (b) == 1) |
1389 | /* P5600 */ | ||
1390 | #define IS_BOTH_COUNTERS_P5600_EVENT(b) \ | ||
1391 | ((b) == 0 || (b) == 1) | ||
1389 | 1392 | ||
1390 | /* 1004K */ | 1393 | /* 1004K */ |
1391 | #define IS_BOTH_COUNTERS_1004K_EVENT(b) \ | 1394 | #define IS_BOTH_COUNTERS_1004K_EVENT(b) \ |
@@ -1420,20 +1423,23 @@ static irqreturn_t mipsxx_pmu_handle_irq(int irq, void *dev) | |||
1420 | 1423 | ||
1421 | 1424 | ||
1422 | /* | 1425 | /* |
1423 | * User can use 0-255 raw events, where 0-127 for the events of even | 1426 | * For most cores the user can use 0-255 raw events, where 0-127 for the events |
1424 | * counters, and 128-255 for odd counters. Note that bit 7 is used to | 1427 | * of even counters, and 128-255 for odd counters. Note that bit 7 is used to |
1425 | * indicate the parity. So, for example, when user wants to take the | 1428 | * indicate the even/odd bank selector. So, for example, when user wants to take |
1426 | * Event Num of 15 for odd counters (by referring to the user manual), | 1429 | * the Event Num of 15 for odd counters (by referring to the user manual), then |
1427 | * then 128 needs to be added to 15 as the input for the event config, | 1430 | * 128 needs to be added to 15 as the input for the event config, i.e., 143 (0x8F) |
1428 | * i.e., 143 (0x8F) to be used. | 1431 | * to be used. |
1432 | * | ||
1433 | * Some newer cores have even more events, in which case the user can use raw | ||
1434 | * events 0-511, where 0-255 are for the events of even counters, and 256-511 | ||
1435 | * are for odd counters, so bit 8 is used to indicate the even/odd bank selector. | ||
1429 | */ | 1436 | */ |
1430 | static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) | 1437 | static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) |
1431 | { | 1438 | { |
1439 | /* currently most cores have 7-bit event numbers */ | ||
1432 | unsigned int raw_id = config & 0xff; | 1440 | unsigned int raw_id = config & 0xff; |
1433 | unsigned int base_id = raw_id & 0x7f; | 1441 | unsigned int base_id = raw_id & 0x7f; |
1434 | 1442 | ||
1435 | raw_event.event_id = base_id; | ||
1436 | |||
1437 | switch (current_cpu_type()) { | 1443 | switch (current_cpu_type()) { |
1438 | case CPU_24K: | 1444 | case CPU_24K: |
1439 | if (IS_BOTH_COUNTERS_24K_EVENT(base_id)) | 1445 | if (IS_BOTH_COUNTERS_24K_EVENT(base_id)) |
@@ -1485,6 +1491,19 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) | |||
1485 | raw_event.range = P; | 1491 | raw_event.range = P; |
1486 | #endif | 1492 | #endif |
1487 | break; | 1493 | break; |
1494 | case CPU_P5600: | ||
1495 | /* 8-bit event numbers */ | ||
1496 | raw_id = config & 0x1ff; | ||
1497 | base_id = raw_id & 0xff; | ||
1498 | if (IS_BOTH_COUNTERS_P5600_EVENT(base_id)) | ||
1499 | raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; | ||
1500 | else | ||
1501 | raw_event.cntr_mask = | ||
1502 | raw_id > 255 ? CNTR_ODD : CNTR_EVEN; | ||
1503 | #ifdef CONFIG_MIPS_MT_SMP | ||
1504 | raw_event.range = P; | ||
1505 | #endif | ||
1506 | break; | ||
1488 | case CPU_1004K: | 1507 | case CPU_1004K: |
1489 | if (IS_BOTH_COUNTERS_1004K_EVENT(base_id)) | 1508 | if (IS_BOTH_COUNTERS_1004K_EVENT(base_id)) |
1490 | raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; | 1509 | raw_event.cntr_mask = CNTR_EVEN | CNTR_ODD; |
@@ -1523,6 +1542,8 @@ static const struct mips_perf_event *mipsxx_pmu_map_raw_event(u64 config) | |||
1523 | raw_id > 127 ? CNTR_ODD : CNTR_EVEN; | 1542 | raw_id > 127 ? CNTR_ODD : CNTR_EVEN; |
1524 | } | 1543 | } |
1525 | 1544 | ||
1545 | raw_event.event_id = base_id; | ||
1546 | |||
1526 | return &raw_event; | 1547 | return &raw_event; |
1527 | } | 1548 | } |
1528 | 1549 | ||
@@ -1633,6 +1654,11 @@ init_hw_perf_events(void) | |||
1633 | mipspmu.general_event_map = &mipsxxcore_event_map2; | 1654 | mipspmu.general_event_map = &mipsxxcore_event_map2; |
1634 | mipspmu.cache_event_map = &mipsxxcore_cache_map2; | 1655 | mipspmu.cache_event_map = &mipsxxcore_cache_map2; |
1635 | break; | 1656 | break; |
1657 | case CPU_P5600: | ||
1658 | mipspmu.name = "mips/P5600"; | ||
1659 | mipspmu.general_event_map = &mipsxxcore_event_map2; | ||
1660 | mipspmu.cache_event_map = &mipsxxcore_cache_map2; | ||
1661 | break; | ||
1636 | case CPU_1004K: | 1662 | case CPU_1004K: |
1637 | mipspmu.name = "mips/1004K"; | 1663 | mipspmu.name = "mips/1004K"; |
1638 | mipspmu.general_event_map = &mipsxxcore_event_map; | 1664 | mipspmu.general_event_map = &mipsxxcore_event_map; |
diff --git a/arch/mips/kernel/pm-cps.c b/arch/mips/kernel/pm-cps.c index c4c2069d3a20..06147179a175 100644 --- a/arch/mips/kernel/pm-cps.c +++ b/arch/mips/kernel/pm-cps.c | |||
@@ -149,8 +149,12 @@ int cps_pm_enter_state(enum cps_pm_state state) | |||
149 | 149 | ||
150 | /* Setup the VPE to run mips_cps_pm_restore when started again */ | 150 | /* Setup the VPE to run mips_cps_pm_restore when started again */ |
151 | if (config_enabled(CONFIG_CPU_PM) && state == CPS_PM_POWER_GATED) { | 151 | if (config_enabled(CONFIG_CPU_PM) && state == CPS_PM_POWER_GATED) { |
152 | /* Power gating relies upon CPS SMP */ | ||
153 | if (!mips_cps_smp_in_use()) | ||
154 | return -EINVAL; | ||
155 | |||
152 | core_cfg = &mips_cps_core_bootcfg[core]; | 156 | core_cfg = &mips_cps_core_bootcfg[core]; |
153 | vpe_cfg = &core_cfg->vpe_config[current_cpu_data.vpe_id]; | 157 | vpe_cfg = &core_cfg->vpe_config[cpu_vpe_id(¤t_cpu_data)]; |
154 | vpe_cfg->pc = (unsigned long)mips_cps_pm_restore; | 158 | vpe_cfg->pc = (unsigned long)mips_cps_pm_restore; |
155 | vpe_cfg->gp = (unsigned long)current_thread_info(); | 159 | vpe_cfg->gp = (unsigned long)current_thread_info(); |
156 | vpe_cfg->sp = 0; | 160 | vpe_cfg->sp = 0; |
@@ -376,6 +380,10 @@ static void * __init cps_gen_entry_code(unsigned cpu, enum cps_pm_state state) | |||
376 | memset(relocs, 0, sizeof(relocs)); | 380 | memset(relocs, 0, sizeof(relocs)); |
377 | 381 | ||
378 | if (config_enabled(CONFIG_CPU_PM) && state == CPS_PM_POWER_GATED) { | 382 | if (config_enabled(CONFIG_CPU_PM) && state == CPS_PM_POWER_GATED) { |
383 | /* Power gating relies upon CPS SMP */ | ||
384 | if (!mips_cps_smp_in_use()) | ||
385 | goto out_err; | ||
386 | |||
379 | /* | 387 | /* |
380 | * Save CPU state. Note the non-standard calling convention | 388 | * Save CPU state. Note the non-standard calling convention |
381 | * with the return address placed in v0 to avoid clobbering | 389 | * with the return address placed in v0 to avoid clobbering |
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index 037a44d962f3..097fc8d14e42 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c | |||
@@ -113,6 +113,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
113 | if (cpu_has_vz) seq_printf(m, "%s", " vz"); | 113 | if (cpu_has_vz) seq_printf(m, "%s", " vz"); |
114 | if (cpu_has_msa) seq_printf(m, "%s", " msa"); | 114 | if (cpu_has_msa) seq_printf(m, "%s", " msa"); |
115 | if (cpu_has_eva) seq_printf(m, "%s", " eva"); | 115 | if (cpu_has_eva) seq_printf(m, "%s", " eva"); |
116 | if (cpu_has_htw) seq_printf(m, "%s", " htw"); | ||
116 | seq_printf(m, "\n"); | 117 | seq_printf(m, "\n"); |
117 | 118 | ||
118 | if (cpu_has_mmips) { | 119 | if (cpu_has_mmips) { |
@@ -123,6 +124,7 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
123 | cpu_data[n].srsets); | 124 | cpu_data[n].srsets); |
124 | seq_printf(m, "kscratch registers\t: %d\n", | 125 | seq_printf(m, "kscratch registers\t: %d\n", |
125 | hweight8(cpu_data[n].kscratch_mask)); | 126 | hweight8(cpu_data[n].kscratch_mask)); |
127 | seq_printf(m, "package\t\t\t: %d\n", cpu_data[n].package); | ||
126 | seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); | 128 | seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); |
127 | 129 | ||
128 | sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", | 130 | sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", |
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index 0a1ec0f3beff..636b0745d7c7 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -21,7 +21,6 @@ | |||
21 | #include <linux/mman.h> | 21 | #include <linux/mman.h> |
22 | #include <linux/personality.h> | 22 | #include <linux/personality.h> |
23 | #include <linux/sys.h> | 23 | #include <linux/sys.h> |
24 | #include <linux/user.h> | ||
25 | #include <linux/init.h> | 24 | #include <linux/init.h> |
26 | #include <linux/completion.h> | 25 | #include <linux/completion.h> |
27 | #include <linux/kallsyms.h> | 26 | #include <linux/kallsyms.h> |
@@ -36,6 +35,7 @@ | |||
36 | #include <asm/pgtable.h> | 35 | #include <asm/pgtable.h> |
37 | #include <asm/mipsregs.h> | 36 | #include <asm/mipsregs.h> |
38 | #include <asm/processor.h> | 37 | #include <asm/processor.h> |
38 | #include <asm/reg.h> | ||
39 | #include <asm/uaccess.h> | 39 | #include <asm/uaccess.h> |
40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
41 | #include <asm/elf.h> | 41 | #include <asm/elf.h> |
@@ -66,6 +66,7 @@ void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp) | |||
66 | clear_used_math(); | 66 | clear_used_math(); |
67 | clear_fpu_owner(); | 67 | clear_fpu_owner(); |
68 | init_dsp(); | 68 | init_dsp(); |
69 | clear_thread_flag(TIF_USEDMSA); | ||
69 | clear_thread_flag(TIF_MSA_CTX_LIVE); | 70 | clear_thread_flag(TIF_MSA_CTX_LIVE); |
70 | disable_msa(); | 71 | disable_msa(); |
71 | regs->cp0_epc = pc; | 72 | regs->cp0_epc = pc; |
@@ -141,6 +142,8 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
141 | childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); | 142 | childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); |
142 | 143 | ||
143 | clear_tsk_thread_flag(p, TIF_USEDFPU); | 144 | clear_tsk_thread_flag(p, TIF_USEDFPU); |
145 | clear_tsk_thread_flag(p, TIF_USEDMSA); | ||
146 | clear_tsk_thread_flag(p, TIF_MSA_CTX_LIVE); | ||
144 | 147 | ||
145 | #ifdef CONFIG_MIPS_MT_FPAFF | 148 | #ifdef CONFIG_MIPS_MT_FPAFF |
146 | clear_tsk_thread_flag(p, TIF_FPUBOUND); | 149 | clear_tsk_thread_flag(p, TIF_FPUBOUND); |
@@ -152,61 +155,6 @@ int copy_thread(unsigned long clone_flags, unsigned long usp, | |||
152 | return 0; | 155 | return 0; |
153 | } | 156 | } |
154 | 157 | ||
155 | /* Fill in the fpu structure for a core dump.. */ | ||
156 | int dump_fpu(struct pt_regs *regs, elf_fpregset_t *r) | ||
157 | { | ||
158 | int i; | ||
159 | |||
160 | for (i = 0; i < NUM_FPU_REGS; i++) | ||
161 | memcpy(&r[i], ¤t->thread.fpu.fpr[i], sizeof(*r)); | ||
162 | |||
163 | memcpy(&r[NUM_FPU_REGS], ¤t->thread.fpu.fcr31, | ||
164 | sizeof(current->thread.fpu.fcr31)); | ||
165 | |||
166 | return 1; | ||
167 | } | ||
168 | |||
169 | void elf_dump_regs(elf_greg_t *gp, struct pt_regs *regs) | ||
170 | { | ||
171 | int i; | ||
172 | |||
173 | for (i = 0; i < EF_R0; i++) | ||
174 | gp[i] = 0; | ||
175 | gp[EF_R0] = 0; | ||
176 | for (i = 1; i <= 31; i++) | ||
177 | gp[EF_R0 + i] = regs->regs[i]; | ||
178 | gp[EF_R26] = 0; | ||
179 | gp[EF_R27] = 0; | ||
180 | gp[EF_LO] = regs->lo; | ||
181 | gp[EF_HI] = regs->hi; | ||
182 | gp[EF_CP0_EPC] = regs->cp0_epc; | ||
183 | gp[EF_CP0_BADVADDR] = regs->cp0_badvaddr; | ||
184 | gp[EF_CP0_STATUS] = regs->cp0_status; | ||
185 | gp[EF_CP0_CAUSE] = regs->cp0_cause; | ||
186 | #ifdef EF_UNUSED0 | ||
187 | gp[EF_UNUSED0] = 0; | ||
188 | #endif | ||
189 | } | ||
190 | |||
191 | int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) | ||
192 | { | ||
193 | elf_dump_regs(*regs, task_pt_regs(tsk)); | ||
194 | return 1; | ||
195 | } | ||
196 | |||
197 | int dump_task_fpu(struct task_struct *t, elf_fpregset_t *fpr) | ||
198 | { | ||
199 | int i; | ||
200 | |||
201 | for (i = 0; i < NUM_FPU_REGS; i++) | ||
202 | memcpy(&fpr[i], &t->thread.fpu.fpr[i], sizeof(*fpr)); | ||
203 | |||
204 | memcpy(&fpr[NUM_FPU_REGS], &t->thread.fpu.fcr31, | ||
205 | sizeof(t->thread.fpu.fcr31)); | ||
206 | |||
207 | return 1; | ||
208 | } | ||
209 | |||
210 | #ifdef CONFIG_CC_STACKPROTECTOR | 158 | #ifdef CONFIG_CC_STACKPROTECTOR |
211 | #include <linux/stackprotector.h> | 159 | #include <linux/stackprotector.h> |
212 | unsigned long __stack_chk_guard __read_mostly; | 160 | unsigned long __stack_chk_guard __read_mostly; |
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index f639ccd5060c..645b3c4fcfba 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -24,7 +24,6 @@ | |||
24 | #include <linux/ptrace.h> | 24 | #include <linux/ptrace.h> |
25 | #include <linux/regset.h> | 25 | #include <linux/regset.h> |
26 | #include <linux/smp.h> | 26 | #include <linux/smp.h> |
27 | #include <linux/user.h> | ||
28 | #include <linux/security.h> | 27 | #include <linux/security.h> |
29 | #include <linux/tracehook.h> | 28 | #include <linux/tracehook.h> |
30 | #include <linux/audit.h> | 29 | #include <linux/audit.h> |
@@ -63,7 +62,7 @@ void ptrace_disable(struct task_struct *child) | |||
63 | * for 32-bit kernels and for 32-bit processes on a 64-bit kernel. | 62 | * for 32-bit kernels and for 32-bit processes on a 64-bit kernel. |
64 | * Registers are sign extended to fill the available space. | 63 | * Registers are sign extended to fill the available space. |
65 | */ | 64 | */ |
66 | int ptrace_getregs(struct task_struct *child, __s64 __user *data) | 65 | int ptrace_getregs(struct task_struct *child, struct user_pt_regs __user *data) |
67 | { | 66 | { |
68 | struct pt_regs *regs; | 67 | struct pt_regs *regs; |
69 | int i; | 68 | int i; |
@@ -74,13 +73,13 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data) | |||
74 | regs = task_pt_regs(child); | 73 | regs = task_pt_regs(child); |
75 | 74 | ||
76 | for (i = 0; i < 32; i++) | 75 | for (i = 0; i < 32; i++) |
77 | __put_user((long)regs->regs[i], data + i); | 76 | __put_user((long)regs->regs[i], (__s64 __user *)&data->regs[i]); |
78 | __put_user((long)regs->lo, data + EF_LO - EF_R0); | 77 | __put_user((long)regs->lo, (__s64 __user *)&data->lo); |
79 | __put_user((long)regs->hi, data + EF_HI - EF_R0); | 78 | __put_user((long)regs->hi, (__s64 __user *)&data->hi); |
80 | __put_user((long)regs->cp0_epc, data + EF_CP0_EPC - EF_R0); | 79 | __put_user((long)regs->cp0_epc, (__s64 __user *)&data->cp0_epc); |
81 | __put_user((long)regs->cp0_badvaddr, data + EF_CP0_BADVADDR - EF_R0); | 80 | __put_user((long)regs->cp0_badvaddr, (__s64 __user *)&data->cp0_badvaddr); |
82 | __put_user((long)regs->cp0_status, data + EF_CP0_STATUS - EF_R0); | 81 | __put_user((long)regs->cp0_status, (__s64 __user *)&data->cp0_status); |
83 | __put_user((long)regs->cp0_cause, data + EF_CP0_CAUSE - EF_R0); | 82 | __put_user((long)regs->cp0_cause, (__s64 __user *)&data->cp0_cause); |
84 | 83 | ||
85 | return 0; | 84 | return 0; |
86 | } | 85 | } |
@@ -90,7 +89,7 @@ int ptrace_getregs(struct task_struct *child, __s64 __user *data) | |||
90 | * the 64-bit format. On a 32-bit kernel only the lower order half | 89 | * the 64-bit format. On a 32-bit kernel only the lower order half |
91 | * (according to endianness) will be used. | 90 | * (according to endianness) will be used. |
92 | */ | 91 | */ |
93 | int ptrace_setregs(struct task_struct *child, __s64 __user *data) | 92 | int ptrace_setregs(struct task_struct *child, struct user_pt_regs __user *data) |
94 | { | 93 | { |
95 | struct pt_regs *regs; | 94 | struct pt_regs *regs; |
96 | int i; | 95 | int i; |
@@ -101,10 +100,10 @@ int ptrace_setregs(struct task_struct *child, __s64 __user *data) | |||
101 | regs = task_pt_regs(child); | 100 | regs = task_pt_regs(child); |
102 | 101 | ||
103 | for (i = 0; i < 32; i++) | 102 | for (i = 0; i < 32; i++) |
104 | __get_user(regs->regs[i], data + i); | 103 | __get_user(regs->regs[i], (__s64 __user *)&data->regs[i]); |
105 | __get_user(regs->lo, data + EF_LO - EF_R0); | 104 | __get_user(regs->lo, (__s64 __user *)&data->lo); |
106 | __get_user(regs->hi, data + EF_HI - EF_R0); | 105 | __get_user(regs->hi, (__s64 __user *)&data->hi); |
107 | __get_user(regs->cp0_epc, data + EF_CP0_EPC - EF_R0); | 106 | __get_user(regs->cp0_epc, (__s64 __user *)&data->cp0_epc); |
108 | 107 | ||
109 | /* badvaddr, status, and cause may not be written. */ | 108 | /* badvaddr, status, and cause may not be written. */ |
110 | 109 | ||
@@ -129,7 +128,7 @@ int ptrace_getfpregs(struct task_struct *child, __u32 __user *data) | |||
129 | } | 128 | } |
130 | 129 | ||
131 | __put_user(child->thread.fpu.fcr31, data + 64); | 130 | __put_user(child->thread.fpu.fcr31, data + 64); |
132 | __put_user(current_cpu_data.fpu_id, data + 65); | 131 | __put_user(boot_cpu_data.fpu_id, data + 65); |
133 | 132 | ||
134 | return 0; | 133 | return 0; |
135 | } | 134 | } |
@@ -151,6 +150,7 @@ int ptrace_setfpregs(struct task_struct *child, __u32 __user *data) | |||
151 | } | 150 | } |
152 | 151 | ||
153 | __get_user(child->thread.fpu.fcr31, data + 64); | 152 | __get_user(child->thread.fpu.fcr31, data + 64); |
153 | child->thread.fpu.fcr31 &= ~FPU_CSR_ALL_X; | ||
154 | 154 | ||
155 | /* FIR may not be written. */ | 155 | /* FIR may not be written. */ |
156 | 156 | ||
@@ -246,36 +246,160 @@ int ptrace_set_watch_regs(struct task_struct *child, | |||
246 | 246 | ||
247 | /* regset get/set implementations */ | 247 | /* regset get/set implementations */ |
248 | 248 | ||
249 | static int gpr_get(struct task_struct *target, | 249 | #if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32) |
250 | const struct user_regset *regset, | 250 | |
251 | unsigned int pos, unsigned int count, | 251 | static int gpr32_get(struct task_struct *target, |
252 | void *kbuf, void __user *ubuf) | 252 | const struct user_regset *regset, |
253 | unsigned int pos, unsigned int count, | ||
254 | void *kbuf, void __user *ubuf) | ||
253 | { | 255 | { |
254 | struct pt_regs *regs = task_pt_regs(target); | 256 | struct pt_regs *regs = task_pt_regs(target); |
257 | u32 uregs[ELF_NGREG] = {}; | ||
258 | unsigned i; | ||
259 | |||
260 | for (i = MIPS32_EF_R1; i <= MIPS32_EF_R31; i++) { | ||
261 | /* k0/k1 are copied as zero. */ | ||
262 | if (i == MIPS32_EF_R26 || i == MIPS32_EF_R27) | ||
263 | continue; | ||
264 | |||
265 | uregs[i] = regs->regs[i - MIPS32_EF_R0]; | ||
266 | } | ||
255 | 267 | ||
256 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, | 268 | uregs[MIPS32_EF_LO] = regs->lo; |
257 | regs, 0, sizeof(*regs)); | 269 | uregs[MIPS32_EF_HI] = regs->hi; |
270 | uregs[MIPS32_EF_CP0_EPC] = regs->cp0_epc; | ||
271 | uregs[MIPS32_EF_CP0_BADVADDR] = regs->cp0_badvaddr; | ||
272 | uregs[MIPS32_EF_CP0_STATUS] = regs->cp0_status; | ||
273 | uregs[MIPS32_EF_CP0_CAUSE] = regs->cp0_cause; | ||
274 | |||
275 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, | ||
276 | sizeof(uregs)); | ||
258 | } | 277 | } |
259 | 278 | ||
260 | static int gpr_set(struct task_struct *target, | 279 | static int gpr32_set(struct task_struct *target, |
261 | const struct user_regset *regset, | 280 | const struct user_regset *regset, |
262 | unsigned int pos, unsigned int count, | 281 | unsigned int pos, unsigned int count, |
263 | const void *kbuf, const void __user *ubuf) | 282 | const void *kbuf, const void __user *ubuf) |
264 | { | 283 | { |
265 | struct pt_regs newregs; | 284 | struct pt_regs *regs = task_pt_regs(target); |
266 | int ret; | 285 | u32 uregs[ELF_NGREG]; |
286 | unsigned start, num_regs, i; | ||
287 | int err; | ||
288 | |||
289 | start = pos / sizeof(u32); | ||
290 | num_regs = count / sizeof(u32); | ||
291 | |||
292 | if (start + num_regs > ELF_NGREG) | ||
293 | return -EIO; | ||
294 | |||
295 | err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0, | ||
296 | sizeof(uregs)); | ||
297 | if (err) | ||
298 | return err; | ||
299 | |||
300 | for (i = start; i < num_regs; i++) { | ||
301 | /* | ||
302 | * Cast all values to signed here so that if this is a 64-bit | ||
303 | * kernel, the supplied 32-bit values will be sign extended. | ||
304 | */ | ||
305 | switch (i) { | ||
306 | case MIPS32_EF_R1 ... MIPS32_EF_R25: | ||
307 | /* k0/k1 are ignored. */ | ||
308 | case MIPS32_EF_R28 ... MIPS32_EF_R31: | ||
309 | regs->regs[i - MIPS32_EF_R0] = (s32)uregs[i]; | ||
310 | break; | ||
311 | case MIPS32_EF_LO: | ||
312 | regs->lo = (s32)uregs[i]; | ||
313 | break; | ||
314 | case MIPS32_EF_HI: | ||
315 | regs->hi = (s32)uregs[i]; | ||
316 | break; | ||
317 | case MIPS32_EF_CP0_EPC: | ||
318 | regs->cp0_epc = (s32)uregs[i]; | ||
319 | break; | ||
320 | } | ||
321 | } | ||
322 | |||
323 | return 0; | ||
324 | } | ||
325 | |||
326 | #endif /* CONFIG_32BIT || CONFIG_MIPS32_O32 */ | ||
327 | |||
328 | #ifdef CONFIG_64BIT | ||
329 | |||
330 | static int gpr64_get(struct task_struct *target, | ||
331 | const struct user_regset *regset, | ||
332 | unsigned int pos, unsigned int count, | ||
333 | void *kbuf, void __user *ubuf) | ||
334 | { | ||
335 | struct pt_regs *regs = task_pt_regs(target); | ||
336 | u64 uregs[ELF_NGREG] = {}; | ||
337 | unsigned i; | ||
338 | |||
339 | for (i = MIPS64_EF_R1; i <= MIPS64_EF_R31; i++) { | ||
340 | /* k0/k1 are copied as zero. */ | ||
341 | if (i == MIPS64_EF_R26 || i == MIPS64_EF_R27) | ||
342 | continue; | ||
343 | |||
344 | uregs[i] = regs->regs[i - MIPS64_EF_R0]; | ||
345 | } | ||
346 | |||
347 | uregs[MIPS64_EF_LO] = regs->lo; | ||
348 | uregs[MIPS64_EF_HI] = regs->hi; | ||
349 | uregs[MIPS64_EF_CP0_EPC] = regs->cp0_epc; | ||
350 | uregs[MIPS64_EF_CP0_BADVADDR] = regs->cp0_badvaddr; | ||
351 | uregs[MIPS64_EF_CP0_STATUS] = regs->cp0_status; | ||
352 | uregs[MIPS64_EF_CP0_CAUSE] = regs->cp0_cause; | ||
353 | |||
354 | return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, 0, | ||
355 | sizeof(uregs)); | ||
356 | } | ||
267 | 357 | ||
268 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, | 358 | static int gpr64_set(struct task_struct *target, |
269 | &newregs, | 359 | const struct user_regset *regset, |
270 | 0, sizeof(newregs)); | 360 | unsigned int pos, unsigned int count, |
271 | if (ret) | 361 | const void *kbuf, const void __user *ubuf) |
272 | return ret; | 362 | { |
363 | struct pt_regs *regs = task_pt_regs(target); | ||
364 | u64 uregs[ELF_NGREG]; | ||
365 | unsigned start, num_regs, i; | ||
366 | int err; | ||
367 | |||
368 | start = pos / sizeof(u64); | ||
369 | num_regs = count / sizeof(u64); | ||
273 | 370 | ||
274 | *task_pt_regs(target) = newregs; | 371 | if (start + num_regs > ELF_NGREG) |
372 | return -EIO; | ||
373 | |||
374 | err = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0, | ||
375 | sizeof(uregs)); | ||
376 | if (err) | ||
377 | return err; | ||
378 | |||
379 | for (i = start; i < num_regs; i++) { | ||
380 | switch (i) { | ||
381 | case MIPS64_EF_R1 ... MIPS64_EF_R25: | ||
382 | /* k0/k1 are ignored. */ | ||
383 | case MIPS64_EF_R28 ... MIPS64_EF_R31: | ||
384 | regs->regs[i - MIPS64_EF_R0] = uregs[i]; | ||
385 | break; | ||
386 | case MIPS64_EF_LO: | ||
387 | regs->lo = uregs[i]; | ||
388 | break; | ||
389 | case MIPS64_EF_HI: | ||
390 | regs->hi = uregs[i]; | ||
391 | break; | ||
392 | case MIPS64_EF_CP0_EPC: | ||
393 | regs->cp0_epc = uregs[i]; | ||
394 | break; | ||
395 | } | ||
396 | } | ||
275 | 397 | ||
276 | return 0; | 398 | return 0; |
277 | } | 399 | } |
278 | 400 | ||
401 | #endif /* CONFIG_64BIT */ | ||
402 | |||
279 | static int fpr_get(struct task_struct *target, | 403 | static int fpr_get(struct task_struct *target, |
280 | const struct user_regset *regset, | 404 | const struct user_regset *regset, |
281 | unsigned int pos, unsigned int count, | 405 | unsigned int pos, unsigned int count, |
@@ -337,14 +461,16 @@ enum mips_regset { | |||
337 | REGSET_FPR, | 461 | REGSET_FPR, |
338 | }; | 462 | }; |
339 | 463 | ||
464 | #if defined(CONFIG_32BIT) || defined(CONFIG_MIPS32_O32) | ||
465 | |||
340 | static const struct user_regset mips_regsets[] = { | 466 | static const struct user_regset mips_regsets[] = { |
341 | [REGSET_GPR] = { | 467 | [REGSET_GPR] = { |
342 | .core_note_type = NT_PRSTATUS, | 468 | .core_note_type = NT_PRSTATUS, |
343 | .n = ELF_NGREG, | 469 | .n = ELF_NGREG, |
344 | .size = sizeof(unsigned int), | 470 | .size = sizeof(unsigned int), |
345 | .align = sizeof(unsigned int), | 471 | .align = sizeof(unsigned int), |
346 | .get = gpr_get, | 472 | .get = gpr32_get, |
347 | .set = gpr_set, | 473 | .set = gpr32_set, |
348 | }, | 474 | }, |
349 | [REGSET_FPR] = { | 475 | [REGSET_FPR] = { |
350 | .core_note_type = NT_PRFPREG, | 476 | .core_note_type = NT_PRFPREG, |
@@ -364,14 +490,18 @@ static const struct user_regset_view user_mips_view = { | |||
364 | .n = ARRAY_SIZE(mips_regsets), | 490 | .n = ARRAY_SIZE(mips_regsets), |
365 | }; | 491 | }; |
366 | 492 | ||
493 | #endif /* CONFIG_32BIT || CONFIG_MIPS32_O32 */ | ||
494 | |||
495 | #ifdef CONFIG_64BIT | ||
496 | |||
367 | static const struct user_regset mips64_regsets[] = { | 497 | static const struct user_regset mips64_regsets[] = { |
368 | [REGSET_GPR] = { | 498 | [REGSET_GPR] = { |
369 | .core_note_type = NT_PRSTATUS, | 499 | .core_note_type = NT_PRSTATUS, |
370 | .n = ELF_NGREG, | 500 | .n = ELF_NGREG, |
371 | .size = sizeof(unsigned long), | 501 | .size = sizeof(unsigned long), |
372 | .align = sizeof(unsigned long), | 502 | .align = sizeof(unsigned long), |
373 | .get = gpr_get, | 503 | .get = gpr64_get, |
374 | .set = gpr_set, | 504 | .set = gpr64_set, |
375 | }, | 505 | }, |
376 | [REGSET_FPR] = { | 506 | [REGSET_FPR] = { |
377 | .core_note_type = NT_PRFPREG, | 507 | .core_note_type = NT_PRFPREG, |
@@ -384,25 +514,26 @@ static const struct user_regset mips64_regsets[] = { | |||
384 | }; | 514 | }; |
385 | 515 | ||
386 | static const struct user_regset_view user_mips64_view = { | 516 | static const struct user_regset_view user_mips64_view = { |
387 | .name = "mips", | 517 | .name = "mips64", |
388 | .e_machine = ELF_ARCH, | 518 | .e_machine = ELF_ARCH, |
389 | .ei_osabi = ELF_OSABI, | 519 | .ei_osabi = ELF_OSABI, |
390 | .regsets = mips64_regsets, | 520 | .regsets = mips64_regsets, |
391 | .n = ARRAY_SIZE(mips_regsets), | 521 | .n = ARRAY_SIZE(mips64_regsets), |
392 | }; | 522 | }; |
393 | 523 | ||
524 | #endif /* CONFIG_64BIT */ | ||
525 | |||
394 | const struct user_regset_view *task_user_regset_view(struct task_struct *task) | 526 | const struct user_regset_view *task_user_regset_view(struct task_struct *task) |
395 | { | 527 | { |
396 | #ifdef CONFIG_32BIT | 528 | #ifdef CONFIG_32BIT |
397 | return &user_mips_view; | 529 | return &user_mips_view; |
398 | #endif | 530 | #else |
399 | |||
400 | #ifdef CONFIG_MIPS32_O32 | 531 | #ifdef CONFIG_MIPS32_O32 |
401 | if (test_thread_flag(TIF_32BIT_REGS)) | 532 | if (test_tsk_thread_flag(task, TIF_32BIT_REGS)) |
402 | return &user_mips_view; | 533 | return &user_mips_view; |
403 | #endif | 534 | #endif |
404 | |||
405 | return &user_mips64_view; | 535 | return &user_mips64_view; |
536 | #endif | ||
406 | } | 537 | } |
407 | 538 | ||
408 | long arch_ptrace(struct task_struct *child, long request, | 539 | long arch_ptrace(struct task_struct *child, long request, |
@@ -480,7 +611,7 @@ long arch_ptrace(struct task_struct *child, long request, | |||
480 | break; | 611 | break; |
481 | case FPC_EIR: | 612 | case FPC_EIR: |
482 | /* implementation / version register */ | 613 | /* implementation / version register */ |
483 | tmp = current_cpu_data.fpu_id; | 614 | tmp = boot_cpu_data.fpu_id; |
484 | break; | 615 | break; |
485 | case DSP_BASE ... DSP_BASE + 5: { | 616 | case DSP_BASE ... DSP_BASE + 5: { |
486 | dspreg_t *dregs; | 617 | dspreg_t *dregs; |
@@ -565,7 +696,7 @@ long arch_ptrace(struct task_struct *child, long request, | |||
565 | break; | 696 | break; |
566 | #endif | 697 | #endif |
567 | case FPC_CSR: | 698 | case FPC_CSR: |
568 | child->thread.fpu.fcr31 = data; | 699 | child->thread.fpu.fcr31 = data & ~FPU_CSR_ALL_X; |
569 | break; | 700 | break; |
570 | case DSP_BASE ... DSP_BASE + 5: { | 701 | case DSP_BASE ... DSP_BASE + 5: { |
571 | dspreg_t *dregs; | 702 | dspreg_t *dregs; |
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index b40c3ca60ee5..283b5a1967d1 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
23 | #include <linux/ptrace.h> | 23 | #include <linux/ptrace.h> |
24 | #include <linux/smp.h> | 24 | #include <linux/smp.h> |
25 | #include <linux/user.h> | ||
26 | #include <linux/security.h> | 25 | #include <linux/security.h> |
27 | 26 | ||
28 | #include <asm/cpu.h> | 27 | #include <asm/cpu.h> |
@@ -32,6 +31,7 @@ | |||
32 | #include <asm/mipsmtregs.h> | 31 | #include <asm/mipsmtregs.h> |
33 | #include <asm/pgtable.h> | 32 | #include <asm/pgtable.h> |
34 | #include <asm/page.h> | 33 | #include <asm/page.h> |
34 | #include <asm/reg.h> | ||
35 | #include <asm/uaccess.h> | 35 | #include <asm/uaccess.h> |
36 | #include <asm/bootinfo.h> | 36 | #include <asm/bootinfo.h> |
37 | 37 | ||
@@ -129,7 +129,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, | |||
129 | break; | 129 | break; |
130 | case FPC_EIR: | 130 | case FPC_EIR: |
131 | /* implementation / version register */ | 131 | /* implementation / version register */ |
132 | tmp = current_cpu_data.fpu_id; | 132 | tmp = boot_cpu_data.fpu_id; |
133 | break; | 133 | break; |
134 | case DSP_BASE ... DSP_BASE + 5: { | 134 | case DSP_BASE ... DSP_BASE + 5: { |
135 | dspreg_t *dregs; | 135 | dspreg_t *dregs; |
@@ -256,11 +256,13 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, | |||
256 | } | 256 | } |
257 | 257 | ||
258 | case PTRACE_GETREGS: | 258 | case PTRACE_GETREGS: |
259 | ret = ptrace_getregs(child, (__s64 __user *) (__u64) data); | 259 | ret = ptrace_getregs(child, |
260 | (struct user_pt_regs __user *) (__u64) data); | ||
260 | break; | 261 | break; |
261 | 262 | ||
262 | case PTRACE_SETREGS: | 263 | case PTRACE_SETREGS: |
263 | ret = ptrace_setregs(child, (__s64 __user *) (__u64) data); | 264 | ret = ptrace_setregs(child, |
265 | (struct user_pt_regs __user *) (__u64) data); | ||
264 | break; | 266 | break; |
265 | 267 | ||
266 | case PTRACE_GETFPREGS: | 268 | case PTRACE_GETFPREGS: |
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index 81ca3f70fe29..4c4ec1812420 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S | |||
@@ -64,8 +64,10 @@ | |||
64 | /* Check whether we're saving scalar or vector context. */ | 64 | /* Check whether we're saving scalar or vector context. */ |
65 | bgtz a3, 1f | 65 | bgtz a3, 1f |
66 | 66 | ||
67 | /* Save 128b MSA vector context. */ | 67 | /* Save 128b MSA vector context + scalar FP control & status. */ |
68 | cfc1 t1, fcr31 | ||
68 | msa_save_all a0 | 69 | msa_save_all a0 |
70 | sw t1, THREAD_FCR31(a0) | ||
69 | b 2f | 71 | b 2f |
70 | 72 | ||
71 | 1: /* Save 32b/64b scalar FP context. */ | 73 | 1: /* Save 32b/64b scalar FP context. */ |
@@ -142,6 +144,11 @@ LEAF(_restore_msa) | |||
142 | jr ra | 144 | jr ra |
143 | END(_restore_msa) | 145 | END(_restore_msa) |
144 | 146 | ||
147 | LEAF(_init_msa_upper) | ||
148 | msa_init_all_upper | ||
149 | jr ra | ||
150 | END(_init_msa_upper) | ||
151 | |||
145 | #endif | 152 | #endif |
146 | 153 | ||
147 | /* | 154 | /* |
diff --git a/arch/mips/kernel/rtlx-cmp.c b/arch/mips/kernel/rtlx-cmp.c index 758fb3cd2326..d26dcc4b46e7 100644 --- a/arch/mips/kernel/rtlx-cmp.c +++ b/arch/mips/kernel/rtlx-cmp.c | |||
@@ -77,6 +77,9 @@ int __init rtlx_module_init(void) | |||
77 | dev = device_create(mt_class, NULL, MKDEV(major, i), NULL, | 77 | dev = device_create(mt_class, NULL, MKDEV(major, i), NULL, |
78 | "%s%d", RTLX_MODULE_NAME, i); | 78 | "%s%d", RTLX_MODULE_NAME, i); |
79 | if (IS_ERR(dev)) { | 79 | if (IS_ERR(dev)) { |
80 | while (i--) | ||
81 | device_destroy(mt_class, MKDEV(major, i)); | ||
82 | |||
80 | err = PTR_ERR(dev); | 83 | err = PTR_ERR(dev); |
81 | goto out_chrdev; | 84 | goto out_chrdev; |
82 | } | 85 | } |
diff --git a/arch/mips/kernel/rtlx-mt.c b/arch/mips/kernel/rtlx-mt.c index 5a66b975989e..cb95470e2e69 100644 --- a/arch/mips/kernel/rtlx-mt.c +++ b/arch/mips/kernel/rtlx-mt.c | |||
@@ -103,6 +103,9 @@ int __init rtlx_module_init(void) | |||
103 | dev = device_create(mt_class, NULL, MKDEV(major, i), NULL, | 103 | dev = device_create(mt_class, NULL, MKDEV(major, i), NULL, |
104 | "%s%d", RTLX_MODULE_NAME, i); | 104 | "%s%d", RTLX_MODULE_NAME, i); |
105 | if (IS_ERR(dev)) { | 105 | if (IS_ERR(dev)) { |
106 | while (i--) | ||
107 | device_destroy(mt_class, MKDEV(major, i)); | ||
108 | |||
106 | err = PTR_ERR(dev); | 109 | err = PTR_ERR(dev); |
107 | goto out_chrdev; | 110 | goto out_chrdev; |
108 | } | 111 | } |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index ab02d14f1b5c..f93b4cbec739 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -67,8 +67,6 @@ NESTED(handle_sys, PT_SIZE, sp) | |||
67 | 67 | ||
68 | /* | 68 | /* |
69 | * Ok, copy the args from the luser stack to the kernel stack. | 69 | * Ok, copy the args from the luser stack to the kernel stack. |
70 | * t3 is the precomputed number of instruction bytes needed to | ||
71 | * load or store arguments 6-8. | ||
72 | */ | 70 | */ |
73 | 71 | ||
74 | .set push | 72 | .set push |
@@ -495,8 +493,8 @@ EXPORT(sys_call_table) | |||
495 | PTR sys_tgkill | 493 | PTR sys_tgkill |
496 | PTR sys_utimes | 494 | PTR sys_utimes |
497 | PTR sys_mbind | 495 | PTR sys_mbind |
498 | PTR sys_ni_syscall /* sys_get_mempolicy */ | 496 | PTR sys_get_mempolicy |
499 | PTR sys_ni_syscall /* 4270 sys_set_mempolicy */ | 497 | PTR sys_set_mempolicy /* 4270 */ |
500 | PTR sys_mq_open | 498 | PTR sys_mq_open |
501 | PTR sys_mq_unlink | 499 | PTR sys_mq_unlink |
502 | PTR sys_mq_timedsend | 500 | PTR sys_mq_timedsend |
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 010dccf128ec..03ebd9979ad2 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -347,8 +347,8 @@ EXPORT(sys_call_table) | |||
347 | PTR sys_tgkill /* 5225 */ | 347 | PTR sys_tgkill /* 5225 */ |
348 | PTR sys_utimes | 348 | PTR sys_utimes |
349 | PTR sys_mbind | 349 | PTR sys_mbind |
350 | PTR sys_ni_syscall /* sys_get_mempolicy */ | 350 | PTR sys_get_mempolicy |
351 | PTR sys_ni_syscall /* sys_set_mempolicy */ | 351 | PTR sys_set_mempolicy |
352 | PTR sys_mq_open /* 5230 */ | 352 | PTR sys_mq_open /* 5230 */ |
353 | PTR sys_mq_unlink | 353 | PTR sys_mq_unlink |
354 | PTR sys_mq_timedsend | 354 | PTR sys_mq_timedsend |
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index c3b3b6525df5..ebc9228e2e15 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -162,7 +162,7 @@ EXPORT(sysn32_call_table) | |||
162 | PTR sys_getpeername | 162 | PTR sys_getpeername |
163 | PTR sys_socketpair | 163 | PTR sys_socketpair |
164 | PTR compat_sys_setsockopt | 164 | PTR compat_sys_setsockopt |
165 | PTR sys_getsockopt | 165 | PTR compat_sys_getsockopt |
166 | PTR __sys_clone /* 6055 */ | 166 | PTR __sys_clone /* 6055 */ |
167 | PTR __sys_fork | 167 | PTR __sys_fork |
168 | PTR compat_sys_execve | 168 | PTR compat_sys_execve |
@@ -339,9 +339,9 @@ EXPORT(sysn32_call_table) | |||
339 | PTR compat_sys_clock_nanosleep | 339 | PTR compat_sys_clock_nanosleep |
340 | PTR sys_tgkill | 340 | PTR sys_tgkill |
341 | PTR compat_sys_utimes /* 6230 */ | 341 | PTR compat_sys_utimes /* 6230 */ |
342 | PTR sys_ni_syscall /* sys_mbind */ | 342 | PTR compat_sys_mbind |
343 | PTR sys_ni_syscall /* sys_get_mempolicy */ | 343 | PTR compat_sys_get_mempolicy |
344 | PTR sys_ni_syscall /* sys_set_mempolicy */ | 344 | PTR compat_sys_set_mempolicy |
345 | PTR compat_sys_mq_open | 345 | PTR compat_sys_mq_open |
346 | PTR sys_mq_unlink /* 6235 */ | 346 | PTR sys_mq_unlink /* 6235 */ |
347 | PTR compat_sys_mq_timedsend | 347 | PTR compat_sys_mq_timedsend |
@@ -358,7 +358,7 @@ EXPORT(sysn32_call_table) | |||
358 | PTR sys_inotify_init | 358 | PTR sys_inotify_init |
359 | PTR sys_inotify_add_watch | 359 | PTR sys_inotify_add_watch |
360 | PTR sys_inotify_rm_watch | 360 | PTR sys_inotify_rm_watch |
361 | PTR sys_migrate_pages /* 6250 */ | 361 | PTR compat_sys_migrate_pages /* 6250 */ |
362 | PTR sys_openat | 362 | PTR sys_openat |
363 | PTR sys_mkdirat | 363 | PTR sys_mkdirat |
364 | PTR sys_mknodat | 364 | PTR sys_mknodat |
@@ -379,7 +379,7 @@ EXPORT(sysn32_call_table) | |||
379 | PTR sys_sync_file_range | 379 | PTR sys_sync_file_range |
380 | PTR sys_tee | 380 | PTR sys_tee |
381 | PTR compat_sys_vmsplice /* 6270 */ | 381 | PTR compat_sys_vmsplice /* 6270 */ |
382 | PTR sys_move_pages | 382 | PTR compat_sys_move_pages |
383 | PTR compat_sys_set_robust_list | 383 | PTR compat_sys_set_robust_list |
384 | PTR compat_sys_get_robust_list | 384 | PTR compat_sys_get_robust_list |
385 | PTR compat_sys_kexec_load | 385 | PTR compat_sys_kexec_load |
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index bb1550b1f501..13b964fddc4a 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -473,9 +473,9 @@ EXPORT(sys32_call_table) | |||
473 | PTR compat_sys_clock_nanosleep /* 4265 */ | 473 | PTR compat_sys_clock_nanosleep /* 4265 */ |
474 | PTR sys_tgkill | 474 | PTR sys_tgkill |
475 | PTR compat_sys_utimes | 475 | PTR compat_sys_utimes |
476 | PTR sys_ni_syscall /* sys_mbind */ | 476 | PTR compat_sys_mbind |
477 | PTR sys_ni_syscall /* sys_get_mempolicy */ | 477 | PTR compat_sys_get_mempolicy |
478 | PTR sys_ni_syscall /* 4270 sys_set_mempolicy */ | 478 | PTR compat_sys_set_mempolicy /* 4270 */ |
479 | PTR compat_sys_mq_open | 479 | PTR compat_sys_mq_open |
480 | PTR sys_mq_unlink | 480 | PTR sys_mq_unlink |
481 | PTR compat_sys_mq_timedsend | 481 | PTR compat_sys_mq_timedsend |
@@ -492,7 +492,7 @@ EXPORT(sys32_call_table) | |||
492 | PTR sys_inotify_init | 492 | PTR sys_inotify_init |
493 | PTR sys_inotify_add_watch /* 4285 */ | 493 | PTR sys_inotify_add_watch /* 4285 */ |
494 | PTR sys_inotify_rm_watch | 494 | PTR sys_inotify_rm_watch |
495 | PTR sys_migrate_pages | 495 | PTR compat_sys_migrate_pages |
496 | PTR compat_sys_openat | 496 | PTR compat_sys_openat |
497 | PTR sys_mkdirat | 497 | PTR sys_mkdirat |
498 | PTR sys_mknodat /* 4290 */ | 498 | PTR sys_mknodat /* 4290 */ |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index a842154d57dc..7c1fe2b42d40 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -282,7 +282,7 @@ static unsigned long __init init_initrd(void) | |||
282 | * Initialize the bootmem allocator. It also setup initrd related data | 282 | * Initialize the bootmem allocator. It also setup initrd related data |
283 | * if needed. | 283 | * if needed. |
284 | */ | 284 | */ |
285 | #ifdef CONFIG_SGI_IP27 | 285 | #if defined(CONFIG_SGI_IP27) || (defined(CONFIG_CPU_LOONGSON3) && defined(CONFIG_NUMA)) |
286 | 286 | ||
287 | static void __init bootmem_init(void) | 287 | static void __init bootmem_init(void) |
288 | { | 288 | { |
@@ -729,6 +729,25 @@ static void __init resource_init(void) | |||
729 | } | 729 | } |
730 | } | 730 | } |
731 | 731 | ||
732 | #ifdef CONFIG_SMP | ||
733 | static void __init prefill_possible_map(void) | ||
734 | { | ||
735 | int i, possible = num_possible_cpus(); | ||
736 | |||
737 | if (possible > nr_cpu_ids) | ||
738 | possible = nr_cpu_ids; | ||
739 | |||
740 | for (i = 0; i < possible; i++) | ||
741 | set_cpu_possible(i, true); | ||
742 | for (; i < NR_CPUS; i++) | ||
743 | set_cpu_possible(i, false); | ||
744 | |||
745 | nr_cpu_ids = possible; | ||
746 | } | ||
747 | #else | ||
748 | static inline void prefill_possible_map(void) {} | ||
749 | #endif | ||
750 | |||
732 | void __init setup_arch(char **cmdline_p) | 751 | void __init setup_arch(char **cmdline_p) |
733 | { | 752 | { |
734 | cpu_probe(); | 753 | cpu_probe(); |
@@ -752,6 +771,7 @@ void __init setup_arch(char **cmdline_p) | |||
752 | 771 | ||
753 | resource_init(); | 772 | resource_init(); |
754 | plat_smp_setup(); | 773 | plat_smp_setup(); |
774 | prefill_possible_map(); | ||
755 | 775 | ||
756 | cpu_cache_init(); | 776 | cpu_cache_init(); |
757 | } | 777 | } |
diff --git a/arch/mips/kernel/smp-cps.c b/arch/mips/kernel/smp-cps.c index 949f2c6827a0..e6e16a1d4add 100644 --- a/arch/mips/kernel/smp-cps.c +++ b/arch/mips/kernel/smp-cps.c | |||
@@ -14,13 +14,14 @@ | |||
14 | #include <linux/smp.h> | 14 | #include <linux/smp.h> |
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | 16 | ||
17 | #include <asm/cacheflush.h> | 17 | #include <asm/bcache.h> |
18 | #include <asm/gic.h> | 18 | #include <asm/gic.h> |
19 | #include <asm/mips-cm.h> | 19 | #include <asm/mips-cm.h> |
20 | #include <asm/mips-cpc.h> | 20 | #include <asm/mips-cpc.h> |
21 | #include <asm/mips_mt.h> | 21 | #include <asm/mips_mt.h> |
22 | #include <asm/mipsregs.h> | 22 | #include <asm/mipsregs.h> |
23 | #include <asm/pm-cps.h> | 23 | #include <asm/pm-cps.h> |
24 | #include <asm/r4kcache.h> | ||
24 | #include <asm/smp-cps.h> | 25 | #include <asm/smp-cps.h> |
25 | #include <asm/time.h> | 26 | #include <asm/time.h> |
26 | #include <asm/uasm.h> | 27 | #include <asm/uasm.h> |
@@ -132,8 +133,11 @@ static void __init cps_prepare_cpus(unsigned int max_cpus) | |||
132 | entry_code = (u32 *)&mips_cps_core_entry; | 133 | entry_code = (u32 *)&mips_cps_core_entry; |
133 | UASM_i_LA(&entry_code, 3, (long)mips_cm_base); | 134 | UASM_i_LA(&entry_code, 3, (long)mips_cm_base); |
134 | uasm_i_addiu(&entry_code, 16, 0, cca); | 135 | uasm_i_addiu(&entry_code, 16, 0, cca); |
135 | dma_cache_wback_inv((unsigned long)&mips_cps_core_entry, | 136 | blast_dcache_range((unsigned long)&mips_cps_core_entry, |
136 | (void *)entry_code - (void *)&mips_cps_core_entry); | 137 | (unsigned long)entry_code); |
138 | bc_wback_inv((unsigned long)&mips_cps_core_entry, | ||
139 | (void *)entry_code - (void *)&mips_cps_core_entry); | ||
140 | __sync(); | ||
137 | 141 | ||
138 | /* Allocate core boot configuration structs */ | 142 | /* Allocate core boot configuration structs */ |
139 | mips_cps_core_bootcfg = kcalloc(ncores, sizeof(*mips_cps_core_bootcfg), | 143 | mips_cps_core_bootcfg = kcalloc(ncores, sizeof(*mips_cps_core_bootcfg), |
@@ -360,7 +364,7 @@ void play_dead(void) | |||
360 | static void wait_for_sibling_halt(void *ptr_cpu) | 364 | static void wait_for_sibling_halt(void *ptr_cpu) |
361 | { | 365 | { |
362 | unsigned cpu = (unsigned)ptr_cpu; | 366 | unsigned cpu = (unsigned)ptr_cpu; |
363 | unsigned vpe_id = cpu_data[cpu].vpe_id; | 367 | unsigned vpe_id = cpu_vpe_id(&cpu_data[cpu]); |
364 | unsigned halted; | 368 | unsigned halted; |
365 | unsigned long flags; | 369 | unsigned long flags; |
366 | 370 | ||
diff --git a/arch/mips/kernel/smp-mt.c b/arch/mips/kernel/smp-mt.c index 3babf6e4f894..21f23add04f4 100644 --- a/arch/mips/kernel/smp-mt.c +++ b/arch/mips/kernel/smp-mt.c | |||
@@ -288,6 +288,7 @@ struct plat_smp_ops vsmp_smp_ops = { | |||
288 | .prepare_cpus = vsmp_prepare_cpus, | 288 | .prepare_cpus = vsmp_prepare_cpus, |
289 | }; | 289 | }; |
290 | 290 | ||
291 | #ifdef CONFIG_PROC_FS | ||
291 | static int proc_cpuinfo_chain_call(struct notifier_block *nfb, | 292 | static int proc_cpuinfo_chain_call(struct notifier_block *nfb, |
292 | unsigned long action_unused, void *data) | 293 | unsigned long action_unused, void *data) |
293 | { | 294 | { |
@@ -309,3 +310,4 @@ static int __init proc_cpuinfo_notifier_init(void) | |||
309 | } | 310 | } |
310 | 311 | ||
311 | subsys_initcall(proc_cpuinfo_notifier_init); | 312 | subsys_initcall(proc_cpuinfo_notifier_init); |
313 | #endif | ||
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 9bad52ede903..c94c4e92e17d 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -59,9 +59,16 @@ EXPORT_SYMBOL(smp_num_siblings); | |||
59 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; | 59 | cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; |
60 | EXPORT_SYMBOL(cpu_sibling_map); | 60 | EXPORT_SYMBOL(cpu_sibling_map); |
61 | 61 | ||
62 | /* representing the core map of multi-core chips of each logical CPU */ | ||
63 | cpumask_t cpu_core_map[NR_CPUS] __read_mostly; | ||
64 | EXPORT_SYMBOL(cpu_core_map); | ||
65 | |||
62 | /* representing cpus for which sibling maps can be computed */ | 66 | /* representing cpus for which sibling maps can be computed */ |
63 | static cpumask_t cpu_sibling_setup_map; | 67 | static cpumask_t cpu_sibling_setup_map; |
64 | 68 | ||
69 | /* representing cpus for which core maps can be computed */ | ||
70 | static cpumask_t cpu_core_setup_map; | ||
71 | |||
65 | cpumask_t cpu_coherent_mask; | 72 | cpumask_t cpu_coherent_mask; |
66 | 73 | ||
67 | static inline void set_cpu_sibling_map(int cpu) | 74 | static inline void set_cpu_sibling_map(int cpu) |
@@ -72,7 +79,8 @@ static inline void set_cpu_sibling_map(int cpu) | |||
72 | 79 | ||
73 | if (smp_num_siblings > 1) { | 80 | if (smp_num_siblings > 1) { |
74 | for_each_cpu_mask(i, cpu_sibling_setup_map) { | 81 | for_each_cpu_mask(i, cpu_sibling_setup_map) { |
75 | if (cpu_data[cpu].core == cpu_data[i].core) { | 82 | if (cpu_data[cpu].package == cpu_data[i].package && |
83 | cpu_data[cpu].core == cpu_data[i].core) { | ||
76 | cpu_set(i, cpu_sibling_map[cpu]); | 84 | cpu_set(i, cpu_sibling_map[cpu]); |
77 | cpu_set(cpu, cpu_sibling_map[i]); | 85 | cpu_set(cpu, cpu_sibling_map[i]); |
78 | } | 86 | } |
@@ -81,6 +89,20 @@ static inline void set_cpu_sibling_map(int cpu) | |||
81 | cpu_set(cpu, cpu_sibling_map[cpu]); | 89 | cpu_set(cpu, cpu_sibling_map[cpu]); |
82 | } | 90 | } |
83 | 91 | ||
92 | static inline void set_cpu_core_map(int cpu) | ||
93 | { | ||
94 | int i; | ||
95 | |||
96 | cpu_set(cpu, cpu_core_setup_map); | ||
97 | |||
98 | for_each_cpu_mask(i, cpu_core_setup_map) { | ||
99 | if (cpu_data[cpu].package == cpu_data[i].package) { | ||
100 | cpu_set(i, cpu_core_map[cpu]); | ||
101 | cpu_set(cpu, cpu_core_map[i]); | ||
102 | } | ||
103 | } | ||
104 | } | ||
105 | |||
84 | struct plat_smp_ops *mp_ops; | 106 | struct plat_smp_ops *mp_ops; |
85 | EXPORT_SYMBOL(mp_ops); | 107 | EXPORT_SYMBOL(mp_ops); |
86 | 108 | ||
@@ -122,6 +144,7 @@ asmlinkage void start_secondary(void) | |||
122 | set_cpu_online(cpu, true); | 144 | set_cpu_online(cpu, true); |
123 | 145 | ||
124 | set_cpu_sibling_map(cpu); | 146 | set_cpu_sibling_map(cpu); |
147 | set_cpu_core_map(cpu); | ||
125 | 148 | ||
126 | cpu_set(cpu, cpu_callin_map); | 149 | cpu_set(cpu, cpu_callin_map); |
127 | 150 | ||
@@ -175,6 +198,7 @@ void __init smp_prepare_cpus(unsigned int max_cpus) | |||
175 | current_thread_info()->cpu = 0; | 198 | current_thread_info()->cpu = 0; |
176 | mp_ops->prepare_cpus(max_cpus); | 199 | mp_ops->prepare_cpus(max_cpus); |
177 | set_cpu_sibling_map(0); | 200 | set_cpu_sibling_map(0); |
201 | set_cpu_core_map(0); | ||
178 | #ifndef CONFIG_HOTPLUG_CPU | 202 | #ifndef CONFIG_HOTPLUG_CPU |
179 | init_cpu_present(cpu_possible_mask); | 203 | init_cpu_present(cpu_possible_mask); |
180 | #endif | 204 | #endif |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index 51706d6dd5b0..22b19c275044 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -90,6 +90,7 @@ extern asmlinkage void handle_mt(void); | |||
90 | extern asmlinkage void handle_dsp(void); | 90 | extern asmlinkage void handle_dsp(void); |
91 | extern asmlinkage void handle_mcheck(void); | 91 | extern asmlinkage void handle_mcheck(void); |
92 | extern asmlinkage void handle_reserved(void); | 92 | extern asmlinkage void handle_reserved(void); |
93 | extern void tlb_do_page_fault_0(void); | ||
93 | 94 | ||
94 | void (*board_be_init)(void); | 95 | void (*board_be_init)(void); |
95 | int (*board_be_handler)(struct pt_regs *regs, int is_fixup); | 96 | int (*board_be_handler)(struct pt_regs *regs, int is_fixup); |
@@ -1088,13 +1089,19 @@ static int default_cu2_call(struct notifier_block *nfb, unsigned long action, | |||
1088 | 1089 | ||
1089 | static int enable_restore_fp_context(int msa) | 1090 | static int enable_restore_fp_context(int msa) |
1090 | { | 1091 | { |
1091 | int err, was_fpu_owner; | 1092 | int err, was_fpu_owner, prior_msa; |
1092 | 1093 | ||
1093 | if (!used_math()) { | 1094 | if (!used_math()) { |
1094 | /* First time FP context user. */ | 1095 | /* First time FP context user. */ |
1096 | preempt_disable(); | ||
1095 | err = init_fpu(); | 1097 | err = init_fpu(); |
1096 | if (msa && !err) | 1098 | if (msa && !err) { |
1097 | enable_msa(); | 1099 | enable_msa(); |
1100 | _init_msa_upper(); | ||
1101 | set_thread_flag(TIF_USEDMSA); | ||
1102 | set_thread_flag(TIF_MSA_CTX_LIVE); | ||
1103 | } | ||
1104 | preempt_enable(); | ||
1098 | if (!err) | 1105 | if (!err) |
1099 | set_used_math(); | 1106 | set_used_math(); |
1100 | return err; | 1107 | return err; |
@@ -1134,10 +1141,11 @@ static int enable_restore_fp_context(int msa) | |||
1134 | * This task is using or has previously used MSA. Thus we require | 1141 | * This task is using or has previously used MSA. Thus we require |
1135 | * that Status.FR == 1. | 1142 | * that Status.FR == 1. |
1136 | */ | 1143 | */ |
1144 | preempt_disable(); | ||
1137 | was_fpu_owner = is_fpu_owner(); | 1145 | was_fpu_owner = is_fpu_owner(); |
1138 | err = own_fpu(0); | 1146 | err = own_fpu_inatomic(0); |
1139 | if (err) | 1147 | if (err) |
1140 | return err; | 1148 | goto out; |
1141 | 1149 | ||
1142 | enable_msa(); | 1150 | enable_msa(); |
1143 | write_msa_csr(current->thread.fpu.msacsr); | 1151 | write_msa_csr(current->thread.fpu.msacsr); |
@@ -1146,13 +1154,42 @@ static int enable_restore_fp_context(int msa) | |||
1146 | /* | 1154 | /* |
1147 | * If this is the first time that the task is using MSA and it has | 1155 | * If this is the first time that the task is using MSA and it has |
1148 | * previously used scalar FP in this time slice then we already nave | 1156 | * previously used scalar FP in this time slice then we already nave |
1149 | * FP context which we shouldn't clobber. | 1157 | * FP context which we shouldn't clobber. We do however need to clear |
1158 | * the upper 64b of each vector register so that this task has no | ||
1159 | * opportunity to see data left behind by another. | ||
1150 | */ | 1160 | */ |
1151 | if (!test_and_set_thread_flag(TIF_MSA_CTX_LIVE) && was_fpu_owner) | 1161 | prior_msa = test_and_set_thread_flag(TIF_MSA_CTX_LIVE); |
1152 | return 0; | 1162 | if (!prior_msa && was_fpu_owner) { |
1163 | _init_msa_upper(); | ||
1164 | |||
1165 | goto out; | ||
1166 | } | ||
1167 | |||
1168 | if (!prior_msa) { | ||
1169 | /* | ||
1170 | * Restore the least significant 64b of each vector register | ||
1171 | * from the existing scalar FP context. | ||
1172 | */ | ||
1173 | _restore_fp(current); | ||
1174 | |||
1175 | /* | ||
1176 | * The task has not formerly used MSA, so clear the upper 64b | ||
1177 | * of each vector register such that it cannot see data left | ||
1178 | * behind by another task. | ||
1179 | */ | ||
1180 | _init_msa_upper(); | ||
1181 | } else { | ||
1182 | /* We need to restore the vector context. */ | ||
1183 | restore_msa(current); | ||
1184 | |||
1185 | /* Restore the scalar FP control & status register */ | ||
1186 | if (!was_fpu_owner) | ||
1187 | asm volatile("ctc1 %0, $31" : : "r"(current->thread.fpu.fcr31)); | ||
1188 | } | ||
1189 | |||
1190 | out: | ||
1191 | preempt_enable(); | ||
1153 | 1192 | ||
1154 | /* We need to restore the vector context. */ | ||
1155 | restore_msa(current); | ||
1156 | return 0; | 1193 | return 0; |
1157 | } | 1194 | } |
1158 | 1195 | ||
@@ -2114,6 +2151,12 @@ void __init trap_init(void) | |||
2114 | set_except_vector(15, handle_fpe); | 2151 | set_except_vector(15, handle_fpe); |
2115 | 2152 | ||
2116 | set_except_vector(16, handle_ftlb); | 2153 | set_except_vector(16, handle_ftlb); |
2154 | |||
2155 | if (cpu_has_rixiex) { | ||
2156 | set_except_vector(19, tlb_do_page_fault_0); | ||
2157 | set_except_vector(20, tlb_do_page_fault_0); | ||
2158 | } | ||
2159 | |||
2117 | set_except_vector(21, handle_msa); | 2160 | set_except_vector(21, handle_msa); |
2118 | set_except_vector(22, handle_mdmx); | 2161 | set_except_vector(22, handle_mdmx); |
2119 | 2162 | ||
diff --git a/arch/mips/kernel/unaligned.c b/arch/mips/kernel/unaligned.c index 2b3517214d6d..e11906dff885 100644 --- a/arch/mips/kernel/unaligned.c +++ b/arch/mips/kernel/unaligned.c | |||
@@ -690,7 +690,6 @@ static void emulate_load_store_insn(struct pt_regs *regs, | |||
690 | case sdc1_op: | 690 | case sdc1_op: |
691 | die_if_kernel("Unaligned FP access in kernel code", regs); | 691 | die_if_kernel("Unaligned FP access in kernel code", regs); |
692 | BUG_ON(!used_math()); | 692 | BUG_ON(!used_math()); |
693 | BUG_ON(!is_fpu_owner()); | ||
694 | 693 | ||
695 | lose_fpu(1); /* Save FPU state for the emulator. */ | 694 | lose_fpu(1); /* Save FPU state for the emulator. */ |
696 | res = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, | 695 | res = fpu_emulator_cop1Handler(regs, ¤t->thread.fpu, 1, |
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig index e6a86ccc4421..1b91fc6a921b 100644 --- a/arch/mips/loongson/Kconfig +++ b/arch/mips/loongson/Kconfig | |||
@@ -60,8 +60,8 @@ config LEMOTE_MACH2F | |||
60 | These family machines include fuloong2f mini PC, yeeloong2f notebook, | 60 | These family machines include fuloong2f mini PC, yeeloong2f notebook, |
61 | LingLoong allinone PC and so forth. | 61 | LingLoong allinone PC and so forth. |
62 | 62 | ||
63 | config LEMOTE_MACH3A | 63 | config LOONGSON_MACH3X |
64 | bool "Lemote Loongson 3A family machines" | 64 | bool "Generic Loongson 3 family machines" |
65 | select ARCH_SPARSEMEM_ENABLE | 65 | select ARCH_SPARSEMEM_ENABLE |
66 | select GENERIC_ISA_DMA_SUPPORT_BROKEN | 66 | select GENERIC_ISA_DMA_SUPPORT_BROKEN |
67 | select BOOT_ELF32 | 67 | select BOOT_ELF32 |
@@ -79,6 +79,7 @@ config LEMOTE_MACH3A | |||
79 | select SYS_HAS_EARLY_PRINTK | 79 | select SYS_HAS_EARLY_PRINTK |
80 | select SYS_SUPPORTS_SMP | 80 | select SYS_SUPPORTS_SMP |
81 | select SYS_SUPPORTS_HOTPLUG_CPU | 81 | select SYS_SUPPORTS_HOTPLUG_CPU |
82 | select SYS_SUPPORTS_NUMA | ||
82 | select SYS_SUPPORTS_64BIT_KERNEL | 83 | select SYS_SUPPORTS_64BIT_KERNEL |
83 | select SYS_SUPPORTS_HIGHMEM | 84 | select SYS_SUPPORTS_HIGHMEM |
84 | select SYS_SUPPORTS_LITTLE_ENDIAN | 85 | select SYS_SUPPORTS_LITTLE_ENDIAN |
@@ -86,8 +87,8 @@ config LEMOTE_MACH3A | |||
86 | select ZONE_DMA32 | 87 | select ZONE_DMA32 |
87 | select LEFI_FIRMWARE_INTERFACE | 88 | select LEFI_FIRMWARE_INTERFACE |
88 | help | 89 | help |
89 | Lemote Loongson 3A family machines utilize the 3A revision of | 90 | Generic Loongson 3 family machines utilize the 3A/3B revision |
90 | Loongson processor and RS780/SBX00 chipset. | 91 | of Loongson processor and RS780/SBX00 chipset. |
91 | endchoice | 92 | endchoice |
92 | 93 | ||
93 | config CS5536 | 94 | config CS5536 |
diff --git a/arch/mips/loongson/Platform b/arch/mips/loongson/Platform index 6205372b6c2d..0ac20eb84ecc 100644 --- a/arch/mips/loongson/Platform +++ b/arch/mips/loongson/Platform | |||
@@ -30,4 +30,4 @@ platform-$(CONFIG_MACH_LOONGSON) += loongson/ | |||
30 | cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson -mno-branch-likely | 30 | cflags-$(CONFIG_MACH_LOONGSON) += -I$(srctree)/arch/mips/include/asm/mach-loongson -mno-branch-likely |
31 | load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000 | 31 | load-$(CONFIG_LEMOTE_FULOONG2E) += 0xffffffff80100000 |
32 | load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000 | 32 | load-$(CONFIG_LEMOTE_MACH2F) += 0xffffffff80200000 |
33 | load-$(CONFIG_CPU_LOONGSON3) += 0xffffffff80200000 | 33 | load-$(CONFIG_LOONGSON_MACH3X) += 0xffffffff80200000 |
diff --git a/arch/mips/loongson/common/env.c b/arch/mips/loongson/common/env.c index 0c543eae49bf..f15228550a22 100644 --- a/arch/mips/loongson/common/env.c +++ b/arch/mips/loongson/common/env.c | |||
@@ -27,6 +27,12 @@ EXPORT_SYMBOL(cpu_clock_freq); | |||
27 | struct efi_memory_map_loongson *loongson_memmap; | 27 | struct efi_memory_map_loongson *loongson_memmap; |
28 | struct loongson_system_configuration loongson_sysconf; | 28 | struct loongson_system_configuration loongson_sysconf; |
29 | 29 | ||
30 | u64 loongson_chipcfg[MAX_PACKAGES] = {0xffffffffbfc00180}; | ||
31 | u64 loongson_freqctrl[MAX_PACKAGES]; | ||
32 | |||
33 | unsigned long long smp_group[4]; | ||
34 | int cpuhotplug_workaround = 0; | ||
35 | |||
30 | #define parse_even_earlier(res, option, p) \ | 36 | #define parse_even_earlier(res, option, p) \ |
31 | do { \ | 37 | do { \ |
32 | unsigned int tmp __maybe_unused; \ | 38 | unsigned int tmp __maybe_unused; \ |
@@ -77,9 +83,47 @@ void __init prom_init_env(void) | |||
77 | 83 | ||
78 | cpu_clock_freq = ecpu->cpu_clock_freq; | 84 | cpu_clock_freq = ecpu->cpu_clock_freq; |
79 | loongson_sysconf.cputype = ecpu->cputype; | 85 | loongson_sysconf.cputype = ecpu->cputype; |
86 | if (ecpu->cputype == Loongson_3A) { | ||
87 | loongson_sysconf.cores_per_node = 4; | ||
88 | loongson_sysconf.cores_per_package = 4; | ||
89 | smp_group[0] = 0x900000003ff01000; | ||
90 | smp_group[1] = 0x900010003ff01000; | ||
91 | smp_group[2] = 0x900020003ff01000; | ||
92 | smp_group[3] = 0x900030003ff01000; | ||
93 | loongson_chipcfg[0] = 0x900000001fe00180; | ||
94 | loongson_chipcfg[1] = 0x900010001fe00180; | ||
95 | loongson_chipcfg[2] = 0x900020001fe00180; | ||
96 | loongson_chipcfg[3] = 0x900030001fe00180; | ||
97 | loongson_sysconf.ht_control_base = 0x90000EFDFB000000; | ||
98 | } else if (ecpu->cputype == Loongson_3B) { | ||
99 | loongson_sysconf.cores_per_node = 4; /* One chip has 2 nodes */ | ||
100 | loongson_sysconf.cores_per_package = 8; | ||
101 | smp_group[0] = 0x900000003ff01000; | ||
102 | smp_group[1] = 0x900010003ff05000; | ||
103 | smp_group[2] = 0x900020003ff09000; | ||
104 | smp_group[3] = 0x900030003ff0d000; | ||
105 | loongson_chipcfg[0] = 0x900000001fe00180; | ||
106 | loongson_chipcfg[1] = 0x900020001fe00180; | ||
107 | loongson_chipcfg[2] = 0x900040001fe00180; | ||
108 | loongson_chipcfg[3] = 0x900060001fe00180; | ||
109 | loongson_freqctrl[0] = 0x900000001fe001d0; | ||
110 | loongson_freqctrl[1] = 0x900020001fe001d0; | ||
111 | loongson_freqctrl[2] = 0x900040001fe001d0; | ||
112 | loongson_freqctrl[3] = 0x900060001fe001d0; | ||
113 | loongson_sysconf.ht_control_base = 0x90001EFDFB000000; | ||
114 | cpuhotplug_workaround = 1; | ||
115 | } else { | ||
116 | loongson_sysconf.cores_per_node = 1; | ||
117 | loongson_sysconf.cores_per_package = 1; | ||
118 | loongson_chipcfg[0] = 0x900000001fe00180; | ||
119 | } | ||
120 | |||
80 | loongson_sysconf.nr_cpus = ecpu->nr_cpus; | 121 | loongson_sysconf.nr_cpus = ecpu->nr_cpus; |
81 | if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) | 122 | if (ecpu->nr_cpus > NR_CPUS || ecpu->nr_cpus == 0) |
82 | loongson_sysconf.nr_cpus = NR_CPUS; | 123 | loongson_sysconf.nr_cpus = NR_CPUS; |
124 | loongson_sysconf.nr_nodes = (loongson_sysconf.nr_cpus + | ||
125 | loongson_sysconf.cores_per_node - 1) / | ||
126 | loongson_sysconf.cores_per_node; | ||
83 | 127 | ||
84 | loongson_sysconf.pci_mem_start_addr = eirq_source->pci_mem_start_addr; | 128 | loongson_sysconf.pci_mem_start_addr = eirq_source->pci_mem_start_addr; |
85 | loongson_sysconf.pci_mem_end_addr = eirq_source->pci_mem_end_addr; | 129 | loongson_sysconf.pci_mem_end_addr = eirq_source->pci_mem_end_addr; |
@@ -93,7 +137,6 @@ void __init prom_init_env(void) | |||
93 | loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown; | 137 | loongson_sysconf.poweroff_addr = boot_p->reset_system.Shutdown; |
94 | loongson_sysconf.suspend_addr = boot_p->reset_system.DoSuspend; | 138 | loongson_sysconf.suspend_addr = boot_p->reset_system.DoSuspend; |
95 | 139 | ||
96 | loongson_sysconf.ht_control_base = 0x90000EFDFB000000; | ||
97 | loongson_sysconf.vgabios_addr = boot_p->efi.smbios.vga_bios; | 140 | loongson_sysconf.vgabios_addr = boot_p->efi.smbios.vga_bios; |
98 | pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", | 141 | pr_debug("Shutdown Addr: %llx, Restart Addr: %llx, VBIOS Addr: %llx\n", |
99 | loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, | 142 | loongson_sysconf.poweroff_addr, loongson_sysconf.restart_addr, |
@@ -111,6 +154,10 @@ void __init prom_init_env(void) | |||
111 | case PRID_REV_LOONGSON3A: | 154 | case PRID_REV_LOONGSON3A: |
112 | cpu_clock_freq = 900000000; | 155 | cpu_clock_freq = 900000000; |
113 | break; | 156 | break; |
157 | case PRID_REV_LOONGSON3B_R1: | ||
158 | case PRID_REV_LOONGSON3B_R2: | ||
159 | cpu_clock_freq = 1000000000; | ||
160 | break; | ||
114 | default: | 161 | default: |
115 | cpu_clock_freq = 100000000; | 162 | cpu_clock_freq = 100000000; |
116 | break; | 163 | break; |
diff --git a/arch/mips/loongson/common/init.c b/arch/mips/loongson/common/init.c index f37fe5413b73..f6af3aba4c86 100644 --- a/arch/mips/loongson/common/init.c +++ b/arch/mips/loongson/common/init.c | |||
@@ -30,7 +30,11 @@ void __init prom_init(void) | |||
30 | set_io_port_base((unsigned long) | 30 | set_io_port_base((unsigned long) |
31 | ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE)); | 31 | ioremap(LOONGSON_PCIIO_BASE, LOONGSON_PCIIO_SIZE)); |
32 | 32 | ||
33 | #ifdef CONFIG_NUMA | ||
34 | prom_init_numa_memory(); | ||
35 | #else | ||
33 | prom_init_memory(); | 36 | prom_init_memory(); |
37 | #endif | ||
34 | 38 | ||
35 | /*init the uart base address */ | 39 | /*init the uart base address */ |
36 | prom_init_uart_base(); | 40 | prom_init_uart_base(); |
diff --git a/arch/mips/loongson/common/pm.c b/arch/mips/loongson/common/pm.c index f55e07aee071..a6b67ccfc811 100644 --- a/arch/mips/loongson/common/pm.c +++ b/arch/mips/loongson/common/pm.c | |||
@@ -79,7 +79,7 @@ int __weak wakeup_loongson(void) | |||
79 | static void wait_for_wakeup_events(void) | 79 | static void wait_for_wakeup_events(void) |
80 | { | 80 | { |
81 | while (!wakeup_loongson()) | 81 | while (!wakeup_loongson()) |
82 | LOONGSON_CHIPCFG0 &= ~0x7; | 82 | LOONGSON_CHIPCFG(0) &= ~0x7; |
83 | } | 83 | } |
84 | 84 | ||
85 | /* | 85 | /* |
@@ -102,15 +102,15 @@ static void loongson_suspend_enter(void) | |||
102 | 102 | ||
103 | stop_perf_counters(); | 103 | stop_perf_counters(); |
104 | 104 | ||
105 | cached_cpu_freq = LOONGSON_CHIPCFG0; | 105 | cached_cpu_freq = LOONGSON_CHIPCFG(0); |
106 | 106 | ||
107 | /* Put CPU into wait mode */ | 107 | /* Put CPU into wait mode */ |
108 | LOONGSON_CHIPCFG0 &= ~0x7; | 108 | LOONGSON_CHIPCFG(0) &= ~0x7; |
109 | 109 | ||
110 | /* wait for the given events to wakeup cpu from wait mode */ | 110 | /* wait for the given events to wakeup cpu from wait mode */ |
111 | wait_for_wakeup_events(); | 111 | wait_for_wakeup_events(); |
112 | 112 | ||
113 | LOONGSON_CHIPCFG0 = cached_cpu_freq; | 113 | LOONGSON_CHIPCFG(0) = cached_cpu_freq; |
114 | mmiowb(); | 114 | mmiowb(); |
115 | } | 115 | } |
116 | 116 | ||
diff --git a/arch/mips/loongson/lemote-2f/clock.c b/arch/mips/loongson/lemote-2f/clock.c index 1eed38e28b1e..a217061beee3 100644 --- a/arch/mips/loongson/lemote-2f/clock.c +++ b/arch/mips/loongson/lemote-2f/clock.c | |||
@@ -114,9 +114,9 @@ int clk_set_rate(struct clk *clk, unsigned long rate) | |||
114 | 114 | ||
115 | clk->rate = rate; | 115 | clk->rate = rate; |
116 | 116 | ||
117 | regval = LOONGSON_CHIPCFG0; | 117 | regval = LOONGSON_CHIPCFG(0); |
118 | regval = (regval & ~0x7) | (pos->driver_data - 1); | 118 | regval = (regval & ~0x7) | (pos->driver_data - 1); |
119 | LOONGSON_CHIPCFG0 = regval; | 119 | LOONGSON_CHIPCFG(0) = regval; |
120 | 120 | ||
121 | return ret; | 121 | return ret; |
122 | } | 122 | } |
diff --git a/arch/mips/loongson/lemote-2f/reset.c b/arch/mips/loongson/lemote-2f/reset.c index 90962a3a1731..79ac694fe744 100644 --- a/arch/mips/loongson/lemote-2f/reset.c +++ b/arch/mips/loongson/lemote-2f/reset.c | |||
@@ -28,7 +28,7 @@ static void reset_cpu(void) | |||
28 | * reset cpu to full speed, this is needed when enabling cpu frequency | 28 | * reset cpu to full speed, this is needed when enabling cpu frequency |
29 | * scalling | 29 | * scalling |
30 | */ | 30 | */ |
31 | LOONGSON_CHIPCFG0 |= 0x7; | 31 | LOONGSON_CHIPCFG(0) |= 0x7; |
32 | } | 32 | } |
33 | 33 | ||
34 | /* reset support for fuloong2f */ | 34 | /* reset support for fuloong2f */ |
diff --git a/arch/mips/loongson/loongson-3/Makefile b/arch/mips/loongson/loongson-3/Makefile index 70152b252ddc..b4df775b9f30 100644 --- a/arch/mips/loongson/loongson-3/Makefile +++ b/arch/mips/loongson/loongson-3/Makefile | |||
@@ -1,6 +1,8 @@ | |||
1 | # | 1 | # |
2 | # Makefile for Loongson-3 family machines | 2 | # Makefile for Loongson-3 family machines |
3 | # | 3 | # |
4 | obj-y += irq.o | 4 | obj-y += irq.o cop2-ex.o |
5 | 5 | ||
6 | obj-$(CONFIG_SMP) += smp.o | 6 | obj-$(CONFIG_SMP) += smp.o |
7 | |||
8 | obj-$(CONFIG_NUMA) += numa.o | ||
diff --git a/arch/mips/loongson/loongson-3/cop2-ex.c b/arch/mips/loongson/loongson-3/cop2-ex.c new file mode 100644 index 000000000000..9182e8d2967c --- /dev/null +++ b/arch/mips/loongson/loongson-3/cop2-ex.c | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2014 Lemote Corporation. | ||
7 | * written by Huacai Chen <chenhc@lemote.com> | ||
8 | * | ||
9 | * based on arch/mips/cavium-octeon/cpu.c | ||
10 | * Copyright (C) 2009 Wind River Systems, | ||
11 | * written by Ralf Baechle <ralf@linux-mips.org> | ||
12 | */ | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/sched.h> | ||
15 | #include <linux/notifier.h> | ||
16 | |||
17 | #include <asm/fpu.h> | ||
18 | #include <asm/cop2.h> | ||
19 | #include <asm/current.h> | ||
20 | #include <asm/mipsregs.h> | ||
21 | |||
22 | static int loongson_cu2_call(struct notifier_block *nfb, unsigned long action, | ||
23 | void *data) | ||
24 | { | ||
25 | int fpu_enabled; | ||
26 | int fr = !test_thread_flag(TIF_32BIT_FPREGS); | ||
27 | |||
28 | switch (action) { | ||
29 | case CU2_EXCEPTION: | ||
30 | preempt_disable(); | ||
31 | fpu_enabled = read_c0_status() & ST0_CU1; | ||
32 | if (!fr) | ||
33 | set_c0_status(ST0_CU1 | ST0_CU2); | ||
34 | else | ||
35 | set_c0_status(ST0_CU1 | ST0_CU2 | ST0_FR); | ||
36 | enable_fpu_hazard(); | ||
37 | KSTK_STATUS(current) |= (ST0_CU1 | ST0_CU2); | ||
38 | if (fr) | ||
39 | KSTK_STATUS(current) |= ST0_FR; | ||
40 | else | ||
41 | KSTK_STATUS(current) &= ~ST0_FR; | ||
42 | /* If FPU is enabled, we needn't init or restore fp */ | ||
43 | if(!fpu_enabled) { | ||
44 | set_thread_flag(TIF_USEDFPU); | ||
45 | if (!used_math()) { | ||
46 | _init_fpu(); | ||
47 | set_used_math(); | ||
48 | } else | ||
49 | _restore_fp(current); | ||
50 | } | ||
51 | preempt_enable(); | ||
52 | |||
53 | return NOTIFY_STOP; /* Don't call default notifier */ | ||
54 | } | ||
55 | |||
56 | return NOTIFY_OK; /* Let default notifier send signals */ | ||
57 | } | ||
58 | |||
59 | static int __init loongson_cu2_setup(void) | ||
60 | { | ||
61 | return cu2_notifier(loongson_cu2_call, 0); | ||
62 | } | ||
63 | early_initcall(loongson_cu2_setup); | ||
diff --git a/arch/mips/loongson/loongson-3/irq.c b/arch/mips/loongson/loongson-3/irq.c index f240828181ff..ca1c62af5188 100644 --- a/arch/mips/loongson/loongson-3/irq.c +++ b/arch/mips/loongson/loongson-3/irq.c | |||
@@ -7,6 +7,8 @@ | |||
7 | #include <asm/i8259.h> | 7 | #include <asm/i8259.h> |
8 | #include <asm/mipsregs.h> | 8 | #include <asm/mipsregs.h> |
9 | 9 | ||
10 | #include "smp.h" | ||
11 | |||
10 | unsigned int ht_irq[] = {1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; | 12 | unsigned int ht_irq[] = {1, 3, 4, 5, 6, 7, 8, 12, 14, 15}; |
11 | 13 | ||
12 | static void ht_irqdispatch(void) | 14 | static void ht_irqdispatch(void) |
@@ -53,9 +55,15 @@ static inline void mask_loongson_irq(struct irq_data *d) | |||
53 | /* Workaround: UART IRQ may deliver to any core */ | 55 | /* Workaround: UART IRQ may deliver to any core */ |
54 | if (d->irq == LOONGSON_UART_IRQ) { | 56 | if (d->irq == LOONGSON_UART_IRQ) { |
55 | int cpu = smp_processor_id(); | 57 | int cpu = smp_processor_id(); |
56 | 58 | int node_id = cpu / loongson_sysconf.cores_per_node; | |
57 | LOONGSON_INT_ROUTER_INTENCLR = 1 << 10; | 59 | int core_id = cpu % loongson_sysconf.cores_per_node; |
58 | LOONGSON_INT_ROUTER_LPC = 0x10 + (1<<cpu); | 60 | u64 intenclr_addr = smp_group[node_id] | |
61 | (u64)(&LOONGSON_INT_ROUTER_INTENCLR); | ||
62 | u64 introuter_lpc_addr = smp_group[node_id] | | ||
63 | (u64)(&LOONGSON_INT_ROUTER_LPC); | ||
64 | |||
65 | *(volatile u32 *)intenclr_addr = 1 << 10; | ||
66 | *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<<core_id); | ||
59 | } | 67 | } |
60 | } | 68 | } |
61 | 69 | ||
@@ -64,9 +72,15 @@ static inline void unmask_loongson_irq(struct irq_data *d) | |||
64 | /* Workaround: UART IRQ may deliver to any core */ | 72 | /* Workaround: UART IRQ may deliver to any core */ |
65 | if (d->irq == LOONGSON_UART_IRQ) { | 73 | if (d->irq == LOONGSON_UART_IRQ) { |
66 | int cpu = smp_processor_id(); | 74 | int cpu = smp_processor_id(); |
67 | 75 | int node_id = cpu / loongson_sysconf.cores_per_node; | |
68 | LOONGSON_INT_ROUTER_INTENSET = 1 << 10; | 76 | int core_id = cpu % loongson_sysconf.cores_per_node; |
69 | LOONGSON_INT_ROUTER_LPC = 0x10 + (1<<cpu); | 77 | u64 intenset_addr = smp_group[node_id] | |
78 | (u64)(&LOONGSON_INT_ROUTER_INTENSET); | ||
79 | u64 introuter_lpc_addr = smp_group[node_id] | | ||
80 | (u64)(&LOONGSON_INT_ROUTER_LPC); | ||
81 | |||
82 | *(volatile u32 *)intenset_addr = 1 << 10; | ||
83 | *(volatile u8 *)introuter_lpc_addr = 0x10 + (1<<core_id); | ||
70 | } | 84 | } |
71 | 85 | ||
72 | set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); | 86 | set_c0_status(0x100 << (d->irq - MIPS_CPU_IRQ_BASE)); |
diff --git a/arch/mips/loongson/loongson-3/numa.c b/arch/mips/loongson/loongson-3/numa.c new file mode 100644 index 000000000000..ca025a6ba559 --- /dev/null +++ b/arch/mips/loongson/loongson-3/numa.c | |||
@@ -0,0 +1,291 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2010 Loongson Inc. & Lemote Inc. & | ||
3 | * Insititute of Computing Technology | ||
4 | * Author: Xiang Gao, gaoxiang@ict.ac.cn | ||
5 | * Huacai Chen, chenhc@lemote.com | ||
6 | * Xiaofu Meng, Shuangshuang Zhang | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/mm.h> | ||
16 | #include <linux/mmzone.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/nodemask.h> | ||
19 | #include <linux/swap.h> | ||
20 | #include <linux/memblock.h> | ||
21 | #include <linux/bootmem.h> | ||
22 | #include <linux/pfn.h> | ||
23 | #include <linux/highmem.h> | ||
24 | #include <asm/page.h> | ||
25 | #include <asm/pgalloc.h> | ||
26 | #include <asm/sections.h> | ||
27 | #include <linux/bootmem.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/irq.h> | ||
30 | #include <asm/bootinfo.h> | ||
31 | #include <asm/mc146818-time.h> | ||
32 | #include <asm/time.h> | ||
33 | #include <asm/wbflush.h> | ||
34 | #include <boot_param.h> | ||
35 | |||
36 | static struct node_data prealloc__node_data[MAX_NUMNODES]; | ||
37 | unsigned char __node_distances[MAX_NUMNODES][MAX_NUMNODES]; | ||
38 | struct node_data *__node_data[MAX_NUMNODES]; | ||
39 | EXPORT_SYMBOL(__node_data); | ||
40 | |||
41 | static void enable_lpa(void) | ||
42 | { | ||
43 | unsigned long value; | ||
44 | |||
45 | value = __read_32bit_c0_register($16, 3); | ||
46 | value |= 0x00000080; | ||
47 | __write_32bit_c0_register($16, 3, value); | ||
48 | value = __read_32bit_c0_register($16, 3); | ||
49 | pr_info("CP0_Config3: CP0 16.3 (0x%lx)\n", value); | ||
50 | |||
51 | value = __read_32bit_c0_register($5, 1); | ||
52 | value |= 0x20000000; | ||
53 | __write_32bit_c0_register($5, 1, value); | ||
54 | value = __read_32bit_c0_register($5, 1); | ||
55 | pr_info("CP0_PageGrain: CP0 5.1 (0x%lx)\n", value); | ||
56 | } | ||
57 | |||
58 | static void cpu_node_probe(void) | ||
59 | { | ||
60 | int i; | ||
61 | |||
62 | nodes_clear(node_possible_map); | ||
63 | nodes_clear(node_online_map); | ||
64 | for (i = 0; i < loongson_sysconf.nr_nodes; i++) { | ||
65 | node_set_state(num_online_nodes(), N_POSSIBLE); | ||
66 | node_set_online(num_online_nodes()); | ||
67 | } | ||
68 | |||
69 | pr_info("NUMA: Discovered %d cpus on %d nodes\n", | ||
70 | loongson_sysconf.nr_cpus, num_online_nodes()); | ||
71 | } | ||
72 | |||
73 | static int __init compute_node_distance(int row, int col) | ||
74 | { | ||
75 | int package_row = row * loongson_sysconf.cores_per_node / | ||
76 | loongson_sysconf.cores_per_package; | ||
77 | int package_col = col * loongson_sysconf.cores_per_node / | ||
78 | loongson_sysconf.cores_per_package; | ||
79 | |||
80 | if (col == row) | ||
81 | return 0; | ||
82 | else if (package_row == package_col) | ||
83 | return 40; | ||
84 | else | ||
85 | return 100; | ||
86 | } | ||
87 | |||
88 | static void __init init_topology_matrix(void) | ||
89 | { | ||
90 | int row, col; | ||
91 | |||
92 | for (row = 0; row < MAX_NUMNODES; row++) | ||
93 | for (col = 0; col < MAX_NUMNODES; col++) | ||
94 | __node_distances[row][col] = -1; | ||
95 | |||
96 | for_each_online_node(row) { | ||
97 | for_each_online_node(col) { | ||
98 | __node_distances[row][col] = | ||
99 | compute_node_distance(row, col); | ||
100 | } | ||
101 | } | ||
102 | } | ||
103 | |||
104 | static unsigned long nid_to_addroffset(unsigned int nid) | ||
105 | { | ||
106 | unsigned long result; | ||
107 | switch (nid) { | ||
108 | case 0: | ||
109 | default: | ||
110 | result = NODE0_ADDRSPACE_OFFSET; | ||
111 | break; | ||
112 | case 1: | ||
113 | result = NODE1_ADDRSPACE_OFFSET; | ||
114 | break; | ||
115 | case 2: | ||
116 | result = NODE2_ADDRSPACE_OFFSET; | ||
117 | break; | ||
118 | case 3: | ||
119 | result = NODE3_ADDRSPACE_OFFSET; | ||
120 | break; | ||
121 | } | ||
122 | return result; | ||
123 | } | ||
124 | |||
125 | static void __init szmem(unsigned int node) | ||
126 | { | ||
127 | u32 i, mem_type; | ||
128 | static unsigned long num_physpages = 0; | ||
129 | u64 node_id, node_psize, start_pfn, end_pfn, mem_start, mem_size; | ||
130 | |||
131 | /* Parse memory information and activate */ | ||
132 | for (i = 0; i < loongson_memmap->nr_map; i++) { | ||
133 | node_id = loongson_memmap->map[i].node_id; | ||
134 | if (node_id != node) | ||
135 | continue; | ||
136 | |||
137 | mem_type = loongson_memmap->map[i].mem_type; | ||
138 | mem_size = loongson_memmap->map[i].mem_size; | ||
139 | mem_start = loongson_memmap->map[i].mem_start; | ||
140 | |||
141 | switch (mem_type) { | ||
142 | case SYSTEM_RAM_LOW: | ||
143 | start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; | ||
144 | node_psize = (mem_size << 20) >> PAGE_SHIFT; | ||
145 | end_pfn = start_pfn + node_psize; | ||
146 | num_physpages += node_psize; | ||
147 | pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", | ||
148 | (u32)node_id, mem_type, mem_start, mem_size); | ||
149 | pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", | ||
150 | start_pfn, end_pfn, num_physpages); | ||
151 | add_memory_region((node_id << 44) + mem_start, | ||
152 | (u64)mem_size << 20, BOOT_MEM_RAM); | ||
153 | memblock_add_node(PFN_PHYS(start_pfn), | ||
154 | PFN_PHYS(end_pfn - start_pfn), node); | ||
155 | break; | ||
156 | case SYSTEM_RAM_HIGH: | ||
157 | start_pfn = ((node_id << 44) + mem_start) >> PAGE_SHIFT; | ||
158 | node_psize = (mem_size << 20) >> PAGE_SHIFT; | ||
159 | end_pfn = start_pfn + node_psize; | ||
160 | num_physpages += node_psize; | ||
161 | pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", | ||
162 | (u32)node_id, mem_type, mem_start, mem_size); | ||
163 | pr_info(" start_pfn:0x%llx, end_pfn:0x%llx, num_physpages:0x%lx\n", | ||
164 | start_pfn, end_pfn, num_physpages); | ||
165 | add_memory_region((node_id << 44) + mem_start, | ||
166 | (u64)mem_size << 20, BOOT_MEM_RAM); | ||
167 | memblock_add_node(PFN_PHYS(start_pfn), | ||
168 | PFN_PHYS(end_pfn - start_pfn), node); | ||
169 | break; | ||
170 | case MEM_RESERVED: | ||
171 | pr_info("Node%d: mem_type:%d, mem_start:0x%llx, mem_size:0x%llx MB\n", | ||
172 | (u32)node_id, mem_type, mem_start, mem_size); | ||
173 | add_memory_region((node_id << 44) + mem_start, | ||
174 | (u64)mem_size << 20, BOOT_MEM_RESERVED); | ||
175 | memblock_reserve(((node_id << 44) + mem_start), | ||
176 | mem_size << 20); | ||
177 | break; | ||
178 | } | ||
179 | } | ||
180 | } | ||
181 | |||
182 | static void __init node_mem_init(unsigned int node) | ||
183 | { | ||
184 | unsigned long bootmap_size; | ||
185 | unsigned long node_addrspace_offset; | ||
186 | unsigned long start_pfn, end_pfn, freepfn; | ||
187 | |||
188 | node_addrspace_offset = nid_to_addroffset(node); | ||
189 | pr_info("Node%d's addrspace_offset is 0x%lx\n", | ||
190 | node, node_addrspace_offset); | ||
191 | |||
192 | get_pfn_range_for_nid(node, &start_pfn, &end_pfn); | ||
193 | freepfn = start_pfn; | ||
194 | if (node == 0) | ||
195 | freepfn = PFN_UP(__pa_symbol(&_end)); /* kernel end address */ | ||
196 | pr_info("Node%d: start_pfn=0x%lx, end_pfn=0x%lx, freepfn=0x%lx\n", | ||
197 | node, start_pfn, end_pfn, freepfn); | ||
198 | |||
199 | __node_data[node] = prealloc__node_data + node; | ||
200 | |||
201 | NODE_DATA(node)->bdata = &bootmem_node_data[node]; | ||
202 | NODE_DATA(node)->node_start_pfn = start_pfn; | ||
203 | NODE_DATA(node)->node_spanned_pages = end_pfn - start_pfn; | ||
204 | |||
205 | bootmap_size = init_bootmem_node(NODE_DATA(node), freepfn, | ||
206 | start_pfn, end_pfn); | ||
207 | free_bootmem_with_active_regions(node, end_pfn); | ||
208 | if (node == 0) /* used by finalize_initrd() */ | ||
209 | max_low_pfn = end_pfn; | ||
210 | |||
211 | /* This is reserved for the kernel and bdata->node_bootmem_map */ | ||
212 | reserve_bootmem_node(NODE_DATA(node), start_pfn << PAGE_SHIFT, | ||
213 | ((freepfn - start_pfn) << PAGE_SHIFT) + bootmap_size, | ||
214 | BOOTMEM_DEFAULT); | ||
215 | |||
216 | if (node == 0 && node_end_pfn(0) >= (0xffffffff >> PAGE_SHIFT)) { | ||
217 | /* Reserve 0xff800000~0xffffffff for RS780E integrated GPU */ | ||
218 | reserve_bootmem_node(NODE_DATA(node), | ||
219 | (node_addrspace_offset | 0xff800000), | ||
220 | 8 << 20, BOOTMEM_DEFAULT); | ||
221 | } | ||
222 | |||
223 | sparse_memory_present_with_active_regions(node); | ||
224 | } | ||
225 | |||
226 | static __init void prom_meminit(void) | ||
227 | { | ||
228 | unsigned int node, cpu; | ||
229 | |||
230 | cpu_node_probe(); | ||
231 | init_topology_matrix(); | ||
232 | |||
233 | for (node = 0; node < loongson_sysconf.nr_nodes; node++) { | ||
234 | if (node_online(node)) { | ||
235 | szmem(node); | ||
236 | node_mem_init(node); | ||
237 | cpus_clear(__node_data[(node)]->cpumask); | ||
238 | } | ||
239 | } | ||
240 | for (cpu = 0; cpu < loongson_sysconf.nr_cpus; cpu++) { | ||
241 | node = cpu / loongson_sysconf.cores_per_node; | ||
242 | if (node >= num_online_nodes()) | ||
243 | node = 0; | ||
244 | pr_info("NUMA: set cpumask cpu %d on node %d\n", cpu, node); | ||
245 | cpu_set(cpu, __node_data[(node)]->cpumask); | ||
246 | } | ||
247 | } | ||
248 | |||
249 | void __init paging_init(void) | ||
250 | { | ||
251 | unsigned node; | ||
252 | unsigned long zones_size[MAX_NR_ZONES] = {0, }; | ||
253 | |||
254 | pagetable_init(); | ||
255 | |||
256 | for_each_online_node(node) { | ||
257 | unsigned long start_pfn, end_pfn; | ||
258 | |||
259 | get_pfn_range_for_nid(node, &start_pfn, &end_pfn); | ||
260 | |||
261 | if (end_pfn > max_low_pfn) | ||
262 | max_low_pfn = end_pfn; | ||
263 | } | ||
264 | #ifdef CONFIG_ZONE_DMA32 | ||
265 | zones_size[ZONE_DMA32] = MAX_DMA32_PFN; | ||
266 | #endif | ||
267 | zones_size[ZONE_NORMAL] = max_low_pfn; | ||
268 | free_area_init_nodes(zones_size); | ||
269 | } | ||
270 | |||
271 | void __init mem_init(void) | ||
272 | { | ||
273 | high_memory = (void *) __va(get_num_physpages() << PAGE_SHIFT); | ||
274 | free_all_bootmem(); | ||
275 | setup_zero_pages(); /* This comes from node 0 */ | ||
276 | mem_init_print_info(NULL); | ||
277 | } | ||
278 | |||
279 | /* All PCI device belongs to logical Node-0 */ | ||
280 | int pcibus_to_node(struct pci_bus *bus) | ||
281 | { | ||
282 | return 0; | ||
283 | } | ||
284 | EXPORT_SYMBOL(pcibus_to_node); | ||
285 | |||
286 | void __init prom_init_numa_memory(void) | ||
287 | { | ||
288 | enable_lpa(); | ||
289 | prom_meminit(); | ||
290 | } | ||
291 | EXPORT_SYMBOL(prom_init_numa_memory); | ||
diff --git a/arch/mips/loongson/loongson-3/smp.c b/arch/mips/loongson/loongson-3/smp.c index 1e8894020ea5..74e827b4ec8f 100644 --- a/arch/mips/loongson/loongson-3/smp.c +++ b/arch/mips/loongson/loongson-3/smp.c | |||
@@ -31,6 +31,12 @@ | |||
31 | DEFINE_PER_CPU(int, cpu_state); | 31 | DEFINE_PER_CPU(int, cpu_state); |
32 | DEFINE_PER_CPU(uint32_t, core0_c0count); | 32 | DEFINE_PER_CPU(uint32_t, core0_c0count); |
33 | 33 | ||
34 | static void *ipi_set0_regs[16]; | ||
35 | static void *ipi_clear0_regs[16]; | ||
36 | static void *ipi_status0_regs[16]; | ||
37 | static void *ipi_en0_regs[16]; | ||
38 | static void *ipi_mailbox_buf[16]; | ||
39 | |||
34 | /* read a 32bit value from ipi register */ | 40 | /* read a 32bit value from ipi register */ |
35 | #define loongson3_ipi_read32(addr) readl(addr) | 41 | #define loongson3_ipi_read32(addr) readl(addr) |
36 | /* read a 64bit value from ipi register */ | 42 | /* read a 64bit value from ipi register */ |
@@ -48,100 +54,185 @@ DEFINE_PER_CPU(uint32_t, core0_c0count); | |||
48 | __wbflush(); \ | 54 | __wbflush(); \ |
49 | } while (0) | 55 | } while (0) |
50 | 56 | ||
51 | static void *ipi_set0_regs[] = { | 57 | static void ipi_set0_regs_init(void) |
52 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + SET0), | 58 | { |
53 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + SET0), | 59 | ipi_set0_regs[0] = (void *) |
54 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + SET0), | 60 | (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + SET0); |
55 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + SET0), | 61 | ipi_set0_regs[1] = (void *) |
56 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + SET0), | 62 | (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + SET0); |
57 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + SET0), | 63 | ipi_set0_regs[2] = (void *) |
58 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + SET0), | 64 | (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + SET0); |
59 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + SET0), | 65 | ipi_set0_regs[3] = (void *) |
60 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + SET0), | 66 | (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + SET0); |
61 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + SET0), | 67 | ipi_set0_regs[4] = (void *) |
62 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + SET0), | 68 | (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + SET0); |
63 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + SET0), | 69 | ipi_set0_regs[5] = (void *) |
64 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + SET0), | 70 | (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + SET0); |
65 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + SET0), | 71 | ipi_set0_regs[6] = (void *) |
66 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + SET0), | 72 | (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + SET0); |
67 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + SET0), | 73 | ipi_set0_regs[7] = (void *) |
68 | }; | 74 | (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + SET0); |
75 | ipi_set0_regs[8] = (void *) | ||
76 | (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + SET0); | ||
77 | ipi_set0_regs[9] = (void *) | ||
78 | (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + SET0); | ||
79 | ipi_set0_regs[10] = (void *) | ||
80 | (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + SET0); | ||
81 | ipi_set0_regs[11] = (void *) | ||
82 | (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + SET0); | ||
83 | ipi_set0_regs[12] = (void *) | ||
84 | (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + SET0); | ||
85 | ipi_set0_regs[13] = (void *) | ||
86 | (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + SET0); | ||
87 | ipi_set0_regs[14] = (void *) | ||
88 | (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + SET0); | ||
89 | ipi_set0_regs[15] = (void *) | ||
90 | (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + SET0); | ||
91 | } | ||
69 | 92 | ||
70 | static void *ipi_clear0_regs[] = { | 93 | static void ipi_clear0_regs_init(void) |
71 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + CLEAR0), | 94 | { |
72 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + CLEAR0), | 95 | ipi_clear0_regs[0] = (void *) |
73 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + CLEAR0), | 96 | (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + CLEAR0); |
74 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + CLEAR0), | 97 | ipi_clear0_regs[1] = (void *) |
75 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + CLEAR0), | 98 | (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + CLEAR0); |
76 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + CLEAR0), | 99 | ipi_clear0_regs[2] = (void *) |
77 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + CLEAR0), | 100 | (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + CLEAR0); |
78 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + CLEAR0), | 101 | ipi_clear0_regs[3] = (void *) |
79 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + CLEAR0), | 102 | (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + CLEAR0); |
80 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + CLEAR0), | 103 | ipi_clear0_regs[4] = (void *) |
81 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + CLEAR0), | 104 | (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + CLEAR0); |
82 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + CLEAR0), | 105 | ipi_clear0_regs[5] = (void *) |
83 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + CLEAR0), | 106 | (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + CLEAR0); |
84 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + CLEAR0), | 107 | ipi_clear0_regs[6] = (void *) |
85 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + CLEAR0), | 108 | (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + CLEAR0); |
86 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + CLEAR0), | 109 | ipi_clear0_regs[7] = (void *) |
87 | }; | 110 | (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + CLEAR0); |
111 | ipi_clear0_regs[8] = (void *) | ||
112 | (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + CLEAR0); | ||
113 | ipi_clear0_regs[9] = (void *) | ||
114 | (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + CLEAR0); | ||
115 | ipi_clear0_regs[10] = (void *) | ||
116 | (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + CLEAR0); | ||
117 | ipi_clear0_regs[11] = (void *) | ||
118 | (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + CLEAR0); | ||
119 | ipi_clear0_regs[12] = (void *) | ||
120 | (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + CLEAR0); | ||
121 | ipi_clear0_regs[13] = (void *) | ||
122 | (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + CLEAR0); | ||
123 | ipi_clear0_regs[14] = (void *) | ||
124 | (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + CLEAR0); | ||
125 | ipi_clear0_regs[15] = (void *) | ||
126 | (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + CLEAR0); | ||
127 | } | ||
88 | 128 | ||
89 | static void *ipi_status0_regs[] = { | 129 | static void ipi_status0_regs_init(void) |
90 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + STATUS0), | 130 | { |
91 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + STATUS0), | 131 | ipi_status0_regs[0] = (void *) |
92 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + STATUS0), | 132 | (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + STATUS0); |
93 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + STATUS0), | 133 | ipi_status0_regs[1] = (void *) |
94 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + STATUS0), | 134 | (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + STATUS0); |
95 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + STATUS0), | 135 | ipi_status0_regs[2] = (void *) |
96 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + STATUS0), | 136 | (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + STATUS0); |
97 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + STATUS0), | 137 | ipi_status0_regs[3] = (void *) |
98 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + STATUS0), | 138 | (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + STATUS0); |
99 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + STATUS0), | 139 | ipi_status0_regs[4] = (void *) |
100 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + STATUS0), | 140 | (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + STATUS0); |
101 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + STATUS0), | 141 | ipi_status0_regs[5] = (void *) |
102 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + STATUS0), | 142 | (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + STATUS0); |
103 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + STATUS0), | 143 | ipi_status0_regs[6] = (void *) |
104 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + STATUS0), | 144 | (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + STATUS0); |
105 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + STATUS0), | 145 | ipi_status0_regs[7] = (void *) |
106 | }; | 146 | (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + STATUS0); |
147 | ipi_status0_regs[8] = (void *) | ||
148 | (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + STATUS0); | ||
149 | ipi_status0_regs[9] = (void *) | ||
150 | (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + STATUS0); | ||
151 | ipi_status0_regs[10] = (void *) | ||
152 | (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + STATUS0); | ||
153 | ipi_status0_regs[11] = (void *) | ||
154 | (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + STATUS0); | ||
155 | ipi_status0_regs[12] = (void *) | ||
156 | (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + STATUS0); | ||
157 | ipi_status0_regs[13] = (void *) | ||
158 | (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + STATUS0); | ||
159 | ipi_status0_regs[14] = (void *) | ||
160 | (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + STATUS0); | ||
161 | ipi_status0_regs[15] = (void *) | ||
162 | (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + STATUS0); | ||
163 | } | ||
107 | 164 | ||
108 | static void *ipi_en0_regs[] = { | 165 | static void ipi_en0_regs_init(void) |
109 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + EN0), | 166 | { |
110 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + EN0), | 167 | ipi_en0_regs[0] = (void *) |
111 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + EN0), | 168 | (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + EN0); |
112 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + EN0), | 169 | ipi_en0_regs[1] = (void *) |
113 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + EN0), | 170 | (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + EN0); |
114 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + EN0), | 171 | ipi_en0_regs[2] = (void *) |
115 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + EN0), | 172 | (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + EN0); |
116 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + EN0), | 173 | ipi_en0_regs[3] = (void *) |
117 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + EN0), | 174 | (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + EN0); |
118 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + EN0), | 175 | ipi_en0_regs[4] = (void *) |
119 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + EN0), | 176 | (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + EN0); |
120 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + EN0), | 177 | ipi_en0_regs[5] = (void *) |
121 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + EN0), | 178 | (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + EN0); |
122 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + EN0), | 179 | ipi_en0_regs[6] = (void *) |
123 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + EN0), | 180 | (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + EN0); |
124 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + EN0), | 181 | ipi_en0_regs[7] = (void *) |
125 | }; | 182 | (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + EN0); |
183 | ipi_en0_regs[8] = (void *) | ||
184 | (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + EN0); | ||
185 | ipi_en0_regs[9] = (void *) | ||
186 | (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + EN0); | ||
187 | ipi_en0_regs[10] = (void *) | ||
188 | (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + EN0); | ||
189 | ipi_en0_regs[11] = (void *) | ||
190 | (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + EN0); | ||
191 | ipi_en0_regs[12] = (void *) | ||
192 | (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + EN0); | ||
193 | ipi_en0_regs[13] = (void *) | ||
194 | (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + EN0); | ||
195 | ipi_en0_regs[14] = (void *) | ||
196 | (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + EN0); | ||
197 | ipi_en0_regs[15] = (void *) | ||
198 | (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + EN0); | ||
199 | } | ||
126 | 200 | ||
127 | static void *ipi_mailbox_buf[] = { | 201 | static void ipi_mailbox_buf_init(void) |
128 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + BUF), | 202 | { |
129 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + BUF), | 203 | ipi_mailbox_buf[0] = (void *) |
130 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + BUF), | 204 | (SMP_CORE_GROUP0_BASE + SMP_CORE0_OFFSET + BUF); |
131 | (void *)(SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + BUF), | 205 | ipi_mailbox_buf[1] = (void *) |
132 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + BUF), | 206 | (SMP_CORE_GROUP0_BASE + SMP_CORE1_OFFSET + BUF); |
133 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + BUF), | 207 | ipi_mailbox_buf[2] = (void *) |
134 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + BUF), | 208 | (SMP_CORE_GROUP0_BASE + SMP_CORE2_OFFSET + BUF); |
135 | (void *)(SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + BUF), | 209 | ipi_mailbox_buf[3] = (void *) |
136 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + BUF), | 210 | (SMP_CORE_GROUP0_BASE + SMP_CORE3_OFFSET + BUF); |
137 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + BUF), | 211 | ipi_mailbox_buf[4] = (void *) |
138 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + BUF), | 212 | (SMP_CORE_GROUP1_BASE + SMP_CORE0_OFFSET + BUF); |
139 | (void *)(SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + BUF), | 213 | ipi_mailbox_buf[5] = (void *) |
140 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + BUF), | 214 | (SMP_CORE_GROUP1_BASE + SMP_CORE1_OFFSET + BUF); |
141 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + BUF), | 215 | ipi_mailbox_buf[6] = (void *) |
142 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + BUF), | 216 | (SMP_CORE_GROUP1_BASE + SMP_CORE2_OFFSET + BUF); |
143 | (void *)(SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + BUF), | 217 | ipi_mailbox_buf[7] = (void *) |
144 | }; | 218 | (SMP_CORE_GROUP1_BASE + SMP_CORE3_OFFSET + BUF); |
219 | ipi_mailbox_buf[8] = (void *) | ||
220 | (SMP_CORE_GROUP2_BASE + SMP_CORE0_OFFSET + BUF); | ||
221 | ipi_mailbox_buf[9] = (void *) | ||
222 | (SMP_CORE_GROUP2_BASE + SMP_CORE1_OFFSET + BUF); | ||
223 | ipi_mailbox_buf[10] = (void *) | ||
224 | (SMP_CORE_GROUP2_BASE + SMP_CORE2_OFFSET + BUF); | ||
225 | ipi_mailbox_buf[11] = (void *) | ||
226 | (SMP_CORE_GROUP2_BASE + SMP_CORE3_OFFSET + BUF); | ||
227 | ipi_mailbox_buf[12] = (void *) | ||
228 | (SMP_CORE_GROUP3_BASE + SMP_CORE0_OFFSET + BUF); | ||
229 | ipi_mailbox_buf[13] = (void *) | ||
230 | (SMP_CORE_GROUP3_BASE + SMP_CORE1_OFFSET + BUF); | ||
231 | ipi_mailbox_buf[14] = (void *) | ||
232 | (SMP_CORE_GROUP3_BASE + SMP_CORE2_OFFSET + BUF); | ||
233 | ipi_mailbox_buf[15] = (void *) | ||
234 | (SMP_CORE_GROUP3_BASE + SMP_CORE3_OFFSET + BUF); | ||
235 | } | ||
145 | 236 | ||
146 | /* | 237 | /* |
147 | * Simple enough, just poke the appropriate ipi register | 238 | * Simple enough, just poke the appropriate ipi register |
@@ -203,6 +294,8 @@ static void loongson3_init_secondary(void) | |||
203 | for (i = 0; i < loongson_sysconf.nr_cpus; i++) | 294 | for (i = 0; i < loongson_sysconf.nr_cpus; i++) |
204 | loongson3_ipi_write32(0xffffffff, ipi_en0_regs[i]); | 295 | loongson3_ipi_write32(0xffffffff, ipi_en0_regs[i]); |
205 | 296 | ||
297 | cpu_data[cpu].package = cpu / loongson_sysconf.cores_per_package; | ||
298 | cpu_data[cpu].core = cpu % loongson_sysconf.cores_per_package; | ||
206 | per_cpu(cpu_state, cpu) = CPU_ONLINE; | 299 | per_cpu(cpu_state, cpu) = CPU_ONLINE; |
207 | 300 | ||
208 | i = 0; | 301 | i = 0; |
@@ -246,6 +339,11 @@ static void __init loongson3_smp_setup(void) | |||
246 | __cpu_number_map[i] = ++num; | 339 | __cpu_number_map[i] = ++num; |
247 | __cpu_logical_map[num] = i; | 340 | __cpu_logical_map[num] = i; |
248 | } | 341 | } |
342 | ipi_set0_regs_init(); | ||
343 | ipi_clear0_regs_init(); | ||
344 | ipi_status0_regs_init(); | ||
345 | ipi_en0_regs_init(); | ||
346 | ipi_mailbox_buf_init(); | ||
249 | pr_info("Detected %i available secondary CPU(s)\n", num); | 347 | pr_info("Detected %i available secondary CPU(s)\n", num); |
250 | } | 348 | } |
251 | 349 | ||
@@ -313,7 +411,7 @@ static void loongson3_cpu_die(unsigned int cpu) | |||
313 | * flush all L1 entries at first. Then, another core (usually Core 0) can | 411 | * flush all L1 entries at first. Then, another core (usually Core 0) can |
314 | * safely disable the clock of the target core. loongson3_play_dead() is | 412 | * safely disable the clock of the target core. loongson3_play_dead() is |
315 | * called via CKSEG1 (uncached and unmmaped) */ | 413 | * called via CKSEG1 (uncached and unmmaped) */ |
316 | static void loongson3_play_dead(int *state_addr) | 414 | static void loongson3a_play_dead(int *state_addr) |
317 | { | 415 | { |
318 | register int val; | 416 | register int val; |
319 | register long cpuid, core, node, count; | 417 | register long cpuid, core, node, count; |
@@ -375,6 +473,70 @@ static void loongson3_play_dead(int *state_addr) | |||
375 | : "a1"); | 473 | : "a1"); |
376 | } | 474 | } |
377 | 475 | ||
476 | static void loongson3b_play_dead(int *state_addr) | ||
477 | { | ||
478 | register int val; | ||
479 | register long cpuid, core, node, count; | ||
480 | register void *addr, *base, *initfunc; | ||
481 | |||
482 | __asm__ __volatile__( | ||
483 | " .set push \n" | ||
484 | " .set noreorder \n" | ||
485 | " li %[addr], 0x80000000 \n" /* KSEG0 */ | ||
486 | "1: cache 0, 0(%[addr]) \n" /* flush L1 ICache */ | ||
487 | " cache 0, 1(%[addr]) \n" | ||
488 | " cache 0, 2(%[addr]) \n" | ||
489 | " cache 0, 3(%[addr]) \n" | ||
490 | " cache 1, 0(%[addr]) \n" /* flush L1 DCache */ | ||
491 | " cache 1, 1(%[addr]) \n" | ||
492 | " cache 1, 2(%[addr]) \n" | ||
493 | " cache 1, 3(%[addr]) \n" | ||
494 | " addiu %[sets], %[sets], -1 \n" | ||
495 | " bnez %[sets], 1b \n" | ||
496 | " addiu %[addr], %[addr], 0x20 \n" | ||
497 | " li %[val], 0x7 \n" /* *state_addr = CPU_DEAD; */ | ||
498 | " sw %[val], (%[state_addr]) \n" | ||
499 | " sync \n" | ||
500 | " cache 21, (%[state_addr]) \n" /* flush entry of *state_addr */ | ||
501 | " .set pop \n" | ||
502 | : [addr] "=&r" (addr), [val] "=&r" (val) | ||
503 | : [state_addr] "r" (state_addr), | ||
504 | [sets] "r" (cpu_data[smp_processor_id()].dcache.sets)); | ||
505 | |||
506 | __asm__ __volatile__( | ||
507 | " .set push \n" | ||
508 | " .set noreorder \n" | ||
509 | " .set mips64 \n" | ||
510 | " mfc0 %[cpuid], $15, 1 \n" | ||
511 | " andi %[cpuid], 0x3ff \n" | ||
512 | " dli %[base], 0x900000003ff01000 \n" | ||
513 | " andi %[core], %[cpuid], 0x3 \n" | ||
514 | " sll %[core], 8 \n" /* get core id */ | ||
515 | " or %[base], %[base], %[core] \n" | ||
516 | " andi %[node], %[cpuid], 0xc \n" | ||
517 | " dsll %[node], 42 \n" /* get node id */ | ||
518 | " or %[base], %[base], %[node] \n" | ||
519 | " dsrl %[node], 30 \n" /* 15:14 */ | ||
520 | " or %[base], %[base], %[node] \n" | ||
521 | "1: li %[count], 0x100 \n" /* wait for init loop */ | ||
522 | "2: bnez %[count], 2b \n" /* limit mailbox access */ | ||
523 | " addiu %[count], -1 \n" | ||
524 | " ld %[initfunc], 0x20(%[base]) \n" /* get PC via mailbox */ | ||
525 | " beqz %[initfunc], 1b \n" | ||
526 | " nop \n" | ||
527 | " ld $sp, 0x28(%[base]) \n" /* get SP via mailbox */ | ||
528 | " ld $gp, 0x30(%[base]) \n" /* get GP via mailbox */ | ||
529 | " ld $a1, 0x38(%[base]) \n" | ||
530 | " jr %[initfunc] \n" /* jump to initial PC */ | ||
531 | " nop \n" | ||
532 | " .set pop \n" | ||
533 | : [core] "=&r" (core), [node] "=&r" (node), | ||
534 | [base] "=&r" (base), [cpuid] "=&r" (cpuid), | ||
535 | [count] "=&r" (count), [initfunc] "=&r" (initfunc) | ||
536 | : /* No Input */ | ||
537 | : "a1"); | ||
538 | } | ||
539 | |||
378 | void play_dead(void) | 540 | void play_dead(void) |
379 | { | 541 | { |
380 | int *state_addr; | 542 | int *state_addr; |
@@ -382,13 +544,48 @@ void play_dead(void) | |||
382 | void (*play_dead_at_ckseg1)(int *); | 544 | void (*play_dead_at_ckseg1)(int *); |
383 | 545 | ||
384 | idle_task_exit(); | 546 | idle_task_exit(); |
385 | play_dead_at_ckseg1 = | 547 | switch (loongson_sysconf.cputype) { |
386 | (void *)CKSEG1ADDR((unsigned long)loongson3_play_dead); | 548 | case Loongson_3A: |
549 | default: | ||
550 | play_dead_at_ckseg1 = | ||
551 | (void *)CKSEG1ADDR((unsigned long)loongson3a_play_dead); | ||
552 | break; | ||
553 | case Loongson_3B: | ||
554 | play_dead_at_ckseg1 = | ||
555 | (void *)CKSEG1ADDR((unsigned long)loongson3b_play_dead); | ||
556 | break; | ||
557 | } | ||
387 | state_addr = &per_cpu(cpu_state, cpu); | 558 | state_addr = &per_cpu(cpu_state, cpu); |
388 | mb(); | 559 | mb(); |
389 | play_dead_at_ckseg1(state_addr); | 560 | play_dead_at_ckseg1(state_addr); |
390 | } | 561 | } |
391 | 562 | ||
563 | void loongson3_disable_clock(int cpu) | ||
564 | { | ||
565 | uint64_t core_id = cpu_data[cpu].core; | ||
566 | uint64_t package_id = cpu_data[cpu].package; | ||
567 | |||
568 | if (loongson_sysconf.cputype == Loongson_3A) { | ||
569 | LOONGSON_CHIPCFG(package_id) &= ~(1 << (12 + core_id)); | ||
570 | } else if (loongson_sysconf.cputype == Loongson_3B) { | ||
571 | if (!cpuhotplug_workaround) | ||
572 | LOONGSON_FREQCTRL(package_id) &= ~(1 << (core_id * 4 + 3)); | ||
573 | } | ||
574 | } | ||
575 | |||
576 | void loongson3_enable_clock(int cpu) | ||
577 | { | ||
578 | uint64_t core_id = cpu_data[cpu].core; | ||
579 | uint64_t package_id = cpu_data[cpu].package; | ||
580 | |||
581 | if (loongson_sysconf.cputype == Loongson_3A) { | ||
582 | LOONGSON_CHIPCFG(package_id) |= 1 << (12 + core_id); | ||
583 | } else if (loongson_sysconf.cputype == Loongson_3B) { | ||
584 | if (!cpuhotplug_workaround) | ||
585 | LOONGSON_FREQCTRL(package_id) |= 1 << (core_id * 4 + 3); | ||
586 | } | ||
587 | } | ||
588 | |||
392 | #define CPU_POST_DEAD_FROZEN (CPU_POST_DEAD | CPU_TASKS_FROZEN) | 589 | #define CPU_POST_DEAD_FROZEN (CPU_POST_DEAD | CPU_TASKS_FROZEN) |
393 | static int loongson3_cpu_callback(struct notifier_block *nfb, | 590 | static int loongson3_cpu_callback(struct notifier_block *nfb, |
394 | unsigned long action, void *hcpu) | 591 | unsigned long action, void *hcpu) |
@@ -399,12 +596,12 @@ static int loongson3_cpu_callback(struct notifier_block *nfb, | |||
399 | case CPU_POST_DEAD: | 596 | case CPU_POST_DEAD: |
400 | case CPU_POST_DEAD_FROZEN: | 597 | case CPU_POST_DEAD_FROZEN: |
401 | pr_info("Disable clock for CPU#%d\n", cpu); | 598 | pr_info("Disable clock for CPU#%d\n", cpu); |
402 | LOONGSON_CHIPCFG0 &= ~(1 << (12 + cpu)); | 599 | loongson3_disable_clock(cpu); |
403 | break; | 600 | break; |
404 | case CPU_UP_PREPARE: | 601 | case CPU_UP_PREPARE: |
405 | case CPU_UP_PREPARE_FROZEN: | 602 | case CPU_UP_PREPARE_FROZEN: |
406 | pr_info("Enable clock for CPU#%d\n", cpu); | 603 | pr_info("Enable clock for CPU#%d\n", cpu); |
407 | LOONGSON_CHIPCFG0 |= 1 << (12 + cpu); | 604 | loongson3_enable_clock(cpu); |
408 | break; | 605 | break; |
409 | } | 606 | } |
410 | 607 | ||
diff --git a/arch/mips/loongson/loongson-3/smp.h b/arch/mips/loongson/loongson-3/smp.h index 3453e8c4f2f0..d98ff654b7d7 100644 --- a/arch/mips/loongson/loongson-3/smp.h +++ b/arch/mips/loongson/loongson-3/smp.h | |||
@@ -1,29 +1,30 @@ | |||
1 | #ifndef __LOONGSON_SMP_H_ | 1 | #ifndef __LOONGSON_SMP_H_ |
2 | #define __LOONGSON_SMP_H_ | 2 | #define __LOONGSON_SMP_H_ |
3 | 3 | ||
4 | /* for Loongson-3A smp support */ | 4 | /* for Loongson-3 smp support */ |
5 | extern unsigned long long smp_group[4]; | ||
5 | 6 | ||
6 | /* 4 groups(nodes) in maximum in numa case */ | 7 | /* 4 groups(nodes) in maximum in numa case */ |
7 | #define SMP_CORE_GROUP0_BASE 0x900000003ff01000 | 8 | #define SMP_CORE_GROUP0_BASE (smp_group[0]) |
8 | #define SMP_CORE_GROUP1_BASE 0x900010003ff01000 | 9 | #define SMP_CORE_GROUP1_BASE (smp_group[1]) |
9 | #define SMP_CORE_GROUP2_BASE 0x900020003ff01000 | 10 | #define SMP_CORE_GROUP2_BASE (smp_group[2]) |
10 | #define SMP_CORE_GROUP3_BASE 0x900030003ff01000 | 11 | #define SMP_CORE_GROUP3_BASE (smp_group[3]) |
11 | 12 | ||
12 | /* 4 cores in each group(node) */ | 13 | /* 4 cores in each group(node) */ |
13 | #define SMP_CORE0_OFFSET 0x000 | 14 | #define SMP_CORE0_OFFSET 0x000 |
14 | #define SMP_CORE1_OFFSET 0x100 | 15 | #define SMP_CORE1_OFFSET 0x100 |
15 | #define SMP_CORE2_OFFSET 0x200 | 16 | #define SMP_CORE2_OFFSET 0x200 |
16 | #define SMP_CORE3_OFFSET 0x300 | 17 | #define SMP_CORE3_OFFSET 0x300 |
17 | 18 | ||
18 | /* ipi registers offsets */ | 19 | /* ipi registers offsets */ |
19 | #define STATUS0 0x00 | 20 | #define STATUS0 0x00 |
20 | #define EN0 0x04 | 21 | #define EN0 0x04 |
21 | #define SET0 0x08 | 22 | #define SET0 0x08 |
22 | #define CLEAR0 0x0c | 23 | #define CLEAR0 0x0c |
23 | #define STATUS1 0x10 | 24 | #define STATUS1 0x10 |
24 | #define MASK1 0x14 | 25 | #define MASK1 0x14 |
25 | #define SET1 0x18 | 26 | #define SET1 0x18 |
26 | #define CLEAR1 0x1c | 27 | #define CLEAR1 0x1c |
27 | #define BUF 0x20 | 28 | #define BUF 0x20 |
28 | 29 | ||
29 | #endif | 30 | #endif |
diff --git a/arch/mips/math-emu/cp1emu.c b/arch/mips/math-emu/cp1emu.c index 736c17a226e9..bf0fc6b16ad9 100644 --- a/arch/mips/math-emu/cp1emu.c +++ b/arch/mips/math-emu/cp1emu.c | |||
@@ -1827,7 +1827,7 @@ dcopuop: | |||
1827 | case -1: | 1827 | case -1: |
1828 | 1828 | ||
1829 | if (cpu_has_mips_4_5_r) | 1829 | if (cpu_has_mips_4_5_r) |
1830 | cbit = fpucondbit[MIPSInst_RT(ir) >> 2]; | 1830 | cbit = fpucondbit[MIPSInst_FD(ir) >> 2]; |
1831 | else | 1831 | else |
1832 | cbit = FPU_CSR_COND; | 1832 | cbit = FPU_CSR_COND; |
1833 | if (rv.w) | 1833 | if (rv.w) |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index f2e8302fa70f..fbcd8674ff1d 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -1230,19 +1230,19 @@ static void probe_pcache(void) | |||
1230 | case CPU_R14000: | 1230 | case CPU_R14000: |
1231 | break; | 1231 | break; |
1232 | 1232 | ||
1233 | case CPU_74K: | ||
1234 | case CPU_1074K: | ||
1235 | alias_74k_erratum(c); | ||
1236 | /* Fall through. */ | ||
1233 | case CPU_M14KC: | 1237 | case CPU_M14KC: |
1234 | case CPU_M14KEC: | 1238 | case CPU_M14KEC: |
1235 | case CPU_24K: | 1239 | case CPU_24K: |
1236 | case CPU_34K: | 1240 | case CPU_34K: |
1237 | case CPU_74K: | ||
1238 | case CPU_1004K: | 1241 | case CPU_1004K: |
1239 | case CPU_1074K: | ||
1240 | case CPU_INTERAPTIV: | 1242 | case CPU_INTERAPTIV: |
1241 | case CPU_P5600: | 1243 | case CPU_P5600: |
1242 | case CPU_PROAPTIV: | 1244 | case CPU_PROAPTIV: |
1243 | case CPU_M5150: | 1245 | case CPU_M5150: |
1244 | if ((c->cputype == CPU_74K) || (c->cputype == CPU_1074K)) | ||
1245 | alias_74k_erratum(c); | ||
1246 | if (!(read_c0_config7() & MIPS_CONF7_IAR) && | 1246 | if (!(read_c0_config7() & MIPS_CONF7_IAR) && |
1247 | (c->icache.waysize > PAGE_SIZE)) | 1247 | (c->icache.waysize > PAGE_SIZE)) |
1248 | c->icache.flags |= MIPS_CACHE_ALIASES; | 1248 | c->icache.flags |= MIPS_CACHE_ALIASES; |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index 6e4413330e36..571aab064936 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -325,6 +325,38 @@ static inline void mem_init_free_highmem(void) | |||
325 | #endif | 325 | #endif |
326 | } | 326 | } |
327 | 327 | ||
328 | unsigned __weak platform_maar_init(unsigned num_maars) | ||
329 | { | ||
330 | return 0; | ||
331 | } | ||
332 | |||
333 | static void maar_init(void) | ||
334 | { | ||
335 | unsigned num_maars, used, i; | ||
336 | |||
337 | if (!cpu_has_maar) | ||
338 | return; | ||
339 | |||
340 | /* Detect the number of MAARs */ | ||
341 | write_c0_maari(~0); | ||
342 | back_to_back_c0_hazard(); | ||
343 | num_maars = read_c0_maari() + 1; | ||
344 | |||
345 | /* MAARs should be in pairs */ | ||
346 | WARN_ON(num_maars % 2); | ||
347 | |||
348 | /* Configure the required MAARs */ | ||
349 | used = platform_maar_init(num_maars / 2); | ||
350 | |||
351 | /* Disable any further MAARs */ | ||
352 | for (i = (used * 2); i < num_maars; i++) { | ||
353 | write_c0_maari(i); | ||
354 | back_to_back_c0_hazard(); | ||
355 | write_c0_maar(0); | ||
356 | back_to_back_c0_hazard(); | ||
357 | } | ||
358 | } | ||
359 | |||
328 | void __init mem_init(void) | 360 | void __init mem_init(void) |
329 | { | 361 | { |
330 | #ifdef CONFIG_HIGHMEM | 362 | #ifdef CONFIG_HIGHMEM |
@@ -337,6 +369,7 @@ void __init mem_init(void) | |||
337 | #endif | 369 | #endif |
338 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); | 370 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); |
339 | 371 | ||
372 | maar_init(); | ||
340 | free_all_bootmem(); | 373 | free_all_bootmem(); |
341 | setup_zero_pages(); /* Setup zeroed pages. */ | 374 | setup_zero_pages(); /* Setup zeroed pages. */ |
342 | mem_init_free_highmem(); | 375 | mem_init_free_highmem(); |
diff --git a/arch/mips/mm/tlb-r3k.c b/arch/mips/mm/tlb-r3k.c index d657493ef561..4094bbd42adf 100644 --- a/arch/mips/mm/tlb-r3k.c +++ b/arch/mips/mm/tlb-r3k.c | |||
@@ -158,7 +158,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
158 | { | 158 | { |
159 | int cpu = smp_processor_id(); | 159 | int cpu = smp_processor_id(); |
160 | 160 | ||
161 | if (!vma || cpu_context(cpu, vma->vm_mm) != 0) { | 161 | if (cpu_context(cpu, vma->vm_mm) != 0) { |
162 | unsigned long flags; | 162 | unsigned long flags; |
163 | int oldpid, newpid, idx; | 163 | int oldpid, newpid, idx; |
164 | 164 | ||
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index 3914e27456f2..fa6ebd4bc9e9 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -57,6 +57,7 @@ void local_flush_tlb_all(void) | |||
57 | local_irq_save(flags); | 57 | local_irq_save(flags); |
58 | /* Save old context and create impossible VPN2 value */ | 58 | /* Save old context and create impossible VPN2 value */ |
59 | old_ctx = read_c0_entryhi(); | 59 | old_ctx = read_c0_entryhi(); |
60 | htw_stop(); | ||
60 | write_c0_entrylo0(0); | 61 | write_c0_entrylo0(0); |
61 | write_c0_entrylo1(0); | 62 | write_c0_entrylo1(0); |
62 | 63 | ||
@@ -90,6 +91,7 @@ void local_flush_tlb_all(void) | |||
90 | } | 91 | } |
91 | tlbw_use_hazard(); | 92 | tlbw_use_hazard(); |
92 | write_c0_entryhi(old_ctx); | 93 | write_c0_entryhi(old_ctx); |
94 | htw_start(); | ||
93 | flush_itlb(); | 95 | flush_itlb(); |
94 | local_irq_restore(flags); | 96 | local_irq_restore(flags); |
95 | } | 97 | } |
@@ -131,6 +133,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
131 | int oldpid = read_c0_entryhi(); | 133 | int oldpid = read_c0_entryhi(); |
132 | int newpid = cpu_asid(cpu, mm); | 134 | int newpid = cpu_asid(cpu, mm); |
133 | 135 | ||
136 | htw_stop(); | ||
134 | while (start < end) { | 137 | while (start < end) { |
135 | int idx; | 138 | int idx; |
136 | 139 | ||
@@ -151,6 +154,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
151 | } | 154 | } |
152 | tlbw_use_hazard(); | 155 | tlbw_use_hazard(); |
153 | write_c0_entryhi(oldpid); | 156 | write_c0_entryhi(oldpid); |
157 | htw_start(); | ||
154 | } else { | 158 | } else { |
155 | drop_mmu_context(mm, cpu); | 159 | drop_mmu_context(mm, cpu); |
156 | } | 160 | } |
@@ -174,6 +178,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | |||
174 | start &= (PAGE_MASK << 1); | 178 | start &= (PAGE_MASK << 1); |
175 | end += ((PAGE_SIZE << 1) - 1); | 179 | end += ((PAGE_SIZE << 1) - 1); |
176 | end &= (PAGE_MASK << 1); | 180 | end &= (PAGE_MASK << 1); |
181 | htw_stop(); | ||
177 | 182 | ||
178 | while (start < end) { | 183 | while (start < end) { |
179 | int idx; | 184 | int idx; |
@@ -195,6 +200,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | |||
195 | } | 200 | } |
196 | tlbw_use_hazard(); | 201 | tlbw_use_hazard(); |
197 | write_c0_entryhi(pid); | 202 | write_c0_entryhi(pid); |
203 | htw_start(); | ||
198 | } else { | 204 | } else { |
199 | local_flush_tlb_all(); | 205 | local_flush_tlb_all(); |
200 | } | 206 | } |
@@ -214,6 +220,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
214 | page &= (PAGE_MASK << 1); | 220 | page &= (PAGE_MASK << 1); |
215 | local_irq_save(flags); | 221 | local_irq_save(flags); |
216 | oldpid = read_c0_entryhi(); | 222 | oldpid = read_c0_entryhi(); |
223 | htw_stop(); | ||
217 | write_c0_entryhi(page | newpid); | 224 | write_c0_entryhi(page | newpid); |
218 | mtc0_tlbw_hazard(); | 225 | mtc0_tlbw_hazard(); |
219 | tlb_probe(); | 226 | tlb_probe(); |
@@ -231,6 +238,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
231 | 238 | ||
232 | finish: | 239 | finish: |
233 | write_c0_entryhi(oldpid); | 240 | write_c0_entryhi(oldpid); |
241 | htw_start(); | ||
234 | flush_itlb_vm(vma); | 242 | flush_itlb_vm(vma); |
235 | local_irq_restore(flags); | 243 | local_irq_restore(flags); |
236 | } | 244 | } |
@@ -247,6 +255,7 @@ void local_flush_tlb_one(unsigned long page) | |||
247 | 255 | ||
248 | local_irq_save(flags); | 256 | local_irq_save(flags); |
249 | oldpid = read_c0_entryhi(); | 257 | oldpid = read_c0_entryhi(); |
258 | htw_stop(); | ||
250 | page &= (PAGE_MASK << 1); | 259 | page &= (PAGE_MASK << 1); |
251 | write_c0_entryhi(page); | 260 | write_c0_entryhi(page); |
252 | mtc0_tlbw_hazard(); | 261 | mtc0_tlbw_hazard(); |
@@ -263,6 +272,7 @@ void local_flush_tlb_one(unsigned long page) | |||
263 | tlbw_use_hazard(); | 272 | tlbw_use_hazard(); |
264 | } | 273 | } |
265 | write_c0_entryhi(oldpid); | 274 | write_c0_entryhi(oldpid); |
275 | htw_start(); | ||
266 | flush_itlb(); | 276 | flush_itlb(); |
267 | local_irq_restore(flags); | 277 | local_irq_restore(flags); |
268 | } | 278 | } |
@@ -351,6 +361,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
351 | local_irq_save(flags); | 361 | local_irq_save(flags); |
352 | /* Save old context and create impossible VPN2 value */ | 362 | /* Save old context and create impossible VPN2 value */ |
353 | old_ctx = read_c0_entryhi(); | 363 | old_ctx = read_c0_entryhi(); |
364 | htw_stop(); | ||
354 | old_pagemask = read_c0_pagemask(); | 365 | old_pagemask = read_c0_pagemask(); |
355 | wired = read_c0_wired(); | 366 | wired = read_c0_wired(); |
356 | write_c0_wired(wired + 1); | 367 | write_c0_wired(wired + 1); |
@@ -366,6 +377,7 @@ void add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
366 | 377 | ||
367 | write_c0_entryhi(old_ctx); | 378 | write_c0_entryhi(old_ctx); |
368 | tlbw_use_hazard(); /* What is the hazard here? */ | 379 | tlbw_use_hazard(); /* What is the hazard here? */ |
380 | htw_start(); | ||
369 | write_c0_pagemask(old_pagemask); | 381 | write_c0_pagemask(old_pagemask); |
370 | local_flush_tlb_all(); | 382 | local_flush_tlb_all(); |
371 | local_irq_restore(flags); | 383 | local_irq_restore(flags); |
@@ -391,6 +403,51 @@ int __init has_transparent_hugepage(void) | |||
391 | 403 | ||
392 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | 404 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ |
393 | 405 | ||
406 | /* | ||
407 | * Used for loading TLB entries before trap_init() has started, when we | ||
408 | * don't actually want to add a wired entry which remains throughout the | ||
409 | * lifetime of the system | ||
410 | */ | ||
411 | |||
412 | int temp_tlb_entry __cpuinitdata; | ||
413 | |||
414 | __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, | ||
415 | unsigned long entryhi, unsigned long pagemask) | ||
416 | { | ||
417 | int ret = 0; | ||
418 | unsigned long flags; | ||
419 | unsigned long wired; | ||
420 | unsigned long old_pagemask; | ||
421 | unsigned long old_ctx; | ||
422 | |||
423 | local_irq_save(flags); | ||
424 | /* Save old context and create impossible VPN2 value */ | ||
425 | old_ctx = read_c0_entryhi(); | ||
426 | old_pagemask = read_c0_pagemask(); | ||
427 | wired = read_c0_wired(); | ||
428 | if (--temp_tlb_entry < wired) { | ||
429 | printk(KERN_WARNING | ||
430 | "No TLB space left for add_temporary_entry\n"); | ||
431 | ret = -ENOSPC; | ||
432 | goto out; | ||
433 | } | ||
434 | |||
435 | write_c0_index(temp_tlb_entry); | ||
436 | write_c0_pagemask(pagemask); | ||
437 | write_c0_entryhi(entryhi); | ||
438 | write_c0_entrylo0(entrylo0); | ||
439 | write_c0_entrylo1(entrylo1); | ||
440 | mtc0_tlbw_hazard(); | ||
441 | tlb_write_indexed(); | ||
442 | tlbw_use_hazard(); | ||
443 | |||
444 | write_c0_entryhi(old_ctx); | ||
445 | write_c0_pagemask(old_pagemask); | ||
446 | out: | ||
447 | local_irq_restore(flags); | ||
448 | return ret; | ||
449 | } | ||
450 | |||
394 | static int ntlb; | 451 | static int ntlb; |
395 | static int __init set_ntlb(char *str) | 452 | static int __init set_ntlb(char *str) |
396 | { | 453 | { |
@@ -431,6 +488,8 @@ static void r4k_tlb_configure(void) | |||
431 | write_c0_pagegrain(pg); | 488 | write_c0_pagegrain(pg); |
432 | } | 489 | } |
433 | 490 | ||
491 | temp_tlb_entry = current_cpu_data.tlbsize - 1; | ||
492 | |||
434 | /* From this point on the ARC firmware is dead. */ | 493 | /* From this point on the ARC firmware is dead. */ |
435 | local_flush_tlb_all(); | 494 | local_flush_tlb_all(); |
436 | 495 | ||
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index e80e10bafc83..a08dd53a1cc5 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -429,6 +429,7 @@ static void build_r3000_tlb_refill_handler(void) | |||
429 | (unsigned int)(p - tlb_handler)); | 429 | (unsigned int)(p - tlb_handler)); |
430 | 430 | ||
431 | memcpy((void *)ebase, tlb_handler, 0x80); | 431 | memcpy((void *)ebase, tlb_handler, 0x80); |
432 | local_flush_icache_range(ebase, ebase + 0x80); | ||
432 | 433 | ||
433 | dump_handler("r3000_tlb_refill", (u32 *)ebase, 32); | 434 | dump_handler("r3000_tlb_refill", (u32 *)ebase, 32); |
434 | } | 435 | } |
@@ -1299,6 +1300,7 @@ static void build_r4000_tlb_refill_handler(void) | |||
1299 | } | 1300 | } |
1300 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT | 1301 | #ifdef CONFIG_MIPS_HUGE_TLB_SUPPORT |
1301 | uasm_l_tlb_huge_update(&l, p); | 1302 | uasm_l_tlb_huge_update(&l, p); |
1303 | UASM_i_LW(&p, K0, 0, K1); | ||
1302 | build_huge_update_entries(&p, htlb_info.huge_pte, K1); | 1304 | build_huge_update_entries(&p, htlb_info.huge_pte, K1); |
1303 | build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random, | 1305 | build_huge_tlb_write_entry(&p, &l, &r, K0, tlb_random, |
1304 | htlb_info.restore_scratch); | 1306 | htlb_info.restore_scratch); |
@@ -1415,6 +1417,7 @@ static void build_r4000_tlb_refill_handler(void) | |||
1415 | final_len); | 1417 | final_len); |
1416 | 1418 | ||
1417 | memcpy((void *)ebase, final_handler, 0x100); | 1419 | memcpy((void *)ebase, final_handler, 0x100); |
1420 | local_flush_icache_range(ebase, ebase + 0x100); | ||
1418 | 1421 | ||
1419 | dump_handler("r4000_tlb_refill", (u32 *)ebase, 64); | 1422 | dump_handler("r4000_tlb_refill", (u32 *)ebase, 64); |
1420 | } | 1423 | } |
@@ -1919,7 +1922,7 @@ static void build_r4000_tlb_load_handler(void) | |||
1919 | if (m4kc_tlbp_war()) | 1922 | if (m4kc_tlbp_war()) |
1920 | build_tlb_probe_entry(&p); | 1923 | build_tlb_probe_entry(&p); |
1921 | 1924 | ||
1922 | if (cpu_has_rixi) { | 1925 | if (cpu_has_rixi && !cpu_has_rixiex) { |
1923 | /* | 1926 | /* |
1924 | * If the page is not _PAGE_VALID, RI or XI could not | 1927 | * If the page is not _PAGE_VALID, RI or XI could not |
1925 | * have triggered it. Skip the expensive test.. | 1928 | * have triggered it. Skip the expensive test.. |
@@ -1986,7 +1989,7 @@ static void build_r4000_tlb_load_handler(void) | |||
1986 | build_pte_present(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbl); | 1989 | build_pte_present(&p, &r, wr.r1, wr.r2, wr.r3, label_nopage_tlbl); |
1987 | build_tlb_probe_entry(&p); | 1990 | build_tlb_probe_entry(&p); |
1988 | 1991 | ||
1989 | if (cpu_has_rixi) { | 1992 | if (cpu_has_rixi && !cpu_has_rixiex) { |
1990 | /* | 1993 | /* |
1991 | * If the page is not _PAGE_VALID, RI or XI could not | 1994 | * If the page is not _PAGE_VALID, RI or XI could not |
1992 | * have triggered it. Skip the expensive test.. | 1995 | * have triggered it. Skip the expensive test.. |
@@ -2194,6 +2197,94 @@ static void flush_tlb_handlers(void) | |||
2194 | (unsigned long)tlbmiss_handler_setup_pgd_end); | 2197 | (unsigned long)tlbmiss_handler_setup_pgd_end); |
2195 | } | 2198 | } |
2196 | 2199 | ||
2200 | static void print_htw_config(void) | ||
2201 | { | ||
2202 | unsigned long config; | ||
2203 | unsigned int pwctl; | ||
2204 | const int field = 2 * sizeof(unsigned long); | ||
2205 | |||
2206 | config = read_c0_pwfield(); | ||
2207 | pr_debug("PWField (0x%0*lx): GDI: 0x%02lx UDI: 0x%02lx MDI: 0x%02lx PTI: 0x%02lx PTEI: 0x%02lx\n", | ||
2208 | field, config, | ||
2209 | (config & MIPS_PWFIELD_GDI_MASK) >> MIPS_PWFIELD_GDI_SHIFT, | ||
2210 | (config & MIPS_PWFIELD_UDI_MASK) >> MIPS_PWFIELD_UDI_SHIFT, | ||
2211 | (config & MIPS_PWFIELD_MDI_MASK) >> MIPS_PWFIELD_MDI_SHIFT, | ||
2212 | (config & MIPS_PWFIELD_PTI_MASK) >> MIPS_PWFIELD_PTI_SHIFT, | ||
2213 | (config & MIPS_PWFIELD_PTEI_MASK) >> MIPS_PWFIELD_PTEI_SHIFT); | ||
2214 | |||
2215 | config = read_c0_pwsize(); | ||
2216 | pr_debug("PWSize (0x%0*lx): GDW: 0x%02lx UDW: 0x%02lx MDW: 0x%02lx PTW: 0x%02lx PTEW: 0x%02lx\n", | ||
2217 | field, config, | ||
2218 | (config & MIPS_PWSIZE_GDW_MASK) >> MIPS_PWSIZE_GDW_SHIFT, | ||
2219 | (config & MIPS_PWSIZE_UDW_MASK) >> MIPS_PWSIZE_UDW_SHIFT, | ||
2220 | (config & MIPS_PWSIZE_MDW_MASK) >> MIPS_PWSIZE_MDW_SHIFT, | ||
2221 | (config & MIPS_PWSIZE_PTW_MASK) >> MIPS_PWSIZE_PTW_SHIFT, | ||
2222 | (config & MIPS_PWSIZE_PTEW_MASK) >> MIPS_PWSIZE_PTEW_SHIFT); | ||
2223 | |||
2224 | pwctl = read_c0_pwctl(); | ||
2225 | pr_debug("PWCtl (0x%x): PWEn: 0x%x DPH: 0x%x HugePg: 0x%x Psn: 0x%x\n", | ||
2226 | pwctl, | ||
2227 | (pwctl & MIPS_PWCTL_PWEN_MASK) >> MIPS_PWCTL_PWEN_SHIFT, | ||
2228 | (pwctl & MIPS_PWCTL_DPH_MASK) >> MIPS_PWCTL_DPH_SHIFT, | ||
2229 | (pwctl & MIPS_PWCTL_HUGEPG_MASK) >> MIPS_PWCTL_HUGEPG_SHIFT, | ||
2230 | (pwctl & MIPS_PWCTL_PSN_MASK) >> MIPS_PWCTL_PSN_SHIFT); | ||
2231 | } | ||
2232 | |||
2233 | static void config_htw_params(void) | ||
2234 | { | ||
2235 | unsigned long pwfield, pwsize, ptei; | ||
2236 | unsigned int config; | ||
2237 | |||
2238 | /* | ||
2239 | * We are using 2-level page tables, so we only need to | ||
2240 | * setup GDW and PTW appropriately. UDW and MDW will remain 0. | ||
2241 | * The default value of GDI/UDI/MDI/PTI is 0xc. It is illegal to | ||
2242 | * write values less than 0xc in these fields because the entire | ||
2243 | * write will be dropped. As a result of which, we must preserve | ||
2244 | * the original reset values and overwrite only what we really want. | ||
2245 | */ | ||
2246 | |||
2247 | pwfield = read_c0_pwfield(); | ||
2248 | /* re-initialize the GDI field */ | ||
2249 | pwfield &= ~MIPS_PWFIELD_GDI_MASK; | ||
2250 | pwfield |= PGDIR_SHIFT << MIPS_PWFIELD_GDI_SHIFT; | ||
2251 | /* re-initialize the PTI field including the even/odd bit */ | ||
2252 | pwfield &= ~MIPS_PWFIELD_PTI_MASK; | ||
2253 | pwfield |= PAGE_SHIFT << MIPS_PWFIELD_PTI_SHIFT; | ||
2254 | /* Set the PTEI right shift */ | ||
2255 | ptei = _PAGE_GLOBAL_SHIFT << MIPS_PWFIELD_PTEI_SHIFT; | ||
2256 | pwfield |= ptei; | ||
2257 | write_c0_pwfield(pwfield); | ||
2258 | /* Check whether the PTEI value is supported */ | ||
2259 | back_to_back_c0_hazard(); | ||
2260 | pwfield = read_c0_pwfield(); | ||
2261 | if (((pwfield & MIPS_PWFIELD_PTEI_MASK) << MIPS_PWFIELD_PTEI_SHIFT) | ||
2262 | != ptei) { | ||
2263 | pr_warn("Unsupported PTEI field value: 0x%lx. HTW will not be enabled", | ||
2264 | ptei); | ||
2265 | /* | ||
2266 | * Drop option to avoid HTW being enabled via another path | ||
2267 | * (eg htw_reset()) | ||
2268 | */ | ||
2269 | current_cpu_data.options &= ~MIPS_CPU_HTW; | ||
2270 | return; | ||
2271 | } | ||
2272 | |||
2273 | pwsize = ilog2(PTRS_PER_PGD) << MIPS_PWSIZE_GDW_SHIFT; | ||
2274 | pwsize |= ilog2(PTRS_PER_PTE) << MIPS_PWSIZE_PTW_SHIFT; | ||
2275 | write_c0_pwsize(pwsize); | ||
2276 | |||
2277 | /* Make sure everything is set before we enable the HTW */ | ||
2278 | back_to_back_c0_hazard(); | ||
2279 | |||
2280 | /* Enable HTW and disable the rest of the pwctl fields */ | ||
2281 | config = 1 << MIPS_PWCTL_PWEN_SHIFT; | ||
2282 | write_c0_pwctl(config); | ||
2283 | pr_info("Hardware Page Table Walker enabled\n"); | ||
2284 | |||
2285 | print_htw_config(); | ||
2286 | } | ||
2287 | |||
2197 | void build_tlb_refill_handler(void) | 2288 | void build_tlb_refill_handler(void) |
2198 | { | 2289 | { |
2199 | /* | 2290 | /* |
@@ -2258,5 +2349,8 @@ void build_tlb_refill_handler(void) | |||
2258 | } | 2349 | } |
2259 | if (cpu_has_local_ebase) | 2350 | if (cpu_has_local_ebase) |
2260 | build_r4000_tlb_refill_handler(); | 2351 | build_r4000_tlb_refill_handler(); |
2352 | if (cpu_has_htw) | ||
2353 | config_htw_params(); | ||
2354 | |||
2261 | } | 2355 | } |
2262 | } | 2356 | } |
diff --git a/arch/mips/mti-malta/malta-int.c b/arch/mips/mti-malta/malta-int.c index ecc2785f7858..e4f43baa8f67 100644 --- a/arch/mips/mti-malta/malta-int.c +++ b/arch/mips/mti-malta/malta-int.c | |||
@@ -42,6 +42,10 @@ static unsigned int ipi_map[NR_CPUS]; | |||
42 | 42 | ||
43 | static DEFINE_RAW_SPINLOCK(mips_irq_lock); | 43 | static DEFINE_RAW_SPINLOCK(mips_irq_lock); |
44 | 44 | ||
45 | #ifdef CONFIG_MIPS_GIC_IPI | ||
46 | DECLARE_BITMAP(ipi_ints, GIC_NUM_INTRS); | ||
47 | #endif | ||
48 | |||
45 | static inline int mips_pcibios_iack(void) | 49 | static inline int mips_pcibios_iack(void) |
46 | { | 50 | { |
47 | int irq; | 51 | int irq; |
@@ -125,16 +129,22 @@ static void malta_hw0_irqdispatch(void) | |||
125 | 129 | ||
126 | static void malta_ipi_irqdispatch(void) | 130 | static void malta_ipi_irqdispatch(void) |
127 | { | 131 | { |
128 | int irq; | 132 | #ifdef CONFIG_MIPS_GIC_IPI |
133 | unsigned long irq; | ||
134 | DECLARE_BITMAP(pending, GIC_NUM_INTRS); | ||
129 | 135 | ||
130 | if (gic_compare_int()) | 136 | gic_get_int_mask(pending, ipi_ints); |
131 | do_IRQ(MIPS_GIC_IRQ_BASE); | 137 | |
138 | irq = find_first_bit(pending, GIC_NUM_INTRS); | ||
132 | 139 | ||
133 | irq = gic_get_int(); | 140 | while (irq < GIC_NUM_INTRS) { |
134 | if (irq < 0) | 141 | do_IRQ(MIPS_GIC_IRQ_BASE + irq); |
135 | return; /* interrupt has already been cleared */ | ||
136 | 142 | ||
137 | do_IRQ(MIPS_GIC_IRQ_BASE + irq); | 143 | irq = find_next_bit(pending, GIC_NUM_INTRS, irq + 1); |
144 | } | ||
145 | #endif | ||
146 | if (gic_compare_int()) | ||
147 | do_IRQ(MIPS_GIC_IRQ_BASE); | ||
138 | } | 148 | } |
139 | 149 | ||
140 | static void corehi_irqdispatch(void) | 150 | static void corehi_irqdispatch(void) |
@@ -427,8 +437,9 @@ static void __init fill_ipi_map1(int baseintr, int cpu, int cpupin) | |||
427 | gic_intr_map[intr].pin = cpupin; | 437 | gic_intr_map[intr].pin = cpupin; |
428 | gic_intr_map[intr].polarity = GIC_POL_POS; | 438 | gic_intr_map[intr].polarity = GIC_POL_POS; |
429 | gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; | 439 | gic_intr_map[intr].trigtype = GIC_TRIG_EDGE; |
430 | gic_intr_map[intr].flags = GIC_FLAG_IPI; | 440 | gic_intr_map[intr].flags = 0; |
431 | ipi_map[cpu] |= (1 << (cpupin + 2)); | 441 | ipi_map[cpu] |= (1 << (cpupin + 2)); |
442 | bitmap_set(ipi_ints, intr, 1); | ||
432 | } | 443 | } |
433 | 444 | ||
434 | static void __init fill_ipi_map(void) | 445 | static void __init fill_ipi_map(void) |
diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c index 6d9773096750..0c35dee0a215 100644 --- a/arch/mips/mti-malta/malta-memory.c +++ b/arch/mips/mti-malta/malta-memory.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/string.h> | 16 | #include <linux/string.h> |
17 | 17 | ||
18 | #include <asm/bootinfo.h> | 18 | #include <asm/bootinfo.h> |
19 | #include <asm/maar.h> | ||
19 | #include <asm/sections.h> | 20 | #include <asm/sections.h> |
20 | #include <asm/fw/fw.h> | 21 | #include <asm/fw/fw.h> |
21 | 22 | ||
@@ -164,3 +165,28 @@ void __init prom_free_prom_memory(void) | |||
164 | addr, addr + boot_mem_map.map[i].size); | 165 | addr, addr + boot_mem_map.map[i].size); |
165 | } | 166 | } |
166 | } | 167 | } |
168 | |||
169 | unsigned platform_maar_init(unsigned num_pairs) | ||
170 | { | ||
171 | phys_addr_t mem_end = (physical_memsize & ~0xffffull) - 1; | ||
172 | struct maar_config cfg[] = { | ||
173 | /* DRAM preceding I/O */ | ||
174 | { 0x00000000, 0x0fffffff, MIPS_MAAR_S }, | ||
175 | |||
176 | /* DRAM following I/O */ | ||
177 | { 0x20000000, mem_end, MIPS_MAAR_S }, | ||
178 | |||
179 | /* DRAM alias in upper half of physical */ | ||
180 | { 0x80000000, 0x80000000 + mem_end, MIPS_MAAR_S }, | ||
181 | }; | ||
182 | unsigned i, num_cfg = ARRAY_SIZE(cfg); | ||
183 | |||
184 | /* If DRAM fits before I/O, drop the region following it */ | ||
185 | if (physical_memsize <= 0x10000000) { | ||
186 | num_cfg--; | ||
187 | for (i = 1; i < num_cfg; i++) | ||
188 | cfg[i] = cfg[i + 1]; | ||
189 | } | ||
190 | |||
191 | return maar_config(cfg, num_cfg, num_pairs); | ||
192 | } | ||
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index ff8a5539b363..6523d558ff5a 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile | |||
@@ -29,7 +29,7 @@ obj-$(CONFIG_LASAT) += pci-lasat.o | |||
29 | obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o | 29 | obj-$(CONFIG_MIPS_COBALT) += fixup-cobalt.o |
30 | obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o | 30 | obj-$(CONFIG_LEMOTE_FULOONG2E) += fixup-fuloong2e.o ops-loongson2.o |
31 | obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o | 31 | obj-$(CONFIG_LEMOTE_MACH2F) += fixup-lemote2f.o ops-loongson2.o |
32 | obj-$(CONFIG_LEMOTE_MACH3A) += fixup-loongson3.o ops-loongson3.o | 32 | obj-$(CONFIG_LOONGSON_MACH3X) += fixup-loongson3.o ops-loongson3.o |
33 | obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o pci-malta.o | 33 | obj-$(CONFIG_MIPS_MALTA) += fixup-malta.o pci-malta.o |
34 | obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o | 34 | obj-$(CONFIG_PMC_MSP7120_GW) += fixup-pmcmsp.o ops-pmcmsp.o |
35 | obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o | 35 | obj-$(CONFIG_PMC_MSP7120_EVAL) += fixup-pmcmsp.o ops-pmcmsp.o |
diff --git a/arch/mips/pci/ops-tx4927.c b/arch/mips/pci/ops-tx4927.c index 0e046d82e4e3..d54ea93651ac 100644 --- a/arch/mips/pci/ops-tx4927.c +++ b/arch/mips/pci/ops-tx4927.c | |||
@@ -199,8 +199,6 @@ static struct { | |||
199 | 199 | ||
200 | char *tx4927_pcibios_setup(char *str) | 200 | char *tx4927_pcibios_setup(char *str) |
201 | { | 201 | { |
202 | unsigned long val; | ||
203 | |||
204 | if (!strncmp(str, "trdyto=", 7)) { | 202 | if (!strncmp(str, "trdyto=", 7)) { |
205 | u8 val = 0; | 203 | u8 val = 0; |
206 | if (kstrtou8(str + 7, 0, &val) == 0) | 204 | if (kstrtou8(str + 7, 0, &val) == 0) |
diff --git a/arch/mips/pci/pci-alchemy.c b/arch/mips/pci/pci-alchemy.c index 563d1f61d6ee..c19600a03460 100644 --- a/arch/mips/pci/pci-alchemy.c +++ b/arch/mips/pci/pci-alchemy.c | |||
@@ -7,6 +7,7 @@ | |||
7 | * Support for all devices (greater than 16) added by David Gathright. | 7 | * Support for all devices (greater than 16) added by David Gathright. |
8 | */ | 8 | */ |
9 | 9 | ||
10 | #include <linux/clk.h> | ||
10 | #include <linux/export.h> | 11 | #include <linux/export.h> |
11 | #include <linux/types.h> | 12 | #include <linux/types.h> |
12 | #include <linux/pci.h> | 13 | #include <linux/pci.h> |
@@ -364,6 +365,7 @@ static int alchemy_pci_probe(struct platform_device *pdev) | |||
364 | void __iomem *virt_io; | 365 | void __iomem *virt_io; |
365 | unsigned long val; | 366 | unsigned long val; |
366 | struct resource *r; | 367 | struct resource *r; |
368 | struct clk *c; | ||
367 | int ret; | 369 | int ret; |
368 | 370 | ||
369 | /* need at least PCI IRQ mapping table */ | 371 | /* need at least PCI IRQ mapping table */ |
@@ -393,11 +395,24 @@ static int alchemy_pci_probe(struct platform_device *pdev) | |||
393 | goto out1; | 395 | goto out1; |
394 | } | 396 | } |
395 | 397 | ||
398 | c = clk_get(&pdev->dev, "pci_clko"); | ||
399 | if (IS_ERR(c)) { | ||
400 | dev_err(&pdev->dev, "unable to find PCI clock\n"); | ||
401 | ret = PTR_ERR(c); | ||
402 | goto out2; | ||
403 | } | ||
404 | |||
405 | ret = clk_prepare_enable(c); | ||
406 | if (ret) { | ||
407 | dev_err(&pdev->dev, "cannot enable PCI clock\n"); | ||
408 | goto out6; | ||
409 | } | ||
410 | |||
396 | ctx->regs = ioremap_nocache(r->start, resource_size(r)); | 411 | ctx->regs = ioremap_nocache(r->start, resource_size(r)); |
397 | if (!ctx->regs) { | 412 | if (!ctx->regs) { |
398 | dev_err(&pdev->dev, "cannot map pci regs\n"); | 413 | dev_err(&pdev->dev, "cannot map pci regs\n"); |
399 | ret = -ENODEV; | 414 | ret = -ENODEV; |
400 | goto out2; | 415 | goto out5; |
401 | } | 416 | } |
402 | 417 | ||
403 | /* map parts of the PCI IO area */ | 418 | /* map parts of the PCI IO area */ |
@@ -465,12 +480,19 @@ static int alchemy_pci_probe(struct platform_device *pdev) | |||
465 | register_syscore_ops(&alchemy_pci_pmops); | 480 | register_syscore_ops(&alchemy_pci_pmops); |
466 | register_pci_controller(&ctx->alchemy_pci_ctrl); | 481 | register_pci_controller(&ctx->alchemy_pci_ctrl); |
467 | 482 | ||
483 | dev_info(&pdev->dev, "PCI controller at %ld MHz\n", | ||
484 | clk_get_rate(c) / 1000000); | ||
485 | |||
468 | return 0; | 486 | return 0; |
469 | 487 | ||
470 | out4: | 488 | out4: |
471 | iounmap(virt_io); | 489 | iounmap(virt_io); |
472 | out3: | 490 | out3: |
473 | iounmap(ctx->regs); | 491 | iounmap(ctx->regs); |
492 | out5: | ||
493 | clk_disable_unprepare(c); | ||
494 | out6: | ||
495 | clk_put(c); | ||
474 | out2: | 496 | out2: |
475 | release_mem_region(r->start, resource_size(r)); | 497 | release_mem_region(r->start, resource_size(r)); |
476 | out1: | 498 | out1: |
diff --git a/arch/mips/ralink/of.c b/arch/mips/ralink/of.c index 251395210e23..7c4598cb6de8 100644 --- a/arch/mips/ralink/of.c +++ b/arch/mips/ralink/of.c | |||
@@ -81,7 +81,7 @@ static int __init plat_of_setup(void) | |||
81 | panic("device tree not present"); | 81 | panic("device tree not present"); |
82 | 82 | ||
83 | strlcpy(of_ids[0].compatible, soc_info.compatible, len); | 83 | strlcpy(of_ids[0].compatible, soc_info.compatible, len); |
84 | strncpy(of_ids[1].compatible, "palmbus", len); | 84 | strlcpy(of_ids[1].compatible, "palmbus", len); |
85 | 85 | ||
86 | if (of_platform_populate(NULL, of_ids, NULL, NULL)) | 86 | if (of_platform_populate(NULL, of_ids, NULL, NULL)) |
87 | panic("failed to populate DT"); | 87 | panic("failed to populate DT"); |
diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c index 3af00b2a26ee..e31e8cdcb296 100644 --- a/arch/mips/rb532/devices.c +++ b/arch/mips/rb532/devices.c | |||
@@ -223,6 +223,7 @@ static struct platform_device rb532_wdt = { | |||
223 | 223 | ||
224 | static struct plat_serial8250_port rb532_uart_res[] = { | 224 | static struct plat_serial8250_port rb532_uart_res[] = { |
225 | { | 225 | { |
226 | .type = PORT_16550A, | ||
226 | .membase = (char *)KSEG1ADDR(REGBASE + UART0BASE), | 227 | .membase = (char *)KSEG1ADDR(REGBASE + UART0BASE), |
227 | .irq = UART0_IRQ, | 228 | .irq = UART0_IRQ, |
228 | .regshift = 2, | 229 | .regshift = 2, |
@@ -250,28 +251,6 @@ static struct platform_device *rb532_devs[] = { | |||
250 | &rb532_wdt | 251 | &rb532_wdt |
251 | }; | 252 | }; |
252 | 253 | ||
253 | static void __init parse_mac_addr(char *macstr) | ||
254 | { | ||
255 | int i, h, l; | ||
256 | |||
257 | for (i = 0; i < 6; i++) { | ||
258 | if (i != 5 && *(macstr + 2) != ':') | ||
259 | return; | ||
260 | |||
261 | h = hex_to_bin(*macstr++); | ||
262 | if (h == -1) | ||
263 | return; | ||
264 | |||
265 | l = hex_to_bin(*macstr++); | ||
266 | if (l == -1) | ||
267 | return; | ||
268 | |||
269 | macstr++; | ||
270 | korina_dev0_data.mac[i] = (h << 4) + l; | ||
271 | } | ||
272 | } | ||
273 | |||
274 | |||
275 | /* NAND definitions */ | 254 | /* NAND definitions */ |
276 | #define NAND_CHIP_DELAY 25 | 255 | #define NAND_CHIP_DELAY 25 |
277 | 256 | ||
@@ -333,7 +312,10 @@ static int __init plat_setup_devices(void) | |||
333 | static int __init setup_kmac(char *s) | 312 | static int __init setup_kmac(char *s) |
334 | { | 313 | { |
335 | printk(KERN_INFO "korina mac = %s\n", s); | 314 | printk(KERN_INFO "korina mac = %s\n", s); |
336 | parse_mac_addr(s); | 315 | if (!mac_pton(s, korina_dev0_data.mac)) { |
316 | printk(KERN_ERR "Invalid mac\n"); | ||
317 | return -EINVAL; | ||
318 | } | ||
337 | return 0; | 319 | return 0; |
338 | } | 320 | } |
339 | 321 | ||
diff --git a/arch/mips/sgi-ip22/ip22-gio.c b/arch/mips/sgi-ip22/ip22-gio.c index 8e52446286ca..8f1b86d4da84 100644 --- a/arch/mips/sgi-ip22/ip22-gio.c +++ b/arch/mips/sgi-ip22/ip22-gio.c | |||
@@ -27,8 +27,14 @@ static struct { | |||
27 | { .name = "SGI GR2/GR3", .id = 0x7f }, | 27 | { .name = "SGI GR2/GR3", .id = 0x7f }, |
28 | }; | 28 | }; |
29 | 29 | ||
30 | static void gio_bus_release(struct device *dev) | ||
31 | { | ||
32 | kfree(dev); | ||
33 | } | ||
34 | |||
30 | static struct device gio_bus = { | 35 | static struct device gio_bus = { |
31 | .init_name = "gio", | 36 | .init_name = "gio", |
37 | .release = &gio_bus_release, | ||
32 | }; | 38 | }; |
33 | 39 | ||
34 | /** | 40 | /** |
@@ -413,8 +419,10 @@ int __init ip22_gio_init(void) | |||
413 | int ret; | 419 | int ret; |
414 | 420 | ||
415 | ret = device_register(&gio_bus); | 421 | ret = device_register(&gio_bus); |
416 | if (ret) | 422 | if (ret) { |
423 | put_device(&gio_bus); | ||
417 | return ret; | 424 | return ret; |
425 | } | ||
418 | 426 | ||
419 | ret = bus_register(&gio_bus_type); | 427 | ret = bus_register(&gio_bus_type); |
420 | if (!ret) { | 428 | if (!ret) { |
diff --git a/arch/mips/txx9/generic/7segled.c b/arch/mips/txx9/generic/7segled.c index 4642f56e70e5..566c58bd44d0 100644 --- a/arch/mips/txx9/generic/7segled.c +++ b/arch/mips/txx9/generic/7segled.c | |||
@@ -83,6 +83,11 @@ static struct bus_type tx_7segled_subsys = { | |||
83 | .dev_name = "7segled", | 83 | .dev_name = "7segled", |
84 | }; | 84 | }; |
85 | 85 | ||
86 | static void tx_7segled_release(struct device *dev) | ||
87 | { | ||
88 | kfree(dev); | ||
89 | } | ||
90 | |||
86 | static int __init tx_7segled_init_sysfs(void) | 91 | static int __init tx_7segled_init_sysfs(void) |
87 | { | 92 | { |
88 | int error, i; | 93 | int error, i; |
@@ -103,11 +108,14 @@ static int __init tx_7segled_init_sysfs(void) | |||
103 | } | 108 | } |
104 | dev->id = i; | 109 | dev->id = i; |
105 | dev->bus = &tx_7segled_subsys; | 110 | dev->bus = &tx_7segled_subsys; |
111 | dev->release = &tx_7segled_release; | ||
106 | error = device_register(dev); | 112 | error = device_register(dev); |
107 | if (!error) { | 113 | if (error) { |
108 | device_create_file(dev, &dev_attr_ascii); | 114 | put_device(dev); |
109 | device_create_file(dev, &dev_attr_raw); | 115 | return error; |
110 | } | 116 | } |
117 | device_create_file(dev, &dev_attr_ascii); | ||
118 | device_create_file(dev, &dev_attr_raw); | ||
111 | } | 119 | } |
112 | return error; | 120 | return error; |
113 | } | 121 | } |
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 28713274e0cc..a77698ff2b6f 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c | |||
@@ -268,7 +268,7 @@ static int txx9_i8259_irq_setup(int irq) | |||
268 | return err; | 268 | return err; |
269 | } | 269 | } |
270 | 270 | ||
271 | static void quirk_slc90e66_bridge(struct pci_dev *dev) | 271 | static void __init_refok quirk_slc90e66_bridge(struct pci_dev *dev) |
272 | { | 272 | { |
273 | int irq; /* PCI/ISA Bridge interrupt */ | 273 | int irq; /* PCI/ISA Bridge interrupt */ |
274 | u8 reg_64; | 274 | u8 reg_64; |
@@ -331,7 +331,7 @@ static void quirk_slc90e66_ide(struct pci_dev *dev) | |||
331 | * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! | 331 | * !!! DO NOT REMOVE THIS COMMENT IT IS REQUIRED BY SMSC !!! |
332 | */ | 332 | */ |
333 | dat |= 0x01; | 333 | dat |= 0x01; |
334 | pci_write_config_byte(dev, regs[i], dat); | 334 | pci_write_config_byte(dev, 0x5c, dat); |
335 | pci_read_config_byte(dev, 0x5c, &dat); | 335 | pci_read_config_byte(dev, 0x5c, &dat); |
336 | printk(KERN_CONT " REG5C %02x", dat); | 336 | printk(KERN_CONT " REG5C %02x", dat); |
337 | printk(KERN_CONT "\n"); | 337 | printk(KERN_CONT "\n"); |
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c index dd2cf25b5ae5..9ff200ae1c9a 100644 --- a/arch/mips/txx9/generic/setup.c +++ b/arch/mips/txx9/generic/setup.c | |||
@@ -937,6 +937,14 @@ static ssize_t txx9_sram_write(struct file *filp, struct kobject *kobj, | |||
937 | return size; | 937 | return size; |
938 | } | 938 | } |
939 | 939 | ||
940 | static void txx9_device_release(struct device *dev) | ||
941 | { | ||
942 | struct txx9_sramc_dev *tdev; | ||
943 | |||
944 | tdev = container_of(dev, struct txx9_sramc_dev, dev); | ||
945 | kfree(tdev); | ||
946 | } | ||
947 | |||
940 | void __init txx9_sramc_init(struct resource *r) | 948 | void __init txx9_sramc_init(struct resource *r) |
941 | { | 949 | { |
942 | struct txx9_sramc_dev *dev; | 950 | struct txx9_sramc_dev *dev; |
@@ -951,8 +959,11 @@ void __init txx9_sramc_init(struct resource *r) | |||
951 | return; | 959 | return; |
952 | size = resource_size(r); | 960 | size = resource_size(r); |
953 | dev->base = ioremap(r->start, size); | 961 | dev->base = ioremap(r->start, size); |
954 | if (!dev->base) | 962 | if (!dev->base) { |
955 | goto exit; | 963 | kfree(dev); |
964 | return; | ||
965 | } | ||
966 | dev->dev.release = &txx9_device_release; | ||
956 | dev->dev.bus = &txx9_sramc_subsys; | 967 | dev->dev.bus = &txx9_sramc_subsys; |
957 | sysfs_bin_attr_init(&dev->bindata_attr); | 968 | sysfs_bin_attr_init(&dev->bindata_attr); |
958 | dev->bindata_attr.attr.name = "bindata"; | 969 | dev->bindata_attr.attr.name = "bindata"; |
@@ -963,17 +974,15 @@ void __init txx9_sramc_init(struct resource *r) | |||
963 | dev->bindata_attr.private = dev; | 974 | dev->bindata_attr.private = dev; |
964 | err = device_register(&dev->dev); | 975 | err = device_register(&dev->dev); |
965 | if (err) | 976 | if (err) |
966 | goto exit; | 977 | goto exit_put; |
967 | err = sysfs_create_bin_file(&dev->dev.kobj, &dev->bindata_attr); | 978 | err = sysfs_create_bin_file(&dev->dev.kobj, &dev->bindata_attr); |
968 | if (err) { | 979 | if (err) { |
969 | device_unregister(&dev->dev); | 980 | device_unregister(&dev->dev); |
970 | goto exit; | 981 | iounmap(dev->base); |
971 | } | ||
972 | return; | ||
973 | exit: | ||
974 | if (dev) { | ||
975 | if (dev->base) | ||
976 | iounmap(dev->base); | ||
977 | kfree(dev); | 982 | kfree(dev); |
978 | } | 983 | } |
984 | return; | ||
985 | exit_put: | ||
986 | put_device(&dev->dev); | ||
987 | return; | ||
979 | } | 988 | } |