aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/ath79
diff options
context:
space:
mode:
Diffstat (limited to 'arch/mips/ath79')
-rw-r--r--arch/mips/ath79/Kconfig25
-rw-r--r--arch/mips/ath79/Makefile2
-rw-r--r--arch/mips/ath79/clock.c81
-rw-r--r--arch/mips/ath79/common.c9
-rw-r--r--arch/mips/ath79/dev-common.c3
-rw-r--r--arch/mips/ath79/dev-gpio-buttons.c4
-rw-r--r--arch/mips/ath79/dev-leds-gpio.c4
-rw-r--r--arch/mips/ath79/dev-wmac.c30
-rw-r--r--arch/mips/ath79/early_printk.c3
-rw-r--r--arch/mips/ath79/gpio.c47
-rw-r--r--arch/mips/ath79/irq.c147
-rw-r--r--arch/mips/ath79/mach-db120.c134
-rw-r--r--arch/mips/ath79/mach-pb44.c2
-rw-r--r--arch/mips/ath79/mach-ubnt-xm.c43
-rw-r--r--arch/mips/ath79/machtypes.h1
-rw-r--r--arch/mips/ath79/pci.c130
-rw-r--r--arch/mips/ath79/pci.h34
-rw-r--r--arch/mips/ath79/setup.c45
18 files changed, 679 insertions, 65 deletions
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
29config 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
29config ATH79_MACH_PB44 41config 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
52config SOC_AR71XX 64config 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
57config SOC_AR724X 70config 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
63config SOC_AR913X 77config 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
85config SOC_AR934X
86 select USB_ARCH_HAS_EHCI
87 select HW_HAS_PCI
88 select PCI_AR724X if PCI
89 def_bool n
90
91config PCI_AR724X
92 def_bool n
93
71config ATH79_DEV_GPIO_BUTTONS 94config 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
83config ATH79_DEV_WMAC 106config 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
87endif 110endif
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 @@
11obj-y := prom.o setup.o irq.o common.o clock.o gpio.o 11obj-y := prom.o setup.o irq.o common.o clock.o gpio.o
12 12
13obj-$(CONFIG_EARLY_PRINTK) += early_printk.o 13obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
14obj-$(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#
28obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o 29obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o
29obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o 30obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o
31obj-$(CONFIG_ATH79_MACH_DB120) += mach-db120.o
30obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o 32obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o
31obj-$(CONFIG_ATH79_MACH_UBNT_XM) += mach-ubnt-xm.o 33obj-$(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
169static 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
166void __init ath79_clocks_init(void) 245void __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
101static 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
95void __init ath79_register_wmac(u8 *cal_data) 119void __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
95static 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
110static 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
92static struct gpio_chip ath79_gpio_chip = { 131static 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
26static unsigned int ath79_ip2_flush_reg; 27static void (*ath79_ip2_handler)(void);
27static unsigned int ath79_ip3_flush_reg; 28static void (*ath79_ip3_handler)(void);
28 29
29static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) 30static 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
147static 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
168static 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
146asmlinkage void plat_irq_dispatch(void) 180asmlinkage 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 */
215static 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
221static 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
227static 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
233static 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
239static void ar934x_ip2_handler(void)
240{
241 do_IRQ(ATH79_CPU_IRQ_IP2);
242}
243
244static 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
250static 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
256static 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
262static 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
268static 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
178void __init arch_init_irq(void) 274void __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
44static 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
67static 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
78static 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
87static struct ath79_spi_platform_data db120_spi_data = {
88 .bus_num = 0,
89 .num_chipselect = 1,
90};
91
92#ifdef CONFIG_PCI
93static struct ath9k_platform_data db120_ath9k_data;
94
95static 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
106static 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
115static inline void db120_pci_init(void) {}
116#endif /* CONFIG_PCI */
117
118static 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
133MIPS_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
119MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board", 121MIPS_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
39static struct gpio_led ubnt_xm_leds_gpio[] __initdata = { 37static 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
85static struct ath9k_platform_data ubnt_xm_eeprom_data; 83static struct ath9k_platform_data ubnt_xm_eeprom_data;
86 84
87static struct ath724x_pci_data ubnt_xm_pci_data[] = { 85static 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
96static 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
105static inline void ubnt_xm_pci_init(void) {}
93#endif /* CONFIG_PCI */ 106#endif /* CONFIG_PCI */
94 107
95static void __init ubnt_xm_init(void) 108static 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
116MIPS_MACHINE(ATH79_MACH_UBNT_XM, 123MIPS_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
23static int (*ath79_pci_plat_dev_init)(struct pci_dev *dev);
24static const struct ath79_pci_irq *ath79_pci_irq_map __initdata;
25static unsigned ath79_pci_nr_irqs __initdata;
26
27static 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
43static 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
51int __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
93int 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
101void __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
108void __init ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev))
109{
110 ath79_pci_plat_dev_init = func;
111}
112
113int __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
16struct ath79_pci_irq {
17 u8 slot;
18 u8 pin;
19 int irq;
20};
21
22#ifdef CONFIG_PCI
23void ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map);
24void ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *dev));
25int ath79_register_pci(void);
26#else
27static inline void
28ath79_pci_set_irq_map(unsigned nr_irqs, const struct ath79_pci_irq *map) {}
29static inline void
30ath79_pci_set_plat_dev_init(int (*func)(struct pci_dev *)) {}
31static 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 }