diff options
author | 2025-03-08 22:04:20 +0800 | |
---|---|---|
committer | 2025-03-08 22:04:20 +0800 | |
commit | a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch) | |
tree | 84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/bcm47xx | |
download | ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.tar.gz ohosKernel-a07bb8fd1299070229f0e8f3dcb57ffd5ef9870a.zip |
Initial commit: OpenHarmony-v4.0-ReleaseOpenHarmony-v4.0-Release
Diffstat (limited to 'arch/mips/bcm47xx')
-rw-r--r-- | arch/mips/bcm47xx/Kconfig | 39 | ||||
-rw-r--r-- | arch/mips/bcm47xx/Makefile | 8 | ||||
-rw-r--r-- | arch/mips/bcm47xx/Platform | 7 | ||||
-rw-r--r-- | arch/mips/bcm47xx/bcm47xx_private.h | 26 | ||||
-rw-r--r-- | arch/mips/bcm47xx/board.c | 362 | ||||
-rw-r--r-- | arch/mips/bcm47xx/buttons.c | 718 | ||||
-rw-r--r-- | arch/mips/bcm47xx/irq.c | 98 | ||||
-rw-r--r-- | arch/mips/bcm47xx/leds.c | 793 | ||||
-rw-r--r-- | arch/mips/bcm47xx/prom.c | 182 | ||||
-rw-r--r-- | arch/mips/bcm47xx/serial.c | 93 | ||||
-rw-r--r-- | arch/mips/bcm47xx/setup.c | 280 | ||||
-rw-r--r-- | arch/mips/bcm47xx/time.c | 81 | ||||
-rw-r--r-- | arch/mips/bcm47xx/workarounds.c | 35 |
13 files changed, 2722 insertions, 0 deletions
diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig new file mode 100644 index 000000000..490bb6da7 --- /dev/null +++ b/arch/mips/bcm47xx/Kconfig | |||
@@ -0,0 +1,39 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0 | ||
2 | if BCM47XX | ||
3 | |||
4 | config BCM47XX_SSB | ||
5 | bool "SSB Support for Broadcom BCM47XX" | ||
6 | select SYS_HAS_CPU_BMIPS32_3300 | ||
7 | select SSB | ||
8 | select SSB_HOST_SOC | ||
9 | select SSB_DRIVER_MIPS | ||
10 | select SSB_DRIVER_EXTIF | ||
11 | select SSB_EMBEDDED | ||
12 | select SSB_B43_PCI_BRIDGE if PCI | ||
13 | select SSB_DRIVER_PCICORE if PCI | ||
14 | select SSB_PCICORE_HOSTMODE if PCI | ||
15 | select SSB_DRIVER_GPIO | ||
16 | default y | ||
17 | help | ||
18 | Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support. | ||
19 | |||
20 | This will generate an image with support for SSB and MIPS32 R1 instruction set. | ||
21 | |||
22 | config BCM47XX_BCMA | ||
23 | bool "BCMA Support for Broadcom BCM47XX" | ||
24 | select SYS_HAS_CPU_MIPS32_R2 | ||
25 | select SYS_SUPPORTS_HIGHMEM | ||
26 | select CPU_MIPSR2_IRQ_VI | ||
27 | select BCMA | ||
28 | select BCMA_HOST_SOC | ||
29 | select BCMA_DRIVER_MIPS | ||
30 | select BCMA_DRIVER_PCI if PCI | ||
31 | select BCMA_DRIVER_PCI_HOSTMODE if PCI | ||
32 | select BCMA_DRIVER_GPIO | ||
33 | default y | ||
34 | help | ||
35 | Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus. | ||
36 | |||
37 | This will generate an image with support for BCMA and MIPS32 R2 instruction set. | ||
38 | |||
39 | endif | ||
diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile new file mode 100644 index 000000000..c7438a410 --- /dev/null +++ b/arch/mips/bcm47xx/Makefile | |||
@@ -0,0 +1,8 @@ | |||
1 | # SPDX-License-Identifier: GPL-2.0-only | ||
2 | # | ||
3 | # Makefile for the BCM47XX specific kernel interface routines | ||
4 | # under Linux. | ||
5 | # | ||
6 | |||
7 | obj-y += irq.o prom.o serial.o setup.o time.o | ||
8 | obj-y += board.o buttons.o leds.o workarounds.o | ||
diff --git a/arch/mips/bcm47xx/Platform b/arch/mips/bcm47xx/Platform new file mode 100644 index 000000000..833b204fe --- /dev/null +++ b/arch/mips/bcm47xx/Platform | |||
@@ -0,0 +1,7 @@ | |||
1 | # | ||
2 | # Broadcom BCM47XX boards | ||
3 | # | ||
4 | cflags-$(CONFIG_BCM47XX) += \ | ||
5 | -I$(srctree)/arch/mips/include/asm/mach-bcm47xx | ||
6 | load-$(CONFIG_BCM47XX) := 0xffffffff80001000 | ||
7 | zload-$(CONFIG_BCM47XX) += 0xffffffff80400000 | ||
diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h new file mode 100644 index 000000000..bb96743bb --- /dev/null +++ b/arch/mips/bcm47xx/bcm47xx_private.h | |||
@@ -0,0 +1,26 @@ | |||
1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
2 | #ifndef LINUX_BCM47XX_PRIVATE_H_ | ||
3 | #define LINUX_BCM47XX_PRIVATE_H_ | ||
4 | |||
5 | #ifndef pr_fmt | ||
6 | #define pr_fmt(fmt) "bcm47xx: " fmt | ||
7 | #endif | ||
8 | |||
9 | #include <linux/kernel.h> | ||
10 | |||
11 | /* prom.c */ | ||
12 | void __init bcm47xx_prom_highmem_init(void); | ||
13 | |||
14 | /* buttons.c */ | ||
15 | int __init bcm47xx_buttons_register(void); | ||
16 | |||
17 | /* leds.c */ | ||
18 | void __init bcm47xx_leds_register(void); | ||
19 | |||
20 | /* setup.c */ | ||
21 | void __init bcm47xx_bus_setup(void); | ||
22 | |||
23 | /* workarounds.c */ | ||
24 | void __init bcm47xx_workarounds(void); | ||
25 | |||
26 | #endif | ||
diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c new file mode 100644 index 000000000..35266a70e --- /dev/null +++ b/arch/mips/bcm47xx/board.c | |||
@@ -0,0 +1,362 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | #include <linux/errno.h> | ||
3 | #include <linux/export.h> | ||
4 | #include <linux/string.h> | ||
5 | #include <bcm47xx.h> | ||
6 | #include <bcm47xx_board.h> | ||
7 | |||
8 | struct bcm47xx_board_type { | ||
9 | const enum bcm47xx_board board; | ||
10 | const char *name; | ||
11 | }; | ||
12 | |||
13 | struct bcm47xx_board_type_list1 { | ||
14 | struct bcm47xx_board_type board; | ||
15 | const char *value1; | ||
16 | }; | ||
17 | |||
18 | struct bcm47xx_board_type_list2 { | ||
19 | struct bcm47xx_board_type board; | ||
20 | const char *value1; | ||
21 | const char *value2; | ||
22 | }; | ||
23 | |||
24 | struct bcm47xx_board_type_list3 { | ||
25 | struct bcm47xx_board_type board; | ||
26 | const char *value1; | ||
27 | const char *value2; | ||
28 | const char *value3; | ||
29 | }; | ||
30 | |||
31 | struct bcm47xx_board_store { | ||
32 | enum bcm47xx_board board; | ||
33 | char name[BCM47XX_BOARD_MAX_NAME]; | ||
34 | }; | ||
35 | |||
36 | /* model_name */ | ||
37 | static const | ||
38 | struct bcm47xx_board_type_list1 bcm47xx_board_list_model_name[] __initconst = { | ||
39 | {{BCM47XX_BOARD_DLINK_DIR130, "D-Link DIR-130"}, "DIR-130"}, | ||
40 | {{BCM47XX_BOARD_DLINK_DIR330, "D-Link DIR-330"}, "DIR-330"}, | ||
41 | { {0}, NULL}, | ||
42 | }; | ||
43 | |||
44 | /* hardware_version */ | ||
45 | static const | ||
46 | struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initconst = { | ||
47 | {{BCM47XX_BOARD_ASUS_RTN10U, "Asus RT-N10U"}, "RTN10U"}, | ||
48 | {{BCM47XX_BOARD_ASUS_RTN10D, "Asus RT-N10D"}, "RTN10D"}, | ||
49 | {{BCM47XX_BOARD_ASUS_RTN12, "Asus RT-N12"}, "RT-N12"}, | ||
50 | {{BCM47XX_BOARD_ASUS_RTN12B1, "Asus RT-N12B1"}, "RTN12B1"}, | ||
51 | {{BCM47XX_BOARD_ASUS_RTN12C1, "Asus RT-N12C1"}, "RTN12C1"}, | ||
52 | {{BCM47XX_BOARD_ASUS_RTN12D1, "Asus RT-N12D1"}, "RTN12D1"}, | ||
53 | {{BCM47XX_BOARD_ASUS_RTN12HP, "Asus RT-N12HP"}, "RTN12HP"}, | ||
54 | {{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16-"}, | ||
55 | {{BCM47XX_BOARD_ASUS_WL320GE, "Asus WL320GE"}, "WL320G-"}, | ||
56 | {{BCM47XX_BOARD_ASUS_WL330GE, "Asus WL330GE"}, "WL330GE-"}, | ||
57 | {{BCM47XX_BOARD_ASUS_WL500GD, "Asus WL500GD"}, "WL500gd-"}, | ||
58 | {{BCM47XX_BOARD_ASUS_WL500GPV1, "Asus WL500GP V1"}, "WL500gp-"}, | ||
59 | {{BCM47XX_BOARD_ASUS_WL500GPV2, "Asus WL500GP V2"}, "WL500GPV2-"}, | ||
60 | {{BCM47XX_BOARD_ASUS_WL500W, "Asus WL500W"}, "WL500gW-"}, | ||
61 | {{BCM47XX_BOARD_ASUS_WL520GC, "Asus WL520GC"}, "WL520GC-"}, | ||
62 | {{BCM47XX_BOARD_ASUS_WL520GU, "Asus WL520GU"}, "WL520GU-"}, | ||
63 | {{BCM47XX_BOARD_BELKIN_F7D3301, "Belkin F7D3301"}, "F7D3301"}, | ||
64 | {{BCM47XX_BOARD_BELKIN_F7D3302, "Belkin F7D3302"}, "F7D3302"}, | ||
65 | {{BCM47XX_BOARD_BELKIN_F7D4301, "Belkin F7D4301"}, "F7D4301"}, | ||
66 | {{BCM47XX_BOARD_BELKIN_F7D4302, "Belkin F7D4302"}, "F7D4302"}, | ||
67 | {{BCM47XX_BOARD_BELKIN_F7D4401, "Belkin F7D4401"}, "F7D4401"}, | ||
68 | { {0}, NULL}, | ||
69 | }; | ||
70 | |||
71 | /* hardware_version, boardnum */ | ||
72 | static const | ||
73 | struct bcm47xx_board_type_list2 bcm47xx_board_list_hw_version_num[] __initconst = { | ||
74 | {{BCM47XX_BOARD_MICROSOFT_MN700, "Microsoft MN-700"}, "WL500-", "mn700"}, | ||
75 | {{BCM47XX_BOARD_ASUS_WL500G, "Asus WL500G"}, "WL500-", "asusX"}, | ||
76 | { {0}, NULL}, | ||
77 | }; | ||
78 | |||
79 | /* productid */ | ||
80 | static const | ||
81 | struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = { | ||
82 | {{BCM47XX_BOARD_ASUS_RTAC66U, "Asus RT-AC66U"}, "RT-AC66U"}, | ||
83 | {{BCM47XX_BOARD_ASUS_RTN10, "Asus RT-N10"}, "RT-N10"}, | ||
84 | {{BCM47XX_BOARD_ASUS_RTN10D, "Asus RT-N10D"}, "RT-N10D"}, | ||
85 | {{BCM47XX_BOARD_ASUS_RTN15U, "Asus RT-N15U"}, "RT-N15U"}, | ||
86 | {{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16"}, | ||
87 | {{BCM47XX_BOARD_ASUS_RTN53, "Asus RT-N53"}, "RT-N53"}, | ||
88 | {{BCM47XX_BOARD_ASUS_RTN66U, "Asus RT-N66U"}, "RT-N66U"}, | ||
89 | {{BCM47XX_BOARD_ASUS_WL300G, "Asus WL300G"}, "WL300g"}, | ||
90 | {{BCM47XX_BOARD_ASUS_WLHDD, "Asus WLHDD"}, "WLHDD"}, | ||
91 | { {0}, NULL}, | ||
92 | }; | ||
93 | |||
94 | /* ModelId */ | ||
95 | static const | ||
96 | struct bcm47xx_board_type_list1 bcm47xx_board_list_ModelId[] __initconst = { | ||
97 | {{BCM47XX_BOARD_DELL_TM2300, "Dell TrueMobile 2300"}, "WX-5565"}, | ||
98 | {{BCM47XX_BOARD_MOTOROLA_WE800G, "Motorola WE800G"}, "WE800G"}, | ||
99 | {{BCM47XX_BOARD_MOTOROLA_WR850GP, "Motorola WR850GP"}, "WR850GP"}, | ||
100 | {{BCM47XX_BOARD_MOTOROLA_WR850GV2V3, "Motorola WR850G"}, "WR850G"}, | ||
101 | { {0}, NULL}, | ||
102 | }; | ||
103 | |||
104 | /* melco_id or buf1falo_id */ | ||
105 | static const | ||
106 | struct bcm47xx_board_type_list1 bcm47xx_board_list_melco_id[] __initconst = { | ||
107 | {{BCM47XX_BOARD_BUFFALO_WBR2_G54, "Buffalo WBR2-G54"}, "29bb0332"}, | ||
108 | {{BCM47XX_BOARD_BUFFALO_WHR2_A54G54, "Buffalo WHR2-A54G54"}, "290441dd"}, | ||
109 | {{BCM47XX_BOARD_BUFFALO_WHR_G125, "Buffalo WHR-G125"}, "32093"}, | ||
110 | {{BCM47XX_BOARD_BUFFALO_WHR_G54S, "Buffalo WHR-G54S"}, "30182"}, | ||
111 | {{BCM47XX_BOARD_BUFFALO_WHR_HP_G54, "Buffalo WHR-HP-G54"}, "30189"}, | ||
112 | {{BCM47XX_BOARD_BUFFALO_WLA2_G54L, "Buffalo WLA2-G54L"}, "29129"}, | ||
113 | {{BCM47XX_BOARD_BUFFALO_WZR_G300N, "Buffalo WZR-G300N"}, "31120"}, | ||
114 | {{BCM47XX_BOARD_BUFFALO_WZR_RS_G54, "Buffalo WZR-RS-G54"}, "30083"}, | ||
115 | {{BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP, "Buffalo WZR-RS-G54HP"}, "30103"}, | ||
116 | { {0}, NULL}, | ||
117 | }; | ||
118 | |||
119 | /* boot_hw_model, boot_hw_ver */ | ||
120 | static const | ||
121 | struct bcm47xx_board_type_list2 bcm47xx_board_list_boot_hw[] __initconst = { | ||
122 | /* like WRT160N v3.0 */ | ||
123 | {{BCM47XX_BOARD_CISCO_M10V1, "Cisco M10"}, "M10", "1.0"}, | ||
124 | /* like WRT310N v2.0 */ | ||
125 | {{BCM47XX_BOARD_CISCO_M20V1, "Cisco M20"}, "M20", "1.0"}, | ||
126 | {{BCM47XX_BOARD_LINKSYS_E900V1, "Linksys E900 V1"}, "E900", "1.0"}, | ||
127 | /* like WRT160N v3.0 */ | ||
128 | {{BCM47XX_BOARD_LINKSYS_E1000V1, "Linksys E1000 V1"}, "E100", "1.0"}, | ||
129 | {{BCM47XX_BOARD_LINKSYS_E1000V2, "Linksys E1000 V2"}, "E1000", "2.0"}, | ||
130 | {{BCM47XX_BOARD_LINKSYS_E1000V21, "Linksys E1000 V2.1"}, "E1000", "2.1"}, | ||
131 | {{BCM47XX_BOARD_LINKSYS_E1200V2, "Linksys E1200 V2"}, "E1200", "2.0"}, | ||
132 | {{BCM47XX_BOARD_LINKSYS_E2000V1, "Linksys E2000 V1"}, "Linksys E2000", "1.0"}, | ||
133 | /* like WRT610N v2.0 */ | ||
134 | {{BCM47XX_BOARD_LINKSYS_E3000V1, "Linksys E3000 V1"}, "E300", "1.0"}, | ||
135 | {{BCM47XX_BOARD_LINKSYS_E3200V1, "Linksys E3200 V1"}, "E3200", "1.0"}, | ||
136 | {{BCM47XX_BOARD_LINKSYS_E4200V1, "Linksys E4200 V1"}, "E4200", "1.0"}, | ||
137 | {{BCM47XX_BOARD_LINKSYS_WRT150NV11, "Linksys WRT150N V1.1"}, "WRT150N", "1.1"}, | ||
138 | {{BCM47XX_BOARD_LINKSYS_WRT150NV1, "Linksys WRT150N V1"}, "WRT150N", "1"}, | ||
139 | {{BCM47XX_BOARD_LINKSYS_WRT160NV1, "Linksys WRT160N V1"}, "WRT160N", "1.0"}, | ||
140 | {{BCM47XX_BOARD_LINKSYS_WRT160NV3, "Linksys WRT160N V3"}, "WRT160N", "3.0"}, | ||
141 | {{BCM47XX_BOARD_LINKSYS_WRT300NV11, "Linksys WRT300N V1.1"}, "WRT300N", "1.1"}, | ||
142 | {{BCM47XX_BOARD_LINKSYS_WRT310NV1, "Linksys WRT310N V1"}, "WRT310N", "1.0"}, | ||
143 | {{BCM47XX_BOARD_LINKSYS_WRT310NV2, "Linksys WRT310N V2"}, "WRT310N", "2.0"}, | ||
144 | {{BCM47XX_BOARD_LINKSYS_WRT54G3GV2, "Linksys WRT54G3GV2-VF"}, "WRT54G3GV2-VF", "1.0"}, | ||
145 | {{BCM47XX_BOARD_LINKSYS_WRT610NV1, "Linksys WRT610N V1"}, "WRT610N", "1.0"}, | ||
146 | {{BCM47XX_BOARD_LINKSYS_WRT610NV2, "Linksys WRT610N V2"}, "WRT610N", "2.0"}, | ||
147 | { {0}, NULL}, | ||
148 | }; | ||
149 | |||
150 | /* board_id */ | ||
151 | static const | ||
152 | struct bcm47xx_board_type_list1 bcm47xx_board_list_board_id[] __initconst = { | ||
153 | {{BCM47XX_BOARD_LUXUL_ABR_4400_V1, "Luxul ABR-4400 V1"}, "luxul_abr4400_v1"}, | ||
154 | {{BCM47XX_BOARD_LUXUL_XAP_310_V1, "Luxul XAP-310 V1"}, "luxul_xap310_v1"}, | ||
155 | {{BCM47XX_BOARD_LUXUL_XAP_1210_V1, "Luxul XAP-1210 V1"}, "luxul_xap1210_v1"}, | ||
156 | {{BCM47XX_BOARD_LUXUL_XAP_1230_V1, "Luxul XAP-1230 V1"}, "luxul_xap1230_v1"}, | ||
157 | {{BCM47XX_BOARD_LUXUL_XAP_1240_V1, "Luxul XAP-1240 V1"}, "luxul_xap1240_v1"}, | ||
158 | {{BCM47XX_BOARD_LUXUL_XAP_1500_V1, "Luxul XAP-1500 V1"}, "luxul_xap1500_v1"}, | ||
159 | {{BCM47XX_BOARD_LUXUL_XBR_4400_V1, "Luxul XBR-4400 V1"}, "luxul_xbr4400_v1"}, | ||
160 | {{BCM47XX_BOARD_LUXUL_XVW_P30_V1, "Luxul XVW-P30 V1"}, "luxul_xvwp30_v1"}, | ||
161 | {{BCM47XX_BOARD_LUXUL_XWR_600_V1, "Luxul XWR-600 V1"}, "luxul_xwr600_v1"}, | ||
162 | {{BCM47XX_BOARD_LUXUL_XWR_1750_V1, "Luxul XWR-1750 V1"}, "luxul_xwr1750_v1"}, | ||
163 | {{BCM47XX_BOARD_NETGEAR_R6200_V1, "Netgear R6200 V1"}, "U12H192T00_NETGEAR"}, | ||
164 | {{BCM47XX_BOARD_NETGEAR_WGR614V8, "Netgear WGR614 V8"}, "U12H072T00_NETGEAR"}, | ||
165 | {{BCM47XX_BOARD_NETGEAR_WGR614V9, "Netgear WGR614 V9"}, "U12H094T00_NETGEAR"}, | ||
166 | {{BCM47XX_BOARD_NETGEAR_WGR614_V10, "Netgear WGR614 V10"}, "U12H139T01_NETGEAR"}, | ||
167 | {{BCM47XX_BOARD_NETGEAR_WNDR3300, "Netgear WNDR3300"}, "U12H093T00_NETGEAR"}, | ||
168 | {{BCM47XX_BOARD_NETGEAR_WNDR3400V1, "Netgear WNDR3400 V1"}, "U12H155T00_NETGEAR"}, | ||
169 | {{BCM47XX_BOARD_NETGEAR_WNDR3400V2, "Netgear WNDR3400 V2"}, "U12H187T00_NETGEAR"}, | ||
170 | {{BCM47XX_BOARD_NETGEAR_WNDR3400_V3, "Netgear WNDR3400 V3"}, "U12H208T00_NETGEAR"}, | ||
171 | {{BCM47XX_BOARD_NETGEAR_WNDR3400VCNA, "Netgear WNDR3400 Vcna"}, "U12H155T01_NETGEAR"}, | ||
172 | {{BCM47XX_BOARD_NETGEAR_WNDR3700V3, "Netgear WNDR3700 V3"}, "U12H194T00_NETGEAR"}, | ||
173 | {{BCM47XX_BOARD_NETGEAR_WNDR4000, "Netgear WNDR4000"}, "U12H181T00_NETGEAR"}, | ||
174 | {{BCM47XX_BOARD_NETGEAR_WNDR4500V1, "Netgear WNDR4500 V1"}, "U12H189T00_NETGEAR"}, | ||
175 | {{BCM47XX_BOARD_NETGEAR_WNDR4500V2, "Netgear WNDR4500 V2"}, "U12H224T00_NETGEAR"}, | ||
176 | {{BCM47XX_BOARD_NETGEAR_WNR1000_V3, "Netgear WNR1000 V3"}, "U12H139T00_NETGEAR"}, | ||
177 | {{BCM47XX_BOARD_NETGEAR_WNR1000_V3, "Netgear WNR1000 V3"}, "U12H139T50_NETGEAR"}, | ||
178 | {{BCM47XX_BOARD_NETGEAR_WNR2000, "Netgear WNR2000"}, "U12H114T00_NETGEAR"}, | ||
179 | {{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "U12H136T99_NETGEAR"}, | ||
180 | {{BCM47XX_BOARD_NETGEAR_WNR3500U, "Netgear WNR3500U"}, "U12H136T00_NETGEAR"}, | ||
181 | {{BCM47XX_BOARD_NETGEAR_WNR3500V2, "Netgear WNR3500 V2"}, "U12H127T00_NETGEAR"}, | ||
182 | {{BCM47XX_BOARD_NETGEAR_WNR3500V2VC, "Netgear WNR3500 V2vc"}, "U12H127T70_NETGEAR"}, | ||
183 | {{BCM47XX_BOARD_NETGEAR_WNR834BV2, "Netgear WNR834B V2"}, "U12H081T00_NETGEAR"}, | ||
184 | { {0}, NULL}, | ||
185 | }; | ||
186 | |||
187 | /* boardtype, boardnum, boardrev */ | ||
188 | static const | ||
189 | struct bcm47xx_board_type_list3 bcm47xx_board_list_board[] __initconst = { | ||
190 | {{BCM47XX_BOARD_HUAWEI_E970, "Huawei E970"}, "0x048e", "0x5347", "0x11"}, | ||
191 | {{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"}, | ||
192 | {{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"}, | ||
193 | {{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "0x04CF", "3500", "02"}, | ||
194 | {{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101, "Linksys WRT54G/GS/GL"}, "0x0101", "42", "0x10"}, | ||
195 | {{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467, "Linksys WRT54G/GS/GL"}, "0x0467", "42", "0x10"}, | ||
196 | {{BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708, "Linksys WRT54G/GS/GL"}, "0x0708", "42", "0x10"}, | ||
197 | { {0}, NULL}, | ||
198 | }; | ||
199 | |||
200 | /* boardtype, boardrev */ | ||
201 | static const | ||
202 | struct bcm47xx_board_type_list2 bcm47xx_board_list_board_type_rev[] __initconst = { | ||
203 | {{BCM47XX_BOARD_SIEMENS_SE505V2, "Siemens SE505 V2"}, "0x0101", "0x10"}, | ||
204 | { {0}, NULL}, | ||
205 | }; | ||
206 | |||
207 | /* | ||
208 | * Some devices don't use any common NVRAM entry for identification and they | ||
209 | * have only one model specific variable. | ||
210 | * They don't deserve own arrays, let's group them there using key-value array. | ||
211 | */ | ||
212 | static const | ||
213 | struct bcm47xx_board_type_list2 bcm47xx_board_list_key_value[] __initconst = { | ||
214 | {{BCM47XX_BOARD_ASUS_WL700GE, "Asus WL700"}, "model_no", "WL700"}, | ||
215 | {{BCM47XX_BOARD_LINKSYS_WRT300N_V1, "Linksys WRT300N V1"}, "router_name", "WRT300N"}, | ||
216 | {{BCM47XX_BOARD_LINKSYS_WRT600N_V11, "Linksys WRT600N V1.1"}, "Model_Name", "WRT600N"}, | ||
217 | {{BCM47XX_BOARD_LINKSYS_WRTSL54GS, "Linksys WRTSL54GS"}, "machine_name", "WRTSL54GS"}, | ||
218 | { {0}, NULL}, | ||
219 | }; | ||
220 | |||
221 | static const | ||
222 | struct bcm47xx_board_type bcm47xx_board_unknown[] __initconst = { | ||
223 | {BCM47XX_BOARD_UNKNOWN, "Unknown Board"}, | ||
224 | }; | ||
225 | |||
226 | static struct bcm47xx_board_store bcm47xx_board = {BCM47XX_BOARD_NO, "Unknown Board"}; | ||
227 | |||
228 | static __init const struct bcm47xx_board_type *bcm47xx_board_get_nvram(void) | ||
229 | { | ||
230 | char buf1[30]; | ||
231 | char buf2[30]; | ||
232 | char buf3[30]; | ||
233 | const struct bcm47xx_board_type_list1 *e1; | ||
234 | const struct bcm47xx_board_type_list2 *e2; | ||
235 | const struct bcm47xx_board_type_list3 *e3; | ||
236 | |||
237 | if (bcm47xx_nvram_getenv("model_name", buf1, sizeof(buf1)) >= 0) { | ||
238 | for (e1 = bcm47xx_board_list_model_name; e1->value1; e1++) { | ||
239 | if (!strcmp(buf1, e1->value1)) | ||
240 | return &e1->board; | ||
241 | } | ||
242 | } | ||
243 | |||
244 | if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0) { | ||
245 | for (e1 = bcm47xx_board_list_hardware_version; e1->value1; e1++) { | ||
246 | if (strstarts(buf1, e1->value1)) | ||
247 | return &e1->board; | ||
248 | } | ||
249 | } | ||
250 | |||
251 | if (bcm47xx_nvram_getenv("hardware_version", buf1, sizeof(buf1)) >= 0 && | ||
252 | bcm47xx_nvram_getenv("boardnum", buf2, sizeof(buf2)) >= 0) { | ||
253 | for (e2 = bcm47xx_board_list_hw_version_num; e2->value1; e2++) { | ||
254 | if (!strstarts(buf1, e2->value1) && | ||
255 | !strcmp(buf2, e2->value2)) | ||
256 | return &e2->board; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | if (bcm47xx_nvram_getenv("productid", buf1, sizeof(buf1)) >= 0) { | ||
261 | for (e1 = bcm47xx_board_list_productid; e1->value1; e1++) { | ||
262 | if (!strcmp(buf1, e1->value1)) | ||
263 | return &e1->board; | ||
264 | } | ||
265 | } | ||
266 | |||
267 | if (bcm47xx_nvram_getenv("ModelId", buf1, sizeof(buf1)) >= 0) { | ||
268 | for (e1 = bcm47xx_board_list_ModelId; e1->value1; e1++) { | ||
269 | if (!strcmp(buf1, e1->value1)) | ||
270 | return &e1->board; | ||
271 | } | ||
272 | } | ||
273 | |||
274 | if (bcm47xx_nvram_getenv("melco_id", buf1, sizeof(buf1)) >= 0 || | ||
275 | bcm47xx_nvram_getenv("buf1falo_id", buf1, sizeof(buf1)) >= 0) { | ||
276 | /* buffalo hardware, check id for specific hardware matches */ | ||
277 | for (e1 = bcm47xx_board_list_melco_id; e1->value1; e1++) { | ||
278 | if (!strcmp(buf1, e1->value1)) | ||
279 | return &e1->board; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | if (bcm47xx_nvram_getenv("boot_hw_model", buf1, sizeof(buf1)) >= 0 && | ||
284 | bcm47xx_nvram_getenv("boot_hw_ver", buf2, sizeof(buf2)) >= 0) { | ||
285 | for (e2 = bcm47xx_board_list_boot_hw; e2->value1; e2++) { | ||
286 | if (!strcmp(buf1, e2->value1) && | ||
287 | !strcmp(buf2, e2->value2)) | ||
288 | return &e2->board; | ||
289 | } | ||
290 | } | ||
291 | |||
292 | if (bcm47xx_nvram_getenv("board_id", buf1, sizeof(buf1)) >= 0) { | ||
293 | for (e1 = bcm47xx_board_list_board_id; e1->value1; e1++) { | ||
294 | if (!strcmp(buf1, e1->value1)) | ||
295 | return &e1->board; | ||
296 | } | ||
297 | } | ||
298 | |||
299 | if (bcm47xx_nvram_getenv("boardtype", buf1, sizeof(buf1)) >= 0 && | ||
300 | bcm47xx_nvram_getenv("boardnum", buf2, sizeof(buf2)) >= 0 && | ||
301 | bcm47xx_nvram_getenv("boardrev", buf3, sizeof(buf3)) >= 0) { | ||
302 | for (e3 = bcm47xx_board_list_board; e3->value1; e3++) { | ||
303 | if (!strcmp(buf1, e3->value1) && | ||
304 | !strcmp(buf2, e3->value2) && | ||
305 | !strcmp(buf3, e3->value3)) | ||
306 | return &e3->board; | ||
307 | } | ||
308 | } | ||
309 | |||
310 | if (bcm47xx_nvram_getenv("boardtype", buf1, sizeof(buf1)) >= 0 && | ||
311 | bcm47xx_nvram_getenv("boardrev", buf2, sizeof(buf2)) >= 0 && | ||
312 | bcm47xx_nvram_getenv("boardnum", buf3, sizeof(buf3)) == -ENOENT) { | ||
313 | for (e2 = bcm47xx_board_list_board_type_rev; e2->value1; e2++) { | ||
314 | if (!strcmp(buf1, e2->value1) && | ||
315 | !strcmp(buf2, e2->value2)) | ||
316 | return &e2->board; | ||
317 | } | ||
318 | } | ||
319 | |||
320 | for (e2 = bcm47xx_board_list_key_value; e2->value1; e2++) { | ||
321 | if (bcm47xx_nvram_getenv(e2->value1, buf1, sizeof(buf1)) >= 0) { | ||
322 | if (!strcmp(buf1, e2->value2)) | ||
323 | return &e2->board; | ||
324 | } | ||
325 | } | ||
326 | |||
327 | return bcm47xx_board_unknown; | ||
328 | } | ||
329 | |||
330 | void __init bcm47xx_board_detect(void) | ||
331 | { | ||
332 | int err; | ||
333 | char buf[10]; | ||
334 | const struct bcm47xx_board_type *board_detected; | ||
335 | |||
336 | if (bcm47xx_board.board != BCM47XX_BOARD_NO) | ||
337 | return; | ||
338 | |||
339 | /* check if the nvram is available */ | ||
340 | err = bcm47xx_nvram_getenv("boardtype", buf, sizeof(buf)); | ||
341 | |||
342 | /* init of nvram failed, probably too early now */ | ||
343 | if (err == -ENXIO) | ||
344 | return; | ||
345 | |||
346 | board_detected = bcm47xx_board_get_nvram(); | ||
347 | bcm47xx_board.board = board_detected->board; | ||
348 | strlcpy(bcm47xx_board.name, board_detected->name, | ||
349 | BCM47XX_BOARD_MAX_NAME); | ||
350 | } | ||
351 | |||
352 | enum bcm47xx_board bcm47xx_board_get(void) | ||
353 | { | ||
354 | return bcm47xx_board.board; | ||
355 | } | ||
356 | EXPORT_SYMBOL(bcm47xx_board_get); | ||
357 | |||
358 | const char *bcm47xx_board_get_name(void) | ||
359 | { | ||
360 | return bcm47xx_board.name; | ||
361 | } | ||
362 | EXPORT_SYMBOL(bcm47xx_board_get_name); | ||
diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c new file mode 100644 index 000000000..535d84add --- /dev/null +++ b/arch/mips/bcm47xx/buttons.c | |||
@@ -0,0 +1,718 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | #include "bcm47xx_private.h" | ||
3 | |||
4 | #include <linux/input.h> | ||
5 | #include <linux/gpio_keys.h> | ||
6 | #include <linux/interrupt.h> | ||
7 | #include <bcm47xx_board.h> | ||
8 | #include <bcm47xx.h> | ||
9 | |||
10 | /************************************************** | ||
11 | * Database | ||
12 | **************************************************/ | ||
13 | |||
14 | #define BCM47XX_GPIO_KEY(_gpio, _code) \ | ||
15 | { \ | ||
16 | .code = _code, \ | ||
17 | .gpio = _gpio, \ | ||
18 | .active_low = 1, \ | ||
19 | } | ||
20 | |||
21 | #define BCM47XX_GPIO_KEY_H(_gpio, _code) \ | ||
22 | { \ | ||
23 | .code = _code, \ | ||
24 | .gpio = _gpio, \ | ||
25 | } | ||
26 | |||
27 | /* Asus */ | ||
28 | |||
29 | static const struct gpio_keys_button | ||
30 | bcm47xx_buttons_asus_rtn12[] __initconst = { | ||
31 | BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), | ||
32 | BCM47XX_GPIO_KEY(1, KEY_RESTART), | ||
33 | BCM47XX_GPIO_KEY(4, BTN_0), /* Router mode */ | ||
34 | BCM47XX_GPIO_KEY(5, BTN_1), /* Repeater mode */ | ||
35 | BCM47XX_GPIO_KEY(6, BTN_2), /* AP mode */ | ||
36 | }; | ||
37 | |||
38 | static const struct gpio_keys_button | ||
39 | bcm47xx_buttons_asus_rtn16[] __initconst = { | ||
40 | BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON), | ||
41 | BCM47XX_GPIO_KEY(8, KEY_RESTART), | ||
42 | }; | ||
43 | |||
44 | static const struct gpio_keys_button | ||
45 | bcm47xx_buttons_asus_rtn66u[] __initconst = { | ||
46 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
47 | BCM47XX_GPIO_KEY(9, KEY_RESTART), | ||
48 | }; | ||
49 | |||
50 | static const struct gpio_keys_button | ||
51 | bcm47xx_buttons_asus_wl300g[] __initconst = { | ||
52 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
53 | }; | ||
54 | |||
55 | static const struct gpio_keys_button | ||
56 | bcm47xx_buttons_asus_wl320ge[] __initconst = { | ||
57 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
58 | }; | ||
59 | |||
60 | static const struct gpio_keys_button | ||
61 | bcm47xx_buttons_asus_wl330ge[] __initconst = { | ||
62 | BCM47XX_GPIO_KEY(2, KEY_RESTART), | ||
63 | }; | ||
64 | |||
65 | static const struct gpio_keys_button | ||
66 | bcm47xx_buttons_asus_wl500g[] __initconst = { | ||
67 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
68 | }; | ||
69 | |||
70 | static const struct gpio_keys_button | ||
71 | bcm47xx_buttons_asus_wl500gd[] __initconst = { | ||
72 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
73 | }; | ||
74 | |||
75 | static const struct gpio_keys_button | ||
76 | bcm47xx_buttons_asus_wl500gpv1[] __initconst = { | ||
77 | BCM47XX_GPIO_KEY(0, KEY_RESTART), | ||
78 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
79 | }; | ||
80 | |||
81 | static const struct gpio_keys_button | ||
82 | bcm47xx_buttons_asus_wl500gpv2[] __initconst = { | ||
83 | BCM47XX_GPIO_KEY(2, KEY_RESTART), | ||
84 | BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON), | ||
85 | }; | ||
86 | |||
87 | static const struct gpio_keys_button | ||
88 | bcm47xx_buttons_asus_wl500w[] __initconst = { | ||
89 | BCM47XX_GPIO_KEY_H(6, KEY_RESTART), | ||
90 | BCM47XX_GPIO_KEY_H(7, KEY_WPS_BUTTON), | ||
91 | }; | ||
92 | |||
93 | static const struct gpio_keys_button | ||
94 | bcm47xx_buttons_asus_wl520gc[] __initconst = { | ||
95 | BCM47XX_GPIO_KEY(2, KEY_RESTART), | ||
96 | BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON), | ||
97 | }; | ||
98 | |||
99 | static const struct gpio_keys_button | ||
100 | bcm47xx_buttons_asus_wl520gu[] __initconst = { | ||
101 | BCM47XX_GPIO_KEY(2, KEY_RESTART), | ||
102 | BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON), | ||
103 | }; | ||
104 | |||
105 | static const struct gpio_keys_button | ||
106 | bcm47xx_buttons_asus_wl700ge[] __initconst = { | ||
107 | BCM47XX_GPIO_KEY(0, KEY_POWER), /* Hard disk power switch */ | ||
108 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), /* EZSetup */ | ||
109 | BCM47XX_GPIO_KEY(6, KEY_COPY), /* Copy data from USB to internal disk */ | ||
110 | BCM47XX_GPIO_KEY(7, KEY_RESTART), /* Hard reset */ | ||
111 | }; | ||
112 | |||
113 | static const struct gpio_keys_button | ||
114 | bcm47xx_buttons_asus_wlhdd[] __initconst = { | ||
115 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
116 | }; | ||
117 | |||
118 | /* Huawei */ | ||
119 | |||
120 | static const struct gpio_keys_button | ||
121 | bcm47xx_buttons_huawei_e970[] __initconst = { | ||
122 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
123 | }; | ||
124 | |||
125 | /* Belkin */ | ||
126 | |||
127 | static const struct gpio_keys_button | ||
128 | bcm47xx_buttons_belkin_f7d4301[] __initconst = { | ||
129 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
130 | BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON), | ||
131 | }; | ||
132 | |||
133 | /* Buffalo */ | ||
134 | |||
135 | static const struct gpio_keys_button | ||
136 | bcm47xx_buttons_buffalo_whr2_a54g54[] __initconst = { | ||
137 | BCM47XX_GPIO_KEY(4, KEY_RESTART), | ||
138 | }; | ||
139 | |||
140 | static const struct gpio_keys_button | ||
141 | bcm47xx_buttons_buffalo_whr_g125[] __initconst = { | ||
142 | BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), | ||
143 | BCM47XX_GPIO_KEY(4, KEY_RESTART), | ||
144 | BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */ | ||
145 | }; | ||
146 | |||
147 | static const struct gpio_keys_button | ||
148 | bcm47xx_buttons_buffalo_whr_g54s[] __initconst = { | ||
149 | BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), | ||
150 | BCM47XX_GPIO_KEY_H(4, KEY_RESTART), | ||
151 | BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */ | ||
152 | }; | ||
153 | |||
154 | static const struct gpio_keys_button | ||
155 | bcm47xx_buttons_buffalo_whr_hp_g54[] __initconst = { | ||
156 | BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), | ||
157 | BCM47XX_GPIO_KEY(4, KEY_RESTART), | ||
158 | BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */ | ||
159 | }; | ||
160 | |||
161 | static const struct gpio_keys_button | ||
162 | bcm47xx_buttons_buffalo_wzr_g300n[] __initconst = { | ||
163 | BCM47XX_GPIO_KEY(4, KEY_RESTART), | ||
164 | }; | ||
165 | |||
166 | static const struct gpio_keys_button | ||
167 | bcm47xx_buttons_buffalo_wzr_rs_g54[] __initconst = { | ||
168 | BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), | ||
169 | BCM47XX_GPIO_KEY(4, KEY_RESTART), | ||
170 | }; | ||
171 | |||
172 | static const struct gpio_keys_button | ||
173 | bcm47xx_buttons_buffalo_wzr_rs_g54hp[] __initconst = { | ||
174 | BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON), | ||
175 | BCM47XX_GPIO_KEY(4, KEY_RESTART), | ||
176 | }; | ||
177 | |||
178 | /* Dell */ | ||
179 | |||
180 | static const struct gpio_keys_button | ||
181 | bcm47xx_buttons_dell_tm2300[] __initconst = { | ||
182 | BCM47XX_GPIO_KEY(0, KEY_RESTART), | ||
183 | }; | ||
184 | |||
185 | /* D-Link */ | ||
186 | |||
187 | static const struct gpio_keys_button | ||
188 | bcm47xx_buttons_dlink_dir130[] __initconst = { | ||
189 | BCM47XX_GPIO_KEY(3, KEY_RESTART), | ||
190 | BCM47XX_GPIO_KEY(7, KEY_UNKNOWN), | ||
191 | }; | ||
192 | |||
193 | static const struct gpio_keys_button | ||
194 | bcm47xx_buttons_dlink_dir330[] __initconst = { | ||
195 | BCM47XX_GPIO_KEY(3, KEY_RESTART), | ||
196 | BCM47XX_GPIO_KEY(7, KEY_UNKNOWN), | ||
197 | }; | ||
198 | |||
199 | /* Linksys */ | ||
200 | |||
201 | static const struct gpio_keys_button | ||
202 | bcm47xx_buttons_linksys_e1000v1[] __initconst = { | ||
203 | BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON), | ||
204 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
205 | }; | ||
206 | |||
207 | static const struct gpio_keys_button | ||
208 | bcm47xx_buttons_linksys_e1000v21[] __initconst = { | ||
209 | BCM47XX_GPIO_KEY(9, KEY_WPS_BUTTON), | ||
210 | BCM47XX_GPIO_KEY(10, KEY_RESTART), | ||
211 | }; | ||
212 | |||
213 | static const struct gpio_keys_button | ||
214 | bcm47xx_buttons_linksys_e2000v1[] __initconst = { | ||
215 | BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON), | ||
216 | BCM47XX_GPIO_KEY(8, KEY_RESTART), | ||
217 | }; | ||
218 | |||
219 | static const struct gpio_keys_button | ||
220 | bcm47xx_buttons_linksys_e3000v1[] __initconst = { | ||
221 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
222 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
223 | }; | ||
224 | |||
225 | static const struct gpio_keys_button | ||
226 | bcm47xx_buttons_linksys_e3200v1[] __initconst = { | ||
227 | BCM47XX_GPIO_KEY(5, KEY_RESTART), | ||
228 | BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON), | ||
229 | }; | ||
230 | |||
231 | static const struct gpio_keys_button | ||
232 | bcm47xx_buttons_linksys_e4200v1[] __initconst = { | ||
233 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
234 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
235 | }; | ||
236 | |||
237 | static const struct gpio_keys_button | ||
238 | bcm47xx_buttons_linksys_wrt150nv1[] __initconst = { | ||
239 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
240 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
241 | }; | ||
242 | |||
243 | static const struct gpio_keys_button | ||
244 | bcm47xx_buttons_linksys_wrt150nv11[] __initconst = { | ||
245 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
246 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
247 | }; | ||
248 | |||
249 | static const struct gpio_keys_button | ||
250 | bcm47xx_buttons_linksys_wrt160nv1[] __initconst = { | ||
251 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
252 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
253 | }; | ||
254 | |||
255 | static const struct gpio_keys_button | ||
256 | bcm47xx_buttons_linksys_wrt160nv3[] __initconst = { | ||
257 | BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON), | ||
258 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
259 | }; | ||
260 | |||
261 | static const struct gpio_keys_button | ||
262 | bcm47xx_buttons_linksys_wrt300n_v1[] __initconst = { | ||
263 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
264 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
265 | }; | ||
266 | |||
267 | static const struct gpio_keys_button | ||
268 | bcm47xx_buttons_linksys_wrt300nv11[] __initconst = { | ||
269 | BCM47XX_GPIO_KEY(4, KEY_UNKNOWN), | ||
270 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
271 | }; | ||
272 | |||
273 | static const struct gpio_keys_button | ||
274 | bcm47xx_buttons_linksys_wrt310nv1[] __initconst = { | ||
275 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
276 | BCM47XX_GPIO_KEY(8, KEY_UNKNOWN), | ||
277 | }; | ||
278 | |||
279 | static const struct gpio_keys_button | ||
280 | bcm47xx_buttons_linksys_wrt54g3gv2[] __initconst = { | ||
281 | BCM47XX_GPIO_KEY(5, KEY_WIMAX), | ||
282 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
283 | }; | ||
284 | |||
285 | static const struct gpio_keys_button | ||
286 | bcm47xx_buttons_linksys_wrt54g_generic[] __initconst = { | ||
287 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
288 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
289 | }; | ||
290 | |||
291 | static const struct gpio_keys_button | ||
292 | bcm47xx_buttons_linksys_wrt610nv1[] __initconst = { | ||
293 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
294 | BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON), | ||
295 | }; | ||
296 | |||
297 | static const struct gpio_keys_button | ||
298 | bcm47xx_buttons_linksys_wrt610nv2[] __initconst = { | ||
299 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
300 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
301 | }; | ||
302 | |||
303 | static const struct gpio_keys_button | ||
304 | bcm47xx_buttons_linksys_wrtsl54gs[] __initconst = { | ||
305 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
306 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
307 | }; | ||
308 | |||
309 | /* Luxul */ | ||
310 | |||
311 | static const struct gpio_keys_button | ||
312 | bcm47xx_buttons_luxul_abr_4400_v1[] = { | ||
313 | BCM47XX_GPIO_KEY(14, KEY_RESTART), | ||
314 | }; | ||
315 | |||
316 | static const struct gpio_keys_button | ||
317 | bcm47xx_buttons_luxul_xap_310_v1[] = { | ||
318 | BCM47XX_GPIO_KEY(20, KEY_RESTART), | ||
319 | }; | ||
320 | |||
321 | static const struct gpio_keys_button | ||
322 | bcm47xx_buttons_luxul_xap_1210_v1[] = { | ||
323 | BCM47XX_GPIO_KEY(8, KEY_RESTART), | ||
324 | }; | ||
325 | |||
326 | static const struct gpio_keys_button | ||
327 | bcm47xx_buttons_luxul_xap_1230_v1[] = { | ||
328 | BCM47XX_GPIO_KEY(8, KEY_RESTART), | ||
329 | }; | ||
330 | |||
331 | static const struct gpio_keys_button | ||
332 | bcm47xx_buttons_luxul_xap_1240_v1[] = { | ||
333 | BCM47XX_GPIO_KEY(8, KEY_RESTART), | ||
334 | }; | ||
335 | |||
336 | static const struct gpio_keys_button | ||
337 | bcm47xx_buttons_luxul_xap_1500_v1[] = { | ||
338 | BCM47XX_GPIO_KEY(14, KEY_RESTART), | ||
339 | }; | ||
340 | |||
341 | static const struct gpio_keys_button | ||
342 | bcm47xx_buttons_luxul_xbr_4400_v1[] = { | ||
343 | BCM47XX_GPIO_KEY(14, KEY_RESTART), | ||
344 | }; | ||
345 | |||
346 | static const struct gpio_keys_button | ||
347 | bcm47xx_buttons_luxul_xvw_p30_v1[] = { | ||
348 | BCM47XX_GPIO_KEY(20, KEY_RESTART), | ||
349 | }; | ||
350 | |||
351 | static const struct gpio_keys_button | ||
352 | bcm47xx_buttons_luxul_xwr_600_v1[] = { | ||
353 | BCM47XX_GPIO_KEY(8, KEY_RESTART), | ||
354 | }; | ||
355 | |||
356 | static const struct gpio_keys_button | ||
357 | bcm47xx_buttons_luxul_xwr_1750_v1[] = { | ||
358 | BCM47XX_GPIO_KEY(14, KEY_RESTART), | ||
359 | }; | ||
360 | |||
361 | /* Microsoft */ | ||
362 | |||
363 | static const struct gpio_keys_button | ||
364 | bcm47xx_buttons_microsoft_nm700[] __initconst = { | ||
365 | BCM47XX_GPIO_KEY(7, KEY_RESTART), | ||
366 | }; | ||
367 | |||
368 | /* Motorola */ | ||
369 | |||
370 | static const struct gpio_keys_button | ||
371 | bcm47xx_buttons_motorola_we800g[] __initconst = { | ||
372 | BCM47XX_GPIO_KEY(0, KEY_RESTART), | ||
373 | }; | ||
374 | |||
375 | static const struct gpio_keys_button | ||
376 | bcm47xx_buttons_motorola_wr850gp[] __initconst = { | ||
377 | BCM47XX_GPIO_KEY(5, KEY_RESTART), | ||
378 | }; | ||
379 | |||
380 | static const struct gpio_keys_button | ||
381 | bcm47xx_buttons_motorola_wr850gv2v3[] __initconst = { | ||
382 | BCM47XX_GPIO_KEY(5, KEY_RESTART), | ||
383 | }; | ||
384 | |||
385 | /* Netgear */ | ||
386 | |||
387 | static const struct gpio_keys_button | ||
388 | bcm47xx_buttons_netgear_r6200_v1[] __initconst = { | ||
389 | BCM47XX_GPIO_KEY(2, KEY_RFKILL), | ||
390 | BCM47XX_GPIO_KEY(3, KEY_RESTART), | ||
391 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
392 | }; | ||
393 | |||
394 | static const struct gpio_keys_button | ||
395 | bcm47xx_buttons_netgear_wndr3400v1[] __initconst = { | ||
396 | BCM47XX_GPIO_KEY(4, KEY_RESTART), | ||
397 | BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON), | ||
398 | BCM47XX_GPIO_KEY(8, KEY_RFKILL), | ||
399 | }; | ||
400 | |||
401 | static const struct gpio_keys_button | ||
402 | bcm47xx_buttons_netgear_wndr3400_v3[] __initconst = { | ||
403 | BCM47XX_GPIO_KEY(12, KEY_RESTART), | ||
404 | BCM47XX_GPIO_KEY(23, KEY_WPS_BUTTON), | ||
405 | }; | ||
406 | |||
407 | static const struct gpio_keys_button | ||
408 | bcm47xx_buttons_netgear_wndr3700v3[] __initconst = { | ||
409 | BCM47XX_GPIO_KEY(2, KEY_RFKILL), | ||
410 | BCM47XX_GPIO_KEY(3, KEY_RESTART), | ||
411 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
412 | }; | ||
413 | |||
414 | static const struct gpio_keys_button | ||
415 | bcm47xx_buttons_netgear_wndr4500v1[] __initconst = { | ||
416 | BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), | ||
417 | BCM47XX_GPIO_KEY(5, KEY_RFKILL), | ||
418 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
419 | }; | ||
420 | |||
421 | static const struct gpio_keys_button | ||
422 | bcm47xx_buttons_netgear_wnr1000_v3[] __initconst = { | ||
423 | BCM47XX_GPIO_KEY(2, KEY_WPS_BUTTON), | ||
424 | BCM47XX_GPIO_KEY(3, KEY_RESTART), | ||
425 | }; | ||
426 | |||
427 | static const struct gpio_keys_button | ||
428 | bcm47xx_buttons_netgear_wnr3500lv1[] __initconst = { | ||
429 | BCM47XX_GPIO_KEY(4, KEY_RESTART), | ||
430 | BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON), | ||
431 | }; | ||
432 | |||
433 | static const struct gpio_keys_button | ||
434 | bcm47xx_buttons_netgear_wnr834bv2[] __initconst = { | ||
435 | BCM47XX_GPIO_KEY(6, KEY_RESTART), | ||
436 | }; | ||
437 | |||
438 | /* SimpleTech */ | ||
439 | |||
440 | static const struct gpio_keys_button | ||
441 | bcm47xx_buttons_simpletech_simpleshare[] __initconst = { | ||
442 | BCM47XX_GPIO_KEY(0, KEY_RESTART), | ||
443 | }; | ||
444 | |||
445 | /************************************************** | ||
446 | * Init | ||
447 | **************************************************/ | ||
448 | |||
449 | static struct gpio_keys_platform_data bcm47xx_button_pdata; | ||
450 | |||
451 | static struct platform_device bcm47xx_buttons_gpio_keys = { | ||
452 | .name = "gpio-keys", | ||
453 | .dev = { | ||
454 | .platform_data = &bcm47xx_button_pdata, | ||
455 | } | ||
456 | }; | ||
457 | |||
458 | /* Copy data from __initconst */ | ||
459 | static int __init bcm47xx_buttons_copy(const struct gpio_keys_button *buttons, | ||
460 | size_t nbuttons) | ||
461 | { | ||
462 | size_t size = nbuttons * sizeof(*buttons); | ||
463 | |||
464 | bcm47xx_button_pdata.buttons = kmemdup(buttons, size, GFP_KERNEL); | ||
465 | if (!bcm47xx_button_pdata.buttons) | ||
466 | return -ENOMEM; | ||
467 | bcm47xx_button_pdata.nbuttons = nbuttons; | ||
468 | |||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | #define bcm47xx_copy_bdata(dev_buttons) \ | ||
473 | bcm47xx_buttons_copy(dev_buttons, ARRAY_SIZE(dev_buttons)); | ||
474 | |||
475 | int __init bcm47xx_buttons_register(void) | ||
476 | { | ||
477 | enum bcm47xx_board board = bcm47xx_board_get(); | ||
478 | int err; | ||
479 | |||
480 | switch (board) { | ||
481 | case BCM47XX_BOARD_ASUS_RTN12: | ||
482 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn12); | ||
483 | break; | ||
484 | case BCM47XX_BOARD_ASUS_RTN16: | ||
485 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn16); | ||
486 | break; | ||
487 | case BCM47XX_BOARD_ASUS_RTN66U: | ||
488 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn66u); | ||
489 | break; | ||
490 | case BCM47XX_BOARD_ASUS_WL300G: | ||
491 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl300g); | ||
492 | break; | ||
493 | case BCM47XX_BOARD_ASUS_WL320GE: | ||
494 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl320ge); | ||
495 | break; | ||
496 | case BCM47XX_BOARD_ASUS_WL330GE: | ||
497 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl330ge); | ||
498 | break; | ||
499 | case BCM47XX_BOARD_ASUS_WL500G: | ||
500 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500g); | ||
501 | break; | ||
502 | case BCM47XX_BOARD_ASUS_WL500GD: | ||
503 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gd); | ||
504 | break; | ||
505 | case BCM47XX_BOARD_ASUS_WL500GPV1: | ||
506 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gpv1); | ||
507 | break; | ||
508 | case BCM47XX_BOARD_ASUS_WL500GPV2: | ||
509 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gpv2); | ||
510 | break; | ||
511 | case BCM47XX_BOARD_ASUS_WL500W: | ||
512 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500w); | ||
513 | break; | ||
514 | case BCM47XX_BOARD_ASUS_WL520GC: | ||
515 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl520gc); | ||
516 | break; | ||
517 | case BCM47XX_BOARD_ASUS_WL520GU: | ||
518 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl520gu); | ||
519 | break; | ||
520 | case BCM47XX_BOARD_ASUS_WL700GE: | ||
521 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl700ge); | ||
522 | break; | ||
523 | case BCM47XX_BOARD_ASUS_WLHDD: | ||
524 | err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wlhdd); | ||
525 | break; | ||
526 | |||
527 | case BCM47XX_BOARD_BELKIN_F7D3301: | ||
528 | case BCM47XX_BOARD_BELKIN_F7D3302: | ||
529 | case BCM47XX_BOARD_BELKIN_F7D4301: | ||
530 | case BCM47XX_BOARD_BELKIN_F7D4302: | ||
531 | case BCM47XX_BOARD_BELKIN_F7D4401: | ||
532 | err = bcm47xx_copy_bdata(bcm47xx_buttons_belkin_f7d4301); | ||
533 | break; | ||
534 | |||
535 | case BCM47XX_BOARD_BUFFALO_WHR2_A54G54: | ||
536 | err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr2_a54g54); | ||
537 | break; | ||
538 | case BCM47XX_BOARD_BUFFALO_WHR_G125: | ||
539 | err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_g125); | ||
540 | break; | ||
541 | case BCM47XX_BOARD_BUFFALO_WHR_G54S: | ||
542 | err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_g54s); | ||
543 | break; | ||
544 | case BCM47XX_BOARD_BUFFALO_WHR_HP_G54: | ||
545 | err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_hp_g54); | ||
546 | break; | ||
547 | case BCM47XX_BOARD_BUFFALO_WZR_G300N: | ||
548 | err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_g300n); | ||
549 | break; | ||
550 | case BCM47XX_BOARD_BUFFALO_WZR_RS_G54: | ||
551 | err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_rs_g54); | ||
552 | break; | ||
553 | case BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP: | ||
554 | err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_rs_g54hp); | ||
555 | break; | ||
556 | |||
557 | case BCM47XX_BOARD_DELL_TM2300: | ||
558 | err = bcm47xx_copy_bdata(bcm47xx_buttons_dell_tm2300); | ||
559 | break; | ||
560 | |||
561 | case BCM47XX_BOARD_DLINK_DIR130: | ||
562 | err = bcm47xx_copy_bdata(bcm47xx_buttons_dlink_dir130); | ||
563 | break; | ||
564 | case BCM47XX_BOARD_DLINK_DIR330: | ||
565 | err = bcm47xx_copy_bdata(bcm47xx_buttons_dlink_dir330); | ||
566 | break; | ||
567 | |||
568 | case BCM47XX_BOARD_HUAWEI_E970: | ||
569 | err = bcm47xx_copy_bdata(bcm47xx_buttons_huawei_e970); | ||
570 | break; | ||
571 | |||
572 | case BCM47XX_BOARD_LINKSYS_E1000V1: | ||
573 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e1000v1); | ||
574 | break; | ||
575 | case BCM47XX_BOARD_LINKSYS_E1000V21: | ||
576 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e1000v21); | ||
577 | break; | ||
578 | case BCM47XX_BOARD_LINKSYS_E2000V1: | ||
579 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e2000v1); | ||
580 | break; | ||
581 | case BCM47XX_BOARD_LINKSYS_E3000V1: | ||
582 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e3000v1); | ||
583 | break; | ||
584 | case BCM47XX_BOARD_LINKSYS_E3200V1: | ||
585 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e3200v1); | ||
586 | break; | ||
587 | case BCM47XX_BOARD_LINKSYS_E4200V1: | ||
588 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e4200v1); | ||
589 | break; | ||
590 | case BCM47XX_BOARD_LINKSYS_WRT150NV1: | ||
591 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt150nv1); | ||
592 | break; | ||
593 | case BCM47XX_BOARD_LINKSYS_WRT150NV11: | ||
594 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt150nv11); | ||
595 | break; | ||
596 | case BCM47XX_BOARD_LINKSYS_WRT160NV1: | ||
597 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt160nv1); | ||
598 | break; | ||
599 | case BCM47XX_BOARD_LINKSYS_WRT160NV3: | ||
600 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt160nv3); | ||
601 | break; | ||
602 | case BCM47XX_BOARD_LINKSYS_WRT300N_V1: | ||
603 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt300n_v1); | ||
604 | break; | ||
605 | case BCM47XX_BOARD_LINKSYS_WRT300NV11: | ||
606 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt300nv11); | ||
607 | break; | ||
608 | case BCM47XX_BOARD_LINKSYS_WRT310NV1: | ||
609 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt310nv1); | ||
610 | break; | ||
611 | case BCM47XX_BOARD_LINKSYS_WRT54G3GV2: | ||
612 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g3gv2); | ||
613 | break; | ||
614 | case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101: | ||
615 | case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467: | ||
616 | case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708: | ||
617 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt54g_generic); | ||
618 | break; | ||
619 | case BCM47XX_BOARD_LINKSYS_WRT610NV1: | ||
620 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv1); | ||
621 | break; | ||
622 | case BCM47XX_BOARD_LINKSYS_WRT610NV2: | ||
623 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv2); | ||
624 | break; | ||
625 | case BCM47XX_BOARD_LINKSYS_WRTSL54GS: | ||
626 | err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrtsl54gs); | ||
627 | break; | ||
628 | |||
629 | case BCM47XX_BOARD_LUXUL_ABR_4400_V1: | ||
630 | err = bcm47xx_copy_bdata(bcm47xx_buttons_luxul_abr_4400_v1); | ||
631 | break; | ||
632 | case BCM47XX_BOARD_LUXUL_XAP_310_V1: | ||
633 | err = bcm47xx_copy_bdata(bcm47xx_buttons_luxul_xap_310_v1); | ||
634 | break; | ||
635 | case BCM47XX_BOARD_LUXUL_XAP_1210_V1: | ||
636 | err = bcm47xx_copy_bdata(bcm47xx_buttons_luxul_xap_1210_v1); | ||
637 | break; | ||
638 | case BCM47XX_BOARD_LUXUL_XAP_1230_V1: | ||
639 | err = bcm47xx_copy_bdata(bcm47xx_buttons_luxul_xap_1230_v1); | ||
640 | break; | ||
641 | case BCM47XX_BOARD_LUXUL_XAP_1240_V1: | ||
642 | err = bcm47xx_copy_bdata(bcm47xx_buttons_luxul_xap_1240_v1); | ||
643 | break; | ||
644 | case BCM47XX_BOARD_LUXUL_XAP_1500_V1: | ||
645 | err = bcm47xx_copy_bdata(bcm47xx_buttons_luxul_xap_1500_v1); | ||
646 | break; | ||
647 | case BCM47XX_BOARD_LUXUL_XBR_4400_V1: | ||
648 | err = bcm47xx_copy_bdata(bcm47xx_buttons_luxul_xbr_4400_v1); | ||
649 | break; | ||
650 | case BCM47XX_BOARD_LUXUL_XVW_P30_V1: | ||
651 | err = bcm47xx_copy_bdata(bcm47xx_buttons_luxul_xvw_p30_v1); | ||
652 | break; | ||
653 | case BCM47XX_BOARD_LUXUL_XWR_600_V1: | ||
654 | err = bcm47xx_copy_bdata(bcm47xx_buttons_luxul_xwr_600_v1); | ||
655 | break; | ||
656 | case BCM47XX_BOARD_LUXUL_XWR_1750_V1: | ||
657 | err = bcm47xx_copy_bdata(bcm47xx_buttons_luxul_xwr_1750_v1); | ||
658 | break; | ||
659 | |||
660 | case BCM47XX_BOARD_MICROSOFT_MN700: | ||
661 | err = bcm47xx_copy_bdata(bcm47xx_buttons_microsoft_nm700); | ||
662 | break; | ||
663 | |||
664 | case BCM47XX_BOARD_MOTOROLA_WE800G: | ||
665 | err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_we800g); | ||
666 | break; | ||
667 | case BCM47XX_BOARD_MOTOROLA_WR850GP: | ||
668 | err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_wr850gp); | ||
669 | break; | ||
670 | case BCM47XX_BOARD_MOTOROLA_WR850GV2V3: | ||
671 | err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_wr850gv2v3); | ||
672 | break; | ||
673 | |||
674 | case BCM47XX_BOARD_NETGEAR_R6200_V1: | ||
675 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_r6200_v1); | ||
676 | break; | ||
677 | case BCM47XX_BOARD_NETGEAR_WNDR3400V1: | ||
678 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3400v1); | ||
679 | break; | ||
680 | case BCM47XX_BOARD_NETGEAR_WNDR3400_V3: | ||
681 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3400_v3); | ||
682 | break; | ||
683 | case BCM47XX_BOARD_NETGEAR_WNDR3700V3: | ||
684 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3700v3); | ||
685 | break; | ||
686 | case BCM47XX_BOARD_NETGEAR_WNDR4500V1: | ||
687 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500v1); | ||
688 | break; | ||
689 | case BCM47XX_BOARD_NETGEAR_WNR1000_V3: | ||
690 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr1000_v3); | ||
691 | break; | ||
692 | case BCM47XX_BOARD_NETGEAR_WNR3500L: | ||
693 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr3500lv1); | ||
694 | break; | ||
695 | case BCM47XX_BOARD_NETGEAR_WNR834BV2: | ||
696 | err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr834bv2); | ||
697 | break; | ||
698 | |||
699 | case BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE: | ||
700 | err = bcm47xx_copy_bdata(bcm47xx_buttons_simpletech_simpleshare); | ||
701 | break; | ||
702 | |||
703 | default: | ||
704 | pr_debug("No buttons configuration found for this device\n"); | ||
705 | return -ENOTSUPP; | ||
706 | } | ||
707 | |||
708 | if (err) | ||
709 | return -ENOMEM; | ||
710 | |||
711 | err = platform_device_register(&bcm47xx_buttons_gpio_keys); | ||
712 | if (err) { | ||
713 | pr_err("Failed to register platform device: %d\n", err); | ||
714 | return err; | ||
715 | } | ||
716 | |||
717 | return 0; | ||
718 | } | ||
diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c new file mode 100644 index 000000000..21b4497f0 --- /dev/null +++ b/arch/mips/bcm47xx/irq.c | |||
@@ -0,0 +1,98 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | * | ||
9 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
10 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
12 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
13 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
14 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
15 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
16 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
17 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
18 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | #include "bcm47xx_private.h" | ||
26 | |||
27 | #include <linux/types.h> | ||
28 | #include <linux/interrupt.h> | ||
29 | #include <linux/irq.h> | ||
30 | #include <asm/setup.h> | ||
31 | #include <asm/irq_cpu.h> | ||
32 | #include <bcm47xx.h> | ||
33 | |||
34 | asmlinkage void plat_irq_dispatch(void) | ||
35 | { | ||
36 | u32 cause; | ||
37 | |||
38 | cause = read_c0_cause() & read_c0_status() & CAUSEF_IP; | ||
39 | |||
40 | clear_c0_status(cause); | ||
41 | |||
42 | if (cause & CAUSEF_IP7) | ||
43 | do_IRQ(7); | ||
44 | if (cause & CAUSEF_IP2) | ||
45 | do_IRQ(2); | ||
46 | if (cause & CAUSEF_IP3) | ||
47 | do_IRQ(3); | ||
48 | if (cause & CAUSEF_IP4) | ||
49 | do_IRQ(4); | ||
50 | if (cause & CAUSEF_IP5) | ||
51 | do_IRQ(5); | ||
52 | if (cause & CAUSEF_IP6) | ||
53 | do_IRQ(6); | ||
54 | } | ||
55 | |||
56 | #define DEFINE_HWx_IRQDISPATCH(x) \ | ||
57 | static void bcm47xx_hw ## x ## _irqdispatch(void) \ | ||
58 | { \ | ||
59 | do_IRQ(x); \ | ||
60 | } | ||
61 | DEFINE_HWx_IRQDISPATCH(2) | ||
62 | DEFINE_HWx_IRQDISPATCH(3) | ||
63 | DEFINE_HWx_IRQDISPATCH(4) | ||
64 | DEFINE_HWx_IRQDISPATCH(5) | ||
65 | DEFINE_HWx_IRQDISPATCH(6) | ||
66 | DEFINE_HWx_IRQDISPATCH(7) | ||
67 | |||
68 | void __init arch_init_irq(void) | ||
69 | { | ||
70 | /* | ||
71 | * This is the first arch callback after mm_init (we can use kmalloc), | ||
72 | * so let's finish bus initialization now. | ||
73 | */ | ||
74 | bcm47xx_bus_setup(); | ||
75 | |||
76 | #ifdef CONFIG_BCM47XX_BCMA | ||
77 | if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { | ||
78 | bcma_write32(bcm47xx_bus.bcma.bus.drv_mips.core, | ||
79 | BCMA_MIPS_MIPS74K_INTMASK(5), 1 << 31); | ||
80 | /* | ||
81 | * the kernel reads the timer irq from some register and thinks | ||
82 | * it's #5, but we offset it by 2 and route to #7 | ||
83 | */ | ||
84 | cp0_compare_irq = 7; | ||
85 | } | ||
86 | #endif | ||
87 | mips_cpu_irq_init(); | ||
88 | |||
89 | if (cpu_has_vint) { | ||
90 | pr_info("Setting up vectored interrupts\n"); | ||
91 | set_vi_handler(2, bcm47xx_hw2_irqdispatch); | ||
92 | set_vi_handler(3, bcm47xx_hw3_irqdispatch); | ||
93 | set_vi_handler(4, bcm47xx_hw4_irqdispatch); | ||
94 | set_vi_handler(5, bcm47xx_hw5_irqdispatch); | ||
95 | set_vi_handler(6, bcm47xx_hw6_irqdispatch); | ||
96 | set_vi_handler(7, bcm47xx_hw7_irqdispatch); | ||
97 | } | ||
98 | } | ||
diff --git a/arch/mips/bcm47xx/leds.c b/arch/mips/bcm47xx/leds.c new file mode 100644 index 000000000..167c42c71 --- /dev/null +++ b/arch/mips/bcm47xx/leds.c | |||
@@ -0,0 +1,793 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | #include "bcm47xx_private.h" | ||
3 | |||
4 | #include <linux/leds.h> | ||
5 | #include <bcm47xx_board.h> | ||
6 | |||
7 | /************************************************** | ||
8 | * Database | ||
9 | **************************************************/ | ||
10 | |||
11 | #define BCM47XX_GPIO_LED(_gpio, _color, _function, _active_low, \ | ||
12 | _default_state) \ | ||
13 | { \ | ||
14 | .name = "bcm47xx:" _color ":" _function, \ | ||
15 | .gpio = _gpio, \ | ||
16 | .active_low = _active_low, \ | ||
17 | .default_state = _default_state, \ | ||
18 | } | ||
19 | |||
20 | #define BCM47XX_GPIO_LED_TRIGGER(_gpio, _color, _function, _active_low, \ | ||
21 | _default_trigger) \ | ||
22 | { \ | ||
23 | .name = "bcm47xx:" _color ":" _function, \ | ||
24 | .gpio = _gpio, \ | ||
25 | .active_low = _active_low, \ | ||
26 | .default_state = LEDS_GPIO_DEFSTATE_OFF, \ | ||
27 | .default_trigger = _default_trigger, \ | ||
28 | } | ||
29 | |||
30 | /* Asus */ | ||
31 | |||
32 | static const struct gpio_led | ||
33 | bcm47xx_leds_asus_rtn12[] __initconst = { | ||
34 | BCM47XX_GPIO_LED(2, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
35 | BCM47XX_GPIO_LED(7, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
36 | }; | ||
37 | |||
38 | static const struct gpio_led | ||
39 | bcm47xx_leds_asus_rtn15u[] __initconst = { | ||
40 | /* TODO: Add "wlan" LED */ | ||
41 | BCM47XX_GPIO_LED(3, "blue", "wan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
42 | BCM47XX_GPIO_LED(4, "blue", "lan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
43 | BCM47XX_GPIO_LED(6, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
44 | BCM47XX_GPIO_LED(9, "blue", "usb", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
45 | }; | ||
46 | |||
47 | static const struct gpio_led | ||
48 | bcm47xx_leds_asus_rtn16[] __initconst = { | ||
49 | BCM47XX_GPIO_LED(1, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
50 | BCM47XX_GPIO_LED(7, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
51 | }; | ||
52 | |||
53 | static const struct gpio_led | ||
54 | bcm47xx_leds_asus_rtn66u[] __initconst = { | ||
55 | BCM47XX_GPIO_LED(12, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
56 | BCM47XX_GPIO_LED(15, "blue", "usb", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
57 | }; | ||
58 | |||
59 | static const struct gpio_led | ||
60 | bcm47xx_leds_asus_wl300g[] __initconst = { | ||
61 | BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
62 | }; | ||
63 | |||
64 | static const struct gpio_led | ||
65 | bcm47xx_leds_asus_wl320ge[] __initconst = { | ||
66 | BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
67 | BCM47XX_GPIO_LED(2, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
68 | BCM47XX_GPIO_LED(11, "unk", "link", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
69 | }; | ||
70 | |||
71 | static const struct gpio_led | ||
72 | bcm47xx_leds_asus_wl330ge[] __initconst = { | ||
73 | BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
74 | }; | ||
75 | |||
76 | static const struct gpio_led | ||
77 | bcm47xx_leds_asus_wl500g[] __initconst = { | ||
78 | BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
79 | }; | ||
80 | |||
81 | static const struct gpio_led | ||
82 | bcm47xx_leds_asus_wl500gd[] __initconst = { | ||
83 | BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
84 | }; | ||
85 | |||
86 | static const struct gpio_led | ||
87 | bcm47xx_leds_asus_wl500gpv1[] __initconst = { | ||
88 | BCM47XX_GPIO_LED(1, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
89 | }; | ||
90 | |||
91 | static const struct gpio_led | ||
92 | bcm47xx_leds_asus_wl500gpv2[] __initconst = { | ||
93 | BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
94 | BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
95 | }; | ||
96 | |||
97 | static const struct gpio_led | ||
98 | bcm47xx_leds_asus_wl500w[] __initconst = { | ||
99 | BCM47XX_GPIO_LED(5, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
100 | }; | ||
101 | |||
102 | static const struct gpio_led | ||
103 | bcm47xx_leds_asus_wl520gc[] __initconst = { | ||
104 | BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
105 | BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
106 | }; | ||
107 | |||
108 | static const struct gpio_led | ||
109 | bcm47xx_leds_asus_wl520gu[] __initconst = { | ||
110 | BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
111 | BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
112 | }; | ||
113 | |||
114 | static const struct gpio_led | ||
115 | bcm47xx_leds_asus_wl700ge[] __initconst = { | ||
116 | BCM47XX_GPIO_LED(1, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), /* Labeled "READY" (there is no "power" LED). Originally ON, flashing on USB activity. */ | ||
117 | }; | ||
118 | |||
119 | static const struct gpio_led | ||
120 | bcm47xx_leds_asus_wlhdd[] __initconst = { | ||
121 | BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
122 | BCM47XX_GPIO_LED(2, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
123 | }; | ||
124 | |||
125 | /* Belkin */ | ||
126 | |||
127 | static const struct gpio_led | ||
128 | bcm47xx_leds_belkin_f7d4301[] __initconst = { | ||
129 | BCM47XX_GPIO_LED(10, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
130 | BCM47XX_GPIO_LED(11, "amber", "power", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
131 | BCM47XX_GPIO_LED(12, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
132 | BCM47XX_GPIO_LED(13, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
133 | BCM47XX_GPIO_LED(14, "unk", "usb0", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
134 | BCM47XX_GPIO_LED(15, "unk", "usb1", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
135 | }; | ||
136 | |||
137 | /* Buffalo */ | ||
138 | |||
139 | static const struct gpio_led | ||
140 | bcm47xx_leds_buffalo_whr2_a54g54[] __initconst = { | ||
141 | BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
142 | }; | ||
143 | |||
144 | static const struct gpio_led | ||
145 | bcm47xx_leds_buffalo_whr_g125[] __initconst = { | ||
146 | BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
147 | BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
148 | BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
149 | BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
150 | BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
151 | }; | ||
152 | |||
153 | static const struct gpio_led | ||
154 | bcm47xx_leds_buffalo_whr_g54s[] __initconst = { | ||
155 | BCM47XX_GPIO_LED(1, "green", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
156 | BCM47XX_GPIO_LED(2, "green", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
157 | BCM47XX_GPIO_LED(3, "green", "internal", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
158 | BCM47XX_GPIO_LED(6, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
159 | BCM47XX_GPIO_LED(7, "red", "diag", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
160 | }; | ||
161 | |||
162 | static const struct gpio_led | ||
163 | bcm47xx_leds_buffalo_whr_hp_g54[] __initconst = { | ||
164 | BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
165 | BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
166 | BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
167 | BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
168 | BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
169 | }; | ||
170 | |||
171 | static const struct gpio_led | ||
172 | bcm47xx_leds_buffalo_wzr_g300n[] __initconst = { | ||
173 | BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
174 | BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
175 | BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
176 | }; | ||
177 | |||
178 | static const struct gpio_led | ||
179 | bcm47xx_leds_buffalo_wzr_rs_g54[] __initconst = { | ||
180 | BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
181 | BCM47XX_GPIO_LED(1, "unk", "vpn", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
182 | BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
183 | }; | ||
184 | |||
185 | static const struct gpio_led | ||
186 | bcm47xx_leds_buffalo_wzr_rs_g54hp[] __initconst = { | ||
187 | BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
188 | BCM47XX_GPIO_LED(1, "unk", "vpn", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
189 | BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
190 | }; | ||
191 | |||
192 | /* Dell */ | ||
193 | |||
194 | static const struct gpio_led | ||
195 | bcm47xx_leds_dell_tm2300[] __initconst = { | ||
196 | BCM47XX_GPIO_LED(6, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
197 | BCM47XX_GPIO_LED(7, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
198 | }; | ||
199 | |||
200 | /* D-Link */ | ||
201 | |||
202 | static const struct gpio_led | ||
203 | bcm47xx_leds_dlink_dir130[] __initconst = { | ||
204 | BCM47XX_GPIO_LED_TRIGGER(0, "green", "status", 1, "timer"), /* Originally blinking when device is ready, separated from "power" LED */ | ||
205 | BCM47XX_GPIO_LED(6, "blue", "unk", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
206 | }; | ||
207 | |||
208 | static const struct gpio_led | ||
209 | bcm47xx_leds_dlink_dir330[] __initconst = { | ||
210 | BCM47XX_GPIO_LED_TRIGGER(0, "green", "status", 1, "timer"), /* Originally blinking when device is ready, separated from "power" LED */ | ||
211 | BCM47XX_GPIO_LED(4, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
212 | BCM47XX_GPIO_LED(6, "blue", "unk", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
213 | }; | ||
214 | |||
215 | /* Huawei */ | ||
216 | |||
217 | static const struct gpio_led | ||
218 | bcm47xx_leds_huawei_e970[] __initconst = { | ||
219 | BCM47XX_GPIO_LED(0, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
220 | }; | ||
221 | |||
222 | /* Linksys */ | ||
223 | |||
224 | static const struct gpio_led | ||
225 | bcm47xx_leds_linksys_e1000v1[] __initconst = { | ||
226 | BCM47XX_GPIO_LED(0, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
227 | BCM47XX_GPIO_LED(1, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
228 | BCM47XX_GPIO_LED(2, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
229 | BCM47XX_GPIO_LED(4, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
230 | }; | ||
231 | |||
232 | static const struct gpio_led | ||
233 | bcm47xx_leds_linksys_e1000v21[] __initconst = { | ||
234 | BCM47XX_GPIO_LED(5, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
235 | BCM47XX_GPIO_LED(6, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
236 | BCM47XX_GPIO_LED(7, "amber", "wps", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
237 | BCM47XX_GPIO_LED(8, "blue", "wps", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
238 | }; | ||
239 | |||
240 | static const struct gpio_led | ||
241 | bcm47xx_leds_linksys_e2000v1[] __initconst = { | ||
242 | BCM47XX_GPIO_LED(1, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
243 | BCM47XX_GPIO_LED(2, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
244 | BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
245 | BCM47XX_GPIO_LED(4, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
246 | }; | ||
247 | |||
248 | static const struct gpio_led | ||
249 | bcm47xx_leds_linksys_e3000v1[] __initconst = { | ||
250 | BCM47XX_GPIO_LED(0, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
251 | BCM47XX_GPIO_LED(1, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
252 | BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
253 | BCM47XX_GPIO_LED(5, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
254 | BCM47XX_GPIO_LED(7, "unk", "usb", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
255 | }; | ||
256 | |||
257 | static const struct gpio_led | ||
258 | bcm47xx_leds_linksys_e3200v1[] __initconst = { | ||
259 | BCM47XX_GPIO_LED(3, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
260 | }; | ||
261 | |||
262 | static const struct gpio_led | ||
263 | bcm47xx_leds_linksys_e4200v1[] __initconst = { | ||
264 | BCM47XX_GPIO_LED(5, "white", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
265 | }; | ||
266 | |||
267 | static const struct gpio_led | ||
268 | bcm47xx_leds_linksys_wrt150nv1[] __initconst = { | ||
269 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
270 | BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
271 | BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
272 | }; | ||
273 | |||
274 | static const struct gpio_led | ||
275 | bcm47xx_leds_linksys_wrt150nv11[] __initconst = { | ||
276 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
277 | BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
278 | BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
279 | }; | ||
280 | |||
281 | static const struct gpio_led | ||
282 | bcm47xx_leds_linksys_wrt160nv1[] __initconst = { | ||
283 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
284 | BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
285 | BCM47XX_GPIO_LED(5, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
286 | }; | ||
287 | |||
288 | static const struct gpio_led | ||
289 | bcm47xx_leds_linksys_wrt160nv3[] __initconst = { | ||
290 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
291 | BCM47XX_GPIO_LED(2, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
292 | BCM47XX_GPIO_LED(4, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
293 | }; | ||
294 | |||
295 | static const struct gpio_led | ||
296 | bcm47xx_leds_linksys_wrt300n_v1[] __initconst = { | ||
297 | BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
298 | BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
299 | BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
300 | }; | ||
301 | |||
302 | static const struct gpio_led | ||
303 | bcm47xx_leds_linksys_wrt300nv11[] __initconst = { | ||
304 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
305 | BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
306 | BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
307 | }; | ||
308 | |||
309 | static const struct gpio_led | ||
310 | bcm47xx_leds_linksys_wrt310nv1[] __initconst = { | ||
311 | BCM47XX_GPIO_LED(1, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
312 | BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
313 | BCM47XX_GPIO_LED(9, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
314 | }; | ||
315 | |||
316 | static const struct gpio_led | ||
317 | bcm47xx_leds_linksys_wrt54g_generic[] __initconst = { | ||
318 | BCM47XX_GPIO_LED(0, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
319 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
320 | BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
321 | BCM47XX_GPIO_LED(7, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
322 | }; | ||
323 | |||
324 | static const struct gpio_led | ||
325 | bcm47xx_leds_linksys_wrt54g3gv2[] __initconst = { | ||
326 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
327 | BCM47XX_GPIO_LED(2, "green", "3g", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
328 | BCM47XX_GPIO_LED(3, "blue", "3g", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
329 | }; | ||
330 | |||
331 | /* Verified on: WRT54GS V1.0 */ | ||
332 | static const struct gpio_led | ||
333 | bcm47xx_leds_linksys_wrt54g_type_0101[] __initconst = { | ||
334 | BCM47XX_GPIO_LED(0, "green", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
335 | BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
336 | BCM47XX_GPIO_LED(7, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
337 | }; | ||
338 | |||
339 | /* Verified on: WRT54GL V1.1 */ | ||
340 | static const struct gpio_led | ||
341 | bcm47xx_leds_linksys_wrt54g_type_0467[] __initconst = { | ||
342 | BCM47XX_GPIO_LED(0, "green", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
343 | BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
344 | BCM47XX_GPIO_LED(2, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
345 | BCM47XX_GPIO_LED(3, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
346 | BCM47XX_GPIO_LED(7, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
347 | }; | ||
348 | |||
349 | static const struct gpio_led | ||
350 | bcm47xx_leds_linksys_wrt610nv1[] __initconst = { | ||
351 | BCM47XX_GPIO_LED(0, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
352 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
353 | BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
354 | BCM47XX_GPIO_LED(9, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
355 | }; | ||
356 | |||
357 | static const struct gpio_led | ||
358 | bcm47xx_leds_linksys_wrt610nv2[] __initconst = { | ||
359 | BCM47XX_GPIO_LED(0, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
360 | BCM47XX_GPIO_LED(1, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
361 | BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
362 | BCM47XX_GPIO_LED(5, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
363 | BCM47XX_GPIO_LED(7, "unk", "usb", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
364 | }; | ||
365 | |||
366 | static const struct gpio_led | ||
367 | bcm47xx_leds_linksys_wrtsl54gs[] __initconst = { | ||
368 | BCM47XX_GPIO_LED(0, "green", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
369 | BCM47XX_GPIO_LED(1, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
370 | BCM47XX_GPIO_LED(5, "white", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
371 | BCM47XX_GPIO_LED(7, "orange", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
372 | }; | ||
373 | |||
374 | /* Luxul */ | ||
375 | |||
376 | static const struct gpio_led | ||
377 | bcm47xx_leds_luxul_abr_4400_v1[] __initconst = { | ||
378 | BCM47XX_GPIO_LED(12, "green", "usb", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
379 | BCM47XX_GPIO_LED_TRIGGER(15, "green", "status", 0, "timer"), | ||
380 | }; | ||
381 | |||
382 | static const struct gpio_led | ||
383 | bcm47xx_leds_luxul_xap_310_v1[] __initconst = { | ||
384 | BCM47XX_GPIO_LED_TRIGGER(6, "green", "status", 1, "timer"), | ||
385 | }; | ||
386 | |||
387 | static const struct gpio_led | ||
388 | bcm47xx_leds_luxul_xap_1210_v1[] __initconst = { | ||
389 | BCM47XX_GPIO_LED_TRIGGER(6, "green", "status", 1, "timer"), | ||
390 | }; | ||
391 | |||
392 | static const struct gpio_led | ||
393 | bcm47xx_leds_luxul_xap_1230_v1[] __initconst = { | ||
394 | BCM47XX_GPIO_LED(3, "blue", "2ghz", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
395 | BCM47XX_GPIO_LED(4, "green", "bridge", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
396 | BCM47XX_GPIO_LED_TRIGGER(6, "green", "status", 1, "timer"), | ||
397 | }; | ||
398 | |||
399 | static const struct gpio_led | ||
400 | bcm47xx_leds_luxul_xap_1240_v1[] __initconst = { | ||
401 | BCM47XX_GPIO_LED(3, "blue", "2ghz", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
402 | BCM47XX_GPIO_LED(4, "green", "bridge", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
403 | BCM47XX_GPIO_LED_TRIGGER(6, "green", "status", 1, "timer"), | ||
404 | }; | ||
405 | |||
406 | static const struct gpio_led | ||
407 | bcm47xx_leds_luxul_xap_1500_v1[] __initconst = { | ||
408 | BCM47XX_GPIO_LED_TRIGGER(13, "green", "status", 1, "timer"), | ||
409 | }; | ||
410 | |||
411 | static const struct gpio_led | ||
412 | bcm47xx_leds_luxul_xap1500_v1_extra[] __initconst = { | ||
413 | BCM47XX_GPIO_LED(44, "green", "5ghz", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
414 | BCM47XX_GPIO_LED(76, "green", "2ghz", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
415 | }; | ||
416 | |||
417 | static const struct gpio_led | ||
418 | bcm47xx_leds_luxul_xbr_4400_v1[] __initconst = { | ||
419 | BCM47XX_GPIO_LED(12, "green", "usb", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
420 | BCM47XX_GPIO_LED_TRIGGER(15, "green", "status", 0, "timer"), | ||
421 | }; | ||
422 | |||
423 | static const struct gpio_led | ||
424 | bcm47xx_leds_luxul_xvw_p30_v1[] __initconst = { | ||
425 | BCM47XX_GPIO_LED_TRIGGER(0, "blue", "status", 1, "timer"), | ||
426 | BCM47XX_GPIO_LED(1, "green", "link", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
427 | }; | ||
428 | |||
429 | static const struct gpio_led | ||
430 | bcm47xx_leds_luxul_xwr_600_v1[] __initconst = { | ||
431 | BCM47XX_GPIO_LED(3, "green", "wps", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
432 | BCM47XX_GPIO_LED_TRIGGER(6, "green", "status", 1, "timer"), | ||
433 | BCM47XX_GPIO_LED(9, "green", "usb", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
434 | }; | ||
435 | |||
436 | static const struct gpio_led | ||
437 | bcm47xx_leds_luxul_xwr_1750_v1[] __initconst = { | ||
438 | BCM47XX_GPIO_LED(5, "green", "5ghz", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
439 | BCM47XX_GPIO_LED(12, "green", "usb", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
440 | BCM47XX_GPIO_LED_TRIGGER(13, "green", "status", 0, "timer"), | ||
441 | BCM47XX_GPIO_LED(15, "green", "wps", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
442 | }; | ||
443 | |||
444 | static const struct gpio_led | ||
445 | bcm47xx_leds_luxul_xwr1750_v1_extra[] __initconst = { | ||
446 | BCM47XX_GPIO_LED(76, "green", "2ghz", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
447 | }; | ||
448 | |||
449 | /* Microsoft */ | ||
450 | |||
451 | static const struct gpio_led | ||
452 | bcm47xx_leds_microsoft_nm700[] __initconst = { | ||
453 | BCM47XX_GPIO_LED(6, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
454 | }; | ||
455 | |||
456 | /* Motorola */ | ||
457 | |||
458 | static const struct gpio_led | ||
459 | bcm47xx_leds_motorola_we800g[] __initconst = { | ||
460 | BCM47XX_GPIO_LED(1, "amber", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
461 | BCM47XX_GPIO_LED(2, "unk", "unk", 1, LEDS_GPIO_DEFSTATE_OFF), /* There are only 3 LEDs: Power, Wireless and Device (ethernet) */ | ||
462 | BCM47XX_GPIO_LED(4, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
463 | }; | ||
464 | |||
465 | static const struct gpio_led | ||
466 | bcm47xx_leds_motorola_wr850gp[] __initconst = { | ||
467 | BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
468 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
469 | BCM47XX_GPIO_LED(6, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
470 | BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
471 | }; | ||
472 | |||
473 | static const struct gpio_led | ||
474 | bcm47xx_leds_motorola_wr850gv2v3[] __initconst = { | ||
475 | BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
476 | BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
477 | BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
478 | }; | ||
479 | |||
480 | /* Netgear */ | ||
481 | |||
482 | static const struct gpio_led | ||
483 | bcm47xx_leds_netgear_wndr3400v1[] __initconst = { | ||
484 | BCM47XX_GPIO_LED(2, "green", "usb", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
485 | BCM47XX_GPIO_LED(3, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
486 | BCM47XX_GPIO_LED(7, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
487 | }; | ||
488 | |||
489 | static const struct gpio_led | ||
490 | bcm47xx_leds_netgear_wndr4500v1[] __initconst = { | ||
491 | BCM47XX_GPIO_LED(1, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
492 | BCM47XX_GPIO_LED(2, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
493 | BCM47XX_GPIO_LED(3, "amber", "power", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
494 | BCM47XX_GPIO_LED(8, "green", "usb1", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
495 | BCM47XX_GPIO_LED(9, "green", "2ghz", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
496 | BCM47XX_GPIO_LED(11, "blue", "5ghz", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
497 | BCM47XX_GPIO_LED(14, "green", "usb2", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
498 | }; | ||
499 | |||
500 | static const struct gpio_led | ||
501 | bcm47xx_leds_netgear_wnr1000_v3[] __initconst = { | ||
502 | BCM47XX_GPIO_LED(0, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
503 | BCM47XX_GPIO_LED(1, "green", "wps", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
504 | }; | ||
505 | |||
506 | static const struct gpio_led | ||
507 | bcm47xx_leds_netgear_wnr3500lv1[] __initconst = { | ||
508 | BCM47XX_GPIO_LED(0, "blue", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
509 | BCM47XX_GPIO_LED(1, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
510 | BCM47XX_GPIO_LED(2, "green", "wan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
511 | BCM47XX_GPIO_LED(3, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
512 | BCM47XX_GPIO_LED(7, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
513 | }; | ||
514 | |||
515 | static const struct gpio_led | ||
516 | bcm47xx_leds_netgear_wnr834bv2[] __initconst = { | ||
517 | BCM47XX_GPIO_LED(2, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON), | ||
518 | BCM47XX_GPIO_LED(3, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
519 | BCM47XX_GPIO_LED(7, "unk", "connected", 0, LEDS_GPIO_DEFSTATE_OFF), | ||
520 | }; | ||
521 | |||
522 | /* Siemens */ | ||
523 | static const struct gpio_led | ||
524 | bcm47xx_leds_siemens_se505v2[] __initconst = { | ||
525 | BCM47XX_GPIO_LED(0, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
526 | BCM47XX_GPIO_LED(3, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF), | ||
527 | BCM47XX_GPIO_LED(5, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), | ||
528 | }; | ||
529 | |||
530 | /* SimpleTech */ | ||
531 | |||
532 | static const struct gpio_led | ||
533 | bcm47xx_leds_simpletech_simpleshare[] __initconst = { | ||
534 | BCM47XX_GPIO_LED(1, "unk", "status", 1, LEDS_GPIO_DEFSTATE_OFF), /* "Ready" LED */ | ||
535 | }; | ||
536 | |||
537 | /************************************************** | ||
538 | * Init | ||
539 | **************************************************/ | ||
540 | |||
541 | static struct gpio_led_platform_data bcm47xx_leds_pdata __initdata; | ||
542 | |||
543 | #define bcm47xx_set_pdata(dev_leds) do { \ | ||
544 | bcm47xx_leds_pdata.leds = dev_leds; \ | ||
545 | bcm47xx_leds_pdata.num_leds = ARRAY_SIZE(dev_leds); \ | ||
546 | } while (0) | ||
547 | |||
548 | static struct gpio_led_platform_data bcm47xx_leds_pdata_extra __initdata = {}; | ||
549 | #define bcm47xx_set_pdata_extra(dev_leds) do { \ | ||
550 | bcm47xx_leds_pdata_extra.leds = dev_leds; \ | ||
551 | bcm47xx_leds_pdata_extra.num_leds = ARRAY_SIZE(dev_leds); \ | ||
552 | } while (0) | ||
553 | |||
554 | void __init bcm47xx_leds_register(void) | ||
555 | { | ||
556 | enum bcm47xx_board board = bcm47xx_board_get(); | ||
557 | |||
558 | switch (board) { | ||
559 | case BCM47XX_BOARD_ASUS_RTN12: | ||
560 | bcm47xx_set_pdata(bcm47xx_leds_asus_rtn12); | ||
561 | break; | ||
562 | case BCM47XX_BOARD_ASUS_RTN15U: | ||
563 | bcm47xx_set_pdata(bcm47xx_leds_asus_rtn15u); | ||
564 | break; | ||
565 | case BCM47XX_BOARD_ASUS_RTN16: | ||
566 | bcm47xx_set_pdata(bcm47xx_leds_asus_rtn16); | ||
567 | break; | ||
568 | case BCM47XX_BOARD_ASUS_RTN66U: | ||
569 | bcm47xx_set_pdata(bcm47xx_leds_asus_rtn66u); | ||
570 | break; | ||
571 | case BCM47XX_BOARD_ASUS_WL300G: | ||
572 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl300g); | ||
573 | break; | ||
574 | case BCM47XX_BOARD_ASUS_WL320GE: | ||
575 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl320ge); | ||
576 | break; | ||
577 | case BCM47XX_BOARD_ASUS_WL330GE: | ||
578 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl330ge); | ||
579 | break; | ||
580 | case BCM47XX_BOARD_ASUS_WL500G: | ||
581 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl500g); | ||
582 | break; | ||
583 | case BCM47XX_BOARD_ASUS_WL500GD: | ||
584 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gd); | ||
585 | break; | ||
586 | case BCM47XX_BOARD_ASUS_WL500GPV1: | ||
587 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gpv1); | ||
588 | break; | ||
589 | case BCM47XX_BOARD_ASUS_WL500GPV2: | ||
590 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gpv2); | ||
591 | break; | ||
592 | case BCM47XX_BOARD_ASUS_WL500W: | ||
593 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl500w); | ||
594 | break; | ||
595 | case BCM47XX_BOARD_ASUS_WL520GC: | ||
596 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl520gc); | ||
597 | break; | ||
598 | case BCM47XX_BOARD_ASUS_WL520GU: | ||
599 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl520gu); | ||
600 | break; | ||
601 | case BCM47XX_BOARD_ASUS_WL700GE: | ||
602 | bcm47xx_set_pdata(bcm47xx_leds_asus_wl700ge); | ||
603 | break; | ||
604 | case BCM47XX_BOARD_ASUS_WLHDD: | ||
605 | bcm47xx_set_pdata(bcm47xx_leds_asus_wlhdd); | ||
606 | break; | ||
607 | |||
608 | case BCM47XX_BOARD_BELKIN_F7D3301: | ||
609 | case BCM47XX_BOARD_BELKIN_F7D3302: | ||
610 | case BCM47XX_BOARD_BELKIN_F7D4301: | ||
611 | case BCM47XX_BOARD_BELKIN_F7D4302: | ||
612 | case BCM47XX_BOARD_BELKIN_F7D4401: | ||
613 | bcm47xx_set_pdata(bcm47xx_leds_belkin_f7d4301); | ||
614 | break; | ||
615 | |||
616 | case BCM47XX_BOARD_BUFFALO_WHR2_A54G54: | ||
617 | bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr2_a54g54); | ||
618 | break; | ||
619 | case BCM47XX_BOARD_BUFFALO_WHR_G125: | ||
620 | bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_g125); | ||
621 | break; | ||
622 | case BCM47XX_BOARD_BUFFALO_WHR_G54S: | ||
623 | bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_g54s); | ||
624 | break; | ||
625 | case BCM47XX_BOARD_BUFFALO_WHR_HP_G54: | ||
626 | bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_hp_g54); | ||
627 | break; | ||
628 | case BCM47XX_BOARD_BUFFALO_WZR_G300N: | ||
629 | bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_g300n); | ||
630 | break; | ||
631 | case BCM47XX_BOARD_BUFFALO_WZR_RS_G54: | ||
632 | bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_rs_g54); | ||
633 | break; | ||
634 | case BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP: | ||
635 | bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_rs_g54hp); | ||
636 | break; | ||
637 | |||
638 | case BCM47XX_BOARD_DELL_TM2300: | ||
639 | bcm47xx_set_pdata(bcm47xx_leds_dell_tm2300); | ||
640 | break; | ||
641 | |||
642 | case BCM47XX_BOARD_DLINK_DIR130: | ||
643 | bcm47xx_set_pdata(bcm47xx_leds_dlink_dir130); | ||
644 | break; | ||
645 | case BCM47XX_BOARD_DLINK_DIR330: | ||
646 | bcm47xx_set_pdata(bcm47xx_leds_dlink_dir330); | ||
647 | break; | ||
648 | |||
649 | case BCM47XX_BOARD_HUAWEI_E970: | ||
650 | bcm47xx_set_pdata(bcm47xx_leds_huawei_e970); | ||
651 | break; | ||
652 | |||
653 | case BCM47XX_BOARD_LINKSYS_E1000V1: | ||
654 | bcm47xx_set_pdata(bcm47xx_leds_linksys_e1000v1); | ||
655 | break; | ||
656 | case BCM47XX_BOARD_LINKSYS_E1000V21: | ||
657 | bcm47xx_set_pdata(bcm47xx_leds_linksys_e1000v21); | ||
658 | break; | ||
659 | case BCM47XX_BOARD_LINKSYS_E2000V1: | ||
660 | bcm47xx_set_pdata(bcm47xx_leds_linksys_e2000v1); | ||
661 | break; | ||
662 | case BCM47XX_BOARD_LINKSYS_E3000V1: | ||
663 | bcm47xx_set_pdata(bcm47xx_leds_linksys_e3000v1); | ||
664 | break; | ||
665 | case BCM47XX_BOARD_LINKSYS_E3200V1: | ||
666 | bcm47xx_set_pdata(bcm47xx_leds_linksys_e3200v1); | ||
667 | break; | ||
668 | case BCM47XX_BOARD_LINKSYS_E4200V1: | ||
669 | bcm47xx_set_pdata(bcm47xx_leds_linksys_e4200v1); | ||
670 | break; | ||
671 | case BCM47XX_BOARD_LINKSYS_WRT150NV1: | ||
672 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt150nv1); | ||
673 | break; | ||
674 | case BCM47XX_BOARD_LINKSYS_WRT150NV11: | ||
675 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt150nv11); | ||
676 | break; | ||
677 | case BCM47XX_BOARD_LINKSYS_WRT160NV1: | ||
678 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt160nv1); | ||
679 | break; | ||
680 | case BCM47XX_BOARD_LINKSYS_WRT160NV3: | ||
681 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt160nv3); | ||
682 | break; | ||
683 | case BCM47XX_BOARD_LINKSYS_WRT300N_V1: | ||
684 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt300n_v1); | ||
685 | break; | ||
686 | case BCM47XX_BOARD_LINKSYS_WRT300NV11: | ||
687 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt300nv11); | ||
688 | break; | ||
689 | case BCM47XX_BOARD_LINKSYS_WRT310NV1: | ||
690 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt310nv1); | ||
691 | break; | ||
692 | case BCM47XX_BOARD_LINKSYS_WRT54G3GV2: | ||
693 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g3gv2); | ||
694 | break; | ||
695 | case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0101: | ||
696 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_type_0101); | ||
697 | break; | ||
698 | case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0467: | ||
699 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_type_0467); | ||
700 | break; | ||
701 | case BCM47XX_BOARD_LINKSYS_WRT54G_TYPE_0708: | ||
702 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt54g_generic); | ||
703 | break; | ||
704 | case BCM47XX_BOARD_LINKSYS_WRT610NV1: | ||
705 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv1); | ||
706 | break; | ||
707 | case BCM47XX_BOARD_LINKSYS_WRT610NV2: | ||
708 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv2); | ||
709 | break; | ||
710 | case BCM47XX_BOARD_LINKSYS_WRTSL54GS: | ||
711 | bcm47xx_set_pdata(bcm47xx_leds_linksys_wrtsl54gs); | ||
712 | break; | ||
713 | |||
714 | case BCM47XX_BOARD_LUXUL_ABR_4400_V1: | ||
715 | bcm47xx_set_pdata(bcm47xx_leds_luxul_abr_4400_v1); | ||
716 | break; | ||
717 | case BCM47XX_BOARD_LUXUL_XAP_310_V1: | ||
718 | bcm47xx_set_pdata(bcm47xx_leds_luxul_xap_310_v1); | ||
719 | break; | ||
720 | case BCM47XX_BOARD_LUXUL_XAP_1210_V1: | ||
721 | bcm47xx_set_pdata(bcm47xx_leds_luxul_xap_1210_v1); | ||
722 | break; | ||
723 | case BCM47XX_BOARD_LUXUL_XAP_1230_V1: | ||
724 | bcm47xx_set_pdata(bcm47xx_leds_luxul_xap_1230_v1); | ||
725 | break; | ||
726 | case BCM47XX_BOARD_LUXUL_XAP_1240_V1: | ||
727 | bcm47xx_set_pdata(bcm47xx_leds_luxul_xap_1240_v1); | ||
728 | break; | ||
729 | case BCM47XX_BOARD_LUXUL_XAP_1500_V1: | ||
730 | bcm47xx_set_pdata(bcm47xx_leds_luxul_xap_1500_v1); | ||
731 | bcm47xx_set_pdata_extra(bcm47xx_leds_luxul_xap1500_v1_extra); | ||
732 | break; | ||
733 | case BCM47XX_BOARD_LUXUL_XBR_4400_V1: | ||
734 | bcm47xx_set_pdata(bcm47xx_leds_luxul_xbr_4400_v1); | ||
735 | break; | ||
736 | case BCM47XX_BOARD_LUXUL_XVW_P30_V1: | ||
737 | bcm47xx_set_pdata(bcm47xx_leds_luxul_xvw_p30_v1); | ||
738 | break; | ||
739 | case BCM47XX_BOARD_LUXUL_XWR_600_V1: | ||
740 | bcm47xx_set_pdata(bcm47xx_leds_luxul_xwr_600_v1); | ||
741 | break; | ||
742 | case BCM47XX_BOARD_LUXUL_XWR_1750_V1: | ||
743 | bcm47xx_set_pdata(bcm47xx_leds_luxul_xwr_1750_v1); | ||
744 | bcm47xx_set_pdata_extra(bcm47xx_leds_luxul_xwr1750_v1_extra); | ||
745 | break; | ||
746 | |||
747 | case BCM47XX_BOARD_MICROSOFT_MN700: | ||
748 | bcm47xx_set_pdata(bcm47xx_leds_microsoft_nm700); | ||
749 | break; | ||
750 | |||
751 | case BCM47XX_BOARD_MOTOROLA_WE800G: | ||
752 | bcm47xx_set_pdata(bcm47xx_leds_motorola_we800g); | ||
753 | break; | ||
754 | case BCM47XX_BOARD_MOTOROLA_WR850GP: | ||
755 | bcm47xx_set_pdata(bcm47xx_leds_motorola_wr850gp); | ||
756 | break; | ||
757 | case BCM47XX_BOARD_MOTOROLA_WR850GV2V3: | ||
758 | bcm47xx_set_pdata(bcm47xx_leds_motorola_wr850gv2v3); | ||
759 | break; | ||
760 | |||
761 | case BCM47XX_BOARD_NETGEAR_WNDR3400V1: | ||
762 | bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr3400v1); | ||
763 | break; | ||
764 | case BCM47XX_BOARD_NETGEAR_WNDR4500V1: | ||
765 | bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr4500v1); | ||
766 | break; | ||
767 | case BCM47XX_BOARD_NETGEAR_WNR1000_V3: | ||
768 | bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr1000_v3); | ||
769 | break; | ||
770 | case BCM47XX_BOARD_NETGEAR_WNR3500L: | ||
771 | bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr3500lv1); | ||
772 | break; | ||
773 | case BCM47XX_BOARD_NETGEAR_WNR834BV2: | ||
774 | bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr834bv2); | ||
775 | break; | ||
776 | |||
777 | case BCM47XX_BOARD_SIEMENS_SE505V2: | ||
778 | bcm47xx_set_pdata(bcm47xx_leds_siemens_se505v2); | ||
779 | break; | ||
780 | |||
781 | case BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE: | ||
782 | bcm47xx_set_pdata(bcm47xx_leds_simpletech_simpleshare); | ||
783 | break; | ||
784 | |||
785 | default: | ||
786 | pr_debug("No LEDs configuration found for this device\n"); | ||
787 | return; | ||
788 | } | ||
789 | |||
790 | gpio_led_register_device(-1, &bcm47xx_leds_pdata); | ||
791 | if (bcm47xx_leds_pdata_extra.num_leds) | ||
792 | gpio_led_register_device(0, &bcm47xx_leds_pdata_extra); | ||
793 | } | ||
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c new file mode 100644 index 000000000..22509b5fa --- /dev/null +++ b/arch/mips/bcm47xx/prom.c | |||
@@ -0,0 +1,182 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> | ||
3 | * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net> | ||
4 | * Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> | ||
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 as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
12 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
13 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
14 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
15 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
16 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
17 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
18 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
19 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
20 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License along | ||
23 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
24 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | */ | ||
26 | |||
27 | #include <linux/init.h> | ||
28 | #include <linux/types.h> | ||
29 | #include <linux/kernel.h> | ||
30 | #include <linux/memblock.h> | ||
31 | #include <linux/spinlock.h> | ||
32 | #include <linux/ssb/ssb_driver_chipcommon.h> | ||
33 | #include <linux/ssb/ssb_regs.h> | ||
34 | #include <linux/smp.h> | ||
35 | #include <asm/bootinfo.h> | ||
36 | #include <bcm47xx.h> | ||
37 | #include <bcm47xx_board.h> | ||
38 | |||
39 | static char bcm47xx_system_type[20] = "Broadcom BCM47XX"; | ||
40 | |||
41 | const char *get_system_type(void) | ||
42 | { | ||
43 | return bcm47xx_system_type; | ||
44 | } | ||
45 | |||
46 | __init void bcm47xx_set_system_type(u16 chip_id) | ||
47 | { | ||
48 | snprintf(bcm47xx_system_type, sizeof(bcm47xx_system_type), | ||
49 | (chip_id > 0x9999) ? "Broadcom BCM%d" : | ||
50 | "Broadcom BCM%04X", | ||
51 | chip_id); | ||
52 | } | ||
53 | |||
54 | static unsigned long lowmem __initdata; | ||
55 | |||
56 | static __init void prom_init_mem(void) | ||
57 | { | ||
58 | unsigned long mem; | ||
59 | unsigned long max; | ||
60 | unsigned long off; | ||
61 | struct cpuinfo_mips *c = ¤t_cpu_data; | ||
62 | |||
63 | /* Figure out memory size by finding aliases. | ||
64 | * | ||
65 | * We should theoretically use the mapping from CFE using cfe_enummem(). | ||
66 | * However as the BCM47XX is mostly used on low-memory systems, we | ||
67 | * want to reuse the memory used by CFE (around 4MB). That means cfe_* | ||
68 | * functions stop to work at some point during the boot, we should only | ||
69 | * call them at the beginning of the boot. | ||
70 | * | ||
71 | * BCM47XX uses 128MB for addressing the ram, if the system contains | ||
72 | * less that that amount of ram it remaps the ram more often into the | ||
73 | * available space. | ||
74 | */ | ||
75 | |||
76 | /* Physical address, without mapping to any kernel segment */ | ||
77 | off = CPHYSADDR((unsigned long)prom_init); | ||
78 | |||
79 | /* Accessing memory after 128 MiB will cause an exception */ | ||
80 | max = 128 << 20; | ||
81 | |||
82 | for (mem = 1 << 20; mem < max; mem += 1 << 20) { | ||
83 | /* Loop condition may be not enough, off may be over 1 MiB */ | ||
84 | if (off + mem >= max) { | ||
85 | mem = max; | ||
86 | pr_debug("Assume 128MB RAM\n"); | ||
87 | break; | ||
88 | } | ||
89 | if (!memcmp((void *)prom_init, (void *)prom_init + mem, 32)) | ||
90 | break; | ||
91 | } | ||
92 | lowmem = mem; | ||
93 | |||
94 | /* Ignoring the last page when ddr size is 128M. Cached | ||
95 | * accesses to last page is causing the processor to prefetch | ||
96 | * using address above 128M stepping out of the ddr address | ||
97 | * space. | ||
98 | */ | ||
99 | if (c->cputype == CPU_74K && (mem == (128 << 20))) | ||
100 | mem -= 0x1000; | ||
101 | memblock_add(0, mem); | ||
102 | } | ||
103 | |||
104 | /* | ||
105 | * This is the first serial on the chip common core, it is at this position | ||
106 | * for sb (ssb) and ai (bcma) bus. | ||
107 | */ | ||
108 | #define BCM47XX_SERIAL_ADDR (SSB_ENUM_BASE + SSB_CHIPCO_UART0_DATA) | ||
109 | |||
110 | void __init prom_init(void) | ||
111 | { | ||
112 | prom_init_mem(); | ||
113 | setup_8250_early_printk_port(CKSEG1ADDR(BCM47XX_SERIAL_ADDR), 0, 0); | ||
114 | } | ||
115 | |||
116 | void __init prom_free_prom_memory(void) | ||
117 | { | ||
118 | } | ||
119 | |||
120 | #if defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) | ||
121 | |||
122 | #define EXTVBASE 0xc0000000 | ||
123 | #define ENTRYLO(x) ((pte_val(pfn_pte((x) >> _PFN_SHIFT, PAGE_KERNEL_UNCACHED)) >> 6) | 1) | ||
124 | |||
125 | #include <asm/tlbflush.h> | ||
126 | |||
127 | /* Stripped version of tlb_init, with the call to build_tlb_refill_handler | ||
128 | * dropped. Calling it at this stage causes a hang. | ||
129 | */ | ||
130 | void early_tlb_init(void) | ||
131 | { | ||
132 | write_c0_pagemask(PM_DEFAULT_MASK); | ||
133 | write_c0_wired(0); | ||
134 | temp_tlb_entry = current_cpu_data.tlbsize - 1; | ||
135 | local_flush_tlb_all(); | ||
136 | } | ||
137 | |||
138 | void __init bcm47xx_prom_highmem_init(void) | ||
139 | { | ||
140 | unsigned long off = (unsigned long)prom_init; | ||
141 | unsigned long extmem = 0; | ||
142 | bool highmem_region = false; | ||
143 | |||
144 | if (WARN_ON(bcm47xx_bus_type != BCM47XX_BUS_TYPE_BCMA)) | ||
145 | return; | ||
146 | |||
147 | if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706) | ||
148 | highmem_region = true; | ||
149 | |||
150 | if (lowmem != 128 << 20 || !highmem_region) | ||
151 | return; | ||
152 | |||
153 | early_tlb_init(); | ||
154 | |||
155 | /* Add one temporary TLB entry to map SDRAM Region 2. | ||
156 | * Physical Virtual | ||
157 | * 0x80000000 0xc0000000 (1st: 256MB) | ||
158 | * 0x90000000 0xd0000000 (2nd: 256MB) | ||
159 | */ | ||
160 | add_temporary_entry(ENTRYLO(0x80000000), | ||
161 | ENTRYLO(0x80000000 + (256 << 20)), | ||
162 | EXTVBASE, PM_256M); | ||
163 | |||
164 | off = EXTVBASE + __pa(off); | ||
165 | for (extmem = 128 << 20; extmem < 512 << 20; extmem <<= 1) { | ||
166 | if (!memcmp((void *)prom_init, (void *)(off + extmem), 16)) | ||
167 | break; | ||
168 | } | ||
169 | extmem -= lowmem; | ||
170 | |||
171 | early_tlb_init(); | ||
172 | |||
173 | if (!extmem) | ||
174 | return; | ||
175 | |||
176 | pr_warn("Found %lu MiB of extra memory, but highmem is unsupported yet!\n", | ||
177 | extmem >> 20); | ||
178 | |||
179 | /* TODO: Register extra memory */ | ||
180 | } | ||
181 | |||
182 | #endif /* defined(CONFIG_BCM47XX_BCMA) && defined(CONFIG_HIGHMEM) */ | ||
diff --git a/arch/mips/bcm47xx/serial.c b/arch/mips/bcm47xx/serial.c new file mode 100644 index 000000000..e3c9872a4 --- /dev/null +++ b/arch/mips/bcm47xx/serial.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * 8250 UART probe driver for the BCM47XX platforms | ||
3 | * Author: Aurelien Jarno | ||
4 | * | ||
5 | * This file is subject to the terms and conditions of the GNU General Public | ||
6 | * License. See the file "COPYING" in the main directory of this archive | ||
7 | * for more details. | ||
8 | * | ||
9 | * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net> | ||
10 | */ | ||
11 | |||
12 | #include <linux/init.h> | ||
13 | #include <linux/serial.h> | ||
14 | #include <linux/serial_8250.h> | ||
15 | #include <linux/ssb/ssb.h> | ||
16 | #include <bcm47xx.h> | ||
17 | |||
18 | static struct plat_serial8250_port uart8250_data[5]; | ||
19 | |||
20 | static struct platform_device uart8250_device = { | ||
21 | .name = "serial8250", | ||
22 | .id = PLAT8250_DEV_PLATFORM, | ||
23 | .dev = { | ||
24 | .platform_data = uart8250_data, | ||
25 | }, | ||
26 | }; | ||
27 | |||
28 | #ifdef CONFIG_BCM47XX_SSB | ||
29 | static int __init uart8250_init_ssb(void) | ||
30 | { | ||
31 | int i; | ||
32 | struct ssb_mipscore *mcore = &(bcm47xx_bus.ssb.mipscore); | ||
33 | |||
34 | memset(&uart8250_data, 0, sizeof(uart8250_data)); | ||
35 | |||
36 | for (i = 0; i < mcore->nr_serial_ports && | ||
37 | i < ARRAY_SIZE(uart8250_data) - 1; i++) { | ||
38 | struct plat_serial8250_port *p = &(uart8250_data[i]); | ||
39 | struct ssb_serial_port *ssb_port = &(mcore->serial_ports[i]); | ||
40 | |||
41 | p->mapbase = (unsigned int)ssb_port->regs; | ||
42 | p->membase = (void *)ssb_port->regs; | ||
43 | p->irq = ssb_port->irq + 2; | ||
44 | p->uartclk = ssb_port->baud_base; | ||
45 | p->regshift = ssb_port->reg_shift; | ||
46 | p->iotype = UPIO_MEM; | ||
47 | p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; | ||
48 | } | ||
49 | return platform_device_register(&uart8250_device); | ||
50 | } | ||
51 | #endif | ||
52 | |||
53 | #ifdef CONFIG_BCM47XX_BCMA | ||
54 | static int __init uart8250_init_bcma(void) | ||
55 | { | ||
56 | int i; | ||
57 | struct bcma_drv_cc *cc = &(bcm47xx_bus.bcma.bus.drv_cc); | ||
58 | |||
59 | memset(&uart8250_data, 0, sizeof(uart8250_data)); | ||
60 | |||
61 | for (i = 0; i < cc->nr_serial_ports && | ||
62 | i < ARRAY_SIZE(uart8250_data) - 1; i++) { | ||
63 | struct plat_serial8250_port *p = &(uart8250_data[i]); | ||
64 | struct bcma_serial_port *bcma_port; | ||
65 | bcma_port = &(cc->serial_ports[i]); | ||
66 | |||
67 | p->mapbase = (unsigned int)bcma_port->regs; | ||
68 | p->membase = (void *)bcma_port->regs; | ||
69 | p->irq = bcma_port->irq; | ||
70 | p->uartclk = bcma_port->baud_base; | ||
71 | p->regshift = bcma_port->reg_shift; | ||
72 | p->iotype = UPIO_MEM; | ||
73 | p->flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; | ||
74 | } | ||
75 | return platform_device_register(&uart8250_device); | ||
76 | } | ||
77 | #endif | ||
78 | |||
79 | static int __init uart8250_init(void) | ||
80 | { | ||
81 | switch (bcm47xx_bus_type) { | ||
82 | #ifdef CONFIG_BCM47XX_SSB | ||
83 | case BCM47XX_BUS_TYPE_SSB: | ||
84 | return uart8250_init_ssb(); | ||
85 | #endif | ||
86 | #ifdef CONFIG_BCM47XX_BCMA | ||
87 | case BCM47XX_BUS_TYPE_BCMA: | ||
88 | return uart8250_init_bcma(); | ||
89 | #endif | ||
90 | } | ||
91 | return -EINVAL; | ||
92 | } | ||
93 | device_initcall(uart8250_init); | ||
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c new file mode 100644 index 000000000..94bf83957 --- /dev/null +++ b/arch/mips/bcm47xx/setup.c | |||
@@ -0,0 +1,280 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> | ||
3 | * Copyright (C) 2006 Felix Fietkau <nbd@openwrt.org> | ||
4 | * Copyright (C) 2006 Michael Buesch <m@bues.ch> | ||
5 | * Copyright (C) 2010 Waldemar Brodkorb <wbx@openadk.org> | ||
6 | * Copyright (C) 2010-2012 Hauke Mehrtens <hauke@hauke-m.de> | ||
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 as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
14 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
16 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
17 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
18 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
19 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
21 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
22 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
23 | * | ||
24 | * You should have received a copy of the GNU General Public License along | ||
25 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
26 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
27 | */ | ||
28 | |||
29 | #include "bcm47xx_private.h" | ||
30 | |||
31 | #include <linux/bcm47xx_sprom.h> | ||
32 | #include <linux/export.h> | ||
33 | #include <linux/types.h> | ||
34 | #include <linux/ethtool.h> | ||
35 | #include <linux/phy.h> | ||
36 | #include <linux/phy_fixed.h> | ||
37 | #include <linux/ssb/ssb.h> | ||
38 | #include <linux/ssb/ssb_embedded.h> | ||
39 | #include <linux/bcma/bcma_soc.h> | ||
40 | #include <asm/bootinfo.h> | ||
41 | #include <asm/idle.h> | ||
42 | #include <asm/prom.h> | ||
43 | #include <asm/reboot.h> | ||
44 | #include <asm/time.h> | ||
45 | #include <bcm47xx.h> | ||
46 | #include <bcm47xx_board.h> | ||
47 | |||
48 | union bcm47xx_bus bcm47xx_bus; | ||
49 | EXPORT_SYMBOL(bcm47xx_bus); | ||
50 | |||
51 | enum bcm47xx_bus_type bcm47xx_bus_type; | ||
52 | EXPORT_SYMBOL(bcm47xx_bus_type); | ||
53 | |||
54 | static void bcm47xx_machine_restart(char *command) | ||
55 | { | ||
56 | pr_alert("Please stand by while rebooting the system...\n"); | ||
57 | local_irq_disable(); | ||
58 | /* Set the watchdog timer to reset immediately */ | ||
59 | switch (bcm47xx_bus_type) { | ||
60 | #ifdef CONFIG_BCM47XX_SSB | ||
61 | case BCM47XX_BUS_TYPE_SSB: | ||
62 | if (bcm47xx_bus.ssb.chip_id == 0x4785) | ||
63 | write_c0_diag4(1 << 22); | ||
64 | ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 1); | ||
65 | if (bcm47xx_bus.ssb.chip_id == 0x4785) { | ||
66 | __asm__ __volatile__( | ||
67 | ".set\tmips3\n\t" | ||
68 | "sync\n\t" | ||
69 | "wait\n\t" | ||
70 | ".set\tmips0"); | ||
71 | } | ||
72 | break; | ||
73 | #endif | ||
74 | #ifdef CONFIG_BCM47XX_BCMA | ||
75 | case BCM47XX_BUS_TYPE_BCMA: | ||
76 | bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 1); | ||
77 | break; | ||
78 | #endif | ||
79 | } | ||
80 | while (1) | ||
81 | cpu_relax(); | ||
82 | } | ||
83 | |||
84 | static void bcm47xx_machine_halt(void) | ||
85 | { | ||
86 | /* Disable interrupts and watchdog and spin forever */ | ||
87 | local_irq_disable(); | ||
88 | switch (bcm47xx_bus_type) { | ||
89 | #ifdef CONFIG_BCM47XX_SSB | ||
90 | case BCM47XX_BUS_TYPE_SSB: | ||
91 | ssb_watchdog_timer_set(&bcm47xx_bus.ssb, 0); | ||
92 | break; | ||
93 | #endif | ||
94 | #ifdef CONFIG_BCM47XX_BCMA | ||
95 | case BCM47XX_BUS_TYPE_BCMA: | ||
96 | bcma_chipco_watchdog_timer_set(&bcm47xx_bus.bcma.bus.drv_cc, 0); | ||
97 | break; | ||
98 | #endif | ||
99 | } | ||
100 | while (1) | ||
101 | cpu_relax(); | ||
102 | } | ||
103 | |||
104 | #ifdef CONFIG_BCM47XX_SSB | ||
105 | static void __init bcm47xx_register_ssb(void) | ||
106 | { | ||
107 | int err; | ||
108 | char buf[100]; | ||
109 | struct ssb_mipscore *mcore; | ||
110 | |||
111 | err = ssb_bus_host_soc_register(&bcm47xx_bus.ssb, SSB_ENUM_BASE); | ||
112 | if (err) | ||
113 | panic("Failed to initialize SSB bus (err %d)", err); | ||
114 | |||
115 | mcore = &bcm47xx_bus.ssb.mipscore; | ||
116 | if (bcm47xx_nvram_getenv("kernel_args", buf, sizeof(buf)) >= 0) { | ||
117 | if (strstr(buf, "console=ttyS1")) { | ||
118 | struct ssb_serial_port port; | ||
119 | |||
120 | pr_debug("Swapping serial ports!\n"); | ||
121 | /* swap serial ports */ | ||
122 | memcpy(&port, &mcore->serial_ports[0], sizeof(port)); | ||
123 | memcpy(&mcore->serial_ports[0], &mcore->serial_ports[1], | ||
124 | sizeof(port)); | ||
125 | memcpy(&mcore->serial_ports[1], &port, sizeof(port)); | ||
126 | } | ||
127 | } | ||
128 | } | ||
129 | #endif | ||
130 | |||
131 | #ifdef CONFIG_BCM47XX_BCMA | ||
132 | static void __init bcm47xx_register_bcma(void) | ||
133 | { | ||
134 | int err; | ||
135 | |||
136 | err = bcma_host_soc_register(&bcm47xx_bus.bcma); | ||
137 | if (err) | ||
138 | panic("Failed to register BCMA bus (err %d)", err); | ||
139 | } | ||
140 | #endif | ||
141 | |||
142 | /* | ||
143 | * Memory setup is done in the early part of MIPS's arch_mem_init. It's supposed | ||
144 | * to detect memory and record it with memblock_add. | ||
145 | * Any extra initializaion performed here must not use kmalloc or bootmem. | ||
146 | */ | ||
147 | void __init plat_mem_setup(void) | ||
148 | { | ||
149 | struct cpuinfo_mips *c = ¤t_cpu_data; | ||
150 | |||
151 | if (c->cputype == CPU_74K) { | ||
152 | pr_info("Using bcma bus\n"); | ||
153 | #ifdef CONFIG_BCM47XX_BCMA | ||
154 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; | ||
155 | bcm47xx_register_bcma(); | ||
156 | bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id); | ||
157 | #ifdef CONFIG_HIGHMEM | ||
158 | bcm47xx_prom_highmem_init(); | ||
159 | #endif | ||
160 | #endif | ||
161 | } else { | ||
162 | pr_info("Using ssb bus\n"); | ||
163 | #ifdef CONFIG_BCM47XX_SSB | ||
164 | bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB; | ||
165 | bcm47xx_sprom_register_fallbacks(); | ||
166 | bcm47xx_register_ssb(); | ||
167 | bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id); | ||
168 | #endif | ||
169 | } | ||
170 | |||
171 | _machine_restart = bcm47xx_machine_restart; | ||
172 | _machine_halt = bcm47xx_machine_halt; | ||
173 | pm_power_off = bcm47xx_machine_halt; | ||
174 | } | ||
175 | |||
176 | #ifdef CONFIG_BCM47XX_BCMA | ||
177 | static struct device * __init bcm47xx_setup_device(void) | ||
178 | { | ||
179 | struct device *dev; | ||
180 | int err; | ||
181 | |||
182 | dev = kzalloc(sizeof(*dev), GFP_KERNEL); | ||
183 | if (!dev) | ||
184 | return NULL; | ||
185 | |||
186 | err = dev_set_name(dev, "bcm47xx_soc"); | ||
187 | if (err) { | ||
188 | pr_err("Failed to set SoC device name: %d\n", err); | ||
189 | kfree(dev); | ||
190 | return NULL; | ||
191 | } | ||
192 | |||
193 | err = dma_coerce_mask_and_coherent(dev, DMA_BIT_MASK(32)); | ||
194 | if (err) | ||
195 | pr_err("Failed to set SoC DMA mask: %d\n", err); | ||
196 | |||
197 | return dev; | ||
198 | } | ||
199 | #endif | ||
200 | |||
201 | /* | ||
202 | * This finishes bus initialization doing things that were not possible without | ||
203 | * kmalloc. Make sure to call it late enough (after mm_init). | ||
204 | */ | ||
205 | void __init bcm47xx_bus_setup(void) | ||
206 | { | ||
207 | #ifdef CONFIG_BCM47XX_BCMA | ||
208 | if (bcm47xx_bus_type == BCM47XX_BUS_TYPE_BCMA) { | ||
209 | int err; | ||
210 | |||
211 | bcm47xx_bus.bcma.dev = bcm47xx_setup_device(); | ||
212 | if (!bcm47xx_bus.bcma.dev) | ||
213 | panic("Failed to setup SoC device\n"); | ||
214 | |||
215 | err = bcma_host_soc_init(&bcm47xx_bus.bcma); | ||
216 | if (err) | ||
217 | panic("Failed to initialize BCMA bus (err %d)", err); | ||
218 | } | ||
219 | #endif | ||
220 | |||
221 | /* With bus initialized we can access NVRAM and detect the board */ | ||
222 | bcm47xx_board_detect(); | ||
223 | mips_set_machine_name(bcm47xx_board_get_name()); | ||
224 | } | ||
225 | |||
226 | static int __init bcm47xx_cpu_fixes(void) | ||
227 | { | ||
228 | switch (bcm47xx_bus_type) { | ||
229 | #ifdef CONFIG_BCM47XX_SSB | ||
230 | case BCM47XX_BUS_TYPE_SSB: | ||
231 | /* Nothing to do */ | ||
232 | break; | ||
233 | #endif | ||
234 | #ifdef CONFIG_BCM47XX_BCMA | ||
235 | case BCM47XX_BUS_TYPE_BCMA: | ||
236 | /* The BCM4706 has a problem with the CPU wait instruction. | ||
237 | * When r4k_wait or r4k_wait_irqoff is used will just hang and | ||
238 | * not return from a msleep(). Removing the cpu_wait | ||
239 | * functionality is a workaround for this problem. The BCM4716 | ||
240 | * does not have this problem. | ||
241 | */ | ||
242 | if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706) | ||
243 | cpu_wait = NULL; | ||
244 | break; | ||
245 | #endif | ||
246 | } | ||
247 | return 0; | ||
248 | } | ||
249 | arch_initcall(bcm47xx_cpu_fixes); | ||
250 | |||
251 | static struct fixed_phy_status bcm47xx_fixed_phy_status __initdata = { | ||
252 | .link = 1, | ||
253 | .speed = SPEED_100, | ||
254 | .duplex = DUPLEX_FULL, | ||
255 | }; | ||
256 | |||
257 | static int __init bcm47xx_register_bus_complete(void) | ||
258 | { | ||
259 | switch (bcm47xx_bus_type) { | ||
260 | #ifdef CONFIG_BCM47XX_SSB | ||
261 | case BCM47XX_BUS_TYPE_SSB: | ||
262 | /* Nothing to do */ | ||
263 | break; | ||
264 | #endif | ||
265 | #ifdef CONFIG_BCM47XX_BCMA | ||
266 | case BCM47XX_BUS_TYPE_BCMA: | ||
267 | if (device_register(bcm47xx_bus.bcma.dev)) | ||
268 | pr_err("Failed to register SoC device\n"); | ||
269 | bcma_bus_register(&bcm47xx_bus.bcma.bus); | ||
270 | break; | ||
271 | #endif | ||
272 | } | ||
273 | bcm47xx_buttons_register(); | ||
274 | bcm47xx_leds_register(); | ||
275 | bcm47xx_workarounds(); | ||
276 | |||
277 | fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status); | ||
278 | return 0; | ||
279 | } | ||
280 | device_initcall(bcm47xx_register_bus_complete); | ||
diff --git a/arch/mips/bcm47xx/time.c b/arch/mips/bcm47xx/time.c new file mode 100644 index 000000000..74224cf2e --- /dev/null +++ b/arch/mips/bcm47xx/time.c | |||
@@ -0,0 +1,81 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2004 Florian Schirmer <jolt@tuxbox.org> | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | * | ||
9 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
10 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
12 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
13 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
14 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
15 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
16 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
17 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
18 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
19 | * | ||
20 | * You should have received a copy of the GNU General Public License along | ||
21 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
22 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
23 | */ | ||
24 | |||
25 | #include <linux/init.h> | ||
26 | #include <linux/ssb/ssb.h> | ||
27 | #include <asm/time.h> | ||
28 | #include <bcm47xx.h> | ||
29 | #include <bcm47xx_board.h> | ||
30 | |||
31 | void __init plat_time_init(void) | ||
32 | { | ||
33 | unsigned long hz = 0; | ||
34 | u16 chip_id = 0; | ||
35 | char buf[10]; | ||
36 | int len; | ||
37 | enum bcm47xx_board board = bcm47xx_board_get(); | ||
38 | |||
39 | /* | ||
40 | * Use deterministic values for initial counter interrupt | ||
41 | * so that calibrate delay avoids encountering a counter wrap. | ||
42 | */ | ||
43 | write_c0_count(0); | ||
44 | write_c0_compare(0xffff); | ||
45 | |||
46 | switch (bcm47xx_bus_type) { | ||
47 | #ifdef CONFIG_BCM47XX_SSB | ||
48 | case BCM47XX_BUS_TYPE_SSB: | ||
49 | hz = ssb_cpu_clock(&bcm47xx_bus.ssb.mipscore) / 2; | ||
50 | chip_id = bcm47xx_bus.ssb.chip_id; | ||
51 | break; | ||
52 | #endif | ||
53 | #ifdef CONFIG_BCM47XX_BCMA | ||
54 | case BCM47XX_BUS_TYPE_BCMA: | ||
55 | hz = bcma_cpu_clock(&bcm47xx_bus.bcma.bus.drv_mips) / 2; | ||
56 | chip_id = bcm47xx_bus.bcma.bus.chipinfo.id; | ||
57 | break; | ||
58 | #endif | ||
59 | } | ||
60 | |||
61 | if (chip_id == 0x5354) { | ||
62 | len = bcm47xx_nvram_getenv("clkfreq", buf, sizeof(buf)); | ||
63 | if (len >= 0 && !strncmp(buf, "200", 4)) | ||
64 | hz = 100000000; | ||
65 | } | ||
66 | |||
67 | switch (board) { | ||
68 | case BCM47XX_BOARD_ASUS_WL520GC: | ||
69 | case BCM47XX_BOARD_ASUS_WL520GU: | ||
70 | hz = 100000000; | ||
71 | break; | ||
72 | default: | ||
73 | break; | ||
74 | } | ||
75 | |||
76 | if (!hz) | ||
77 | hz = 100000000; | ||
78 | |||
79 | /* Set MIPS counter frequency for fixed_rate_gettimeoffset() */ | ||
80 | mips_hpt_frequency = hz; | ||
81 | } | ||
diff --git a/arch/mips/bcm47xx/workarounds.c b/arch/mips/bcm47xx/workarounds.c new file mode 100644 index 000000000..0ab95dd43 --- /dev/null +++ b/arch/mips/bcm47xx/workarounds.c | |||
@@ -0,0 +1,35 @@ | |||
1 | // SPDX-License-Identifier: GPL-2.0 | ||
2 | #include "bcm47xx_private.h" | ||
3 | |||
4 | #include <linux/gpio.h> | ||
5 | #include <bcm47xx_board.h> | ||
6 | #include <bcm47xx.h> | ||
7 | |||
8 | static void __init bcm47xx_workarounds_enable_usb_power(int usb_power) | ||
9 | { | ||
10 | int err; | ||
11 | |||
12 | err = gpio_request_one(usb_power, GPIOF_OUT_INIT_HIGH, "usb_power"); | ||
13 | if (err) | ||
14 | pr_err("Failed to request USB power gpio: %d\n", err); | ||
15 | else | ||
16 | gpio_free(usb_power); | ||
17 | } | ||
18 | |||
19 | void __init bcm47xx_workarounds(void) | ||
20 | { | ||
21 | enum bcm47xx_board board = bcm47xx_board_get(); | ||
22 | |||
23 | switch (board) { | ||
24 | case BCM47XX_BOARD_NETGEAR_WNR3500L: | ||
25 | bcm47xx_workarounds_enable_usb_power(12); | ||
26 | break; | ||
27 | case BCM47XX_BOARD_NETGEAR_WNDR3400V2: | ||
28 | case BCM47XX_BOARD_NETGEAR_WNDR3400_V3: | ||
29 | bcm47xx_workarounds_enable_usb_power(21); | ||
30 | break; | ||
31 | default: | ||
32 | /* No workaround(s) needed */ | ||
33 | break; | ||
34 | } | ||
35 | } | ||