ar71xx: add 4.1 support

Signed-off-by: Roman Yeryomin <roman@advem.lv>

SVN-Revision: 46426
This commit is contained in:
Felix Fietkau 2015-07-19 17:58:40 +00:00
parent d26e8d9439
commit 78b1a6b773
95 changed files with 10253 additions and 0 deletions

View File

@ -0,0 +1,336 @@
CONFIG_AG71XX=y
CONFIG_AG71XX_AR8216_SUPPORT=y
# CONFIG_AG71XX_DEBUG is not set
# CONFIG_AG71XX_DEBUG_FS is not set
CONFIG_AT803X_PHY=y
CONFIG_AR8216_PHY=y
CONFIG_AR8216_PHY_LEDS=y
CONFIG_ARCH_BINFMT_ELF_RANDOMIZE_PIE=y
CONFIG_ARCH_DISCARD_MEMBLOCK=y
CONFIG_ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE=y
# CONFIG_ARCH_HAS_SG_CHAIN is not set
CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y
CONFIG_ARCH_HIBERNATION_POSSIBLE=y
CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y
CONFIG_ARCH_MIGHT_HAVE_PC_SERIO=y
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y
CONFIG_ATH79=y
CONFIG_ATH79_DEV_AP9X_PCI=y
CONFIG_ATH79_DEV_DSA=y
CONFIG_ATH79_DEV_ETH=y
CONFIG_ATH79_DEV_GPIO_BUTTONS=y
CONFIG_ATH79_DEV_LEDS_GPIO=y
CONFIG_ATH79_DEV_M25P80=y
CONFIG_ATH79_DEV_NFC=y
CONFIG_ATH79_DEV_SPI=y
CONFIG_ATH79_DEV_USB=y
CONFIG_ATH79_DEV_WMAC=y
CONFIG_ATH79_MACH_ALFA_AP96=y
CONFIG_ATH79_MACH_ALFA_NX=y
CONFIG_ATH79_MACH_ALL0258N=y
CONFIG_ATH79_MACH_ALL0315N=y
CONFIG_ATH79_MACH_AP113=y
CONFIG_ATH79_MACH_AP121=y
CONFIG_ATH79_MACH_AP132=y
CONFIG_ATH79_MACH_AP136=y
CONFIG_ATH79_MACH_AP143=y
CONFIG_ATH79_MACH_AP81=y
CONFIG_ATH79_MACH_AP83=y
CONFIG_ATH79_MACH_AP96=y
CONFIG_ATH79_MACH_ARCHER_C7=y
CONFIG_ATH79_MACH_AW_NR580=y
CONFIG_ATH79_MACH_ANTMINER_S1=y
CONFIG_ATH79_MACH_ANTMINER_S3=y
CONFIG_ATH79_MACH_BHU_BXU2000N2_A=y
CONFIG_ATH79_MACH_CAP4200AG=y
CONFIG_ATH79_MACH_CARAMBOLA2=y
CONFIG_ATH79_MACH_CPE510=y
CONFIG_ATH79_MACH_DB120=y
CONFIG_ATH79_MACH_DGL_5500_A1=y
CONFIG_ATH79_MACH_DHP_1565_A1=y
CONFIG_ATH79_MACH_DIR_505_A1=y
CONFIG_ATH79_MACH_DIR_600_A1=y
CONFIG_ATH79_MACH_DIR_615_C1=y
CONFIG_ATH79_MACH_DIR_615_I1=y
CONFIG_ATH79_MACH_DIR_825_B1=y
CONFIG_ATH79_MACH_DIR_825_C1=y
CONFIG_ATH79_MACH_DLAN_PRO_1200_AC=y
CONFIG_ATH79_MACH_DLAN_PRO_500_WP=y
CONFIG_ATH79_MACH_DRAGINO2=y
CONFIG_ATH79_MACH_EAP300V2=y
CONFIG_ATH79_MACH_EAP7660D=y
CONFIG_ATH79_MACH_EL_M150=y
CONFIG_ATH79_MACH_EL_MINI=y
CONFIG_ATH79_MACH_EPG5000=y
CONFIG_ATH79_MACH_ESR1750=y
CONFIG_ATH79_MACH_ESR900=y
CONFIG_ATH79_MACH_EW_DORIN=y
CONFIG_ATH79_MACH_F9K1115V2=y
CONFIG_ATH79_MACH_GL_INET=y
CONFIG_ATH79_MACH_GS_OOLITE=y
CONFIG_ATH79_MACH_HIWIFI_HC6361=y
CONFIG_ATH79_MACH_HORNET_UB=y
CONFIG_ATH79_MACH_JA76PF=y
CONFIG_ATH79_MACH_JWAP003=y
CONFIG_ATH79_MACH_MC_MAC1200R=y
CONFIG_ATH79_MACH_MR16=y
CONFIG_ATH79_MACH_MR12=y
CONFIG_ATH79_MACH_MR600=y
CONFIG_ATH79_MACH_MR900=y
CONFIG_ATH79_MACH_MYNET_N600=y
CONFIG_ATH79_MACH_MYNET_N750=y
CONFIG_ATH79_MACH_MYNET_REXT=y
CONFIG_ATH79_MACH_MZK_W04NU=y
CONFIG_ATH79_MACH_MZK_W300NH=y
CONFIG_ATH79_MACH_NBG460N=y
CONFIG_ATH79_MACH_NBG6716=y
CONFIG_ATH79_MACH_OM2P=y
CONFIG_ATH79_MACH_OM5P=y
CONFIG_ATH79_MACH_PB42=y
CONFIG_ATH79_MACH_PB44=y
CONFIG_ATH79_MACH_PB92=y
CONFIG_ATH79_MACH_QIHOO_C301=y
CONFIG_ATH79_MACH_R6100=y
# CONFIG_ATH79_MACH_RB2011 is not set
# CONFIG_ATH79_MACH_RB4XX is not set
# CONFIG_ATH79_MACH_RB750 is not set
# CONFIG_ATH79_MACH_RB91X is not set
# CONFIG_ATH79_MACH_RB922 is not set
# CONFIG_ATH79_MACH_RB95X is not set
# CONFIG_ATH79_MACH_RBSXTLITE is not set
CONFIG_ATH79_MACH_RW2458N=y
CONFIG_ATH79_MACH_SMART_300=y
CONFIG_ATH79_MACH_TEW_632BRP=y
CONFIG_ATH79_MACH_TEW_673GRU=y
CONFIG_ATH79_MACH_TEW_712BR=y
CONFIG_ATH79_MACH_TEW_732BR=y
CONFIG_ATH79_MACH_TL_MR11U=y
CONFIG_ATH79_MACH_TL_MR13U=y
CONFIG_ATH79_MACH_TL_MR3020=y
CONFIG_ATH79_MACH_TL_MR3X20=y
CONFIG_ATH79_MACH_TL_WA701ND_V2=y
CONFIG_ATH79_MACH_TL_WA7210N_V2=y
CONFIG_ATH79_MACH_TL_WA830RE_V2=y
CONFIG_ATH79_MACH_TL_WA901ND=y
CONFIG_ATH79_MACH_TL_WA901ND_V2=y
CONFIG_ATH79_MACH_TL_WAX50RE=y
CONFIG_ATH79_MACH_TL_WDR3500=y
CONFIG_ATH79_MACH_TL_WDR4300=y
CONFIG_ATH79_MACH_TL_WR1041N_V2=y
CONFIG_ATH79_MACH_TL_WR1043ND=y
CONFIG_ATH79_MACH_TL_WR1043ND_V2=y
CONFIG_ATH79_MACH_TL_WR2543N=y
CONFIG_ATH79_MACH_TL_WR703N=y
CONFIG_ATH79_MACH_TL_WR720N_V3=y
CONFIG_ATH79_MACH_TL_WR741ND=y
CONFIG_ATH79_MACH_TL_WR741ND_V4=y
CONFIG_ATH79_MACH_TL_WR841N_V1=y
CONFIG_ATH79_MACH_TL_WR841N_V8=y
CONFIG_ATH79_MACH_TL_WR841N_V9=y
CONFIG_ATH79_MACH_TL_WR941ND=y
CONFIG_ATH79_MACH_TUBE2H=y
CONFIG_ATH79_MACH_UBNT=y
CONFIG_ATH79_MACH_UBNT_XM=y
CONFIG_ATH79_MACH_WHR_HP_G300N=y
CONFIG_ATH79_MACH_WLAE_AG300N=y
CONFIG_ATH79_MACH_WLR8100=y
CONFIG_ATH79_MACH_WNDAP360=y
CONFIG_ATH79_MACH_WNDR3700=y
CONFIG_ATH79_MACH_WNDR4300=y
CONFIG_ATH79_MACH_WNR2000=y
CONFIG_ATH79_MACH_WNR2000_V3=y
CONFIG_ATH79_MACH_WNR2000_V4=y
CONFIG_ATH79_MACH_WNR2200=y
CONFIG_ATH79_MACH_WP543=y
CONFIG_ATH79_MACH_WPE72=y
CONFIG_ATH79_MACH_WPJ344=y
CONFIG_ATH79_MACH_WPJ531=y
CONFIG_ATH79_MACH_WPJ558=y
CONFIG_ATH79_MACH_WRT160NL=y
CONFIG_ATH79_MACH_WRT400N=y
CONFIG_ATH79_MACH_WAP4410N=y
CONFIG_ATH79_MACH_WZR_450HP2=y
CONFIG_ATH79_MACH_WZR_HP_AG300H=y
CONFIG_ATH79_MACH_WZR_HP_G300NH=y
CONFIG_ATH79_MACH_WZR_HP_G300NH2=y
CONFIG_ATH79_MACH_WZR_HP_G450H=y
CONFIG_ATH79_MACH_ZCN_1523H=y
CONFIG_ATH79_NVRAM=y
CONFIG_ATH79_PCI_ATH9K_FIXUP=y
# CONFIG_ATH79_ROUTERBOOT is not set
CONFIG_ATH79_WDT=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_CEVT_R4K=y
CONFIG_CLKDEV_LOOKUP=y
CONFIG_CLONE_BACKWARDS=y
CONFIG_CMDLINE="rootfstype=squashfs,jffs2 noinitrd"
CONFIG_CMDLINE_BOOL=y
# CONFIG_CMDLINE_OVERRIDE is not set
CONFIG_CPU_BIG_ENDIAN=y
CONFIG_CPU_GENERIC_DUMP_TLB=y
CONFIG_CPU_HAS_PREFETCH=y
CONFIG_CPU_HAS_SYNC=y
CONFIG_CPU_MIPS32=y
CONFIG_CPU_MIPS32_R2=y
CONFIG_CPU_MIPSR2=y
CONFIG_CPU_NEEDS_NO_SMARTMIPS_OR_MICROMIPS=y
CONFIG_CPU_R4K_CACHE_TLB=y
CONFIG_CPU_R4K_FPU=y
CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y
CONFIG_CPU_SUPPORTS_HIGHMEM=y
CONFIG_CPU_SUPPORTS_MSA=y
CONFIG_CSRC_R4K=y
CONFIG_DMA_NONCOHERENT=y
CONFIG_EARLY_PRINTK=y
CONFIG_ETHERNET_PACKET_MANGLE=y
CONFIG_GENERIC_ATOMIC64=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
CONFIG_GENERIC_CMOS_UPDATE=y
CONFIG_GENERIC_IO=y
CONFIG_GENERIC_IRQ_SHOW=y
CONFIG_GENERIC_PCI_IOMAP=y
CONFIG_GENERIC_SMP_IDLE_THREAD=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_DEVRES=y
# CONFIG_GPIO_LATCH is not set
CONFIG_GPIO_NXP_74HC153=y
CONFIG_GPIO_PCF857X=y
CONFIG_GPIO_SYSFS=y
CONFIG_HARDWARE_WATCHPOINTS=y
CONFIG_HAS_DMA=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT_MAP=y
# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set
CONFIG_HAVE_ARCH_JUMP_LABEL=y
CONFIG_HAVE_ARCH_KGDB=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=y
CONFIG_HAVE_ARCH_TRACEHOOK=y
# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set
CONFIG_HAVE_BPF_JIT=y
CONFIG_HAVE_CC_STACKPROTECTOR=y
CONFIG_HAVE_CLK=y
CONFIG_HAVE_CONTEXT_TRACKING=y
CONFIG_HAVE_C_RECORDMCOUNT=y
CONFIG_HAVE_DEBUG_KMEMLEAK=y
CONFIG_HAVE_DEBUG_STACKOVERFLOW=y
CONFIG_HAVE_DMA_API_DEBUG=y
CONFIG_HAVE_DMA_ATTRS=y
CONFIG_HAVE_DMA_CONTIGUOUS=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_GENERIC_DMA_COHERENT=y
CONFIG_HAVE_IDE=y
CONFIG_HAVE_KVM=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_HAVE_MEMBLOCK_NODE_MAP=y
CONFIG_HAVE_MOD_ARCH_SPECIFIC=y
CONFIG_HAVE_NET_DSA=y
CONFIG_HAVE_OPROFILE=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_HAVE_SYSCALL_TRACEPOINTS=y
CONFIG_HW_HAS_PCI=y
CONFIG_HZ_PERIODIC=y
CONFIG_I2C=y
CONFIG_I2C_ALGOBIT=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_GPIO=y
CONFIG_IMAGE_CMDLINE_HACK=y
CONFIG_INITRAMFS_ROOT_GID=0
CONFIG_INITRAMFS_ROOT_UID=0
CONFIG_INITRAMFS_SOURCE="../../root"
CONFIG_IP17XX_PHY=y
CONFIG_IRQ_CPU=y
CONFIG_IRQ_DOMAIN=y
CONFIG_IRQ_FORCED_THREADING=y
CONFIG_IRQ_WORK=y
CONFIG_LEDS_GPIO=y
# CONFIG_LEDS_WNDR3700_USB is not set
CONFIG_MARVELL_PHY=y
CONFIG_MDIO_BOARDINFO=y
CONFIG_MICREL_PHY=y
CONFIG_MIPS=y
# CONFIG_MIPS_CDMM is not set
# CONFIG_MIPS_HUGE_TLB_SUPPORT is not set
CONFIG_MIPS_L1_CACHE_SHIFT=5
CONFIG_MIPS_MACHINE=y
CONFIG_MODULES_USE_ELF_REL=y
CONFIG_MTD_CFI_ADV_OPTIONS=y
CONFIG_MTD_CFI_GEOMETRY=y
# CONFIG_MTD_CFI_I2 is not set
# CONFIG_MTD_CFI_INTELEXT is not set
CONFIG_MTD_CMDLINE_PARTS=y
CONFIG_MTD_CYBERTAN_PARTS=y
CONFIG_MTD_M25P80=y
# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
CONFIG_MTD_MYLOADER_PARTS=y
CONFIG_MTD_PHYSMAP=y
CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-2
CONFIG_MTD_REDBOOT_PARTS=y
CONFIG_MTD_SPI_NOR=y
CONFIG_MTD_SPLIT_FIRMWARE=y
CONFIG_MTD_SPLIT_LZMA_FW=y
CONFIG_MTD_SPLIT_SEAMA_FW=y
CONFIG_MTD_SPLIT_UIMAGE_FW=y
CONFIG_MTD_TPLINK_PARTS=y
CONFIG_MYLOADER=y
CONFIG_NEED_DMA_MAP_STATE=y
CONFIG_NEED_PER_CPU_KM=y
CONFIG_NET_DSA=y
CONFIG_NET_DSA_MV88E6060=y
CONFIG_NET_DSA_MV88E6063=y
CONFIG_NET_DSA_TAG_TRAILER=y
CONFIG_NO_GENERIC_PCI_IOPORT_MAP=y
# CONFIG_NO_IOPORT_MAP is not set
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_PCI=y
CONFIG_PCI_AR724X=y
CONFIG_PCI_DISABLE_COMMON_QUIRKS=y
CONFIG_PCI_DOMAINS=y
CONFIG_PERF_USE_VMALLOC=y
CONFIG_PHYLIB=y
# CONFIG_PREEMPT_RCU is not set
# CONFIG_RCU_STALL_COMMON is not set
CONFIG_RTL8306_PHY=y
CONFIG_RTL8366RB_PHY=y
CONFIG_RTL8366S_PHY=y
CONFIG_RTL8366_SMI=y
CONFIG_RTL8367_PHY=y
# CONFIG_SCSI_DMA is not set
CONFIG_SERIAL_8250_NR_UARTS=1
CONFIG_SERIAL_8250_RUNTIME_UARTS=1
CONFIG_SERIAL_AR933X=y
CONFIG_SERIAL_AR933X_CONSOLE=y
CONFIG_SERIAL_AR933X_NR_UARTS=2
# CONFIG_SLAB is not set
CONFIG_SLUB=y
CONFIG_SOC_AR71XX=y
CONFIG_SOC_AR724X=y
CONFIG_SOC_AR913X=y
CONFIG_SOC_AR933X=y
CONFIG_SOC_AR934X=y
CONFIG_SOC_QCA953X=y
CONFIG_SOC_QCA955X=y
# CONFIG_SOC_QCA956X is not set
CONFIG_SPI=y
CONFIG_SPI_AP83=y
CONFIG_SPI_ATH79=y
CONFIG_SPI_BITBANG=y
CONFIG_SPI_MASTER=y
# CONFIG_SPI_VSC7385 is not set
CONFIG_SWCONFIG=y
CONFIG_SWCONFIG_LEDS=y
CONFIG_SYS_HAS_CPU_MIPS32_R2=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_SYS_SUPPORTS_MIPS16=y
CONFIG_TICK_CPU_ACCOUNTING=y
CONFIG_USB_SUPPORT=y
CONFIG_ZONE_DMA_FLAG=0

View File

@ -0,0 +1,42 @@
From 8b7a76e72fc819753878cd5684e243f33f847c79 Mon Sep 17 00:00:00 2001
From: Markos Chandras <markos.chandras@imgtec.com>
Date: Wed, 21 Aug 2013 11:47:22 +0100
Subject: [PATCH] MIPS: ath79: Avoid using unitialized 'reg' variable
Fixes the following build error:
arch/mips/include/asm/mach-ath79/ath79.h:139:20: error: 'reg' may be used
uninitialized in this function [-Werror=maybe-uninitialized]
arch/mips/ath79/common.c:62:6: note: 'reg' was declared here
In file included from arch/mips/ath79/common.c:20:0:
arch/mips/ath79/common.c: In function 'ath79_device_reset_clear':
arch/mips/include/asm/mach-ath79/ath79.h:139:20:
error: 'reg' may be used uninitialized in this function
[-Werror=maybe-uninitialized]
arch/mips/ath79/common.c:90:6: note: 'reg' was declared here
Signed-off-by: Markos Chandras <markos.chandras@imgtec.com>
Acked-by: Gabor Juhos <juhosg@openwrt.org>
---
arch/mips/ath79/common.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/mips/ath79/common.c
+++ b/arch/mips/ath79/common.c
@@ -75,7 +75,7 @@ void ath79_device_reset_set(u32 mask)
else if (soc_is_qca955x())
reg = QCA955X_RESET_REG_RESET_MODULE;
else
- BUG();
+ panic("Reset register not defined for this SOC");
spin_lock_irqsave(&ath79_device_reset_lock, flags);
t = ath79_reset_rr(reg);
@@ -103,7 +103,7 @@ void ath79_device_reset_clear(u32 mask)
else if (soc_is_qca955x())
reg = QCA955X_RESET_REG_RESET_MODULE;
else
- BUG();
+ panic("Reset register not defined for this SOC");
spin_lock_irqsave(&ath79_device_reset_lock, flags);
t = ath79_reset_rr(reg);

View File

@ -0,0 +1,191 @@
From 7008284716403237f6bc7d7590b3ed073555bd56 Mon Sep 17 00:00:00 2001
From: Gabor Juhos <juhosg@openwrt.org>
Date: Wed, 11 Jan 2012 22:25:11 +0100
Subject: [PATCH 34/34] spi/ath79: make chipselect logic more flexible
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
arch/mips/ath79/mach-pb44.c | 6 ++
.../include/asm/mach-ath79/ath79_spi_platform.h | 8 ++-
drivers/spi/spi-ath79.c | 67 +++++++++++++-------
8 files changed, 88 insertions(+), 23 deletions(-)
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -87,12 +87,18 @@ static struct gpio_keys_button pb44_gpio
}
};
+static struct ath79_spi_controller_data pb44_spi0_data = {
+ .cs_type = ATH79_SPI_CS_TYPE_INTERNAL,
+ .cs_line = 0,
+};
+
static struct spi_board_info pb44_spi_info[] = {
{
.bus_num = 0,
.chip_select = 0,
.max_speed_hz = 25000000,
.modalias = "m25p64",
+ .controller_data = &pb44_spi0_data,
},
};
--- a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
+++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
@@ -16,8 +16,14 @@ struct ath79_spi_platform_data {
unsigned num_chipselect;
};
+enum ath79_spi_cs_type {
+ ATH79_SPI_CS_TYPE_INTERNAL,
+ ATH79_SPI_CS_TYPE_GPIO,
+};
+
struct ath79_spi_controller_data {
- unsigned gpio;
+ enum ath79_spi_cs_type cs_type;
+ unsigned cs_line;
};
#endif /* _ATH79_SPI_PLATFORM_H */
--- a/drivers/spi/spi-ath79.c
+++ b/drivers/spi/spi-ath79.c
@@ -33,6 +33,8 @@
#define ATH79_SPI_RRW_DELAY_FACTOR 12000
#define MHZ (1000 * 1000)
+#define ATH79_SPI_CS_LINE_MAX 2
+
struct ath79_spi {
struct spi_bitbang bitbang;
u32 ioc_base;
@@ -67,6 +69,7 @@ static void ath79_spi_chipselect(struct
{
struct ath79_spi *sp = ath79_spidev_to_sp(spi);
int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
+ struct ath79_spi_controller_data *cdata = spi->controller_data;
if (is_active) {
/* set initial clock polarity */
@@ -78,20 +81,24 @@ static void ath79_spi_chipselect(struct
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
}
- if (spi->chip_select) {
- struct ath79_spi_controller_data *cdata = spi->controller_data;
-
- /* SPI is normally active-low */
- gpio_set_value(cdata->gpio, cs_high);
- } else {
+ switch (cdata->cs_type) {
+ case ATH79_SPI_CS_TYPE_INTERNAL:
if (cs_high)
- sp->ioc_base |= AR71XX_SPI_IOC_CS0;
+ sp->ioc_base |= AR71XX_SPI_IOC_CS(cdata->cs_line);
else
- sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
+ sp->ioc_base &= ~AR71XX_SPI_IOC_CS(cdata->cs_line);
ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
- }
+ break;
+ case ATH79_SPI_CS_TYPE_GPIO:
+ /* SPI is normally active-low */
+ if (gpio_cansleep(cdata->cs_line))
+ gpio_set_value_cansleep(cdata->cs_line, cs_high);
+ else
+ gpio_set_value(cdata->cs_line, cs_high);
+ break;
+ }
}
static void ath79_spi_enable(struct ath79_spi *sp)
@@ -118,24 +125,30 @@ static void ath79_spi_disable(struct ath
static int ath79_spi_setup_cs(struct spi_device *spi)
{
struct ath79_spi_controller_data *cdata;
+ unsigned long flags;
int status;
cdata = spi->controller_data;
- if (spi->chip_select && !cdata)
+ if (!cdata)
return -EINVAL;
status = 0;
- if (spi->chip_select) {
- unsigned long flags;
+ switch (cdata->cs_type) {
+ case ATH79_SPI_CS_TYPE_INTERNAL:
+ if (cdata->cs_line > ATH79_SPI_CS_LINE_MAX)
+ status = -EINVAL;
+ break;
+ case ATH79_SPI_CS_TYPE_GPIO:
flags = GPIOF_DIR_OUT;
if (spi->mode & SPI_CS_HIGH)
flags |= GPIOF_INIT_LOW;
else
flags |= GPIOF_INIT_HIGH;
- status = gpio_request_one(cdata->gpio, flags,
+ status = gpio_request_one(cdata->cs_line, flags,
dev_name(&spi->dev));
+ break;
}
return status;
@@ -143,9 +156,19 @@ static int ath79_spi_setup_cs(struct spi
static void ath79_spi_cleanup_cs(struct spi_device *spi)
{
- if (spi->chip_select) {
- struct ath79_spi_controller_data *cdata = spi->controller_data;
- gpio_free(cdata->gpio);
+ struct ath79_spi_controller_data *cdata;
+
+ cdata = spi->controller_data;
+ if (!cdata)
+ return;
+
+ switch (cdata->cs_type) {
+ case ATH79_SPI_CS_TYPE_INTERNAL:
+ /* nothing to do */
+ break;
+ case ATH79_SPI_CS_TYPE_GPIO:
+ gpio_free(cdata->cs_line);
+ break;
}
}
@@ -210,6 +233,10 @@ static int ath79_spi_probe(struct platfo
unsigned long rate;
int ret;
+ pdata = pdev->dev.platform_data;
+ if (!pdata)
+ return -EINVAL;
+
master = spi_alloc_master(&pdev->dev, sizeof(*sp));
if (master == NULL) {
dev_err(&pdev->dev, "failed to allocate spi master\n");
@@ -219,15 +246,11 @@ static int ath79_spi_probe(struct platfo
sp = spi_master_get_devdata(master);
platform_set_drvdata(pdev, sp);
- pdata = dev_get_platdata(&pdev->dev);
-
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
master->setup = ath79_spi_setup;
master->cleanup = ath79_spi_cleanup;
- if (pdata) {
- master->bus_num = pdata->bus_num;
- master->num_chipselect = pdata->num_chipselect;
- }
+ master->bus_num = pdata->bus_num;
+ master->num_chipselect = pdata->num_chipselect;
sp->bitbang.master = master;
sp->bitbang.chipselect = ath79_spi_chipselect;

View File

@ -0,0 +1,31 @@
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -62,10 +62,27 @@ static void __init ar913x_wmac_setup(voi
static int ar933x_wmac_reset(void)
{
+ int retries = 20;
+
ath79_device_reset_set(AR933X_RESET_WMAC);
ath79_device_reset_clear(AR933X_RESET_WMAC);
- return 0;
+ while (1) {
+ u32 bootstrap;
+
+ bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
+ if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0)
+ return 0;
+
+ if (retries-- == 0)
+ break;
+
+ udelay(10000);
+ retries++;
+ }
+
+ pr_err("ar933x: WMAC reset timed out");
+ return -ETIMEDOUT;
}
static int ar933x_r1_get_wmac_revision(void)

View File

@ -0,0 +1,28 @@
--- a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
@@ -36,6 +36,7 @@
#define cpu_has_mdmx 0
#define cpu_has_mips3d 0
#define cpu_has_smartmips 0
+#define cpu_has_rixi 0
#define cpu_has_mips32r1 1
#define cpu_has_mips32r2 1
@@ -43,6 +44,7 @@
#define cpu_has_mips64r2 0
#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
#define cpu_has_64bits 0
#define cpu_has_64bit_zero_reg 0
@@ -51,5 +53,9 @@
#define cpu_dcache_line_size() 32
#define cpu_icache_line_size() 32
+#define cpu_has_vtag_icache 0
+#define cpu_has_dc_aliases 1
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_pindexed_dcache 0
#endif /* __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H */

View File

@ -0,0 +1,21 @@
--- a/arch/mips/include/asm/mips_machine.h
+++ b/arch/mips/include/asm/mips_machine.h
@@ -36,6 +36,18 @@ static struct mips_machine machine_##_ty
.mach_setup = _setup, \
};
+#define MIPS_MACHINE_NONAME(_type, _id, _setup) \
+static const char machine_id_##_type[] __initconst \
+ __aligned(1) = _id; \
+static struct mips_machine machine_##_type \
+ __used __section(.mips.machines.init) = \
+{ \
+ .mach_type = _type, \
+ .mach_id = machine_id_##_type, \
+ .mach_name = NULL, \
+ .mach_setup = _setup, \
+};
+
extern long __mips_machines_start;
extern long __mips_machines_end;

View File

@ -0,0 +1,124 @@
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -233,6 +233,9 @@ config LZMA_COMPRESS
config LZMA_DECOMPRESS
tristate
+config RLE_DECOMPRESS
+ tristate
+
#
# These all provide a common interface (hence the apparent duplication with
# ZLIB_INFLATE; DECOMPRESS_GZIP is just a wrapper.)
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -97,6 +97,7 @@ obj-$(CONFIG_XZ_DEC) += xz/
obj-$(CONFIG_RAID6_PQ) += raid6/
obj-$(CONFIG_LZMA_COMPRESS) += lzma/
obj-$(CONFIG_LZMA_DECOMPRESS) += lzma/
+obj-$(CONFIG_RLE_DECOMPRESS) += rle.o
lib-$(CONFIG_DECOMPRESS_GZIP) += decompress_inflate.o
lib-$(CONFIG_DECOMPRESS_BZIP2) += decompress_bunzip2.o
--- /dev/null
+++ b/include/linux/rle.h
@@ -0,0 +1,18 @@
+#ifndef _RLE_H_
+#define _RLE_H_
+
+#ifdef CONFIG_RLE_DECOMPRESS
+int rle_decode(const unsigned char *src, size_t srclen,
+ unsigned char *dst, size_t dstlen,
+ size_t *src_done, size_t *dst_done);
+#else
+static inline int
+rle_decode(const unsigned char *src, size_t srclen,
+ unsigned char *dst, size_t dstlen,
+ size_t *src_done, size_t *dst_done)
+{
+ return -ENOTSUPP;
+}
+#endif /* CONFIG_RLE_DECOMPRESS */
+
+#endif /* _RLE_H_ */
--- /dev/null
+++ b/lib/rle.c
@@ -0,0 +1,78 @@
+/*
+ * RLE decoding routine
+ *
+ * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * 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/kernel.h>
+#include <linux/module.h>
+#include <linux/rle.h>
+
+int rle_decode(const unsigned char *src, size_t srclen,
+ unsigned char *dst, size_t dstlen,
+ size_t *src_done, size_t *dst_done)
+{
+ size_t srcpos, dstpos;
+ int ret;
+
+ srcpos = 0;
+ dstpos = 0;
+ ret = -EINVAL;
+
+ /* sanity checks */
+ if (!src || !srclen || !dst || !dstlen)
+ goto out;
+
+ while (1) {
+ char count;
+
+ if (srcpos >= srclen)
+ break;
+
+ count = (char) src[srcpos++];
+ if (count == 0) {
+ ret = 0;
+ break;
+ }
+
+ if (count > 0) {
+ unsigned char c;
+
+ if (srcpos >= srclen)
+ break;
+
+ c = src[srcpos++];
+
+ while (count--) {
+ if (dstpos >= dstlen)
+ break;
+
+ dst[dstpos++] = c;
+ }
+ } else {
+ count *= -1;
+
+ while (count--) {
+ if (srcpos >= srclen)
+ break;
+ if (dstpos >= dstlen)
+ break;
+ dst[dstpos++] = src[srcpos++];
+ }
+ }
+ }
+
+out:
+ if (src_done)
+ *src_done = srcpos;
+ if (dst_done)
+ *dst_done = dstpos;
+
+ return ret;
+}
+
+EXPORT_SYMBOL_GPL(rle_decode);

View File

@ -0,0 +1,94 @@
--- a/drivers/mtd/maps/physmap.c
+++ b/drivers/mtd/maps/physmap.c
@@ -31,6 +31,66 @@ struct physmap_flash_info {
int vpp_refcnt;
};
+static struct platform_device *physmap_map2pdev(struct map_info *map)
+{
+ return (struct platform_device *) map->map_priv_1;
+}
+
+static void physmap_lock(struct map_info *map)
+{
+ struct platform_device *pdev;
+ struct physmap_flash_data *physmap_data;
+
+ pdev = physmap_map2pdev(map);
+ physmap_data = pdev->dev.platform_data;
+ physmap_data->lock(pdev);
+}
+
+static void physmap_unlock(struct map_info *map)
+{
+ struct platform_device *pdev;
+ struct physmap_flash_data *physmap_data;
+
+ pdev = physmap_map2pdev(map);
+ physmap_data = pdev->dev.platform_data;
+ physmap_data->unlock(pdev);
+}
+
+static map_word physmap_flash_read_lock(struct map_info *map, unsigned long ofs)
+{
+ map_word ret;
+
+ physmap_lock(map);
+ ret = inline_map_read(map, ofs);
+ physmap_unlock(map);
+
+ return ret;
+}
+
+static void physmap_flash_write_lock(struct map_info *map, map_word d,
+ unsigned long ofs)
+{
+ physmap_lock(map);
+ inline_map_write(map, d, ofs);
+ physmap_unlock(map);
+}
+
+static void physmap_flash_copy_from_lock(struct map_info *map, void *to,
+ unsigned long from, ssize_t len)
+{
+ physmap_lock(map);
+ inline_map_copy_from(map, to, from, len);
+ physmap_unlock(map);
+}
+
+static void physmap_flash_copy_to_lock(struct map_info *map, unsigned long to,
+ const void *from, ssize_t len)
+{
+ physmap_lock(map);
+ inline_map_copy_to(map, to, from, len);
+ physmap_unlock(map);
+}
+
static int physmap_flash_remove(struct platform_device *dev)
{
struct physmap_flash_info *info;
@@ -153,6 +213,13 @@ static int physmap_flash_probe(struct pl
simple_map_init(&info->map[i]);
+ if (physmap_data->lock && physmap_data->unlock) {
+ info->map[i].read = physmap_flash_read_lock;
+ info->map[i].write = physmap_flash_write_lock;
+ info->map[i].copy_from = physmap_flash_copy_from_lock;
+ info->map[i].copy_to = physmap_flash_copy_to_lock;
+ }
+
probe_type = rom_probe_types;
if (physmap_data->probe_type == NULL) {
for (; info->mtd[i] == NULL && *probe_type != NULL; probe_type++)
--- a/include/linux/mtd/physmap.h
+++ b/include/linux/mtd/physmap.h
@@ -25,6 +25,8 @@ struct physmap_flash_data {
unsigned int width;
int (*init)(struct platform_device *);
void (*exit)(struct platform_device *);
+ void (*lock)(struct platform_device *);
+ void (*unlock)(struct platform_device *);
void (*set_vpp)(struct platform_device *, int);
unsigned int nr_parts;
unsigned int pfow_base;

View File

@ -0,0 +1,29 @@
--- a/drivers/mtd/chips/jedec_probe.c
+++ b/drivers/mtd/chips/jedec_probe.c
@@ -148,6 +148,7 @@
#define SST39LF160 0x2782
#define SST39VF1601 0x234b
#define SST39VF3201 0x235b
+#define SST39VF6401B 0x236d
#define SST39WF1601 0x274b
#define SST39WF1602 0x274a
#define SST39LF512 0x00D4
@@ -1569,6 +1570,18 @@ static const struct amd_flash_info jedec
ERASEINFO(0x10000,64),
}
}, {
+ .mfr_id = CFI_MFR_SST,
+ .dev_id = SST39VF6401B,
+ .name = "SST 39VF6401B",
+ .devtypes = CFI_DEVICETYPE_X16,
+ .uaddr = MTD_UADDR_0xAAAA_0x5555,
+ .dev_size = SIZE_8MiB,
+ .cmd_set = P_ID_AMD_STD,
+ .nr_regions = 1,
+ .regions = {
+ ERASEINFO(0x10000,128)
+ }
+ }, {
.mfr_id = CFI_MFR_ST,
.dev_id = M29F800AB,
.name = "ST M29F800AB",

View File

@ -0,0 +1,69 @@
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -1632,8 +1632,8 @@ static int __xipram do_write_oneword(str
break;
}
- if (chip_ready(map, adr))
- break;
+ if (chip_good(map, adr, datum))
+ goto enable_xip;
/* Latency issues. Drop the lock, wait a while and retry */
UDELAY(map, chip, adr, 1);
@@ -1649,6 +1649,8 @@ static int __xipram do_write_oneword(str
ret = -EIO;
}
+
+ enable_xip:
xip_enable(map, chip, adr);
op_done:
if (mode == FL_OTP_WRITE)
@@ -2227,7 +2229,6 @@ static int cfi_amdstd_panic_write(struct
return 0;
}
-
/*
* Handle devices with one erase region, that only implement
* the chip erase command.
@@ -2291,8 +2292,8 @@ static int __xipram do_erase_chip(struct
chip->erase_suspended = 0;
}
- if (chip_ready(map, adr))
- break;
+ if (chip_good(map, adr, map_word_ff(map)))
+ goto op_done;
if (time_after(jiffies, timeo)) {
printk(KERN_WARNING "MTD %s(): software timeout\n",
@@ -2312,6 +2313,7 @@ static int __xipram do_erase_chip(struct
ret = -EIO;
}
+ op_done:
chip->state = FL_READY;
xip_enable(map, chip, adr);
DISABLE_VPP(map);
@@ -2380,9 +2382,9 @@ static int __xipram do_erase_oneblock(st
chip->erase_suspended = 0;
}
- if (chip_ready(map, adr)) {
+ if (chip_good(map, adr, map_word_ff(map))) {
xip_enable(map, chip, adr);
- break;
+ goto op_done;
}
if (time_after(jiffies, timeo)) {
@@ -2404,6 +2406,7 @@ static int __xipram do_erase_oneblock(st
ret = -EIO;
}
+ op_done:
chip->state = FL_READY;
DISABLE_VPP(map);
put_chip(map, chip, adr);

View File

@ -0,0 +1,25 @@
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -184,6 +184,12 @@ config MTD_BCM47XX_PARTS
This provides partitions parser for devices based on BCM47xx
boards.
+config MTD_CYBERTAN_PARTS
+ tristate "Cybertan partitioning support"
+ depends on ATH79
+ ---help---
+ Cybertan partitioning support
+
config MTD_MYLOADER_PARTS
tristate "MyLoader partition parsing"
depends on ADM5120 || ATH25 || ATH79
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
+obj-$(CONFIG_MTD_CYBERTAN_PARTS) += cybertan_part.o
# 'Users' - code which presents functionality to userspace.
obj-$(CONFIG_MTD_BLKDEVS) += mtd_blkdevs.o

View File

@ -0,0 +1,25 @@
--- a/drivers/mtd/Kconfig
+++ b/drivers/mtd/Kconfig
@@ -206,6 +206,12 @@ config MTD_MYLOADER_PARTS
You will still need the parsing functions to be called by the driver
for your particular device. It won't happen automatically.
+config MTD_TPLINK_PARTS
+ tristate "TP-Link AR7XXX/AR9XXX partitioning support"
+ depends on ATH79
+ ---help---
+ TBD.
+
comment "User Modules And Translation Layers"
#
--- a/drivers/mtd/Makefile
+++ b/drivers/mtd/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o
obj-$(CONFIG_MTD_BCM63XX_PARTS) += bcm63xxpart.o
obj-$(CONFIG_MTD_BCM47XX_PARTS) += bcm47xxpart.o
obj-$(CONFIG_MTD_MYLOADER_PARTS) += myloader.o
+obj-$(CONFIG_MTD_TPLINK_PARTS) += tplinkpart.o
obj-$(CONFIG_MTD_CYBERTAN_PARTS) += cybertan_part.o
# 'Users' - code which presents functionality to userspace.

View File

@ -0,0 +1,23 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -246,7 +246,9 @@ static int m25p_probe(struct spi_device
ppdata.of_node = spi->dev.of_node;
- return mtd_device_parse_register(&flash->mtd, NULL, &ppdata,
+ return mtd_device_parse_register(&flash->mtd,
+ data ? data->part_probes : NULL,
+ &ppdata,
data ? data->parts : NULL,
data ? data->nr_parts : 0);
}
--- a/include/linux/spi/flash.h
+++ b/include/linux/spi/flash.h
@@ -24,6 +24,7 @@ struct flash_platform_data {
unsigned int nr_parts;
char *type;
+ const char **part_probes;
/* we'll likely add more ... use JEDEC IDs, etc */
};

View File

@ -0,0 +1,44 @@
--- a/drivers/mtd/redboot.c
+++ b/drivers/mtd/redboot.c
@@ -76,12 +76,18 @@ static int parse_redboot_partitions(stru
static char nullstring[] = "unallocated";
#endif
+ buf = vmalloc(master->erasesize);
+ if (!buf)
+ return -ENOMEM;
+
+ restart:
if ( directory < 0 ) {
offset = master->size + directory * master->erasesize;
while (mtd_block_isbad(master, offset)) {
if (!offset) {
nogood:
printk(KERN_NOTICE "Failed to find a non-bad block to check for RedBoot partition table\n");
+ vfree(buf);
return -EIO;
}
offset -= master->erasesize;
@@ -94,10 +100,6 @@ static int parse_redboot_partitions(stru
goto nogood;
}
}
- buf = vmalloc(master->erasesize);
-
- if (!buf)
- return -ENOMEM;
printk(KERN_NOTICE "Searching for RedBoot partition table in %s at offset 0x%lx\n",
master->name, offset);
@@ -170,6 +172,11 @@ static int parse_redboot_partitions(stru
}
if (i == numslots) {
/* Didn't find it */
+ if (offset + master->erasesize < master->size) {
+ /* not at the end of the flash yet, maybe next block :) */
+ directory++;
+ goto restart;
+ }
printk(KERN_NOTICE "No RedBoot partition table detected in %s\n",
master->name);
ret = 0;

View File

@ -0,0 +1,21 @@
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -516,4 +516,8 @@ config MTD_NAND_XWAY
Enables support for NAND Flash chips on Lantiq XWAY SoCs. NAND is attached
to the External Bus Unit (EBU).
+config MTD_NAND_RB4XX
+ tristate "NAND flash driver for RouterBoard 4xx series"
+ depends on MTD_NAND && ATH79_MACH_RB4XX
+
endif # MTD_NAND
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -32,6 +32,7 @@ obj-$(CONFIG_MTD_NAND_CM_X270) += cmx27
obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx_nand.o
obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o
obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
+obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o
obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o
obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o
obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o

View File

@ -0,0 +1,21 @@
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -520,4 +520,8 @@ config MTD_NAND_RB4XX
tristate "NAND flash driver for RouterBoard 4xx series"
depends on MTD_NAND && ATH79_MACH_RB4XX
+config MTD_NAND_RB750
+ tristate "NAND flash driver for the RouterBoard 750"
+ depends on MTD_NAND && ATH79_MACH_RB750
+
endif # MTD_NAND
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -33,6 +33,7 @@ obj-$(CONFIG_MTD_NAND_PXA3xx) += pxa3xx
obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nand.o
obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o
+obj-$(CONFIG_MTD_NAND_RB750) += rb750_nand.o
obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o
obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o
obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o

View File

@ -0,0 +1,61 @@
--- a/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -40,7 +40,7 @@
#include <linux/mtd/xip.h>
#define AMD_BOOTLOC_BUG
-#define FORCE_WORD_WRITE 0
+#define FORCE_WORD_WRITE 1
#define MAX_WORD_RETRIES 3
@@ -51,7 +51,9 @@
static int cfi_amdstd_read (struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int cfi_amdstd_write_words(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+#if !FORCE_WORD_WRITE
static int cfi_amdstd_write_buffers(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
+#endif
static int cfi_amdstd_erase_chip(struct mtd_info *, struct erase_info *);
static int cfi_amdstd_erase_varsize(struct mtd_info *, struct erase_info *);
static void cfi_amdstd_sync (struct mtd_info *);
@@ -202,6 +204,7 @@ static void fixup_amd_bootblock(struct m
}
#endif
+#if !FORCE_WORD_WRITE
static void fixup_use_write_buffers(struct mtd_info *mtd)
{
struct map_info *map = mtd->priv;
@@ -211,6 +214,7 @@ static void fixup_use_write_buffers(stru
mtd->_write = cfi_amdstd_write_buffers;
}
}
+#endif /* !FORCE_WORD_WRITE */
/* Atmel chips don't use the same PRI format as AMD chips */
static void fixup_convert_atmel_pri(struct mtd_info *mtd)
@@ -1791,6 +1795,7 @@ static int cfi_amdstd_write_words(struct
/*
* FIXME: interleaved mode not tested, and probably not supported!
*/
+#if !FORCE_WORD_WRITE
static int __xipram do_write_buffer(struct map_info *map, struct flchip *chip,
unsigned long adr, const u_char *buf,
int len)
@@ -1919,7 +1924,6 @@ static int __xipram do_write_buffer(stru
return ret;
}
-
static int cfi_amdstd_write_buffers(struct mtd_info *mtd, loff_t to, size_t len,
size_t *retlen, const u_char *buf)
{
@@ -1994,6 +1998,7 @@ static int cfi_amdstd_write_buffers(stru
return 0;
}
+#endif /* !FORCE_WORD_WRITE */
/*
* Wait for the flash chip to become ready to write data

View File

@ -0,0 +1,10 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -244,6 +244,7 @@ static int m25p_probe(struct spi_device
if (ret)
return ret;
+ memset(&ppdata, '\0', sizeof(ppdata));
ppdata.of_node = spi->dev.of_node;
return mtd_device_parse_register(&flash->mtd,

View File

@ -0,0 +1,25 @@
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -524,4 +524,12 @@ config MTD_NAND_RB750
tristate "NAND flash driver for the RouterBoard 750"
depends on MTD_NAND && ATH79_MACH_RB750
+config MTD_NAND_AR934X
+ tristate "NAND flash driver for the Qualcomm Atheros AR934x/QCA955x SoCs"
+ depends on (SOC_AR934X || SOC_QCA955X)
+
+config MTD_NAND_AR934X_HW_ECC
+ bool "Hardware ECC support for the AR934X NAND Controller (EXPERIMENTAL)"
+ depends on MTD_NAND_AR934X
+
endif # MTD_NAND
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_NAND_AMS_DELTA) += ams-
obj-$(CONFIG_MTD_NAND_DENALI) += denali.o
obj-$(CONFIG_MTD_NAND_DENALI_PCI) += denali_pci.o
obj-$(CONFIG_MTD_NAND_DENALI_DT) += denali_dt.o
+obj-$(CONFIG_MTD_NAND_AR934X) += ar934x_nfc.o
obj-$(CONFIG_MTD_NAND_AU1550) += au1550nd.o
obj-$(CONFIG_MTD_NAND_BF5XX) += bf5xx_nand.o
obj-$(CONFIG_MTD_NAND_S3C2410) += s3c2410.o

View File

@ -0,0 +1,23 @@
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -524,6 +524,10 @@ config MTD_NAND_RB750
tristate "NAND flash driver for the RouterBoard 750"
depends on MTD_NAND && ATH79_MACH_RB750
+config MTD_NAND_RB91X
+ tristate "NAND flash driver for the RouterBOARD 91x series"
+ depends on MTD_NAND && ATH79_MACH_RB91X
+
config MTD_NAND_AR934X
tristate "NAND flash driver for the Qualcomm Atheros AR934x/QCA955x SoCs"
depends on (SOC_AR934X || SOC_QCA955X)
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -35,6 +35,7 @@ obj-$(CONFIG_MTD_NAND_TMIO) += tmio_nan
obj-$(CONFIG_MTD_NAND_PLATFORM) += plat_nand.o
obj-$(CONFIG_MTD_NAND_RB4XX) += rb4xx_nand.o
obj-$(CONFIG_MTD_NAND_RB750) += rb750_nand.o
+obj-$(CONFIG_MTD_NAND_RB91X) += rb91x_nand.o
obj-$(CONFIG_MTD_NAND_PASEMI) += pasemi_nand.o
obj-$(CONFIG_MTD_NAND_ORION) += orion_nand.o
obj-$(CONFIG_MTD_NAND_FSL_ELBC) += fsl_elbc_nand.o

View File

@ -0,0 +1,28 @@
--- a/drivers/net/ethernet/atheros/Kconfig
+++ b/drivers/net/ethernet/atheros/Kconfig
@@ -5,7 +5,7 @@
config NET_VENDOR_ATHEROS
bool "Atheros devices"
default y
- depends on PCI
+ depends on (PCI || ATH79)
---help---
If you have a network (Ethernet) card belonging to this class, say Y
and read the Ethernet-HOWTO, available from
@@ -80,4 +80,6 @@ config ALX
To compile this driver as a module, choose M here. The module
will be called alx.
+source drivers/net/ethernet/atheros/ag71xx/Kconfig
+
endif # NET_VENDOR_ATHEROS
--- a/drivers/net/ethernet/atheros/Makefile
+++ b/drivers/net/ethernet/atheros/Makefile
@@ -2,6 +2,7 @@
# Makefile for the Atheros network device drivers.
#
+obj-$(CONFIG_AG71XX) += ag71xx/
obj-$(CONFIG_ATL1) += atlx/
obj-$(CONFIG_ATL2) += atlx/
obj-$(CONFIG_ATL1E) += atl1e/

View File

@ -0,0 +1,11 @@
--- a/net/dsa/tag_trailer.c
+++ b/net/dsa/tag_trailer.c
@@ -86,7 +86,7 @@ static int trailer_rcv(struct sk_buff *s
trailer = skb_tail_pointer(skb) - 4;
if (trailer[0] != 0x80 || (trailer[1] & 0xf8) != 0x00 ||
- (trailer[3] & 0xef) != 0x00 || trailer[3] != 0x00)
+ (trailer[2] & 0xef) != 0x00 || (trailer[3] & 0xfe) != 0x00)
goto out_drop;
source_port = trailer[1] & 7;

View File

@ -0,0 +1,24 @@
--- a/drivers/net/dsa/Kconfig
+++ b/drivers/net/dsa/Kconfig
@@ -13,6 +13,13 @@ config NET_DSA_MV88E6060
This enables support for the Marvell 88E6060 ethernet switch
chip.
+config NET_DSA_MV88E6063
+ bool "Marvell 88E6063 ethernet switch chip support"
+ select NET_DSA_TAG_TRAILER
+ ---help---
+ This enables support for the Marvell 88E6063 ethernet switch
+ chip
+
config NET_DSA_MV88E6XXX_NEED_PPU
bool
default n
--- a/drivers/net/dsa/Makefile
+++ b/drivers/net/dsa/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_NET_DSA_MV88E6060) += mv88e6060.o
+obj-$(CONFIG_NET_DSA_MV88E6063) += mv88e6063.o
obj-$(CONFIG_NET_DSA_MV88E6XXX) += mv88e6xxx_drv.o
mv88e6xxx_drv-y += mv88e6xxx.o
ifdef CONFIG_NET_DSA_MV88E6123_61_65

View File

@ -0,0 +1,180 @@
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -12,12 +12,14 @@
*/
#include <linux/phy.h>
+#include <linux/mdio.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
+#include <linux/platform_data/phy-at803x.h>
#define AT803X_INTR_ENABLE 0x12
#define AT803X_INTR_STATUS 0x13
@@ -34,8 +36,16 @@
#define AT803X_INER 0x0012
#define AT803X_INER_INIT 0xec00
#define AT803X_INSR 0x0013
+
+#define AT803X_PCS_SMART_EEE_CTRL3 0x805D
+#define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_MASK 0x3
+#define AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_SHIFT 12
+#define AT803X_SMART_EEE_CTRL3_LPI_EN BIT(8)
+
#define AT803X_DEBUG_ADDR 0x1D
#define AT803X_DEBUG_DATA 0x1E
+#define AT803X_DBG0_REG 0x00
+#define AT803X_DEBUG_RGMII_RX_CLK_DLY BIT(8)
#define AT803X_DEBUG_SYSTEM_MODE_CTRL 0x05
#define AT803X_DEBUG_RGMII_TX_CLK_DLY BIT(8)
@@ -50,6 +60,7 @@ MODULE_LICENSE("GPL");
struct at803x_priv {
bool phy_reset:1;
struct gpio_desc *gpiod_reset;
+ int prev_speed;
};
struct at803x_context {
@@ -61,6 +72,43 @@ struct at803x_context {
u16 led_control;
};
+static u16
+at803x_dbg_reg_rmw(struct phy_device *phydev, u16 reg, u16 clear, u16 set)
+{
+ struct mii_bus *bus = phydev->bus;
+ int val;
+
+ mutex_lock(&bus->mdio_lock);
+
+ bus->write(bus, phydev->addr, AT803X_DEBUG_ADDR, reg);
+ val = bus->read(bus, phydev->addr, AT803X_DEBUG_DATA);
+ if (val < 0) {
+ val = 0xffff;
+ goto out;
+ }
+
+ val &= ~clear;
+ val |= set;
+ bus->write(bus, phydev->addr, AT803X_DEBUG_DATA, val);
+
+out:
+ mutex_unlock(&bus->mdio_lock);
+ return val;
+}
+
+static inline void
+at803x_dbg_reg_set(struct phy_device *phydev, u16 reg, u16 set)
+{
+ at803x_dbg_reg_rmw(phydev, reg, 0, set);
+}
+
+static inline void
+at803x_dbg_reg_clr(struct phy_device *phydev, u16 reg, u16 clear)
+{
+ at803x_dbg_reg_rmw(phydev, reg, clear, 0);
+}
+
+
/* save relevant PHY registers to private copy */
static void at803x_context_save(struct phy_device *phydev,
struct at803x_context *context)
@@ -208,8 +256,16 @@ static int at803x_probe(struct phy_devic
return 0;
}
+static void at803x_disable_smarteee(struct phy_device *phydev)
+{
+ phy_write_mmd(phydev, MDIO_MMD_PCS, AT803X_PCS_SMART_EEE_CTRL3,
+ 1 << AT803X_SMART_EEE_CTRL3_LPI_TX_DELAY_SEL_SHIFT);
+ phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+}
+
static int at803x_config_init(struct phy_device *phydev)
{
+ struct at803x_platform_data *pdata;
int ret;
ret = genphy_config_init(phydev);
@@ -227,6 +283,26 @@ static int at803x_config_init(struct phy
return ret;
}
+ pdata = dev_get_platdata(&phydev->dev);
+ if (pdata) {
+ if (pdata->disable_smarteee)
+ at803x_disable_smarteee(phydev);
+
+ if (pdata->enable_rgmii_rx_delay)
+ at803x_dbg_reg_set(phydev, AT803X_DBG0_REG,
+ AT803X_DEBUG_RGMII_RX_CLK_DLY);
+ else
+ at803x_dbg_reg_clr(phydev, AT803X_DBG0_REG,
+ AT803X_DEBUG_RGMII_RX_CLK_DLY);
+
+ if (pdata->enable_rgmii_tx_delay)
+ at803x_dbg_reg_set(phydev, AT803X_DEBUG_SYSTEM_MODE_CTRL,
+ AT803X_DEBUG_RGMII_TX_CLK_DLY);
+ else
+ at803x_dbg_reg_clr(phydev, AT803X_DEBUG_SYSTEM_MODE_CTRL,
+ AT803X_DEBUG_RGMII_TX_CLK_DLY);
+ }
+
return 0;
}
@@ -258,6 +334,8 @@ static int at803x_config_intr(struct phy
static void at803x_link_change_notify(struct phy_device *phydev)
{
struct at803x_priv *priv = phydev->priv;
+ struct at803x_platform_data *pdata;
+ pdata = dev_get_platdata(&phydev->dev);
/*
* Conduct a hardware reset for AT8030 every time a link loss is
@@ -288,6 +366,26 @@ static void at803x_link_change_notify(st
priv->phy_reset = false;
}
}
+ if (pdata && pdata->fixup_rgmii_tx_delay &&
+ phydev->speed != priv->prev_speed) {
+ switch (phydev->speed) {
+ case SPEED_10:
+ case SPEED_100:
+ at803x_dbg_reg_set(phydev,
+ AT803X_DEBUG_SYSTEM_MODE_CTRL,
+ AT803X_DEBUG_RGMII_TX_CLK_DLY);
+ break;
+ case SPEED_1000:
+ at803x_dbg_reg_clr(phydev,
+ AT803X_DEBUG_SYSTEM_MODE_CTRL,
+ AT803X_DEBUG_RGMII_TX_CLK_DLY);
+ break;
+ default:
+ break;
+ }
+
+ priv->prev_speed = phydev->speed;
+ }
}
static struct phy_driver at803x_driver[] = {
--- /dev/null
+++ b/include/linux/platform_data/phy-at803x.h
@@ -0,0 +1,11 @@
+#ifndef _PHY_AT803X_PDATA_H
+#define _PHY_AT803X_PDATA_H
+
+struct at803x_platform_data {
+ int disable_smarteee:1;
+ int enable_rgmii_tx_delay:1;
+ int enable_rgmii_rx_delay:1;
+ int fixup_rgmii_tx_delay:1;
+};
+
+#endif /* _PHY_AT803X_PDATA_H */

View File

@ -0,0 +1,12 @@
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -68,8 +68,8 @@ obj-$(CONFIG_IDE) += ide/
obj-$(CONFIG_SCSI) += scsi/
obj-$(CONFIG_ATA) += ata/
obj-$(CONFIG_TARGET_CORE) += target/
-obj-$(CONFIG_MTD) += mtd/
obj-$(CONFIG_SPI) += spi/
+obj-$(CONFIG_MTD) += mtd/
obj-$(CONFIG_SPMI) += spmi/
obj-y += hsi/
obj-y += net/

View File

@ -0,0 +1,19 @@
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -620,6 +620,8 @@ struct spi_transfer {
unsigned cs_change:1;
unsigned tx_nbits:3;
unsigned rx_nbits:3;
+ unsigned verify:1;
+ unsigned fast_write:1;
#define SPI_NBITS_SINGLE 0x01 /* 1bit transfer */
#define SPI_NBITS_DUAL 0x02 /* 2bits transfer */
#define SPI_NBITS_QUAD 0x04 /* 4bits transfer */
@@ -665,6 +667,7 @@ struct spi_message {
struct spi_device *spi;
unsigned is_dma_mapped:1;
+ unsigned fast_read:1;
/* REVISIT: we might want a flag affecting the behavior of the
* last transfer ... allowing things like "read 16 bit length L"

View File

@ -0,0 +1,25 @@
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -433,6 +433,12 @@ config SPI_QUP
This driver can also be built as a module. If so, the module
will be called spi_qup.
+config SPI_RB4XX
+ tristate "Mikrotik RB4XX SPI master"
+ depends on SPI_MASTER && ATH79_MACH_RB4XX
+ help
+ SPI controller driver for the Mikrotik RB4xx series boards.
+
config SPI_S3C24XX
tristate "Samsung S3C24XX series SPI"
depends on ARCH_S3C24XX
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -62,6 +62,7 @@ spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_
spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_DMA) += spi-pxa2xx-dma.o
obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx-platform.o
obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o
+obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o
obj-$(CONFIG_SPI_QUP) += spi-qup.o
obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o
obj-$(CONFIG_SPI_RSPI) += spi-rspi.o

View File

@ -0,0 +1,26 @@
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -647,6 +647,13 @@ config SPI_TLE62X0
sysfs interface, with each line presented as a kind of GPIO
exposing both switch control and diagnostic feedback.
+config SPI_RB4XX_CPLD
+ tristate "MikroTik RB4XX CPLD driver"
+ depends on ATH79_MACH_RB4XX
+ help
+ SPI driver for the Xilinx CPLD chip present on the
+ MikroTik RB4xx boards.
+
#
# Add new SPI protocol masters in alphabetical order above this line
#
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -63,6 +63,7 @@ spi-pxa2xx-platform-$(CONFIG_SPI_PXA2XX_
obj-$(CONFIG_SPI_PXA2XX) += spi-pxa2xx-platform.o
obj-$(CONFIG_SPI_PXA2XX_PCI) += spi-pxa2xx-pci.o
obj-$(CONFIG_SPI_RB4XX) += spi-rb4xx.o
+obj-$(CONFIG_SPI_RB4XX_CPLD) += spi-rb4xx-cpld.o
obj-$(CONFIG_SPI_QUP) += spi-qup.o
obj-$(CONFIG_SPI_ROCKCHIP) += spi-rockchip.o
obj-$(CONFIG_SPI_RSPI) += spi-rspi.o

View File

@ -0,0 +1,27 @@
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -12,6 +12,7 @@ obj-$(CONFIG_SPI_SPIDEV) += spidev.o
# SPI master controller drivers (bus)
obj-$(CONFIG_SPI_ALTERA) += spi-altera.o
obj-$(CONFIG_SPI_ATMEL) += spi-atmel.o
+obj-$(CONFIG_SPI_AP83) += spi-ap83.o
obj-$(CONFIG_SPI_ATH79) += spi-ath79.o
obj-$(CONFIG_SPI_AU1550) += spi-au1550.o
obj-$(CONFIG_SPI_BCM2835) += spi-bcm2835.o
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -59,6 +59,14 @@ config SPI_ALTERA
help
This is the driver for the Altera SPI Controller.
+config SPI_AP83
+ tristate "Atheros AP83 specific SPI Controller"
+ depends on SPI_MASTER && ATH79_MACH_AP83
+ select SPI_BITBANG
+ help
+ This is a specific SPI controller driver for the Atheros AP83
+ reference board.
+
config SPI_ATH79
tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver"
depends on ATH79 && GPIOLIB

View File

@ -0,0 +1,24 @@
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -662,6 +662,11 @@ config SPI_RB4XX_CPLD
SPI driver for the Xilinx CPLD chip present on the
MikroTik RB4xx boards.
+config SPI_VSC7385
+ tristate "Vitesse VSC7385 ethernet switch driver"
+ help
+ SPI driver for the Vitesse VSC7385 ethernet switch.
+
#
# Add new SPI protocol masters in alphabetical order above this line
#
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_SPI_TEGRA20_SLINK) += spi-
obj-$(CONFIG_SPI_TLE62X0) += spi-tle62x0.o
obj-$(CONFIG_SPI_TOPCLIFF_PCH) += spi-topcliff-pch.o
obj-$(CONFIG_SPI_TXX9) += spi-txx9.o
+obj-$(CONFIG_SPI_VSC7385) += spi-vsc7385.o
obj-$(CONFIG_SPI_XCOMM) += spi-xcomm.o
obj-$(CONFIG_SPI_XILINX) += spi-xilinx.o
obj-$(CONFIG_SPI_XTENSA_XTFPGA) += spi-xtensa-xtfpga.o

View File

@ -0,0 +1,26 @@
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -505,6 +505,13 @@ config LEDS_VERSATILE
This option enabled support for the LEDs on the ARM Versatile
and RealView boards. Say Y to enabled these.
+config LEDS_WNDR3700_USB
+ tristate "NETGEAR WNDR3700 USB LED driver"
+ depends on LEDS_CLASS && ATH79_MACH_WNDR3700
+ help
+ This option enables support for the USB LED found on the
+ NETGEAR WNDR3700 board.
+
comment "LED Triggers"
source "drivers/leds/trigger/Kconfig"
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -41,6 +41,7 @@ obj-$(CONFIG_LEDS_DA9052) += leds-da905
obj-$(CONFIG_LEDS_WM831X_STATUS) += leds-wm831x-status.o
obj-$(CONFIG_LEDS_WM8350) += leds-wm8350.o
obj-$(CONFIG_LEDS_PWM) += leds-pwm.o
+obj-${CONFIG_LEDS_WNDR3700_USB} += leds-wndr3700-usb.o
obj-$(CONFIG_LEDS_REGULATOR) += leds-regulator.o
obj-$(CONFIG_LEDS_INTEL_SS4200) += leds-ss4200.o
obj-$(CONFIG_LEDS_LT3593) += leds-lt3593.o

View File

@ -0,0 +1,23 @@
--- a/drivers/leds/Kconfig
+++ b/drivers/leds/Kconfig
@@ -512,6 +512,10 @@ config LEDS_WNDR3700_USB
This option enables support for the USB LED found on the
NETGEAR WNDR3700 board.
+config LEDS_RB750
+ tristate "LED driver for the Mikrotik RouterBOARD 750"
+ depends on LEDS_CLASS && ATH79_MACH_RB750
+
comment "LED Triggers"
source "drivers/leds/trigger/Kconfig"
--- a/drivers/leds/Makefile
+++ b/drivers/leds/Makefile
@@ -48,6 +48,7 @@ obj-$(CONFIG_LEDS_LT3593) += leds-lt359
obj-$(CONFIG_LEDS_ADP5520) += leds-adp5520.o
obj-$(CONFIG_LEDS_DELL_NETBOOKS) += dell-led.o
obj-$(CONFIG_LEDS_MC13783) += leds-mc13783.o
+obj-$(CONFIG_LEDS_RB750) += leds-rb750.o
obj-$(CONFIG_LEDS_NS2) += leds-ns2.o
obj-$(CONFIG_LEDS_NETXBIG) += leds-netxbig.o
obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o

View File

@ -0,0 +1,25 @@
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -905,4 +905,12 @@ config GPIO_VIPERBOARD
River Tech's viperboard.h for detailed meaning
of the module parameters.
+comment "Other GPIO expanders"
+
+config GPIO_NXP_74HC153
+ tristate "NXP 74HC153 Dual 4-input multiplexer"
+ help
+ Platform driver for NXP 74HC153 Dual 4-input Multiplexer. This
+ provides a GPIO interface supporting input mode only.
+
endif
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -60,6 +60,7 @@ obj-$(CONFIG_GPIO_MSM_V2) += gpio-msm-v2
obj-$(CONFIG_GPIO_MVEBU) += gpio-mvebu.o
obj-$(CONFIG_GPIO_MXC) += gpio-mxc.o
obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o
+obj-$(CONFIG_GPIO_NXP_74HC153) += gpio-nxp-74hc153.o
obj-$(CONFIG_GPIO_OCTEON) += gpio-octeon.o
obj-$(CONFIG_GPIO_OMAP) += gpio-omap.o
obj-$(CONFIG_GPIO_PCA953X) += gpio-pca953x.o

View File

@ -0,0 +1,111 @@
--- a/drivers/gpio/gpio-74x164.c
+++ b/drivers/gpio/gpio-74x164.c
@@ -12,6 +12,7 @@
#include <linux/init.h>
#include <linux/mutex.h>
#include <linux/spi/spi.h>
+#include <linux/spi/74x164.h>
#include <linux/gpio.h>
#include <linux/of_gpio.h>
#include <linux/slab.h>
@@ -107,8 +108,18 @@ static int gen_74x164_direction_output(s
static int gen_74x164_probe(struct spi_device *spi)
{
struct gen_74x164_chip *chip;
+ struct gen_74x164_chip_platform_data *pdata;
+ struct device_node *np;
int ret;
+ pdata = spi->dev.platform_data;
+ np = spi->dev.of_node;
+
+ if (!np && !pdata) {
+ dev_err(&spi->dev, "No configuration data available.\n");
+ return -EINVAL;
+ }
+
/*
* bits_per_word cannot be configured in platform data
*/
@@ -130,18 +141,28 @@ static int gen_74x164_probe(struct spi_d
chip->gpio_chip.set = gen_74x164_set_value;
chip->gpio_chip.base = -1;
- if (of_property_read_u32(spi->dev.of_node, "registers-number",
- &chip->registers)) {
- dev_err(&spi->dev,
- "Missing registers-number property in the DT.\n");
- return -EINVAL;
+ if (np) {
+ if (of_property_read_u32(spi->dev.of_node, "registers-number", &chip->registers)) {
+ dev_err(&spi->dev, "Missing registers-number property in the DT.\n");
+ ret = -EINVAL;
+ goto exit_destroy;
+ }
+ } else if (pdata) {
+ chip->gpio_chip.base = pdata->base;
+ chip->registers = pdata->num_registers;
}
+ if (!chip->registers)
+ chip->registers = 1;
+
chip->gpio_chip.ngpio = GEN_74X164_NUMBER_GPIOS * chip->registers;
chip->buffer = devm_kzalloc(&spi->dev, chip->registers, GFP_KERNEL);
if (!chip->buffer)
return -ENOMEM;
+ if (pdata && pdata->init_data)
+ memcpy(chip->buffer, pdata->init_data, chip->registers);
+
chip->gpio_chip.can_sleep = true;
chip->gpio_chip.dev = &spi->dev;
chip->gpio_chip.owner = THIS_MODULE;
@@ -174,17 +195,19 @@ static int gen_74x164_remove(struct spi_
return 0;
}
+#ifdef CONFIG_OF
static const struct of_device_id gen_74x164_dt_ids[] = {
{ .compatible = "fairchild,74hc595" },
{},
};
MODULE_DEVICE_TABLE(of, gen_74x164_dt_ids);
+#endif /* CONFIG_OF */
static struct spi_driver gen_74x164_driver = {
.driver = {
.name = "74x164",
.owner = THIS_MODULE,
- .of_match_table = gen_74x164_dt_ids,
+ .of_match_table = of_match_ptr(gen_74x164_dt_ids),
},
.probe = gen_74x164_probe,
.remove = gen_74x164_remove,
--- /dev/null
+++ b/include/linux/spi/74x164.h
@@ -0,0 +1,13 @@
+#ifndef LINUX_SPI_74X164_H
+#define LINUX_SPI_74X164_H
+
+struct gen_74x164_chip_platform_data {
+ /* number assigned to the first GPIO */
+ unsigned base;
+ /* number of chained registers */
+ unsigned num_registers;
+ /* address of a buffer containing initial data */
+ u8 *init_data;
+};
+
+#endif
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -821,7 +821,7 @@ config GPIO_MC33880
config GPIO_74X164
tristate "74x164 serial-in/parallel-out 8-bits shift register"
- depends on SPI_MASTER && OF
+ depends on SPI_MASTER
help
Driver for 74x164 compatible serial-in/parallel-out 8-outputs
shift registers. This driver can be used to provide access

View File

@ -0,0 +1,22 @@
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -996,4 +996,9 @@ config GPIO_NXP_74HC153
Platform driver for NXP 74HC153 Dual 4-input Multiplexer. This
provides a GPIO interface supporting input mode only.
+config GPIO_LATCH
+ tristate "GPIO latch driver"
+ help
+ Say yes here to enable a GPIO latch driver.
+
endif
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz
obj-$(CONFIG_GPIO_KEMPLD) += gpio-kempld.o
obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o
obj-$(CONFIG_GPIO_INTEL_MID) += gpio-intel-mid.o
+obj-$(CONFIG_GPIO_LATCH) += gpio-latch.o
obj-$(CONFIG_GPIO_LOONGSON) += gpio-loongson.o
obj-$(CONFIG_GPIO_LP3943) += gpio-lp3943.o
obj-$(CONFIG_ARCH_LPC32XX) += gpio-lpc32xx.o

View File

@ -0,0 +1,28 @@
--- a/drivers/spi/spi-bitbang.c
+++ b/drivers/spi/spi-bitbang.c
@@ -234,13 +234,14 @@ void spi_bitbang_cleanup(struct spi_devi
}
EXPORT_SYMBOL_GPL(spi_bitbang_cleanup);
-static int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
+int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t)
{
struct spi_bitbang_cs *cs = spi->controller_state;
unsigned nsecs = cs->nsecs;
return cs->txrx_bufs(spi, cs->txrx_word, nsecs, t);
}
+EXPORT_SYMBOL_GPL(spi_bitbang_bufs);
/*----------------------------------------------------------------------*/
--- a/include/linux/spi/spi_bitbang.h
+++ b/include/linux/spi/spi_bitbang.h
@@ -39,6 +39,7 @@ extern int spi_bitbang_setup(struct spi_
extern void spi_bitbang_cleanup(struct spi_device *spi);
extern int spi_bitbang_setup_transfer(struct spi_device *spi,
struct spi_transfer *t);
+extern int spi_bitbang_bufs(struct spi_device *spi, struct spi_transfer *t);
/* start or stop queue processing */
extern int spi_bitbang_start(struct spi_bitbang *spi);

View File

@ -0,0 +1,23 @@
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -508,6 +508,12 @@ extern struct spi_master *spi_busnum_to_
/*---------------------------------------------------------------------------*/
+enum spi_transfer_type {
+ SPI_TRANSFER_GENERIC = 0,
+ SPI_TRANSFER_FLASH_READ_CMD,
+ SPI_TRANSFER_FLASH_READ_DATA,
+};
+
/*
* I/O INTERFACE between SPI controller and protocol drivers
*
@@ -628,6 +634,7 @@ struct spi_transfer {
u8 bits_per_word;
u16 delay_usecs;
u32 speed_hz;
+ enum spi_transfer_type type;
struct list_head transfer_list;
};

View File

@ -0,0 +1,15 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -142,10 +142,12 @@ static int m25p80_read(struct spi_nor *n
flash->command[0] = nor->read_opcode;
m25p_addr2cmd(nor, from, flash->command);
+ t[0].type = SPI_TRANSFER_FLASH_READ_CMD;
t[0].tx_buf = flash->command;
t[0].len = m25p_cmdsz(nor) + dummy;
spi_message_add_tail(&t[0], &m);
+ t[1].type = SPI_TRANSFER_FLASH_READ_DATA;
t[1].rx_buf = buf;
t[1].rx_nbits = m25p80_rx_nbits(nor);
t[1].len = len;

View File

@ -0,0 +1,185 @@
--- a/drivers/spi/spi-ath79.c
+++ b/drivers/spi/spi-ath79.c
@@ -35,6 +35,11 @@
#define ATH79_SPI_CS_LINE_MAX 2
+enum ath79_spi_state {
+ ATH79_SPI_STATE_WAIT_CMD = 0,
+ ATH79_SPI_STATE_WAIT_READ,
+};
+
struct ath79_spi {
struct spi_bitbang bitbang;
u32 ioc_base;
@@ -42,6 +47,11 @@ struct ath79_spi {
void __iomem *base;
struct clk *clk;
unsigned rrw_delay;
+
+ enum ath79_spi_state state;
+ u32 clk_div;
+ unsigned long read_addr;
+ unsigned long ahb_rate;
};
static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg)
@@ -109,9 +119,6 @@ static void ath79_spi_enable(struct ath7
/* save CTRL register */
sp->reg_ctrl = ath79_spi_rr(sp, AR71XX_SPI_REG_CTRL);
sp->ioc_base = ath79_spi_rr(sp, AR71XX_SPI_REG_IOC);
-
- /* TODO: setup speed? */
- ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, 0x43);
}
static void ath79_spi_disable(struct ath79_spi *sp)
@@ -224,6 +231,110 @@ static u32 ath79_spi_txrx_mode0(struct s
return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS);
}
+static int ath79_spi_do_read_flash_data(struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ struct ath79_spi *sp = ath79_spidev_to_sp(spi);
+
+ /* disable GPIO mode */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
+
+ memcpy_fromio(t->rx_buf, sp->base + sp->read_addr, t->len);
+
+ /* enable GPIO mode */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
+
+ /* restore IOC register */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+
+ return t->len;
+}
+
+static int ath79_spi_do_read_flash_cmd(struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ struct ath79_spi *sp = ath79_spidev_to_sp(spi);
+ int len;
+ const u8 *p;
+
+ sp->read_addr = 0;
+
+ len = t->len - 1;
+ p = t->tx_buf;
+
+ while (len--) {
+ p++;
+ sp->read_addr <<= 8;
+ sp->read_addr |= *p;
+ }
+
+ return t->len;
+}
+
+static bool ath79_spi_is_read_cmd(struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ return t->type == SPI_TRANSFER_FLASH_READ_CMD;
+}
+
+static bool ath79_spi_is_data_read(struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ return t->type == SPI_TRANSFER_FLASH_READ_DATA;
+}
+
+static int ath79_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
+{
+ struct ath79_spi *sp = ath79_spidev_to_sp(spi);
+ int ret;
+
+ switch (sp->state) {
+ case ATH79_SPI_STATE_WAIT_CMD:
+ if (ath79_spi_is_read_cmd(spi, t)) {
+ ret = ath79_spi_do_read_flash_cmd(spi, t);
+ sp->state = ATH79_SPI_STATE_WAIT_READ;
+ } else {
+ ret = spi_bitbang_bufs(spi, t);
+ }
+ break;
+
+ case ATH79_SPI_STATE_WAIT_READ:
+ if (ath79_spi_is_data_read(spi, t)) {
+ ret = ath79_spi_do_read_flash_data(spi, t);
+ } else {
+ dev_warn(&spi->dev, "flash data read expected\n");
+ ret = -EIO;
+ }
+ sp->state = ATH79_SPI_STATE_WAIT_CMD;
+ break;
+
+ default:
+ BUG();
+ }
+
+ return ret;
+}
+
+static int ath79_spi_setup_transfer(struct spi_device *spi,
+ struct spi_transfer *t)
+{
+ struct ath79_spi *sp = ath79_spidev_to_sp(spi);
+ struct ath79_spi_controller_data *cdata;
+ int ret;
+
+ ret = spi_bitbang_setup_transfer(spi, t);
+ if (ret)
+ return ret;
+
+ cdata = spi->controller_data;
+ if (cdata->is_flash)
+ sp->bitbang.txrx_bufs = ath79_spi_txrx_bufs;
+ else
+ sp->bitbang.txrx_bufs = spi_bitbang_bufs;
+
+ return ret;
+}
+
static int ath79_spi_probe(struct platform_device *pdev)
{
struct spi_master *master;
@@ -246,6 +357,8 @@ static int ath79_spi_probe(struct platfo
sp = spi_master_get_devdata(master);
platform_set_drvdata(pdev, sp);
+ sp->state = ATH79_SPI_STATE_WAIT_CMD;
+
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(1, 32);
master->setup = ath79_spi_setup;
master->cleanup = ath79_spi_cleanup;
@@ -255,7 +368,7 @@ static int ath79_spi_probe(struct platfo
sp->bitbang.master = master;
sp->bitbang.chipselect = ath79_spi_chipselect;
sp->bitbang.txrx_word[SPI_MODE_0] = ath79_spi_txrx_mode0;
- sp->bitbang.setup_transfer = spi_bitbang_setup_transfer;
+ sp->bitbang.setup_transfer = ath79_spi_setup_transfer;
sp->bitbang.flags = SPI_CS_HIGH;
r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -280,7 +393,8 @@ static int ath79_spi_probe(struct platfo
if (ret)
goto err_put_master;
- rate = DIV_ROUND_UP(clk_get_rate(sp->clk), MHZ);
+ sp->ahb_rate = clk_get_rate(sp->clk);
+ rate = DIV_ROUND_UP(sp->ahb_rate, MHZ);
if (!rate) {
ret = -EINVAL;
goto err_clk_disable;
--- a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
+++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
@@ -24,6 +24,7 @@ enum ath79_spi_cs_type {
struct ath79_spi_controller_data {
enum ath79_spi_cs_type cs_type;
unsigned cs_line;
+ bool is_flash;
};
#endif /* _ATH79_SPI_PLATFORM_H */

View File

@ -0,0 +1,35 @@
--- a/drivers/mtd/devices/m25p80.c
+++ b/drivers/mtd/devices/m25p80.c
@@ -142,6 +142,9 @@ static int m25p80_read(struct spi_nor *n
flash->command[0] = nor->read_opcode;
m25p_addr2cmd(nor, from, flash->command);
+ if (dummy == 1)
+ t[0].dummy = true;
+
t[0].type = SPI_TRANSFER_FLASH_READ_CMD;
t[0].tx_buf = flash->command;
t[0].len = m25p_cmdsz(nor) + dummy;
--- a/drivers/spi/spi-ath79.c
+++ b/drivers/spi/spi-ath79.c
@@ -260,6 +260,10 @@ static int ath79_spi_do_read_flash_cmd(s
sp->read_addr = 0;
len = t->len - 1;
+
+ if (t->dummy)
+ len -= 1;
+
p = t->tx_buf;
while (len--) {
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -635,6 +635,7 @@ struct spi_transfer {
u16 delay_usecs;
u32 speed_hz;
enum spi_transfer_type type;
+ bool dummy;
struct list_head transfer_list;
};

View File

@ -0,0 +1,111 @@
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/mangle-port.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2012 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This file was derived from: inlude/asm-mips/mach-generic/mangle-port.h
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ *
+ * 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.
+ */
+
+#ifndef __ASM_MACH_ATH79_MANGLE_PORT_H
+#define __ASM_MACH_ATH79_MANGLE_PORT_H
+
+#ifdef CONFIG_PCI
+extern unsigned long (ath79_pci_swizzle_b)(unsigned long port);
+extern unsigned long (ath79_pci_swizzle_w)(unsigned long port);
+#else
+#define ath79_pci_swizzle_b(port) (port)
+#define ath79_pci_swizzle_w(port) (port)
+#endif
+
+#define __swizzle_addr_b(port) ath79_pci_swizzle_b(port)
+#define __swizzle_addr_w(port) ath79_pci_swizzle_w(port)
+#define __swizzle_addr_l(port) (port)
+#define __swizzle_addr_q(port) (port)
+
+# define ioswabb(a, x) (x)
+# define __mem_ioswabb(a, x) (x)
+# define ioswabw(a, x) (x)
+# define __mem_ioswabw(a, x) cpu_to_le16(x)
+# define ioswabl(a, x) (x)
+# define __mem_ioswabl(a, x) cpu_to_le32(x)
+# define ioswabq(a, x) (x)
+# define __mem_ioswabq(a, x) cpu_to_le64(x)
+
+#endif /* __ASM_MACH_ATH79_MANGLE_PORT_H */
--- a/arch/mips/ath79/pci.c
+++ b/arch/mips/ath79/pci.c
@@ -13,6 +13,7 @@
*/
#include <linux/init.h>
+#include <linux/export.h>
#include <linux/pci.h>
#include <linux/resource.h>
#include <linux/platform_device.h>
@@ -25,6 +26,9 @@ static int (*ath79_pci_plat_dev_init)(st
static const struct ath79_pci_irq *ath79_pci_irq_map __initdata;
static unsigned ath79_pci_nr_irqs __initdata;
+static unsigned long (*__ath79_pci_swizzle_b)(unsigned long port);
+static unsigned long (*__ath79_pci_swizzle_w)(unsigned long port);
+
static const struct ath79_pci_irq ar71xx_pci_irq_map[] __initconst = {
{
.slot = 17,
@@ -212,12 +216,50 @@ ath79_register_pci_ar724x(int id,
return pdev;
}
+static inline bool ar71xx_is_pci_addr(unsigned long port)
+{
+ unsigned long phys = CPHYSADDR(port);
+
+ return (phys >= AR71XX_PCI_MEM_BASE &&
+ phys < AR71XX_PCI_MEM_BASE + AR71XX_PCI_MEM_SIZE);
+}
+
+static unsigned long ar71xx_pci_swizzle_b(unsigned long port)
+{
+ return ar71xx_is_pci_addr(port) ? port ^ 3 : port;
+}
+
+static unsigned long ar71xx_pci_swizzle_w(unsigned long port)
+{
+ return ar71xx_is_pci_addr(port) ? port ^ 2 : port;
+}
+
+unsigned long ath79_pci_swizzle_b(unsigned long port)
+{
+ if (__ath79_pci_swizzle_b)
+ return __ath79_pci_swizzle_b(port);
+
+ return port;
+}
+EXPORT_SYMBOL(ath79_pci_swizzle_b);
+
+unsigned long ath79_pci_swizzle_w(unsigned long port)
+{
+ if (__ath79_pci_swizzle_w)
+ return __ath79_pci_swizzle_w(port);
+
+ return port;
+}
+EXPORT_SYMBOL(ath79_pci_swizzle_w);
+
int __init ath79_register_pci(void)
{
struct platform_device *pdev = NULL;
if (soc_is_ar71xx()) {
pdev = ath79_register_pci_ar71xx();
+ __ath79_pci_swizzle_b = ar71xx_pci_swizzle_b;
+ __ath79_pci_swizzle_w = ar71xx_pci_swizzle_w;
} else if (soc_is_ar724x()) {
pdev = ath79_register_pci_ar724x(-1,
AR724X_PCI_CFG_BASE,

View File

@ -0,0 +1,31 @@
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -44,7 +44,7 @@ static struct platform_device ath79_wmac
},
};
-static void __init ar913x_wmac_setup(void)
+static int ar913x_wmac_reset(void)
{
/* reset the WMAC */
ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
@@ -53,10 +53,19 @@ static void __init ar913x_wmac_setup(voi
ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
mdelay(10);
+ return 0;
+}
+
+static void __init ar913x_wmac_setup(void)
+{
+ ar913x_wmac_reset();
+
ath79_wmac_resources[0].start = AR913X_WMAC_BASE;
ath79_wmac_resources[0].end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1;
ath79_wmac_resources[1].start = ATH79_CPU_IRQ(2);
ath79_wmac_resources[1].end = ATH79_CPU_IRQ(2);
+
+ ath79_wmac_data.external_reset = ar913x_wmac_reset;
}

View File

@ -0,0 +1,103 @@
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -252,6 +252,37 @@ static int ehci_reset (struct ehci_hcd *
command |= CMD_RESET;
dbg_cmd (ehci, "reset", command);
ehci_writel(ehci, command, &ehci->regs->command);
+
+ if (ehci->qca_force_host_mode) {
+ u32 usbmode;
+
+ udelay(1000);
+
+ usbmode = ehci_readl(ehci, &ehci->regs->usbmode);
+ usbmode |= USBMODE_CM_HC | (1 << 4);
+ ehci_writel(ehci, usbmode, &ehci->regs->usbmode);
+
+ ehci_dbg(ehci, "forced host mode, usbmode: %08x\n",
+ ehci_readl(ehci, &ehci->regs->usbmode));
+ }
+
+ if (ehci->qca_force_16bit_ptw) {
+ u32 port_status;
+
+ udelay(1000);
+
+ /* enable 16-bit UTMI interface */
+ port_status = ehci_readl(ehci, &ehci->regs->port_status[0]);
+ port_status |= BIT(28);
+ ehci_writel(ehci, port_status, &ehci->regs->port_status[0]);
+
+ ehci_dbg(ehci, "16-bit UTMI interface enabled, status: %08x\n",
+ ehci_readl(ehci, &ehci->regs->port_status[0]));
+ }
+
+ if (ehci->reset_notifier)
+ ehci->reset_notifier(ehci_to_hcd(ehci));
+
ehci->rh_state = EHCI_RH_HALTED;
ehci->next_statechange = jiffies;
retval = ehci_handshake(ehci, &ehci->regs->command,
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -227,6 +227,10 @@ struct ehci_hcd { /* one per controlle
unsigned need_oc_pp_cycle:1; /* MPC834X port power */
unsigned imx28_write_fix:1; /* For Freescale i.MX28 */
unsigned ignore_oc:1;
+ unsigned qca_force_host_mode:1;
+ unsigned qca_force_16bit_ptw:1; /* force 16 bit UTMI */
+
+ void (*reset_notifier)(struct usb_hcd *hcd);
/* required for usb32 quirk */
#define OHCI_CTRL_HCFS (3 << 6)
--- a/include/linux/usb/ehci_pdriver.h
+++ b/include/linux/usb/ehci_pdriver.h
@@ -46,6 +46,8 @@ struct usb_ehci_pdata {
unsigned big_endian_mmio:1;
unsigned no_io_watchdog:1;
unsigned ignore_oc:1;
+ unsigned qca_force_host_mode:1;
+ unsigned qca_force_16bit_ptw:1;
/* Turn on all power and clocks */
int (*power_on)(struct platform_device *pdev);
@@ -55,6 +57,7 @@ struct usb_ehci_pdata {
* turn off everything else */
void (*power_suspend)(struct platform_device *pdev);
int (*pre_setup)(struct usb_hcd *hcd);
+ void (*reset_notifier)(struct platform_device *pdev);
};
#endif /* __USB_CORE_EHCI_PDRIVER_H */
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -48,6 +48,14 @@ struct ehci_platform_priv {
static const char hcd_name[] = "ehci-platform";
+static void ehci_platform_reset_notifier(struct usb_hcd *hcd)
+{
+ struct platform_device *pdev = to_platform_device(hcd->self.controller);
+ struct usb_ehci_pdata *pdata = pdev->dev.platform_data;
+
+ pdata->reset_notifier(pdev);
+}
+
static int ehci_platform_reset(struct usb_hcd *hcd)
{
struct platform_device *pdev = to_platform_device(hcd->self.controller);
@@ -228,6 +236,13 @@ static int ehci_platform_probe(struct pl
ehci->big_endian_mmio = 1;
if (pdata->ignore_oc)
ehci->ignore_oc = 1;
+ if (pdata->qca_force_host_mode)
+ ehci->qca_force_host_mode = 1;
+ if (pdata->qca_force_16bit_ptw)
+ ehci->qca_force_16bit_ptw = 1;
+
+ if (pdata->reset_notifier)
+ ehci->reset_notifier = ehci_platform_reset_notifier;
#ifndef CONFIG_USB_EHCI_BIG_ENDIAN_MMIO
if (ehci->big_endian_mmio) {

View File

@ -0,0 +1,22 @@
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -208,6 +208,7 @@ endif
#
libs-$(CONFIG_FW_ARC) += arch/mips/fw/arc/
libs-$(CONFIG_FW_CFE) += arch/mips/fw/cfe/
+libs-$(CONFIG_MYLOADER) += arch/mips/fw/myloader/
libs-$(CONFIG_FW_SNIPROM) += arch/mips/fw/sni/
libs-y += arch/mips/fw/lib/
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -982,6 +982,9 @@ config MIPS_MSC
config MIPS_NILE4
bool
+config MYLOADER
+ bool
+
config SYNC_R4K
bool

View File

@ -0,0 +1,81 @@
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -15,6 +15,7 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
+#include <linux/etherdevice.h>
#include <linux/platform_device.h>
#include <linux/ath9k_platform.h>
@@ -22,6 +23,7 @@
#include <asm/mach-ath79/ar71xx_regs.h>
#include "dev-wmac.h"
+static u8 ath79_wmac_mac[ETH_ALEN];
static struct ath9k_platform_data ath79_wmac_data;
static struct resource ath79_wmac_resources[] = {
@@ -160,7 +162,7 @@ static void qca955x_wmac_setup(void)
ath79_wmac_data.is_clk_25mhz = true;
}
-void __init ath79_register_wmac(u8 *cal_data)
+void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr)
{
if (soc_is_ar913x())
ar913x_wmac_setup();
@@ -177,5 +179,10 @@ void __init ath79_register_wmac(u8 *cal_
memcpy(ath79_wmac_data.eeprom_data, cal_data,
sizeof(ath79_wmac_data.eeprom_data));
+ if (mac_addr) {
+ memcpy(ath79_wmac_mac, mac_addr, sizeof(ath79_wmac_mac));
+ ath79_wmac_data.macaddr = ath79_wmac_mac;
+ }
+
platform_device_register(&ath79_wmac_device);
}
--- a/arch/mips/ath79/dev-wmac.h
+++ b/arch/mips/ath79/dev-wmac.h
@@ -12,6 +12,6 @@
#ifndef _ATH79_DEV_WMAC_H
#define _ATH79_DEV_WMAC_H
-void ath79_register_wmac(u8 *cal_data);
+void ath79_register_wmac(u8 *cal_data, u8 *mac_addr);
#endif /* _ATH79_DEV_WMAC_H */
--- a/arch/mips/ath79/mach-ap81.c
+++ b/arch/mips/ath79/mach-ap81.c
@@ -92,7 +92,7 @@ static void __init ap81_setup(void)
ap81_gpio_keys);
ath79_register_spi(&ap81_spi_data, ap81_spi_info,
ARRAY_SIZE(ap81_spi_info));
- ath79_register_wmac(cal_data);
+ ath79_register_wmac(cal_data, NULL);
ath79_register_usb();
}
--- a/arch/mips/ath79/mach-db120.c
+++ b/arch/mips/ath79/mach-db120.c
@@ -128,7 +128,7 @@ static void __init db120_setup(void)
ath79_register_spi(&db120_spi_data, db120_spi_info,
ARRAY_SIZE(db120_spi_info));
ath79_register_usb();
- ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET);
+ ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET, NULL);
db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET);
}
--- a/arch/mips/ath79/mach-ap121.c
+++ b/arch/mips/ath79/mach-ap121.c
@@ -85,7 +85,7 @@ static void __init ap121_setup(void)
ath79_register_spi(&ap121_spi_data, ap121_spi_info,
ARRAY_SIZE(ap121_spi_info));
ath79_register_usb();
- ath79_register_wmac(cal_data);
+ ath79_register_wmac(cal_data, NULL);
}
MIPS_MACHINE(ATH79_MACH_AP121, "AP121", "Atheros AP121 reference board",

View File

@ -0,0 +1,23 @@
--- a/arch/mips/ath79/gpio.c
+++ b/arch/mips/ath79/gpio.c
@@ -25,7 +25,9 @@
#include <asm/mach-ath79/ath79.h>
#include "common.h"
-static void __iomem *ath79_gpio_base;
+void __iomem *ath79_gpio_base;
+EXPORT_SYMBOL_GPL(ath79_gpio_base);
+
static unsigned long ath79_gpio_count;
static DEFINE_SPINLOCK(ath79_gpio_lock);
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -116,6 +116,7 @@ static inline int soc_is_qca955x(void)
}
extern void __iomem *ath79_ddr_base;
+extern void __iomem *ath79_gpio_base;
extern void __iomem *ath79_pll_base;
extern void __iomem *ath79_reset_base;

View File

@ -0,0 +1,37 @@
--- a/arch/mips/ath79/common.c
+++ b/arch/mips/ath79/common.c
@@ -22,6 +22,7 @@
#include "common.h"
static DEFINE_SPINLOCK(ath79_device_reset_lock);
+static DEFINE_MUTEX(ath79_flash_mutex);
u32 ath79_cpu_freq;
EXPORT_SYMBOL_GPL(ath79_cpu_freq);
@@ -111,3 +112,16 @@ void ath79_device_reset_clear(u32 mask)
spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
}
EXPORT_SYMBOL_GPL(ath79_device_reset_clear);
+
+void ath79_flash_acquire(void)
+{
+ mutex_lock(&ath79_flash_mutex);
+}
+EXPORT_SYMBOL_GPL(ath79_flash_acquire);
+
+void ath79_flash_release(void)
+{
+ mutex_unlock(&ath79_flash_mutex);
+}
+EXPORT_SYMBOL_GPL(ath79_flash_release);
+
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -143,4 +143,7 @@ static inline u32 ath79_reset_rr(unsigne
void ath79_device_reset_set(u32 mask);
void ath79_device_reset_clear(u32 mask);
+void ath79_flash_acquire(void);
+void ath79_flash_release(void);
+
#endif /* __ASM_MACH_ATH79_H */

View File

@ -0,0 +1,45 @@
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -142,6 +142,7 @@ static inline u32 ath79_reset_rr(unsigne
void ath79_device_reset_set(u32 mask);
void ath79_device_reset_clear(u32 mask);
+u32 ath79_device_reset_get(u32 mask);
void ath79_flash_acquire(void);
void ath79_flash_release(void);
--- a/arch/mips/ath79/common.c
+++ b/arch/mips/ath79/common.c
@@ -113,6 +113,32 @@ void ath79_device_reset_clear(u32 mask)
}
EXPORT_SYMBOL_GPL(ath79_device_reset_clear);
+u32 ath79_device_reset_get(u32 mask)
+{
+ unsigned long flags;
+ u32 reg;
+ u32 ret;
+
+ if (soc_is_ar71xx())
+ reg = AR71XX_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar724x())
+ reg = AR724X_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar913x())
+ reg = AR913X_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar933x())
+ reg = AR933X_RESET_REG_RESET_MODULE;
+ else if (soc_is_ar934x())
+ reg = AR934X_RESET_REG_RESET_MODULE;
+ else
+ BUG();
+
+ spin_lock_irqsave(&ath79_device_reset_lock, flags);
+ ret = ath79_reset_rr(reg);
+ spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(ath79_device_reset_get);
+
void ath79_flash_acquire(void)
{
mutex_lock(&ath79_flash_mutex);

View File

@ -0,0 +1,47 @@
--- a/arch/mips/ath79/common.h
+++ b/arch/mips/ath79/common.h
@@ -27,6 +27,7 @@ void ath79_ddr_wb_flush(unsigned int reg
void ath79_gpio_function_enable(u32 mask);
void ath79_gpio_function_disable(u32 mask);
void ath79_gpio_function_setup(u32 set, u32 clear);
+void ath79_gpio_output_select(unsigned gpio, u8 val);
void ath79_gpio_init(void);
#endif /* __ATH79_COMMON_H */
--- a/arch/mips/ath79/gpio.c
+++ b/arch/mips/ath79/gpio.c
@@ -180,6 +180,34 @@ void ath79_gpio_function_disable(u32 mas
ath79_gpio_function_setup(0, mask);
}
+void __init ath79_gpio_output_select(unsigned gpio, u8 val)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+ unsigned int reg;
+ u32 t, s;
+
+ BUG_ON(!soc_is_ar934x());
+
+ if (gpio >= AR934X_GPIO_COUNT)
+ return;
+
+ reg = AR934X_GPIO_REG_OUT_FUNC0 + 4 * (gpio / 4);
+ s = 8 * (gpio % 4);
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ t = __raw_readl(base + reg);
+ t &= ~(0xff << s);
+ t |= val << s;
+ __raw_writel(t, base + reg);
+
+ /* flush write */
+ (void) __raw_readl(base + reg);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
void __init ath79_gpio_init(void)
{
int err;

View File

@ -0,0 +1,42 @@
--- a/arch/mips/ath79/prom.c
+++ b/arch/mips/ath79/prom.c
@@ -21,10 +21,39 @@
#include "common.h"
+static char ath79_cmdline_buf[COMMAND_LINE_SIZE] __initdata;
+
+static void __init ath79_prom_append_cmdline(const char *name,
+ const char *value)
+{
+ snprintf(ath79_cmdline_buf, sizeof(ath79_cmdline_buf),
+ " %s=%s", name, value);
+ strlcat(arcs_cmdline, ath79_cmdline_buf, sizeof(arcs_cmdline));
+}
+
void __init prom_init(void)
{
+ const char *env;
+
fw_init_cmdline();
+ env = fw_getenv("ethaddr");
+ if (env)
+ ath79_prom_append_cmdline("ethaddr", env);
+
+ env = fw_getenv("board");
+ if (env) {
+ /* Workaround for buggy bootloaders */
+ if (strcmp(env, "RouterStation") == 0 ||
+ strcmp(env, "Ubiquiti AR71xx-based board") == 0)
+ env = "UBNT-RS";
+
+ if (strcmp(env, "RouterStation PRO") == 0)
+ env = "UBNT-RSPRO";
+
+ ath79_prom_append_cmdline("board", env);
+ }
+
#ifdef CONFIG_BLK_DEV_INITRD
/* Read the initrd address from the firmware environment */
initrd_start = fw_getenvl("initrd_start");

View File

@ -0,0 +1,55 @@
--- a/arch/mips/ath79/prom.c
+++ b/arch/mips/ath79/prom.c
@@ -18,6 +18,7 @@
#include <asm/bootinfo.h>
#include <asm/addrspace.h>
#include <asm/fw/fw.h>
+#include <asm/fw/myloader/myloader.h>
#include "common.h"
@@ -31,10 +32,44 @@ static void __init ath79_prom_append_cmd
strlcat(arcs_cmdline, ath79_cmdline_buf, sizeof(arcs_cmdline));
}
+static int __init ath79_prom_init_myloader(void)
+{
+ struct myloader_info *mylo;
+ char mac_buf[32];
+ unsigned char *mac;
+
+ mylo = myloader_get_info();
+ if (!mylo)
+ return 0;
+
+ switch (mylo->did) {
+ case DEVID_COMPEX_WP543:
+ ath79_prom_append_cmdline("board", "WP543");
+ break;
+ case DEVID_COMPEX_WPE72:
+ ath79_prom_append_cmdline("board", "WPE72");
+ break;
+ default:
+ pr_warn("prom: unknown device id: %x\n", mylo->did);
+ return 0;
+ }
+
+ mac = mylo->macs[0];
+ snprintf(mac_buf, sizeof(mac_buf), "%02x:%02x:%02x:%02x:%02x:%02x",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+
+ ath79_prom_append_cmdline("ethaddr", mac_buf);
+
+ return 1;
+}
+
void __init prom_init(void)
{
const char *env;
+ if (ath79_prom_init_myloader())
+ return;
+
fw_init_cmdline();
env = fw_getenv("ethaddr");

View File

@ -0,0 +1,57 @@
--- a/arch/mips/ath79/prom.c
+++ b/arch/mips/ath79/prom.c
@@ -32,6 +32,35 @@ static void __init ath79_prom_append_cmd
strlcat(arcs_cmdline, ath79_cmdline_buf, sizeof(arcs_cmdline));
}
+#ifdef CONFIG_IMAGE_CMDLINE_HACK
+extern char __image_cmdline[];
+
+static int __init ath79_use_image_cmdline(void)
+{
+ char *p = __image_cmdline;
+ int replace = 0;
+
+ if (*p == '-') {
+ replace = 1;
+ p++;
+ }
+
+ if (*p == '\0')
+ return 0;
+
+ if (replace) {
+ strlcpy(arcs_cmdline, p, sizeof(arcs_cmdline));
+ } else {
+ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
+ strlcat(arcs_cmdline, p, sizeof(arcs_cmdline));
+ }
+
+ return 1;
+}
+#else
+static inline int ath79_use_image_cmdline(void) { return 0; }
+#endif
+
static int __init ath79_prom_init_myloader(void)
{
struct myloader_info *mylo;
@@ -60,6 +89,8 @@ static int __init ath79_prom_init_myload
ath79_prom_append_cmdline("ethaddr", mac_buf);
+ ath79_use_image_cmdline();
+
return 1;
}
@@ -70,7 +101,8 @@ void __init prom_init(void)
if (ath79_prom_init_myloader())
return;
- fw_init_cmdline();
+ if (!ath79_use_image_cmdline())
+ fw_init_cmdline();
env = fw_getenv("ethaddr");
if (env)

View File

@ -0,0 +1,11 @@
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -229,6 +229,8 @@ void __init plat_time_init(void)
mips_hpt_frequency = cpu_clk_rate / 2;
}
+__setup("board=", mips_machtype_setup);
+
static int __init ath79_setup(void)
{
ath79_gpio_init();

View File

@ -0,0 +1,14 @@
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -24,7 +24,10 @@
#include "dev-wmac.h"
static u8 ath79_wmac_mac[ETH_ALEN];
-static struct ath9k_platform_data ath79_wmac_data;
+
+static struct ath9k_platform_data ath79_wmac_data = {
+ .led_pin = -1,
+};
static struct resource ath79_wmac_resources[] = {
{

View File

@ -0,0 +1,18 @@
--- a/arch/mips/ath79/dev-common.c
+++ b/arch/mips/ath79/dev-common.c
@@ -80,6 +80,15 @@ void __init ath79_register_uart(void)
uart_clk_rate = ath79_get_sys_clk_rate("uart");
+ if (soc_is_ar71xx())
+ ath79_gpio_function_enable(AR71XX_GPIO_FUNC_UART_EN);
+ else if (soc_is_ar724x())
+ ath79_gpio_function_enable(AR724X_GPIO_FUNC_UART_EN);
+ else if (soc_is_ar913x())
+ ath79_gpio_function_enable(AR913X_GPIO_FUNC_UART_EN);
+ else if (soc_is_ar933x())
+ ath79_gpio_function_enable(AR933X_GPIO_FUNC_UART_EN);
+
if (soc_is_ar71xx() ||
soc_is_ar724x() ||
soc_is_ar913x() ||

View File

@ -0,0 +1,61 @@
--- a/arch/mips/ath79/early_printk.c
+++ b/arch/mips/ath79/early_printk.c
@@ -56,6 +56,46 @@ static void prom_putchar_dummy(unsigned
/* nothing to do */
}
+static void prom_enable_uart(u32 id)
+{
+ void __iomem *gpio_base;
+ u32 uart_en;
+ u32 t;
+
+ switch (id) {
+ case REV_ID_MAJOR_AR71XX:
+ uart_en = AR71XX_GPIO_FUNC_UART_EN;
+ break;
+
+ case REV_ID_MAJOR_AR7240:
+ case REV_ID_MAJOR_AR7241:
+ case REV_ID_MAJOR_AR7242:
+ uart_en = AR724X_GPIO_FUNC_UART_EN;
+ break;
+
+ case REV_ID_MAJOR_AR913X:
+ uart_en = AR913X_GPIO_FUNC_UART_EN;
+ break;
+
+ case REV_ID_MAJOR_AR9330:
+ case REV_ID_MAJOR_AR9331:
+ uart_en = AR933X_GPIO_FUNC_UART_EN;
+ break;
+
+ case REV_ID_MAJOR_AR9341:
+ case REV_ID_MAJOR_AR9342:
+ case REV_ID_MAJOR_AR9344:
+ /* TODO */
+ default:
+ return;
+ }
+
+ gpio_base = (void __iomem *)(KSEG1ADDR(AR71XX_GPIO_BASE));
+ t = __raw_readl(gpio_base + AR71XX_GPIO_REG_FUNC);
+ t |= uart_en;
+ __raw_writel(t, gpio_base + AR71XX_GPIO_REG_FUNC);
+}
+
static void prom_putchar_init(void)
{
void __iomem *base;
@@ -86,8 +126,10 @@ static void prom_putchar_init(void)
default:
_prom_putchar = prom_putchar_dummy;
- break;
+ return;
}
+
+ prom_enable_uart(id);
}
void prom_putchar(unsigned char ch)

View File

@ -0,0 +1,21 @@
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -189,3 +189,9 @@ void __init ath79_register_wmac(u8 *cal_
platform_device_register(&ath79_wmac_device);
}
+
+void __init ath79_register_wmac_simple(void)
+{
+ ath79_register_wmac(NULL, NULL);
+ ath79_wmac_data.eeprom_name = "soc_wmac.eeprom";
+}
--- a/arch/mips/ath79/dev-wmac.h
+++ b/arch/mips/ath79/dev-wmac.h
@@ -13,5 +13,6 @@
#define _ATH79_DEV_WMAC_H
void ath79_register_wmac(u8 *cal_data, u8 *mac_addr);
+void ath79_register_wmac_simple(void);
#endif /* _ATH79_DEV_WMAC_H */

View File

@ -0,0 +1,166 @@
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -165,6 +165,137 @@ static void qca955x_wmac_setup(void)
ath79_wmac_data.is_clk_25mhz = true;
}
+static bool __init
+ar93xx_wmac_otp_read_word(void __iomem *base, int addr, u32 *data)
+{
+ int timeout = 1000;
+ u32 val;
+
+ __raw_readl(base + AR9300_OTP_BASE + (4 * addr));
+ while (timeout--) {
+ val = __raw_readl(base + AR9300_OTP_STATUS);
+ if ((val & AR9300_OTP_STATUS_TYPE) == AR9300_OTP_STATUS_VALID)
+ break;
+
+ udelay(10);
+ }
+
+ if (!timeout)
+ return false;
+
+ *data = __raw_readl(base + AR9300_OTP_READ_DATA);
+ return true;
+}
+
+static bool __init
+ar93xx_wmac_otp_read(void __iomem *base, int addr, u8 *dest, int len)
+{
+ u32 data;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ int offset = 8 * ((addr - i) % 4);
+
+ if (!ar93xx_wmac_otp_read_word(base, (addr - i) / 4, &data))
+ return false;
+
+ dest[i] = (data >> offset) & 0xff;
+ }
+
+ return true;
+}
+
+static bool __init
+ar93xx_wmac_otp_uncompress(void __iomem *base, int addr, int len, u8 *dest,
+ int dest_start, int dest_len)
+{
+ int dest_bytes = 0;
+ int offset = 0;
+ int end = addr - len;
+ u8 hdr[2];
+
+ while (addr > end) {
+ if (!ar93xx_wmac_otp_read(base, addr, hdr, 2))
+ return false;
+
+ addr -= 2;
+ offset += hdr[0];
+
+ if (offset <= dest_start + dest_len &&
+ offset + len >= dest_start) {
+ int data_offset = 0;
+ int dest_offset = 0;
+ int copy_len;
+
+ if (offset < dest_start)
+ data_offset = dest_start - offset;
+ else
+ dest_offset = offset - dest_start;
+
+ copy_len = len - data_offset;
+ if (copy_len > dest_len - dest_offset)
+ copy_len = dest_len - dest_offset;
+
+ ar93xx_wmac_otp_read(base, addr - data_offset,
+ dest + dest_offset,
+ copy_len);
+
+ dest_bytes += copy_len;
+ }
+ addr -= hdr[1];
+ }
+ return !!dest_bytes;
+}
+
+bool __init ar93xx_wmac_read_mac_address(u8 *dest)
+{
+ void __iomem *base;
+ bool ret = false;
+ int addr = 0x1ff;
+ unsigned int len;
+ u32 hdr_u32;
+ u8 *hdr = (u8 *) &hdr_u32;
+ u8 mac[6] = { 0x00, 0x02, 0x03, 0x04, 0x05, 0x06 };
+ int mac_start = 2, mac_end = 8;
+
+ BUG_ON(!soc_is_ar933x() && !soc_is_ar934x());
+ base = ioremap_nocache(AR933X_WMAC_BASE, AR933X_WMAC_SIZE);
+ while (addr > sizeof(hdr)) {
+ if (!ar93xx_wmac_otp_read(base, addr, hdr, sizeof(hdr)))
+ break;
+
+ if (hdr_u32 == 0 || hdr_u32 == ~0)
+ break;
+
+ len = (hdr[1] << 4) | (hdr[2] >> 4);
+ addr -= 4;
+
+ switch (hdr[0] >> 5) {
+ case 0:
+ if (len < mac_end)
+ break;
+
+ ar93xx_wmac_otp_read(base, addr - mac_start, mac, 6);
+ ret = true;
+ break;
+ case 3:
+ ret |= ar93xx_wmac_otp_uncompress(base, addr, len, mac,
+ mac_start, 6);
+ break;
+ default:
+ break;
+ }
+
+ addr -= len + 2;
+ }
+
+ iounmap(base);
+ if (ret)
+ memcpy(dest, mac, 6);
+
+ return ret;
+}
+
void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr)
{
if (soc_is_ar913x())
--- a/arch/mips/ath79/dev-wmac.h
+++ b/arch/mips/ath79/dev-wmac.h
@@ -14,5 +14,6 @@
void ath79_register_wmac(u8 *cal_data, u8 *mac_addr);
void ath79_register_wmac_simple(void);
+bool ar93xx_wmac_read_mac_address(u8 *dest);
#endif /* _ATH79_DEV_WMAC_H */
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -112,6 +112,14 @@
#define QCA955X_EHCI1_BASE 0x1b400000
#define QCA955X_EHCI_SIZE 0x1000
+#define AR9300_OTP_BASE 0x14000
+#define AR9300_OTP_STATUS 0x15f18
+#define AR9300_OTP_STATUS_TYPE 0x7
+#define AR9300_OTP_STATUS_VALID 0x4
+#define AR9300_OTP_STATUS_ACCESS_BUSY 0x2
+#define AR9300_OTP_STATUS_SM_BUSY 0x1
+#define AR9300_OTP_READ_DATA 0x15f1c
+
/*
* DDR_CTRL block
*/

View File

@ -0,0 +1,31 @@
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -296,6 +296,16 @@ bool __init ar93xx_wmac_read_mac_address
return ret;
}
+void __init ath79_wmac_disable_2ghz(void)
+{
+ ath79_wmac_data.disable_2ghz = true;
+}
+
+void __init ath79_wmac_disable_5ghz(void)
+{
+ ath79_wmac_data.disable_5ghz = true;
+}
+
void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr)
{
if (soc_is_ar913x())
--- a/arch/mips/ath79/dev-wmac.h
+++ b/arch/mips/ath79/dev-wmac.h
@@ -14,6 +14,9 @@
void ath79_register_wmac(u8 *cal_data, u8 *mac_addr);
void ath79_register_wmac_simple(void);
+void ath79_wmac_disable_2ghz(void);
+void ath79_wmac_disable_5ghz(void);
+
bool ar93xx_wmac_read_mac_address(u8 *dest);
#endif /* _ATH79_DEV_WMAC_H */

View File

@ -0,0 +1,101 @@
--- a/arch/mips/ath79/dev-usb.c
+++ b/arch/mips/ath79/dev-usb.c
@@ -37,6 +37,8 @@ static struct usb_ehci_pdata ath79_ehci_
static struct usb_ehci_pdata ath79_ehci_pdata_v2 = {
.caps_offset = 0x100,
.has_tt = 1,
+ .qca_force_host_mode = 1,
+ .qca_force_16bit_ptw = 1,
};
static void __init ath79_usb_register(const char *name, int id,
@@ -159,6 +161,9 @@ static void __init ar913x_usb_setup(void
ath79_device_reset_clear(AR913X_RESET_USB_PHY);
mdelay(10);
+ ath79_ehci_pdata_v2.qca_force_host_mode = 0;
+ ath79_ehci_pdata_v2.qca_force_16bit_ptw = 0;
+
ath79_usb_register("ehci-platform", -1,
AR913X_EHCI_BASE, AR913X_EHCI_SIZE,
ATH79_CPU_IRQ(3),
@@ -182,14 +187,34 @@ static void __init ar933x_usb_setup(void
&ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
}
-static void __init ar934x_usb_setup(void)
+static void enable_tx_tx_idp_violation_fix(unsigned base)
{
- u32 bootstrap;
+ void __iomem *phy_reg;
+ u32 t;
+
+ phy_reg = ioremap(base, 4);
+ if (!phy_reg)
+ return;
+
+ t = ioread32(phy_reg);
+ t &= ~0xff;
+ t |= 0x58;
+ iowrite32(t, phy_reg);
+
+ iounmap(phy_reg);
+}
- bootstrap = ath79_reset_rr(AR934X_RESET_REG_BOOTSTRAP);
- if (bootstrap & AR934X_BOOTSTRAP_USB_MODE_DEVICE)
+static void ar934x_usb_reset_notifier(struct platform_device *pdev)
+{
+ if (pdev->id != -1)
return;
+ enable_tx_tx_idp_violation_fix(0x18116c94);
+ dev_info(&pdev->dev, "TX-TX IDP fix enabled\n");
+}
+
+static void __init ar934x_usb_setup(void)
+{
ath79_device_reset_set(AR934X_RESET_USBSUS_OVERRIDE);
udelay(1000);
@@ -202,14 +227,40 @@ static void __init ar934x_usb_setup(void
ath79_device_reset_clear(AR934X_RESET_USB_HOST);
udelay(1000);
+ if (ath79_soc_rev >= 3)
+ ath79_ehci_pdata_v2.reset_notifier = ar934x_usb_reset_notifier;
+
ath79_usb_register("ehci-platform", -1,
AR934X_EHCI_BASE, AR934X_EHCI_SIZE,
ATH79_CPU_IRQ(3),
&ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
}
+static void qca955x_usb_reset_notifier(struct platform_device *pdev)
+{
+ u32 base;
+
+ switch (pdev->id) {
+ case 0:
+ base = 0x18116c94;
+ break;
+
+ case 1:
+ base = 0x18116e54;
+ break;
+
+ default:
+ return;
+ }
+
+ enable_tx_tx_idp_violation_fix(base);
+ dev_info(&pdev->dev, "TX-TX IDP fix enabled\n");
+}
+
static void __init qca955x_usb_setup(void)
{
+ ath79_ehci_pdata_v2.reset_notifier = qca955x_usb_reset_notifier;
+
ath79_usb_register("ehci-platform", 0,
QCA955X_EHCI0_BASE, QCA955X_EHCI_SIZE,
ATH79_IP3_IRQ(0),

View File

@ -0,0 +1,363 @@
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -20,6 +20,10 @@
#include <linux/bitops.h>
#define AR71XX_APB_BASE 0x18000000
+#define AR71XX_GE0_BASE 0x19000000
+#define AR71XX_GE0_SIZE 0x10000
+#define AR71XX_GE1_BASE 0x1a000000
+#define AR71XX_GE1_SIZE 0x10000
#define AR71XX_EHCI_BASE 0x1b000000
#define AR71XX_EHCI_SIZE 0x1000
#define AR71XX_OHCI_BASE 0x1c000000
@@ -39,6 +43,8 @@
#define AR71XX_PLL_SIZE 0x100
#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
#define AR71XX_RESET_SIZE 0x100
+#define AR71XX_MII_BASE (AR71XX_APB_BASE + 0x00070000)
+#define AR71XX_MII_SIZE 0x100
#define AR71XX_PCI_MEM_BASE 0x10000000
#define AR71XX_PCI_MEM_SIZE 0x07000000
@@ -81,15 +87,21 @@
#define AR933X_UART_BASE (AR71XX_APB_BASE + 0x00020000)
#define AR933X_UART_SIZE 0x14
+#define AR933X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000)
+#define AR933X_GMAC_SIZE 0x04
#define AR933X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000)
#define AR933X_WMAC_SIZE 0x20000
#define AR933X_EHCI_BASE 0x1b000000
#define AR933X_EHCI_SIZE 0x1000
+#define AR934X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000)
+#define AR934X_GMAC_SIZE 0x14
#define AR934X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000)
#define AR934X_WMAC_SIZE 0x20000
#define AR934X_EHCI_BASE 0x1b000000
#define AR934X_EHCI_SIZE 0x200
+#define AR934X_NFC_BASE 0x1b000200
+#define AR934X_NFC_SIZE 0xb8
#define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000)
#define AR934X_SRIF_SIZE 0x1000
@@ -106,11 +118,15 @@
#define QCA955X_PCI_CTRL_BASE1 (AR71XX_APB_BASE + 0x00280000)
#define QCA955X_PCI_CTRL_SIZE 0x100
+#define QCA955X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000)
+#define QCA955X_GMAC_SIZE 0x40
#define QCA955X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000)
#define QCA955X_WMAC_SIZE 0x20000
#define QCA955X_EHCI0_BASE 0x1b000000
#define QCA955X_EHCI1_BASE 0x1b400000
#define QCA955X_EHCI_SIZE 0x1000
+#define QCA955X_NFC_BASE 0x1b800200
+#define QCA955X_NFC_SIZE 0xb8
#define AR9300_OTP_BASE 0x14000
#define AR9300_OTP_STATUS 0x15f18
@@ -174,6 +190,9 @@
#define AR71XX_AHB_DIV_SHIFT 20
#define AR71XX_AHB_DIV_MASK 0x7
+#define AR71XX_ETH0_PLL_SHIFT 17
+#define AR71XX_ETH1_PLL_SHIFT 19
+
#define AR724X_PLL_REG_CPU_CONFIG 0x00
#define AR724X_PLL_REG_PCIE_CONFIG 0x18
@@ -186,6 +205,8 @@
#define AR724X_DDR_DIV_SHIFT 22
#define AR724X_DDR_DIV_MASK 0x3
+#define AR7242_PLL_REG_ETH0_INT_CLOCK 0x2c
+
#define AR913X_PLL_REG_CPU_CONFIG 0x00
#define AR913X_PLL_REG_ETH_CONFIG 0x04
#define AR913X_PLL_REG_ETH0_INT_CLOCK 0x14
@@ -198,6 +219,9 @@
#define AR913X_AHB_DIV_SHIFT 19
#define AR913X_AHB_DIV_MASK 0x1
+#define AR913X_ETH0_PLL_SHIFT 20
+#define AR913X_ETH1_PLL_SHIFT 22
+
#define AR933X_PLL_CPU_CONFIG_REG 0x00
#define AR933X_PLL_CLOCK_CTRL_REG 0x08
@@ -219,6 +243,8 @@
#define AR934X_PLL_CPU_CONFIG_REG 0x00
#define AR934X_PLL_DDR_CONFIG_REG 0x04
#define AR934X_PLL_CPU_DDR_CLK_CTRL_REG 0x08
+#define AR934X_PLL_SWITCH_CLOCK_CONTROL_REG 0x24
+#define AR934X_PLL_ETH_XMII_CONTROL_REG 0x2c
#define AR934X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
#define AR934X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f
@@ -251,9 +277,13 @@
#define AR934X_PLL_CPU_DDR_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
#define AR934X_PLL_CPU_DDR_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+#define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6)
+
#define QCA955X_PLL_CPU_CONFIG_REG 0x00
#define QCA955X_PLL_DDR_CONFIG_REG 0x04
#define QCA955X_PLL_CLK_CTRL_REG 0x08
+#define QCA955X_PLL_ETH_XMII_CONTROL_REG 0x28
+#define QCA955X_PLL_ETH_SGMII_CONTROL_REG 0x48
#define QCA955X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
#define QCA955X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f
@@ -378,16 +408,83 @@
#define AR913X_RESET_USB_HOST BIT(5)
#define AR913X_RESET_USB_PHY BIT(4)
+#define AR933X_RESET_GE1_MDIO BIT(23)
+#define AR933X_RESET_GE0_MDIO BIT(22)
+#define AR933X_RESET_GE1_MAC BIT(13)
#define AR933X_RESET_WMAC BIT(11)
+#define AR933X_RESET_GE0_MAC BIT(9)
#define AR933X_RESET_USB_HOST BIT(5)
#define AR933X_RESET_USB_PHY BIT(4)
#define AR933X_RESET_USBSUS_OVERRIDE BIT(3)
+#define AR934X_RESET_HOST BIT(31)
+#define AR934X_RESET_SLIC BIT(30)
+#define AR934X_RESET_HDMA BIT(29)
+#define AR934X_RESET_EXTERNAL BIT(28)
+#define AR934X_RESET_RTC BIT(27)
+#define AR934X_RESET_PCIE_EP_INT BIT(26)
+#define AR934X_RESET_CHKSUM_ACC BIT(25)
+#define AR934X_RESET_FULL_CHIP BIT(24)
+#define AR934X_RESET_GE1_MDIO BIT(23)
+#define AR934X_RESET_GE0_MDIO BIT(22)
+#define AR934X_RESET_CPU_NMI BIT(21)
+#define AR934X_RESET_CPU_COLD BIT(20)
+#define AR934X_RESET_HOST_RESET_INT BIT(19)
+#define AR934X_RESET_PCIE_EP BIT(18)
+#define AR934X_RESET_UART1 BIT(17)
+#define AR934X_RESET_DDR BIT(16)
+#define AR934X_RESET_USB_PHY_PLL_PWD_EXT BIT(15)
+#define AR934X_RESET_NANDF BIT(14)
+#define AR934X_RESET_GE1_MAC BIT(13)
+#define AR934X_RESET_ETH_SWITCH_ANALOG BIT(12)
#define AR934X_RESET_USB_PHY_ANALOG BIT(11)
+#define AR934X_RESET_HOST_DMA_INT BIT(10)
+#define AR934X_RESET_GE0_MAC BIT(9)
+#define AR934X_RESET_ETH_SWITCH BIT(8)
+#define AR934X_RESET_PCIE_PHY BIT(7)
+#define AR934X_RESET_PCIE BIT(6)
#define AR934X_RESET_USB_HOST BIT(5)
#define AR934X_RESET_USB_PHY BIT(4)
#define AR934X_RESET_USBSUS_OVERRIDE BIT(3)
+#define AR934X_RESET_LUT BIT(2)
+#define AR934X_RESET_MBOX BIT(1)
+#define AR934X_RESET_I2S BIT(0)
+
+#define QCA955X_RESET_HOST BIT(31)
+#define QCA955X_RESET_SLIC BIT(30)
+#define QCA955X_RESET_HDMA BIT(29)
+#define QCA955X_RESET_EXTERNAL BIT(28)
+#define QCA955X_RESET_RTC BIT(27)
+#define QCA955X_RESET_PCIE_EP_INT BIT(26)
+#define QCA955X_RESET_CHKSUM_ACC BIT(25)
+#define QCA955X_RESET_FULL_CHIP BIT(24)
+#define QCA955X_RESET_GE1_MDIO BIT(23)
+#define QCA955X_RESET_GE0_MDIO BIT(22)
+#define QCA955X_RESET_CPU_NMI BIT(21)
+#define QCA955X_RESET_CPU_COLD BIT(20)
+#define QCA955X_RESET_HOST_RESET_INT BIT(19)
+#define QCA955X_RESET_PCIE_EP BIT(18)
+#define QCA955X_RESET_UART1 BIT(17)
+#define QCA955X_RESET_DDR BIT(16)
+#define QCA955X_RESET_USB_PHY_PLL_PWD_EXT BIT(15)
+#define QCA955X_RESET_NANDF BIT(14)
+#define QCA955X_RESET_GE1_MAC BIT(13)
+#define QCA955X_RESET_SGMII_ANALOG BIT(12)
+#define QCA955X_RESET_USB_PHY_ANALOG BIT(11)
+#define QCA955X_RESET_HOST_DMA_INT BIT(10)
+#define QCA955X_RESET_GE0_MAC BIT(9)
+#define QCA955X_RESET_SGMII BIT(8)
+#define QCA955X_RESET_PCIE_PHY BIT(7)
+#define QCA955X_RESET_PCIE BIT(6)
+#define QCA955X_RESET_USB_HOST BIT(5)
+#define QCA955X_RESET_USB_PHY BIT(4)
+#define QCA955X_RESET_USBSUS_OVERRIDE BIT(3)
+#define QCA955X_RESET_LUT BIT(2)
+#define QCA955X_RESET_MBOX BIT(1)
+#define QCA955X_RESET_I2S BIT(0)
+#define AR933X_BOOTSTRAP_MDIO_GPIO_EN BIT(18)
+#define AR933X_BOOTSTRAP_EEPBUSY BIT(4)
#define AR933X_BOOTSTRAP_REF_CLK_40 BIT(0)
#define AR934X_BOOTSTRAP_SW_OPTION8 BIT(23)
@@ -529,6 +626,12 @@
#define AR71XX_GPIO_REG_INT_ENABLE 0x24
#define AR71XX_GPIO_REG_FUNC 0x28
+#define AR934X_GPIO_REG_OUT_FUNC0 0x2c
+#define AR934X_GPIO_REG_OUT_FUNC1 0x30
+#define AR934X_GPIO_REG_OUT_FUNC2 0x34
+#define AR934X_GPIO_REG_OUT_FUNC3 0x38
+#define AR934X_GPIO_REG_OUT_FUNC4 0x3c
+#define AR934X_GPIO_REG_OUT_FUNC5 0x40
#define AR934X_GPIO_REG_FUNC 0x6c
#define AR71XX_GPIO_COUNT 16
@@ -560,4 +663,153 @@
#define AR934X_SRIF_DPLL2_OUTDIV_SHIFT 13
#define AR934X_SRIF_DPLL2_OUTDIV_MASK 0x7
+#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17)
+#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16)
+#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13)
+#define AR71XX_GPIO_FUNC_SPI_CS1_EN BIT(12)
+#define AR71XX_GPIO_FUNC_UART_EN BIT(8)
+#define AR71XX_GPIO_FUNC_USB_OC_EN BIT(4)
+#define AR71XX_GPIO_FUNC_USB_CLK_EN BIT(0)
+
+#define AR724X_GPIO_FUNC_GE0_MII_CLK_EN BIT(19)
+#define AR724X_GPIO_FUNC_SPI_EN BIT(18)
+#define AR724X_GPIO_FUNC_SPI_CS_EN2 BIT(14)
+#define AR724X_GPIO_FUNC_SPI_CS_EN1 BIT(13)
+#define AR724X_GPIO_FUNC_CLK_OBS5_EN BIT(12)
+#define AR724X_GPIO_FUNC_CLK_OBS4_EN BIT(11)
+#define AR724X_GPIO_FUNC_CLK_OBS3_EN BIT(10)
+#define AR724X_GPIO_FUNC_CLK_OBS2_EN BIT(9)
+#define AR724X_GPIO_FUNC_CLK_OBS1_EN BIT(8)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4)
+#define AR724X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3)
+#define AR724X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2)
+#define AR724X_GPIO_FUNC_UART_EN BIT(1)
+#define AR724X_GPIO_FUNC_JTAG_DISABLE BIT(0)
+
+#define AR913X_GPIO_FUNC_WMAC_LED_EN BIT(22)
+#define AR913X_GPIO_FUNC_EXP_PORT_CS_EN BIT(21)
+#define AR913X_GPIO_FUNC_I2S_REFCLKEN BIT(20)
+#define AR913X_GPIO_FUNC_I2S_MCKEN BIT(19)
+#define AR913X_GPIO_FUNC_I2S1_EN BIT(18)
+#define AR913X_GPIO_FUNC_I2S0_EN BIT(17)
+#define AR913X_GPIO_FUNC_SLIC_EN BIT(16)
+#define AR913X_GPIO_FUNC_UART_RTSCTS_EN BIT(9)
+#define AR913X_GPIO_FUNC_UART_EN BIT(8)
+#define AR913X_GPIO_FUNC_USB_CLK_EN BIT(4)
+
+#define AR933X_GPIO_FUNC_SPDIF2TCK BIT(31)
+#define AR933X_GPIO_FUNC_SPDIF_EN BIT(30)
+#define AR933X_GPIO_FUNC_I2SO_22_18_EN BIT(29)
+#define AR933X_GPIO_FUNC_I2S_MCK_EN BIT(27)
+#define AR933X_GPIO_FUNC_I2SO_EN BIT(26)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_DUPL BIT(25)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_COLL BIT(24)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED_ACT BIT(23)
+#define AR933X_GPIO_FUNC_SPI_EN BIT(18)
+#define AR933X_GPIO_FUNC_SPI_CS_EN2 BIT(14)
+#define AR933X_GPIO_FUNC_SPI_CS_EN1 BIT(13)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN BIT(7)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN BIT(6)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN BIT(5)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN BIT(4)
+#define AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN BIT(3)
+#define AR933X_GPIO_FUNC_UART_RTS_CTS_EN BIT(2)
+#define AR933X_GPIO_FUNC_UART_EN BIT(1)
+#define AR933X_GPIO_FUNC_JTAG_DISABLE BIT(0)
+
+#define AR934X_GPIO_FUNC_CLK_OBS7_EN BIT(9)
+#define AR934X_GPIO_FUNC_CLK_OBS6_EN BIT(8)
+#define AR934X_GPIO_FUNC_CLK_OBS5_EN BIT(7)
+#define AR934X_GPIO_FUNC_CLK_OBS4_EN BIT(6)
+#define AR934X_GPIO_FUNC_CLK_OBS3_EN BIT(5)
+#define AR934X_GPIO_FUNC_CLK_OBS2_EN BIT(4)
+#define AR934X_GPIO_FUNC_CLK_OBS1_EN BIT(3)
+#define AR934X_GPIO_FUNC_CLK_OBS0_EN BIT(2)
+#define AR934X_GPIO_FUNC_JTAG_DISABLE BIT(1)
+
+#define AR934X_GPIO_OUT_GPIO 0
+#define AR934X_GPIO_OUT_SPI_CS1 7
+#define AR934X_GPIO_OUT_LED_LINK0 41
+#define AR934X_GPIO_OUT_LED_LINK1 42
+#define AR934X_GPIO_OUT_LED_LINK2 43
+#define AR934X_GPIO_OUT_LED_LINK3 44
+#define AR934X_GPIO_OUT_LED_LINK4 45
+#define AR934X_GPIO_OUT_EXT_LNA0 46
+#define AR934X_GPIO_OUT_EXT_LNA1 47
+
+/*
+ * MII_CTRL block
+ */
+#define AR71XX_MII_REG_MII0_CTRL 0x00
+#define AR71XX_MII_REG_MII1_CTRL 0x04
+
+#define AR71XX_MII_CTRL_IF_MASK 3
+#define AR71XX_MII_CTRL_SPEED_SHIFT 4
+#define AR71XX_MII_CTRL_SPEED_MASK 3
+#define AR71XX_MII_CTRL_SPEED_10 0
+#define AR71XX_MII_CTRL_SPEED_100 1
+#define AR71XX_MII_CTRL_SPEED_1000 2
+
+#define AR71XX_MII0_CTRL_IF_GMII 0
+#define AR71XX_MII0_CTRL_IF_MII 1
+#define AR71XX_MII0_CTRL_IF_RGMII 2
+#define AR71XX_MII0_CTRL_IF_RMII 3
+
+#define AR71XX_MII1_CTRL_IF_RGMII 0
+#define AR71XX_MII1_CTRL_IF_RMII 1
+
+/*
+ * AR933X GMAC interface
+ */
+#define AR933X_GMAC_REG_ETH_CFG 0x00
+
+#define AR933X_ETH_CFG_RGMII_GE0 BIT(0)
+#define AR933X_ETH_CFG_MII_GE0 BIT(1)
+#define AR933X_ETH_CFG_GMII_GE0 BIT(2)
+#define AR933X_ETH_CFG_MII_GE0_MASTER BIT(3)
+#define AR933X_ETH_CFG_MII_GE0_SLAVE BIT(4)
+#define AR933X_ETH_CFG_MII_GE0_ERR_EN BIT(5)
+#define AR933X_ETH_CFG_SW_PHY_SWAP BIT(7)
+#define AR933X_ETH_CFG_SW_PHY_ADDR_SWAP BIT(8)
+#define AR933X_ETH_CFG_RMII_GE0 BIT(9)
+#define AR933X_ETH_CFG_RMII_GE0_SPD_10 0
+#define AR933X_ETH_CFG_RMII_GE0_SPD_100 BIT(10)
+
+/*
+ * AR934X GMAC Interface
+ */
+#define AR934X_GMAC_REG_ETH_CFG 0x00
+
+#define AR934X_ETH_CFG_RGMII_GMAC0 BIT(0)
+#define AR934X_ETH_CFG_MII_GMAC0 BIT(1)
+#define AR934X_ETH_CFG_GMII_GMAC0 BIT(2)
+#define AR934X_ETH_CFG_MII_GMAC0_MASTER BIT(3)
+#define AR934X_ETH_CFG_MII_GMAC0_SLAVE BIT(4)
+#define AR934X_ETH_CFG_MII_GMAC0_ERR_EN BIT(5)
+#define AR934X_ETH_CFG_SW_ONLY_MODE BIT(6)
+#define AR934X_ETH_CFG_SW_PHY_SWAP BIT(7)
+#define AR934X_ETH_CFG_SW_APB_ACCESS BIT(9)
+#define AR934X_ETH_CFG_RMII_GMAC0 BIT(10)
+#define AR933X_ETH_CFG_MII_CNTL_SPEED BIT(11)
+#define AR934X_ETH_CFG_RMII_GMAC0_MASTER BIT(12)
+#define AR933X_ETH_CFG_SW_ACC_MSB_FIRST BIT(13)
+#define AR934X_ETH_CFG_RXD_DELAY BIT(14)
+#define AR934X_ETH_CFG_RXD_DELAY_MASK 0x3
+#define AR934X_ETH_CFG_RXD_DELAY_SHIFT 14
+#define AR934X_ETH_CFG_RDV_DELAY BIT(16)
+#define AR934X_ETH_CFG_RDV_DELAY_MASK 0x3
+#define AR934X_ETH_CFG_RDV_DELAY_SHIFT 16
+
+/*
+ * QCA955X GMAC Interface
+ */
+
+#define QCA955X_GMAC_REG_ETH_CFG 0x00
+
+#define QCA955X_ETH_CFG_RGMII_EN BIT(0)
+#define QCA955X_ETH_CFG_GE0_SGMII BIT(6)
+
#endif /* __ASM_MACH_AR71XX_REGS_H */

View File

@ -0,0 +1,76 @@
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -98,6 +98,20 @@ config SOC_QCA955X
select PCI_AR724X if PCI
def_bool n
+config ATH79_DEV_M25P80
+ select ATH79_DEV_SPI
+ def_bool n
+
+config ATH79_DEV_AP9X_PCI
+ select ATH79_PCI_ATH9K_FIXUP
+ def_bool n
+
+config ATH79_DEV_DSA
+ def_bool n
+
+config ATH79_DEV_ETH
+ def_bool n
+
config PCI_AR724X
def_bool n
@@ -107,6 +121,10 @@ config ATH79_DEV_GPIO_BUTTONS
config ATH79_DEV_LEDS_GPIO
def_bool n
+config ATH79_DEV_NFC
+ depends on (SOC_AR934X || SOC_QCA955X)
+ def_bool n
+
config ATH79_DEV_SPI
def_bool n
@@ -117,4 +135,13 @@ config ATH79_DEV_WMAC
depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA955X)
def_bool n
+config ATH79_NVRAM
+ def_bool n
+
+config ATH79_PCI_ATH9K_FIXUP
+ def_bool n
+
+config ATH79_ROUTERBOOT
+ def_bool n
+
endif
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -17,13 +17,25 @@ obj-$(CONFIG_PCI) += pci.o
# Devices
#
obj-y += dev-common.o
+obj-$(CONFIG_ATH79_DEV_AP9X_PCI) += dev-ap9x-pci.o
+obj-$(CONFIG_ATH79_DEV_DSA) += dev-dsa.o
+obj-$(CONFIG_ATH79_DEV_ETH) += dev-eth.o
obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o
obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o
+obj-$(CONFIG_ATH79_DEV_M25P80) += dev-m25p80.o
+obj-$(CONFIG_ATH79_DEV_NFC) += dev-nfc.o
obj-$(CONFIG_ATH79_DEV_SPI) += dev-spi.o
obj-$(CONFIG_ATH79_DEV_USB) += dev-usb.o
obj-$(CONFIG_ATH79_DEV_WMAC) += dev-wmac.o
#
+# Miscellaneous objects
+#
+obj-$(CONFIG_ATH79_NVRAM) += nvram.o
+obj-$(CONFIG_ATH79_PCI_ATH9K_FIXUP) += pci-ath9k-fixup.o
+obj-$(CONFIG_ATH79_ROUTERBOOT) += routerboot.o
+
+#
# Machines
#
obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o

View File

@ -0,0 +1,159 @@
--- a/arch/mips/ath79/mach-ap121.c
+++ b/arch/mips/ath79/mach-ap121.c
@@ -1,19 +1,21 @@
/*
* Atheros AP121 board support
*
- * Copyright (C) 2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
*
* 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 "machtypes.h"
+#include "dev-eth.h"
#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
+#include "dev-m25p80.h"
#include "dev-spi.h"
#include "dev-usb.h"
#include "dev-wmac.h"
+#include "machtypes.h"
#define AP121_GPIO_LED_WLAN 0
#define AP121_GPIO_LED_USB 1
@@ -24,7 +26,14 @@
#define AP121_KEYS_POLL_INTERVAL 20 /* msecs */
#define AP121_KEYS_DEBOUNCE_INTERVAL (3 * AP121_KEYS_POLL_INTERVAL)
-#define AP121_CAL_DATA_ADDR 0x1fff1000
+#define AP121_MAC0_OFFSET 0x0000
+#define AP121_MAC1_OFFSET 0x0006
+#define AP121_CALDATA_OFFSET 0x1000
+#define AP121_WMAC_MAC_OFFSET 0x1002
+
+#define AP121_MINI_GPIO_LED_WLAN 0
+#define AP121_MINI_GPIO_BTN_JUMPSTART 12
+#define AP121_MINI_GPIO_BTN_RESET 11
static struct gpio_led ap121_leds_gpio[] __initdata = {
{
@@ -58,35 +67,78 @@ static struct gpio_keys_button ap121_gpi
}
};
-static struct spi_board_info ap121_spi_info[] = {
+static struct gpio_led ap121_mini_leds_gpio[] __initdata = {
{
- .bus_num = 0,
- .chip_select = 0,
- .max_speed_hz = 25000000,
- .modalias = "mx25l1606e",
- }
+ .name = "ap121:green:wlan",
+ .gpio = AP121_MINI_GPIO_LED_WLAN,
+ .active_low = 0,
+ },
};
-static struct ath79_spi_platform_data ap121_spi_data = {
- .bus_num = 0,
- .num_chipselect = 1,
+static struct gpio_keys_button ap121_mini_gpio_keys[] __initdata = {
+ {
+ .desc = "jumpstart button",
+ .type = EV_KEY,
+ .code = KEY_WPS_BUTTON,
+ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = AP121_MINI_GPIO_BTN_JUMPSTART,
+ .active_low = 1,
+ },
+ {
+ .desc = "reset button",
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .debounce_interval = AP121_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = AP121_MINI_GPIO_BTN_RESET,
+ .active_low = 1,
+ }
};
+static void __init ap121_common_setup(void)
+{
+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
+
+ ath79_register_m25p80(NULL);
+ ath79_register_wmac(art + AP121_CALDATA_OFFSET,
+ art + AP121_WMAC_MAC_OFFSET);
+
+ ath79_init_mac(ath79_eth0_data.mac_addr, art + AP121_MAC0_OFFSET, 0);
+ ath79_init_mac(ath79_eth1_data.mac_addr, art + AP121_MAC1_OFFSET, 0);
+
+ ath79_register_mdio(0, 0x0);
+
+ /* LAN ports */
+ ath79_register_eth(1);
+
+ /* WAN port */
+ ath79_register_eth(0);
+}
+
static void __init ap121_setup(void)
{
- u8 *cal_data = (u8 *) KSEG1ADDR(AP121_CAL_DATA_ADDR);
+ ap121_common_setup();
ath79_register_leds_gpio(-1, ARRAY_SIZE(ap121_leds_gpio),
ap121_leds_gpio);
ath79_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL,
ARRAY_SIZE(ap121_gpio_keys),
ap121_gpio_keys);
-
- ath79_register_spi(&ap121_spi_data, ap121_spi_info,
- ARRAY_SIZE(ap121_spi_info));
ath79_register_usb();
- ath79_register_wmac(cal_data, NULL);
}
MIPS_MACHINE(ATH79_MACH_AP121, "AP121", "Atheros AP121 reference board",
ap121_setup);
+
+static void __init ap121_mini_setup(void)
+{
+ ap121_common_setup();
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap121_mini_leds_gpio),
+ ap121_mini_leds_gpio);
+ ath79_register_gpio_keys_polled(-1, AP121_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(ap121_mini_gpio_keys),
+ ap121_mini_gpio_keys);
+}
+
+MIPS_MACHINE(ATH79_MACH_AP121_MINI, "AP121-MINI", "Atheros AP121-MINI",
+ ap121_mini_setup);
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -5,9 +5,10 @@ menu "Atheros AR71XX/AR724X/AR913X machi
config ATH79_MACH_AP121
bool "Atheros AP121 reference board"
select SOC_AR933X
+ select ATH79_DEV_ETH
select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO
- select ATH79_DEV_SPI
+ select ATH79_DEV_M25P80
select ATH79_DEV_USB
select ATH79_DEV_WMAC
help
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -17,6 +17,7 @@
enum ath79_mach_type {
ATH79_MACH_GENERIC = 0,
ATH79_MACH_AP121, /* Atheros AP121 reference board */
+ ATH79_MACH_AP121_MINI, /* Atheros AP121-MINI reference board */
ATH79_MACH_AP136_010, /* Atheros AP136-010 reference board */
ATH79_MACH_AP81, /* Atheros AP81 reference board */
ATH79_MACH_DB120, /* Atheros DB120 reference board */

View File

@ -0,0 +1,84 @@
--- a/arch/mips/ath79/mach-ap81.c
+++ b/arch/mips/ath79/mach-ap81.c
@@ -9,12 +9,16 @@
* by the Free Software Foundation.
*/
-#include "machtypes.h"
-#include "dev-wmac.h"
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+
+#include "dev-eth.h"
#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
-#include "dev-spi.h"
+#include "dev-m25p80.h"
#include "dev-usb.h"
+#include "dev-wmac.h"
+#include "machtypes.h"
#define AP81_GPIO_LED_STATUS 1
#define AP81_GPIO_LED_AOSS 3
@@ -67,20 +71,6 @@ static struct gpio_keys_button ap81_gpio
}
};
-static struct spi_board_info ap81_spi_info[] = {
- {
- .bus_num = 0,
- .chip_select = 0,
- .max_speed_hz = 25000000,
- .modalias = "m25p64",
- }
-};
-
-static struct ath79_spi_platform_data ap81_spi_data = {
- .bus_num = 0,
- .num_chipselect = 1,
-};
-
static void __init ap81_setup(void)
{
u8 *cal_data = (u8 *) KSEG1ADDR(AP81_CAL_DATA_ADDR);
@@ -90,10 +80,24 @@ static void __init ap81_setup(void)
ath79_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL,
ARRAY_SIZE(ap81_gpio_keys),
ap81_gpio_keys);
- ath79_register_spi(&ap81_spi_data, ap81_spi_info,
- ARRAY_SIZE(ap81_spi_info));
+ ath79_register_m25p80(NULL);
ath79_register_wmac(cal_data, NULL);
ath79_register_usb();
+
+ ath79_register_mdio(0, 0x0);
+
+ ath79_init_mac(ath79_eth0_data.mac_addr, cal_data, 0);
+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
+ ath79_eth0_data.speed = SPEED_100;
+ ath79_eth0_data.duplex = DUPLEX_FULL;
+ ath79_eth0_data.has_ar8216 = 1;
+
+ ath79_init_mac(ath79_eth1_data.mac_addr, cal_data, 1);
+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RMII;
+ ath79_eth1_data.phy_mask = 0x10;
+
+ ath79_register_eth(0);
+ ath79_register_eth(1);
}
MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board",
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -30,9 +30,10 @@ config ATH79_MACH_AP136
config ATH79_MACH_AP81
bool "Atheros AP81 reference board"
select SOC_AR913X
+ select ATH79_DEV_ETH
select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO
- select ATH79_DEV_SPI
+ select ATH79_DEV_M25P80
select ATH79_DEV_USB
select ATH79_DEV_WMAC
help

View File

@ -0,0 +1,204 @@
--- a/arch/mips/ath79/mach-db120.c
+++ b/arch/mips/ath79/mach-db120.c
@@ -2,7 +2,7 @@
* Atheros DB120 reference board support
*
* Copyright (c) 2011 Qualcomm Atheros
- * Copyright (c) 2011 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (c) 2011-2012 Gabor Juhos <juhosg@openwrt.org>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
@@ -19,16 +19,26 @@
*/
#include <linux/pci.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
#include <linux/ath9k_platform.h>
+#include <linux/ar8216_platform.h>
-#include "machtypes.h"
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+#include "common.h"
+#include "dev-ap9x-pci.h"
+#include "dev-eth.h"
#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
+#include "dev-m25p80.h"
+#include "dev-nfc.h"
#include "dev-spi.h"
#include "dev-usb.h"
#include "dev-wmac.h"
-#include "pci.h"
+#include "machtypes.h"
+#define DB120_GPIO_LED_USB 11
#define DB120_GPIO_LED_WLAN_5G 12
#define DB120_GPIO_LED_WLAN_2G 13
#define DB120_GPIO_LED_STATUS 14
@@ -39,8 +49,10 @@
#define DB120_KEYS_POLL_INTERVAL 20 /* msecs */
#define DB120_KEYS_DEBOUNCE_INTERVAL (3 * DB120_KEYS_POLL_INTERVAL)
-#define DB120_WMAC_CALDATA_OFFSET 0x1000
-#define DB120_PCIE_CALDATA_OFFSET 0x5000
+#define DB120_MAC0_OFFSET 0
+#define DB120_MAC1_OFFSET 6
+#define DB120_WMAC_CALDATA_OFFSET 0x1000
+#define DB120_PCIE_CALDATA_OFFSET 0x5000
static struct gpio_led db120_leds_gpio[] __initdata = {
{
@@ -63,6 +75,11 @@ static struct gpio_led db120_leds_gpio[]
.gpio = DB120_GPIO_LED_WLAN_2G,
.active_low = 1,
},
+ {
+ .name = "db120:green:usb",
+ .gpio = DB120_GPIO_LED_USB,
+ .active_low = 1,
+ }
};
static struct gpio_keys_button db120_gpio_keys[] __initdata = {
@@ -76,60 +93,85 @@ static struct gpio_keys_button db120_gpi
},
};
-static struct spi_board_info db120_spi_info[] = {
- {
- .bus_num = 0,
- .chip_select = 0,
- .max_speed_hz = 25000000,
- .modalias = "s25sl064a",
- }
+static struct ar8327_pad_cfg db120_ar8327_pad0_cfg = {
+ .mode = AR8327_PAD_MAC_RGMII,
+ .txclk_delay_en = true,
+ .rxclk_delay_en = true,
+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1,
+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2,
};
-static struct ath79_spi_platform_data db120_spi_data = {
- .bus_num = 0,
- .num_chipselect = 1,
+static struct ar8327_led_cfg db120_ar8327_led_cfg = {
+ .led_ctrl0 = 0x00000000,
+ .led_ctrl1 = 0xc737c737,
+ .led_ctrl2 = 0x00000000,
+ .led_ctrl3 = 0x00c30c00,
+ .open_drain = true,
};
-#ifdef CONFIG_PCI
-static struct ath9k_platform_data db120_ath9k_data;
-
-static int db120_pci_plat_dev_init(struct pci_dev *dev)
-{
- switch (PCI_SLOT(dev->devfn)) {
- case 0:
- dev->dev.platform_data = &db120_ath9k_data;
- break;
- }
-
- return 0;
-}
-
-static void __init db120_pci_init(u8 *eeprom)
-{
- memcpy(db120_ath9k_data.eeprom_data, eeprom,
- sizeof(db120_ath9k_data.eeprom_data));
+static struct ar8327_platform_data db120_ar8327_data = {
+ .pad0_cfg = &db120_ar8327_pad0_cfg,
+ .port0_cfg = {
+ .force_link = 1,
+ .speed = AR8327_PORT_SPEED_1000,
+ .duplex = 1,
+ .txpause = 1,
+ .rxpause = 1,
+ },
+ .led_cfg = &db120_ar8327_led_cfg,
+};
- ath79_pci_set_plat_dev_init(db120_pci_plat_dev_init);
- ath79_register_pci();
-}
-#else
-static inline void db120_pci_init(u8 *eeprom) {}
-#endif /* CONFIG_PCI */
+static struct mdio_board_info db120_mdio0_info[] = {
+ {
+ .bus_id = "ag71xx-mdio.0",
+ .phy_addr = 0,
+ .platform_data = &db120_ar8327_data,
+ },
+};
static void __init db120_setup(void)
{
u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
+ ath79_gpio_output_select(DB120_GPIO_LED_USB, AR934X_GPIO_OUT_GPIO);
+ ath79_register_m25p80(NULL);
+
ath79_register_leds_gpio(-1, ARRAY_SIZE(db120_leds_gpio),
db120_leds_gpio);
ath79_register_gpio_keys_polled(-1, DB120_KEYS_POLL_INTERVAL,
ARRAY_SIZE(db120_gpio_keys),
db120_gpio_keys);
- ath79_register_spi(&db120_spi_data, db120_spi_info,
- ARRAY_SIZE(db120_spi_info));
ath79_register_usb();
ath79_register_wmac(art + DB120_WMAC_CALDATA_OFFSET, NULL);
- db120_pci_init(art + DB120_PCIE_CALDATA_OFFSET);
+ ap91_pci_init(art + DB120_PCIE_CALDATA_OFFSET, NULL);
+
+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0 |
+ AR934X_ETH_CFG_SW_ONLY_MODE);
+
+ ath79_register_mdio(1, 0x0);
+ ath79_register_mdio(0, 0x0);
+
+ ath79_init_mac(ath79_eth0_data.mac_addr, art + DB120_MAC0_OFFSET, 0);
+
+ mdiobus_register_board_info(db120_mdio0_info,
+ ARRAY_SIZE(db120_mdio0_info));
+
+ /* GMAC0 is connected to an AR8327 switch */
+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
+ ath79_eth0_data.phy_mask = BIT(0);
+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev;
+ ath79_eth0_pll_data.pll_1000 = 0x06000000;
+ ath79_register_eth(0);
+
+ /* GMAC1 is connected to the internal switch */
+ ath79_init_mac(ath79_eth1_data.mac_addr, art + DB120_MAC1_OFFSET, 0);
+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII;
+ ath79_eth1_data.speed = SPEED_1000;
+ ath79_eth1_data.duplex = DUPLEX_FULL;
+
+ ath79_register_eth(1);
+
+ ath79_register_nfc();
}
MIPS_MACHINE(ATH79_MACH_DB120, "DB120", "Atheros DB120 reference board",
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -43,9 +43,12 @@ config ATH79_MACH_AP81
config ATH79_MACH_DB120
bool "Atheros DB120 reference board"
select SOC_AR934X
+ select ATH79_DEV_AP9X_PCI if PCI
+ select ATH79_DEV_ETH
select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO
- select ATH79_DEV_SPI
+ select ATH79_DEV_M25P80
+ select ATH79_DEV_NFC
select ATH79_DEV_USB
select ATH79_DEV_WMAC
help

View File

@ -0,0 +1,153 @@
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -8,23 +8,48 @@
* by the Free Software Foundation.
*/
+#include <linux/delay.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/i2c-gpio.h>
#include <linux/i2c/pcf857x.h>
+#include <linux/i2c/pcf857x.h>
+#include <linux/spi/flash.h>
+#include <linux/spi/vsc7385.h>
-#include "machtypes.h"
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79.h>
+
+#include "dev-eth.h"
#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
#include "dev-spi.h"
#include "dev-usb.h"
+#include "machtypes.h"
#include "pci.h"
#define PB44_GPIO_I2C_SCL 0
#define PB44_GPIO_I2C_SDA 1
+#define PB44_PCF8757_VSC7395_CS 0
+#define PB44_PCF8757_STEREO_CS 1
+#define PB44_PCF8757_SLIC_CS0 2
+#define PB44_PCF8757_SLIC_TEST 3
+#define PB44_PCF8757_SLIC_INT0 4
+#define PB44_PCF8757_SLIC_INT1 5
+#define PB44_PCF8757_SW_RESET 6
+#define PB44_PCF8757_SW_JUMP 8
+#define PB44_PCF8757_LED_JUMP1 9
+#define PB44_PCF8757_LED_JUMP2 10
+#define PB44_PCF8757_TP24 11
+#define PB44_PCF8757_TP25 12
+#define PB44_PCF8757_TP26 13
+#define PB44_PCF8757_TP27 14
+#define PB44_PCF8757_TP28 15
+
#define PB44_GPIO_EXP_BASE 16
+#define PB44_GPIO_VSC7395_CS (PB44_GPIO_EXP_BASE + PB44_PCF8757_VSC7395_CS)
#define PB44_GPIO_SW_RESET (PB44_GPIO_EXP_BASE + 6)
#define PB44_GPIO_SW_JUMP (PB44_GPIO_EXP_BASE + 8)
#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + 9)
@@ -92,21 +117,66 @@ static struct ath79_spi_controller_data
.cs_line = 0,
};
+static struct ath79_spi_controller_data pb44_spi1_data = {
+ .cs_type = ATH79_SPI_CS_TYPE_GPIO,
+ .cs_line = PB44_GPIO_VSC7395_CS,
+};
+
+static void pb44_vsc7395_reset(void)
+{
+ ath79_device_reset_set(AR71XX_RESET_GE1_PHY);
+ udelay(10);
+ ath79_device_reset_clear(AR71XX_RESET_GE1_PHY);
+ mdelay(50);
+}
+
+static struct vsc7385_platform_data pb44_vsc7395_data = {
+ .reset = pb44_vsc7395_reset,
+ .ucode_name = "vsc7395_ucode_pb44.bin",
+ .mac_cfg = {
+ .tx_ipg = 6,
+ .bit2 = 1,
+ .clk_sel = 0,
+ },
+};
+
+static const char *pb44_part_probes[] = {
+ "RedBoot",
+ NULL,
+};
+
+static struct flash_platform_data pb44_flash_data = {
+ .part_probes = pb44_part_probes,
+};
+
static struct spi_board_info pb44_spi_info[] = {
{
.bus_num = 0,
.chip_select = 0,
.max_speed_hz = 25000000,
.modalias = "m25p64",
+ .platform_data = &pb44_flash_data,
.controller_data = &pb44_spi0_data,
},
+ {
+ .bus_num = 0,
+ .chip_select = 1,
+ .max_speed_hz = 25000000,
+ .modalias = "spi-vsc7385",
+ .platform_data = &pb44_vsc7395_data,
+ .controller_data = &pb44_spi1_data,
+ }
};
static struct ath79_spi_platform_data pb44_spi_data = {
.bus_num = 0,
- .num_chipselect = 1,
+ .num_chipselect = 2,
};
+#define PB44_WAN_PHYMASK BIT(0)
+#define PB44_LAN_PHYMASK 0
+#define PB44_MDIO_PHYMASK (PB44_LAN_PHYMASK | PB44_WAN_PHYMASK)
+
static void __init pb44_init(void)
{
i2c_register_board_info(0, pb44_i2c_board_info,
@@ -122,6 +192,22 @@ static void __init pb44_init(void)
ARRAY_SIZE(pb44_spi_info));
ath79_register_usb();
ath79_register_pci();
+
+ ath79_register_mdio(0, ~PB44_MDIO_PHYMASK);
+
+ ath79_init_mac(ath79_eth0_data.mac_addr, ath79_mac_base, 0);
+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
+ ath79_eth0_data.phy_mask = PB44_WAN_PHYMASK;
+
+ ath79_register_eth(0);
+
+ ath79_init_mac(ath79_eth1_data.mac_addr, ath79_mac_base, 1);
+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
+ ath79_eth1_data.speed = SPEED_1000;
+ ath79_eth1_data.duplex = DUPLEX_FULL;
+ ath79_eth1_pll_data.pll_1000 = 0x110000;
+
+ ath79_register_eth(1);
}
MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -58,6 +58,7 @@ config ATH79_MACH_DB120
config ATH79_MACH_PB44
bool "Atheros PB44 reference board"
select SOC_AR71XX
+ select ATH79_DEV_ETH
select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO
select ATH79_DEV_SPI

View File

@ -0,0 +1,103 @@
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -70,9 +70,10 @@ config ATH79_MACH_PB44
config ATH79_MACH_UBNT_XM
bool "Ubiquiti Networks XM (rev 1.0) board"
select SOC_AR724X
+ select ATH79_DEV_AP9X_PCI if PCI
select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO
- select ATH79_DEV_SPI
+ select ATH79_DEV_M25P80
help
Say 'Y' here if you want your kernel to support the
Ubiquiti Networks XM (rev 1.0) board.
--- a/arch/mips/ath79/mach-ubnt-xm.c
+++ b/arch/mips/ath79/mach-ubnt-xm.c
@@ -16,10 +16,11 @@
#include <asm/mach-ath79/irq.h>
-#include "machtypes.h"
+#include "dev-ap9x-pci.h"
#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
-#include "dev-spi.h"
+#include "dev-m25p80.h"
+#include "machtypes.h"
#include "pci.h"
#define UBNT_XM_GPIO_LED_L1 0
@@ -32,7 +33,7 @@
#define UBNT_XM_KEYS_POLL_INTERVAL 20
#define UBNT_XM_KEYS_DEBOUNCE_INTERVAL (3 * UBNT_XM_KEYS_POLL_INTERVAL)
-#define UBNT_XM_EEPROM_ADDR (u8 *) KSEG1ADDR(0x1fff1000)
+#define UBNT_XM_EEPROM_ADDR 0x1fff1000
static struct gpio_led ubnt_xm_leds_gpio[] __initdata = {
{
@@ -65,48 +66,10 @@ static struct gpio_keys_button ubnt_xm_g
}
};
-static struct spi_board_info ubnt_xm_spi_info[] = {
- {
- .bus_num = 0,
- .chip_select = 0,
- .max_speed_hz = 25000000,
- .modalias = "mx25l6405d",
- }
-};
-
-static struct ath79_spi_platform_data ubnt_xm_spi_data = {
- .bus_num = 0,
- .num_chipselect = 1,
-};
-
-#ifdef CONFIG_PCI
-static struct ath9k_platform_data ubnt_xm_eeprom_data;
-
-static int ubnt_xm_pci_plat_dev_init(struct pci_dev *dev)
-{
- switch (PCI_SLOT(dev->devfn)) {
- case 0:
- dev->dev.platform_data = &ubnt_xm_eeprom_data;
- break;
- }
-
- return 0;
-}
-
-static void __init ubnt_xm_pci_init(void)
-{
- memcpy(ubnt_xm_eeprom_data.eeprom_data, UBNT_XM_EEPROM_ADDR,
- sizeof(ubnt_xm_eeprom_data.eeprom_data));
-
- ath79_pci_set_plat_dev_init(ubnt_xm_pci_plat_dev_init);
- ath79_register_pci();
-}
-#else
-static inline void ubnt_xm_pci_init(void) {}
-#endif /* CONFIG_PCI */
-
static void __init ubnt_xm_init(void)
{
+ u8 *eeprom = (u8 *) KSEG1ADDR(UBNT_XM_EEPROM_ADDR);
+
ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xm_leds_gpio),
ubnt_xm_leds_gpio);
@@ -114,10 +77,8 @@ static void __init ubnt_xm_init(void)
ARRAY_SIZE(ubnt_xm_gpio_keys),
ubnt_xm_gpio_keys);
- ath79_register_spi(&ubnt_xm_spi_data, ubnt_xm_spi_info,
- ARRAY_SIZE(ubnt_xm_spi_info));
-
- ubnt_xm_pci_init();
+ ath79_register_m25p80(NULL);
+ ap91_pci_init(eeprom, NULL);
}
MIPS_MACHINE(ATH79_MACH_UBNT_XM,

View File

@ -0,0 +1,531 @@
--- a/arch/mips/ath79/mach-ubnt-xm.c
+++ b/arch/mips/ath79/mach-ubnt-xm.c
@@ -12,16 +12,24 @@
#include <linux/init.h>
#include <linux/pci.h>
+#include <linux/platform_device.h>
#include <linux/ath9k_platform.h>
+#include <linux/etherdevice.h>
+#include <linux/ar8216_platform.h>
+#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/irq.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
#include "dev-ap9x-pci.h"
+#include "dev-eth.h"
#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
#include "dev-m25p80.h"
+#include "dev-usb.h"
+#include "dev-wmac.h"
#include "machtypes.h"
-#include "pci.h"
#define UBNT_XM_GPIO_LED_L1 0
#define UBNT_XM_GPIO_LED_L2 1
@@ -37,19 +45,19 @@
static struct gpio_led ubnt_xm_leds_gpio[] __initdata = {
{
- .name = "ubnt-xm:red:link1",
+ .name = "ubnt:red:link1",
.gpio = UBNT_XM_GPIO_LED_L1,
.active_low = 0,
}, {
- .name = "ubnt-xm:orange:link2",
+ .name = "ubnt:orange:link2",
.gpio = UBNT_XM_GPIO_LED_L2,
.active_low = 0,
}, {
- .name = "ubnt-xm:green:link3",
+ .name = "ubnt:green:link3",
.gpio = UBNT_XM_GPIO_LED_L3,
.active_low = 0,
}, {
- .name = "ubnt-xm:green:link4",
+ .name = "ubnt:green:link4",
.gpio = UBNT_XM_GPIO_LED_L4,
.active_low = 0,
},
@@ -66,9 +74,13 @@ static struct gpio_keys_button ubnt_xm_g
}
};
+#define UBNT_M_WAN_PHYMASK BIT(4)
+
static void __init ubnt_xm_init(void)
{
u8 *eeprom = (u8 *) KSEG1ADDR(UBNT_XM_EEPROM_ADDR);
+ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000);
+ u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN);
ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xm_leds_gpio),
ubnt_xm_leds_gpio);
@@ -79,9 +91,428 @@ static void __init ubnt_xm_init(void)
ath79_register_m25p80(NULL);
ap91_pci_init(eeprom, NULL);
+
+ ath79_register_mdio(0, ~UBNT_M_WAN_PHYMASK);
+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0);
+ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0);
+ ath79_register_eth(0);
}
MIPS_MACHINE(ATH79_MACH_UBNT_XM,
"UBNT-XM",
"Ubiquiti Networks XM (rev 1.0) board",
ubnt_xm_init);
+
+MIPS_MACHINE(ATH79_MACH_UBNT_BULLET_M, "UBNT-BM", "Ubiquiti Bullet M",
+ ubnt_xm_init);
+
+static void __init ubnt_rocket_m_setup(void)
+{
+ ubnt_xm_init();
+ ath79_register_usb();
+}
+
+MIPS_MACHINE(ATH79_MACH_UBNT_ROCKET_M, "UBNT-RM", "Ubiquiti Rocket M",
+ ubnt_rocket_m_setup);
+
+static void __init ubnt_nano_m_setup(void)
+{
+ ubnt_xm_init();
+ ath79_register_eth(1);
+}
+
+MIPS_MACHINE(ATH79_MACH_UBNT_NANO_M, "UBNT-NM", "Ubiquiti Nanostation M",
+ ubnt_nano_m_setup);
+
+static struct gpio_led ubnt_airrouter_leds_gpio[] __initdata = {
+ {
+ .name = "ubnt:green:globe",
+ .gpio = 0,
+ .active_low = 1,
+ }, {
+ .name = "ubnt:green:power",
+ .gpio = 11,
+ .active_low = 1,
+ .default_state = LEDS_GPIO_DEFSTATE_ON,
+ }
+};
+
+static void __init ubnt_airrouter_setup(void)
+{
+ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000);
+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
+
+ ath79_register_m25p80(NULL);
+ ath79_register_mdio(0, ~UBNT_M_WAN_PHYMASK);
+
+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0);
+ ath79_init_local_mac(ath79_eth1_data.mac_addr, mac1);
+
+ ath79_register_eth(1);
+ ath79_register_eth(0);
+ ath79_register_usb();
+
+ ap91_pci_init(ee, NULL);
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_airrouter_leds_gpio),
+ ubnt_airrouter_leds_gpio);
+
+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(ubnt_xm_gpio_keys),
+ ubnt_xm_gpio_keys);
+}
+
+MIPS_MACHINE(ATH79_MACH_UBNT_AIRROUTER, "UBNT-AR", "Ubiquiti AirRouter",
+ ubnt_airrouter_setup);
+
+static struct gpio_led ubnt_unifi_leds_gpio[] __initdata = {
+ {
+ .name = "ubnt:orange:dome",
+ .gpio = 1,
+ .active_low = 0,
+ }, {
+ .name = "ubnt:green:dome",
+ .gpio = 0,
+ .active_low = 0,
+ }
+};
+
+static struct gpio_led ubnt_unifi_outdoor_leds_gpio[] __initdata = {
+ {
+ .name = "ubnt:orange:front",
+ .gpio = 1,
+ .active_low = 0,
+ }, {
+ .name = "ubnt:green:front",
+ .gpio = 0,
+ .active_low = 0,
+ }
+};
+
+static struct gpio_led ubnt_unifi_outdoor_plus_leds_gpio[] __initdata = {
+ {
+ .name = "ubnt:white:front",
+ .gpio = 1,
+ .active_low = 0,
+ }, {
+ .name = "ubnt:blue:front",
+ .gpio = 0,
+ .active_low = 0,
+ }
+};
+
+
+static void __init ubnt_unifi_setup(void)
+{
+ u8 *mac = (u8 *) KSEG1ADDR(0x1fff0000);
+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
+
+ ath79_register_m25p80(NULL);
+
+ ath79_register_mdio(0, ~UBNT_M_WAN_PHYMASK);
+
+ ath79_init_mac(ath79_eth0_data.mac_addr, mac, 0);
+ ath79_register_eth(0);
+
+ ap91_pci_init(ee, NULL);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_unifi_leds_gpio),
+ ubnt_unifi_leds_gpio);
+
+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(ubnt_xm_gpio_keys),
+ ubnt_xm_gpio_keys);
+}
+
+MIPS_MACHINE(ATH79_MACH_UBNT_UNIFI, "UBNT-UF", "Ubiquiti UniFi",
+ ubnt_unifi_setup);
+
+
+#define UBNT_UNIFIOD_PRI_PHYMASK BIT(4)
+#define UBNT_UNIFIOD_2ND_PHYMASK (BIT(0) | BIT(1) | BIT(2) | BIT(3))
+
+static void __init ubnt_unifi_outdoor_setup(void)
+{
+ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000);
+ u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN);
+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
+
+ ath79_register_m25p80(NULL);
+
+ ath79_register_mdio(0, ~(UBNT_UNIFIOD_PRI_PHYMASK |
+ UBNT_UNIFIOD_2ND_PHYMASK));
+
+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0);
+ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0);
+ ath79_register_eth(0);
+ ath79_register_eth(1);
+
+ ap91_pci_init(ee, NULL);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_unifi_outdoor_leds_gpio),
+ ubnt_unifi_outdoor_leds_gpio);
+
+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(ubnt_xm_gpio_keys),
+ ubnt_xm_gpio_keys);
+}
+
+MIPS_MACHINE(ATH79_MACH_UBNT_UNIFI_OUTDOOR, "UBNT-U20",
+ "Ubiquiti UniFiAP Outdoor",
+ ubnt_unifi_outdoor_setup);
+
+
+static void __init ubnt_unifi_outdoor_plus_setup(void)
+{
+ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000);
+ u8 *mac2 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN);
+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
+
+ ath79_register_m25p80(NULL);
+
+ ath79_register_mdio(0, ~(UBNT_UNIFIOD_PRI_PHYMASK |
+ UBNT_UNIFIOD_2ND_PHYMASK));
+
+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0);
+ ath79_init_mac(ath79_eth1_data.mac_addr, mac2, 0);
+ ath79_register_eth(0);
+ ath79_register_eth(1);
+
+ ap91_pci_init(ee, NULL);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_unifi_outdoor_plus_leds_gpio),
+ ubnt_unifi_outdoor_plus_leds_gpio);
+
+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(ubnt_xm_gpio_keys),
+ ubnt_xm_gpio_keys);
+}
+
+MIPS_MACHINE(ATH79_MACH_UBNT_UNIFI_OUTDOOR_PLUS, "UBNT-UOP",
+ "Ubiquiti UniFiAP Outdoor+",
+ ubnt_unifi_outdoor_plus_setup);
+
+
+static struct gpio_led ubnt_uap_pro_gpio_leds[] __initdata = {
+ {
+ .name = "ubnt:white:dome",
+ .gpio = 12,
+ }, {
+ .name = "ubnt:blue:dome",
+ .gpio = 13,
+ }
+};
+
+static struct gpio_keys_button uap_pro_gpio_keys[] __initdata = {
+ {
+ .desc = "reset",
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .debounce_interval = UBNT_XM_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = 17,
+ .active_low = 1,
+ }
+};
+
+static struct ar8327_pad_cfg uap_pro_ar8327_pad0_cfg = {
+ .mode = AR8327_PAD_MAC_RGMII,
+ .txclk_delay_en = true,
+ .rxclk_delay_en = true,
+ .txclk_delay_sel = AR8327_CLK_DELAY_SEL1,
+ .rxclk_delay_sel = AR8327_CLK_DELAY_SEL2,
+};
+
+static struct ar8327_platform_data uap_pro_ar8327_data = {
+ .pad0_cfg = &uap_pro_ar8327_pad0_cfg,
+ .port0_cfg = {
+ .force_link = 1,
+ .speed = AR8327_PORT_SPEED_1000,
+ .duplex = 1,
+ .txpause = 1,
+ .rxpause = 1,
+ },
+};
+
+static struct mdio_board_info uap_pro_mdio0_info[] = {
+ {
+ .bus_id = "ag71xx-mdio.0",
+ .phy_addr = 0,
+ .platform_data = &uap_pro_ar8327_data,
+ },
+};
+
+#define UAP_PRO_MAC0_OFFSET 0x0000
+#define UAP_PRO_MAC1_OFFSET 0x0006
+#define UAP_PRO_WMAC_CALDATA_OFFSET 0x1000
+#define UAP_PRO_PCI_CALDATA_OFFSET 0x5000
+
+static void __init ubnt_uap_pro_setup(void)
+{
+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000);
+
+ ath79_register_m25p80(NULL);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_uap_pro_gpio_leds),
+ ubnt_uap_pro_gpio_leds);
+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(uap_pro_gpio_keys),
+ uap_pro_gpio_keys);
+
+ ath79_register_wmac(eeprom + UAP_PRO_WMAC_CALDATA_OFFSET, NULL);
+ ap91_pci_init(eeprom + UAP_PRO_PCI_CALDATA_OFFSET, NULL);
+
+ ath79_register_mdio(0, 0x0);
+ mdiobus_register_board_info(uap_pro_mdio0_info,
+ ARRAY_SIZE(uap_pro_mdio0_info));
+
+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0);
+ ath79_init_mac(ath79_eth0_data.mac_addr,
+ eeprom + UAP_PRO_MAC0_OFFSET, 0);
+
+ /* GMAC0 is connected to an AR8327 switch */
+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
+ ath79_eth0_data.phy_mask = BIT(0);
+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev;
+ ath79_eth0_pll_data.pll_1000 = 0x06000000;
+ ath79_register_eth(0);
+}
+
+MIPS_MACHINE(ATH79_MACH_UBNT_UAP_PRO, "UAP-PRO", "Ubiquiti UniFi AP Pro",
+ ubnt_uap_pro_setup);
+
+#define UBNT_XW_GPIO_LED_L1 11
+#define UBNT_XW_GPIO_LED_L2 16
+#define UBNT_XW_GPIO_LED_L3 13
+#define UBNT_XW_GPIO_LED_L4 14
+
+static struct gpio_led ubnt_xw_leds_gpio[] __initdata = {
+ {
+ .name = "ubnt:red:link1",
+ .gpio = UBNT_XW_GPIO_LED_L1,
+ .active_low = 1,
+ }, {
+ .name = "ubnt:orange:link2",
+ .gpio = UBNT_XW_GPIO_LED_L2,
+ .active_low = 1,
+ }, {
+ .name = "ubnt:green:link3",
+ .gpio = UBNT_XW_GPIO_LED_L3,
+ .active_low = 1,
+ }, {
+ .name = "ubnt:green:link4",
+ .gpio = UBNT_XW_GPIO_LED_L4,
+ .active_low = 1,
+ },
+};
+
+static void __init ubnt_xw_init(void)
+{
+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000);
+
+ ath79_register_m25p80(NULL);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xw_leds_gpio),
+ ubnt_xw_leds_gpio);
+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(ubnt_xm_gpio_keys),
+ ubnt_xm_gpio_keys);
+
+ ath79_register_wmac(eeprom + UAP_PRO_WMAC_CALDATA_OFFSET, NULL);
+ ap91_pci_init(eeprom + UAP_PRO_PCI_CALDATA_OFFSET, NULL);
+
+
+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_MII_GMAC0 | AR934X_ETH_CFG_MII_GMAC0_SLAVE);
+ ath79_init_mac(ath79_eth0_data.mac_addr,
+ eeprom + UAP_PRO_MAC0_OFFSET, 0);
+
+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_MII;
+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev;
+}
+
+static void __init ubnt_nano_m_xw_setup(void)
+{
+ ubnt_xw_init();
+
+ /* GMAC0 is connected to an AR8326 switch */
+ ath79_register_mdio(0, ~(BIT(0) | BIT(1) | BIT(5)));
+ ath79_eth0_data.phy_mask = (BIT(0) | BIT(1) | BIT(5));
+ ath79_eth0_data.speed = SPEED_100;
+ ath79_eth0_data.duplex = DUPLEX_FULL;
+ ath79_register_eth(0);
+}
+
+static void __init ubnt_loco_m_xw_setup(void)
+{
+ ubnt_xw_init();
+
+ ath79_register_mdio(0, ~BIT(1));
+ ath79_eth0_data.phy_mask = BIT(1);
+ ath79_register_eth(0);
+}
+
+MIPS_MACHINE(ATH79_MACH_UBNT_NANO_M_XW, "UBNT-NM-XW", "Ubiquiti Nanostation M XW",
+ ubnt_nano_m_xw_setup);
+
+MIPS_MACHINE(ATH79_MACH_UBNT_LOCO_M_XW, "UBNT-LOCO-XW", "Ubiquiti Loco M XW",
+ ubnt_loco_m_xw_setup);
+
+static struct gpio_led ubnt_airgateway_gpio_leds[] __initdata = {
+ {
+ .name = "ubnt:blue:wlan",
+ .gpio = 0,
+ }, {
+ .name = "ubnt:white:status",
+ .gpio = 1,
+ },
+};
+
+static struct gpio_keys_button airgateway_gpio_keys[] __initdata = {
+ {
+ .desc = "reset",
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .debounce_interval = UBNT_XM_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = 12,
+ .active_low = 1,
+ }
+};
+
+static void __init ubnt_airgateway_setup(void)
+{
+ u32 t;
+ u8 *mac0 = (u8 *) KSEG1ADDR(0x1fff0000);
+ u8 *mac1 = (u8 *) KSEG1ADDR(0x1fff0000 + ETH_ALEN);
+ u8 *ee = (u8 *) KSEG1ADDR(0x1fff1000);
+
+
+ ath79_gpio_function_disable(AR933X_GPIO_FUNC_ETH_SWITCH_LED0_EN |
+ AR933X_GPIO_FUNC_ETH_SWITCH_LED1_EN |
+ AR933X_GPIO_FUNC_ETH_SWITCH_LED2_EN |
+ AR933X_GPIO_FUNC_ETH_SWITCH_LED3_EN |
+ AR933X_GPIO_FUNC_ETH_SWITCH_LED4_EN);
+
+ t = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
+ t |= AR933X_BOOTSTRAP_MDIO_GPIO_EN;
+ ath79_reset_wr(AR933X_RESET_REG_BOOTSTRAP, t);
+
+ ath79_register_m25p80(NULL);
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_airgateway_gpio_leds),
+ ubnt_airgateway_gpio_leds);
+
+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(airgateway_gpio_keys),
+ airgateway_gpio_keys);
+
+ ath79_init_mac(ath79_eth1_data.mac_addr, mac0, 0);
+ ath79_init_mac(ath79_eth0_data.mac_addr, mac1, 0);
+
+ ath79_register_mdio(0, 0x0);
+
+ ath79_register_eth(1);
+ ath79_register_eth(0);
+
+ ath79_register_wmac(ee, NULL);
+}
+
+MIPS_MACHINE(ATH79_MACH_UBNT_AIRGW, "UBNT-AGW", "Ubiquiti AirGateway",
+ ubnt_airgateway_setup);
+
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -68,12 +68,16 @@ config ATH79_MACH_PB44
Atheros PB44 reference board.
config ATH79_MACH_UBNT_XM
- bool "Ubiquiti Networks XM (rev 1.0) board"
+ bool "Ubiquiti Networks XM/UniFi boards"
select SOC_AR724X
+ select SOC_AR934X
select ATH79_DEV_AP9X_PCI if PCI
+ select ATH79_DEV_ETH
select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO
select ATH79_DEV_M25P80
+ select ATH79_DEV_USB
+ select ATH79_DEV_WMAC
help
Say 'Y' here if you want your kernel to support the
Ubiquiti Networks XM (rev 1.0) board.
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -22,6 +22,13 @@ enum ath79_mach_type {
ATH79_MACH_AP81, /* Atheros AP81 reference board */
ATH79_MACH_DB120, /* Atheros DB120 reference board */
ATH79_MACH_PB44, /* Atheros PB44 reference board */
+ ATH79_MACH_UBNT_AIRROUTER, /* Ubiquiti AirRouter */
+ ATH79_MACH_UBNT_BULLET_M, /* Ubiquiti Bullet M */
+ ATH79_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */
+ ATH79_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */
+ ATH79_MACH_UBNT_UAP_PRO, /* Ubiquiti UniFi AP Pro */
+ ATH79_MACH_UBNT_UNIFI, /* Ubiquiti Unifi */
+ ATH79_MACH_UBNT_UNIFI_OUTDOOR, /* Ubiquiti UnifiAP Outdoor */
ATH79_MACH_UBNT_XM, /* Ubiquiti Networks XM board rev 1.0 */
};

View File

@ -0,0 +1,312 @@
--- a/arch/mips/ath79/mach-ap136.c
+++ b/arch/mips/ath79/mach-ap136.c
@@ -18,23 +18,29 @@
*
*/
-#include <linux/pci.h>
-#include <linux/ath9k_platform.h>
+#include <linux/platform_device.h>
+#include <linux/ar8216_platform.h>
-#include "machtypes.h"
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+#include "common.h"
+#include "pci.h"
+#include "dev-ap9x-pci.h"
#include "dev-gpio-buttons.h"
+#include "dev-eth.h"
#include "dev-leds-gpio.h"
-#include "dev-spi.h"
+#include "dev-m25p80.h"
+#include "dev-nfc.h"
#include "dev-usb.h"
#include "dev-wmac.h"
-#include "pci.h"
+#include "machtypes.h"
-#define AP136_GPIO_LED_STATUS_RED 14
-#define AP136_GPIO_LED_STATUS_GREEN 19
#define AP136_GPIO_LED_USB 4
-#define AP136_GPIO_LED_WLAN_2G 13
#define AP136_GPIO_LED_WLAN_5G 12
+#define AP136_GPIO_LED_WLAN_2G 13
+#define AP136_GPIO_LED_STATUS_RED 14
#define AP136_GPIO_LED_WPS_RED 15
+#define AP136_GPIO_LED_STATUS_GREEN 19
#define AP136_GPIO_LED_WPS_GREEN 20
#define AP136_GPIO_BTN_WPS 16
@@ -43,37 +49,39 @@
#define AP136_KEYS_POLL_INTERVAL 20 /* msecs */
#define AP136_KEYS_DEBOUNCE_INTERVAL (3 * AP136_KEYS_POLL_INTERVAL)
-#define AP136_WMAC_CALDATA_OFFSET 0x1000
-#define AP136_PCIE_CALDATA_OFFSET 0x5000
+#define AP136_MAC0_OFFSET 0
+#define AP136_MAC1_OFFSET 6
+#define AP136_WMAC_CALDATA_OFFSET 0x1000
+#define AP136_PCIE_CALDATA_OFFSET 0x5000
static struct gpio_led ap136_leds_gpio[] __initdata = {
{
- .name = "qca:green:status",
+ .name = "ap136:green:status",
.gpio = AP136_GPIO_LED_STATUS_GREEN,
.active_low = 1,
},
{
- .name = "qca:red:status",
+ .name = "ap136:red:status",
.gpio = AP136_GPIO_LED_STATUS_RED,
.active_low = 1,
},
{
- .name = "qca:green:wps",
+ .name = "ap136:green:wps",
.gpio = AP136_GPIO_LED_WPS_GREEN,
.active_low = 1,
},
{
- .name = "qca:red:wps",
+ .name = "ap136:red:wps",
.gpio = AP136_GPIO_LED_WPS_RED,
.active_low = 1,
},
{
- .name = "qca:red:wlan-2g",
+ .name = "ap136:red:wlan-2g",
.gpio = AP136_GPIO_LED_WLAN_2G,
.active_low = 1,
},
{
- .name = "qca:red:usb",
+ .name = "ap136:red:usb",
.gpio = AP136_GPIO_LED_USB,
.active_low = 1,
}
@@ -98,59 +106,151 @@ static struct gpio_keys_button ap136_gpi
},
};
-static struct spi_board_info ap136_spi_info[] = {
- {
- .bus_num = 0,
- .chip_select = 0,
- .max_speed_hz = 25000000,
- .modalias = "mx25l6405d",
- }
+static struct ar8327_pad_cfg ap136_ar8327_pad0_cfg;
+static struct ar8327_pad_cfg ap136_ar8327_pad6_cfg;
+
+static struct ar8327_platform_data ap136_ar8327_data = {
+ .pad0_cfg = &ap136_ar8327_pad0_cfg,
+ .pad6_cfg = &ap136_ar8327_pad6_cfg,
+ .port0_cfg = {
+ .force_link = 1,
+ .speed = AR8327_PORT_SPEED_1000,
+ .duplex = 1,
+ .txpause = 1,
+ .rxpause = 1,
+ },
+ .port6_cfg = {
+ .force_link = 1,
+ .speed = AR8327_PORT_SPEED_1000,
+ .duplex = 1,
+ .txpause = 1,
+ .rxpause = 1,
+ },
};
-static struct ath79_spi_platform_data ap136_spi_data = {
- .bus_num = 0,
- .num_chipselect = 1,
+static struct mdio_board_info ap136_mdio0_info[] = {
+ {
+ .bus_id = "ag71xx-mdio.0",
+ .phy_addr = 0,
+ .platform_data = &ap136_ar8327_data,
+ },
};
-#ifdef CONFIG_PCI
-static struct ath9k_platform_data ap136_ath9k_data;
+static void __init ap136_common_setup(void)
+{
+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
+
+ ath79_register_m25p80(NULL);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap136_leds_gpio),
+ ap136_leds_gpio);
+ ath79_register_gpio_keys_polled(-1, AP136_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(ap136_gpio_keys),
+ ap136_gpio_keys);
+
+ ath79_register_usb();
+ ath79_register_nfc();
+
+ ath79_register_wmac(art + AP136_WMAC_CALDATA_OFFSET, NULL);
+
+ ath79_setup_qca955x_eth_cfg(QCA955X_ETH_CFG_RGMII_EN);
-static int ap136_pci_plat_dev_init(struct pci_dev *dev)
+ ath79_register_mdio(0, 0x0);
+ ath79_init_mac(ath79_eth0_data.mac_addr, art + AP136_MAC0_OFFSET, 0);
+
+ mdiobus_register_board_info(ap136_mdio0_info,
+ ARRAY_SIZE(ap136_mdio0_info));
+
+ /* GMAC0 is connected to the RMGII interface */
+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
+ ath79_eth0_data.phy_mask = BIT(0);
+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev;
+
+ ath79_register_eth(0);
+
+ /* GMAC1 is connected tot eh SGMII interface */
+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_SGMII;
+ ath79_eth1_data.speed = SPEED_1000;
+ ath79_eth1_data.duplex = DUPLEX_FULL;
+
+ ath79_register_eth(1);
+}
+
+static void __init ap136_010_setup(void)
{
- if (dev->bus->number == 1 && (PCI_SLOT(dev->devfn)) == 0)
- dev->dev.platform_data = &ap136_ath9k_data;
+ u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
- return 0;
+ /* GMAC0 of the AR8327 switch is connected to GMAC0 via RGMII */
+ ap136_ar8327_pad0_cfg.mode = AR8327_PAD_MAC_RGMII;
+ ap136_ar8327_pad0_cfg.txclk_delay_en = true;
+ ap136_ar8327_pad0_cfg.rxclk_delay_en = true;
+ ap136_ar8327_pad0_cfg.txclk_delay_sel = AR8327_CLK_DELAY_SEL1;
+ ap136_ar8327_pad0_cfg.rxclk_delay_sel = AR8327_CLK_DELAY_SEL2;
+
+ /* GMAC6 of the AR8327 switch is connected to GMAC1 via SGMII */
+ ap136_ar8327_pad6_cfg.mode = AR8327_PAD_MAC_SGMII;
+ ap136_ar8327_pad6_cfg.rxclk_delay_en = true;
+ ap136_ar8327_pad6_cfg.rxclk_delay_sel = AR8327_CLK_DELAY_SEL0;
+
+ ath79_eth0_pll_data.pll_1000 = 0xa6000000;
+ ath79_eth1_pll_data.pll_1000 = 0x03000101;
+
+ ap136_common_setup();
+ ap91_pci_init(art + AP136_PCIE_CALDATA_OFFSET, NULL);
}
-static void __init ap136_pci_init(u8 *eeprom)
+MIPS_MACHINE(ATH79_MACH_AP136_010, "AP136-010",
+ "Atheros AP136-010 reference board",
+ ap136_010_setup);
+
+static void __init ap136_020_common_setup(void)
{
- memcpy(ap136_ath9k_data.eeprom_data, eeprom,
- sizeof(ap136_ath9k_data.eeprom_data));
+ /* GMAC0 of the AR8327 switch is connected to GMAC1 via SGMII */
+ ap136_ar8327_pad0_cfg.mode = AR8327_PAD_MAC_SGMII;
+ ap136_ar8327_pad0_cfg.sgmii_delay_en = true;
+
+ /* GMAC6 of the AR8327 switch is connected to GMAC0 via RGMII */
+ ap136_ar8327_pad6_cfg.mode = AR8327_PAD_MAC_RGMII;
+ ap136_ar8327_pad6_cfg.txclk_delay_en = true;
+ ap136_ar8327_pad6_cfg.rxclk_delay_en = true;
+ ap136_ar8327_pad6_cfg.txclk_delay_sel = AR8327_CLK_DELAY_SEL1;
+ ap136_ar8327_pad6_cfg.rxclk_delay_sel = AR8327_CLK_DELAY_SEL2;
- ath79_pci_set_plat_dev_init(ap136_pci_plat_dev_init);
- ath79_register_pci();
+ ath79_eth0_pll_data.pll_1000 = 0x56000000;
+ ath79_eth1_pll_data.pll_1000 = 0x03000101;
+
+ ap136_common_setup();
}
-#else
-static inline void ap136_pci_init(u8 *eeprom) {}
-#endif /* CONFIG_PCI */
-static void __init ap136_setup(void)
+static void __init ap136_020_setup(void)
{
u8 *art = (u8 *) KSEG1ADDR(0x1fff0000);
- ath79_register_leds_gpio(-1, ARRAY_SIZE(ap136_leds_gpio),
- ap136_leds_gpio);
- ath79_register_gpio_keys_polled(-1, AP136_KEYS_POLL_INTERVAL,
- ARRAY_SIZE(ap136_gpio_keys),
- ap136_gpio_keys);
- ath79_register_spi(&ap136_spi_data, ap136_spi_info,
- ARRAY_SIZE(ap136_spi_info));
- ath79_register_usb();
- ath79_register_wmac(art + AP136_WMAC_CALDATA_OFFSET);
- ap136_pci_init(art + AP136_PCIE_CALDATA_OFFSET);
+ ap136_020_common_setup();
+ ap91_pci_init(art + AP136_PCIE_CALDATA_OFFSET, NULL);
}
-MIPS_MACHINE(ATH79_MACH_AP136_010, "AP136-010",
- "Atheros AP136-010 reference board",
- ap136_setup);
+MIPS_MACHINE(ATH79_MACH_AP136_020, "AP136-020",
+ "Atheros AP136-020 reference board",
+ ap136_020_setup);
+
+/*
+ * AP135-020 is similar to AP136-020, any future AP135 specific init
+ * code can be added here.
+ */
+static void __init ap135_020_setup(void)
+{
+ ap136_leds_gpio[0].name = "ap135:green:status";
+ ap136_leds_gpio[1].name = "ap135:red:status";
+ ap136_leds_gpio[2].name = "ap135:green:wps";
+ ap136_leds_gpio[3].name = "ap135:red:wps";
+ ap136_leds_gpio[4].name = "ap135:red:wlan-2g";
+ ap136_leds_gpio[5].name = "ap135:red:usb";
+
+ ap136_020_common_setup();
+ ath79_register_pci();
+}
+
+MIPS_MACHINE(ATH79_MACH_AP135_020, "AP135-020",
+ "Atheros AP135-020 reference board",
+ ap135_020_setup);
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -18,7 +18,9 @@ enum ath79_mach_type {
ATH79_MACH_GENERIC = 0,
ATH79_MACH_AP121, /* Atheros AP121 reference board */
ATH79_MACH_AP121_MINI, /* Atheros AP121-MINI reference board */
+ ATH79_MACH_AP135_020, /* Atheros AP135-020 reference board */
ATH79_MACH_AP136_010, /* Atheros AP136-010 reference board */
+ ATH79_MACH_AP136_020, /* Atheros AP136-020 reference board */
ATH79_MACH_AP81, /* Atheros AP81 reference board */
ATH79_MACH_DB120, /* Atheros DB120 reference board */
ATH79_MACH_PB44, /* Atheros PB44 reference board */
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -16,16 +16,17 @@ config ATH79_MACH_AP121
Atheros AP121 reference board.
config ATH79_MACH_AP136
- bool "Atheros AP136 reference board"
+ bool "Atheros AP136/AP135 reference board"
select SOC_QCA955X
select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_NFC
select ATH79_DEV_SPI
select ATH79_DEV_USB
select ATH79_DEV_WMAC
help
Say 'Y' here if you want your kernel to support the
- Atheros AP136 reference board.
+ Atheros AP136 or AP135 reference boards.
config ATH79_MACH_AP81
bool "Atheros AP81 reference board"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,25 @@
MIPS: ath79: fix maximum timeout
If the userland tries to set a timeout higher than the max_timeout, then we should fallback to max_timeout.
Signed-off-by: John Crispin <blogic@openwrt.org>
--- a/drivers/watchdog/ath79_wdt.c
+++ b/drivers/watchdog/ath79_wdt.c
@@ -114,10 +114,14 @@ static inline void ath79_wdt_disable(voi
static int ath79_wdt_set_timeout(int val)
{
- if (val < 1 || val > max_timeout)
+ if (val < 1)
return -EINVAL;
- timeout = val;
+ if (val > max_timeout)
+ timeout = max_timeout;
+ else
+ timeout = val;
+
ath79_wdt_keepalive();
return 0;

View File

@ -0,0 +1,24 @@
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -306,6 +306,11 @@ void __init ath79_wmac_disable_5ghz(void
ath79_wmac_data.disable_5ghz = true;
}
+void __init ath79_wmac_set_tx_gain_buffalo(void)
+{
+ ath79_wmac_data.tx_gain_buffalo = true;
+}
+
void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr)
{
if (soc_is_ar913x())
--- a/arch/mips/ath79/dev-wmac.h
+++ b/arch/mips/ath79/dev-wmac.h
@@ -16,6 +16,7 @@ void ath79_register_wmac(u8 *cal_data, u
void ath79_register_wmac_simple(void);
void ath79_wmac_disable_2ghz(void);
void ath79_wmac_disable_5ghz(void);
+void ath79_wmac_set_tx_gain_buffalo(void);
bool ar93xx_wmac_read_mac_address(u8 *dest);

View File

@ -0,0 +1,76 @@
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -18,9 +18,11 @@
#include <linux/etherdevice.h>
#include <linux/platform_device.h>
#include <linux/ath9k_platform.h>
+#include <linux/gpio.h>
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
#include "dev-wmac.h"
static u8 ath79_wmac_mac[ETH_ALEN];
@@ -311,6 +313,51 @@ void __init ath79_wmac_set_tx_gain_buffa
ath79_wmac_data.tx_gain_buffalo = true;
}
+static int ath79_request_ext_lna_gpio(unsigned chain, int gpio)
+{
+ char buf[32];
+ char *label;
+ int err;
+
+ scnprintf(buf, sizeof(buf), "external LNA%u", chain);
+ label = kstrdup(buf, GFP_KERNEL);
+
+ err = gpio_request_one(gpio, GPIOF_DIR_OUT | GPIOF_INIT_LOW, label);
+ if (err) {
+ pr_err("unable to request GPIO%d for external LNA%u\n",
+ gpio, chain);
+ kfree(label);
+ }
+
+ return err;
+}
+
+static void ar934x_set_ext_lna_gpio(unsigned chain, int gpio)
+{
+ unsigned int sel;
+ int err;
+
+ if (WARN_ON(chain > 1))
+ return;
+
+ err = ath79_request_ext_lna_gpio(chain, gpio);
+ if (err)
+ return;
+
+ if (chain == 0)
+ sel = AR934X_GPIO_OUT_EXT_LNA0;
+ else
+ sel = AR934X_GPIO_OUT_EXT_LNA1;
+
+ ath79_gpio_output_select(gpio, sel);
+}
+
+void __init ath79_wmac_set_ext_lna_gpio(unsigned chain, int gpio)
+{
+ if (soc_is_ar934x())
+ ar934x_set_ext_lna_gpio(chain, gpio);
+}
+
void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr)
{
if (soc_is_ar913x())
--- a/arch/mips/ath79/dev-wmac.h
+++ b/arch/mips/ath79/dev-wmac.h
@@ -17,6 +17,7 @@ void ath79_register_wmac_simple(void);
void ath79_wmac_disable_2ghz(void);
void ath79_wmac_disable_5ghz(void);
void ath79_wmac_set_tx_gain_buffalo(void);
+void ath79_wmac_set_ext_lna_gpio(unsigned chain, int gpio);
bool ar93xx_wmac_read_mac_address(u8 *dest);

View File

@ -0,0 +1,44 @@
--- a/arch/mips/ath79/mach-ap83.c
+++ b/arch/mips/ath79/mach-ap83.c
@@ -42,41 +42,8 @@
#define AP83_KEYS_POLL_INTERVAL 20 /* msecs */
#define AP83_KEYS_DEBOUNCE_INTERVAL (3 * AP83_KEYS_POLL_INTERVAL)
-static struct mtd_partition ap83_flash_partitions[] = {
- {
- .name = "u-boot",
- .offset = 0,
- .size = 0x040000,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "u-boot-env",
- .offset = 0x040000,
- .size = 0x020000,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "kernel",
- .offset = 0x060000,
- .size = 0x140000,
- }, {
- .name = "rootfs",
- .offset = 0x1a0000,
- .size = 0x650000,
- }, {
- .name = "art",
- .offset = 0x7f0000,
- .size = 0x010000,
- .mask_flags = MTD_WRITEABLE,
- }, {
- .name = "firmware",
- .offset = 0x060000,
- .size = 0x790000,
- }
-};
-
static struct physmap_flash_data ap83_flash_data = {
.width = 2,
- .parts = ap83_flash_partitions,
- .nr_parts = ARRAY_SIZE(ap83_flash_partitions),
};
static struct resource ap83_flash_resources[] = {

View File

@ -0,0 +1,721 @@
From 5300a7cd7ed2f88488ddba62947b9c6bb9663777 Mon Sep 17 00:00:00 2001
Message-Id: <5300a7cd7ed2f88488ddba62947b9c6bb9663777.1396122227.git.mschiffer@universe-factory.net>
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Sat, 29 Mar 2014 20:26:08 +0100
Subject: [PATCH 1/2] MIPS: ath79: add support for QCA953x SoC
Note that the clock calculation looks very similar to the QCA955x, but the
meaning of the bits CPUCLK_FROM_CPUPLL and DDRCLK_FROM_DDRPLL is reversed.
---
arch/mips/ath79/Kconfig | 6 +-
arch/mips/ath79/clock.c | 78 ++++++++++++++++++++++++++
arch/mips/ath79/common.c | 4 ++
arch/mips/ath79/dev-common.c | 1 +
arch/mips/ath79/dev-wmac.c | 20 +++++++
arch/mips/ath79/early_printk.c | 1 +
arch/mips/ath79/gpio.c | 4 +-
arch/mips/ath79/irq.c | 4 ++
arch/mips/ath79/setup.c | 8 ++-
arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 48 ++++++++++++++++
arch/mips/include/asm/mach-ath79/ath79.h | 11 ++++
11 files changed, 182 insertions(+), 3 deletions(-)
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -1205,6 +1205,10 @@ config SOC_AR934X
select PCI_AR724X if PCI
def_bool n
+config SOC_QCA953X
+ select USB_ARCH_HAS_EHCI
+ def_bool n
+
config SOC_QCA955X
select HW_HAS_PCI
select PCI_AR724X if PCI
@@ -1247,7 +1251,7 @@ config ATH79_DEV_USB
def_bool n
config ATH79_DEV_WMAC
- depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA955X)
+ depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA953X || SOC_QCA955X)
def_bool n
config ATH79_NVRAM
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -350,6 +350,91 @@ static void __init ar934x_clocks_init(vo
iounmap(dpll_base);
}
+static void __init qca953x_clocks_init(void)
+{
+ unsigned long ref_rate;
+ unsigned long cpu_rate;
+ unsigned long ddr_rate;
+ unsigned long ahb_rate;
+ u32 pll, out_div, ref_div, nint, frac, clk_ctrl, postdiv;
+ u32 cpu_pll, ddr_pll;
+ u32 bootstrap;
+
+ bootstrap = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP);
+ if (bootstrap & QCA953X_BOOTSTRAP_REF_CLK_40)
+ ref_rate = 40 * 1000 * 1000;
+ else
+ ref_rate = 25 * 1000 * 1000;
+
+ pll = ath79_pll_rr(QCA953X_PLL_CPU_CONFIG_REG);
+ out_div = (pll >> QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
+ QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK;
+ ref_div = (pll >> QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
+ QCA953X_PLL_CPU_CONFIG_REFDIV_MASK;
+ nint = (pll >> QCA953X_PLL_CPU_CONFIG_NINT_SHIFT) &
+ QCA953X_PLL_CPU_CONFIG_NINT_MASK;
+ frac = (pll >> QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT) &
+ QCA953X_PLL_CPU_CONFIG_NFRAC_MASK;
+
+ cpu_pll = nint * ref_rate / ref_div;
+ cpu_pll += frac * (ref_rate >> 6) / ref_div;
+ cpu_pll /= (1 << out_div);
+
+ pll = ath79_pll_rr(QCA953X_PLL_DDR_CONFIG_REG);
+ out_div = (pll >> QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
+ QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK;
+ ref_div = (pll >> QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
+ QCA953X_PLL_DDR_CONFIG_REFDIV_MASK;
+ nint = (pll >> QCA953X_PLL_DDR_CONFIG_NINT_SHIFT) &
+ QCA953X_PLL_DDR_CONFIG_NINT_MASK;
+ frac = (pll >> QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT) &
+ QCA953X_PLL_DDR_CONFIG_NFRAC_MASK;
+
+ ddr_pll = nint * ref_rate / ref_div;
+ ddr_pll += frac * (ref_rate >> 6) / (ref_div << 4);
+ ddr_pll /= (1 << out_div);
+
+ clk_ctrl = ath79_pll_rr(QCA953X_PLL_CLK_CTRL_REG);
+
+ postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
+ QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
+
+ if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
+ cpu_rate = ref_rate;
+ else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL)
+ cpu_rate = cpu_pll / (postdiv + 1);
+ else
+ cpu_rate = ddr_pll / (postdiv + 1);
+
+ postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
+ QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
+
+ if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
+ ddr_rate = ref_rate;
+ else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL)
+ ddr_rate = ddr_pll / (postdiv + 1);
+ else
+ ddr_rate = cpu_pll / (postdiv + 1);
+
+ postdiv = (clk_ctrl >> QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
+ QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
+
+ if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
+ ahb_rate = ref_rate;
+ else if (clk_ctrl & QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
+ ahb_rate = ddr_pll / (postdiv + 1);
+ else
+ ahb_rate = cpu_pll / (postdiv + 1);
+
+ ath79_add_sys_clkdev("ref", ref_rate);
+ ath79_add_sys_clkdev("cpu", cpu_rate);
+ ath79_add_sys_clkdev("ddr", ddr_rate);
+ ath79_add_sys_clkdev("ahb", ahb_rate);
+
+ clk_add_alias("wdt", NULL, "ref", NULL);
+ clk_add_alias("uart", NULL, "ref", NULL);
+}
+
static void __init qca955x_clocks_init(void)
{
unsigned long ref_rate;
@@ -447,6 +532,8 @@ void __init ath79_clocks_init(void)
ar933x_clocks_init();
else if (soc_is_ar934x())
ar934x_clocks_init();
+ else if (soc_is_qca953x())
+ qca953x_clocks_init();
else if (soc_is_qca955x())
qca955x_clocks_init();
else
--- a/arch/mips/ath79/common.c
+++ b/arch/mips/ath79/common.c
@@ -73,6 +73,8 @@ void ath79_device_reset_set(u32 mask)
reg = AR933X_RESET_REG_RESET_MODULE;
else if (soc_is_ar934x())
reg = AR934X_RESET_REG_RESET_MODULE;
+ else if (soc_is_qca953x())
+ reg = QCA953X_RESET_REG_RESET_MODULE;
else if (soc_is_qca955x())
reg = QCA955X_RESET_REG_RESET_MODULE;
else
@@ -101,6 +103,8 @@ void ath79_device_reset_clear(u32 mask)
reg = AR933X_RESET_REG_RESET_MODULE;
else if (soc_is_ar934x())
reg = AR934X_RESET_REG_RESET_MODULE;
+ else if (soc_is_qca953x())
+ reg = QCA953X_RESET_REG_RESET_MODULE;
else if (soc_is_qca955x())
reg = QCA955X_RESET_REG_RESET_MODULE;
else
--- a/arch/mips/ath79/dev-common.c
+++ b/arch/mips/ath79/dev-common.c
@@ -93,6 +93,7 @@ void __init ath79_register_uart(void)
soc_is_ar724x() ||
soc_is_ar913x() ||
soc_is_ar934x() ||
+ soc_is_qca953x() ||
soc_is_qca955x()) {
ath79_uart_data[0].uartclk = uart_clk_rate;
platform_device_register(&ath79_uart_device);
--- a/arch/mips/ath79/dev-usb.c
+++ b/arch/mips/ath79/dev-usb.c
@@ -236,6 +236,30 @@ static void __init ar934x_usb_setup(void
&ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
}
+static void __init qca953x_usb_setup(void)
+{
+ u32 bootstrap;
+
+ bootstrap = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP);
+
+ ath79_device_reset_set(QCA953X_RESET_USBSUS_OVERRIDE);
+ udelay(1000);
+
+ ath79_device_reset_clear(QCA953X_RESET_USB_PHY);
+ udelay(1000);
+
+ ath79_device_reset_clear(QCA953X_RESET_USB_PHY_ANALOG);
+ udelay(1000);
+
+ ath79_device_reset_clear(QCA953X_RESET_USB_HOST);
+ udelay(1000);
+
+ ath79_usb_register("ehci-platform", -1,
+ QCA953X_EHCI_BASE, QCA953X_EHCI_SIZE,
+ ATH79_CPU_IRQ(3),
+ &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
+}
+
static void qca955x_usb_reset_notifier(struct platform_device *pdev)
{
u32 base;
@@ -286,6 +310,8 @@ void __init ath79_register_usb(void)
ar933x_usb_setup();
else if (soc_is_ar934x())
ar934x_usb_setup();
+ else if (soc_is_qca953x())
+ qca953x_usb_setup();
else if (soc_is_qca955x())
qca955x_usb_setup();
else
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -101,7 +101,7 @@ static int ar933x_wmac_reset(void)
return -ETIMEDOUT;
}
-static int ar933x_r1_get_wmac_revision(void)
+static int ar93xx_get_soc_revision(void)
{
return ath79_soc_rev;
}
@@ -126,7 +126,7 @@ static void __init ar933x_wmac_setup(voi
ath79_wmac_data.is_clk_25mhz = true;
if (ath79_soc_rev == 1)
- ath79_wmac_data.get_mac_revision = ar933x_r1_get_wmac_revision;
+ ath79_wmac_data.get_mac_revision = ar93xx_get_soc_revision;
ath79_wmac_data.external_reset = ar933x_wmac_reset;
}
@@ -149,6 +149,26 @@ static void ar934x_wmac_setup(void)
ath79_wmac_data.is_clk_25mhz = true;
}
+static void qca953x_wmac_setup(void)
+{
+ u32 t;
+
+ ath79_wmac_device.name = "qca953x_wmac";
+
+ ath79_wmac_resources[0].start = QCA953X_WMAC_BASE;
+ ath79_wmac_resources[0].end = QCA953X_WMAC_BASE + QCA953X_WMAC_SIZE - 1;
+ ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1);
+ ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1);
+
+ t = ath79_reset_rr(QCA953X_RESET_REG_BOOTSTRAP);
+ if (t & QCA953X_BOOTSTRAP_REF_CLK_40)
+ ath79_wmac_data.is_clk_25mhz = false;
+ else
+ ath79_wmac_data.is_clk_25mhz = true;
+
+ ath79_wmac_data.get_mac_revision = ar93xx_get_soc_revision;
+}
+
static void qca955x_wmac_setup(void)
{
u32 t;
@@ -366,6 +386,8 @@ void __init ath79_register_wmac(u8 *cal_
ar933x_wmac_setup();
else if (soc_is_ar934x())
ar934x_wmac_setup();
+ else if (soc_is_qca953x())
+ qca953x_wmac_setup();
else if (soc_is_qca955x())
qca955x_wmac_setup();
else
--- a/arch/mips/ath79/early_printk.c
+++ b/arch/mips/ath79/early_printk.c
@@ -114,6 +114,8 @@ static void prom_putchar_init(void)
case REV_ID_MAJOR_AR9341:
case REV_ID_MAJOR_AR9342:
case REV_ID_MAJOR_AR9344:
+ case REV_ID_MAJOR_QCA9533:
+ case REV_ID_MAJOR_QCA9533_V2:
case REV_ID_MAJOR_QCA9556:
case REV_ID_MAJOR_QCA9558:
_prom_putchar = prom_putchar_ar71xx;
--- a/arch/mips/ath79/gpio.c
+++ b/arch/mips/ath79/gpio.c
@@ -148,7 +148,7 @@ static void __iomem *ath79_gpio_get_func
soc_is_ar913x() ||
soc_is_ar933x())
reg = AR71XX_GPIO_REG_FUNC;
- else if (soc_is_ar934x())
+ else if (soc_is_ar934x() || soc_is_qca953x())
reg = AR934X_GPIO_REG_FUNC;
else
BUG();
@@ -187,7 +187,7 @@ void __init ath79_gpio_output_select(uns
unsigned int reg;
u32 t, s;
- BUG_ON(!soc_is_ar934x());
+ BUG_ON(!soc_is_ar934x() && !soc_is_qca953x());
if (gpio >= AR934X_GPIO_COUNT)
return;
@@ -224,6 +224,8 @@ void __init ath79_gpio_init(void)
ath79_gpio_count = AR933X_GPIO_COUNT;
else if (soc_is_ar934x())
ath79_gpio_count = AR934X_GPIO_COUNT;
+ else if (soc_is_qca953x())
+ ath79_gpio_count = QCA953X_GPIO_COUNT;
else if (soc_is_qca955x())
ath79_gpio_count = QCA955X_GPIO_COUNT;
else
@@ -231,7 +233,7 @@ void __init ath79_gpio_init(void)
ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
ath79_gpio_chip.ngpio = ath79_gpio_count;
- if (soc_is_ar934x() || soc_is_qca955x()) {
+ if (soc_is_ar934x() || soc_is_qca953x() || soc_is_qca955x()) {
ath79_gpio_chip.direction_input = ar934x_gpio_direction_input;
ath79_gpio_chip.direction_output = ar934x_gpio_direction_output;
}
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -106,6 +106,7 @@ static void __init ath79_misc_irq_init(v
else if (soc_is_ar724x() ||
soc_is_ar933x() ||
soc_is_ar934x() ||
+ soc_is_qca953x() ||
soc_is_qca955x())
ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
else
@@ -153,6 +154,38 @@ static void ar934x_ip2_irq_init(void)
irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch);
}
+static void qca953x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc)
+{
+ u32 status;
+
+ disable_irq_nosync(irq);
+
+ status = ath79_reset_rr(QCA953X_RESET_REG_PCIE_WMAC_INT_STATUS);
+
+ if (status & QCA953X_PCIE_WMAC_INT_PCIE_ALL) {
+ ath79_ddr_wb_flush(QCA953X_DDR_REG_FLUSH_PCIE);
+ generic_handle_irq(ATH79_IP2_IRQ(0));
+ } else if (status & QCA953X_PCIE_WMAC_INT_WMAC_ALL) {
+ ath79_ddr_wb_flush(QCA953X_DDR_REG_FLUSH_WMAC);
+ generic_handle_irq(ATH79_IP2_IRQ(1));
+ } else {
+ spurious_interrupt();
+ }
+
+ enable_irq(irq);
+}
+
+static void qca953x_irq_init(void)
+{
+ int i;
+
+ for (i = ATH79_IP2_IRQ_BASE;
+ i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
+ irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq);
+
+ irq_set_chained_handler(ATH79_CPU_IRQ(2), qca953x_ip2_irq_dispatch);
+}
+
static void qca955x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc)
{
u32 status;
@@ -335,6 +368,12 @@ static void ar934x_ip3_handler(void)
do_IRQ(ATH79_CPU_IRQ(3));
}
+static void qca953x_ip3_handler(void)
+{
+ ath79_ddr_wb_flush(QCA953X_DDR_REG_FLUSH_USB);
+ do_IRQ(ATH79_CPU_IRQ(3));
+}
+
void __init arch_init_irq(void)
{
if (soc_is_ar71xx()) {
@@ -352,6 +391,9 @@ void __init arch_init_irq(void)
} else if (soc_is_ar934x()) {
ath79_ip2_handler = ath79_default_ip2_handler;
ath79_ip3_handler = ar934x_ip3_handler;
+ } else if (soc_is_qca953x()) {
+ ath79_ip2_handler = ath79_default_ip2_handler;
+ ath79_ip3_handler = qca953x_ip3_handler;
} else if (soc_is_qca955x()) {
ath79_ip2_handler = ath79_default_ip2_handler;
ath79_ip3_handler = ath79_default_ip3_handler;
@@ -365,6 +407,8 @@ void __init arch_init_irq(void)
if (soc_is_ar934x())
ar934x_ip2_irq_init();
+ else if (soc_is_qca953x())
+ qca953x_irq_init();
else if (soc_is_qca955x())
qca955x_irq_init();
}
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -59,6 +59,7 @@ static void __init ath79_detect_sys_type
u32 major;
u32 minor;
u32 rev = 0;
+ u32 ver = 1;
id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID);
major = id & REV_ID_MAJOR_MASK;
@@ -151,6 +152,16 @@ static void __init ath79_detect_sys_type
rev = id & AR934X_REV_ID_REVISION_MASK;
break;
+ case REV_ID_MAJOR_QCA9533_V2:
+ ver = 2;
+ /* drop through */
+
+ case REV_ID_MAJOR_QCA9533:
+ ath79_soc = ATH79_SOC_QCA9533;
+ chip = "9533";
+ rev = id & QCA953X_REV_ID_REVISION_MASK;
+ break;
+
case REV_ID_MAJOR_QCA9556:
ath79_soc = ATH79_SOC_QCA9556;
chip = "9556";
@@ -169,7 +180,7 @@ static void __init ath79_detect_sys_type
ath79_soc_rev = rev;
- if (soc_is_qca955x())
+ if (soc_is_qca953x() || soc_is_qca955x())
sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s rev %u",
chip, rev);
else
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -105,6 +105,21 @@
#define AR934X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000)
#define AR934X_SRIF_SIZE 0x1000
+#define QCA953X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000)
+#define QCA953X_GMAC_SIZE 0x14
+#define QCA953X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000)
+#define QCA953X_WMAC_SIZE 0x20000
+#define QCA953X_EHCI_BASE 0x1b000000
+#define QCA953X_EHCI_SIZE 0x200
+#define QCA953X_SRIF_BASE (AR71XX_APB_BASE + 0x00116000)
+#define QCA953X_SRIF_SIZE 0x1000
+
+#define QCA953X_PCI_CFG_BASE0 0x14000000
+#define QCA953X_PCI_CTRL_BASE0 (AR71XX_APB_BASE + 0x000f0000)
+#define QCA953X_PCI_CRP_BASE0 (AR71XX_APB_BASE + 0x000c0000)
+#define QCA953X_PCI_MEM_BASE0 0x10000000
+#define QCA953X_PCI_MEM_SIZE 0x02000000
+
#define QCA955X_PCI_MEM_BASE0 0x10000000
#define QCA955X_PCI_MEM_BASE1 0x12000000
#define QCA955X_PCI_MEM_SIZE 0x02000000
@@ -173,6 +188,12 @@
#define AR934X_DDR_REG_FLUSH_PCIE 0xa8
#define AR934X_DDR_REG_FLUSH_WMAC 0xac
+#define QCA953X_DDR_REG_FLUSH_GE0 0x9c
+#define QCA953X_DDR_REG_FLUSH_GE1 0xa0
+#define QCA953X_DDR_REG_FLUSH_USB 0xa4
+#define QCA953X_DDR_REG_FLUSH_PCIE 0xa8
+#define QCA953X_DDR_REG_FLUSH_WMAC 0xac
+
/*
* PLL block
*/
@@ -279,6 +300,44 @@
#define AR934X_PLL_SWITCH_CLOCK_CONTROL_MDIO_CLK_SEL BIT(6)
+#define QCA953X_PLL_CPU_CONFIG_REG 0x00
+#define QCA953X_PLL_DDR_CONFIG_REG 0x04
+#define QCA953X_PLL_CLK_CTRL_REG 0x08
+#define QCA953X_PLL_SWITCH_CLOCK_CONTROL_REG 0x24
+#define QCA953X_PLL_ETH_XMII_CONTROL_REG 0x2c
+#define QCA953X_PLL_ETH_SGMII_CONTROL_REG 0x48
+
+#define QCA953X_PLL_CPU_CONFIG_NFRAC_SHIFT 0
+#define QCA953X_PLL_CPU_CONFIG_NFRAC_MASK 0x3f
+#define QCA953X_PLL_CPU_CONFIG_NINT_SHIFT 6
+#define QCA953X_PLL_CPU_CONFIG_NINT_MASK 0x3f
+#define QCA953X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
+#define QCA953X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
+#define QCA953X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
+#define QCA953X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7
+
+#define QCA953X_PLL_DDR_CONFIG_NFRAC_SHIFT 0
+#define QCA953X_PLL_DDR_CONFIG_NFRAC_MASK 0x3ff
+#define QCA953X_PLL_DDR_CONFIG_NINT_SHIFT 10
+#define QCA953X_PLL_DDR_CONFIG_NINT_MASK 0x3f
+#define QCA953X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
+#define QCA953X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
+#define QCA953X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
+#define QCA953X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
+
+#define QCA953X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
+#define QCA953X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
+#define QCA953X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4)
+#define QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5
+#define QCA953X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f
+#define QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10
+#define QCA953X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f
+#define QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15
+#define QCA953X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f
+#define QCA953X_PLL_CLK_CTRL_CPUCLK_FROM_CPUPLL BIT(20)
+#define QCA953X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
+#define QCA953X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+
#define QCA955X_PLL_CPU_CONFIG_REG 0x00
#define QCA955X_PLL_DDR_CONFIG_REG 0x04
#define QCA955X_PLL_CLK_CTRL_REG 0x08
@@ -355,6 +414,10 @@
#define AR934X_RESET_REG_BOOTSTRAP 0xb0
#define AR934X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac
+#define QCA953X_RESET_REG_RESET_MODULE 0x1c
+#define QCA953X_RESET_REG_BOOTSTRAP 0xb0
+#define QCA953X_RESET_REG_PCIE_WMAC_INT_STATUS 0xac
+
#define QCA955X_RESET_REG_RESET_MODULE 0x1c
#define QCA955X_RESET_REG_BOOTSTRAP 0xb0
#define QCA955X_RESET_REG_EXT_INT_STATUS 0xac
@@ -450,6 +513,27 @@
#define AR934X_RESET_MBOX BIT(1)
#define AR934X_RESET_I2S BIT(0)
+#define QCA953X_RESET_USB_EXT_PWR BIT(29)
+#define QCA953X_RESET_EXTERNAL BIT(28)
+#define QCA953X_RESET_RTC BIT(27)
+#define QCA953X_RESET_FULL_CHIP BIT(24)
+#define QCA953X_RESET_GE1_MDIO BIT(23)
+#define QCA953X_RESET_GE0_MDIO BIT(22)
+#define QCA953X_RESET_CPU_NMI BIT(21)
+#define QCA953X_RESET_CPU_COLD BIT(20)
+#define QCA953X_RESET_DDR BIT(16)
+#define QCA953X_RESET_USB_PHY_PLL_PWD_EXT BIT(15)
+#define QCA953X_RESET_GE1_MAC BIT(13)
+#define QCA953X_RESET_ETH_SWITCH_ANALOG BIT(12)
+#define QCA953X_RESET_USB_PHY_ANALOG BIT(11)
+#define QCA953X_RESET_GE0_MAC BIT(9)
+#define QCA953X_RESET_ETH_SWITCH BIT(8)
+#define QCA953X_RESET_PCIE_PHY BIT(7)
+#define QCA953X_RESET_PCIE BIT(6)
+#define QCA953X_RESET_USB_HOST BIT(5)
+#define QCA953X_RESET_USB_PHY BIT(4)
+#define QCA953X_RESET_USBSUS_OVERRIDE BIT(3)
+
#define QCA955X_RESET_HOST BIT(31)
#define QCA955X_RESET_SLIC BIT(30)
#define QCA955X_RESET_HDMA BIT(29)
@@ -503,6 +587,13 @@
#define AR934X_BOOTSTRAP_SDRAM_DISABLED BIT(1)
#define AR934X_BOOTSTRAP_DDR1 BIT(0)
+#define QCA953X_BOOTSTRAP_SW_OPTION2 BIT(12)
+#define QCA953X_BOOTSTRAP_SW_OPTION1 BIT(11)
+#define QCA953X_BOOTSTRAP_EJTAG_MODE BIT(5)
+#define QCA953X_BOOTSTRAP_REF_CLK_40 BIT(4)
+#define QCA953X_BOOTSTRAP_SDRAM_DISABLED BIT(1)
+#define QCA953X_BOOTSTRAP_DDR1 BIT(0)
+
#define QCA955X_BOOTSTRAP_REF_CLK_40 BIT(4)
#define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0)
@@ -523,6 +614,24 @@
AR934X_PCIE_WMAC_INT_PCIE_RC1 | AR934X_PCIE_WMAC_INT_PCIE_RC2 | \
AR934X_PCIE_WMAC_INT_PCIE_RC3)
+#define QCA953X_PCIE_WMAC_INT_WMAC_MISC BIT(0)
+#define QCA953X_PCIE_WMAC_INT_WMAC_TX BIT(1)
+#define QCA953X_PCIE_WMAC_INT_WMAC_RXLP BIT(2)
+#define QCA953X_PCIE_WMAC_INT_WMAC_RXHP BIT(3)
+#define QCA953X_PCIE_WMAC_INT_PCIE_RC BIT(4)
+#define QCA953X_PCIE_WMAC_INT_PCIE_RC0 BIT(5)
+#define QCA953X_PCIE_WMAC_INT_PCIE_RC1 BIT(6)
+#define QCA953X_PCIE_WMAC_INT_PCIE_RC2 BIT(7)
+#define QCA953X_PCIE_WMAC_INT_PCIE_RC3 BIT(8)
+#define QCA953X_PCIE_WMAC_INT_WMAC_ALL \
+ (QCA953X_PCIE_WMAC_INT_WMAC_MISC | QCA953X_PCIE_WMAC_INT_WMAC_TX | \
+ QCA953X_PCIE_WMAC_INT_WMAC_RXLP | QCA953X_PCIE_WMAC_INT_WMAC_RXHP)
+
+#define QCA953X_PCIE_WMAC_INT_PCIE_ALL \
+ (QCA953X_PCIE_WMAC_INT_PCIE_RC | QCA953X_PCIE_WMAC_INT_PCIE_RC0 | \
+ QCA953X_PCIE_WMAC_INT_PCIE_RC1 | QCA953X_PCIE_WMAC_INT_PCIE_RC2 | \
+ QCA953X_PCIE_WMAC_INT_PCIE_RC3)
+
#define QCA955X_EXT_INT_WMAC_MISC BIT(0)
#define QCA955X_EXT_INT_WMAC_TX BIT(1)
#define QCA955X_EXT_INT_WMAC_RXLP BIT(2)
@@ -565,6 +674,8 @@
#define REV_ID_MAJOR_AR9341 0x0120
#define REV_ID_MAJOR_AR9342 0x1120
#define REV_ID_MAJOR_AR9344 0x2120
+#define REV_ID_MAJOR_QCA9533 0x0140
+#define REV_ID_MAJOR_QCA9533_V2 0x0160
#define REV_ID_MAJOR_QCA9556 0x0130
#define REV_ID_MAJOR_QCA9558 0x1130
@@ -587,6 +698,8 @@
#define AR934X_REV_ID_REVISION_MASK 0xf
+#define QCA953X_REV_ID_REVISION_MASK 0xf
+
#define QCA955X_REV_ID_REVISION_MASK 0xf
/*
@@ -634,12 +747,32 @@
#define AR934X_GPIO_REG_OUT_FUNC5 0x40
#define AR934X_GPIO_REG_FUNC 0x6c
+#define QCA953X_GPIO_REG_OUT_FUNC0 0x2c
+#define QCA953X_GPIO_REG_OUT_FUNC1 0x30
+#define QCA953X_GPIO_REG_OUT_FUNC2 0x34
+#define QCA953X_GPIO_REG_OUT_FUNC3 0x38
+#define QCA953X_GPIO_REG_OUT_FUNC4 0x3c
+#define QCA953X_GPIO_REG_IN_ENABLE0 0x44
+#define QCA953X_GPIO_REG_FUNC 0x6c
+
+#define QCA953X_GPIO_OUT_MUX_SPI_CS1 10
+#define QCA953X_GPIO_OUT_MUX_SPI_CS2 11
+#define QCA953X_GPIO_OUT_MUX_SPI_CS0 9
+#define QCA953X_GPIO_OUT_MUX_SPI_CLK 8
+#define QCA953X_GPIO_OUT_MUX_SPI_MOSI 12
+#define QCA953X_GPIO_OUT_MUX_LED_LINK1 41
+#define QCA953X_GPIO_OUT_MUX_LED_LINK2 42
+#define QCA953X_GPIO_OUT_MUX_LED_LINK3 43
+#define QCA953X_GPIO_OUT_MUX_LED_LINK4 44
+#define QCA953X_GPIO_OUT_MUX_LED_LINK5 45
+
#define AR71XX_GPIO_COUNT 16
#define AR7240_GPIO_COUNT 18
#define AR7241_GPIO_COUNT 20
#define AR913X_GPIO_COUNT 22
#define AR933X_GPIO_COUNT 30
#define AR934X_GPIO_COUNT 23
+#define QCA953X_GPIO_COUNT 18
#define QCA955X_GPIO_COUNT 24
/*
@@ -663,6 +796,24 @@
#define AR934X_SRIF_DPLL2_OUTDIV_SHIFT 13
#define AR934X_SRIF_DPLL2_OUTDIV_MASK 0x7
+#define QCA953X_SRIF_CPU_DPLL1_REG 0x1c0
+#define QCA953X_SRIF_CPU_DPLL2_REG 0x1c4
+#define QCA953X_SRIF_CPU_DPLL3_REG 0x1c8
+
+#define QCA953X_SRIF_DDR_DPLL1_REG 0x240
+#define QCA953X_SRIF_DDR_DPLL2_REG 0x244
+#define QCA953X_SRIF_DDR_DPLL3_REG 0x248
+
+#define QCA953X_SRIF_DPLL1_REFDIV_SHIFT 27
+#define QCA953X_SRIF_DPLL1_REFDIV_MASK 0x1f
+#define QCA953X_SRIF_DPLL1_NINT_SHIFT 18
+#define QCA953X_SRIF_DPLL1_NINT_MASK 0x1ff
+#define QCA953X_SRIF_DPLL1_NFRAC_MASK 0x0003ffff
+
+#define QCA953X_SRIF_DPLL2_LOCAL_PLL BIT(30)
+#define QCA953X_SRIF_DPLL2_OUTDIV_SHIFT 13
+#define QCA953X_SRIF_DPLL2_OUTDIV_MASK 0x7
+
#define AR71XX_GPIO_FUNC_STEREO_EN BIT(17)
#define AR71XX_GPIO_FUNC_SLIC_EN BIT(16)
#define AR71XX_GPIO_FUNC_SPI_CS2_EN BIT(13)
@@ -804,6 +955,16 @@
#define AR934X_ETH_CFG_RDV_DELAY_SHIFT 16
/*
+ * QCA953X GMAC Interface
+ */
+#define QCA953X_GMAC_REG_ETH_CFG 0x00
+
+#define QCA953X_ETH_CFG_SW_ONLY_MODE BIT(6)
+#define QCA953X_ETH_CFG_SW_PHY_SWAP BIT(7)
+#define QCA953X_ETH_CFG_SW_APB_ACCESS BIT(9)
+#define QCA953X_ETH_CFG_SW_ACC_MSB_FIRST BIT(13)
+
+/*
* QCA955X GMAC Interface
*/
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -32,6 +32,7 @@ enum ath79_soc_type {
ATH79_SOC_AR9341,
ATH79_SOC_AR9342,
ATH79_SOC_AR9344,
+ ATH79_SOC_QCA9533,
ATH79_SOC_QCA9556,
ATH79_SOC_QCA9558,
};
@@ -100,6 +101,16 @@ static inline int soc_is_ar934x(void)
return soc_is_ar9341() || soc_is_ar9342() || soc_is_ar9344();
}
+static inline int soc_is_qca9533(void)
+{
+ return ath79_soc == ATH79_SOC_QCA9533;
+}
+
+static inline int soc_is_qca953x(void)
+{
+ return soc_is_qca9533();
+}
+
static inline int soc_is_qca9556(void)
{
return ath79_soc == ATH79_SOC_QCA9556;

View File

@ -0,0 +1,40 @@
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -196,6 +196,17 @@ config ATH79_MACH_F9K1115V2
select ATH79_DEV_USB
select ATH79_DEV_WMAC
+config ATH79_MACH_EPG5000
+ bool "EnGenius EPG5000 board support"
+ select SOC_QCA955X
+ select ATH79_DEV_ETH
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_M25P80
+ select ATH79_DEV_USB
+ select ATH79_DEV_WMAC
+ select ATH79_NVRAM
+
config ATH79_MACH_ESR1750
bool "EnGenius ESR1750 board support"
select SOC_QCA955X
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_ATH79_MACH_EAP300V2) += mac
obj-$(CONFIG_ATH79_MACH_EAP7660D) += mach-eap7660d.o
obj-$(CONFIG_ATH79_MACH_EL_M150) += mach-el-m150.o
obj-$(CONFIG_ATH79_MACH_EL_MINI) += mach-el-mini.o
+obj-$(CONFIG_ATH79_MACH_EPG5000) += mach-epg5000.o
obj-$(CONFIG_ATH79_MACH_ESR1750) += mach-esr1750.o
obj-$(CONFIG_ATH79_MACH_F9K1115V2) += mach-f9k1115v2.o
obj-$(CONFIG_ATH79_MACH_GL_INET) += mach-gl-inet.o
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -60,6 +60,7 @@ enum ath79_mach_type {
ATH79_MACH_EL_M150, /* EasyLink EL-M150 */
ATH79_MACH_EL_MINI, /* EasyLink EL-MINI */
ATH79_MACH_ESR1750, /* EnGenius ESR1750 */
+ ATH79_MACH_EPG5000, /* EnGenius EPG5000 */
ATH79_MACH_F9K1115V2, /* Belkin AC1750DB */
ATH79_MACH_GL_INET, /* GL-CONNECT GL-INET */
ATH79_MACH_GS_OOLITE, /* GS OOLITE V1.0 */

View File

@ -0,0 +1,11 @@
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -147,6 +147,8 @@ static void ar934x_wmac_setup(void)
ath79_wmac_data.is_clk_25mhz = false;
else
ath79_wmac_data.is_clk_25mhz = true;
+
+ ath79_wmac_data.get_mac_revision = ar93xx_get_soc_revision;
}
static void qca953x_wmac_setup(void)

View File

@ -0,0 +1,20 @@
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -40,6 +40,7 @@ static char ath79_sys_type[ATH79_SYS_TYP
static void ath79_restart(char *command)
{
+ local_irq_disable();
ath79_device_reset_set(AR71XX_RESET_FULL_CHIP);
for (;;)
if (cpu_wait)
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -144,6 +144,7 @@ static inline u32 ath79_pll_rr(unsigned
static inline void ath79_reset_wr(unsigned reg, u32 val)
{
__raw_writel(val, ath79_reset_base + reg);
+ (void) __raw_readl(ath79_reset_base + reg); /* flush */
}
static inline u32 ath79_reset_rr(unsigned reg)

View File

@ -0,0 +1,700 @@
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -1225,6 +1225,12 @@ config SOC_QCA955X
select PCI_AR724X if PCI
def_bool n
+config SOC_QCA956X
+ select USB_ARCH_HAS_EHCI
+ select HW_HAS_PCI
+ select PCI_AR724X if PCI
+ def_bool n
+
config ATH79_DEV_M25P80
select ATH79_DEV_SPI
def_bool n
@@ -1262,7 +1268,7 @@ config ATH79_DEV_USB
def_bool n
config ATH79_DEV_WMAC
- depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA953X || SOC_QCA955X)
+ depends on (SOC_AR913X || SOC_AR933X || SOC_AR934X || SOC_QCA953X || SOC_QCA955X || SOC_QCA956X)
def_bool n
config ATH79_NVRAM
--- a/arch/mips/ath79/clock.c
+++ b/arch/mips/ath79/clock.c
@@ -520,6 +520,100 @@ static void __init qca955x_clocks_init(v
clk_add_alias("uart", NULL, "ref", NULL);
}
+static void __init qca956x_clocks_init(void)
+{
+ unsigned long ref_rate;
+ unsigned long cpu_rate;
+ unsigned long ddr_rate;
+ unsigned long ahb_rate;
+ u32 pll, out_div, ref_div, nint, hfrac, lfrac, clk_ctrl, postdiv;
+ u32 cpu_pll, ddr_pll;
+ u32 bootstrap;
+
+ bootstrap = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP);
+ if (bootstrap & QCA956X_BOOTSTRAP_REF_CLK_40)
+ ref_rate = 40 * 1000 * 1000;
+ else
+ ref_rate = 25 * 1000 * 1000;
+
+ pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG_REG);
+ out_div = (pll >> QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK;
+ ref_div = (pll >> QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG_REFDIV_MASK;
+
+ pll = ath79_pll_rr(QCA956X_PLL_CPU_CONFIG1_REG);
+ nint = (pll >> QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG1_NINT_MASK;
+ hfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK;
+ lfrac = (pll >> QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT) &
+ QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK;
+
+ cpu_pll = nint * ref_rate / ref_div;
+ cpu_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
+ cpu_pll += (hfrac >> 13) * ref_rate / ref_div;
+ cpu_pll /= (1 << out_div);
+
+ pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG_REG);
+ out_div = (pll >> QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK;
+ ref_div = (pll >> QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG_REFDIV_MASK;
+ pll = ath79_pll_rr(QCA956X_PLL_DDR_CONFIG1_REG);
+ nint = (pll >> QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG1_NINT_MASK;
+ hfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK;
+ lfrac = (pll >> QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT) &
+ QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK;
+
+ ddr_pll = nint * ref_rate / ref_div;
+ ddr_pll += (lfrac * ref_rate) / ((ref_div * 25) << 13);
+ ddr_pll += (hfrac >> 13) * ref_rate / ref_div;
+ ddr_pll /= (1 << out_div);
+
+ clk_ctrl = ath79_pll_rr(QCA956X_PLL_CLK_CTRL_REG);
+
+ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT) &
+ QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK;
+
+ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS)
+ cpu_rate = ref_rate;
+ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL)
+ cpu_rate = ddr_pll / (postdiv + 1);
+ else
+ cpu_rate = cpu_pll / (postdiv + 1);
+
+ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT) &
+ QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK;
+
+ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS)
+ ddr_rate = ref_rate;
+ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL)
+ ddr_rate = cpu_pll / (postdiv + 1);
+ else
+ ddr_rate = ddr_pll / (postdiv + 1);
+
+ postdiv = (clk_ctrl >> QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT) &
+ QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK;
+
+ if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS)
+ ahb_rate = ref_rate;
+ else if (clk_ctrl & QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL)
+ ahb_rate = ddr_pll / (postdiv + 1);
+ else
+ ahb_rate = cpu_pll / (postdiv + 1);
+
+ ath79_add_sys_clkdev("ref", ref_rate);
+ ath79_add_sys_clkdev("cpu", cpu_rate);
+ ath79_add_sys_clkdev("ddr", ddr_rate);
+ ath79_add_sys_clkdev("ahb", ahb_rate);
+
+ clk_add_alias("wdt", NULL, "ref", NULL);
+ clk_add_alias("uart", NULL, "ref", NULL);
+}
+
void __init ath79_clocks_init(void)
{
if (soc_is_ar71xx())
@@ -536,6 +630,8 @@ void __init ath79_clocks_init(void)
qca953x_clocks_init();
else if (soc_is_qca955x())
qca955x_clocks_init();
+ else if (soc_is_qca956x())
+ qca956x_clocks_init();
else
BUG();
}
--- a/arch/mips/ath79/common.c
+++ b/arch/mips/ath79/common.c
@@ -77,6 +77,8 @@ void ath79_device_reset_set(u32 mask)
reg = QCA953X_RESET_REG_RESET_MODULE;
else if (soc_is_qca955x())
reg = QCA955X_RESET_REG_RESET_MODULE;
+ else if (soc_is_qca956x())
+ reg = QCA956X_RESET_REG_RESET_MODULE;
else
panic("Reset register not defined for this SOC");
@@ -107,6 +109,8 @@ void ath79_device_reset_clear(u32 mask)
reg = QCA953X_RESET_REG_RESET_MODULE;
else if (soc_is_qca955x())
reg = QCA955X_RESET_REG_RESET_MODULE;
+ else if (soc_is_qca956x())
+ reg = QCA956X_RESET_REG_RESET_MODULE;
else
panic("Reset register not defined for this SOC");
--- a/arch/mips/ath79/dev-common.c
+++ b/arch/mips/ath79/dev-common.c
@@ -94,7 +94,8 @@ void __init ath79_register_uart(void)
soc_is_ar913x() ||
soc_is_ar934x() ||
soc_is_qca953x() ||
- soc_is_qca955x()) {
+ soc_is_qca955x() ||
+ soc_is_qca956x()) {
ath79_uart_data[0].uartclk = uart_clk_rate;
platform_device_register(&ath79_uart_device);
} else if (soc_is_ar933x()) {
--- a/arch/mips/ath79/dev-usb.c
+++ b/arch/mips/ath79/dev-usb.c
@@ -296,6 +296,19 @@ static void __init qca955x_usb_setup(voi
&ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
}
+static void __init qca956x_usb_setup(void)
+{
+ ath79_usb_register("ehci-platform", 0,
+ QCA956X_EHCI0_BASE, QCA956X_EHCI_SIZE,
+ ATH79_IP3_IRQ(0),
+ &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
+
+ ath79_usb_register("ehci-platform", 1,
+ QCA956X_EHCI1_BASE, QCA956X_EHCI_SIZE,
+ ATH79_IP3_IRQ(1),
+ &ath79_ehci_pdata_v2, sizeof(ath79_ehci_pdata_v2));
+}
+
void __init ath79_register_usb(void)
{
if (soc_is_ar71xx())
@@ -314,6 +327,8 @@ void __init ath79_register_usb(void)
qca953x_usb_setup();
else if (soc_is_qca955x())
qca955x_usb_setup();
+ else if (soc_is_qca9561())
+ qca956x_usb_setup();
else
BUG();
}
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -189,6 +189,24 @@ static void qca955x_wmac_setup(void)
ath79_wmac_data.is_clk_25mhz = true;
}
+static void qca956x_wmac_setup(void)
+{
+ u32 t;
+
+ ath79_wmac_device.name = "qca956x_wmac";
+
+ ath79_wmac_resources[0].start = QCA956X_WMAC_BASE;
+ ath79_wmac_resources[0].end = QCA956X_WMAC_BASE + QCA956X_WMAC_SIZE - 1;
+ ath79_wmac_resources[1].start = ATH79_IP2_IRQ(1);
+ ath79_wmac_resources[1].end = ATH79_IP2_IRQ(1);
+
+ t = ath79_reset_rr(QCA956X_RESET_REG_BOOTSTRAP);
+ if (t & QCA956X_BOOTSTRAP_REF_CLK_40)
+ ath79_wmac_data.is_clk_25mhz = false;
+ else
+ ath79_wmac_data.is_clk_25mhz = true;
+}
+
static bool __init
ar93xx_wmac_otp_read_word(void __iomem *base, int addr, u32 *data)
{
@@ -392,6 +410,8 @@ void __init ath79_register_wmac(u8 *cal_
qca953x_wmac_setup();
else if (soc_is_qca955x())
qca955x_wmac_setup();
+ else if (soc_is_qca956x())
+ qca956x_wmac_setup();
else
BUG();
--- a/arch/mips/ath79/early_printk.c
+++ b/arch/mips/ath79/early_printk.c
@@ -118,6 +118,8 @@ static void prom_putchar_init(void)
case REV_ID_MAJOR_QCA9533_V2:
case REV_ID_MAJOR_QCA9556:
case REV_ID_MAJOR_QCA9558:
+ case REV_ID_MAJOR_TP9343:
+ case REV_ID_MAJOR_QCA9561:
_prom_putchar = prom_putchar_ar71xx;
break;
--- a/arch/mips/ath79/gpio.c
+++ b/arch/mips/ath79/gpio.c
@@ -148,7 +148,8 @@ static void __iomem *ath79_gpio_get_func
soc_is_ar913x() ||
soc_is_ar933x())
reg = AR71XX_GPIO_REG_FUNC;
- else if (soc_is_ar934x() || soc_is_qca953x())
+ else if (soc_is_ar934x() ||
+ soc_is_qca953x() || soc_is_qca956x())
reg = AR934X_GPIO_REG_FUNC;
else
BUG();
@@ -228,12 +229,15 @@ void __init ath79_gpio_init(void)
ath79_gpio_count = QCA953X_GPIO_COUNT;
else if (soc_is_qca955x())
ath79_gpio_count = QCA955X_GPIO_COUNT;
+ else if (soc_is_qca956x())
+ ath79_gpio_count = QCA956X_GPIO_COUNT;
else
BUG();
ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
ath79_gpio_chip.ngpio = ath79_gpio_count;
- if (soc_is_ar934x() || soc_is_qca953x() || soc_is_qca955x()) {
+ if (soc_is_ar934x() || soc_is_qca953x() || soc_is_qca955x() ||
+ soc_is_qca956x()) {
ath79_gpio_chip.direction_input = ar934x_gpio_direction_input;
ath79_gpio_chip.direction_output = ar934x_gpio_direction_output;
}
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -107,7 +107,8 @@ static void __init ath79_misc_irq_init(v
soc_is_ar933x() ||
soc_is_ar934x() ||
soc_is_qca953x() ||
- soc_is_qca955x())
+ soc_is_qca955x() ||
+ soc_is_qca956x())
ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
else
BUG();
@@ -268,6 +269,97 @@ static void qca955x_irq_init(void)
irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch);
}
+static void qca956x_ip2_irq_dispatch(unsigned int irq, struct irq_desc *desc)
+{
+ u32 status;
+
+ disable_irq_nosync(irq);
+
+ status = ath79_reset_rr(QCA956X_RESET_REG_EXT_INT_STATUS);
+ status &= QCA956X_EXT_INT_PCIE_RC1_ALL | QCA956X_EXT_INT_WMAC_ALL;
+
+ if (status == 0) {
+ spurious_interrupt();
+ goto enable;
+ }
+
+ if (status & QCA956X_EXT_INT_PCIE_RC1_ALL) {
+ /* TODO: flush DDR? */
+ generic_handle_irq(ATH79_IP2_IRQ(0));
+ }
+
+ if (status & QCA956X_EXT_INT_WMAC_ALL) {
+ /* TODO: flsuh DDR? */
+ generic_handle_irq(ATH79_IP2_IRQ(1));
+ }
+
+enable:
+ enable_irq(irq);
+}
+
+static void qca956x_ip3_irq_dispatch(unsigned int irq, struct irq_desc *desc)
+{
+ u32 status;
+
+ disable_irq_nosync(irq);
+
+ status = ath79_reset_rr(QCA956X_RESET_REG_EXT_INT_STATUS);
+ status &= QCA956X_EXT_INT_PCIE_RC2_ALL |
+ QCA956X_EXT_INT_USB1 | QCA956X_EXT_INT_USB2;
+
+ if (status == 0) {
+ spurious_interrupt();
+ goto enable;
+ }
+
+ if (status & QCA956X_EXT_INT_USB1) {
+ /* TODO: flush DDR? */
+ generic_handle_irq(ATH79_IP3_IRQ(0));
+ }
+
+ if (status & QCA956X_EXT_INT_USB2) {
+ /* TODO: flush DDR? */
+ generic_handle_irq(ATH79_IP3_IRQ(1));
+ }
+
+ if (status & QCA956X_EXT_INT_PCIE_RC2_ALL) {
+ /* TODO: flush DDR? */
+ generic_handle_irq(ATH79_IP3_IRQ(2));
+ }
+
+enable:
+ enable_irq(irq);
+}
+
+static void qca956x_enable_timer_cb(void) {
+ u32 misc;
+
+ misc = ath79_reset_rr(AR71XX_RESET_REG_MISC_INT_ENABLE);
+ misc |= MISC_INT_MIPS_SI_TIMERINT_MASK;
+ ath79_reset_wr(AR71XX_RESET_REG_MISC_INT_ENABLE, misc);
+}
+
+static void qca956x_irq_init(void)
+{
+ int i;
+
+ for (i = ATH79_IP2_IRQ_BASE;
+ i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
+ irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq);
+
+ irq_set_chained_handler(ATH79_CPU_IRQ(2), qca956x_ip2_irq_dispatch);
+
+ for (i = ATH79_IP3_IRQ_BASE;
+ i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++)
+ irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq);
+
+ irq_set_chained_handler(ATH79_CPU_IRQ(3), qca956x_ip3_irq_dispatch);
+
+ /* QCA956x timer init workaround has to be applied right before setting
+ * up the clock. Else, there will be no jiffies */
+ late_time_init = &qca956x_enable_timer_cb;
+}
+
asmlinkage void plat_irq_dispatch(void)
{
unsigned long pending;
@@ -397,6 +489,9 @@ void __init arch_init_irq(void)
} else if (soc_is_qca955x()) {
ath79_ip2_handler = ath79_default_ip2_handler;
ath79_ip3_handler = ath79_default_ip3_handler;
+ } else if (soc_is_qca956x()) {
+ ath79_ip2_handler = ath79_default_ip2_handler;
+ ath79_ip3_handler = ath79_default_ip3_handler;
} else {
BUG();
}
@@ -411,4 +506,6 @@ void __init arch_init_irq(void)
qca953x_irq_init();
else if (soc_is_qca955x())
qca955x_irq_init();
+ else if (soc_is_qca956x())
+ qca956x_irq_init();
}
--- a/arch/mips/ath79/pci.c
+++ b/arch/mips/ath79/pci.c
@@ -68,6 +68,21 @@ static const struct ath79_pci_irq qca955
},
};
+static const struct ath79_pci_irq qca956x_pci_irq_map[] __initconst = {
+ {
+ .bus = 0,
+ .slot = 0,
+ .pin = 1,
+ .irq = ATH79_PCI_IRQ(0),
+ },
+ {
+ .bus = 1,
+ .slot = 0,
+ .pin = 1,
+ .irq = ATH79_PCI_IRQ(1),
+ },
+};
+
int __init pcibios_map_irq(const struct pci_dev *dev, uint8_t slot, uint8_t pin)
{
int irq = -1;
@@ -86,6 +101,9 @@ int __init pcibios_map_irq(const struct
} else if (soc_is_qca955x()) {
ath79_pci_irq_map = qca955x_pci_irq_map;
ath79_pci_nr_irqs = ARRAY_SIZE(qca955x_pci_irq_map);
+ } else if (soc_is_qca9561()) {
+ ath79_pci_irq_map = qca956x_pci_irq_map;
+ ath79_pci_nr_irqs = ARRAY_SIZE(qca956x_pci_irq_map);
} else {
pr_crit("pci %s: invalid irq map\n",
pci_name((struct pci_dev *) dev));
@@ -303,6 +321,15 @@ int __init ath79_register_pci(void)
QCA955X_PCI_MEM_SIZE,
1,
ATH79_IP3_IRQ(2));
+ } else if (soc_is_qca9561()) {
+ pdev = ath79_register_pci_ar724x(0,
+ QCA956X_PCI_CFG_BASE1,
+ QCA956X_PCI_CTRL_BASE1,
+ QCA956X_PCI_CRP_BASE1,
+ QCA956X_PCI_MEM_BASE1,
+ QCA956X_PCI_MEM_SIZE,
+ 1,
+ ATH79_IP3_IRQ(2));
} else {
/* No PCI support */
return -ENODEV;
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -175,14 +175,29 @@ static void __init ath79_detect_sys_type
rev = id & QCA955X_REV_ID_REVISION_MASK;
break;
+ case REV_ID_MAJOR_TP9343:
+ ath79_soc = ATH79_SOC_TP9343;
+ chip = "9343";
+ rev = id & QCA956X_REV_ID_REVISION_MASK;
+ break;
+
+ case REV_ID_MAJOR_QCA9561:
+ ath79_soc = ATH79_SOC_QCA9561;
+ chip = "9561";
+ rev = id & QCA956X_REV_ID_REVISION_MASK;
+ break;
+
default:
panic("ath79: unknown SoC, id:0x%08x", id);
}
ath79_soc_rev = rev;
- if (soc_is_qca953x() || soc_is_qca955x())
- sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s rev %u",
+ if (soc_is_qca953x() || soc_is_qca955x() || soc_is_qca9561())
+ sprintf(ath79_sys_type, "Qualcomm Atheros QCA%s ver %u rev %u",
+ chip, ver, rev);
+ else if (soc_is_tp9343())
+ sprintf(ath79_sys_type, "Qualcomm Atheros TP%s rev %u",
chip, rev);
else
sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev);
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -143,6 +143,23 @@
#define QCA955X_NFC_BASE 0x1b800200
#define QCA955X_NFC_SIZE 0xb8
+#define QCA956X_PCI_MEM_BASE1 0x12000000
+#define QCA956X_PCI_MEM_SIZE 0x02000000
+#define QCA956X_PCI_CFG_BASE1 0x16000000
+#define QCA956X_PCI_CFG_SIZE 0x1000
+#define QCA956X_PCI_CRP_BASE1 (AR71XX_APB_BASE + 0x00250000)
+#define QCA956X_PCI_CRP_SIZE 0x1000
+#define QCA956X_PCI_CTRL_BASE1 (AR71XX_APB_BASE + 0x00280000)
+#define QCA956X_PCI_CTRL_SIZE 0x100
+
+#define QCA956X_WMAC_BASE (AR71XX_APB_BASE + 0x00100000)
+#define QCA956X_WMAC_SIZE 0x20000
+#define QCA956X_EHCI0_BASE 0x1b000000
+#define QCA956X_EHCI1_BASE 0x1b400000
+#define QCA956X_EHCI_SIZE 0x200
+#define QCA956X_GMAC_BASE (AR71XX_APB_BASE + 0x00070000)
+#define QCA956X_GMAC_SIZE 0x64
+
#define AR9300_OTP_BASE 0x14000
#define AR9300_OTP_STATUS 0x15f18
#define AR9300_OTP_STATUS_TYPE 0x7
@@ -375,6 +392,49 @@
#define QCA955X_PLL_CLK_CTRL_DDRCLK_FROM_DDRPLL BIT(21)
#define QCA955X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+#define QCA956X_PLL_CPU_CONFIG_REG 0x00
+#define QCA956X_PLL_CPU_CONFIG1_REG 0x04
+#define QCA956X_PLL_DDR_CONFIG_REG 0x08
+#define QCA956X_PLL_DDR_CONFIG1_REG 0x0c
+#define QCA956X_PLL_CLK_CTRL_REG 0x10
+
+#define QCA956X_PLL_CPU_CONFIG_REFDIV_SHIFT 12
+#define QCA956X_PLL_CPU_CONFIG_REFDIV_MASK 0x1f
+#define QCA956X_PLL_CPU_CONFIG_OUTDIV_SHIFT 19
+#define QCA956X_PLL_CPU_CONFIG_OUTDIV_MASK 0x7
+
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_SHIFT 0
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_L_MASK 0x1f
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_SHIFT 5
+#define QCA956X_PLL_CPU_CONFIG1_NFRAC_H_MASK 0x3fff
+#define QCA956X_PLL_CPU_CONFIG1_NINT_SHIFT 18
+#define QCA956X_PLL_CPU_CONFIG1_NINT_MASK 0x1ff
+
+#define QCA956X_PLL_DDR_CONFIG_REFDIV_SHIFT 16
+#define QCA956X_PLL_DDR_CONFIG_REFDIV_MASK 0x1f
+#define QCA956X_PLL_DDR_CONFIG_OUTDIV_SHIFT 23
+#define QCA956X_PLL_DDR_CONFIG_OUTDIV_MASK 0x7
+
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_SHIFT 0
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_L_MASK 0x1f
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_SHIFT 5
+#define QCA956X_PLL_DDR_CONFIG1_NFRAC_H_MASK 0x3fff
+#define QCA956X_PLL_DDR_CONFIG1_NINT_SHIFT 18
+#define QCA956X_PLL_DDR_CONFIG1_NINT_MASK 0x1ff
+
+#define QCA956X_PLL_CLK_CTRL_CPU_PLL_BYPASS BIT(2)
+#define QCA956X_PLL_CLK_CTRL_DDR_PLL_BYPASS BIT(3)
+#define QCA956X_PLL_CLK_CTRL_AHB_PLL_BYPASS BIT(4)
+#define QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_SHIFT 5
+#define QCA956X_PLL_CLK_CTRL_CPU_POST_DIV_MASK 0x1f
+#define QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_SHIFT 10
+#define QCA956X_PLL_CLK_CTRL_DDR_POST_DIV_MASK 0x1f
+#define QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_SHIFT 15
+#define QCA956X_PLL_CLK_CTRL_AHB_POST_DIV_MASK 0x1f
+#define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_DDRPLL BIT(20)
+#define QCA956X_PLL_CLK_CTRL_CPU_DDRCLK_FROM_CPUPLL BIT(21)
+#define QCA956X_PLL_CLK_CTRL_AHBCLK_FROM_DDRPLL BIT(24)
+
/*
* USB_CONFIG block
*/
@@ -422,6 +482,11 @@
#define QCA955X_RESET_REG_BOOTSTRAP 0xb0
#define QCA955X_RESET_REG_EXT_INT_STATUS 0xac
+#define QCA956X_RESET_REG_RESET_MODULE 0x1c
+#define QCA956X_RESET_REG_BOOTSTRAP 0xb0
+#define QCA956X_RESET_REG_EXT_INT_STATUS 0xac
+
+#define MISC_INT_MIPS_SI_TIMERINT_MASK BIT(28)
#define MISC_INT_ETHSW BIT(12)
#define MISC_INT_TIMER4 BIT(10)
#define MISC_INT_TIMER3 BIT(9)
@@ -596,6 +661,8 @@
#define QCA955X_BOOTSTRAP_REF_CLK_40 BIT(4)
+#define QCA956X_BOOTSTRAP_REF_CLK_40 BIT(2)
+
#define AR934X_PCIE_WMAC_INT_WMAC_MISC BIT(0)
#define AR934X_PCIE_WMAC_INT_WMAC_TX BIT(1)
#define AR934X_PCIE_WMAC_INT_WMAC_RXLP BIT(2)
@@ -663,6 +730,37 @@
QCA955X_EXT_INT_PCIE_RC2_INT1 | QCA955X_EXT_INT_PCIE_RC2_INT2 | \
QCA955X_EXT_INT_PCIE_RC2_INT3)
+#define QCA956X_EXT_INT_WMAC_MISC BIT(0)
+#define QCA956X_EXT_INT_WMAC_TX BIT(1)
+#define QCA956X_EXT_INT_WMAC_RXLP BIT(2)
+#define QCA956X_EXT_INT_WMAC_RXHP BIT(3)
+#define QCA956X_EXT_INT_PCIE_RC1 BIT(4)
+#define QCA956X_EXT_INT_PCIE_RC1_INT0 BIT(5)
+#define QCA956X_EXT_INT_PCIE_RC1_INT1 BIT(6)
+#define QCA956X_EXT_INT_PCIE_RC1_INT2 BIT(7)
+#define QCA956X_EXT_INT_PCIE_RC1_INT3 BIT(8)
+#define QCA956X_EXT_INT_PCIE_RC2 BIT(12)
+#define QCA956X_EXT_INT_PCIE_RC2_INT0 BIT(13)
+#define QCA956X_EXT_INT_PCIE_RC2_INT1 BIT(14)
+#define QCA956X_EXT_INT_PCIE_RC2_INT2 BIT(15)
+#define QCA956X_EXT_INT_PCIE_RC2_INT3 BIT(16)
+#define QCA956X_EXT_INT_USB1 BIT(24)
+#define QCA956X_EXT_INT_USB2 BIT(28)
+
+#define QCA956X_EXT_INT_WMAC_ALL \
+ (QCA956X_EXT_INT_WMAC_MISC | QCA956X_EXT_INT_WMAC_TX | \
+ QCA956X_EXT_INT_WMAC_RXLP | QCA956X_EXT_INT_WMAC_RXHP)
+
+#define QCA956X_EXT_INT_PCIE_RC1_ALL \
+ (QCA956X_EXT_INT_PCIE_RC1 | QCA956X_EXT_INT_PCIE_RC1_INT0 | \
+ QCA956X_EXT_INT_PCIE_RC1_INT1 | QCA956X_EXT_INT_PCIE_RC1_INT2 | \
+ QCA956X_EXT_INT_PCIE_RC1_INT3)
+
+#define QCA956X_EXT_INT_PCIE_RC2_ALL \
+ (QCA956X_EXT_INT_PCIE_RC2 | QCA956X_EXT_INT_PCIE_RC2_INT0 | \
+ QCA956X_EXT_INT_PCIE_RC2_INT1 | QCA956X_EXT_INT_PCIE_RC2_INT2 | \
+ QCA956X_EXT_INT_PCIE_RC2_INT3)
+
#define REV_ID_MAJOR_MASK 0xfff0
#define REV_ID_MAJOR_AR71XX 0x00a0
#define REV_ID_MAJOR_AR913X 0x00b0
@@ -678,6 +776,8 @@
#define REV_ID_MAJOR_QCA9533_V2 0x0160
#define REV_ID_MAJOR_QCA9556 0x0130
#define REV_ID_MAJOR_QCA9558 0x1130
+#define REV_ID_MAJOR_TP9343 0x0150
+#define REV_ID_MAJOR_QCA9561 0x1150
#define AR71XX_REV_ID_MINOR_MASK 0x3
#define AR71XX_REV_ID_MINOR_AR7130 0x0
@@ -702,6 +802,8 @@
#define QCA955X_REV_ID_REVISION_MASK 0xf
+#define QCA956X_REV_ID_REVISION_MASK 0xf
+
/*
* SPI block
*/
@@ -766,6 +868,19 @@
#define QCA953X_GPIO_OUT_MUX_LED_LINK4 44
#define QCA953X_GPIO_OUT_MUX_LED_LINK5 45
+#define QCA956X_GPIO_REG_OUT_FUNC0 0x2c
+#define QCA956X_GPIO_REG_OUT_FUNC1 0x30
+#define QCA956X_GPIO_REG_OUT_FUNC2 0x34
+#define QCA956X_GPIO_REG_OUT_FUNC3 0x38
+#define QCA956X_GPIO_REG_OUT_FUNC4 0x3c
+#define QCA956X_GPIO_REG_OUT_FUNC5 0x40
+#define QCA956X_GPIO_REG_IN_ENABLE0 0x44
+#define QCA956X_GPIO_REG_IN_ENABLE3 0x50
+#define QCA956X_GPIO_REG_FUNC 0x6c
+
+#define QCA956X_GPIO_OUT_MUX_GE0_MDO 32
+#define QCA956X_GPIO_OUT_MUX_GE0_MDC 33
+
#define AR71XX_GPIO_COUNT 16
#define AR7240_GPIO_COUNT 18
#define AR7241_GPIO_COUNT 20
@@ -774,6 +889,7 @@
#define AR934X_GPIO_COUNT 23
#define QCA953X_GPIO_COUNT 18
#define QCA955X_GPIO_COUNT 24
+#define QCA956X_GPIO_COUNT 23
/*
* SRIF block
--- a/arch/mips/include/asm/mach-ath79/ath79.h
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -35,6 +35,8 @@ enum ath79_soc_type {
ATH79_SOC_QCA9533,
ATH79_SOC_QCA9556,
ATH79_SOC_QCA9558,
+ ATH79_SOC_TP9343,
+ ATH79_SOC_QCA9561,
};
extern enum ath79_soc_type ath79_soc;
@@ -126,6 +128,21 @@ static inline int soc_is_qca955x(void)
return soc_is_qca9556() || soc_is_qca9558();
}
+static inline int soc_is_tp9343(void)
+{
+ return ath79_soc == ATH79_SOC_TP9343;
+}
+
+static inline int soc_is_qca9561(void)
+{
+ return ath79_soc == ATH79_SOC_QCA9561;
+}
+
+static inline int soc_is_qca956x(void)
+{
+ return soc_is_tp9343() || soc_is_qca9561();
+}
+
extern void __iomem *ath79_ddr_base;
extern void __iomem *ath79_gpio_base;
extern void __iomem *ath79_pll_base;

View File

@ -0,0 +1,39 @@
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -566,6 +566,16 @@ config ATH79_MACH_R6100
select ATH79_DEV_USB
select ATH79_DEV_WMAC
+config ATH79_MACH_MC_MAC1200R
+ bool "MERCURY MAC1200R board support"
+ select SOC_AR934X
+ select ATH79_DEV_AP9X_PCI if PCI
+ select ATH79_DEV_ETH
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_M25P80
+ select ATH79_DEV_WMAC
+
config ATH79_MACH_RB4XX
bool "MikroTik RouterBOARD 4xx series support"
select SOC_AR71XX
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -79,6 +79,7 @@ obj-$(CONFIG_ATH79_MACH_HIWIFI_HC6361) +
obj-$(CONFIG_ATH79_MACH_JA76PF) += mach-ja76pf.o
obj-$(CONFIG_ATH79_MACH_JWAP003) += mach-jwap003.o
obj-$(CONFIG_ATH79_MACH_HORNET_UB) += mach-hornet-ub.o
+obj-$(CONFIG_ATH79_MACH_MC_MAC1200R) += mach-mc-mac1200r.o
obj-$(CONFIG_ATH79_MACH_MR600) += mach-mr600.o
obj-$(CONFIG_ATH79_MACH_MR900) += mach-mr900.o
obj-$(CONFIG_ATH79_MACH_MYNET_N600) += mach-mynet-n600.o
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -118,6 +118,7 @@ enum ath79_mach_type {
ATH79_MACH_TEW_673GRU, /* TRENDnet TEW-673GRU */
ATH79_MACH_TEW_712BR, /* TRENDnet TEW-712BR */
ATH79_MACH_TEW_732BR, /* TRENDnet TEW-732BR */
+ ATH79_MACH_MC_MAC1200R, /* MERCURY MAC1200R*/
ATH79_MACH_TL_MR10U, /* TP-LINK TL-MR10U */
ATH79_MACH_TL_MR11U, /* TP-LINK TL-MR11U */
ATH79_MACH_TL_MR13U, /* TP-LINK TL-MR13U */

View File

@ -0,0 +1,100 @@
--- a/arch/mips/ath79/irq.c
+++ b/arch/mips/ath79/irq.c
@@ -26,6 +26,8 @@
static void (*ath79_ip2_handler)(void);
static void (*ath79_ip3_handler)(void);
+static struct irq_chip ip2_chip;
+static struct irq_chip ip3_chip;
static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
{
@@ -149,8 +151,7 @@ static void ar934x_ip2_irq_init(void)
for (i = ATH79_IP2_IRQ_BASE;
i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
- irq_set_chip_and_handler(i, &dummy_irq_chip,
- handle_level_irq);
+ irq_set_chip_and_handler(i, &ip2_chip, handle_level_irq);
irq_set_chained_handler(ATH79_CPU_IRQ(2), ar934x_ip2_irq_dispatch);
}
@@ -182,7 +183,7 @@ static void qca953x_irq_init(void)
for (i = ATH79_IP2_IRQ_BASE;
i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
- irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq);
+ irq_set_chip_and_handler(i, &ip2_chip, handle_level_irq);
irq_set_chained_handler(ATH79_CPU_IRQ(2), qca953x_ip2_irq_dispatch);
}
@@ -256,15 +257,13 @@ static void qca955x_irq_init(void)
for (i = ATH79_IP2_IRQ_BASE;
i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
- irq_set_chip_and_handler(i, &dummy_irq_chip,
- handle_level_irq);
+ irq_set_chip_and_handler(i, &ip2_chip, handle_level_irq);
irq_set_chained_handler(ATH79_CPU_IRQ(2), qca955x_ip2_irq_dispatch);
for (i = ATH79_IP3_IRQ_BASE;
i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++)
- irq_set_chip_and_handler(i, &dummy_irq_chip,
- handle_level_irq);
+ irq_set_chip_and_handler(i, &ip3_chip, handle_level_irq);
irq_set_chained_handler(ATH79_CPU_IRQ(3), qca955x_ip3_irq_dispatch);
}
@@ -345,13 +344,13 @@ static void qca956x_irq_init(void)
for (i = ATH79_IP2_IRQ_BASE;
i < ATH79_IP2_IRQ_BASE + ATH79_IP2_IRQ_COUNT; i++)
- irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq);
+ irq_set_chip_and_handler(i, &ip2_chip, handle_level_irq);
irq_set_chained_handler(ATH79_CPU_IRQ(2), qca956x_ip2_irq_dispatch);
for (i = ATH79_IP3_IRQ_BASE;
i < ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT; i++)
- irq_set_chip_and_handler(i, &dummy_irq_chip, handle_level_irq);
+ irq_set_chip_and_handler(i, &ip3_chip, handle_level_irq);
irq_set_chained_handler(ATH79_CPU_IRQ(3), qca956x_ip3_irq_dispatch);
@@ -466,8 +465,35 @@ static void qca953x_ip3_handler(void)
do_IRQ(ATH79_CPU_IRQ(3));
}
+static void ath79_ip2_disable(struct irq_data *data)
+{
+ disable_irq(ATH79_CPU_IRQ(2));
+}
+
+static void ath79_ip2_enable(struct irq_data *data)
+{
+ enable_irq(ATH79_CPU_IRQ(2));
+}
+
+static void ath79_ip3_disable(struct irq_data *data)
+{
+ disable_irq(ATH79_CPU_IRQ(3));
+}
+
+static void ath79_ip3_enable(struct irq_data *data)
+{
+ enable_irq(ATH79_CPU_IRQ(3));
+}
+
void __init arch_init_irq(void)
{
+ ip2_chip = dummy_irq_chip;
+ ip3_chip = dummy_irq_chip;
+ ip2_chip.irq_disable = ath79_ip2_disable;
+ ip2_chip.irq_enable = ath79_ip2_enable;
+ ip3_chip.irq_disable = ath79_ip3_disable;
+ ip3_chip.irq_enable = ath79_ip3_enable;
+
if (soc_is_ar71xx()) {
ath79_ip2_handler = ar71xx_ip2_handler;
ath79_ip3_handler = ar71xx_ip3_handler;

View File

@ -0,0 +1,20 @@
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -85,6 +85,7 @@ enum ath79_mach_type {
ATH79_MACH_OM2P_LC, /* OpenMesh OM2P-LC */
ATH79_MACH_OM2Pv2, /* OpenMesh OM2Pv2 */
ATH79_MACH_OM2P, /* OpenMesh OM2P */
+ ATH79_MACH_OM5P_AN, /* OpenMesh OM5P-AN */
ATH79_MACH_OM5P, /* OpenMesh OM5P */
ATH79_MACH_PB42, /* Atheros PB42 */
ATH79_MACH_PB92, /* Atheros PB92 */
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -719,6 +719,7 @@ config ATH79_MACH_OM2P
config ATH79_MACH_OM5P
bool "OpenMesh OM5P board support"
select SOC_AR934X
+ select ATH79_DEV_AP9X_PCI if PCI
select ATH79_DEV_ETH
select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO

View File

@ -0,0 +1,51 @@
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -726,6 +726,26 @@ config ATH79_MACH_OM5P
select ATH79_DEV_M25P80
select ATH79_DEV_WMAC
+config ATH79_MACH_MR12
+ bool "Meraki MR12 board support"
+ select SOC_AR724X
+ select ATH79_DEV_AP9X_PCI if PCI
+ select ATH79_DEV_ETH
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_M25P80
+ select ATH79_DEV_WMAC
+
+config ATH79_MACH_MR16
+ bool "Meraki MR16 board support"
+ select SOC_AR71XX
+ select ATH79_DEV_AP9X_PCI if PCI
+ select ATH79_DEV_ETH
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_M25P80
+ select ATH79_DEV_WMAC
+
config ATH79_MACH_MR600
bool "OpenMesh MR600 board support"
select SOC_AR934X
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -80,6 +80,8 @@ obj-$(CONFIG_ATH79_MACH_JA76PF) += mach
obj-$(CONFIG_ATH79_MACH_JWAP003) += mach-jwap003.o
obj-$(CONFIG_ATH79_MACH_HORNET_UB) += mach-hornet-ub.o
obj-$(CONFIG_ATH79_MACH_MC_MAC1200R) += mach-mc-mac1200r.o
+obj-$(CONFIG_ATH79_MACH_MR12) += mach-mr12.o
+obj-$(CONFIG_ATH79_MACH_MR16) += mach-mr16.o
obj-$(CONFIG_ATH79_MACH_MR600) += mach-mr600.o
obj-$(CONFIG_ATH79_MACH_MR900) += mach-mr900.o
obj-$(CONFIG_ATH79_MACH_MYNET_N600) += mach-mynet-n600.o
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -69,6 +69,8 @@ enum ath79_mach_type {
ATH79_MACH_JA76PF2, /* jjPlus JA76PF2 */
ATH79_MACH_JWAP003, /* jjPlus JWAP003 */
ATH79_MACH_HORNET_UB, /* ALFA Networks Hornet-UB */
+ ATH79_MACH_MR12, /* Cisco Meraki MR12 */
+ ATH79_MACH_MR16, /* Cisco Meraki MR16 */
ATH79_MACH_MR600V2, /* OpenMesh MR600v2 */
ATH79_MACH_MR600, /* OpenMesh MR600 */
ATH79_MACH_MR900, /* OpenMesh MR900 */

View File

@ -0,0 +1,224 @@
--- a/arch/mips/ath79/gpio.c
+++ b/arch/mips/ath79/gpio.c
@@ -20,9 +20,14 @@
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/gpio.h>
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+
+#include <linux/of.h>
#include <asm/mach-ath79/ar71xx_regs.h>
#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/irq.h>
#include "common.h"
void __iomem *ath79_gpio_base;
@@ -31,6 +36,13 @@ EXPORT_SYMBOL_GPL(ath79_gpio_base);
static unsigned long ath79_gpio_count;
static DEFINE_SPINLOCK(ath79_gpio_lock);
+/*
+ * gpio_both_edge is a bitmask of which gpio pins need to have
+ * the detect priority flipped from the interrupt handler to
+ * emulate IRQ_TYPE_EDGE_BOTH.
+ */
+static unsigned long gpio_both_edge = 0;
+
static void __ath79_gpio_set_value(unsigned gpio, int value)
{
void __iomem *base = ath79_gpio_base;
@@ -209,6 +221,132 @@ void __init ath79_gpio_output_select(uns
spin_unlock_irqrestore(&ath79_gpio_lock, flags);
}
+static int ath79_gpio_irq_type(struct irq_data *d, unsigned type)
+{
+ int offset = d->irq - ATH79_GPIO_IRQ_BASE;
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+ unsigned long int_type;
+ unsigned long int_polarity;
+ unsigned long bit = (1 << offset);
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ int_type = __raw_readl(base + AR71XX_GPIO_REG_INT_TYPE);
+ int_polarity = __raw_readl(base + AR71XX_GPIO_REG_INT_POLARITY);
+
+ gpio_both_edge &= ~bit;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ int_type &= ~bit;
+ int_polarity |= bit;
+ break;
+
+ case IRQ_TYPE_EDGE_FALLING:
+ int_type &= ~bit;
+ int_polarity &= ~bit;
+ break;
+
+ case IRQ_TYPE_LEVEL_HIGH:
+ int_type |= bit;
+ int_polarity |= bit;
+ break;
+
+ case IRQ_TYPE_LEVEL_LOW:
+ int_type |= bit;
+ int_polarity &= ~bit;
+ break;
+
+ case IRQ_TYPE_EDGE_BOTH:
+ int_type |= bit;
+ /* set polarity based on current value */
+ if (gpio_get_value(offset)) {
+ int_polarity &= ~bit;
+ } else {
+ int_polarity |= bit;
+ }
+ /* flip this gpio in the interrupt handler */
+ gpio_both_edge |= bit;
+ break;
+
+ default:
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+ return -EINVAL;
+ }
+
+ __raw_writel(int_type, base + AR71XX_GPIO_REG_INT_TYPE);
+ __raw_writel(int_polarity, base + AR71XX_GPIO_REG_INT_POLARITY);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_INT_MODE) | (1 << offset),
+ base + AR71XX_GPIO_REG_INT_MODE);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_INT_ENABLE) & ~(1 << offset),
+ base + AR71XX_GPIO_REG_INT_ENABLE);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+ return 0;
+}
+
+static void ath79_gpio_irq_enable(struct irq_data *d)
+{
+ int offset = d->irq - ATH79_GPIO_IRQ_BASE;
+ void __iomem *base = ath79_gpio_base;
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_INT_ENABLE) | (1 << offset),
+ base + AR71XX_GPIO_REG_INT_ENABLE);
+}
+
+static void ath79_gpio_irq_disable(struct irq_data *d)
+{
+ int offset = d->irq - ATH79_GPIO_IRQ_BASE;
+ void __iomem *base = ath79_gpio_base;
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_INT_ENABLE) & ~(1 << offset),
+ base + AR71XX_GPIO_REG_INT_ENABLE);
+}
+
+static struct irq_chip ath79_gpio_irqchip = {
+ .name = "GPIO",
+ .irq_enable = ath79_gpio_irq_enable,
+ .irq_disable = ath79_gpio_irq_disable,
+ .irq_set_type = ath79_gpio_irq_type,
+};
+
+static irqreturn_t ath79_gpio_irq(int irq, void *dev)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long stat = __raw_readl(base + AR71XX_GPIO_REG_INT_PENDING);
+ int bit_num;
+
+ for_each_set_bit(bit_num, &stat, sizeof(stat) * BITS_PER_BYTE) {
+ unsigned long bit = BIT(bit_num);
+
+ if (bit & gpio_both_edge) {
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_INT_POLARITY) ^ bit,
+ base + AR71XX_GPIO_REG_INT_POLARITY);
+ }
+
+ generic_handle_irq(ATH79_GPIO_IRQ(bit_num));
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int __init ath79_gpio_irq_init(struct gpio_chip *chip)
+{
+ int irq;
+ int irq_base = ATH79_GPIO_IRQ_BASE;
+
+ for (irq = irq_base; irq < irq_base + chip->ngpio; irq++) {
+ irq_set_chip_data(irq, chip);
+ irq_set_chip_and_handler(irq, &ath79_gpio_irqchip, handle_simple_irq);
+ irq_set_noprobe(irq);
+ }
+
+ return 0;
+}
+
void __init ath79_gpio_init(void)
{
int err;
@@ -245,6 +383,10 @@ void __init ath79_gpio_init(void)
err = gpiochip_add(&ath79_gpio_chip);
if (err)
panic("cannot add AR71xx GPIO chip, error=%d", err);
+
+ ath79_gpio_irq_init(&ath79_gpio_chip);
+
+ request_irq(ATH79_MISC_IRQ(2), ath79_gpio_irq, 0, "ath79-gpio", NULL);
}
int gpio_get_value(unsigned gpio)
@@ -267,14 +409,22 @@ EXPORT_SYMBOL(gpio_set_value);
int gpio_to_irq(unsigned gpio)
{
- /* FIXME */
- return -EINVAL;
+ if (gpio > ath79_gpio_count) {
+ return -EINVAL;
+ }
+
+ return ATH79_GPIO_IRQ_BASE + gpio;
}
EXPORT_SYMBOL(gpio_to_irq);
int irq_to_gpio(unsigned irq)
{
- /* FIXME */
- return -EINVAL;
+ unsigned gpio = irq - ATH79_GPIO_IRQ_BASE;
+
+ if (gpio > ath79_gpio_count) {
+ return -EINVAL;
+ }
+
+ return gpio;
}
EXPORT_SYMBOL(irq_to_gpio);
--- a/arch/mips/include/asm/mach-ath79/irq.h
+++ b/arch/mips/include/asm/mach-ath79/irq.h
@@ -10,7 +10,7 @@
#define __ASM_MACH_ATH79_IRQ_H
#define MIPS_CPU_IRQ_BASE 0
-#define NR_IRQS 51
+#define NR_IRQS 83
#define ATH79_CPU_IRQ(_x) (MIPS_CPU_IRQ_BASE + (_x))
@@ -30,6 +30,10 @@
#define ATH79_IP3_IRQ_COUNT 3
#define ATH79_IP3_IRQ(_x) (ATH79_IP3_IRQ_BASE + (_x))
+#define ATH79_GPIO_IRQ_BASE (ATH79_IP3_IRQ_BASE + ATH79_IP3_IRQ_COUNT)
+#define ATH79_GPIO_IRQ_COUNT 32
+#define ATH79_GPIO_IRQ(_x) (ATH79_GPIO_IRQ_BASE + (_x))
+
#include_next <irq.h>
#endif /* __ASM_MACH_ATH79_IRQ_H */

View File

@ -0,0 +1,51 @@
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -601,6 +601,16 @@ config ATH79_MACH_RB91X
select ATH79_DEV_USB
select ATH79_ROUTERBOOT
+config ATH79_MACH_RB922
+ bool "MikroTik RouterBOARD 922 support"
+ select SOC_QCA955X
+ select ATH79_DEV_ETH
+ select ATH79_DEV_M25P80
+ select ATH79_DEV_NFC
+ select ATH79_DEV_USB
+ select ATH79_ROUTERBOOT
+ select RLE_DECOMPRESS
+
config ATH79_MACH_RB95X
bool "MikroTik RouterBOARD 95X support"
select SOC_AR934X
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -100,6 +100,7 @@ obj-$(CONFIG_ATH79_MACH_R6100) += mach-
obj-$(CONFIG_ATH79_MACH_RB4XX) += mach-rb4xx.o
obj-$(CONFIG_ATH79_MACH_RB750) += mach-rb750.o
obj-$(CONFIG_ATH79_MACH_RB91X) += mach-rb91x.o
+obj-$(CONFIG_ATH79_MACH_RB922) += mach-rb922.o
obj-$(CONFIG_ATH79_MACH_RB95X) += mach-rb95x.o
obj-$(CONFIG_ATH79_MACH_RB2011) += mach-rb2011.o
obj-$(CONFIG_ATH79_MACH_RBSXTLITE) += mach-rbsxtlite.o
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -107,6 +107,7 @@ enum ath79_mach_type {
ATH79_MACH_RB_750G_R3, /* MikroTik RouterBOARD 750GL */
ATH79_MACH_RB_751, /* MikroTik RouterBOARD 751 */
ATH79_MACH_RB_751G, /* Mikrotik RouterBOARD 751G */
+ ATH79_MACH_RB_922GS, /* Mikrotik RouterBOARD 911/922GS boards */
ATH79_MACH_RB_951G, /* Mikrotik RouterBOARD 951G */
ATH79_MACH_RB_951U, /* Mikrotik RouterBOARD 951Ui-2HnD */
ATH79_MACH_RB_2011G, /* Mikrotik RouterBOARD 2011UAS-2HnD */
--- a/arch/mips/ath79/prom.c
+++ b/arch/mips/ath79/prom.c
@@ -184,7 +184,8 @@ void __init prom_init(void)
if (strstr(arcs_cmdline, "board=750Gr3") ||
strstr(arcs_cmdline, "board=951G") ||
strstr(arcs_cmdline, "board=2011L") ||
- strstr(arcs_cmdline, "board=711Gr100"))
+ strstr(arcs_cmdline, "board=711Gr100") ||
+ strstr(arcs_cmdline, "board=922gs"))
ath79_prom_append_cmdline("console", "ttyS0,115200");
}

View File

@ -0,0 +1,24 @@
--- a/arch/mips/ath79/dev-wmac.c
+++ b/arch/mips/ath79/dev-wmac.c
@@ -398,6 +398,11 @@ void __init ath79_wmac_set_ext_lna_gpio(
ar934x_set_ext_lna_gpio(chain, gpio);
}
+void __init ath79_wmac_set_led_pin(int gpio)
+{
+ ath79_wmac_data.led_pin = gpio;
+}
+
void __init ath79_register_wmac(u8 *cal_data, u8 *mac_addr)
{
if (soc_is_ar913x())
--- a/arch/mips/ath79/dev-wmac.h
+++ b/arch/mips/ath79/dev-wmac.h
@@ -18,6 +18,7 @@ void ath79_wmac_disable_2ghz(void);
void ath79_wmac_disable_5ghz(void);
void ath79_wmac_set_tx_gain_buffalo(void);
void ath79_wmac_set_ext_lna_gpio(unsigned chain, int gpio);
+void ath79_wmac_set_led_pin(int gpio);
bool ar93xx_wmac_read_mac_address(u8 *dest);

View File

@ -0,0 +1,43 @@
--- a/arch/mips/ath79/common.h
+++ b/arch/mips/ath79/common.h
@@ -28,6 +28,7 @@ void ath79_gpio_function_enable(u32 mask
void ath79_gpio_function_disable(u32 mask);
void ath79_gpio_function_setup(u32 set, u32 clear);
void ath79_gpio_output_select(unsigned gpio, u8 val);
+int ath79_gpio_direction_select(unsigned gpio, bool oe);
void ath79_gpio_init(void);
#endif /* __ATH79_COMMON_H */
--- a/arch/mips/ath79/gpio.c
+++ b/arch/mips/ath79/gpio.c
@@ -130,6 +130,30 @@ static int ar934x_gpio_direction_output(
return 0;
}
+int ath79_gpio_direction_select(unsigned gpio, bool oe)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+ bool ieq_1 = (soc_is_ar934x() ||
+ soc_is_qca953x());
+
+ if (gpio >= ath79_gpio_count)
+ return -1;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ if ((ieq_1 && oe) || (!ieq_1 && !oe))
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << gpio),
+ base + AR71XX_GPIO_REG_OE);
+ else
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << gpio),
+ base + AR71XX_GPIO_REG_OE);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+
+ return 0;
+}
+
static struct gpio_chip ath79_gpio_chip = {
.label = "ath79",
.get = ath79_gpio_get_value,

View File

@ -0,0 +1,43 @@
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -104,6 +104,20 @@ config ATH79_MACH_AP136
Say 'Y' here if you want your kernel to support the
Atheros AP136 or AP135 reference boards.
+config ATH79_MACH_AP143
+ bool "Atheros AP143 reference board"
+ select SOC_QCA953X
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_SPI
+ select ATH79_DEV_USB
+ select ATH79_DEV_WMAC
+ select ATH79_DEV_ETH
+ select ATH79_DEV_M25P80
+ help
+ Say 'Y' here if you want your kernel to support the
+ Atheros AP143 reference board.
+
config ATH79_MACH_AP81
bool "Atheros AP81 reference board"
select SOC_AR913X
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_ATH79_MACH_AP113) += mach-
obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o
obj-$(CONFIG_ATH79_MACH_AP132) += mach-ap132.o
obj-$(CONFIG_ATH79_MACH_AP136) += mach-ap136.o
+obj-$(CONFIG_ATH79_MACH_AP143) += mach-ap143.o
obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o
obj-$(CONFIG_ATH79_MACH_AP83) += mach-ap83.o
obj-$(CONFIG_ATH79_MACH_AP96) += mach-ap96.o
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -28,6 +28,7 @@ enum ath79_mach_type {
ATH79_MACH_AP135_020, /* Atheros AP135-020 reference board */
ATH79_MACH_AP136_010, /* Atheros AP136-010 reference board */
ATH79_MACH_AP136_020, /* Atheros AP136-020 reference board */
+ ATH79_MACH_AP143, /* Atheros AP143 reference board */
ATH79_MACH_AP81, /* Atheros AP81 reference board */
ATH79_MACH_AP83, /* Atheros AP83 */
ATH79_MACH_AP96, /* Atheros AP96 */

View File

@ -0,0 +1,20 @@
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -165,16 +165,7 @@ static int mdiobb_read(struct mii_bus *b
ctrl->ops->set_mdio_dir(ctrl, 0);
- /* check the turnaround bit: the PHY should be driving it to zero */
- if (mdiobb_get_bit(ctrl) != 0) {
- /* PHY didn't drive TA low -- flush any bits it
- * may be trying to send.
- */
- for (i = 0; i < 32; i++)
- mdiobb_get_bit(ctrl);
-
- return 0xffff;
- }
+ mdiobb_get_bit(ctrl);
ret = mdiobb_get_num(ctrl, 16);
mdiobb_get_bit(ctrl);

View File

@ -0,0 +1,878 @@
--- a/arch/mips/include/asm/checksum.h
+++ b/arch/mips/include/asm/checksum.h
@@ -134,26 +134,30 @@ static inline __sum16 ip_fast_csum(const
const unsigned int *stop = word + ihl;
unsigned int csum;
int carry;
+ unsigned int w;
- csum = word[0];
- csum += word[1];
- carry = (csum < word[1]);
+ csum = net_hdr_word(word++);
+
+ w = net_hdr_word(word++);
+ csum += w;
+ carry = (csum < w);
csum += carry;
- csum += word[2];
- carry = (csum < word[2]);
+ w = net_hdr_word(word++);
+ csum += w;
+ carry = (csum < w);
csum += carry;
- csum += word[3];
- carry = (csum < word[3]);
+ w = net_hdr_word(word++);
+ csum += w;
+ carry = (csum < w);
csum += carry;
- word += 4;
do {
- csum += *word;
- carry = (csum < *word);
+ w = net_hdr_word(word++);
+ csum += w;
+ carry = (csum < w);
csum += carry;
- word++;
} while (word != stop);
return csum_fold(csum);
@@ -212,73 +216,6 @@ static inline __sum16 ip_compute_csum(co
return csum_fold(csum_partial(buff, len, 0));
}
-#define _HAVE_ARCH_IPV6_CSUM
-static __inline__ __sum16 csum_ipv6_magic(const struct in6_addr *saddr,
- const struct in6_addr *daddr,
- __u32 len, unsigned short proto,
- __wsum sum)
-{
- __wsum tmp;
-
- __asm__(
- " .set push # csum_ipv6_magic\n"
- " .set noreorder \n"
- " .set noat \n"
- " addu %0, %5 # proto (long in network byte order)\n"
- " sltu $1, %0, %5 \n"
- " addu %0, $1 \n"
-
- " addu %0, %6 # csum\n"
- " sltu $1, %0, %6 \n"
- " lw %1, 0(%2) # four words source address\n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 4(%2) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 8(%2) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 12(%2) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 0(%3) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 4(%3) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 8(%3) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " lw %1, 12(%3) \n"
- " addu %0, $1 \n"
- " addu %0, %1 \n"
- " sltu $1, %0, %1 \n"
-
- " addu %0, $1 # Add final carry\n"
- " .set pop"
- : "=&r" (sum), "=&r" (tmp)
- : "r" (saddr), "r" (daddr),
- "0" (htonl(len)), "r" (htonl(proto)), "r" (sum));
-
- return csum_fold(sum);
-}
-
#include <asm-generic/checksum.h>
#endif /* CONFIG_GENERIC_CSUM */
--- a/include/uapi/linux/ip.h
+++ b/include/uapi/linux/ip.h
@@ -102,7 +102,7 @@ struct iphdr {
__be32 saddr;
__be32 daddr;
/*The options start here. */
-};
+} __attribute__((packed, aligned(2)));
struct ip_auth_hdr {
--- a/include/uapi/linux/ipv6.h
+++ b/include/uapi/linux/ipv6.h
@@ -129,7 +129,7 @@ struct ipv6hdr {
struct in6_addr saddr;
struct in6_addr daddr;
-};
+} __attribute__((packed, aligned(2)));
/* index values for the variables in ipv6_devconf */
--- a/include/uapi/linux/tcp.h
+++ b/include/uapi/linux/tcp.h
@@ -54,7 +54,7 @@ struct tcphdr {
__be16 window;
__sum16 check;
__be16 urg_ptr;
-};
+} __attribute__((packed, aligned(2)));
/*
* The union cast uses a gcc extension to avoid aliasing problems
@@ -64,7 +64,7 @@ struct tcphdr {
union tcp_word_hdr {
struct tcphdr hdr;
__be32 words[5];
-};
+} __attribute__((packed, aligned(2)));
#define tcp_flag_word(tp) ( ((union tcp_word_hdr *)(tp))->words [3])
--- a/include/uapi/linux/udp.h
+++ b/include/uapi/linux/udp.h
@@ -24,7 +24,7 @@ struct udphdr {
__be16 dest;
__be16 len;
__sum16 check;
-};
+} __attribute__((packed, aligned(2)));
/* UDP socket options */
#define UDP_CORK 1 /* Never send partially complete segments */
--- a/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
+++ b/net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c
@@ -41,8 +41,8 @@ static bool ipv4_pkt_to_tuple(const stru
if (ap == NULL)
return false;
- tuple->src.u3.ip = ap[0];
- tuple->dst.u3.ip = ap[1];
+ tuple->src.u3.ip = net_hdr_word(ap++);
+ tuple->dst.u3.ip = net_hdr_word(ap);
return true;
}
--- a/include/uapi/linux/icmp.h
+++ b/include/uapi/linux/icmp.h
@@ -80,7 +80,7 @@ struct icmphdr {
__be16 mtu;
} frag;
} un;
-};
+} __attribute__((packed, aligned(2)));
/*
--- a/include/uapi/linux/in6.h
+++ b/include/uapi/linux/in6.h
@@ -42,7 +42,7 @@ struct in6_addr {
#define s6_addr16 in6_u.u6_addr16
#define s6_addr32 in6_u.u6_addr32
#endif
-};
+} __attribute__((packed, aligned(2)));
#endif /* __UAPI_DEF_IN6_ADDR */
#if __UAPI_DEF_SOCKADDR_IN6
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -39,6 +39,7 @@
#include <linux/ipsec.h>
#include <linux/times.h>
#include <linux/slab.h>
+#include <asm/unaligned.h>
#include <linux/uaccess.h>
#include <linux/ipv6.h>
#include <linux/icmpv6.h>
@@ -772,10 +773,10 @@ static void tcp_v6_send_response(struct
topt = (__be32 *)(t1 + 1);
if (tsecr) {
- *topt++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
- (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP);
- *topt++ = htonl(tsval);
- *topt++ = htonl(tsecr);
+ put_unaligned_be32((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+ (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP, topt++);
+ put_unaligned_be32(tsval, topt++);
+ put_unaligned_be32(tsecr, topt++);
}
#ifdef CONFIG_TCP_MD5SIG
--- a/include/linux/ipv6.h
+++ b/include/linux/ipv6.h
@@ -5,6 +5,7 @@
#define ipv6_optlen(p) (((p)->hdrlen+1) << 3)
#define ipv6_authlen(p) (((p)->hdrlen+2) << 2)
+
/*
* This structure contains configuration options per IPv6 link.
*/
--- a/net/ipv6/datagram.c
+++ b/net/ipv6/datagram.c
@@ -414,7 +414,7 @@ int ipv6_recv_error(struct sock *sk, str
ipv6_iface_scope_id(&sin->sin6_addr,
IP6CB(skb)->iif);
} else {
- ipv6_addr_set_v4mapped(*(__be32 *)(nh + serr->addr_offset),
+ ipv6_addr_set_v4mapped(net_hdr_word(nh + serr->addr_offset),
&sin->sin6_addr);
sin->sin6_scope_id = 0;
}
@@ -751,12 +751,12 @@ int ip6_datagram_send_ctl(struct net *ne
}
if (fl6->flowlabel&IPV6_FLOWINFO_MASK) {
- if ((fl6->flowlabel^*(__be32 *)CMSG_DATA(cmsg))&~IPV6_FLOWINFO_MASK) {
+ if ((fl6->flowlabel^net_hdr_word(CMSG_DATA(cmsg)))&~IPV6_FLOWINFO_MASK) {
err = -EINVAL;
goto exit_f;
}
}
- fl6->flowlabel = IPV6_FLOWINFO_MASK & *(__be32 *)CMSG_DATA(cmsg);
+ fl6->flowlabel = IPV6_FLOWINFO_MASK & net_hdr_word(CMSG_DATA(cmsg));
break;
case IPV6_2292HOPOPTS:
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -393,7 +393,7 @@ static void ip6gre_err(struct sk_buff *s
t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr,
flags & GRE_KEY ?
- *(((__be32 *)p) + (grehlen / 4) - 1) : 0,
+ net_hdr_word(((__be32 *)p) + (grehlen / 4) - 1) : 0,
p[1]);
if (!t)
return;
@@ -475,11 +475,11 @@ static int ip6gre_rcv(struct sk_buff *sk
offset += 4;
}
if (flags&GRE_KEY) {
- key = *(__be32 *)(h + offset);
+ key = net_hdr_word(h + offset);
offset += 4;
}
if (flags&GRE_SEQ) {
- seqno = ntohl(*(__be32 *)(h + offset));
+ seqno = ntohl(net_hdr_word(h + offset));
offset += 4;
}
}
@@ -744,7 +744,7 @@ static netdev_tx_t ip6gre_xmit2(struct s
if (tunnel->parms.o_flags&GRE_SEQ) {
++tunnel->o_seqno;
- *ptr = htonl(tunnel->o_seqno);
+ net_hdr_word(ptr) = htonl(tunnel->o_seqno);
ptr--;
}
if (tunnel->parms.o_flags&GRE_KEY) {
@@ -840,7 +840,7 @@ static inline int ip6gre_xmit_ipv6(struc
dsfield = ipv6_get_dsfield(ipv6h);
if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
- fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK);
+ fl6.flowlabel |= net_hdr_word(ipv6h) & IPV6_TCLASS_MASK;
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)
fl6.flowlabel |= ip6_flowlabel(ipv6h);
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1340,7 +1340,7 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, str
dsfield = ipv6_get_dsfield(ipv6h);
if (t->parms.flags & IP6_TNL_F_USE_ORIG_TCLASS)
- fl6.flowlabel |= (*(__be32 *) ipv6h & IPV6_TCLASS_MASK);
+ fl6.flowlabel |= net_hdr_word(ipv6h) & IPV6_TCLASS_MASK;
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FLOWLABEL)
fl6.flowlabel |= ip6_flowlabel(ipv6h);
if (t->parms.flags & IP6_TNL_F_USE_ORIG_FWMARK)
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -573,7 +573,7 @@ static bool ipv6_hop_jumbo(struct sk_buf
goto drop;
}
- pkt_len = ntohl(*(__be32 *)(nh + optoff + 2));
+ pkt_len = ntohl(net_hdr_word(nh + optoff + 2));
if (pkt_len <= IPV6_MAXPLEN) {
IP6_INC_STATS_BH(net, ipv6_skb_idev(skb),
IPSTATS_MIB_INHDRERRORS);
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -207,5 +207,11 @@ struct callback_head {
/* clocksource cycle base type */
typedef u64 cycle_t;
+struct net_hdr_word {
+ u32 words[1];
+} __attribute__((packed, aligned(2)));
+
+#define net_hdr_word(_p) (((struct net_hdr_word *) (_p))->words[0])
+
#endif /* __ASSEMBLY__ */
#endif /* _LINUX_TYPES_H */
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1323,8 +1323,8 @@ static struct sk_buff **inet_gro_receive
if (unlikely(ip_fast_csum((u8 *)iph, 5)))
goto out_unlock;
- id = ntohl(*(__be32 *)&iph->id);
- flush = (u16)((ntohl(*(__be32 *)iph) ^ skb_gro_len(skb)) | (id & ~IP_DF));
+ id = ntohl(net_hdr_word(&iph->id));
+ flush = (u16)((ntohl(net_hdr_word(iph)) ^ skb_gro_len(skb)) | (id & ~IP_DF));
id >>= 16;
for (p = *head; p; p = p->next) {
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -453,7 +453,7 @@ static struct neighbour *ipv4_neigh_look
else if (skb)
pkey = &ip_hdr(skb)->daddr;
- n = __ipv4_neigh_lookup(dev, *(__force u32 *)pkey);
+ n = __ipv4_neigh_lookup(dev, net_hdr_word(pkey));
if (n)
return n;
return neigh_create(&arp_tbl, pkey, dev);
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -452,48 +452,53 @@ static void tcp_options_write(__be32 *pt
u16 options = opts->options; /* mungable copy */
if (unlikely(OPTION_MD5 & options)) {
- *ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
- (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+ (TCPOPT_MD5SIG << 8) | TCPOLEN_MD5SIG);
/* overload cookie hash location */
opts->hash_location = (__u8 *)ptr;
ptr += 4;
}
if (unlikely(opts->mss)) {
- *ptr++ = htonl((TCPOPT_MSS << 24) |
- (TCPOLEN_MSS << 16) |
- opts->mss);
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_MSS << 24) | (TCPOLEN_MSS << 16) |
+ opts->mss);
}
if (likely(OPTION_TS & options)) {
if (unlikely(OPTION_SACK_ADVERTISE & options)) {
- *ptr++ = htonl((TCPOPT_SACK_PERM << 24) |
- (TCPOLEN_SACK_PERM << 16) |
- (TCPOPT_TIMESTAMP << 8) |
- TCPOLEN_TIMESTAMP);
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_SACK_PERM << 24) |
+ (TCPOLEN_SACK_PERM << 16) |
+ (TCPOPT_TIMESTAMP << 8) |
+ TCPOLEN_TIMESTAMP);
options &= ~OPTION_SACK_ADVERTISE;
} else {
- *ptr++ = htonl((TCPOPT_NOP << 24) |
- (TCPOPT_NOP << 16) |
- (TCPOPT_TIMESTAMP << 8) |
- TCPOLEN_TIMESTAMP);
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_NOP << 24) |
+ (TCPOPT_NOP << 16) |
+ (TCPOPT_TIMESTAMP << 8) |
+ TCPOLEN_TIMESTAMP);
}
- *ptr++ = htonl(opts->tsval);
- *ptr++ = htonl(opts->tsecr);
+ net_hdr_word(ptr++) = htonl(opts->tsval);
+ net_hdr_word(ptr++) = htonl(opts->tsecr);
}
if (unlikely(OPTION_SACK_ADVERTISE & options)) {
- *ptr++ = htonl((TCPOPT_NOP << 24) |
- (TCPOPT_NOP << 16) |
- (TCPOPT_SACK_PERM << 8) |
- TCPOLEN_SACK_PERM);
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_NOP << 24) |
+ (TCPOPT_NOP << 16) |
+ (TCPOPT_SACK_PERM << 8) |
+ TCPOLEN_SACK_PERM);
}
if (unlikely(OPTION_WSCALE & options)) {
- *ptr++ = htonl((TCPOPT_NOP << 24) |
- (TCPOPT_WINDOW << 16) |
- (TCPOLEN_WINDOW << 8) |
- opts->ws);
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_NOP << 24) |
+ (TCPOPT_WINDOW << 16) |
+ (TCPOLEN_WINDOW << 8) |
+ opts->ws);
}
if (unlikely(opts->num_sack_blocks)) {
@@ -501,16 +506,17 @@ static void tcp_options_write(__be32 *pt
tp->duplicate_sack : tp->selective_acks;
int this_sack;
- *ptr++ = htonl((TCPOPT_NOP << 24) |
- (TCPOPT_NOP << 16) |
- (TCPOPT_SACK << 8) |
- (TCPOLEN_SACK_BASE + (opts->num_sack_blocks *
+ net_hdr_word(ptr++) =
+ htonl((TCPOPT_NOP << 24) |
+ (TCPOPT_NOP << 16) |
+ (TCPOPT_SACK << 8) |
+ (TCPOLEN_SACK_BASE + (opts->num_sack_blocks *
TCPOLEN_SACK_PERBLOCK)));
for (this_sack = 0; this_sack < opts->num_sack_blocks;
++this_sack) {
- *ptr++ = htonl(sp[this_sack].start_seq);
- *ptr++ = htonl(sp[this_sack].end_seq);
+ net_hdr_word(ptr++) = htonl(sp[this_sack].start_seq);
+ net_hdr_word(ptr++) = htonl(sp[this_sack].end_seq);
}
tp->rx_opt.dsack = 0;
@@ -523,13 +529,14 @@ static void tcp_options_write(__be32 *pt
if (foc->exp) {
len = TCPOLEN_EXP_FASTOPEN_BASE + foc->len;
- *ptr = htonl((TCPOPT_EXP << 24) | (len << 16) |
+ net_hdr_word(ptr) =
+ htonl((TCPOPT_EXP << 24) | (len << 16) |
TCPOPT_FASTOPEN_MAGIC);
p += TCPOLEN_EXP_FASTOPEN_BASE;
} else {
len = TCPOLEN_FASTOPEN_BASE + foc->len;
- *p++ = TCPOPT_FASTOPEN;
- *p++ = len;
+ net_hdr_word(p++) = TCPOPT_FASTOPEN;
+ net_hdr_word(p++) = len;
}
memcpy(p, foc->val, foc->len);
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -496,7 +496,7 @@ static struct sk_buff *add_grec(struct s
if (!skb)
return NULL;
psrc = (__be32 *)skb_put(skb, sizeof(__be32));
- *psrc = psf->sf_inaddr;
+ net_hdr_word(psrc) = psf->sf_inaddr;
scount++; stotal++;
if ((type == IGMPV3_ALLOW_NEW_SOURCES ||
type == IGMPV3_BLOCK_OLD_SOURCES) && psf->sf_crcount) {
--- a/include/uapi/linux/igmp.h
+++ b/include/uapi/linux/igmp.h
@@ -32,7 +32,7 @@ struct igmphdr {
__u8 code; /* For newer IGMP */
__sum16 csum;
__be32 group;
-};
+} __attribute__((packed, aligned(2)));
/* V3 group record types [grec_type] */
#define IGMPV3_MODE_IS_INCLUDE 1
@@ -48,7 +48,7 @@ struct igmpv3_grec {
__be16 grec_nsrcs;
__be32 grec_mca;
__be32 grec_src[0];
-};
+} __attribute__((packed, aligned(2)));
struct igmpv3_report {
__u8 type;
@@ -57,7 +57,7 @@ struct igmpv3_report {
__be16 resv2;
__be16 ngrec;
struct igmpv3_grec grec[0];
-};
+} __attribute__((packed, aligned(2)));
struct igmpv3_query {
__u8 type;
@@ -78,7 +78,7 @@ struct igmpv3_query {
__u8 qqic;
__be16 nsrcs;
__be32 srcs[0];
-};
+} __attribute__((packed, aligned(2)));
#define IGMP_HOST_MEMBERSHIP_QUERY 0x11 /* From RFC1112 */
#define IGMP_HOST_MEMBERSHIP_REPORT 0x12 /* Ditto */
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -53,7 +53,7 @@ __be32 __skb_flow_get_ports(const struct
ports = __skb_header_pointer(skb, thoff + poff,
sizeof(_ports), data, hlen, &_ports);
if (ports)
- return *ports;
+ return (__be32)net_hdr_word(ports);
}
return 0;
--- a/include/uapi/linux/icmpv6.h
+++ b/include/uapi/linux/icmpv6.h
@@ -76,7 +76,7 @@ struct icmp6hdr {
#define icmp6_addrconf_other icmp6_dataun.u_nd_ra.other
#define icmp6_rt_lifetime icmp6_dataun.u_nd_ra.rt_lifetime
#define icmp6_router_pref icmp6_dataun.u_nd_ra.router_pref
-};
+} __attribute__((packed, aligned(2)));
#define ICMPV6_ROUTER_PREF_LOW 0x3
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -76,7 +76,7 @@ struct ra_msg {
struct icmp6hdr icmph;
__be32 reachable_time;
__be32 retrans_timer;
-};
+} __attribute__((packed, aligned(2)));
struct rd_msg {
struct icmp6hdr icmph;
@@ -148,10 +148,10 @@ static inline u32 ndisc_hashfn(const voi
{
const u32 *p32 = pkey;
- return (((p32[0] ^ hash32_ptr(dev)) * hash_rnd[0]) +
- (p32[1] * hash_rnd[1]) +
- (p32[2] * hash_rnd[2]) +
- (p32[3] * hash_rnd[3]));
+ return (((net_hdr_word(&p32[0]) ^ hash32_ptr(dev)) * hash_rnd[0]) +
+ (net_hdr_word(&p32[1]) * hash_rnd[1]) +
+ (net_hdr_word(&p32[2]) * hash_rnd[2]) +
+ (net_hdr_word(&p32[3]) * hash_rnd[3]));
}
static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey)
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -151,7 +151,7 @@ next_knode:
data = skb_header_pointer(skb, toff, 4, &hdata);
if (!data)
goto out;
- if ((*data ^ key->val) & key->mask) {
+ if ((net_hdr_word(data) ^ key->val) & key->mask) {
n = rcu_dereference_bh(n->next);
goto next_knode;
}
@@ -204,8 +204,8 @@ check_terminal:
&hdata);
if (!data)
goto out;
- sel = ht->divisor & u32_hash_fold(*data, &n->sel,
- n->fshift);
+ sel = ht->divisor & u32_hash_fold(net_hdr_word(data),
+ &n->sel, n->fshift);
}
if (!(n->sel.flags & (TC_U32_VAROFFSET | TC_U32_OFFSET | TC_U32_EAT)))
goto next_ht;
--- a/net/ipv6/ip6_offload.c
+++ b/net/ipv6/ip6_offload.c
@@ -221,7 +221,7 @@ static struct sk_buff **ipv6_gro_receive
continue;
iph2 = (struct ipv6hdr *)(p->data + off);
- first_word = *(__be32 *)iph ^ *(__be32 *)iph2;
+ first_word = net_hdr_word(iph) ^ net_hdr_word(iph2);
/* All fields must match except length and Traffic Class.
* XXX skbs on the gro_list have all been parsed and pulled
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -43,7 +43,7 @@ struct prefix_info {
__be32 reserved2;
struct in6_addr prefix;
-};
+} __attribute__((packed, aligned(2)));
#include <linux/netdevice.h>
--- a/include/net/inet_ecn.h
+++ b/include/net/inet_ecn.h
@@ -115,13 +115,13 @@ static inline int IP6_ECN_set_ce(struct
{
if (INET_ECN_is_not_ect(ipv6_get_dsfield(iph)))
return 0;
- *(__be32*)iph |= htonl(INET_ECN_CE << 20);
+ net_hdr_word(iph) |= htonl(INET_ECN_CE << 20);
return 1;
}
static inline void IP6_ECN_clear(struct ipv6hdr *iph)
{
- *(__be32*)iph &= ~htonl(INET_ECN_MASK << 20);
+ net_hdr_word(iph) &= ~htonl(INET_ECN_MASK << 20);
}
static inline void ipv6_copy_dscp(unsigned int dscp, struct ipv6hdr *inner)
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -107,7 +107,7 @@ struct frag_hdr {
__u8 reserved;
__be16 frag_off;
__be32 identification;
-};
+} __attribute__((packed, aligned(2)));
#define IP6_MF 0x0001
#define IP6_OFFSET 0xFFF8
@@ -396,8 +396,8 @@ static inline void __ipv6_addr_set_half(
}
#endif
#endif
- addr[0] = wh;
- addr[1] = wl;
+ net_hdr_word(&addr[0]) = wh;
+ net_hdr_word(&addr[1]) = wl;
}
static inline void ipv6_addr_set(struct in6_addr *addr,
@@ -456,6 +456,8 @@ static inline bool ipv6_prefix_equal(con
const __be32 *a1 = addr1->s6_addr32;
const __be32 *a2 = addr2->s6_addr32;
unsigned int pdw, pbi;
+ /* Used for last <32-bit fraction of prefix */
+ u32 pbia1, pbia2;
/* check complete u32 in prefix */
pdw = prefixlen >> 5;
@@ -464,7 +466,9 @@ static inline bool ipv6_prefix_equal(con
/* check incomplete u32 in prefix */
pbi = prefixlen & 0x1f;
- if (pbi && ((a1[pdw] ^ a2[pdw]) & htonl((0xffffffff) << (32 - pbi))))
+ pbia1 = net_hdr_word(&a1[pdw]);
+ pbia2 = net_hdr_word(&a2[pdw]);
+ if (pbi && ((pbia1 ^ pbia2) & htonl((0xffffffff) << (32 - pbi))))
return false;
return true;
@@ -607,13 +611,13 @@ static inline void ipv6_addr_set_v4mappe
*/
static inline int __ipv6_addr_diff32(const void *token1, const void *token2, int addrlen)
{
- const __be32 *a1 = token1, *a2 = token2;
+ const struct in6_addr *a1 = token1, *a2 = token2;
int i;
addrlen >>= 2;
for (i = 0; i < addrlen; i++) {
- __be32 xb = a1[i] ^ a2[i];
+ __be32 xb = a1->s6_addr32[i] ^ a2->s6_addr32[i];
if (xb)
return i * 32 + 31 - __fls(ntohl(xb));
}
@@ -739,17 +743,18 @@ static inline __be32 ip6_make_flowlabel(
static inline void ip6_flow_hdr(struct ipv6hdr *hdr, unsigned int tclass,
__be32 flowlabel)
{
- *(__be32 *)hdr = htonl(0x60000000 | (tclass << 20)) | flowlabel;
+ net_hdr_word((__be32 *)hdr) =
+ htonl(0x60000000 | (tclass << 20)) | flowlabel;
}
static inline __be32 ip6_flowinfo(const struct ipv6hdr *hdr)
{
- return *(__be32 *)hdr & IPV6_FLOWINFO_MASK;
+ return net_hdr_word((__be32 *)hdr) & IPV6_FLOWINFO_MASK;
}
static inline __be32 ip6_flowlabel(const struct ipv6hdr *hdr)
{
- return *(__be32 *)hdr & IPV6_FLOWLABEL_MASK;
+ return net_hdr_word((__be32 *)hdr) & IPV6_FLOWLABEL_MASK;
}
static inline u8 ip6_tclass(__be32 flowinfo)
--- a/include/net/secure_seq.h
+++ b/include/net/secure_seq.h
@@ -2,6 +2,7 @@
#define _NET_SECURE_SEQ
#include <linux/types.h>
+#include <linux/in6.h>
u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
--- a/include/uapi/linux/in.h
+++ b/include/uapi/linux/in.h
@@ -81,7 +81,7 @@ enum {
/* Internet address. */
struct in_addr {
__be32 s_addr;
-};
+} __attribute__((packed, aligned(2)));
#endif
#define IP_TOS 1
--- a/net/core/secure_seq.c
+++ b/net/core/secure_seq.c
@@ -46,11 +46,12 @@ __u32 secure_tcpv6_sequence_number(const
u32 secret[MD5_MESSAGE_BYTES / 4];
u32 hash[MD5_DIGEST_WORDS];
u32 i;
+ const struct in6_addr *daddr6 = (struct in6_addr *) daddr;
net_secret_init();
memcpy(hash, saddr, 16);
for (i = 0; i < 4; i++)
- secret[i] = net_secret[i] + (__force u32)daddr[i];
+ secret[i] = net_secret[i] + (__force u32)daddr6->s6_addr32[i];
secret[4] = net_secret[4] +
(((__force u16)sport << 16) + (__force u16)dport);
for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++)
@@ -68,11 +69,12 @@ u32 secure_ipv6_port_ephemeral(const __b
u32 secret[MD5_MESSAGE_BYTES / 4];
u32 hash[MD5_DIGEST_WORDS];
u32 i;
+ const struct in6_addr *daddr6 = (struct in6_addr *) daddr;
net_secret_init();
memcpy(hash, saddr, 16);
for (i = 0; i < 4; i++)
- secret[i] = net_secret[i] + (__force u32) daddr[i];
+ secret[i] = net_secret[i] + (__force u32) daddr6->s6_addr32[i];
secret[4] = net_secret[4] + (__force u32)dport;
for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++)
secret[i] = net_secret[i];
@@ -150,11 +152,12 @@ u64 secure_dccpv6_sequence_number(__be32
u32 hash[MD5_DIGEST_WORDS];
u64 seq;
u32 i;
+ const struct in6_addr *daddr6 = (struct in6_addr *) daddr;
net_secret_init();
memcpy(hash, saddr, 16);
for (i = 0; i < 4; i++)
- secret[i] = net_secret[i] + daddr[i];
+ secret[i] = net_secret[i] + daddr6->s6_addr32[i];
secret[4] = net_secret[4] +
(((__force u16)sport << 16) + (__force u16)dport);
for (i = 5; i < MD5_MESSAGE_BYTES / 4; i++)
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -137,7 +137,7 @@ static __be32 addr_bit_set(const void *t
* See include/asm-generic/bitops/le.h.
*/
return (__force __be32)(1 << ((~fn_bit ^ BITOP_BE32_SWIZZLE) & 0x1f)) &
- addr[fn_bit >> 5];
+ net_hdr_word(&addr[fn_bit >> 5]);
}
static struct fib6_node *node_alloc(void)
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -456,7 +456,7 @@ static void tcp_sack(const struct sk_buf
/* Fast path for timestamp-only option */
if (length == TCPOLEN_TSTAMP_ALIGNED
- && *(__be32 *)ptr == htonl((TCPOPT_NOP << 24)
+ && net_hdr_word(ptr) == htonl((TCPOPT_NOP << 24)
| (TCPOPT_NOP << 16)
| (TCPOPT_TIMESTAMP << 8)
| TCPOLEN_TIMESTAMP))
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -154,8 +154,8 @@ int xfrm_parse_spi(struct sk_buff *skb,
if (!pskb_may_pull(skb, hlen))
return -EINVAL;
- *spi = *(__be32 *)(skb_transport_header(skb) + offset);
- *seq = *(__be32 *)(skb_transport_header(skb) + offset_seq);
+ *spi = net_hdr_word(skb_transport_header(skb) + offset);
+ *seq = net_hdr_word(skb_transport_header(skb) + offset_seq);
return 0;
}
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -3760,14 +3760,16 @@ static bool tcp_parse_aligned_timestamp(
{
const __be32 *ptr = (const __be32 *)(th + 1);
- if (*ptr == htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16)
- | (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
+ if (net_hdr_word(ptr) ==
+ htonl((TCPOPT_NOP << 24) | (TCPOPT_NOP << 16) |
+ (TCPOPT_TIMESTAMP << 8) | TCPOLEN_TIMESTAMP)) {
tp->rx_opt.saw_tstamp = 1;
++ptr;
- tp->rx_opt.rcv_tsval = ntohl(*ptr);
+ tp->rx_opt.rcv_tsval = get_unaligned_be32(ptr);
++ptr;
- if (*ptr)
- tp->rx_opt.rcv_tsecr = ntohl(*ptr) - tp->tsoffset;
+ if (net_hdr_word(ptr))
+ tp->rx_opt.rcv_tsecr = get_unaligned_be32(ptr) -
+ tp->tsoffset;
else
tp->rx_opt.rcv_tsecr = 0;
return true;
--- a/include/uapi/linux/if_pppox.h
+++ b/include/uapi/linux/if_pppox.h
@@ -47,6 +47,7 @@ struct pppoe_addr {
*/
struct pptp_addr {
__u16 call_id;
+ __u16 pad;
struct in_addr sin_addr;
};
--- a/net/ipv6/netfilter/nf_log_ipv6.c
+++ b/net/ipv6/netfilter/nf_log_ipv6.c
@@ -66,9 +66,9 @@ static void dump_ipv6_packet(struct nf_l
/* Max length: 44 "LEN=65535 TC=255 HOPLIMIT=255 FLOWLBL=FFFFF " */
nf_log_buf_add(m, "LEN=%Zu TC=%u HOPLIMIT=%u FLOWLBL=%u ",
ntohs(ih->payload_len) + sizeof(struct ipv6hdr),
- (ntohl(*(__be32 *)ih) & 0x0ff00000) >> 20,
+ (ntohl(net_hdr_word(ih)) & 0x0ff00000) >> 20,
ih->hop_limit,
- (ntohl(*(__be32 *)ih) & 0x000fffff));
+ (ntohl(net_hdr_word(ih)) & 0x000fffff));
fragment = 0;
ptr = ip6hoff + sizeof(struct ipv6hdr);

View File

@ -0,0 +1,56 @@
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -174,6 +174,7 @@ enum ath79_mach_type {
ATH79_MACH_UBNT_NANO_M, /* Ubiquiti NanoStation M */
ATH79_MACH_UBNT_NANO_M_XW, /* Ubiquiti NanoStation M XW */
ATH79_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */
+ ATH79_MACH_UBNT_ROCKET_M_XW, /* Ubiquiti Rocket M XW*/
ATH79_MACH_UBNT_RSPRO, /* Ubiquiti RouterStation Pro */
ATH79_MACH_UBNT_RS, /* Ubiquiti RouterStation */
ATH79_MACH_UBNT_UAP_PRO, /* Ubiquiti UniFi AP Pro */
--- a/arch/mips/ath79/mach-ubnt-xm.c
+++ b/arch/mips/ath79/mach-ubnt-xm.c
@@ -449,12 +449,43 @@ static void __init ubnt_loco_m_xw_setup(
ath79_register_eth(0);
}
+static void __init ubnt_rocket_m_xw_setup(void)
+{
+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000);
+
+ ath79_register_m25p80(NULL);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_xw_leds_gpio),
+ ubnt_xw_leds_gpio);
+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(ubnt_xm_gpio_keys),
+ ubnt_xm_gpio_keys);
+
+ ath79_register_wmac(eeprom + UAP_PRO_WMAC_CALDATA_OFFSET, NULL);
+ ap91_pci_init(eeprom + UAP_PRO_PCI_CALDATA_OFFSET, NULL);
+
+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0);
+ ath79_init_mac(ath79_eth0_data.mac_addr,
+ eeprom + UAP_PRO_MAC0_OFFSET, 0);
+
+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev;
+
+ ath79_register_mdio(0, ~BIT(4));
+ ath79_eth0_data.phy_mask = BIT(4);
+ ath79_eth0_pll_data.pll_1000 = 0x06000000;
+ ath79_register_eth(0);
+}
+
MIPS_MACHINE(ATH79_MACH_UBNT_NANO_M_XW, "UBNT-NM-XW", "Ubiquiti Nanostation M XW",
ubnt_nano_m_xw_setup);
MIPS_MACHINE(ATH79_MACH_UBNT_LOCO_M_XW, "UBNT-LOCO-XW", "Ubiquiti Loco M XW",
ubnt_loco_m_xw_setup);
+MIPS_MACHINE(ATH79_MACH_UBNT_ROCKET_M_XW, "UBNT-RM-XW", "Ubiquiti Rocket M XW",
+ ubnt_rocket_m_xw_setup);
+
static struct gpio_led ubnt_airgateway_gpio_leds[] __initdata = {
{
.name = "ubnt:blue:wlan",

View File

@ -0,0 +1,39 @@
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -21,6 +21,7 @@ enum ath79_mach_type {
ATH79_MACH_ALL0258N, /* Allnet ALL0258N */
ATH79_MACH_ALL0305, /* Allnet ALL0305 */
ATH79_MACH_ALL0315N, /* Allnet ALL0315N */
+ ATH79_MACH_ANTMINER_S1, /* Bitmain Antminer S1 */
ATH79_MACH_AP113, /* Atheros AP113 reference board */
ATH79_MACH_AP121, /* Atheros AP121 reference board */
ATH79_MACH_AP121_MINI, /* Atheros AP121-MINI reference board */
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -56,6 +56,16 @@ config ATH79_MACH_ALL0315N
select ATH79_DEV_LEDS_GPIO
select ATH79_DEV_M25P80
+config ATH79_MACH_ANTMINER_S1
+ bool "Bitmain Antminer S1 support"
+ select SOC_AR933X
+ select ATH79_DEV_ETH
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_M25P80
+ select ATH79_DEV_USB
+ select ATH79_DEV_WMAC
+
config ATH79_MACH_AP113
bool "Atheros AP113 board support"
select SOC_AR724X
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_ATH79_MACH_ALFA_AP96) += ma
obj-$(CONFIG_ATH79_MACH_ALFA_NX) += mach-alfa-nx.o
obj-$(CONFIG_ATH79_MACH_ALL0258N) += mach-all0258n.o
obj-$(CONFIG_ATH79_MACH_ALL0315N) += mach-all0315n.o
+obj-$(CONFIG_ATH79_MACH_ANTMINER_S1)+= mach-antminer-s1.o
obj-$(CONFIG_ATH79_MACH_AP113) += mach-ap113.o
obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o
obj-$(CONFIG_ATH79_MACH_AP132) += mach-ap132.o

View File

@ -0,0 +1,135 @@
--- a/arch/mips/ath79/mach-ubnt-xm.c
+++ b/arch/mips/ath79/mach-ubnt-xm.c
@@ -21,6 +21,8 @@
#include <asm/mach-ath79/irq.h>
#include <asm/mach-ath79/ar71xx_regs.h>
+#include <linux/platform_data/phy-at803x.h>
+
#include "common.h"
#include "dev-ap9x-pci.h"
#include "dev-eth.h"
@@ -404,6 +406,40 @@ static struct gpio_led ubnt_xw_leds_gpio
},
};
+#define UBNT_ROCKET_TI_GPIO_LED_L1 16
+#define UBNT_ROCKET_TI_GPIO_LED_L2 17
+#define UBNT_ROCKET_TI_GPIO_LED_L3 18
+#define UBNT_ROCKET_TI_GPIO_LED_L4 19
+#define UBNT_ROCKET_TI_GPIO_LED_L5 20
+#define UBNT_ROCKET_TI_GPIO_LED_L6 21
+static struct gpio_led ubnt_rocket_ti_leds_gpio[] __initdata = {
+ {
+ .name = "ubnt:green:link1",
+ .gpio = UBNT_ROCKET_TI_GPIO_LED_L1,
+ .active_low = 1,
+ }, {
+ .name = "ubnt:green:link2",
+ .gpio = UBNT_ROCKET_TI_GPIO_LED_L2,
+ .active_low = 1,
+ }, {
+ .name = "ubnt:green:link3",
+ .gpio = UBNT_ROCKET_TI_GPIO_LED_L3,
+ .active_low = 1,
+ }, {
+ .name = "ubnt:green:link4",
+ .gpio = UBNT_ROCKET_TI_GPIO_LED_L4,
+ .active_low = 0,
+ }, {
+ .name = "ubnt:green:link5",
+ .gpio = UBNT_ROCKET_TI_GPIO_LED_L5,
+ .active_low = 0,
+ }, {
+ .name = "ubnt:green:link6",
+ .gpio = UBNT_ROCKET_TI_GPIO_LED_L6,
+ .active_low = 0,
+ },
+};
+
static void __init ubnt_xw_init(void)
{
u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000);
@@ -477,6 +513,62 @@ static void __init ubnt_rocket_m_xw_setu
ath79_register_eth(0);
}
+static struct at803x_platform_data ubnt_rocket_m_ti_at803_data = {
+ .disable_smarteee = 1,
+ .enable_rgmii_rx_delay = 1,
+ .enable_rgmii_tx_delay = 1,
+};
+static struct mdio_board_info ubnt_rocket_m_ti_mdio_info[] = {
+ {
+ .bus_id = "ag71xx-mdio.0",
+ .phy_addr = 4,
+ .platform_data = &ubnt_rocket_m_ti_at803_data,
+ },
+};
+
+static void __init ubnt_rocket_m_ti_setup(void)
+{
+ u8 *eeprom = (u8 *) KSEG1ADDR(0x1fff0000);
+
+ ath79_register_m25p80(NULL);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ubnt_rocket_ti_leds_gpio),
+ ubnt_rocket_ti_leds_gpio);
+ ath79_register_gpio_keys_polled(-1, UBNT_XM_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(ubnt_xm_gpio_keys),
+ ubnt_xm_gpio_keys);
+
+ ap91_pci_init(eeprom + 0x1000, NULL);
+
+ ath79_setup_ar934x_eth_cfg(AR934X_ETH_CFG_RGMII_GMAC0);
+ ath79_setup_ar934x_eth_rx_delay(3, 3);
+ ath79_init_mac(ath79_eth0_data.mac_addr,
+ eeprom + UAP_PRO_MAC0_OFFSET, 0);
+ ath79_init_mac(ath79_eth1_data.mac_addr,
+ eeprom + UAP_PRO_MAC1_OFFSET, 0);
+
+ ath79_eth0_data.phy_if_mode = PHY_INTERFACE_MODE_RGMII;
+ ath79_eth0_data.mii_bus_dev = &ath79_mdio0_device.dev;
+ ath79_eth1_data.phy_if_mode = PHY_INTERFACE_MODE_GMII;
+ ath79_eth1_data.mii_bus_dev = &ath79_mdio1_device.dev;
+
+ mdiobus_register_board_info(ubnt_rocket_m_ti_mdio_info,
+ ARRAY_SIZE(ubnt_rocket_m_ti_mdio_info));
+ ath79_register_mdio(0, 0x0);
+
+
+ ath79_eth0_data.phy_mask = BIT(4);
+ /* read out from vendor */
+ ath79_eth0_pll_data.pll_1000 = 0x2000000;
+ ath79_eth0_pll_data.pll_10 = 0x1313;
+ ath79_register_eth(0);
+
+ ath79_register_mdio(1, 0x0);
+ ath79_eth1_data.phy_mask = BIT(3);
+ ath79_register_eth(1);
+}
+
+
MIPS_MACHINE(ATH79_MACH_UBNT_NANO_M_XW, "UBNT-NM-XW", "Ubiquiti Nanostation M XW",
ubnt_nano_m_xw_setup);
@@ -486,6 +578,9 @@ MIPS_MACHINE(ATH79_MACH_UBNT_LOCO_M_XW,
MIPS_MACHINE(ATH79_MACH_UBNT_ROCKET_M_XW, "UBNT-RM-XW", "Ubiquiti Rocket M XW",
ubnt_rocket_m_xw_setup);
+MIPS_MACHINE(ATH79_MACH_UBNT_ROCKET_M_TI, "UBNT-RM-TI", "Ubiquiti Rocket M TI",
+ ubnt_rocket_m_ti_setup);
+
static struct gpio_led ubnt_airgateway_gpio_leds[] __initdata = {
{
.name = "ubnt:blue:wlan",
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -176,6 +176,7 @@ enum ath79_mach_type {
ATH79_MACH_UBNT_NANO_M_XW, /* Ubiquiti NanoStation M XW */
ATH79_MACH_UBNT_ROCKET_M, /* Ubiquiti Rocket M */
ATH79_MACH_UBNT_ROCKET_M_XW, /* Ubiquiti Rocket M XW*/
+ ATH79_MACH_UBNT_ROCKET_M_TI, /* Ubiquiti Rocket M TI*/
ATH79_MACH_UBNT_RSPRO, /* Ubiquiti RouterStation Pro */
ATH79_MACH_UBNT_RS, /* Ubiquiti RouterStation */
ATH79_MACH_UBNT_UAP_PRO, /* Ubiquiti UniFi AP Pro */

View File

@ -0,0 +1,61 @@
From 66e584435ac0de6e0abeb6d7166fe4fe25d6bb73 Mon Sep 17 00:00:00 2001
From: Jonas Gorski <jogo@openwrt.org>
Date: Tue, 16 Jun 2015 13:15:08 +0200
Subject: [PATCH] phy/mdio-bitbang: prevent rescheduling during command
It seems some phys have some maximum timings for accessing the MDIO line,
resulting in bit errors under cpu stress. Prevent this from happening by
disabling interrupts when sending commands.
Signed-off-by: Jonas Gorski <jogo@openwrt.org>
---
drivers/net/phy/mdio-bitbang.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/drivers/net/phy/mdio-bitbang.c
+++ b/drivers/net/phy/mdio-bitbang.c
@@ -17,6 +17,7 @@
* kind, whether express or implied.
*/
+#include <linux/irqflags.h>
#include <linux/module.h>
#include <linux/mdio-bitbang.h>
#include <linux/types.h>
@@ -156,7 +157,9 @@ static int mdiobb_read(struct mii_bus *b
{
struct mdiobb_ctrl *ctrl = bus->priv;
int ret, i;
+ long flags;
+ local_irq_save(flags);
if (reg & MII_ADDR_C45) {
reg = mdiobb_cmd_addr(ctrl, phy, reg);
mdiobb_cmd(ctrl, MDIO_C45_READ, phy, reg);
@@ -169,13 +172,17 @@ static int mdiobb_read(struct mii_bus *b
ret = mdiobb_get_num(ctrl, 16);
mdiobb_get_bit(ctrl);
+ local_irq_restore(flags);
+
return ret;
}
static int mdiobb_write(struct mii_bus *bus, int phy, int reg, u16 val)
{
struct mdiobb_ctrl *ctrl = bus->priv;
+ long flags;
+ local_irq_save(flags);
if (reg & MII_ADDR_C45) {
reg = mdiobb_cmd_addr(ctrl, phy, reg);
mdiobb_cmd(ctrl, MDIO_C45_WRITE, phy, reg);
@@ -190,6 +197,8 @@ static int mdiobb_write(struct mii_bus *
ctrl->ops->set_mdio_dir(ctrl, 0);
mdiobb_get_bit(ctrl);
+ local_irq_restore(flags);
+
return 0;
}

View File

@ -0,0 +1,39 @@
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -22,6 +22,7 @@ enum ath79_mach_type {
ATH79_MACH_ALL0305, /* Allnet ALL0305 */
ATH79_MACH_ALL0315N, /* Allnet ALL0315N */
ATH79_MACH_ANTMINER_S1, /* Bitmain Antminer S1 */
+ ATH79_MACH_ANTMINER_S3, /* Bitmain Antminer S3 */
ATH79_MACH_AP113, /* Atheros AP113 reference board */
ATH79_MACH_AP121, /* Atheros AP121 reference board */
ATH79_MACH_AP121_MINI, /* Atheros AP121-MINI reference board */
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -66,6 +66,16 @@ config ATH79_MACH_ANTMINER_S1
select ATH79_DEV_USB
select ATH79_DEV_WMAC
+config ATH79_MACH_ANTMINER_S3
+ bool "Bitmain Antminer S3 support"
+ select SOC_AR933X
+ select ATH79_DEV_ETH
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_M25P80
+ select ATH79_DEV_USB
+ select ATH79_DEV_WMAC
+
config ATH79_MACH_AP113
bool "Atheros AP113 board support"
select SOC_AR724X
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -43,6 +43,7 @@ obj-$(CONFIG_ATH79_MACH_ALFA_NX) += mach
obj-$(CONFIG_ATH79_MACH_ALL0258N) += mach-all0258n.o
obj-$(CONFIG_ATH79_MACH_ALL0315N) += mach-all0315n.o
obj-$(CONFIG_ATH79_MACH_ANTMINER_S1)+= mach-antminer-s1.o
+obj-$(CONFIG_ATH79_MACH_ANTMINER_S3)+= mach-antminer-s3.o
obj-$(CONFIG_ATH79_MACH_AP113) += mach-ap113.o
obj-$(CONFIG_ATH79_MACH_AP121) += mach-ap121.o
obj-$(CONFIG_ATH79_MACH_AP132) += mach-ap132.o