aboutsummaryrefslogtreecommitdiffstats
path: root/arch/mips/bcm47xx
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-01-30 20:20:32 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-01-30 20:20:32 -0500
commitcdfc83075fb76369a31e6c187d0cebcab9f8b9c8 (patch)
tree33d1cdca3e2cb610451ed30943189f55652bac4c /arch/mips/bcm47xx
parent04a24ae45d018e177db7e4ae2d03a70f79149782 (diff)
parentb26a21c1eacdb7daf22a304fa857413df2650cfe (diff)
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle: "The most notable new addition inside this pull request is the support for MIPS's latest and greatest core called "inter/proAptiv". The patch series describes this core as follows. "The interAptiv is a power-efficient multi-core microprocessor for use in system-on-chip (SoC) applications. The interAptiv combines a multi-threading pipeline with a coherence manager to deliver improved computational throughput and power efficiency. The interAptiv can contain one to four MIPS32R3 interAptiv cores, system level coherence manager with L2 cache, optional coherent I/O port, and optional floating point unit." The platform specific patches touch all 3 Broadcom families. It adds support for the new Broadcom/Netlogix XLP9xx Soc, building a common BCM63XX SMP kernel for all BCM63XX SoCs regardless of core type/count and full gpio button/led descriptions for BCM47xx. The rest of the series are cleanups and bug fixes that are MIPS generic and consist largely of changes that Imgtec/MIPS had published in their linux-mti-3.10.git stable tree. Random other cleanups and patches preparing code to be merged in 3.15" * 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (139 commits) mips: select ARCH_MIGHT_HAVE_PC_SERIO mips: delete non-required instances of include <linux/init.h> MIPS: KVM: remove shadow_tlb code MIPS: KVM: use common EHINV aware UNIQUE_ENTRYHI mips/ide: flush dcache also if icache does not snoop dcache MIPS: BCM47XX: fix position of cpu_wait disabling MIPS: BCM63XX: select correct MIPS_L1_CACHE_SHIFT value MIPS: update MIPS_L1_CACHE_SHIFT based on MIPS_L1_CACHE_SHIFT_<N> MIPS: introduce MIPS_L1_CACHE_SHIFT_<N> MIPS: ZBOOT: gather string functions into string.c arch/mips/pci: don't check resource with devm_ioremap_resource arch/mips/lantiq/xway: don't check resource with devm_ioremap_resource bcma: gpio: don't cast u32 to unsigned long ssb: gpio: add own IRQ domain MIPS: BCM47XX: fix sparse warnings in board.c MIPS: BCM47XX: add board detection for Linksys WRT54GS V1 MIPS: BCM47XX: fix detection for some boards MIPS: BCM47XX: Enable buttons support on SSB MIPS: BCM47XX: Convert WNDR4500 to new syntax MIPS: BCM47XX: Use "timer" trigger for status LEDs ...
Diffstat (limited to 'arch/mips/bcm47xx')
-rw-r--r--arch/mips/bcm47xx/Kconfig4
-rw-r--r--arch/mips/bcm47xx/Makefile3
-rw-r--r--arch/mips/bcm47xx/bcm47xx_private.h12
-rw-r--r--arch/mips/bcm47xx/board.c34
-rw-r--r--arch/mips/bcm47xx/buttons.c531
-rw-r--r--arch/mips/bcm47xx/irq.c25
-rw-r--r--arch/mips/bcm47xx/leds.c542
-rw-r--r--arch/mips/bcm47xx/nvram.c3
-rw-r--r--arch/mips/bcm47xx/prom.c127
-rw-r--r--arch/mips/bcm47xx/serial.c6
-rw-r--r--arch/mips/bcm47xx/setup.c35
-rw-r--r--arch/mips/bcm47xx/sprom.c18
-rw-r--r--arch/mips/bcm47xx/wgt634u.c174
13 files changed, 1197 insertions, 317 deletions
diff --git a/arch/mips/bcm47xx/Kconfig b/arch/mips/bcm47xx/Kconfig
index 2b8b118398c4..09cb6f7aa3db 100644
--- a/arch/mips/bcm47xx/Kconfig
+++ b/arch/mips/bcm47xx/Kconfig
@@ -2,6 +2,7 @@ if BCM47XX
2 2
3config BCM47XX_SSB 3config BCM47XX_SSB
4 bool "SSB Support for Broadcom BCM47XX" 4 bool "SSB Support for Broadcom BCM47XX"
5 select SYS_HAS_CPU_BMIPS32_3300
5 select SSB 6 select SSB
6 select SSB_DRIVER_MIPS 7 select SSB_DRIVER_MIPS
7 select SSB_DRIVER_EXTIF 8 select SSB_DRIVER_EXTIF
@@ -11,6 +12,7 @@ config BCM47XX_SSB
11 select SSB_PCICORE_HOSTMODE if PCI 12 select SSB_PCICORE_HOSTMODE if PCI
12 select SSB_DRIVER_GPIO 13 select SSB_DRIVER_GPIO
13 select GPIOLIB 14 select GPIOLIB
15 select LEDS_GPIO_REGISTER
14 default y 16 default y
15 help 17 help
16 Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support. 18 Add support for old Broadcom BCM47xx boards with Sonics Silicon Backplane support.
@@ -20,6 +22,7 @@ config BCM47XX_SSB
20config BCM47XX_BCMA 22config BCM47XX_BCMA
21 bool "BCMA Support for Broadcom BCM47XX" 23 bool "BCMA Support for Broadcom BCM47XX"
22 select SYS_HAS_CPU_MIPS32_R2 24 select SYS_HAS_CPU_MIPS32_R2
25 select CPU_MIPSR2_IRQ_VI
23 select BCMA 26 select BCMA
24 select BCMA_HOST_SOC 27 select BCMA_HOST_SOC
25 select BCMA_DRIVER_MIPS 28 select BCMA_DRIVER_MIPS
@@ -27,6 +30,7 @@ config BCM47XX_BCMA
27 select BCMA_DRIVER_PCI_HOSTMODE if PCI 30 select BCMA_DRIVER_PCI_HOSTMODE if PCI
28 select BCMA_DRIVER_GPIO 31 select BCMA_DRIVER_GPIO
29 select GPIOLIB 32 select GPIOLIB
33 select LEDS_GPIO_REGISTER
30 default y 34 default y
31 help 35 help
32 Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus. 36 Add support for new Broadcom BCM47xx boards with Broadcom specific Advanced Microcontroller Bus.
diff --git a/arch/mips/bcm47xx/Makefile b/arch/mips/bcm47xx/Makefile
index c52daf9b05c6..4688b6a6211b 100644
--- a/arch/mips/bcm47xx/Makefile
+++ b/arch/mips/bcm47xx/Makefile
@@ -4,5 +4,4 @@
4# 4#
5 5
6obj-y += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o 6obj-y += irq.o nvram.o prom.o serial.o setup.o time.o sprom.o
7obj-y += board.o 7obj-y += board.o buttons.o leds.o
8obj-$(CONFIG_BCM47XX_SSB) += wgt634u.o
diff --git a/arch/mips/bcm47xx/bcm47xx_private.h b/arch/mips/bcm47xx/bcm47xx_private.h
new file mode 100644
index 000000000000..5c94acebf76a
--- /dev/null
+++ b/arch/mips/bcm47xx/bcm47xx_private.h
@@ -0,0 +1,12 @@
1#ifndef LINUX_BCM47XX_PRIVATE_H_
2#define LINUX_BCM47XX_PRIVATE_H_
3
4#include <linux/kernel.h>
5
6/* buttons.c */
7int __init bcm47xx_buttons_register(void);
8
9/* leds.c */
10void __init bcm47xx_leds_register(void);
11
12#endif
diff --git a/arch/mips/bcm47xx/board.c b/arch/mips/bcm47xx/board.c
index f3f6bfe68a2a..6d612e2b949b 100644
--- a/arch/mips/bcm47xx/board.c
+++ b/arch/mips/bcm47xx/board.c
@@ -36,26 +36,32 @@ static const
36struct bcm47xx_board_type_list1 bcm47xx_board_list_model_name[] __initconst = { 36struct bcm47xx_board_type_list1 bcm47xx_board_list_model_name[] __initconst = {
37 {{BCM47XX_BOARD_DLINK_DIR130, "D-Link DIR-130"}, "DIR-130"}, 37 {{BCM47XX_BOARD_DLINK_DIR130, "D-Link DIR-130"}, "DIR-130"},
38 {{BCM47XX_BOARD_DLINK_DIR330, "D-Link DIR-330"}, "DIR-330"}, 38 {{BCM47XX_BOARD_DLINK_DIR330, "D-Link DIR-330"}, "DIR-330"},
39 { {0}, 0}, 39 { {0}, NULL},
40}; 40};
41 41
42/* model_no */ 42/* model_no */
43static const 43static const
44struct bcm47xx_board_type_list1 bcm47xx_board_list_model_no[] __initconst = { 44struct bcm47xx_board_type_list1 bcm47xx_board_list_model_no[] __initconst = {
45 {{BCM47XX_BOARD_ASUS_WL700GE, "Asus WL700"}, "WL700"}, 45 {{BCM47XX_BOARD_ASUS_WL700GE, "Asus WL700"}, "WL700"},
46 { {0}, 0}, 46 { {0}, NULL},
47}; 47};
48 48
49/* machine_name */ 49/* machine_name */
50static const 50static const
51struct bcm47xx_board_type_list1 bcm47xx_board_list_machine_name[] __initconst = { 51struct bcm47xx_board_type_list1 bcm47xx_board_list_machine_name[] __initconst = {
52 {{BCM47XX_BOARD_LINKSYS_WRTSL54GS, "Linksys WRTSL54GS"}, "WRTSL54GS"}, 52 {{BCM47XX_BOARD_LINKSYS_WRTSL54GS, "Linksys WRTSL54GS"}, "WRTSL54GS"},
53 { {0}, 0}, 53 { {0}, NULL},
54}; 54};
55 55
56/* hardware_version */ 56/* hardware_version */
57static const 57static const
58struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initconst = { 58struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initconst = {
59 {{BCM47XX_BOARD_ASUS_RTN10U, "Asus RT-N10U"}, "RTN10U"},
60 {{BCM47XX_BOARD_ASUS_RTN12, "Asus RT-N12"}, "RT-N12"},
61 {{BCM47XX_BOARD_ASUS_RTN12B1, "Asus RT-N12B1"}, "RTN12B1"},
62 {{BCM47XX_BOARD_ASUS_RTN12C1, "Asus RT-N12C1"}, "RTN12C1"},
63 {{BCM47XX_BOARD_ASUS_RTN12D1, "Asus RT-N12D1"}, "RTN12D1"},
64 {{BCM47XX_BOARD_ASUS_RTN12HP, "Asus RT-N12HP"}, "RTN12HP"},
59 {{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16-"}, 65 {{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16-"},
60 {{BCM47XX_BOARD_ASUS_WL320GE, "Asus WL320GE"}, "WL320G-"}, 66 {{BCM47XX_BOARD_ASUS_WL320GE, "Asus WL320GE"}, "WL320G-"},
61 {{BCM47XX_BOARD_ASUS_WL330GE, "Asus WL330GE"}, "WL330GE-"}, 67 {{BCM47XX_BOARD_ASUS_WL330GE, "Asus WL330GE"}, "WL330GE-"},
@@ -66,7 +72,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_hardware_version[] __initcons
66 {{BCM47XX_BOARD_ASUS_WL520GC, "Asus WL520GC"}, "WL520GC-"}, 72 {{BCM47XX_BOARD_ASUS_WL520GC, "Asus WL520GC"}, "WL520GC-"},
67 {{BCM47XX_BOARD_ASUS_WL520GU, "Asus WL520GU"}, "WL520GU-"}, 73 {{BCM47XX_BOARD_ASUS_WL520GU, "Asus WL520GU"}, "WL520GU-"},
68 {{BCM47XX_BOARD_BELKIN_F7D4301, "Belkin F7D4301"}, "F7D4301"}, 74 {{BCM47XX_BOARD_BELKIN_F7D4301, "Belkin F7D4301"}, "F7D4301"},
69 { {0}, 0}, 75 { {0}, NULL},
70}; 76};
71 77
72/* productid */ 78/* productid */
@@ -75,19 +81,13 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_productid[] __initconst = {
75 {{BCM47XX_BOARD_ASUS_RTAC66U, "Asus RT-AC66U"}, "RT-AC66U"}, 81 {{BCM47XX_BOARD_ASUS_RTAC66U, "Asus RT-AC66U"}, "RT-AC66U"},
76 {{BCM47XX_BOARD_ASUS_RTN10, "Asus RT-N10"}, "RT-N10"}, 82 {{BCM47XX_BOARD_ASUS_RTN10, "Asus RT-N10"}, "RT-N10"},
77 {{BCM47XX_BOARD_ASUS_RTN10D, "Asus RT-N10D"}, "RT-N10D"}, 83 {{BCM47XX_BOARD_ASUS_RTN10D, "Asus RT-N10D"}, "RT-N10D"},
78 {{BCM47XX_BOARD_ASUS_RTN10U, "Asus RT-N10U"}, "RT-N10U"},
79 {{BCM47XX_BOARD_ASUS_RTN12, "Asus RT-N12"}, "RT-N12"},
80 {{BCM47XX_BOARD_ASUS_RTN12B1, "Asus RT-N12B1"}, "RT-N12B1"},
81 {{BCM47XX_BOARD_ASUS_RTN12C1, "Asus RT-N12C1"}, "RT-N12C1"},
82 {{BCM47XX_BOARD_ASUS_RTN12D1, "Asus RT-N12D1"}, "RT-N12D1"},
83 {{BCM47XX_BOARD_ASUS_RTN12HP, "Asus RT-N12HP"}, "RT-N12HP"},
84 {{BCM47XX_BOARD_ASUS_RTN15U, "Asus RT-N15U"}, "RT-N15U"}, 84 {{BCM47XX_BOARD_ASUS_RTN15U, "Asus RT-N15U"}, "RT-N15U"},
85 {{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16"}, 85 {{BCM47XX_BOARD_ASUS_RTN16, "Asus RT-N16"}, "RT-N16"},
86 {{BCM47XX_BOARD_ASUS_RTN53, "Asus RT-N53"}, "RT-N53"}, 86 {{BCM47XX_BOARD_ASUS_RTN53, "Asus RT-N53"}, "RT-N53"},
87 {{BCM47XX_BOARD_ASUS_RTN66U, "Asus RT-N66U"}, "RT-N66U"}, 87 {{BCM47XX_BOARD_ASUS_RTN66U, "Asus RT-N66U"}, "RT-N66U"},
88 {{BCM47XX_BOARD_ASUS_WL300G, "Asus WL300G"}, "WL300g"}, 88 {{BCM47XX_BOARD_ASUS_WL300G, "Asus WL300G"}, "WL300g"},
89 {{BCM47XX_BOARD_ASUS_WLHDD, "Asus WLHDD"}, "WLHDD"}, 89 {{BCM47XX_BOARD_ASUS_WLHDD, "Asus WLHDD"}, "WLHDD"},
90 { {0}, 0}, 90 { {0}, NULL},
91}; 91};
92 92
93/* ModelId */ 93/* ModelId */
@@ -97,7 +97,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_ModelId[] __initconst = {
97 {{BCM47XX_BOARD_MOTOROLA_WE800G, "Motorola WE800G"}, "WE800G"}, 97 {{BCM47XX_BOARD_MOTOROLA_WE800G, "Motorola WE800G"}, "WE800G"},
98 {{BCM47XX_BOARD_MOTOROLA_WR850GP, "Motorola WR850GP"}, "WR850GP"}, 98 {{BCM47XX_BOARD_MOTOROLA_WR850GP, "Motorola WR850GP"}, "WR850GP"},
99 {{BCM47XX_BOARD_MOTOROLA_WR850GV2V3, "Motorola WR850G"}, "WR850G"}, 99 {{BCM47XX_BOARD_MOTOROLA_WR850GV2V3, "Motorola WR850G"}, "WR850G"},
100 { {0}, 0}, 100 { {0}, NULL},
101}; 101};
102 102
103/* melco_id or buf1falo_id */ 103/* melco_id or buf1falo_id */
@@ -112,7 +112,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_melco_id[] __initconst = {
112 {{BCM47XX_BOARD_BUFFALO_WZR_G300N, "Buffalo WZR-G300N"}, "31120"}, 112 {{BCM47XX_BOARD_BUFFALO_WZR_G300N, "Buffalo WZR-G300N"}, "31120"},
113 {{BCM47XX_BOARD_BUFFALO_WZR_RS_G54, "Buffalo WZR-RS-G54"}, "30083"}, 113 {{BCM47XX_BOARD_BUFFALO_WZR_RS_G54, "Buffalo WZR-RS-G54"}, "30083"},
114 {{BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP, "Buffalo WZR-RS-G54HP"}, "30103"}, 114 {{BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP, "Buffalo WZR-RS-G54HP"}, "30103"},
115 { {0}, 0}, 115 { {0}, NULL},
116}; 116};
117 117
118/* boot_hw_model, boot_hw_ver */ 118/* boot_hw_model, boot_hw_ver */
@@ -143,7 +143,7 @@ struct bcm47xx_board_type_list2 bcm47xx_board_list_boot_hw[] __initconst = {
143 {{BCM47XX_BOARD_LINKSYS_WRT54G3GV2, "Linksys WRT54G3GV2-VF"}, "WRT54G3GV2-VF", "1.0"}, 143 {{BCM47XX_BOARD_LINKSYS_WRT54G3GV2, "Linksys WRT54G3GV2-VF"}, "WRT54G3GV2-VF", "1.0"},
144 {{BCM47XX_BOARD_LINKSYS_WRT610NV1, "Linksys WRT610N V1"}, "WRT610N", "1.0"}, 144 {{BCM47XX_BOARD_LINKSYS_WRT610NV1, "Linksys WRT610N V1"}, "WRT610N", "1.0"},
145 {{BCM47XX_BOARD_LINKSYS_WRT610NV2, "Linksys WRT610N V2"}, "WRT610N", "2.0"}, 145 {{BCM47XX_BOARD_LINKSYS_WRT610NV2, "Linksys WRT610N V2"}, "WRT610N", "2.0"},
146 { {0}, 0}, 146 { {0}, NULL},
147}; 147};
148 148
149/* board_id */ 149/* board_id */
@@ -165,7 +165,7 @@ struct bcm47xx_board_type_list1 bcm47xx_board_list_board_id[] __initconst = {
165 {{BCM47XX_BOARD_NETGEAR_WNR3500V2, "Netgear WNR3500 V2"}, "U12H127T00_NETGEAR"}, 165 {{BCM47XX_BOARD_NETGEAR_WNR3500V2, "Netgear WNR3500 V2"}, "U12H127T00_NETGEAR"},
166 {{BCM47XX_BOARD_NETGEAR_WNR3500V2VC, "Netgear WNR3500 V2vc"}, "U12H127T70_NETGEAR"}, 166 {{BCM47XX_BOARD_NETGEAR_WNR3500V2VC, "Netgear WNR3500 V2vc"}, "U12H127T70_NETGEAR"},
167 {{BCM47XX_BOARD_NETGEAR_WNR834BV2, "Netgear WNR834B V2"}, "U12H081T00_NETGEAR"}, 167 {{BCM47XX_BOARD_NETGEAR_WNR834BV2, "Netgear WNR834B V2"}, "U12H081T00_NETGEAR"},
168 { {0}, 0}, 168 { {0}, NULL},
169}; 169};
170 170
171/* boardtype, boardnum, boardrev */ 171/* boardtype, boardnum, boardrev */
@@ -174,7 +174,9 @@ struct bcm47xx_board_type_list3 bcm47xx_board_list_board[] __initconst = {
174 {{BCM47XX_BOARD_HUAWEI_E970, "Huawei E970"}, "0x048e", "0x5347", "0x11"}, 174 {{BCM47XX_BOARD_HUAWEI_E970, "Huawei E970"}, "0x048e", "0x5347", "0x11"},
175 {{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"}, 175 {{BCM47XX_BOARD_PHICOMM_M1, "Phicomm M1"}, "0x0590", "80", "0x1104"},
176 {{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"}, 176 {{BCM47XX_BOARD_ZTE_H218N, "ZTE H218N"}, "0x053d", "1234", "0x1305"},
177 { {0}, 0}, 177 {{BCM47XX_BOARD_NETGEAR_WNR3500L, "Netgear WNR3500L"}, "0x04CF", "3500", "02"},
178 {{BCM47XX_BOARD_LINKSYS_WRT54GSV1, "Linksys WRT54GS V1"}, "0x0101", "42", "0x10"},
179 { {0}, NULL},
178}; 180};
179 181
180static const 182static const
diff --git a/arch/mips/bcm47xx/buttons.c b/arch/mips/bcm47xx/buttons.c
new file mode 100644
index 000000000000..872c62e93e0e
--- /dev/null
+++ b/arch/mips/bcm47xx/buttons.c
@@ -0,0 +1,531 @@
1#include "bcm47xx_private.h"
2
3#include <linux/input.h>
4#include <linux/gpio_keys.h>
5#include <linux/interrupt.h>
6#include <bcm47xx_board.h>
7#include <bcm47xx.h>
8
9/**************************************************
10 * Database
11 **************************************************/
12
13#define BCM47XX_GPIO_KEY(_gpio, _code) \
14 { \
15 .code = _code, \
16 .gpio = _gpio, \
17 .active_low = 1, \
18 }
19
20/* Asus */
21
22static const struct gpio_keys_button
23bcm47xx_buttons_asus_rtn12[] __initconst = {
24 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
25 BCM47XX_GPIO_KEY(1, KEY_RESTART),
26 BCM47XX_GPIO_KEY(4, BTN_0), /* Router mode */
27 BCM47XX_GPIO_KEY(5, BTN_1), /* Repeater mode */
28 BCM47XX_GPIO_KEY(6, BTN_2), /* AP mode */
29};
30
31static const struct gpio_keys_button
32bcm47xx_buttons_asus_rtn16[] __initconst = {
33 BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
34 BCM47XX_GPIO_KEY(8, KEY_RESTART),
35};
36
37static const struct gpio_keys_button
38bcm47xx_buttons_asus_rtn66u[] __initconst = {
39 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
40 BCM47XX_GPIO_KEY(9, KEY_RESTART),
41};
42
43static const struct gpio_keys_button
44bcm47xx_buttons_asus_wl300g[] __initconst = {
45 BCM47XX_GPIO_KEY(6, KEY_RESTART),
46};
47
48static const struct gpio_keys_button
49bcm47xx_buttons_asus_wl320ge[] __initconst = {
50 BCM47XX_GPIO_KEY(6, KEY_RESTART),
51};
52
53static const struct gpio_keys_button
54bcm47xx_buttons_asus_wl330ge[] __initconst = {
55 BCM47XX_GPIO_KEY(2, KEY_RESTART),
56};
57
58static const struct gpio_keys_button
59bcm47xx_buttons_asus_wl500gd[] __initconst = {
60 BCM47XX_GPIO_KEY(6, KEY_RESTART),
61};
62
63static const struct gpio_keys_button
64bcm47xx_buttons_asus_wl500gpv1[] __initconst = {
65 BCM47XX_GPIO_KEY(0, KEY_RESTART),
66 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
67};
68
69static const struct gpio_keys_button
70bcm47xx_buttons_asus_wl500gpv2[] __initconst = {
71 BCM47XX_GPIO_KEY(2, KEY_RESTART),
72 BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
73};
74
75static const struct gpio_keys_button
76bcm47xx_buttons_asus_wl500w[] __initconst = {
77 BCM47XX_GPIO_KEY(6, KEY_RESTART),
78 BCM47XX_GPIO_KEY(7, KEY_WPS_BUTTON),
79};
80
81static const struct gpio_keys_button
82bcm47xx_buttons_asus_wl520gc[] __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_wl520gu[] __initconst = {
89 BCM47XX_GPIO_KEY(2, KEY_RESTART),
90 BCM47XX_GPIO_KEY(3, KEY_WPS_BUTTON),
91};
92
93static const struct gpio_keys_button
94bcm47xx_buttons_asus_wl700ge[] __initconst = {
95 BCM47XX_GPIO_KEY(0, KEY_POWER), /* Hard disk power switch */
96 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON), /* EZSetup */
97 BCM47XX_GPIO_KEY(6, KEY_COPY), /* Copy data from USB to internal disk */
98 BCM47XX_GPIO_KEY(7, KEY_RESTART), /* Hard reset */
99};
100
101static const struct gpio_keys_button
102bcm47xx_buttons_asus_wlhdd[] __initconst = {
103 BCM47XX_GPIO_KEY(6, KEY_RESTART),
104};
105
106/* Huawei */
107
108static const struct gpio_keys_button
109bcm47xx_buttons_huawei_e970[] __initconst = {
110 BCM47XX_GPIO_KEY(6, KEY_RESTART),
111};
112
113/* Belkin */
114
115static const struct gpio_keys_button
116bcm47xx_buttons_belkin_f7d4301[] __initconst = {
117 BCM47XX_GPIO_KEY(6, KEY_RESTART),
118 BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
119};
120
121/* Buffalo */
122
123static const struct gpio_keys_button
124bcm47xx_buttons_buffalo_whr2_a54g54[] __initconst = {
125 BCM47XX_GPIO_KEY(4, KEY_RESTART),
126};
127
128static const struct gpio_keys_button
129bcm47xx_buttons_buffalo_whr_g125[] __initconst = {
130 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
131 BCM47XX_GPIO_KEY(4, KEY_RESTART),
132 BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
133};
134
135static const struct gpio_keys_button
136bcm47xx_buttons_buffalo_whr_g54s[] __initconst = {
137 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
138 BCM47XX_GPIO_KEY(4, KEY_RESTART),
139 BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
140};
141
142static const struct gpio_keys_button
143bcm47xx_buttons_buffalo_whr_hp_g54[] __initconst = {
144 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
145 BCM47XX_GPIO_KEY(4, KEY_RESTART),
146 BCM47XX_GPIO_KEY(5, BTN_0), /* Router / AP mode swtich */
147};
148
149static const struct gpio_keys_button
150bcm47xx_buttons_buffalo_wzr_g300n[] __initconst = {
151 BCM47XX_GPIO_KEY(4, KEY_RESTART),
152};
153
154static const struct gpio_keys_button
155bcm47xx_buttons_buffalo_wzr_rs_g54[] __initconst = {
156 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
157 BCM47XX_GPIO_KEY(4, KEY_RESTART),
158};
159
160static const struct gpio_keys_button
161bcm47xx_buttons_buffalo_wzr_rs_g54hp[] __initconst = {
162 BCM47XX_GPIO_KEY(0, KEY_WPS_BUTTON),
163 BCM47XX_GPIO_KEY(4, KEY_RESTART),
164};
165
166/* Dell */
167
168static const struct gpio_keys_button
169bcm47xx_buttons_dell_tm2300[] __initconst = {
170 BCM47XX_GPIO_KEY(0, KEY_RESTART),
171};
172
173/* D-Link */
174
175static const struct gpio_keys_button
176bcm47xx_buttons_dlink_dir130[] __initconst = {
177 BCM47XX_GPIO_KEY(3, KEY_RESTART),
178 BCM47XX_GPIO_KEY(7, KEY_UNKNOWN),
179};
180
181static const struct gpio_keys_button
182bcm47xx_buttons_dlink_dir330[] __initconst = {
183 BCM47XX_GPIO_KEY(3, KEY_RESTART),
184 BCM47XX_GPIO_KEY(7, KEY_UNKNOWN),
185};
186
187/* Linksys */
188
189static const struct gpio_keys_button
190bcm47xx_buttons_linksys_e1000v1[] __initconst = {
191 BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
192 BCM47XX_GPIO_KEY(6, KEY_RESTART),
193};
194
195static const struct gpio_keys_button
196bcm47xx_buttons_linksys_e1000v21[] __initconst = {
197 BCM47XX_GPIO_KEY(9, KEY_WPS_BUTTON),
198 BCM47XX_GPIO_KEY(10, KEY_RESTART),
199};
200
201static const struct gpio_keys_button
202bcm47xx_buttons_linksys_e2000v1[] __initconst = {
203 BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
204 BCM47XX_GPIO_KEY(8, KEY_RESTART),
205};
206
207static const struct gpio_keys_button
208bcm47xx_buttons_linksys_e3000v1[] __initconst = {
209 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
210 BCM47XX_GPIO_KEY(6, KEY_RESTART),
211};
212
213static const struct gpio_keys_button
214bcm47xx_buttons_linksys_e3200v1[] __initconst = {
215 BCM47XX_GPIO_KEY(5, KEY_RESTART),
216 BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
217};
218
219static const struct gpio_keys_button
220bcm47xx_buttons_linksys_e4200v1[] __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_wrt150nv1[] __initconst = {
227 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
228 BCM47XX_GPIO_KEY(6, KEY_RESTART),
229};
230
231static const struct gpio_keys_button
232bcm47xx_buttons_linksys_wrt150nv11[] __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_wrt160nv1[] __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_wrt160nv3[] __initconst = {
245 BCM47XX_GPIO_KEY(5, KEY_WPS_BUTTON),
246 BCM47XX_GPIO_KEY(6, KEY_RESTART),
247};
248
249static const struct gpio_keys_button
250bcm47xx_buttons_linksys_wrt300nv11[] __initconst = {
251 BCM47XX_GPIO_KEY(4, KEY_UNKNOWN),
252 BCM47XX_GPIO_KEY(6, KEY_RESTART),
253};
254
255static const struct gpio_keys_button
256bcm47xx_buttons_linksys_wrt310nv1[] __initconst = {
257 BCM47XX_GPIO_KEY(6, KEY_RESTART),
258 BCM47XX_GPIO_KEY(8, KEY_UNKNOWN),
259};
260
261static const struct gpio_keys_button
262bcm47xx_buttons_linksys_wrt610nv1[] __initconst = {
263 BCM47XX_GPIO_KEY(6, KEY_RESTART),
264 BCM47XX_GPIO_KEY(8, KEY_WPS_BUTTON),
265};
266
267static const struct gpio_keys_button
268bcm47xx_buttons_linksys_wrt610nv2[] __initconst = {
269 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
270 BCM47XX_GPIO_KEY(6, KEY_RESTART),
271};
272
273/* Motorola */
274
275static const struct gpio_keys_button
276bcm47xx_buttons_motorola_we800g[] __initconst = {
277 BCM47XX_GPIO_KEY(0, KEY_RESTART),
278};
279
280static const struct gpio_keys_button
281bcm47xx_buttons_motorola_wr850gp[] __initconst = {
282 BCM47XX_GPIO_KEY(5, KEY_RESTART),
283};
284
285static const struct gpio_keys_button
286bcm47xx_buttons_motorola_wr850gv2v3[] __initconst = {
287 BCM47XX_GPIO_KEY(5, KEY_RESTART),
288};
289
290/* Netgear */
291
292static const struct gpio_keys_button
293bcm47xx_buttons_netgear_wndr3400v1[] __initconst = {
294 BCM47XX_GPIO_KEY(4, KEY_RESTART),
295 BCM47XX_GPIO_KEY(6, KEY_WPS_BUTTON),
296 BCM47XX_GPIO_KEY(8, KEY_RFKILL),
297};
298
299static const struct gpio_keys_button
300bcm47xx_buttons_netgear_wndr3700v3[] __initconst = {
301 BCM47XX_GPIO_KEY(2, KEY_RFKILL),
302 BCM47XX_GPIO_KEY(3, KEY_RESTART),
303 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
304};
305
306static const struct gpio_keys_button
307bcm47xx_buttons_netgear_wndr4500v1[] __initconst = {
308 BCM47XX_GPIO_KEY(4, KEY_WPS_BUTTON),
309 BCM47XX_GPIO_KEY(5, KEY_RFKILL),
310 BCM47XX_GPIO_KEY(6, KEY_RESTART),
311};
312
313static const struct gpio_keys_button
314bcm47xx_buttons_netgear_wnr834bv2[] __initconst = {
315 BCM47XX_GPIO_KEY(6, KEY_RESTART),
316};
317
318/* SimpleTech */
319
320static const struct gpio_keys_button
321bcm47xx_buttons_simpletech_simpleshare[] __initconst = {
322 BCM47XX_GPIO_KEY(0, KEY_RESTART),
323};
324
325/**************************************************
326 * Init
327 **************************************************/
328
329static struct gpio_keys_platform_data bcm47xx_button_pdata;
330
331static struct platform_device bcm47xx_buttons_gpio_keys = {
332 .name = "gpio-keys",
333 .dev = {
334 .platform_data = &bcm47xx_button_pdata,
335 }
336};
337
338/* Copy data from __initconst */
339static int __init bcm47xx_buttons_copy(const struct gpio_keys_button *buttons,
340 size_t nbuttons)
341{
342 size_t size = nbuttons * sizeof(*buttons);
343
344 bcm47xx_button_pdata.buttons = kmalloc(size, GFP_KERNEL);
345 if (!bcm47xx_button_pdata.buttons)
346 return -ENOMEM;
347 memcpy(bcm47xx_button_pdata.buttons, buttons, size);
348 bcm47xx_button_pdata.nbuttons = nbuttons;
349
350 return 0;
351}
352
353#define bcm47xx_copy_bdata(dev_buttons) \
354 bcm47xx_buttons_copy(dev_buttons, ARRAY_SIZE(dev_buttons));
355
356int __init bcm47xx_buttons_register(void)
357{
358 enum bcm47xx_board board = bcm47xx_board_get();
359 int err;
360
361 switch (board) {
362 case BCM47XX_BOARD_ASUS_RTN12:
363 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn12);
364 break;
365 case BCM47XX_BOARD_ASUS_RTN16:
366 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn16);
367 break;
368 case BCM47XX_BOARD_ASUS_RTN66U:
369 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_rtn66u);
370 break;
371 case BCM47XX_BOARD_ASUS_WL300G:
372 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl300g);
373 break;
374 case BCM47XX_BOARD_ASUS_WL320GE:
375 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl320ge);
376 break;
377 case BCM47XX_BOARD_ASUS_WL330GE:
378 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl330ge);
379 break;
380 case BCM47XX_BOARD_ASUS_WL500GD:
381 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gd);
382 break;
383 case BCM47XX_BOARD_ASUS_WL500GPV1:
384 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gpv1);
385 break;
386 case BCM47XX_BOARD_ASUS_WL500GPV2:
387 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500gpv2);
388 break;
389 case BCM47XX_BOARD_ASUS_WL500W:
390 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl500w);
391 break;
392 case BCM47XX_BOARD_ASUS_WL520GC:
393 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl520gc);
394 break;
395 case BCM47XX_BOARD_ASUS_WL520GU:
396 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl520gu);
397 break;
398 case BCM47XX_BOARD_ASUS_WL700GE:
399 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wl700ge);
400 break;
401 case BCM47XX_BOARD_ASUS_WLHDD:
402 err = bcm47xx_copy_bdata(bcm47xx_buttons_asus_wlhdd);
403 break;
404
405 case BCM47XX_BOARD_BELKIN_F7D4301:
406 err = bcm47xx_copy_bdata(bcm47xx_buttons_belkin_f7d4301);
407 break;
408
409 case BCM47XX_BOARD_BUFFALO_WHR2_A54G54:
410 err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr2_a54g54);
411 break;
412 case BCM47XX_BOARD_BUFFALO_WHR_G125:
413 err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_g125);
414 break;
415 case BCM47XX_BOARD_BUFFALO_WHR_G54S:
416 err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_g54s);
417 break;
418 case BCM47XX_BOARD_BUFFALO_WHR_HP_G54:
419 err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_whr_hp_g54);
420 break;
421 case BCM47XX_BOARD_BUFFALO_WZR_G300N:
422 err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_g300n);
423 break;
424 case BCM47XX_BOARD_BUFFALO_WZR_RS_G54:
425 err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_rs_g54);
426 break;
427 case BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP:
428 err = bcm47xx_copy_bdata(bcm47xx_buttons_buffalo_wzr_rs_g54hp);
429 break;
430
431 case BCM47XX_BOARD_DELL_TM2300:
432 err = bcm47xx_copy_bdata(bcm47xx_buttons_dell_tm2300);
433 break;
434
435 case BCM47XX_BOARD_DLINK_DIR130:
436 err = bcm47xx_copy_bdata(bcm47xx_buttons_dlink_dir130);
437 break;
438 case BCM47XX_BOARD_DLINK_DIR330:
439 err = bcm47xx_copy_bdata(bcm47xx_buttons_dlink_dir330);
440 break;
441
442 case BCM47XX_BOARD_HUAWEI_E970:
443 err = bcm47xx_copy_bdata(bcm47xx_buttons_huawei_e970);
444 break;
445
446 case BCM47XX_BOARD_LINKSYS_E1000V1:
447 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e1000v1);
448 break;
449 case BCM47XX_BOARD_LINKSYS_E1000V21:
450 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e1000v21);
451 break;
452 case BCM47XX_BOARD_LINKSYS_E2000V1:
453 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e2000v1);
454 break;
455 case BCM47XX_BOARD_LINKSYS_E3000V1:
456 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e3000v1);
457 break;
458 case BCM47XX_BOARD_LINKSYS_E3200V1:
459 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e3200v1);
460 break;
461 case BCM47XX_BOARD_LINKSYS_E4200V1:
462 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_e4200v1);
463 break;
464 case BCM47XX_BOARD_LINKSYS_WRT150NV1:
465 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt150nv1);
466 break;
467 case BCM47XX_BOARD_LINKSYS_WRT150NV11:
468 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt150nv11);
469 break;
470 case BCM47XX_BOARD_LINKSYS_WRT160NV1:
471 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt160nv1);
472 break;
473 case BCM47XX_BOARD_LINKSYS_WRT160NV3:
474 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt160nv3);
475 break;
476 case BCM47XX_BOARD_LINKSYS_WRT300NV11:
477 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt300nv11);
478 break;
479 case BCM47XX_BOARD_LINKSYS_WRT310NV1:
480 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt310nv1);
481 break;
482 case BCM47XX_BOARD_LINKSYS_WRT610NV1:
483 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv1);
484 break;
485 case BCM47XX_BOARD_LINKSYS_WRT610NV2:
486 err = bcm47xx_copy_bdata(bcm47xx_buttons_linksys_wrt610nv2);
487 break;
488
489 case BCM47XX_BOARD_MOTOROLA_WE800G:
490 err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_we800g);
491 break;
492 case BCM47XX_BOARD_MOTOROLA_WR850GP:
493 err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_wr850gp);
494 break;
495 case BCM47XX_BOARD_MOTOROLA_WR850GV2V3:
496 err = bcm47xx_copy_bdata(bcm47xx_buttons_motorola_wr850gv2v3);
497 break;
498
499 case BCM47XX_BOARD_NETGEAR_WNDR3400V1:
500 err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3400v1);
501 break;
502 case BCM47XX_BOARD_NETGEAR_WNDR3700V3:
503 err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr3700v3);
504 break;
505 case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
506 err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wndr4500v1);
507 break;
508 case BCM47XX_BOARD_NETGEAR_WNR834BV2:
509 err = bcm47xx_copy_bdata(bcm47xx_buttons_netgear_wnr834bv2);
510 break;
511
512 case BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE:
513 err = bcm47xx_copy_bdata(bcm47xx_buttons_simpletech_simpleshare);
514 break;
515
516 default:
517 pr_debug("No buttons configuration found for this device\n");
518 return -ENOTSUPP;
519 }
520
521 if (err)
522 return -ENOMEM;
523
524 err = platform_device_register(&bcm47xx_buttons_gpio_keys);
525 if (err) {
526 pr_err("Failed to register platform device: %d\n", err);
527 return err;
528 }
529
530 return 0;
531}
diff --git a/arch/mips/bcm47xx/irq.c b/arch/mips/bcm47xx/irq.c
index 8cf3833b2d29..e0585b76ec19 100644
--- a/arch/mips/bcm47xx/irq.c
+++ b/arch/mips/bcm47xx/irq.c
@@ -25,10 +25,11 @@
25#include <linux/types.h> 25#include <linux/types.h>
26#include <linux/interrupt.h> 26#include <linux/interrupt.h>
27#include <linux/irq.h> 27#include <linux/irq.h>
28#include <asm/setup.h>
28#include <asm/irq_cpu.h> 29#include <asm/irq_cpu.h>
29#include <bcm47xx.h> 30#include <bcm47xx.h>
30 31
31void plat_irq_dispatch(void) 32asmlinkage void plat_irq_dispatch(void)
32{ 33{
33 u32 cause; 34 u32 cause;
34 35
@@ -50,6 +51,18 @@ void plat_irq_dispatch(void)
50 do_IRQ(6); 51 do_IRQ(6);
51} 52}
52 53
54#define DEFINE_HWx_IRQDISPATCH(x) \
55 static void bcm47xx_hw ## x ## _irqdispatch(void) \
56 { \
57 do_IRQ(x); \
58 }
59DEFINE_HWx_IRQDISPATCH(2)
60DEFINE_HWx_IRQDISPATCH(3)
61DEFINE_HWx_IRQDISPATCH(4)
62DEFINE_HWx_IRQDISPATCH(5)
63DEFINE_HWx_IRQDISPATCH(6)
64DEFINE_HWx_IRQDISPATCH(7)
65
53void __init arch_init_irq(void) 66void __init arch_init_irq(void)
54{ 67{
55#ifdef CONFIG_BCM47XX_BCMA 68#ifdef CONFIG_BCM47XX_BCMA
@@ -64,4 +77,14 @@ void __init arch_init_irq(void)
64 } 77 }
65#endif 78#endif
66 mips_cpu_irq_init(); 79 mips_cpu_irq_init();
80
81 if (cpu_has_vint) {
82 pr_info("Setting up vectored interrupts\n");
83 set_vi_handler(2, bcm47xx_hw2_irqdispatch);
84 set_vi_handler(3, bcm47xx_hw3_irqdispatch);
85 set_vi_handler(4, bcm47xx_hw4_irqdispatch);
86 set_vi_handler(5, bcm47xx_hw5_irqdispatch);
87 set_vi_handler(6, bcm47xx_hw6_irqdispatch);
88 set_vi_handler(7, bcm47xx_hw7_irqdispatch);
89 }
67} 90}
diff --git a/arch/mips/bcm47xx/leds.c b/arch/mips/bcm47xx/leds.c
new file mode 100644
index 000000000000..647d15527066
--- /dev/null
+++ b/arch/mips/bcm47xx/leds.c
@@ -0,0 +1,542 @@
1#include "bcm47xx_private.h"
2
3#include <linux/leds.h>
4#include <bcm47xx_board.h>
5
6/**************************************************
7 * Database
8 **************************************************/
9
10#define BCM47XX_GPIO_LED(_gpio, _color, _function, _active_low, \
11 _default_state) \
12 { \
13 .name = "bcm47xx:" _color ":" _function, \
14 .gpio = _gpio, \
15 .active_low = _active_low, \
16 .default_state = _default_state, \
17 }
18
19#define BCM47XX_GPIO_LED_TRIGGER(_gpio, _color, _function, _active_low, \
20 _default_trigger) \
21 { \
22 .name = "bcm47xx:" _color ":" _function, \
23 .gpio = _gpio, \
24 .active_low = _active_low, \
25 .default_state = LEDS_GPIO_DEFSTATE_OFF, \
26 .default_trigger = _default_trigger, \
27 }
28
29/* Asus */
30
31static const struct gpio_led
32bcm47xx_leds_asus_rtn12[] __initconst = {
33 BCM47XX_GPIO_LED(2, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
34 BCM47XX_GPIO_LED(7, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
35};
36
37static const struct gpio_led
38bcm47xx_leds_asus_rtn16[] __initconst = {
39 BCM47XX_GPIO_LED(1, "blue", "power", 1, LEDS_GPIO_DEFSTATE_ON),
40 BCM47XX_GPIO_LED(7, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
41};
42
43static const struct gpio_led
44bcm47xx_leds_asus_rtn66u[] __initconst = {
45 BCM47XX_GPIO_LED(12, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
46 BCM47XX_GPIO_LED(15, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
47};
48
49static const struct gpio_led
50bcm47xx_leds_asus_wl300g[] __initconst = {
51 BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
52};
53
54static const struct gpio_led
55bcm47xx_leds_asus_wl320ge[] __initconst = {
56 BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
57 BCM47XX_GPIO_LED(2, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
58 BCM47XX_GPIO_LED(11, "unk", "link", 1, LEDS_GPIO_DEFSTATE_OFF),
59};
60
61static const struct gpio_led
62bcm47xx_leds_asus_wl330ge[] __initconst = {
63 BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
64};
65
66static const struct gpio_led
67bcm47xx_leds_asus_wl500gd[] __initconst = {
68 BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
69};
70
71static const struct gpio_led
72bcm47xx_leds_asus_wl500gpv1[] __initconst = {
73 BCM47XX_GPIO_LED(1, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
74};
75
76static const struct gpio_led
77bcm47xx_leds_asus_wl500gpv2[] __initconst = {
78 BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
79 BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
80};
81
82static const struct gpio_led
83bcm47xx_leds_asus_wl500w[] __initconst = {
84 BCM47XX_GPIO_LED(5, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
85};
86
87static const struct gpio_led
88bcm47xx_leds_asus_wl520gc[] __initconst = {
89 BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
90 BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
91};
92
93static const struct gpio_led
94bcm47xx_leds_asus_wl520gu[] __initconst = {
95 BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
96 BCM47XX_GPIO_LED(1, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
97};
98
99static const struct gpio_led
100bcm47xx_leds_asus_wl700ge[] __initconst = {
101 BCM47XX_GPIO_LED(1, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON), /* Labeled "READY" (there is no "power" LED). Originally ON, flashing on USB activity. */
102};
103
104static const struct gpio_led
105bcm47xx_leds_asus_wlhdd[] __initconst = {
106 BCM47XX_GPIO_LED(0, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
107 BCM47XX_GPIO_LED(2, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
108};
109
110/* Belkin */
111
112static const struct gpio_led
113bcm47xx_leds_belkin_f7d4301[] __initconst = {
114 BCM47XX_GPIO_LED(10, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
115 BCM47XX_GPIO_LED(11, "amber", "power", 1, LEDS_GPIO_DEFSTATE_OFF),
116 BCM47XX_GPIO_LED(12, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
117 BCM47XX_GPIO_LED(13, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
118 BCM47XX_GPIO_LED(14, "unk", "usb0", 1, LEDS_GPIO_DEFSTATE_OFF),
119 BCM47XX_GPIO_LED(15, "unk", "usb1", 1, LEDS_GPIO_DEFSTATE_OFF),
120};
121
122/* Buffalo */
123
124static const struct gpio_led
125bcm47xx_leds_buffalo_whr2_a54g54[] __initconst = {
126 BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
127};
128
129static const struct gpio_led
130bcm47xx_leds_buffalo_whr_g125[] __initconst = {
131 BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
132 BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
133 BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
134 BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
135 BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
136};
137
138static const struct gpio_led
139bcm47xx_leds_buffalo_whr_g54s[] __initconst = {
140 BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
141 BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
142 BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
143 BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
144 BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
145};
146
147static const struct gpio_led
148bcm47xx_leds_buffalo_whr_hp_g54[] __initconst = {
149 BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
150 BCM47XX_GPIO_LED(2, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
151 BCM47XX_GPIO_LED(3, "unk", "internal", 1, LEDS_GPIO_DEFSTATE_OFF),
152 BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
153 BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
154};
155
156static const struct gpio_led
157bcm47xx_leds_buffalo_wzr_g300n[] __initconst = {
158 BCM47XX_GPIO_LED(1, "unk", "bridge", 1, LEDS_GPIO_DEFSTATE_OFF),
159 BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
160 BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
161};
162
163static const struct gpio_led
164bcm47xx_leds_buffalo_wzr_rs_g54[] __initconst = {
165 BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
166 BCM47XX_GPIO_LED(1, "unk", "vpn", 1, LEDS_GPIO_DEFSTATE_OFF),
167 BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
168};
169
170static const struct gpio_led
171bcm47xx_leds_buffalo_wzr_rs_g54hp[] __initconst = {
172 BCM47XX_GPIO_LED(6, "unk", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
173 BCM47XX_GPIO_LED(1, "unk", "vpn", 1, LEDS_GPIO_DEFSTATE_OFF),
174 BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
175};
176
177/* Dell */
178
179static const struct gpio_led
180bcm47xx_leds_dell_tm2300[] __initconst = {
181 BCM47XX_GPIO_LED(6, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
182 BCM47XX_GPIO_LED(7, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
183};
184
185/* D-Link */
186
187static const struct gpio_led
188bcm47xx_leds_dlink_dir130[] __initconst = {
189 BCM47XX_GPIO_LED_TRIGGER(0, "green", "status", 1, "timer"), /* Originally blinking when device is ready, separated from "power" LED */
190 BCM47XX_GPIO_LED(6, "blue", "unk", 1, LEDS_GPIO_DEFSTATE_OFF),
191};
192
193static const struct gpio_led
194bcm47xx_leds_dlink_dir330[] __initconst = {
195 BCM47XX_GPIO_LED_TRIGGER(0, "green", "status", 1, "timer"), /* Originally blinking when device is ready, separated from "power" LED */
196 BCM47XX_GPIO_LED(4, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
197 BCM47XX_GPIO_LED(6, "blue", "unk", 1, LEDS_GPIO_DEFSTATE_OFF),
198};
199
200/* Huawei */
201
202static const struct gpio_led
203bcm47xx_leds_huawei_e970[] __initconst = {
204 BCM47XX_GPIO_LED(0, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
205};
206
207/* Linksys */
208
209static const struct gpio_led
210bcm47xx_leds_linksys_e1000v1[] __initconst = {
211 BCM47XX_GPIO_LED(0, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
212 BCM47XX_GPIO_LED(1, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON),
213 BCM47XX_GPIO_LED(2, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
214 BCM47XX_GPIO_LED(4, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
215};
216
217static const struct gpio_led
218bcm47xx_leds_linksys_e1000v21[] __initconst = {
219 BCM47XX_GPIO_LED(5, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
220 BCM47XX_GPIO_LED(6, "unk", "power", 1, LEDS_GPIO_DEFSTATE_ON),
221 BCM47XX_GPIO_LED(7, "amber", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
222 BCM47XX_GPIO_LED(8, "blue", "wps", 0, LEDS_GPIO_DEFSTATE_OFF),
223};
224
225static const struct gpio_led
226bcm47xx_leds_linksys_e2000v1[] __initconst = {
227 BCM47XX_GPIO_LED(1, "blue", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
228 BCM47XX_GPIO_LED(2, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON),
229 BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
230 BCM47XX_GPIO_LED(4, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
231};
232
233static const struct gpio_led
234bcm47xx_leds_linksys_e3000v1[] __initconst = {
235 BCM47XX_GPIO_LED(0, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
236 BCM47XX_GPIO_LED(1, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
237 BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
238 BCM47XX_GPIO_LED(5, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
239 BCM47XX_GPIO_LED(7, "unk", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
240};
241
242static const struct gpio_led
243bcm47xx_leds_linksys_e3200v1[] __initconst = {
244 BCM47XX_GPIO_LED(3, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
245};
246
247static const struct gpio_led
248bcm47xx_leds_linksys_e4200v1[] __initconst = {
249 BCM47XX_GPIO_LED(5, "white", "power", 1, LEDS_GPIO_DEFSTATE_ON),
250};
251
252static const struct gpio_led
253bcm47xx_leds_linksys_wrt150nv1[] __initconst = {
254 BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
255 BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
256 BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
257};
258
259static const struct gpio_led
260bcm47xx_leds_linksys_wrt150nv11[] __initconst = {
261 BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
262 BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
263 BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
264};
265
266static const struct gpio_led
267bcm47xx_leds_linksys_wrt160nv1[] __initconst = {
268 BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
269 BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
270 BCM47XX_GPIO_LED(5, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
271};
272
273static const struct gpio_led
274bcm47xx_leds_linksys_wrt160nv3[] __initconst = {
275 BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
276 BCM47XX_GPIO_LED(2, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
277 BCM47XX_GPIO_LED(4, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
278};
279
280static const struct gpio_led
281bcm47xx_leds_linksys_wrt300nv11[] __initconst = {
282 BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
283 BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
284 BCM47XX_GPIO_LED(5, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
285};
286
287static const struct gpio_led
288bcm47xx_leds_linksys_wrt310nv1[] __initconst = {
289 BCM47XX_GPIO_LED(1, "blue", "power", 0, LEDS_GPIO_DEFSTATE_ON),
290 BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
291 BCM47XX_GPIO_LED(9, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
292};
293
294static const struct gpio_led
295bcm47xx_leds_linksys_wrt610nv1[] __initconst = {
296 BCM47XX_GPIO_LED(0, "unk", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
297 BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
298 BCM47XX_GPIO_LED(3, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
299 BCM47XX_GPIO_LED(9, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
300};
301
302static const struct gpio_led
303bcm47xx_leds_linksys_wrt610nv2[] __initconst = {
304 BCM47XX_GPIO_LED(0, "amber", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
305 BCM47XX_GPIO_LED(1, "unk", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
306 BCM47XX_GPIO_LED(3, "blue", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
307 BCM47XX_GPIO_LED(5, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
308 BCM47XX_GPIO_LED(7, "unk", "usb", 0, LEDS_GPIO_DEFSTATE_OFF),
309};
310
311/* Motorola */
312
313static const struct gpio_led
314bcm47xx_leds_motorola_we800g[] __initconst = {
315 BCM47XX_GPIO_LED(1, "amber", "wlan", 0, LEDS_GPIO_DEFSTATE_OFF),
316 BCM47XX_GPIO_LED(2, "unk", "unk", 1, LEDS_GPIO_DEFSTATE_OFF), /* There are only 3 LEDs: Power, Wireless and Device (ethernet) */
317 BCM47XX_GPIO_LED(4, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
318};
319
320static const struct gpio_led
321bcm47xx_leds_motorola_wr850gp[] __initconst = {
322 BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
323 BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
324 BCM47XX_GPIO_LED(6, "unk", "dmz", 1, LEDS_GPIO_DEFSTATE_OFF),
325 BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
326};
327
328static const struct gpio_led
329bcm47xx_leds_motorola_wr850gv2v3[] __initconst = {
330 BCM47XX_GPIO_LED(0, "unk", "wlan", 1, LEDS_GPIO_DEFSTATE_OFF),
331 BCM47XX_GPIO_LED(1, "unk", "power", 0, LEDS_GPIO_DEFSTATE_ON),
332 BCM47XX_GPIO_LED(7, "unk", "diag", 1, LEDS_GPIO_DEFSTATE_OFF),
333};
334
335/* Netgear */
336
337static const struct gpio_led
338bcm47xx_leds_netgear_wndr3400v1[] __initconst = {
339 BCM47XX_GPIO_LED(2, "green", "usb", 1, LEDS_GPIO_DEFSTATE_OFF),
340 BCM47XX_GPIO_LED(3, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
341 BCM47XX_GPIO_LED(7, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
342};
343
344static const struct gpio_led
345bcm47xx_leds_netgear_wndr4500v1[] __initconst = {
346 BCM47XX_GPIO_LED(1, "green", "wps", 1, LEDS_GPIO_DEFSTATE_OFF),
347 BCM47XX_GPIO_LED(2, "green", "power", 1, LEDS_GPIO_DEFSTATE_ON),
348 BCM47XX_GPIO_LED(3, "amber", "power", 1, LEDS_GPIO_DEFSTATE_OFF),
349 BCM47XX_GPIO_LED(8, "green", "usb1", 1, LEDS_GPIO_DEFSTATE_OFF),
350 BCM47XX_GPIO_LED(9, "green", "2ghz", 1, LEDS_GPIO_DEFSTATE_OFF),
351 BCM47XX_GPIO_LED(11, "blue", "5ghz", 1, LEDS_GPIO_DEFSTATE_OFF),
352 BCM47XX_GPIO_LED(14, "green", "usb2", 1, LEDS_GPIO_DEFSTATE_OFF),
353};
354
355static const struct gpio_led
356bcm47xx_leds_netgear_wnr834bv2[] __initconst = {
357 BCM47XX_GPIO_LED(2, "green", "power", 0, LEDS_GPIO_DEFSTATE_ON),
358 BCM47XX_GPIO_LED(3, "amber", "power", 0, LEDS_GPIO_DEFSTATE_OFF),
359 BCM47XX_GPIO_LED(7, "unk", "connected", 0, LEDS_GPIO_DEFSTATE_OFF),
360};
361
362/* SimpleTech */
363
364static const struct gpio_led
365bcm47xx_leds_simpletech_simpleshare[] __initconst = {
366 BCM47XX_GPIO_LED(1, "unk", "status", 1, LEDS_GPIO_DEFSTATE_OFF), /* "Ready" LED */
367};
368
369/**************************************************
370 * Init
371 **************************************************/
372
373static struct gpio_led_platform_data bcm47xx_leds_pdata;
374
375#define bcm47xx_set_pdata(dev_leds) do { \
376 bcm47xx_leds_pdata.leds = dev_leds; \
377 bcm47xx_leds_pdata.num_leds = ARRAY_SIZE(dev_leds); \
378} while (0)
379
380void __init bcm47xx_leds_register(void)
381{
382 enum bcm47xx_board board = bcm47xx_board_get();
383
384 switch (board) {
385 case BCM47XX_BOARD_ASUS_RTN12:
386 bcm47xx_set_pdata(bcm47xx_leds_asus_rtn12);
387 break;
388 case BCM47XX_BOARD_ASUS_RTN16:
389 bcm47xx_set_pdata(bcm47xx_leds_asus_rtn16);
390 break;
391 case BCM47XX_BOARD_ASUS_RTN66U:
392 bcm47xx_set_pdata(bcm47xx_leds_asus_rtn66u);
393 break;
394 case BCM47XX_BOARD_ASUS_WL300G:
395 bcm47xx_set_pdata(bcm47xx_leds_asus_wl300g);
396 break;
397 case BCM47XX_BOARD_ASUS_WL320GE:
398 bcm47xx_set_pdata(bcm47xx_leds_asus_wl320ge);
399 break;
400 case BCM47XX_BOARD_ASUS_WL330GE:
401 bcm47xx_set_pdata(bcm47xx_leds_asus_wl330ge);
402 break;
403 case BCM47XX_BOARD_ASUS_WL500GD:
404 bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gd);
405 break;
406 case BCM47XX_BOARD_ASUS_WL500GPV1:
407 bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gpv1);
408 break;
409 case BCM47XX_BOARD_ASUS_WL500GPV2:
410 bcm47xx_set_pdata(bcm47xx_leds_asus_wl500gpv2);
411 break;
412 case BCM47XX_BOARD_ASUS_WL500W:
413 bcm47xx_set_pdata(bcm47xx_leds_asus_wl500w);
414 break;
415 case BCM47XX_BOARD_ASUS_WL520GC:
416 bcm47xx_set_pdata(bcm47xx_leds_asus_wl520gc);
417 break;
418 case BCM47XX_BOARD_ASUS_WL520GU:
419 bcm47xx_set_pdata(bcm47xx_leds_asus_wl520gu);
420 break;
421 case BCM47XX_BOARD_ASUS_WL700GE:
422 bcm47xx_set_pdata(bcm47xx_leds_asus_wl700ge);
423 break;
424 case BCM47XX_BOARD_ASUS_WLHDD:
425 bcm47xx_set_pdata(bcm47xx_leds_asus_wlhdd);
426 break;
427
428 case BCM47XX_BOARD_BELKIN_F7D4301:
429 bcm47xx_set_pdata(bcm47xx_leds_belkin_f7d4301);
430 break;
431
432 case BCM47XX_BOARD_BUFFALO_WHR2_A54G54:
433 bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr2_a54g54);
434 break;
435 case BCM47XX_BOARD_BUFFALO_WHR_G125:
436 bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_g125);
437 break;
438 case BCM47XX_BOARD_BUFFALO_WHR_G54S:
439 bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_g54s);
440 break;
441 case BCM47XX_BOARD_BUFFALO_WHR_HP_G54:
442 bcm47xx_set_pdata(bcm47xx_leds_buffalo_whr_hp_g54);
443 break;
444 case BCM47XX_BOARD_BUFFALO_WZR_G300N:
445 bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_g300n);
446 break;
447 case BCM47XX_BOARD_BUFFALO_WZR_RS_G54:
448 bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_rs_g54);
449 break;
450 case BCM47XX_BOARD_BUFFALO_WZR_RS_G54HP:
451 bcm47xx_set_pdata(bcm47xx_leds_buffalo_wzr_rs_g54hp);
452 break;
453
454 case BCM47XX_BOARD_DELL_TM2300:
455 bcm47xx_set_pdata(bcm47xx_leds_dell_tm2300);
456 break;
457
458 case BCM47XX_BOARD_DLINK_DIR130:
459 bcm47xx_set_pdata(bcm47xx_leds_dlink_dir130);
460 break;
461 case BCM47XX_BOARD_DLINK_DIR330:
462 bcm47xx_set_pdata(bcm47xx_leds_dlink_dir330);
463 break;
464
465 case BCM47XX_BOARD_HUAWEI_E970:
466 bcm47xx_set_pdata(bcm47xx_leds_huawei_e970);
467 break;
468
469 case BCM47XX_BOARD_LINKSYS_E1000V1:
470 bcm47xx_set_pdata(bcm47xx_leds_linksys_e1000v1);
471 break;
472 case BCM47XX_BOARD_LINKSYS_E1000V21:
473 bcm47xx_set_pdata(bcm47xx_leds_linksys_e1000v21);
474 break;
475 case BCM47XX_BOARD_LINKSYS_E2000V1:
476 bcm47xx_set_pdata(bcm47xx_leds_linksys_e2000v1);
477 break;
478 case BCM47XX_BOARD_LINKSYS_E3000V1:
479 bcm47xx_set_pdata(bcm47xx_leds_linksys_e3000v1);
480 break;
481 case BCM47XX_BOARD_LINKSYS_E3200V1:
482 bcm47xx_set_pdata(bcm47xx_leds_linksys_e3200v1);
483 break;
484 case BCM47XX_BOARD_LINKSYS_E4200V1:
485 bcm47xx_set_pdata(bcm47xx_leds_linksys_e4200v1);
486 break;
487 case BCM47XX_BOARD_LINKSYS_WRT150NV1:
488 bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt150nv1);
489 break;
490 case BCM47XX_BOARD_LINKSYS_WRT150NV11:
491 bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt150nv11);
492 break;
493 case BCM47XX_BOARD_LINKSYS_WRT160NV1:
494 bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt160nv1);
495 break;
496 case BCM47XX_BOARD_LINKSYS_WRT160NV3:
497 bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt160nv3);
498 break;
499 case BCM47XX_BOARD_LINKSYS_WRT300NV11:
500 bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt300nv11);
501 break;
502 case BCM47XX_BOARD_LINKSYS_WRT310NV1:
503 bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt310nv1);
504 break;
505 case BCM47XX_BOARD_LINKSYS_WRT610NV1:
506 bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv1);
507 break;
508 case BCM47XX_BOARD_LINKSYS_WRT610NV2:
509 bcm47xx_set_pdata(bcm47xx_leds_linksys_wrt610nv2);
510 break;
511
512 case BCM47XX_BOARD_MOTOROLA_WE800G:
513 bcm47xx_set_pdata(bcm47xx_leds_motorola_we800g);
514 break;
515 case BCM47XX_BOARD_MOTOROLA_WR850GP:
516 bcm47xx_set_pdata(bcm47xx_leds_motorola_wr850gp);
517 break;
518 case BCM47XX_BOARD_MOTOROLA_WR850GV2V3:
519 bcm47xx_set_pdata(bcm47xx_leds_motorola_wr850gv2v3);
520 break;
521
522 case BCM47XX_BOARD_NETGEAR_WNDR3400V1:
523 bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr3400v1);
524 break;
525 case BCM47XX_BOARD_NETGEAR_WNDR4500V1:
526 bcm47xx_set_pdata(bcm47xx_leds_netgear_wndr4500v1);
527 break;
528 case BCM47XX_BOARD_NETGEAR_WNR834BV2:
529 bcm47xx_set_pdata(bcm47xx_leds_netgear_wnr834bv2);
530 break;
531
532 case BCM47XX_BOARD_SIMPLETECH_SIMPLESHARE:
533 bcm47xx_set_pdata(bcm47xx_leds_simpletech_simpleshare);
534 break;
535
536 default:
537 pr_debug("No LEDs configuration found for this device\n");
538 return;
539 }
540
541 gpio_led_register_device(-1, &bcm47xx_leds_pdata);
542}
diff --git a/arch/mips/bcm47xx/nvram.c b/arch/mips/bcm47xx/nvram.c
index b4c585b1c62e..6decb27cf48b 100644
--- a/arch/mips/bcm47xx/nvram.c
+++ b/arch/mips/bcm47xx/nvram.c
@@ -11,7 +11,6 @@
11 * option) any later version. 11 * option) any later version.
12 */ 12 */
13 13
14#include <linux/init.h>
15#include <linux/types.h> 14#include <linux/types.h>
16#include <linux/module.h> 15#include <linux/module.h>
17#include <linux/ssb/ssb.h> 16#include <linux/ssb/ssb.h>
@@ -22,11 +21,11 @@
22#include <asm/mach-bcm47xx/bcm47xx.h> 21#include <asm/mach-bcm47xx/bcm47xx.h>
23 22
24static char nvram_buf[NVRAM_SPACE]; 23static char nvram_buf[NVRAM_SPACE];
24static const u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000};
25 25
26static u32 find_nvram_size(u32 end) 26static u32 find_nvram_size(u32 end)
27{ 27{
28 struct nvram_header *header; 28 struct nvram_header *header;
29 u32 nvram_sizes[] = {0x8000, 0xF000, 0x10000};
30 int i; 29 int i;
31 30
32 for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) { 31 for (i = 0; i < ARRAY_SIZE(nvram_sizes); i++) {
diff --git a/arch/mips/bcm47xx/prom.c b/arch/mips/bcm47xx/prom.c
index 5cba318bc1cd..0af808dfd1ca 100644
--- a/arch/mips/bcm47xx/prom.c
+++ b/arch/mips/bcm47xx/prom.c
@@ -28,126 +28,27 @@
28#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/spinlock.h> 30#include <linux/spinlock.h>
31#include <linux/ssb/ssb_driver_chipcommon.h>
32#include <linux/ssb/ssb_regs.h>
31#include <linux/smp.h> 33#include <linux/smp.h>
32#include <asm/bootinfo.h> 34#include <asm/bootinfo.h>
33#include <asm/fw/cfe/cfe_api.h>
34#include <asm/fw/cfe/cfe_error.h>
35#include <bcm47xx.h> 35#include <bcm47xx.h>
36#include <bcm47xx_board.h> 36#include <bcm47xx_board.h>
37 37
38static int cfe_cons_handle;
39 38
40static u16 get_chip_id(void) 39static char bcm47xx_system_type[20] = "Broadcom BCM47XX";
41{
42 switch (bcm47xx_bus_type) {
43#ifdef CONFIG_BCM47XX_SSB
44 case BCM47XX_BUS_TYPE_SSB:
45 return bcm47xx_bus.ssb.chip_id;
46#endif
47#ifdef CONFIG_BCM47XX_BCMA
48 case BCM47XX_BUS_TYPE_BCMA:
49 return bcm47xx_bus.bcma.bus.chipinfo.id;
50#endif
51 }
52 return 0;
53}
54 40
55const char *get_system_type(void) 41const char *get_system_type(void)
56{ 42{
57 static char buf[50]; 43 return bcm47xx_system_type;
58 u16 chip_id = get_chip_id();
59
60 snprintf(buf, sizeof(buf),
61 (chip_id > 0x9999) ? "Broadcom BCM%d (%s)" :
62 "Broadcom BCM%04X (%s)",
63 chip_id, bcm47xx_board_get_name());
64
65 return buf;
66}
67
68void prom_putchar(char c)
69{
70 while (cfe_write(cfe_cons_handle, &c, 1) == 0)
71 ;
72} 44}
73 45
74static __init void prom_init_cfe(void) 46__init void bcm47xx_set_system_type(u16 chip_id)
75{ 47{
76 uint32_t cfe_ept; 48 snprintf(bcm47xx_system_type, sizeof(bcm47xx_system_type),
77 uint32_t cfe_handle; 49 (chip_id > 0x9999) ? "Broadcom BCM%d" :
78 uint32_t cfe_eptseal; 50 "Broadcom BCM%04X",
79 int argc = fw_arg0; 51 chip_id);
80 char **envp = (char **) fw_arg2;
81 int *prom_vec = (int *) fw_arg3;
82
83 /*
84 * Check if a loader was used; if NOT, the 4 arguments are
85 * what CFE gives us (handle, 0, EPT and EPTSEAL)
86 */
87 if (argc < 0) {
88 cfe_handle = (uint32_t)argc;
89 cfe_ept = (uint32_t)envp;
90 cfe_eptseal = (uint32_t)prom_vec;
91 } else {
92 if ((int)prom_vec < 0) {
93 /*
94 * Old loader; all it gives us is the handle,
95 * so use the "known" entrypoint and assume
96 * the seal.
97 */
98 cfe_handle = (uint32_t)prom_vec;
99 cfe_ept = 0xBFC00500;
100 cfe_eptseal = CFE_EPTSEAL;
101 } else {
102 /*
103 * Newer loaders bundle the handle/ept/eptseal
104 * Note: prom_vec is in the loader's useg
105 * which is still alive in the TLB.
106 */
107 cfe_handle = prom_vec[0];
108 cfe_ept = prom_vec[2];
109 cfe_eptseal = prom_vec[3];
110 }
111 }
112
113 if (cfe_eptseal != CFE_EPTSEAL) {
114 /* too early for panic to do any good */
115 printk(KERN_ERR "CFE's entrypoint seal doesn't match.");
116 while (1) ;
117 }
118
119 cfe_init(cfe_handle, cfe_ept);
120}
121
122static __init void prom_init_console(void)
123{
124 /* Initialize CFE console */
125 cfe_cons_handle = cfe_getstdhandle(CFE_STDHANDLE_CONSOLE);
126}
127
128static __init void prom_init_cmdline(void)
129{
130 static char buf[COMMAND_LINE_SIZE] __initdata;
131
132 /* Get the kernel command line from CFE */
133 if (cfe_getenv("LINUX_CMDLINE", buf, COMMAND_LINE_SIZE) >= 0) {
134 buf[COMMAND_LINE_SIZE - 1] = 0;
135 strcpy(arcs_cmdline, buf);
136 }
137
138 /* Force a console handover by adding a console= argument if needed,
139 * as CFE is not available anymore later in the boot process. */
140 if ((strstr(arcs_cmdline, "console=")) == NULL) {
141 /* Try to read the default serial port used by CFE */
142 if ((cfe_getenv("BOOT_CONSOLE", buf, COMMAND_LINE_SIZE) < 0)
143 || (strncmp("uart", buf, 4)))
144 /* Default to uart0 */
145 strcpy(buf, "uart0");
146
147 /* Compute the new command line */
148 snprintf(arcs_cmdline, COMMAND_LINE_SIZE, "%s console=ttyS%c,115200",
149 arcs_cmdline, buf[4]);
150 }
151} 52}
152 53
153static __init void prom_init_mem(void) 54static __init void prom_init_mem(void)
@@ -195,12 +96,16 @@ static __init void prom_init_mem(void)
195 add_memory_region(0, mem, BOOT_MEM_RAM); 96 add_memory_region(0, mem, BOOT_MEM_RAM);
196} 97}
197 98
99/*
100 * This is the first serial on the chip common core, it is at this position
101 * for sb (ssb) and ai (bcma) bus.
102 */
103#define BCM47XX_SERIAL_ADDR (SSB_ENUM_BASE + SSB_CHIPCO_UART0_DATA)
104
198void __init prom_init(void) 105void __init prom_init(void)
199{ 106{
200 prom_init_cfe();
201 prom_init_console();
202 prom_init_cmdline();
203 prom_init_mem(); 107 prom_init_mem();
108 setup_8250_early_printk_port(CKSEG1ADDR(BCM47XX_SERIAL_ADDR), 0, 0);
204} 109}
205 110
206void __init prom_free_prom_memory(void) 111void __init prom_free_prom_memory(void)
diff --git a/arch/mips/bcm47xx/serial.c b/arch/mips/bcm47xx/serial.c
index b8ef965705cf..2f5bbd68e9a0 100644
--- a/arch/mips/bcm47xx/serial.c
+++ b/arch/mips/bcm47xx/serial.c
@@ -31,7 +31,8 @@ static int __init uart8250_init_ssb(void)
31 31
32 memset(&uart8250_data, 0, sizeof(uart8250_data)); 32 memset(&uart8250_data, 0, sizeof(uart8250_data));
33 33
34 for (i = 0; i < mcore->nr_serial_ports; i++) { 34 for (i = 0; i < mcore->nr_serial_ports &&
35 i < ARRAY_SIZE(uart8250_data) - 1; i++) {
35 struct plat_serial8250_port *p = &(uart8250_data[i]); 36 struct plat_serial8250_port *p = &(uart8250_data[i]);
36 struct ssb_serial_port *ssb_port = &(mcore->serial_ports[i]); 37 struct ssb_serial_port *ssb_port = &(mcore->serial_ports[i]);
37 38
@@ -55,7 +56,8 @@ static int __init uart8250_init_bcma(void)
55 56
56 memset(&uart8250_data, 0, sizeof(uart8250_data)); 57 memset(&uart8250_data, 0, sizeof(uart8250_data));
57 58
58 for (i = 0; i < cc->nr_serial_ports; i++) { 59 for (i = 0; i < cc->nr_serial_ports &&
60 i < ARRAY_SIZE(uart8250_data) - 1; i++) {
59 struct plat_serial8250_port *p = &(uart8250_data[i]); 61 struct plat_serial8250_port *p = &(uart8250_data[i]);
60 struct bcma_serial_port *bcma_port; 62 struct bcma_serial_port *bcma_port;
61 bcma_port = &(cc->serial_ports[i]); 63 bcma_port = &(cc->serial_ports[i]);
diff --git a/arch/mips/bcm47xx/setup.c b/arch/mips/bcm47xx/setup.c
index 9057728ac56b..025be218ea15 100644
--- a/arch/mips/bcm47xx/setup.c
+++ b/arch/mips/bcm47xx/setup.c
@@ -26,6 +26,8 @@
26 * 675 Mass Ave, Cambridge, MA 02139, USA. 26 * 675 Mass Ave, Cambridge, MA 02139, USA.
27 */ 27 */
28 28
29#include "bcm47xx_private.h"
30
29#include <linux/export.h> 31#include <linux/export.h>
30#include <linux/types.h> 32#include <linux/types.h>
31#include <linux/ethtool.h> 33#include <linux/ethtool.h>
@@ -35,6 +37,8 @@
35#include <linux/ssb/ssb_embedded.h> 37#include <linux/ssb/ssb_embedded.h>
36#include <linux/bcma/bcma_soc.h> 38#include <linux/bcma/bcma_soc.h>
37#include <asm/bootinfo.h> 39#include <asm/bootinfo.h>
40#include <asm/idle.h>
41#include <asm/prom.h>
38#include <asm/reboot.h> 42#include <asm/reboot.h>
39#include <asm/time.h> 43#include <asm/time.h>
40#include <bcm47xx.h> 44#include <bcm47xx.h>
@@ -213,12 +217,14 @@ void __init plat_mem_setup(void)
213#ifdef CONFIG_BCM47XX_BCMA 217#ifdef CONFIG_BCM47XX_BCMA
214 bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA; 218 bcm47xx_bus_type = BCM47XX_BUS_TYPE_BCMA;
215 bcm47xx_register_bcma(); 219 bcm47xx_register_bcma();
220 bcm47xx_set_system_type(bcm47xx_bus.bcma.bus.chipinfo.id);
216#endif 221#endif
217 } else { 222 } else {
218 printk(KERN_INFO "bcm47xx: using ssb bus\n"); 223 printk(KERN_INFO "bcm47xx: using ssb bus\n");
219#ifdef CONFIG_BCM47XX_SSB 224#ifdef CONFIG_BCM47XX_SSB
220 bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB; 225 bcm47xx_bus_type = BCM47XX_BUS_TYPE_SSB;
221 bcm47xx_register_ssb(); 226 bcm47xx_register_ssb();
227 bcm47xx_set_system_type(bcm47xx_bus.ssb.chip_id);
222#endif 228#endif
223 } 229 }
224 230
@@ -226,8 +232,34 @@ void __init plat_mem_setup(void)
226 _machine_halt = bcm47xx_machine_halt; 232 _machine_halt = bcm47xx_machine_halt;
227 pm_power_off = bcm47xx_machine_halt; 233 pm_power_off = bcm47xx_machine_halt;
228 bcm47xx_board_detect(); 234 bcm47xx_board_detect();
235 mips_set_machine_name(bcm47xx_board_get_name());
229} 236}
230 237
238static int __init bcm47xx_cpu_fixes(void)
239{
240 switch (bcm47xx_bus_type) {
241#ifdef CONFIG_BCM47XX_SSB
242 case BCM47XX_BUS_TYPE_SSB:
243 /* Nothing to do */
244 break;
245#endif
246#ifdef CONFIG_BCM47XX_BCMA
247 case BCM47XX_BUS_TYPE_BCMA:
248 /* The BCM4706 has a problem with the CPU wait instruction.
249 * When r4k_wait or r4k_wait_irqoff is used will just hang and
250 * not return from a msleep(). Removing the cpu_wait
251 * functionality is a workaround for this problem. The BCM4716
252 * does not have this problem.
253 */
254 if (bcm47xx_bus.bcma.bus.chipinfo.id == BCMA_CHIP_ID_BCM4706)
255 cpu_wait = NULL;
256 break;
257#endif
258 }
259 return 0;
260}
261arch_initcall(bcm47xx_cpu_fixes);
262
231static struct fixed_phy_status bcm47xx_fixed_phy_status __initdata = { 263static struct fixed_phy_status bcm47xx_fixed_phy_status __initdata = {
232 .link = 1, 264 .link = 1,
233 .speed = SPEED_100, 265 .speed = SPEED_100,
@@ -248,6 +280,9 @@ static int __init bcm47xx_register_bus_complete(void)
248 break; 280 break;
249#endif 281#endif
250 } 282 }
283 bcm47xx_buttons_register();
284 bcm47xx_leds_register();
285
251 fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status); 286 fixed_phy_add(PHY_POLL, 0, &bcm47xx_fixed_phy_status);
252 return 0; 287 return 0;
253} 288}
diff --git a/arch/mips/bcm47xx/sprom.c b/arch/mips/bcm47xx/sprom.c
index ad03c931b905..a8b5408dd349 100644
--- a/arch/mips/bcm47xx/sprom.c
+++ b/arch/mips/bcm47xx/sprom.c
@@ -135,7 +135,7 @@ static void nvram_read_leddc(const char *prefix, const char *name,
135} 135}
136 136
137static void nvram_read_macaddr(const char *prefix, const char *name, 137static void nvram_read_macaddr(const char *prefix, const char *name,
138 u8 (*val)[6], bool fallback) 138 u8 val[6], bool fallback)
139{ 139{
140 char buf[100]; 140 char buf[100];
141 int err; 141 int err;
@@ -144,11 +144,11 @@ static void nvram_read_macaddr(const char *prefix, const char *name,
144 if (err < 0) 144 if (err < 0)
145 return; 145 return;
146 146
147 bcm47xx_nvram_parse_macaddr(buf, *val); 147 bcm47xx_nvram_parse_macaddr(buf, val);
148} 148}
149 149
150static void nvram_read_alpha2(const char *prefix, const char *name, 150static void nvram_read_alpha2(const char *prefix, const char *name,
151 char (*val)[2], bool fallback) 151 char val[2], bool fallback)
152{ 152{
153 char buf[10]; 153 char buf[10];
154 int err; 154 int err;
@@ -162,7 +162,7 @@ static void nvram_read_alpha2(const char *prefix, const char *name,
162 pr_warn("alpha2 is too long %s\n", buf); 162 pr_warn("alpha2 is too long %s\n", buf);
163 return; 163 return;
164 } 164 }
165 memcpy(val, buf, sizeof(val)); 165 memcpy(val, buf, 2);
166} 166}
167 167
168static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom, 168static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom,
@@ -180,7 +180,7 @@ static void bcm47xx_fill_sprom_r1234589(struct ssb_sprom *sprom,
180 fallback); 180 fallback);
181 nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0, 181 nvram_read_s8(prefix, NULL, "ag1", &sprom->antenna_gain.a1, 0,
182 fallback); 182 fallback);
183 nvram_read_alpha2(prefix, "ccode", &sprom->alpha2, fallback); 183 nvram_read_alpha2(prefix, "ccode", sprom->alpha2, fallback);
184} 184}
185 185
186static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom, 186static void bcm47xx_fill_sprom_r12389(struct ssb_sprom *sprom,
@@ -633,20 +633,20 @@ static void bcm47xx_fill_sprom_path_r45(struct ssb_sprom *sprom,
633static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom, 633static void bcm47xx_fill_sprom_ethernet(struct ssb_sprom *sprom,
634 const char *prefix, bool fallback) 634 const char *prefix, bool fallback)
635{ 635{
636 nvram_read_macaddr(prefix, "et0macaddr", &sprom->et0mac, fallback); 636 nvram_read_macaddr(prefix, "et0macaddr", sprom->et0mac, fallback);
637 nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0, 637 nvram_read_u8(prefix, NULL, "et0mdcport", &sprom->et0mdcport, 0,
638 fallback); 638 fallback);
639 nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0, 639 nvram_read_u8(prefix, NULL, "et0phyaddr", &sprom->et0phyaddr, 0,
640 fallback); 640 fallback);
641 641
642 nvram_read_macaddr(prefix, "et1macaddr", &sprom->et1mac, fallback); 642 nvram_read_macaddr(prefix, "et1macaddr", sprom->et1mac, fallback);
643 nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0, 643 nvram_read_u8(prefix, NULL, "et1mdcport", &sprom->et1mdcport, 0,
644 fallback); 644 fallback);
645 nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0, 645 nvram_read_u8(prefix, NULL, "et1phyaddr", &sprom->et1phyaddr, 0,
646 fallback); 646 fallback);
647 647
648 nvram_read_macaddr(prefix, "macaddr", &sprom->il0mac, fallback); 648 nvram_read_macaddr(prefix, "macaddr", sprom->il0mac, fallback);
649 nvram_read_macaddr(prefix, "il0macaddr", &sprom->il0mac, fallback); 649 nvram_read_macaddr(prefix, "il0macaddr", sprom->il0mac, fallback);
650} 650}
651 651
652static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix, 652static void bcm47xx_fill_board_data(struct ssb_sprom *sprom, const char *prefix,
diff --git a/arch/mips/bcm47xx/wgt634u.c b/arch/mips/bcm47xx/wgt634u.c
deleted file mode 100644
index c63a4c287b5c..000000000000
--- a/arch/mips/bcm47xx/wgt634u.c
+++ /dev/null
@@ -1,174 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2007 Aurelien Jarno <aurelien@aurel32.net>
7 */
8
9#include <linux/platform_device.h>
10#include <linux/module.h>
11#include <linux/leds.h>
12#include <linux/mtd/physmap.h>
13#include <linux/ssb/ssb.h>
14#include <linux/ssb/ssb_embedded.h>
15#include <linux/interrupt.h>
16#include <linux/reboot.h>
17#include <linux/gpio.h>
18#include <asm/mach-bcm47xx/bcm47xx.h>
19
20/* GPIO definitions for the WGT634U */
21#define WGT634U_GPIO_LED 3
22#define WGT634U_GPIO_RESET 2
23#define WGT634U_GPIO_TP1 7
24#define WGT634U_GPIO_TP2 6
25#define WGT634U_GPIO_TP3 5
26#define WGT634U_GPIO_TP4 4
27#define WGT634U_GPIO_TP5 1
28
29static struct gpio_led wgt634u_leds[] = {
30 {
31 .name = "power",
32 .gpio = WGT634U_GPIO_LED,
33 .active_low = 1,
34 .default_trigger = "heartbeat",
35 },
36};
37
38static struct gpio_led_platform_data wgt634u_led_data = {
39 .num_leds = ARRAY_SIZE(wgt634u_leds),
40 .leds = wgt634u_leds,
41};
42
43static struct platform_device wgt634u_gpio_leds = {
44 .name = "leds-gpio",
45 .id = -1,
46 .dev = {
47 .platform_data = &wgt634u_led_data,
48 }
49};
50
51
52/* 8MiB flash. The struct mtd_partition matches original Netgear WGT634U
53 firmware. */
54static struct mtd_partition wgt634u_partitions[] = {
55 {
56 .name = "cfe",
57 .offset = 0,
58 .size = 0x60000, /* 384k */
59 .mask_flags = MTD_WRITEABLE /* force read-only */
60 },
61 {
62 .name = "config",
63 .offset = 0x60000,
64 .size = 0x20000 /* 128k */
65 },
66 {
67 .name = "linux",
68 .offset = 0x80000,
69 .size = 0x140000 /* 1280k */
70 },
71 {
72 .name = "jffs",
73 .offset = 0x1c0000,
74 .size = 0x620000 /* 6272k */
75 },
76 {
77 .name = "nvram",
78 .offset = 0x7e0000,
79 .size = 0x20000 /* 128k */
80 },
81};
82
83static struct physmap_flash_data wgt634u_flash_data = {
84 .parts = wgt634u_partitions,
85 .nr_parts = ARRAY_SIZE(wgt634u_partitions)
86};
87
88static struct resource wgt634u_flash_resource = {
89 .flags = IORESOURCE_MEM,
90};
91
92static struct platform_device wgt634u_flash = {
93 .name = "physmap-flash",
94 .id = 0,
95 .dev = { .platform_data = &wgt634u_flash_data, },
96 .resource = &wgt634u_flash_resource,
97 .num_resources = 1,
98};
99
100/* Platform devices */
101static struct platform_device *wgt634u_devices[] __initdata = {
102 &wgt634u_flash,
103 &wgt634u_gpio_leds,
104};
105
106static irqreturn_t gpio_interrupt(int irq, void *ignored)
107{
108 int state;
109
110 /* Interrupts are shared, check if the current one is
111 a GPIO interrupt. */
112 if (!ssb_chipco_irq_status(&bcm47xx_bus.ssb.chipco,
113 SSB_CHIPCO_IRQ_GPIO))
114 return IRQ_NONE;
115
116 state = gpio_get_value(WGT634U_GPIO_RESET);
117
118 /* Interrupt are level triggered, revert the interrupt polarity
119 to clear the interrupt. */
120 ssb_gpio_polarity(&bcm47xx_bus.ssb, 1 << WGT634U_GPIO_RESET,
121 state ? 1 << WGT634U_GPIO_RESET : 0);
122
123 if (!state) {
124 printk(KERN_INFO "Reset button pressed");
125 ctrl_alt_del();
126 }
127
128 return IRQ_HANDLED;
129}
130
131static int __init wgt634u_init(void)
132{
133 /* There is no easy way to detect that we are running on a WGT634U
134 * machine. Use the MAC address as an heuristic. Netgear Inc. has
135 * been allocated ranges 00:09:5b:xx:xx:xx and 00:0f:b5:xx:xx:xx.
136 */
137 u8 *et0mac;
138
139 if (bcm47xx_bus_type != BCM47XX_BUS_TYPE_SSB)
140 return -ENODEV;
141
142 et0mac = bcm47xx_bus.ssb.sprom.et0mac;
143
144 if (et0mac[0] == 0x00 &&
145 ((et0mac[1] == 0x09 && et0mac[2] == 0x5b) ||
146 (et0mac[1] == 0x0f && et0mac[2] == 0xb5))) {
147 struct ssb_mipscore *mcore = &bcm47xx_bus.ssb.mipscore;
148
149 printk(KERN_INFO "WGT634U machine detected.\n");
150
151 if (!request_irq(gpio_to_irq(WGT634U_GPIO_RESET),
152 gpio_interrupt, IRQF_SHARED,
153 "WGT634U GPIO", &bcm47xx_bus.ssb.chipco)) {
154 gpio_direction_input(WGT634U_GPIO_RESET);
155 ssb_gpio_intmask(&bcm47xx_bus.ssb,
156 1 << WGT634U_GPIO_RESET,
157 1 << WGT634U_GPIO_RESET);
158 ssb_chipco_irq_mask(&bcm47xx_bus.ssb.chipco,
159 SSB_CHIPCO_IRQ_GPIO,
160 SSB_CHIPCO_IRQ_GPIO);
161 }
162
163 wgt634u_flash_data.width = mcore->pflash.buswidth;
164 wgt634u_flash_resource.start = mcore->pflash.window;
165 wgt634u_flash_resource.end = mcore->pflash.window
166 + mcore->pflash.window_size
167 - 1;
168 return platform_add_devices(wgt634u_devices,
169 ARRAY_SIZE(wgt634u_devices));
170 } else
171 return -ENODEV;
172}
173
174module_init(wgt634u_init);