ar5312.c revision 1.8 1 1.8 matt /* $NetBSD: ar5312.c,v 1.8 2011/07/07 05:06:44 matt Exp $ */
2 1.1 gdamore
3 1.1 gdamore /*
4 1.1 gdamore * Copyright (c) 2006 Urbana-Champaign Independent Media Center.
5 1.1 gdamore * Copyright (c) 2006 Garrett D'Amore.
6 1.1 gdamore * All rights reserved.
7 1.1 gdamore *
8 1.1 gdamore * Portions of this code were written by Garrett D'Amore for the
9 1.1 gdamore * Champaign-Urbana Community Wireless Network Project.
10 1.1 gdamore *
11 1.1 gdamore * Redistribution and use in source and binary forms, with or
12 1.1 gdamore * without modification, are permitted provided that the following
13 1.1 gdamore * conditions are met:
14 1.1 gdamore * 1. Redistributions of source code must retain the above copyright
15 1.1 gdamore * notice, this list of conditions and the following disclaimer.
16 1.1 gdamore * 2. Redistributions in binary form must reproduce the above
17 1.1 gdamore * copyright notice, this list of conditions and the following
18 1.1 gdamore * disclaimer in the documentation and/or other materials provided
19 1.1 gdamore * with the distribution.
20 1.1 gdamore * 3. All advertising materials mentioning features or use of this
21 1.1 gdamore * software must display the following acknowledgements:
22 1.1 gdamore * This product includes software developed by the Urbana-Champaign
23 1.1 gdamore * Independent Media Center.
24 1.1 gdamore * This product includes software developed by Garrett D'Amore.
25 1.1 gdamore * 4. Urbana-Champaign Independent Media Center's name and Garrett
26 1.1 gdamore * D'Amore's name may not be used to endorse or promote products
27 1.1 gdamore * derived from this software without specific prior written permission.
28 1.1 gdamore *
29 1.1 gdamore * THIS SOFTWARE IS PROVIDED BY THE URBANA-CHAMPAIGN INDEPENDENT
30 1.1 gdamore * MEDIA CENTER AND GARRETT D'AMORE ``AS IS'' AND ANY EXPRESS OR
31 1.1 gdamore * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
32 1.1 gdamore * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
33 1.1 gdamore * ARE DISCLAIMED. IN NO EVENT SHALL THE URBANA-CHAMPAIGN INDEPENDENT
34 1.1 gdamore * MEDIA CENTER OR GARRETT D'AMORE BE LIABLE FOR ANY DIRECT, INDIRECT,
35 1.1 gdamore * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36 1.1 gdamore * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
37 1.1 gdamore * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38 1.1 gdamore * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 1.1 gdamore * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
40 1.1 gdamore * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
41 1.1 gdamore * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
42 1.1 gdamore */
43 1.1 gdamore
44 1.1 gdamore /*
45 1.1 gdamore * This file includes a bunch of implementation specific bits for
46 1.1 gdamore * AR5312, which differents these from other members of the AR5315
47 1.1 gdamore * family.
48 1.1 gdamore */
49 1.1 gdamore #include "opt_ddb.h"
50 1.1 gdamore #include "opt_kgdb.h"
51 1.8 matt #define __INTR_PRIVATE
52 1.1 gdamore
53 1.1 gdamore #include "opt_memsize.h"
54 1.1 gdamore #include <sys/param.h>
55 1.1 gdamore #include <sys/systm.h>
56 1.7 matt #include <sys/device.h>
57 1.1 gdamore #include <sys/kernel.h>
58 1.1 gdamore #include <sys/buf.h>
59 1.1 gdamore
60 1.1 gdamore #include <mips/cache.h>
61 1.1 gdamore #include <mips/locore.h>
62 1.1 gdamore #include <mips/cpuregs.h>
63 1.1 gdamore
64 1.2 gdamore #include <sys/socket.h> /* these three just to get ETHER_ADDR_LEN(!) */
65 1.2 gdamore #include <net/if.h>
66 1.2 gdamore #include <net/if_ether.h>
67 1.2 gdamore
68 1.5 dyoung #include <prop/proplib.h>
69 1.5 dyoung
70 1.8 matt #include <ah_soc.h>
71 1.8 matt
72 1.8 matt #include <mips/atheros/include/platform.h>
73 1.8 matt #include <mips/atheros/include/arbusvar.h>
74 1.1 gdamore #include <mips/atheros/include/ar5312reg.h>
75 1.1 gdamore #include "com.h"
76 1.1 gdamore
77 1.8 matt static uint32_t
78 1.8 matt ar5312_get_memsize(void)
79 1.1 gdamore {
80 1.1 gdamore uint32_t memsize;
81 1.1 gdamore uint32_t memcfg, bank0, bank1;
82 1.1 gdamore
83 1.1 gdamore /*
84 1.2 gdamore * Determine the memory size as established by system
85 1.2 gdamore * firmware.
86 1.1 gdamore *
87 1.1 gdamore * NB: we allow compile time override
88 1.1 gdamore */
89 1.1 gdamore #if defined(MEMSIZE)
90 1.1 gdamore memsize = MEMSIZE;
91 1.1 gdamore #else
92 1.1 gdamore memcfg = GETSDRAMREG(AR5312_SDRAMCTL_MEM_CFG1);
93 1.8 matt bank0 = __SHIFTOUT(memcfg, AR5312_MEM_CFG1_BANK0);
94 1.8 matt bank1 = __SHIFTOUT(memcfg, AR5312_MEM_CFG1_BANK1);
95 1.1 gdamore
96 1.1 gdamore memsize = (bank0 ? (1 << (bank0 + 1)) : 0) +
97 1.1 gdamore (bank1 ? (1 << (bank1 + 1)) : 0);
98 1.1 gdamore memsize <<= 20;
99 1.1 gdamore #endif
100 1.1 gdamore
101 1.1 gdamore return (memsize);
102 1.1 gdamore }
103 1.1 gdamore
104 1.8 matt static void
105 1.8 matt ar5312_wdog_reload(uint32_t period)
106 1.1 gdamore {
107 1.1 gdamore
108 1.1 gdamore if (period == 0) {
109 1.1 gdamore PUTSYSREG(AR5312_SYSREG_WDOG_CTL, AR5312_WDOG_CTL_IGNORE);
110 1.1 gdamore PUTSYSREG(AR5312_SYSREG_WDOG_TIMER, 0);
111 1.1 gdamore } else {
112 1.1 gdamore PUTSYSREG(AR5312_SYSREG_WDOG_TIMER, period);
113 1.1 gdamore PUTSYSREG(AR5312_SYSREG_WDOG_CTL, AR5312_WDOG_CTL_RESET);
114 1.1 gdamore }
115 1.1 gdamore }
116 1.1 gdamore
117 1.8 matt static void
118 1.8 matt ar5312_bus_init(void)
119 1.1 gdamore {
120 1.1 gdamore /*
121 1.1 gdamore * Clear previous AHB errors
122 1.1 gdamore */
123 1.1 gdamore GETSYSREG(AR5312_SYSREG_AHBPERR);
124 1.1 gdamore GETSYSREG(AR5312_SYSREG_AHBDMAE);
125 1.1 gdamore }
126 1.1 gdamore
127 1.8 matt static void
128 1.8 matt ar5312_reset(void)
129 1.8 matt {
130 1.8 matt PUTSYSREG(AR5312_SYSREG_RESETCTL, AR5312_RESET_SYSTEM);
131 1.8 matt }
132 1.8 matt
133 1.8 matt static void
134 1.8 matt ar5312_get_freqs(struct arfreqs *freqs)
135 1.1 gdamore {
136 1.8 matt const uint32_t wisoc = GETSYSREG(AR5312_SYSREG_REVISION);
137 1.1 gdamore
138 1.8 matt uint32_t predivisor;
139 1.1 gdamore uint32_t multiplier;
140 1.1 gdamore
141 1.1 gdamore /*
142 1.1 gdamore * This logic looks at the clock control register and
143 1.1 gdamore * determines the actual CPU frequency. These parts lack any
144 1.1 gdamore * kind of real-time clock on them, but the cpu clocks should
145 1.1 gdamore * be very accurate -- WiFi requires usec resolution timers.
146 1.1 gdamore */
147 1.1 gdamore
148 1.8 matt const uint32_t clockctl = GETSYSREG(AR5312_SYSREG_CLOCKCTL);
149 1.1 gdamore
150 1.1 gdamore if (AR5312_REVISION_MAJOR(wisoc) == AR5312_REVISION_MAJ_AR2313) {
151 1.8 matt predivisor = __SHIFTOUT(clockctl, AR2313_CLOCKCTL_PREDIVIDE);
152 1.8 matt multiplier = __SHIFTOUT(clockctl, AR2313_CLOCKCTL_MULTIPLIER);
153 1.1 gdamore } else {
154 1.8 matt predivisor = __SHIFTOUT(clockctl, AR5312_CLOCKCTL_PREDIVIDE);
155 1.8 matt multiplier = __SHIFTOUT(clockctl, AR5312_CLOCKCTL_MULTIPLIER);
156 1.8 matt if (clockctl & AR5312_CLOCKCTL_DOUBLER)
157 1.8 matt multiplier <<= 1;
158 1.1 gdamore }
159 1.1 gdamore
160 1.1 gdamore /*
161 1.1 gdamore * Note that the source clock involved here is a 40MHz.
162 1.1 gdamore */
163 1.1 gdamore
164 1.8 matt const uint32_t divisor = (0x5421 >> (predivisor * 4)) & 15;
165 1.1 gdamore
166 1.8 matt const uint32_t cpufreq = (40000000 / divisor) * multiplier;
167 1.1 gdamore
168 1.8 matt freqs->freq_cpu = cpufreq;
169 1.8 matt freqs->freq_bus = cpufreq / 4;
170 1.8 matt freqs->freq_mem = 0;
171 1.8 matt freqs->freq_ref = 40000000;
172 1.8 matt freqs->freq_pll = 40000000;
173 1.1 gdamore }
174 1.1 gdamore
175 1.2 gdamore
176 1.2 gdamore static void
177 1.2 gdamore addprop_data(struct device *dev, const char *name, const uint8_t *data,
178 1.2 gdamore int len)
179 1.2 gdamore {
180 1.2 gdamore prop_data_t pd;
181 1.2 gdamore pd = prop_data_create_data(data, len);
182 1.2 gdamore KASSERT(pd != NULL);
183 1.4 thorpej if (prop_dictionary_set(device_properties(dev), name, pd) == false) {
184 1.2 gdamore printf("WARNING: unable to set %s property for %s\n",
185 1.2 gdamore name, device_xname(dev));
186 1.2 gdamore }
187 1.2 gdamore prop_object_release(pd);
188 1.2 gdamore }
189 1.2 gdamore
190 1.2 gdamore static void
191 1.2 gdamore addprop_integer(struct device *dev, const char *name, uint32_t val)
192 1.2 gdamore {
193 1.2 gdamore prop_number_t pn;
194 1.2 gdamore pn = prop_number_create_integer(val);
195 1.2 gdamore KASSERT(pn != NULL);
196 1.4 thorpej if (prop_dictionary_set(device_properties(dev), name, pn) == false) {
197 1.2 gdamore printf("WARNING: unable to set %s property for %s",
198 1.2 gdamore name, device_xname(dev));
199 1.2 gdamore }
200 1.2 gdamore prop_object_release(pn);
201 1.2 gdamore }
202 1.2 gdamore
203 1.8 matt static void
204 1.8 matt ar5312_device_register(device_t dev, void *aux)
205 1.2 gdamore {
206 1.8 matt const struct arbus_attach_args * const aa = aux;
207 1.8 matt
208 1.8 matt if (device_is_a(dev, "com")) {
209 1.8 matt addprop_integer(dev, "frequency", atheros_get_bus_freq());
210 1.8 matt }
211 1.2 gdamore
212 1.8 matt const struct ar531x_boarddata * const info = atheros_get_board_info();
213 1.2 gdamore if (info == NULL) {
214 1.2 gdamore /* nothing known about this board! */
215 1.2 gdamore return;
216 1.2 gdamore }
217 1.2 gdamore
218 1.2 gdamore /*
219 1.2 gdamore * We don't ever know the boot device. But that's because the
220 1.2 gdamore * firmware only loads from the network.
221 1.2 gdamore */
222 1.2 gdamore
223 1.2 gdamore /* Fetch the MAC addresses. */
224 1.2 gdamore if (device_is_a(dev, "ae")) {
225 1.2 gdamore const uint8_t *enet;
226 1.2 gdamore
227 1.2 gdamore if (aa->aa_addr == AR5312_ENET0_BASE)
228 1.2 gdamore enet = info->enet0Mac;
229 1.2 gdamore else if (aa->aa_addr == AR5312_ENET1_BASE)
230 1.2 gdamore enet = info->enet1Mac;
231 1.2 gdamore else
232 1.2 gdamore return;
233 1.2 gdamore
234 1.6 martin addprop_data(dev, "mac-address", enet, ETHER_ADDR_LEN);
235 1.2 gdamore }
236 1.2 gdamore
237 1.2 gdamore if (device_is_a(dev, "ath")) {
238 1.2 gdamore const uint8_t *enet;
239 1.2 gdamore
240 1.2 gdamore if (aa->aa_addr == AR5312_WLAN0_BASE)
241 1.2 gdamore enet = info->wlan0Mac;
242 1.2 gdamore else if (aa->aa_addr == AR5312_WLAN1_BASE)
243 1.2 gdamore enet = info->wlan1Mac;
244 1.2 gdamore else
245 1.2 gdamore return;
246 1.2 gdamore
247 1.6 martin addprop_data(dev, "mac-address", enet, ETHER_ADDR_LEN);
248 1.3 gdamore
249 1.3 gdamore addprop_integer(dev, "wmac-rev",
250 1.3 gdamore AR5312_REVISION_WMAC(GETSYSREG(AR5312_SYSREG_REVISION)));
251 1.3 gdamore
252 1.2 gdamore }
253 1.2 gdamore
254 1.2 gdamore if (device_is_a(dev, "argpio")) {
255 1.2 gdamore if (info->config & BD_RSTFACTORY) {
256 1.2 gdamore addprop_integer(dev, "reset-pin",
257 1.2 gdamore info->resetConfigGpio);
258 1.2 gdamore }
259 1.2 gdamore if (info->config & BD_SYSLED) {
260 1.2 gdamore addprop_integer(dev, "sysled-pin",
261 1.2 gdamore info->sysLedGpio);
262 1.2 gdamore }
263 1.2 gdamore }
264 1.2 gdamore }
265 1.2 gdamore
266 1.8 matt static int
267 1.8 matt ar5312_enable_device(const struct atheros_device *adv)
268 1.2 gdamore {
269 1.8 matt const struct ar531x_boarddata * const info = atheros_get_board_info();
270 1.2 gdamore
271 1.8 matt if (info != NULL
272 1.8 matt && adv->adv_mask && ((adv->adv_mask & info->config) == 0)) {
273 1.2 gdamore return -1;
274 1.2 gdamore }
275 1.8 matt if (adv->adv_reset) {
276 1.2 gdamore /* put device into reset */
277 1.2 gdamore PUTSYSREG(AR5312_SYSREG_RESETCTL,
278 1.8 matt GETSYSREG(AR5312_SYSREG_RESETCTL) | adv->adv_reset);
279 1.2 gdamore
280 1.2 gdamore delay(15000); /* XXX: tsleep? */
281 1.2 gdamore
282 1.2 gdamore /* take it out of reset */
283 1.2 gdamore PUTSYSREG(AR5312_SYSREG_RESETCTL,
284 1.8 matt GETSYSREG(AR5312_SYSREG_RESETCTL) & ~adv->adv_reset);
285 1.2 gdamore
286 1.2 gdamore delay(25);
287 1.2 gdamore }
288 1.8 matt if (adv->adv_enable) {
289 1.2 gdamore PUTSYSREG(AR5312_SYSREG_ENABLE,
290 1.8 matt GETSYSREG(AR5312_SYSREG_ENABLE) | adv->adv_enable);
291 1.2 gdamore }
292 1.2 gdamore return 0;
293 1.2 gdamore }
294 1.2 gdamore
295 1.8 matt static void
296 1.8 matt ar5312_intr_init(void)
297 1.2 gdamore {
298 1.8 matt atheros_intr_init();
299 1.8 matt }
300 1.2 gdamore
301 1.8 matt static const struct atheros_device ar5312_devices[] = {
302 1.8 matt {
303 1.8 matt .adv_name = "ae",
304 1.8 matt .adv_addr = AR5312_ENET0_BASE,
305 1.8 matt .adv_size = 0x100000,
306 1.8 matt .adv_cirq = AR5312_IRQ_ENET0,
307 1.8 matt .adv_mirq = -1,
308 1.8 matt .adv_mask = AR5312_BOARD_CONFIG_ENET0,
309 1.8 matt .adv_reset = AR5312_RESET_ENET0 | AR5312_RESET_PHY0,
310 1.8 matt .adv_enable = AR5312_ENABLE_ENET0
311 1.8 matt }, {
312 1.8 matt .adv_name = "ae",
313 1.8 matt .adv_addr = AR5312_ENET1_BASE,
314 1.8 matt .adv_size = 0x100000,
315 1.8 matt .adv_cirq = AR5312_IRQ_ENET1,
316 1.8 matt .adv_mirq = -1,
317 1.8 matt .adv_mask = AR5312_BOARD_CONFIG_ENET1,
318 1.8 matt .adv_reset = AR5312_RESET_ENET1 | AR5312_RESET_PHY1,
319 1.8 matt .adv_enable = AR5312_ENABLE_ENET1
320 1.8 matt }, {
321 1.8 matt .adv_name = "com",
322 1.8 matt .adv_addr = AR5312_UART0_BASE,
323 1.8 matt .adv_size = 0x1000,
324 1.8 matt .adv_cirq = AR5312_IRQ_MISC,
325 1.8 matt .adv_mirq = AR5312_MISC_IRQ_UART0,
326 1.8 matt .adv_mask = AR5312_BOARD_CONFIG_UART0,
327 1.8 matt }, {
328 1.8 matt .adv_name = "com",
329 1.8 matt .adv_addr = AR5312_UART1_BASE,
330 1.8 matt .adv_size = 0x1000,
331 1.8 matt .adv_cirq = -1,
332 1.8 matt .adv_mirq = -1,
333 1.8 matt .adv_mask = AR5312_BOARD_CONFIG_UART1,
334 1.8 matt }, {
335 1.8 matt .adv_name = "ath",
336 1.8 matt .adv_addr = AR5312_WLAN0_BASE,
337 1.8 matt .adv_size = 0x100000,
338 1.8 matt .adv_cirq = AR5312_IRQ_WLAN0,
339 1.8 matt .adv_mirq = -1,
340 1.8 matt .adv_mask = AR5312_BOARD_CONFIG_WLAN0,
341 1.8 matt .adv_reset = AR5312_RESET_WLAN0 | AR5312_RESET_WARM_WLAN0_MAC
342 1.8 matt | AR5312_RESET_WARM_WLAN0_BB,
343 1.8 matt .adv_enable = AR5312_ENABLE_WLAN0
344 1.8 matt }, {
345 1.8 matt .adv_name = "ath",
346 1.8 matt .adv_addr = AR5312_WLAN1_BASE,
347 1.8 matt .adv_size = 0x100000,
348 1.8 matt .adv_cirq = AR5312_IRQ_WLAN1,
349 1.8 matt .adv_mirq = -1,
350 1.8 matt .adv_mask = AR5312_BOARD_CONFIG_WLAN1,
351 1.8 matt .adv_reset = AR5312_RESET_WLAN1 | AR5312_RESET_WARM_WLAN1_MAC
352 1.8 matt | AR5312_RESET_WARM_WLAN1_BB,
353 1.8 matt .adv_enable = AR5312_ENABLE_WLAN1
354 1.8 matt }, {
355 1.8 matt .adv_name = "athflash",
356 1.8 matt .adv_addr = AR5312_FLASH_BASE,
357 1.8 matt .adv_size = 0,
358 1.8 matt .adv_cirq = -1,
359 1.8 matt .adv_mirq = -1,
360 1.8 matt }, {
361 1.8 matt .adv_name = "argpio",
362 1.8 matt .adv_addr = AR5312_GPIO_BASE,
363 1.8 matt .adv_size = 0x1000,
364 1.8 matt .adv_cirq = AR5312_IRQ_MISC,
365 1.8 matt .adv_mirq = AR5312_MISC_IRQ_GPIO,
366 1.8 matt }, {
367 1.8 matt .adv_name = NULL
368 1.8 matt }
369 1.8 matt };
370 1.8 matt
371 1.8 matt static const struct ipl_sr_map ar5312_ipl_sr_map = {
372 1.8 matt .sr_bits = {
373 1.8 matt [IPL_NONE] = 0,
374 1.8 matt [IPL_SOFTCLOCK] = MIPS_SOFT_INT_MASK_0,
375 1.8 matt [IPL_SOFTBIO] = MIPS_SOFT_INT_MASK_0,
376 1.8 matt [IPL_SOFTNET] = MIPS_SOFT_INT_MASK,
377 1.8 matt [IPL_SOFTSERIAL] = MIPS_SOFT_INT_MASK,
378 1.8 matt [IPL_VM] = MIPS_SOFT_INT_MASK | MIPS_INT_MASK_0
379 1.8 matt | MIPS_INT_MASK_1 | MIPS_INT_MASK_2
380 1.8 matt | MIPS_INT_MASK_3,
381 1.8 matt [IPL_SCHED] = MIPS_INT_MASK,
382 1.8 matt [IPL_DDB] = MIPS_INT_MASK,
383 1.8 matt [IPL_HIGH] = MIPS_INT_MASK,
384 1.8 matt },
385 1.8 matt };
386 1.8 matt
387 1.8 matt static const char * const ar5312_cpu_intrnames[] = {
388 1.8 matt "int 0 (wlan0)",
389 1.8 matt "int 1 (enet0)",
390 1.8 matt "int 2 (enet1)",
391 1.8 matt "int 3 (wlan1)",
392 1.8 matt "int 4 (misc)",
393 1.8 matt "int 5 (timer)",
394 1.8 matt };
395 1.8 matt
396 1.8 matt static const char * const ar5312_misc_intrnames[] = {
397 1.8 matt "misc 0 (timer)",
398 1.8 matt "misc 1 (AHBproc error)",
399 1.8 matt "misc 2 (AHBdma error)",
400 1.8 matt "misc 3 (gpio)",
401 1.8 matt "misc 4 (uart)",
402 1.8 matt "misc 5 (uart dma)",
403 1.8 matt "misc 6 (watchdog)"
404 1.8 matt };
405 1.8 matt
406 1.8 matt
407 1.8 matt const struct atheros_platformsw ar5312_platformsw = {
408 1.8 matt .apsw_intrsw = &atheros_intrsw,
409 1.8 matt .apsw_intr_init = ar5312_intr_init,
410 1.8 matt .apsw_cpu_intrnames = ar5312_cpu_intrnames,
411 1.8 matt .apsw_misc_intrnames = ar5312_misc_intrnames,
412 1.8 matt .apsw_cpu_nintrs = __arraycount(ar5312_cpu_intrnames),
413 1.8 matt .apsw_misc_nintrs = __arraycount(ar5312_misc_intrnames),
414 1.8 matt .apsw_cpuirq_misc = AR5312_IRQ_MISC,
415 1.8 matt .apsw_ipl_sr_map = &ar5312_ipl_sr_map,
416 1.8 matt
417 1.8 matt .apsw_revision_id_addr = AR5312_SYSREG_BASE + AR5312_SYSREG_REVISION,
418 1.8 matt .apsw_uart0_base = AR5312_UART0_BASE,
419 1.8 matt .apsw_misc_intstat = AR5312_SYSREG_BASE + AR5312_SYSREG_MISC_INTSTAT,
420 1.8 matt .apsw_misc_intmask = AR5312_SYSREG_BASE + AR5312_SYSREG_MISC_INTMASK,
421 1.2 gdamore
422 1.8 matt /*
423 1.8 matt * CPU specific routines.
424 1.8 matt */
425 1.8 matt .apsw_get_memsize = ar5312_get_memsize,
426 1.8 matt .apsw_wdog_reload = ar5312_wdog_reload,
427 1.8 matt .apsw_bus_init = ar5312_bus_init,
428 1.8 matt .apsw_reset = ar5312_reset,
429 1.8 matt
430 1.8 matt .apsw_get_freqs = ar5312_get_freqs,
431 1.8 matt .apsw_device_register = ar5312_device_register,
432 1.8 matt .apsw_enable_device = ar5312_enable_device,
433 1.8 matt .apsw_devices = ar5312_devices,
434 1.8 matt };
435