diff options
129 files changed, 4497 insertions, 2372 deletions
diff --git a/Documentation/devicetree/bindings/gpio/gpio-mm-lantiq.txt b/Documentation/devicetree/bindings/gpio/gpio-mm-lantiq.txt new file mode 100644 index 000000000000..f93d51478d5a --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-mm-lantiq.txt | |||
@@ -0,0 +1,38 @@ | |||
1 | Lantiq SoC External Bus memory mapped GPIO controller | ||
2 | |||
3 | By attaching hardware latches to the EBU it is possible to create output | ||
4 | only gpios. This driver configures a special memory address, which when | ||
5 | written to outputs 16 bit to the latches. | ||
6 | |||
7 | The node describing the memory mapped GPIOs needs to be a child of the node | ||
8 | describing the "lantiq,localbus". | ||
9 | |||
10 | Required properties: | ||
11 | - compatible : Should be "lantiq,gpio-mm-lantiq" | ||
12 | - reg : Address and length of the register set for the device | ||
13 | - #gpio-cells : Should be two. The first cell is the pin number and | ||
14 | the second cell is used to specify optional parameters (currently | ||
15 | unused). | ||
16 | - gpio-controller : Marks the device node as a gpio controller. | ||
17 | |||
18 | Optional properties: | ||
19 | - lantiq,shadow : The default value that we shall assume as already set on the | ||
20 | shift register cascade. | ||
21 | |||
22 | Example: | ||
23 | |||
24 | localbus@0 { | ||
25 | #address-cells = <2>; | ||
26 | #size-cells = <1>; | ||
27 | ranges = <0 0 0x0 0x3ffffff /* addrsel0 */ | ||
28 | 1 0 0x4000000 0x4000010>; /* addsel1 */ | ||
29 | compatible = "lantiq,localbus", "simple-bus"; | ||
30 | |||
31 | gpio_mm0: gpio@4000000 { | ||
32 | compatible = "lantiq,gpio-mm"; | ||
33 | reg = <1 0x0 0x10>; | ||
34 | gpio-controller; | ||
35 | #gpio-cells = <2>; | ||
36 | lantiq,shadow = <0x77f> | ||
37 | }; | ||
38 | } | ||
diff --git a/Documentation/devicetree/bindings/gpio/gpio-stp-xway.txt b/Documentation/devicetree/bindings/gpio/gpio-stp-xway.txt new file mode 100644 index 000000000000..854de130a971 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/gpio-stp-xway.txt | |||
@@ -0,0 +1,42 @@ | |||
1 | Lantiq SoC Serial To Parallel (STP) GPIO controller | ||
2 | |||
3 | The Serial To Parallel (STP) is found on MIPS based Lantiq socs. It is a | ||
4 | peripheral controller used to drive external shift register cascades. At most | ||
5 | 3 groups of 8 bits can be driven. The hardware is able to allow the DSL modem | ||
6 | to drive the 2 LSBs of the cascade automatically. | ||
7 | |||
8 | |||
9 | Required properties: | ||
10 | - compatible : Should be "lantiq,gpio-stp-xway" | ||
11 | - reg : Address and length of the register set for the device | ||
12 | - #gpio-cells : Should be two. The first cell is the pin number and | ||
13 | the second cell is used to specify optional parameters (currently | ||
14 | unused). | ||
15 | - gpio-controller : Marks the device node as a gpio controller. | ||
16 | |||
17 | Optional properties: | ||
18 | - lantiq,shadow : The default value that we shall assume as already set on the | ||
19 | shift register cascade. | ||
20 | - lantiq,groups : Set the 3 bit mask to select which of the 3 groups are enabled | ||
21 | in the shift register cascade. | ||
22 | - lantiq,dsl : The dsl core can control the 2 LSBs of the gpio cascade. This 2 bit | ||
23 | property can enable this feature. | ||
24 | - lantiq,phy1 : The gphy1 core can control 3 bits of the gpio cascade. | ||
25 | - lantiq,phy2 : The gphy2 core can control 3 bits of the gpio cascade. | ||
26 | - lantiq,rising : use rising instead of falling edge for the shift register | ||
27 | |||
28 | Example: | ||
29 | |||
30 | gpio1: stp@E100BB0 { | ||
31 | compatible = "lantiq,gpio-stp-xway"; | ||
32 | reg = <0xE100BB0 0x40>; | ||
33 | #gpio-cells = <2>; | ||
34 | gpio-controller; | ||
35 | |||
36 | lantiq,shadow = <0xffff>; | ||
37 | lantiq,groups = <0x7>; | ||
38 | lantiq,dsl = <0x3>; | ||
39 | lantiq,phy1 = <0x7>; | ||
40 | lantiq,phy2 = <0x7>; | ||
41 | /* lantiq,rising; */ | ||
42 | }; | ||
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 6e041639a40d..54be81c5a3b6 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -228,8 +228,9 @@ config LANTIQ | |||
228 | select ARCH_REQUIRE_GPIOLIB | 228 | select ARCH_REQUIRE_GPIOLIB |
229 | select SWAP_IO_SPACE | 229 | select SWAP_IO_SPACE |
230 | select BOOT_RAW | 230 | select BOOT_RAW |
231 | select HAVE_CLK | 231 | select HAVE_MACH_CLKDEV |
232 | select MIPS_MACHINE | 232 | select CLKDEV_LOOKUP |
233 | select USE_OF | ||
233 | 234 | ||
234 | config LASAT | 235 | config LASAT |
235 | bool "LASAT Networks platforms" | 236 | bool "LASAT Networks platforms" |
diff --git a/arch/mips/alchemy/devboards/db1200.c b/arch/mips/alchemy/devboards/db1200.c index a83302b96c01..7dde01642d6b 100644 --- a/arch/mips/alchemy/devboards/db1200.c +++ b/arch/mips/alchemy/devboards/db1200.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/gpio.h> | 22 | #include <linux/gpio.h> |
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include <linux/init.h> | 24 | #include <linux/init.h> |
25 | #include <linux/module.h> | ||
25 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
26 | #include <linux/io.h> | 27 | #include <linux/io.h> |
27 | #include <linux/leds.h> | 28 | #include <linux/leds.h> |
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index e0fae8f4442b..f44feee2d67f 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig | |||
@@ -26,6 +26,18 @@ config ATH79_MACH_AP81 | |||
26 | Say 'Y' here if you want your kernel to support the | 26 | Say 'Y' here if you want your kernel to support the |
27 | Atheros AP81 reference board. | 27 | Atheros AP81 reference board. |
28 | 28 | ||
29 | config ATH79_MACH_DB120 | ||
30 | bool "Atheros DB120 reference board" | ||
31 | select SOC_AR934X | ||
32 | select ATH79_DEV_GPIO_BUTTONS | ||
33 | select ATH79_DEV_LEDS_GPIO | ||
34 | select ATH79_DEV_SPI | ||
35 | select ATH79_DEV_USB | ||
36 | select ATH79_DEV_WMAC | ||
37 | help | ||
38 | Say 'Y' here if you want your kernel to support the | ||
39 | Atheros DB120 reference board. | ||
40 | |||
29 | config ATH79_MACH_PB44 | 41 | config ATH79_MACH_PB44 |
30 | bool "Atheros PB44 reference board" | 42 | bool "Atheros PB44 reference board" |
31 | select SOC_AR71XX | 43 | select SOC_AR71XX |
@@ -52,12 +64,14 @@ endmenu | |||
52 | config SOC_AR71XX | 64 | config SOC_AR71XX |
53 | select USB_ARCH_HAS_EHCI | 65 | select USB_ARCH_HAS_EHCI |
54 | select USB_ARCH_HAS_OHCI | 66 | select USB_ARCH_HAS_OHCI |
67 | select HW_HAS_PCI | ||
55 | def_bool n | 68 | def_bool n |
56 | 69 | ||
57 | config SOC_AR724X | 70 | config SOC_AR724X |
58 | select USB_ARCH_HAS_EHCI | 71 | select USB_ARCH_HAS_EHCI |
59 | select USB_ARCH_HAS_OHCI | 72 | select USB_ARCH_HAS_OHCI |
60 | select HW_HAS_PCI | 73 | select HW_HAS_PCI |
74 | select PCI_AR724X if PCI | ||
61 | def_bool n | 75 | def_bool n |
62 | 76 | ||
63 | config SOC_AR913X | 77 | config SOC_AR913X |
@@ -68,6 +82,15 @@ config SOC_AR933X | |||
68 | select USB_ARCH_HAS_EHCI | 82 | select USB_ARCH_HAS_EHCI |
69 | def_bool n | 83 | def_bool n |
70 | 84 | ||
85 | config SOC_AR934X | ||
86 | select USB_ARCH_HAS_EHCI | ||
87 | select HW_HAS_PCI | ||
88 | select PCI_AR724X if PCI | ||
89 | def_bool n | ||
90 | |||
91 | config PCI_AR724X | ||
92 | def_bool n | ||
93 | |||
71 | config ATH79_DEV_GPIO_BUTTONS | 94 | config ATH79_DEV_GPIO_BUTTONS |
72 | def_bool n | 95 | def_bool n |
73 | 96 | ||
@@ -81,7 +104,7 @@ config ATH79_DEV_USB | |||
81 | def_bool n | 104 | def_bool n |
82 | 105 | ||
83 | config ATH79_DEV_WMAC | 106 | config ATH79_DEV_WMAC |
84 | depends on (SOC_AR913X || SOC_AR933X) | 107 | depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X) |
85 | def_bool n | 108 | def_bool n |
86 | 109 | ||
87 | endif | 110 | endif |
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile index 3b911e09dbec..2b54d98263f3 100644 --- a/arch/mips/ath79/Makefile +++ b/arch/mips/ath79/Makefile | |||
@@ -11,6 +11,7 @@ | |||
11 | obj-y := prom.o setup.o irq.o common.o clock.o gpio.o | 11 | obj-y := prom.o setup.o irq.o common.o clock.o gpio.o |
12 | 12 | ||
13 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 13 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
14 | obj-$(CONFIG_PCI) += pci.o | ||
14 | 15 | ||
15 | # | 16 | # |
16 | # Devices | 17 | # Devices |
@@ -27,5 +28,6 @@ obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wmac.o | |||
27 | # | 28 | # |
28 | obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o | 29 | obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o |
29 | obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o | 30 | obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o |
31 | obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o | ||
30 | obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o | 32 | obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o |
31 | obj-$(CONFIG_ATH79_MACH_UBNT_XM) += mach-ubnt-xm.o | 33 | obj-$(CONFIG_ATH79_MACH_UBNT_XM) += mach-ubnt-xm.o |
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c index 54d0eb4db987..b91ad3efe29e 100644 --- a/arch/mips/ath79/clock.c +++ b/arch/mips/ath79/clock.c | |||
@@ -1,8 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * Atheros AR71XX/AR724X/AR913X common routines | 2 | * Atheros AR71XX/AR724X/AR913X common routines |
3 | * | 3 | * |
4 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> | ||
4 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | 5 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> |
5 | * | 6 | * |
7 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP | ||
8 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | 9 | * This program is free software; you can redistribute it and/or modify it |
7 | * under the terms of the GNU General Public License version 2 as published | 10 | * under the terms of the GNU General Public License version 2 as published |
8 | * by the Free Software Foundation. | 11 | * by the Free Software Foundation. |
@@ -163,6 +166,82 @@ static void __init ar933x_clocks_init(void) | |||
163 | ath79_uart_clk.rate = ath79_ref_clk.rate; | 166 | ath79_uart_clk.rate = ath79_ref_clk.rate; |
164 | } | 167 | } |
165 | 168 | ||
169 | static void __init ar934x_clocks_init(void) | ||
170 | { | ||
171 | u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv; | ||
172 | u32 cpu_pll, ddr_pll; | ||
173 | u32 bootstrap; | ||
174 | |||
175 | bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); | ||
176 | if (bootstrap & AR934X_BOOTSTRAP_REF_CLK_40) | ||
177 | ath79_ref_clk.rate = 40 * 1000 * 1000; | ||
178 | else | ||
179 | ath79_ref_clk.rate = 25 * 1000 * 1000; | ||
180 | |||
181 | pll = ath79_pll_rr(AR934X_PLL_CPU_CONFIG_REG); | ||
182 | out_div = (pll >> AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT) & | ||
183 | AR934X_PLL_CPU_CONFIG_OUTDIV_MASK; | ||
184 | ref_div = (pll >> AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT) & | ||
185 | AR934X_PLL_CPU_CONFIG_REFDIV_MASK; | ||
186 | nint = (pll >> AR934X_PLL_CPU_CONFIG_NINT_SHIFT) & | ||
187 | AR934X_PLL_CPU_CONFIG_NINT_MASK; | ||
188 | frac = (pll >> AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT) & | ||
189 | AR934X_PLL_CPU_CONFIG_NFRAC_MASK; | ||
190 | |||
191 | cpu_pll = nint * ath79_ref_clk.rate / ref_div; | ||
192 | cpu_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 6)); | ||
193 | cpu_pll /= (1 << out_div); | ||
194 | |||
195 | pll = ath79_pll_rr(AR934X_PLL_DDR_CONFIG_REG); | ||
196 | out_div = (pll >> AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT) & | ||
197 | AR934X_PLL_DDR_CONFIG_OUTDIV_MASK; | ||
198 | ref_div = (pll >> AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT) & | ||
199 | AR934X_PLL_DDR_CONFIG_REFDIV_MASK; | ||
200 | nint = (pll >> AR934X_PLL_DDR_CONFIG_NINT_SHIFT) & | ||
201 | AR934X_PLL_DDR_CONFIG_NINT_MASK; | ||
202 | frac = (pll >> AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT) & | ||
203 | AR934X_PLL_DDR_CONFIG_NFRAC_MASK; | ||
204 | |||
205 | ddr_pll = nint * ath79_ref_clk.rate / ref_div; | ||
206 | ddr_pll += frac * ath79_ref_clk.rate / (ref_div * (2 << 10)); | ||
207 | ddr_pll /= (1 << out_div); | ||
208 | |||
209 | clk_ctrl = ath79_pll_rr(AR934X_PLL_CPU_DDR_CLK_CTRL_REG); | ||
210 | |||
211 | postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT) & | ||
212 | AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK; | ||
213 | |||
214 | if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS) | ||
215 | ath79_cpu_clk.rate = ath79_ref_clk.rate; | ||
216 | else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL) | ||
217 | ath79_cpu_clk.rate = cpu_pll / (postdiv + 1); | ||
218 | else | ||
219 | ath79_cpu_clk.rate = ddr_pll / (postdiv + 1); | ||
220 | |||
221 | postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT) & | ||
222 | AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK; | ||
223 | |||
224 | if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS) | ||
225 | ath79_ddr_clk.rate = ath79_ref_clk.rate; | ||
226 | else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL) | ||
227 | ath79_ddr_clk.rate = ddr_pll / (postdiv + 1); | ||
228 | else | ||
229 | ath79_ddr_clk.rate = cpu_pll / (postdiv + 1); | ||
230 | |||
231 | postdiv = (clk_ctrl >> AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT) & | ||
232 | AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK; | ||
233 | |||
234 | if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS) | ||
235 | ath79_ahb_clk.rate = ath79_ref_clk.rate; | ||
236 | else if (clk_ctrl & AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL) | ||
237 | ath79_ahb_clk.rate = ddr_pll / (postdiv + 1); | ||
238 | else | ||
239 | ath79_ahb_clk.rate = cpu_pll / (postdiv + 1); | ||
240 | |||
241 | ath79_wdt_clk.rate = ath79_ref_clk.rate; | ||
242 | ath79_uart_clk.rate = ath79_ref_clk.rate; | ||
243 | } | ||
244 | |||
166 | void __init ath79_clocks_init(void) | 245 | void __init ath79_clocks_init(void) |
167 | { | 246 | { |
168 | if (soc_is_ar71xx()) | 247 | if (soc_is_ar71xx()) |
@@ -173,6 +252,8 @@ void __init ath79_clocks_init(void) | |||
173 | ar913x_clocks_init(); | 252 | ar913x_clocks_init(); |
174 | else if (soc_is_ar933x()) | 253 | else if (soc_is_ar933x()) |
175 | ar933x_clocks_init(); | 254 | ar933x_clocks_init(); |
255 | else if (soc_is_ar934x()) | ||
256 | ar934x_clocks_init(); | ||
176 | else | 257 | else |
177 | BUG(); | 258 | BUG(); |
178 | 259 | ||
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c index f0fda982b965..5a4adfc9d79d 100644 --- a/arch/mips/ath79/common.c +++ b/arch/mips/ath79/common.c | |||
@@ -1,9 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Atheros AR71XX/AR724X/AR913X common routines | 2 | * Atheros AR71XX/AR724X/AR913X common routines |
3 | * | 3 | * |
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | 4 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> |
5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
6 | * | 7 | * |
8 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP | ||
9 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License version 2 as published | 11 | * under the terms of the GNU General Public License version 2 as published |
9 | * by the Free Software Foundation. | 12 | * by the Free Software Foundation. |
@@ -67,6 +70,8 @@ void ath79_device_reset_set(u32 mask) | |||
67 | reg = AR913X_RESET_REG_RESET_MODULE; | 70 | reg = AR913X_RESET_REG_RESET_MODULE; |
68 | else if (soc_is_ar933x()) | 71 | else if (soc_is_ar933x()) |
69 | reg = AR933X_RESET_REG_RESET_MODULE; | 72 | reg = AR933X_RESET_REG_RESET_MODULE; |
73 | else if (soc_is_ar934x()) | ||
74 | reg = AR934X_RESET_REG_RESET_MODULE; | ||
70 | else | 75 | else |
71 | BUG(); | 76 | BUG(); |
72 | 77 | ||
@@ -91,6 +96,8 @@ void ath79_device_reset_clear(u32 mask) | |||
91 | reg = AR913X_RESET_REG_RESET_MODULE; | 96 | reg = AR913X_RESET_REG_RESET_MODULE; |
92 | else if (soc_is_ar933x()) | 97 | else if (soc_is_ar933x()) |
93 | reg = AR933X_RESET_REG_RESET_MODULE; | 98 | reg = AR933X_RESET_REG_RESET_MODULE; |
99 | else if (soc_is_ar934x()) | ||
100 | reg = AR934X_RESET_REG_RESET_MODULE; | ||
94 | else | 101 | else |
95 | BUG(); | 102 | BUG(); |
96 | 103 | ||
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c index f4956f809072..45efc63b08b6 100644 --- a/arch/mips/ath79/dev-common.c +++ b/arch/mips/ath79/dev-common.c | |||
@@ -89,7 +89,8 @@ void __init ath79_register_uart(void) | |||
89 | 89 | ||
90 | if (soc_is_ar71xx() || | 90 | if (soc_is_ar71xx() || |
91 | soc_is_ar724x() || | 91 | soc_is_ar724x() || |
92 | soc_is_ar913x()) { | 92 | soc_is_ar913x() || |
93 | soc_is_ar934x()) { | ||
93 | ath79_uart_data[0].uartclk = clk_get_rate(clk); | 94 | ath79_uart_data[0].uartclk = clk_get_rate(clk); |
94 | platform_device_register(&ath79_uart_device); | 95 | platform_device_register(&ath79_uart_device); |
95 | } else if (soc_is_ar933x()) { | 96 | } else if (soc_is_ar933x()) { |
diff --git a/arch/mips/ath79/dev-gpio-buttons.c b/arch/mips/ath79/dev-gpio-buttons.c index 4b0168a11c01..366b35fb164d 100644 --- a/arch/mips/ath79/dev-gpio-buttons.c +++ b/arch/mips/ath79/dev-gpio-buttons.c | |||
@@ -25,12 +25,10 @@ void __init ath79_register_gpio_keys_polled(int id, | |||
25 | struct gpio_keys_button *p; | 25 | struct gpio_keys_button *p; |
26 | int err; | 26 | int err; |
27 | 27 | ||
28 | p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL); | 28 | p = kmemdup(buttons, nbuttons * sizeof(*p), GFP_KERNEL); |
29 | if (!p) | 29 | if (!p) |
30 | return; | 30 | return; |
31 | 31 | ||
32 | memcpy(p, buttons, nbuttons * sizeof(*p)); | ||
33 | |||
34 | pdev = platform_device_alloc("gpio-keys-polled", id); | 32 | pdev = platform_device_alloc("gpio-keys-polled", id); |
35 | if (!pdev) | 33 | if (!pdev) |
36 | goto err_free_buttons; | 34 | goto err_free_buttons; |
diff --git a/arch/mips/ath79/dev-leds-gpio.c b/arch/mips/ath79/dev-leds-gpio.c index cdade68dcd17..dcb1debcefb8 100644 --- a/arch/mips/ath79/dev-leds-gpio.c +++ b/arch/mips/ath79/dev-leds-gpio.c | |||
@@ -24,12 +24,10 @@ void __init ath79_register_leds_gpio(int id, | |||
24 | struct gpio_led *p; | 24 | struct gpio_led *p; |
25 | int err; | 25 | int err; |
26 | 26 | ||
27 | p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL); | 27 | p = kmemdup(leds, num_leds * sizeof(*p), GFP_KERNEL); |
28 | if (!p) | 28 | if (!p) |
29 | return; | 29 | return; |
30 | 30 | ||
31 | memcpy(p, leds, num_leds * sizeof(*p)); | ||
32 | |||
33 | pdev = platform_device_alloc("leds-gpio", id); | 31 | pdev = platform_device_alloc("leds-gpio", id); |
34 | if (!pdev) | 32 | if (!pdev) |
35 | goto err_free_leds; | 33 | goto err_free_leds; |
diff --git a/arch/mips/ath79/dev-wmac.c b/arch/mips/ath79/dev-wmac.c index 9c717bf98ffe..d6d893c16ad4 100644 --- a/arch/mips/ath79/dev-wmac.c +++ b/arch/mips/ath79/dev-wmac.c | |||
@@ -1,9 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Atheros AR913X/AR933X SoC built-in WMAC device support | 2 | * Atheros AR913X/AR933X SoC built-in WMAC device support |
3 | * | 3 | * |
4 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> | ||
4 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | 5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
6 | * | 7 | * |
8 | * Parts of this file are based on Atheros 2.6.15/2.6.31 BSP | ||
9 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License version 2 as published | 11 | * under the terms of the GNU General Public License version 2 as published |
9 | * by the Free Software Foundation. | 12 | * by the Free Software Foundation. |
@@ -26,8 +29,7 @@ static struct resource ath79_wmac_resources[] = { | |||
26 | /* .start and .end fields are filled dynamically */ | 29 | /* .start and .end fields are filled dynamically */ |
27 | .flags = IORESOURCE_MEM, | 30 | .flags = IORESOURCE_MEM, |
28 | }, { | 31 | }, { |
29 | .start = ATH79_CPU_IRQ_IP2, | 32 | /* .start and .end fields are filled dynamically */ |
30 | .end = ATH79_CPU_IRQ_IP2, | ||
31 | .flags = IORESOURCE_IRQ, | 33 | .flags = IORESOURCE_IRQ, |
32 | }, | 34 | }, |
33 | }; | 35 | }; |
@@ -53,6 +55,8 @@ static void __init ar913x_wmac_setup(void) | |||
53 | 55 | ||
54 | ath79_wmac_resources[0].start = AR913X_WMAC_BASE; | 56 | ath79_wmac_resources[0].start = AR913X_WMAC_BASE; |
55 | ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1; | 57 | ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1; |
58 | ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2; | ||
59 | ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2; | ||
56 | } | 60 | } |
57 | 61 | ||
58 | 62 | ||
@@ -79,6 +83,8 @@ static void __init ar933x_wmac_setup(void) | |||
79 | 83 | ||
80 | ath79_wmac_resources[0].start = AR933X_WMAC_BASE; | 84 | ath79_wmac_resources[0].start = AR933X_WMAC_BASE; |
81 | ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1; | 85 | ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1; |
86 | ath79_wmac_resources[1].start = ATH79_CPU_IRQ_IP2; | ||
87 | ath79_wmac_resources[1].end = ATH79_CPU_IRQ_IP2; | ||
82 | 88 | ||
83 | t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); | 89 | t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP); |
84 | if (t & AR933X_BOOTSTRAP_REF_CLK_40) | 90 | if (t & AR933X_BOOTSTRAP_REF_CLK_40) |
@@ -92,12 +98,32 @@ static void __init ar933x_wmac_setup(void) | |||
92 | ath79_wmac_data.external_reset = ar933x_wmac_reset; | 98 | ath79_wmac_data.external_reset = ar933x_wmac_reset; |
93 | } | 99 | } |
94 | 100 | ||
101 | static void ar934x_wmac_setup(void) | ||
102 | { | ||
103 | u32 t; | ||
104 | |||
105 | ath79_wmac_device.name = "ar934x_wmac"; | ||
106 | |||
107 | ath79_wmac_resources[0].start = AR934X_WMAC_BASE; | ||
108 | ath79_wmac_resources[0].end = AR934X_WMAC_BASE + AR934X_WMAC_SIZE - 1; | ||
109 | ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); | ||
110 | ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1); | ||
111 | |||
112 | t = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); | ||
113 | if (t & AR934X_BOOTSTRAP_REF_CLK_40) | ||
114 | ath79_wmac_data.is_clk_25mhz = false; | ||
115 | else | ||
116 | ath79_wmac_data.is_clk_25mhz = true; | ||
117 | } | ||
118 | |||
95 | void __init ath79_register_wmac(u8 *cal_data) | 119 | void __init ath79_register_wmac(u8 *cal_data) |
96 | { | 120 | { |
97 | if (soc_is_ar913x()) | 121 | if (soc_is_ar913x()) |
98 | ar913x_wmac_setup(); | 122 | ar913x_wmac_setup(); |
99 | else if (soc_is_ar933x()) | 123 | else if (soc_is_ar933x()) |
100 | ar933x_wmac_setup(); | 124 | ar933x_wmac_setup(); |
125 | else if (soc_is_ar934x()) | ||
126 | ar934x_wmac_setup(); | ||
101 | else | 127 | else |
102 | BUG(); | 128 | BUG(); |
103 | 129 | ||
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c index 6a51ced7a293..dc938cb2ba58 100644 --- a/arch/mips/ath79/early_printk.c +++ b/arch/mips/ath79/early_printk.c | |||
@@ -71,6 +71,9 @@ static void prom_putchar_init(void) | |||
71 | case REV_ID_MAJOR_AR7241: | 71 | case REV_ID_MAJOR_AR7241: |
72 | case REV_ID_MAJOR_AR7242: | 72 | case REV_ID_MAJOR_AR7242: |
73 | case REV_ID_MAJOR_AR913X: | 73 | case REV_ID_MAJOR_AR913X: |
74 | case REV_ID_MAJOR_AR9341: | ||
75 | case REV_ID_MAJOR_AR9342: | ||
76 | case REV_ID_MAJOR_AR9344: | ||
74 | _prom_putchar = prom_putchar_ar71xx; | 77 | _prom_putchar = prom_putchar_ar71xx; |
75 | break; | 78 | break; |
76 | 79 | ||
diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c index a2f8ca630ed6..29054f211832 100644 --- a/arch/mips/ath79/gpio.c +++ b/arch/mips/ath79/gpio.c | |||
@@ -1,9 +1,12 @@ | |||
1 | /* | 1 | /* |
2 | * Atheros AR71XX/AR724X/AR913X GPIO API support | 2 | * Atheros AR71XX/AR724X/AR913X GPIO API support |
3 | * | 3 | * |
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | 4 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> |
5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
6 | * | 7 | * |
8 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP | ||
9 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
8 | * under the terms of the GNU General Public License version 2 as published | 11 | * under the terms of the GNU General Public License version 2 as published |
9 | * by the Free Software Foundation. | 12 | * by the Free Software Foundation. |
@@ -89,6 +92,42 @@ static int ath79_gpio_direction_output(struct gpio_chip *chip, | |||
89 | return 0; | 92 | return 0; |
90 | } | 93 | } |
91 | 94 | ||
95 | static int ar934x_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | ||
96 | { | ||
97 | void __iomem *base = ath79_gpio_base; | ||
98 | unsigned long flags; | ||
99 | |||
100 | spin_lock_irqsave(&ath79_gpio_lock, flags); | ||
101 | |||
102 | __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset), | ||
103 | base + AR71XX_GPIO_REG_OE); | ||
104 | |||
105 | spin_unlock_irqrestore(&ath79_gpio_lock, flags); | ||
106 | |||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | static int ar934x_gpio_direction_output(struct gpio_chip *chip, unsigned offset, | ||
111 | int value) | ||
112 | { | ||
113 | void __iomem *base = ath79_gpio_base; | ||
114 | unsigned long flags; | ||
115 | |||
116 | spin_lock_irqsave(&ath79_gpio_lock, flags); | ||
117 | |||
118 | if (value) | ||
119 | __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET); | ||
120 | else | ||
121 | __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR); | ||
122 | |||
123 | __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset), | ||
124 | base + AR71XX_GPIO_REG_OE); | ||
125 | |||
126 | spin_unlock_irqrestore(&ath79_gpio_lock, flags); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
92 | static struct gpio_chip ath79_gpio_chip = { | 131 | static struct gpio_chip ath79_gpio_chip = { |
93 | .label = "ath79", | 132 | .label = "ath79", |
94 | .get = ath79_gpio_get_value, | 133 | .get = ath79_gpio_get_value, |
@@ -155,11 +194,17 @@ void __init ath79_gpio_init(void) | |||
155 | ath79_gpio_count = AR913X_GPIO_COUNT; | 194 | ath79_gpio_count = AR913X_GPIO_COUNT; |
156 | else if (soc_is_ar933x()) | 195 | else if (soc_is_ar933x()) |
157 | ath79_gpio_count = AR933X_GPIO_COUNT; | 196 | ath79_gpio_count = AR933X_GPIO_COUNT; |
197 | else if (soc_is_ar934x()) | ||
198 | ath79_gpio_count = AR934X_GPIO_COUNT; | ||
158 | else | 199 | else |
159 | BUG(); | 200 | BUG(); |
160 | 201 | ||
161 | ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); | 202 | ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); |
162 | ath79_gpio_chip.ngpio = ath79_gpio_count; | 203 | ath79_gpio_chip.ngpio = ath79_gpio_count; |
204 | if (soc_is_ar934x()) { | ||
205 | ath79_gpio_chip.direction_input = ar934x_gpio_direction_input; | ||
206 | ath79_gpio_chip.direction_output = ar934x_gpio_direction_output; | ||
207 | } | ||
163 | 208 | ||
164 | err = gpiochip_add(&ath79_gpio_chip); | 209 | err = gpiochip_add(&ath79_gpio_chip); |
165 | if (err) | 210 | if (err) |
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c index 1b073de44680..90d09fc15398 100644 --- a/arch/mips/ath79/irq.c +++ b/arch/mips/ath79/irq.c | |||
@@ -1,10 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * Atheros AR71xx/AR724x/AR913x specific interrupt handling | 2 | * Atheros AR71xx/AR724x/AR913x specific interrupt handling |
3 | * | 3 | * |
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | 4 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> |
5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
6 | * | 7 | * |
7 | * Parts of this file are based on Atheros' 2.6.15 BSP | 8 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP |
8 | * | 9 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License version 2 as published | 11 | * under the terms of the GNU General Public License version 2 as published |
@@ -23,8 +24,8 @@ | |||
23 | #include <asm/mach-ath79/ar71xx_regs.h> | 24 | #include <asm/mach-ath79/ar71xx_regs.h> |
24 | #include "common.h" | 25 | #include "common.h" |
25 | 26 | ||
26 | static unsigned int ath79_ip2_flush_reg; | 27 | static void (*ath79_ip2_handler)(void); |
27 | static unsigned int ath79_ip3_flush_reg; | 28 | static void (*ath79_ip3_handler)(void); |
28 | 29 | ||
29 | static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) | 30 | static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) |
30 | { | 31 | { |
@@ -129,7 +130,7 @@ static void __init ath79_misc_irq_init(void) | |||
129 | 130 | ||
130 | if (soc_is_ar71xx() || soc_is_ar913x()) | 131 | if (soc_is_ar71xx() || soc_is_ar913x()) |
131 | ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; | 132 | ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask; |
132 | else if (soc_is_ar724x() || soc_is_ar933x()) | 133 | else if (soc_is_ar724x() || soc_is_ar933x() || soc_is_ar934x()) |
133 | ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; | 134 | ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack; |
134 | else | 135 | else |
135 | BUG(); | 136 | BUG(); |
@@ -143,6 +144,39 @@ static void __init ath79_misc_irq_init(void) | |||
143 | irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler); | 144 | irq_set_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler); |
144 | } | 145 | } |
145 | 146 | ||
147 | static void ar934x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc) | ||
148 | { | ||
149 | u32 status; | ||
150 | |||
151 | disable_irq_nosync(irq); | ||
152 | |||
153 | status = ath79_reset_rr(AR934X_RESET_REG_PCIE_WMAC_INT_STATUS); | ||
154 | |||
155 | if (status & AR934X_PCIE_WMAC_INT_PCIE_ALL) { | ||
156 | ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_PCIE); | ||
157 | generic_handle_irq(ATH79_IP2_IRQ(0)); | ||
158 | } else if (status & AR934X_PCIE_WMAC_INT_WMAC_ALL) { | ||
159 | ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_WMAC); | ||
160 | generic_handle_irq(ATH79_IP2_IRQ(1)); | ||
161 | } else { | ||
162 | spurious_interrupt(); | ||
163 | } | ||
164 | |||
165 | enable_irq(irq); | ||
166 | } | ||
167 | |||
168 | static void ar934x_ip2_irq_init(void) | ||
169 | { | ||
170 | int i; | ||
171 | |||
172 | for (i = ATH79_IP2_IRQ_BASE; | ||
173 | i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++) | ||
174 | irq_set_chip_and_handler(i, &dummy_irq_chip, | ||
175 | handle_level_irq); | ||
176 | |||
177 | irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar934x_ip2_irq_dispatch); | ||
178 | } | ||
179 | |||
146 | asmlinkage void plat_irq_dispatch(void) | 180 | asmlinkage void plat_irq_dispatch(void) |
147 | { | 181 | { |
148 | unsigned long pending; | 182 | unsigned long pending; |
@@ -152,10 +186,8 @@ asmlinkage void plat_irq_dispatch(void) | |||
152 | if (pending & STATUSF_IP7) | 186 | if (pending & STATUSF_IP7) |
153 | do_IRQ(ATH79_CPU_IRQ_TIMER); | 187 | do_IRQ(ATH79_CPU_IRQ_TIMER); |
154 | 188 | ||
155 | else if (pending & STATUSF_IP2) { | 189 | else if (pending & STATUSF_IP2) |
156 | ath79_ddr_wb_flush(ath79_ip2_flush_reg); | 190 | ath79_ip2_handler(); |
157 | do_IRQ(ATH79_CPU_IRQ_IP2); | ||
158 | } | ||
159 | 191 | ||
160 | else if (pending & STATUSF_IP4) | 192 | else if (pending & STATUSF_IP4) |
161 | do_IRQ(ATH79_CPU_IRQ_GE0); | 193 | do_IRQ(ATH79_CPU_IRQ_GE0); |
@@ -163,10 +195,8 @@ asmlinkage void plat_irq_dispatch(void) | |||
163 | else if (pending & STATUSF_IP5) | 195 | else if (pending & STATUSF_IP5) |
164 | do_IRQ(ATH79_CPU_IRQ_GE1); | 196 | do_IRQ(ATH79_CPU_IRQ_GE1); |
165 | 197 | ||
166 | else if (pending & STATUSF_IP3) { | 198 | else if (pending & STATUSF_IP3) |
167 | ath79_ddr_wb_flush(ath79_ip3_flush_reg); | 199 | ath79_ip3_handler(); |
168 | do_IRQ(ATH79_CPU_IRQ_USB); | ||
169 | } | ||
170 | 200 | ||
171 | else if (pending & STATUSF_IP6) | 201 | else if (pending & STATUSF_IP6) |
172 | do_IRQ(ATH79_CPU_IRQ_MISC); | 202 | do_IRQ(ATH79_CPU_IRQ_MISC); |
@@ -175,24 +205,97 @@ asmlinkage void plat_irq_dispatch(void) | |||
175 | spurious_interrupt(); | 205 | spurious_interrupt(); |
176 | } | 206 | } |
177 | 207 | ||
208 | /* | ||
209 | * The IP2/IP3 lines are tied to a PCI/WMAC/USB device. Drivers for | ||
210 | * these devices typically allocate coherent DMA memory, however the | ||
211 | * DMA controller may still have some unsynchronized data in the FIFO. | ||
212 | * Issue a flush in the handlers to ensure that the driver sees | ||
213 | * the update. | ||
214 | */ | ||
215 | static void ar71xx_ip2_handler(void) | ||
216 | { | ||
217 | ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_PCI); | ||
218 | do_IRQ(ATH79_CPU_IRQ_IP2); | ||
219 | } | ||
220 | |||
221 | static void ar724x_ip2_handler(void) | ||
222 | { | ||
223 | ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_PCIE); | ||
224 | do_IRQ(ATH79_CPU_IRQ_IP2); | ||
225 | } | ||
226 | |||
227 | static void ar913x_ip2_handler(void) | ||
228 | { | ||
229 | ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_WMAC); | ||
230 | do_IRQ(ATH79_CPU_IRQ_IP2); | ||
231 | } | ||
232 | |||
233 | static void ar933x_ip2_handler(void) | ||
234 | { | ||
235 | ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_WMAC); | ||
236 | do_IRQ(ATH79_CPU_IRQ_IP2); | ||
237 | } | ||
238 | |||
239 | static void ar934x_ip2_handler(void) | ||
240 | { | ||
241 | do_IRQ(ATH79_CPU_IRQ_IP2); | ||
242 | } | ||
243 | |||
244 | static void ar71xx_ip3_handler(void) | ||
245 | { | ||
246 | ath79_ddr_wb_flush(AR71XX_DDR_REG_FLUSH_USB); | ||
247 | do_IRQ(ATH79_CPU_IRQ_USB); | ||
248 | } | ||
249 | |||
250 | static void ar724x_ip3_handler(void) | ||
251 | { | ||
252 | ath79_ddr_wb_flush(AR724X_DDR_REG_FLUSH_USB); | ||
253 | do_IRQ(ATH79_CPU_IRQ_USB); | ||
254 | } | ||
255 | |||
256 | static void ar913x_ip3_handler(void) | ||
257 | { | ||
258 | ath79_ddr_wb_flush(AR913X_DDR_REG_FLUSH_USB); | ||
259 | do_IRQ(ATH79_CPU_IRQ_USB); | ||
260 | } | ||
261 | |||
262 | static void ar933x_ip3_handler(void) | ||
263 | { | ||
264 | ath79_ddr_wb_flush(AR933X_DDR_REG_FLUSH_USB); | ||
265 | do_IRQ(ATH79_CPU_IRQ_USB); | ||
266 | } | ||
267 | |||
268 | static void ar934x_ip3_handler(void) | ||
269 | { | ||
270 | ath79_ddr_wb_flush(AR934X_DDR_REG_FLUSH_USB); | ||
271 | do_IRQ(ATH79_CPU_IRQ_USB); | ||
272 | } | ||
273 | |||
178 | void __init arch_init_irq(void) | 274 | void __init arch_init_irq(void) |
179 | { | 275 | { |
180 | if (soc_is_ar71xx()) { | 276 | if (soc_is_ar71xx()) { |
181 | ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI; | 277 | ath79_ip2_handler = ar71xx_ip2_handler; |
182 | ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB; | 278 | ath79_ip3_handler = ar71xx_ip3_handler; |
183 | } else if (soc_is_ar724x()) { | 279 | } else if (soc_is_ar724x()) { |
184 | ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE; | 280 | ath79_ip2_handler = ar724x_ip2_handler; |
185 | ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB; | 281 | ath79_ip3_handler = ar724x_ip3_handler; |
186 | } else if (soc_is_ar913x()) { | 282 | } else if (soc_is_ar913x()) { |
187 | ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC; | 283 | ath79_ip2_handler = ar913x_ip2_handler; |
188 | ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB; | 284 | ath79_ip3_handler = ar913x_ip3_handler; |
189 | } else if (soc_is_ar933x()) { | 285 | } else if (soc_is_ar933x()) { |
190 | ath79_ip2_flush_reg = AR933X_DDR_REG_FLUSH_WMAC; | 286 | ath79_ip2_handler = ar933x_ip2_handler; |
191 | ath79_ip3_flush_reg = AR933X_DDR_REG_FLUSH_USB; | 287 | ath79_ip3_handler = ar933x_ip3_handler; |
192 | } else | 288 | } else if (soc_is_ar934x()) { |
289 | ath79_ip2_handler = ar934x_ip2_handler; | ||
290 | ath79_ip3_handler = ar934x_ip3_handler; | ||
291 | } else { | ||
193 | BUG(); | 292 | BUG(); |
293 | } | ||
194 | 294 | ||
195 | cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC; | 295 | cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC; |
196 | mips_cpu_irq_init(); | 296 | mips_cpu_irq_init(); |
197 | ath79_misc_irq_init(); | 297 | ath79_misc_irq_init(); |
298 | |||
299 | if (soc_is_ar934x()) | ||
300 | ar934x_ip2_irq_init(); | ||
198 | } | 301 | } |
diff --git a/arch/mips/ath79/mach-db120.c b/arch/mips/ath79/mach-db120.c new file mode 100644 index 000000000000..1983e4d2af4b --- /dev/null +++ b/arch/mips/ath79/mach-db120.c | |||
@@ -0,0 +1,134 @@ | |||
1 | /* | ||
2 | * Atheros DB120 reference board support | ||
3 | * | ||
4 | * Copyright (c) 2011 Qualcomm Atheros | ||
5 | * Copyright (c) 2011 Gabor Juhos <juhosg@openwrt.org> | ||
6 | * | ||
7 | * Permission to use, copy, modify, and/or distribute this software for any | ||
8 | * purpose with or without fee is hereby granted, provided that the above | ||
9 | * copyright notice and this permission notice appear in all copies. | ||
10 | * | ||
11 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
12 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
13 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
14 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | #include <linux/pci.h> | ||
22 | #include <linux/ath9k_platform.h> | ||
23 | |||
24 | #include "machtypes.h" | ||
25 | #include "dev-gpio-buttons.h" | ||
26 | #include "dev-leds-gpio.h" | ||
27 | #include "dev-spi.h" | ||
28 | #include "dev-wmac.h" | ||
29 | #include "pci.h" | ||
30 | |||
31 | #define DB120_GPIO_LED_WLAN_5G 12 | ||
32 | #define DB120_GPIO_LED_WLAN_2G 13 | ||
33 | #define DB120_GPIO_LED_STATUS 14 | ||
34 | #define DB120_GPIO_LED_WPS 15 | ||
35 | |||
36 | #define DB120_GPIO_BTN_WPS 16 | ||
37 | |||
38 | #define DB120_KEYS_POLL_INTERVAL 20 /* msecs */ | ||
39 | #define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL) | ||
40 | |||
41 | #define DB120_WMAC_CALDATA_OFFSET 0x1000 | ||
42 | #define DB120_PCIE_CALDATA_OFFSET 0x5000 | ||
43 | |||
44 | static struct gpio_led db120_leds_gpio[] __initdata = { | ||
45 | { | ||
46 | .name = "db120:green:status", | ||
47 | .gpio = DB120_GPIO_LED_STATUS, | ||
48 | .active_low = 1, | ||
49 | }, | ||
50 | { | ||
51 | .name = "db120:green:wps", | ||
52 | .gpio = DB120_GPIO_LED_WPS, | ||
53 | .active_low = 1, | ||
54 | }, | ||
55 | { | ||
56 | .name = "db120:green:wlan-5g", | ||
57 | .gpio = DB120_GPIO_LED_WLAN_5G, | ||
58 | .active_low = 1, | ||
59 | }, | ||
60 | { | ||
61 | .name = "db120:green:wlan-2g", | ||
62 | .gpio = DB120_GPIO_LED_WLAN_2G, | ||
63 | .active_low = 1, | ||
64 | }, | ||
65 | }; | ||
66 | |||
67 | static struct gpio_keys_button db120_gpio_keys[] __initdata = { | ||
68 | { | ||
69 | .desc = "WPS button", | ||
70 | .type = EV_KEY, | ||
71 | .code = KEY_WPS_BUTTON, | ||
72 | .debounce_interval = DB120_KEYS_DEBOUNCE_INTERVAL, | ||
73 | .gpio = DB120_GPIO_BTN_WPS, | ||
74 | .active_low = 1, | ||
75 | }, | ||
76 | }; | ||
77 | |||
78 | static struct spi_board_info db120_spi_info[] = { | ||
79 | { | ||
80 | .bus_num = 0, | ||
81 | .chip_select = 0, | ||
82 | .max_speed_hz = 25000000, | ||
83 | .modalias = "s25sl064a", | ||
84 | } | ||
85 | }; | ||
86 | |||
87 | static struct ath79_spi_platform_data db120_spi_data = { | ||
88 | .bus_num = 0, | ||
89 | .num_chipselect = 1, | ||
90 | }; | ||
91 | |||
92 | #ifdef CONFIG_PCI | ||
93 | static struct ath9k_platform_data db120_ath9k_data; | ||
94 | |||
95 | static int db120_pci_plat_dev_init(struct pci_dev *dev) | ||
96 | { | ||
97 | switch (PCI_SLOT(dev->devfn)) { | ||
98 | case 0: | ||
99 | dev->dev.platform_data = &db120_ath9k_data; | ||
100 | break; | ||
101 | } | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
106 | static void __init db120_pci_init(u8 *eeprom) | ||
107 | { | ||
108 | memcpy(db120_ath9k_data.eeprom_data, eeprom, | ||
109 | sizeof(db120_ath9k_data.eeprom_data)); | ||
110 | |||
111 | ath79_pci_set_plat_dev_init(db120_pci_plat_dev_init); | ||
112 | ath79_register_pci(); | ||
113 | } | ||
114 | #else | ||
115 | static inline void db120_pci_init(void) {} | ||
116 | #endif /* CONFIG_PCI */ | ||
117 | |||
118 | static void __init db120_setup(void) | ||
119 | { | ||
120 | u8 *art = (u8 *) KSEG1ADDR(0x1fff0000); | ||
121 | |||
122 | ath79_register_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio), | ||
123 | db120_leds_gpio); | ||
124 | ath79_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL, | ||
125 | ARRAY_SIZE(db120_gpio_keys), | ||
126 | db120_gpio_keys); | ||
127 | ath79_register_spi(&db120_spi_data, db120_spi_info, | ||
128 | ARRAY_SIZE(db120_spi_info)); | ||
129 | ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET); | ||
130 | db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET); | ||
131 | } | ||
132 | |||
133 | MIPS_MACHINE(ATH79_MACH_DB120, "DB120", "Atheros DB120 reference board", | ||
134 | db120_setup); | ||
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c index fe9701a32291..c5f0ea5e00c3 100644 --- a/arch/mips/ath79/mach-pb44.c +++ b/arch/mips/ath79/mach-pb44.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include "dev-leds-gpio.h" | 19 | #include "dev-leds-gpio.h" |
20 | #include "dev-spi.h" | 20 | #include "dev-spi.h" |
21 | #include "dev-usb.h" | 21 | #include "dev-usb.h" |
22 | #include "pci.h" | ||
22 | 23 | ||
23 | #define PB44_GPIO_I2C_SCL 0 | 24 | #define PB44_GPIO_I2C_SCL 0 |
24 | #define PB44_GPIO_I2C_SDA 1 | 25 | #define PB44_GPIO_I2C_SDA 1 |
@@ -114,6 +115,7 @@ static void __init pb44_init(void) | |||
114 | ath79_register_spi(&pb44_spi_data, pb44_spi_info, | 115 | ath79_register_spi(&pb44_spi_data, pb44_spi_info, |
115 | ARRAY_SIZE(pb44_spi_info)); | 116 | ARRAY_SIZE(pb44_spi_info)); |
116 | ath79_register_usb(); | 117 | ath79_register_usb(); |
118 | ath79_register_pci(); | ||
117 | } | 119 | } |
118 | 120 | ||
119 | MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board", | 121 | MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board", |
diff --git a/arch/mips/ath79/mach-ubnt-xm.c b/arch/mips/ath79/mach-ubnt-xm.c index 3c311a539347..4a3c60694c75 100644 --- a/arch/mips/ath79/mach-ubnt-xm.c +++ b/arch/mips/ath79/mach-ubnt-xm.c | |||
@@ -12,16 +12,15 @@ | |||
12 | 12 | ||
13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
14 | #include <linux/pci.h> | 14 | #include <linux/pci.h> |
15 | |||
16 | #ifdef CONFIG_PCI | ||
17 | #include <linux/ath9k_platform.h> | 15 | #include <linux/ath9k_platform.h> |
18 | #include <asm/mach-ath79/pci-ath724x.h> | 16 | |
19 | #endif /* CONFIG_PCI */ | 17 | #include <asm/mach-ath79/irq.h> |
20 | 18 | ||
21 | #include "machtypes.h" | 19 | #include "machtypes.h" |
22 | #include "dev-gpio-buttons.h" | 20 | #include "dev-gpio-buttons.h" |
23 | #include "dev-leds-gpio.h" | 21 | #include "dev-leds-gpio.h" |
24 | #include "dev-spi.h" | 22 | #include "dev-spi.h" |
23 | #include "pci.h" | ||
25 | 24 | ||
26 | #define UBNT_XM_GPIO_LED_L1 0 | 25 | #define UBNT_XM_GPIO_LED_L1 0 |
27 | #define UBNT_XM_GPIO_LED_L2 1 | 26 | #define UBNT_XM_GPIO_LED_L2 1 |
@@ -33,7 +32,6 @@ | |||
33 | #define UBNT_XM_KEYS_POLL_INTERVAL 20 | 32 | #define UBNT_XM_KEYS_POLL_INTERVAL 20 |
34 | #define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL) | 33 | #define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL) |
35 | 34 | ||
36 | #define UBNT_XM_PCI_IRQ 48 | ||
37 | #define UBNT_XM_EEPROM_ADDR (u8 *) KSEG1ADDR(0x1fff1000) | 35 | #define UBNT_XM_EEPROM_ADDR (u8 *) KSEG1ADDR(0x1fff1000) |
38 | 36 | ||
39 | static struct gpio_led ubnt_xm_leds_gpio[] __initdata = { | 37 | static struct gpio_led ubnt_xm_leds_gpio[] __initdata = { |
@@ -84,12 +82,27 @@ static struct ath79_spi_platform_data ubnt_xm_spi_data = { | |||
84 | #ifdef CONFIG_PCI | 82 | #ifdef CONFIG_PCI |
85 | static struct ath9k_platform_data ubnt_xm_eeprom_data; | 83 | static struct ath9k_platform_data ubnt_xm_eeprom_data; |
86 | 84 | ||
87 | static struct ath724x_pci_data ubnt_xm_pci_data[] = { | 85 | static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev) |
88 | { | 86 | { |
89 | .irq = UBNT_XM_PCI_IRQ, | 87 | switch (PCI_SLOT(dev->devfn)) { |
90 | .pdata = &ubnt_xm_eeprom_data, | 88 | case 0: |
91 | }, | 89 | dev->dev.platform_data = &ubnt_xm_eeprom_data; |
92 | }; | 90 | break; |
91 | } | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | static void __init ubnt_xm_pci_init(void) | ||
97 | { | ||
98 | memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR, | ||
99 | sizeof(ubnt_xm_eeprom_data.eeprom_data)); | ||
100 | |||
101 | ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init); | ||
102 | ath79_register_pci(); | ||
103 | } | ||
104 | #else | ||
105 | static inline void ubnt_xm_pci_init(void) {} | ||
93 | #endif /* CONFIG_PCI */ | 106 | #endif /* CONFIG_PCI */ |
94 | 107 | ||
95 | static void __init ubnt_xm_init(void) | 108 | static void __init ubnt_xm_init(void) |
@@ -104,13 +117,7 @@ static void __init ubnt_xm_init(void) | |||
104 | ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info, | 117 | ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info, |
105 | ARRAY_SIZE(ubnt_xm_spi_info)); | 118 | ARRAY_SIZE(ubnt_xm_spi_info)); |
106 | 119 | ||
107 | #ifdef CONFIG_PCI | 120 | ubnt_xm_pci_init(); |
108 | memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR, | ||
109 | sizeof(ubnt_xm_eeprom_data.eeprom_data)); | ||
110 | |||
111 | ath724x_pci_add_data(ubnt_xm_pci_data, ARRAY_SIZE(ubnt_xm_pci_data)); | ||
112 | #endif /* CONFIG_PCI */ | ||
113 | |||
114 | } | 121 | } |
115 | 122 | ||
116 | MIPS_MACHINE(ATH79_MACH_UBNT_XM, | 123 | MIPS_MACHINE(ATH79_MACH_UBNT_XM, |
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h index 9a1f3826626e..af92e5c30d66 100644 --- a/arch/mips/ath79/machtypes.h +++ b/arch/mips/ath79/machtypes.h | |||
@@ -18,6 +18,7 @@ enum ath79_mach_type { | |||
18 | ATH79_MACH_GENERIC = 0, | 18 | ATH79_MACH_GENERIC = 0, |
19 | ATH79_MACH_AP121, /* Atheros AP121 reference board */ | 19 | ATH79_MACH_AP121, /* Atheros AP121 reference board */ |
20 | ATH79_MACH_AP81, /* Atheros AP81 reference board */ | 20 | ATH79_MACH_AP81, /* Atheros AP81 reference board */ |
21 | ATH79_MACH_DB120, /* Atheros DB120 reference board */ | ||
21 | ATH79_MACH_PB44, /* Atheros PB44 reference board */ | 22 | ATH79_MACH_PB44, /* Atheros PB44 reference board */ |
22 | ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */ | 23 | ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */ |
23 | }; | 24 | }; |
diff --git a/arch/mips/ath79/pci.c b/arch/mips/ath79/pci.c new file mode 100644 index 000000000000..ca83abd9d31e --- /dev/null +++ b/arch/mips/ath79/pci.c | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X specific PCI setup code | ||
3 | * | ||
4 | * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com> | ||
5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
7 | * | ||
8 | * Parts of this file are based on Atheros' 2.6.15 BSP | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License version 2 as published | ||
12 | * by the Free Software Foundation. | ||
13 | */ | ||
14 | |||
15 | #include <linux/init.h> | ||
16 | #include <linux/pci.h> | ||
17 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
18 | #include <asm/mach-ath79/ath79.h> | ||
19 | #include <asm/mach-ath79/irq.h> | ||
20 | #include <asm/mach-ath79/pci.h> | ||
21 | #include "pci.h" | ||
22 | |||
23 | static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev); | ||
24 | static const struct ath79_pci_irq *ath79_pci_irq_map __initdata; | ||
25 | static unsigned ath79_pci_nr_irqs __initdata; | ||
26 | |||
27 | static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = { | ||
28 | { | ||
29 | .slot = 17, | ||
30 | .pin = 1, | ||
31 | .irq = ATH79_PCI_IRQ(0), | ||
32 | }, { | ||
33 | .slot = 18, | ||
34 | .pin = 1, | ||
35 | .irq = ATH79_PCI_IRQ(1), | ||
36 | }, { | ||
37 | .slot = 19, | ||
38 | .pin = 1, | ||
39 | .irq = ATH79_PCI_IRQ(2), | ||
40 | } | ||
41 | }; | ||
42 | |||
43 | static const struct ath79_pci_irq ar724x_pci_irq_map[] __initconst = { | ||
44 | { | ||
45 | .slot = 0, | ||
46 | .pin = 1, | ||
47 | .irq = ATH79_PCI_IRQ(0), | ||
48 | } | ||
49 | }; | ||
50 | |||
51 | int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) | ||
52 | { | ||
53 | int irq = -1; | ||
54 | int i; | ||
55 | |||
56 | if (ath79_pci_nr_irqs == 0 || | ||
57 | ath79_pci_irq_map == NULL) { | ||
58 | if (soc_is_ar71xx()) { | ||
59 | ath79_pci_irq_map = ar71xx_pci_irq_map; | ||
60 | ath79_pci_nr_irqs = ARRAY_SIZE(ar71xx_pci_irq_map); | ||
61 | } else if (soc_is_ar724x() || | ||
62 | soc_is_ar9342() || | ||
63 | soc_is_ar9344()) { | ||
64 | ath79_pci_irq_map = ar724x_pci_irq_map; | ||
65 | ath79_pci_nr_irqs = ARRAY_SIZE(ar724x_pci_irq_map); | ||
66 | } else { | ||
67 | pr_crit("pci %s: invalid irq map\n", | ||
68 | pci_name((struct pci_dev *) dev)); | ||
69 | return irq; | ||
70 | } | ||
71 | } | ||
72 | |||
73 | for (i = 0; i < ath79_pci_nr_irqs; i++) { | ||
74 | const struct ath79_pci_irq *entry; | ||
75 | |||
76 | entry = &ath79_pci_irq_map[i]; | ||
77 | if (entry->slot == slot && entry->pin == pin) { | ||
78 | irq = entry->irq; | ||
79 | break; | ||
80 | } | ||
81 | } | ||
82 | |||
83 | if (irq < 0) | ||
84 | pr_crit("pci %s: no irq found for pin %u\n", | ||
85 | pci_name((struct pci_dev *) dev), pin); | ||
86 | else | ||
87 | pr_info("pci %s: using irq %d for pin %u\n", | ||
88 | pci_name((struct pci_dev *) dev), irq, pin); | ||
89 | |||
90 | return irq; | ||
91 | } | ||
92 | |||
93 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
94 | { | ||
95 | if (ath79_pci_plat_dev_init) | ||
96 | return ath79_pci_plat_dev_init(dev); | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | void __init ath79_pci_set_irq_map(unsigned nr_irqs, | ||
102 | const struct ath79_pci_irq *map) | ||
103 | { | ||
104 | ath79_pci_nr_irqs = nr_irqs; | ||
105 | ath79_pci_irq_map = map; | ||
106 | } | ||
107 | |||
108 | void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)) | ||
109 | { | ||
110 | ath79_pci_plat_dev_init = func; | ||
111 | } | ||
112 | |||
113 | int __init ath79_register_pci(void) | ||
114 | { | ||
115 | if (soc_is_ar71xx()) | ||
116 | return ar71xx_pcibios_init(); | ||
117 | |||
118 | if (soc_is_ar724x()) | ||
119 | return ar724x_pcibios_init(ATH79_CPU_IRQ_IP2); | ||
120 | |||
121 | if (soc_is_ar9342() || soc_is_ar9344()) { | ||
122 | u32 bootstrap; | ||
123 | |||
124 | bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP); | ||
125 | if (bootstrap & AR934X_BOOTSTRAP_PCIE_RC) | ||
126 | return ar724x_pcibios_init(ATH79_IP2_IRQ(0)); | ||
127 | } | ||
128 | |||
129 | return -ENODEV; | ||
130 | } | ||
diff --git a/arch/mips/ath79/pci.h b/arch/mips/ath79/pci.h new file mode 100644 index 000000000000..51c6625dcc6d --- /dev/null +++ b/arch/mips/ath79/pci.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X PCI support | ||
3 | * | ||
4 | * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com> | ||
5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
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 version 2 as published | ||
10 | * by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef _ATH79_PCI_H | ||
14 | #define _ATH79_PCI_H | ||
15 | |||
16 | struct ath79_pci_irq { | ||
17 | u8 slot; | ||
18 | u8 pin; | ||
19 | int irq; | ||
20 | }; | ||
21 | |||
22 | #ifdef CONFIG_PCI | ||
23 | void ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map); | ||
24 | void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev)); | ||
25 | int ath79_register_pci(void); | ||
26 | #else | ||
27 | static inline void | ||
28 | ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map) {} | ||
29 | static inline void | ||
30 | ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {} | ||
31 | static inline int ath79_register_pci(void) { return 0; } | ||
32 | #endif | ||
33 | |||
34 | #endif /* _ATH79_PCI_H */ | ||
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index 80a7d4023d7f..60d212ef8629 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c | |||
@@ -1,10 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * Atheros AR71XX/AR724X/AR913X specific setup | 2 | * Atheros AR71XX/AR724X/AR913X specific setup |
3 | * | 3 | * |
4 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> | ||
4 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | 5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> |
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
6 | * | 7 | * |
7 | * Parts of this file are based on Atheros' 2.6.15 BSP | 8 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP |
8 | * | 9 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License version 2 as published | 11 | * under the terms of the GNU General Public License version 2 as published |
@@ -116,18 +117,6 @@ static void __init ath79_detect_sys_type(void) | |||
116 | rev = id & AR724X_REV_ID_REVISION_MASK; | 117 | rev = id & AR724X_REV_ID_REVISION_MASK; |
117 | break; | 118 | break; |
118 | 119 | ||
119 | case REV_ID_MAJOR_AR9330: | ||
120 | ath79_soc = ATH79_SOC_AR9330; | ||
121 | chip = "9330"; | ||
122 | rev = id & AR933X_REV_ID_REVISION_MASK; | ||
123 | break; | ||
124 | |||
125 | case REV_ID_MAJOR_AR9331: | ||
126 | ath79_soc = ATH79_SOC_AR9331; | ||
127 | chip = "9331"; | ||
128 | rev = id & AR933X_REV_ID_REVISION_MASK; | ||
129 | break; | ||
130 | |||
131 | case REV_ID_MAJOR_AR913X: | 120 | case REV_ID_MAJOR_AR913X: |
132 | minor = id & AR913X_REV_ID_MINOR_MASK; | 121 | minor = id & AR913X_REV_ID_MINOR_MASK; |
133 | rev = id >> AR913X_REV_ID_REVISION_SHIFT; | 122 | rev = id >> AR913X_REV_ID_REVISION_SHIFT; |
@@ -145,6 +134,36 @@ static void __init ath79_detect_sys_type(void) | |||
145 | } | 134 | } |
146 | break; | 135 | break; |
147 | 136 | ||
137 | case REV_ID_MAJOR_AR9330: | ||
138 | ath79_soc = ATH79_SOC_AR9330; | ||
139 | chip = "9330"; | ||
140 | rev = id & AR933X_REV_ID_REVISION_MASK; | ||
141 | break; | ||
142 | |||
143 | case REV_ID_MAJOR_AR9331: | ||
144 | ath79_soc = ATH79_SOC_AR9331; | ||
145 | chip = "9331"; | ||
146 | rev = id & AR933X_REV_ID_REVISION_MASK; | ||
147 | break; | ||
148 | |||
149 | case REV_ID_MAJOR_AR9341: | ||
150 | ath79_soc = ATH79_SOC_AR9341; | ||
151 | chip = "9341"; | ||
152 | rev = id & AR934X_REV_ID_REVISION_MASK; | ||
153 | break; | ||
154 | |||
155 | case REV_ID_MAJOR_AR9342: | ||
156 | ath79_soc = ATH79_SOC_AR9342; | ||
157 | chip = "9342"; | ||
158 | rev = id & AR934X_REV_ID_REVISION_MASK; | ||
159 | break; | ||
160 | |||
161 | case REV_ID_MAJOR_AR9344: | ||
162 | ath79_soc = ATH79_SOC_AR9344; | ||
163 | chip = "9344"; | ||
164 | rev = id & AR934X_REV_ID_REVISION_MASK; | ||
165 | break; | ||
166 | |||
148 | default: | 167 | default: |
149 | panic("ath79: unknown SoC, id:0x%08x", id); | 168 | panic("ath79: unknown SoC, id:0x%08x", id); |
150 | } | 169 | } |
diff --git a/arch/mips/bcm63xx/boards/Makefile b/arch/mips/bcm63xx/boards/Makefile index 9f64fb414077..af07c1aa202f 100644 --- a/arch/mips/bcm63xx/boards/Makefile +++ b/arch/mips/bcm63xx/boards/Makefile | |||
@@ -1,3 +1 @@ | |||
1 | obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o | obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o | |
2 | |||
3 | ccflags-y := -Werror | ||
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c index d3a9f012aa0a..260dc247c052 100644 --- a/arch/mips/cavium-octeon/setup.c +++ b/arch/mips/cavium-octeon/setup.c | |||
@@ -9,6 +9,7 @@ | |||
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/console.h> | 10 | #include <linux/console.h> |
11 | #include <linux/delay.h> | 11 | #include <linux/delay.h> |
12 | #include <linux/export.h> | ||
12 | #include <linux/interrupt.h> | 13 | #include <linux/interrupt.h> |
13 | #include <linux/io.h> | 14 | #include <linux/io.h> |
14 | #include <linux/serial.h> | 15 | #include <linux/serial.h> |
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c index 97e7ce9b50ed..4b93048044eb 100644 --- a/arch/mips/cavium-octeon/smp.c +++ b/arch/mips/cavium-octeon/smp.c | |||
@@ -257,8 +257,6 @@ DEFINE_PER_CPU(int, cpu_state); | |||
257 | 257 | ||
258 | extern void fixup_irqs(void); | 258 | extern void fixup_irqs(void); |
259 | 259 | ||
260 | static DEFINE_SPINLOCK(smp_reserve_lock); | ||
261 | |||
262 | static int octeon_cpu_disable(void) | 260 | static int octeon_cpu_disable(void) |
263 | { | 261 | { |
264 | unsigned int cpu = smp_processor_id(); | 262 | unsigned int cpu = smp_processor_id(); |
@@ -266,8 +264,6 @@ static int octeon_cpu_disable(void) | |||
266 | if (cpu == 0) | 264 | if (cpu == 0) |
267 | return -EBUSY; | 265 | return -EBUSY; |
268 | 266 | ||
269 | spin_lock(&smp_reserve_lock); | ||
270 | |||
271 | set_cpu_online(cpu, false); | 267 | set_cpu_online(cpu, false); |
272 | cpu_clear(cpu, cpu_callin_map); | 268 | cpu_clear(cpu, cpu_callin_map); |
273 | local_irq_disable(); | 269 | local_irq_disable(); |
@@ -277,8 +273,6 @@ static int octeon_cpu_disable(void) | |||
277 | flush_cache_all(); | 273 | flush_cache_all(); |
278 | local_flush_tlb_all(); | 274 | local_flush_tlb_all(); |
279 | 275 | ||
280 | spin_unlock(&smp_reserve_lock); | ||
281 | |||
282 | return 0; | 276 | return 0; |
283 | } | 277 | } |
284 | 278 | ||
diff --git a/arch/mips/fw/arc/Makefile b/arch/mips/fw/arc/Makefile index 5314b37aff2c..4f349ec1ea2d 100644 --- a/arch/mips/fw/arc/Makefile +++ b/arch/mips/fw/arc/Makefile | |||
@@ -8,5 +8,3 @@ lib-y += cmdline.o env.o file.o identify.o init.o \ | |||
8 | lib-$(CONFIG_ARC_MEMORY) += memory.o | 8 | lib-$(CONFIG_ARC_MEMORY) += memory.o |
9 | lib-$(CONFIG_ARC_CONSOLE) += arc_con.o | 9 | lib-$(CONFIG_ARC_CONSOLE) += arc_con.o |
10 | lib-$(CONFIG_ARC_PROMLIB) += promlib.o | 10 | lib-$(CONFIG_ARC_PROMLIB) += promlib.o |
11 | |||
12 | ccflags-y := -Werror | ||
diff --git a/arch/mips/include/asm/clkdev.h b/arch/mips/include/asm/clkdev.h new file mode 100644 index 000000000000..262475414e5f --- /dev/null +++ b/arch/mips/include/asm/clkdev.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * based on arch/arm/include/asm/clkdev.h | ||
3 | * | ||
4 | * Copyright (C) 2008 Russell King. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * Helper for the clk API to assist looking up a struct clk. | ||
11 | */ | ||
12 | #ifndef __ASM_CLKDEV_H | ||
13 | #define __ASM_CLKDEV_H | ||
14 | |||
15 | #include <linux/slab.h> | ||
16 | |||
17 | #define __clk_get(clk) ({ 1; }) | ||
18 | #define __clk_put(clk) do { } while (0) | ||
19 | |||
20 | static inline struct clk_lookup_alloc *__clkdev_alloc(size_t size) | ||
21 | { | ||
22 | return kzalloc(size, GFP_KERNEL); | ||
23 | } | ||
24 | |||
25 | #endif | ||
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h index 2f0becb4ec8f..1caa78ad06d5 100644 --- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h +++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h | |||
@@ -1,10 +1,11 @@ | |||
1 | /* | 1 | /* |
2 | * Atheros AR71XX/AR724X/AR913X SoC register definitions | 2 | * Atheros AR71XX/AR724X/AR913X SoC register definitions |
3 | * | 3 | * |
4 | * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com> | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | 5 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> |
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | 6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> |
6 | * | 7 | * |
7 | * Parts of this file are based on Atheros' 2.6.15 BSP | 8 | * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP |
8 | * | 9 | * |
9 | * This program is free software; you can redistribute it and/or modify it | 10 | * This program is free software; you can redistribute it and/or modify it |
10 | * under the terms of the GNU General Public License version 2 as published | 11 | * under the terms of the GNU General Public License version 2 as published |
@@ -60,6 +61,9 @@ | |||
60 | #define AR933X_EHCI_BASE 0x1b000000 | 61 | #define AR933X_EHCI_BASE 0x1b000000 |
61 | #define AR933X_EHCI_SIZE 0x1000 | 62 | #define AR933X_EHCI_SIZE 0x1000 |
62 | 63 | ||
64 | #define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000) | ||
65 | #define AR934X_WMAC_SIZE 0x20000 | ||
66 | |||
63 | /* | 67 | /* |
64 | * DDR_CTRL block | 68 | * DDR_CTRL block |
65 | */ | 69 | */ |
@@ -91,6 +95,12 @@ | |||
91 | #define AR933X_DDR_REG_FLUSH_USB 0x84 | 95 | #define AR933X_DDR_REG_FLUSH_USB 0x84 |
92 | #define AR933X_DDR_REG_FLUSH_WMAC 0x88 | 96 | #define AR933X_DDR_REG_FLUSH_WMAC 0x88 |
93 | 97 | ||
98 | #define AR934X_DDR_REG_FLUSH_GE0 0x9c | ||
99 | #define AR934X_DDR_REG_FLUSH_GE1 0xa0 | ||
100 | #define AR934X_DDR_REG_FLUSH_USB 0xa4 | ||
101 | #define AR934X_DDR_REG_FLUSH_PCIE 0xa8 | ||
102 | #define AR934X_DDR_REG_FLUSH_WMAC 0xac | ||
103 | |||
94 | /* | 104 | /* |
95 | * PLL block | 105 | * PLL block |
96 | */ | 106 | */ |
@@ -150,6 +160,41 @@ | |||
150 | #define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15 | 160 | #define AR933X_PLL_CLOCK_CTRL_AHB_DIV_SHIFT 15 |
151 | #define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7 | 161 | #define AR933X_PLL_CLOCK_CTRL_AHB_DIV_MASK 0x7 |
152 | 162 | ||
163 | #define AR934X_PLL_CPU_CONFIG_REG 0x00 | ||
164 | #define AR934X_PLL_DDR_CONFIG_REG 0x04 | ||
165 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_REG 0x08 | ||
166 | |||
167 | #define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT 0 | ||
168 | #define AR934X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f | ||
169 | #define AR934X_PLL_CPU_CONFIG_NINT_SHIFT 6 | ||
170 | #define AR934X_PLL_CPU_CONFIG_NINT_MASK 0x3f | ||
171 | #define AR934X_PLL_CPU_CONFIG_REFDIV_SHIFT 12 | ||
172 | #define AR934X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f | ||
173 | #define AR934X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19 | ||
174 | #define AR934X_PLL_CPU_CONFIG_OUTDIV_MASK 0x3 | ||
175 | |||
176 | #define AR934X_PLL_DDR_CONFIG_NFRAC_SHIFT 0 | ||
177 | #define AR934X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff | ||
178 | #define AR934X_PLL_DDR_CONFIG_NINT_SHIFT 10 | ||
179 | #define AR934X_PLL_DDR_CONFIG_NINT_MASK 0x3f | ||
180 | #define AR934X_PLL_DDR_CONFIG_REFDIV_SHIFT 16 | ||
181 | #define AR934X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f | ||
182 | #define AR934X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23 | ||
183 | #define AR934X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7 | ||
184 | |||
185 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_PLL_BYPASS BIT(2) | ||
186 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_PLL_BYPASS BIT(3) | ||
187 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_PLL_BYPASS BIT(4) | ||
188 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_SHIFT 5 | ||
189 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_CPU_POST_DIV_MASK 0x1f | ||
190 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_SHIFT 10 | ||
191 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_DDR_POST_DIV_MASK 0x1f | ||
192 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_SHIFT 15 | ||
193 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHB_POST_DIV_MASK 0x1f | ||
194 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20) | ||
195 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21) | ||
196 | #define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24) | ||
197 | |||
153 | /* | 198 | /* |
154 | * USB_CONFIG block | 199 | * USB_CONFIG block |
155 | */ | 200 | */ |
@@ -185,6 +230,10 @@ | |||
185 | #define AR933X_RESET_REG_RESET_MODULE 0x1c | 230 | #define AR933X_RESET_REG_RESET_MODULE 0x1c |
186 | #define AR933X_RESET_REG_BOOTSTRAP 0xac | 231 | #define AR933X_RESET_REG_BOOTSTRAP 0xac |
187 | 232 | ||
233 | #define AR934X_RESET_REG_RESET_MODULE 0x1c | ||
234 | #define AR934X_RESET_REG_BOOTSTRAP 0xb0 | ||
235 | #define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac | ||
236 | |||
188 | #define MISC_INT_ETHSW BIT(12) | 237 | #define MISC_INT_ETHSW BIT(12) |
189 | #define MISC_INT_TIMER4 BIT(10) | 238 | #define MISC_INT_TIMER4 BIT(10) |
190 | #define MISC_INT_TIMER3 BIT(9) | 239 | #define MISC_INT_TIMER3 BIT(9) |
@@ -241,6 +290,40 @@ | |||
241 | 290 | ||
242 | #define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) | 291 | #define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0) |
243 | 292 | ||
293 | #define AR934X_BOOTSTRAP_SW_OPTION8 BIT(23) | ||
294 | #define AR934X_BOOTSTRAP_SW_OPTION7 BIT(22) | ||
295 | #define AR934X_BOOTSTRAP_SW_OPTION6 BIT(21) | ||
296 | #define AR934X_BOOTSTRAP_SW_OPTION5 BIT(20) | ||
297 | #define AR934X_BOOTSTRAP_SW_OPTION4 BIT(19) | ||
298 | #define AR934X_BOOTSTRAP_SW_OPTION3 BIT(18) | ||
299 | #define AR934X_BOOTSTRAP_SW_OPTION2 BIT(17) | ||
300 | #define AR934X_BOOTSTRAP_SW_OPTION1 BIT(16) | ||
301 | #define AR934X_BOOTSTRAP_USB_MODE_DEVICE BIT(7) | ||
302 | #define AR934X_BOOTSTRAP_PCIE_RC BIT(6) | ||
303 | #define AR934X_BOOTSTRAP_EJTAG_MODE BIT(5) | ||
304 | #define AR934X_BOOTSTRAP_REF_CLK_40 BIT(4) | ||
305 | #define AR934X_BOOTSTRAP_BOOT_FROM_SPI BIT(2) | ||
306 | #define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1) | ||
307 | #define AR934X_BOOTSTRAP_DDR1 BIT(0) | ||
308 | |||
309 | #define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0) | ||
310 | #define AR934X_PCIE_WMAC_INT_WMAC_TX BIT(1) | ||
311 | #define AR934X_PCIE_WMAC_INT_WMAC_RXLP BIT(2) | ||
312 | #define AR934X_PCIE_WMAC_INT_WMAC_RXHP BIT(3) | ||
313 | #define AR934X_PCIE_WMAC_INT_PCIE_RC BIT(4) | ||
314 | #define AR934X_PCIE_WMAC_INT_PCIE_RC0 BIT(5) | ||
315 | #define AR934X_PCIE_WMAC_INT_PCIE_RC1 BIT(6) | ||
316 | #define AR934X_PCIE_WMAC_INT_PCIE_RC2 BIT(7) | ||
317 | #define AR934X_PCIE_WMAC_INT_PCIE_RC3 BIT(8) | ||
318 | #define AR934X_PCIE_WMAC_INT_WMAC_ALL \ | ||
319 | (AR934X_PCIE_WMAC_INT_WMAC_MISC | AR934X_PCIE_WMAC_INT_WMAC_TX | \ | ||
320 | AR934X_PCIE_WMAC_INT_WMAC_RXLP | AR934X_PCIE_WMAC_INT_WMAC_RXHP) | ||
321 | |||
322 | #define AR934X_PCIE_WMAC_INT_PCIE_ALL \ | ||
323 | (AR934X_PCIE_WMAC_INT_PCIE_RC | AR934X_PCIE_WMAC_INT_PCIE_RC0 | \ | ||
324 | AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \ | ||
325 | AR934X_PCIE_WMAC_INT_PCIE_RC3) | ||
326 | |||
244 | #define REV_ID_MAJOR_MASK 0xfff0 | 327 | #define REV_ID_MAJOR_MASK 0xfff0 |
245 | #define REV_ID_MAJOR_AR71XX 0x00a0 | 328 | #define REV_ID_MAJOR_AR71XX 0x00a0 |
246 | #define REV_ID_MAJOR_AR913X 0x00b0 | 329 | #define REV_ID_MAJOR_AR913X 0x00b0 |
@@ -249,6 +332,9 @@ | |||
249 | #define REV_ID_MAJOR_AR7242 0x1100 | 332 | #define REV_ID_MAJOR_AR7242 0x1100 |
250 | #define REV_ID_MAJOR_AR9330 0x0110 | 333 | #define REV_ID_MAJOR_AR9330 0x0110 |
251 | #define REV_ID_MAJOR_AR9331 0x1110 | 334 | #define REV_ID_MAJOR_AR9331 0x1110 |
335 | #define REV_ID_MAJOR_AR9341 0x0120 | ||
336 | #define REV_ID_MAJOR_AR9342 0x1120 | ||
337 | #define REV_ID_MAJOR_AR9344 0x2120 | ||
252 | 338 | ||
253 | #define AR71XX_REV_ID_MINOR_MASK 0x3 | 339 | #define AR71XX_REV_ID_MINOR_MASK 0x3 |
254 | #define AR71XX_REV_ID_MINOR_AR7130 0x0 | 340 | #define AR71XX_REV_ID_MINOR_AR7130 0x0 |
@@ -267,6 +353,8 @@ | |||
267 | 353 | ||
268 | #define AR724X_REV_ID_REVISION_MASK 0x3 | 354 | #define AR724X_REV_ID_REVISION_MASK 0x3 |
269 | 355 | ||
356 | #define AR934X_REV_ID_REVISION_MASK 0xf | ||
357 | |||
270 | /* | 358 | /* |
271 | * SPI block | 359 | * SPI block |
272 | */ | 360 | */ |
@@ -308,5 +396,6 @@ | |||
308 | #define AR724X_GPIO_COUNT 18 | 396 | #define AR724X_GPIO_COUNT 18 |
309 | #define AR913X_GPIO_COUNT 22 | 397 | #define AR913X_GPIO_COUNT 22 |
310 | #define AR933X_GPIO_COUNT 30 | 398 | #define AR933X_GPIO_COUNT 30 |
399 | #define AR934X_GPIO_COUNT 23 | ||
311 | 400 | ||
312 | #endif /* __ASM_MACH_AR71XX_REGS_H */ | 401 | #endif /* __ASM_MACH_AR71XX_REGS_H */ |
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h index 6d0c6c9d5622..4f248c3d7b23 100644 --- a/arch/mips/include/asm/mach-ath79/ath79.h +++ b/arch/mips/include/asm/mach-ath79/ath79.h | |||
@@ -29,6 +29,9 @@ enum ath79_soc_type { | |||
29 | ATH79_SOC_AR9132, | 29 | ATH79_SOC_AR9132, |
30 | ATH79_SOC_AR9330, | 30 | ATH79_SOC_AR9330, |
31 | ATH79_SOC_AR9331, | 31 | ATH79_SOC_AR9331, |
32 | ATH79_SOC_AR9341, | ||
33 | ATH79_SOC_AR9342, | ||
34 | ATH79_SOC_AR9344, | ||
32 | }; | 35 | }; |
33 | 36 | ||
34 | extern enum ath79_soc_type ath79_soc; | 37 | extern enum ath79_soc_type ath79_soc; |
@@ -75,6 +78,26 @@ static inline int soc_is_ar933x(void) | |||
75 | ath79_soc == ATH79_SOC_AR9331); | 78 | ath79_soc == ATH79_SOC_AR9331); |
76 | } | 79 | } |
77 | 80 | ||
81 | static inline int soc_is_ar9341(void) | ||
82 | { | ||
83 | return (ath79_soc == ATH79_SOC_AR9341); | ||
84 | } | ||
85 | |||
86 | static inline int soc_is_ar9342(void) | ||
87 | { | ||
88 | return (ath79_soc == ATH79_SOC_AR9342); | ||
89 | } | ||
90 | |||
91 | static inline int soc_is_ar9344(void) | ||
92 | { | ||
93 | return (ath79_soc == ATH79_SOC_AR9344); | ||
94 | } | ||
95 | |||
96 | static inline int soc_is_ar934x(void) | ||
97 | { | ||
98 | return soc_is_ar9341() || soc_is_ar9342() || soc_is_ar9344(); | ||
99 | } | ||
100 | |||
78 | extern void __iomem *ath79_ddr_base; | 101 | extern void __iomem *ath79_ddr_base; |
79 | extern void __iomem *ath79_pll_base; | 102 | extern void __iomem *ath79_pll_base; |
80 | extern void __iomem *ath79_reset_base; | 103 | extern void __iomem *ath79_reset_base; |
diff --git a/arch/mips/include/asm/mach-ath79/irq.h b/arch/mips/include/asm/mach-ath79/irq.h index 519958fe4e3c..0968f69e2018 100644 --- a/arch/mips/include/asm/mach-ath79/irq.h +++ b/arch/mips/include/asm/mach-ath79/irq.h | |||
@@ -10,11 +10,19 @@ | |||
10 | #define __ASM_MACH_ATH79_IRQ_H | 10 | #define __ASM_MACH_ATH79_IRQ_H |
11 | 11 | ||
12 | #define MIPS_CPU_IRQ_BASE 0 | 12 | #define MIPS_CPU_IRQ_BASE 0 |
13 | #define NR_IRQS 40 | 13 | #define NR_IRQS 48 |
14 | 14 | ||
15 | #define ATH79_MISC_IRQ_BASE 8 | 15 | #define ATH79_MISC_IRQ_BASE 8 |
16 | #define ATH79_MISC_IRQ_COUNT 32 | 16 | #define ATH79_MISC_IRQ_COUNT 32 |
17 | 17 | ||
18 | #define ATH79_PCI_IRQ_BASE (ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT) | ||
19 | #define ATH79_PCI_IRQ_COUNT 6 | ||
20 | #define ATH79_PCI_IRQ(_x) (ATH79_PCI_IRQ_BASE + (_x)) | ||
21 | |||
22 | #define ATH79_IP2_IRQ_BASE (ATH79_PCI_IRQ_BASE + ATH79_PCI_IRQ_COUNT) | ||
23 | #define ATH79_IP2_IRQ_COUNT 2 | ||
24 | #define ATH79_IP2_IRQ(_x) (ATH79_IP2_IRQ_BASE + (_x)) | ||
25 | |||
18 | #define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2) | 26 | #define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2) |
19 | #define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3) | 27 | #define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3) |
20 | #define ATH79_CPU_IRQ_GE0 (MIPS_CPU_IRQ_BASE + 4) | 28 | #define ATH79_CPU_IRQ_GE0 (MIPS_CPU_IRQ_BASE + 4) |
diff --git a/arch/mips/include/asm/mach-ath79/pci-ath724x.h b/arch/mips/include/asm/mach-ath79/pci-ath724x.h deleted file mode 100644 index 454885fa30c3..000000000000 --- a/arch/mips/include/asm/mach-ath79/pci-ath724x.h +++ /dev/null | |||
@@ -1,21 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros 724x PCI support | ||
3 | * | ||
4 | * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published | ||
8 | * by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_MACH_ATH79_PCI_ATH724X_H | ||
12 | #define __ASM_MACH_ATH79_PCI_ATH724X_H | ||
13 | |||
14 | struct ath724x_pci_data { | ||
15 | int irq; | ||
16 | void *pdata; | ||
17 | }; | ||
18 | |||
19 | void ath724x_pci_add_data(struct ath724x_pci_data *data, int size); | ||
20 | |||
21 | #endif /* __ASM_MACH_ATH79_PCI_ATH724X_H */ | ||
diff --git a/arch/mips/include/asm/mach-ath79/pci.h b/arch/mips/include/asm/mach-ath79/pci.h new file mode 100644 index 000000000000..7868f7fa028f --- /dev/null +++ b/arch/mips/include/asm/mach-ath79/pci.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X PCI support | ||
3 | * | ||
4 | * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com> | ||
5 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
6 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
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 version 2 as published | ||
10 | * by the Free Software Foundation. | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_MACH_ATH79_PCI_H | ||
14 | #define __ASM_MACH_ATH79_PCI_H | ||
15 | |||
16 | #if defined(CONFIG_PCI) && defined(CONFIG_SOC_AR71XX) | ||
17 | int ar71xx_pcibios_init(void); | ||
18 | #else | ||
19 | static inline int ar71xx_pcibios_init(void) { return 0; } | ||
20 | #endif | ||
21 | |||
22 | #if defined(CONFIG_PCI_AR724X) | ||
23 | int ar724x_pcibios_init(int irq); | ||
24 | #else | ||
25 | static inline int ar724x_pcibios_init(int irq) { return 0; } | ||
26 | #endif | ||
27 | |||
28 | #endif /* __ASM_MACH_ATH79_PCI_H */ | ||
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h new file mode 100644 index 000000000000..318f982f04ff --- /dev/null +++ b/arch/mips/include/asm/mach-lantiq/falcon/falcon_irq.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 Thomas Langer <thomas.langer@lantiq.com> | ||
7 | */ | ||
8 | |||
9 | #ifndef _FALCON_IRQ__ | ||
10 | #define _FALCON_IRQ__ | ||
11 | |||
12 | #define INT_NUM_IRQ0 8 | ||
13 | #define INT_NUM_IM0_IRL0 (INT_NUM_IRQ0 + 0) | ||
14 | #define INT_NUM_IM1_IRL0 (INT_NUM_IM0_IRL0 + 32) | ||
15 | #define INT_NUM_IM2_IRL0 (INT_NUM_IM1_IRL0 + 32) | ||
16 | #define INT_NUM_IM3_IRL0 (INT_NUM_IM2_IRL0 + 32) | ||
17 | #define INT_NUM_IM4_IRL0 (INT_NUM_IM3_IRL0 + 32) | ||
18 | #define INT_NUM_EXTRA_START (INT_NUM_IM4_IRL0 + 32) | ||
19 | #define INT_NUM_IM_OFFSET (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0) | ||
20 | |||
21 | #define MIPS_CPU_TIMER_IRQ 7 | ||
22 | |||
23 | #endif /* _FALCON_IRQ__ */ | ||
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/irq.h b/arch/mips/include/asm/mach-lantiq/falcon/irq.h new file mode 100644 index 000000000000..2caccd9f9dbc --- /dev/null +++ b/arch/mips/include/asm/mach-lantiq/falcon/irq.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com> | ||
7 | */ | ||
8 | |||
9 | #ifndef __FALCON_IRQ_H | ||
10 | #define __FALCON_IRQ_H | ||
11 | |||
12 | #include <falcon_irq.h> | ||
13 | |||
14 | #define NR_IRQS 328 | ||
15 | |||
16 | #include_next <irq.h> | ||
17 | |||
18 | #endif | ||
diff --git a/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h new file mode 100644 index 000000000000..b385252584ee --- /dev/null +++ b/arch/mips/include/asm/mach-lantiq/falcon/lantiq_soc.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LTQ_FALCON_H__ | ||
10 | #define _LTQ_FALCON_H__ | ||
11 | |||
12 | #ifdef CONFIG_SOC_FALCON | ||
13 | |||
14 | #include <linux/pinctrl/pinctrl.h> | ||
15 | #include <lantiq.h> | ||
16 | |||
17 | /* Chip IDs */ | ||
18 | #define SOC_ID_FALCON 0x01B8 | ||
19 | |||
20 | /* SoC Types */ | ||
21 | #define SOC_TYPE_FALCON 0x01 | ||
22 | |||
23 | /* | ||
24 | * during early_printk no ioremap possible at this early stage | ||
25 | * lets use KSEG1 instead | ||
26 | */ | ||
27 | #define LTQ_ASC0_BASE_ADDR 0x1E100C00 | ||
28 | #define LTQ_EARLY_ASC KSEG1ADDR(LTQ_ASC0_BASE_ADDR) | ||
29 | |||
30 | /* WDT */ | ||
31 | #define LTQ_RST_CAUSE_WDTRST 0x0002 | ||
32 | |||
33 | /* CHIP ID */ | ||
34 | #define LTQ_STATUS_BASE_ADDR 0x1E802000 | ||
35 | |||
36 | #define FALCON_CHIPID ((u32 *)(KSEG1 + LTQ_STATUS_BASE_ADDR + 0x0c)) | ||
37 | #define FALCON_CHIPTYPE ((u32 *)(KSEG1 + LTQ_STATUS_BASE_ADDR + 0x38)) | ||
38 | #define FALCON_CHIPCONF ((u32 *)(KSEG1 + LTQ_STATUS_BASE_ADDR + 0x40)) | ||
39 | |||
40 | /* SYSCTL - start/stop/restart/configure/... different parts of the Soc */ | ||
41 | #define SYSCTL_SYS1 0 | ||
42 | #define SYSCTL_SYSETH 1 | ||
43 | #define SYSCTL_SYSGPE 2 | ||
44 | |||
45 | /* BOOT_SEL - find what boot media we have */ | ||
46 | #define BS_FLASH 0x1 | ||
47 | #define BS_SPI 0x4 | ||
48 | |||
49 | /* global register ranges */ | ||
50 | extern __iomem void *ltq_ebu_membase; | ||
51 | extern __iomem void *ltq_sys1_membase; | ||
52 | #define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y)) | ||
53 | #define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x)) | ||
54 | |||
55 | #define ltq_sys1_w32(x, y) ltq_w32((x), ltq_sys1_membase + (y)) | ||
56 | #define ltq_sys1_r32(x) ltq_r32(ltq_sys1_membase + (x)) | ||
57 | #define ltq_sys1_w32_mask(clear, set, reg) \ | ||
58 | ltq_sys1_w32((ltq_sys1_r32(reg) & ~(clear)) | (set), reg) | ||
59 | |||
60 | /* | ||
61 | * to keep the irq code generic we need to define this to 0 as falcon | ||
62 | * has no EIU/EBU | ||
63 | */ | ||
64 | #define LTQ_EBU_PCC_ISTAT 0 | ||
65 | |||
66 | #endif /* CONFIG_SOC_FALCON */ | ||
67 | #endif /* _LTQ_XWAY_H__ */ | ||
diff --git a/arch/mips/include/asm/mach-lantiq/gpio.h b/arch/mips/include/asm/mach-lantiq/gpio.h new file mode 100644 index 000000000000..f79505b43609 --- /dev/null +++ b/arch/mips/include/asm/mach-lantiq/gpio.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef __ASM_MIPS_MACH_LANTIQ_GPIO_H | ||
2 | #define __ASM_MIPS_MACH_LANTIQ_GPIO_H | ||
3 | |||
4 | static inline int gpio_to_irq(unsigned int gpio) | ||
5 | { | ||
6 | return -1; | ||
7 | } | ||
8 | |||
9 | #define gpio_get_value __gpio_get_value | ||
10 | #define gpio_set_value __gpio_set_value | ||
11 | |||
12 | #define gpio_cansleep __gpio_cansleep | ||
13 | |||
14 | #include <asm-generic/gpio.h> | ||
15 | |||
16 | #endif | ||
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq.h b/arch/mips/include/asm/mach-lantiq/lantiq.h index ce2f02929d22..5e8a6e965756 100644 --- a/arch/mips/include/asm/mach-lantiq/lantiq.h +++ b/arch/mips/include/asm/mach-lantiq/lantiq.h | |||
@@ -9,6 +9,8 @@ | |||
9 | #define _LANTIQ_H__ | 9 | #define _LANTIQ_H__ |
10 | 10 | ||
11 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
12 | #include <linux/device.h> | ||
13 | #include <linux/clk.h> | ||
12 | 14 | ||
13 | /* generic reg access functions */ | 15 | /* generic reg access functions */ |
14 | #define ltq_r32(reg) __raw_readl(reg) | 16 | #define ltq_r32(reg) __raw_readl(reg) |
@@ -21,25 +23,9 @@ | |||
21 | /* register access macros for EBU and CGU */ | 23 | /* register access macros for EBU and CGU */ |
22 | #define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y)) | 24 | #define ltq_ebu_w32(x, y) ltq_w32((x), ltq_ebu_membase + (y)) |
23 | #define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x)) | 25 | #define ltq_ebu_r32(x) ltq_r32(ltq_ebu_membase + (x)) |
24 | #define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y)) | 26 | #define ltq_ebu_w32_mask(x, y, z) \ |
25 | #define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x)) | 27 | ltq_w32_mask(x, y, ltq_ebu_membase + (z)) |
26 | |||
27 | extern __iomem void *ltq_ebu_membase; | 28 | extern __iomem void *ltq_ebu_membase; |
28 | extern __iomem void *ltq_cgu_membase; | ||
29 | |||
30 | extern unsigned int ltq_get_cpu_ver(void); | ||
31 | extern unsigned int ltq_get_soc_type(void); | ||
32 | |||
33 | /* clock speeds */ | ||
34 | #define CLOCK_60M 60000000 | ||
35 | #define CLOCK_83M 83333333 | ||
36 | #define CLOCK_111M 111111111 | ||
37 | #define CLOCK_133M 133333333 | ||
38 | #define CLOCK_167M 166666667 | ||
39 | #define CLOCK_200M 200000000 | ||
40 | #define CLOCK_266M 266666666 | ||
41 | #define CLOCK_333M 333333333 | ||
42 | #define CLOCK_400M 400000000 | ||
43 | 29 | ||
44 | /* spinlock all ebu i/o */ | 30 | /* spinlock all ebu i/o */ |
45 | extern spinlock_t ebu_lock; | 31 | extern spinlock_t ebu_lock; |
@@ -49,15 +35,21 @@ extern void ltq_disable_irq(struct irq_data *data); | |||
49 | extern void ltq_mask_and_ack_irq(struct irq_data *data); | 35 | extern void ltq_mask_and_ack_irq(struct irq_data *data); |
50 | extern void ltq_enable_irq(struct irq_data *data); | 36 | extern void ltq_enable_irq(struct irq_data *data); |
51 | 37 | ||
38 | /* clock handling */ | ||
39 | extern int clk_activate(struct clk *clk); | ||
40 | extern void clk_deactivate(struct clk *clk); | ||
41 | extern struct clk *clk_get_cpu(void); | ||
42 | extern struct clk *clk_get_fpi(void); | ||
43 | extern struct clk *clk_get_io(void); | ||
44 | |||
45 | /* find out what bootsource we have */ | ||
46 | extern unsigned char ltq_boot_select(void); | ||
52 | /* find out what caused the last cpu reset */ | 47 | /* find out what caused the last cpu reset */ |
53 | extern int ltq_reset_cause(void); | 48 | extern int ltq_reset_cause(void); |
54 | #define LTQ_RST_CAUSE_WDTRST 0x20 | ||
55 | 49 | ||
56 | #define IOPORT_RESOURCE_START 0x10000000 | 50 | #define IOPORT_RESOURCE_START 0x10000000 |
57 | #define IOPORT_RESOURCE_END 0xffffffff | 51 | #define IOPORT_RESOURCE_END 0xffffffff |
58 | #define IOMEM_RESOURCE_START 0x10000000 | 52 | #define IOMEM_RESOURCE_START 0x10000000 |
59 | #define IOMEM_RESOURCE_END 0xffffffff | 53 | #define IOMEM_RESOURCE_END 0xffffffff |
60 | #define LTQ_FLASH_START 0x10000000 | ||
61 | #define LTQ_FLASH_MAX 0x04000000 | ||
62 | 54 | ||
63 | #endif | 55 | #endif |
diff --git a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h index a305f1d0259e..e23bf7c9a2d0 100644 --- a/arch/mips/include/asm/mach-lantiq/lantiq_platform.h +++ b/arch/mips/include/asm/mach-lantiq/lantiq_platform.h | |||
@@ -9,41 +9,8 @@ | |||
9 | #ifndef _LANTIQ_PLATFORM_H__ | 9 | #ifndef _LANTIQ_PLATFORM_H__ |
10 | #define _LANTIQ_PLATFORM_H__ | 10 | #define _LANTIQ_PLATFORM_H__ |
11 | 11 | ||
12 | #include <linux/mtd/partitions.h> | ||
13 | #include <linux/socket.h> | 12 | #include <linux/socket.h> |
14 | 13 | ||
15 | /* struct used to pass info to the pci core */ | ||
16 | enum { | ||
17 | PCI_CLOCK_INT = 0, | ||
18 | PCI_CLOCK_EXT | ||
19 | }; | ||
20 | |||
21 | #define PCI_EXIN0 0x0001 | ||
22 | #define PCI_EXIN1 0x0002 | ||
23 | #define PCI_EXIN2 0x0004 | ||
24 | #define PCI_EXIN3 0x0008 | ||
25 | #define PCI_EXIN4 0x0010 | ||
26 | #define PCI_EXIN5 0x0020 | ||
27 | #define PCI_EXIN_MAX 6 | ||
28 | |||
29 | #define PCI_GNT1 0x0040 | ||
30 | #define PCI_GNT2 0x0080 | ||
31 | #define PCI_GNT3 0x0100 | ||
32 | #define PCI_GNT4 0x0200 | ||
33 | |||
34 | #define PCI_REQ1 0x0400 | ||
35 | #define PCI_REQ2 0x0800 | ||
36 | #define PCI_REQ3 0x1000 | ||
37 | #define PCI_REQ4 0x2000 | ||
38 | #define PCI_REQ_SHIFT 10 | ||
39 | #define PCI_REQ_MASK 0xf | ||
40 | |||
41 | struct ltq_pci_data { | ||
42 | int clock; | ||
43 | int gpio; | ||
44 | int irq[16]; | ||
45 | }; | ||
46 | |||
47 | /* struct used to pass info to network drivers */ | 14 | /* struct used to pass info to network drivers */ |
48 | struct ltq_eth_data { | 15 | struct ltq_eth_data { |
49 | struct sockaddr mac; | 16 | struct sockaddr mac; |
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h index b4465a888e20..aa0b3b866f84 100644 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_irq.h | |||
@@ -17,50 +17,8 @@ | |||
17 | #define INT_NUM_IM4_IRL0 (INT_NUM_IRQ0 + 128) | 17 | #define INT_NUM_IM4_IRL0 (INT_NUM_IRQ0 + 128) |
18 | #define INT_NUM_IM_OFFSET (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0) | 18 | #define INT_NUM_IM_OFFSET (INT_NUM_IM1_IRL0 - INT_NUM_IM0_IRL0) |
19 | 19 | ||
20 | #define LTQ_ASC_TIR(x) (INT_NUM_IM3_IRL0 + (x * 8)) | ||
21 | #define LTQ_ASC_RIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 1) | ||
22 | #define LTQ_ASC_EIR(x) (INT_NUM_IM3_IRL0 + (x * 8) + 2) | ||
23 | |||
24 | #define LTQ_ASC_ASE_TIR INT_NUM_IM2_IRL0 | ||
25 | #define LTQ_ASC_ASE_RIR (INT_NUM_IM2_IRL0 + 2) | ||
26 | #define LTQ_ASC_ASE_EIR (INT_NUM_IM2_IRL0 + 3) | ||
27 | |||
28 | #define LTQ_SSC_TIR (INT_NUM_IM0_IRL0 + 15) | ||
29 | #define LTQ_SSC_RIR (INT_NUM_IM0_IRL0 + 14) | ||
30 | #define LTQ_SSC_EIR (INT_NUM_IM0_IRL0 + 16) | ||
31 | |||
32 | #define LTQ_MEI_DYING_GASP_INT (INT_NUM_IM1_IRL0 + 21) | ||
33 | #define LTQ_MEI_INT (INT_NUM_IM1_IRL0 + 23) | ||
34 | |||
35 | #define LTQ_TIMER6_INT (INT_NUM_IM1_IRL0 + 23) | ||
36 | #define LTQ_USB_INT (INT_NUM_IM1_IRL0 + 22) | ||
37 | #define LTQ_USB_OC_INT (INT_NUM_IM4_IRL0 + 23) | ||
38 | |||
39 | #define MIPS_CPU_TIMER_IRQ 7 | ||
40 | |||
41 | #define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0) | 20 | #define LTQ_DMA_CH0_INT (INT_NUM_IM2_IRL0) |
42 | #define LTQ_DMA_CH1_INT (INT_NUM_IM2_IRL0 + 1) | ||
43 | #define LTQ_DMA_CH2_INT (INT_NUM_IM2_IRL0 + 2) | ||
44 | #define LTQ_DMA_CH3_INT (INT_NUM_IM2_IRL0 + 3) | ||
45 | #define LTQ_DMA_CH4_INT (INT_NUM_IM2_IRL0 + 4) | ||
46 | #define LTQ_DMA_CH5_INT (INT_NUM_IM2_IRL0 + 5) | ||
47 | #define LTQ_DMA_CH6_INT (INT_NUM_IM2_IRL0 + 6) | ||
48 | #define LTQ_DMA_CH7_INT (INT_NUM_IM2_IRL0 + 7) | ||
49 | #define LTQ_DMA_CH8_INT (INT_NUM_IM2_IRL0 + 8) | ||
50 | #define LTQ_DMA_CH9_INT (INT_NUM_IM2_IRL0 + 9) | ||
51 | #define LTQ_DMA_CH10_INT (INT_NUM_IM2_IRL0 + 10) | ||
52 | #define LTQ_DMA_CH11_INT (INT_NUM_IM2_IRL0 + 11) | ||
53 | #define LTQ_DMA_CH12_INT (INT_NUM_IM2_IRL0 + 25) | ||
54 | #define LTQ_DMA_CH13_INT (INT_NUM_IM2_IRL0 + 26) | ||
55 | #define LTQ_DMA_CH14_INT (INT_NUM_IM2_IRL0 + 27) | ||
56 | #define LTQ_DMA_CH15_INT (INT_NUM_IM2_IRL0 + 28) | ||
57 | #define LTQ_DMA_CH16_INT (INT_NUM_IM2_IRL0 + 29) | ||
58 | #define LTQ_DMA_CH17_INT (INT_NUM_IM2_IRL0 + 30) | ||
59 | #define LTQ_DMA_CH18_INT (INT_NUM_IM2_IRL0 + 16) | ||
60 | #define LTQ_DMA_CH19_INT (INT_NUM_IM2_IRL0 + 21) | ||
61 | |||
62 | #define LTQ_PPE_MBOX_INT (INT_NUM_IM2_IRL0 + 24) | ||
63 | 21 | ||
64 | #define INT_NUM_IM4_IRL14 (INT_NUM_IM4_IRL0 + 14) | 22 | #define MIPS_CPU_TIMER_IRQ 7 |
65 | 23 | ||
66 | #endif | 24 | #endif |
diff --git a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h index 8a3c6be669d2..6a2df709c576 100644 --- a/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h +++ b/arch/mips/include/asm/mach-lantiq/xway/lantiq_soc.h | |||
@@ -17,38 +17,56 @@ | |||
17 | #define SOC_ID_DANUBE1 0x129 | 17 | #define SOC_ID_DANUBE1 0x129 |
18 | #define SOC_ID_DANUBE2 0x12B | 18 | #define SOC_ID_DANUBE2 0x12B |
19 | #define SOC_ID_TWINPASS 0x12D | 19 | #define SOC_ID_TWINPASS 0x12D |
20 | #define SOC_ID_AMAZON_SE 0x152 | 20 | #define SOC_ID_AMAZON_SE_1 0x152 /* 50601 */ |
21 | #define SOC_ID_AMAZON_SE_2 0x153 /* 50600 */ | ||
21 | #define SOC_ID_ARX188 0x16C | 22 | #define SOC_ID_ARX188 0x16C |
22 | #define SOC_ID_ARX168 0x16D | 23 | #define SOC_ID_ARX168_1 0x16D |
24 | #define SOC_ID_ARX168_2 0x16E | ||
23 | #define SOC_ID_ARX182 0x16F | 25 | #define SOC_ID_ARX182 0x16F |
24 | 26 | #define SOC_ID_GRX188 0x170 | |
25 | /* SoC Types */ | 27 | #define SOC_ID_GRX168 0x171 |
28 | |||
29 | #define SOC_ID_VRX288 0x1C0 /* v1.1 */ | ||
30 | #define SOC_ID_VRX282 0x1C1 /* v1.1 */ | ||
31 | #define SOC_ID_VRX268 0x1C2 /* v1.1 */ | ||
32 | #define SOC_ID_GRX268 0x1C8 /* v1.1 */ | ||
33 | #define SOC_ID_GRX288 0x1C9 /* v1.1 */ | ||
34 | #define SOC_ID_VRX288_2 0x00B /* v1.2 */ | ||
35 | #define SOC_ID_VRX268_2 0x00C /* v1.2 */ | ||
36 | #define SOC_ID_GRX288_2 0x00D /* v1.2 */ | ||
37 | #define SOC_ID_GRX282_2 0x00E /* v1.2 */ | ||
38 | |||
39 | /* SoC Types */ | ||
26 | #define SOC_TYPE_DANUBE 0x01 | 40 | #define SOC_TYPE_DANUBE 0x01 |
27 | #define SOC_TYPE_TWINPASS 0x02 | 41 | #define SOC_TYPE_TWINPASS 0x02 |
28 | #define SOC_TYPE_AR9 0x03 | 42 | #define SOC_TYPE_AR9 0x03 |
29 | #define SOC_TYPE_VR9 0x04 | 43 | #define SOC_TYPE_VR9 0x04 /* v1.1 */ |
30 | #define SOC_TYPE_AMAZON_SE 0x05 | 44 | #define SOC_TYPE_VR9_2 0x05 /* v1.2 */ |
45 | #define SOC_TYPE_AMAZON_SE 0x06 | ||
46 | |||
47 | /* BOOT_SEL - find what boot media we have */ | ||
48 | #define BS_EXT_ROM 0x0 | ||
49 | #define BS_FLASH 0x1 | ||
50 | #define BS_MII0 0x2 | ||
51 | #define BS_PCI 0x3 | ||
52 | #define BS_UART1 0x4 | ||
53 | #define BS_SPI 0x5 | ||
54 | #define BS_NAND 0x6 | ||
55 | #define BS_RMII0 0x7 | ||
56 | |||
57 | /* helpers used to access the cgu */ | ||
58 | #define ltq_cgu_w32(x, y) ltq_w32((x), ltq_cgu_membase + (y)) | ||
59 | #define ltq_cgu_r32(x) ltq_r32(ltq_cgu_membase + (x)) | ||
60 | extern __iomem void *ltq_cgu_membase; | ||
31 | 61 | ||
32 | /* ASC0/1 - serial port */ | 62 | /* |
33 | #define LTQ_ASC0_BASE_ADDR 0x1E100400 | 63 | * during early_printk no ioremap is possible |
64 | * lets use KSEG1 instead | ||
65 | */ | ||
34 | #define LTQ_ASC1_BASE_ADDR 0x1E100C00 | 66 | #define LTQ_ASC1_BASE_ADDR 0x1E100C00 |
35 | #define LTQ_ASC_SIZE 0x400 | 67 | #define LTQ_EARLY_ASC KSEG1ADDR(LTQ_ASC1_BASE_ADDR) |
36 | |||
37 | /* RCU - reset control unit */ | ||
38 | #define LTQ_RCU_BASE_ADDR 0x1F203000 | ||
39 | #define LTQ_RCU_SIZE 0x1000 | ||
40 | |||
41 | /* GPTU - general purpose timer unit */ | ||
42 | #define LTQ_GPTU_BASE_ADDR 0x18000300 | ||
43 | #define LTQ_GPTU_SIZE 0x100 | ||
44 | 68 | ||
45 | /* EBU - external bus unit */ | 69 | /* EBU - external bus unit */ |
46 | #define LTQ_EBU_GPIO_START 0x14000000 | ||
47 | #define LTQ_EBU_GPIO_SIZE 0x1000 | ||
48 | |||
49 | #define LTQ_EBU_BASE_ADDR 0x1E105300 | ||
50 | #define LTQ_EBU_SIZE 0x100 | ||
51 | |||
52 | #define LTQ_EBU_BUSCON0 0x0060 | 70 | #define LTQ_EBU_BUSCON0 0x0060 |
53 | #define LTQ_EBU_PCC_CON 0x0090 | 71 | #define LTQ_EBU_PCC_CON 0x0090 |
54 | #define LTQ_EBU_PCC_IEN 0x00A4 | 72 | #define LTQ_EBU_PCC_IEN 0x00A4 |
@@ -57,85 +75,17 @@ | |||
57 | #define LTQ_EBU_ADDRSEL1 0x0024 | 75 | #define LTQ_EBU_ADDRSEL1 0x0024 |
58 | #define EBU_WRDIS 0x80000000 | 76 | #define EBU_WRDIS 0x80000000 |
59 | 77 | ||
60 | /* CGU - clock generation unit */ | ||
61 | #define LTQ_CGU_BASE_ADDR 0x1F103000 | ||
62 | #define LTQ_CGU_SIZE 0x1000 | ||
63 | |||
64 | /* ICU - interrupt control unit */ | ||
65 | #define LTQ_ICU_BASE_ADDR 0x1F880200 | ||
66 | #define LTQ_ICU_SIZE 0x100 | ||
67 | |||
68 | /* EIU - external interrupt unit */ | ||
69 | #define LTQ_EIU_BASE_ADDR 0x1F101000 | ||
70 | #define LTQ_EIU_SIZE 0x1000 | ||
71 | |||
72 | /* PMU - power management unit */ | ||
73 | #define LTQ_PMU_BASE_ADDR 0x1F102000 | ||
74 | #define LTQ_PMU_SIZE 0x1000 | ||
75 | |||
76 | #define PMU_DMA 0x0020 | ||
77 | #define PMU_USB 0x8041 | ||
78 | #define PMU_LED 0x0800 | ||
79 | #define PMU_GPT 0x1000 | ||
80 | #define PMU_PPE 0x2000 | ||
81 | #define PMU_FPI 0x4000 | ||
82 | #define PMU_SWITCH 0x10000000 | ||
83 | |||
84 | /* ETOP - ethernet */ | ||
85 | #define LTQ_ETOP_BASE_ADDR 0x1E180000 | ||
86 | #define LTQ_ETOP_SIZE 0x40000 | ||
87 | |||
88 | /* DMA */ | ||
89 | #define LTQ_DMA_BASE_ADDR 0x1E104100 | ||
90 | #define LTQ_DMA_SIZE 0x800 | ||
91 | |||
92 | /* PCI */ | ||
93 | #define PCI_CR_BASE_ADDR 0x1E105400 | ||
94 | #define PCI_CR_SIZE 0x400 | ||
95 | |||
96 | /* WDT */ | 78 | /* WDT */ |
97 | #define LTQ_WDT_BASE_ADDR 0x1F8803F0 | 79 | #define LTQ_RST_CAUSE_WDTRST 0x20 |
98 | #define LTQ_WDT_SIZE 0x10 | ||
99 | |||
100 | /* STP - serial to parallel conversion unit */ | ||
101 | #define LTQ_STP_BASE_ADDR 0x1E100BB0 | ||
102 | #define LTQ_STP_SIZE 0x40 | ||
103 | |||
104 | /* GPIO */ | ||
105 | #define LTQ_GPIO0_BASE_ADDR 0x1E100B10 | ||
106 | #define LTQ_GPIO1_BASE_ADDR 0x1E100B40 | ||
107 | #define LTQ_GPIO2_BASE_ADDR 0x1E100B70 | ||
108 | #define LTQ_GPIO_SIZE 0x30 | ||
109 | |||
110 | /* SSC */ | ||
111 | #define LTQ_SSC_BASE_ADDR 0x1e100800 | ||
112 | #define LTQ_SSC_SIZE 0x100 | ||
113 | |||
114 | /* MEI - dsl core */ | ||
115 | #define LTQ_MEI_BASE_ADDR 0x1E116000 | ||
116 | |||
117 | /* DEU - data encryption unit */ | ||
118 | #define LTQ_DEU_BASE_ADDR 0x1E103100 | ||
119 | 80 | ||
120 | /* MPS - multi processor unit (voice) */ | 81 | /* MPS - multi processor unit (voice) */ |
121 | #define LTQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000) | 82 | #define LTQ_MPS_BASE_ADDR (KSEG1 + 0x1F107000) |
122 | #define LTQ_MPS_CHIPID ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344)) | 83 | #define LTQ_MPS_CHIPID ((u32 *)(LTQ_MPS_BASE_ADDR + 0x0344)) |
123 | 84 | ||
124 | /* request a non-gpio and set the PIO config */ | 85 | /* request a non-gpio and set the PIO config */ |
125 | extern int ltq_gpio_request(unsigned int pin, unsigned int alt0, | 86 | #define PMU_PPE BIT(13) |
126 | unsigned int alt1, unsigned int dir, const char *name); | ||
127 | extern void ltq_pmu_enable(unsigned int module); | 87 | extern void ltq_pmu_enable(unsigned int module); |
128 | extern void ltq_pmu_disable(unsigned int module); | 88 | extern void ltq_pmu_disable(unsigned int module); |
129 | 89 | ||
130 | static inline int ltq_is_ar9(void) | ||
131 | { | ||
132 | return (ltq_get_soc_type() == SOC_TYPE_AR9); | ||
133 | } | ||
134 | |||
135 | static inline int ltq_is_vr9(void) | ||
136 | { | ||
137 | return (ltq_get_soc_type() == SOC_TYPE_VR9); | ||
138 | } | ||
139 | |||
140 | #endif /* CONFIG_SOC_TYPE_XWAY */ | 90 | #endif /* CONFIG_SOC_TYPE_XWAY */ |
141 | #endif /* _LTQ_XWAY_H__ */ | 91 | #endif /* _LTQ_XWAY_H__ */ |
diff --git a/arch/mips/include/asm/mips-boards/generic.h b/arch/mips/include/asm/mips-boards/generic.h index 46c08563e532..6e23ceb0ba8c 100644 --- a/arch/mips/include/asm/mips-boards/generic.h +++ b/arch/mips/include/asm/mips-boards/generic.h | |||
@@ -93,8 +93,4 @@ extern void mips_pcibios_init(void); | |||
93 | #define mips_pcibios_init() do { } while (0) | 93 | #define mips_pcibios_init() do { } while (0) |
94 | #endif | 94 | #endif |
95 | 95 | ||
96 | #ifdef CONFIG_KGDB | ||
97 | extern void kgdb_config(void); | ||
98 | #endif | ||
99 | |||
100 | #endif /* __ASM_MIPS_BOARDS_GENERIC_H */ | 96 | #endif /* __ASM_MIPS_BOARDS_GENERIC_H */ |
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h index 7467d1d933d5..530008048c62 100644 --- a/arch/mips/include/asm/module.h +++ b/arch/mips/include/asm/module.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _ASM_MODULE_H | 2 | #define _ASM_MODULE_H |
3 | 3 | ||
4 | #include <linux/list.h> | 4 | #include <linux/list.h> |
5 | #include <linux/elf.h> | ||
5 | #include <asm/uaccess.h> | 6 | #include <asm/uaccess.h> |
6 | 7 | ||
7 | struct mod_arch_specific { | 8 | struct mod_arch_specific { |
diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h index fcd4060f6421..90bf3b3fce19 100644 --- a/arch/mips/include/asm/pci.h +++ b/arch/mips/include/asm/pci.h | |||
@@ -17,6 +17,7 @@ | |||
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/ioport.h> | 19 | #include <linux/ioport.h> |
20 | #include <linux/of.h> | ||
20 | 21 | ||
21 | /* | 22 | /* |
22 | * Each pci channel is a top-level PCI bus seem by CPU. A machine with | 23 | * Each pci channel is a top-level PCI bus seem by CPU. A machine with |
@@ -26,6 +27,7 @@ | |||
26 | struct pci_controller { | 27 | struct pci_controller { |
27 | struct pci_controller *next; | 28 | struct pci_controller *next; |
28 | struct pci_bus *bus; | 29 | struct pci_bus *bus; |
30 | struct device_node *of_node; | ||
29 | 31 | ||
30 | struct pci_ops *pci_ops; | 32 | struct pci_ops *pci_ops; |
31 | struct resource *mem_resource; | 33 | struct resource *mem_resource; |
@@ -142,4 +144,8 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) | |||
142 | 144 | ||
143 | extern char * (*pcibios_plat_setup)(char *str); | 145 | extern char * (*pcibios_plat_setup)(char *str); |
144 | 146 | ||
147 | /* this function parses memory ranges from a device node */ | ||
148 | extern void __devinit pci_load_of_ranges(struct pci_controller *hose, | ||
149 | struct device_node *node); | ||
150 | |||
145 | #endif /* _ASM_PCI_H */ | 151 | #endif /* _ASM_PCI_H */ |
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h index 7a6e82ef449b..7206d445bab8 100644 --- a/arch/mips/include/asm/prom.h +++ b/arch/mips/include/asm/prom.h | |||
@@ -12,6 +12,9 @@ | |||
12 | #define __ASM_PROM_H | 12 | #define __ASM_PROM_H |
13 | 13 | ||
14 | #ifdef CONFIG_OF | 14 | #ifdef CONFIG_OF |
15 | #include <linux/bug.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/types.h> | ||
15 | #include <asm/bootinfo.h> | 18 | #include <asm/bootinfo.h> |
16 | 19 | ||
17 | extern int early_init_dt_scan_memory_arch(unsigned long node, | 20 | extern int early_init_dt_scan_memory_arch(unsigned long node, |
@@ -21,6 +24,29 @@ extern int reserve_mem_mach(unsigned long addr, unsigned long size); | |||
21 | extern void free_mem_mach(unsigned long addr, unsigned long size); | 24 | extern void free_mem_mach(unsigned long addr, unsigned long size); |
22 | 25 | ||
23 | extern void device_tree_init(void); | 26 | extern void device_tree_init(void); |
27 | |||
28 | static inline unsigned long pci_address_to_pio(phys_addr_t address) | ||
29 | { | ||
30 | /* | ||
31 | * The ioport address can be directly used by inX() / outX() | ||
32 | */ | ||
33 | BUG_ON(address > IO_SPACE_LIMIT); | ||
34 | |||
35 | return (unsigned long) address; | ||
36 | } | ||
37 | #define pci_address_to_pio pci_address_to_pio | ||
38 | |||
39 | struct boot_param_header; | ||
40 | |||
41 | extern void __dt_setup_arch(struct boot_param_header *bph); | ||
42 | |||
43 | #define dt_setup_arch(sym) \ | ||
44 | ({ \ | ||
45 | extern struct boot_param_header __dtb_##sym##_begin; \ | ||
46 | \ | ||
47 | __dt_setup_arch(&__dtb_##sym##_begin); \ | ||
48 | }) | ||
49 | |||
24 | #else /* CONFIG_OF */ | 50 | #else /* CONFIG_OF */ |
25 | static inline void device_tree_init(void) { } | 51 | static inline void device_tree_init(void) { } |
26 | #endif /* CONFIG_OF */ | 52 | #endif /* CONFIG_OF */ |
diff --git a/arch/mips/include/asm/setup.h b/arch/mips/include/asm/setup.h index 6dce6d8d09ab..2560b6b6a7d8 100644 --- a/arch/mips/include/asm/setup.h +++ b/arch/mips/include/asm/setup.h | |||
@@ -14,7 +14,8 @@ extern void *set_vi_handler(int n, vi_handler_t addr); | |||
14 | 14 | ||
15 | extern void *set_except_vector(int n, void *addr); | 15 | extern void *set_except_vector(int n, void *addr); |
16 | extern unsigned long ebase; | 16 | extern unsigned long ebase; |
17 | extern void per_cpu_trap_init(void); | 17 | extern void per_cpu_trap_init(bool); |
18 | extern void cpu_cache_init(void); | ||
18 | 19 | ||
19 | #endif /* __KERNEL__ */ | 20 | #endif /* __KERNEL__ */ |
20 | 21 | ||
diff --git a/arch/mips/include/asm/termios.h b/arch/mips/include/asm/termios.h index 8f77f774a2a0..abdd87aaf609 100644 --- a/arch/mips/include/asm/termios.h +++ b/arch/mips/include/asm/termios.h | |||
@@ -60,7 +60,7 @@ struct termio { | |||
60 | }; | 60 | }; |
61 | 61 | ||
62 | #ifdef __KERNEL__ | 62 | #ifdef __KERNEL__ |
63 | #include <linux/module.h> | 63 | #include <asm/uaccess.h> |
64 | 64 | ||
65 | /* | 65 | /* |
66 | * intr=^C quit=^\ erase=del kill=^U | 66 | * intr=^C quit=^\ erase=del kill=^U |
diff --git a/arch/mips/include/asm/traps.h b/arch/mips/include/asm/traps.h index ff74aec3561a..420ca06b2f42 100644 --- a/arch/mips/include/asm/traps.h +++ b/arch/mips/include/asm/traps.h | |||
@@ -25,6 +25,7 @@ extern void (*board_nmi_handler_setup)(void); | |||
25 | extern void (*board_ejtag_handler_setup)(void); | 25 | extern void (*board_ejtag_handler_setup)(void); |
26 | extern void (*board_bind_eic_interrupt)(int irq, int regset); | 26 | extern void (*board_bind_eic_interrupt)(int irq, int regset); |
27 | extern void (*board_ebase_setup)(void); | 27 | extern void (*board_ebase_setup)(void); |
28 | extern void (*board_cache_error_setup)(void); | ||
28 | 29 | ||
29 | extern int register_nmi_notifier(struct notifier_block *nb); | 30 | extern int register_nmi_notifier(struct notifier_block *nb); |
30 | 31 | ||
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h index 504d40aedfae..440a21dab575 100644 --- a/arch/mips/include/asm/uasm.h +++ b/arch/mips/include/asm/uasm.h | |||
@@ -11,7 +11,7 @@ | |||
11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
12 | 12 | ||
13 | #ifdef CONFIG_EXPORT_UASM | 13 | #ifdef CONFIG_EXPORT_UASM |
14 | #include <linux/module.h> | 14 | #include <linux/export.h> |
15 | #define __uasminit | 15 | #define __uasminit |
16 | #define __uasminitdata | 16 | #define __uasminitdata |
17 | #define UASM_EXPORT_SYMBOL(sym) EXPORT_SYMBOL(sym) | 17 | #define UASM_EXPORT_SYMBOL(sym) EXPORT_SYMBOL(sym) |
diff --git a/arch/mips/jz4740/Makefile b/arch/mips/jz4740/Makefile index a9dff3321251..e44abea9c209 100644 --- a/arch/mips/jz4740/Makefile +++ b/arch/mips/jz4740/Makefile | |||
@@ -16,5 +16,3 @@ obj-$(CONFIG_JZ4740_QI_LB60) += board-qi_lb60.o | |||
16 | # PM support | 16 | # PM support |
17 | 17 | ||
18 | obj-$(CONFIG_PM) += pm.o | 18 | obj-$(CONFIG_PM) += pm.o |
19 | |||
20 | ccflags-y := -Werror -Wall | ||
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index 5099201fb7bc..6ae7ce4ac63e 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -340,7 +340,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
340 | __cpu_name[cpu] = "R2000"; | 340 | __cpu_name[cpu] = "R2000"; |
341 | c->isa_level = MIPS_CPU_ISA_I; | 341 | c->isa_level = MIPS_CPU_ISA_I; |
342 | c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | | 342 | c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | |
343 | MIPS_CPU_NOFPUEX; | 343 | MIPS_CPU_NOFPUEX; |
344 | if (__cpu_has_fpu()) | 344 | if (__cpu_has_fpu()) |
345 | c->options |= MIPS_CPU_FPU; | 345 | c->options |= MIPS_CPU_FPU; |
346 | c->tlbsize = 64; | 346 | c->tlbsize = 64; |
@@ -361,7 +361,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
361 | } | 361 | } |
362 | c->isa_level = MIPS_CPU_ISA_I; | 362 | c->isa_level = MIPS_CPU_ISA_I; |
363 | c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | | 363 | c->options = MIPS_CPU_TLB | MIPS_CPU_3K_CACHE | |
364 | MIPS_CPU_NOFPUEX; | 364 | MIPS_CPU_NOFPUEX; |
365 | if (__cpu_has_fpu()) | 365 | if (__cpu_has_fpu()) |
366 | c->options |= MIPS_CPU_FPU; | 366 | c->options |= MIPS_CPU_FPU; |
367 | c->tlbsize = 64; | 367 | c->tlbsize = 64; |
@@ -387,8 +387,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
387 | 387 | ||
388 | c->isa_level = MIPS_CPU_ISA_III; | 388 | c->isa_level = MIPS_CPU_ISA_III; |
389 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | | 389 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
390 | MIPS_CPU_WATCH | MIPS_CPU_VCE | | 390 | MIPS_CPU_WATCH | MIPS_CPU_VCE | |
391 | MIPS_CPU_LLSC; | 391 | MIPS_CPU_LLSC; |
392 | c->tlbsize = 48; | 392 | c->tlbsize = 48; |
393 | break; | 393 | break; |
394 | case PRID_IMP_VR41XX: | 394 | case PRID_IMP_VR41XX: |
@@ -434,7 +434,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
434 | __cpu_name[cpu] = "R4300"; | 434 | __cpu_name[cpu] = "R4300"; |
435 | c->isa_level = MIPS_CPU_ISA_III; | 435 | c->isa_level = MIPS_CPU_ISA_III; |
436 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | | 436 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
437 | MIPS_CPU_LLSC; | 437 | MIPS_CPU_LLSC; |
438 | c->tlbsize = 32; | 438 | c->tlbsize = 32; |
439 | break; | 439 | break; |
440 | case PRID_IMP_R4600: | 440 | case PRID_IMP_R4600: |
@@ -446,7 +446,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
446 | c->tlbsize = 48; | 446 | c->tlbsize = 48; |
447 | break; | 447 | break; |
448 | #if 0 | 448 | #if 0 |
449 | case PRID_IMP_R4650: | 449 | case PRID_IMP_R4650: |
450 | /* | 450 | /* |
451 | * This processor doesn't have an MMU, so it's not | 451 | * This processor doesn't have an MMU, so it's not |
452 | * "real easy" to run Linux on it. It is left purely | 452 | * "real easy" to run Linux on it. It is left purely |
@@ -455,9 +455,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
455 | */ | 455 | */ |
456 | c->cputype = CPU_R4650; | 456 | c->cputype = CPU_R4650; |
457 | __cpu_name[cpu] = "R4650"; | 457 | __cpu_name[cpu] = "R4650"; |
458 | c->isa_level = MIPS_CPU_ISA_III; | 458 | c->isa_level = MIPS_CPU_ISA_III; |
459 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; | 459 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_LLSC; |
460 | c->tlbsize = 48; | 460 | c->tlbsize = 48; |
461 | break; | 461 | break; |
462 | #endif | 462 | #endif |
463 | case PRID_IMP_TX39: | 463 | case PRID_IMP_TX39: |
@@ -488,7 +488,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
488 | __cpu_name[cpu] = "R4700"; | 488 | __cpu_name[cpu] = "R4700"; |
489 | c->isa_level = MIPS_CPU_ISA_III; | 489 | c->isa_level = MIPS_CPU_ISA_III; |
490 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | | 490 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
491 | MIPS_CPU_LLSC; | 491 | MIPS_CPU_LLSC; |
492 | c->tlbsize = 48; | 492 | c->tlbsize = 48; |
493 | break; | 493 | break; |
494 | case PRID_IMP_TX49: | 494 | case PRID_IMP_TX49: |
@@ -505,7 +505,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
505 | __cpu_name[cpu] = "R5000"; | 505 | __cpu_name[cpu] = "R5000"; |
506 | c->isa_level = MIPS_CPU_ISA_IV; | 506 | c->isa_level = MIPS_CPU_ISA_IV; |
507 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | | 507 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
508 | MIPS_CPU_LLSC; | 508 | MIPS_CPU_LLSC; |
509 | c->tlbsize = 48; | 509 | c->tlbsize = 48; |
510 | break; | 510 | break; |
511 | case PRID_IMP_R5432: | 511 | case PRID_IMP_R5432: |
@@ -513,7 +513,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
513 | __cpu_name[cpu] = "R5432"; | 513 | __cpu_name[cpu] = "R5432"; |
514 | c->isa_level = MIPS_CPU_ISA_IV; | 514 | c->isa_level = MIPS_CPU_ISA_IV; |
515 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | | 515 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
516 | MIPS_CPU_WATCH | MIPS_CPU_LLSC; | 516 | MIPS_CPU_WATCH | MIPS_CPU_LLSC; |
517 | c->tlbsize = 48; | 517 | c->tlbsize = 48; |
518 | break; | 518 | break; |
519 | case PRID_IMP_R5500: | 519 | case PRID_IMP_R5500: |
@@ -521,7 +521,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
521 | __cpu_name[cpu] = "R5500"; | 521 | __cpu_name[cpu] = "R5500"; |
522 | c->isa_level = MIPS_CPU_ISA_IV; | 522 | c->isa_level = MIPS_CPU_ISA_IV; |
523 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | | 523 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
524 | MIPS_CPU_WATCH | MIPS_CPU_LLSC; | 524 | MIPS_CPU_WATCH | MIPS_CPU_LLSC; |
525 | c->tlbsize = 48; | 525 | c->tlbsize = 48; |
526 | break; | 526 | break; |
527 | case PRID_IMP_NEVADA: | 527 | case PRID_IMP_NEVADA: |
@@ -529,7 +529,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
529 | __cpu_name[cpu] = "Nevada"; | 529 | __cpu_name[cpu] = "Nevada"; |
530 | c->isa_level = MIPS_CPU_ISA_IV; | 530 | c->isa_level = MIPS_CPU_ISA_IV; |
531 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | | 531 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
532 | MIPS_CPU_DIVEC | MIPS_CPU_LLSC; | 532 | MIPS_CPU_DIVEC | MIPS_CPU_LLSC; |
533 | c->tlbsize = 48; | 533 | c->tlbsize = 48; |
534 | break; | 534 | break; |
535 | case PRID_IMP_R6000: | 535 | case PRID_IMP_R6000: |
@@ -537,7 +537,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
537 | __cpu_name[cpu] = "R6000"; | 537 | __cpu_name[cpu] = "R6000"; |
538 | c->isa_level = MIPS_CPU_ISA_II; | 538 | c->isa_level = MIPS_CPU_ISA_II; |
539 | c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | | 539 | c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | |
540 | MIPS_CPU_LLSC; | 540 | MIPS_CPU_LLSC; |
541 | c->tlbsize = 32; | 541 | c->tlbsize = 32; |
542 | break; | 542 | break; |
543 | case PRID_IMP_R6000A: | 543 | case PRID_IMP_R6000A: |
@@ -545,7 +545,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
545 | __cpu_name[cpu] = "R6000A"; | 545 | __cpu_name[cpu] = "R6000A"; |
546 | c->isa_level = MIPS_CPU_ISA_II; | 546 | c->isa_level = MIPS_CPU_ISA_II; |
547 | c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | | 547 | c->options = MIPS_CPU_TLB | MIPS_CPU_FPU | |
548 | MIPS_CPU_LLSC; | 548 | MIPS_CPU_LLSC; |
549 | c->tlbsize = 32; | 549 | c->tlbsize = 32; |
550 | break; | 550 | break; |
551 | case PRID_IMP_RM7000: | 551 | case PRID_IMP_RM7000: |
@@ -553,7 +553,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
553 | __cpu_name[cpu] = "RM7000"; | 553 | __cpu_name[cpu] = "RM7000"; |
554 | c->isa_level = MIPS_CPU_ISA_IV; | 554 | c->isa_level = MIPS_CPU_ISA_IV; |
555 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | | 555 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
556 | MIPS_CPU_LLSC; | 556 | MIPS_CPU_LLSC; |
557 | /* | 557 | /* |
558 | * Undocumented RM7000: Bit 29 in the info register of | 558 | * Undocumented RM7000: Bit 29 in the info register of |
559 | * the RM7000 v2.0 indicates if the TLB has 48 or 64 | 559 | * the RM7000 v2.0 indicates if the TLB has 48 or 64 |
@@ -569,7 +569,7 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
569 | __cpu_name[cpu] = "RM9000"; | 569 | __cpu_name[cpu] = "RM9000"; |
570 | c->isa_level = MIPS_CPU_ISA_IV; | 570 | c->isa_level = MIPS_CPU_ISA_IV; |
571 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | | 571 | c->options = R4K_OPTS | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
572 | MIPS_CPU_LLSC; | 572 | MIPS_CPU_LLSC; |
573 | /* | 573 | /* |
574 | * Bit 29 in the info register of the RM9000 | 574 | * Bit 29 in the info register of the RM9000 |
575 | * indicates if the TLB has 48 or 64 entries. | 575 | * indicates if the TLB has 48 or 64 entries. |
@@ -584,8 +584,8 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
584 | __cpu_name[cpu] = "RM8000"; | 584 | __cpu_name[cpu] = "RM8000"; |
585 | c->isa_level = MIPS_CPU_ISA_IV; | 585 | c->isa_level = MIPS_CPU_ISA_IV; |
586 | c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | | 586 | c->options = MIPS_CPU_TLB | MIPS_CPU_4KEX | |
587 | MIPS_CPU_FPU | MIPS_CPU_32FPR | | 587 | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
588 | MIPS_CPU_LLSC; | 588 | MIPS_CPU_LLSC; |
589 | c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ | 589 | c->tlbsize = 384; /* has weird TLB: 3-way x 128 */ |
590 | break; | 590 | break; |
591 | case PRID_IMP_R10000: | 591 | case PRID_IMP_R10000: |
@@ -593,9 +593,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
593 | __cpu_name[cpu] = "R10000"; | 593 | __cpu_name[cpu] = "R10000"; |
594 | c->isa_level = MIPS_CPU_ISA_IV; | 594 | c->isa_level = MIPS_CPU_ISA_IV; |
595 | c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | | 595 | c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | |
596 | MIPS_CPU_FPU | MIPS_CPU_32FPR | | 596 | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
597 | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | | 597 | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | |
598 | MIPS_CPU_LLSC; | 598 | MIPS_CPU_LLSC; |
599 | c->tlbsize = 64; | 599 | c->tlbsize = 64; |
600 | break; | 600 | break; |
601 | case PRID_IMP_R12000: | 601 | case PRID_IMP_R12000: |
@@ -603,9 +603,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
603 | __cpu_name[cpu] = "R12000"; | 603 | __cpu_name[cpu] = "R12000"; |
604 | c->isa_level = MIPS_CPU_ISA_IV; | 604 | c->isa_level = MIPS_CPU_ISA_IV; |
605 | c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | | 605 | c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | |
606 | MIPS_CPU_FPU | MIPS_CPU_32FPR | | 606 | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
607 | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | | 607 | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | |
608 | MIPS_CPU_LLSC; | 608 | MIPS_CPU_LLSC; |
609 | c->tlbsize = 64; | 609 | c->tlbsize = 64; |
610 | break; | 610 | break; |
611 | case PRID_IMP_R14000: | 611 | case PRID_IMP_R14000: |
@@ -613,9 +613,9 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
613 | __cpu_name[cpu] = "R14000"; | 613 | __cpu_name[cpu] = "R14000"; |
614 | c->isa_level = MIPS_CPU_ISA_IV; | 614 | c->isa_level = MIPS_CPU_ISA_IV; |
615 | c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | | 615 | c->options = MIPS_CPU_TLB | MIPS_CPU_4K_CACHE | MIPS_CPU_4KEX | |
616 | MIPS_CPU_FPU | MIPS_CPU_32FPR | | 616 | MIPS_CPU_FPU | MIPS_CPU_32FPR | |
617 | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | | 617 | MIPS_CPU_COUNTER | MIPS_CPU_WATCH | |
618 | MIPS_CPU_LLSC; | 618 | MIPS_CPU_LLSC; |
619 | c->tlbsize = 64; | 619 | c->tlbsize = 64; |
620 | break; | 620 | break; |
621 | case PRID_IMP_LOONGSON2: | 621 | case PRID_IMP_LOONGSON2: |
@@ -739,7 +739,7 @@ static inline unsigned int decode_config3(struct cpuinfo_mips *c) | |||
739 | if (config3 & MIPS_CONF3_VEIC) | 739 | if (config3 & MIPS_CONF3_VEIC) |
740 | c->options |= MIPS_CPU_VEIC; | 740 | c->options |= MIPS_CPU_VEIC; |
741 | if (config3 & MIPS_CONF3_MT) | 741 | if (config3 & MIPS_CONF3_MT) |
742 | c->ases |= MIPS_ASE_MIPSMT; | 742 | c->ases |= MIPS_ASE_MIPSMT; |
743 | if (config3 & MIPS_CONF3_ULRI) | 743 | if (config3 & MIPS_CONF3_ULRI) |
744 | c->options |= MIPS_CPU_ULRI; | 744 | c->options |= MIPS_CPU_ULRI; |
745 | 745 | ||
@@ -767,7 +767,7 @@ static void __cpuinit decode_configs(struct cpuinfo_mips *c) | |||
767 | 767 | ||
768 | /* MIPS32 or MIPS64 compliant CPU. */ | 768 | /* MIPS32 or MIPS64 compliant CPU. */ |
769 | c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER | | 769 | c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER | |
770 | MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK; | 770 | MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK; |
771 | 771 | ||
772 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; | 772 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; |
773 | 773 | ||
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index 811084f4e422..574b4e9df50f 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c | |||
@@ -1532,7 +1532,8 @@ init_hw_perf_events(void) | |||
1532 | irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; | 1532 | irq = MSC01E_INT_BASE + MSC01E_INT_PERFCTR; |
1533 | } else { | 1533 | } else { |
1534 | #endif | 1534 | #endif |
1535 | if (cp0_perfcount_irq >= 0) | 1535 | if ((cp0_perfcount_irq >= 0) && |
1536 | (cp0_compare_irq != cp0_perfcount_irq)) | ||
1536 | irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; | 1537 | irq = MIPS_CPU_IRQ_BASE + cp0_perfcount_irq; |
1537 | else | 1538 | else |
1538 | irq = -1; | 1539 | irq = -1; |
diff --git a/arch/mips/kernel/proc.c b/arch/mips/kernel/proc.c index f8b2c592514d..5542817c1b49 100644 --- a/arch/mips/kernel/proc.c +++ b/arch/mips/kernel/proc.c | |||
@@ -41,27 +41,27 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
41 | 41 | ||
42 | seq_printf(m, "processor\t\t: %ld\n", n); | 42 | seq_printf(m, "processor\t\t: %ld\n", n); |
43 | sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", | 43 | sprintf(fmt, "cpu model\t\t: %%s V%%d.%%d%s\n", |
44 | cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : ""); | 44 | cpu_data[n].options & MIPS_CPU_FPU ? " FPU V%d.%d" : ""); |
45 | seq_printf(m, fmt, __cpu_name[n], | 45 | seq_printf(m, fmt, __cpu_name[n], |
46 | (version >> 4) & 0x0f, version & 0x0f, | 46 | (version >> 4) & 0x0f, version & 0x0f, |
47 | (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); | 47 | (fp_vers >> 4) & 0x0f, fp_vers & 0x0f); |
48 | seq_printf(m, "BogoMIPS\t\t: %u.%02u\n", | 48 | seq_printf(m, "BogoMIPS\t\t: %u.%02u\n", |
49 | cpu_data[n].udelay_val / (500000/HZ), | 49 | cpu_data[n].udelay_val / (500000/HZ), |
50 | (cpu_data[n].udelay_val / (5000/HZ)) % 100); | 50 | (cpu_data[n].udelay_val / (5000/HZ)) % 100); |
51 | seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no"); | 51 | seq_printf(m, "wait instruction\t: %s\n", cpu_wait ? "yes" : "no"); |
52 | seq_printf(m, "microsecond timers\t: %s\n", | 52 | seq_printf(m, "microsecond timers\t: %s\n", |
53 | cpu_has_counter ? "yes" : "no"); | 53 | cpu_has_counter ? "yes" : "no"); |
54 | seq_printf(m, "tlb_entries\t\t: %d\n", cpu_data[n].tlbsize); | 54 | seq_printf(m, "tlb_entries\t\t: %d\n", cpu_data[n].tlbsize); |
55 | seq_printf(m, "extra interrupt vector\t: %s\n", | 55 | seq_printf(m, "extra interrupt vector\t: %s\n", |
56 | cpu_has_divec ? "yes" : "no"); | 56 | cpu_has_divec ? "yes" : "no"); |
57 | seq_printf(m, "hardware watchpoint\t: %s", | 57 | seq_printf(m, "hardware watchpoint\t: %s", |
58 | cpu_has_watch ? "yes, " : "no\n"); | 58 | cpu_has_watch ? "yes, " : "no\n"); |
59 | if (cpu_has_watch) { | 59 | if (cpu_has_watch) { |
60 | seq_printf(m, "count: %d, address/irw mask: [", | 60 | seq_printf(m, "count: %d, address/irw mask: [", |
61 | cpu_data[n].watch_reg_count); | 61 | cpu_data[n].watch_reg_count); |
62 | for (i = 0; i < cpu_data[n].watch_reg_count; i++) | 62 | for (i = 0; i < cpu_data[n].watch_reg_count; i++) |
63 | seq_printf(m, "%s0x%04x", i ? ", " : "" , | 63 | seq_printf(m, "%s0x%04x", i ? ", " : "" , |
64 | cpu_data[n].watch_reg_masks[i]); | 64 | cpu_data[n].watch_reg_masks[i]); |
65 | seq_printf(m, "]\n"); | 65 | seq_printf(m, "]\n"); |
66 | } | 66 | } |
67 | seq_printf(m, "ASEs implemented\t:%s%s%s%s%s%s\n", | 67 | seq_printf(m, "ASEs implemented\t:%s%s%s%s%s%s\n", |
@@ -73,13 +73,13 @@ static int show_cpuinfo(struct seq_file *m, void *v) | |||
73 | cpu_has_mipsmt ? " mt" : "" | 73 | cpu_has_mipsmt ? " mt" : "" |
74 | ); | 74 | ); |
75 | seq_printf(m, "shadow register sets\t: %d\n", | 75 | seq_printf(m, "shadow register sets\t: %d\n", |
76 | cpu_data[n].srsets); | 76 | cpu_data[n].srsets); |
77 | seq_printf(m, "kscratch registers\t: %d\n", | 77 | seq_printf(m, "kscratch registers\t: %d\n", |
78 | hweight8(cpu_data[n].kscratch_mask)); | 78 | hweight8(cpu_data[n].kscratch_mask)); |
79 | seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); | 79 | seq_printf(m, "core\t\t\t: %d\n", cpu_data[n].core); |
80 | 80 | ||
81 | sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", | 81 | sprintf(fmt, "VCE%%c exceptions\t\t: %s\n", |
82 | cpu_has_vce ? "%u" : "not available"); | 82 | cpu_has_vce ? "%u" : "not available"); |
83 | seq_printf(m, fmt, 'D', vced_count); | 83 | seq_printf(m, fmt, 'D', vced_count); |
84 | seq_printf(m, fmt, 'I', vcei_count); | 84 | seq_printf(m, fmt, 'I', vcei_count); |
85 | seq_printf(m, "\n"); | 85 | seq_printf(m, "\n"); |
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index 558b5395795d..f11b2bbb826d 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c | |||
@@ -95,3 +95,16 @@ void __init device_tree_init(void) | |||
95 | /* free the space reserved for the dt blob */ | 95 | /* free the space reserved for the dt blob */ |
96 | free_mem_mach(base, size); | 96 | free_mem_mach(base, size); |
97 | } | 97 | } |
98 | |||
99 | void __init __dt_setup_arch(struct boot_param_header *bph) | ||
100 | { | ||
101 | if (be32_to_cpu(bph->magic) != OF_DT_HEADER) { | ||
102 | pr_err("DTB has bad magic, ignoring builtin OF DTB\n"); | ||
103 | |||
104 | return; | ||
105 | } | ||
106 | |||
107 | initial_boot_params = bph; | ||
108 | |||
109 | early_init_devtree(initial_boot_params); | ||
110 | } | ||
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index c504b212f8f3..a53f8ec37aac 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -605,6 +605,8 @@ void __init setup_arch(char **cmdline_p) | |||
605 | 605 | ||
606 | resource_init(); | 606 | resource_init(); |
607 | plat_smp_setup(); | 607 | plat_smp_setup(); |
608 | |||
609 | cpu_cache_init(); | ||
608 | } | 610 | } |
609 | 611 | ||
610 | unsigned long kernelsp[NR_CPUS]; | 612 | unsigned long kernelsp[NR_CPUS]; |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index ba9376bf52a1..dc019a1f128d 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -106,7 +106,7 @@ asmlinkage __cpuinit void start_secondary(void) | |||
106 | #endif /* CONFIG_MIPS_MT_SMTC */ | 106 | #endif /* CONFIG_MIPS_MT_SMTC */ |
107 | cpu_probe(); | 107 | cpu_probe(); |
108 | cpu_report(); | 108 | cpu_report(); |
109 | per_cpu_trap_init(); | 109 | per_cpu_trap_init(false); |
110 | mips_clockevent_init(); | 110 | mips_clockevent_init(); |
111 | mp_ops->init_secondary(); | 111 | mp_ops->init_secondary(); |
112 | 112 | ||
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index cfdaaa4cffc0..2d0c2a277f52 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/compiler.h> | 15 | #include <linux/compiler.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/module.h> | ||
18 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
19 | #include <linux/sched.h> | 20 | #include <linux/sched.h> |
20 | #include <linux/smp.h> | 21 | #include <linux/smp.h> |
@@ -91,7 +92,7 @@ void (*board_nmi_handler_setup)(void); | |||
91 | void (*board_ejtag_handler_setup)(void); | 92 | void (*board_ejtag_handler_setup)(void); |
92 | void (*board_bind_eic_interrupt)(int irq, int regset); | 93 | void (*board_bind_eic_interrupt)(int irq, int regset); |
93 | void (*board_ebase_setup)(void); | 94 | void (*board_ebase_setup)(void); |
94 | 95 | void __cpuinitdata(*board_cache_error_setup)(void); | |
95 | 96 | ||
96 | static void show_raw_backtrace(unsigned long reg29) | 97 | static void show_raw_backtrace(unsigned long reg29) |
97 | { | 98 | { |
@@ -1490,7 +1491,6 @@ void *set_vi_handler(int n, vi_handler_t addr) | |||
1490 | return set_vi_srs_handler(n, addr, 0); | 1491 | return set_vi_srs_handler(n, addr, 0); |
1491 | } | 1492 | } |
1492 | 1493 | ||
1493 | extern void cpu_cache_init(void); | ||
1494 | extern void tlb_init(void); | 1494 | extern void tlb_init(void); |
1495 | extern void flush_tlb_handlers(void); | 1495 | extern void flush_tlb_handlers(void); |
1496 | 1496 | ||
@@ -1517,7 +1517,7 @@ static int __init ulri_disable(char *s) | |||
1517 | } | 1517 | } |
1518 | __setup("noulri", ulri_disable); | 1518 | __setup("noulri", ulri_disable); |
1519 | 1519 | ||
1520 | void __cpuinit per_cpu_trap_init(void) | 1520 | void __cpuinit per_cpu_trap_init(bool is_boot_cpu) |
1521 | { | 1521 | { |
1522 | unsigned int cpu = smp_processor_id(); | 1522 | unsigned int cpu = smp_processor_id(); |
1523 | unsigned int status_set = ST0_CU0; | 1523 | unsigned int status_set = ST0_CU0; |
@@ -1616,7 +1616,9 @@ void __cpuinit per_cpu_trap_init(void) | |||
1616 | #ifdef CONFIG_MIPS_MT_SMTC | 1616 | #ifdef CONFIG_MIPS_MT_SMTC |
1617 | if (bootTC) { | 1617 | if (bootTC) { |
1618 | #endif /* CONFIG_MIPS_MT_SMTC */ | 1618 | #endif /* CONFIG_MIPS_MT_SMTC */ |
1619 | cpu_cache_init(); | 1619 | /* Boot CPU's cache setup in setup_arch(). */ |
1620 | if (!is_boot_cpu) | ||
1621 | cpu_cache_init(); | ||
1620 | tlb_init(); | 1622 | tlb_init(); |
1621 | #ifdef CONFIG_MIPS_MT_SMTC | 1623 | #ifdef CONFIG_MIPS_MT_SMTC |
1622 | } else if (!secondaryTC) { | 1624 | } else if (!secondaryTC) { |
@@ -1632,7 +1634,7 @@ void __cpuinit per_cpu_trap_init(void) | |||
1632 | } | 1634 | } |
1633 | 1635 | ||
1634 | /* Install CPU exception handler */ | 1636 | /* Install CPU exception handler */ |
1635 | void __init set_handler(unsigned long offset, void *addr, unsigned long size) | 1637 | void __cpuinit set_handler(unsigned long offset, void *addr, unsigned long size) |
1636 | { | 1638 | { |
1637 | memcpy((void *)(ebase + offset), addr, size); | 1639 | memcpy((void *)(ebase + offset), addr, size); |
1638 | local_flush_icache_range(ebase + offset, ebase + offset + size); | 1640 | local_flush_icache_range(ebase + offset, ebase + offset + size); |
@@ -1693,7 +1695,7 @@ void __init trap_init(void) | |||
1693 | 1695 | ||
1694 | if (board_ebase_setup) | 1696 | if (board_ebase_setup) |
1695 | board_ebase_setup(); | 1697 | board_ebase_setup(); |
1696 | per_cpu_trap_init(); | 1698 | per_cpu_trap_init(true); |
1697 | 1699 | ||
1698 | /* | 1700 | /* |
1699 | * Copy the generic exception handlers to their final destination. | 1701 | * Copy the generic exception handlers to their final destination. |
@@ -1797,6 +1799,9 @@ void __init trap_init(void) | |||
1797 | 1799 | ||
1798 | set_except_vector(26, handle_dsp); | 1800 | set_except_vector(26, handle_dsp); |
1799 | 1801 | ||
1802 | if (board_cache_error_setup) | ||
1803 | board_cache_error_setup(); | ||
1804 | |||
1800 | if (cpu_has_vce) | 1805 | if (cpu_has_vce) |
1801 | /* Special exception: R4[04]00 uses also the divec space. */ | 1806 | /* Special exception: R4[04]00 uses also the divec space. */ |
1802 | memcpy((void *)(ebase + 0x180), &except_vec3_r4000, 0x100); | 1807 | memcpy((void *)(ebase + 0x180), &except_vec3_r4000, 0x100); |
diff --git a/arch/mips/lantiq/Kconfig b/arch/mips/lantiq/Kconfig index 3fccf2104513..20bdf40b3efa 100644 --- a/arch/mips/lantiq/Kconfig +++ b/arch/mips/lantiq/Kconfig | |||
@@ -16,8 +16,22 @@ config SOC_XWAY | |||
16 | bool "XWAY" | 16 | bool "XWAY" |
17 | select SOC_TYPE_XWAY | 17 | select SOC_TYPE_XWAY |
18 | select HW_HAS_PCI | 18 | select HW_HAS_PCI |
19 | |||
20 | config SOC_FALCON | ||
21 | bool "FALCON" | ||
22 | |||
23 | endchoice | ||
24 | |||
25 | choice | ||
26 | prompt "Devicetree" | ||
27 | |||
28 | config DT_EASY50712 | ||
29 | bool "Easy50712" | ||
30 | depends on SOC_XWAY | ||
19 | endchoice | 31 | endchoice |
20 | 32 | ||
21 | source "arch/mips/lantiq/xway/Kconfig" | 33 | config PCI_LANTIQ |
34 | bool "PCI Support" | ||
35 | depends on SOC_XWAY && PCI | ||
22 | 36 | ||
23 | endif | 37 | endif |
diff --git a/arch/mips/lantiq/Makefile b/arch/mips/lantiq/Makefile index e5dae0e24b00..d6bdc579419f 100644 --- a/arch/mips/lantiq/Makefile +++ b/arch/mips/lantiq/Makefile | |||
@@ -4,8 +4,11 @@ | |||
4 | # under the terms of the GNU General Public License version 2 as published | 4 | # under the terms of the GNU General Public License version 2 as published |
5 | # by the Free Software Foundation. | 5 | # by the Free Software Foundation. |
6 | 6 | ||
7 | obj-y := irq.o setup.o clk.o prom.o devices.o | 7 | obj-y := irq.o clk.o prom.o |
8 | |||
9 | obj-y += dts/ | ||
8 | 10 | ||
9 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | 11 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o |
10 | 12 | ||
11 | obj-$(CONFIG_SOC_TYPE_XWAY) += xway/ | 13 | obj-$(CONFIG_SOC_TYPE_XWAY) += xway/ |
14 | obj-$(CONFIG_SOC_FALCON) += falcon/ | ||
diff --git a/arch/mips/lantiq/Platform b/arch/mips/lantiq/Platform index f3dff05722de..b3ec49838fd7 100644 --- a/arch/mips/lantiq/Platform +++ b/arch/mips/lantiq/Platform | |||
@@ -6,3 +6,4 @@ platform-$(CONFIG_LANTIQ) += lantiq/ | |||
6 | cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq | 6 | cflags-$(CONFIG_LANTIQ) += -I$(srctree)/arch/mips/include/asm/mach-lantiq |
7 | load-$(CONFIG_LANTIQ) = 0xffffffff80002000 | 7 | load-$(CONFIG_LANTIQ) = 0xffffffff80002000 |
8 | cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway | 8 | cflags-$(CONFIG_SOC_TYPE_XWAY) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/xway |
9 | cflags-$(CONFIG_SOC_FALCON) += -I$(srctree)/arch/mips/include/asm/mach-lantiq/falcon | ||
diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c index 412814fdd3ee..d3bcc33f4699 100644 --- a/arch/mips/lantiq/clk.c +++ b/arch/mips/lantiq/clk.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
13 | #include <linux/types.h> | 13 | #include <linux/types.h> |
14 | #include <linux/clk.h> | 14 | #include <linux/clk.h> |
15 | #include <linux/clkdev.h> | ||
15 | #include <linux/err.h> | 16 | #include <linux/err.h> |
16 | #include <linux/list.h> | 17 | #include <linux/list.h> |
17 | 18 | ||
@@ -22,44 +23,32 @@ | |||
22 | #include <lantiq_soc.h> | 23 | #include <lantiq_soc.h> |
23 | 24 | ||
24 | #include "clk.h" | 25 | #include "clk.h" |
26 | #include "prom.h" | ||
25 | 27 | ||
26 | struct clk { | 28 | /* lantiq socs have 3 static clocks */ |
27 | const char *name; | 29 | static struct clk cpu_clk_generic[3]; |
28 | unsigned long rate; | ||
29 | unsigned long (*get_rate) (void); | ||
30 | }; | ||
31 | 30 | ||
32 | static struct clk *cpu_clk; | 31 | void clkdev_add_static(unsigned long cpu, unsigned long fpi, unsigned long io) |
33 | static int cpu_clk_cnt; | 32 | { |
33 | cpu_clk_generic[0].rate = cpu; | ||
34 | cpu_clk_generic[1].rate = fpi; | ||
35 | cpu_clk_generic[2].rate = io; | ||
36 | } | ||
34 | 37 | ||
35 | /* lantiq socs have 3 static clocks */ | 38 | struct clk *clk_get_cpu(void) |
36 | static struct clk cpu_clk_generic[] = { | 39 | { |
37 | { | 40 | return &cpu_clk_generic[0]; |
38 | .name = "cpu", | 41 | } |
39 | .get_rate = ltq_get_cpu_hz, | 42 | |
40 | }, { | 43 | struct clk *clk_get_fpi(void) |
41 | .name = "fpi", | 44 | { |
42 | .get_rate = ltq_get_fpi_hz, | 45 | return &cpu_clk_generic[1]; |
43 | }, { | 46 | } |
44 | .name = "io", | 47 | EXPORT_SYMBOL_GPL(clk_get_fpi); |
45 | .get_rate = ltq_get_io_region_clock, | 48 | |
46 | }, | 49 | struct clk *clk_get_io(void) |
47 | }; | ||
48 | |||
49 | static struct resource ltq_cgu_resource = { | ||
50 | .name = "cgu", | ||
51 | .start = LTQ_CGU_BASE_ADDR, | ||
52 | .end = LTQ_CGU_BASE_ADDR + LTQ_CGU_SIZE - 1, | ||
53 | .flags = IORESOURCE_MEM, | ||
54 | }; | ||
55 | |||
56 | /* remapped clock register range */ | ||
57 | void __iomem *ltq_cgu_membase; | ||
58 | |||
59 | void clk_init(void) | ||
60 | { | 50 | { |
61 | cpu_clk = cpu_clk_generic; | 51 | return &cpu_clk_generic[2]; |
62 | cpu_clk_cnt = ARRAY_SIZE(cpu_clk_generic); | ||
63 | } | 52 | } |
64 | 53 | ||
65 | static inline int clk_good(struct clk *clk) | 54 | static inline int clk_good(struct clk *clk) |
@@ -82,38 +71,71 @@ unsigned long clk_get_rate(struct clk *clk) | |||
82 | } | 71 | } |
83 | EXPORT_SYMBOL(clk_get_rate); | 72 | EXPORT_SYMBOL(clk_get_rate); |
84 | 73 | ||
85 | struct clk *clk_get(struct device *dev, const char *id) | 74 | int clk_set_rate(struct clk *clk, unsigned long rate) |
86 | { | 75 | { |
87 | int i; | 76 | if (unlikely(!clk_good(clk))) |
88 | 77 | return 0; | |
89 | for (i = 0; i < cpu_clk_cnt; i++) | 78 | if (clk->rates && *clk->rates) { |
90 | if (!strcmp(id, cpu_clk[i].name)) | 79 | unsigned long *r = clk->rates; |
91 | return &cpu_clk[i]; | 80 | |
92 | BUG(); | 81 | while (*r && (*r != rate)) |
93 | return ERR_PTR(-ENOENT); | 82 | r++; |
94 | } | 83 | if (!*r) { |
95 | EXPORT_SYMBOL(clk_get); | 84 | pr_err("clk %s.%s: trying to set invalid rate %ld\n", |
96 | 85 | clk->cl.dev_id, clk->cl.con_id, rate); | |
97 | void clk_put(struct clk *clk) | 86 | return -1; |
98 | { | 87 | } |
99 | /* not used */ | 88 | } |
89 | clk->rate = rate; | ||
90 | return 0; | ||
100 | } | 91 | } |
101 | EXPORT_SYMBOL(clk_put); | 92 | EXPORT_SYMBOL(clk_set_rate); |
102 | 93 | ||
103 | int clk_enable(struct clk *clk) | 94 | int clk_enable(struct clk *clk) |
104 | { | 95 | { |
105 | /* not used */ | 96 | if (unlikely(!clk_good(clk))) |
106 | return 0; | 97 | return -1; |
98 | |||
99 | if (clk->enable) | ||
100 | return clk->enable(clk); | ||
101 | |||
102 | return -1; | ||
107 | } | 103 | } |
108 | EXPORT_SYMBOL(clk_enable); | 104 | EXPORT_SYMBOL(clk_enable); |
109 | 105 | ||
110 | void clk_disable(struct clk *clk) | 106 | void clk_disable(struct clk *clk) |
111 | { | 107 | { |
112 | /* not used */ | 108 | if (unlikely(!clk_good(clk))) |
109 | return; | ||
110 | |||
111 | if (clk->disable) | ||
112 | clk->disable(clk); | ||
113 | } | 113 | } |
114 | EXPORT_SYMBOL(clk_disable); | 114 | EXPORT_SYMBOL(clk_disable); |
115 | 115 | ||
116 | static inline u32 ltq_get_counter_resolution(void) | 116 | int clk_activate(struct clk *clk) |
117 | { | ||
118 | if (unlikely(!clk_good(clk))) | ||
119 | return -1; | ||
120 | |||
121 | if (clk->activate) | ||
122 | return clk->activate(clk); | ||
123 | |||
124 | return -1; | ||
125 | } | ||
126 | EXPORT_SYMBOL(clk_activate); | ||
127 | |||
128 | void clk_deactivate(struct clk *clk) | ||
129 | { | ||
130 | if (unlikely(!clk_good(clk))) | ||
131 | return; | ||
132 | |||
133 | if (clk->deactivate) | ||
134 | clk->deactivate(clk); | ||
135 | } | ||
136 | EXPORT_SYMBOL(clk_deactivate); | ||
137 | |||
138 | static inline u32 get_counter_resolution(void) | ||
117 | { | 139 | { |
118 | u32 res; | 140 | u32 res; |
119 | 141 | ||
@@ -133,21 +155,11 @@ void __init plat_time_init(void) | |||
133 | { | 155 | { |
134 | struct clk *clk; | 156 | struct clk *clk; |
135 | 157 | ||
136 | if (insert_resource(&iomem_resource, <q_cgu_resource) < 0) | 158 | ltq_soc_init(); |
137 | panic("Failed to insert cgu memory"); | ||
138 | 159 | ||
139 | if (request_mem_region(ltq_cgu_resource.start, | 160 | clk = clk_get_cpu(); |
140 | resource_size(<q_cgu_resource), "cgu") < 0) | 161 | mips_hpt_frequency = clk_get_rate(clk) / get_counter_resolution(); |
141 | panic("Failed to request cgu memory"); | ||
142 | |||
143 | ltq_cgu_membase = ioremap_nocache(ltq_cgu_resource.start, | ||
144 | resource_size(<q_cgu_resource)); | ||
145 | if (!ltq_cgu_membase) { | ||
146 | pr_err("Failed to remap cgu memory\n"); | ||
147 | unreachable(); | ||
148 | } | ||
149 | clk = clk_get(0, "cpu"); | ||
150 | mips_hpt_frequency = clk_get_rate(clk) / ltq_get_counter_resolution(); | ||
151 | write_c0_compare(read_c0_count()); | 162 | write_c0_compare(read_c0_count()); |
163 | pr_info("CPU Clock: %ldMHz\n", clk_get_rate(clk) / 1000000); | ||
152 | clk_put(clk); | 164 | clk_put(clk); |
153 | } | 165 | } |
diff --git a/arch/mips/lantiq/clk.h b/arch/mips/lantiq/clk.h index 3328925f2c3f..fa670602b91b 100644 --- a/arch/mips/lantiq/clk.h +++ b/arch/mips/lantiq/clk.h | |||
@@ -9,10 +9,70 @@ | |||
9 | #ifndef _LTQ_CLK_H__ | 9 | #ifndef _LTQ_CLK_H__ |
10 | #define _LTQ_CLK_H__ | 10 | #define _LTQ_CLK_H__ |
11 | 11 | ||
12 | extern void clk_init(void); | 12 | #include <linux/clkdev.h> |
13 | 13 | ||
14 | extern unsigned long ltq_get_cpu_hz(void); | 14 | /* clock speeds */ |
15 | extern unsigned long ltq_get_fpi_hz(void); | 15 | #define CLOCK_33M 33333333 |
16 | extern unsigned long ltq_get_io_region_clock(void); | 16 | #define CLOCK_60M 60000000 |
17 | #define CLOCK_62_5M 62500000 | ||
18 | #define CLOCK_83M 83333333 | ||
19 | #define CLOCK_83_5M 83500000 | ||
20 | #define CLOCK_98_304M 98304000 | ||
21 | #define CLOCK_100M 100000000 | ||
22 | #define CLOCK_111M 111111111 | ||
23 | #define CLOCK_125M 125000000 | ||
24 | #define CLOCK_133M 133333333 | ||
25 | #define CLOCK_150M 150000000 | ||
26 | #define CLOCK_166M 166666666 | ||
27 | #define CLOCK_167M 166666667 | ||
28 | #define CLOCK_196_608M 196608000 | ||
29 | #define CLOCK_200M 200000000 | ||
30 | #define CLOCK_250M 250000000 | ||
31 | #define CLOCK_266M 266666666 | ||
32 | #define CLOCK_300M 300000000 | ||
33 | #define CLOCK_333M 333333333 | ||
34 | #define CLOCK_393M 393215332 | ||
35 | #define CLOCK_400M 400000000 | ||
36 | #define CLOCK_500M 500000000 | ||
37 | #define CLOCK_600M 600000000 | ||
38 | |||
39 | /* clock out speeds */ | ||
40 | #define CLOCK_32_768K 32768 | ||
41 | #define CLOCK_1_536M 1536000 | ||
42 | #define CLOCK_2_5M 2500000 | ||
43 | #define CLOCK_12M 12000000 | ||
44 | #define CLOCK_24M 24000000 | ||
45 | #define CLOCK_25M 25000000 | ||
46 | #define CLOCK_30M 30000000 | ||
47 | #define CLOCK_40M 40000000 | ||
48 | #define CLOCK_48M 48000000 | ||
49 | #define CLOCK_50M 50000000 | ||
50 | #define CLOCK_60M 60000000 | ||
51 | |||
52 | struct clk { | ||
53 | struct clk_lookup cl; | ||
54 | unsigned long rate; | ||
55 | unsigned long *rates; | ||
56 | unsigned int module; | ||
57 | unsigned int bits; | ||
58 | unsigned long (*get_rate) (void); | ||
59 | int (*enable) (struct clk *clk); | ||
60 | void (*disable) (struct clk *clk); | ||
61 | int (*activate) (struct clk *clk); | ||
62 | void (*deactivate) (struct clk *clk); | ||
63 | void (*reboot) (struct clk *clk); | ||
64 | }; | ||
65 | |||
66 | extern void clkdev_add_static(unsigned long cpu, unsigned long fpi, | ||
67 | unsigned long io); | ||
68 | |||
69 | extern unsigned long ltq_danube_cpu_hz(void); | ||
70 | extern unsigned long ltq_danube_fpi_hz(void); | ||
71 | |||
72 | extern unsigned long ltq_ar9_cpu_hz(void); | ||
73 | extern unsigned long ltq_ar9_fpi_hz(void); | ||
74 | |||
75 | extern unsigned long ltq_vr9_cpu_hz(void); | ||
76 | extern unsigned long ltq_vr9_fpi_hz(void); | ||
17 | 77 | ||
18 | #endif | 78 | #endif |
diff --git a/arch/mips/lantiq/devices.c b/arch/mips/lantiq/devices.c deleted file mode 100644 index de1cb2bcd79a..000000000000 --- a/arch/mips/lantiq/devices.c +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/export.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/kernel.h> | ||
14 | #include <linux/reboot.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/leds.h> | ||
17 | #include <linux/etherdevice.h> | ||
18 | #include <linux/time.h> | ||
19 | #include <linux/io.h> | ||
20 | #include <linux/gpio.h> | ||
21 | |||
22 | #include <asm/bootinfo.h> | ||
23 | #include <asm/irq.h> | ||
24 | |||
25 | #include <lantiq_soc.h> | ||
26 | |||
27 | #include "devices.h" | ||
28 | |||
29 | /* nor flash */ | ||
30 | static struct resource ltq_nor_resource = { | ||
31 | .name = "nor", | ||
32 | .start = LTQ_FLASH_START, | ||
33 | .end = LTQ_FLASH_START + LTQ_FLASH_MAX - 1, | ||
34 | .flags = IORESOURCE_MEM, | ||
35 | }; | ||
36 | |||
37 | static struct platform_device ltq_nor = { | ||
38 | .name = "ltq_nor", | ||
39 | .resource = <q_nor_resource, | ||
40 | .num_resources = 1, | ||
41 | }; | ||
42 | |||
43 | void __init ltq_register_nor(struct physmap_flash_data *data) | ||
44 | { | ||
45 | ltq_nor.dev.platform_data = data; | ||
46 | platform_device_register(<q_nor); | ||
47 | } | ||
48 | |||
49 | /* watchdog */ | ||
50 | static struct resource ltq_wdt_resource = { | ||
51 | .name = "watchdog", | ||
52 | .start = LTQ_WDT_BASE_ADDR, | ||
53 | .end = LTQ_WDT_BASE_ADDR + LTQ_WDT_SIZE - 1, | ||
54 | .flags = IORESOURCE_MEM, | ||
55 | }; | ||
56 | |||
57 | void __init ltq_register_wdt(void) | ||
58 | { | ||
59 | platform_device_register_simple("ltq_wdt", 0, <q_wdt_resource, 1); | ||
60 | } | ||
61 | |||
62 | /* asc ports */ | ||
63 | static struct resource ltq_asc0_resources[] = { | ||
64 | { | ||
65 | .name = "asc0", | ||
66 | .start = LTQ_ASC0_BASE_ADDR, | ||
67 | .end = LTQ_ASC0_BASE_ADDR + LTQ_ASC_SIZE - 1, | ||
68 | .flags = IORESOURCE_MEM, | ||
69 | }, | ||
70 | IRQ_RES(tx, LTQ_ASC_TIR(0)), | ||
71 | IRQ_RES(rx, LTQ_ASC_RIR(0)), | ||
72 | IRQ_RES(err, LTQ_ASC_EIR(0)), | ||
73 | }; | ||
74 | |||
75 | static struct resource ltq_asc1_resources[] = { | ||
76 | { | ||
77 | .name = "asc1", | ||
78 | .start = LTQ_ASC1_BASE_ADDR, | ||
79 | .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1, | ||
80 | .flags = IORESOURCE_MEM, | ||
81 | }, | ||
82 | IRQ_RES(tx, LTQ_ASC_TIR(1)), | ||
83 | IRQ_RES(rx, LTQ_ASC_RIR(1)), | ||
84 | IRQ_RES(err, LTQ_ASC_EIR(1)), | ||
85 | }; | ||
86 | |||
87 | void __init ltq_register_asc(int port) | ||
88 | { | ||
89 | switch (port) { | ||
90 | case 0: | ||
91 | platform_device_register_simple("ltq_asc", 0, | ||
92 | ltq_asc0_resources, ARRAY_SIZE(ltq_asc0_resources)); | ||
93 | break; | ||
94 | case 1: | ||
95 | platform_device_register_simple("ltq_asc", 1, | ||
96 | ltq_asc1_resources, ARRAY_SIZE(ltq_asc1_resources)); | ||
97 | break; | ||
98 | default: | ||
99 | break; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | #ifdef CONFIG_PCI | ||
104 | /* pci */ | ||
105 | static struct platform_device ltq_pci = { | ||
106 | .name = "ltq_pci", | ||
107 | .num_resources = 0, | ||
108 | }; | ||
109 | |||
110 | void __init ltq_register_pci(struct ltq_pci_data *data) | ||
111 | { | ||
112 | ltq_pci.dev.platform_data = data; | ||
113 | platform_device_register(<q_pci); | ||
114 | } | ||
115 | #else | ||
116 | void __init ltq_register_pci(struct ltq_pci_data *data) | ||
117 | { | ||
118 | pr_err("kernel is compiled without PCI support\n"); | ||
119 | } | ||
120 | #endif | ||
diff --git a/arch/mips/lantiq/devices.h b/arch/mips/lantiq/devices.h deleted file mode 100644 index 2947bb19a528..000000000000 --- a/arch/mips/lantiq/devices.h +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LTQ_DEVICES_H__ | ||
10 | #define _LTQ_DEVICES_H__ | ||
11 | |||
12 | #include <lantiq_platform.h> | ||
13 | #include <linux/mtd/physmap.h> | ||
14 | |||
15 | #define IRQ_RES(resname, irq) \ | ||
16 | {.name = #resname, .start = (irq), .flags = IORESOURCE_IRQ} | ||
17 | |||
18 | extern void ltq_register_nor(struct physmap_flash_data *data); | ||
19 | extern void ltq_register_wdt(void); | ||
20 | extern void ltq_register_asc(int port); | ||
21 | extern void ltq_register_pci(struct ltq_pci_data *data); | ||
22 | |||
23 | #endif | ||
diff --git a/arch/mips/lantiq/dts/Makefile b/arch/mips/lantiq/dts/Makefile new file mode 100644 index 000000000000..674fca45f72d --- /dev/null +++ b/arch/mips/lantiq/dts/Makefile | |||
@@ -0,0 +1,4 @@ | |||
1 | obj-$(CONFIG_DT_EASY50712) := easy50712.dtb.o | ||
2 | |||
3 | $(obj)/%.dtb: $(obj)/%.dts | ||
4 | $(call if_changed,dtc) | ||
diff --git a/arch/mips/lantiq/dts/danube.dtsi b/arch/mips/lantiq/dts/danube.dtsi new file mode 100644 index 000000000000..3a4520f009cf --- /dev/null +++ b/arch/mips/lantiq/dts/danube.dtsi | |||
@@ -0,0 +1,105 @@ | |||
1 | / { | ||
2 | #address-cells = <1>; | ||
3 | #size-cells = <1>; | ||
4 | compatible = "lantiq,xway", "lantiq,danube"; | ||
5 | |||
6 | cpus { | ||
7 | cpu@0 { | ||
8 | compatible = "mips,mips24Kc"; | ||
9 | }; | ||
10 | }; | ||
11 | |||
12 | biu@1F800000 { | ||
13 | #address-cells = <1>; | ||
14 | #size-cells = <1>; | ||
15 | compatible = "lantiq,biu", "simple-bus"; | ||
16 | reg = <0x1F800000 0x800000>; | ||
17 | ranges = <0x0 0x1F800000 0x7FFFFF>; | ||
18 | |||
19 | icu0: icu@80200 { | ||
20 | #interrupt-cells = <1>; | ||
21 | interrupt-controller; | ||
22 | compatible = "lantiq,icu"; | ||
23 | reg = <0x80200 0x120>; | ||
24 | }; | ||
25 | |||
26 | watchdog@803F0 { | ||
27 | compatible = "lantiq,wdt"; | ||
28 | reg = <0x803F0 0x10>; | ||
29 | }; | ||
30 | }; | ||
31 | |||
32 | sram@1F000000 { | ||
33 | #address-cells = <1>; | ||
34 | #size-cells = <1>; | ||
35 | compatible = "lantiq,sram"; | ||
36 | reg = <0x1F000000 0x800000>; | ||
37 | ranges = <0x0 0x1F000000 0x7FFFFF>; | ||
38 | |||
39 | eiu0: eiu@101000 { | ||
40 | #interrupt-cells = <1>; | ||
41 | interrupt-controller; | ||
42 | interrupt-parent; | ||
43 | compatible = "lantiq,eiu-xway"; | ||
44 | reg = <0x101000 0x1000>; | ||
45 | }; | ||
46 | |||
47 | pmu0: pmu@102000 { | ||
48 | compatible = "lantiq,pmu-xway"; | ||
49 | reg = <0x102000 0x1000>; | ||
50 | }; | ||
51 | |||
52 | cgu0: cgu@103000 { | ||
53 | compatible = "lantiq,cgu-xway"; | ||
54 | reg = <0x103000 0x1000>; | ||
55 | #clock-cells = <1>; | ||
56 | }; | ||
57 | |||
58 | rcu0: rcu@203000 { | ||
59 | compatible = "lantiq,rcu-xway"; | ||
60 | reg = <0x203000 0x1000>; | ||
61 | }; | ||
62 | }; | ||
63 | |||
64 | fpi@10000000 { | ||
65 | #address-cells = <1>; | ||
66 | #size-cells = <1>; | ||
67 | compatible = "lantiq,fpi", "simple-bus"; | ||
68 | ranges = <0x0 0x10000000 0xEEFFFFF>; | ||
69 | reg = <0x10000000 0xEF00000>; | ||
70 | |||
71 | gptu@E100A00 { | ||
72 | compatible = "lantiq,gptu-xway"; | ||
73 | reg = <0xE100A00 0x100>; | ||
74 | }; | ||
75 | |||
76 | serial@E100C00 { | ||
77 | compatible = "lantiq,asc"; | ||
78 | reg = <0xE100C00 0x400>; | ||
79 | interrupt-parent = <&icu0>; | ||
80 | interrupts = <112 113 114>; | ||
81 | }; | ||
82 | |||
83 | dma0: dma@E104100 { | ||
84 | compatible = "lantiq,dma-xway"; | ||
85 | reg = <0xE104100 0x800>; | ||
86 | }; | ||
87 | |||
88 | ebu0: ebu@E105300 { | ||
89 | compatible = "lantiq,ebu-xway"; | ||
90 | reg = <0xE105300 0x100>; | ||
91 | }; | ||
92 | |||
93 | pci0: pci@E105400 { | ||
94 | #address-cells = <3>; | ||
95 | #size-cells = <2>; | ||
96 | #interrupt-cells = <1>; | ||
97 | compatible = "lantiq,pci-xway"; | ||
98 | bus-range = <0x0 0x0>; | ||
99 | ranges = <0x2000000 0 0x8000000 0x8000000 0 0x2000000 /* pci memory */ | ||
100 | 0x1000000 0 0x00000000 0xAE00000 0 0x200000>; /* io space */ | ||
101 | reg = <0x7000000 0x8000 /* config space */ | ||
102 | 0xE105400 0x400>; /* pci bridge */ | ||
103 | }; | ||
104 | }; | ||
105 | }; | ||
diff --git a/arch/mips/lantiq/dts/easy50712.dts b/arch/mips/lantiq/dts/easy50712.dts new file mode 100644 index 000000000000..68c17310bc82 --- /dev/null +++ b/arch/mips/lantiq/dts/easy50712.dts | |||
@@ -0,0 +1,113 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "danube.dtsi" | ||
4 | |||
5 | / { | ||
6 | chosen { | ||
7 | bootargs = "console=ttyLTQ0,115200 init=/etc/preinit"; | ||
8 | }; | ||
9 | |||
10 | memory@0 { | ||
11 | reg = <0x0 0x2000000>; | ||
12 | }; | ||
13 | |||
14 | fpi@10000000 { | ||
15 | #address-cells = <1>; | ||
16 | #size-cells = <1>; | ||
17 | localbus@0 { | ||
18 | #address-cells = <2>; | ||
19 | #size-cells = <1>; | ||
20 | ranges = <0 0 0x0 0x3ffffff /* addrsel0 */ | ||
21 | 1 0 0x4000000 0x4000010>; /* addsel1 */ | ||
22 | compatible = "lantiq,localbus", "simple-bus"; | ||
23 | |||
24 | nor-boot@0 { | ||
25 | compatible = "lantiq,nor"; | ||
26 | bank-width = <2>; | ||
27 | reg = <0 0x0 0x2000000>; | ||
28 | #address-cells = <1>; | ||
29 | #size-cells = <1>; | ||
30 | |||
31 | partition@0 { | ||
32 | label = "uboot"; | ||
33 | reg = <0x00000 0x10000>; /* 64 KB */ | ||
34 | }; | ||
35 | |||
36 | partition@10000 { | ||
37 | label = "uboot_env"; | ||
38 | reg = <0x10000 0x10000>; /* 64 KB */ | ||
39 | }; | ||
40 | |||
41 | partition@20000 { | ||
42 | label = "linux"; | ||
43 | reg = <0x20000 0x3d0000>; | ||
44 | }; | ||
45 | |||
46 | partition@400000 { | ||
47 | label = "rootfs"; | ||
48 | reg = <0x400000 0x400000>; | ||
49 | }; | ||
50 | }; | ||
51 | }; | ||
52 | |||
53 | gpio: pinmux@E100B10 { | ||
54 | compatible = "lantiq,pinctrl-xway"; | ||
55 | pinctrl-names = "default"; | ||
56 | pinctrl-0 = <&state_default>; | ||
57 | |||
58 | #gpio-cells = <2>; | ||
59 | gpio-controller; | ||
60 | reg = <0xE100B10 0xA0>; | ||
61 | |||
62 | state_default: pinmux { | ||
63 | stp { | ||
64 | lantiq,groups = "stp"; | ||
65 | lantiq,function = "stp"; | ||
66 | }; | ||
67 | exin { | ||
68 | lantiq,groups = "exin1"; | ||
69 | lantiq,function = "exin"; | ||
70 | }; | ||
71 | pci { | ||
72 | lantiq,groups = "gnt1"; | ||
73 | lantiq,function = "pci"; | ||
74 | }; | ||
75 | conf_out { | ||
76 | lantiq,pins = "io4", "io5", "io6"; /* stp */ | ||
77 | lantiq,open-drain; | ||
78 | lantiq,pull = <0>; | ||
79 | }; | ||
80 | }; | ||
81 | }; | ||
82 | |||
83 | etop@E180000 { | ||
84 | compatible = "lantiq,etop-xway"; | ||
85 | reg = <0xE180000 0x40000>; | ||
86 | interrupt-parent = <&icu0>; | ||
87 | interrupts = <73 78>; | ||
88 | phy-mode = "rmii"; | ||
89 | mac-address = [ 00 11 22 33 44 55 ]; | ||
90 | }; | ||
91 | |||
92 | stp0: stp@E100BB0 { | ||
93 | #gpio-cells = <2>; | ||
94 | compatible = "lantiq,gpio-stp-xway"; | ||
95 | gpio-controller; | ||
96 | reg = <0xE100BB0 0x40>; | ||
97 | |||
98 | lantiq,shadow = <0xfff>; | ||
99 | lantiq,groups = <0x3>; | ||
100 | }; | ||
101 | |||
102 | pci@E105400 { | ||
103 | lantiq,bus-clock = <33333333>; | ||
104 | interrupt-map-mask = <0xf800 0x0 0x0 0x7>; | ||
105 | interrupt-map = < | ||
106 | 0x7000 0 0 1 &icu0 29 1 // slot 14, irq 29 | ||
107 | >; | ||
108 | gpios-reset = <&gpio 21 0>; | ||
109 | req-mask = <0x1>; /* GNT1 */ | ||
110 | }; | ||
111 | |||
112 | }; | ||
113 | }; | ||
diff --git a/arch/mips/lantiq/early_printk.c b/arch/mips/lantiq/early_printk.c index 972e05f87631..9b28d0940ef4 100644 --- a/arch/mips/lantiq/early_printk.c +++ b/arch/mips/lantiq/early_printk.c | |||
@@ -6,17 +6,16 @@ | |||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | 6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> |
7 | */ | 7 | */ |
8 | 8 | ||
9 | #include <linux/init.h> | ||
10 | #include <linux/cpu.h> | 9 | #include <linux/cpu.h> |
11 | |||
12 | #include <lantiq.h> | ||
13 | #include <lantiq_soc.h> | 10 | #include <lantiq_soc.h> |
14 | 11 | ||
15 | /* no ioremap possible at this early stage, lets use KSEG1 instead */ | ||
16 | #define LTQ_ASC_BASE KSEG1ADDR(LTQ_ASC1_BASE_ADDR) | ||
17 | #define ASC_BUF 1024 | 12 | #define ASC_BUF 1024 |
18 | #define LTQ_ASC_FSTAT ((u32 *)(LTQ_ASC_BASE + 0x0048)) | 13 | #define LTQ_ASC_FSTAT ((u32 *)(LTQ_EARLY_ASC + 0x0048)) |
19 | #define LTQ_ASC_TBUF ((u32 *)(LTQ_ASC_BASE + 0x0020)) | 14 | #ifdef __BIG_ENDIAN |
15 | #define LTQ_ASC_TBUF ((u32 *)(LTQ_EARLY_ASC + 0x0020 + 3)) | ||
16 | #else | ||
17 | #define LTQ_ASC_TBUF ((u32 *)(LTQ_EARLY_ASC + 0x0020)) | ||
18 | #endif | ||
20 | #define TXMASK 0x3F00 | 19 | #define TXMASK 0x3F00 |
21 | #define TXOFFSET 8 | 20 | #define TXOFFSET 8 |
22 | 21 | ||
@@ -27,7 +26,7 @@ void prom_putchar(char c) | |||
27 | local_irq_save(flags); | 26 | local_irq_save(flags); |
28 | do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET); | 27 | do { } while ((ltq_r32(LTQ_ASC_FSTAT) & TXMASK) >> TXOFFSET); |
29 | if (c == '\n') | 28 | if (c == '\n') |
30 | ltq_w32('\r', LTQ_ASC_TBUF); | 29 | ltq_w8('\r', LTQ_ASC_TBUF); |
31 | ltq_w32(c, LTQ_ASC_TBUF); | 30 | ltq_w8(c, LTQ_ASC_TBUF); |
32 | local_irq_restore(flags); | 31 | local_irq_restore(flags); |
33 | } | 32 | } |
diff --git a/arch/mips/lantiq/falcon/Makefile b/arch/mips/lantiq/falcon/Makefile new file mode 100644 index 000000000000..ff220f97693d --- /dev/null +++ b/arch/mips/lantiq/falcon/Makefile | |||
@@ -0,0 +1 @@ | |||
obj-y := prom.o reset.o sysctrl.o | |||
diff --git a/arch/mips/lantiq/falcon/prom.c b/arch/mips/lantiq/falcon/prom.c new file mode 100644 index 000000000000..c1d278f05a3a --- /dev/null +++ b/arch/mips/lantiq/falcon/prom.c | |||
@@ -0,0 +1,87 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com> | ||
7 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | ||
8 | */ | ||
9 | |||
10 | #include <linux/kernel.h> | ||
11 | #include <asm/io.h> | ||
12 | |||
13 | #include <lantiq_soc.h> | ||
14 | |||
15 | #include "../prom.h" | ||
16 | |||
17 | #define SOC_FALCON "Falcon" | ||
18 | #define SOC_FALCON_D "Falcon-D" | ||
19 | #define SOC_FALCON_V "Falcon-V" | ||
20 | #define SOC_FALCON_M "Falcon-M" | ||
21 | |||
22 | #define COMP_FALCON "lantiq,falcon" | ||
23 | |||
24 | #define PART_SHIFT 12 | ||
25 | #define PART_MASK 0x0FFFF000 | ||
26 | #define REV_SHIFT 28 | ||
27 | #define REV_MASK 0xF0000000 | ||
28 | #define SREV_SHIFT 22 | ||
29 | #define SREV_MASK 0x03C00000 | ||
30 | #define TYPE_SHIFT 26 | ||
31 | #define TYPE_MASK 0x3C000000 | ||
32 | |||
33 | /* reset, nmi and ejtag exception vectors */ | ||
34 | #define BOOT_REG_BASE (KSEG1 | 0x1F200000) | ||
35 | #define BOOT_RVEC (BOOT_REG_BASE | 0x00) | ||
36 | #define BOOT_NVEC (BOOT_REG_BASE | 0x04) | ||
37 | #define BOOT_EVEC (BOOT_REG_BASE | 0x08) | ||
38 | |||
39 | void __init ltq_soc_nmi_setup(void) | ||
40 | { | ||
41 | extern void (*nmi_handler)(void); | ||
42 | |||
43 | ltq_w32((unsigned long)&nmi_handler, (void *)BOOT_NVEC); | ||
44 | } | ||
45 | |||
46 | void __init ltq_soc_ejtag_setup(void) | ||
47 | { | ||
48 | extern void (*ejtag_debug_handler)(void); | ||
49 | |||
50 | ltq_w32((unsigned long)&ejtag_debug_handler, (void *)BOOT_EVEC); | ||
51 | } | ||
52 | |||
53 | void __init ltq_soc_detect(struct ltq_soc_info *i) | ||
54 | { | ||
55 | u32 type; | ||
56 | i->partnum = (ltq_r32(FALCON_CHIPID) & PART_MASK) >> PART_SHIFT; | ||
57 | i->rev = (ltq_r32(FALCON_CHIPID) & REV_MASK) >> REV_SHIFT; | ||
58 | i->srev = ((ltq_r32(FALCON_CHIPCONF) & SREV_MASK) >> SREV_SHIFT); | ||
59 | i->compatible = COMP_FALCON; | ||
60 | i->type = SOC_TYPE_FALCON; | ||
61 | sprintf(i->rev_type, "%c%d%d", (i->srev & 0x4) ? ('B') : ('A'), | ||
62 | i->rev & 0x7, (i->srev & 0x3) + 1); | ||
63 | |||
64 | switch (i->partnum) { | ||
65 | case SOC_ID_FALCON: | ||
66 | type = (ltq_r32(FALCON_CHIPTYPE) & TYPE_MASK) >> TYPE_SHIFT; | ||
67 | switch (type) { | ||
68 | case 0: | ||
69 | i->name = SOC_FALCON_D; | ||
70 | break; | ||
71 | case 1: | ||
72 | i->name = SOC_FALCON_V; | ||
73 | break; | ||
74 | case 2: | ||
75 | i->name = SOC_FALCON_M; | ||
76 | break; | ||
77 | default: | ||
78 | i->name = SOC_FALCON; | ||
79 | break; | ||
80 | } | ||
81 | break; | ||
82 | |||
83 | default: | ||
84 | unreachable(); | ||
85 | break; | ||
86 | } | ||
87 | } | ||
diff --git a/arch/mips/lantiq/falcon/reset.c b/arch/mips/lantiq/falcon/reset.c new file mode 100644 index 000000000000..568248253426 --- /dev/null +++ b/arch/mips/lantiq/falcon/reset.c | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2012 Thomas Langer <thomas.langer@lantiq.com> | ||
7 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | ||
8 | */ | ||
9 | |||
10 | #include <linux/init.h> | ||
11 | #include <linux/io.h> | ||
12 | #include <linux/pm.h> | ||
13 | #include <asm/reboot.h> | ||
14 | #include <linux/export.h> | ||
15 | |||
16 | #include <lantiq_soc.h> | ||
17 | |||
18 | /* CPU0 Reset Source Register */ | ||
19 | #define SYS1_CPU0RS 0x0040 | ||
20 | /* reset cause mask */ | ||
21 | #define CPU0RS_MASK 0x0003 | ||
22 | /* CPU0 Boot Mode Register */ | ||
23 | #define SYS1_BM 0x00a0 | ||
24 | /* boot mode mask */ | ||
25 | #define BM_MASK 0x0005 | ||
26 | |||
27 | /* allow platform code to find out what surce we booted from */ | ||
28 | unsigned char ltq_boot_select(void) | ||
29 | { | ||
30 | return ltq_sys1_r32(SYS1_BM) & BM_MASK; | ||
31 | } | ||
32 | |||
33 | /* allow the watchdog driver to find out what the boot reason was */ | ||
34 | int ltq_reset_cause(void) | ||
35 | { | ||
36 | return ltq_sys1_r32(SYS1_CPU0RS) & CPU0RS_MASK; | ||
37 | } | ||
38 | EXPORT_SYMBOL_GPL(ltq_reset_cause); | ||
39 | |||
40 | #define BOOT_REG_BASE (KSEG1 | 0x1F200000) | ||
41 | #define BOOT_PW1_REG (BOOT_REG_BASE | 0x20) | ||
42 | #define BOOT_PW2_REG (BOOT_REG_BASE | 0x24) | ||
43 | #define BOOT_PW1 0x4C545100 | ||
44 | #define BOOT_PW2 0x0051544C | ||
45 | |||
46 | #define WDT_REG_BASE (KSEG1 | 0x1F8803F0) | ||
47 | #define WDT_PW1 0x00BE0000 | ||
48 | #define WDT_PW2 0x00DC0000 | ||
49 | |||
50 | static void machine_restart(char *command) | ||
51 | { | ||
52 | local_irq_disable(); | ||
53 | |||
54 | /* reboot magic */ | ||
55 | ltq_w32(BOOT_PW1, (void *)BOOT_PW1_REG); /* 'LTQ\0' */ | ||
56 | ltq_w32(BOOT_PW2, (void *)BOOT_PW2_REG); /* '\0QTL' */ | ||
57 | ltq_w32(0, (void *)BOOT_REG_BASE); /* reset Bootreg RVEC */ | ||
58 | |||
59 | /* watchdog magic */ | ||
60 | ltq_w32(WDT_PW1, (void *)WDT_REG_BASE); | ||
61 | ltq_w32(WDT_PW2 | | ||
62 | (0x3 << 26) | /* PWL */ | ||
63 | (0x2 << 24) | /* CLKDIV */ | ||
64 | (0x1 << 31) | /* enable */ | ||
65 | (1), /* reload */ | ||
66 | (void *)WDT_REG_BASE); | ||
67 | unreachable(); | ||
68 | } | ||
69 | |||
70 | static void machine_halt(void) | ||
71 | { | ||
72 | local_irq_disable(); | ||
73 | unreachable(); | ||
74 | } | ||
75 | |||
76 | static void machine_power_off(void) | ||
77 | { | ||
78 | local_irq_disable(); | ||
79 | unreachable(); | ||
80 | } | ||
81 | |||
82 | static int __init mips_reboot_setup(void) | ||
83 | { | ||
84 | _machine_restart = machine_restart; | ||
85 | _machine_halt = machine_halt; | ||
86 | pm_power_off = machine_power_off; | ||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | arch_initcall(mips_reboot_setup); | ||
diff --git a/arch/mips/lantiq/falcon/sysctrl.c b/arch/mips/lantiq/falcon/sysctrl.c new file mode 100644 index 000000000000..ba0123d13d40 --- /dev/null +++ b/arch/mips/lantiq/falcon/sysctrl.c | |||
@@ -0,0 +1,260 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2011 Thomas Langer <thomas.langer@lantiq.com> | ||
7 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | ||
8 | */ | ||
9 | |||
10 | #include <linux/ioport.h> | ||
11 | #include <linux/export.h> | ||
12 | #include <linux/clkdev.h> | ||
13 | #include <linux/of_address.h> | ||
14 | #include <asm/delay.h> | ||
15 | |||
16 | #include <lantiq_soc.h> | ||
17 | |||
18 | #include "../clk.h" | ||
19 | |||
20 | /* infrastructure control register */ | ||
21 | #define SYS1_INFRAC 0x00bc | ||
22 | /* Configuration fuses for drivers and pll */ | ||
23 | #define STATUS_CONFIG 0x0040 | ||
24 | |||
25 | /* GPE frequency selection */ | ||
26 | #define GPPC_OFFSET 24 | ||
27 | #define GPEFREQ_MASK 0x00000C0 | ||
28 | #define GPEFREQ_OFFSET 10 | ||
29 | /* Clock status register */ | ||
30 | #define SYSCTL_CLKS 0x0000 | ||
31 | /* Clock enable register */ | ||
32 | #define SYSCTL_CLKEN 0x0004 | ||
33 | /* Clock clear register */ | ||
34 | #define SYSCTL_CLKCLR 0x0008 | ||
35 | /* Activation Status Register */ | ||
36 | #define SYSCTL_ACTS 0x0020 | ||
37 | /* Activation Register */ | ||
38 | #define SYSCTL_ACT 0x0024 | ||
39 | /* Deactivation Register */ | ||
40 | #define SYSCTL_DEACT 0x0028 | ||
41 | /* reboot Register */ | ||
42 | #define SYSCTL_RBT 0x002c | ||
43 | /* CPU0 Clock Control Register */ | ||
44 | #define SYS1_CPU0CC 0x0040 | ||
45 | /* HRST_OUT_N Control Register */ | ||
46 | #define SYS1_HRSTOUTC 0x00c0 | ||
47 | /* clock divider bit */ | ||
48 | #define CPU0CC_CPUDIV 0x0001 | ||
49 | |||
50 | /* Activation Status Register */ | ||
51 | #define ACTS_ASC1_ACT 0x00000800 | ||
52 | #define ACTS_I2C_ACT 0x00004000 | ||
53 | #define ACTS_P0 0x00010000 | ||
54 | #define ACTS_P1 0x00010000 | ||
55 | #define ACTS_P2 0x00020000 | ||
56 | #define ACTS_P3 0x00020000 | ||
57 | #define ACTS_P4 0x00040000 | ||
58 | #define ACTS_PADCTRL0 0x00100000 | ||
59 | #define ACTS_PADCTRL1 0x00100000 | ||
60 | #define ACTS_PADCTRL2 0x00200000 | ||
61 | #define ACTS_PADCTRL3 0x00200000 | ||
62 | #define ACTS_PADCTRL4 0x00400000 | ||
63 | |||
64 | #define sysctl_w32(m, x, y) ltq_w32((x), sysctl_membase[m] + (y)) | ||
65 | #define sysctl_r32(m, x) ltq_r32(sysctl_membase[m] + (x)) | ||
66 | #define sysctl_w32_mask(m, clear, set, reg) \ | ||
67 | sysctl_w32(m, (sysctl_r32(m, reg) & ~(clear)) | (set), reg) | ||
68 | |||
69 | #define status_w32(x, y) ltq_w32((x), status_membase + (y)) | ||
70 | #define status_r32(x) ltq_r32(status_membase + (x)) | ||
71 | |||
72 | static void __iomem *sysctl_membase[3], *status_membase; | ||
73 | void __iomem *ltq_sys1_membase, *ltq_ebu_membase; | ||
74 | |||
75 | void falcon_trigger_hrst(int level) | ||
76 | { | ||
77 | sysctl_w32(SYSCTL_SYS1, level & 1, SYS1_HRSTOUTC); | ||
78 | } | ||
79 | |||
80 | static inline void sysctl_wait(struct clk *clk, | ||
81 | unsigned int test, unsigned int reg) | ||
82 | { | ||
83 | int err = 1000000; | ||
84 | |||
85 | do {} while (--err && ((sysctl_r32(clk->module, reg) | ||
86 | & clk->bits) != test)); | ||
87 | if (!err) | ||
88 | pr_err("module de/activation failed %d %08X %08X %08X\n", | ||
89 | clk->module, clk->bits, test, | ||
90 | sysctl_r32(clk->module, reg) & clk->bits); | ||
91 | } | ||
92 | |||
93 | static int sysctl_activate(struct clk *clk) | ||
94 | { | ||
95 | sysctl_w32(clk->module, clk->bits, SYSCTL_CLKEN); | ||
96 | sysctl_w32(clk->module, clk->bits, SYSCTL_ACT); | ||
97 | sysctl_wait(clk, clk->bits, SYSCTL_ACTS); | ||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | static void sysctl_deactivate(struct clk *clk) | ||
102 | { | ||
103 | sysctl_w32(clk->module, clk->bits, SYSCTL_CLKCLR); | ||
104 | sysctl_w32(clk->module, clk->bits, SYSCTL_DEACT); | ||
105 | sysctl_wait(clk, 0, SYSCTL_ACTS); | ||
106 | } | ||
107 | |||
108 | static int sysctl_clken(struct clk *clk) | ||
109 | { | ||
110 | sysctl_w32(clk->module, clk->bits, SYSCTL_CLKEN); | ||
111 | sysctl_wait(clk, clk->bits, SYSCTL_CLKS); | ||
112 | return 0; | ||
113 | } | ||
114 | |||
115 | static void sysctl_clkdis(struct clk *clk) | ||
116 | { | ||
117 | sysctl_w32(clk->module, clk->bits, SYSCTL_CLKCLR); | ||
118 | sysctl_wait(clk, 0, SYSCTL_CLKS); | ||
119 | } | ||
120 | |||
121 | static void sysctl_reboot(struct clk *clk) | ||
122 | { | ||
123 | unsigned int act; | ||
124 | unsigned int bits; | ||
125 | |||
126 | act = sysctl_r32(clk->module, SYSCTL_ACT); | ||
127 | bits = ~act & clk->bits; | ||
128 | if (bits != 0) { | ||
129 | sysctl_w32(clk->module, bits, SYSCTL_CLKEN); | ||
130 | sysctl_w32(clk->module, bits, SYSCTL_ACT); | ||
131 | sysctl_wait(clk, bits, SYSCTL_ACTS); | ||
132 | } | ||
133 | sysctl_w32(clk->module, act & clk->bits, SYSCTL_RBT); | ||
134 | sysctl_wait(clk, clk->bits, SYSCTL_ACTS); | ||
135 | } | ||
136 | |||
137 | /* enable the ONU core */ | ||
138 | static void falcon_gpe_enable(void) | ||
139 | { | ||
140 | unsigned int freq; | ||
141 | unsigned int status; | ||
142 | |||
143 | /* if if the clock is already enabled */ | ||
144 | status = sysctl_r32(SYSCTL_SYS1, SYS1_INFRAC); | ||
145 | if (status & (1 << (GPPC_OFFSET + 1))) | ||
146 | return; | ||
147 | |||
148 | if (status_r32(STATUS_CONFIG) == 0) | ||
149 | freq = 1; /* use 625MHz on unfused chip */ | ||
150 | else | ||
151 | freq = (status_r32(STATUS_CONFIG) & | ||
152 | GPEFREQ_MASK) >> | ||
153 | GPEFREQ_OFFSET; | ||
154 | |||
155 | /* apply new frequency */ | ||
156 | sysctl_w32_mask(SYSCTL_SYS1, 7 << (GPPC_OFFSET + 1), | ||
157 | freq << (GPPC_OFFSET + 2) , SYS1_INFRAC); | ||
158 | udelay(1); | ||
159 | |||
160 | /* enable new frequency */ | ||
161 | sysctl_w32_mask(SYSCTL_SYS1, 0, 1 << (GPPC_OFFSET + 1), SYS1_INFRAC); | ||
162 | udelay(1); | ||
163 | } | ||
164 | |||
165 | static inline void clkdev_add_sys(const char *dev, unsigned int module, | ||
166 | unsigned int bits) | ||
167 | { | ||
168 | struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); | ||
169 | |||
170 | clk->cl.dev_id = dev; | ||
171 | clk->cl.con_id = NULL; | ||
172 | clk->cl.clk = clk; | ||
173 | clk->module = module; | ||
174 | clk->activate = sysctl_activate; | ||
175 | clk->deactivate = sysctl_deactivate; | ||
176 | clk->enable = sysctl_clken; | ||
177 | clk->disable = sysctl_clkdis; | ||
178 | clk->reboot = sysctl_reboot; | ||
179 | clkdev_add(&clk->cl); | ||
180 | } | ||
181 | |||
182 | void __init ltq_soc_init(void) | ||
183 | { | ||
184 | struct device_node *np_status = | ||
185 | of_find_compatible_node(NULL, NULL, "lantiq,status-falcon"); | ||
186 | struct device_node *np_ebu = | ||
187 | of_find_compatible_node(NULL, NULL, "lantiq,ebu-falcon"); | ||
188 | struct device_node *np_sys1 = | ||
189 | of_find_compatible_node(NULL, NULL, "lantiq,sys1-falcon"); | ||
190 | struct device_node *np_syseth = | ||
191 | of_find_compatible_node(NULL, NULL, "lantiq,syseth-falcon"); | ||
192 | struct device_node *np_sysgpe = | ||
193 | of_find_compatible_node(NULL, NULL, "lantiq,sysgpe-falcon"); | ||
194 | struct resource res_status, res_ebu, res_sys[3]; | ||
195 | int i; | ||
196 | |||
197 | /* check if all the core register ranges are available */ | ||
198 | if (!np_status || !np_ebu || !np_sys1 || !np_syseth || !np_sysgpe) | ||
199 | panic("Failed to load core nodes from devicetree"); | ||
200 | |||
201 | if (of_address_to_resource(np_status, 0, &res_status) || | ||
202 | of_address_to_resource(np_ebu, 0, &res_ebu) || | ||
203 | of_address_to_resource(np_sys1, 0, &res_sys[0]) || | ||
204 | of_address_to_resource(np_syseth, 0, &res_sys[1]) || | ||
205 | of_address_to_resource(np_sysgpe, 0, &res_sys[2])) | ||
206 | panic("Failed to get core resources"); | ||
207 | |||
208 | if ((request_mem_region(res_status.start, resource_size(&res_status), | ||
209 | res_status.name) < 0) || | ||
210 | (request_mem_region(res_ebu.start, resource_size(&res_ebu), | ||
211 | res_ebu.name) < 0) || | ||
212 | (request_mem_region(res_sys[0].start, | ||
213 | resource_size(&res_sys[0]), | ||
214 | res_sys[0].name) < 0) || | ||
215 | (request_mem_region(res_sys[1].start, | ||
216 | resource_size(&res_sys[1]), | ||
217 | res_sys[1].name) < 0) || | ||
218 | (request_mem_region(res_sys[2].start, | ||
219 | resource_size(&res_sys[2]), | ||
220 | res_sys[2].name) < 0)) | ||
221 | pr_err("Failed to request core reources"); | ||
222 | |||
223 | status_membase = ioremap_nocache(res_status.start, | ||
224 | resource_size(&res_status)); | ||
225 | ltq_ebu_membase = ioremap_nocache(res_ebu.start, | ||
226 | resource_size(&res_ebu)); | ||
227 | |||
228 | if (!status_membase || !ltq_ebu_membase) | ||
229 | panic("Failed to remap core resources"); | ||
230 | |||
231 | for (i = 0; i < 3; i++) { | ||
232 | sysctl_membase[i] = ioremap_nocache(res_sys[i].start, | ||
233 | resource_size(&res_sys[i])); | ||
234 | if (!sysctl_membase[i]) | ||
235 | panic("Failed to remap sysctrl resources"); | ||
236 | } | ||
237 | ltq_sys1_membase = sysctl_membase[0]; | ||
238 | |||
239 | falcon_gpe_enable(); | ||
240 | |||
241 | /* get our 3 static rates for cpu, fpi and io clocks */ | ||
242 | if (ltq_sys1_r32(SYS1_CPU0CC) & CPU0CC_CPUDIV) | ||
243 | clkdev_add_static(CLOCK_200M, CLOCK_100M, CLOCK_200M); | ||
244 | else | ||
245 | clkdev_add_static(CLOCK_400M, CLOCK_100M, CLOCK_200M); | ||
246 | |||
247 | /* add our clock domains */ | ||
248 | clkdev_add_sys("1d810000.gpio", SYSCTL_SYSETH, ACTS_P0); | ||
249 | clkdev_add_sys("1d810100.gpio", SYSCTL_SYSETH, ACTS_P2); | ||
250 | clkdev_add_sys("1e800100.gpio", SYSCTL_SYS1, ACTS_P1); | ||
251 | clkdev_add_sys("1e800200.gpio", SYSCTL_SYS1, ACTS_P3); | ||
252 | clkdev_add_sys("1e800300.gpio", SYSCTL_SYS1, ACTS_P4); | ||
253 | clkdev_add_sys("1db01000.pad", SYSCTL_SYSETH, ACTS_PADCTRL0); | ||
254 | clkdev_add_sys("1db02000.pad", SYSCTL_SYSETH, ACTS_PADCTRL2); | ||
255 | clkdev_add_sys("1e800400.pad", SYSCTL_SYS1, ACTS_PADCTRL1); | ||
256 | clkdev_add_sys("1e800500.pad", SYSCTL_SYS1, ACTS_PADCTRL3); | ||
257 | clkdev_add_sys("1e800600.pad", SYSCTL_SYS1, ACTS_PADCTRL4); | ||
258 | clkdev_add_sys("1e100C00.serial", SYSCTL_SYS1, ACTS_ASC1_ACT); | ||
259 | clkdev_add_sys("1e200000.i2c", SYSCTL_SYS1, ACTS_I2C_ACT); | ||
260 | } | ||
diff --git a/arch/mips/lantiq/irq.c b/arch/mips/lantiq/irq.c index d673731c538a..57c1a4e51408 100644 --- a/arch/mips/lantiq/irq.c +++ b/arch/mips/lantiq/irq.c | |||
@@ -9,6 +9,11 @@ | |||
9 | 9 | ||
10 | #include <linux/interrupt.h> | 10 | #include <linux/interrupt.h> |
11 | #include <linux/ioport.h> | 11 | #include <linux/ioport.h> |
12 | #include <linux/sched.h> | ||
13 | #include <linux/irqdomain.h> | ||
14 | #include <linux/of_platform.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/of_irq.h> | ||
12 | 17 | ||
13 | #include <asm/bootinfo.h> | 18 | #include <asm/bootinfo.h> |
14 | #include <asm/irq_cpu.h> | 19 | #include <asm/irq_cpu.h> |
@@ -16,7 +21,7 @@ | |||
16 | #include <lantiq_soc.h> | 21 | #include <lantiq_soc.h> |
17 | #include <irq.h> | 22 | #include <irq.h> |
18 | 23 | ||
19 | /* register definitions */ | 24 | /* register definitions - internal irqs */ |
20 | #define LTQ_ICU_IM0_ISR 0x0000 | 25 | #define LTQ_ICU_IM0_ISR 0x0000 |
21 | #define LTQ_ICU_IM0_IER 0x0008 | 26 | #define LTQ_ICU_IM0_IER 0x0008 |
22 | #define LTQ_ICU_IM0_IOSR 0x0010 | 27 | #define LTQ_ICU_IM0_IOSR 0x0010 |
@@ -25,6 +30,7 @@ | |||
25 | #define LTQ_ICU_IM1_ISR 0x0028 | 30 | #define LTQ_ICU_IM1_ISR 0x0028 |
26 | #define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR) | 31 | #define LTQ_ICU_OFFSET (LTQ_ICU_IM1_ISR - LTQ_ICU_IM0_ISR) |
27 | 32 | ||
33 | /* register definitions - external irqs */ | ||
28 | #define LTQ_EIU_EXIN_C 0x0000 | 34 | #define LTQ_EIU_EXIN_C 0x0000 |
29 | #define LTQ_EIU_EXIN_INIC 0x0004 | 35 | #define LTQ_EIU_EXIN_INIC 0x0004 |
30 | #define LTQ_EIU_EXIN_INEN 0x000C | 36 | #define LTQ_EIU_EXIN_INEN 0x000C |
@@ -37,10 +43,14 @@ | |||
37 | #define LTQ_EIU_IR4 (INT_NUM_IM1_IRL0 + 1) | 43 | #define LTQ_EIU_IR4 (INT_NUM_IM1_IRL0 + 1) |
38 | #define LTQ_EIU_IR5 (INT_NUM_IM1_IRL0 + 2) | 44 | #define LTQ_EIU_IR5 (INT_NUM_IM1_IRL0 + 2) |
39 | #define LTQ_EIU_IR6 (INT_NUM_IM2_IRL0 + 30) | 45 | #define LTQ_EIU_IR6 (INT_NUM_IM2_IRL0 + 30) |
40 | 46 | #define XWAY_EXIN_COUNT 3 | |
41 | #define MAX_EIU 6 | 47 | #define MAX_EIU 6 |
42 | 48 | ||
43 | /* irqs generated by device attached to the EBU need to be acked in | 49 | /* the performance counter */ |
50 | #define LTQ_PERF_IRQ (INT_NUM_IM4_IRL0 + 31) | ||
51 | |||
52 | /* | ||
53 | * irqs generated by devices attached to the EBU need to be acked in | ||
44 | * a special manner | 54 | * a special manner |
45 | */ | 55 | */ |
46 | #define LTQ_ICU_EBU_IRQ 22 | 56 | #define LTQ_ICU_EBU_IRQ 22 |
@@ -51,6 +61,17 @@ | |||
51 | #define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y)) | 61 | #define ltq_eiu_w32(x, y) ltq_w32((x), ltq_eiu_membase + (y)) |
52 | #define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x)) | 62 | #define ltq_eiu_r32(x) ltq_r32(ltq_eiu_membase + (x)) |
53 | 63 | ||
64 | /* our 2 ipi interrupts for VSMP */ | ||
65 | #define MIPS_CPU_IPI_RESCHED_IRQ 0 | ||
66 | #define MIPS_CPU_IPI_CALL_IRQ 1 | ||
67 | |||
68 | /* we have a cascade of 8 irqs */ | ||
69 | #define MIPS_CPU_IRQ_CASCADE 8 | ||
70 | |||
71 | #if defined(CONFIG_MIPS_MT_SMP) || defined(CONFIG_MIPS_MT_SMTC) | ||
72 | int gic_present; | ||
73 | #endif | ||
74 | |||
54 | static unsigned short ltq_eiu_irq[MAX_EIU] = { | 75 | static unsigned short ltq_eiu_irq[MAX_EIU] = { |
55 | LTQ_EIU_IR0, | 76 | LTQ_EIU_IR0, |
56 | LTQ_EIU_IR1, | 77 | LTQ_EIU_IR1, |
@@ -60,64 +81,51 @@ static unsigned short ltq_eiu_irq[MAX_EIU] = { | |||
60 | LTQ_EIU_IR5, | 81 | LTQ_EIU_IR5, |
61 | }; | 82 | }; |
62 | 83 | ||
63 | static struct resource ltq_icu_resource = { | 84 | static int exin_avail; |
64 | .name = "icu", | ||
65 | .start = LTQ_ICU_BASE_ADDR, | ||
66 | .end = LTQ_ICU_BASE_ADDR + LTQ_ICU_SIZE - 1, | ||
67 | .flags = IORESOURCE_MEM, | ||
68 | }; | ||
69 | |||
70 | static struct resource ltq_eiu_resource = { | ||
71 | .name = "eiu", | ||
72 | .start = LTQ_EIU_BASE_ADDR, | ||
73 | .end = LTQ_EIU_BASE_ADDR + LTQ_ICU_SIZE - 1, | ||
74 | .flags = IORESOURCE_MEM, | ||
75 | }; | ||
76 | |||
77 | static void __iomem *ltq_icu_membase; | 85 | static void __iomem *ltq_icu_membase; |
78 | static void __iomem *ltq_eiu_membase; | 86 | static void __iomem *ltq_eiu_membase; |
79 | 87 | ||
80 | void ltq_disable_irq(struct irq_data *d) | 88 | void ltq_disable_irq(struct irq_data *d) |
81 | { | 89 | { |
82 | u32 ier = LTQ_ICU_IM0_IER; | 90 | u32 ier = LTQ_ICU_IM0_IER; |
83 | int irq_nr = d->irq - INT_NUM_IRQ0; | 91 | int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE; |
84 | 92 | ||
85 | ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); | 93 | ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET); |
86 | irq_nr %= INT_NUM_IM_OFFSET; | 94 | offset %= INT_NUM_IM_OFFSET; |
87 | ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier); | 95 | ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier); |
88 | } | 96 | } |
89 | 97 | ||
90 | void ltq_mask_and_ack_irq(struct irq_data *d) | 98 | void ltq_mask_and_ack_irq(struct irq_data *d) |
91 | { | 99 | { |
92 | u32 ier = LTQ_ICU_IM0_IER; | 100 | u32 ier = LTQ_ICU_IM0_IER; |
93 | u32 isr = LTQ_ICU_IM0_ISR; | 101 | u32 isr = LTQ_ICU_IM0_ISR; |
94 | int irq_nr = d->irq - INT_NUM_IRQ0; | 102 | int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE; |
95 | 103 | ||
96 | ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); | 104 | ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET); |
97 | isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); | 105 | isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET); |
98 | irq_nr %= INT_NUM_IM_OFFSET; | 106 | offset %= INT_NUM_IM_OFFSET; |
99 | ltq_icu_w32(ltq_icu_r32(ier) & ~(1 << irq_nr), ier); | 107 | ltq_icu_w32(ltq_icu_r32(ier) & ~BIT(offset), ier); |
100 | ltq_icu_w32((1 << irq_nr), isr); | 108 | ltq_icu_w32(BIT(offset), isr); |
101 | } | 109 | } |
102 | 110 | ||
103 | static void ltq_ack_irq(struct irq_data *d) | 111 | static void ltq_ack_irq(struct irq_data *d) |
104 | { | 112 | { |
105 | u32 isr = LTQ_ICU_IM0_ISR; | 113 | u32 isr = LTQ_ICU_IM0_ISR; |
106 | int irq_nr = d->irq - INT_NUM_IRQ0; | 114 | int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE; |
107 | 115 | ||
108 | isr += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); | 116 | isr += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET); |
109 | irq_nr %= INT_NUM_IM_OFFSET; | 117 | offset %= INT_NUM_IM_OFFSET; |
110 | ltq_icu_w32((1 << irq_nr), isr); | 118 | ltq_icu_w32(BIT(offset), isr); |
111 | } | 119 | } |
112 | 120 | ||
113 | void ltq_enable_irq(struct irq_data *d) | 121 | void ltq_enable_irq(struct irq_data *d) |
114 | { | 122 | { |
115 | u32 ier = LTQ_ICU_IM0_IER; | 123 | u32 ier = LTQ_ICU_IM0_IER; |
116 | int irq_nr = d->irq - INT_NUM_IRQ0; | 124 | int offset = d->hwirq - MIPS_CPU_IRQ_CASCADE; |
117 | 125 | ||
118 | ier += LTQ_ICU_OFFSET * (irq_nr / INT_NUM_IM_OFFSET); | 126 | ier += LTQ_ICU_OFFSET * (offset / INT_NUM_IM_OFFSET); |
119 | irq_nr %= INT_NUM_IM_OFFSET; | 127 | offset %= INT_NUM_IM_OFFSET; |
120 | ltq_icu_w32(ltq_icu_r32(ier) | (1 << irq_nr), ier); | 128 | ltq_icu_w32(ltq_icu_r32(ier) | BIT(offset), ier); |
121 | } | 129 | } |
122 | 130 | ||
123 | static unsigned int ltq_startup_eiu_irq(struct irq_data *d) | 131 | static unsigned int ltq_startup_eiu_irq(struct irq_data *d) |
@@ -126,15 +134,15 @@ static unsigned int ltq_startup_eiu_irq(struct irq_data *d) | |||
126 | 134 | ||
127 | ltq_enable_irq(d); | 135 | ltq_enable_irq(d); |
128 | for (i = 0; i < MAX_EIU; i++) { | 136 | for (i = 0; i < MAX_EIU; i++) { |
129 | if (d->irq == ltq_eiu_irq[i]) { | 137 | if (d->hwirq == ltq_eiu_irq[i]) { |
130 | /* low level - we should really handle set_type */ | 138 | /* low level - we should really handle set_type */ |
131 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) | | 139 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_C) | |
132 | (0x6 << (i * 4)), LTQ_EIU_EXIN_C); | 140 | (0x6 << (i * 4)), LTQ_EIU_EXIN_C); |
133 | /* clear all pending */ | 141 | /* clear all pending */ |
134 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~(1 << i), | 142 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INIC) & ~BIT(i), |
135 | LTQ_EIU_EXIN_INIC); | 143 | LTQ_EIU_EXIN_INIC); |
136 | /* enable */ | 144 | /* enable */ |
137 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | (1 << i), | 145 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) | BIT(i), |
138 | LTQ_EIU_EXIN_INEN); | 146 | LTQ_EIU_EXIN_INEN); |
139 | break; | 147 | break; |
140 | } | 148 | } |
@@ -149,9 +157,9 @@ static void ltq_shutdown_eiu_irq(struct irq_data *d) | |||
149 | 157 | ||
150 | ltq_disable_irq(d); | 158 | ltq_disable_irq(d); |
151 | for (i = 0; i < MAX_EIU; i++) { | 159 | for (i = 0; i < MAX_EIU; i++) { |
152 | if (d->irq == ltq_eiu_irq[i]) { | 160 | if (d->hwirq == ltq_eiu_irq[i]) { |
153 | /* disable */ | 161 | /* disable */ |
154 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~(1 << i), | 162 | ltq_eiu_w32(ltq_eiu_r32(LTQ_EIU_EXIN_INEN) & ~BIT(i), |
155 | LTQ_EIU_EXIN_INEN); | 163 | LTQ_EIU_EXIN_INEN); |
156 | break; | 164 | break; |
157 | } | 165 | } |
@@ -188,14 +196,15 @@ static void ltq_hw_irqdispatch(int module) | |||
188 | if (irq == 0) | 196 | if (irq == 0) |
189 | return; | 197 | return; |
190 | 198 | ||
191 | /* silicon bug causes only the msb set to 1 to be valid. all | 199 | /* |
200 | * silicon bug causes only the msb set to 1 to be valid. all | ||
192 | * other bits might be bogus | 201 | * other bits might be bogus |
193 | */ | 202 | */ |
194 | irq = __fls(irq); | 203 | irq = __fls(irq); |
195 | do_IRQ((int)irq + INT_NUM_IM0_IRL0 + (INT_NUM_IM_OFFSET * module)); | 204 | do_IRQ((int)irq + MIPS_CPU_IRQ_CASCADE + (INT_NUM_IM_OFFSET * module)); |
196 | 205 | ||
197 | /* if this is a EBU irq, we need to ack it or get a deadlock */ | 206 | /* if this is a EBU irq, we need to ack it or get a deadlock */ |
198 | if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0)) | 207 | if ((irq == LTQ_ICU_EBU_IRQ) && (module == 0) && LTQ_EBU_PCC_ISTAT) |
199 | ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10, | 208 | ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_ISTAT) | 0x10, |
200 | LTQ_EBU_PCC_ISTAT); | 209 | LTQ_EBU_PCC_ISTAT); |
201 | } | 210 | } |
@@ -216,6 +225,47 @@ static void ltq_hw5_irqdispatch(void) | |||
216 | do_IRQ(MIPS_CPU_TIMER_IRQ); | 225 | do_IRQ(MIPS_CPU_TIMER_IRQ); |
217 | } | 226 | } |
218 | 227 | ||
228 | #ifdef CONFIG_MIPS_MT_SMP | ||
229 | void __init arch_init_ipiirq(int irq, struct irqaction *action) | ||
230 | { | ||
231 | setup_irq(irq, action); | ||
232 | irq_set_handler(irq, handle_percpu_irq); | ||
233 | } | ||
234 | |||
235 | static void ltq_sw0_irqdispatch(void) | ||
236 | { | ||
237 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ); | ||
238 | } | ||
239 | |||
240 | static void ltq_sw1_irqdispatch(void) | ||
241 | { | ||
242 | do_IRQ(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ); | ||
243 | } | ||
244 | static irqreturn_t ipi_resched_interrupt(int irq, void *dev_id) | ||
245 | { | ||
246 | scheduler_ipi(); | ||
247 | return IRQ_HANDLED; | ||
248 | } | ||
249 | |||
250 | static irqreturn_t ipi_call_interrupt(int irq, void *dev_id) | ||
251 | { | ||
252 | smp_call_function_interrupt(); | ||
253 | return IRQ_HANDLED; | ||
254 | } | ||
255 | |||
256 | static struct irqaction irq_resched = { | ||
257 | .handler = ipi_resched_interrupt, | ||
258 | .flags = IRQF_PERCPU, | ||
259 | .name = "IPI_resched" | ||
260 | }; | ||
261 | |||
262 | static struct irqaction irq_call = { | ||
263 | .handler = ipi_call_interrupt, | ||
264 | .flags = IRQF_PERCPU, | ||
265 | .name = "IPI_call" | ||
266 | }; | ||
267 | #endif | ||
268 | |||
219 | asmlinkage void plat_irq_dispatch(void) | 269 | asmlinkage void plat_irq_dispatch(void) |
220 | { | 270 | { |
221 | unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; | 271 | unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; |
@@ -238,45 +288,75 @@ out: | |||
238 | return; | 288 | return; |
239 | } | 289 | } |
240 | 290 | ||
291 | static int icu_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw) | ||
292 | { | ||
293 | struct irq_chip *chip = <q_irq_type; | ||
294 | int i; | ||
295 | |||
296 | for (i = 0; i < exin_avail; i++) | ||
297 | if (hw == ltq_eiu_irq[i]) | ||
298 | chip = <q_eiu_type; | ||
299 | |||
300 | irq_set_chip_and_handler(hw, chip, handle_level_irq); | ||
301 | |||
302 | return 0; | ||
303 | } | ||
304 | |||
305 | static const struct irq_domain_ops irq_domain_ops = { | ||
306 | .xlate = irq_domain_xlate_onetwocell, | ||
307 | .map = icu_map, | ||
308 | }; | ||
309 | |||
241 | static struct irqaction cascade = { | 310 | static struct irqaction cascade = { |
242 | .handler = no_action, | 311 | .handler = no_action, |
243 | .name = "cascade", | 312 | .name = "cascade", |
244 | }; | 313 | }; |
245 | 314 | ||
246 | void __init arch_init_irq(void) | 315 | int __init icu_of_init(struct device_node *node, struct device_node *parent) |
247 | { | 316 | { |
317 | struct device_node *eiu_node; | ||
318 | struct resource res; | ||
248 | int i; | 319 | int i; |
249 | 320 | ||
250 | if (insert_resource(&iomem_resource, <q_icu_resource) < 0) | 321 | if (of_address_to_resource(node, 0, &res)) |
251 | panic("Failed to insert icu memory"); | 322 | panic("Failed to get icu memory range"); |
252 | 323 | ||
253 | if (request_mem_region(ltq_icu_resource.start, | 324 | if (request_mem_region(res.start, resource_size(&res), res.name) < 0) |
254 | resource_size(<q_icu_resource), "icu") < 0) | 325 | pr_err("Failed to request icu memory"); |
255 | panic("Failed to request icu memory"); | ||
256 | 326 | ||
257 | ltq_icu_membase = ioremap_nocache(ltq_icu_resource.start, | 327 | ltq_icu_membase = ioremap_nocache(res.start, resource_size(&res)); |
258 | resource_size(<q_icu_resource)); | ||
259 | if (!ltq_icu_membase) | 328 | if (!ltq_icu_membase) |
260 | panic("Failed to remap icu memory"); | 329 | panic("Failed to remap icu memory"); |
261 | 330 | ||
262 | if (insert_resource(&iomem_resource, <q_eiu_resource) < 0) | 331 | /* the external interrupts are optional and xway only */ |
263 | panic("Failed to insert eiu memory"); | 332 | eiu_node = of_find_compatible_node(NULL, NULL, "lantiq,eiu"); |
264 | 333 | if (eiu_node && of_address_to_resource(eiu_node, 0, &res)) { | |
265 | if (request_mem_region(ltq_eiu_resource.start, | 334 | /* find out how many external irq sources we have */ |
266 | resource_size(<q_eiu_resource), "eiu") < 0) | 335 | const __be32 *count = of_get_property(node, |
267 | panic("Failed to request eiu memory"); | 336 | "lantiq,count", NULL); |
268 | 337 | ||
269 | ltq_eiu_membase = ioremap_nocache(ltq_eiu_resource.start, | 338 | if (count) |
270 | resource_size(<q_eiu_resource)); | 339 | exin_avail = *count; |
271 | if (!ltq_eiu_membase) | 340 | if (exin_avail > MAX_EIU) |
272 | panic("Failed to remap eiu memory"); | 341 | exin_avail = MAX_EIU; |
342 | |||
343 | if (request_mem_region(res.start, resource_size(&res), | ||
344 | res.name) < 0) | ||
345 | pr_err("Failed to request eiu memory"); | ||
346 | |||
347 | ltq_eiu_membase = ioremap_nocache(res.start, | ||
348 | resource_size(&res)); | ||
349 | if (!ltq_eiu_membase) | ||
350 | panic("Failed to remap eiu memory"); | ||
351 | } | ||
273 | 352 | ||
274 | /* make sure all irqs are turned off by default */ | 353 | /* turn off all irqs by default */ |
275 | for (i = 0; i < 5; i++) | 354 | for (i = 0; i < 5; i++) { |
355 | /* make sure all irqs are turned off by default */ | ||
276 | ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET)); | 356 | ltq_icu_w32(0, LTQ_ICU_IM0_IER + (i * LTQ_ICU_OFFSET)); |
277 | 357 | /* clear all possibly pending interrupts */ | |
278 | /* clear all possibly pending interrupts */ | 358 | ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET)); |
279 | ltq_icu_w32(~0, LTQ_ICU_IM0_ISR + (i * LTQ_ICU_OFFSET)); | 359 | } |
280 | 360 | ||
281 | mips_cpu_irq_init(); | 361 | mips_cpu_irq_init(); |
282 | 362 | ||
@@ -293,20 +373,19 @@ void __init arch_init_irq(void) | |||
293 | set_vi_handler(7, ltq_hw5_irqdispatch); | 373 | set_vi_handler(7, ltq_hw5_irqdispatch); |
294 | } | 374 | } |
295 | 375 | ||
296 | for (i = INT_NUM_IRQ0; | 376 | irq_domain_add_linear(node, 6 * INT_NUM_IM_OFFSET, |
297 | i <= (INT_NUM_IRQ0 + (5 * INT_NUM_IM_OFFSET)); i++) | 377 | &irq_domain_ops, 0); |
298 | if ((i == LTQ_EIU_IR0) || (i == LTQ_EIU_IR1) || | 378 | |
299 | (i == LTQ_EIU_IR2)) | 379 | #if defined(CONFIG_MIPS_MT_SMP) |
300 | irq_set_chip_and_handler(i, <q_eiu_type, | 380 | if (cpu_has_vint) { |
301 | handle_level_irq); | 381 | pr_info("Setting up IPI vectored interrupts\n"); |
302 | /* EIU3-5 only exist on ar9 and vr9 */ | 382 | set_vi_handler(MIPS_CPU_IPI_RESCHED_IRQ, ltq_sw0_irqdispatch); |
303 | else if (((i == LTQ_EIU_IR3) || (i == LTQ_EIU_IR4) || | 383 | set_vi_handler(MIPS_CPU_IPI_CALL_IRQ, ltq_sw1_irqdispatch); |
304 | (i == LTQ_EIU_IR5)) && (ltq_is_ar9() || ltq_is_vr9())) | 384 | } |
305 | irq_set_chip_and_handler(i, <q_eiu_type, | 385 | arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_RESCHED_IRQ, |
306 | handle_level_irq); | 386 | &irq_resched); |
307 | else | 387 | arch_init_ipiirq(MIPS_CPU_IRQ_BASE + MIPS_CPU_IPI_CALL_IRQ, &irq_call); |
308 | irq_set_chip_and_handler(i, <q_irq_type, | 388 | #endif |
309 | handle_level_irq); | ||
310 | 389 | ||
311 | #if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC) | 390 | #if !defined(CONFIG_MIPS_MT_SMP) && !defined(CONFIG_MIPS_MT_SMTC) |
312 | set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | | 391 | set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | |
@@ -315,9 +394,23 @@ void __init arch_init_irq(void) | |||
315 | set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 | | 394 | set_c0_status(IE_SW0 | IE_SW1 | IE_IRQ0 | IE_IRQ1 | |
316 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5); | 395 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4 | IE_IRQ5); |
317 | #endif | 396 | #endif |
397 | |||
398 | /* tell oprofile which irq to use */ | ||
399 | cp0_perfcount_irq = LTQ_PERF_IRQ; | ||
400 | return 0; | ||
318 | } | 401 | } |
319 | 402 | ||
320 | unsigned int __cpuinit get_c0_compare_int(void) | 403 | unsigned int __cpuinit get_c0_compare_int(void) |
321 | { | 404 | { |
322 | return CP0_LEGACY_COMPARE_IRQ; | 405 | return CP0_LEGACY_COMPARE_IRQ; |
323 | } | 406 | } |
407 | |||
408 | static struct of_device_id __initdata of_irq_ids[] = { | ||
409 | { .compatible = "lantiq,icu", .data = icu_of_init }, | ||
410 | {}, | ||
411 | }; | ||
412 | |||
413 | void __init arch_init_irq(void) | ||
414 | { | ||
415 | of_irq_init(of_irq_ids); | ||
416 | } | ||
diff --git a/arch/mips/lantiq/machtypes.h b/arch/mips/lantiq/machtypes.h deleted file mode 100644 index 7e01b8c484eb..000000000000 --- a/arch/mips/lantiq/machtypes.h +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LANTIQ_MACH_H__ | ||
10 | #define _LANTIQ_MACH_H__ | ||
11 | |||
12 | #include <asm/mips_machine.h> | ||
13 | |||
14 | enum lantiq_mach_type { | ||
15 | LTQ_MACH_GENERIC = 0, | ||
16 | LTQ_MACH_EASY50712, /* Danube evaluation board */ | ||
17 | LTQ_MACH_EASY50601, /* Amazon SE evaluation board */ | ||
18 | }; | ||
19 | |||
20 | #endif | ||
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c index e34fcfd0d5ca..d185e8477fdf 100644 --- a/arch/mips/lantiq/prom.c +++ b/arch/mips/lantiq/prom.c | |||
@@ -8,6 +8,7 @@ | |||
8 | 8 | ||
9 | #include <linux/export.h> | 9 | #include <linux/export.h> |
10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
11 | #include <linux/of_platform.h> | ||
11 | #include <asm/bootinfo.h> | 12 | #include <asm/bootinfo.h> |
12 | #include <asm/time.h> | 13 | #include <asm/time.h> |
13 | 14 | ||
@@ -16,19 +17,15 @@ | |||
16 | #include "prom.h" | 17 | #include "prom.h" |
17 | #include "clk.h" | 18 | #include "clk.h" |
18 | 19 | ||
19 | static struct ltq_soc_info soc_info; | 20 | /* access to the ebu needs to be locked between different drivers */ |
20 | 21 | DEFINE_SPINLOCK(ebu_lock); | |
21 | unsigned int ltq_get_cpu_ver(void) | 22 | EXPORT_SYMBOL_GPL(ebu_lock); |
22 | { | ||
23 | return soc_info.rev; | ||
24 | } | ||
25 | EXPORT_SYMBOL(ltq_get_cpu_ver); | ||
26 | 23 | ||
27 | unsigned int ltq_get_soc_type(void) | 24 | /* |
28 | { | 25 | * this struct is filled by the soc specific detection code and holds |
29 | return soc_info.type; | 26 | * information about the specific soc type, revision and name |
30 | } | 27 | */ |
31 | EXPORT_SYMBOL(ltq_get_soc_type); | 28 | static struct ltq_soc_info soc_info; |
32 | 29 | ||
33 | const char *get_system_type(void) | 30 | const char *get_system_type(void) |
34 | { | 31 | { |
@@ -45,27 +42,62 @@ static void __init prom_init_cmdline(void) | |||
45 | char **argv = (char **) KSEG1ADDR(fw_arg1); | 42 | char **argv = (char **) KSEG1ADDR(fw_arg1); |
46 | int i; | 43 | int i; |
47 | 44 | ||
45 | arcs_cmdline[0] = '\0'; | ||
46 | |||
48 | for (i = 0; i < argc; i++) { | 47 | for (i = 0; i < argc; i++) { |
49 | char *p = (char *) KSEG1ADDR(argv[i]); | 48 | char *p = (char *) KSEG1ADDR(argv[i]); |
50 | 49 | ||
51 | if (p && *p) { | 50 | if (CPHYSADDR(p) && *p) { |
52 | strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); | 51 | strlcat(arcs_cmdline, p, sizeof(arcs_cmdline)); |
53 | strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); | 52 | strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); |
54 | } | 53 | } |
55 | } | 54 | } |
56 | } | 55 | } |
57 | 56 | ||
58 | void __init prom_init(void) | 57 | void __init plat_mem_setup(void) |
59 | { | 58 | { |
60 | struct clk *clk; | 59 | ioport_resource.start = IOPORT_RESOURCE_START; |
60 | ioport_resource.end = IOPORT_RESOURCE_END; | ||
61 | iomem_resource.start = IOMEM_RESOURCE_START; | ||
62 | iomem_resource.end = IOMEM_RESOURCE_END; | ||
63 | |||
64 | set_io_port_base((unsigned long) KSEG1); | ||
61 | 65 | ||
66 | /* | ||
67 | * Load the builtin devicetree. This causes the chosen node to be | ||
68 | * parsed resulting in our memory appearing | ||
69 | */ | ||
70 | __dt_setup_arch(&__dtb_start); | ||
71 | } | ||
72 | |||
73 | void __init prom_init(void) | ||
74 | { | ||
75 | /* call the soc specific detetcion code and get it to fill soc_info */ | ||
62 | ltq_soc_detect(&soc_info); | 76 | ltq_soc_detect(&soc_info); |
63 | clk_init(); | 77 | snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev %s", |
64 | clk = clk_get(0, "cpu"); | 78 | soc_info.name, soc_info.rev_type); |
65 | snprintf(soc_info.sys_type, LTQ_SYS_TYPE_LEN - 1, "%s rev1.%d", | ||
66 | soc_info.name, soc_info.rev); | ||
67 | clk_put(clk); | ||
68 | soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0'; | 79 | soc_info.sys_type[LTQ_SYS_TYPE_LEN - 1] = '\0'; |
69 | pr_info("SoC: %s\n", soc_info.sys_type); | 80 | pr_info("SoC: %s\n", soc_info.sys_type); |
70 | prom_init_cmdline(); | 81 | prom_init_cmdline(); |
82 | |||
83 | #if defined(CONFIG_MIPS_MT_SMP) | ||
84 | if (register_vsmp_smp_ops()) | ||
85 | panic("failed to register_vsmp_smp_ops()"); | ||
86 | #endif | ||
71 | } | 87 | } |
88 | |||
89 | int __init plat_of_setup(void) | ||
90 | { | ||
91 | static struct of_device_id of_ids[3]; | ||
92 | |||
93 | if (!of_have_populated_dt()) | ||
94 | panic("device tree not present"); | ||
95 | |||
96 | strncpy(of_ids[0].compatible, soc_info.compatible, | ||
97 | sizeof(of_ids[0].compatible)); | ||
98 | strncpy(of_ids[1].compatible, "simple-bus", | ||
99 | sizeof(of_ids[1].compatible)); | ||
100 | return of_platform_bus_probe(NULL, of_ids, NULL); | ||
101 | } | ||
102 | |||
103 | arch_initcall(plat_of_setup); | ||
diff --git a/arch/mips/lantiq/prom.h b/arch/mips/lantiq/prom.h index b4229d94280f..a3fa1a2bfaae 100644 --- a/arch/mips/lantiq/prom.h +++ b/arch/mips/lantiq/prom.h | |||
@@ -10,16 +10,22 @@ | |||
10 | #define _LTQ_PROM_H__ | 10 | #define _LTQ_PROM_H__ |
11 | 11 | ||
12 | #define LTQ_SYS_TYPE_LEN 0x100 | 12 | #define LTQ_SYS_TYPE_LEN 0x100 |
13 | #define LTQ_SYS_REV_LEN 0x10 | ||
13 | 14 | ||
14 | struct ltq_soc_info { | 15 | struct ltq_soc_info { |
15 | unsigned char *name; | 16 | unsigned char *name; |
16 | unsigned int rev; | 17 | unsigned int rev; |
18 | unsigned char rev_type[LTQ_SYS_REV_LEN]; | ||
19 | unsigned int srev; | ||
17 | unsigned int partnum; | 20 | unsigned int partnum; |
18 | unsigned int type; | 21 | unsigned int type; |
19 | unsigned char sys_type[LTQ_SYS_TYPE_LEN]; | 22 | unsigned char sys_type[LTQ_SYS_TYPE_LEN]; |
23 | unsigned char *compatible; | ||
20 | }; | 24 | }; |
21 | 25 | ||
22 | extern void ltq_soc_detect(struct ltq_soc_info *i); | 26 | extern void ltq_soc_detect(struct ltq_soc_info *i); |
23 | extern void ltq_soc_setup(void); | 27 | extern void ltq_soc_init(void); |
28 | |||
29 | extern struct boot_param_header __dtb_start; | ||
24 | 30 | ||
25 | #endif | 31 | #endif |
diff --git a/arch/mips/lantiq/setup.c b/arch/mips/lantiq/setup.c deleted file mode 100644 index 1ff6c9d6cb93..000000000000 --- a/arch/mips/lantiq/setup.c +++ /dev/null | |||
@@ -1,66 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/export.h> | ||
11 | #include <linux/io.h> | ||
12 | #include <linux/ioport.h> | ||
13 | #include <asm/bootinfo.h> | ||
14 | |||
15 | #include <lantiq_soc.h> | ||
16 | |||
17 | #include "machtypes.h" | ||
18 | #include "devices.h" | ||
19 | #include "prom.h" | ||
20 | |||
21 | void __init plat_mem_setup(void) | ||
22 | { | ||
23 | /* assume 16M as default incase uboot fails to pass proper ramsize */ | ||
24 | unsigned long memsize = 16; | ||
25 | char **envp = (char **) KSEG1ADDR(fw_arg2); | ||
26 | |||
27 | ioport_resource.start = IOPORT_RESOURCE_START; | ||
28 | ioport_resource.end = IOPORT_RESOURCE_END; | ||
29 | iomem_resource.start = IOMEM_RESOURCE_START; | ||
30 | iomem_resource.end = IOMEM_RESOURCE_END; | ||
31 | |||
32 | set_io_port_base((unsigned long) KSEG1); | ||
33 | |||
34 | while (*envp) { | ||
35 | char *e = (char *)KSEG1ADDR(*envp); | ||
36 | if (!strncmp(e, "memsize=", 8)) { | ||
37 | e += 8; | ||
38 | if (strict_strtoul(e, 0, &memsize)) | ||
39 | pr_warn("bad memsize specified\n"); | ||
40 | } | ||
41 | envp++; | ||
42 | } | ||
43 | memsize *= 1024 * 1024; | ||
44 | add_memory_region(0x00000000, memsize, BOOT_MEM_RAM); | ||
45 | } | ||
46 | |||
47 | static int __init | ||
48 | lantiq_setup(void) | ||
49 | { | ||
50 | ltq_soc_setup(); | ||
51 | mips_machine_setup(); | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | arch_initcall(lantiq_setup); | ||
56 | |||
57 | static void __init | ||
58 | lantiq_generic_init(void) | ||
59 | { | ||
60 | /* Nothing to do */ | ||
61 | } | ||
62 | |||
63 | MIPS_MACHINE(LTQ_MACH_GENERIC, | ||
64 | "Generic", | ||
65 | "Generic Lantiq based board", | ||
66 | lantiq_generic_init); | ||
diff --git a/arch/mips/lantiq/xway/Kconfig b/arch/mips/lantiq/xway/Kconfig deleted file mode 100644 index 2b857de36620..000000000000 --- a/arch/mips/lantiq/xway/Kconfig +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | if SOC_XWAY | ||
2 | |||
3 | menu "MIPS Machine" | ||
4 | |||
5 | config LANTIQ_MACH_EASY50712 | ||
6 | bool "Easy50712 - Danube" | ||
7 | default y | ||
8 | |||
9 | endmenu | ||
10 | |||
11 | endif | ||
12 | |||
13 | if SOC_AMAZON_SE | ||
14 | |||
15 | menu "MIPS Machine" | ||
16 | |||
17 | config LANTIQ_MACH_EASY50601 | ||
18 | bool "Easy50601 - Amazon SE" | ||
19 | default y | ||
20 | |||
21 | endmenu | ||
22 | |||
23 | endif | ||
diff --git a/arch/mips/lantiq/xway/Makefile b/arch/mips/lantiq/xway/Makefile index c517f2e77563..dc3194f6ee42 100644 --- a/arch/mips/lantiq/xway/Makefile +++ b/arch/mips/lantiq/xway/Makefile | |||
@@ -1,7 +1 @@ | |||
1 | obj-y := pmu.o ebu.o reset.o gpio.o gpio_stp.o gpio_ebu.o devices.o dma.o | obj-y := prom.o sysctrl.o clk.o reset.o gpio.o dma.o | |
2 | |||
3 | obj-$(CONFIG_SOC_XWAY) += clk-xway.o prom-xway.o setup-xway.o | ||
4 | obj-$(CONFIG_SOC_AMAZON_SE) += clk-ase.o prom-ase.o setup-ase.o | ||
5 | |||
6 | obj-$(CONFIG_LANTIQ_MACH_EASY50712) += mach-easy50712.o | ||
7 | obj-$(CONFIG_LANTIQ_MACH_EASY50601) += mach-easy50601.o | ||
diff --git a/arch/mips/lantiq/xway/clk-ase.c b/arch/mips/lantiq/xway/clk-ase.c deleted file mode 100644 index 652258309c9c..000000000000 --- a/arch/mips/lantiq/xway/clk-ase.c +++ /dev/null | |||
@@ -1,48 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/io.h> | ||
10 | #include <linux/export.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/clk.h> | ||
13 | |||
14 | #include <asm/time.h> | ||
15 | #include <asm/irq.h> | ||
16 | #include <asm/div64.h> | ||
17 | |||
18 | #include <lantiq_soc.h> | ||
19 | |||
20 | /* cgu registers */ | ||
21 | #define LTQ_CGU_SYS 0x0010 | ||
22 | |||
23 | unsigned int ltq_get_io_region_clock(void) | ||
24 | { | ||
25 | return CLOCK_133M; | ||
26 | } | ||
27 | EXPORT_SYMBOL(ltq_get_io_region_clock); | ||
28 | |||
29 | unsigned int ltq_get_fpi_bus_clock(int fpi) | ||
30 | { | ||
31 | return CLOCK_133M; | ||
32 | } | ||
33 | EXPORT_SYMBOL(ltq_get_fpi_bus_clock); | ||
34 | |||
35 | unsigned int ltq_get_cpu_hz(void) | ||
36 | { | ||
37 | if (ltq_cgu_r32(LTQ_CGU_SYS) & (1 << 5)) | ||
38 | return CLOCK_266M; | ||
39 | else | ||
40 | return CLOCK_133M; | ||
41 | } | ||
42 | EXPORT_SYMBOL(ltq_get_cpu_hz); | ||
43 | |||
44 | unsigned int ltq_get_fpi_hz(void) | ||
45 | { | ||
46 | return CLOCK_133M; | ||
47 | } | ||
48 | EXPORT_SYMBOL(ltq_get_fpi_hz); | ||
diff --git a/arch/mips/lantiq/xway/clk-xway.c b/arch/mips/lantiq/xway/clk-xway.c deleted file mode 100644 index 696b1a3e0642..000000000000 --- a/arch/mips/lantiq/xway/clk-xway.c +++ /dev/null | |||
@@ -1,223 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/io.h> | ||
10 | #include <linux/export.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/clk.h> | ||
13 | |||
14 | #include <asm/time.h> | ||
15 | #include <asm/irq.h> | ||
16 | #include <asm/div64.h> | ||
17 | |||
18 | #include <lantiq_soc.h> | ||
19 | |||
20 | static unsigned int ltq_ram_clocks[] = { | ||
21 | CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M }; | ||
22 | #define DDR_HZ ltq_ram_clocks[ltq_cgu_r32(LTQ_CGU_SYS) & 0x3] | ||
23 | |||
24 | #define BASIC_FREQUENCY_1 35328000 | ||
25 | #define BASIC_FREQUENCY_2 36000000 | ||
26 | #define BASIS_REQUENCY_USB 12000000 | ||
27 | |||
28 | #define GET_BITS(x, msb, lsb) \ | ||
29 | (((x) & ((1 << ((msb) + 1)) - 1)) >> (lsb)) | ||
30 | |||
31 | #define LTQ_CGU_PLL0_CFG 0x0004 | ||
32 | #define LTQ_CGU_PLL1_CFG 0x0008 | ||
33 | #define LTQ_CGU_PLL2_CFG 0x000C | ||
34 | #define LTQ_CGU_SYS 0x0010 | ||
35 | #define LTQ_CGU_UPDATE 0x0014 | ||
36 | #define LTQ_CGU_IF_CLK 0x0018 | ||
37 | #define LTQ_CGU_OSC_CON 0x001C | ||
38 | #define LTQ_CGU_SMD 0x0020 | ||
39 | #define LTQ_CGU_CT1SR 0x0028 | ||
40 | #define LTQ_CGU_CT2SR 0x002C | ||
41 | #define LTQ_CGU_PCMCR 0x0030 | ||
42 | #define LTQ_CGU_PCI_CR 0x0034 | ||
43 | #define LTQ_CGU_PD_PC 0x0038 | ||
44 | #define LTQ_CGU_FMR 0x003C | ||
45 | |||
46 | #define CGU_PLL0_PHASE_DIVIDER_ENABLE \ | ||
47 | (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 31)) | ||
48 | #define CGU_PLL0_BYPASS \ | ||
49 | (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 30)) | ||
50 | #define CGU_PLL0_CFG_DSMSEL \ | ||
51 | (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 28)) | ||
52 | #define CGU_PLL0_CFG_FRAC_EN \ | ||
53 | (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & (1 << 27)) | ||
54 | #define CGU_PLL1_SRC \ | ||
55 | (ltq_cgu_r32(LTQ_CGU_PLL1_CFG) & (1 << 31)) | ||
56 | #define CGU_PLL2_PHASE_DIVIDER_ENABLE \ | ||
57 | (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & (1 << 20)) | ||
58 | #define CGU_SYS_FPI_SEL (1 << 6) | ||
59 | #define CGU_SYS_DDR_SEL 0x3 | ||
60 | #define CGU_PLL0_SRC (1 << 29) | ||
61 | |||
62 | #define CGU_PLL0_CFG_PLLK GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 26, 17) | ||
63 | #define CGU_PLL0_CFG_PLLN GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 12, 6) | ||
64 | #define CGU_PLL0_CFG_PLLM GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL0_CFG), 5, 2) | ||
65 | #define CGU_PLL2_SRC GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 18, 17) | ||
66 | #define CGU_PLL2_CFG_INPUT_DIV GET_BITS(ltq_cgu_r32(LTQ_CGU_PLL2_CFG), 16, 13) | ||
67 | |||
68 | static unsigned int ltq_get_pll0_fdiv(void); | ||
69 | |||
70 | static inline unsigned int get_input_clock(int pll) | ||
71 | { | ||
72 | switch (pll) { | ||
73 | case 0: | ||
74 | if (ltq_cgu_r32(LTQ_CGU_PLL0_CFG) & CGU_PLL0_SRC) | ||
75 | return BASIS_REQUENCY_USB; | ||
76 | else if (CGU_PLL0_PHASE_DIVIDER_ENABLE) | ||
77 | return BASIC_FREQUENCY_1; | ||
78 | else | ||
79 | return BASIC_FREQUENCY_2; | ||
80 | case 1: | ||
81 | if (CGU_PLL1_SRC) | ||
82 | return BASIS_REQUENCY_USB; | ||
83 | else if (CGU_PLL0_PHASE_DIVIDER_ENABLE) | ||
84 | return BASIC_FREQUENCY_1; | ||
85 | else | ||
86 | return BASIC_FREQUENCY_2; | ||
87 | case 2: | ||
88 | switch (CGU_PLL2_SRC) { | ||
89 | case 0: | ||
90 | return ltq_get_pll0_fdiv(); | ||
91 | case 1: | ||
92 | return CGU_PLL2_PHASE_DIVIDER_ENABLE ? | ||
93 | BASIC_FREQUENCY_1 : | ||
94 | BASIC_FREQUENCY_2; | ||
95 | case 2: | ||
96 | return BASIS_REQUENCY_USB; | ||
97 | } | ||
98 | default: | ||
99 | return 0; | ||
100 | } | ||
101 | } | ||
102 | |||
103 | static inline unsigned int cal_dsm(int pll, unsigned int num, unsigned int den) | ||
104 | { | ||
105 | u64 res, clock = get_input_clock(pll); | ||
106 | |||
107 | res = num * clock; | ||
108 | do_div(res, den); | ||
109 | return res; | ||
110 | } | ||
111 | |||
112 | static inline unsigned int mash_dsm(int pll, unsigned int M, unsigned int N, | ||
113 | unsigned int K) | ||
114 | { | ||
115 | unsigned int num = ((N + 1) << 10) + K; | ||
116 | unsigned int den = (M + 1) << 10; | ||
117 | |||
118 | return cal_dsm(pll, num, den); | ||
119 | } | ||
120 | |||
121 | static inline unsigned int ssff_dsm_1(int pll, unsigned int M, unsigned int N, | ||
122 | unsigned int K) | ||
123 | { | ||
124 | unsigned int num = ((N + 1) << 11) + K + 512; | ||
125 | unsigned int den = (M + 1) << 11; | ||
126 | |||
127 | return cal_dsm(pll, num, den); | ||
128 | } | ||
129 | |||
130 | static inline unsigned int ssff_dsm_2(int pll, unsigned int M, unsigned int N, | ||
131 | unsigned int K) | ||
132 | { | ||
133 | unsigned int num = K >= 512 ? | ||
134 | ((N + 1) << 12) + K - 512 : ((N + 1) << 12) + K + 3584; | ||
135 | unsigned int den = (M + 1) << 12; | ||
136 | |||
137 | return cal_dsm(pll, num, den); | ||
138 | } | ||
139 | |||
140 | static inline unsigned int dsm(int pll, unsigned int M, unsigned int N, | ||
141 | unsigned int K, unsigned int dsmsel, unsigned int phase_div_en) | ||
142 | { | ||
143 | if (!dsmsel) | ||
144 | return mash_dsm(pll, M, N, K); | ||
145 | else if (!phase_div_en) | ||
146 | return mash_dsm(pll, M, N, K); | ||
147 | else | ||
148 | return ssff_dsm_2(pll, M, N, K); | ||
149 | } | ||
150 | |||
151 | static inline unsigned int ltq_get_pll0_fosc(void) | ||
152 | { | ||
153 | if (CGU_PLL0_BYPASS) | ||
154 | return get_input_clock(0); | ||
155 | else | ||
156 | return !CGU_PLL0_CFG_FRAC_EN | ||
157 | ? dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, 0, | ||
158 | CGU_PLL0_CFG_DSMSEL, | ||
159 | CGU_PLL0_PHASE_DIVIDER_ENABLE) | ||
160 | : dsm(0, CGU_PLL0_CFG_PLLM, CGU_PLL0_CFG_PLLN, | ||
161 | CGU_PLL0_CFG_PLLK, CGU_PLL0_CFG_DSMSEL, | ||
162 | CGU_PLL0_PHASE_DIVIDER_ENABLE); | ||
163 | } | ||
164 | |||
165 | static unsigned int ltq_get_pll0_fdiv(void) | ||
166 | { | ||
167 | unsigned int div = CGU_PLL2_CFG_INPUT_DIV + 1; | ||
168 | |||
169 | return (ltq_get_pll0_fosc() + (div >> 1)) / div; | ||
170 | } | ||
171 | |||
172 | unsigned int ltq_get_io_region_clock(void) | ||
173 | { | ||
174 | unsigned int ret = ltq_get_pll0_fosc(); | ||
175 | |||
176 | switch (ltq_cgu_r32(LTQ_CGU_PLL2_CFG) & CGU_SYS_DDR_SEL) { | ||
177 | default: | ||
178 | case 0: | ||
179 | return (ret + 1) / 2; | ||
180 | case 1: | ||
181 | return (ret * 2 + 2) / 5; | ||
182 | case 2: | ||
183 | return (ret + 1) / 3; | ||
184 | case 3: | ||
185 | return (ret + 2) / 4; | ||
186 | } | ||
187 | } | ||
188 | EXPORT_SYMBOL(ltq_get_io_region_clock); | ||
189 | |||
190 | unsigned int ltq_get_fpi_bus_clock(int fpi) | ||
191 | { | ||
192 | unsigned int ret = ltq_get_io_region_clock(); | ||
193 | |||
194 | if ((fpi == 2) && (ltq_cgu_r32(LTQ_CGU_SYS) & CGU_SYS_FPI_SEL)) | ||
195 | ret >>= 1; | ||
196 | return ret; | ||
197 | } | ||
198 | EXPORT_SYMBOL(ltq_get_fpi_bus_clock); | ||
199 | |||
200 | unsigned int ltq_get_cpu_hz(void) | ||
201 | { | ||
202 | switch (ltq_cgu_r32(LTQ_CGU_SYS) & 0xc) { | ||
203 | case 0: | ||
204 | return CLOCK_333M; | ||
205 | case 4: | ||
206 | return DDR_HZ; | ||
207 | case 8: | ||
208 | return DDR_HZ << 1; | ||
209 | default: | ||
210 | return DDR_HZ >> 1; | ||
211 | } | ||
212 | } | ||
213 | EXPORT_SYMBOL(ltq_get_cpu_hz); | ||
214 | |||
215 | unsigned int ltq_get_fpi_hz(void) | ||
216 | { | ||
217 | unsigned int ddr_clock = DDR_HZ; | ||
218 | |||
219 | if (ltq_cgu_r32(LTQ_CGU_SYS) & 0x40) | ||
220 | return ddr_clock >> 1; | ||
221 | return ddr_clock; | ||
222 | } | ||
223 | EXPORT_SYMBOL(ltq_get_fpi_hz); | ||
diff --git a/arch/mips/lantiq/xway/clk.c b/arch/mips/lantiq/xway/clk.c new file mode 100644 index 000000000000..9aa17f79a742 --- /dev/null +++ b/arch/mips/lantiq/xway/clk.c | |||
@@ -0,0 +1,151 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/io.h> | ||
10 | #include <linux/export.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/clk.h> | ||
13 | |||
14 | #include <asm/time.h> | ||
15 | #include <asm/irq.h> | ||
16 | #include <asm/div64.h> | ||
17 | |||
18 | #include <lantiq_soc.h> | ||
19 | |||
20 | #include "../clk.h" | ||
21 | |||
22 | static unsigned int ram_clocks[] = { | ||
23 | CLOCK_167M, CLOCK_133M, CLOCK_111M, CLOCK_83M }; | ||
24 | #define DDR_HZ ram_clocks[ltq_cgu_r32(CGU_SYS) & 0x3] | ||
25 | |||
26 | /* legacy xway clock */ | ||
27 | #define CGU_SYS 0x10 | ||
28 | |||
29 | /* vr9 clock */ | ||
30 | #define CGU_SYS_VR9 0x0c | ||
31 | #define CGU_IF_CLK_VR9 0x24 | ||
32 | |||
33 | unsigned long ltq_danube_fpi_hz(void) | ||
34 | { | ||
35 | unsigned long ddr_clock = DDR_HZ; | ||
36 | |||
37 | if (ltq_cgu_r32(CGU_SYS) & 0x40) | ||
38 | return ddr_clock >> 1; | ||
39 | return ddr_clock; | ||
40 | } | ||
41 | |||
42 | unsigned long ltq_danube_cpu_hz(void) | ||
43 | { | ||
44 | switch (ltq_cgu_r32(CGU_SYS) & 0xc) { | ||
45 | case 0: | ||
46 | return CLOCK_333M; | ||
47 | case 4: | ||
48 | return DDR_HZ; | ||
49 | case 8: | ||
50 | return DDR_HZ << 1; | ||
51 | default: | ||
52 | return DDR_HZ >> 1; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | unsigned long ltq_ar9_sys_hz(void) | ||
57 | { | ||
58 | if (((ltq_cgu_r32(CGU_SYS) >> 3) & 0x3) == 0x2) | ||
59 | return CLOCK_393M; | ||
60 | return CLOCK_333M; | ||
61 | } | ||
62 | |||
63 | unsigned long ltq_ar9_fpi_hz(void) | ||
64 | { | ||
65 | unsigned long sys = ltq_ar9_sys_hz(); | ||
66 | |||
67 | if (ltq_cgu_r32(CGU_SYS) & BIT(0)) | ||
68 | return sys; | ||
69 | return sys >> 1; | ||
70 | } | ||
71 | |||
72 | unsigned long ltq_ar9_cpu_hz(void) | ||
73 | { | ||
74 | if (ltq_cgu_r32(CGU_SYS) & BIT(2)) | ||
75 | return ltq_ar9_fpi_hz(); | ||
76 | else | ||
77 | return ltq_ar9_sys_hz(); | ||
78 | } | ||
79 | |||
80 | unsigned long ltq_vr9_cpu_hz(void) | ||
81 | { | ||
82 | unsigned int cpu_sel; | ||
83 | unsigned long clk; | ||
84 | |||
85 | cpu_sel = (ltq_cgu_r32(CGU_SYS_VR9) >> 4) & 0xf; | ||
86 | |||
87 | switch (cpu_sel) { | ||
88 | case 0: | ||
89 | clk = CLOCK_600M; | ||
90 | break; | ||
91 | case 1: | ||
92 | clk = CLOCK_500M; | ||
93 | break; | ||
94 | case 2: | ||
95 | clk = CLOCK_393M; | ||
96 | break; | ||
97 | case 3: | ||
98 | clk = CLOCK_333M; | ||
99 | break; | ||
100 | case 5: | ||
101 | case 6: | ||
102 | clk = CLOCK_196_608M; | ||
103 | break; | ||
104 | case 7: | ||
105 | clk = CLOCK_167M; | ||
106 | break; | ||
107 | case 4: | ||
108 | case 8: | ||
109 | case 9: | ||
110 | clk = CLOCK_125M; | ||
111 | break; | ||
112 | default: | ||
113 | clk = 0; | ||
114 | break; | ||
115 | } | ||
116 | |||
117 | return clk; | ||
118 | } | ||
119 | |||
120 | unsigned long ltq_vr9_fpi_hz(void) | ||
121 | { | ||
122 | unsigned int ocp_sel, cpu_clk; | ||
123 | unsigned long clk; | ||
124 | |||
125 | cpu_clk = ltq_vr9_cpu_hz(); | ||
126 | ocp_sel = ltq_cgu_r32(CGU_SYS_VR9) & 0x3; | ||
127 | |||
128 | switch (ocp_sel) { | ||
129 | case 0: | ||
130 | /* OCP ratio 1 */ | ||
131 | clk = cpu_clk; | ||
132 | break; | ||
133 | case 2: | ||
134 | /* OCP ratio 2 */ | ||
135 | clk = cpu_clk / 2; | ||
136 | break; | ||
137 | case 3: | ||
138 | /* OCP ratio 2.5 */ | ||
139 | clk = (cpu_clk * 2) / 5; | ||
140 | break; | ||
141 | case 4: | ||
142 | /* OCP ratio 3 */ | ||
143 | clk = cpu_clk / 3; | ||
144 | break; | ||
145 | default: | ||
146 | clk = 0; | ||
147 | break; | ||
148 | } | ||
149 | |||
150 | return clk; | ||
151 | } | ||
diff --git a/arch/mips/lantiq/xway/devices.c b/arch/mips/lantiq/xway/devices.c deleted file mode 100644 index d614aa7ff07f..000000000000 --- a/arch/mips/lantiq/xway/devices.c +++ /dev/null | |||
@@ -1,119 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/export.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/string.h> | ||
13 | #include <linux/mtd/physmap.h> | ||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/reboot.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/leds.h> | ||
18 | #include <linux/etherdevice.h> | ||
19 | #include <linux/time.h> | ||
20 | #include <linux/io.h> | ||
21 | #include <linux/gpio.h> | ||
22 | |||
23 | #include <asm/bootinfo.h> | ||
24 | #include <asm/irq.h> | ||
25 | |||
26 | #include <lantiq_soc.h> | ||
27 | #include <lantiq_irq.h> | ||
28 | #include <lantiq_platform.h> | ||
29 | |||
30 | #include "devices.h" | ||
31 | |||
32 | /* gpio */ | ||
33 | static struct resource ltq_gpio_resource[] = { | ||
34 | { | ||
35 | .name = "gpio0", | ||
36 | .start = LTQ_GPIO0_BASE_ADDR, | ||
37 | .end = LTQ_GPIO0_BASE_ADDR + LTQ_GPIO_SIZE - 1, | ||
38 | .flags = IORESOURCE_MEM, | ||
39 | }, { | ||
40 | .name = "gpio1", | ||
41 | .start = LTQ_GPIO1_BASE_ADDR, | ||
42 | .end = LTQ_GPIO1_BASE_ADDR + LTQ_GPIO_SIZE - 1, | ||
43 | .flags = IORESOURCE_MEM, | ||
44 | }, { | ||
45 | .name = "gpio2", | ||
46 | .start = LTQ_GPIO2_BASE_ADDR, | ||
47 | .end = LTQ_GPIO2_BASE_ADDR + LTQ_GPIO_SIZE - 1, | ||
48 | .flags = IORESOURCE_MEM, | ||
49 | } | ||
50 | }; | ||
51 | |||
52 | void __init ltq_register_gpio(void) | ||
53 | { | ||
54 | platform_device_register_simple("ltq_gpio", 0, | ||
55 | <q_gpio_resource[0], 1); | ||
56 | platform_device_register_simple("ltq_gpio", 1, | ||
57 | <q_gpio_resource[1], 1); | ||
58 | |||
59 | /* AR9 and VR9 have an extra gpio block */ | ||
60 | if (ltq_is_ar9() || ltq_is_vr9()) { | ||
61 | platform_device_register_simple("ltq_gpio", 2, | ||
62 | <q_gpio_resource[2], 1); | ||
63 | } | ||
64 | } | ||
65 | |||
66 | /* serial to parallel conversion */ | ||
67 | static struct resource ltq_stp_resource = { | ||
68 | .name = "stp", | ||
69 | .start = LTQ_STP_BASE_ADDR, | ||
70 | .end = LTQ_STP_BASE_ADDR + LTQ_STP_SIZE - 1, | ||
71 | .flags = IORESOURCE_MEM, | ||
72 | }; | ||
73 | |||
74 | void __init ltq_register_gpio_stp(void) | ||
75 | { | ||
76 | platform_device_register_simple("ltq_stp", 0, <q_stp_resource, 1); | ||
77 | } | ||
78 | |||
79 | /* asc ports - amazon se has its own serial mapping */ | ||
80 | static struct resource ltq_ase_asc_resources[] = { | ||
81 | { | ||
82 | .name = "asc0", | ||
83 | .start = LTQ_ASC1_BASE_ADDR, | ||
84 | .end = LTQ_ASC1_BASE_ADDR + LTQ_ASC_SIZE - 1, | ||
85 | .flags = IORESOURCE_MEM, | ||
86 | }, | ||
87 | IRQ_RES(tx, LTQ_ASC_ASE_TIR), | ||
88 | IRQ_RES(rx, LTQ_ASC_ASE_RIR), | ||
89 | IRQ_RES(err, LTQ_ASC_ASE_EIR), | ||
90 | }; | ||
91 | |||
92 | void __init ltq_register_ase_asc(void) | ||
93 | { | ||
94 | platform_device_register_simple("ltq_asc", 0, | ||
95 | ltq_ase_asc_resources, ARRAY_SIZE(ltq_ase_asc_resources)); | ||
96 | } | ||
97 | |||
98 | /* ethernet */ | ||
99 | static struct resource ltq_etop_resources = { | ||
100 | .name = "etop", | ||
101 | .start = LTQ_ETOP_BASE_ADDR, | ||
102 | .end = LTQ_ETOP_BASE_ADDR + LTQ_ETOP_SIZE - 1, | ||
103 | .flags = IORESOURCE_MEM, | ||
104 | }; | ||
105 | |||
106 | static struct platform_device ltq_etop = { | ||
107 | .name = "ltq_etop", | ||
108 | .resource = <q_etop_resources, | ||
109 | .num_resources = 1, | ||
110 | }; | ||
111 | |||
112 | void __init | ||
113 | ltq_register_etop(struct ltq_eth_data *eth) | ||
114 | { | ||
115 | if (eth) { | ||
116 | ltq_etop.dev.platform_data = eth; | ||
117 | platform_device_register(<q_etop); | ||
118 | } | ||
119 | } | ||
diff --git a/arch/mips/lantiq/xway/devices.h b/arch/mips/lantiq/xway/devices.h deleted file mode 100644 index e90493471bc1..000000000000 --- a/arch/mips/lantiq/xway/devices.h +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #ifndef _LTQ_DEVICES_XWAY_H__ | ||
10 | #define _LTQ_DEVICES_XWAY_H__ | ||
11 | |||
12 | #include "../devices.h" | ||
13 | #include <linux/phy.h> | ||
14 | |||
15 | extern void ltq_register_gpio(void); | ||
16 | extern void ltq_register_gpio_stp(void); | ||
17 | extern void ltq_register_ase_asc(void); | ||
18 | extern void ltq_register_etop(struct ltq_eth_data *eth); | ||
19 | |||
20 | #endif | ||
diff --git a/arch/mips/lantiq/xway/dma.c b/arch/mips/lantiq/xway/dma.c index b210e936c7c3..55d2c4fa4714 100644 --- a/arch/mips/lantiq/xway/dma.c +++ b/arch/mips/lantiq/xway/dma.c | |||
@@ -19,7 +19,8 @@ | |||
19 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/dma-mapping.h> | 21 | #include <linux/dma-mapping.h> |
22 | #include <linux/export.h> | 22 | #include <linux/module.h> |
23 | #include <linux/clk.h> | ||
23 | 24 | ||
24 | #include <lantiq_soc.h> | 25 | #include <lantiq_soc.h> |
25 | #include <xway_dma.h> | 26 | #include <xway_dma.h> |
@@ -55,13 +56,6 @@ | |||
55 | #define ltq_dma_w32_mask(x, y, z) ltq_w32_mask(x, y, \ | 56 | #define ltq_dma_w32_mask(x, y, z) ltq_w32_mask(x, y, \ |
56 | ltq_dma_membase + (z)) | 57 | ltq_dma_membase + (z)) |
57 | 58 | ||
58 | static struct resource ltq_dma_resource = { | ||
59 | .name = "dma", | ||
60 | .start = LTQ_DMA_BASE_ADDR, | ||
61 | .end = LTQ_DMA_BASE_ADDR + LTQ_DMA_SIZE - 1, | ||
62 | .flags = IORESOURCE_MEM, | ||
63 | }; | ||
64 | |||
65 | static void __iomem *ltq_dma_membase; | 59 | static void __iomem *ltq_dma_membase; |
66 | 60 | ||
67 | void | 61 | void |
@@ -215,27 +209,28 @@ ltq_dma_init_port(int p) | |||
215 | } | 209 | } |
216 | EXPORT_SYMBOL_GPL(ltq_dma_init_port); | 210 | EXPORT_SYMBOL_GPL(ltq_dma_init_port); |
217 | 211 | ||
218 | int __init | 212 | static int __devinit |
219 | ltq_dma_init(void) | 213 | ltq_dma_init(struct platform_device *pdev) |
220 | { | 214 | { |
215 | struct clk *clk; | ||
216 | struct resource *res; | ||
221 | int i; | 217 | int i; |
222 | 218 | ||
223 | /* insert and request the memory region */ | 219 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
224 | if (insert_resource(&iomem_resource, <q_dma_resource) < 0) | 220 | if (!res) |
225 | panic("Failed to insert dma memory"); | 221 | panic("Failed to get dma resource"); |
226 | |||
227 | if (request_mem_region(ltq_dma_resource.start, | ||
228 | resource_size(<q_dma_resource), "dma") < 0) | ||
229 | panic("Failed to request dma memory"); | ||
230 | 222 | ||
231 | /* remap dma register range */ | 223 | /* remap dma register range */ |
232 | ltq_dma_membase = ioremap_nocache(ltq_dma_resource.start, | 224 | ltq_dma_membase = devm_request_and_ioremap(&pdev->dev, res); |
233 | resource_size(<q_dma_resource)); | ||
234 | if (!ltq_dma_membase) | 225 | if (!ltq_dma_membase) |
235 | panic("Failed to remap dma memory"); | 226 | panic("Failed to remap dma resource"); |
236 | 227 | ||
237 | /* power up and reset the dma engine */ | 228 | /* power up and reset the dma engine */ |
238 | ltq_pmu_enable(PMU_DMA); | 229 | clk = clk_get(&pdev->dev, NULL); |
230 | if (IS_ERR(clk)) | ||
231 | panic("Failed to get dma clock"); | ||
232 | |||
233 | clk_enable(clk); | ||
239 | ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL); | 234 | ltq_dma_w32_mask(0, DMA_RESET, LTQ_DMA_CTRL); |
240 | 235 | ||
241 | /* disable all interrupts */ | 236 | /* disable all interrupts */ |
@@ -248,7 +243,29 @@ ltq_dma_init(void) | |||
248 | ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); | 243 | ltq_dma_w32(DMA_POLL | DMA_CLK_DIV4, LTQ_DMA_CPOLL); |
249 | ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); | 244 | ltq_dma_w32_mask(DMA_CHAN_ON, 0, LTQ_DMA_CCTRL); |
250 | } | 245 | } |
246 | dev_info(&pdev->dev, "init done\n"); | ||
251 | return 0; | 247 | return 0; |
252 | } | 248 | } |
253 | 249 | ||
254 | postcore_initcall(ltq_dma_init); | 250 | static const struct of_device_id dma_match[] = { |
251 | { .compatible = "lantiq,dma-xway" }, | ||
252 | {}, | ||
253 | }; | ||
254 | MODULE_DEVICE_TABLE(of, dma_match); | ||
255 | |||
256 | static struct platform_driver dma_driver = { | ||
257 | .probe = ltq_dma_init, | ||
258 | .driver = { | ||
259 | .name = "dma-xway", | ||
260 | .owner = THIS_MODULE, | ||
261 | .of_match_table = dma_match, | ||
262 | }, | ||
263 | }; | ||
264 | |||
265 | int __init | ||
266 | dma_init(void) | ||
267 | { | ||
268 | return platform_driver_register(&dma_driver); | ||
269 | } | ||
270 | |||
271 | postcore_initcall(dma_init); | ||
diff --git a/arch/mips/lantiq/xway/ebu.c b/arch/mips/lantiq/xway/ebu.c deleted file mode 100644 index 862e3e830680..000000000000 --- a/arch/mips/lantiq/xway/ebu.c +++ /dev/null | |||
@@ -1,52 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * EBU - the external bus unit attaches PCI, NOR and NAND | ||
7 | * | ||
8 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
9 | */ | ||
10 | |||
11 | #include <linux/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/ioport.h> | ||
14 | |||
15 | #include <lantiq_soc.h> | ||
16 | |||
17 | /* all access to the ebu must be locked */ | ||
18 | DEFINE_SPINLOCK(ebu_lock); | ||
19 | EXPORT_SYMBOL_GPL(ebu_lock); | ||
20 | |||
21 | static struct resource ltq_ebu_resource = { | ||
22 | .name = "ebu", | ||
23 | .start = LTQ_EBU_BASE_ADDR, | ||
24 | .end = LTQ_EBU_BASE_ADDR + LTQ_EBU_SIZE - 1, | ||
25 | .flags = IORESOURCE_MEM, | ||
26 | }; | ||
27 | |||
28 | /* remapped base addr of the clock unit and external bus unit */ | ||
29 | void __iomem *ltq_ebu_membase; | ||
30 | |||
31 | static int __init lantiq_ebu_init(void) | ||
32 | { | ||
33 | /* insert and request the memory region */ | ||
34 | if (insert_resource(&iomem_resource, <q_ebu_resource) < 0) | ||
35 | panic("Failed to insert ebu memory"); | ||
36 | |||
37 | if (request_mem_region(ltq_ebu_resource.start, | ||
38 | resource_size(<q_ebu_resource), "ebu") < 0) | ||
39 | panic("Failed to request ebu memory"); | ||
40 | |||
41 | /* remap ebu register range */ | ||
42 | ltq_ebu_membase = ioremap_nocache(ltq_ebu_resource.start, | ||
43 | resource_size(<q_ebu_resource)); | ||
44 | if (!ltq_ebu_membase) | ||
45 | panic("Failed to remap ebu memory"); | ||
46 | |||
47 | /* make sure to unprotect the memory region where flash is located */ | ||
48 | ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0); | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | postcore_initcall(lantiq_ebu_init); | ||
diff --git a/arch/mips/lantiq/xway/gpio.c b/arch/mips/lantiq/xway/gpio.c index d2fa98f3c78d..a8b2edc80855 100644 --- a/arch/mips/lantiq/xway/gpio.c +++ b/arch/mips/lantiq/xway/gpio.c | |||
@@ -36,18 +36,6 @@ struct ltq_gpio { | |||
36 | 36 | ||
37 | static struct ltq_gpio ltq_gpio_port[MAX_PORTS]; | 37 | static struct ltq_gpio ltq_gpio_port[MAX_PORTS]; |
38 | 38 | ||
39 | int gpio_to_irq(unsigned int gpio) | ||
40 | { | ||
41 | return -EINVAL; | ||
42 | } | ||
43 | EXPORT_SYMBOL(gpio_to_irq); | ||
44 | |||
45 | int irq_to_gpio(unsigned int gpio) | ||
46 | { | ||
47 | return -EINVAL; | ||
48 | } | ||
49 | EXPORT_SYMBOL(irq_to_gpio); | ||
50 | |||
51 | int ltq_gpio_request(unsigned int pin, unsigned int alt0, | 39 | int ltq_gpio_request(unsigned int pin, unsigned int alt0, |
52 | unsigned int alt1, unsigned int dir, const char *name) | 40 | unsigned int alt1, unsigned int dir, const char *name) |
53 | { | 41 | { |
diff --git a/arch/mips/lantiq/xway/gpio_ebu.c b/arch/mips/lantiq/xway/gpio_ebu.c deleted file mode 100644 index b91c7f17f10f..000000000000 --- a/arch/mips/lantiq/xway/gpio_ebu.c +++ /dev/null | |||
@@ -1,126 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/export.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/mutex.h> | ||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/io.h> | ||
16 | |||
17 | #include <lantiq_soc.h> | ||
18 | |||
19 | /* | ||
20 | * By attaching hardware latches to the EBU it is possible to create output | ||
21 | * only gpios. This driver configures a special memory address, which when | ||
22 | * written to outputs 16 bit to the latches. | ||
23 | */ | ||
24 | |||
25 | #define LTQ_EBU_BUSCON 0x1e7ff /* 16 bit access, slowest timing */ | ||
26 | #define LTQ_EBU_WP 0x80000000 /* write protect bit */ | ||
27 | |||
28 | /* we keep a shadow value of the last value written to the ebu */ | ||
29 | static int ltq_ebu_gpio_shadow = 0x0; | ||
30 | static void __iomem *ltq_ebu_gpio_membase; | ||
31 | |||
32 | static void ltq_ebu_apply(void) | ||
33 | { | ||
34 | unsigned long flags; | ||
35 | |||
36 | spin_lock_irqsave(&ebu_lock, flags); | ||
37 | ltq_ebu_w32(LTQ_EBU_BUSCON, LTQ_EBU_BUSCON1); | ||
38 | *((__u16 *)ltq_ebu_gpio_membase) = ltq_ebu_gpio_shadow; | ||
39 | ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1); | ||
40 | spin_unlock_irqrestore(&ebu_lock, flags); | ||
41 | } | ||
42 | |||
43 | static void ltq_ebu_set(struct gpio_chip *chip, unsigned offset, int value) | ||
44 | { | ||
45 | if (value) | ||
46 | ltq_ebu_gpio_shadow |= (1 << offset); | ||
47 | else | ||
48 | ltq_ebu_gpio_shadow &= ~(1 << offset); | ||
49 | ltq_ebu_apply(); | ||
50 | } | ||
51 | |||
52 | static int ltq_ebu_direction_output(struct gpio_chip *chip, unsigned offset, | ||
53 | int value) | ||
54 | { | ||
55 | ltq_ebu_set(chip, offset, value); | ||
56 | |||
57 | return 0; | ||
58 | } | ||
59 | |||
60 | static struct gpio_chip ltq_ebu_chip = { | ||
61 | .label = "ltq_ebu", | ||
62 | .direction_output = ltq_ebu_direction_output, | ||
63 | .set = ltq_ebu_set, | ||
64 | .base = 72, | ||
65 | .ngpio = 16, | ||
66 | .can_sleep = 1, | ||
67 | .owner = THIS_MODULE, | ||
68 | }; | ||
69 | |||
70 | static int ltq_ebu_probe(struct platform_device *pdev) | ||
71 | { | ||
72 | int ret = 0; | ||
73 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
74 | |||
75 | if (!res) { | ||
76 | dev_err(&pdev->dev, "failed to get memory resource\n"); | ||
77 | return -ENOENT; | ||
78 | } | ||
79 | |||
80 | res = devm_request_mem_region(&pdev->dev, res->start, | ||
81 | resource_size(res), dev_name(&pdev->dev)); | ||
82 | if (!res) { | ||
83 | dev_err(&pdev->dev, "failed to request memory resource\n"); | ||
84 | return -EBUSY; | ||
85 | } | ||
86 | |||
87 | ltq_ebu_gpio_membase = devm_ioremap_nocache(&pdev->dev, res->start, | ||
88 | resource_size(res)); | ||
89 | if (!ltq_ebu_gpio_membase) { | ||
90 | dev_err(&pdev->dev, "Failed to ioremap mem region\n"); | ||
91 | return -ENOMEM; | ||
92 | } | ||
93 | |||
94 | /* grab the default shadow value passed form the platform code */ | ||
95 | ltq_ebu_gpio_shadow = (unsigned int) pdev->dev.platform_data; | ||
96 | |||
97 | /* tell the ebu controller which memory address we will be using */ | ||
98 | ltq_ebu_w32(pdev->resource->start | 0x1, LTQ_EBU_ADDRSEL1); | ||
99 | |||
100 | /* write protect the region */ | ||
101 | ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1); | ||
102 | |||
103 | ret = gpiochip_add(<q_ebu_chip); | ||
104 | if (!ret) | ||
105 | ltq_ebu_apply(); | ||
106 | return ret; | ||
107 | } | ||
108 | |||
109 | static struct platform_driver ltq_ebu_driver = { | ||
110 | .probe = ltq_ebu_probe, | ||
111 | .driver = { | ||
112 | .name = "ltq_ebu", | ||
113 | .owner = THIS_MODULE, | ||
114 | }, | ||
115 | }; | ||
116 | |||
117 | static int __init ltq_ebu_init(void) | ||
118 | { | ||
119 | int ret = platform_driver_register(<q_ebu_driver); | ||
120 | |||
121 | if (ret) | ||
122 | pr_info("ltq_ebu : Error registering platfom driver!"); | ||
123 | return ret; | ||
124 | } | ||
125 | |||
126 | postcore_initcall(ltq_ebu_init); | ||
diff --git a/arch/mips/lantiq/xway/gpio_stp.c b/arch/mips/lantiq/xway/gpio_stp.c deleted file mode 100644 index ff9991cddeaa..000000000000 --- a/arch/mips/lantiq/xway/gpio_stp.c +++ /dev/null | |||
@@ -1,157 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2007 John Crispin <blogic@openwrt.org> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/slab.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/export.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | #include <linux/mutex.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/gpio.h> | ||
18 | |||
19 | #include <lantiq_soc.h> | ||
20 | |||
21 | #define LTQ_STP_CON0 0x00 | ||
22 | #define LTQ_STP_CON1 0x04 | ||
23 | #define LTQ_STP_CPU0 0x08 | ||
24 | #define LTQ_STP_CPU1 0x0C | ||
25 | #define LTQ_STP_AR 0x10 | ||
26 | |||
27 | #define LTQ_STP_CON_SWU (1 << 31) | ||
28 | #define LTQ_STP_2HZ 0 | ||
29 | #define LTQ_STP_4HZ (1 << 23) | ||
30 | #define LTQ_STP_8HZ (2 << 23) | ||
31 | #define LTQ_STP_10HZ (3 << 23) | ||
32 | #define LTQ_STP_SPEED_MASK (0xf << 23) | ||
33 | #define LTQ_STP_UPD_FPI (1 << 31) | ||
34 | #define LTQ_STP_UPD_MASK (3 << 30) | ||
35 | #define LTQ_STP_ADSL_SRC (3 << 24) | ||
36 | |||
37 | #define LTQ_STP_GROUP0 (1 << 0) | ||
38 | |||
39 | #define LTQ_STP_RISING 0 | ||
40 | #define LTQ_STP_FALLING (1 << 26) | ||
41 | #define LTQ_STP_EDGE_MASK (1 << 26) | ||
42 | |||
43 | #define ltq_stp_r32(reg) __raw_readl(ltq_stp_membase + reg) | ||
44 | #define ltq_stp_w32(val, reg) __raw_writel(val, ltq_stp_membase + reg) | ||
45 | #define ltq_stp_w32_mask(clear, set, reg) \ | ||
46 | ltq_w32((ltq_r32(ltq_stp_membase + reg) & ~(clear)) | (set), \ | ||
47 | ltq_stp_membase + (reg)) | ||
48 | |||
49 | static int ltq_stp_shadow = 0xffff; | ||
50 | static void __iomem *ltq_stp_membase; | ||
51 | |||
52 | static void ltq_stp_set(struct gpio_chip *chip, unsigned offset, int value) | ||
53 | { | ||
54 | if (value) | ||
55 | ltq_stp_shadow |= (1 << offset); | ||
56 | else | ||
57 | ltq_stp_shadow &= ~(1 << offset); | ||
58 | ltq_stp_w32(ltq_stp_shadow, LTQ_STP_CPU0); | ||
59 | } | ||
60 | |||
61 | static int ltq_stp_direction_output(struct gpio_chip *chip, unsigned offset, | ||
62 | int value) | ||
63 | { | ||
64 | ltq_stp_set(chip, offset, value); | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static struct gpio_chip ltq_stp_chip = { | ||
70 | .label = "ltq_stp", | ||
71 | .direction_output = ltq_stp_direction_output, | ||
72 | .set = ltq_stp_set, | ||
73 | .base = 48, | ||
74 | .ngpio = 24, | ||
75 | .can_sleep = 1, | ||
76 | .owner = THIS_MODULE, | ||
77 | }; | ||
78 | |||
79 | static int ltq_stp_hw_init(void) | ||
80 | { | ||
81 | /* the 3 pins used to control the external stp */ | ||
82 | ltq_gpio_request(4, 1, 0, 1, "stp-st"); | ||
83 | ltq_gpio_request(5, 1, 0, 1, "stp-d"); | ||
84 | ltq_gpio_request(6, 1, 0, 1, "stp-sh"); | ||
85 | |||
86 | /* sane defaults */ | ||
87 | ltq_stp_w32(0, LTQ_STP_AR); | ||
88 | ltq_stp_w32(0, LTQ_STP_CPU0); | ||
89 | ltq_stp_w32(0, LTQ_STP_CPU1); | ||
90 | ltq_stp_w32(LTQ_STP_CON_SWU, LTQ_STP_CON0); | ||
91 | ltq_stp_w32(0, LTQ_STP_CON1); | ||
92 | |||
93 | /* rising or falling edge */ | ||
94 | ltq_stp_w32_mask(LTQ_STP_EDGE_MASK, LTQ_STP_FALLING, LTQ_STP_CON0); | ||
95 | |||
96 | /* per default stp 15-0 are set */ | ||
97 | ltq_stp_w32_mask(0, LTQ_STP_GROUP0, LTQ_STP_CON1); | ||
98 | |||
99 | /* stp are update periodically by the FPI bus */ | ||
100 | ltq_stp_w32_mask(LTQ_STP_UPD_MASK, LTQ_STP_UPD_FPI, LTQ_STP_CON1); | ||
101 | |||
102 | /* set stp update speed */ | ||
103 | ltq_stp_w32_mask(LTQ_STP_SPEED_MASK, LTQ_STP_8HZ, LTQ_STP_CON1); | ||
104 | |||
105 | /* tell the hardware that pin (led) 0 and 1 are controlled | ||
106 | * by the dsl arc | ||
107 | */ | ||
108 | ltq_stp_w32_mask(0, LTQ_STP_ADSL_SRC, LTQ_STP_CON0); | ||
109 | |||
110 | ltq_pmu_enable(PMU_LED); | ||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | static int __devinit ltq_stp_probe(struct platform_device *pdev) | ||
115 | { | ||
116 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
117 | int ret = 0; | ||
118 | |||
119 | if (!res) | ||
120 | return -ENOENT; | ||
121 | res = devm_request_mem_region(&pdev->dev, res->start, | ||
122 | resource_size(res), dev_name(&pdev->dev)); | ||
123 | if (!res) { | ||
124 | dev_err(&pdev->dev, "failed to request STP memory\n"); | ||
125 | return -EBUSY; | ||
126 | } | ||
127 | ltq_stp_membase = devm_ioremap_nocache(&pdev->dev, res->start, | ||
128 | resource_size(res)); | ||
129 | if (!ltq_stp_membase) { | ||
130 | dev_err(&pdev->dev, "failed to remap STP memory\n"); | ||
131 | return -ENOMEM; | ||
132 | } | ||
133 | ret = gpiochip_add(<q_stp_chip); | ||
134 | if (!ret) | ||
135 | ret = ltq_stp_hw_init(); | ||
136 | |||
137 | return ret; | ||
138 | } | ||
139 | |||
140 | static struct platform_driver ltq_stp_driver = { | ||
141 | .probe = ltq_stp_probe, | ||
142 | .driver = { | ||
143 | .name = "ltq_stp", | ||
144 | .owner = THIS_MODULE, | ||
145 | }, | ||
146 | }; | ||
147 | |||
148 | int __init ltq_stp_init(void) | ||
149 | { | ||
150 | int ret = platform_driver_register(<q_stp_driver); | ||
151 | |||
152 | if (ret) | ||
153 | pr_info("ltq_stp: error registering platfom driver"); | ||
154 | return ret; | ||
155 | } | ||
156 | |||
157 | postcore_initcall(ltq_stp_init); | ||
diff --git a/arch/mips/lantiq/xway/mach-easy50601.c b/arch/mips/lantiq/xway/mach-easy50601.c deleted file mode 100644 index d5aaf637ab19..000000000000 --- a/arch/mips/lantiq/xway/mach-easy50601.c +++ /dev/null | |||
@@ -1,57 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/mtd/mtd.h> | ||
12 | #include <linux/mtd/partitions.h> | ||
13 | #include <linux/mtd/physmap.h> | ||
14 | #include <linux/input.h> | ||
15 | |||
16 | #include <lantiq.h> | ||
17 | |||
18 | #include "../machtypes.h" | ||
19 | #include "devices.h" | ||
20 | |||
21 | static struct mtd_partition easy50601_partitions[] = { | ||
22 | { | ||
23 | .name = "uboot", | ||
24 | .offset = 0x0, | ||
25 | .size = 0x10000, | ||
26 | }, | ||
27 | { | ||
28 | .name = "uboot_env", | ||
29 | .offset = 0x10000, | ||
30 | .size = 0x10000, | ||
31 | }, | ||
32 | { | ||
33 | .name = "linux", | ||
34 | .offset = 0x20000, | ||
35 | .size = 0xE0000, | ||
36 | }, | ||
37 | { | ||
38 | .name = "rootfs", | ||
39 | .offset = 0x100000, | ||
40 | .size = 0x300000, | ||
41 | }, | ||
42 | }; | ||
43 | |||
44 | static struct physmap_flash_data easy50601_flash_data = { | ||
45 | .nr_parts = ARRAY_SIZE(easy50601_partitions), | ||
46 | .parts = easy50601_partitions, | ||
47 | }; | ||
48 | |||
49 | static void __init easy50601_init(void) | ||
50 | { | ||
51 | ltq_register_nor(&easy50601_flash_data); | ||
52 | } | ||
53 | |||
54 | MIPS_MACHINE(LTQ_MACH_EASY50601, | ||
55 | "EASY50601", | ||
56 | "EASY50601 Eval Board", | ||
57 | easy50601_init); | ||
diff --git a/arch/mips/lantiq/xway/mach-easy50712.c b/arch/mips/lantiq/xway/mach-easy50712.c deleted file mode 100644 index ea5027b3239d..000000000000 --- a/arch/mips/lantiq/xway/mach-easy50712.c +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/platform_device.h> | ||
11 | #include <linux/mtd/mtd.h> | ||
12 | #include <linux/mtd/partitions.h> | ||
13 | #include <linux/mtd/physmap.h> | ||
14 | #include <linux/input.h> | ||
15 | #include <linux/phy.h> | ||
16 | |||
17 | #include <lantiq_soc.h> | ||
18 | #include <irq.h> | ||
19 | |||
20 | #include "../machtypes.h" | ||
21 | #include "devices.h" | ||
22 | |||
23 | static struct mtd_partition easy50712_partitions[] = { | ||
24 | { | ||
25 | .name = "uboot", | ||
26 | .offset = 0x0, | ||
27 | .size = 0x10000, | ||
28 | }, | ||
29 | { | ||
30 | .name = "uboot_env", | ||
31 | .offset = 0x10000, | ||
32 | .size = 0x10000, | ||
33 | }, | ||
34 | { | ||
35 | .name = "linux", | ||
36 | .offset = 0x20000, | ||
37 | .size = 0xe0000, | ||
38 | }, | ||
39 | { | ||
40 | .name = "rootfs", | ||
41 | .offset = 0x100000, | ||
42 | .size = 0x300000, | ||
43 | }, | ||
44 | }; | ||
45 | |||
46 | static struct physmap_flash_data easy50712_flash_data = { | ||
47 | .nr_parts = ARRAY_SIZE(easy50712_partitions), | ||
48 | .parts = easy50712_partitions, | ||
49 | }; | ||
50 | |||
51 | static struct ltq_pci_data ltq_pci_data = { | ||
52 | .clock = PCI_CLOCK_INT, | ||
53 | .gpio = PCI_GNT1 | PCI_REQ1, | ||
54 | .irq = { | ||
55 | [14] = INT_NUM_IM0_IRL0 + 22, | ||
56 | }, | ||
57 | }; | ||
58 | |||
59 | static struct ltq_eth_data ltq_eth_data = { | ||
60 | .mii_mode = PHY_INTERFACE_MODE_MII, | ||
61 | }; | ||
62 | |||
63 | static void __init easy50712_init(void) | ||
64 | { | ||
65 | ltq_register_gpio_stp(); | ||
66 | ltq_register_nor(&easy50712_flash_data); | ||
67 | ltq_register_pci(<q_pci_data); | ||
68 | ltq_register_etop(<q_eth_data); | ||
69 | } | ||
70 | |||
71 | MIPS_MACHINE(LTQ_MACH_EASY50712, | ||
72 | "EASY50712", | ||
73 | "EASY50712 Eval Board", | ||
74 | easy50712_init); | ||
diff --git a/arch/mips/lantiq/xway/pmu.c b/arch/mips/lantiq/xway/pmu.c deleted file mode 100644 index fe85361e032e..000000000000 --- a/arch/mips/lantiq/xway/pmu.c +++ /dev/null | |||
@@ -1,69 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/ioport.h> | ||
12 | |||
13 | #include <lantiq_soc.h> | ||
14 | |||
15 | /* PMU - the power management unit allows us to turn part of the core | ||
16 | * on and off | ||
17 | */ | ||
18 | |||
19 | /* the enable / disable registers */ | ||
20 | #define LTQ_PMU_PWDCR 0x1C | ||
21 | #define LTQ_PMU_PWDSR 0x20 | ||
22 | |||
23 | #define ltq_pmu_w32(x, y) ltq_w32((x), ltq_pmu_membase + (y)) | ||
24 | #define ltq_pmu_r32(x) ltq_r32(ltq_pmu_membase + (x)) | ||
25 | |||
26 | static struct resource ltq_pmu_resource = { | ||
27 | .name = "pmu", | ||
28 | .start = LTQ_PMU_BASE_ADDR, | ||
29 | .end = LTQ_PMU_BASE_ADDR + LTQ_PMU_SIZE - 1, | ||
30 | .flags = IORESOURCE_MEM, | ||
31 | }; | ||
32 | |||
33 | static void __iomem *ltq_pmu_membase; | ||
34 | |||
35 | void ltq_pmu_enable(unsigned int module) | ||
36 | { | ||
37 | int err = 1000000; | ||
38 | |||
39 | ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) & ~module, LTQ_PMU_PWDCR); | ||
40 | do {} while (--err && (ltq_pmu_r32(LTQ_PMU_PWDSR) & module)); | ||
41 | |||
42 | if (!err) | ||
43 | panic("activating PMU module failed!"); | ||
44 | } | ||
45 | EXPORT_SYMBOL(ltq_pmu_enable); | ||
46 | |||
47 | void ltq_pmu_disable(unsigned int module) | ||
48 | { | ||
49 | ltq_pmu_w32(ltq_pmu_r32(LTQ_PMU_PWDCR) | module, LTQ_PMU_PWDCR); | ||
50 | } | ||
51 | EXPORT_SYMBOL(ltq_pmu_disable); | ||
52 | |||
53 | int __init ltq_pmu_init(void) | ||
54 | { | ||
55 | if (insert_resource(&iomem_resource, <q_pmu_resource) < 0) | ||
56 | panic("Failed to insert pmu memory"); | ||
57 | |||
58 | if (request_mem_region(ltq_pmu_resource.start, | ||
59 | resource_size(<q_pmu_resource), "pmu") < 0) | ||
60 | panic("Failed to request pmu memory"); | ||
61 | |||
62 | ltq_pmu_membase = ioremap_nocache(ltq_pmu_resource.start, | ||
63 | resource_size(<q_pmu_resource)); | ||
64 | if (!ltq_pmu_membase) | ||
65 | panic("Failed to remap pmu memory"); | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | core_initcall(ltq_pmu_init); | ||
diff --git a/arch/mips/lantiq/xway/prom-ase.c b/arch/mips/lantiq/xway/prom-ase.c deleted file mode 100644 index ae4959ae865c..000000000000 --- a/arch/mips/lantiq/xway/prom-ase.c +++ /dev/null | |||
@@ -1,39 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/export.h> | ||
10 | #include <linux/clk.h> | ||
11 | #include <asm/bootinfo.h> | ||
12 | #include <asm/time.h> | ||
13 | |||
14 | #include <lantiq_soc.h> | ||
15 | |||
16 | #include "../prom.h" | ||
17 | |||
18 | #define SOC_AMAZON_SE "Amazon_SE" | ||
19 | |||
20 | #define PART_SHIFT 12 | ||
21 | #define PART_MASK 0x0FFFFFFF | ||
22 | #define REV_SHIFT 28 | ||
23 | #define REV_MASK 0xF0000000 | ||
24 | |||
25 | void __init ltq_soc_detect(struct ltq_soc_info *i) | ||
26 | { | ||
27 | i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT; | ||
28 | i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT; | ||
29 | switch (i->partnum) { | ||
30 | case SOC_ID_AMAZON_SE: | ||
31 | i->name = SOC_AMAZON_SE; | ||
32 | i->type = SOC_TYPE_AMAZON_SE; | ||
33 | break; | ||
34 | |||
35 | default: | ||
36 | unreachable(); | ||
37 | break; | ||
38 | } | ||
39 | } | ||
diff --git a/arch/mips/lantiq/xway/prom-xway.c b/arch/mips/lantiq/xway/prom-xway.c deleted file mode 100644 index 2228133ca356..000000000000 --- a/arch/mips/lantiq/xway/prom-xway.c +++ /dev/null | |||
@@ -1,54 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/export.h> | ||
10 | #include <linux/clk.h> | ||
11 | #include <asm/bootinfo.h> | ||
12 | #include <asm/time.h> | ||
13 | |||
14 | #include <lantiq_soc.h> | ||
15 | |||
16 | #include "../prom.h" | ||
17 | |||
18 | #define SOC_DANUBE "Danube" | ||
19 | #define SOC_TWINPASS "Twinpass" | ||
20 | #define SOC_AR9 "AR9" | ||
21 | |||
22 | #define PART_SHIFT 12 | ||
23 | #define PART_MASK 0x0FFFFFFF | ||
24 | #define REV_SHIFT 28 | ||
25 | #define REV_MASK 0xF0000000 | ||
26 | |||
27 | void __init ltq_soc_detect(struct ltq_soc_info *i) | ||
28 | { | ||
29 | i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT; | ||
30 | i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT; | ||
31 | switch (i->partnum) { | ||
32 | case SOC_ID_DANUBE1: | ||
33 | case SOC_ID_DANUBE2: | ||
34 | i->name = SOC_DANUBE; | ||
35 | i->type = SOC_TYPE_DANUBE; | ||
36 | break; | ||
37 | |||
38 | case SOC_ID_TWINPASS: | ||
39 | i->name = SOC_TWINPASS; | ||
40 | i->type = SOC_TYPE_DANUBE; | ||
41 | break; | ||
42 | |||
43 | case SOC_ID_ARX188: | ||
44 | case SOC_ID_ARX168: | ||
45 | case SOC_ID_ARX182: | ||
46 | i->name = SOC_AR9; | ||
47 | i->type = SOC_TYPE_AR9; | ||
48 | break; | ||
49 | |||
50 | default: | ||
51 | unreachable(); | ||
52 | break; | ||
53 | } | ||
54 | } | ||
diff --git a/arch/mips/lantiq/xway/prom.c b/arch/mips/lantiq/xway/prom.c new file mode 100644 index 000000000000..248429ab2622 --- /dev/null +++ b/arch/mips/lantiq/xway/prom.c | |||
@@ -0,0 +1,115 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2010 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/export.h> | ||
10 | #include <linux/clk.h> | ||
11 | #include <asm/bootinfo.h> | ||
12 | #include <asm/time.h> | ||
13 | |||
14 | #include <lantiq_soc.h> | ||
15 | |||
16 | #include "../prom.h" | ||
17 | |||
18 | #define SOC_DANUBE "Danube" | ||
19 | #define SOC_TWINPASS "Twinpass" | ||
20 | #define SOC_AMAZON_SE "Amazon_SE" | ||
21 | #define SOC_AR9 "AR9" | ||
22 | #define SOC_GR9 "GR9" | ||
23 | #define SOC_VR9 "VR9" | ||
24 | |||
25 | #define COMP_DANUBE "lantiq,danube" | ||
26 | #define COMP_TWINPASS "lantiq,twinpass" | ||
27 | #define COMP_AMAZON_SE "lantiq,ase" | ||
28 | #define COMP_AR9 "lantiq,ar9" | ||
29 | #define COMP_GR9 "lantiq,gr9" | ||
30 | #define COMP_VR9 "lantiq,vr9" | ||
31 | |||
32 | #define PART_SHIFT 12 | ||
33 | #define PART_MASK 0x0FFFFFFF | ||
34 | #define REV_SHIFT 28 | ||
35 | #define REV_MASK 0xF0000000 | ||
36 | |||
37 | void __init ltq_soc_detect(struct ltq_soc_info *i) | ||
38 | { | ||
39 | i->partnum = (ltq_r32(LTQ_MPS_CHIPID) & PART_MASK) >> PART_SHIFT; | ||
40 | i->rev = (ltq_r32(LTQ_MPS_CHIPID) & REV_MASK) >> REV_SHIFT; | ||
41 | sprintf(i->rev_type, "1.%d", i->rev); | ||
42 | switch (i->partnum) { | ||
43 | case SOC_ID_DANUBE1: | ||
44 | case SOC_ID_DANUBE2: | ||
45 | i->name = SOC_DANUBE; | ||
46 | i->type = SOC_TYPE_DANUBE; | ||
47 | i->compatible = COMP_DANUBE; | ||
48 | break; | ||
49 | |||
50 | case SOC_ID_TWINPASS: | ||
51 | i->name = SOC_TWINPASS; | ||
52 | i->type = SOC_TYPE_DANUBE; | ||
53 | i->compatible = COMP_TWINPASS; | ||
54 | break; | ||
55 | |||
56 | case SOC_ID_ARX188: | ||
57 | case SOC_ID_ARX168_1: | ||
58 | case SOC_ID_ARX168_2: | ||
59 | case SOC_ID_ARX182: | ||
60 | i->name = SOC_AR9; | ||
61 | i->type = SOC_TYPE_AR9; | ||
62 | i->compatible = COMP_AR9; | ||
63 | break; | ||
64 | |||
65 | case SOC_ID_GRX188: | ||
66 | case SOC_ID_GRX168: | ||
67 | i->name = SOC_GR9; | ||
68 | i->type = SOC_TYPE_AR9; | ||
69 | i->compatible = COMP_GR9; | ||
70 | break; | ||
71 | |||
72 | case SOC_ID_AMAZON_SE_1: | ||
73 | case SOC_ID_AMAZON_SE_2: | ||
74 | #ifdef CONFIG_PCI | ||
75 | panic("ase is only supported for non pci kernels"); | ||
76 | #endif | ||
77 | i->name = SOC_AMAZON_SE; | ||
78 | i->type = SOC_TYPE_AMAZON_SE; | ||
79 | i->compatible = COMP_AMAZON_SE; | ||
80 | break; | ||
81 | |||
82 | case SOC_ID_VRX282: | ||
83 | case SOC_ID_VRX268: | ||
84 | case SOC_ID_VRX288: | ||
85 | i->name = SOC_VR9; | ||
86 | i->type = SOC_TYPE_VR9; | ||
87 | i->compatible = COMP_VR9; | ||
88 | break; | ||
89 | |||
90 | case SOC_ID_GRX268: | ||
91 | case SOC_ID_GRX288: | ||
92 | i->name = SOC_GR9; | ||
93 | i->type = SOC_TYPE_VR9; | ||
94 | i->compatible = COMP_GR9; | ||
95 | break; | ||
96 | |||
97 | case SOC_ID_VRX268_2: | ||
98 | case SOC_ID_VRX288_2: | ||
99 | i->name = SOC_VR9; | ||
100 | i->type = SOC_TYPE_VR9_2; | ||
101 | i->compatible = COMP_VR9; | ||
102 | break; | ||
103 | |||
104 | case SOC_ID_GRX282_2: | ||
105 | case SOC_ID_GRX288_2: | ||
106 | i->name = SOC_GR9; | ||
107 | i->type = SOC_TYPE_VR9_2; | ||
108 | i->compatible = COMP_GR9; | ||
109 | break; | ||
110 | |||
111 | default: | ||
112 | unreachable(); | ||
113 | break; | ||
114 | } | ||
115 | } | ||
diff --git a/arch/mips/lantiq/xway/reset.c b/arch/mips/lantiq/xway/reset.c index 8b66bd87f0c1..22c55f73aa9d 100644 --- a/arch/mips/lantiq/xway/reset.c +++ b/arch/mips/lantiq/xway/reset.c | |||
@@ -11,26 +11,31 @@ | |||
11 | #include <linux/ioport.h> | 11 | #include <linux/ioport.h> |
12 | #include <linux/pm.h> | 12 | #include <linux/pm.h> |
13 | #include <linux/export.h> | 13 | #include <linux/export.h> |
14 | #include <linux/delay.h> | ||
15 | #include <linux/of_address.h> | ||
16 | #include <linux/of_platform.h> | ||
17 | |||
14 | #include <asm/reboot.h> | 18 | #include <asm/reboot.h> |
15 | 19 | ||
16 | #include <lantiq_soc.h> | 20 | #include <lantiq_soc.h> |
17 | 21 | ||
22 | #include "../prom.h" | ||
23 | |||
18 | #define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y)) | 24 | #define ltq_rcu_w32(x, y) ltq_w32((x), ltq_rcu_membase + (y)) |
19 | #define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x)) | 25 | #define ltq_rcu_r32(x) ltq_r32(ltq_rcu_membase + (x)) |
20 | 26 | ||
21 | /* register definitions */ | 27 | /* reset request register */ |
22 | #define LTQ_RCU_RST 0x0010 | 28 | #define RCU_RST_REQ 0x0010 |
23 | #define LTQ_RCU_RST_ALL 0x40000000 | 29 | /* reset status register */ |
24 | 30 | #define RCU_RST_STAT 0x0014 | |
25 | #define LTQ_RCU_RST_STAT 0x0014 | ||
26 | #define LTQ_RCU_STAT_SHIFT 26 | ||
27 | 31 | ||
28 | static struct resource ltq_rcu_resource = { | 32 | /* reboot bit */ |
29 | .name = "rcu", | 33 | #define RCU_RD_SRST BIT(30) |
30 | .start = LTQ_RCU_BASE_ADDR, | 34 | /* reset cause */ |
31 | .end = LTQ_RCU_BASE_ADDR + LTQ_RCU_SIZE - 1, | 35 | #define RCU_STAT_SHIFT 26 |
32 | .flags = IORESOURCE_MEM, | 36 | /* boot selection */ |
33 | }; | 37 | #define RCU_BOOT_SEL_SHIFT 26 |
38 | #define RCU_BOOT_SEL_MASK 0x7 | ||
34 | 39 | ||
35 | /* remapped base addr of the reset control unit */ | 40 | /* remapped base addr of the reset control unit */ |
36 | static void __iomem *ltq_rcu_membase; | 41 | static void __iomem *ltq_rcu_membase; |
@@ -38,48 +43,64 @@ static void __iomem *ltq_rcu_membase; | |||
38 | /* This function is used by the watchdog driver */ | 43 | /* This function is used by the watchdog driver */ |
39 | int ltq_reset_cause(void) | 44 | int ltq_reset_cause(void) |
40 | { | 45 | { |
41 | u32 val = ltq_rcu_r32(LTQ_RCU_RST_STAT); | 46 | u32 val = ltq_rcu_r32(RCU_RST_STAT); |
42 | return val >> LTQ_RCU_STAT_SHIFT; | 47 | return val >> RCU_STAT_SHIFT; |
43 | } | 48 | } |
44 | EXPORT_SYMBOL_GPL(ltq_reset_cause); | 49 | EXPORT_SYMBOL_GPL(ltq_reset_cause); |
45 | 50 | ||
51 | /* allow platform code to find out what source we booted from */ | ||
52 | unsigned char ltq_boot_select(void) | ||
53 | { | ||
54 | u32 val = ltq_rcu_r32(RCU_RST_STAT); | ||
55 | return (val >> RCU_BOOT_SEL_SHIFT) & RCU_BOOT_SEL_MASK; | ||
56 | } | ||
57 | |||
58 | /* reset a io domain for u micro seconds */ | ||
59 | void ltq_reset_once(unsigned int module, ulong u) | ||
60 | { | ||
61 | ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | module, RCU_RST_REQ); | ||
62 | udelay(u); | ||
63 | ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) & ~module, RCU_RST_REQ); | ||
64 | } | ||
65 | |||
46 | static void ltq_machine_restart(char *command) | 66 | static void ltq_machine_restart(char *command) |
47 | { | 67 | { |
48 | pr_notice("System restart\n"); | ||
49 | local_irq_disable(); | 68 | local_irq_disable(); |
50 | ltq_rcu_w32(ltq_rcu_r32(LTQ_RCU_RST) | LTQ_RCU_RST_ALL, LTQ_RCU_RST); | 69 | ltq_rcu_w32(ltq_rcu_r32(RCU_RST_REQ) | RCU_RD_SRST, RCU_RST_REQ); |
51 | unreachable(); | 70 | unreachable(); |
52 | } | 71 | } |
53 | 72 | ||
54 | static void ltq_machine_halt(void) | 73 | static void ltq_machine_halt(void) |
55 | { | 74 | { |
56 | pr_notice("System halted.\n"); | ||
57 | local_irq_disable(); | 75 | local_irq_disable(); |
58 | unreachable(); | 76 | unreachable(); |
59 | } | 77 | } |
60 | 78 | ||
61 | static void ltq_machine_power_off(void) | 79 | static void ltq_machine_power_off(void) |
62 | { | 80 | { |
63 | pr_notice("Please turn off the power now.\n"); | ||
64 | local_irq_disable(); | 81 | local_irq_disable(); |
65 | unreachable(); | 82 | unreachable(); |
66 | } | 83 | } |
67 | 84 | ||
68 | static int __init mips_reboot_setup(void) | 85 | static int __init mips_reboot_setup(void) |
69 | { | 86 | { |
70 | /* insert and request the memory region */ | 87 | struct resource res; |
71 | if (insert_resource(&iomem_resource, <q_rcu_resource) < 0) | 88 | struct device_node *np = |
72 | panic("Failed to insert rcu memory"); | 89 | of_find_compatible_node(NULL, NULL, "lantiq,rcu-xway"); |
90 | |||
91 | /* check if all the reset register range is available */ | ||
92 | if (!np) | ||
93 | panic("Failed to load reset resources from devicetree"); | ||
94 | |||
95 | if (of_address_to_resource(np, 0, &res)) | ||
96 | panic("Failed to get rcu memory range"); | ||
73 | 97 | ||
74 | if (request_mem_region(ltq_rcu_resource.start, | 98 | if (request_mem_region(res.start, resource_size(&res), res.name) < 0) |
75 | resource_size(<q_rcu_resource), "rcu") < 0) | 99 | pr_err("Failed to request rcu memory"); |
76 | panic("Failed to request rcu memory"); | ||
77 | 100 | ||
78 | /* remap rcu register range */ | 101 | ltq_rcu_membase = ioremap_nocache(res.start, resource_size(&res)); |
79 | ltq_rcu_membase = ioremap_nocache(ltq_rcu_resource.start, | ||
80 | resource_size(<q_rcu_resource)); | ||
81 | if (!ltq_rcu_membase) | 102 | if (!ltq_rcu_membase) |
82 | panic("Failed to remap rcu memory"); | 103 | panic("Failed to remap core memory"); |
83 | 104 | ||
84 | _machine_restart = ltq_machine_restart; | 105 | _machine_restart = ltq_machine_restart; |
85 | _machine_halt = ltq_machine_halt; | 106 | _machine_halt = ltq_machine_halt; |
diff --git a/arch/mips/lantiq/xway/setup-ase.c b/arch/mips/lantiq/xway/setup-ase.c deleted file mode 100644 index f6f326798a39..000000000000 --- a/arch/mips/lantiq/xway/setup-ase.c +++ /dev/null | |||
@@ -1,19 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <lantiq_soc.h> | ||
10 | |||
11 | #include "../prom.h" | ||
12 | #include "devices.h" | ||
13 | |||
14 | void __init ltq_soc_setup(void) | ||
15 | { | ||
16 | ltq_register_ase_asc(); | ||
17 | ltq_register_gpio(); | ||
18 | ltq_register_wdt(); | ||
19 | } | ||
diff --git a/arch/mips/lantiq/xway/setup-xway.c b/arch/mips/lantiq/xway/setup-xway.c deleted file mode 100644 index c292f643a858..000000000000 --- a/arch/mips/lantiq/xway/setup-xway.c +++ /dev/null | |||
@@ -1,20 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2011 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <lantiq_soc.h> | ||
10 | |||
11 | #include "../prom.h" | ||
12 | #include "devices.h" | ||
13 | |||
14 | void __init ltq_soc_setup(void) | ||
15 | { | ||
16 | ltq_register_asc(0); | ||
17 | ltq_register_asc(1); | ||
18 | ltq_register_gpio(); | ||
19 | ltq_register_wdt(); | ||
20 | } | ||
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c new file mode 100644 index 000000000000..83780f7c842b --- /dev/null +++ b/arch/mips/lantiq/xway/sysctrl.c | |||
@@ -0,0 +1,371 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2011-2012 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/ioport.h> | ||
10 | #include <linux/export.h> | ||
11 | #include <linux/clkdev.h> | ||
12 | #include <linux/of.h> | ||
13 | #include <linux/of_platform.h> | ||
14 | #include <linux/of_address.h> | ||
15 | |||
16 | #include <lantiq_soc.h> | ||
17 | |||
18 | #include "../clk.h" | ||
19 | #include "../prom.h" | ||
20 | |||
21 | /* clock control register */ | ||
22 | #define CGU_IFCCR 0x0018 | ||
23 | /* system clock register */ | ||
24 | #define CGU_SYS 0x0010 | ||
25 | /* pci control register */ | ||
26 | #define CGU_PCICR 0x0034 | ||
27 | /* ephy configuration register */ | ||
28 | #define CGU_EPHY 0x10 | ||
29 | /* power control register */ | ||
30 | #define PMU_PWDCR 0x1C | ||
31 | /* power status register */ | ||
32 | #define PMU_PWDSR 0x20 | ||
33 | /* power control register */ | ||
34 | #define PMU_PWDCR1 0x24 | ||
35 | /* power status register */ | ||
36 | #define PMU_PWDSR1 0x28 | ||
37 | /* power control register */ | ||
38 | #define PWDCR(x) ((x) ? (PMU_PWDCR1) : (PMU_PWDCR)) | ||
39 | /* power status register */ | ||
40 | #define PWDSR(x) ((x) ? (PMU_PWDSR1) : (PMU_PWDSR)) | ||
41 | |||
42 | /* clock gates that we can en/disable */ | ||
43 | #define PMU_USB0_P BIT(0) | ||
44 | #define PMU_PCI BIT(4) | ||
45 | #define PMU_DMA BIT(5) | ||
46 | #define PMU_USB0 BIT(6) | ||
47 | #define PMU_ASC0 BIT(7) | ||
48 | #define PMU_EPHY BIT(7) /* ase */ | ||
49 | #define PMU_SPI BIT(8) | ||
50 | #define PMU_DFE BIT(9) | ||
51 | #define PMU_EBU BIT(10) | ||
52 | #define PMU_STP BIT(11) | ||
53 | #define PMU_GPT BIT(12) | ||
54 | #define PMU_AHBS BIT(13) /* vr9 */ | ||
55 | #define PMU_FPI BIT(14) | ||
56 | #define PMU_AHBM BIT(15) | ||
57 | #define PMU_ASC1 BIT(17) | ||
58 | #define PMU_PPE_QSB BIT(18) | ||
59 | #define PMU_PPE_SLL01 BIT(19) | ||
60 | #define PMU_PPE_TC BIT(21) | ||
61 | #define PMU_PPE_EMA BIT(22) | ||
62 | #define PMU_PPE_DPLUM BIT(23) | ||
63 | #define PMU_PPE_DPLUS BIT(24) | ||
64 | #define PMU_USB1_P BIT(26) | ||
65 | #define PMU_USB1 BIT(27) | ||
66 | #define PMU_SWITCH BIT(28) | ||
67 | #define PMU_PPE_TOP BIT(29) | ||
68 | #define PMU_GPHY BIT(30) | ||
69 | #define PMU_PCIE_CLK BIT(31) | ||
70 | |||
71 | #define PMU1_PCIE_PHY BIT(0) | ||
72 | #define PMU1_PCIE_CTL BIT(1) | ||
73 | #define PMU1_PCIE_PDI BIT(4) | ||
74 | #define PMU1_PCIE_MSI BIT(5) | ||
75 | |||
76 | #define pmu_w32(x, y) ltq_w32((x), pmu_membase + (y)) | ||
77 | #define pmu_r32(x) ltq_r32(pmu_membase + (x)) | ||
78 | |||
79 | static void __iomem *pmu_membase; | ||
80 | void __iomem *ltq_cgu_membase; | ||
81 | void __iomem *ltq_ebu_membase; | ||
82 | |||
83 | /* legacy function kept alive to ease clkdev transition */ | ||
84 | void ltq_pmu_enable(unsigned int module) | ||
85 | { | ||
86 | int err = 1000000; | ||
87 | |||
88 | pmu_w32(pmu_r32(PMU_PWDCR) & ~module, PMU_PWDCR); | ||
89 | do {} while (--err && (pmu_r32(PMU_PWDSR) & module)); | ||
90 | |||
91 | if (!err) | ||
92 | panic("activating PMU module failed!"); | ||
93 | } | ||
94 | EXPORT_SYMBOL(ltq_pmu_enable); | ||
95 | |||
96 | /* legacy function kept alive to ease clkdev transition */ | ||
97 | void ltq_pmu_disable(unsigned int module) | ||
98 | { | ||
99 | pmu_w32(pmu_r32(PMU_PWDCR) | module, PMU_PWDCR); | ||
100 | } | ||
101 | EXPORT_SYMBOL(ltq_pmu_disable); | ||
102 | |||
103 | /* enable a hw clock */ | ||
104 | static int cgu_enable(struct clk *clk) | ||
105 | { | ||
106 | ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | clk->bits, CGU_IFCCR); | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | /* disable a hw clock */ | ||
111 | static void cgu_disable(struct clk *clk) | ||
112 | { | ||
113 | ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~clk->bits, CGU_IFCCR); | ||
114 | } | ||
115 | |||
116 | /* enable a clock gate */ | ||
117 | static int pmu_enable(struct clk *clk) | ||
118 | { | ||
119 | int retry = 1000000; | ||
120 | |||
121 | pmu_w32(pmu_r32(PWDCR(clk->module)) & ~clk->bits, | ||
122 | PWDCR(clk->module)); | ||
123 | do {} while (--retry && (pmu_r32(PWDSR(clk->module)) & clk->bits)); | ||
124 | |||
125 | if (!retry) | ||
126 | panic("activating PMU module failed!\n"); | ||
127 | |||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | /* disable a clock gate */ | ||
132 | static void pmu_disable(struct clk *clk) | ||
133 | { | ||
134 | pmu_w32(pmu_r32(PWDCR(clk->module)) | clk->bits, | ||
135 | PWDCR(clk->module)); | ||
136 | } | ||
137 | |||
138 | /* the pci enable helper */ | ||
139 | static int pci_enable(struct clk *clk) | ||
140 | { | ||
141 | unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR); | ||
142 | /* set bus clock speed */ | ||
143 | if (of_machine_is_compatible("lantiq,ar9")) { | ||
144 | ifccr &= ~0x1f00000; | ||
145 | if (clk->rate == CLOCK_33M) | ||
146 | ifccr |= 0xe00000; | ||
147 | else | ||
148 | ifccr |= 0x700000; /* 62.5M */ | ||
149 | } else { | ||
150 | ifccr &= ~0xf00000; | ||
151 | if (clk->rate == CLOCK_33M) | ||
152 | ifccr |= 0x800000; | ||
153 | else | ||
154 | ifccr |= 0x400000; /* 62.5M */ | ||
155 | } | ||
156 | ltq_cgu_w32(ifccr, CGU_IFCCR); | ||
157 | pmu_enable(clk); | ||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | /* enable the external clock as a source */ | ||
162 | static int pci_ext_enable(struct clk *clk) | ||
163 | { | ||
164 | ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~(1 << 16), | ||
165 | CGU_IFCCR); | ||
166 | ltq_cgu_w32((1 << 30), CGU_PCICR); | ||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | /* disable the external clock as a source */ | ||
171 | static void pci_ext_disable(struct clk *clk) | ||
172 | { | ||
173 | ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | (1 << 16), | ||
174 | CGU_IFCCR); | ||
175 | ltq_cgu_w32((1 << 31) | (1 << 30), CGU_PCICR); | ||
176 | } | ||
177 | |||
178 | /* enable a clockout source */ | ||
179 | static int clkout_enable(struct clk *clk) | ||
180 | { | ||
181 | int i; | ||
182 | |||
183 | /* get the correct rate */ | ||
184 | for (i = 0; i < 4; i++) { | ||
185 | if (clk->rates[i] == clk->rate) { | ||
186 | int shift = 14 - (2 * clk->module); | ||
187 | unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR); | ||
188 | |||
189 | ifccr &= ~(3 << shift); | ||
190 | ifccr |= i << shift; | ||
191 | ltq_cgu_w32(ifccr, CGU_IFCCR); | ||
192 | return 0; | ||
193 | } | ||
194 | } | ||
195 | return -1; | ||
196 | } | ||
197 | |||
198 | /* manage the clock gates via PMU */ | ||
199 | static void clkdev_add_pmu(const char *dev, const char *con, | ||
200 | unsigned int module, unsigned int bits) | ||
201 | { | ||
202 | struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); | ||
203 | |||
204 | clk->cl.dev_id = dev; | ||
205 | clk->cl.con_id = con; | ||
206 | clk->cl.clk = clk; | ||
207 | clk->enable = pmu_enable; | ||
208 | clk->disable = pmu_disable; | ||
209 | clk->module = module; | ||
210 | clk->bits = bits; | ||
211 | clkdev_add(&clk->cl); | ||
212 | } | ||
213 | |||
214 | /* manage the clock generator */ | ||
215 | static void clkdev_add_cgu(const char *dev, const char *con, | ||
216 | unsigned int bits) | ||
217 | { | ||
218 | struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); | ||
219 | |||
220 | clk->cl.dev_id = dev; | ||
221 | clk->cl.con_id = con; | ||
222 | clk->cl.clk = clk; | ||
223 | clk->enable = cgu_enable; | ||
224 | clk->disable = cgu_disable; | ||
225 | clk->bits = bits; | ||
226 | clkdev_add(&clk->cl); | ||
227 | } | ||
228 | |||
229 | /* pci needs its own enable function as the setup is a bit more complex */ | ||
230 | static unsigned long valid_pci_rates[] = {CLOCK_33M, CLOCK_62_5M, 0}; | ||
231 | |||
232 | static void clkdev_add_pci(void) | ||
233 | { | ||
234 | struct clk *clk = kzalloc(sizeof(struct clk), GFP_KERNEL); | ||
235 | struct clk *clk_ext = kzalloc(sizeof(struct clk), GFP_KERNEL); | ||
236 | |||
237 | /* main pci clock */ | ||
238 | clk->cl.dev_id = "17000000.pci"; | ||
239 | clk->cl.con_id = NULL; | ||
240 | clk->cl.clk = clk; | ||
241 | clk->rate = CLOCK_33M; | ||
242 | clk->rates = valid_pci_rates; | ||
243 | clk->enable = pci_enable; | ||
244 | clk->disable = pmu_disable; | ||
245 | clk->module = 0; | ||
246 | clk->bits = PMU_PCI; | ||
247 | clkdev_add(&clk->cl); | ||
248 | |||
249 | /* use internal/external bus clock */ | ||
250 | clk_ext->cl.dev_id = "17000000.pci"; | ||
251 | clk_ext->cl.con_id = "external"; | ||
252 | clk_ext->cl.clk = clk_ext; | ||
253 | clk_ext->enable = pci_ext_enable; | ||
254 | clk_ext->disable = pci_ext_disable; | ||
255 | clkdev_add(&clk_ext->cl); | ||
256 | } | ||
257 | |||
258 | /* xway socs can generate clocks on gpio pins */ | ||
259 | static unsigned long valid_clkout_rates[4][5] = { | ||
260 | {CLOCK_32_768K, CLOCK_1_536M, CLOCK_2_5M, CLOCK_12M, 0}, | ||
261 | {CLOCK_40M, CLOCK_12M, CLOCK_24M, CLOCK_48M, 0}, | ||
262 | {CLOCK_25M, CLOCK_40M, CLOCK_30M, CLOCK_60M, 0}, | ||
263 | {CLOCK_12M, CLOCK_50M, CLOCK_32_768K, CLOCK_25M, 0}, | ||
264 | }; | ||
265 | |||
266 | static void clkdev_add_clkout(void) | ||
267 | { | ||
268 | int i; | ||
269 | |||
270 | for (i = 0; i < 4; i++) { | ||
271 | struct clk *clk; | ||
272 | char *name; | ||
273 | |||
274 | name = kzalloc(sizeof("clkout0"), GFP_KERNEL); | ||
275 | sprintf(name, "clkout%d", i); | ||
276 | |||
277 | clk = kzalloc(sizeof(struct clk), GFP_KERNEL); | ||
278 | clk->cl.dev_id = "1f103000.cgu"; | ||
279 | clk->cl.con_id = name; | ||
280 | clk->cl.clk = clk; | ||
281 | clk->rate = 0; | ||
282 | clk->rates = valid_clkout_rates[i]; | ||
283 | clk->enable = clkout_enable; | ||
284 | clk->module = i; | ||
285 | clkdev_add(&clk->cl); | ||
286 | } | ||
287 | } | ||
288 | |||
289 | /* bring up all register ranges that we need for basic system control */ | ||
290 | void __init ltq_soc_init(void) | ||
291 | { | ||
292 | struct resource res_pmu, res_cgu, res_ebu; | ||
293 | struct device_node *np_pmu = | ||
294 | of_find_compatible_node(NULL, NULL, "lantiq,pmu-xway"); | ||
295 | struct device_node *np_cgu = | ||
296 | of_find_compatible_node(NULL, NULL, "lantiq,cgu-xway"); | ||
297 | struct device_node *np_ebu = | ||
298 | of_find_compatible_node(NULL, NULL, "lantiq,ebu-xway"); | ||
299 | |||
300 | /* check if all the core register ranges are available */ | ||
301 | if (!np_pmu || !np_cgu || !np_ebu) | ||
302 | panic("Failed to load core nodess from devicetree"); | ||
303 | |||
304 | if (of_address_to_resource(np_pmu, 0, &res_pmu) || | ||
305 | of_address_to_resource(np_cgu, 0, &res_cgu) || | ||
306 | of_address_to_resource(np_ebu, 0, &res_ebu)) | ||
307 | panic("Failed to get core resources"); | ||
308 | |||
309 | if ((request_mem_region(res_pmu.start, resource_size(&res_pmu), | ||
310 | res_pmu.name) < 0) || | ||
311 | (request_mem_region(res_cgu.start, resource_size(&res_cgu), | ||
312 | res_cgu.name) < 0) || | ||
313 | (request_mem_region(res_ebu.start, resource_size(&res_ebu), | ||
314 | res_ebu.name) < 0)) | ||
315 | pr_err("Failed to request core reources"); | ||
316 | |||
317 | pmu_membase = ioremap_nocache(res_pmu.start, resource_size(&res_pmu)); | ||
318 | ltq_cgu_membase = ioremap_nocache(res_cgu.start, | ||
319 | resource_size(&res_cgu)); | ||
320 | ltq_ebu_membase = ioremap_nocache(res_ebu.start, | ||
321 | resource_size(&res_ebu)); | ||
322 | if (!pmu_membase || !ltq_cgu_membase || !ltq_ebu_membase) | ||
323 | panic("Failed to remap core resources"); | ||
324 | |||
325 | /* make sure to unprotect the memory region where flash is located */ | ||
326 | ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_BUSCON0) & ~EBU_WRDIS, LTQ_EBU_BUSCON0); | ||
327 | |||
328 | /* add our generic xway clocks */ | ||
329 | clkdev_add_pmu("10000000.fpi", NULL, 0, PMU_FPI); | ||
330 | clkdev_add_pmu("1e100400.serial", NULL, 0, PMU_ASC0); | ||
331 | clkdev_add_pmu("1e100a00.gptu", NULL, 0, PMU_GPT); | ||
332 | clkdev_add_pmu("1e100bb0.stp", NULL, 0, PMU_STP); | ||
333 | clkdev_add_pmu("1e104100.dma", NULL, 0, PMU_DMA); | ||
334 | clkdev_add_pmu("1e100800.spi", NULL, 0, PMU_SPI); | ||
335 | clkdev_add_pmu("1e105300.ebu", NULL, 0, PMU_EBU); | ||
336 | clkdev_add_clkout(); | ||
337 | |||
338 | /* add the soc dependent clocks */ | ||
339 | if (!of_machine_is_compatible("lantiq,vr9")) | ||
340 | clkdev_add_pmu("1e180000.etop", NULL, 0, PMU_PPE); | ||
341 | |||
342 | if (!of_machine_is_compatible("lantiq,ase")) { | ||
343 | clkdev_add_pmu("1e100c00.serial", NULL, 0, PMU_ASC1); | ||
344 | clkdev_add_pci(); | ||
345 | } | ||
346 | |||
347 | if (of_machine_is_compatible("lantiq,ase")) { | ||
348 | if (ltq_cgu_r32(CGU_SYS) & (1 << 5)) | ||
349 | clkdev_add_static(CLOCK_266M, CLOCK_133M, CLOCK_133M); | ||
350 | else | ||
351 | clkdev_add_static(CLOCK_133M, CLOCK_133M, CLOCK_133M); | ||
352 | clkdev_add_cgu("1e180000.etop", "ephycgu", CGU_EPHY), | ||
353 | clkdev_add_pmu("1e180000.etop", "ephy", 0, PMU_EPHY); | ||
354 | } else if (of_machine_is_compatible("lantiq,vr9")) { | ||
355 | clkdev_add_static(ltq_vr9_cpu_hz(), ltq_vr9_fpi_hz(), | ||
356 | ltq_vr9_fpi_hz()); | ||
357 | clkdev_add_pmu("1d900000.pcie", "phy", 1, PMU1_PCIE_PHY); | ||
358 | clkdev_add_pmu("1d900000.pcie", "bus", 0, PMU_PCIE_CLK); | ||
359 | clkdev_add_pmu("1d900000.pcie", "msi", 1, PMU1_PCIE_MSI); | ||
360 | clkdev_add_pmu("1d900000.pcie", "pdi", 1, PMU1_PCIE_PDI); | ||
361 | clkdev_add_pmu("1d900000.pcie", "ctl", 1, PMU1_PCIE_CTL); | ||
362 | clkdev_add_pmu("1d900000.pcie", "ahb", 0, PMU_AHBM | PMU_AHBS); | ||
363 | } else if (of_machine_is_compatible("lantiq,ar9")) { | ||
364 | clkdev_add_static(ltq_ar9_cpu_hz(), ltq_ar9_fpi_hz(), | ||
365 | ltq_ar9_fpi_hz()); | ||
366 | clkdev_add_pmu("1e180000.etop", "switch", 0, PMU_SWITCH); | ||
367 | } else { | ||
368 | clkdev_add_static(ltq_danube_cpu_hz(), ltq_danube_fpi_hz(), | ||
369 | ltq_danube_fpi_hz()); | ||
370 | } | ||
371 | } | ||
diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c index 47037ec5589b..44e69e7a4519 100644 --- a/arch/mips/mm/c-octeon.c +++ b/arch/mips/mm/c-octeon.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <asm/page.h> | 21 | #include <asm/page.h> |
22 | #include <asm/pgtable.h> | 22 | #include <asm/pgtable.h> |
23 | #include <asm/r4kcache.h> | 23 | #include <asm/r4kcache.h> |
24 | #include <asm/traps.h> | ||
24 | #include <asm/mmu_context.h> | 25 | #include <asm/mmu_context.h> |
25 | #include <asm/war.h> | 26 | #include <asm/war.h> |
26 | 27 | ||
@@ -248,6 +249,11 @@ static void __cpuinit probe_octeon(void) | |||
248 | } | 249 | } |
249 | } | 250 | } |
250 | 251 | ||
252 | static void __cpuinit octeon_cache_error_setup(void) | ||
253 | { | ||
254 | extern char except_vec2_octeon; | ||
255 | set_handler(0x100, &except_vec2_octeon, 0x80); | ||
256 | } | ||
251 | 257 | ||
252 | /** | 258 | /** |
253 | * Setup the Octeon cache flush routines | 259 | * Setup the Octeon cache flush routines |
@@ -255,12 +261,6 @@ static void __cpuinit probe_octeon(void) | |||
255 | */ | 261 | */ |
256 | void __cpuinit octeon_cache_init(void) | 262 | void __cpuinit octeon_cache_init(void) |
257 | { | 263 | { |
258 | extern unsigned long ebase; | ||
259 | extern char except_vec2_octeon; | ||
260 | |||
261 | memcpy((void *)(ebase + 0x100), &except_vec2_octeon, 0x80); | ||
262 | octeon_flush_cache_sigtramp(ebase + 0x100); | ||
263 | |||
264 | probe_octeon(); | 264 | probe_octeon(); |
265 | 265 | ||
266 | shm_align_mask = PAGE_SIZE - 1; | 266 | shm_align_mask = PAGE_SIZE - 1; |
@@ -280,6 +280,8 @@ void __cpuinit octeon_cache_init(void) | |||
280 | 280 | ||
281 | build_clear_page(); | 281 | build_clear_page(); |
282 | build_copy_page(); | 282 | build_copy_page(); |
283 | |||
284 | board_cache_error_setup = octeon_cache_error_setup; | ||
283 | } | 285 | } |
284 | 286 | ||
285 | /** | 287 | /** |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index bda8eb26ece7..5109be96d98d 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <asm/mmu_context.h> | 32 | #include <asm/mmu_context.h> |
33 | #include <asm/war.h> | 33 | #include <asm/war.h> |
34 | #include <asm/cacheflush.h> /* for run_uncached() */ | 34 | #include <asm/cacheflush.h> /* for run_uncached() */ |
35 | 35 | #include <asm/traps.h> | |
36 | 36 | ||
37 | /* | 37 | /* |
38 | * Special Variant of smp_call_function for use by cache functions: | 38 | * Special Variant of smp_call_function for use by cache functions: |
@@ -1385,10 +1385,8 @@ static int __init setcoherentio(char *str) | |||
1385 | __setup("coherentio", setcoherentio); | 1385 | __setup("coherentio", setcoherentio); |
1386 | #endif | 1386 | #endif |
1387 | 1387 | ||
1388 | void __cpuinit r4k_cache_init(void) | 1388 | static void __cpuinit r4k_cache_error_setup(void) |
1389 | { | 1389 | { |
1390 | extern void build_clear_page(void); | ||
1391 | extern void build_copy_page(void); | ||
1392 | extern char __weak except_vec2_generic; | 1390 | extern char __weak except_vec2_generic; |
1393 | extern char __weak except_vec2_sb1; | 1391 | extern char __weak except_vec2_sb1; |
1394 | struct cpuinfo_mips *c = ¤t_cpu_data; | 1392 | struct cpuinfo_mips *c = ¤t_cpu_data; |
@@ -1403,6 +1401,13 @@ void __cpuinit r4k_cache_init(void) | |||
1403 | set_uncached_handler(0x100, &except_vec2_generic, 0x80); | 1401 | set_uncached_handler(0x100, &except_vec2_generic, 0x80); |
1404 | break; | 1402 | break; |
1405 | } | 1403 | } |
1404 | } | ||
1405 | |||
1406 | void __cpuinit r4k_cache_init(void) | ||
1407 | { | ||
1408 | extern void build_clear_page(void); | ||
1409 | extern void build_copy_page(void); | ||
1410 | struct cpuinfo_mips *c = ¤t_cpu_data; | ||
1406 | 1411 | ||
1407 | probe_pcache(); | 1412 | probe_pcache(); |
1408 | setup_scache(); | 1413 | setup_scache(); |
@@ -1465,4 +1470,5 @@ void __cpuinit r4k_cache_init(void) | |||
1465 | local_r4k___flush_cache_all(NULL); | 1470 | local_r4k___flush_cache_all(NULL); |
1466 | #endif | 1471 | #endif |
1467 | coherency_setup(); | 1472 | coherency_setup(); |
1473 | board_cache_error_setup = r4k_cache_error_setup; | ||
1468 | } | 1474 | } |
diff --git a/arch/mips/oprofile/Makefile b/arch/mips/oprofile/Makefile index 29f2f13eb31c..1208c280f77d 100644 --- a/arch/mips/oprofile/Makefile +++ b/arch/mips/oprofile/Makefile | |||
@@ -1,5 +1,3 @@ | |||
1 | ccflags-y := -Werror | ||
2 | |||
3 | obj-$(CONFIG_OPROFILE) += oprofile.o | 1 | obj-$(CONFIG_OPROFILE) += oprofile.o |
4 | 2 | ||
5 | DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ | 3 | DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ |
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c index 54759f1669d3..baba3bcaa3c2 100644 --- a/arch/mips/oprofile/op_model_mipsxx.c +++ b/arch/mips/oprofile/op_model_mipsxx.c | |||
@@ -298,6 +298,11 @@ static void reset_counters(void *arg) | |||
298 | } | 298 | } |
299 | } | 299 | } |
300 | 300 | ||
301 | static irqreturn_t mipsxx_perfcount_int(int irq, void *dev_id) | ||
302 | { | ||
303 | return mipsxx_perfcount_handler(); | ||
304 | } | ||
305 | |||
301 | static int __init mipsxx_init(void) | 306 | static int __init mipsxx_init(void) |
302 | { | 307 | { |
303 | int counters; | 308 | int counters; |
@@ -374,6 +379,10 @@ static int __init mipsxx_init(void) | |||
374 | save_perf_irq = perf_irq; | 379 | save_perf_irq = perf_irq; |
375 | perf_irq = mipsxx_perfcount_handler; | 380 | perf_irq = mipsxx_perfcount_handler; |
376 | 381 | ||
382 | if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq)) | ||
383 | return request_irq(cp0_perfcount_irq, mipsxx_perfcount_int, | ||
384 | 0, "Perfcounter", save_perf_irq); | ||
385 | |||
377 | return 0; | 386 | return 0; |
378 | } | 387 | } |
379 | 388 | ||
@@ -381,6 +390,9 @@ static void mipsxx_exit(void) | |||
381 | { | 390 | { |
382 | int counters = op_model_mipsxx_ops.num_counters; | 391 | int counters = op_model_mipsxx_ops.num_counters; |
383 | 392 | ||
393 | if ((cp0_perfcount_irq >= 0) && (cp0_compare_irq != cp0_perfcount_irq)) | ||
394 | free_irq(cp0_perfcount_irq, save_perf_irq); | ||
395 | |||
384 | counters = counters_per_cpu_to_total(counters); | 396 | counters = counters_per_cpu_to_total(counters); |
385 | on_each_cpu(reset_counters, (void *)(long)counters, 1); | 397 | on_each_cpu(reset_counters, (void *)(long)counters, 1); |
386 | 398 | ||
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile index c3ac4b086eb2..c703f43a9914 100644 --- a/arch/mips/pci/Makefile +++ b/arch/mips/pci/Makefile | |||
@@ -19,7 +19,8 @@ obj-$(CONFIG_BCM47XX) += pci-bcm47xx.o | |||
19 | obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ | 19 | obj-$(CONFIG_BCM63XX) += pci-bcm63xx.o fixup-bcm63xx.o \ |
20 | ops-bcm63xx.o | 20 | ops-bcm63xx.o |
21 | obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o | 21 | obj-$(CONFIG_MIPS_ALCHEMY) += pci-alchemy.o |
22 | obj-$(CONFIG_SOC_AR724X) += pci-ath724x.o | 22 | obj-$(CONFIG_SOC_AR71XX) += pci-ar71xx.o |
23 | obj-$(CONFIG_PCI_AR724X) += pci-ar724x.o | ||
23 | 24 | ||
24 | # | 25 | # |
25 | # These are still pretty much in the old state, watch, go blind. | 26 | # These are still pretty much in the old state, watch, go blind. |
@@ -41,7 +42,8 @@ obj-$(CONFIG_SIBYTE_SB1250) += fixup-sb1250.o pci-sb1250.o | |||
41 | obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o | 42 | obj-$(CONFIG_SIBYTE_BCM112X) += fixup-sb1250.o pci-sb1250.o |
42 | obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o | 43 | obj-$(CONFIG_SIBYTE_BCM1x80) += pci-bcm1480.o pci-bcm1480ht.o |
43 | obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o | 44 | obj-$(CONFIG_SNI_RM) += fixup-sni.o ops-sni.o |
44 | obj-$(CONFIG_SOC_XWAY) += pci-lantiq.o ops-lantiq.o | 45 | obj-$(CONFIG_LANTIQ) += fixup-lantiq.o |
46 | obj-$(CONFIG_PCI_LANTIQ) += pci-lantiq.o ops-lantiq.o | ||
45 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o | 47 | obj-$(CONFIG_TANBAC_TB0219) += fixup-tb0219.o |
46 | obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o | 48 | obj-$(CONFIG_TANBAC_TB0226) += fixup-tb0226.o |
47 | obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o | 49 | obj-$(CONFIG_TANBAC_TB0287) += fixup-tb0287.o |
diff --git a/arch/mips/pci/fixup-lantiq.c b/arch/mips/pci/fixup-lantiq.c new file mode 100644 index 000000000000..6c829df28dc7 --- /dev/null +++ b/arch/mips/pci/fixup-lantiq.c | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/of_irq.h> | ||
10 | #include <linux/of_pci.h> | ||
11 | |||
12 | int (*ltq_pci_plat_arch_init)(struct pci_dev *dev) = NULL; | ||
13 | int (*ltq_pci_plat_dev_init)(struct pci_dev *dev) = NULL; | ||
14 | |||
15 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
16 | { | ||
17 | if (ltq_pci_plat_arch_init) | ||
18 | return ltq_pci_plat_arch_init(dev); | ||
19 | |||
20 | if (ltq_pci_plat_dev_init) | ||
21 | return ltq_pci_plat_dev_init(dev); | ||
22 | |||
23 | return 0; | ||
24 | } | ||
25 | |||
26 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
27 | { | ||
28 | struct of_irq dev_irq; | ||
29 | int irq; | ||
30 | |||
31 | if (of_irq_map_pci(dev, &dev_irq)) { | ||
32 | dev_err(&dev->dev, "trying to map irq for unknown slot:%d pin:%d\n", | ||
33 | slot, pin); | ||
34 | return 0; | ||
35 | } | ||
36 | irq = irq_create_of_mapping(dev_irq.controller, dev_irq.specifier, | ||
37 | dev_irq.size); | ||
38 | dev_info(&dev->dev, "SLOT:%d PIN:%d IRQ:%d\n", slot, pin, irq); | ||
39 | return irq; | ||
40 | } | ||
diff --git a/arch/mips/pci/pci-ar71xx.c b/arch/mips/pci/pci-ar71xx.c new file mode 100644 index 000000000000..1552522b8718 --- /dev/null +++ b/arch/mips/pci/pci-ar71xx.c | |||
@@ -0,0 +1,375 @@ | |||
1 | /* | ||
2 | * Atheros AR71xx PCI host controller driver | ||
3 | * | ||
4 | * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org> | ||
6 | * | ||
7 | * Parts of this file are based on Atheros' 2.6.15 BSP | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License version 2 as published | ||
11 | * by the Free Software Foundation. | ||
12 | */ | ||
13 | |||
14 | #include <linux/resource.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/bitops.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/pci_regs.h> | ||
20 | #include <linux/interrupt.h> | ||
21 | |||
22 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
23 | #include <asm/mach-ath79/ath79.h> | ||
24 | #include <asm/mach-ath79/pci.h> | ||
25 | |||
26 | #define AR71XX_PCI_MEM_BASE 0x10000000 | ||
27 | #define AR71XX_PCI_MEM_SIZE 0x08000000 | ||
28 | |||
29 | #define AR71XX_PCI_WIN0_OFFS 0x10000000 | ||
30 | #define AR71XX_PCI_WIN1_OFFS 0x11000000 | ||
31 | #define AR71XX_PCI_WIN2_OFFS 0x12000000 | ||
32 | #define AR71XX_PCI_WIN3_OFFS 0x13000000 | ||
33 | #define AR71XX_PCI_WIN4_OFFS 0x14000000 | ||
34 | #define AR71XX_PCI_WIN5_OFFS 0x15000000 | ||
35 | #define AR71XX_PCI_WIN6_OFFS 0x16000000 | ||
36 | #define AR71XX_PCI_WIN7_OFFS 0x07000000 | ||
37 | |||
38 | #define AR71XX_PCI_CFG_BASE \ | ||
39 | (AR71XX_PCI_MEM_BASE + AR71XX_PCI_WIN7_OFFS + 0x10000) | ||
40 | #define AR71XX_PCI_CFG_SIZE 0x100 | ||
41 | |||
42 | #define AR71XX_PCI_REG_CRP_AD_CBE 0x00 | ||
43 | #define AR71XX_PCI_REG_CRP_WRDATA 0x04 | ||
44 | #define AR71XX_PCI_REG_CRP_RDDATA 0x08 | ||
45 | #define AR71XX_PCI_REG_CFG_AD 0x0c | ||
46 | #define AR71XX_PCI_REG_CFG_CBE 0x10 | ||
47 | #define AR71XX_PCI_REG_CFG_WRDATA 0x14 | ||
48 | #define AR71XX_PCI_REG_CFG_RDDATA 0x18 | ||
49 | #define AR71XX_PCI_REG_PCI_ERR 0x1c | ||
50 | #define AR71XX_PCI_REG_PCI_ERR_ADDR 0x20 | ||
51 | #define AR71XX_PCI_REG_AHB_ERR 0x24 | ||
52 | #define AR71XX_PCI_REG_AHB_ERR_ADDR 0x28 | ||
53 | |||
54 | #define AR71XX_PCI_CRP_CMD_WRITE 0x00010000 | ||
55 | #define AR71XX_PCI_CRP_CMD_READ 0x00000000 | ||
56 | #define AR71XX_PCI_CFG_CMD_READ 0x0000000a | ||
57 | #define AR71XX_PCI_CFG_CMD_WRITE 0x0000000b | ||
58 | |||
59 | #define AR71XX_PCI_INT_CORE BIT(4) | ||
60 | #define AR71XX_PCI_INT_DEV2 BIT(2) | ||
61 | #define AR71XX_PCI_INT_DEV1 BIT(1) | ||
62 | #define AR71XX_PCI_INT_DEV0 BIT(0) | ||
63 | |||
64 | #define AR71XX_PCI_IRQ_COUNT 5 | ||
65 | |||
66 | static DEFINE_SPINLOCK(ar71xx_pci_lock); | ||
67 | static void __iomem *ar71xx_pcicfg_base; | ||
68 | |||
69 | /* Byte lane enable bits */ | ||
70 | static const u8 ar71xx_pci_ble_table[4][4] = { | ||
71 | {0x0, 0xf, 0xf, 0xf}, | ||
72 | {0xe, 0xd, 0xb, 0x7}, | ||
73 | {0xc, 0xf, 0x3, 0xf}, | ||
74 | {0xf, 0xf, 0xf, 0xf}, | ||
75 | }; | ||
76 | |||
77 | static const u32 ar71xx_pci_read_mask[8] = { | ||
78 | 0, 0xff, 0xffff, 0, 0xffffffff, 0, 0, 0 | ||
79 | }; | ||
80 | |||
81 | static inline u32 ar71xx_pci_get_ble(int where, int size, int local) | ||
82 | { | ||
83 | u32 t; | ||
84 | |||
85 | t = ar71xx_pci_ble_table[size & 3][where & 3]; | ||
86 | BUG_ON(t == 0xf); | ||
87 | t <<= (local) ? 20 : 4; | ||
88 | |||
89 | return t; | ||
90 | } | ||
91 | |||
92 | static inline u32 ar71xx_pci_bus_addr(struct pci_bus *bus, unsigned int devfn, | ||
93 | int where) | ||
94 | { | ||
95 | u32 ret; | ||
96 | |||
97 | if (!bus->number) { | ||
98 | /* type 0 */ | ||
99 | ret = (1 << PCI_SLOT(devfn)) | (PCI_FUNC(devfn) << 8) | | ||
100 | (where & ~3); | ||
101 | } else { | ||
102 | /* type 1 */ | ||
103 | ret = (bus->number << 16) | (PCI_SLOT(devfn) << 11) | | ||
104 | (PCI_FUNC(devfn) << 8) | (where & ~3) | 1; | ||
105 | } | ||
106 | |||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | static int ar71xx_pci_check_error(int quiet) | ||
111 | { | ||
112 | void __iomem *base = ar71xx_pcicfg_base; | ||
113 | u32 pci_err; | ||
114 | u32 ahb_err; | ||
115 | |||
116 | pci_err = __raw_readl(base + AR71XX_PCI_REG_PCI_ERR) & 3; | ||
117 | if (pci_err) { | ||
118 | if (!quiet) { | ||
119 | u32 addr; | ||
120 | |||
121 | addr = __raw_readl(base + AR71XX_PCI_REG_PCI_ERR_ADDR); | ||
122 | pr_crit("ar71xx: %s bus error %d at addr 0x%x\n", | ||
123 | "PCI", pci_err, addr); | ||
124 | } | ||
125 | |||
126 | /* clear PCI error status */ | ||
127 | __raw_writel(pci_err, base + AR71XX_PCI_REG_PCI_ERR); | ||
128 | } | ||
129 | |||
130 | ahb_err = __raw_readl(base + AR71XX_PCI_REG_AHB_ERR) & 1; | ||
131 | if (ahb_err) { | ||
132 | if (!quiet) { | ||
133 | u32 addr; | ||
134 | |||
135 | addr = __raw_readl(base + AR71XX_PCI_REG_AHB_ERR_ADDR); | ||
136 | pr_crit("ar71xx: %s bus error %d at addr 0x%x\n", | ||
137 | "AHB", ahb_err, addr); | ||
138 | } | ||
139 | |||
140 | /* clear AHB error status */ | ||
141 | __raw_writel(ahb_err, base + AR71XX_PCI_REG_AHB_ERR); | ||
142 | } | ||
143 | |||
144 | return !!(ahb_err | pci_err); | ||
145 | } | ||
146 | |||
147 | static inline void ar71xx_pci_local_write(int where, int size, u32 value) | ||
148 | { | ||
149 | void __iomem *base = ar71xx_pcicfg_base; | ||
150 | u32 ad_cbe; | ||
151 | |||
152 | value = value << (8 * (where & 3)); | ||
153 | |||
154 | ad_cbe = AR71XX_PCI_CRP_CMD_WRITE | (where & ~3); | ||
155 | ad_cbe |= ar71xx_pci_get_ble(where, size, 1); | ||
156 | |||
157 | __raw_writel(ad_cbe, base + AR71XX_PCI_REG_CRP_AD_CBE); | ||
158 | __raw_writel(value, base + AR71XX_PCI_REG_CRP_WRDATA); | ||
159 | } | ||
160 | |||
161 | static inline int ar71xx_pci_set_cfgaddr(struct pci_bus *bus, | ||
162 | unsigned int devfn, | ||
163 | int where, int size, u32 cmd) | ||
164 | { | ||
165 | void __iomem *base = ar71xx_pcicfg_base; | ||
166 | u32 addr; | ||
167 | |||
168 | addr = ar71xx_pci_bus_addr(bus, devfn, where); | ||
169 | |||
170 | __raw_writel(addr, base + AR71XX_PCI_REG_CFG_AD); | ||
171 | __raw_writel(cmd | ar71xx_pci_get_ble(where, size, 0), | ||
172 | base + AR71XX_PCI_REG_CFG_CBE); | ||
173 | |||
174 | return ar71xx_pci_check_error(1); | ||
175 | } | ||
176 | |||
177 | static int ar71xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, | ||
178 | int where, int size, u32 *value) | ||
179 | { | ||
180 | void __iomem *base = ar71xx_pcicfg_base; | ||
181 | unsigned long flags; | ||
182 | u32 data; | ||
183 | int err; | ||
184 | int ret; | ||
185 | |||
186 | ret = PCIBIOS_SUCCESSFUL; | ||
187 | data = ~0; | ||
188 | |||
189 | spin_lock_irqsave(&ar71xx_pci_lock, flags); | ||
190 | |||
191 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, | ||
192 | AR71XX_PCI_CFG_CMD_READ); | ||
193 | if (err) | ||
194 | ret = PCIBIOS_DEVICE_NOT_FOUND; | ||
195 | else | ||
196 | data = __raw_readl(base + AR71XX_PCI_REG_CFG_RDDATA); | ||
197 | |||
198 | spin_unlock_irqrestore(&ar71xx_pci_lock, flags); | ||
199 | |||
200 | *value = (data >> (8 * (where & 3))) & ar71xx_pci_read_mask[size & 7]; | ||
201 | |||
202 | return ret; | ||
203 | } | ||
204 | |||
205 | static int ar71xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, | ||
206 | int where, int size, u32 value) | ||
207 | { | ||
208 | void __iomem *base = ar71xx_pcicfg_base; | ||
209 | unsigned long flags; | ||
210 | int err; | ||
211 | int ret; | ||
212 | |||
213 | value = value << (8 * (where & 3)); | ||
214 | ret = PCIBIOS_SUCCESSFUL; | ||
215 | |||
216 | spin_lock_irqsave(&ar71xx_pci_lock, flags); | ||
217 | |||
218 | err = ar71xx_pci_set_cfgaddr(bus, devfn, where, size, | ||
219 | AR71XX_PCI_CFG_CMD_WRITE); | ||
220 | if (err) | ||
221 | ret = PCIBIOS_DEVICE_NOT_FOUND; | ||
222 | else | ||
223 | __raw_writel(value, base + AR71XX_PCI_REG_CFG_WRDATA); | ||
224 | |||
225 | spin_unlock_irqrestore(&ar71xx_pci_lock, flags); | ||
226 | |||
227 | return ret; | ||
228 | } | ||
229 | |||
230 | static struct pci_ops ar71xx_pci_ops = { | ||
231 | .read = ar71xx_pci_read_config, | ||
232 | .write = ar71xx_pci_write_config, | ||
233 | }; | ||
234 | |||
235 | static struct resource ar71xx_pci_io_resource = { | ||
236 | .name = "PCI IO space", | ||
237 | .start = 0, | ||
238 | .end = 0, | ||
239 | .flags = IORESOURCE_IO, | ||
240 | }; | ||
241 | |||
242 | static struct resource ar71xx_pci_mem_resource = { | ||
243 | .name = "PCI memory space", | ||
244 | .start = AR71XX_PCI_MEM_BASE, | ||
245 | .end = AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE - 1, | ||
246 | .flags = IORESOURCE_MEM | ||
247 | }; | ||
248 | |||
249 | static struct pci_controller ar71xx_pci_controller = { | ||
250 | .pci_ops = &ar71xx_pci_ops, | ||
251 | .mem_resource = &ar71xx_pci_mem_resource, | ||
252 | .io_resource = &ar71xx_pci_io_resource, | ||
253 | }; | ||
254 | |||
255 | static void ar71xx_pci_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
256 | { | ||
257 | void __iomem *base = ath79_reset_base; | ||
258 | u32 pending; | ||
259 | |||
260 | pending = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_STATUS) & | ||
261 | __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); | ||
262 | |||
263 | if (pending & AR71XX_PCI_INT_DEV0) | ||
264 | generic_handle_irq(ATH79_PCI_IRQ(0)); | ||
265 | |||
266 | else if (pending & AR71XX_PCI_INT_DEV1) | ||
267 | generic_handle_irq(ATH79_PCI_IRQ(1)); | ||
268 | |||
269 | else if (pending & AR71XX_PCI_INT_DEV2) | ||
270 | generic_handle_irq(ATH79_PCI_IRQ(2)); | ||
271 | |||
272 | else if (pending & AR71XX_PCI_INT_CORE) | ||
273 | generic_handle_irq(ATH79_PCI_IRQ(4)); | ||
274 | |||
275 | else | ||
276 | spurious_interrupt(); | ||
277 | } | ||
278 | |||
279 | static void ar71xx_pci_irq_unmask(struct irq_data *d) | ||
280 | { | ||
281 | unsigned int irq = d->irq - ATH79_PCI_IRQ_BASE; | ||
282 | void __iomem *base = ath79_reset_base; | ||
283 | u32 t; | ||
284 | |||
285 | t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); | ||
286 | __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); | ||
287 | |||
288 | /* flush write */ | ||
289 | __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); | ||
290 | } | ||
291 | |||
292 | static void ar71xx_pci_irq_mask(struct irq_data *d) | ||
293 | { | ||
294 | unsigned int irq = d->irq - ATH79_PCI_IRQ_BASE; | ||
295 | void __iomem *base = ath79_reset_base; | ||
296 | u32 t; | ||
297 | |||
298 | t = __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); | ||
299 | __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_PCI_INT_ENABLE); | ||
300 | |||
301 | /* flush write */ | ||
302 | __raw_readl(base + AR71XX_RESET_REG_PCI_INT_ENABLE); | ||
303 | } | ||
304 | |||
305 | static struct irq_chip ar71xx_pci_irq_chip = { | ||
306 | .name = "AR71XX PCI", | ||
307 | .irq_mask = ar71xx_pci_irq_mask, | ||
308 | .irq_unmask = ar71xx_pci_irq_unmask, | ||
309 | .irq_mask_ack = ar71xx_pci_irq_mask, | ||
310 | }; | ||
311 | |||
312 | static __init void ar71xx_pci_irq_init(void) | ||
313 | { | ||
314 | void __iomem *base = ath79_reset_base; | ||
315 | int i; | ||
316 | |||
317 | __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_ENABLE); | ||
318 | __raw_writel(0, base + AR71XX_RESET_REG_PCI_INT_STATUS); | ||
319 | |||
320 | BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR71XX_PCI_IRQ_COUNT); | ||
321 | |||
322 | for (i = ATH79_PCI_IRQ_BASE; | ||
323 | i < ATH79_PCI_IRQ_BASE + AR71XX_PCI_IRQ_COUNT; i++) | ||
324 | irq_set_chip_and_handler(i, &ar71xx_pci_irq_chip, | ||
325 | handle_level_irq); | ||
326 | |||
327 | irq_set_chained_handler(ATH79_CPU_IRQ_IP2, ar71xx_pci_irq_handler); | ||
328 | } | ||
329 | |||
330 | static __init void ar71xx_pci_reset(void) | ||
331 | { | ||
332 | void __iomem *ddr_base = ath79_ddr_base; | ||
333 | |||
334 | ath79_device_reset_set(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE); | ||
335 | mdelay(100); | ||
336 | |||
337 | ath79_device_reset_clear(AR71XX_RESET_PCI_BUS | AR71XX_RESET_PCI_CORE); | ||
338 | mdelay(100); | ||
339 | |||
340 | __raw_writel(AR71XX_PCI_WIN0_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN0); | ||
341 | __raw_writel(AR71XX_PCI_WIN1_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN1); | ||
342 | __raw_writel(AR71XX_PCI_WIN2_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN2); | ||
343 | __raw_writel(AR71XX_PCI_WIN3_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN3); | ||
344 | __raw_writel(AR71XX_PCI_WIN4_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN4); | ||
345 | __raw_writel(AR71XX_PCI_WIN5_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN5); | ||
346 | __raw_writel(AR71XX_PCI_WIN6_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN6); | ||
347 | __raw_writel(AR71XX_PCI_WIN7_OFFS, ddr_base + AR71XX_DDR_REG_PCI_WIN7); | ||
348 | |||
349 | mdelay(100); | ||
350 | } | ||
351 | |||
352 | __init int ar71xx_pcibios_init(void) | ||
353 | { | ||
354 | u32 t; | ||
355 | |||
356 | ar71xx_pcicfg_base = ioremap(AR71XX_PCI_CFG_BASE, AR71XX_PCI_CFG_SIZE); | ||
357 | if (ar71xx_pcicfg_base == NULL) | ||
358 | return -ENOMEM; | ||
359 | |||
360 | ar71xx_pci_reset(); | ||
361 | |||
362 | /* setup COMMAND register */ | ||
363 | t = PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE | ||
364 | | PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK; | ||
365 | ar71xx_pci_local_write(PCI_COMMAND, 4, t); | ||
366 | |||
367 | /* clear bus errors */ | ||
368 | ar71xx_pci_check_error(1); | ||
369 | |||
370 | ar71xx_pci_irq_init(); | ||
371 | |||
372 | register_pci_controller(&ar71xx_pci_controller); | ||
373 | |||
374 | return 0; | ||
375 | } | ||
diff --git a/arch/mips/pci/pci-ar724x.c b/arch/mips/pci/pci-ar724x.c new file mode 100644 index 000000000000..414a7459858d --- /dev/null +++ b/arch/mips/pci/pci-ar724x.c | |||
@@ -0,0 +1,292 @@ | |||
1 | /* | ||
2 | * Atheros AR724X PCI host controller driver | ||
3 | * | ||
4 | * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com> | ||
5 | * Copyright (C) 2009-2011 Gabor Juhos <juhosg@openwrt.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License version 2 as published | ||
9 | * by the Free Software Foundation. | ||
10 | */ | ||
11 | |||
12 | #include <linux/irq.h> | ||
13 | #include <linux/pci.h> | ||
14 | #include <asm/mach-ath79/ath79.h> | ||
15 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
16 | #include <asm/mach-ath79/pci.h> | ||
17 | |||
18 | #define AR724X_PCI_CFG_BASE 0x14000000 | ||
19 | #define AR724X_PCI_CFG_SIZE 0x1000 | ||
20 | #define AR724X_PCI_CTRL_BASE (AR71XX_APB_BASE + 0x000f0000) | ||
21 | #define AR724X_PCI_CTRL_SIZE 0x100 | ||
22 | |||
23 | #define AR724X_PCI_MEM_BASE 0x10000000 | ||
24 | #define AR724X_PCI_MEM_SIZE 0x08000000 | ||
25 | |||
26 | #define AR724X_PCI_REG_INT_STATUS 0x4c | ||
27 | #define AR724X_PCI_REG_INT_MASK 0x50 | ||
28 | |||
29 | #define AR724X_PCI_INT_DEV0 BIT(14) | ||
30 | |||
31 | #define AR724X_PCI_IRQ_COUNT 1 | ||
32 | |||
33 | #define AR7240_BAR0_WAR_VALUE 0xffff | ||
34 | |||
35 | static DEFINE_SPINLOCK(ar724x_pci_lock); | ||
36 | static void __iomem *ar724x_pci_devcfg_base; | ||
37 | static void __iomem *ar724x_pci_ctrl_base; | ||
38 | |||
39 | static u32 ar724x_pci_bar0_value; | ||
40 | static bool ar724x_pci_bar0_is_cached; | ||
41 | |||
42 | static int ar724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | ||
43 | int size, uint32_t *value) | ||
44 | { | ||
45 | unsigned long flags; | ||
46 | void __iomem *base; | ||
47 | u32 data; | ||
48 | |||
49 | if (devfn) | ||
50 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
51 | |||
52 | base = ar724x_pci_devcfg_base; | ||
53 | |||
54 | spin_lock_irqsave(&ar724x_pci_lock, flags); | ||
55 | data = __raw_readl(base + (where & ~3)); | ||
56 | |||
57 | switch (size) { | ||
58 | case 1: | ||
59 | if (where & 1) | ||
60 | data >>= 8; | ||
61 | if (where & 2) | ||
62 | data >>= 16; | ||
63 | data &= 0xff; | ||
64 | break; | ||
65 | case 2: | ||
66 | if (where & 2) | ||
67 | data >>= 16; | ||
68 | data &= 0xffff; | ||
69 | break; | ||
70 | case 4: | ||
71 | break; | ||
72 | default: | ||
73 | spin_unlock_irqrestore(&ar724x_pci_lock, flags); | ||
74 | |||
75 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
76 | } | ||
77 | |||
78 | spin_unlock_irqrestore(&ar724x_pci_lock, flags); | ||
79 | |||
80 | if (where == PCI_BASE_ADDRESS_0 && size == 4 && | ||
81 | ar724x_pci_bar0_is_cached) { | ||
82 | /* use the cached value */ | ||
83 | *value = ar724x_pci_bar0_value; | ||
84 | } else { | ||
85 | *value = data; | ||
86 | } | ||
87 | |||
88 | return PCIBIOS_SUCCESSFUL; | ||
89 | } | ||
90 | |||
91 | static int ar724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | ||
92 | int size, uint32_t value) | ||
93 | { | ||
94 | unsigned long flags; | ||
95 | void __iomem *base; | ||
96 | u32 data; | ||
97 | int s; | ||
98 | |||
99 | if (devfn) | ||
100 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
101 | |||
102 | if (soc_is_ar7240() && where == PCI_BASE_ADDRESS_0 && size == 4) { | ||
103 | if (value != 0xffffffff) { | ||
104 | /* | ||
105 | * WAR for a hw issue. If the BAR0 register of the | ||
106 | * device is set to the proper base address, the | ||
107 | * memory space of the device is not accessible. | ||
108 | * | ||
109 | * Cache the intended value so it can be read back, | ||
110 | * and write a SoC specific constant value to the | ||
111 | * BAR0 register in order to make the device memory | ||
112 | * accessible. | ||
113 | */ | ||
114 | ar724x_pci_bar0_is_cached = true; | ||
115 | ar724x_pci_bar0_value = value; | ||
116 | |||
117 | value = AR7240_BAR0_WAR_VALUE; | ||
118 | } else { | ||
119 | ar724x_pci_bar0_is_cached = false; | ||
120 | } | ||
121 | } | ||
122 | |||
123 | base = ar724x_pci_devcfg_base; | ||
124 | |||
125 | spin_lock_irqsave(&ar724x_pci_lock, flags); | ||
126 | data = __raw_readl(base + (where & ~3)); | ||
127 | |||
128 | switch (size) { | ||
129 | case 1: | ||
130 | s = ((where & 3) * 8); | ||
131 | data &= ~(0xff << s); | ||
132 | data |= ((value & 0xff) << s); | ||
133 | break; | ||
134 | case 2: | ||
135 | s = ((where & 2) * 8); | ||
136 | data &= ~(0xffff << s); | ||
137 | data |= ((value & 0xffff) << s); | ||
138 | break; | ||
139 | case 4: | ||
140 | data = value; | ||
141 | break; | ||
142 | default: | ||
143 | spin_unlock_irqrestore(&ar724x_pci_lock, flags); | ||
144 | |||
145 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
146 | } | ||
147 | |||
148 | __raw_writel(data, base + (where & ~3)); | ||
149 | /* flush write */ | ||
150 | __raw_readl(base + (where & ~3)); | ||
151 | spin_unlock_irqrestore(&ar724x_pci_lock, flags); | ||
152 | |||
153 | return PCIBIOS_SUCCESSFUL; | ||
154 | } | ||
155 | |||
156 | static struct pci_ops ar724x_pci_ops = { | ||
157 | .read = ar724x_pci_read, | ||
158 | .write = ar724x_pci_write, | ||
159 | }; | ||
160 | |||
161 | static struct resource ar724x_io_resource = { | ||
162 | .name = "PCI IO space", | ||
163 | .start = 0, | ||
164 | .end = 0, | ||
165 | .flags = IORESOURCE_IO, | ||
166 | }; | ||
167 | |||
168 | static struct resource ar724x_mem_resource = { | ||
169 | .name = "PCI memory space", | ||
170 | .start = AR724X_PCI_MEM_BASE, | ||
171 | .end = AR724X_PCI_MEM_BASE + AR724X_PCI_MEM_SIZE - 1, | ||
172 | .flags = IORESOURCE_MEM, | ||
173 | }; | ||
174 | |||
175 | static struct pci_controller ar724x_pci_controller = { | ||
176 | .pci_ops = &ar724x_pci_ops, | ||
177 | .io_resource = &ar724x_io_resource, | ||
178 | .mem_resource = &ar724x_mem_resource, | ||
179 | }; | ||
180 | |||
181 | static void ar724x_pci_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
182 | { | ||
183 | void __iomem *base; | ||
184 | u32 pending; | ||
185 | |||
186 | base = ar724x_pci_ctrl_base; | ||
187 | |||
188 | pending = __raw_readl(base + AR724X_PCI_REG_INT_STATUS) & | ||
189 | __raw_readl(base + AR724X_PCI_REG_INT_MASK); | ||
190 | |||
191 | if (pending & AR724X_PCI_INT_DEV0) | ||
192 | generic_handle_irq(ATH79_PCI_IRQ(0)); | ||
193 | |||
194 | else | ||
195 | spurious_interrupt(); | ||
196 | } | ||
197 | |||
198 | static void ar724x_pci_irq_unmask(struct irq_data *d) | ||
199 | { | ||
200 | void __iomem *base; | ||
201 | u32 t; | ||
202 | |||
203 | base = ar724x_pci_ctrl_base; | ||
204 | |||
205 | switch (d->irq) { | ||
206 | case ATH79_PCI_IRQ(0): | ||
207 | t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); | ||
208 | __raw_writel(t | AR724X_PCI_INT_DEV0, | ||
209 | base + AR724X_PCI_REG_INT_MASK); | ||
210 | /* flush write */ | ||
211 | __raw_readl(base + AR724X_PCI_REG_INT_MASK); | ||
212 | } | ||
213 | } | ||
214 | |||
215 | static void ar724x_pci_irq_mask(struct irq_data *d) | ||
216 | { | ||
217 | void __iomem *base; | ||
218 | u32 t; | ||
219 | |||
220 | base = ar724x_pci_ctrl_base; | ||
221 | |||
222 | switch (d->irq) { | ||
223 | case ATH79_PCI_IRQ(0): | ||
224 | t = __raw_readl(base + AR724X_PCI_REG_INT_MASK); | ||
225 | __raw_writel(t & ~AR724X_PCI_INT_DEV0, | ||
226 | base + AR724X_PCI_REG_INT_MASK); | ||
227 | |||
228 | /* flush write */ | ||
229 | __raw_readl(base + AR724X_PCI_REG_INT_MASK); | ||
230 | |||
231 | t = __raw_readl(base + AR724X_PCI_REG_INT_STATUS); | ||
232 | __raw_writel(t | AR724X_PCI_INT_DEV0, | ||
233 | base + AR724X_PCI_REG_INT_STATUS); | ||
234 | |||
235 | /* flush write */ | ||
236 | __raw_readl(base + AR724X_PCI_REG_INT_STATUS); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | static struct irq_chip ar724x_pci_irq_chip = { | ||
241 | .name = "AR724X PCI ", | ||
242 | .irq_mask = ar724x_pci_irq_mask, | ||
243 | .irq_unmask = ar724x_pci_irq_unmask, | ||
244 | .irq_mask_ack = ar724x_pci_irq_mask, | ||
245 | }; | ||
246 | |||
247 | static void __init ar724x_pci_irq_init(int irq) | ||
248 | { | ||
249 | void __iomem *base; | ||
250 | int i; | ||
251 | |||
252 | base = ar724x_pci_ctrl_base; | ||
253 | |||
254 | __raw_writel(0, base + AR724X_PCI_REG_INT_MASK); | ||
255 | __raw_writel(0, base + AR724X_PCI_REG_INT_STATUS); | ||
256 | |||
257 | BUILD_BUG_ON(ATH79_PCI_IRQ_COUNT < AR724X_PCI_IRQ_COUNT); | ||
258 | |||
259 | for (i = ATH79_PCI_IRQ_BASE; | ||
260 | i < ATH79_PCI_IRQ_BASE + AR724X_PCI_IRQ_COUNT; i++) | ||
261 | irq_set_chip_and_handler(i, &ar724x_pci_irq_chip, | ||
262 | handle_level_irq); | ||
263 | |||
264 | irq_set_chained_handler(irq, ar724x_pci_irq_handler); | ||
265 | } | ||
266 | |||
267 | int __init ar724x_pcibios_init(int irq) | ||
268 | { | ||
269 | int ret; | ||
270 | |||
271 | ret = -ENOMEM; | ||
272 | |||
273 | ar724x_pci_devcfg_base = ioremap(AR724X_PCI_CFG_BASE, | ||
274 | AR724X_PCI_CFG_SIZE); | ||
275 | if (ar724x_pci_devcfg_base == NULL) | ||
276 | goto err; | ||
277 | |||
278 | ar724x_pci_ctrl_base = ioremap(AR724X_PCI_CTRL_BASE, | ||
279 | AR724X_PCI_CTRL_SIZE); | ||
280 | if (ar724x_pci_ctrl_base == NULL) | ||
281 | goto err_unmap_devcfg; | ||
282 | |||
283 | ar724x_pci_irq_init(irq); | ||
284 | register_pci_controller(&ar724x_pci_controller); | ||
285 | |||
286 | return PCIBIOS_SUCCESSFUL; | ||
287 | |||
288 | err_unmap_devcfg: | ||
289 | iounmap(ar724x_pci_devcfg_base); | ||
290 | err: | ||
291 | return ret; | ||
292 | } | ||
diff --git a/arch/mips/pci/pci-ath724x.c b/arch/mips/pci/pci-ath724x.c deleted file mode 100644 index a4dd24a4130b..000000000000 --- a/arch/mips/pci/pci-ath724x.c +++ /dev/null | |||
@@ -1,174 +0,0 @@ | |||
1 | /* | ||
2 | * Atheros 724x PCI support | ||
3 | * | ||
4 | * Copyright (C) 2011 René Bolldorf <xsecute@googlemail.com> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License version 2 as published | ||
8 | * by the Free Software Foundation. | ||
9 | */ | ||
10 | |||
11 | #include <linux/pci.h> | ||
12 | #include <asm/mach-ath79/pci-ath724x.h> | ||
13 | |||
14 | #define reg_read(_phys) (*(unsigned int *) KSEG1ADDR(_phys)) | ||
15 | #define reg_write(_phys, _val) ((*(unsigned int *) KSEG1ADDR(_phys)) = (_val)) | ||
16 | |||
17 | #define ATH724X_PCI_DEV_BASE 0x14000000 | ||
18 | #define ATH724X_PCI_MEM_BASE 0x10000000 | ||
19 | #define ATH724X_PCI_MEM_SIZE 0x08000000 | ||
20 | |||
21 | static DEFINE_SPINLOCK(ath724x_pci_lock); | ||
22 | static struct ath724x_pci_data *pci_data; | ||
23 | static int pci_data_size; | ||
24 | |||
25 | static int ath724x_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | ||
26 | int size, uint32_t *value) | ||
27 | { | ||
28 | unsigned long flags, addr, tval, mask; | ||
29 | |||
30 | if (devfn) | ||
31 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
32 | |||
33 | if (where & (size - 1)) | ||
34 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
35 | |||
36 | spin_lock_irqsave(&ath724x_pci_lock, flags); | ||
37 | |||
38 | switch (size) { | ||
39 | case 1: | ||
40 | addr = where & ~3; | ||
41 | mask = 0xff000000 >> ((where % 4) * 8); | ||
42 | tval = reg_read(ATH724X_PCI_DEV_BASE + addr); | ||
43 | tval = tval & ~mask; | ||
44 | *value = (tval >> ((4 - (where % 4))*8)); | ||
45 | break; | ||
46 | case 2: | ||
47 | addr = where & ~3; | ||
48 | mask = 0xffff0000 >> ((where % 4)*8); | ||
49 | tval = reg_read(ATH724X_PCI_DEV_BASE + addr); | ||
50 | tval = tval & ~mask; | ||
51 | *value = (tval >> ((4 - (where % 4))*8)); | ||
52 | break; | ||
53 | case 4: | ||
54 | *value = reg_read(ATH724X_PCI_DEV_BASE + where); | ||
55 | break; | ||
56 | default: | ||
57 | spin_unlock_irqrestore(&ath724x_pci_lock, flags); | ||
58 | |||
59 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
60 | } | ||
61 | |||
62 | spin_unlock_irqrestore(&ath724x_pci_lock, flags); | ||
63 | |||
64 | return PCIBIOS_SUCCESSFUL; | ||
65 | } | ||
66 | |||
67 | static int ath724x_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | ||
68 | int size, uint32_t value) | ||
69 | { | ||
70 | unsigned long flags, tval, addr, mask; | ||
71 | |||
72 | if (devfn) | ||
73 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
74 | |||
75 | if (where & (size - 1)) | ||
76 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
77 | |||
78 | spin_lock_irqsave(&ath724x_pci_lock, flags); | ||
79 | |||
80 | switch (size) { | ||
81 | case 1: | ||
82 | addr = (ATH724X_PCI_DEV_BASE + where) & ~3; | ||
83 | mask = 0xff000000 >> ((where % 4)*8); | ||
84 | tval = reg_read(addr); | ||
85 | tval = tval & ~mask; | ||
86 | tval |= (value << ((4 - (where % 4))*8)) & mask; | ||
87 | reg_write(addr, tval); | ||
88 | break; | ||
89 | case 2: | ||
90 | addr = (ATH724X_PCI_DEV_BASE + where) & ~3; | ||
91 | mask = 0xffff0000 >> ((where % 4)*8); | ||
92 | tval = reg_read(addr); | ||
93 | tval = tval & ~mask; | ||
94 | tval |= (value << ((4 - (where % 4))*8)) & mask; | ||
95 | reg_write(addr, tval); | ||
96 | break; | ||
97 | case 4: | ||
98 | reg_write((ATH724X_PCI_DEV_BASE + where), value); | ||
99 | break; | ||
100 | default: | ||
101 | spin_unlock_irqrestore(&ath724x_pci_lock, flags); | ||
102 | |||
103 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
104 | } | ||
105 | |||
106 | spin_unlock_irqrestore(&ath724x_pci_lock, flags); | ||
107 | |||
108 | return PCIBIOS_SUCCESSFUL; | ||
109 | } | ||
110 | |||
111 | static struct pci_ops ath724x_pci_ops = { | ||
112 | .read = ath724x_pci_read, | ||
113 | .write = ath724x_pci_write, | ||
114 | }; | ||
115 | |||
116 | static struct resource ath724x_io_resource = { | ||
117 | .name = "PCI IO space", | ||
118 | .start = 0, | ||
119 | .end = 0, | ||
120 | .flags = IORESOURCE_IO, | ||
121 | }; | ||
122 | |||
123 | static struct resource ath724x_mem_resource = { | ||
124 | .name = "PCI memory space", | ||
125 | .start = ATH724X_PCI_MEM_BASE, | ||
126 | .end = ATH724X_PCI_MEM_BASE + ATH724X_PCI_MEM_SIZE - 1, | ||
127 | .flags = IORESOURCE_MEM, | ||
128 | }; | ||
129 | |||
130 | static struct pci_controller ath724x_pci_controller = { | ||
131 | .pci_ops = &ath724x_pci_ops, | ||
132 | .io_resource = &ath724x_io_resource, | ||
133 | .mem_resource = &ath724x_mem_resource, | ||
134 | }; | ||
135 | |||
136 | void ath724x_pci_add_data(struct ath724x_pci_data *data, int size) | ||
137 | { | ||
138 | pci_data = data; | ||
139 | pci_data_size = size; | ||
140 | } | ||
141 | |||
142 | int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin) | ||
143 | { | ||
144 | unsigned int devfn = dev->devfn; | ||
145 | int irq = -1; | ||
146 | |||
147 | if (devfn > pci_data_size - 1) | ||
148 | return irq; | ||
149 | |||
150 | irq = pci_data[devfn].irq; | ||
151 | |||
152 | return irq; | ||
153 | } | ||
154 | |||
155 | int pcibios_plat_dev_init(struct pci_dev *dev) | ||
156 | { | ||
157 | unsigned int devfn = dev->devfn; | ||
158 | |||
159 | if (devfn > pci_data_size - 1) | ||
160 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
161 | |||
162 | dev->dev.platform_data = pci_data[devfn].pdata; | ||
163 | |||
164 | return PCIBIOS_SUCCESSFUL; | ||
165 | } | ||
166 | |||
167 | static int __init ath724x_pcibios_init(void) | ||
168 | { | ||
169 | register_pci_controller(&ath724x_pci_controller); | ||
170 | |||
171 | return PCIBIOS_SUCCESSFUL; | ||
172 | } | ||
173 | |||
174 | arch_initcall(ath724x_pcibios_init); | ||
diff --git a/arch/mips/pci/pci-lantiq.c b/arch/mips/pci/pci-lantiq.c index 030c77e7926e..ea453532a33c 100644 --- a/arch/mips/pci/pci-lantiq.c +++ b/arch/mips/pci/pci-lantiq.c | |||
@@ -13,8 +13,12 @@ | |||
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/vmalloc.h> | 15 | #include <linux/vmalloc.h> |
16 | #include <linux/export.h> | 16 | #include <linux/module.h> |
17 | #include <linux/platform_device.h> | 17 | #include <linux/clk.h> |
18 | #include <linux/of_platform.h> | ||
19 | #include <linux/of_gpio.h> | ||
20 | #include <linux/of_irq.h> | ||
21 | #include <linux/of_pci.h> | ||
18 | 22 | ||
19 | #include <asm/pci.h> | 23 | #include <asm/pci.h> |
20 | #include <asm/gpio.h> | 24 | #include <asm/gpio.h> |
@@ -22,17 +26,9 @@ | |||
22 | 26 | ||
23 | #include <lantiq_soc.h> | 27 | #include <lantiq_soc.h> |
24 | #include <lantiq_irq.h> | 28 | #include <lantiq_irq.h> |
25 | #include <lantiq_platform.h> | ||
26 | 29 | ||
27 | #include "pci-lantiq.h" | 30 | #include "pci-lantiq.h" |
28 | 31 | ||
29 | #define LTQ_PCI_CFG_BASE 0x17000000 | ||
30 | #define LTQ_PCI_CFG_SIZE 0x00008000 | ||
31 | #define LTQ_PCI_MEM_BASE 0x18000000 | ||
32 | #define LTQ_PCI_MEM_SIZE 0x02000000 | ||
33 | #define LTQ_PCI_IO_BASE 0x1AE00000 | ||
34 | #define LTQ_PCI_IO_SIZE 0x00200000 | ||
35 | |||
36 | #define PCI_CR_FCI_ADDR_MAP0 0x00C0 | 32 | #define PCI_CR_FCI_ADDR_MAP0 0x00C0 |
37 | #define PCI_CR_FCI_ADDR_MAP1 0x00C4 | 33 | #define PCI_CR_FCI_ADDR_MAP1 0x00C4 |
38 | #define PCI_CR_FCI_ADDR_MAP2 0x00C8 | 34 | #define PCI_CR_FCI_ADDR_MAP2 0x00C8 |
@@ -68,79 +64,27 @@ | |||
68 | #define ltq_pci_cfg_w32(x, y) ltq_w32((x), ltq_pci_mapped_cfg + (y)) | 64 | #define ltq_pci_cfg_w32(x, y) ltq_w32((x), ltq_pci_mapped_cfg + (y)) |
69 | #define ltq_pci_cfg_r32(x) ltq_r32(ltq_pci_mapped_cfg + (x)) | 65 | #define ltq_pci_cfg_r32(x) ltq_r32(ltq_pci_mapped_cfg + (x)) |
70 | 66 | ||
71 | struct ltq_pci_gpio_map { | ||
72 | int pin; | ||
73 | int alt0; | ||
74 | int alt1; | ||
75 | int dir; | ||
76 | char *name; | ||
77 | }; | ||
78 | |||
79 | /* the pci core can make use of the following gpios */ | ||
80 | static struct ltq_pci_gpio_map ltq_pci_gpio_map[] = { | ||
81 | { 0, 1, 0, 0, "pci-exin0" }, | ||
82 | { 1, 1, 0, 0, "pci-exin1" }, | ||
83 | { 2, 1, 0, 0, "pci-exin2" }, | ||
84 | { 39, 1, 0, 0, "pci-exin3" }, | ||
85 | { 10, 1, 0, 0, "pci-exin4" }, | ||
86 | { 9, 1, 0, 0, "pci-exin5" }, | ||
87 | { 30, 1, 0, 1, "pci-gnt1" }, | ||
88 | { 23, 1, 0, 1, "pci-gnt2" }, | ||
89 | { 19, 1, 0, 1, "pci-gnt3" }, | ||
90 | { 38, 1, 0, 1, "pci-gnt4" }, | ||
91 | { 29, 1, 0, 0, "pci-req1" }, | ||
92 | { 31, 1, 0, 0, "pci-req2" }, | ||
93 | { 3, 1, 0, 0, "pci-req3" }, | ||
94 | { 37, 1, 0, 0, "pci-req4" }, | ||
95 | }; | ||
96 | |||
97 | __iomem void *ltq_pci_mapped_cfg; | 67 | __iomem void *ltq_pci_mapped_cfg; |
98 | static __iomem void *ltq_pci_membase; | 68 | static __iomem void *ltq_pci_membase; |
99 | 69 | ||
100 | int (*ltqpci_plat_dev_init)(struct pci_dev *dev) = NULL; | 70 | static int reset_gpio; |
101 | 71 | static struct clk *clk_pci, *clk_external; | |
102 | /* Since the PCI REQ pins can be reused for other functionality, make it | 72 | static struct resource pci_io_resource; |
103 | possible to exclude those from interpretation by the PCI controller */ | 73 | static struct resource pci_mem_resource; |
104 | static int ltq_pci_req_mask = 0xf; | 74 | static struct pci_ops pci_ops = { |
105 | |||
106 | static int *ltq_pci_irq_map; | ||
107 | |||
108 | struct pci_ops ltq_pci_ops = { | ||
109 | .read = ltq_pci_read_config_dword, | 75 | .read = ltq_pci_read_config_dword, |
110 | .write = ltq_pci_write_config_dword | 76 | .write = ltq_pci_write_config_dword |
111 | }; | 77 | }; |
112 | 78 | ||
113 | static struct resource pci_io_resource = { | 79 | static struct pci_controller pci_controller = { |
114 | .name = "pci io space", | 80 | .pci_ops = &pci_ops, |
115 | .start = LTQ_PCI_IO_BASE, | ||
116 | .end = LTQ_PCI_IO_BASE + LTQ_PCI_IO_SIZE - 1, | ||
117 | .flags = IORESOURCE_IO | ||
118 | }; | ||
119 | |||
120 | static struct resource pci_mem_resource = { | ||
121 | .name = "pci memory space", | ||
122 | .start = LTQ_PCI_MEM_BASE, | ||
123 | .end = LTQ_PCI_MEM_BASE + LTQ_PCI_MEM_SIZE - 1, | ||
124 | .flags = IORESOURCE_MEM | ||
125 | }; | ||
126 | |||
127 | static struct pci_controller ltq_pci_controller = { | ||
128 | .pci_ops = <q_pci_ops, | ||
129 | .mem_resource = &pci_mem_resource, | 81 | .mem_resource = &pci_mem_resource, |
130 | .mem_offset = 0x00000000UL, | 82 | .mem_offset = 0x00000000UL, |
131 | .io_resource = &pci_io_resource, | 83 | .io_resource = &pci_io_resource, |
132 | .io_offset = 0x00000000UL, | 84 | .io_offset = 0x00000000UL, |
133 | }; | 85 | }; |
134 | 86 | ||
135 | int pcibios_plat_dev_init(struct pci_dev *dev) | 87 | static inline u32 ltq_calc_bar11mask(void) |
136 | { | ||
137 | if (ltqpci_plat_dev_init) | ||
138 | return ltqpci_plat_dev_init(dev); | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | static u32 ltq_calc_bar11mask(void) | ||
144 | { | 88 | { |
145 | u32 mem, bar11mask; | 89 | u32 mem, bar11mask; |
146 | 90 | ||
@@ -151,48 +95,42 @@ static u32 ltq_calc_bar11mask(void) | |||
151 | return bar11mask; | 95 | return bar11mask; |
152 | } | 96 | } |
153 | 97 | ||
154 | static void ltq_pci_setup_gpio(int gpio) | 98 | static int __devinit ltq_pci_startup(struct platform_device *pdev) |
155 | { | ||
156 | int i; | ||
157 | for (i = 0; i < ARRAY_SIZE(ltq_pci_gpio_map); i++) { | ||
158 | if (gpio & (1 << i)) { | ||
159 | ltq_gpio_request(ltq_pci_gpio_map[i].pin, | ||
160 | ltq_pci_gpio_map[i].alt0, | ||
161 | ltq_pci_gpio_map[i].alt1, | ||
162 | ltq_pci_gpio_map[i].dir, | ||
163 | ltq_pci_gpio_map[i].name); | ||
164 | } | ||
165 | } | ||
166 | ltq_gpio_request(21, 0, 0, 1, "pci-reset"); | ||
167 | ltq_pci_req_mask = (gpio >> PCI_REQ_SHIFT) & PCI_REQ_MASK; | ||
168 | } | ||
169 | |||
170 | static int __devinit ltq_pci_startup(struct ltq_pci_data *conf) | ||
171 | { | 99 | { |
100 | struct device_node *node = pdev->dev.of_node; | ||
101 | const __be32 *req_mask, *bus_clk; | ||
172 | u32 temp_buffer; | 102 | u32 temp_buffer; |
173 | 103 | ||
174 | /* set clock to 33Mhz */ | 104 | /* get our clocks */ |
175 | if (ltq_is_ar9()) { | 105 | clk_pci = clk_get(&pdev->dev, NULL); |
176 | ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0x1f00000, LTQ_CGU_IFCCR); | 106 | if (IS_ERR(clk_pci)) { |
177 | ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0xe00000, LTQ_CGU_IFCCR); | 107 | dev_err(&pdev->dev, "failed to get pci clock\n"); |
178 | } else { | 108 | return PTR_ERR(clk_pci); |
179 | ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~0xf00000, LTQ_CGU_IFCCR); | ||
180 | ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | 0x800000, LTQ_CGU_IFCCR); | ||
181 | } | 109 | } |
182 | 110 | ||
183 | /* external or internal clock ? */ | 111 | clk_external = clk_get(&pdev->dev, "external"); |
184 | if (conf->clock) { | 112 | if (IS_ERR(clk_external)) { |
185 | ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) & ~(1 << 16), | 113 | clk_put(clk_pci); |
186 | LTQ_CGU_IFCCR); | 114 | dev_err(&pdev->dev, "failed to get external pci clock\n"); |
187 | ltq_cgu_w32((1 << 30), LTQ_CGU_PCICR); | 115 | return PTR_ERR(clk_external); |
188 | } else { | ||
189 | ltq_cgu_w32(ltq_cgu_r32(LTQ_CGU_IFCCR) | (1 << 16), | ||
190 | LTQ_CGU_IFCCR); | ||
191 | ltq_cgu_w32((1 << 31) | (1 << 30), LTQ_CGU_PCICR); | ||
192 | } | 116 | } |
193 | 117 | ||
194 | /* setup pci clock and gpis used by pci */ | 118 | /* read the bus speed that we want */ |
195 | ltq_pci_setup_gpio(conf->gpio); | 119 | bus_clk = of_get_property(node, "lantiq,bus-clock", NULL); |
120 | if (bus_clk) | ||
121 | clk_set_rate(clk_pci, *bus_clk); | ||
122 | |||
123 | /* and enable the clocks */ | ||
124 | clk_enable(clk_pci); | ||
125 | if (of_find_property(node, "lantiq,external-clock", NULL)) | ||
126 | clk_enable(clk_external); | ||
127 | else | ||
128 | clk_disable(clk_external); | ||
129 | |||
130 | /* setup reset gpio used by pci */ | ||
131 | reset_gpio = of_get_named_gpio(node, "gpio-reset", 0); | ||
132 | if (reset_gpio > 0) | ||
133 | devm_gpio_request(&pdev->dev, reset_gpio, "pci-reset"); | ||
196 | 134 | ||
197 | /* enable auto-switching between PCI and EBU */ | 135 | /* enable auto-switching between PCI and EBU */ |
198 | ltq_pci_w32(0xa, PCI_CR_CLK_CTRL); | 136 | ltq_pci_w32(0xa, PCI_CR_CLK_CTRL); |
@@ -205,7 +143,12 @@ static int __devinit ltq_pci_startup(struct ltq_pci_data *conf) | |||
205 | 143 | ||
206 | /* enable external 2 PCI masters */ | 144 | /* enable external 2 PCI masters */ |
207 | temp_buffer = ltq_pci_r32(PCI_CR_PC_ARB); | 145 | temp_buffer = ltq_pci_r32(PCI_CR_PC_ARB); |
208 | temp_buffer &= (~(ltq_pci_req_mask << 16)); | 146 | /* setup the request mask */ |
147 | req_mask = of_get_property(node, "req-mask", NULL); | ||
148 | if (req_mask) | ||
149 | temp_buffer &= ~((*req_mask & 0xf) << 16); | ||
150 | else | ||
151 | temp_buffer &= ~0xf0000; | ||
209 | /* enable internal arbiter */ | 152 | /* enable internal arbiter */ |
210 | temp_buffer |= (1 << INTERNAL_ARB_ENABLE_BIT); | 153 | temp_buffer |= (1 << INTERNAL_ARB_ENABLE_BIT); |
211 | /* enable internal PCI master reqest */ | 154 | /* enable internal PCI master reqest */ |
@@ -249,47 +192,55 @@ static int __devinit ltq_pci_startup(struct ltq_pci_data *conf) | |||
249 | ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_IEN) | 0x10, LTQ_EBU_PCC_IEN); | 192 | ltq_ebu_w32(ltq_ebu_r32(LTQ_EBU_PCC_IEN) | 0x10, LTQ_EBU_PCC_IEN); |
250 | 193 | ||
251 | /* toggle reset pin */ | 194 | /* toggle reset pin */ |
252 | __gpio_set_value(21, 0); | 195 | if (reset_gpio > 0) { |
253 | wmb(); | 196 | __gpio_set_value(reset_gpio, 0); |
254 | mdelay(1); | 197 | wmb(); |
255 | __gpio_set_value(21, 1); | 198 | mdelay(1); |
256 | return 0; | 199 | __gpio_set_value(reset_gpio, 1); |
257 | } | 200 | } |
258 | |||
259 | int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) | ||
260 | { | ||
261 | if (ltq_pci_irq_map[slot]) | ||
262 | return ltq_pci_irq_map[slot]; | ||
263 | printk(KERN_ERR "lq_pci: trying to map irq for unknown slot %d\n", | ||
264 | slot); | ||
265 | |||
266 | return 0; | 201 | return 0; |
267 | } | 202 | } |
268 | 203 | ||
269 | static int __devinit ltq_pci_probe(struct platform_device *pdev) | 204 | static int __devinit ltq_pci_probe(struct platform_device *pdev) |
270 | { | 205 | { |
271 | struct ltq_pci_data *ltq_pci_data = | 206 | struct resource *res_cfg, *res_bridge; |
272 | (struct ltq_pci_data *) pdev->dev.platform_data; | ||
273 | 207 | ||
274 | pci_clear_flags(PCI_PROBE_ONLY); | 208 | pci_clear_flags(PCI_PROBE_ONLY); |
275 | ltq_pci_irq_map = ltq_pci_data->irq; | ||
276 | ltq_pci_membase = ioremap_nocache(PCI_CR_BASE_ADDR, PCI_CR_SIZE); | ||
277 | ltq_pci_mapped_cfg = | ||
278 | ioremap_nocache(LTQ_PCI_CFG_BASE, LTQ_PCI_CFG_BASE); | ||
279 | ltq_pci_controller.io_map_base = | ||
280 | (unsigned long)ioremap(LTQ_PCI_IO_BASE, LTQ_PCI_IO_SIZE - 1); | ||
281 | ltq_pci_startup(ltq_pci_data); | ||
282 | register_pci_controller(<q_pci_controller); | ||
283 | 209 | ||
210 | res_cfg = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
211 | res_bridge = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
212 | if (!res_cfg || !res_bridge) { | ||
213 | dev_err(&pdev->dev, "missing memory reources\n"); | ||
214 | return -EINVAL; | ||
215 | } | ||
216 | |||
217 | ltq_pci_membase = devm_request_and_ioremap(&pdev->dev, res_bridge); | ||
218 | ltq_pci_mapped_cfg = devm_request_and_ioremap(&pdev->dev, res_cfg); | ||
219 | |||
220 | if (!ltq_pci_membase || !ltq_pci_mapped_cfg) { | ||
221 | dev_err(&pdev->dev, "failed to remap resources\n"); | ||
222 | return -ENOMEM; | ||
223 | } | ||
224 | |||
225 | ltq_pci_startup(pdev); | ||
226 | |||
227 | pci_load_of_ranges(&pci_controller, pdev->dev.of_node); | ||
228 | register_pci_controller(&pci_controller); | ||
284 | return 0; | 229 | return 0; |
285 | } | 230 | } |
286 | 231 | ||
287 | static struct platform_driver | 232 | static const struct of_device_id ltq_pci_match[] = { |
288 | ltq_pci_driver = { | 233 | { .compatible = "lantiq,pci-xway" }, |
234 | {}, | ||
235 | }; | ||
236 | MODULE_DEVICE_TABLE(of, ltq_pci_match); | ||
237 | |||
238 | static struct platform_driver ltq_pci_driver = { | ||
289 | .probe = ltq_pci_probe, | 239 | .probe = ltq_pci_probe, |
290 | .driver = { | 240 | .driver = { |
291 | .name = "ltq_pci", | 241 | .name = "pci-xway", |
292 | .owner = THIS_MODULE, | 242 | .owner = THIS_MODULE, |
243 | .of_match_table = ltq_pci_match, | ||
293 | }, | 244 | }, |
294 | }; | 245 | }; |
295 | 246 | ||
@@ -297,7 +248,7 @@ int __init pcibios_init(void) | |||
297 | { | 248 | { |
298 | int ret = platform_driver_register(<q_pci_driver); | 249 | int ret = platform_driver_register(<q_pci_driver); |
299 | if (ret) | 250 | if (ret) |
300 | printk(KERN_INFO "ltq_pci: Error registering platfom driver!"); | 251 | pr_info("pci-xway: Error registering platform driver!"); |
301 | return ret; | 252 | return ret; |
302 | } | 253 | } |
303 | 254 | ||
diff --git a/arch/mips/pci/pci.c b/arch/mips/pci/pci.c index 0514866fa925..271e8c4a54c7 100644 --- a/arch/mips/pci/pci.c +++ b/arch/mips/pci/pci.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #include <linux/pci.h> | 18 | #include <linux/pci.h> |
19 | #include <linux/of_address.h> | ||
19 | 20 | ||
20 | #include <asm/cpu-info.h> | 21 | #include <asm/cpu-info.h> |
21 | 22 | ||
@@ -114,9 +115,63 @@ static void __devinit pcibios_scanbus(struct pci_controller *hose) | |||
114 | pci_bus_assign_resources(bus); | 115 | pci_bus_assign_resources(bus); |
115 | pci_enable_bridges(bus); | 116 | pci_enable_bridges(bus); |
116 | } | 117 | } |
118 | bus->dev.of_node = hose->of_node; | ||
117 | } | 119 | } |
118 | } | 120 | } |
119 | 121 | ||
122 | #ifdef CONFIG_OF | ||
123 | void __devinit pci_load_of_ranges(struct pci_controller *hose, | ||
124 | struct device_node *node) | ||
125 | { | ||
126 | const __be32 *ranges; | ||
127 | int rlen; | ||
128 | int pna = of_n_addr_cells(node); | ||
129 | int np = pna + 5; | ||
130 | |||
131 | pr_info("PCI host bridge %s ranges:\n", node->full_name); | ||
132 | ranges = of_get_property(node, "ranges", &rlen); | ||
133 | if (ranges == NULL) | ||
134 | return; | ||
135 | hose->of_node = node; | ||
136 | |||
137 | while ((rlen -= np * 4) >= 0) { | ||
138 | u32 pci_space; | ||
139 | struct resource *res = NULL; | ||
140 | u64 addr, size; | ||
141 | |||
142 | pci_space = be32_to_cpup(&ranges[0]); | ||
143 | addr = of_translate_address(node, ranges + 3); | ||
144 | size = of_read_number(ranges + pna + 3, 2); | ||
145 | ranges += np; | ||
146 | switch ((pci_space >> 24) & 0x3) { | ||
147 | case 1: /* PCI IO space */ | ||
148 | pr_info(" IO 0x%016llx..0x%016llx\n", | ||
149 | addr, addr + size - 1); | ||
150 | hose->io_map_base = | ||
151 | (unsigned long)ioremap(addr, size); | ||
152 | res = hose->io_resource; | ||
153 | res->flags = IORESOURCE_IO; | ||
154 | break; | ||
155 | case 2: /* PCI Memory space */ | ||
156 | case 3: /* PCI 64 bits Memory space */ | ||
157 | pr_info(" MEM 0x%016llx..0x%016llx\n", | ||
158 | addr, addr + size - 1); | ||
159 | res = hose->mem_resource; | ||
160 | res->flags = IORESOURCE_MEM; | ||
161 | break; | ||
162 | } | ||
163 | if (res != NULL) { | ||
164 | res->start = addr; | ||
165 | res->name = node->full_name; | ||
166 | res->end = res->start + size - 1; | ||
167 | res->parent = NULL; | ||
168 | res->sibling = NULL; | ||
169 | res->child = NULL; | ||
170 | } | ||
171 | } | ||
172 | } | ||
173 | #endif | ||
174 | |||
120 | static DEFINE_MUTEX(pci_scan_mutex); | 175 | static DEFINE_MUTEX(pci_scan_mutex); |
121 | 176 | ||
122 | void __devinit register_pci_controller(struct pci_controller *hose) | 177 | void __devinit register_pci_controller(struct pci_controller *hose) |
diff --git a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile index 02f5fb94ea28..5af95ec3319d 100644 --- a/arch/mips/pmc-sierra/yosemite/Makefile +++ b/arch/mips/pmc-sierra/yosemite/Makefile | |||
@@ -5,5 +5,3 @@ | |||
5 | obj-y += irq.o prom.o py-console.o setup.o | 5 | obj-y += irq.o prom.o py-console.o setup.o |
6 | 6 | ||
7 | obj-$(CONFIG_SMP) += smp.o | 7 | obj-$(CONFIG_SMP) += smp.o |
8 | |||
9 | ccflags-y := -Werror | ||
diff --git a/arch/mips/pmc-sierra/yosemite/setup.c b/arch/mips/pmc-sierra/yosemite/setup.c index 3498ac9c35af..b6472fc88a99 100644 --- a/arch/mips/pmc-sierra/yosemite/setup.c +++ b/arch/mips/pmc-sierra/yosemite/setup.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/bcd.h> | 27 | #include <linux/bcd.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
30 | #include <linux/export.h> | ||
30 | #include <linux/types.h> | 31 | #include <linux/types.h> |
31 | #include <linux/mm.h> | 32 | #include <linux/mm.h> |
32 | #include <linux/bootmem.h> | 33 | #include <linux/bootmem.h> |
diff --git a/arch/mips/powertv/Makefile b/arch/mips/powertv/Makefile index 348d2e850ef5..39ca9f8d63ae 100644 --- a/arch/mips/powertv/Makefile +++ b/arch/mips/powertv/Makefile | |||
@@ -27,5 +27,3 @@ obj-y += init.o ioremap.o memory.o powertv_setup.o reset.o time.o \ | |||
27 | asic/ pci/ | 27 | asic/ pci/ |
28 | 28 | ||
29 | obj-$(CONFIG_USB) += powertv-usb.o | 29 | obj-$(CONFIG_USB) += powertv-usb.o |
30 | |||
31 | ccflags-y := -Wall | ||
diff --git a/arch/mips/powertv/asic/Makefile b/arch/mips/powertv/asic/Makefile index d810a33182a4..35dcc53eb25f 100644 --- a/arch/mips/powertv/asic/Makefile +++ b/arch/mips/powertv/asic/Makefile | |||
@@ -19,5 +19,3 @@ | |||
19 | obj-y += asic-calliope.o asic-cronus.o asic-gaia.o asic-zeus.o \ | 19 | obj-y += asic-calliope.o asic-cronus.o asic-gaia.o asic-zeus.o \ |
20 | asic_devices.o asic_int.o irq_asic.o prealloc-calliope.o \ | 20 | asic_devices.o asic_int.o irq_asic.o prealloc-calliope.o \ |
21 | prealloc-cronus.o prealloc-cronuslite.o prealloc-gaia.o prealloc-zeus.o | 21 | prealloc-cronus.o prealloc-cronuslite.o prealloc-gaia.o prealloc-zeus.o |
22 | |||
23 | ccflags-y := -Wall -Werror | ||
diff --git a/arch/mips/powertv/pci/Makefile b/arch/mips/powertv/pci/Makefile index 5783201cd2c8..2610a6af5b2c 100644 --- a/arch/mips/powertv/pci/Makefile +++ b/arch/mips/powertv/pci/Makefile | |||
@@ -17,5 +17,3 @@ | |||
17 | # | 17 | # |
18 | 18 | ||
19 | obj-$(CONFIG_PCI) += fixup-powertv.o | 19 | obj-$(CONFIG_PCI) += fixup-powertv.o |
20 | |||
21 | ccflags-y := -Wall -Werror | ||
diff --git a/arch/mips/rb532/devices.c b/arch/mips/rb532/devices.c index a969eb826634..ea774285e6c5 100644 --- a/arch/mips/rb532/devices.c +++ b/arch/mips/rb532/devices.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * GNU General Public License for more details. | 15 | * GNU General Public License for more details. |
16 | */ | 16 | */ |
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/export.h> | ||
18 | #include <linux/init.h> | 19 | #include <linux/init.h> |
19 | #include <linux/ctype.h> | 20 | #include <linux/ctype.h> |
20 | #include <linux/string.h> | 21 | #include <linux/string.h> |
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c index d16b462154c3..413f17f8e892 100644 --- a/arch/mips/sni/setup.c +++ b/arch/mips/sni/setup.c | |||
@@ -10,6 +10,7 @@ | |||
10 | */ | 10 | */ |
11 | #include <linux/eisa.h> | 11 | #include <linux/eisa.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/export.h> | ||
13 | #include <linux/console.h> | 14 | #include <linux/console.h> |
14 | #include <linux/fb.h> | 15 | #include <linux/fb.h> |
15 | #include <linux/screen_info.h> | 16 | #include <linux/screen_info.h> |
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index e03653d69357..8fae07935cd1 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig | |||
@@ -96,6 +96,14 @@ config GPIO_EP93XX | |||
96 | depends on ARCH_EP93XX | 96 | depends on ARCH_EP93XX |
97 | select GPIO_GENERIC | 97 | select GPIO_GENERIC |
98 | 98 | ||
99 | config GPIO_MM_LANTIQ | ||
100 | bool "Lantiq Memory mapped GPIOs" | ||
101 | depends on LANTIQ && SOC_XWAY | ||
102 | help | ||
103 | This enables support for memory mapped GPIOs on the External Bus Unit | ||
104 | (EBU) found on Lantiq SoCs. The gpios are output only as they are | ||
105 | created by attaching a 16bit latch to the bus. | ||
106 | |||
99 | config GPIO_MPC5200 | 107 | config GPIO_MPC5200 |
100 | def_bool y | 108 | def_bool y |
101 | depends on PPC_MPC52xx | 109 | depends on PPC_MPC52xx |
@@ -306,6 +314,16 @@ config GPIO_STMPE | |||
306 | This enables support for the GPIOs found on the STMPE I/O | 314 | This enables support for the GPIOs found on the STMPE I/O |
307 | Expanders. | 315 | Expanders. |
308 | 316 | ||
317 | config GPIO_STP_XWAY | ||
318 | bool "XWAY STP GPIOs" | ||
319 | depends on SOC_XWAY | ||
320 | help | ||
321 | This enables support for the Serial To Parallel (STP) unit found on | ||
322 | XWAY SoC. The STP allows the SoC to drive a shift registers cascade, | ||
323 | that can be up to 24 bit. This peripheral is aimed at driving leds. | ||
324 | Some of the gpios/leds can be auto updated by the soc with dsl and | ||
325 | phy status. | ||
326 | |||
309 | config GPIO_TC3589X | 327 | config GPIO_TC3589X |
310 | bool "TC3589X GPIOs" | 328 | bool "TC3589X GPIOs" |
311 | depends on MFD_TC3589X | 329 | depends on MFD_TC3589X |
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 007f54bd0081..ed1c96db404b 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile | |||
@@ -30,6 +30,7 @@ obj-$(CONFIG_GPIO_MC33880) += gpio-mc33880.o | |||
30 | obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o | 30 | obj-$(CONFIG_GPIO_MC9S08DZ60) += gpio-mc9s08dz60.o |
31 | obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o | 31 | obj-$(CONFIG_GPIO_MCP23S08) += gpio-mcp23s08.o |
32 | obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o | 32 | obj-$(CONFIG_GPIO_ML_IOH) += gpio-ml-ioh.o |
33 | obj-$(CONFIG_GPIO_MM_LANTIQ) += gpio-mm-lantiq.o | ||
33 | obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o | 34 | obj-$(CONFIG_GPIO_MPC5200) += gpio-mpc5200.o |
34 | obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o | 35 | obj-$(CONFIG_GPIO_MPC8XXX) += gpio-mpc8xxx.o |
35 | obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o | 36 | obj-$(CONFIG_GPIO_MSM_V1) += gpio-msm-v1.o |
@@ -49,6 +50,7 @@ obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o | |||
49 | obj-$(CONFIG_GPIO_SCH) += gpio-sch.o | 50 | obj-$(CONFIG_GPIO_SCH) += gpio-sch.o |
50 | obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o | 51 | obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o |
51 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o | 52 | obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o |
53 | obj-$(CONFIG_GPIO_STP_XWAY) += gpio-stp-xway.o | ||
52 | obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o | 54 | obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o |
53 | obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o | 55 | obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o |
54 | obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o | 56 | obj-$(CONFIG_ARCH_TEGRA) += gpio-tegra.o |
diff --git a/drivers/gpio/gpio-mm-lantiq.c b/drivers/gpio/gpio-mm-lantiq.c new file mode 100644 index 000000000000..2983dfbd0668 --- /dev/null +++ b/drivers/gpio/gpio-mm-lantiq.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | ||
7 | */ | ||
8 | |||
9 | #include <linux/init.h> | ||
10 | #include <linux/module.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/mutex.h> | ||
14 | #include <linux/gpio.h> | ||
15 | #include <linux/of.h> | ||
16 | #include <linux/of_gpio.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/slab.h> | ||
19 | |||
20 | #include <lantiq_soc.h> | ||
21 | |||
22 | /* | ||
23 | * By attaching hardware latches to the EBU it is possible to create output | ||
24 | * only gpios. This driver configures a special memory address, which when | ||
25 | * written to outputs 16 bit to the latches. | ||
26 | */ | ||
27 | |||
28 | #define LTQ_EBU_BUSCON 0x1e7ff /* 16 bit access, slowest timing */ | ||
29 | #define LTQ_EBU_WP 0x80000000 /* write protect bit */ | ||
30 | |||
31 | struct ltq_mm { | ||
32 | struct of_mm_gpio_chip mmchip; | ||
33 | u16 shadow; /* shadow the latches state */ | ||
34 | }; | ||
35 | |||
36 | /** | ||
37 | * ltq_mm_apply() - write the shadow value to the ebu address. | ||
38 | * @chip: Pointer to our private data structure. | ||
39 | * | ||
40 | * Write the shadow value to the EBU to set the gpios. We need to set the | ||
41 | * global EBU lock to make sure that PCI/MTD dont break. | ||
42 | */ | ||
43 | static void ltq_mm_apply(struct ltq_mm *chip) | ||
44 | { | ||
45 | unsigned long flags; | ||
46 | |||
47 | spin_lock_irqsave(&ebu_lock, flags); | ||
48 | ltq_ebu_w32(LTQ_EBU_BUSCON, LTQ_EBU_BUSCON1); | ||
49 | __raw_writew(chip->shadow, chip->mmchip.regs); | ||
50 | ltq_ebu_w32(LTQ_EBU_BUSCON | LTQ_EBU_WP, LTQ_EBU_BUSCON1); | ||
51 | spin_unlock_irqrestore(&ebu_lock, flags); | ||
52 | } | ||
53 | |||
54 | /** | ||
55 | * ltq_mm_set() - gpio_chip->set - set gpios. | ||
56 | * @gc: Pointer to gpio_chip device structure. | ||
57 | * @gpio: GPIO signal number. | ||
58 | * @val: Value to be written to specified signal. | ||
59 | * | ||
60 | * Set the shadow value and call ltq_mm_apply. | ||
61 | */ | ||
62 | static void ltq_mm_set(struct gpio_chip *gc, unsigned offset, int value) | ||
63 | { | ||
64 | struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); | ||
65 | struct ltq_mm *chip = | ||
66 | container_of(mm_gc, struct ltq_mm, mmchip); | ||
67 | |||
68 | if (value) | ||
69 | chip->shadow |= (1 << offset); | ||
70 | else | ||
71 | chip->shadow &= ~(1 << offset); | ||
72 | ltq_mm_apply(chip); | ||
73 | } | ||
74 | |||
75 | /** | ||
76 | * ltq_mm_dir_out() - gpio_chip->dir_out - set gpio direction. | ||
77 | * @gc: Pointer to gpio_chip device structure. | ||
78 | * @gpio: GPIO signal number. | ||
79 | * @val: Value to be written to specified signal. | ||
80 | * | ||
81 | * Same as ltq_mm_set, always returns 0. | ||
82 | */ | ||
83 | static int ltq_mm_dir_out(struct gpio_chip *gc, unsigned offset, int value) | ||
84 | { | ||
85 | ltq_mm_set(gc, offset, value); | ||
86 | |||
87 | return 0; | ||
88 | } | ||
89 | |||
90 | /** | ||
91 | * ltq_mm_save_regs() - Set initial values of GPIO pins | ||
92 | * @mm_gc: pointer to memory mapped GPIO chip structure | ||
93 | */ | ||
94 | static void ltq_mm_save_regs(struct of_mm_gpio_chip *mm_gc) | ||
95 | { | ||
96 | struct ltq_mm *chip = | ||
97 | container_of(mm_gc, struct ltq_mm, mmchip); | ||
98 | |||
99 | /* tell the ebu controller which memory address we will be using */ | ||
100 | ltq_ebu_w32(CPHYSADDR(chip->mmchip.regs) | 0x1, LTQ_EBU_ADDRSEL1); | ||
101 | |||
102 | ltq_mm_apply(chip); | ||
103 | } | ||
104 | |||
105 | static int ltq_mm_probe(struct platform_device *pdev) | ||
106 | { | ||
107 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
108 | struct ltq_mm *chip; | ||
109 | const __be32 *shadow; | ||
110 | int ret = 0; | ||
111 | |||
112 | if (!res) { | ||
113 | dev_err(&pdev->dev, "failed to get memory resource\n"); | ||
114 | return -ENOENT; | ||
115 | } | ||
116 | |||
117 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
118 | if (!chip) | ||
119 | return -ENOMEM; | ||
120 | |||
121 | chip->mmchip.gc.ngpio = 16; | ||
122 | chip->mmchip.gc.label = "gpio-mm-ltq"; | ||
123 | chip->mmchip.gc.direction_output = ltq_mm_dir_out; | ||
124 | chip->mmchip.gc.set = ltq_mm_set; | ||
125 | chip->mmchip.save_regs = ltq_mm_save_regs; | ||
126 | |||
127 | /* store the shadow value if one was passed by the devicetree */ | ||
128 | shadow = of_get_property(pdev->dev.of_node, "lantiq,shadow", NULL); | ||
129 | if (shadow) | ||
130 | chip->shadow = be32_to_cpu(*shadow); | ||
131 | |||
132 | ret = of_mm_gpiochip_add(pdev->dev.of_node, &chip->mmchip); | ||
133 | if (ret) | ||
134 | kfree(chip); | ||
135 | return ret; | ||
136 | } | ||
137 | |||
138 | static const struct of_device_id ltq_mm_match[] = { | ||
139 | { .compatible = "lantiq,gpio-mm" }, | ||
140 | {}, | ||
141 | }; | ||
142 | MODULE_DEVICE_TABLE(of, ltq_mm_match); | ||
143 | |||
144 | static struct platform_driver ltq_mm_driver = { | ||
145 | .probe = ltq_mm_probe, | ||
146 | .driver = { | ||
147 | .name = "gpio-mm-ltq", | ||
148 | .owner = THIS_MODULE, | ||
149 | .of_match_table = ltq_mm_match, | ||
150 | }, | ||
151 | }; | ||
152 | |||
153 | static int __init ltq_mm_init(void) | ||
154 | { | ||
155 | return platform_driver_register(<q_mm_driver); | ||
156 | } | ||
157 | |||
158 | subsys_initcall(ltq_mm_init); | ||
diff --git a/drivers/gpio/gpio-stp-xway.c b/drivers/gpio/gpio-stp-xway.c new file mode 100644 index 000000000000..e35096bf3cfb --- /dev/null +++ b/drivers/gpio/gpio-stp-xway.c | |||
@@ -0,0 +1,301 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify it | ||
3 | * under the terms of the GNU General Public License version 2 as published | ||
4 | * by the Free Software Foundation. | ||
5 | * | ||
6 | * Copyright (C) 2012 John Crispin <blogic@openwrt.org> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #include <linux/slab.h> | ||
11 | #include <linux/init.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/of_platform.h> | ||
15 | #include <linux/mutex.h> | ||
16 | #include <linux/gpio.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/of_gpio.h> | ||
19 | #include <linux/clk.h> | ||
20 | #include <linux/err.h> | ||
21 | |||
22 | #include <lantiq_soc.h> | ||
23 | |||
24 | /* | ||
25 | * The Serial To Parallel (STP) is found on MIPS based Lantiq socs. It is a | ||
26 | * peripheral controller used to drive external shift register cascades. At most | ||
27 | * 3 groups of 8 bits can be driven. The hardware is able to allow the DSL modem | ||
28 | * to drive the 2 LSBs of the cascade automatically. | ||
29 | */ | ||
30 | |||
31 | /* control register 0 */ | ||
32 | #define XWAY_STP_CON0 0x00 | ||
33 | /* control register 1 */ | ||
34 | #define XWAY_STP_CON1 0x04 | ||
35 | /* data register 0 */ | ||
36 | #define XWAY_STP_CPU0 0x08 | ||
37 | /* data register 1 */ | ||
38 | #define XWAY_STP_CPU1 0x0C | ||
39 | /* access register */ | ||
40 | #define XWAY_STP_AR 0x10 | ||
41 | |||
42 | /* software or hardware update select bit */ | ||
43 | #define XWAY_STP_CON_SWU BIT(31) | ||
44 | |||
45 | /* automatic update rates */ | ||
46 | #define XWAY_STP_2HZ 0 | ||
47 | #define XWAY_STP_4HZ BIT(23) | ||
48 | #define XWAY_STP_8HZ BIT(24) | ||
49 | #define XWAY_STP_10HZ (BIT(24) | BIT(23)) | ||
50 | #define XWAY_STP_SPEED_MASK (0xf << 23) | ||
51 | |||
52 | /* clock source for automatic update */ | ||
53 | #define XWAY_STP_UPD_FPI BIT(31) | ||
54 | #define XWAY_STP_UPD_MASK (BIT(31) | BIT(30)) | ||
55 | |||
56 | /* let the adsl core drive the 2 LSBs */ | ||
57 | #define XWAY_STP_ADSL_SHIFT 24 | ||
58 | #define XWAY_STP_ADSL_MASK 0x3 | ||
59 | |||
60 | /* 2 groups of 3 bits can be driven by the phys */ | ||
61 | #define XWAY_STP_PHY_MASK 0x3 | ||
62 | #define XWAY_STP_PHY1_SHIFT 27 | ||
63 | #define XWAY_STP_PHY2_SHIFT 15 | ||
64 | |||
65 | /* STP has 3 groups of 8 bits */ | ||
66 | #define XWAY_STP_GROUP0 BIT(0) | ||
67 | #define XWAY_STP_GROUP1 BIT(1) | ||
68 | #define XWAY_STP_GROUP2 BIT(2) | ||
69 | #define XWAY_STP_GROUP_MASK (0x7) | ||
70 | |||
71 | /* Edge configuration bits */ | ||
72 | #define XWAY_STP_FALLING BIT(26) | ||
73 | #define XWAY_STP_EDGE_MASK BIT(26) | ||
74 | |||
75 | #define xway_stp_r32(m, reg) __raw_readl(m + reg) | ||
76 | #define xway_stp_w32(m, val, reg) __raw_writel(val, m + reg) | ||
77 | #define xway_stp_w32_mask(m, clear, set, reg) \ | ||
78 | ltq_w32((ltq_r32(m + reg) & ~(clear)) | (set), \ | ||
79 | m + reg) | ||
80 | |||
81 | struct xway_stp { | ||
82 | struct gpio_chip gc; | ||
83 | void __iomem *virt; | ||
84 | u32 edge; /* rising or falling edge triggered shift register */ | ||
85 | u16 shadow; /* shadow the shift registers state */ | ||
86 | u8 groups; /* we can drive 1-3 groups of 8bit each */ | ||
87 | u8 dsl; /* the 2 LSBs can be driven by the dsl core */ | ||
88 | u8 phy1; /* 3 bits can be driven by phy1 */ | ||
89 | u8 phy2; /* 3 bits can be driven by phy2 */ | ||
90 | u8 reserved; /* mask out the hw driven bits in gpio_request */ | ||
91 | }; | ||
92 | |||
93 | /** | ||
94 | * xway_stp_set() - gpio_chip->set - set gpios. | ||
95 | * @gc: Pointer to gpio_chip device structure. | ||
96 | * @gpio: GPIO signal number. | ||
97 | * @val: Value to be written to specified signal. | ||
98 | * | ||
99 | * Set the shadow value and call ltq_ebu_apply. | ||
100 | */ | ||
101 | static void xway_stp_set(struct gpio_chip *gc, unsigned gpio, int val) | ||
102 | { | ||
103 | struct xway_stp *chip = | ||
104 | container_of(gc, struct xway_stp, gc); | ||
105 | |||
106 | if (val) | ||
107 | chip->shadow |= BIT(gpio); | ||
108 | else | ||
109 | chip->shadow &= ~BIT(gpio); | ||
110 | xway_stp_w32(chip->virt, chip->shadow, XWAY_STP_CPU0); | ||
111 | xway_stp_w32_mask(chip->virt, 0, XWAY_STP_CON_SWU, XWAY_STP_CON0); | ||
112 | } | ||
113 | |||
114 | /** | ||
115 | * xway_stp_dir_out() - gpio_chip->dir_out - set gpio direction. | ||
116 | * @gc: Pointer to gpio_chip device structure. | ||
117 | * @gpio: GPIO signal number. | ||
118 | * @val: Value to be written to specified signal. | ||
119 | * | ||
120 | * Same as xway_stp_set, always returns 0. | ||
121 | */ | ||
122 | static int xway_stp_dir_out(struct gpio_chip *gc, unsigned gpio, int val) | ||
123 | { | ||
124 | xway_stp_set(gc, gpio, val); | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | /** | ||
130 | * xway_stp_request() - gpio_chip->request | ||
131 | * @gc: Pointer to gpio_chip device structure. | ||
132 | * @gpio: GPIO signal number. | ||
133 | * | ||
134 | * We mask out the HW driven pins | ||
135 | */ | ||
136 | static int xway_stp_request(struct gpio_chip *gc, unsigned gpio) | ||
137 | { | ||
138 | struct xway_stp *chip = | ||
139 | container_of(gc, struct xway_stp, gc); | ||
140 | |||
141 | if ((gpio < 8) && (chip->reserved & BIT(gpio))) { | ||
142 | dev_err(gc->dev, "GPIO %d is driven by hardware\n", gpio); | ||
143 | return -ENODEV; | ||
144 | } | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | /** | ||
150 | * xway_stp_hw_init() - Configure the STP unit and enable the clock gate | ||
151 | * @virt: pointer to the remapped register range | ||
152 | */ | ||
153 | static int xway_stp_hw_init(struct xway_stp *chip) | ||
154 | { | ||
155 | /* sane defaults */ | ||
156 | xway_stp_w32(chip->virt, 0, XWAY_STP_AR); | ||
157 | xway_stp_w32(chip->virt, 0, XWAY_STP_CPU0); | ||
158 | xway_stp_w32(chip->virt, 0, XWAY_STP_CPU1); | ||
159 | xway_stp_w32(chip->virt, XWAY_STP_CON_SWU, XWAY_STP_CON0); | ||
160 | xway_stp_w32(chip->virt, 0, XWAY_STP_CON1); | ||
161 | |||
162 | /* apply edge trigger settings for the shift register */ | ||
163 | xway_stp_w32_mask(chip->virt, XWAY_STP_EDGE_MASK, | ||
164 | chip->edge, XWAY_STP_CON0); | ||
165 | |||
166 | /* apply led group settings */ | ||
167 | xway_stp_w32_mask(chip->virt, XWAY_STP_GROUP_MASK, | ||
168 | chip->groups, XWAY_STP_CON1); | ||
169 | |||
170 | /* tell the hardware which pins are controlled by the dsl modem */ | ||
171 | xway_stp_w32_mask(chip->virt, | ||
172 | XWAY_STP_ADSL_MASK << XWAY_STP_ADSL_SHIFT, | ||
173 | chip->dsl << XWAY_STP_ADSL_SHIFT, | ||
174 | XWAY_STP_CON0); | ||
175 | |||
176 | /* tell the hardware which pins are controlled by the phys */ | ||
177 | xway_stp_w32_mask(chip->virt, | ||
178 | XWAY_STP_PHY_MASK << XWAY_STP_PHY1_SHIFT, | ||
179 | chip->phy1 << XWAY_STP_PHY1_SHIFT, | ||
180 | XWAY_STP_CON0); | ||
181 | xway_stp_w32_mask(chip->virt, | ||
182 | XWAY_STP_PHY_MASK << XWAY_STP_PHY2_SHIFT, | ||
183 | chip->phy2 << XWAY_STP_PHY2_SHIFT, | ||
184 | XWAY_STP_CON1); | ||
185 | |||
186 | /* mask out the hw driven bits in gpio_request */ | ||
187 | chip->reserved = (chip->phy2 << 5) | (chip->phy1 << 2) | chip->dsl; | ||
188 | |||
189 | /* | ||
190 | * if we have pins that are driven by hw, we need to tell the stp what | ||
191 | * clock to use as a timer. | ||
192 | */ | ||
193 | if (chip->reserved) | ||
194 | xway_stp_w32_mask(chip->virt, XWAY_STP_UPD_MASK, | ||
195 | XWAY_STP_UPD_FPI, XWAY_STP_CON1); | ||
196 | |||
197 | return 0; | ||
198 | } | ||
199 | |||
200 | static int __devinit xway_stp_probe(struct platform_device *pdev) | ||
201 | { | ||
202 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
203 | const __be32 *shadow, *groups, *dsl, *phy; | ||
204 | struct xway_stp *chip; | ||
205 | struct clk *clk; | ||
206 | int ret = 0; | ||
207 | |||
208 | if (!res) { | ||
209 | dev_err(&pdev->dev, "failed to request STP resource\n"); | ||
210 | return -ENOENT; | ||
211 | } | ||
212 | |||
213 | chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); | ||
214 | if (!chip) | ||
215 | return -ENOMEM; | ||
216 | |||
217 | chip->virt = devm_request_and_ioremap(&pdev->dev, res); | ||
218 | if (!chip->virt) { | ||
219 | dev_err(&pdev->dev, "failed to remap STP memory\n"); | ||
220 | return -ENOMEM; | ||
221 | } | ||
222 | chip->gc.dev = &pdev->dev; | ||
223 | chip->gc.label = "stp-xway"; | ||
224 | chip->gc.direction_output = xway_stp_dir_out; | ||
225 | chip->gc.set = xway_stp_set; | ||
226 | chip->gc.request = xway_stp_request; | ||
227 | chip->gc.base = -1; | ||
228 | chip->gc.owner = THIS_MODULE; | ||
229 | |||
230 | /* store the shadow value if one was passed by the devicetree */ | ||
231 | shadow = of_get_property(pdev->dev.of_node, "lantiq,shadow", NULL); | ||
232 | if (shadow) | ||
233 | chip->shadow = be32_to_cpu(*shadow); | ||
234 | |||
235 | /* find out which gpio groups should be enabled */ | ||
236 | groups = of_get_property(pdev->dev.of_node, "lantiq,groups", NULL); | ||
237 | if (groups) | ||
238 | chip->groups = be32_to_cpu(*groups) & XWAY_STP_GROUP_MASK; | ||
239 | else | ||
240 | chip->groups = XWAY_STP_GROUP0; | ||
241 | chip->gc.ngpio = fls(chip->groups) * 8; | ||
242 | |||
243 | /* find out which gpios are controlled by the dsl core */ | ||
244 | dsl = of_get_property(pdev->dev.of_node, "lantiq,dsl", NULL); | ||
245 | if (dsl) | ||
246 | chip->dsl = be32_to_cpu(*dsl) & XWAY_STP_ADSL_MASK; | ||
247 | |||
248 | /* find out which gpios are controlled by the phys */ | ||
249 | if (of_machine_is_compatible("lantiq,ar9") || | ||
250 | of_machine_is_compatible("lantiq,gr9") || | ||
251 | of_machine_is_compatible("lantiq,vr9")) { | ||
252 | phy = of_get_property(pdev->dev.of_node, "lantiq,phy1", NULL); | ||
253 | if (phy) | ||
254 | chip->phy1 = be32_to_cpu(*phy) & XWAY_STP_PHY_MASK; | ||
255 | phy = of_get_property(pdev->dev.of_node, "lantiq,phy2", NULL); | ||
256 | if (phy) | ||
257 | chip->phy2 = be32_to_cpu(*phy) & XWAY_STP_PHY_MASK; | ||
258 | } | ||
259 | |||
260 | /* check which edge trigger we should use, default to a falling edge */ | ||
261 | if (!of_find_property(pdev->dev.of_node, "lantiq,rising", NULL)) | ||
262 | chip->edge = XWAY_STP_FALLING; | ||
263 | |||
264 | clk = clk_get(&pdev->dev, NULL); | ||
265 | if (IS_ERR(clk)) { | ||
266 | dev_err(&pdev->dev, "Failed to get clock\n"); | ||
267 | return PTR_ERR(clk); | ||
268 | } | ||
269 | clk_enable(clk); | ||
270 | |||
271 | ret = xway_stp_hw_init(chip); | ||
272 | if (!ret) | ||
273 | ret = gpiochip_add(&chip->gc); | ||
274 | |||
275 | if (!ret) | ||
276 | dev_info(&pdev->dev, "Init done\n"); | ||
277 | |||
278 | return ret; | ||
279 | } | ||
280 | |||
281 | static const struct of_device_id xway_stp_match[] = { | ||
282 | { .compatible = "lantiq,gpio-stp-xway" }, | ||
283 | {}, | ||
284 | }; | ||
285 | MODULE_DEVICE_TABLE(of, xway_stp_match); | ||
286 | |||
287 | static struct platform_driver xway_stp_driver = { | ||
288 | .probe = xway_stp_probe, | ||
289 | .driver = { | ||
290 | .name = "gpio-stp-xway", | ||
291 | .owner = THIS_MODULE, | ||
292 | .of_match_table = xway_stp_match, | ||
293 | }, | ||
294 | }; | ||
295 | |||
296 | int __init xway_stp_init(void) | ||
297 | { | ||
298 | return platform_driver_register(&xway_stp_driver); | ||
299 | } | ||
300 | |||
301 | subsys_initcall(xway_stp_init); | ||
diff --git a/drivers/mtd/maps/lantiq-flash.c b/drivers/mtd/maps/lantiq-flash.c index b5401e355745..c03456f17004 100644 --- a/drivers/mtd/maps/lantiq-flash.c +++ b/drivers/mtd/maps/lantiq-flash.c | |||
@@ -19,9 +19,9 @@ | |||
19 | #include <linux/mtd/cfi.h> | 19 | #include <linux/mtd/cfi.h> |
20 | #include <linux/platform_device.h> | 20 | #include <linux/platform_device.h> |
21 | #include <linux/mtd/physmap.h> | 21 | #include <linux/mtd/physmap.h> |
22 | #include <linux/of.h> | ||
22 | 23 | ||
23 | #include <lantiq_soc.h> | 24 | #include <lantiq_soc.h> |
24 | #include <lantiq_platform.h> | ||
25 | 25 | ||
26 | /* | 26 | /* |
27 | * The NOR flash is connected to the same external bus unit (EBU) as PCI. | 27 | * The NOR flash is connected to the same external bus unit (EBU) as PCI. |
@@ -44,8 +44,9 @@ struct ltq_mtd { | |||
44 | struct map_info *map; | 44 | struct map_info *map; |
45 | }; | 45 | }; |
46 | 46 | ||
47 | static char ltq_map_name[] = "ltq_nor"; | 47 | static const char ltq_map_name[] = "ltq_nor"; |
48 | static const char *ltq_probe_types[] __devinitconst = { "cmdlinepart", NULL }; | 48 | static const char *ltq_probe_types[] __devinitconst = { |
49 | "cmdlinepart", "ofpart", NULL }; | ||
49 | 50 | ||
50 | static map_word | 51 | static map_word |
51 | ltq_read16(struct map_info *map, unsigned long adr) | 52 | ltq_read16(struct map_info *map, unsigned long adr) |
@@ -108,42 +109,38 @@ ltq_copy_to(struct map_info *map, unsigned long to, | |||
108 | spin_unlock_irqrestore(&ebu_lock, flags); | 109 | spin_unlock_irqrestore(&ebu_lock, flags); |
109 | } | 110 | } |
110 | 111 | ||
111 | static int __init | 112 | static int __devinit |
112 | ltq_mtd_probe(struct platform_device *pdev) | 113 | ltq_mtd_probe(struct platform_device *pdev) |
113 | { | 114 | { |
114 | struct physmap_flash_data *ltq_mtd_data = dev_get_platdata(&pdev->dev); | 115 | struct mtd_part_parser_data ppdata; |
115 | struct ltq_mtd *ltq_mtd; | 116 | struct ltq_mtd *ltq_mtd; |
116 | struct resource *res; | ||
117 | struct cfi_private *cfi; | 117 | struct cfi_private *cfi; |
118 | int err; | 118 | int err; |
119 | 119 | ||
120 | if (of_machine_is_compatible("lantiq,falcon") && | ||
121 | (ltq_boot_select() != BS_FLASH)) { | ||
122 | dev_err(&pdev->dev, "invalid bootstrap options\n"); | ||
123 | return -ENODEV; | ||
124 | } | ||
125 | |||
120 | ltq_mtd = kzalloc(sizeof(struct ltq_mtd), GFP_KERNEL); | 126 | ltq_mtd = kzalloc(sizeof(struct ltq_mtd), GFP_KERNEL); |
121 | platform_set_drvdata(pdev, ltq_mtd); | 127 | platform_set_drvdata(pdev, ltq_mtd); |
122 | 128 | ||
123 | ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 129 | ltq_mtd->res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
124 | if (!ltq_mtd->res) { | 130 | if (!ltq_mtd->res) { |
125 | dev_err(&pdev->dev, "failed to get memory resource"); | 131 | dev_err(&pdev->dev, "failed to get memory resource\n"); |
126 | err = -ENOENT; | 132 | err = -ENOENT; |
127 | goto err_out; | 133 | goto err_out; |
128 | } | 134 | } |
129 | 135 | ||
130 | res = devm_request_mem_region(&pdev->dev, ltq_mtd->res->start, | ||
131 | resource_size(ltq_mtd->res), dev_name(&pdev->dev)); | ||
132 | if (!ltq_mtd->res) { | ||
133 | dev_err(&pdev->dev, "failed to request mem resource"); | ||
134 | err = -EBUSY; | ||
135 | goto err_out; | ||
136 | } | ||
137 | |||
138 | ltq_mtd->map = kzalloc(sizeof(struct map_info), GFP_KERNEL); | 136 | ltq_mtd->map = kzalloc(sizeof(struct map_info), GFP_KERNEL); |
139 | ltq_mtd->map->phys = res->start; | 137 | ltq_mtd->map->phys = ltq_mtd->res->start; |
140 | ltq_mtd->map->size = resource_size(res); | 138 | ltq_mtd->map->size = resource_size(ltq_mtd->res); |
141 | ltq_mtd->map->virt = devm_ioremap_nocache(&pdev->dev, | 139 | ltq_mtd->map->virt = devm_request_and_ioremap(&pdev->dev, ltq_mtd->res); |
142 | ltq_mtd->map->phys, ltq_mtd->map->size); | ||
143 | if (!ltq_mtd->map->virt) { | 140 | if (!ltq_mtd->map->virt) { |
144 | dev_err(&pdev->dev, "failed to ioremap!\n"); | 141 | dev_err(&pdev->dev, "failed to remap mem resource\n"); |
145 | err = -ENOMEM; | 142 | err = -EBUSY; |
146 | goto err_free; | 143 | goto err_out; |
147 | } | 144 | } |
148 | 145 | ||
149 | ltq_mtd->map->name = ltq_map_name; | 146 | ltq_mtd->map->name = ltq_map_name; |
@@ -169,9 +166,9 @@ ltq_mtd_probe(struct platform_device *pdev) | |||
169 | cfi->addr_unlock1 ^= 1; | 166 | cfi->addr_unlock1 ^= 1; |
170 | cfi->addr_unlock2 ^= 1; | 167 | cfi->addr_unlock2 ^= 1; |
171 | 168 | ||
172 | err = mtd_device_parse_register(ltq_mtd->mtd, ltq_probe_types, NULL, | 169 | ppdata.of_node = pdev->dev.of_node; |
173 | ltq_mtd_data->parts, | 170 | err = mtd_device_parse_register(ltq_mtd->mtd, ltq_probe_types, |
174 | ltq_mtd_data->nr_parts); | 171 | &ppdata, NULL, 0); |
175 | if (err) { | 172 | if (err) { |
176 | dev_err(&pdev->dev, "failed to add partitions\n"); | 173 | dev_err(&pdev->dev, "failed to add partitions\n"); |
177 | goto err_destroy; | 174 | goto err_destroy; |
@@ -204,32 +201,23 @@ ltq_mtd_remove(struct platform_device *pdev) | |||
204 | return 0; | 201 | return 0; |
205 | } | 202 | } |
206 | 203 | ||
204 | static const struct of_device_id ltq_mtd_match[] = { | ||
205 | { .compatible = "lantiq,nor" }, | ||
206 | {}, | ||
207 | }; | ||
208 | MODULE_DEVICE_TABLE(of, ltq_mtd_match); | ||
209 | |||
207 | static struct platform_driver ltq_mtd_driver = { | 210 | static struct platform_driver ltq_mtd_driver = { |
211 | .probe = ltq_mtd_probe, | ||
208 | .remove = __devexit_p(ltq_mtd_remove), | 212 | .remove = __devexit_p(ltq_mtd_remove), |
209 | .driver = { | 213 | .driver = { |
210 | .name = "ltq_nor", | 214 | .name = "ltq-nor", |
211 | .owner = THIS_MODULE, | 215 | .owner = THIS_MODULE, |
216 | .of_match_table = ltq_mtd_match, | ||
212 | }, | 217 | }, |
213 | }; | 218 | }; |
214 | 219 | ||
215 | static int __init | 220 | module_platform_driver(ltq_mtd_driver); |
216 | init_ltq_mtd(void) | ||
217 | { | ||
218 | int ret = platform_driver_probe(<q_mtd_driver, ltq_mtd_probe); | ||
219 | |||
220 | if (ret) | ||
221 | pr_err("ltq_nor: error registering platform driver"); | ||
222 | return ret; | ||
223 | } | ||
224 | |||
225 | static void __exit | ||
226 | exit_ltq_mtd(void) | ||
227 | { | ||
228 | platform_driver_unregister(<q_mtd_driver); | ||
229 | } | ||
230 | |||
231 | module_init(init_ltq_mtd); | ||
232 | module_exit(exit_ltq_mtd); | ||
233 | 221 | ||
234 | MODULE_LICENSE("GPL"); | 222 | MODULE_LICENSE("GPL"); |
235 | MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); | 223 | MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); |
diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c index 93125163dea2..677053813211 100644 --- a/drivers/of/of_pci_irq.c +++ b/drivers/of/of_pci_irq.c | |||
@@ -15,7 +15,7 @@ | |||
15 | * PCI tree until an device-node is found, at which point it will finish | 15 | * PCI tree until an device-node is found, at which point it will finish |
16 | * resolving using the OF tree walking. | 16 | * resolving using the OF tree walking. |
17 | */ | 17 | */ |
18 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq) | 18 | int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq) |
19 | { | 19 | { |
20 | struct device_node *dn, *ppnode; | 20 | struct device_node *dn, *ppnode; |
21 | struct pci_dev *ppdev; | 21 | struct pci_dev *ppdev; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 111569ccab43..8b91fe741f6a 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -2369,7 +2369,7 @@ void pci_enable_acs(struct pci_dev *dev) | |||
2369 | * number is always 0 (see the Implementation Note in section 2.2.8.1 of | 2369 | * number is always 0 (see the Implementation Note in section 2.2.8.1 of |
2370 | * the PCI Express Base Specification, Revision 2.1) | 2370 | * the PCI Express Base Specification, Revision 2.1) |
2371 | */ | 2371 | */ |
2372 | u8 pci_swizzle_interrupt_pin(struct pci_dev *dev, u8 pin) | 2372 | u8 pci_swizzle_interrupt_pin(const struct pci_dev *dev, u8 pin) |
2373 | { | 2373 | { |
2374 | int slot; | 2374 | int slot; |
2375 | 2375 | ||
diff --git a/drivers/tty/serial/lantiq.c b/drivers/tty/serial/lantiq.c index 96c1cacc7360..02da071fe1e7 100644 --- a/drivers/tty/serial/lantiq.c +++ b/drivers/tty/serial/lantiq.c | |||
@@ -31,16 +31,19 @@ | |||
31 | #include <linux/tty_flip.h> | 31 | #include <linux/tty_flip.h> |
32 | #include <linux/serial_core.h> | 32 | #include <linux/serial_core.h> |
33 | #include <linux/serial.h> | 33 | #include <linux/serial.h> |
34 | #include <linux/platform_device.h> | 34 | #include <linux/of_platform.h> |
35 | #include <linux/of_address.h> | ||
36 | #include <linux/of_irq.h> | ||
35 | #include <linux/io.h> | 37 | #include <linux/io.h> |
36 | #include <linux/clk.h> | 38 | #include <linux/clk.h> |
39 | #include <linux/gpio.h> | ||
37 | 40 | ||
38 | #include <lantiq_soc.h> | 41 | #include <lantiq_soc.h> |
39 | 42 | ||
40 | #define PORT_LTQ_ASC 111 | 43 | #define PORT_LTQ_ASC 111 |
41 | #define MAXPORTS 2 | 44 | #define MAXPORTS 2 |
42 | #define UART_DUMMY_UER_RX 1 | 45 | #define UART_DUMMY_UER_RX 1 |
43 | #define DRVNAME "ltq_asc" | 46 | #define DRVNAME "lantiq,asc" |
44 | #ifdef __BIG_ENDIAN | 47 | #ifdef __BIG_ENDIAN |
45 | #define LTQ_ASC_TBUF (0x0020 + 3) | 48 | #define LTQ_ASC_TBUF (0x0020 + 3) |
46 | #define LTQ_ASC_RBUF (0x0024 + 3) | 49 | #define LTQ_ASC_RBUF (0x0024 + 3) |
@@ -114,6 +117,9 @@ static DEFINE_SPINLOCK(ltq_asc_lock); | |||
114 | 117 | ||
115 | struct ltq_uart_port { | 118 | struct ltq_uart_port { |
116 | struct uart_port port; | 119 | struct uart_port port; |
120 | /* clock used to derive divider */ | ||
121 | struct clk *fpiclk; | ||
122 | /* clock gating of the ASC core */ | ||
117 | struct clk *clk; | 123 | struct clk *clk; |
118 | unsigned int tx_irq; | 124 | unsigned int tx_irq; |
119 | unsigned int rx_irq; | 125 | unsigned int rx_irq; |
@@ -316,7 +322,9 @@ lqasc_startup(struct uart_port *port) | |||
316 | struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); | 322 | struct ltq_uart_port *ltq_port = to_ltq_uart_port(port); |
317 | int retval; | 323 | int retval; |
318 | 324 | ||
319 | port->uartclk = clk_get_rate(ltq_port->clk); | 325 | if (ltq_port->clk) |
326 | clk_enable(ltq_port->clk); | ||
327 | port->uartclk = clk_get_rate(ltq_port->fpiclk); | ||
320 | 328 | ||
321 | ltq_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET), | 329 | ltq_w32_mask(ASCCLC_DISS | ASCCLC_RMCMASK, (1 << ASCCLC_RMCOFFSET), |
322 | port->membase + LTQ_ASC_CLC); | 330 | port->membase + LTQ_ASC_CLC); |
@@ -382,6 +390,8 @@ lqasc_shutdown(struct uart_port *port) | |||
382 | port->membase + LTQ_ASC_RXFCON); | 390 | port->membase + LTQ_ASC_RXFCON); |
383 | ltq_w32_mask(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU, | 391 | ltq_w32_mask(ASCTXFCON_TXFEN, ASCTXFCON_TXFFLU, |
384 | port->membase + LTQ_ASC_TXFCON); | 392 | port->membase + LTQ_ASC_TXFCON); |
393 | if (ltq_port->clk) | ||
394 | clk_disable(ltq_port->clk); | ||
385 | } | 395 | } |
386 | 396 | ||
387 | static void | 397 | static void |
@@ -630,7 +640,7 @@ lqasc_console_setup(struct console *co, char *options) | |||
630 | 640 | ||
631 | port = <q_port->port; | 641 | port = <q_port->port; |
632 | 642 | ||
633 | port->uartclk = clk_get_rate(ltq_port->clk); | 643 | port->uartclk = clk_get_rate(ltq_port->fpiclk); |
634 | 644 | ||
635 | if (options) | 645 | if (options) |
636 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 646 | uart_parse_options(options, &baud, &parity, &bits, &flow); |
@@ -668,37 +678,32 @@ static struct uart_driver lqasc_reg = { | |||
668 | static int __init | 678 | static int __init |
669 | lqasc_probe(struct platform_device *pdev) | 679 | lqasc_probe(struct platform_device *pdev) |
670 | { | 680 | { |
681 | struct device_node *node = pdev->dev.of_node; | ||
671 | struct ltq_uart_port *ltq_port; | 682 | struct ltq_uart_port *ltq_port; |
672 | struct uart_port *port; | 683 | struct uart_port *port; |
673 | struct resource *mmres, *irqres; | 684 | struct resource *mmres, irqres[3]; |
674 | int tx_irq, rx_irq, err_irq; | 685 | int line = 0; |
675 | struct clk *clk; | ||
676 | int ret; | 686 | int ret; |
677 | 687 | ||
678 | mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 688 | mmres = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
679 | irqres = platform_get_resource(pdev, IORESOURCE_IRQ, 0); | 689 | ret = of_irq_to_resource_table(node, irqres, 3); |
680 | if (!mmres || !irqres) | 690 | if (!mmres || (ret != 3)) { |
691 | dev_err(&pdev->dev, | ||
692 | "failed to get memory/irq for serial port\n"); | ||
681 | return -ENODEV; | 693 | return -ENODEV; |
694 | } | ||
682 | 695 | ||
683 | if (pdev->id >= MAXPORTS) | 696 | /* check if this is the console port */ |
684 | return -EBUSY; | 697 | if (mmres->start != CPHYSADDR(LTQ_EARLY_ASC)) |
698 | line = 1; | ||
685 | 699 | ||
686 | if (lqasc_port[pdev->id] != NULL) | 700 | if (lqasc_port[line]) { |
701 | dev_err(&pdev->dev, "port %d already allocated\n", line); | ||
687 | return -EBUSY; | 702 | return -EBUSY; |
688 | |||
689 | clk = clk_get(&pdev->dev, "fpi"); | ||
690 | if (IS_ERR(clk)) { | ||
691 | pr_err("failed to get fpi clk\n"); | ||
692 | return -ENOENT; | ||
693 | } | 703 | } |
694 | 704 | ||
695 | tx_irq = platform_get_irq_byname(pdev, "tx"); | 705 | ltq_port = devm_kzalloc(&pdev->dev, sizeof(struct ltq_uart_port), |
696 | rx_irq = platform_get_irq_byname(pdev, "rx"); | 706 | GFP_KERNEL); |
697 | err_irq = platform_get_irq_byname(pdev, "err"); | ||
698 | if ((tx_irq < 0) | (rx_irq < 0) | (err_irq < 0)) | ||
699 | return -ENODEV; | ||
700 | |||
701 | ltq_port = kzalloc(sizeof(struct ltq_uart_port), GFP_KERNEL); | ||
702 | if (!ltq_port) | 707 | if (!ltq_port) |
703 | return -ENOMEM; | 708 | return -ENOMEM; |
704 | 709 | ||
@@ -709,19 +714,26 @@ lqasc_probe(struct platform_device *pdev) | |||
709 | port->ops = &lqasc_pops; | 714 | port->ops = &lqasc_pops; |
710 | port->fifosize = 16; | 715 | port->fifosize = 16; |
711 | port->type = PORT_LTQ_ASC, | 716 | port->type = PORT_LTQ_ASC, |
712 | port->line = pdev->id; | 717 | port->line = line; |
713 | port->dev = &pdev->dev; | 718 | port->dev = &pdev->dev; |
714 | 719 | /* unused, just to be backward-compatible */ | |
715 | port->irq = tx_irq; /* unused, just to be backward-compatibe */ | 720 | port->irq = irqres[0].start; |
716 | port->mapbase = mmres->start; | 721 | port->mapbase = mmres->start; |
717 | 722 | ||
718 | ltq_port->clk = clk; | 723 | ltq_port->fpiclk = clk_get_fpi(); |
724 | if (IS_ERR(ltq_port->fpiclk)) { | ||
725 | pr_err("failed to get fpi clk\n"); | ||
726 | return -ENOENT; | ||
727 | } | ||
719 | 728 | ||
720 | ltq_port->tx_irq = tx_irq; | 729 | /* not all asc ports have clock gates, lets ignore the return code */ |
721 | ltq_port->rx_irq = rx_irq; | 730 | ltq_port->clk = clk_get(&pdev->dev, NULL); |
722 | ltq_port->err_irq = err_irq; | ||
723 | 731 | ||
724 | lqasc_port[pdev->id] = ltq_port; | 732 | ltq_port->tx_irq = irqres[0].start; |
733 | ltq_port->rx_irq = irqres[1].start; | ||
734 | ltq_port->err_irq = irqres[2].start; | ||
735 | |||
736 | lqasc_port[line] = ltq_port; | ||
725 | platform_set_drvdata(pdev, ltq_port); | 737 | platform_set_drvdata(pdev, ltq_port); |
726 | 738 | ||
727 | ret = uart_add_one_port(&lqasc_reg, port); | 739 | ret = uart_add_one_port(&lqasc_reg, port); |
@@ -729,10 +741,17 @@ lqasc_probe(struct platform_device *pdev) | |||
729 | return ret; | 741 | return ret; |
730 | } | 742 | } |
731 | 743 | ||
744 | static const struct of_device_id ltq_asc_match[] = { | ||
745 | { .compatible = DRVNAME }, | ||
746 | {}, | ||
747 | }; | ||
748 | MODULE_DEVICE_TABLE(of, ltq_asc_match); | ||
749 | |||
732 | static struct platform_driver lqasc_driver = { | 750 | static struct platform_driver lqasc_driver = { |
733 | .driver = { | 751 | .driver = { |
734 | .name = DRVNAME, | 752 | .name = DRVNAME, |
735 | .owner = THIS_MODULE, | 753 | .owner = THIS_MODULE, |
754 | .of_match_table = ltq_asc_match, | ||
736 | }, | 755 | }, |
737 | }; | 756 | }; |
738 | 757 | ||
diff --git a/drivers/tty/serial/sb1250-duart.c b/drivers/tty/serial/sb1250-duart.c index 0be8a2f00d0b..f76b1688c5c8 100644 --- a/drivers/tty/serial/sb1250-duart.c +++ b/drivers/tty/serial/sb1250-duart.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | #include <linux/ioport.h> | 32 | #include <linux/ioport.h> |
33 | #include <linux/kernel.h> | 33 | #include <linux/kernel.h> |
34 | #include <linux/module.h> | ||
34 | #include <linux/major.h> | 35 | #include <linux/major.h> |
35 | #include <linux/serial.h> | 36 | #include <linux/serial.h> |
36 | #include <linux/serial_core.h> | 37 | #include <linux/serial_core.h> |
diff --git a/drivers/tty/serial/zs.c b/drivers/tty/serial/zs.c index 4001eee6c08d..92c00b24d0df 100644 --- a/drivers/tty/serial/zs.c +++ b/drivers/tty/serial/zs.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #include <linux/ioport.h> | 57 | #include <linux/ioport.h> |
58 | #include <linux/irqflags.h> | 58 | #include <linux/irqflags.h> |
59 | #include <linux/kernel.h> | 59 | #include <linux/kernel.h> |
60 | #include <linux/module.h> | ||
60 | #include <linux/major.h> | 61 | #include <linux/major.h> |
61 | #include <linux/serial.h> | 62 | #include <linux/serial.h> |
62 | #include <linux/serial_core.h> | 63 | #include <linux/serial_core.h> |
diff --git a/drivers/watchdog/lantiq_wdt.c b/drivers/watchdog/lantiq_wdt.c index a9593a3a32a0..2e74c3a8ee58 100644 --- a/drivers/watchdog/lantiq_wdt.c +++ b/drivers/watchdog/lantiq_wdt.c | |||
@@ -13,14 +13,15 @@ | |||
13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
14 | #include <linux/miscdevice.h> | 14 | #include <linux/miscdevice.h> |
15 | #include <linux/watchdog.h> | 15 | #include <linux/watchdog.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/of_platform.h> |
17 | #include <linux/uaccess.h> | 17 | #include <linux/uaccess.h> |
18 | #include <linux/clk.h> | 18 | #include <linux/clk.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | 20 | ||
21 | #include <lantiq.h> | 21 | #include <lantiq_soc.h> |
22 | 22 | ||
23 | /* Section 3.4 of the datasheet | 23 | /* |
24 | * Section 3.4 of the datasheet | ||
24 | * The password sequence protects the WDT control register from unintended | 25 | * The password sequence protects the WDT control register from unintended |
25 | * write actions, which might cause malfunction of the WDT. | 26 | * write actions, which might cause malfunction of the WDT. |
26 | * | 27 | * |
@@ -70,7 +71,8 @@ ltq_wdt_disable(void) | |||
70 | { | 71 | { |
71 | /* write the first password magic */ | 72 | /* write the first password magic */ |
72 | ltq_w32(LTQ_WDT_PW1, ltq_wdt_membase + LTQ_WDT_CR); | 73 | ltq_w32(LTQ_WDT_PW1, ltq_wdt_membase + LTQ_WDT_CR); |
73 | /* write the second password magic with no config | 74 | /* |
75 | * write the second password magic with no config | ||
74 | * this turns the watchdog off | 76 | * this turns the watchdog off |
75 | */ | 77 | */ |
76 | ltq_w32(LTQ_WDT_PW2, ltq_wdt_membase + LTQ_WDT_CR); | 78 | ltq_w32(LTQ_WDT_PW2, ltq_wdt_membase + LTQ_WDT_CR); |
@@ -184,7 +186,7 @@ static struct miscdevice ltq_wdt_miscdev = { | |||
184 | .fops = <q_wdt_fops, | 186 | .fops = <q_wdt_fops, |
185 | }; | 187 | }; |
186 | 188 | ||
187 | static int __init | 189 | static int __devinit |
188 | ltq_wdt_probe(struct platform_device *pdev) | 190 | ltq_wdt_probe(struct platform_device *pdev) |
189 | { | 191 | { |
190 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 192 | struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
@@ -194,28 +196,27 @@ ltq_wdt_probe(struct platform_device *pdev) | |||
194 | dev_err(&pdev->dev, "cannot obtain I/O memory region"); | 196 | dev_err(&pdev->dev, "cannot obtain I/O memory region"); |
195 | return -ENOENT; | 197 | return -ENOENT; |
196 | } | 198 | } |
197 | res = devm_request_mem_region(&pdev->dev, res->start, | 199 | |
198 | resource_size(res), dev_name(&pdev->dev)); | 200 | ltq_wdt_membase = devm_request_and_ioremap(&pdev->dev, res); |
199 | if (!res) { | ||
200 | dev_err(&pdev->dev, "cannot request I/O memory region"); | ||
201 | return -EBUSY; | ||
202 | } | ||
203 | ltq_wdt_membase = devm_ioremap_nocache(&pdev->dev, res->start, | ||
204 | resource_size(res)); | ||
205 | if (!ltq_wdt_membase) { | 201 | if (!ltq_wdt_membase) { |
206 | dev_err(&pdev->dev, "cannot remap I/O memory region\n"); | 202 | dev_err(&pdev->dev, "cannot remap I/O memory region\n"); |
207 | return -ENOMEM; | 203 | return -ENOMEM; |
208 | } | 204 | } |
209 | 205 | ||
210 | /* we do not need to enable the clock as it is always running */ | 206 | /* we do not need to enable the clock as it is always running */ |
211 | clk = clk_get(&pdev->dev, "io"); | 207 | clk = clk_get_io(); |
212 | WARN_ON(!clk); | 208 | if (IS_ERR(clk)) { |
209 | dev_err(&pdev->dev, "Failed to get clock\n"); | ||
210 | return -ENOENT; | ||
211 | } | ||
213 | ltq_io_region_clk_rate = clk_get_rate(clk); | 212 | ltq_io_region_clk_rate = clk_get_rate(clk); |
214 | clk_put(clk); | 213 | clk_put(clk); |
215 | 214 | ||
215 | /* find out if the watchdog caused the last reboot */ | ||
216 | if (ltq_reset_cause() == LTQ_RST_CAUSE_WDTRST) | 216 | if (ltq_reset_cause() == LTQ_RST_CAUSE_WDTRST) |
217 | ltq_wdt_bootstatus = WDIOF_CARDRESET; | 217 | ltq_wdt_bootstatus = WDIOF_CARDRESET; |
218 | 218 | ||
219 | dev_info(&pdev->dev, "Init done\n"); | ||
219 | return misc_register(<q_wdt_miscdev); | 220 | return misc_register(<q_wdt_miscdev); |
220 | } | 221 | } |
221 | 222 | ||
@@ -227,33 +228,26 @@ ltq_wdt_remove(struct platform_device *pdev) | |||
227 | return 0; | 228 | return 0; |
228 | } | 229 | } |
229 | 230 | ||
231 | static const struct of_device_id ltq_wdt_match[] = { | ||
232 | { .compatible = "lantiq,wdt" }, | ||
233 | {}, | ||
234 | }; | ||
235 | MODULE_DEVICE_TABLE(of, ltq_wdt_match); | ||
230 | 236 | ||
231 | static struct platform_driver ltq_wdt_driver = { | 237 | static struct platform_driver ltq_wdt_driver = { |
238 | .probe = ltq_wdt_probe, | ||
232 | .remove = __devexit_p(ltq_wdt_remove), | 239 | .remove = __devexit_p(ltq_wdt_remove), |
233 | .driver = { | 240 | .driver = { |
234 | .name = "ltq_wdt", | 241 | .name = "wdt", |
235 | .owner = THIS_MODULE, | 242 | .owner = THIS_MODULE, |
243 | .of_match_table = ltq_wdt_match, | ||
236 | }, | 244 | }, |
237 | }; | 245 | }; |
238 | 246 | ||
239 | static int __init | 247 | module_platform_driver(ltq_wdt_driver); |
240 | init_ltq_wdt(void) | ||
241 | { | ||
242 | return platform_driver_probe(<q_wdt_driver, ltq_wdt_probe); | ||
243 | } | ||
244 | |||
245 | static void __exit | ||
246 | exit_ltq_wdt(void) | ||
247 | { | ||
248 | return platform_driver_unregister(<q_wdt_driver); | ||
249 | } | ||
250 | |||
251 | module_init(init_ltq_wdt); | ||
252 | module_exit(exit_ltq_wdt); | ||
253 | 248 | ||
254 | module_param(nowayout, bool, 0); | 249 | module_param(nowayout, bool, 0); |
255 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); | 250 | MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started"); |
256 | |||
257 | MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); | 251 | MODULE_AUTHOR("John Crispin <blogic@openwrt.org>"); |
258 | MODULE_DESCRIPTION("Lantiq SoC Watchdog"); | 252 | MODULE_DESCRIPTION("Lantiq SoC Watchdog"); |
259 | MODULE_LICENSE("GPL"); | 253 | MODULE_LICENSE("GPL"); |
diff --git a/include/linux/of_pci.h b/include/linux/of_pci.h index f93e21700d3e..bb115deb7612 100644 --- a/include/linux/of_pci.h +++ b/include/linux/of_pci.h | |||
@@ -5,7 +5,7 @@ | |||
5 | 5 | ||
6 | struct pci_dev; | 6 | struct pci_dev; |
7 | struct of_irq; | 7 | struct of_irq; |
8 | int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); | 8 | int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq); |
9 | 9 | ||
10 | struct device_node; | 10 | struct device_node; |
11 | struct device_node *of_pci_find_child_device(struct device_node *parent, | 11 | struct device_node *of_pci_find_child_device(struct device_node *parent, |
diff --git a/include/linux/pci.h b/include/linux/pci.h index e444f5b49118..3bbc77e20a61 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -680,7 +680,7 @@ int __must_check pci_bus_add_device(struct pci_dev *dev); | |||
680 | void pci_read_bridge_bases(struct pci_bus *child); | 680 | void pci_read_bridge_bases(struct pci_bus *child); |
681 | struct resource *pci_find_parent_resource(const struct pci_dev *dev, | 681 | struct resource *pci_find_parent_resource(const struct pci_dev *dev, |
682 | struct resource *res); | 682 | struct resource *res); |
683 | u8 pci_swizzle_interrupt_pin(struct pci_dev *dev, u8 pin); | 683 | u8 pci_swizzle_interrupt_pin(const struct pci_dev *dev, u8 pin); |
684 | int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); | 684 | int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); |
685 | u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp); | 685 | u8 pci_common_swizzle(struct pci_dev *dev, u8 *pinp); |
686 | extern struct pci_dev *pci_dev_get(struct pci_dev *dev); | 686 | extern struct pci_dev *pci_dev_get(struct pci_dev *dev); |
@@ -1685,7 +1685,8 @@ extern void pci_release_bus_of_node(struct pci_bus *bus); | |||
1685 | /* Arch may override this (weak) */ | 1685 | /* Arch may override this (weak) */ |
1686 | extern struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus); | 1686 | extern struct device_node * __weak pcibios_get_phb_of_node(struct pci_bus *bus); |
1687 | 1687 | ||
1688 | static inline struct device_node *pci_device_to_OF_node(struct pci_dev *pdev) | 1688 | static inline struct device_node * |
1689 | pci_device_to_OF_node(const struct pci_dev *pdev) | ||
1689 | { | 1690 | { |
1690 | return pdev ? pdev->dev.of_node : NULL; | 1691 | return pdev ? pdev->dev.of_node : NULL; |
1691 | } | 1692 | } |