MD: Add del_timer_sync to mddev_suspend (fix nasty panic)
[linux-flexiantxendom0-3.2.10.git] / arch / mips / ath79 / dev-wmac.c
1 /*
2  *  Atheros AR913X/AR933X SoC built-in WMAC device support
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
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-wmac.h"
21
22 static struct ath9k_platform_data ath79_wmac_data;
23
24 static struct resource ath79_wmac_resources[] = {
25         {
26                 /* .start and .end fields are filled dynamically */
27                 .flags  = IORESOURCE_MEM,
28         }, {
29                 .start  = ATH79_CPU_IRQ_IP2,
30                 .end    = ATH79_CPU_IRQ_IP2,
31                 .flags  = IORESOURCE_IRQ,
32         },
33 };
34
35 static struct platform_device ath79_wmac_device = {
36         .name           = "ath9k",
37         .id             = -1,
38         .resource       = ath79_wmac_resources,
39         .num_resources  = ARRAY_SIZE(ath79_wmac_resources),
40         .dev = {
41                 .platform_data = &ath79_wmac_data,
42         },
43 };
44
45 static void __init ar913x_wmac_setup(void)
46 {
47         /* reset the WMAC */
48         ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
49         mdelay(10);
50
51         ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
52         mdelay(10);
53
54         ath79_wmac_resources[0].start = AR913X_WMAC_BASE;
55         ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1;
56 }
57
58
59 static int ar933x_wmac_reset(void)
60 {
61         ath79_device_reset_clear(AR933X_RESET_WMAC);
62         ath79_device_reset_set(AR933X_RESET_WMAC);
63
64         return 0;
65 }
66
67 static int ar933x_r1_get_wmac_revision(void)
68 {
69         return ath79_soc_rev;
70 }
71
72 static void __init ar933x_wmac_setup(void)
73 {
74         u32 t;
75
76         ar933x_wmac_reset();
77
78         ath79_wmac_device.name = "ar933x_wmac";
79
80         ath79_wmac_resources[0].start = AR933X_WMAC_BASE;
81         ath79_wmac_resources[0].end = AR933X_WMAC_BASE + AR933X_WMAC_SIZE - 1;
82
83         t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
84         if (t & AR933X_BOOTSTRAP_REF_CLK_40)
85                 ath79_wmac_data.is_clk_25mhz = false;
86         else
87                 ath79_wmac_data.is_clk_25mhz = true;
88
89         if (ath79_soc_rev == 1)
90                 ath79_wmac_data.get_mac_revision = ar933x_r1_get_wmac_revision;
91
92         ath79_wmac_data.external_reset = ar933x_wmac_reset;
93 }
94
95 void __init ath79_register_wmac(u8 *cal_data)
96 {
97         if (soc_is_ar913x())
98                 ar913x_wmac_setup();
99         else if (soc_is_ar933x())
100                 ar933x_wmac_setup();
101         else
102                 BUG();
103
104         if (cal_data)
105                 memcpy(ath79_wmac_data.eeprom_data, cal_data,
106                        sizeof(ath79_wmac_data.eeprom_data));
107
108         platform_device_register(&ath79_wmac_device);
109 }