aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/bcm47xx
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
committerWe-unite <3205135446@qq.com>2025-03-08 22:04:20 +0800
commita07bb8fd1299070229f0e8f3dcb57ffd5ef9870a (patch)
tree84f21bd0bf7071bc5fc7dd989e77d7ceb5476682 /arch/mips/bcm47xx
downloadohosKernel-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/Kconfig39
-rw-r--r--arch/mips/bcm47xx/Makefile8
-rw-r--r--arch/mips/bcm47xx/Platform7
-rw-r--r--arch/mips/bcm47xx/bcm47xx_private.h26
-rw-r--r--arch/mips/bcm47xx/board.c362
-rw-r--r--arch/mips/bcm47xx/buttons.c718
-rw-r--r--arch/mips/bcm47xx/irq.c98
-rw-r--r--arch/mips/bcm47xx/leds.c793
-rw-r--r--arch/mips/bcm47xx/prom.c182
-rw-r--r--arch/mips/bcm47xx/serial.c93
-rw-r--r--arch/mips/bcm47xx/setup.c280
-rw-r--r--arch/mips/bcm47xx/time.c81
-rw-r--r--arch/mips/bcm47xx/workarounds.c35
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
2if BCM47XX
3
4config 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
22config 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
39endif
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
7obj-y += irq.o prom.o serial.o setup.o time.o
8obj-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#
4cflags-$(CONFIG_BCM47XX) += \
5 -I$(srctree)/arch/mips/include/asm/mach-bcm47xx
6load-$(CONFIG_BCM47XX) := 0xffffffff80001000
7zload-$(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 */
12void __init bcm47xx_prom_highmem_init(void);
13
14/* buttons.c */
15int __init bcm47xx_buttons_register(void);
16
17/* leds.c */
18void __init bcm47xx_leds_register(void);
19
20/* setup.c */
21void __init bcm47xx_bus_setup(void);
22
23/* workarounds.c */
24void __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
8struct bcm47xx_board_type {
9 const enum bcm47xx_board board;
10 const char *name;
11};
12
13struct bcm47xx_board_type_list1 {
14 struct bcm47xx_board_type board;
15 const char *value1;
16};
17
18struct bcm47xx_board_type_list2 {
19 struct bcm47xx_board_type board;
20 const char *value1;
21 const char *value2;
22};
23
24struct bcm47xx_board_type_list3 {
25 struct bcm47xx_board_type board;
26 const char *value1;
27 const char *value2;
28 const char *value3;
29};
30
31struct bcm47xx_board_store {
32 enum bcm47xx_board board;
33 char name[BCM47XX_BOARD_MAX_NAME];
34};
35
36/* model_name */
37static const
38struct 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 */
45static const
46struct 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 */
72static const
73struct 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 */
80static const
81struct 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 */
95static const
96struct 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 */
105static const
106struct 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 */
120static const
121struct 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 */
151static const
152struct 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 */
188static const
189struct 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 */
201static const
202struct 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 */
212static const
213struct 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
221static const
222struct bcm47xx_board_type bcm47xx_board_unknown[] __initconst = {
223 {BCM47XX_BOARD_UNKNOWN, "Unknown Board"},
224};
225
226static struct bcm47xx_board_store bcm47xx_board = {BCM47XX_BOARD_NO, "Unknown Board"};
227
228static __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
330void __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
352enum bcm47xx_board bcm47xx_board_get(void)
353{
354 return bcm47xx_board.board;
355}
356EXPORT_SYMBOL(bcm47xx_board_get);
357
358const char *bcm47xx_board_get_name(void)
359{
360 return bcm47xx_board.name;
361}
362EXPORT_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
29static const struct gpio_keys_button
30bcm47xx_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
38static const struct gpio_keys_button
39bcm47xx_buttons_asus_rtn16[] __initconst = {
40 BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
41 BCM47XX_GPIO_KEY(8, KEY_RESTART),
42};
43
44static const struct gpio_keys_button
45bcm47xx_buttons_asus_rtn66u[] __initconst = {
46 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
47 BCM47XX_GPIO_KEY(9, KEY_RESTART),
48};
49
50static const struct gpio_keys_button
51bcm47xx_buttons_asus_wl300g[] __initconst = {
52 BCM47XX_GPIO_KEY(6, KEY_RESTART),
53};
54
55static const struct gpio_keys_button
56bcm47xx_buttons_asus_wl320ge[] __initconst = {
57 BCM47XX_GPIO_KEY(6, KEY_RESTART),
58};
59
60static const struct gpio_keys_button
61bcm47xx_buttons_asus_wl330ge[] __initconst = {
62 BCM47XX_GPIO_KEY(2, KEY_RESTART),
63};
64
65static const struct gpio_keys_button
66bcm47xx_buttons_asus_wl500g[] __initconst = {
67 BCM47XX_GPIO_KEY(6, KEY_RESTART),
68};
69
70static const struct gpio_keys_button
71bcm47xx_buttons_asus_wl500gd[] __initconst = {
72 BCM47XX_GPIO_KEY(6, KEY_RESTART),
73};
74
75static const struct gpio_keys_button
76bcm47xx_buttons_asus_wl500gpv1[] __initconst = {
77 BCM47XX_GPIO_KEY(0, KEY_RESTART),
78 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
79};
80
81static const struct gpio_keys_button
82bcm47xx_buttons_asus_wl500gpv2[] __initconst = {
83 BCM47XX_GPIO_KEY(2, KEY_RESTART),
84 BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
85};
86
87static const struct gpio_keys_button
88bcm47xx_buttons_asus_wl500w[] __initconst = {
89 BCM47XX_GPIO_KEY_H(6, KEY_RESTART),
90 BCM47XX_GPIO_KEY_H(7, KEY_WPS_BUTTON),
91};
92
93static const struct gpio_keys_button
94bcm47xx_buttons_asus_wl520gc[] __initconst = {
95 BCM47XX_GPIO_KEY(2, KEY_RESTART),
96 BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
97};
98
99static const struct gpio_keys_button
100bcm47xx_buttons_asus_wl520gu[] __initconst = {
101 BCM47XX_GPIO_KEY(2, KEY_RESTART),
102 BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
103};
104
105static const struct gpio_keys_button
106bcm47xx_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
113static const struct gpio_keys_button
114bcm47xx_buttons_asus_wlhdd[] __initconst = {
115 BCM47XX_GPIO_KEY(6, KEY_RESTART),
116};
117
118/* Huawei */
119
120static const struct gpio_keys_button
121bcm47xx_buttons_huawei_e970[] __initconst = {
122 BCM47XX_GPIO_KEY(6, KEY_RESTART),
123};
124
125/* Belkin */
126
127static const struct gpio_keys_button
128bcm47xx_buttons_belkin_f7d4301[] __initconst = {
129 BCM47XX_GPIO_KEY(6, KEY_RESTART),
130 BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
131};
132
133/* Buffalo */
134
135static const struct gpio_keys_button
136bcm47xx_buttons_buffalo_whr2_a54g54[] __initconst = {
137 BCM47XX_GPIO_KEY(4, KEY_RESTART),
138};
139
140static const struct gpio_keys_button
141bcm47xx_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
147static const struct gpio_keys_button
148bcm47xx_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
154static const struct gpio_keys_button
155bcm47xx_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
161static const struct gpio_keys_button
162bcm47xx_buttons_buffalo_wzr_g300n[] __initconst = {
163 BCM47XX_GPIO_KEY(4, KEY_RESTART),
164};
165
166static const struct gpio_keys_button
167bcm47xx_buttons_buffalo_wzr_rs_g54[] __initconst = {
168 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
169 BCM47XX_GPIO_KEY(4, KEY_RESTART),
170};
171
172static const struct gpio_keys_button
173bcm47xx_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
180static const struct gpio_keys_button
181bcm47xx_buttons_dell_tm2300[] __initconst = {
182 BCM47XX_GPIO_KEY(0, KEY_RESTART),
183};
184
185/* D-Link */
186
187static const struct gpio_keys_button
188bcm47xx_buttons_dlink_dir130[] __initconst = {
189 BCM47XX_GPIO_KEY(3, KEY_RESTART),
190 BCM47XX_GPIO_KEY(7, KEY_UNKNOWN),
191};
192
193static const struct gpio_keys_button
194bcm47xx_buttons_dlink_dir330[] __initconst = {
195 BCM47XX_GPIO_KEY(3, KEY_RESTART),
196 BCM47XX_GPIO_KEY(7, KEY_UNKNOWN),
197};
198
199/* Linksys */
200
201static const struct gpio_keys_button
202bcm47xx_buttons_linksys_e1000v1[] __initconst = {
203 BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
204 BCM47XX_GPIO_KEY(6, KEY_RESTART),
205};
206
207static const struct gpio_keys_button
208bcm47xx_buttons_linksys_e1000v21[] __initconst = {
209 BCM47XX_GPIO_KEY(9, KEY_WPS_BUTTON),
210 BCM47XX_GPIO_KEY(10, KEY_RESTART),
211};
212
213static const struct gpio_keys_button
214bcm47xx_buttons_linksys_e2000v1[] __initconst = {
215 BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
216 BCM47XX_GPIO_KEY(8, KEY_RESTART),
217};
218
219static const struct gpio_keys_button
220bcm47xx_buttons_linksys_e3000v1[] __initconst = {
221 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
222 BCM47XX_GPIO_KEY(6, KEY_RESTART),
223};
224
225static const struct gpio_keys_button
226bcm47xx_buttons_linksys_e3200v1[] __initconst = {
227 BCM47XX_GPIO_KEY(5, KEY_RESTART),
228 BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
229};
230
231static const struct gpio_keys_button
232bcm47xx_buttons_linksys_e4200v1[] __initconst = {
233 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
234 BCM47XX_GPIO_KEY(6, KEY_RESTART),
235};
236
237static const struct gpio_keys_button
238bcm47xx_buttons_linksys_wrt150nv1[] __initconst = {
239 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
240 BCM47XX_GPIO_KEY(6, KEY_RESTART),
241};
242
243static const struct gpio_keys_button
244bcm47xx_buttons_linksys_wrt150nv11[] __initconst = {
245 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
246 BCM47XX_GPIO_KEY(6, KEY_RESTART),
247};
248
249static const struct gpio_keys_button
250bcm47xx_buttons_linksys_wrt160nv1[] __initconst = {
251 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
252 BCM47XX_GPIO_KEY(6, KEY_RESTART),
253};
254
255static const struct gpio_keys_button
256bcm47xx_buttons_linksys_wrt160nv3[] __initconst = {
257 BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
258 BCM47XX_GPIO_KEY(6, KEY_RESTART),
259};
260
261static const struct gpio_keys_button
262bcm47xx_buttons_linksys_wrt300n_v1[] __initconst = {
263 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
264 BCM47XX_GPIO_KEY(6, KEY_RESTART),
265};
266
267static const struct gpio_keys_button
268bcm47xx_buttons_linksys_wrt300nv11[] __initconst = {
269 BCM47XX_GPIO_KEY(4, KEY_UNKNOWN),
270 BCM47XX_GPIO_KEY(6, KEY_RESTART),
271};
272
273static const struct gpio_keys_button
274bcm47xx_buttons_linksys_wrt310nv1[] __initconst = {
275 BCM47XX_GPIO_KEY(6, KEY_RESTART),
276 BCM47XX_GPIO_KEY(8, KEY_UNKNOWN),
277};
278
279static const struct gpio_keys_button
280bcm47xx_buttons_linksys_wrt54g3gv2[] __initconst = {
281 BCM47XX_GPIO_KEY(5, KEY_WIMAX),
282 BCM47XX_GPIO_KEY(6, KEY_RESTART),
283};
284
285static const struct gpio_keys_button
286bcm47xx_buttons_linksys_wrt54g_generic[] __initconst = {
287 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
288 BCM47XX_GPIO_KEY(6, KEY_RESTART),
289};
290
291static const struct gpio_keys_button
292bcm47xx_buttons_linksys_wrt610nv1[] __initconst = {
293 BCM47XX_GPIO_KEY(6, KEY_RESTART),
294 BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
295};
296
297static const struct gpio_keys_button
298bcm47xx_buttons_linksys_wrt610nv2[] __initconst = {
299 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
300 BCM47XX_GPIO_KEY(6, KEY_RESTART),
301};
302
303static const struct gpio_keys_button
304bcm47xx_buttons_linksys_wrtsl54gs[] __initconst = {
305 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
306 BCM47XX_GPIO_KEY(6, KEY_RESTART),
307};
308
309/* Luxul */
310
311static const struct gpio_keys_button
312bcm47xx_buttons_luxul_abr_4400_v1[] = {
313 BCM47XX_GPIO_KEY(14, KEY_RESTART),
314};
315
316static const struct gpio_keys_button
317bcm47xx_buttons_luxul_xap_310_v1[] = {
318 BCM47XX_GPIO_KEY(20, KEY_RESTART),
319};
320
321static const struct gpio_keys_button
322bcm47xx_buttons_luxul_xap_1210_v1[] = {
323 BCM47XX_GPIO_KEY(8, KEY_RESTART),
324};
325
326static const struct gpio_keys_button
327bcm47xx_buttons_luxul_xap_1230_v1[] = {
328 BCM47XX_GPIO_KEY(8, KEY_RESTART),
329};
330
331static const struct gpio_keys_button
332bcm47xx_buttons_luxul_xap_1240_v1[] = {
333 BCM47XX_GPIO_KEY(8, KEY_RESTART),
334};
335
336static const struct gpio_keys_button
337bcm47xx_buttons_luxul_xap_1500_v1[] = {
338 BCM47XX_GPIO_KEY(14, KEY_RESTART),
339};
340
341static const struct gpio_keys_button
342bcm47xx_buttons_luxul_xbr_4400_v1[] = {
343 BCM47XX_GPIO_KEY(14, KEY_RESTART),
344};
345
346static const struct gpio_keys_button
347bcm47xx_buttons_luxul_xvw_p30_v1[] = {
348 BCM47XX_GPIO_KEY(20, KEY_RESTART),
349};
350
351static const struct gpio_keys_button
352bcm47xx_buttons_luxul_xwr_600_v1[] = {
353 BCM47XX_GPIO_KEY(8, KEY_RESTART),
354};
355
356static const struct gpio_keys_button
357bcm47xx_buttons_luxul_xwr_1750_v1[] = {
358 BCM47XX_GPIO_KEY(14, KEY_RESTART),
359};
360
361/* Microsoft */
362
363static const struct gpio_keys_button
364bcm47xx_buttons_microsoft_nm700[] __initconst = {
365 BCM47XX_GPIO_KEY(7, KEY_RESTART),
366};
367
368/* Motorola */
369
370static const struct gpio_keys_button
371bcm47xx_buttons_motorola_we800g[] __initconst = {
372 BCM47XX_GPIO_KEY(0, KEY_RESTART),
373};
374
375static const struct gpio_keys_button
376bcm47xx_buttons_motorola_wr850gp[] __initconst = {
377 BCM47XX_GPIO_KEY(5, KEY_RESTART),
378};
379
380static const struct gpio_keys_button
381bcm47xx_buttons_motorola_wr850gv2v3[] __initconst = {
382 BCM47XX_GPIO_KEY(5, KEY_RESTART),
383};
384
385/* Netgear */
386
387static const struct gpio_keys_button
388bcm47xx_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
394static const struct gpio_keys_button
395bcm47xx_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
401static const struct gpio_keys_button
402bcm47xx_buttons_netgear_wndr3400_v3[] __initconst = {
403 BCM47XX_GPIO_KEY(12, KEY_RESTART),
404 BCM47XX_GPIO_KEY(23, KEY_WPS_BUTTON),
405};
406
407static const struct gpio_keys_button
408bcm47xx_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
414static const struct gpio_keys_button
415bcm47xx_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
421static const struct gpio_keys_button
422bcm47xx_buttons_netgear_wnr1000_v3[] __initconst = {
423 BCM47XX_GPIO_KEY(2, KEY_WPS_BUTTON),
424 BCM47XX_GPIO_KEY(3, KEY_RESTART),
425};
426
427static const struct gpio_keys_button
428bcm47xx_buttons_netgear_wnr3500lv1[] __initconst = {
429 BCM47XX_GPIO_KEY(4, KEY_RESTART),
430 BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
431};
432
433static const struct gpio_keys_button
434bcm47xx_buttons_netgear_wnr834bv2[] __initconst = {
435 BCM47XX_GPIO_KEY(6, KEY_RESTART),
436};
437
438/* SimpleTech */
439
440static const struct gpio_keys_button
441bcm47xx_buttons_simpletech_simpleshare[] __initconst = {
442 BCM47XX_GPIO_KEY(0, KEY_RESTART),
443};
444
445/**************************************************
446 * Init
447 **************************************************/
448
449static struct gpio_keys_platform_data bcm47xx_button_pdata;
450
451static 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 */
459static 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
475int __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
34asmlinkage 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 }
61DEFINE_HWx_IRQDISPATCH(2)
62DEFINE_HWx_IRQDISPATCH(3)
63DEFINE_HWx_IRQDISPATCH(4)
64DEFINE_HWx_IRQDISPATCH(5)
65DEFINE_HWx_IRQDISPATCH(6)
66DEFINE_HWx_IRQDISPATCH(7)
67
68void __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
32static const struct gpio_led
33bcm47xx_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
38static const struct gpio_led
39bcm47xx_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
47static const struct gpio_led
48bcm47xx_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
53static const struct gpio_led
54bcm47xx_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
59static const struct gpio_led
60bcm47xx_leds_asus_wl300g[] __initconst = {
61 BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
62};
63
64static const struct gpio_led
65bcm47xx_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
71static const struct gpio_led
72bcm47xx_leds_asus_wl330ge[] __initconst = {
73 BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
74};
75
76static const struct gpio_led
77bcm47xx_leds_asus_wl500g[] __initconst = {
78 BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
79};
80
81static const struct gpio_led
82bcm47xx_leds_asus_wl500gd[] __initconst = {
83 BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
84};
85
86static const struct gpio_led
87bcm47xx_leds_asus_wl500gpv1[] __initconst = {
88 BCM47XX_GPIO_LED(1, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
89};
90
91static const struct gpio_led
92bcm47xx_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
97static const struct gpio_led
98bcm47xx_leds_asus_wl500w[] __initconst = {
99 BCM47XX_GPIO_LED(5, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
100};
101
102static const struct gpio_led
103bcm47xx_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
108static const struct gpio_led
109bcm47xx_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
114static const struct gpio_led
115bcm47xx_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
119static const struct gpio_led
120bcm47xx_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
127static const struct gpio_led
128bcm47xx_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
139static const struct gpio_led
140bcm47xx_leds_buffalo_whr2_a54g54[] __initconst = {
141 BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
142};
143
144static const struct gpio_led
145bcm47xx_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
153static const struct gpio_led
154bcm47xx_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
162static const struct gpio_led
163bcm47xx_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
171static const struct gpio_led
172bcm47xx_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
178static const struct gpio_led
179bcm47xx_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
185static const struct gpio_led
186bcm47xx_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
194static const struct gpio_led
195bcm47xx_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
202static const struct gpio_led
203bcm47xx_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
208static const struct gpio_led
209bcm47xx_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
217static const struct gpio_led
218bcm47xx_leds_huawei_e970[] __initconst = {
219 BCM47XX_GPIO_LED(0, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
220};
221
222/* Linksys */
223
224static const struct gpio_led
225bcm47xx_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
232static const struct gpio_led
233bcm47xx_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
240static const struct gpio_led
241bcm47xx_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
248static const struct gpio_led
249bcm47xx_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
257static const struct gpio_led
258bcm47xx_leds_linksys_e3200v1[] __initconst = {
259 BCM47XX_GPIO_LED(3, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
260};
261
262static const struct gpio_led
263bcm47xx_leds_linksys_e4200v1[] __initconst = {
264 BCM47XX_GPIO_LED(5, "white", "power", 1, LEDS_GPIO_DEFSTATE_ON),
265};
266
267static const struct gpio_led
268bcm47xx_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
274static const struct gpio_led
275bcm47xx_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
281static const struct gpio_led
282bcm47xx_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
288static const struct gpio_led
289bcm47xx_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
295static const struct gpio_led
296bcm47xx_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
302static const struct gpio_led
303bcm47xx_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
309static const struct gpio_led
310bcm47xx_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
316static const struct gpio_led
317bcm47xx_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
324static const struct gpio_led
325bcm47xx_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 */
332static const struct gpio_led
333bcm47xx_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 */
340static const struct gpio_led
341bcm47xx_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
349static const struct gpio_led
350bcm47xx_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
357static const struct gpio_led
358bcm47xx_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
366static const struct gpio_led
367bcm47xx_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
376static const struct gpio_led
377bcm47xx_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
382static const struct gpio_led
383bcm47xx_leds_luxul_xap_310_v1[] __initconst = {
384 BCM47XX_GPIO_LED_TRIGGER(6, "green", "status", 1, "timer"),
385};
386
387static const struct gpio_led
388bcm47xx_leds_luxul_xap_1210_v1[] __initconst = {
389 BCM47XX_GPIO_LED_TRIGGER(6, "green", "status", 1, "timer"),
390};
391
392static const struct gpio_led
393bcm47xx_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
399static const struct gpio_led
400bcm47xx_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
406static const struct gpio_led
407bcm47xx_leds_luxul_xap_1500_v1[] __initconst = {
408 BCM47XX_GPIO_LED_TRIGGER(13, "green", "status", 1, "timer"),
409};
410
411static const struct gpio_led
412bcm47xx_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
417static const struct gpio_led
418bcm47xx_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
423static const struct gpio_led
424bcm47xx_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
429static const struct gpio_led
430bcm47xx_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
436static const struct gpio_led
437bcm47xx_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
444static const struct gpio_led
445bcm47xx_leds_luxul_xwr1750_v1_extra[] __initconst = {
446 BCM47XX_GPIO_LED(76, "green", "2ghz", 0, LEDS_GPIO_DEFSTATE_OFF),
447};
448
449/* Microsoft */
450
451static const struct gpio_led
452bcm47xx_leds_microsoft_nm700[] __initconst = {
453 BCM47XX_GPIO_LED(6, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
454};
455
456/* Motorola */
457
458static const struct gpio_led
459bcm47xx_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
465static const struct gpio_led
466bcm47xx_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
473static const struct gpio_led
474bcm47xx_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
482static const struct gpio_led
483bcm47xx_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
489static const struct gpio_led
490bcm47xx_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
500static const struct gpio_led
501bcm47xx_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
506static const struct gpio_led
507bcm47xx_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
515static const struct gpio_led
516bcm47xx_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 */
523static const struct gpio_led
524bcm47xx_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
532static const struct gpio_led
533bcm47xx_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
541static 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
548static 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
554void __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
39static char bcm47xx_system_type[20] = "Broadcom BCM47XX";
40
41const 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
54static unsigned long lowmem __initdata;
55
56static __init void prom_init_mem(void)
57{
58 unsigned long mem;
59 unsigned long max;
60 unsigned long off;
61 struct cpuinfo_mips *c = &current_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
110void __init prom_init(void)
111{
112 prom_init_mem();
113 setup_8250_early_printk_port(CKSEG1ADDR(BCM47XX_SERIAL_ADDR), 0, 0);
114}
115
116void __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 */
130void 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
138void __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
18static struct plat_serial8250_port uart8250_data[5];
19
20static 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
29static 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
54static 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
79static 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}
93device_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
48union bcm47xx_bus bcm47xx_bus;
49EXPORT_SYMBOL(bcm47xx_bus);
50
51enum bcm47xx_bus_type bcm47xx_bus_type;
52EXPORT_SYMBOL(bcm47xx_bus_type);
53
54static 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
84static 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
105static 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
132static 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 */
147void __init plat_mem_setup(void)
148{
149 struct cpuinfo_mips *c = &current_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
177static 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 */
205void __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
226static 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}
249arch_initcall(bcm47xx_cpu_fixes);
250
251static struct fixed_phy_status bcm47xx_fixed_phy_status __initdata = {
252 .link = 1,
253 .speed = SPEED_100,
254 .duplex = DUPLEX_FULL,
255};
256
257static 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}
280device_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
31void __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
8static 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
19void __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}