diff options
Diffstat (limited to 'arch/mips/ath79')
-rw-r--r-- | arch/mips/ath79/Kconfig | 50 | ||||
-rw-r--r-- | arch/mips/ath79/Makefile | 28 | ||||
-rw-r--r-- | arch/mips/ath79/Platform | 7 | ||||
-rw-r--r-- | arch/mips/ath79/clock.c | 183 | ||||
-rw-r--r-- | arch/mips/ath79/common.c | 97 | ||||
-rw-r--r-- | arch/mips/ath79/common.h | 31 | ||||
-rw-r--r-- | arch/mips/ath79/dev-ar913x-wmac.c | 60 | ||||
-rw-r--r-- | arch/mips/ath79/dev-ar913x-wmac.h | 17 | ||||
-rw-r--r-- | arch/mips/ath79/dev-common.c | 77 | ||||
-rw-r--r-- | arch/mips/ath79/dev-common.h | 18 | ||||
-rw-r--r-- | arch/mips/ath79/dev-gpio-buttons.c | 58 | ||||
-rw-r--r-- | arch/mips/ath79/dev-gpio-buttons.h | 23 | ||||
-rw-r--r-- | arch/mips/ath79/dev-leds-gpio.c | 56 | ||||
-rw-r--r-- | arch/mips/ath79/dev-leds-gpio.h | 21 | ||||
-rw-r--r-- | arch/mips/ath79/dev-spi.c | 38 | ||||
-rw-r--r-- | arch/mips/ath79/dev-spi.h | 22 | ||||
-rw-r--r-- | arch/mips/ath79/early_printk.c | 36 | ||||
-rw-r--r-- | arch/mips/ath79/gpio.c | 197 | ||||
-rw-r--r-- | arch/mips/ath79/irq.c | 187 | ||||
-rw-r--r-- | arch/mips/ath79/mach-ap81.c | 98 | ||||
-rw-r--r-- | arch/mips/ath79/mach-pb44.c | 118 | ||||
-rw-r--r-- | arch/mips/ath79/machtypes.h | 23 | ||||
-rw-r--r-- | arch/mips/ath79/prom.c | 57 | ||||
-rw-r--r-- | arch/mips/ath79/setup.c | 206 |
24 files changed, 1708 insertions, 0 deletions
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig new file mode 100644 index 000000000000..b05828260f7f --- /dev/null +++ b/arch/mips/ath79/Kconfig | |||
@@ -0,0 +1,50 @@ | |||
1 | if ATH79 | ||
2 | |||
3 | menu "Atheros AR71XX/AR724X/AR913X machine selection" | ||
4 | |||
5 | config ATH79_MACH_AP81 | ||
6 | bool "Atheros AP81 reference board" | ||
7 | select SOC_AR913X | ||
8 | select ATH79_DEV_AR913X_WMAC | ||
9 | select ATH79_DEV_GPIO_BUTTONS | ||
10 | select ATH79_DEV_LEDS_GPIO | ||
11 | select ATH79_DEV_SPI | ||
12 | help | ||
13 | Say 'Y' here if you want your kernel to support the | ||
14 | Atheros AP81 reference board. | ||
15 | |||
16 | config ATH79_MACH_PB44 | ||
17 | bool "Atheros PB44 reference board" | ||
18 | select SOC_AR71XX | ||
19 | select ATH79_DEV_GPIO_BUTTONS | ||
20 | select ATH79_DEV_LEDS_GPIO | ||
21 | select ATH79_DEV_SPI | ||
22 | help | ||
23 | Say 'Y' here if you want your kernel to support the | ||
24 | Atheros PB44 reference board. | ||
25 | |||
26 | endmenu | ||
27 | |||
28 | config SOC_AR71XX | ||
29 | def_bool n | ||
30 | |||
31 | config SOC_AR724X | ||
32 | def_bool n | ||
33 | |||
34 | config SOC_AR913X | ||
35 | def_bool n | ||
36 | |||
37 | config ATH79_DEV_AR913X_WMAC | ||
38 | depends on SOC_AR913X | ||
39 | def_bool n | ||
40 | |||
41 | config ATH79_DEV_GPIO_BUTTONS | ||
42 | def_bool n | ||
43 | |||
44 | config ATH79_DEV_LEDS_GPIO | ||
45 | def_bool n | ||
46 | |||
47 | config ATH79_DEV_SPI | ||
48 | def_bool n | ||
49 | |||
50 | endif | ||
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile new file mode 100644 index 000000000000..c33d4653007c --- /dev/null +++ b/arch/mips/ath79/Makefile | |||
@@ -0,0 +1,28 @@ | |||
1 | # | ||
2 | # Makefile for the Atheros AR71XX/AR724X/AR913X specific parts of the kernel | ||
3 | # | ||
4 | # Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org> | ||
5 | # Copyright (C) 2008 Imre Kaloz <kaloz@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 | obj-y := prom.o setup.o irq.o common.o clock.o gpio.o | ||
12 | |||
13 | obj-$(CONFIG_EARLY_PRINTK) += early_printk.o | ||
14 | |||
15 | # | ||
16 | # Devices | ||
17 | # | ||
18 | obj-y += dev-common.o | ||
19 | obj-$(CONFIG_ATH79_DEV_AR913X_WMAC) += dev-ar913x-wmac.o | ||
20 | obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o | ||
21 | obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o | ||
22 | obj-$(CONFIG_ATH79_DEV_SPI) += dev-spi.o | ||
23 | |||
24 | # | ||
25 | # Machines | ||
26 | # | ||
27 | obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o | ||
28 | obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o | ||
diff --git a/arch/mips/ath79/Platform b/arch/mips/ath79/Platform new file mode 100644 index 000000000000..2bd663647d27 --- /dev/null +++ b/arch/mips/ath79/Platform | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Atheros AR71xx/AR724x/AR913x | ||
3 | # | ||
4 | |||
5 | platform-$(CONFIG_ATH79) += ath79/ | ||
6 | cflags-$(CONFIG_ATH79) += -I$(srctree)/arch/mips/include/asm/mach-ath79 | ||
7 | load-$(CONFIG_ATH79) = 0xffffffff80060000 | ||
diff --git a/arch/mips/ath79/clock.c b/arch/mips/ath79/clock.c new file mode 100644 index 000000000000..680bde99a26c --- /dev/null +++ b/arch/mips/ath79/clock.c | |||
@@ -0,0 +1,183 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X common routines | ||
3 | * | ||
4 | * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org> | ||
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/kernel.h> | ||
12 | #include <linux/module.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/err.h> | ||
15 | #include <linux/clk.h> | ||
16 | |||
17 | #include <asm/mach-ath79/ath79.h> | ||
18 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
19 | #include "common.h" | ||
20 | |||
21 | #define AR71XX_BASE_FREQ 40000000 | ||
22 | #define AR724X_BASE_FREQ 5000000 | ||
23 | #define AR913X_BASE_FREQ 5000000 | ||
24 | |||
25 | struct clk { | ||
26 | unsigned long rate; | ||
27 | }; | ||
28 | |||
29 | static struct clk ath79_ref_clk; | ||
30 | static struct clk ath79_cpu_clk; | ||
31 | static struct clk ath79_ddr_clk; | ||
32 | static struct clk ath79_ahb_clk; | ||
33 | static struct clk ath79_wdt_clk; | ||
34 | static struct clk ath79_uart_clk; | ||
35 | |||
36 | static void __init ar71xx_clocks_init(void) | ||
37 | { | ||
38 | u32 pll; | ||
39 | u32 freq; | ||
40 | u32 div; | ||
41 | |||
42 | ath79_ref_clk.rate = AR71XX_BASE_FREQ; | ||
43 | |||
44 | pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); | ||
45 | |||
46 | div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; | ||
47 | freq = div * ath79_ref_clk.rate; | ||
48 | |||
49 | div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; | ||
50 | ath79_cpu_clk.rate = freq / div; | ||
51 | |||
52 | div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; | ||
53 | ath79_ddr_clk.rate = freq / div; | ||
54 | |||
55 | div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; | ||
56 | ath79_ahb_clk.rate = ath79_cpu_clk.rate / div; | ||
57 | |||
58 | ath79_wdt_clk.rate = ath79_ahb_clk.rate; | ||
59 | ath79_uart_clk.rate = ath79_ahb_clk.rate; | ||
60 | } | ||
61 | |||
62 | static void __init ar724x_clocks_init(void) | ||
63 | { | ||
64 | u32 pll; | ||
65 | u32 freq; | ||
66 | u32 div; | ||
67 | |||
68 | ath79_ref_clk.rate = AR724X_BASE_FREQ; | ||
69 | pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG); | ||
70 | |||
71 | div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); | ||
72 | freq = div * ath79_ref_clk.rate; | ||
73 | |||
74 | div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK); | ||
75 | freq *= div; | ||
76 | |||
77 | ath79_cpu_clk.rate = freq; | ||
78 | |||
79 | div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; | ||
80 | ath79_ddr_clk.rate = freq / div; | ||
81 | |||
82 | div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; | ||
83 | ath79_ahb_clk.rate = ath79_cpu_clk.rate / div; | ||
84 | |||
85 | ath79_wdt_clk.rate = ath79_ahb_clk.rate; | ||
86 | ath79_uart_clk.rate = ath79_ahb_clk.rate; | ||
87 | } | ||
88 | |||
89 | static void __init ar913x_clocks_init(void) | ||
90 | { | ||
91 | u32 pll; | ||
92 | u32 freq; | ||
93 | u32 div; | ||
94 | |||
95 | ath79_ref_clk.rate = AR913X_BASE_FREQ; | ||
96 | pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG); | ||
97 | |||
98 | div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK); | ||
99 | freq = div * ath79_ref_clk.rate; | ||
100 | |||
101 | ath79_cpu_clk.rate = freq; | ||
102 | |||
103 | div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1; | ||
104 | ath79_ddr_clk.rate = freq / div; | ||
105 | |||
106 | div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2; | ||
107 | ath79_ahb_clk.rate = ath79_cpu_clk.rate / div; | ||
108 | |||
109 | ath79_wdt_clk.rate = ath79_ahb_clk.rate; | ||
110 | ath79_uart_clk.rate = ath79_ahb_clk.rate; | ||
111 | } | ||
112 | |||
113 | void __init ath79_clocks_init(void) | ||
114 | { | ||
115 | if (soc_is_ar71xx()) | ||
116 | ar71xx_clocks_init(); | ||
117 | else if (soc_is_ar724x()) | ||
118 | ar724x_clocks_init(); | ||
119 | else if (soc_is_ar913x()) | ||
120 | ar913x_clocks_init(); | ||
121 | else | ||
122 | BUG(); | ||
123 | |||
124 | pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, " | ||
125 | "Ref:%lu.%03luMHz", | ||
126 | ath79_cpu_clk.rate / 1000000, | ||
127 | (ath79_cpu_clk.rate / 1000) % 1000, | ||
128 | ath79_ddr_clk.rate / 1000000, | ||
129 | (ath79_ddr_clk.rate / 1000) % 1000, | ||
130 | ath79_ahb_clk.rate / 1000000, | ||
131 | (ath79_ahb_clk.rate / 1000) % 1000, | ||
132 | ath79_ref_clk.rate / 1000000, | ||
133 | (ath79_ref_clk.rate / 1000) % 1000); | ||
134 | } | ||
135 | |||
136 | /* | ||
137 | * Linux clock API | ||
138 | */ | ||
139 | struct clk *clk_get(struct device *dev, const char *id) | ||
140 | { | ||
141 | if (!strcmp(id, "ref")) | ||
142 | return &ath79_ref_clk; | ||
143 | |||
144 | if (!strcmp(id, "cpu")) | ||
145 | return &ath79_cpu_clk; | ||
146 | |||
147 | if (!strcmp(id, "ddr")) | ||
148 | return &ath79_ddr_clk; | ||
149 | |||
150 | if (!strcmp(id, "ahb")) | ||
151 | return &ath79_ahb_clk; | ||
152 | |||
153 | if (!strcmp(id, "wdt")) | ||
154 | return &ath79_wdt_clk; | ||
155 | |||
156 | if (!strcmp(id, "uart")) | ||
157 | return &ath79_uart_clk; | ||
158 | |||
159 | return ERR_PTR(-ENOENT); | ||
160 | } | ||
161 | EXPORT_SYMBOL(clk_get); | ||
162 | |||
163 | int clk_enable(struct clk *clk) | ||
164 | { | ||
165 | return 0; | ||
166 | } | ||
167 | EXPORT_SYMBOL(clk_enable); | ||
168 | |||
169 | void clk_disable(struct clk *clk) | ||
170 | { | ||
171 | } | ||
172 | EXPORT_SYMBOL(clk_disable); | ||
173 | |||
174 | unsigned long clk_get_rate(struct clk *clk) | ||
175 | { | ||
176 | return clk->rate; | ||
177 | } | ||
178 | EXPORT_SYMBOL(clk_get_rate); | ||
179 | |||
180 | void clk_put(struct clk *clk) | ||
181 | { | ||
182 | } | ||
183 | EXPORT_SYMBOL(clk_put); | ||
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c new file mode 100644 index 000000000000..58f60e722a03 --- /dev/null +++ b/arch/mips/ath79/common.c | |||
@@ -0,0 +1,97 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X common routines | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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/kernel.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/types.h> | ||
15 | #include <linux/spinlock.h> | ||
16 | |||
17 | #include <asm/mach-ath79/ath79.h> | ||
18 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
19 | #include "common.h" | ||
20 | |||
21 | static DEFINE_SPINLOCK(ath79_device_reset_lock); | ||
22 | |||
23 | u32 ath79_cpu_freq; | ||
24 | EXPORT_SYMBOL_GPL(ath79_cpu_freq); | ||
25 | |||
26 | u32 ath79_ahb_freq; | ||
27 | EXPORT_SYMBOL_GPL(ath79_ahb_freq); | ||
28 | |||
29 | u32 ath79_ddr_freq; | ||
30 | EXPORT_SYMBOL_GPL(ath79_ddr_freq); | ||
31 | |||
32 | enum ath79_soc_type ath79_soc; | ||
33 | |||
34 | void __iomem *ath79_pll_base; | ||
35 | void __iomem *ath79_reset_base; | ||
36 | EXPORT_SYMBOL_GPL(ath79_reset_base); | ||
37 | void __iomem *ath79_ddr_base; | ||
38 | |||
39 | void ath79_ddr_wb_flush(u32 reg) | ||
40 | { | ||
41 | void __iomem *flush_reg = ath79_ddr_base + reg; | ||
42 | |||
43 | /* Flush the DDR write buffer. */ | ||
44 | __raw_writel(0x1, flush_reg); | ||
45 | while (__raw_readl(flush_reg) & 0x1) | ||
46 | ; | ||
47 | |||
48 | /* It must be run twice. */ | ||
49 | __raw_writel(0x1, flush_reg); | ||
50 | while (__raw_readl(flush_reg) & 0x1) | ||
51 | ; | ||
52 | } | ||
53 | EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush); | ||
54 | |||
55 | void ath79_device_reset_set(u32 mask) | ||
56 | { | ||
57 | unsigned long flags; | ||
58 | u32 reg; | ||
59 | u32 t; | ||
60 | |||
61 | if (soc_is_ar71xx()) | ||
62 | reg = AR71XX_RESET_REG_RESET_MODULE; | ||
63 | else if (soc_is_ar724x()) | ||
64 | reg = AR724X_RESET_REG_RESET_MODULE; | ||
65 | else if (soc_is_ar913x()) | ||
66 | reg = AR913X_RESET_REG_RESET_MODULE; | ||
67 | else | ||
68 | BUG(); | ||
69 | |||
70 | spin_lock_irqsave(&ath79_device_reset_lock, flags); | ||
71 | t = ath79_reset_rr(reg); | ||
72 | ath79_reset_wr(reg, t | mask); | ||
73 | spin_unlock_irqrestore(&ath79_device_reset_lock, flags); | ||
74 | } | ||
75 | EXPORT_SYMBOL_GPL(ath79_device_reset_set); | ||
76 | |||
77 | void ath79_device_reset_clear(u32 mask) | ||
78 | { | ||
79 | unsigned long flags; | ||
80 | u32 reg; | ||
81 | u32 t; | ||
82 | |||
83 | if (soc_is_ar71xx()) | ||
84 | reg = AR71XX_RESET_REG_RESET_MODULE; | ||
85 | else if (soc_is_ar724x()) | ||
86 | reg = AR724X_RESET_REG_RESET_MODULE; | ||
87 | else if (soc_is_ar913x()) | ||
88 | reg = AR913X_RESET_REG_RESET_MODULE; | ||
89 | else | ||
90 | BUG(); | ||
91 | |||
92 | spin_lock_irqsave(&ath79_device_reset_lock, flags); | ||
93 | t = ath79_reset_rr(reg); | ||
94 | ath79_reset_wr(reg, t & ~mask); | ||
95 | spin_unlock_irqrestore(&ath79_device_reset_lock, flags); | ||
96 | } | ||
97 | EXPORT_SYMBOL_GPL(ath79_device_reset_clear); | ||
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h new file mode 100644 index 000000000000..561906c2345e --- /dev/null +++ b/arch/mips/ath79/common.h | |||
@@ -0,0 +1,31 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X common definitions | ||
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 | #ifndef __ATH79_COMMON_H | ||
15 | #define __ATH79_COMMON_H | ||
16 | |||
17 | #include <linux/types.h> | ||
18 | #include <linux/init.h> | ||
19 | |||
20 | #define ATH79_MEM_SIZE_MIN (2 * 1024 * 1024) | ||
21 | #define ATH79_MEM_SIZE_MAX (128 * 1024 * 1024) | ||
22 | |||
23 | void ath79_clocks_init(void); | ||
24 | void ath79_ddr_wb_flush(unsigned int reg); | ||
25 | |||
26 | void ath79_gpio_function_enable(u32 mask); | ||
27 | void ath79_gpio_function_disable(u32 mask); | ||
28 | void ath79_gpio_function_setup(u32 set, u32 clear); | ||
29 | void ath79_gpio_init(void); | ||
30 | |||
31 | #endif /* __ATH79_COMMON_H */ | ||
diff --git a/arch/mips/ath79/dev-ar913x-wmac.c b/arch/mips/ath79/dev-ar913x-wmac.c new file mode 100644 index 000000000000..48f425a5ba28 --- /dev/null +++ b/arch/mips/ath79/dev-ar913x-wmac.c | |||
@@ -0,0 +1,60 @@ | |||
1 | /* | ||
2 | * Atheros AR913X SoC built-in WMAC device support | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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/init.h> | ||
13 | #include <linux/delay.h> | ||
14 | #include <linux/irq.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/ath9k_platform.h> | ||
17 | |||
18 | #include <asm/mach-ath79/ath79.h> | ||
19 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
20 | #include "dev-ar913x-wmac.h" | ||
21 | |||
22 | static struct ath9k_platform_data ar913x_wmac_data; | ||
23 | |||
24 | static struct resource ar913x_wmac_resources[] = { | ||
25 | { | ||
26 | .start = AR913X_WMAC_BASE, | ||
27 | .end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1, | ||
28 | .flags = IORESOURCE_MEM, | ||
29 | }, { | ||
30 | .start = ATH79_CPU_IRQ_IP2, | ||
31 | .end = ATH79_CPU_IRQ_IP2, | ||
32 | .flags = IORESOURCE_IRQ, | ||
33 | }, | ||
34 | }; | ||
35 | |||
36 | static struct platform_device ar913x_wmac_device = { | ||
37 | .name = "ath9k", | ||
38 | .id = -1, | ||
39 | .resource = ar913x_wmac_resources, | ||
40 | .num_resources = ARRAY_SIZE(ar913x_wmac_resources), | ||
41 | .dev = { | ||
42 | .platform_data = &ar913x_wmac_data, | ||
43 | }, | ||
44 | }; | ||
45 | |||
46 | void __init ath79_register_ar913x_wmac(u8 *cal_data) | ||
47 | { | ||
48 | if (cal_data) | ||
49 | memcpy(ar913x_wmac_data.eeprom_data, cal_data, | ||
50 | sizeof(ar913x_wmac_data.eeprom_data)); | ||
51 | |||
52 | /* reset the WMAC */ | ||
53 | ath79_device_reset_set(AR913X_RESET_AMBA2WMAC); | ||
54 | mdelay(10); | ||
55 | |||
56 | ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC); | ||
57 | mdelay(10); | ||
58 | |||
59 | platform_device_register(&ar913x_wmac_device); | ||
60 | } | ||
diff --git a/arch/mips/ath79/dev-ar913x-wmac.h b/arch/mips/ath79/dev-ar913x-wmac.h new file mode 100644 index 000000000000..579d562bbda8 --- /dev/null +++ b/arch/mips/ath79/dev-ar913x-wmac.h | |||
@@ -0,0 +1,17 @@ | |||
1 | /* | ||
2 | * Atheros AR913X SoC built-in WMAC device support | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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 | #ifndef _ATH79_DEV_AR913X_WMAC_H | ||
13 | #define _ATH79_DEV_AR913X_WMAC_H | ||
14 | |||
15 | void ath79_register_ar913x_wmac(u8 *cal_data); | ||
16 | |||
17 | #endif /* _ATH79_DEV_AR913X_WMAC_H */ | ||
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c new file mode 100644 index 000000000000..3b82e325bebf --- /dev/null +++ b/arch/mips/ath79/dev-common.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X common devices | ||
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/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/serial_8250.h> | ||
18 | #include <linux/clk.h> | ||
19 | #include <linux/err.h> | ||
20 | |||
21 | #include <asm/mach-ath79/ath79.h> | ||
22 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
23 | #include "common.h" | ||
24 | #include "dev-common.h" | ||
25 | |||
26 | static struct resource ath79_uart_resources[] = { | ||
27 | { | ||
28 | .start = AR71XX_UART_BASE, | ||
29 | .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1, | ||
30 | .flags = IORESOURCE_MEM, | ||
31 | }, | ||
32 | }; | ||
33 | |||
34 | #define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP) | ||
35 | static struct plat_serial8250_port ath79_uart_data[] = { | ||
36 | { | ||
37 | .mapbase = AR71XX_UART_BASE, | ||
38 | .irq = ATH79_MISC_IRQ_UART, | ||
39 | .flags = AR71XX_UART_FLAGS, | ||
40 | .iotype = UPIO_MEM32, | ||
41 | .regshift = 2, | ||
42 | }, { | ||
43 | /* terminating entry */ | ||
44 | } | ||
45 | }; | ||
46 | |||
47 | static struct platform_device ath79_uart_device = { | ||
48 | .name = "serial8250", | ||
49 | .id = PLAT8250_DEV_PLATFORM, | ||
50 | .resource = ath79_uart_resources, | ||
51 | .num_resources = ARRAY_SIZE(ath79_uart_resources), | ||
52 | .dev = { | ||
53 | .platform_data = ath79_uart_data | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | void __init ath79_register_uart(void) | ||
58 | { | ||
59 | struct clk *clk; | ||
60 | |||
61 | clk = clk_get(NULL, "uart"); | ||
62 | if (IS_ERR(clk)) | ||
63 | panic("unable to get UART clock, err=%ld", PTR_ERR(clk)); | ||
64 | |||
65 | ath79_uart_data[0].uartclk = clk_get_rate(clk); | ||
66 | platform_device_register(&ath79_uart_device); | ||
67 | } | ||
68 | |||
69 | static struct platform_device ath79_wdt_device = { | ||
70 | .name = "ath79-wdt", | ||
71 | .id = -1, | ||
72 | }; | ||
73 | |||
74 | void __init ath79_register_wdt(void) | ||
75 | { | ||
76 | platform_device_register(&ath79_wdt_device); | ||
77 | } | ||
diff --git a/arch/mips/ath79/dev-common.h b/arch/mips/ath79/dev-common.h new file mode 100644 index 000000000000..0f514e1affce --- /dev/null +++ b/arch/mips/ath79/dev-common.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X common devices | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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 | #ifndef _ATH79_DEV_COMMON_H | ||
13 | #define _ATH79_DEV_COMMON_H | ||
14 | |||
15 | void ath79_register_uart(void); | ||
16 | void ath79_register_wdt(void); | ||
17 | |||
18 | #endif /* _ATH79_DEV_COMMON_H */ | ||
diff --git a/arch/mips/ath79/dev-gpio-buttons.c b/arch/mips/ath79/dev-gpio-buttons.c new file mode 100644 index 000000000000..4b0168a11c01 --- /dev/null +++ b/arch/mips/ath79/dev-gpio-buttons.c | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X GPIO button support | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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/init.h" | ||
13 | #include "linux/slab.h" | ||
14 | #include <linux/platform_device.h> | ||
15 | |||
16 | #include "dev-gpio-buttons.h" | ||
17 | |||
18 | void __init ath79_register_gpio_keys_polled(int id, | ||
19 | unsigned poll_interval, | ||
20 | unsigned nbuttons, | ||
21 | struct gpio_keys_button *buttons) | ||
22 | { | ||
23 | struct platform_device *pdev; | ||
24 | struct gpio_keys_platform_data pdata; | ||
25 | struct gpio_keys_button *p; | ||
26 | int err; | ||
27 | |||
28 | p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL); | ||
29 | if (!p) | ||
30 | return; | ||
31 | |||
32 | memcpy(p, buttons, nbuttons * sizeof(*p)); | ||
33 | |||
34 | pdev = platform_device_alloc("gpio-keys-polled", id); | ||
35 | if (!pdev) | ||
36 | goto err_free_buttons; | ||
37 | |||
38 | memset(&pdata, 0, sizeof(pdata)); | ||
39 | pdata.poll_interval = poll_interval; | ||
40 | pdata.nbuttons = nbuttons; | ||
41 | pdata.buttons = p; | ||
42 | |||
43 | err = platform_device_add_data(pdev, &pdata, sizeof(pdata)); | ||
44 | if (err) | ||
45 | goto err_put_pdev; | ||
46 | |||
47 | err = platform_device_add(pdev); | ||
48 | if (err) | ||
49 | goto err_put_pdev; | ||
50 | |||
51 | return; | ||
52 | |||
53 | err_put_pdev: | ||
54 | platform_device_put(pdev); | ||
55 | |||
56 | err_free_buttons: | ||
57 | kfree(p); | ||
58 | } | ||
diff --git a/arch/mips/ath79/dev-gpio-buttons.h b/arch/mips/ath79/dev-gpio-buttons.h new file mode 100644 index 000000000000..481847ac1cba --- /dev/null +++ b/arch/mips/ath79/dev-gpio-buttons.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X GPIO button support | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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 | #ifndef _ATH79_DEV_GPIO_BUTTONS_H | ||
13 | #define _ATH79_DEV_GPIO_BUTTONS_H | ||
14 | |||
15 | #include <linux/input.h> | ||
16 | #include <linux/gpio_keys.h> | ||
17 | |||
18 | void ath79_register_gpio_keys_polled(int id, | ||
19 | unsigned poll_interval, | ||
20 | unsigned nbuttons, | ||
21 | struct gpio_keys_button *buttons); | ||
22 | |||
23 | #endif /* _ATH79_DEV_GPIO_BUTTONS_H */ | ||
diff --git a/arch/mips/ath79/dev-leds-gpio.c b/arch/mips/ath79/dev-leds-gpio.c new file mode 100644 index 000000000000..cdade68dcd17 --- /dev/null +++ b/arch/mips/ath79/dev-leds-gpio.c | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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/init.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/platform_device.h> | ||
15 | |||
16 | #include "dev-leds-gpio.h" | ||
17 | |||
18 | void __init ath79_register_leds_gpio(int id, | ||
19 | unsigned num_leds, | ||
20 | struct gpio_led *leds) | ||
21 | { | ||
22 | struct platform_device *pdev; | ||
23 | struct gpio_led_platform_data pdata; | ||
24 | struct gpio_led *p; | ||
25 | int err; | ||
26 | |||
27 | p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL); | ||
28 | if (!p) | ||
29 | return; | ||
30 | |||
31 | memcpy(p, leds, num_leds * sizeof(*p)); | ||
32 | |||
33 | pdev = platform_device_alloc("leds-gpio", id); | ||
34 | if (!pdev) | ||
35 | goto err_free_leds; | ||
36 | |||
37 | memset(&pdata, 0, sizeof(pdata)); | ||
38 | pdata.num_leds = num_leds; | ||
39 | pdata.leds = p; | ||
40 | |||
41 | err = platform_device_add_data(pdev, &pdata, sizeof(pdata)); | ||
42 | if (err) | ||
43 | goto err_put_pdev; | ||
44 | |||
45 | err = platform_device_add(pdev); | ||
46 | if (err) | ||
47 | goto err_put_pdev; | ||
48 | |||
49 | return; | ||
50 | |||
51 | err_put_pdev: | ||
52 | platform_device_put(pdev); | ||
53 | |||
54 | err_free_leds: | ||
55 | kfree(p); | ||
56 | } | ||
diff --git a/arch/mips/ath79/dev-leds-gpio.h b/arch/mips/ath79/dev-leds-gpio.h new file mode 100644 index 000000000000..6e5d8851ebcf --- /dev/null +++ b/arch/mips/ath79/dev-leds-gpio.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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 | #ifndef _ATH79_DEV_LEDS_GPIO_H | ||
13 | #define _ATH79_DEV_LEDS_GPIO_H | ||
14 | |||
15 | #include <linux/leds.h> | ||
16 | |||
17 | void ath79_register_leds_gpio(int id, | ||
18 | unsigned num_leds, | ||
19 | struct gpio_led *leds); | ||
20 | |||
21 | #endif /* _ATH79_DEV_LEDS_GPIO_H */ | ||
diff --git a/arch/mips/ath79/dev-spi.c b/arch/mips/ath79/dev-spi.c new file mode 100644 index 000000000000..aa30163efbfd --- /dev/null +++ b/arch/mips/ath79/dev-spi.c | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X SPI controller device | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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/platform_device.h> | ||
13 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
14 | #include "dev-spi.h" | ||
15 | |||
16 | static struct resource ath79_spi_resources[] = { | ||
17 | { | ||
18 | .start = AR71XX_SPI_BASE, | ||
19 | .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1, | ||
20 | .flags = IORESOURCE_MEM, | ||
21 | }, | ||
22 | }; | ||
23 | |||
24 | static struct platform_device ath79_spi_device = { | ||
25 | .name = "ath79-spi", | ||
26 | .id = -1, | ||
27 | .resource = ath79_spi_resources, | ||
28 | .num_resources = ARRAY_SIZE(ath79_spi_resources), | ||
29 | }; | ||
30 | |||
31 | void __init ath79_register_spi(struct ath79_spi_platform_data *pdata, | ||
32 | struct spi_board_info const *info, | ||
33 | unsigned n) | ||
34 | { | ||
35 | spi_register_board_info(info, n); | ||
36 | ath79_spi_device.dev.platform_data = pdata; | ||
37 | platform_device_register(&ath79_spi_device); | ||
38 | } | ||
diff --git a/arch/mips/ath79/dev-spi.h b/arch/mips/ath79/dev-spi.h new file mode 100644 index 000000000000..d732565ca736 --- /dev/null +++ b/arch/mips/ath79/dev-spi.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X SPI controller device | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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 | #ifndef _ATH79_DEV_SPI_H | ||
13 | #define _ATH79_DEV_SPI_H | ||
14 | |||
15 | #include <linux/spi/spi.h> | ||
16 | #include <asm/mach-ath79/ath79_spi_platform.h> | ||
17 | |||
18 | void ath79_register_spi(struct ath79_spi_platform_data *pdata, | ||
19 | struct spi_board_info const *info, | ||
20 | unsigned n); | ||
21 | |||
22 | #endif /* _ATH79_DEV_SPI_H */ | ||
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c new file mode 100644 index 000000000000..7499b0e9df26 --- /dev/null +++ b/arch/mips/ath79/early_printk.c | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X SoC early printk support | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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/io.h> | ||
13 | #include <linux/serial_reg.h> | ||
14 | #include <asm/addrspace.h> | ||
15 | |||
16 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
17 | |||
18 | static inline void prom_wait_thre(void __iomem *base) | ||
19 | { | ||
20 | u32 lsr; | ||
21 | |||
22 | do { | ||
23 | lsr = __raw_readl(base + UART_LSR * 4); | ||
24 | if (lsr & UART_LSR_THRE) | ||
25 | break; | ||
26 | } while (1); | ||
27 | } | ||
28 | |||
29 | void prom_putchar(unsigned char ch) | ||
30 | { | ||
31 | void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE)); | ||
32 | |||
33 | prom_wait_thre(base); | ||
34 | __raw_writel(ch, base + UART_TX * 4); | ||
35 | prom_wait_thre(base); | ||
36 | } | ||
diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c new file mode 100644 index 000000000000..a0c426b82123 --- /dev/null +++ b/arch/mips/ath79/gpio.c | |||
@@ -0,0 +1,197 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X GPIO API support | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/module.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/spinlock.h> | ||
17 | #include <linux/io.h> | ||
18 | #include <linux/ioport.h> | ||
19 | #include <linux/gpio.h> | ||
20 | |||
21 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
22 | #include <asm/mach-ath79/ath79.h> | ||
23 | #include "common.h" | ||
24 | |||
25 | static void __iomem *ath79_gpio_base; | ||
26 | static unsigned long ath79_gpio_count; | ||
27 | static DEFINE_SPINLOCK(ath79_gpio_lock); | ||
28 | |||
29 | static void __ath79_gpio_set_value(unsigned gpio, int value) | ||
30 | { | ||
31 | void __iomem *base = ath79_gpio_base; | ||
32 | |||
33 | if (value) | ||
34 | __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_SET); | ||
35 | else | ||
36 | __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_CLEAR); | ||
37 | } | ||
38 | |||
39 | static int __ath79_gpio_get_value(unsigned gpio) | ||
40 | { | ||
41 | return (__raw_readl(ath79_gpio_base + AR71XX_GPIO_REG_IN) >> gpio) & 1; | ||
42 | } | ||
43 | |||
44 | static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned offset) | ||
45 | { | ||
46 | return __ath79_gpio_get_value(offset); | ||
47 | } | ||
48 | |||
49 | static void ath79_gpio_set_value(struct gpio_chip *chip, | ||
50 | unsigned offset, int value) | ||
51 | { | ||
52 | __ath79_gpio_set_value(offset, value); | ||
53 | } | ||
54 | |||
55 | static int ath79_gpio_direction_input(struct gpio_chip *chip, | ||
56 | unsigned offset) | ||
57 | { | ||
58 | void __iomem *base = ath79_gpio_base; | ||
59 | unsigned long flags; | ||
60 | |||
61 | spin_lock_irqsave(&ath79_gpio_lock, flags); | ||
62 | |||
63 | __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset), | ||
64 | base + AR71XX_GPIO_REG_OE); | ||
65 | |||
66 | spin_unlock_irqrestore(&ath79_gpio_lock, flags); | ||
67 | |||
68 | return 0; | ||
69 | } | ||
70 | |||
71 | static int ath79_gpio_direction_output(struct gpio_chip *chip, | ||
72 | unsigned offset, int value) | ||
73 | { | ||
74 | void __iomem *base = ath79_gpio_base; | ||
75 | unsigned long flags; | ||
76 | |||
77 | spin_lock_irqsave(&ath79_gpio_lock, flags); | ||
78 | |||
79 | if (value) | ||
80 | __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET); | ||
81 | else | ||
82 | __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR); | ||
83 | |||
84 | __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset), | ||
85 | base + AR71XX_GPIO_REG_OE); | ||
86 | |||
87 | spin_unlock_irqrestore(&ath79_gpio_lock, flags); | ||
88 | |||
89 | return 0; | ||
90 | } | ||
91 | |||
92 | static struct gpio_chip ath79_gpio_chip = { | ||
93 | .label = "ath79", | ||
94 | .get = ath79_gpio_get_value, | ||
95 | .set = ath79_gpio_set_value, | ||
96 | .direction_input = ath79_gpio_direction_input, | ||
97 | .direction_output = ath79_gpio_direction_output, | ||
98 | .base = 0, | ||
99 | }; | ||
100 | |||
101 | void ath79_gpio_function_enable(u32 mask) | ||
102 | { | ||
103 | void __iomem *base = ath79_gpio_base; | ||
104 | unsigned long flags; | ||
105 | |||
106 | spin_lock_irqsave(&ath79_gpio_lock, flags); | ||
107 | |||
108 | __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) | mask, | ||
109 | base + AR71XX_GPIO_REG_FUNC); | ||
110 | /* flush write */ | ||
111 | __raw_readl(base + AR71XX_GPIO_REG_FUNC); | ||
112 | |||
113 | spin_unlock_irqrestore(&ath79_gpio_lock, flags); | ||
114 | } | ||
115 | |||
116 | void ath79_gpio_function_disable(u32 mask) | ||
117 | { | ||
118 | void __iomem *base = ath79_gpio_base; | ||
119 | unsigned long flags; | ||
120 | |||
121 | spin_lock_irqsave(&ath79_gpio_lock, flags); | ||
122 | |||
123 | __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~mask, | ||
124 | base + AR71XX_GPIO_REG_FUNC); | ||
125 | /* flush write */ | ||
126 | __raw_readl(base + AR71XX_GPIO_REG_FUNC); | ||
127 | |||
128 | spin_unlock_irqrestore(&ath79_gpio_lock, flags); | ||
129 | } | ||
130 | |||
131 | void ath79_gpio_function_setup(u32 set, u32 clear) | ||
132 | { | ||
133 | void __iomem *base = ath79_gpio_base; | ||
134 | unsigned long flags; | ||
135 | |||
136 | spin_lock_irqsave(&ath79_gpio_lock, flags); | ||
137 | |||
138 | __raw_writel((__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~clear) | set, | ||
139 | base + AR71XX_GPIO_REG_FUNC); | ||
140 | /* flush write */ | ||
141 | __raw_readl(base + AR71XX_GPIO_REG_FUNC); | ||
142 | |||
143 | spin_unlock_irqrestore(&ath79_gpio_lock, flags); | ||
144 | } | ||
145 | |||
146 | void __init ath79_gpio_init(void) | ||
147 | { | ||
148 | int err; | ||
149 | |||
150 | if (soc_is_ar71xx()) | ||
151 | ath79_gpio_count = AR71XX_GPIO_COUNT; | ||
152 | else if (soc_is_ar724x()) | ||
153 | ath79_gpio_count = AR724X_GPIO_COUNT; | ||
154 | else if (soc_is_ar913x()) | ||
155 | ath79_gpio_count = AR913X_GPIO_COUNT; | ||
156 | else | ||
157 | BUG(); | ||
158 | |||
159 | ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE); | ||
160 | ath79_gpio_chip.ngpio = ath79_gpio_count; | ||
161 | |||
162 | err = gpiochip_add(&ath79_gpio_chip); | ||
163 | if (err) | ||
164 | panic("cannot add AR71xx GPIO chip, error=%d", err); | ||
165 | } | ||
166 | |||
167 | int gpio_get_value(unsigned gpio) | ||
168 | { | ||
169 | if (gpio < ath79_gpio_count) | ||
170 | return __ath79_gpio_get_value(gpio); | ||
171 | |||
172 | return __gpio_get_value(gpio); | ||
173 | } | ||
174 | EXPORT_SYMBOL(gpio_get_value); | ||
175 | |||
176 | void gpio_set_value(unsigned gpio, int value) | ||
177 | { | ||
178 | if (gpio < ath79_gpio_count) | ||
179 | __ath79_gpio_set_value(gpio, value); | ||
180 | else | ||
181 | __gpio_set_value(gpio, value); | ||
182 | } | ||
183 | EXPORT_SYMBOL(gpio_set_value); | ||
184 | |||
185 | int gpio_to_irq(unsigned gpio) | ||
186 | { | ||
187 | /* FIXME */ | ||
188 | return -EINVAL; | ||
189 | } | ||
190 | EXPORT_SYMBOL(gpio_to_irq); | ||
191 | |||
192 | int irq_to_gpio(unsigned irq) | ||
193 | { | ||
194 | /* FIXME */ | ||
195 | return -EINVAL; | ||
196 | } | ||
197 | EXPORT_SYMBOL(irq_to_gpio); | ||
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c new file mode 100644 index 000000000000..1bf7f719ba53 --- /dev/null +++ b/arch/mips/ath79/irq.c | |||
@@ -0,0 +1,187 @@ | |||
1 | /* | ||
2 | * Atheros AR71xx/AR724x/AR913x specific interrupt handling | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 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/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/interrupt.h> | ||
17 | #include <linux/irq.h> | ||
18 | |||
19 | #include <asm/irq_cpu.h> | ||
20 | #include <asm/mipsregs.h> | ||
21 | |||
22 | #include <asm/mach-ath79/ath79.h> | ||
23 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
24 | #include "common.h" | ||
25 | |||
26 | static unsigned int ath79_ip2_flush_reg; | ||
27 | static unsigned int ath79_ip3_flush_reg; | ||
28 | |||
29 | static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
30 | { | ||
31 | void __iomem *base = ath79_reset_base; | ||
32 | u32 pending; | ||
33 | |||
34 | pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) & | ||
35 | __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | ||
36 | |||
37 | if (pending & MISC_INT_UART) | ||
38 | generic_handle_irq(ATH79_MISC_IRQ_UART); | ||
39 | |||
40 | else if (pending & MISC_INT_DMA) | ||
41 | generic_handle_irq(ATH79_MISC_IRQ_DMA); | ||
42 | |||
43 | else if (pending & MISC_INT_PERFC) | ||
44 | generic_handle_irq(ATH79_MISC_IRQ_PERFC); | ||
45 | |||
46 | else if (pending & MISC_INT_TIMER) | ||
47 | generic_handle_irq(ATH79_MISC_IRQ_TIMER); | ||
48 | |||
49 | else if (pending & MISC_INT_OHCI) | ||
50 | generic_handle_irq(ATH79_MISC_IRQ_OHCI); | ||
51 | |||
52 | else if (pending & MISC_INT_ERROR) | ||
53 | generic_handle_irq(ATH79_MISC_IRQ_ERROR); | ||
54 | |||
55 | else if (pending & MISC_INT_GPIO) | ||
56 | generic_handle_irq(ATH79_MISC_IRQ_GPIO); | ||
57 | |||
58 | else if (pending & MISC_INT_WDOG) | ||
59 | generic_handle_irq(ATH79_MISC_IRQ_WDOG); | ||
60 | |||
61 | else | ||
62 | spurious_interrupt(); | ||
63 | } | ||
64 | |||
65 | static void ar71xx_misc_irq_unmask(unsigned int irq) | ||
66 | { | ||
67 | void __iomem *base = ath79_reset_base; | ||
68 | u32 t; | ||
69 | |||
70 | irq -= ATH79_MISC_IRQ_BASE; | ||
71 | |||
72 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | ||
73 | __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); | ||
74 | |||
75 | /* flush write */ | ||
76 | __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | ||
77 | } | ||
78 | |||
79 | static void ar71xx_misc_irq_mask(unsigned int irq) | ||
80 | { | ||
81 | void __iomem *base = ath79_reset_base; | ||
82 | u32 t; | ||
83 | |||
84 | irq -= ATH79_MISC_IRQ_BASE; | ||
85 | |||
86 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | ||
87 | __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE); | ||
88 | |||
89 | /* flush write */ | ||
90 | __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE); | ||
91 | } | ||
92 | |||
93 | static void ar724x_misc_irq_ack(unsigned int irq) | ||
94 | { | ||
95 | void __iomem *base = ath79_reset_base; | ||
96 | u32 t; | ||
97 | |||
98 | irq -= ATH79_MISC_IRQ_BASE; | ||
99 | |||
100 | t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); | ||
101 | __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS); | ||
102 | |||
103 | /* flush write */ | ||
104 | __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS); | ||
105 | } | ||
106 | |||
107 | static struct irq_chip ath79_misc_irq_chip = { | ||
108 | .name = "MISC", | ||
109 | .unmask = ar71xx_misc_irq_unmask, | ||
110 | .mask = ar71xx_misc_irq_mask, | ||
111 | }; | ||
112 | |||
113 | static void __init ath79_misc_irq_init(void) | ||
114 | { | ||
115 | void __iomem *base = ath79_reset_base; | ||
116 | int i; | ||
117 | |||
118 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE); | ||
119 | __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS); | ||
120 | |||
121 | if (soc_is_ar71xx() || soc_is_ar913x()) | ||
122 | ath79_misc_irq_chip.mask_ack = ar71xx_misc_irq_mask; | ||
123 | else if (soc_is_ar724x()) | ||
124 | ath79_misc_irq_chip.ack = ar724x_misc_irq_ack; | ||
125 | else | ||
126 | BUG(); | ||
127 | |||
128 | for (i = ATH79_MISC_IRQ_BASE; | ||
129 | i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) { | ||
130 | irq_desc[i].status = IRQ_DISABLED; | ||
131 | set_irq_chip_and_handler(i, &ath79_misc_irq_chip, | ||
132 | handle_level_irq); | ||
133 | } | ||
134 | |||
135 | set_irq_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler); | ||
136 | } | ||
137 | |||
138 | asmlinkage void plat_irq_dispatch(void) | ||
139 | { | ||
140 | unsigned long pending; | ||
141 | |||
142 | pending = read_c0_status() & read_c0_cause() & ST0_IM; | ||
143 | |||
144 | if (pending & STATUSF_IP7) | ||
145 | do_IRQ(ATH79_CPU_IRQ_TIMER); | ||
146 | |||
147 | else if (pending & STATUSF_IP2) { | ||
148 | ath79_ddr_wb_flush(ath79_ip2_flush_reg); | ||
149 | do_IRQ(ATH79_CPU_IRQ_IP2); | ||
150 | } | ||
151 | |||
152 | else if (pending & STATUSF_IP4) | ||
153 | do_IRQ(ATH79_CPU_IRQ_GE0); | ||
154 | |||
155 | else if (pending & STATUSF_IP5) | ||
156 | do_IRQ(ATH79_CPU_IRQ_GE1); | ||
157 | |||
158 | else if (pending & STATUSF_IP3) { | ||
159 | ath79_ddr_wb_flush(ath79_ip3_flush_reg); | ||
160 | do_IRQ(ATH79_CPU_IRQ_USB); | ||
161 | } | ||
162 | |||
163 | else if (pending & STATUSF_IP6) | ||
164 | do_IRQ(ATH79_CPU_IRQ_MISC); | ||
165 | |||
166 | else | ||
167 | spurious_interrupt(); | ||
168 | } | ||
169 | |||
170 | void __init arch_init_irq(void) | ||
171 | { | ||
172 | if (soc_is_ar71xx()) { | ||
173 | ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI; | ||
174 | ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB; | ||
175 | } else if (soc_is_ar724x()) { | ||
176 | ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE; | ||
177 | ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB; | ||
178 | } else if (soc_is_ar913x()) { | ||
179 | ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC; | ||
180 | ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB; | ||
181 | } else | ||
182 | BUG(); | ||
183 | |||
184 | cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC; | ||
185 | mips_cpu_irq_init(); | ||
186 | ath79_misc_irq_init(); | ||
187 | } | ||
diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c new file mode 100644 index 000000000000..eee4c121deb4 --- /dev/null +++ b/arch/mips/ath79/mach-ap81.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * Atheros AP81 board support | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2009 Imre Kaloz <kaloz@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 "machtypes.h" | ||
13 | #include "dev-ar913x-wmac.h" | ||
14 | #include "dev-gpio-buttons.h" | ||
15 | #include "dev-leds-gpio.h" | ||
16 | #include "dev-spi.h" | ||
17 | |||
18 | #define AP81_GPIO_LED_STATUS 1 | ||
19 | #define AP81_GPIO_LED_AOSS 3 | ||
20 | #define AP81_GPIO_LED_WLAN 6 | ||
21 | #define AP81_GPIO_LED_POWER 14 | ||
22 | |||
23 | #define AP81_GPIO_BTN_SW4 12 | ||
24 | #define AP81_GPIO_BTN_SW1 21 | ||
25 | |||
26 | #define AP81_KEYS_POLL_INTERVAL 20 /* msecs */ | ||
27 | #define AP81_KEYS_DEBOUNCE_INTERVAL (3 * AP81_KEYS_POLL_INTERVAL) | ||
28 | |||
29 | #define AP81_CAL_DATA_ADDR 0x1fff1000 | ||
30 | |||
31 | static struct gpio_led ap81_leds_gpio[] __initdata = { | ||
32 | { | ||
33 | .name = "ap81:green:status", | ||
34 | .gpio = AP81_GPIO_LED_STATUS, | ||
35 | .active_low = 1, | ||
36 | }, { | ||
37 | .name = "ap81:amber:aoss", | ||
38 | .gpio = AP81_GPIO_LED_AOSS, | ||
39 | .active_low = 1, | ||
40 | }, { | ||
41 | .name = "ap81:green:wlan", | ||
42 | .gpio = AP81_GPIO_LED_WLAN, | ||
43 | .active_low = 1, | ||
44 | }, { | ||
45 | .name = "ap81:green:power", | ||
46 | .gpio = AP81_GPIO_LED_POWER, | ||
47 | .active_low = 1, | ||
48 | } | ||
49 | }; | ||
50 | |||
51 | static struct gpio_keys_button ap81_gpio_keys[] __initdata = { | ||
52 | { | ||
53 | .desc = "sw1", | ||
54 | .type = EV_KEY, | ||
55 | .code = BTN_0, | ||
56 | .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL, | ||
57 | .gpio = AP81_GPIO_BTN_SW1, | ||
58 | .active_low = 1, | ||
59 | } , { | ||
60 | .desc = "sw4", | ||
61 | .type = EV_KEY, | ||
62 | .code = BTN_1, | ||
63 | .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL, | ||
64 | .gpio = AP81_GPIO_BTN_SW4, | ||
65 | .active_low = 1, | ||
66 | } | ||
67 | }; | ||
68 | |||
69 | static struct spi_board_info ap81_spi_info[] = { | ||
70 | { | ||
71 | .bus_num = 0, | ||
72 | .chip_select = 0, | ||
73 | .max_speed_hz = 25000000, | ||
74 | .modalias = "m25p64", | ||
75 | } | ||
76 | }; | ||
77 | |||
78 | static struct ath79_spi_platform_data ap81_spi_data = { | ||
79 | .bus_num = 0, | ||
80 | .num_chipselect = 1, | ||
81 | }; | ||
82 | |||
83 | static void __init ap81_setup(void) | ||
84 | { | ||
85 | u8 *cal_data = (u8 *) KSEG1ADDR(AP81_CAL_DATA_ADDR); | ||
86 | |||
87 | ath79_register_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio), | ||
88 | ap81_leds_gpio); | ||
89 | ath79_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL, | ||
90 | ARRAY_SIZE(ap81_gpio_keys), | ||
91 | ap81_gpio_keys); | ||
92 | ath79_register_spi(&ap81_spi_data, ap81_spi_info, | ||
93 | ARRAY_SIZE(ap81_spi_info)); | ||
94 | ath79_register_ar913x_wmac(cal_data); | ||
95 | } | ||
96 | |||
97 | MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board", | ||
98 | ap81_setup); | ||
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c new file mode 100644 index 000000000000..ec7b7a135d53 --- /dev/null +++ b/arch/mips/ath79/mach-pb44.c | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * Atheros PB44 reference board support | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org> | ||
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/init.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/i2c-gpio.h> | ||
15 | #include <linux/i2c/pcf857x.h> | ||
16 | |||
17 | #include "machtypes.h" | ||
18 | #include "dev-gpio-buttons.h" | ||
19 | #include "dev-leds-gpio.h" | ||
20 | #include "dev-spi.h" | ||
21 | |||
22 | #define PB44_GPIO_I2C_SCL 0 | ||
23 | #define PB44_GPIO_I2C_SDA 1 | ||
24 | |||
25 | #define PB44_GPIO_EXP_BASE 16 | ||
26 | #define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + 6) | ||
27 | #define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + 8) | ||
28 | #define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + 9) | ||
29 | #define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + 10) | ||
30 | |||
31 | #define PB44_KEYS_POLL_INTERVAL 20 /* msecs */ | ||
32 | #define PB44_KEYS_DEBOUNCE_INTERVAL (3 * PB44_KEYS_POLL_INTERVAL) | ||
33 | |||
34 | static struct i2c_gpio_platform_data pb44_i2c_gpio_data = { | ||
35 | .sda_pin = PB44_GPIO_I2C_SDA, | ||
36 | .scl_pin = PB44_GPIO_I2C_SCL, | ||
37 | }; | ||
38 | |||
39 | static struct platform_device pb44_i2c_gpio_device = { | ||
40 | .name = "i2c-gpio", | ||
41 | .id = 0, | ||
42 | .dev = { | ||
43 | .platform_data = &pb44_i2c_gpio_data, | ||
44 | } | ||
45 | }; | ||
46 | |||
47 | static struct pcf857x_platform_data pb44_pcf857x_data = { | ||
48 | .gpio_base = PB44_GPIO_EXP_BASE, | ||
49 | }; | ||
50 | |||
51 | static struct i2c_board_info pb44_i2c_board_info[] __initdata = { | ||
52 | { | ||
53 | I2C_BOARD_INFO("pcf8575", 0x20), | ||
54 | .platform_data = &pb44_pcf857x_data, | ||
55 | }, | ||
56 | }; | ||
57 | |||
58 | static struct gpio_led pb44_leds_gpio[] __initdata = { | ||
59 | { | ||
60 | .name = "pb44:amber:jump1", | ||
61 | .gpio = PB44_GPIO_LED_JUMP1, | ||
62 | .active_low = 1, | ||
63 | }, { | ||
64 | .name = "pb44:green:jump2", | ||
65 | .gpio = PB44_GPIO_LED_JUMP2, | ||
66 | .active_low = 1, | ||
67 | }, | ||
68 | }; | ||
69 | |||
70 | static struct gpio_keys_button pb44_gpio_keys[] __initdata = { | ||
71 | { | ||
72 | .desc = "soft_reset", | ||
73 | .type = EV_KEY, | ||
74 | .code = KEY_RESTART, | ||
75 | .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL, | ||
76 | .gpio = PB44_GPIO_SW_RESET, | ||
77 | .active_low = 1, | ||
78 | } , { | ||
79 | .desc = "jumpstart", | ||
80 | .type = EV_KEY, | ||
81 | .code = KEY_WPS_BUTTON, | ||
82 | .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL, | ||
83 | .gpio = PB44_GPIO_SW_JUMP, | ||
84 | .active_low = 1, | ||
85 | } | ||
86 | }; | ||
87 | |||
88 | static struct spi_board_info pb44_spi_info[] = { | ||
89 | { | ||
90 | .bus_num = 0, | ||
91 | .chip_select = 0, | ||
92 | .max_speed_hz = 25000000, | ||
93 | .modalias = "m25p64", | ||
94 | }, | ||
95 | }; | ||
96 | |||
97 | static struct ath79_spi_platform_data pb44_spi_data = { | ||
98 | .bus_num = 0, | ||
99 | .num_chipselect = 1, | ||
100 | }; | ||
101 | |||
102 | static void __init pb44_init(void) | ||
103 | { | ||
104 | i2c_register_board_info(0, pb44_i2c_board_info, | ||
105 | ARRAY_SIZE(pb44_i2c_board_info)); | ||
106 | platform_device_register(&pb44_i2c_gpio_device); | ||
107 | |||
108 | ath79_register_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio), | ||
109 | pb44_leds_gpio); | ||
110 | ath79_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL, | ||
111 | ARRAY_SIZE(pb44_gpio_keys), | ||
112 | pb44_gpio_keys); | ||
113 | ath79_register_spi(&pb44_spi_data, pb44_spi_info, | ||
114 | ARRAY_SIZE(pb44_spi_info)); | ||
115 | } | ||
116 | |||
117 | MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board", | ||
118 | pb44_init); | ||
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h new file mode 100644 index 000000000000..3940fe470b2d --- /dev/null +++ b/arch/mips/ath79/machtypes.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X machine type definitions | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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 | #ifndef _ATH79_MACHTYPE_H | ||
13 | #define _ATH79_MACHTYPE_H | ||
14 | |||
15 | #include <asm/mips_machine.h> | ||
16 | |||
17 | enum ath79_mach_type { | ||
18 | ATH79_MACH_GENERIC = 0, | ||
19 | ATH79_MACH_AP81, /* Atheros AP81 reference board */ | ||
20 | ATH79_MACH_PB44, /* Atheros PB44 reference board */ | ||
21 | }; | ||
22 | |||
23 | #endif /* _ATH79_MACHTYPE_H */ | ||
diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c new file mode 100644 index 000000000000..e9cbd7c2918f --- /dev/null +++ b/arch/mips/ath79/prom.c | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X specific prom routines | ||
3 | * | ||
4 | * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org> | ||
5 | * Copyright (C) 2008 Imre Kaloz <kaloz@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/kernel.h> | ||
13 | #include <linux/init.h> | ||
14 | #include <linux/io.h> | ||
15 | #include <linux/string.h> | ||
16 | |||
17 | #include <asm/bootinfo.h> | ||
18 | #include <asm/addrspace.h> | ||
19 | |||
20 | #include "common.h" | ||
21 | |||
22 | static inline int is_valid_ram_addr(void *addr) | ||
23 | { | ||
24 | if (((u32) addr > KSEG0) && | ||
25 | ((u32) addr < (KSEG0 + ATH79_MEM_SIZE_MAX))) | ||
26 | return 1; | ||
27 | |||
28 | if (((u32) addr > KSEG1) && | ||
29 | ((u32) addr < (KSEG1 + ATH79_MEM_SIZE_MAX))) | ||
30 | return 1; | ||
31 | |||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | static __init void ath79_prom_init_cmdline(int argc, char **argv) | ||
36 | { | ||
37 | int i; | ||
38 | |||
39 | if (!is_valid_ram_addr(argv)) | ||
40 | return; | ||
41 | |||
42 | for (i = 0; i < argc; i++) | ||
43 | if (is_valid_ram_addr(argv[i])) { | ||
44 | strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline)); | ||
45 | strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline)); | ||
46 | } | ||
47 | } | ||
48 | |||
49 | void __init prom_init(void) | ||
50 | { | ||
51 | ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1); | ||
52 | } | ||
53 | |||
54 | void __init prom_free_prom_memory(void) | ||
55 | { | ||
56 | /* We do not have to prom memory to free */ | ||
57 | } | ||
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c new file mode 100644 index 000000000000..159b42f106b0 --- /dev/null +++ b/arch/mips/ath79/setup.c | |||
@@ -0,0 +1,206 @@ | |||
1 | /* | ||
2 | * Atheros AR71XX/AR724X/AR913X specific setup | ||
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/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/bootmem.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/clk.h> | ||
19 | |||
20 | #include <asm/bootinfo.h> | ||
21 | #include <asm/time.h> /* for mips_hpt_frequency */ | ||
22 | #include <asm/reboot.h> /* for _machine_{restart,halt} */ | ||
23 | #include <asm/mips_machine.h> | ||
24 | |||
25 | #include <asm/mach-ath79/ath79.h> | ||
26 | #include <asm/mach-ath79/ar71xx_regs.h> | ||
27 | #include "common.h" | ||
28 | #include "dev-common.h" | ||
29 | #include "machtypes.h" | ||
30 | |||
31 | #define ATH79_SYS_TYPE_LEN 64 | ||
32 | |||
33 | #define AR71XX_BASE_FREQ 40000000 | ||
34 | #define AR724X_BASE_FREQ 5000000 | ||
35 | #define AR913X_BASE_FREQ 5000000 | ||
36 | |||
37 | static char ath79_sys_type[ATH79_SYS_TYPE_LEN]; | ||
38 | |||
39 | static void ath79_restart(char *command) | ||
40 | { | ||
41 | ath79_device_reset_set(AR71XX_RESET_FULL_CHIP); | ||
42 | for (;;) | ||
43 | if (cpu_wait) | ||
44 | cpu_wait(); | ||
45 | } | ||
46 | |||
47 | static void ath79_halt(void) | ||
48 | { | ||
49 | while (1) | ||
50 | cpu_wait(); | ||
51 | } | ||
52 | |||
53 | static void __init ath79_detect_mem_size(void) | ||
54 | { | ||
55 | unsigned long size; | ||
56 | |||
57 | for (size = ATH79_MEM_SIZE_MIN; size < ATH79_MEM_SIZE_MAX; | ||
58 | size <<= 1) { | ||
59 | if (!memcmp(ath79_detect_mem_size, | ||
60 | ath79_detect_mem_size + size, 1024)) | ||
61 | break; | ||
62 | } | ||
63 | |||
64 | add_memory_region(0, size, BOOT_MEM_RAM); | ||
65 | } | ||
66 | |||
67 | static void __init ath79_detect_sys_type(void) | ||
68 | { | ||
69 | char *chip = "????"; | ||
70 | u32 id; | ||
71 | u32 major; | ||
72 | u32 minor; | ||
73 | u32 rev = 0; | ||
74 | |||
75 | id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID); | ||
76 | major = id & REV_ID_MAJOR_MASK; | ||
77 | |||
78 | switch (major) { | ||
79 | case REV_ID_MAJOR_AR71XX: | ||
80 | minor = id & AR71XX_REV_ID_MINOR_MASK; | ||
81 | rev = id >> AR71XX_REV_ID_REVISION_SHIFT; | ||
82 | rev &= AR71XX_REV_ID_REVISION_MASK; | ||
83 | switch (minor) { | ||
84 | case AR71XX_REV_ID_MINOR_AR7130: | ||
85 | ath79_soc = ATH79_SOC_AR7130; | ||
86 | chip = "7130"; | ||
87 | break; | ||
88 | |||
89 | case AR71XX_REV_ID_MINOR_AR7141: | ||
90 | ath79_soc = ATH79_SOC_AR7141; | ||
91 | chip = "7141"; | ||
92 | break; | ||
93 | |||
94 | case AR71XX_REV_ID_MINOR_AR7161: | ||
95 | ath79_soc = ATH79_SOC_AR7161; | ||
96 | chip = "7161"; | ||
97 | break; | ||
98 | } | ||
99 | break; | ||
100 | |||
101 | case REV_ID_MAJOR_AR7240: | ||
102 | ath79_soc = ATH79_SOC_AR7240; | ||
103 | chip = "7240"; | ||
104 | rev = (id & AR724X_REV_ID_REVISION_MASK); | ||
105 | break; | ||
106 | |||
107 | case REV_ID_MAJOR_AR7241: | ||
108 | ath79_soc = ATH79_SOC_AR7241; | ||
109 | chip = "7241"; | ||
110 | rev = (id & AR724X_REV_ID_REVISION_MASK); | ||
111 | break; | ||
112 | |||
113 | case REV_ID_MAJOR_AR7242: | ||
114 | ath79_soc = ATH79_SOC_AR7242; | ||
115 | chip = "7242"; | ||
116 | rev = (id & AR724X_REV_ID_REVISION_MASK); | ||
117 | break; | ||
118 | |||
119 | case REV_ID_MAJOR_AR913X: | ||
120 | minor = id & AR913X_REV_ID_MINOR_MASK; | ||
121 | rev = id >> AR913X_REV_ID_REVISION_SHIFT; | ||
122 | rev &= AR913X_REV_ID_REVISION_MASK; | ||
123 | switch (minor) { | ||
124 | case AR913X_REV_ID_MINOR_AR9130: | ||
125 | ath79_soc = ATH79_SOC_AR9130; | ||
126 | chip = "9130"; | ||
127 | break; | ||
128 | |||
129 | case AR913X_REV_ID_MINOR_AR9132: | ||
130 | ath79_soc = ATH79_SOC_AR9132; | ||
131 | chip = "9132"; | ||
132 | break; | ||
133 | } | ||
134 | break; | ||
135 | |||
136 | default: | ||
137 | panic("ath79: unknown SoC, id:0x%08x\n", id); | ||
138 | } | ||
139 | |||
140 | sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev); | ||
141 | pr_info("SoC: %s\n", ath79_sys_type); | ||
142 | } | ||
143 | |||
144 | const char *get_system_type(void) | ||
145 | { | ||
146 | return ath79_sys_type; | ||
147 | } | ||
148 | |||
149 | unsigned int __cpuinit get_c0_compare_int(void) | ||
150 | { | ||
151 | return CP0_LEGACY_COMPARE_IRQ; | ||
152 | } | ||
153 | |||
154 | void __init plat_mem_setup(void) | ||
155 | { | ||
156 | set_io_port_base(KSEG1); | ||
157 | |||
158 | ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE, | ||
159 | AR71XX_RESET_SIZE); | ||
160 | ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE, | ||
161 | AR71XX_PLL_SIZE); | ||
162 | ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE, | ||
163 | AR71XX_DDR_CTRL_SIZE); | ||
164 | |||
165 | ath79_detect_sys_type(); | ||
166 | ath79_detect_mem_size(); | ||
167 | ath79_clocks_init(); | ||
168 | |||
169 | _machine_restart = ath79_restart; | ||
170 | _machine_halt = ath79_halt; | ||
171 | pm_power_off = ath79_halt; | ||
172 | } | ||
173 | |||
174 | void __init plat_time_init(void) | ||
175 | { | ||
176 | struct clk *clk; | ||
177 | |||
178 | clk = clk_get(NULL, "cpu"); | ||
179 | if (IS_ERR(clk)) | ||
180 | panic("unable to get CPU clock, err=%ld", PTR_ERR(clk)); | ||
181 | |||
182 | mips_hpt_frequency = clk_get_rate(clk) / 2; | ||
183 | } | ||
184 | |||
185 | static int __init ath79_setup(void) | ||
186 | { | ||
187 | ath79_gpio_init(); | ||
188 | ath79_register_uart(); | ||
189 | ath79_register_wdt(); | ||
190 | |||
191 | mips_machine_setup(); | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | arch_initcall(ath79_setup); | ||
197 | |||
198 | static void __init ath79_generic_init(void) | ||
199 | { | ||
200 | /* Nothing to do */ | ||
201 | } | ||
202 | |||
203 | MIPS_MACHINE(ATH79_MACH_GENERIC, | ||
204 | "Generic", | ||
205 | "Generic AR71XX/AR724X/AR913X based board", | ||
206 | ath79_generic_init); | ||