brcm63xx: remove patches/configs for 2.6.35

SVN-Revision: 26709
master
Felix Fietkau 14 years ago
parent 8566daa5df
commit 1fcd26091b
  1. 222
      target/linux/brcm63xx/config-2.6.35
  2. 125
      target/linux/brcm63xx/patches-2.6.35/007-usb-ohci-support.patch
  3. 117
      target/linux/brcm63xx/patches-2.6.35/008-usb-ehci-support.patch
  4. 202
      target/linux/brcm63xx/patches-2.6.35/010-add_bcm63xx_ohci_controller.patch
  5. 178
      target/linux/brcm63xx/patches-2.6.35/011-add_bcm63xx_ehci_controller.patch
  6. 386
      target/linux/brcm63xx/patches-2.6.35/020-watchdog.patch
  7. 389
      target/linux/brcm63xx/patches-2.6.35/040-bcm963xx_flashmap.patch
  8. 11
      target/linux/brcm63xx/patches-2.6.35/070_bcm63xx_enet_vlan_incoming_fixed.patch
  9. 98
      target/linux/brcm63xx/patches-2.6.35/100-reset_buttons.patch
  10. 22
      target/linux/brcm63xx/patches-2.6.35/110-gpiodev.patch
  11. 237
      target/linux/brcm63xx/patches-2.6.35/120-spi-bitbang-norxtx-support.patch
  12. 217
      target/linux/brcm63xx/patches-2.6.35/121-spi-gpio-norxtx-support.patch
  13. 23
      target/linux/brcm63xx/patches-2.6.35/141-led_count.patch
  14. 113
      target/linux/brcm63xx/patches-2.6.35/150-alice_gate2_leds.patch
  15. 251
      target/linux/brcm63xx/patches-2.6.35/170-board_livebox.patch
  16. 243
      target/linux/brcm63xx/patches-2.6.35/180-udc_preliminary_support.patch
  17. 25
      target/linux/brcm63xx/patches-2.6.35/200-extended-platform-devices.patch
  18. 25
      target/linux/brcm63xx/patches-2.6.35/200-spi-board-info.patch
  19. 458
      target/linux/brcm63xx/patches-2.6.35/211-gen-74x164-gpio-chip-driver.patch
  20. 60
      target/linux/brcm63xx/patches-2.6.35/220-board-D4PW.patch
  21. 569
      target/linux/brcm63xx/patches-2.6.35/221-board-NB4.patch
  22. 1002
      target/linux/brcm63xx/patches-2.6.35/240-spi.patch
  23. 22
      target/linux/brcm63xx/patches-2.6.35/250-6358-enet1-external-mii-clk.patch
  24. 16
      target/linux/brcm63xx/patches-2.6.35/260-no_ehci_over_current_check.patch
  25. 49
      target/linux/brcm63xx/patches-2.6.35/270-board-96338W2_E7T.patch
  26. 34
      target/linux/brcm63xx/patches-2.6.35/300-wl_exports.patch
  27. 109
      target/linux/brcm63xx/patches-2.6.35/310-CPVA642_board.patch
  28. 70
      target/linux/brcm63xx/patches-2.6.35/400-board_96358gw.patch
  29. 62
      target/linux/brcm63xx/patches-2.6.35/410-boardid_fixup.patch
  30. 78
      target/linux/brcm63xx/patches-2.6.35/420-board_spw500v.patch
  31. 129
      target/linux/brcm63xx/patches-2.6.35/430-board_gw6200_gw6000.patch
  32. 60
      target/linux/brcm63xx/patches-2.6.35/440-new_96348gw-11_leds.patch
  33. 89
      target/linux/brcm63xx/patches-2.6.35/450-board-MAGIC.patch
  34. 90
      target/linux/brcm63xx/patches-2.6.35/451-board_hw553.patch
  35. 54
      target/linux/brcm63xx/patches-2.6.35/452-board_rta1320_16m.patch
  36. 20
      target/linux/brcm63xx/patches-2.6.35/977-ssb_export_fallback_sprom.patch

@ -1,222 +0,0 @@
CONFIG_32BIT=y
# CONFIG_64BIT is not set
# CONFIG_ALCHEMY_GPIO_INDIRECT is not set
# CONFIG_AR7 is not set
# CONFIG_ARCH_HAS_ILOG2_U32 is not set
# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_POPULATES_NODE_MAP=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
CONFIG_ARCH_SUPPORTS_OPROFILE=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
# CONFIG_ATH_COMMON is not set
CONFIG_AUDIT=y
CONFIG_AUDIT_GENERIC=y
# CONFIG_BATMAN_ADV is not set
# CONFIG_BCM47XX is not set
CONFIG_BCM63XX=y
CONFIG_BCM63XX_CPU_6338=y
CONFIG_BCM63XX_CPU_6345=y
CONFIG_BCM63XX_CPU_6348=y
CONFIG_BCM63XX_CPU_6358=y
CONFIG_BCM63XX_ENET=y
CONFIG_BCM63XX_PHY=y
CONFIG_BCM63XX_WDT=y
CONFIG_BITREVERSE=y
CONFIG_BOARD_BCM963XX=y
# CONFIG_BOARD_LIVEBOX is not set
CONFIG_BSD_PROCESS_ACCT_V3=y
# CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD is not set
# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_CEVT_R4K=y
CONFIG_CEVT_R4K_LIB=y
CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=squashfs,jffs2 noinitrd console=ttyS0,115200"
CONFIG_CMDLINE_BOOL=y
# CONFIG_CMDLINE_OVERRIDE is not set
CONFIG_CPU_BIG_ENDIAN=y
# CONFIG_CPU_CAVIUM_OCTEON is not set
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_SYNC=y
# CONFIG_CPU_LITTLE_ENDIAN is not set
# CONFIG_CPU_LOONGSON2E is not set
# CONFIG_CPU_LOONGSON2F is not set
CONFIG_CPU_MIPS32=y
CONFIG_CPU_MIPS32_R1=y
# CONFIG_CPU_MIPS32_R2 is not set
# CONFIG_CPU_MIPS64_R1 is not set
# CONFIG_CPU_MIPS64_R2 is not set
CONFIG_CPU_MIPSR1=y
# CONFIG_CPU_NEVADA is not set
# CONFIG_CPU_R10000 is not set
# CONFIG_CPU_R3000 is not set
# CONFIG_CPU_R4300 is not set
# CONFIG_CPU_R4X00 is not set
# CONFIG_CPU_R5000 is not set
# CONFIG_CPU_R5432 is not set
# CONFIG_CPU_R5500 is not set
# CONFIG_CPU_R6000 is not set
# CONFIG_CPU_R8000 is not set
# CONFIG_CPU_RM7000 is not set
# CONFIG_CPU_RM9000 is not set
# CONFIG_CPU_SB1 is not set
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
# CONFIG_CPU_TX39XX is not set
# CONFIG_CPU_TX49XX is not set
# CONFIG_CPU_VR41XX is not set
CONFIG_CRAMFS=y
CONFIG_CSRC_R4K=y
CONFIG_CSRC_R4K_LIB=y
CONFIG_DECOMPRESS_LZMA=y
CONFIG_DEFAULT_SECURITY=""
CONFIG_DEVPORT=y
# CONFIG_DM9000 is not set
CONFIG_DMA_NEED_PCI_MAP_STATE=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_EARLY_PRINTK=y
CONFIG_ELF_CORE=y
CONFIG_FIRMWARE_IN_KERNEL=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_GPIO=y
CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
CONFIG_GPIOLIB=y
# CONFIG_GPIO_CS5535 is not set
CONFIG_GPIO_74X164=y
CONFIG_GPIO_DEVICE=y
CONFIG_GPIO_SYSFS=y
# CONFIG_HAMRADIO is not set
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_DYNAMIC_FTRACE=y
CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y
CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y
CONFIG_HAVE_FUNCTION_TRACER=y
CONFIG_HAVE_FUNCTION_TRACE_MCOUNT_TEST=y
CONFIG_HAVE_GENERIC_DMA_COHERENT=y
CONFIG_HAVE_IDE=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HW_HAS_PCI=y
CONFIG_HW_RANDOM=y
CONFIG_HZ=250
# CONFIG_HZ_100 is not set
CONFIG_HZ_250=y
CONFIG_IMAGE_CMDLINE_HACK=y
CONFIG_INITRAMFS_SOURCE=""
CONFIG_INOTIFY=y
CONFIG_INOTIFY_USER=y
CONFIG_IP_PIMSM_V1=y
CONFIG_IP_PIMSM_V2=y
CONFIG_IRQ_CPU=y
CONFIG_KEXEC=y
CONFIG_LEDS_GPIO=y
# CONFIG_LEDS_LT3593 is not set
# CONFIG_LEDS_TRIGGER_HEARTBEAT is not set
CONFIG_LOONGSON_UART_BASE=y
# CONFIG_MACH_ALCHEMY is not set
# CONFIG_MACH_DECSTATION is not set
# CONFIG_MACH_JAZZ is not set
# CONFIG_MACH_LOONGSON is not set
# CONFIG_MACH_TX39XX is not set
# CONFIG_MACH_TX49XX is not set
# CONFIG_MACH_VR41XX is not set
# CONFIG_MIKROTIK_RB532 is not set
CONFIG_MIPS=y
# CONFIG_MIPS_COBALT is not set
CONFIG_MIPS_L1_CACHE_SHIFT=5
# CONFIG_MIPS_MACHINE is not set
# CONFIG_MIPS_MALTA is not set
CONFIG_MIPS_MT_DISABLED=y
# CONFIG_MIPS_MT_SMP is not set
# CONFIG_MIPS_MT_SMTC is not set
# CONFIG_MIPS_SIM is not set
CONFIG_MODULE_FORCE_LOAD=y
CONFIG_MODULE_FORCE_UNLOAD=y
CONFIG_MTD_BCM963XX=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_BE_BYTE_SWAP=y
# CONFIG_MTD_CFI_GEOMETRY is not set
# CONFIG_MTD_CFI_NOSWAP is not set
CONFIG_MTD_CFI_STAA=y
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
CONFIG_MTD_CONCAT=y
CONFIG_MTD_JEDECPROBE=y
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED=y
# CONFIG_NL80211_TESTMODE is not set
# CONFIG_NO_IOPORT is not set
# CONFIG_NXP_STB220 is not set
# CONFIG_NXP_STB225 is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_PCI=y
CONFIG_PCI_DOMAINS=y
CONFIG_PHYLIB=y
# CONFIG_PMC_MSP is not set
# CONFIG_PMC_YOSEMITE is not set
# CONFIG_PNX8550_JBS is not set
# CONFIG_PNX8550_STB810 is not set
CONFIG_POSIX_MQUEUE=y
CONFIG_POSIX_MQUEUE_SYSCTL=y
# CONFIG_POWERTV is not set
# CONFIG_R8187SE is not set
# CONFIG_RAMZSWAP is not set
CONFIG_RELAY=y
CONFIG_SCHED_OMIT_FRAME_POINTER=y
# CONFIG_SCSI_DMA is not set
# CONFIG_SERIAL_8250 is not set
CONFIG_SERIAL_BCM63XX=y
CONFIG_SERIAL_BCM63XX_CONSOLE=y
# CONFIG_SGI_IP22 is not set
# CONFIG_SGI_IP27 is not set
# CONFIG_SGI_IP28 is not set
# CONFIG_SGI_IP32 is not set
# CONFIG_SIBYTE_BIGSUR is not set
# CONFIG_SIBYTE_CARMEL is not set
# CONFIG_SIBYTE_CRHINE is not set
# CONFIG_SIBYTE_CRHONE is not set
# CONFIG_SIBYTE_LITTLESUR is not set
# CONFIG_SIBYTE_RHONE is not set
# CONFIG_SIBYTE_SENTOSA is not set
# CONFIG_SIBYTE_SWARM is not set
CONFIG_SPI=y
CONFIG_SPI_BITBANG=y
CONFIG_SPI_GPIO=y
CONFIG_SPI_MASTER=y
CONFIG_SQUASHFS_EMBEDDED=y
CONFIG_SSB=y
CONFIG_SSB_B43_PCI_BRIDGE=y
# CONFIG_SSB_DRIVER_MIPS is not set
CONFIG_SSB_DRIVER_PCICORE=y
CONFIG_SSB_DRIVER_PCICORE_POSSIBLE=y
CONFIG_SSB_PCIHOST=y
CONFIG_SSB_PCIHOST_POSSIBLE=y
CONFIG_SSB_SPROM=y
CONFIG_SWAP_IO_SPACE=y
CONFIG_SYS_HAS_CPU_MIPS32_R1=y
CONFIG_SYS_HAS_EARLY_PRINTK=y
CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y
CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
CONFIG_SYS_SUPPORTS_BIG_ENDIAN=y
# CONFIG_TC35815 is not set
# CONFIG_TINY_RCU is not set
CONFIG_TRAD_SIGNALS=y
# CONFIG_TREE_PREEMPT_RCU is not set
CONFIG_TREE_RCU=y
CONFIG_USB_EHCI_BIG_ENDIAN_MMIO=y
CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
CONFIG_USB_SUPPORT=y
CONFIG_VM_EVENT_COUNTERS=y
CONFIG_WATCHDOG_NOWAYOUT=y
CONFIG_WEXT_CORE=y
CONFIG_WEXT_PROC=y
CONFIG_ZONE_DMA_FLAG=0

@ -1,125 +0,0 @@
The bcm63xx SOC has an integrated OHCI controller, this patch adds
platform device registration and change board code to register ohci
device when necessary.
Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
---
arch/mips/bcm63xx/Kconfig | 6 ++
arch/mips/bcm63xx/Makefile | 3 +-
arch/mips/bcm63xx/boards/board_bcm963xx.c | 4 ++
arch/mips/bcm63xx/dev-usb-ohci.c | 49 ++++++++++++++++++++
.../asm/mach-bcm63xx/bcm63xx_dev_usb_ohci.h | 6 ++
5 files changed, 67 insertions(+), 1 deletions(-)
create mode 100644 arch/mips/bcm63xx/dev-usb-ohci.c
create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ohci.h
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -16,10 +16,16 @@ config BCM63XX_CPU_6345
config BCM63XX_CPU_6348
bool "support 6348 CPU"
select HW_HAS_PCI
+ select USB_ARCH_HAS_OHCI
+ select USB_OHCI_BIG_ENDIAN_DESC
+ select USB_OHCI_BIG_ENDIAN_MMIO
config BCM63XX_CPU_6358
bool "support 6358 CPU"
select HW_HAS_PCI
+ select USB_ARCH_HAS_OHCI
+ select USB_OHCI_BIG_ENDIAN_DESC
+ select USB_OHCI_BIG_ENDIAN_MMIO
endmenu
source "arch/mips/bcm63xx/boards/Kconfig"
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -1,5 +1,6 @@
obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
- dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o
+ dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o \
+ dev-usb-ohci.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -25,6 +25,7 @@
#include <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_dsp.h>
#include <bcm63xx_dev_pcmcia.h>
+#include <bcm63xx_dev_usb_ohci.h>
#include <board_bcm963xx.h>
#define PFX "board_bcm963xx: "
@@ -877,6 +878,9 @@ int __init board_register_devices(void)
!board_get_mac_address(board.enet1.mac_addr))
bcm63xx_enet_register(1, &board.enet1);
+ if (board.has_ohci0)
+ bcm63xx_ohci_register();
+
if (board.has_dsp)
bcm63xx_dsp_register(&board.dsp);
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-usb-ohci.c
@@ -0,0 +1,49 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2010 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_usb_ohci.h>
+
+static struct resource ohci_resources[] = {
+ {
+ /* start & end filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* start filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ohci_dmamask = ~(u32)0;
+
+static struct platform_device bcm63xx_ohci_device = {
+ .name = "bcm63xx_ohci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ohci_resources),
+ .resource = ohci_resources,
+ .dev = {
+ .dma_mask = &ohci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+int __init bcm63xx_ohci_register(void)
+{
+ if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358())
+ return 0;
+
+ ohci_resources[0].start = bcm63xx_regset_address(RSET_OHCI0);
+ ohci_resources[0].end = ohci_resources[0].start;
+ ohci_resources[0].end += RSET_OHCI_SIZE - 1;
+ ohci_resources[1].start = bcm63xx_get_irq_number(IRQ_OHCI0);
+ return platform_device_register(&bcm63xx_ohci_device);
+}
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ohci.h
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_USB_OHCI_H_
+#define BCM63XX_DEV_USB_OHCI_H_
+
+int bcm63xx_ohci_register(void);
+
+#endif /* BCM63XX_DEV_USB_OHCI_H_ */

@ -1,117 +0,0 @@
The bcm63xx SOC has an integrated EHCI controller, this patch adds
platform device registration and change board code to register
EHCI device when necessary.
Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
---
arch/mips/bcm63xx/Kconfig | 2 +
arch/mips/bcm63xx/Makefile | 2 +-
arch/mips/bcm63xx/boards/board_bcm963xx.c | 4 ++
arch/mips/bcm63xx/dev-usb-ehci.c | 49 ++++++++++++++++++++
.../asm/mach-bcm63xx/bcm63xx_dev_usb_ehci.h | 6 ++
5 files changed, 62 insertions(+), 1 deletions(-)
create mode 100644 arch/mips/bcm63xx/dev-usb-ehci.c
create mode 100644 arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ehci.h
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -26,6 +26,8 @@ config BCM63XX_CPU_6358
select USB_ARCH_HAS_OHCI
select USB_OHCI_BIG_ENDIAN_DESC
select USB_OHCI_BIG_ENDIAN_MMIO
+ select USB_ARCH_HAS_EHCI
+ select USB_EHCI_BIG_ENDIAN_MMIO
endmenu
source "arch/mips/bcm63xx/boards/Kconfig"
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -1,6 +1,6 @@
obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o \
- dev-usb-ohci.o
+ dev-usb-ohci.o dev-usb-ehci.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -26,6 +26,7 @@
#include <bcm63xx_dev_dsp.h>
#include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_usb_ohci.h>
+#include <bcm63xx_dev_usb_ehci.h>
#include <board_bcm963xx.h>
#define PFX "board_bcm963xx: "
@@ -878,6 +879,9 @@ int __init board_register_devices(void)
!board_get_mac_address(board.enet1.mac_addr))
bcm63xx_enet_register(1, &board.enet1);
+ if (board.has_ehci0)
+ bcm63xx_ehci_register();
+
if (board.has_ohci0)
bcm63xx_ohci_register();
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-usb-ehci.c
@@ -0,0 +1,49 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2010 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_usb_ehci.h>
+
+static struct resource ehci_resources[] = {
+ {
+ /* start & end filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* start filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ehci_dmamask = ~(u32)0;
+
+static struct platform_device bcm63xx_ehci_device = {
+ .name = "bcm63xx_ehci",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ehci_resources),
+ .resource = ehci_resources,
+ .dev = {
+ .dma_mask = &ehci_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+int __init bcm63xx_ehci_register(void)
+{
+ if (!BCMCPU_IS_6358())
+ return 0;
+
+ ehci_resources[0].start = bcm63xx_regset_address(RSET_EHCI0);
+ ehci_resources[0].end = ehci_resources[0].start;
+ ehci_resources[0].end += RSET_EHCI_SIZE - 1;
+ ehci_resources[1].start = bcm63xx_get_irq_number(IRQ_EHCI0);
+ return platform_device_register(&bcm63xx_ehci_device);
+}
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_ehci.h
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_USB_EHCI_H_
+#define BCM63XX_DEV_USB_EHCI_H_
+
+int bcm63xx_ehci_register(void);
+
+#endif /* BCM63XX_DEV_USB_EHCI_H_ */

@ -1,202 +0,0 @@
Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
---
drivers/usb/host/ohci-bcm63xx.c | 166 +++++++++++++++++++++++++++++++++++++++
drivers/usb/host/ohci-hcd.c | 5 +
drivers/usb/host/ohci.h | 2 +-
3 files changed, 172 insertions(+), 1 deletions(-)
create mode 100644 drivers/usb/host/ohci-bcm63xx.c
--- /dev/null
+++ b/drivers/usb/host/ohci-bcm63xx.c
@@ -0,0 +1,166 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2010 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+
+static struct clk *usb_host_clock;
+
+static int __devinit ohci_bcm63xx_start(struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ int ret;
+
+ /*
+ * port 2 can be shared with USB slave, but all boards seem to
+ * have only one host port populated, so we can hardcode it
+ */
+ ohci->num_ports = 1;
+
+ ret = ohci_init(ohci);
+ if (ret < 0)
+ return ret;
+
+ ret = ohci_run(ohci);
+ if (ret < 0) {
+ err("can't start %s", hcd->self.bus_name);
+ ohci_stop(hcd);
+ return ret;
+ }
+ return 0;
+}
+
+static const struct hc_driver ohci_bcm63xx_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "BCM63XX integrated OHCI controller",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
+
+ .irq = ohci_irq,
+ .flags = HCD_USB11 | HCD_MEMORY,
+ .start = ohci_bcm63xx_start,
+ .stop = ohci_stop,
+ .shutdown = ohci_shutdown,
+ .urb_enqueue = ohci_urb_enqueue,
+ .urb_dequeue = ohci_urb_dequeue,
+ .endpoint_disable = ohci_endpoint_disable,
+ .get_frame_number = ohci_get_frame,
+ .hub_status_data = ohci_hub_status_data,
+ .hub_control = ohci_hub_control,
+ .start_port_reset = ohci_start_port_reset,
+};
+
+static int __devinit ohci_hcd_bcm63xx_drv_probe(struct platform_device *pdev)
+{
+ struct resource *res_mem;
+ struct usb_hcd *hcd;
+ struct ohci_hcd *ohci;
+ u32 reg;
+ int ret, irq;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!res_mem || irq < 0)
+ return -ENODEV;
+
+ if (BCMCPU_IS_6348()) {
+ struct clk *clk;
+ /* enable USB host clock */
+ clk = clk_get(&pdev->dev, "usbh");
+ if (IS_ERR(clk))
+ return -ENODEV;
+
+ clk_enable(clk);
+ usb_host_clock = clk;
+ bcm_rset_writel(RSET_OHCI_PRIV, 0, OHCI_PRIV_REG);
+
+ } else if (BCMCPU_IS_6358()) {
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_REG);
+ reg &= ~USBH_PRIV_SWAP_OHCI_ENDN_MASK;
+ reg |= USBH_PRIV_SWAP_OHCI_DATA_MASK;
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_REG);
+ /*
+ * The magic value comes for the original vendor BSP
+ * and is needed for USB to work. Datasheet does not
+ * help, so the magic value is used as-is.
+ */
+ bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020, USBH_PRIV_TEST_REG);
+ } else
+ return 0;
+
+ hcd = usb_create_hcd(&ohci_bcm63xx_hc_driver, &pdev->dev, "bcm63xx");
+ if (!hcd)
+ return -ENOMEM;
+ hcd->rsrc_start = res_mem->start;
+ hcd->rsrc_len = res_mem->end - res_mem->start + 1;
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ pr_debug("request_mem_region failed\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ pr_debug("ioremap failed\n");
+ ret = -EIO;
+ goto out1;
+ }
+
+ ohci = hcd_to_ohci(hcd);
+ ohci->flags |= OHCI_QUIRK_BE_MMIO | OHCI_QUIRK_BE_DESC |
+ OHCI_QUIRK_FRAME_NO;
+ ohci_hcd_init(ohci);
+
+ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+ if (ret)
+ goto out2;
+
+ platform_set_drvdata(pdev, hcd);
+ return 0;
+
+out2:
+ iounmap(hcd->regs);
+out1:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+out:
+ usb_put_hcd(hcd);
+ return ret;
+}
+
+static int __devexit ohci_hcd_bcm63xx_drv_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd;
+
+ hcd = platform_get_drvdata(pdev);
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ usb_put_hcd(hcd);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ if (usb_host_clock) {
+ clk_disable(usb_host_clock);
+ clk_put(usb_host_clock);
+ }
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static struct platform_driver ohci_hcd_bcm63xx_driver = {
+ .probe = ohci_hcd_bcm63xx_drv_probe,
+ .remove = __devexit_p(ohci_hcd_bcm63xx_drv_remove),
+ .shutdown = usb_hcd_platform_shutdown,
+ .driver = {
+ .name = "bcm63xx_ohci",
+ .owner = THIS_MODULE,
+ },
+};
+
+MODULE_ALIAS("platform:bcm63xx_ohci");
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1061,6 +1061,11 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_hcd_da8xx_driver
#endif
+#ifdef CONFIG_BCM63XX
+#include "ohci-bcm63xx.c"
+#define PLATFORM_DRIVER ohci_hcd_bcm63xx_driver
+#endif
+
#if defined(CONFIG_CPU_SUBTYPE_SH7720) || \
defined(CONFIG_CPU_SUBTYPE_SH7721) || \
defined(CONFIG_CPU_SUBTYPE_SH7763) || \
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -655,7 +655,7 @@ static inline u32 hc32_to_cpup (const st
* some big-endian SOC implementations. Same thing happens with PSW access.
*/
-#ifdef CONFIG_PPC_MPC52xx
+#if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_BCM63XX)
#define big_endian_frame_no_quirk(ohci) (ohci->flags & OHCI_QUIRK_FRAME_NO)
#else
#define big_endian_frame_no_quirk(ohci) 0

@ -1,178 +0,0 @@
Signed-off-by: Maxime Bizon <mbizon@freebox.fr>
---
drivers/usb/host/ehci-bcm63xx.c | 154 +++++++++++++++++++++++++++++++++++++++
drivers/usb/host/ehci-hcd.c | 5 +
2 files changed, 159 insertions(+), 0 deletions(-)
create mode 100644 drivers/usb/host/ehci-bcm63xx.c
--- /dev/null
+++ b/drivers/usb/host/ehci-bcm63xx.c
@@ -0,0 +1,154 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ */
+
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+
+static int ehci_bcm63xx_setup(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ int retval;
+
+ retval = ehci_halt(ehci);
+ if (retval)
+ return retval;
+
+ retval = ehci_init(hcd);
+ if (retval)
+ return retval;
+
+ ehci_reset(ehci);
+ ehci_port_power(ehci, 0);
+
+ return retval;
+}
+
+
+static const struct hc_driver ehci_bcm63xx_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "BCM63XX integrated EHCI controller",
+ .hcd_priv_size = sizeof(struct ehci_hcd),
+
+ .irq = ehci_irq,
+ .flags = HCD_MEMORY | HCD_USB2,
+
+ .reset = ehci_bcm63xx_setup,
+ .start = ehci_run,
+ .stop = ehci_stop,
+ .shutdown = ehci_shutdown,
+
+ .urb_enqueue = ehci_urb_enqueue,
+ .urb_dequeue = ehci_urb_dequeue,
+ .endpoint_disable = ehci_endpoint_disable,
+
+ .get_frame_number = ehci_get_frame,
+
+ .hub_status_data = ehci_hub_status_data,
+ .hub_control = ehci_hub_control,
+ .bus_suspend = ehci_bus_suspend,
+ .bus_resume = ehci_bus_resume,
+ .relinquish_port = ehci_relinquish_port,
+ .port_handed_over = ehci_port_handed_over,
+};
+
+static int __devinit ehci_hcd_bcm63xx_drv_probe(struct platform_device *pdev)
+{
+ struct resource *res_mem;
+ struct usb_hcd *hcd;
+ struct ehci_hcd *ehci;
+ u32 reg;
+ int ret, irq;
+
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);;
+ if (!res_mem || irq < 0)
+ return -ENODEV;
+
+ reg = bcm_rset_readl(RSET_USBH_PRIV, USBH_PRIV_SWAP_REG);
+ reg &= ~USBH_PRIV_SWAP_EHCI_DATA_MASK;
+ reg |= USBH_PRIV_SWAP_EHCI_ENDN_MASK;
+ bcm_rset_writel(RSET_USBH_PRIV, reg, USBH_PRIV_SWAP_REG);
+
+ /*
+ * The magic value comes for the original vendor BSP and is
+ * needed for USB to work. Datasheet does not help, so the
+ * magic value is used as-is.
+ */
+ bcm_rset_writel(RSET_USBH_PRIV, 0x1c0020, USBH_PRIV_TEST_REG);
+
+ hcd = usb_create_hcd(&ehci_bcm63xx_hc_driver, &pdev->dev, "bcm63xx");
+ if (!hcd)
+ return -ENOMEM;
+ hcd->rsrc_start = res_mem->start;
+ hcd->rsrc_len = res_mem->end - res_mem->start + 1;
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ pr_debug("request_mem_region failed\n");
+ ret = -EBUSY;
+ goto out;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ pr_debug("ioremap failed\n");
+ ret = -EIO;
+ goto out1;
+ }
+
+ ehci = hcd_to_ehci(hcd);
+ ehci->big_endian_mmio = 1;
+ ehci->big_endian_desc = 0;
+ ehci->caps = hcd->regs;
+ ehci->regs = hcd->regs +
+ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+ ehci->sbrn = 0x20;
+
+ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+ if (ret)
+ goto out2;
+
+ platform_set_drvdata(pdev, hcd);
+ return 0;
+
+out2:
+ iounmap(hcd->regs);
+out1:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+out:
+ usb_put_hcd(hcd);
+ return ret;
+}
+
+static int __devexit ehci_hcd_bcm63xx_drv_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd;
+
+ hcd = platform_get_drvdata(pdev);
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ usb_put_hcd(hcd);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static struct platform_driver ehci_hcd_bcm63xx_driver = {
+ .probe = ehci_hcd_bcm63xx_drv_probe,
+ .remove = __devexit_p(ehci_hcd_bcm63xx_drv_remove),
+ .shutdown = usb_hcd_platform_shutdown,
+ .driver = {
+ .name = "bcm63xx_ehci",
+ .owner = THIS_MODULE,
+ },
+};
+
+MODULE_ALIAS("platform:bcm63xx_ehci");
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1158,6 +1158,11 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_atmel_driver
#endif
+#ifdef CONFIG_BCM63XX
+#include "ehci-bcm63xx.c"
+#define PLATFORM_DRIVER ehci_hcd_bcm63xx_driver
+#endif
+
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
!defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
!defined(XILINX_OF_PLATFORM_DRIVER)

@ -1,386 +0,0 @@
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -114,6 +114,7 @@ obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt
obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
+obj-$(CONFIG_BCM63XX_WDT) += bcm63xx_wdt.o
# PARISC Architecture
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -875,6 +875,16 @@ config TXX9_WDT
help
Hardware driver for the built-in watchdog timer on TXx9 MIPS SoCs.
+config BCM63XX_WDT
+ tristate "Broadcom BCM63xx hardware watchdog"
+ depends on BCM63XX
+ help
+ Watchdog driver for the built in watchdog hardware in Broadcom
+ BCM63xx SoC.
+
+ To compile thi driver as a loadable module, choose M here.
+ The module will be called bcm63xx_wdt.
+
# PARISC Architecture
# POWERPC Architecture
--- /dev/null
+++ b/drivers/watchdog/bcm63xx_wdt.c
@@ -0,0 +1,354 @@
+/*
+ * Broadcom BCM63xx SoC watchdog driver
+ *
+ * Copyright (C) 2007, Miguel Gaio <miguel.gaio@efixo.com>
+ * Copyright (C) 2008, Florian Fainelli <florian@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/reboot.h>
+#include <linux/types.h>
+#include <linux/uaccess.h>
+#include <linux/watchdog.h>
+#include <linux/timer.h>
+#include <linux/jiffies.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/resource.h>
+#include <linux/platform_device.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_timer.h>
+
+#define PFX KBUILD_MODNAME
+
+#define WDT_HZ 50000000 /* Fclk */
+#define WDT_DEFAULT_TIME 30 /* seconds */
+#define WDT_MAX_TIME 256 /* seconds */
+
+static struct {
+ void __iomem *regs;
+ struct timer_list timer;
+ int default_ticks;
+ unsigned long inuse;
+ atomic_t ticks;
+} bcm63xx_wdt_device;
+
+static int expect_close;
+
+static int wdt_time = WDT_DEFAULT_TIME;
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+/* HW functions */
+static void bcm63xx_wdt_hw_start(void)
+{
+ bcm_writel(0xfffffffe, bcm63xx_wdt_device.regs + WDT_DEFVAL_REG);
+ bcm_writel(WDT_START_1, bcm63xx_wdt_device.regs + WDT_CTL_REG);
+ bcm_writel(WDT_START_2, bcm63xx_wdt_device.regs + WDT_CTL_REG);
+}
+
+static void bcm63xx_wdt_hw_stop(void)
+{
+ bcm_writel(WDT_STOP_1, bcm63xx_wdt_device.regs + WDT_CTL_REG);
+ bcm_writel(WDT_STOP_2, bcm63xx_wdt_device.regs + WDT_CTL_REG);
+}
+
+static void bcm63xx_wdt_isr(void *data)
+{
+ struct pt_regs *regs = get_irq_regs();
+
+ die(PFX " fire", regs);
+}
+
+static void bcm63xx_timer_tick(unsigned long unused)
+{
+ if (!atomic_dec_and_test(&bcm63xx_wdt_device.ticks)) {
+ bcm63xx_wdt_hw_start();
+ mod_timer(&bcm63xx_wdt_device.timer, jiffies + HZ);
+ } else
+ printk(KERN_CRIT PFX ": watchdog will restart system\n");
+}
+
+static void bcm63xx_wdt_pet(void)
+{
+ atomic_set(&bcm63xx_wdt_device.ticks, wdt_time);
+}
+
+static void bcm63xx_wdt_start(void)
+{
+ bcm63xx_wdt_pet();
+ bcm63xx_timer_tick(0);
+}
+
+static void bcm63xx_wdt_pause(void)
+{
+ del_timer_sync(&bcm63xx_wdt_device.timer);
+ bcm63xx_wdt_hw_stop();
+}
+
+static int bcm63xx_wdt_settimeout(int new_time)
+{
+ if ((new_time <= 0) || (new_time > WDT_MAX_TIME))
+ return -EINVAL;
+
+ wdt_time = new_time;
+
+ return 0;
+}
+
+static int bcm63xx_wdt_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(0, &bcm63xx_wdt_device.inuse))
+ return -EBUSY;
+
+ bcm63xx_wdt_start();
+ return nonseekable_open(inode, file);
+}
+
+static int bcm63xx_wdt_release(struct inode *inode, struct file *file)
+{
+ if (expect_close == 42)
+ bcm63xx_wdt_pause();
+ else {
+ printk(KERN_CRIT PFX
+ ": Unexpected close, not stopping watchdog!\n");
+ bcm63xx_wdt_start();
+ }
+ clear_bit(0, &bcm63xx_wdt_device.inuse);
+ expect_close = 0;
+ return 0;
+}
+
+static ssize_t bcm63xx_wdt_write(struct file *file, const char *data,
+ size_t len, loff_t *ppos)
+{
+ if (len) {
+ if (!nowayout) {
+ size_t i;
+
+ /* In case it was set long ago */
+ expect_close = 0;
+
+ for (i = 0; i != len; i++) {
+ char c;
+ if (get_user(c, data + i))
+ return -EFAULT;
+ if (c == 'V')
+ expect_close = 42;
+ }
+ }
+ bcm63xx_wdt_pet();
+ }
+ return len;
+}
+
+static struct watchdog_info bcm63xx_wdt_info = {
+ .identity = PFX,
+ .options = WDIOF_SETTIMEOUT |
+ WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
+};
+
+
+static long bcm63xx_wdt_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ int new_value, retval = -EINVAL;
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ return copy_to_user(argp, &bcm63xx_wdt_info,
+ sizeof(bcm63xx_wdt_info)) ? -EFAULT : 0;
+
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(0, p);
+
+ case WDIOC_SETOPTIONS:
+ if (get_user(new_value, p))
+ return -EFAULT;
+
+ if (new_value & WDIOS_DISABLECARD) {
+ bcm63xx_wdt_pause();
+ retval = 0;
+ }
+ if (new_value & WDIOS_ENABLECARD) {
+ bcm63xx_wdt_start();
+ retval = 0;
+ }
+
+ return retval;
+
+ case WDIOC_KEEPALIVE:
+ bcm63xx_wdt_pet();
+ return 0;
+
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_value, p))
+ return -EFAULT;
+
+ if (bcm63xx_wdt_settimeout(new_value))
+ return -EINVAL;
+
+ bcm63xx_wdt_pet();
+
+ case WDIOC_GETTIMEOUT:
+ return put_user(wdt_time, p);
+
+ default:
+ return -ENOTTY;
+
+ }
+}
+
+static int bcm63xx_wdt_notify_sys(struct notifier_block *this,
+ unsigned long code, void *unused)
+{
+ if (code == SYS_DOWN || code == SYS_HALT)
+ bcm63xx_wdt_pause();
+ return NOTIFY_DONE;
+}
+
+static const struct file_operations bcm63xx_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = bcm63xx_wdt_write,
+ .unlocked_ioctl = bcm63xx_wdt_ioctl,
+ .open = bcm63xx_wdt_open,
+ .release = bcm63xx_wdt_release,
+};
+
+static struct miscdevice bcm63xx_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &bcm63xx_wdt_fops,
+};
+
+static struct notifier_block bcm63xx_wdt_notifier = {
+ .notifier_call = bcm63xx_wdt_notify_sys,
+};
+
+
+static int bcm63xx_wdt_probe(struct platform_device *pdev)
+{
+ int ret;
+ struct resource *r;
+
+ setup_timer(&bcm63xx_wdt_device.timer, bcm63xx_timer_tick, 0L);
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r) {
+ printk(KERN_ERR PFX
+ "failed to retrieve resources\n");
+ return -ENODEV;
+ }
+
+ bcm63xx_wdt_device.regs = ioremap_nocache(r->start, r->end - r->start);
+ if (!bcm63xx_wdt_device.regs) {
+ printk(KERN_ERR PFX
+ "failed to remap I/O resources\n");
+ return -ENXIO;
+ }
+
+ ret = bcm63xx_timer_register(TIMER_WDT_ID, bcm63xx_wdt_isr, NULL);
+ if (ret < 0) {
+ printk(KERN_ERR PFX
+ "failed to register wdt timer isr\n");
+ goto unmap;
+ }
+
+ if (bcm63xx_wdt_settimeout(wdt_time)) {
+ bcm63xx_wdt_settimeout(WDT_DEFAULT_TIME);
+ printk(KERN_INFO PFX
+ ": wdt_time value must be 1 <= wdt_time <= 256, using %d\n",
+ wdt_time);
+ }
+
+ ret = register_reboot_notifier(&bcm63xx_wdt_notifier);
+ if (ret) {
+ printk(KERN_ERR PFX
+ "failed to register reboot_notifier\n");
+ goto unregister_timer;
+ }
+
+ ret = misc_register(&bcm63xx_wdt_miscdev);
+ if (ret < 0) {
+ printk(KERN_ERR PFX
+ "failed to register watchdog device\n");
+ goto unregister_reboot_notifier;
+ }
+
+ printk(KERN_INFO PFX " started, timer margin: %d sec\n", WDT_DEFAULT_TIME);
+
+ return 0;
+
+unregister_reboot_notifier:
+ unregister_reboot_notifier(&bcm63xx_wdt_notifier);
+unregister_timer:
+ bcm63xx_timer_unregister(TIMER_WDT_ID);
+unmap:
+ iounmap(bcm63xx_wdt_device.regs);
+ return ret;
+}
+
+static int bcm63xx_wdt_remove(struct platform_device *pdev)
+{
+ if (!nowayout)
+ bcm63xx_wdt_pause();
+
+ misc_deregister(&bcm63xx_wdt_miscdev);
+
+ iounmap(bcm63xx_wdt_device.regs);
+
+ unregister_reboot_notifier(&bcm63xx_wdt_notifier);
+ bcm63xx_timer_unregister(TIMER_WDT_ID);
+
+ return 0;
+}
+
+static struct platform_driver bcm63xx_wdt = {
+ .probe = bcm63xx_wdt_probe,
+ .remove = bcm63xx_wdt_remove,
+ .driver = {
+ .name = "bcm63xx-wdt",
+ }
+};
+
+static int __init bcm63xx_wdt_init(void)
+{
+ return platform_driver_register(&bcm63xx_wdt);
+}
+
+static void __exit bcm63xx_wdt_exit(void)
+{
+ platform_driver_unregister(&bcm63xx_wdt);
+}
+
+module_init(bcm63xx_wdt_init);
+module_exit(bcm63xx_wdt_exit);
+
+MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>");
+MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
+MODULE_DESCRIPTION("Driver for the Broadcom BCM63xx SoC watchdog");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:bcm63xx-wdt");

@ -1,389 +0,0 @@
From e734ace5baa04e0e8af1d4483475fbd6bd2b32a1 Mon Sep 17 00:00:00 2001
From: Axel Gembe <ago@bastart.eu.org>
Date: Mon, 12 May 2008 18:54:09 +0200
Subject: [PATCH] bcm963xx: flashmap support
Signed-off-by: Axel Gembe <ago@bastart.eu.org>
---
drivers/mtd/maps/Kconfig | 7 +++++++
drivers/mtd/maps/Makefile | 1 +
drivers/mtd/redboot.c | 13 ++++++++++---
3 files changed, 18 insertions(+), 3 deletions(-)
--- a/drivers/mtd/maps/Kconfig
+++ b/drivers/mtd/maps/Kconfig
@@ -251,6 +251,13 @@ config MTD_NETtel
help
Support for flash chips on NETtel/SecureEdge/SnapGear boards.
+config MTD_BCM963XX
+ tristate "BCM963xx Flash device"
+ depends on MIPS && BCM63XX
+ help
+ Flash memory access on BCM963xx boards. Currently only works with
+ RedBoot and CFE.
+
config MTD_DILNETPC
tristate "CFI Flash device mapped on DIL/Net PC"
depends on X86 && MTD_CONCAT && MTD_PARTITIONS && MTD_CFI_INTELEXT && BROKEN
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -39,7 +39,7 @@ static inline int redboot_checksum(struc
return 1;
}
-static int parse_redboot_partitions(struct mtd_info *master,
+int parse_redboot_partitions(struct mtd_info *master,
struct mtd_partition **pparts,
unsigned long fis_origin)
{
@@ -162,6 +162,14 @@ static int parse_redboot_partitions(stru
goto out;
}
+ if (!fis_origin) {
+ for (i = 0; i < numslots; i++) {
+ if (!strncmp(buf[i].name, "RedBoot", 8)) {
+ fis_origin = (buf[i].flash_base & (master->size << 1) - 1);
+ }
+ }
+ }
+
for (i = 0; i < numslots; i++) {
struct fis_list *new_fl, **prev;
@@ -184,9 +192,8 @@ static int parse_redboot_partitions(stru
new_fl->img = &buf[i];
if (fis_origin) {
buf[i].flash_base -= fis_origin;
- } else {
- buf[i].flash_base &= master->size-1;
}
+ buf[i].flash_base &= (master->size << 1) - 1;
/* I'm sure the JFFS2 code has done me permanent damage.
* I now think the following is _normal_
--- a/drivers/mtd/maps/Makefile
+++ b/drivers/mtd/maps/Makefile
@@ -59,3 +59,4 @@ obj-$(CONFIG_MTD_BFIN_ASYNC) += bfin-asy
obj-$(CONFIG_MTD_RBTX4939) += rbtx4939-flash.o
obj-$(CONFIG_MTD_VMU) += vmu-flash.o
obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o
+obj-$(CONFIG_MTD_BCM963XX) += bcm963xx-flash.o
--- /dev/null
+++ b/drivers/mtd/maps/bcm963xx-flash.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2006-2008 Florian Fainelli <florian@openwrt.org>
+ * Mike Albon <malbon@openwrt.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/platform_device.h>
+#include <linux/magic.h>
+#include <linux/jffs2.h>
+
+#include <bcm_tag.h>
+#include <asm/io.h>
+
+#define BUSWIDTH 2 /* Buswidth */
+#define EXTENDED_SIZE 0xBFC00000 /* Extended flash address */
+
+#define PFX KBUILD_MODNAME ": "
+
+struct squashfs_super_block {
+ __le32 s_magic;
+ __le32 pad0[9];
+ __le64 bytes_used;
+};
+
+extern int parse_redboot_partitions(struct mtd_info *master, struct mtd_partition **pparts, unsigned long fis_origin);
+static struct mtd_partition *parsed_parts;
+
+static struct mtd_info *bcm963xx_mtd_info;
+
+static struct map_info bcm963xx_map = {
+ .name = "bcm963xx",
+ .bankwidth = BUSWIDTH,
+};
+
+static int parse_cfe_partitions( struct mtd_info *master, struct mtd_partition **pparts)
+{
+ int nrparts = 3, curpart = 0; /* CFE,NVRAM and global LINUX are always present. */
+ struct bcm_tag *buf;
+ struct mtd_partition *parts;
+ int ret;
+ size_t retlen;
+ unsigned int rootfsaddr, kerneladdr, spareaddr;
+ unsigned int rootfslen, kernellen, sparelen;
+ int namelen = 0;
+ int i, offset;
+ char *boardid;
+ char *tagversion;
+
+ /* Allocate memory for buffer */
+ buf = vmalloc(sizeof(struct bcm_tag));
+ if (!buf)
+ return -ENOMEM;
+
+ /* Get the tag */
+ ret = master->read(master, master->erasesize, sizeof(struct bcm_tag), &retlen, (void *)buf);
+ if (retlen != sizeof(struct bcm_tag)){
+ vfree(buf);
+ return -EIO;
+ }
+
+ sscanf(buf->kernelAddress, "%u", &kerneladdr);
+ sscanf(buf->kernelLength, "%u", &kernellen);
+ rootfslen = *(uint32_t *)(&(buf->rootLength[0]));
+ tagversion = &(buf->tagVersion[0]);
+ boardid = &(buf->boardid[0]);
+
+ printk(KERN_INFO PFX "CFE boot tag found with version %s and board type %s\n",tagversion, boardid);
+
+ kerneladdr = kerneladdr - EXTENDED_SIZE;
+ rootfsaddr = kerneladdr + kernellen;
+
+ rootfslen = ( ( rootfslen % master->erasesize ) > 0 ? (((rootfslen / master->erasesize) + 1 ) * master->erasesize) : rootfslen);
+
+ spareaddr = rootfsaddr + rootfslen;
+ sparelen = master->size - spareaddr - master->erasesize;
+
+ /* Determine number of partitions */
+ namelen = 8;
+ if (rootfslen > 0){
+ nrparts++;
+ namelen =+ 6;
+ };
+ if (kernellen > 0) {
+ nrparts++;
+ namelen =+ 6;
+ };
+
+ /* Ask kernel for more memory */
+ parts = kzalloc(sizeof(*parts) * nrparts + 10 * nrparts, GFP_KERNEL);
+ if (!parts) {
+ vfree(buf);
+ return -ENOMEM;
+ };
+
+ /* Start building partition list */
+ parts[curpart].name = "CFE";
+ parts[curpart].offset = 0;
+ parts[curpart].size = master->erasesize;
+ curpart++;
+
+ if (kernellen > 0) {
+ parts[curpart].name = "kernel";
+ parts[curpart].offset = kerneladdr;
+ parts[curpart].size = kernellen;
+ curpart++;
+ };
+
+ if (rootfslen > 0) {
+ parts[curpart].name = "rootfs";
+ parts[curpart].offset = rootfsaddr;
+ parts[curpart].size = rootfslen;
+ if (sparelen > 0)
+ parts[curpart].size += sparelen;
+ curpart++;
+ };
+
+ parts[curpart].name = "nvram";
+ parts[curpart].offset = master->size - master->erasesize;
+ parts[curpart].size = master->erasesize;
+
+ /* Global partition "linux" to make easy firmware upgrade */
+ curpart++;
+ parts[curpart].name = "linux";
+ parts[curpart].offset = parts[0].size;
+ parts[curpart].size = master->size - parts[0].size - parts[3].size;
+
+ for (i = 0; i < nrparts; i++)
+ printk(KERN_INFO PFX "Partition %d is %s offset %lx and length %lx\n", i, parts[i].name, (long unsigned int)(parts[i].offset), (long unsigned int)(parts[i].size));
+
+ printk(KERN_INFO PFX "Spare partition is %x offset and length %x\n", spareaddr, sparelen);
+ *pparts = parts;
+ vfree(buf);
+
+ return nrparts;
+};
+
+static int bcm963xx_detect_cfe(struct mtd_info *master)
+{
+ int idoffset = 0x4e0;
+ static char idstring[8] = "CFE1CFE1";
+ char buf[9];
+ int ret;
+ size_t retlen;
+
+ ret = master->read(master, idoffset, 8, &retlen, (void *)buf);
+ buf[retlen] = 0;
+ printk(KERN_INFO PFX "Read Signature value of %s\n", buf);
+
+ return strncmp(idstring, buf, 8);
+}
+
+static int bcm963xx_probe(struct platform_device *pdev)
+{
+ int err = 0;
+ int parsed_nr_parts = 0;
+ char *part_type;
+ struct resource *r;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ bcm963xx_map.phys = r->start;
+ bcm963xx_map.size = (r->end - r->start) + 1;
+ bcm963xx_map.virt = ioremap(r->start, r->end - r->start + 1);
+
+ if (!bcm963xx_map.virt) {
+ printk(KERN_ERR PFX "Failed to ioremap\n");
+ return -EIO;
+ }
+ printk(KERN_INFO PFX "0x%08lx at 0x%08x\n", bcm963xx_map.size, bcm963xx_map.phys);
+
+ simple_map_init(&bcm963xx_map);
+
+ bcm963xx_mtd_info = do_map_probe("cfi_probe", &bcm963xx_map);
+ if (!bcm963xx_mtd_info) {
+ printk(KERN_ERR PFX "Failed to probe using CFI\n");
+ err = -EIO;
+ goto err_probe;
+ }
+
+ bcm963xx_mtd_info->owner = THIS_MODULE;
+
+ /* This is mutually exclusive */
+ if (bcm963xx_detect_cfe(bcm963xx_mtd_info) == 0) {
+ printk(KERN_INFO PFX "CFE bootloader detected\n");
+ if (parsed_nr_parts == 0) {
+ int ret = parse_cfe_partitions(bcm963xx_mtd_info, &parsed_parts);
+ if (ret > 0) {
+ part_type = "CFE";
+ parsed_nr_parts = ret;
+ }
+ }
+ } else {
+ printk(KERN_INFO PFX "assuming RedBoot bootloader\n");
+ if (bcm963xx_mtd_info->size > 0x00400000) {
+ printk(KERN_INFO PFX "Support for extended flash memory size : 0x%lx ; ONLY 64MBIT SUPPORT\n", bcm963xx_mtd_info->size);
+ bcm963xx_map.virt = (u32)(EXTENDED_SIZE);
+ }
+
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+ if (parsed_nr_parts == 0) {
+ int ret = parse_redboot_partitions(bcm963xx_mtd_info, &parsed_parts, 0);
+ if (ret > 0) {
+ part_type = "RedBoot";
+ parsed_nr_parts = ret;
+ }
+ }
+#endif
+ }
+
+ return add_mtd_partitions(bcm963xx_mtd_info, parsed_parts, parsed_nr_parts);
+
+err_probe:
+ iounmap(bcm963xx_map.virt);
+ return err;
+}
+
+static int bcm963xx_remove(struct platform_device *pdev)
+{
+ if (bcm963xx_mtd_info) {
+ del_mtd_partitions(bcm963xx_mtd_info);
+ map_destroy(bcm963xx_mtd_info);
+ }
+
+ if (bcm963xx_map.virt) {
+ iounmap(bcm963xx_map.virt);
+ bcm963xx_map.virt = 0;
+ }
+
+ return 0;
+}
+
+static struct platform_driver bcm63xx_mtd_dev = {
+ .probe = bcm963xx_probe,
+ .remove = bcm963xx_remove,
+ .driver = {
+ .name = "bcm963xx-flash",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init bcm963xx_mtd_init(void)
+{
+ return platform_driver_register(&bcm63xx_mtd_dev);
+}
+
+static void __exit bcm963xx_mtd_exit(void)
+{
+ platform_driver_unregister(&bcm63xx_mtd_dev);
+}
+
+module_init(bcm963xx_mtd_init);
+module_exit(bcm963xx_mtd_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Broadcom BCM63xx MTD partition parser/mapping for CFE and RedBoot");
+MODULE_AUTHOR("Florian Fainelli <florian@openwrt.org>");
+MODULE_AUTHOR("Mike Albon <malbon@openwrt.org>");
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -816,20 +816,6 @@ void __init board_setup(void)
panic("unexpected CPU for bcm963xx board");
}
-static struct mtd_partition mtd_partitions[] = {
- {
- .name = "cfe",
- .offset = 0x0,
- .size = 0x40000,
- }
-};
-
-static struct physmap_flash_data flash_data = {
- .width = 2,
- .nr_parts = ARRAY_SIZE(mtd_partitions),
- .parts = mtd_partitions,
-};
-
static struct resource mtd_resources[] = {
{
.start = 0, /* filled at runtime */
@@ -839,12 +825,9 @@ static struct resource mtd_resources[] =
};
static struct platform_device mtd_dev = {
- .name = "physmap-flash",
+ .name = "bcm963xx-flash",
.resource = mtd_resources,
.num_resources = ARRAY_SIZE(mtd_resources),
- .dev = {
- .platform_data = &flash_data,
- },
};
static struct gpio_led_platform_data bcm63xx_led_data;

@ -1,11 +0,0 @@
--- a/drivers/net/bcm63xx_enet.c
+++ b/drivers/net/bcm63xx_enet.c
@@ -1520,7 +1520,7 @@ static int compute_hw_mtu(struct bcm_ene
actual_mtu = mtu;
/* add ethernet header + vlan tag size */
- actual_mtu += VLAN_ETH_HLEN;
+ actual_mtu += VLAN_ETH_HLEN + VLAN_HLEN;
if (actual_mtu < 64 || actual_mtu > BCMENET_MAX_MTU)
return -EINVAL;

@ -1,98 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -15,6 +15,8 @@
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <linux/ssb/ssb.h>
+#include <linux/gpio_buttons.h>
+#include <linux/input.h>
#include <asm/addrspace.h>
#include <bcm63xx_board.h>
#include <bcm63xx_cpu.h>
@@ -296,6 +298,16 @@ static struct board_info __initdata boar
.active_low = 1,
},
},
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 33,
+ .active_low = 1,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ },
};
static struct board_info __initdata board_96348gw = {
@@ -354,6 +366,16 @@ static struct board_info __initdata boar
.active_low = 1,
},
},
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 36,
+ .active_low = 1,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ },
};
static struct board_info __initdata board_FAST2404 = {
@@ -838,12 +860,23 @@ static struct platform_device bcm63xx_gp
.dev.platform_data = &bcm63xx_led_data,
};
+static struct gpio_buttons_platform_data bcm63xx_gpio_buttons_data = {
+ .poll_interval = 20,
+};
+
+static struct platform_device bcm63xx_gpio_buttons_device = {
+ .name = "gpio-buttons",
+ .id = 0,
+ .dev.platform_data = &bcm63xx_gpio_buttons_data,
+};
+
/*
* third stage init callback, register all board devices.
*/
int __init board_register_devices(void)
{
u32 val;
+ int button_count = 0;
if (board.has_uart0)
bcm63xx_uart_register(0);
@@ -888,5 +921,16 @@ int __init board_register_devices(void)
platform_device_register(&bcm63xx_gpio_leds);
+ /* count number of BUTTONs defined by this device */
+ while (button_count < ARRAY_SIZE(board.buttons) && board.buttons[button_count].desc)
+ button_count++;
+
+ if (button_count) {
+ bcm63xx_gpio_buttons_data.nbuttons = button_count;
+ bcm63xx_gpio_buttons_data.buttons = board.buttons;
+
+ platform_device_register(&bcm63xx_gpio_buttons_device);
+ }
+
return 0;
}
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -57,6 +57,9 @@ struct board_info {
/* GPIO LEDs */
struct gpio_led leds[5];
+
+ /* Buttons */
+ struct gpio_button buttons[2];
};
#endif /* ! BOARD_BCM963XX_H_ */

@ -1,22 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -852,6 +852,10 @@ static struct platform_device mtd_dev =
.num_resources = ARRAY_SIZE(mtd_resources),
};
+static struct resource gpiodev_resource = {
+ .start = 0xFFFFFFFF,
+};
+
static struct gpio_led_platform_data bcm63xx_led_data;
static struct platform_device bcm63xx_gpio_leds = {
@@ -916,6 +920,8 @@ int __init board_register_devices(void)
platform_device_register(&mtd_dev);
+ platform_device_register_simple("GPIODEV", 0, &gpiodev_resource, 1);
+
bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
bcm63xx_led_data.leds = board.leds;

@ -1,237 +0,0 @@
From 04bb2a031cf95b34b7432dd47b318a932a895b4c Mon Sep 17 00:00:00 2001
From: Marek Szyprowski <m.szyprowski@samsung.com>
Date: Wed, 30 Jun 2010 14:27:32 -0600
Subject: [PATCH] spi/bitbang: add support for SPI_MASTER_NO_{TX, RX} modes
This patch adds a new flags argument to bitbang_txrx_be_cpha0 and
bitbang_txrx_be_cpha1 transfer functions. This enables support for
SPI_MASTER_NO_{TX,RX} transfer modes. The change should have no impact
on speed of the existing drivers. bitbank_txrx_* functions are usually
inlined into the drivers. When the argument is equal to constant zero,
the optimizer would be able to eliminate the dead code (flags checks)
easily. Tested on ARM and GCC 4.4.x and in all cases the checks were
eliminated in the inlined function.
Reviewed-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/spi/spi_bitbang_txrx.h | 16 ++++++++++------
drivers/spi/spi_butterfly.c | 2 +-
drivers/spi/spi_gpio.c | 8 ++++----
drivers/spi/spi_lm70llp.c | 2 +-
drivers/spi/spi_s3c24xx_gpio.c | 8 ++++----
drivers/spi/spi_sh_sci.c | 8 ++++----
6 files changed, 24 insertions(+), 20 deletions(-)
--- a/drivers/spi/spi_bitbang_txrx.h
+++ b/drivers/spi/spi_bitbang_txrx.h
@@ -44,7 +44,7 @@
static inline u32
bitbang_txrx_be_cpha0(struct spi_device *spi,
- unsigned nsecs, unsigned cpol,
+ unsigned nsecs, unsigned cpol, unsigned flags,
u32 word, u8 bits)
{
/* if (cpol == 0) this is SPI_MODE_0; else this is SPI_MODE_2 */
@@ -53,7 +53,8 @@ bitbang_txrx_be_cpha0(struct spi_device
for (word <<= (32 - bits); likely(bits); bits--) {
/* setup MSB (to slave) on trailing edge */
- setmosi(spi, word & (1 << 31));
+ if ((flags & SPI_MASTER_NO_TX) == 0)
+ setmosi(spi, word & (1 << 31));
spidelay(nsecs); /* T(setup) */
setsck(spi, !cpol);
@@ -61,7 +62,8 @@ bitbang_txrx_be_cpha0(struct spi_device
/* sample MSB (from slave) on leading edge */
word <<= 1;
- word |= getmiso(spi);
+ if ((flags & SPI_MASTER_NO_RX) == 0)
+ word |= getmiso(spi);
setsck(spi, cpol);
}
return word;
@@ -69,7 +71,7 @@ bitbang_txrx_be_cpha0(struct spi_device
static inline u32
bitbang_txrx_be_cpha1(struct spi_device *spi,
- unsigned nsecs, unsigned cpol,
+ unsigned nsecs, unsigned cpol, unsigned flags,
u32 word, u8 bits)
{
/* if (cpol == 0) this is SPI_MODE_1; else this is SPI_MODE_3 */
@@ -79,7 +81,8 @@ bitbang_txrx_be_cpha1(struct spi_device
/* setup MSB (to slave) on leading edge */
setsck(spi, !cpol);
- setmosi(spi, word & (1 << 31));
+ if ((flags & SPI_MASTER_NO_TX) == 0)
+ setmosi(spi, word & (1 << 31));
spidelay(nsecs); /* T(setup) */
setsck(spi, cpol);
@@ -87,7 +90,8 @@ bitbang_txrx_be_cpha1(struct spi_device
/* sample MSB (from slave) on trailing edge */
word <<= 1;
- word |= getmiso(spi);
+ if ((flags & SPI_MASTER_NO_RX) == 0)
+ word |= getmiso(spi);
}
return word;
}
--- a/drivers/spi/spi_butterfly.c
+++ b/drivers/spi/spi_butterfly.c
@@ -156,7 +156,7 @@ butterfly_txrx_word_mode0(struct spi_dev
unsigned nsecs,
u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
}
/*----------------------------------------------------------------------*/
--- a/drivers/spi/spi_gpio.c
+++ b/drivers/spi/spi_gpio.c
@@ -157,25 +157,25 @@ static inline void spidelay(unsigned nse
static u32 spi_gpio_txrx_word_mode0(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
}
static u32 spi_gpio_txrx_word_mode1(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits);
}
static u32 spi_gpio_txrx_word_mode2(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits);
}
static u32 spi_gpio_txrx_word_mode3(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
}
/*----------------------------------------------------------------------*/
--- a/drivers/spi/spi_lm70llp.c
+++ b/drivers/spi/spi_lm70llp.c
@@ -191,7 +191,7 @@ static void lm70_chipselect(struct spi_d
*/
static u32 lm70_txrx(struct spi_device *spi, unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
}
static void spi_lm70llp_attach(struct parport *p)
--- a/drivers/spi/spi_s3c24xx_gpio.c
+++ b/drivers/spi/spi_s3c24xx_gpio.c
@@ -64,25 +64,25 @@ static inline u32 getmiso(struct spi_dev
static u32 s3c2410_spigpio_txrx_mode0(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
}
static u32 s3c2410_spigpio_txrx_mode1(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits);
}
static u32 s3c2410_spigpio_txrx_mode2(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits);
}
static u32 s3c2410_spigpio_txrx_mode3(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
}
--- a/drivers/spi/spi_sh_sci.c
+++ b/drivers/spi/spi_sh_sci.c
@@ -83,25 +83,25 @@ static inline u32 getmiso(struct spi_dev
static u32 sh_sci_spi_txrx_mode0(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
}
static u32 sh_sci_spi_txrx_mode1(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits);
}
static u32 sh_sci_spi_txrx_mode2(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits);
}
static u32 sh_sci_spi_txrx_mode3(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
}
static void sh_sci_spi_chipselect(struct spi_device *dev, int value)
--- a/drivers/spi/spi_gpio_old.c
+++ b/drivers/spi/spi_gpio_old.c
@@ -80,25 +80,25 @@ static inline void do_spidelay(struct sp
static u32 spi_gpio_txrx_mode0(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha0(spi, nsecs, 0, word, bits);
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
}
static u32 spi_gpio_txrx_mode1(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha1(spi, nsecs, 0, word, bits);
+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, 0, word, bits);
}
static u32 spi_gpio_txrx_mode2(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha0(spi, nsecs, 1, word, bits);
+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, 0, word, bits);
}
static u32 spi_gpio_txrx_mode3(struct spi_device *spi,
unsigned nsecs, u32 word, u8 bits)
{
- return bitbang_txrx_be_cpha1(spi, nsecs, 1, word, bits);
+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
}
static void spi_gpio_chipselect(struct spi_device *dev, int on)

@ -1,217 +0,0 @@
From 3c8e1a84fd6b984a7bce8816db2e3defc57bbfe4 Mon Sep 17 00:00:00 2001
From: Marek Szyprowski <m.szyprowski@samsung.com>
Date: Wed, 30 Jun 2010 14:27:37 -0600
Subject: [PATCH] spi/spi-gpio: add support for controllers without MISO or MOSI pin
There are some boards that do not strictly follow SPI standard and use
only 3 wires (SCLK, MOSI or MISO, SS) for connecting some simple auxiliary
chips and controls them with GPIO based 'spi controller'. In this
configuration the MISO or MOSI line is missing (it is not required if the
chip does not transfer any data back to host or host only reads data from
chip).
This patch adds support for such non-standard configuration in GPIO-based
SPI controller. It has been tested in configuration without MISO pin.
Reviewed-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Marek Szyprowski <m.szyprowski@samsung.com>
Acked-by: David Brownell <dbrownell@users.sourceforge.net>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>
---
drivers/spi/spi_gpio.c | 101 ++++++++++++++++++++++++++++++++++-------
include/linux/spi/spi_gpio.h | 5 ++
2 files changed, 88 insertions(+), 18 deletions(-)
--- a/drivers/spi/spi_gpio.c
+++ b/drivers/spi/spi_gpio.c
@@ -178,6 +178,44 @@ static u32 spi_gpio_txrx_word_mode3(stru
return bitbang_txrx_be_cpha1(spi, nsecs, 1, 0, word, bits);
}
+/*
+ * These functions do not call setmosi or getmiso if respective flag
+ * (SPI_MASTER_NO_RX or SPI_MASTER_NO_TX) is set, so they are safe to
+ * call when such pin is not present or defined in the controller.
+ * A separate set of callbacks is defined to get highest possible
+ * speed in the generic case (when both MISO and MOSI lines are
+ * available), as optimiser will remove the checks when argument is
+ * constant.
+ */
+
+static u32 spi_gpio_spec_txrx_word_mode0(struct spi_device *spi,
+ unsigned nsecs, u32 word, u8 bits)
+{
+ unsigned flags = spi->master->flags;
+ return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits);
+}
+
+static u32 spi_gpio_spec_txrx_word_mode1(struct spi_device *spi,
+ unsigned nsecs, u32 word, u8 bits)
+{
+ unsigned flags = spi->master->flags;
+ return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits);
+}
+
+static u32 spi_gpio_spec_txrx_word_mode2(struct spi_device *spi,
+ unsigned nsecs, u32 word, u8 bits)
+{
+ unsigned flags = spi->master->flags;
+ return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits);
+}
+
+static u32 spi_gpio_spec_txrx_word_mode3(struct spi_device *spi,
+ unsigned nsecs, u32 word, u8 bits)
+{
+ unsigned flags = spi->master->flags;
+ return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits);
+}
+
/*----------------------------------------------------------------------*/
static void spi_gpio_chipselect(struct spi_device *spi, int is_active)
@@ -243,19 +281,30 @@ static int __devinit spi_gpio_alloc(unsi
}
static int __devinit
-spi_gpio_request(struct spi_gpio_platform_data *pdata, const char *label)
+spi_gpio_request(struct spi_gpio_platform_data *pdata, const char *label,
+ u16 *res_flags)
{
int value;
/* NOTE: SPI_*_GPIO symbols may reference "pdata" */
- value = spi_gpio_alloc(SPI_MOSI_GPIO, label, false);
- if (value)
- goto done;
-
- value = spi_gpio_alloc(SPI_MISO_GPIO, label, true);
- if (value)
- goto free_mosi;
+ if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI) {
+ value = spi_gpio_alloc(SPI_MOSI_GPIO, label, false);
+ if (value)
+ goto done;
+ } else {
+ /* HW configuration without MOSI pin */
+ *res_flags |= SPI_MASTER_NO_TX;
+ }
+
+ if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO) {
+ value = spi_gpio_alloc(SPI_MISO_GPIO, label, true);
+ if (value)
+ goto free_mosi;
+ } else {
+ /* HW configuration without MISO pin */
+ *res_flags |= SPI_MASTER_NO_RX;
+ }
value = spi_gpio_alloc(SPI_SCK_GPIO, label, false);
if (value)
@@ -264,9 +313,11 @@ spi_gpio_request(struct spi_gpio_platfor
goto done;
free_miso:
- gpio_free(SPI_MISO_GPIO);
+ if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
+ gpio_free(SPI_MISO_GPIO);
free_mosi:
- gpio_free(SPI_MOSI_GPIO);
+ if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
+ gpio_free(SPI_MOSI_GPIO);
done:
return value;
}
@@ -277,6 +328,7 @@ static int __devinit spi_gpio_probe(stru
struct spi_master *master;
struct spi_gpio *spi_gpio;
struct spi_gpio_platform_data *pdata;
+ u16 master_flags = 0;
pdata = pdev->dev.platform_data;
#ifdef GENERIC_BITBANG
@@ -284,7 +336,7 @@ static int __devinit spi_gpio_probe(stru
return -ENODEV;
#endif
- status = spi_gpio_request(pdata, dev_name(&pdev->dev));
+ status = spi_gpio_request(pdata, dev_name(&pdev->dev), &master_flags);
if (status < 0)
return status;
@@ -300,6 +352,7 @@ static int __devinit spi_gpio_probe(stru
if (pdata)
spi_gpio->pdata = *pdata;
+ master->flags = master_flags;
master->bus_num = pdev->id;
master->num_chipselect = SPI_N_CHIPSEL;
master->setup = spi_gpio_setup;
@@ -307,10 +360,18 @@ static int __devinit spi_gpio_probe(stru
spi_gpio->bitbang.master = spi_master_get(master);
spi_gpio->bitbang.chipselect = spi_gpio_chipselect;
- spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0;
- spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1;
- spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2;
- spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3;
+
+ if ((master_flags & (SPI_MASTER_NO_RX | SPI_MASTER_NO_RX)) == 0) {
+ spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_word_mode0;
+ spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_word_mode1;
+ spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_word_mode2;
+ spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_word_mode3;
+ } else {
+ spi_gpio->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_spec_txrx_word_mode0;
+ spi_gpio->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_spec_txrx_word_mode1;
+ spi_gpio->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_spec_txrx_word_mode2;
+ spi_gpio->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_spec_txrx_word_mode3;
+ }
spi_gpio->bitbang.setup_transfer = spi_bitbang_setup_transfer;
spi_gpio->bitbang.flags = SPI_CS_HIGH;
@@ -318,8 +379,10 @@ static int __devinit spi_gpio_probe(stru
if (status < 0) {
spi_master_put(spi_gpio->bitbang.master);
gpio_free:
- gpio_free(SPI_MISO_GPIO);
- gpio_free(SPI_MOSI_GPIO);
+ if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
+ gpio_free(SPI_MISO_GPIO);
+ if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
+ gpio_free(SPI_MOSI_GPIO);
gpio_free(SPI_SCK_GPIO);
spi_master_put(master);
}
@@ -342,8 +405,10 @@ static int __devexit spi_gpio_remove(str
platform_set_drvdata(pdev, NULL);
- gpio_free(SPI_MISO_GPIO);
- gpio_free(SPI_MOSI_GPIO);
+ if (SPI_MISO_GPIO != SPI_GPIO_NO_MISO)
+ gpio_free(SPI_MISO_GPIO);
+ if (SPI_MOSI_GPIO != SPI_GPIO_NO_MOSI)
+ gpio_free(SPI_MOSI_GPIO);
gpio_free(SPI_SCK_GPIO);
return status;
--- a/include/linux/spi/spi_gpio.h
+++ b/include/linux/spi/spi_gpio.h
@@ -29,11 +29,16 @@
* SPI_GPIO_NO_CHIPSELECT to the controller_data:
* .controller_data = (void *) SPI_GPIO_NO_CHIPSELECT;
*
+ * If the MISO or MOSI pin is not available then it should be set to
+ * SPI_GPIO_NO_MISO or SPI_GPIO_NO_MOSI.
+ *
* If the bitbanged bus is later switched to a "native" controller,
* that platform_device and controller_data should be removed.
*/
#define SPI_GPIO_NO_CHIPSELECT ((unsigned long)-1l)
+#define SPI_GPIO_NO_MISO ((unsigned long)-1l)
+#define SPI_GPIO_NO_MOSI ((unsigned long)-1l)
/**
* struct spi_gpio_platform_data - parameter for bitbanged SPI master

@ -1,23 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -881,6 +881,7 @@ int __init board_register_devices(void)
{
u32 val;
int button_count = 0;
+ int led_count = 0;
if (board.has_uart0)
bcm63xx_uart_register(0);
@@ -922,7 +923,11 @@ int __init board_register_devices(void)
platform_device_register_simple("GPIODEV", 0, &gpiodev_resource, 1);
- bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
+ /* count number of LEDs defined by this device */
+ while (led_count < ARRAY_SIZE(board.leds) && board.leds[led_count].name)
+ led_count++;
+
+ bcm63xx_led_data.num_leds = led_count;
bcm63xx_led_data.leds = board.leds;
platform_device_register(&bcm63xx_gpio_leds);

@ -1,113 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -588,6 +588,99 @@ static struct board_info __initdata boar
.has_ohci0 = 1,
.has_ehci0 = 1,
+
+ .leds = {
+ /*Each led on alice gate is bi-color */
+ {
+ .name = "power:red",
+ .gpio = 5,
+ .active_low = 1,
+ },
+ {
+ .name = "power:green",
+ .gpio = 4,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "service:red",
+ .gpio = 7,
+ .active_low = 1,
+ },
+ {
+ .name = "service:green",
+ .gpio = 6,
+ .active_low = 1,
+ },
+ {
+ .name = "adsl:red",
+ .gpio = 9,
+ .active_low = 1,
+ },
+ {
+ .name = "adsl:green",
+ .gpio = 10,
+ .active_low = 1,
+ },
+ {
+ .name = "wifi:red",
+ .gpio = 23,
+ .active_low = 1,
+ },
+ {
+ .name = "wifi:green",
+ .gpio = 22,
+ .active_low = 1,
+ },
+ {
+ .name = "internet:red",
+ .gpio = 25,
+ .active_low = 1,
+ },
+ {
+ .name = "internet:green",
+ .gpio = 24,
+ .active_low = 1,
+ },
+ {
+ .name = "usr1:red",
+ .gpio = 27,
+ .active_low = 1,
+ },
+ {
+ .name = "usr1:green",
+ .gpio = 26,
+ .active_low = 1,
+ },
+ {
+ .name = "usr2:red",
+ .gpio = 30,
+ .active_low = 1,
+ },
+ {
+ .name = "usr2:green",
+ .gpio = 29,
+ .active_low = 1,
+ },
+ },
+
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 37,
+ .active_low = 1,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ {
+ .desc = "wps",
+ .gpio = 34,
+ .type = EV_KEY,
+ .code = KEY_WPS_BUTTON,
+ .threshold = 3,
+ },
+ },
};
static struct board_info __initdata board_DWVS0 = {
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -56,7 +56,7 @@ struct board_info {
struct bcm63xx_dsp_platform_data dsp;
/* GPIO LEDs */
- struct gpio_led leds[5];
+ struct gpio_led leds[14];
/* Buttons */
struct gpio_button buttons[2];

@ -1,251 +0,0 @@
--- a/arch/mips/bcm63xx/boards/Kconfig
+++ b/arch/mips/bcm63xx/boards/Kconfig
@@ -8,4 +8,10 @@ config BOARD_BCM963XX
select SSB
help
+config BOARD_LIVEBOX
+ bool "Inventel Livebox(es) boards"
+ select SSB
+ help
+ Inventel Livebox boards using the RedBoot bootloader.
+
endchoice
--- a/arch/mips/bcm63xx/boards/Makefile
+++ b/arch/mips/bcm63xx/boards/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_BOARD_BCM963XX) += board_bcm963xx.o
+obj-$(CONFIG_BOARD_LIVEBOX) += board_livebox.o
EXTRA_CFLAGS += -Werror
--- /dev/null
+++ b/arch/mips/bcm63xx/boards/board_livebox.c
@@ -0,0 +1,228 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+#include <linux/input.h>
+#include <linux/gpio_buttons.h>
+#include <asm/addrspace.h>
+#include <bcm63xx_board.h>
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_dev_uart.h>
+#include <bcm63xx_dev_pci.h>
+#include <bcm63xx_dev_enet.h>
+#include <bcm63xx_dev_pcmcia.h>
+#include <bcm63xx_dev_usb_ohci.h>
+#include <bcm63xx_dev_usb_ehci.h>
+#include <board_bcm963xx.h>
+
+#define PFX "board_livebox: "
+
+static unsigned int mac_addr_used = 0;
+static struct board_info board;
+
+/*
+ * known 6348 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6348
+static struct board_info __initdata board_livebox = {
+ .name = "Livebox",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+ .has_pccard = 1,
+ .has_ehci0 = 1,
+};
+#endif
+
+/*
+ * all boards
+ */
+static const struct board_info __initdata *bcm963xx_boards[] = {
+#ifdef CONFIG_BCM63XX_CPU_6348
+ &board_livebox
+#endif
+};
+
+/*
+ * early init callback
+ */
+void __init board_prom_init(void)
+{
+ u32 val;
+
+ /* read base address of boot chip select (0) */
+ val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+ val &= MPI_CSBASE_BASE_MASK;
+
+ /* assume board is a Livebox */
+ memcpy(&board, bcm963xx_boards[0], sizeof(board));
+
+ /* setup pin multiplexing depending on board enabled device,
+ * this has to be done this early since PCI init is done
+ * inside arch_initcall */
+ val = 0;
+
+ if (board.has_pci) {
+ bcm63xx_pci_enabled = 1;
+ if (BCMCPU_IS_6348())
+ val |= GPIO_MODE_6348_G2_PCI;
+ }
+
+ if (board.has_pccard) {
+ if (BCMCPU_IS_6348())
+ val |= GPIO_MODE_6348_G1_MII_PCCARD;
+ }
+
+ if (board.has_enet0 && !board.enet0.use_internal_phy) {
+ if (BCMCPU_IS_6348())
+ val |= GPIO_MODE_6348_G3_EXT_MII |
+ GPIO_MODE_6348_G0_EXT_MII;
+ }
+
+ if (board.has_enet1 && !board.enet1.use_internal_phy) {
+ if (BCMCPU_IS_6348())
+ val |= GPIO_MODE_6348_G3_EXT_MII |
+ GPIO_MODE_6348_G0_EXT_MII;
+ }
+
+ bcm_gpio_writel(val, GPIO_MODE_REG);
+}
+
+/*
+ * second stage init callback, good time to panic if we couldn't
+ * identify on which board we're running since early printk is working
+ */
+void __init board_setup(void)
+{
+ if (!board.name[0])
+ panic("unable to detect bcm963xx board");
+ printk(KERN_INFO PFX "board name: %s\n", board.name);
+
+ /* make sure we're running on expected cpu */
+ if (bcm63xx_get_cpu_id() != board.expected_cpu_id)
+ panic("unexpected CPU for bcm963xx board");
+}
+
+/*
+ * return board name for /proc/cpuinfo
+ */
+const char *board_get_name(void)
+{
+ return board.name;
+}
+
+/*
+ * register & return a new board mac address
+ */
+
+static int board_get_mac_address(u8 *mac)
+{
+ u8 default_mac[ETH_ALEN] = {0x00, 0x07, 0x3A, 0x00, 0x00, 0x00};
+ u8 *p;
+ int count;
+
+ memcpy(mac, default_mac, ETH_ALEN);
+
+ p = mac + ETH_ALEN - 1;
+ count = mac_addr_used;
+
+ while (count--) {
+ do {
+ (*p)++;
+ if (*p != 0)
+ break;
+ p--;
+ } while (p != mac);
+ }
+
+ if (p == mac) {
+ printk(KERN_ERR PFX "unable to fetch mac address\n");
+ return -ENODEV;
+ }
+ mac_addr_used++;
+
+ return 0;
+}
+
+static struct resource mtd_resources[] = {
+ {
+ .start = 0, /* filled at runtime */
+ .end = 0, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device mtd_dev = {
+ .name = "bcm963xx-flash",
+ .resource = mtd_resources,
+ .num_resources = ARRAY_SIZE(mtd_resources),
+};
+
+
+/*
+ * third stage init callback, register all board devices.
+ */
+int __init board_register_devices(void)
+{
+ u32 val;
+
+ if (board.has_uart0)
+ bcm63xx_uart_register(0);
+
+ if (board.has_pccard)
+ bcm63xx_pcmcia_register();
+
+ if (board.has_enet0 &&
+ !board_get_mac_address(board.enet0.mac_addr))
+ bcm63xx_enet_register(0, &board.enet0);
+
+ if (board.has_enet1 &&
+ !board_get_mac_address(board.enet1.mac_addr))
+ bcm63xx_enet_register(1, &board.enet1);
+
+ if (board.has_ohci0)
+ bcm63xx_ohci_register();
+
+ if (board.has_ehci0)
+ bcm63xx_ehci_register();
+
+
+ /* read base address of boot chip select (0) */
+ val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+ val &= MPI_CSBASE_BASE_MASK;
+ mtd_resources[0].start = val;
+ mtd_resources[0].end = 0x1FFFFFFF;
+
+ platform_device_register(&mtd_dev);
+
+ return 0;
+}
+

@ -1,243 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -29,6 +29,7 @@
#include <bcm63xx_dev_pcmcia.h>
#include <bcm63xx_dev_usb_ohci.h>
#include <bcm63xx_dev_usb_ehci.h>
+#include <bcm63xx_dev_usb_udc.h>
#include <board_bcm963xx.h>
#define PFX "board_bcm963xx: "
@@ -400,6 +401,8 @@ static struct board_info __initdata boar
.has_ohci0 = 1,
.has_pccard = 1,
.has_ehci0 = 1,
+
+ .has_udc0 = 1,
};
static struct board_info __initdata board_rta1025w_16 = {
@@ -1002,6 +1005,9 @@ int __init board_register_devices(void)
if (board.has_dsp)
bcm63xx_dsp_register(&board.dsp);
+ if (board.has_udc0)
+ bcm63xx_udc_register();
+
/* read base address of boot chip select (0) */
if (BCMCPU_IS_6345())
val = 0x1fc00000;
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-usb-udc.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2009 Henk Vergonet <Henk.Vergonet@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+
+static struct resource udc_resources[] = {
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = -1, /* filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 udc_dmamask = ~(u32)0;
+
+static struct platform_device bcm63xx_udc_device = {
+ .name = "bcm63xx-udc",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(udc_resources),
+ .resource = udc_resources,
+ .dev = {
+ .dma_mask = &udc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+int __init bcm63xx_udc_register(void)
+{
+ if (!BCMCPU_IS_6338() && !BCMCPU_IS_6345() && !BCMCPU_IS_6348())
+ return 0;
+
+ udc_resources[0].start = bcm63xx_regset_address(RSET_UDC0);
+ udc_resources[0].end = udc_resources[0].start;
+ udc_resources[0].end += RSET_UDC_SIZE - 1;
+ udc_resources[1].start = bcm63xx_get_irq_number(IRQ_UDC0);
+ return platform_device_register(&bcm63xx_udc_device);
+}
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -127,7 +127,7 @@ enum bcm63xx_regs_set {
#define BCM_6338_UART1_BASE (0xdeadbeef)
#define BCM_6338_GPIO_BASE (0xfffe0400)
#define BCM_6338_SPI_BASE (0xfffe0c00)
-#define BCM_6338_UDC0_BASE (0xdeadbeef)
+#define BCM_6338_UDC0_BASE (0xfffe3000)
#define BCM_6338_USBDMA_BASE (0xfffe2400)
#define BCM_6338_OHCI0_BASE (0xdeadbeef)
#define BCM_6338_OHCI_PRIV_BASE (0xfffe3000)
@@ -158,7 +158,7 @@ enum bcm63xx_regs_set {
#define BCM_6345_UART1_BASE (0xdeadbeef)
#define BCM_6345_GPIO_BASE (0xfffe0400)
#define BCM_6345_SPI_BASE (0xdeadbeef)
-#define BCM_6345_UDC0_BASE (0xdeadbeef)
+#define BCM_6345_UDC0_BASE (0xfffe2100)
#define BCM_6345_USBDMA_BASE (0xfffe2800)
#define BCM_6345_ENET0_BASE (0xfffe1800)
#define BCM_6345_ENETDMA_BASE (0xfffe2800)
@@ -215,7 +215,7 @@ enum bcm63xx_regs_set {
#define BCM_6358_UART1_BASE (0xfffe0120)
#define BCM_6358_GPIO_BASE (0xfffe0080)
#define BCM_6358_SPI_BASE (0xdeadbeef)
-#define BCM_6358_UDC0_BASE (0xfffe0800)
+#define BCM_6358_UDC0_BASE (0xfffe0400)
#define BCM_6358_OHCI0_BASE (0xfffe1400)
#define BCM_6358_OHCI_PRIV_BASE (0xdeadbeef)
#define BCM_6358_USBH_PRIV_BASE (0xfffe1500)
@@ -444,6 +444,7 @@ enum bcm63xx_irq {
IRQ_UART0,
IRQ_UART1,
IRQ_DSL,
+ IRQ_UDC0,
IRQ_ENET0,
IRQ_ENET1,
IRQ_ENET_PHY,
@@ -486,7 +487,7 @@ enum bcm63xx_irq {
#define BCM_6345_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6345_DSL_IRQ (IRQ_INTERNAL_BASE + 3)
#define BCM_6345_ATM_IRQ (IRQ_INTERNAL_BASE + 4)
-#define BCM_6345_USB_IRQ (IRQ_INTERNAL_BASE + 5)
+#define BCM_6345_UDC0_IRQ (IRQ_INTERNAL_BASE + 5)
#define BCM_6345_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
#define BCM_6345_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12)
#define BCM_6345_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 13 + 1)
@@ -508,10 +509,17 @@ enum bcm63xx_irq {
#define BCM_6348_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
#define BCM_6348_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6348_DSL_IRQ (IRQ_INTERNAL_BASE + 4)
+#define BCM_6348_UDC0_IRQ (IRQ_INTERNAL_BASE + 6)
#define BCM_6348_ENET1_IRQ (IRQ_INTERNAL_BASE + 7)
#define BCM_6348_ENET0_IRQ (IRQ_INTERNAL_BASE + 8)
#define BCM_6348_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 9)
#define BCM_6348_OHCI0_IRQ (IRQ_INTERNAL_BASE + 12)
+#define BCM_6348_USB_CNTL_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 14)
+#define BCM_6348_USB_CNTL_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 15)
+#define BCM_6348_USB_BULK_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 16)
+#define BCM_6348_USB_BULK_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 17)
+#define BCM_6348_USB_ISO_RX_DMA_IRQ (IRQ_INTERNAL_BASE + 18)
+#define BCM_6348_USB_ISO_TX_DMA_IRQ (IRQ_INTERNAL_BASE + 19)
#define BCM_6348_ENET0_RXDMA_IRQ (IRQ_INTERNAL_BASE + 20)
#define BCM_6348_ENET0_TXDMA_IRQ (IRQ_INTERNAL_BASE + 21)
#define BCM_6348_ENET1_RXDMA_IRQ (IRQ_INTERNAL_BASE + 22)
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_usb_udc.h
@@ -0,0 +1,6 @@
+#ifndef BCM63XX_DEV_USB_UDC_H_
+#define BCM63XX_DEV_USB_UDC_H_
+
+int bcm63xx_udc_register(void);
+
+#endif /* BCM63XX_DEV_USB_UDC_H_ */
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -47,6 +47,7 @@ struct board_info {
unsigned int has_dsp:1;
unsigned int has_uart0:1;
unsigned int has_uart1:1;
+ unsigned int has_udc0:1;
/* ethernet config */
struct bcm63xx_enet_platform_data enet0;
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -1,6 +1,6 @@
obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o \
- dev-usb-ohci.o dev-usb-ehci.o
+ dev-usb-ohci.o dev-usb-ehci.o dev-usb-udc.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -141,6 +141,30 @@ static struct clk clk_usbh = {
};
/*
+ * USB slave clock
+ */
+static void usbs_set(struct clk *clk, int enable)
+{
+ u32 mask;
+
+ switch(bcm63xx_get_cpu_id()) {
+ case BCM6338_CPU_ID:
+ mask = CKCTL_6338_USBS_EN;
+ break;
+ case BCM6348_CPU_ID:
+ mask = CKCTL_6348_USBS_EN;
+ break;
+ default:
+ return;
+ }
+ bcm_hwclock_set(mask, enable);
+}
+
+static struct clk clk_usbs = {
+ .set = usbs_set,
+};
+
+/*
* SPI clock
*/
static void spi_set(struct clk *clk, int enable)
@@ -208,6 +232,8 @@ struct clk *clk_get(struct device *dev,
return &clk_ephy;
if (!strcmp(id, "usbh"))
return &clk_usbh;
+ if (!strcmp(id, "usbs"))
+ return &clk_usbs;
if (!strcmp(id, "spi"))
return &clk_spi;
if (!strcmp(id, "periph"))
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -7,6 +7,7 @@ config BCM63XX_CPU_6338
select USB_ARCH_HAS_OHCI
select USB_OHCI_BIG_ENDIAN_DESC
select USB_OHCI_BIG_ENDIAN_MMIO
+ select USB_ARCH_HAS_UDC
config BCM63XX_CPU_6345
bool "support 6345 CPU"
@@ -19,6 +20,7 @@ config BCM63XX_CPU_6348
select USB_ARCH_HAS_OHCI
select USB_OHCI_BIG_ENDIAN_DESC
select USB_OHCI_BIG_ENDIAN_MMIO
+ select USB_ARCH_HAS_UDC
config BCM63XX_CPU_6358
bool "support 6358 CPU"

@ -1,25 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -1008,6 +1008,9 @@ int __init board_register_devices(void)
if (board.has_udc0)
bcm63xx_udc_register();
+ if (board.num_devs)
+ platform_add_devices(board.devs, board.num_devs);
+
/* read base address of boot chip select (0) */
if (BCMCPU_IS_6345())
val = 0x1fc00000;
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -61,6 +61,10 @@ struct board_info {
/* Buttons */
struct gpio_button buttons[2];
+
+ /* Additional platform devices */
+ struct platform_device **devs;
+ unsigned int num_devs;
};
#endif /* ! BOARD_BCM963XX_H_ */

@ -1,25 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -1011,6 +1011,9 @@ int __init board_register_devices(void)
if (board.num_devs)
platform_add_devices(board.devs, board.num_devs);
+ if (board.num_spis)
+ spi_register_board_info(board.spis, board.num_spis);
+
/* read base address of boot chip select (0) */
if (BCMCPU_IS_6345())
val = 0x1fc00000;
--- a/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
+++ b/arch/mips/include/asm/mach-bcm63xx/board_bcm963xx.h
@@ -65,6 +65,10 @@ struct board_info {
/* Additional platform devices */
struct platform_device **devs;
unsigned int num_devs;
+
+ /* Additional platform devices */
+ struct spi_board_info *spis;
+ unsigned int num_spis;
};
#endif /* ! BOARD_BCM963XX_H_ */

@ -1,458 +0,0 @@
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -321,6 +321,14 @@ config GPIO_MC33880
SPI driver for Freescale MC33880 high-side/low-side switch.
This provides GPIO interface supporting inputs and outputs.
+config GPIO_74X164
+ tristate "74x164 serial-in/parallel-out 8-bits shift register"
+ depends on SPI_MASTER
+ help
+ Platform driver for 74x164 compatible serial-in/parallel-out
+ 8-outputs shift registers. This driver can be used to provide access
+ to more gpio outputs.
+
comment "AC97 GPIO expanders:"
config GPIO_UCB1400
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -17,6 +17,7 @@ obj-$(CONFIG_GPIO_MAX7301) += max7301.o
obj-$(CONFIG_GPIO_MAX732X) += max732x.o
obj-$(CONFIG_GPIO_MC33880) += mc33880.o
obj-$(CONFIG_GPIO_MCP23S08) += mcp23s08.o
+obj-$(CONFIG_GPIO_74X164) += 74x164.o
obj-$(CONFIG_GPIO_PCA953X) += pca953x.o
obj-$(CONFIG_GPIO_PCF857X) += pcf857x.o
obj-$(CONFIG_GPIO_PL061) += pl061.o
--- /dev/null
+++ b/drivers/gpio/nxp_74hc164.c
@@ -0,0 +1,227 @@
+/*
+ * NXP 74HC164 - output expander GPIO driver
+ *
+ * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2010 Miguel Gaio <miguel.gaio@efixo.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Copy from nxp_74hc153.c code
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/gpio.h>
+#include <linux/bitops.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+#include <linux/nxp_74hc164.h>
+
+#define NXP_74HC164_NUM_GPIOS 8
+
+struct nxp_74hc164_chip {
+ struct device *parent;
+ struct gpio_chip gpio_chip;
+ struct mutex lock;
+ long mask;
+};
+
+static void nxp_74hc164_set_value(struct gpio_chip *, unsigned, int);
+
+static struct nxp_74hc164_chip *gpio_to_nxp(struct gpio_chip *gc)
+{
+ return container_of(gc, struct nxp_74hc164_chip, gpio_chip);
+}
+
+static int nxp_74hc164_direction_input(struct gpio_chip *gc, unsigned offset)
+{
+ WARN_ON(1);
+ return -EINVAL;
+}
+
+static int nxp_74hc164_direction_output(struct gpio_chip *gc,
+ unsigned offset, int val)
+{
+ nxp_74hc164_set_value(gc, offset, val);
+ return 0;
+}
+
+static int nxp_74hc164_get_value(struct gpio_chip *gc, unsigned offset)
+{
+ struct nxp_74hc164_chip *nxp = gpio_to_nxp(gc);
+ int ret;
+
+ mutex_lock(&nxp->lock);
+ ret = test_bit(offset, &nxp->mask);
+ mutex_unlock(&nxp->lock);
+
+ return ret;
+}
+
+static void nxp_74hc164_set_value(struct gpio_chip *gc,
+ unsigned offset, int val)
+{
+ struct nxp_74hc164_chip *nxp;
+ struct nxp_74hc164_platform_data *pdata;
+ long mask;
+ int refresh;
+ int i;
+
+ nxp = gpio_to_nxp(gc);
+ pdata = nxp->parent->platform_data;
+
+ mutex_lock(&nxp->lock);
+ if (val)
+ refresh = (test_and_set_bit(offset, &nxp->mask) != val);
+ else
+ refresh = (test_and_clear_bit(offset, &nxp->mask) != val);
+
+ if (refresh) {
+ mask = nxp->mask;
+ for (i = 8; i > 0; --i, mask <<= 1) {
+ gpio_set_value(pdata->gpio_pin_data, mask & 0x80);
+ gpio_set_value(pdata->gpio_pin_clk, 1);
+ gpio_set_value(pdata->gpio_pin_clk, 0);
+ }
+ }
+ mutex_unlock(&nxp->lock);
+}
+
+static int __devinit nxp_74hc164_probe(struct platform_device *pdev)
+{
+ struct nxp_74hc164_platform_data *pdata;
+ struct nxp_74hc164_chip *nxp;
+ struct gpio_chip *gc;
+ int err;
+
+ pdata = pdev->dev.platform_data;
+ if (pdata == NULL) {
+ dev_dbg(&pdev->dev, "no platform data specified\n");
+ return -EINVAL;
+ }
+
+ nxp = kzalloc(sizeof(struct nxp_74hc164_chip), GFP_KERNEL);
+ if (nxp == NULL) {
+ dev_err(&pdev->dev, "no memory for private data\n");
+ return -ENOMEM;
+ }
+
+ err = gpio_request(pdata->gpio_pin_clk, dev_name(&pdev->dev));
+ if (err) {
+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
+ pdata->gpio_pin_clk, err);
+ goto err_free_nxp;
+ }
+
+ err = gpio_request(pdata->gpio_pin_data, dev_name(&pdev->dev));
+ if (err) {
+ dev_err(&pdev->dev, "unable to claim gpio %u, err=%d\n",
+ pdata->gpio_pin_data, err);
+ goto err_free_clk;
+ }
+
+ err = gpio_direction_output(pdata->gpio_pin_clk, 0);
+ if (err) {
+ dev_err(&pdev->dev,
+ "unable to set direction of gpio %u, err=%d\n",
+ pdata->gpio_pin_clk, err);
+ goto err_free_data;
+ }
+
+ err = gpio_direction_output(pdata->gpio_pin_data, 0);
+ if (err) {
+ dev_err(&pdev->dev,
+ "unable to set direction of gpio %u, err=%d\n",
+ pdata->gpio_pin_data, err);
+ goto err_free_data;
+ }
+
+ nxp->parent = &pdev->dev;
+ mutex_init(&nxp->lock);
+
+ gc = &nxp->gpio_chip;
+
+ gc->direction_input = nxp_74hc164_direction_input;
+ gc->direction_output = nxp_74hc164_direction_output;
+ gc->get = nxp_74hc164_get_value;
+ gc->set = nxp_74hc164_set_value;
+ gc->can_sleep = 1;
+
+ gc->base = pdata->gpio_base;
+ gc->ngpio = NXP_74HC164_NUM_GPIOS;
+ gc->label = dev_name(nxp->parent);
+ gc->dev = nxp->parent;
+ gc->owner = THIS_MODULE;
+
+ err = gpiochip_add(&nxp->gpio_chip);
+ if (err) {
+ dev_err(&pdev->dev, "unable to add gpio chip, err=%d\n", err);
+ goto err_free_data;
+ }
+
+ platform_set_drvdata(pdev, nxp);
+ return 0;
+
+ err_free_data:
+ gpio_free(pdata->gpio_pin_data);
+ err_free_clk:
+ gpio_free(pdata->gpio_pin_clk);
+ err_free_nxp:
+ kfree(nxp);
+ return err;
+}
+
+static int nxp_74hc164_remove(struct platform_device *pdev)
+{
+ struct nxp_74hc164_chip *nxp = platform_get_drvdata(pdev);
+ struct nxp_74hc164_platform_data *pdata = pdev->dev.platform_data;
+
+ if (nxp) {
+ int err;
+
+ err = gpiochip_remove(&nxp->gpio_chip);
+ if (err) {
+ dev_err(&pdev->dev,
+ "unable to remove gpio chip, err=%d\n",
+ err);
+ return err;
+ }
+
+ gpio_free(pdata->gpio_pin_clk);
+ gpio_free(pdata->gpio_pin_data);
+
+ kfree(nxp);
+ platform_set_drvdata(pdev, NULL);
+ }
+
+ return 0;
+}
+
+static struct platform_driver nxp_74hc164_driver = {
+ .probe = nxp_74hc164_probe,
+ .remove = __devexit_p(nxp_74hc164_remove),
+ .driver = {
+ .name = NXP_74HC164_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init nxp_74hc164_init(void)
+{
+ return platform_driver_register(&nxp_74hc164_driver);
+}
+subsys_initcall(nxp_74hc164_init);
+
+static void __exit nxp_74hc164_exit(void)
+{
+ platform_driver_unregister(&nxp_74hc164_driver);
+}
+module_exit(nxp_74hc164_exit);
+
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>");
+MODULE_DESCRIPTION("GPIO expander driver for NXP 74HC164");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" NXP_74HC164_DRIVER_NAME);
--- /dev/null
+++ b/drivers/gpio/74x164.c
@@ -0,0 +1,184 @@
+/*
+ * 74Hx164 - Generic serial-in/parallel-out 8-bits shift register GPIO driver
+ *
+ * Copyright (C) 2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2010 Miguel Gaio <miguel.gaio@efixo.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/mutex.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/74x164.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+
+#define GEN_74X164_GPIO_COUNT 8
+
+
+struct gen_74x164_chip {
+ struct spi_device *spi;
+ struct gpio_chip gpio_chip;
+ struct mutex lock;
+ u8 port_config;
+};
+
+static void gen_74x164_set_value(struct gpio_chip *, unsigned, int);
+
+static struct gen_74x164_chip *gpio_to_chip(struct gpio_chip *gc)
+{
+ return container_of(gc, struct gen_74x164_chip, gpio_chip);
+}
+
+static int __gen_74x164_write_config(struct gen_74x164_chip *chip)
+{
+ return spi_write(chip->spi,
+ &chip->port_config, sizeof(chip->port_config));
+}
+
+static int gen_74x164_direction_output(struct gpio_chip *gc,
+ unsigned offset, int val)
+{
+ gen_74x164_set_value(gc, offset, val);
+ return 0;
+}
+
+static int gen_74x164_get_value(struct gpio_chip *gc, unsigned offset)
+{
+ struct gen_74x164_chip *chip = gpio_to_chip(gc);
+ int ret;
+
+ mutex_lock(&chip->lock);
+ ret = (chip->port_config >> offset) & 0x1;
+ mutex_unlock(&chip->lock);
+
+ return ret;
+}
+
+static void gen_74x164_set_value(struct gpio_chip *gc,
+ unsigned offset, int val)
+{
+ struct gen_74x164_chip *chip = gpio_to_chip(gc);
+ bool refresh;
+
+ mutex_lock(&chip->lock);
+ if (val)
+ chip->port_config |= (1 << offset);
+ else
+ chip->port_config &= ~(1 << offset);
+
+ __gen_74x164_write_config(chip);
+ mutex_unlock(&chip->lock);
+}
+
+static int __devinit gen_74x164_probe(struct spi_device *spi)
+{
+ struct gen_74x164_chip *chip;
+ struct gen_74x164_chip_platform_data *pdata;
+ int ret;
+
+ pdata = spi->dev.platform_data;
+ if (!pdata || !pdata->base) {
+ dev_dbg(&spi->dev, "incorrect or missing platform data\n");
+ return -EINVAL;
+ }
+
+ /*
+ * bits_per_word cannot be configured in platform data
+ */
+ spi->bits_per_word = 8;
+
+ ret = spi_setup(spi);
+ if (ret < 0)
+ return ret;
+
+ chip = kzalloc(sizeof(*chip), GFP_KERNEL);
+ if (!chip)
+ return -ENOMEM;
+
+ mutex_init(&chip->lock);
+
+ dev_set_drvdata(&spi->dev, chip);
+
+ chip->spi = spi;
+
+ chip->gpio_chip.label = GEN_74X164_DRIVER_NAME,
+ chip->gpio_chip.direction_output = gen_74x164_direction_output;
+ chip->gpio_chip.get = gen_74x164_get_value;
+ chip->gpio_chip.set = gen_74x164_set_value;
+ chip->gpio_chip.base = pdata->base;
+ chip->gpio_chip.ngpio = GEN_74X164_GPIO_COUNT;
+ chip->gpio_chip.can_sleep = 1;
+ chip->gpio_chip.dev = &spi->dev;
+ chip->gpio_chip.owner = THIS_MODULE;
+
+ ret = __gen_74x164_write_config(chip);
+ if (ret) {
+ dev_err(&spi->dev, "Failed writing: %d\n", ret);
+ goto exit_destroy;
+ }
+
+ ret = gpiochip_add(&chip->gpio_chip);
+ if (ret)
+ goto exit_destroy;
+
+ return ret;
+
+exit_destroy:
+ dev_set_drvdata(&spi->dev, NULL);
+ mutex_destroy(&chip->lock);
+ kfree(chip);
+ return ret;
+}
+
+static int gen_74x164_remove(struct spi_device *spi)
+{
+ struct gen_74x164_chip *chip;
+ int ret;
+
+ chip = dev_get_drvdata(&spi->dev);
+ if (chip == NULL)
+ return -ENODEV;
+
+ dev_set_drvdata(&spi->dev, NULL);
+
+ ret = gpiochip_remove(&chip->gpio_chip);
+ if (!ret) {
+ mutex_destroy(&chip->lock);
+ kfree(chip);
+ } else
+ dev_err(&spi->dev, "Failed to remove the GPIO controller: %d\n",
+ ret);
+
+ return ret;
+}
+
+static struct spi_driver gen_74x164_driver = {
+ .driver = {
+ .name = GEN_74X164_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = gen_74x164_probe,
+ .remove = __devexit_p(gen_74x164_remove),
+};
+
+static int __init gen_74x164_init(void)
+{
+ return spi_register_driver(&gen_74x164_driver);
+}
+subsys_initcall(gen_74x164_init);
+
+static void __exit gen_74x164_exit(void)
+{
+ spi_unregister_driver(&gen_74x164_driver);
+}
+module_exit(gen_74x164_exit);
+
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_AUTHOR("Miguel Gaio <miguel.gaio@efixo.com>");
+MODULE_DESCRIPTION("GPIO expander driver for 74X164 8-bits shift register");
+MODULE_LICENSE("GPL v2");
+
--- /dev/null
+++ b/include/linux/spi/74x164.h
@@ -0,0 +1,11 @@
+#ifndef LINUX_SPI_74X164_H
+#define LINUX_SPI_74X164_H
+
+#define GEN_74X164_DRIVER_NAME "74x164"
+
+struct gen_74x164_chip_platform_data {
+ /* number assigned to the first GPIO */
+ unsigned base;
+};
+
+#endif

@ -1,60 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -464,6 +464,49 @@ static struct board_info __initdata boar
.has_ohci0 = 1,
};
+
+static struct board_info __initdata board_96348_D4PW = {
+ .name = "D-4P-W",
+ .expected_cpu_id = 0x6348,
+
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+ .has_ehci0 = 1,
+
+ .leds = {
+ {
+ .name = "ppp",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp-fail",
+ .gpio = 5,
+ .active_low = 1,
+ },
+ {
+ .name = "power",
+ .gpio = 0,
+ .active_low = 1,
+ .default_trigger = "default-on",
+
+ },
+ },
+
+};
+
#endif
/*
@@ -728,6 +771,7 @@ static const struct board_info __initdat
&board_DV201AMR,
&board_96348gw_a,
&board_rta1025w_16,
+ &board_96348_D4PW,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358

@ -1,569 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -17,6 +17,9 @@
#include <linux/ssb/ssb.h>
#include <linux/gpio_buttons.h>
#include <linux/input.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_gpio.h>
+#include <linux/spi/74x164.h>
#include <asm/addrspace.h>
#include <bcm63xx_board.h>
#include <bcm63xx_cpu.h>
@@ -34,6 +37,12 @@
#define PFX "board_bcm963xx: "
+#define NB4_PID_OFFSET 0xff80
+#define NB4_74X164_GPIO_BASE 64
+#define NB4_SPI_GPIO_MOSI 7
+#define NB4_SPI_GPIO_CLK 6
+#define NB4_74HC64_GPIO(X) (NB4_74X164_GPIO_BASE + (X))
+
static struct bcm963xx_nvram nvram;
static unsigned int mac_addr_used;
static struct board_info board;
@@ -749,6 +758,502 @@ static struct board_info __initdata boar
.has_ohci0 = 1,
};
+
+struct spi_gpio_platform_data nb4_spi_gpio_data = {
+ .sck = NB4_SPI_GPIO_CLK,
+ .mosi = NB4_SPI_GPIO_MOSI,
+ .miso = SPI_GPIO_NO_MISO,
+ .num_chipselect = 1,
+};
+
+
+static struct platform_device nb4_spi_gpio = {
+ .name = "spi_gpio",
+ .id = 1,
+ .dev = {
+ .platform_data = &nb4_spi_gpio_data,
+ },
+};
+
+static struct platform_device * __initdata nb4_devices[] = {
+ &nb4_spi_gpio,
+};
+
+const struct gen_74x164_chip_platform_data nb4_74x164_platform_data = {
+ .base = NB4_74X164_GPIO_BASE
+};
+
+static struct spi_board_info nb4_spi_devices[] = {
+ {
+ .modalias = "74x164",
+ .max_speed_hz = 781000,
+ .bus_num = 1,
+ .controller_data = (void *) SPI_GPIO_NO_CHIPSELECT,
+ .mode = SPI_MODE_0,
+ .platform_data = &nb4_74x164_platform_data
+ }
+};
+
+static struct board_info __initdata board_nb4_ser_r0 = {
+ .name = "NB4-SER-r0",
+ .expected_cpu_id = 0x6358,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+
+ .has_ohci0 = 1,
+ .has_pccard = 1,
+ .has_ehci0 = 1,
+
+ .has_udc0 = 1,
+
+ .leds = {
+ {
+ .name = "adsl",
+ .gpio = NB4_74HC64_GPIO(4),
+ .active_low = 1,
+ },
+ {
+ .name = "traffic",
+ .gpio = 2,
+ .active_low = 1,
+ },
+ {
+ .name = "tel",
+ .gpio = NB4_74HC64_GPIO(3),
+ .active_low = 1,
+ },
+ {
+ .name = "tv",
+ .gpio = NB4_74HC64_GPIO(2),
+ .active_low = 1,
+ },
+ {
+ .name = "wifi",
+ .gpio = 15,
+ .active_low = 1,
+ },
+ {
+ .name = "alarm",
+ .gpio = NB4_74HC64_GPIO(0),
+ .active_low = 1,
+ },
+ {
+ .name = "service:red",
+ .gpio = 29,
+ .active_low = 1,
+ },
+ {
+ .name = "service:green",
+ .gpio = 30,
+ .active_low = 1,
+ },
+ {
+ .name = "service:blue",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ },
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 34,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ {
+ .desc = "wps",
+ .gpio = 37,
+ .type = EV_KEY,
+ .code = KEY_WPS_BUTTON,
+ .threshold = 3,
+ },
+ },
+ .devs = nb4_devices,
+ .num_devs = ARRAY_SIZE(nb4_devices),
+ .spis = nb4_spi_devices,
+ .num_spis = ARRAY_SIZE(nb4_spi_devices),
+};
+
+static struct board_info __initdata board_nb4_ser_r1 = {
+ .name = "NB4-SER-r1",
+ .expected_cpu_id = 0x6358,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+
+ .has_ohci0 = 1,
+ .has_pccard = 1,
+ .has_ehci0 = 1,
+
+ .has_udc0 = 1,
+
+ .leds = {
+ {
+ .name = "adsl",
+ .gpio = NB4_74HC64_GPIO(4),
+ .active_low = 1,
+ },
+ {
+ .name = "traffic",
+ .gpio = 2,
+ .active_low = 1,
+ },
+ {
+ .name = "tel",
+ .gpio = NB4_74HC64_GPIO(3),
+ .active_low = 1,
+ },
+ {
+ .name = "tv",
+ .gpio = NB4_74HC64_GPIO(2),
+ .active_low = 1,
+ },
+ {
+ .name = "wifi",
+ .gpio = 15,
+ .active_low = 1,
+ },
+ {
+ .name = "alarm",
+ .gpio = NB4_74HC64_GPIO(0),
+ .active_low = 1,
+ },
+ {
+ .name = "service:red",
+ .gpio = 29,
+ .active_low = 1,
+ },
+ {
+ .name = "service:green",
+ .gpio = 30,
+ .active_low = 1,
+ },
+ {
+ .name = "service:blue",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ },
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 34,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ {
+ .desc = "wps",
+ .gpio = 37,
+ .type = EV_KEY,
+ .code = KEY_WPS_BUTTON,
+ .threshold = 3,
+ },
+ },
+ .devs = nb4_devices,
+ .num_devs = ARRAY_SIZE(nb4_devices),
+ .spis = nb4_spi_devices,
+ .num_spis = ARRAY_SIZE(nb4_spi_devices),
+};
+
+static struct board_info __initdata board_nb4_ser_r2 = {
+ .name = "NB4-SER-r2",
+ .expected_cpu_id = 0x6358,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+
+ .has_ohci0 = 1,
+ .has_pccard = 1,
+ .has_ehci0 = 1,
+
+ .leds = {
+ {
+ .name = "adsl",
+ .gpio = NB4_74HC64_GPIO(4),
+ .active_low = 1,
+ },
+ {
+ .name = "traffic",
+ .gpio = 2,
+ .active_low = 1,
+ },
+ {
+ .name = "tel",
+ .gpio = NB4_74HC64_GPIO(3),
+ .active_low = 1,
+ },
+ {
+ .name = "tv",
+ .gpio = NB4_74HC64_GPIO(2),
+ .active_low = 1,
+ },
+ {
+ .name = "wifi",
+ .gpio = 15,
+ .active_low = 1,
+ },
+ {
+ .name = "alarm",
+ .gpio = NB4_74HC64_GPIO(0),
+ .active_low = 1,
+ },
+ {
+ .name = "service:red",
+ .gpio = 29,
+ .active_low = 1,
+ },
+ {
+ .name = "service:green",
+ .gpio = 30,
+ .active_low = 1,
+ },
+ {
+ .name = "service:blue",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ },
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 34,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ {
+ .desc = "wps",
+ .gpio = 37,
+ .type = EV_KEY,
+ .code = KEY_WPS_BUTTON,
+ .threshold = 3,
+ },
+ },
+ .devs = nb4_devices,
+ .num_devs = ARRAY_SIZE(nb4_devices),
+ .spis = nb4_spi_devices,
+ .num_spis = ARRAY_SIZE(nb4_spi_devices),
+};
+
+static struct board_info __initdata board_nb4_fxc_r1 = {
+ .name = "NB4-FXC-r1",
+ .expected_cpu_id = 0x6358,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+
+ .has_ohci0 = 1,
+ .has_pccard = 1,
+ .has_ehci0 = 1,
+
+ .has_udc0 = 1,
+
+ .leds = {
+ {
+ .name = "adsl",
+ .gpio = NB4_74HC64_GPIO(4),
+ .active_low = 1,
+ },
+ {
+ .name = "traffic",
+ .gpio = 2,
+ },
+ {
+ .name = "tel",
+ .gpio = NB4_74HC64_GPIO(3),
+ .active_low = 1,
+ },
+ {
+ .name = "tv",
+ .gpio = NB4_74HC64_GPIO(2),
+ .active_low = 1,
+ },
+ {
+ .name = "wifi",
+ .gpio = 15,
+ },
+ {
+ .name = "alarm",
+ .gpio = NB4_74HC64_GPIO(0),
+ .active_low = 1,
+ },
+ {
+ .name = "service:red",
+ .gpio = 29,
+ },
+ {
+ .name = "service:green",
+ .gpio = 30,
+ },
+ {
+ .name = "service:blue",
+ .gpio = 4,
+ },
+ },
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 34,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ {
+ .desc = "wps",
+ .gpio = 37,
+ .type = EV_KEY,
+ .code = KEY_WPS_BUTTON,
+ .threshold = 3,
+ },
+ },
+ .devs = nb4_devices,
+ .num_devs = ARRAY_SIZE(nb4_devices),
+ .spis = nb4_spi_devices,
+ .num_spis = ARRAY_SIZE(nb4_spi_devices),
+};
+
+static struct board_info __initdata board_nb4_fxc_r2 = {
+ .name = "NB4-FXC-r2",
+ .expected_cpu_id = 0x6358,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+
+ .has_ohci0 = 1,
+ .has_pccard = 1,
+ .has_ehci0 = 1,
+
+ .leds = {
+ {
+ .name = "adsl",
+ .gpio = NB4_74HC64_GPIO(4),
+ .active_low = 1,
+ },
+ {
+ .name = "traffic",
+ .gpio = 2,
+ },
+ {
+ .name = "tel",
+ .gpio = NB4_74HC64_GPIO(3),
+ .active_low = 1,
+ },
+ {
+ .name = "tv",
+ .gpio = NB4_74HC64_GPIO(2),
+ .active_low = 1,
+ },
+ {
+ .name = "wifi",
+ .gpio = 15,
+ },
+ {
+ .name = "alarm",
+ .gpio = NB4_74HC64_GPIO(0),
+ .active_low = 1,
+ },
+ {
+ .name = "service:red",
+ .gpio = 29,
+ },
+ {
+ .name = "service:green",
+ .gpio = 30,
+ },
+ {
+ .name = "service:blue",
+ .gpio = 4,
+ },
+ },
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 34,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ {
+ .desc = "wps",
+ .gpio = 37,
+ .type = EV_KEY,
+ .code = KEY_WPS_BUTTON,
+ .threshold = 3,
+ },
+ },
+ .devs = nb4_devices,
+ .num_devs = ARRAY_SIZE(nb4_devices),
+ .spis = nb4_spi_devices,
+ .num_spis = ARRAY_SIZE(nb4_spi_devices),
+};
#endif
/*
@@ -779,9 +1284,30 @@ static const struct board_info __initdat
&board_96358vw2,
&board_AGPFS0,
&board_DWVS0,
+ &board_nb4_ser_r0,
+ &board_nb4_ser_r1,
+ &board_nb4_ser_r2,
+ &board_nb4_fxc_r1,
+ &board_nb4_fxc_r2,
#endif
};
+static void __init nb4_nvram_fixup(void)
+{
+ u8 *boot_addr, *p;
+ u32 val;
+
+ if (BCMCPU_IS_6358() && (!strcmp(nvram.name, "96358VW"))) {
+ val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+ val &= MPI_CSBASE_BASE_MASK;
+ boot_addr = (u8 *)KSEG1ADDR(val);
+ /* Extract nb4 PID */
+ p = boot_addr + NB4_PID_OFFSET;
+ if (!memcmp(p, "NB4-", 4))
+ memcpy(nvram.name, p, sizeof("NB4-XXX-rX"));
+ }
+}
+
/*
* Register a sane SPROMv2 to make the on-board
* bcm4318 WLAN work
@@ -899,6 +1425,9 @@ void __init board_prom_init(void)
return;
}
+ /* Fixup broken nb4 board name */
+ nb4_nvram_fixup();
+
/* find board by name */
for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
if (strncmp(nvram.name, bcm963xx_boards[i]->name,

File diff suppressed because it is too large Load Diff

@ -1,22 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -1477,6 +1477,8 @@ void __init board_prom_init(void)
if (BCMCPU_IS_6348())
val |= GPIO_MODE_6348_G3_EXT_MII |
GPIO_MODE_6348_G0_EXT_MII;
+ else if (BCMCPU_IS_6358())
+ val |= GPIO_MODE_6358_ENET1_MII_CLK_INV;
}
bcm_gpio_writel(val, GPIO_MODE_REG);
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -402,6 +402,8 @@
#define GPIO_MODE_6358_EXTRA_SPI_SS (1 << 7)
#define GPIO_MODE_6358_SERIAL_LED (1 << 10)
#define GPIO_MODE_6358_UTOPIA (1 << 12)
+#define GPIO_MODE_6358_ENET0_MII_CLK_INV (1 << 30)
+#define GPIO_MODE_6358_ENET1_MII_CLK_INV (1 << 31)
/*************************************************************************

@ -1,16 +0,0 @@
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -837,11 +837,13 @@ static int ehci_hub_control (
* power switching; they're allowed to just limit the
* current. khubd will turn the power back on.
*/
+#ifndef CONFIG_BCM63XX
if (HCS_PPC (ehci->hcs_params)){
ehci_writel(ehci,
temp & ~(PORT_RWC_BITS | PORT_POWER),
status_reg);
}
+#endif
}
/* whoever resumes must GetPortStatus to complete it!! */

@ -1,49 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -135,6 +135,38 @@ static struct board_info __initdata boar
},
},
};
+
+static struct board_info __initdata board_96338w2_e7t = {
+ .name = "96338W2_E7T",
+ .expected_cpu_id = 0x6338,
+
+ .has_enet0 = 1,
+
+ .enet0 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .leds = {
+ {
+ .name = "ppp",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp-fail",
+ .gpio = 5,
+ .active_low = 1,
+ },
+ {
+ .name = "power",
+ .gpio = 0,
+ .active_low = 1,
+ .default_trigger = "default-on",
+
+ },
+ },
+};
#endif
/*
@@ -1264,6 +1296,7 @@ static const struct board_info __initdat
#ifdef CONFIG_BCM63XX_CPU_6338
&board_96338gw,
&board_96338w,
+ &board_96338w2_e7t,
#endif
#ifdef CONFIG_BCM63XX_CPU_6345
&board_96345gw2,

@ -1,34 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -49,6 +49,13 @@ static unsigned int mac_addr_used;
static struct board_info board;
/*
+ * Required export for WL
+ */
+#define NVRAM_SPACE 0x8000
+char nvram_buf[NVRAM_SPACE];
+EXPORT_SYMBOL(nvram_buf);
+
+/*
* known 6338 boards
*/
#ifdef CONFIG_BCM63XX_CPU_6338
@@ -1444,6 +1451,7 @@ void __init board_prom_init(void)
/* extract nvram data */
memcpy(&nvram, boot_addr + BCM963XX_NVRAM_OFFSET, sizeof(nvram));
+ memcpy(&nvram_buf, boot_addr + BCM963XX_NVRAM_OFFSET, NVRAM_SPACE);
/* check checksum before using data */
if (nvram.version <= 4)
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -52,6 +52,7 @@ void (*_dma_cache_wback)(unsigned long s
void (*_dma_cache_inv)(unsigned long start, unsigned long size);
EXPORT_SYMBOL(_dma_cache_wback_inv);
+EXPORT_SYMBOL(_dma_cache_inv);
#endif /* CONFIG_DMA_NONCOHERENT */

@ -1,109 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -662,6 +662,98 @@ static struct board_info __initdata boar
},
};
+static struct board_info __initdata board_CPVA642 = {
+ .name = "CPVA642",
+ .expected_cpu_id = 0x6358,
+
+ .has_uart0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+ .has_ehci0 = 1,
+
+ .leds = {
+ /* bi-color */
+ {
+ .name = "power:red",
+ .gpio = 14,
+ .active_low = 1,
+ },
+ {
+ .name = "power:green",
+ .gpio = 11,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "wifi:red",
+ .gpio = 6,
+ .active_low = 1,
+ },
+ {
+ .name = "wifi:green",
+ .gpio = 28,
+ .active_low = 0,
+ },
+ {
+ .name = "link:red",
+ .gpio = 9,
+ .active_low = 1,
+ },
+ {
+ .name = "link:green",
+ .gpio = 10,
+ .active_low = 1,
+ },
+ /* green only */
+ {
+ .name = "ether",
+ .gpio = 1,
+ .active_low = 1,
+ },
+ {
+ .name = "phone1",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "phone2",
+ .gpio = 2,
+ .active_low = 1,
+ },
+ {
+ .name = "usb",
+ .gpio = 3,
+ .active_low = 1,
+ },
+ },
+
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 36,
+ .active_low = 1,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ {
+ .desc = "wps",
+ .gpio = 37,
+ .type = EV_KEY,
+ .code = KEY_WPS_BUTTON,
+ .threshold = 3,
+ },
+ },
+};
+
+
static struct board_info __initdata board_AGPFS0 = {
.name = "AGPF-S0",
.expected_cpu_id = 0x6358,
@@ -1324,6 +1416,7 @@ static const struct board_info __initdat
&board_96358vw,
&board_96358vw2,
&board_AGPFS0,
+ &board_CPVA642,
&board_DWVS0,
&board_nb4_ser_r0,
&board_nb4_ser_r1,

@ -1,70 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -562,6 +562,59 @@ static struct board_info __initdata boar
* known 6358 boards
*/
#ifdef CONFIG_BCM63XX_CPU_6358
+
+static struct board_info __initdata board_96358gw = {
+ .name = "96358GW",
+ .expected_cpu_id = 0x6358,
+
+ .has_uart0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .leds = {
+ {
+ .name = "power:green",
+ .gpio = 5,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "power:red",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "adsl",
+ .gpio = 9,
+ .active_low = 1,
+ },
+ {
+ .name = "internet:green",
+ .gpio = 2,
+ },
+ {
+ .name = "internet:red",
+ .gpio = 10,
+ },
+ },
+
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 34,
+ .active_low = 1,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ },
+};
+
static struct board_info __initdata board_96358vw = {
.name = "96358VW",
.expected_cpu_id = 0x6358,
@@ -1413,6 +1466,7 @@ static const struct board_info __initdat
#endif
#ifdef CONFIG_BCM63XX_CPU_6358
+ &board_96358gw,
&board_96358vw,
&board_96358vw2,
&board_AGPFS0,

@ -1,62 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -35,6 +35,7 @@
#include <bcm63xx_dev_usb_udc.h>
#include <bcm63xx_dev_spi.h>
#include <board_bcm963xx.h>
+#include <bcm_tag.h>
#define PFX "board_bcm963xx: "
@@ -44,6 +45,9 @@
#define NB4_SPI_GPIO_CLK 6
#define NB4_74HC64_GPIO(X) (NB4_74X164_GPIO_BASE + (X))
+#define CFE_OFFSET_64K 0x10000
+#define CFE_OFFSET_128K 0x20000
+
static struct bcm963xx_nvram nvram;
static unsigned int mac_addr_used;
static struct board_info board;
@@ -1566,6 +1570,29 @@ static int board_get_mac_address(u8 *mac
return 0;
}
+static void __init boardid_fixup(u8 *boot_addr)
+{
+ struct bcm_tag *tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_64K);
+
+ /* check if bcm_tag is at 64k offset */
+ if (strncmp(nvram.name, tag->boardid, BOARDID_LEN) != 0) {
+ /* else try 128k */
+ tag = (struct bcm_tag *)(boot_addr + CFE_OFFSET_128K);
+ if (strncmp(nvram.name, tag->boardid, BOARDID_LEN) != 0) {
+ /* No tag found */
+ printk(KERN_DEBUG "No bcm_tag found!\n");
+ return;
+ }
+ }
+ /* check if we should override the boardid */
+ if (tag->information1[0] != '+')
+ return;
+
+ strncpy(nvram.name, &tag->information1[1], BOARDID_LEN);
+
+ printk(KERN_INFO "Overriding boardid with '%s'\n", nvram.name);
+}
+
/*
* early init callback, read nvram data from flash and checksum it
*/
@@ -1617,6 +1644,11 @@ void __init board_prom_init(void)
/* Fixup broken nb4 board name */
nb4_nvram_fixup();
+ if (strcmp(cfe_version, "unknown") != 0) {
+ /* cfe present */
+ boardid_fixup(boot_addr);
+ }
+
/* find board by name */
for (i = 0; i < ARRAY_SIZE(bcm963xx_boards); i++) {
if (strncmp(nvram.name, bcm963xx_boards[i]->name,

@ -1,78 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -560,6 +560,67 @@ static struct board_info __initdata boar
};
+static struct board_info __initdata board_spw500v = {
+ .name = "SPW500V",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .has_dsp = 1,
+ .dsp = {
+ .gpio_rst = 6,
+ .gpio_int = 34,
+ .ext_irq = 2,
+ .cs = 2,
+ },
+
+ .leds = {
+ {
+ .name = "power:red",
+ .gpio = 1,
+ .active_low = 1,
+ },
+ {
+ .name = "power:green",
+ .gpio = 0,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "ppp",
+ .gpio = 3,
+ .active_low = 1,
+ },
+ { .name = "pstn",
+ .gpio = 28,
+ .active_low = 1,
+ },
+ {
+ .name = "voip",
+ .gpio = 32,
+ .active_low = 1,
+ },
+ },
+
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 33,
+ .active_low = 1,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ },
+};
+
#endif
/*
@@ -1467,6 +1528,7 @@ static const struct board_info __initdat
&board_96348gw_a,
&board_rta1025w_16,
&board_96348_D4PW,
+ &board_spw500v,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358

@ -1,129 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -432,6 +432,117 @@ static struct board_info __initdata boar
},
};
+static struct board_info __initdata board_gw6200 = {
+ .name = "GW6200",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+
+ .has_dsp = 1,
+ .dsp = {
+ .gpio_rst = 8, /* FIXME: What is real GPIO here? */
+ .gpio_int = 34,
+ .ext_irq = 2,
+ .cs = 2,
+ },
+
+ .leds = {
+ {
+ .name = "line1",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "line2",
+ .gpio = 5,
+ .active_low = 1,
+ },
+ {
+ .name = "line3",
+ .gpio = 6,
+ .active_low = 1,
+ },
+ {
+ .name = "tel",
+ .gpio = 7,
+ .active_low = 1,
+ },
+ {
+ .name = "ethernet",
+ .gpio = 35,
+ .active_low = 1,
+ },
+ },
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 36,
+ .active_low = 1,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ },
+};
+
+static struct board_info __initdata board_gw6000 = {
+ .name = "GW6000",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+
+ .has_dsp = 1,
+ .dsp = {
+ .gpio_rst = 6,
+ .gpio_int = 34,
+ .ext_irq = 2,
+ .cs = 2,
+ },
+
+ /* GW6000 has no GPIO-controlled leds */
+
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 36,
+ .active_low = 1,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ },
+};
+
+
+
static struct board_info __initdata board_FAST2404 = {
.name = "F@ST2404",
.expected_cpu_id = 0x6348,
@@ -1521,6 +1632,8 @@ static const struct board_info __initdat
#ifdef CONFIG_BCM63XX_CPU_6348
&board_96348r,
&board_96348gw,
+ &board_gw6000,
+ &board_gw6200,
&board_96348gw_10,
&board_96348gw_11,
&board_FAST2404,

@ -1,60 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -364,6 +364,49 @@ static struct board_info __initdata boar
},
};
+static struct board_info __initdata board_ct536_ct5621 = {
+ .name = "CT536_CT5621",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_enet0 = 0,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+ .has_pccard = 1,
+ .has_ehci0 = 1,
+
+ .leds = {
+ {
+ .name = "adsl-fail",
+ .gpio = 2,
+ .active_low = 1,
+ },
+ {
+ .name = "power",
+ .gpio = 0,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ },
+ .buttons = {
+ {
+ .desc = "reset",
+ .gpio = 33,
+ .active_low = 1,
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .threshold = 3,
+ },
+ },
+};
+
static struct board_info __initdata board_96348gw = {
.name = "96348GW",
.expected_cpu_id = 0x6348,
@@ -1642,6 +1685,7 @@ static const struct board_info __initdat
&board_rta1025w_16,
&board_96348_D4PW,
&board_spw500v,
+ &board_ct536_ct5621,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358

@ -1,89 +0,0 @@
Index: linux-2.6.35.9/arch/mips/bcm63xx/boards/board_bcm963xx.c
===================================================================
--- linux-2.6.35.9.orig/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ linux-2.6.35.9/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -775,6 +775,76 @@ static struct board_info __initdata boar
},
};
+static struct board_info __initdata board_96348sv = {
+ .name = "MAGIC",
+ .expected_cpu_id = 0x6348,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+ .enet1 = {
+ /* is has BP_ENET_EXTERNAL_PHY */
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+ .has_pccard = 1,
+ .has_ehci0 = 1,
+
+ .has_dsp = 1,
+ .dsp = {
+ .gpio_rst = 25,
+ .gpio_int = 34,
+ .cs = 2,
+ .ext_irq = 2,
+ },
+
+ .leds = {
+ {
+ .name = "voip",
+ .gpio = 22,
+ .active_low = 1,
+ },
+ {
+ .name = "adsl",
+ .gpio = 5,
+ .active_low = 1,
+ },
+ {
+ .name = "wifi",
+ .gpio = 28,
+ },
+ {
+ .name = "usb",
+ .gpio = 35,
+ .active_low = 1,
+ },
+ {
+ .name = "hpna",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "power",
+ .gpio = 0,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "stop",
+ .gpio = 1,
+ .active_low = 1,
+ },
+ },
+};
+
#endif
/*
@@ -1686,6 +1756,7 @@ static const struct board_info __initdat
&board_96348_D4PW,
&board_spw500v,
&board_ct536_ct5621,
+ &board_96348sv,
#endif
#ifdef CONFIG_BCM63XX_CPU_6358

@ -1,90 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -1730,6 +1730,79 @@ static struct board_info __initdata boar
};
#endif
+static struct board_info __initdata board_HW553 = {
+ .name = "HW553",
+ .expected_cpu_id = 0x6358,
+
+ .has_enet0 = 1,
+ .has_enet1 = 1,
+ .has_pci = 1,
+
+ .enet0 = {
+ .has_phy = 1,
+ .use_internal_phy = 1,
+ },
+
+ .enet1 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .has_ohci0 = 1,
+ .has_ehci0 = 1,
+
+ .leds = {
+ /*Each led on HW553 is bi-color (except wifi) */
+ {
+ .name = "lan:red",
+ .gpio = 34,
+ .active_low = 1,
+ },
+ {
+ .name = "lan:blue",
+ .gpio = 35,
+ .active_low = 1,
+ },
+ {
+ .name = "adsl:red",
+ .gpio = 22,
+ .active_low = 1,
+ },
+ {
+ .name = "adsl:blue",
+ .gpio = 23,
+ .active_low = 1,
+ },
+ {
+ .name = "power:red",
+ .gpio = 5,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+
+ {
+ .name = "power:blue",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "wifi:red",
+ .gpio = 25,
+ .active_low = 1,
+ },
+ {
+ .name = "internetkey:red",
+ .gpio = 12,
+ .active_low = 1,
+ },
+ {
+ .name = "internetkey:blue",
+ .gpio = 13,
+ .active_low = 1,
+ },
+ },
+};
+
/*
* all boards
*/
@@ -1771,6 +1844,7 @@ static const struct board_info __initdat
&board_nb4_ser_r2,
&board_nb4_fxc_r1,
&board_nb4_fxc_r2,
+ &board_HW553,
#endif
};

@ -1,54 +0,0 @@
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -178,6 +178,43 @@ static struct board_info __initdata boar
},
},
};
+
+static struct board_info __initdata board_rta1320_16m = {
+ .name = "RTA1320_16M",
+ .expected_cpu_id = 0x6338,
+
+ .has_uart0 = 1,
+ .has_enet0 = 1,
+
+ .enet0 = {
+ .force_speed_100 = 1,
+ .force_duplex_full = 1,
+ },
+
+ .leds = {
+ {
+ .name = "adsl",
+ .gpio = 3,
+ .active_low = 1,
+ },
+ {
+ .name = "ppp",
+ .gpio = 4,
+ .active_low = 1,
+ },
+ {
+ .name = "power",
+ .gpio = 0,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "stop",
+ .gpio = 1,
+ .active_low = 1,
+ },
+ },
+};
#endif
/*
@@ -1811,6 +1848,7 @@ static const struct board_info __initdat
&board_96338gw,
&board_96338w,
&board_96338w2_e7t,
+ &board_rta1320_16m,
#endif
#ifdef CONFIG_BCM63XX_CPU_6345
&board_96345gw2,

@ -1,20 +0,0 @@
--- a/drivers/ssb/sprom.c
+++ b/drivers/ssb/sprom.c
@@ -176,6 +176,7 @@ const struct ssb_sprom *ssb_get_fallback
{
return fallback_sprom;
}
+EXPORT_SYMBOL(ssb_get_fallback_sprom);
/* http://bcm-v4.sipsolutions.net/802.11/IsSpromAvailable */
bool ssb_is_sprom_available(struct ssb_bus *bus)
--- a/include/linux/ssb/ssb.h
+++ b/include/linux/ssb/ssb.h
@@ -405,6 +405,7 @@ extern bool ssb_is_sprom_available(struc
/* Set a fallback SPROM.
* See kdoc at the function definition for complete documentation. */
extern int ssb_arch_set_fallback_sprom(const struct ssb_sprom *sprom);
+extern const struct ssb_sprom *ssb_get_fallback_sprom(void);
/* Suspend a SSB bus.
* Call this from the parent bus suspend routine. */
Loading…
Cancel
Save