* [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs
@ 2010-12-22 20:30 Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 01/16] MIPS: add initial support for the Atheros AR71XX/AR724X/AR931X SoCs Gabor Juhos
` (15 more replies)
0 siblings, 16 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos
This patch set contains initial support for the
Atheros AR71XX/AR724X/AR913X SoCs.
Generic changes since v1:
- rebased against 2.6.37-rc7
- the 'MIPS: Add generic support for multiple machines within a single kernel'
patch has been removed, because that is in the mips-queue tree already
- the 'input: add input driver for polled GPIO buttons' patch has been removed,
because a slightly different version of that driver is present in 2.6.37-rc7
already as 'gpio_keys_polled'
Gabor Juhos (16):
MIPS: add initial support for the Atheros AR71XX/AR724X/AR931X SoCs
MIPS: ath79: add GPIOLIB support
MIPS: ath79: utilize the MIPS multi-machine support
MIPS: ath79: add initial support for the Atheros PB44 reference board
MIPS: ath79: add common GPIO LEDs device
watchdog: add driver for the Atheros AR71XX/AR724X/AR913X SoCs
MIPS: ath79: add common watchdog device
MIPS: ath79: add common GPIO buttons device
spi: add SPI controller driver for the Atheros AR71XX/AR724X/AR913X
SoCs
MIPS: ath79: add common SPI controller device
USB: ehci: add workaround for Synopsys HC bug
USB: ehci: add bus glue for the Atheros AR71XX/AR724X/AR913X SoCs
USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs
MIPS: ath79: add common USB Host Controller device
MIPS: ath79: add initial support for the Atheros AP81 reference board
MIPS: ath79: add common WMAC device for AR913X based boards
arch/mips/Kbuild.platforms | 1 +
arch/mips/Kconfig | 17 ++
arch/mips/ath79/Kconfig | 60 ++++
arch/mips/ath79/Makefile | 29 ++
arch/mips/ath79/Platform | 7 +
arch/mips/ath79/common.c | 97 +++++++
arch/mips/ath79/common.h | 30 ++
arch/mips/ath79/dev-ar913x-wmac.c | 60 ++++
arch/mips/ath79/dev-ar913x-wmac.h | 17 ++
arch/mips/ath79/dev-common.c | 69 +++++
arch/mips/ath79/dev-common.h | 18 ++
arch/mips/ath79/dev-gpio-buttons.c | 58 ++++
arch/mips/ath79/dev-gpio-buttons.h | 23 ++
arch/mips/ath79/dev-leds-gpio.c | 56 ++++
arch/mips/ath79/dev-leds-gpio.h | 21 ++
arch/mips/ath79/dev-spi.c | 38 +++
arch/mips/ath79/dev-spi.h | 22 ++
arch/mips/ath79/dev-usb.c | 194 +++++++++++++
arch/mips/ath79/dev-usb.h | 17 ++
arch/mips/ath79/early_printk.c | 36 +++
arch/mips/ath79/gpio.c | 197 +++++++++++++
arch/mips/ath79/irq.c | 187 +++++++++++++
arch/mips/ath79/mach-ap81.c | 100 +++++++
arch/mips/ath79/mach-pb44.c | 120 ++++++++
arch/mips/ath79/machtypes.h | 23 ++
arch/mips/ath79/prom.c | 57 ++++
arch/mips/ath79/setup.c | 279 +++++++++++++++++++
arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 253 +++++++++++++++++
arch/mips/include/asm/mach-ath79/ath79.h | 100 +++++++
.../include/asm/mach-ath79/ath79_ehci_platform.h | 18 ++
.../include/asm/mach-ath79/ath79_spi_platform.h | 19 ++
.../include/asm/mach-ath79/cpu-feature-overrides.h | 56 ++++
arch/mips/include/asm/mach-ath79/gpio.h | 26 ++
arch/mips/include/asm/mach-ath79/irq.h | 36 +++
.../include/asm/mach-ath79/kernel-entry-init.h | 32 +++
arch/mips/include/asm/mach-ath79/war.h | 25 ++
drivers/spi/Kconfig | 8 +
drivers/spi/Makefile | 1 +
drivers/spi/ath79_spi.c | 290 +++++++++++++++++++
drivers/usb/host/Kconfig | 16 +
drivers/usb/host/ehci-ath79.c | 176 ++++++++++++
drivers/usb/host/ehci-hcd.c | 5 +
drivers/usb/host/ehci-q.c | 3 +
drivers/usb/host/ehci.h | 1 +
drivers/usb/host/ohci-ath79.c | 162 +++++++++++
drivers/usb/host/ohci-hcd.c | 5 +
drivers/watchdog/Kconfig | 8 +
drivers/watchdog/Makefile | 1 +
drivers/watchdog/ath79_wdt.c | 293 ++++++++++++++++++++
49 files changed, 3367 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/ath79/Kconfig
create mode 100644 arch/mips/ath79/Makefile
create mode 100644 arch/mips/ath79/Platform
create mode 100644 arch/mips/ath79/common.c
create mode 100644 arch/mips/ath79/common.h
create mode 100644 arch/mips/ath79/dev-ar913x-wmac.c
create mode 100644 arch/mips/ath79/dev-ar913x-wmac.h
create mode 100644 arch/mips/ath79/dev-common.c
create mode 100644 arch/mips/ath79/dev-common.h
create mode 100644 arch/mips/ath79/dev-gpio-buttons.c
create mode 100644 arch/mips/ath79/dev-gpio-buttons.h
create mode 100644 arch/mips/ath79/dev-leds-gpio.c
create mode 100644 arch/mips/ath79/dev-leds-gpio.h
create mode 100644 arch/mips/ath79/dev-spi.c
create mode 100644 arch/mips/ath79/dev-spi.h
create mode 100644 arch/mips/ath79/dev-usb.c
create mode 100644 arch/mips/ath79/dev-usb.h
create mode 100644 arch/mips/ath79/early_printk.c
create mode 100644 arch/mips/ath79/gpio.c
create mode 100644 arch/mips/ath79/irq.c
create mode 100644 arch/mips/ath79/mach-ap81.c
create mode 100644 arch/mips/ath79/mach-pb44.c
create mode 100644 arch/mips/ath79/machtypes.h
create mode 100644 arch/mips/ath79/prom.c
create mode 100644 arch/mips/ath79/setup.c
create mode 100644 arch/mips/include/asm/mach-ath79/ar71xx_regs.h
create mode 100644 arch/mips/include/asm/mach-ath79/ath79.h
create mode 100644 arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h
create mode 100644 arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
create mode 100644 arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
create mode 100644 arch/mips/include/asm/mach-ath79/gpio.h
create mode 100644 arch/mips/include/asm/mach-ath79/irq.h
create mode 100644 arch/mips/include/asm/mach-ath79/kernel-entry-init.h
create mode 100644 arch/mips/include/asm/mach-ath79/war.h
create mode 100644 drivers/spi/ath79_spi.c
create mode 100644 drivers/usb/host/ehci-ath79.c
create mode 100644 drivers/usb/host/ohci-ath79.c
create mode 100644 drivers/watchdog/ath79_wdt.c
--
1.7.2.1
^ permalink raw reply [flat|nested] 21+ messages in thread
* [PATCH v2 01/16] MIPS: add initial support for the Atheros AR71XX/AR724X/AR931X SoCs
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
@ 2010-12-22 20:30 ` Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 02/16] MIPS: ath79: add GPIOLIB support Gabor Juhos
` (14 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos
This patch adds initial support for various Atheros SoCs based on the
MIPS 24Kc core. The following models are supported at the moment:
- AR7130
- AR7141
- AR7161
- AR9130
- AR9132
- AR7240
- AR7241
- AR7242
The current patch contains minimal support only, but the resulting
kernel can boot into user-space with using of an initramfs image on
various boards which are using these SoCs. Support for more built-in
devices and individual boards will be implemented in further patches.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC:
- the ATH79_DEV_UART Kconfig option is removed, and the URT platform
code has been moved into dev-common[ch]
Changes since v1:
- ath79_device_{start,stop} has been renamed to ath79_device_reset_{set,clear}
to to reflect the purpose of these functions better
- some definitions has been moved from 'arch/mips/ath79/common.h' to
'arch/mips/include/asm/mach-ath79/ath79.h' to make them available for
future drivers
- rebased against 2.6.37-rc7
arch/mips/Kbuild.platforms | 1 +
arch/mips/Kconfig | 15 ++
arch/mips/ath79/Kconfig | 12 +
arch/mips/ath79/Makefile | 18 ++
arch/mips/ath79/Platform | 7 +
arch/mips/ath79/common.c | 97 +++++++
arch/mips/ath79/common.h | 25 ++
arch/mips/ath79/dev-common.c | 59 +++++
arch/mips/ath79/dev-common.h | 17 ++
arch/mips/ath79/early_printk.c | 36 +++
arch/mips/ath79/irq.c | 187 ++++++++++++++
arch/mips/ath79/prom.c | 57 +++++
arch/mips/ath79/setup.c | 263 ++++++++++++++++++++
arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 207 +++++++++++++++
arch/mips/include/asm/mach-ath79/ath79.h | 100 ++++++++
.../include/asm/mach-ath79/cpu-feature-overrides.h | 56 ++++
arch/mips/include/asm/mach-ath79/irq.h | 36 +++
.../include/asm/mach-ath79/kernel-entry-init.h | 32 +++
arch/mips/include/asm/mach-ath79/war.h | 25 ++
19 files changed, 1250 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/ath79/Kconfig
create mode 100644 arch/mips/ath79/Makefile
create mode 100644 arch/mips/ath79/Platform
create mode 100644 arch/mips/ath79/common.c
create mode 100644 arch/mips/ath79/common.h
create mode 100644 arch/mips/ath79/dev-common.c
create mode 100644 arch/mips/ath79/dev-common.h
create mode 100644 arch/mips/ath79/early_printk.c
create mode 100644 arch/mips/ath79/irq.c
create mode 100644 arch/mips/ath79/prom.c
create mode 100644 arch/mips/ath79/setup.c
create mode 100644 arch/mips/include/asm/mach-ath79/ar71xx_regs.h
create mode 100644 arch/mips/include/asm/mach-ath79/ath79.h
create mode 100644 arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
create mode 100644 arch/mips/include/asm/mach-ath79/irq.h
create mode 100644 arch/mips/include/asm/mach-ath79/kernel-entry-init.h
create mode 100644 arch/mips/include/asm/mach-ath79/war.h
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index 78439b8..7ff9b54 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -2,6 +2,7 @@
platforms += alchemy
platforms += ar7
+platforms += ath79
platforms += bcm47xx
platforms += bcm63xx
platforms += cavium-octeon
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 913d50d..c0511d6 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -65,6 +65,20 @@ config AR7
Support for the Texas Instruments AR7 System-on-a-Chip
family: TNETD7100, 7200 and 7300.
+config ATH79
+ bool "Atheros AR71XX/AR724X/AR913X based boards"
+ select BOOT_RAW
+ select CEVT_R4K
+ select CSRC_R4K
+ select DMA_NONCOHERENT
+ select IRQ_CPU
+ select SYS_HAS_CPU_MIPS32_R2
+ select SYS_HAS_EARLY_PRINTK
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ help
+ Support for the Atheros AR71XX/AR724X/AR913X SoCs.
+
config BCM47XX
bool "Broadcom BCM47XX based boards"
select CEVT_R4K
@@ -717,6 +731,7 @@ config CAVIUM_OCTEON_REFERENCE_BOARD
endchoice
source "arch/mips/alchemy/Kconfig"
+source "arch/mips/ath79/Kconfig"
source "arch/mips/bcm63xx/Kconfig"
source "arch/mips/jazz/Kconfig"
source "arch/mips/jz4740/Kconfig"
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
new file mode 100644
index 0000000..50b9334
--- /dev/null
+++ b/arch/mips/ath79/Kconfig
@@ -0,0 +1,12 @@
+if ATH79
+
+config SOC_AR71XX
+ def_bool n
+
+config SOC_AR724X
+ def_bool n
+
+config SOC_AR913X
+ def_bool n
+
+endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
new file mode 100644
index 0000000..b4ec9c2
--- /dev/null
+++ b/arch/mips/ath79/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for the Atheros AR71XX/AR724X/AR913X specific parts of the kernel
+#
+# Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+# Copyright (C) 2008 Imre Kaloz <kaloz@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.
+
+obj-y := prom.o setup.o irq.o common.o
+
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
+
+#
+# Devices
+#
+obj-y += dev-common.o
diff --git a/arch/mips/ath79/Platform b/arch/mips/ath79/Platform
new file mode 100644
index 0000000..2bd6636
--- /dev/null
+++ b/arch/mips/ath79/Platform
@@ -0,0 +1,7 @@
+#
+# Atheros AR71xx/AR724x/AR913x
+#
+
+platform-$(CONFIG_ATH79) += ath79/
+cflags-$(CONFIG_ATH79) += -I$(srctree)/arch/mips/include/asm/mach-ath79
+load-$(CONFIG_ATH79) = 0xffffffff80060000
diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c
new file mode 100644
index 0000000..58f60e7
--- /dev/null
+++ b/arch/mips/ath79/common.c
@@ -0,0 +1,97 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common routines
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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/types.h>
+#include <linux/spinlock.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+
+static DEFINE_SPINLOCK(ath79_device_reset_lock);
+
+u32 ath79_cpu_freq;
+EXPORT_SYMBOL_GPL(ath79_cpu_freq);
+
+u32 ath79_ahb_freq;
+EXPORT_SYMBOL_GPL(ath79_ahb_freq);
+
+u32 ath79_ddr_freq;
+EXPORT_SYMBOL_GPL(ath79_ddr_freq);
+
+enum ath79_soc_type ath79_soc;
+
+void __iomem *ath79_pll_base;
+void __iomem *ath79_reset_base;
+EXPORT_SYMBOL_GPL(ath79_reset_base);
+void __iomem *ath79_ddr_base;
+
+void ath79_ddr_wb_flush(u32 reg)
+{
+ void __iomem *flush_reg = ath79_ddr_base + reg;
+
+ /* Flush the DDR write buffer. */
+ __raw_writel(0x1, flush_reg);
+ while (__raw_readl(flush_reg) & 0x1)
+ ;
+
+ /* It must be run twice. */
+ __raw_writel(0x1, flush_reg);
+ while (__raw_readl(flush_reg) & 0x1)
+ ;
+}
+EXPORT_SYMBOL_GPL(ath79_ddr_wb_flush);
+
+void ath79_device_reset_set(u32 mask)
+{
+ unsigned long flags;
+ u32 reg;
+ u32 t;
+
+ 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
+ BUG();
+
+ spin_lock_irqsave(&ath79_device_reset_lock, flags);
+ t = ath79_reset_rr(reg);
+ ath79_reset_wr(reg, t | mask);
+ spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
+}
+EXPORT_SYMBOL_GPL(ath79_device_reset_set);
+
+void ath79_device_reset_clear(u32 mask)
+{
+ unsigned long flags;
+ u32 reg;
+ u32 t;
+
+ 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
+ BUG();
+
+ spin_lock_irqsave(&ath79_device_reset_lock, flags);
+ t = ath79_reset_rr(reg);
+ ath79_reset_wr(reg, t & ~mask);
+ spin_unlock_irqrestore(&ath79_device_reset_lock, flags);
+}
+EXPORT_SYMBOL_GPL(ath79_device_reset_clear);
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h
new file mode 100644
index 0000000..a1bcdbb
--- /dev/null
+++ b/arch/mips/ath79/common.h
@@ -0,0 +1,25 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common definitions
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * 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 __ATH79_COMMON_H
+#define __ATH79_COMMON_H
+
+#include <linux/types.h>
+#include <linux/init.h>
+
+#define ATH79_MEM_SIZE_MIN (2 * 1024 * 1024)
+#define ATH79_MEM_SIZE_MAX (128 * 1024 * 1024)
+
+void ath79_ddr_wb_flush(unsigned int reg);
+
+#endif /* __ATH79_COMMON_H */
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
new file mode 100644
index 0000000..897522c
--- /dev/null
+++ b/arch/mips/ath79/dev-common.c
@@ -0,0 +1,59 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common devices
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+#include "dev-common.h"
+
+static struct resource ath79_uart_resources[] = {
+ {
+ .start = AR71XX_UART_BASE,
+ .end = AR71XX_UART_BASE + AR71XX_UART_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+#define AR71XX_UART_FLAGS (UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP)
+static struct plat_serial8250_port ath79_uart_data[] = {
+ {
+ .mapbase = AR71XX_UART_BASE,
+ .irq = ATH79_MISC_IRQ_UART,
+ .flags = AR71XX_UART_FLAGS,
+ .iotype = UPIO_MEM32,
+ .regshift = 2,
+ }, {
+ /* terminating entry */
+ }
+};
+
+static struct platform_device ath79_uart_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .resource = ath79_uart_resources,
+ .num_resources = ARRAY_SIZE(ath79_uart_resources),
+ .dev = {
+ .platform_data = ath79_uart_data
+ },
+};
+
+void __init ath79_register_uart(void)
+{
+ ath79_uart_data[0].uartclk = ath79_ahb_freq;
+ platform_device_register(&ath79_uart_device);
+}
diff --git a/arch/mips/ath79/dev-common.h b/arch/mips/ath79/dev-common.h
new file mode 100644
index 0000000..1cec894
--- /dev/null
+++ b/arch/mips/ath79/dev-common.h
@@ -0,0 +1,17 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common devices
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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.
+ */
+
+#ifndef _ATH79_DEV_COMMON_H
+#define _ATH79_DEV_COMMON_H
+
+void ath79_register_uart(void) __init;
+
+#endif /* _ATH79_DEV_COMMON_H */
diff --git a/arch/mips/ath79/early_printk.c b/arch/mips/ath79/early_printk.c
new file mode 100644
index 0000000..7499b0e
--- /dev/null
+++ b/arch/mips/ath79/early_printk.c
@@ -0,0 +1,36 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X SoC early printk support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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/io.h>
+#include <linux/serial_reg.h>
+#include <asm/addrspace.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+static inline void prom_wait_thre(void __iomem *base)
+{
+ u32 lsr;
+
+ do {
+ lsr = __raw_readl(base + UART_LSR * 4);
+ if (lsr & UART_LSR_THRE)
+ break;
+ } while (1);
+}
+
+void prom_putchar(unsigned char ch)
+{
+ void __iomem *base = (void __iomem *)(KSEG1ADDR(AR71XX_UART_BASE));
+
+ prom_wait_thre(base);
+ __raw_writel(ch, base + UART_TX * 4);
+ prom_wait_thre(base);
+}
diff --git a/arch/mips/ath79/irq.c b/arch/mips/ath79/irq.c
new file mode 100644
index 0000000..1bf7f71
--- /dev/null
+++ b/arch/mips/ath79/irq.c
@@ -0,0 +1,187 @@
+/*
+ * Atheros AR71xx/AR724x/AR913x specific interrupt handling
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * 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/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+
+static unsigned int ath79_ip2_flush_reg;
+static unsigned int ath79_ip3_flush_reg;
+
+static void ath79_misc_irq_handler(unsigned int irq, struct irq_desc *desc)
+{
+ void __iomem *base = ath79_reset_base;
+ u32 pending;
+
+ pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
+ __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+ if (pending & MISC_INT_UART)
+ generic_handle_irq(ATH79_MISC_IRQ_UART);
+
+ else if (pending & MISC_INT_DMA)
+ generic_handle_irq(ATH79_MISC_IRQ_DMA);
+
+ else if (pending & MISC_INT_PERFC)
+ generic_handle_irq(ATH79_MISC_IRQ_PERFC);
+
+ else if (pending & MISC_INT_TIMER)
+ generic_handle_irq(ATH79_MISC_IRQ_TIMER);
+
+ else if (pending & MISC_INT_OHCI)
+ generic_handle_irq(ATH79_MISC_IRQ_OHCI);
+
+ else if (pending & MISC_INT_ERROR)
+ generic_handle_irq(ATH79_MISC_IRQ_ERROR);
+
+ else if (pending & MISC_INT_GPIO)
+ generic_handle_irq(ATH79_MISC_IRQ_GPIO);
+
+ else if (pending & MISC_INT_WDOG)
+ generic_handle_irq(ATH79_MISC_IRQ_WDOG);
+
+ else
+ spurious_interrupt();
+}
+
+static void ar71xx_misc_irq_unmask(unsigned int irq)
+{
+ void __iomem *base = ath79_reset_base;
+ u32 t;
+
+ irq -= ATH79_MISC_IRQ_BASE;
+
+ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+ __raw_writel(t | (1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+ /* flush write */
+ __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+}
+
+static void ar71xx_misc_irq_mask(unsigned int irq)
+{
+ void __iomem *base = ath79_reset_base;
+ u32 t;
+
+ irq -= ATH79_MISC_IRQ_BASE;
+
+ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+
+ /* flush write */
+ __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+}
+
+static void ar724x_misc_irq_ack(unsigned int irq)
+{
+ void __iomem *base = ath79_reset_base;
+ u32 t;
+
+ irq -= ATH79_MISC_IRQ_BASE;
+
+ t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
+ __raw_writel(t & ~(1 << irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
+
+ /* flush write */
+ __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
+}
+
+static struct irq_chip ath79_misc_irq_chip = {
+ .name = "MISC",
+ .unmask = ar71xx_misc_irq_unmask,
+ .mask = ar71xx_misc_irq_mask,
+};
+
+static void __init ath79_misc_irq_init(void)
+{
+ void __iomem *base = ath79_reset_base;
+ int i;
+
+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
+ __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
+
+ if (soc_is_ar71xx() || soc_is_ar913x())
+ ath79_misc_irq_chip.mask_ack = ar71xx_misc_irq_mask;
+ else if (soc_is_ar724x())
+ ath79_misc_irq_chip.ack = ar724x_misc_irq_ack;
+ else
+ BUG();
+
+ for (i = ATH79_MISC_IRQ_BASE;
+ i < ATH79_MISC_IRQ_BASE + ATH79_MISC_IRQ_COUNT; i++) {
+ irq_desc[i].status = IRQ_DISABLED;
+ set_irq_chip_and_handler(i, &ath79_misc_irq_chip,
+ handle_level_irq);
+ }
+
+ set_irq_chained_handler(ATH79_CPU_IRQ_MISC, ath79_misc_irq_handler);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned long pending;
+
+ pending = read_c0_status() & read_c0_cause() & ST0_IM;
+
+ if (pending & STATUSF_IP7)
+ do_IRQ(ATH79_CPU_IRQ_TIMER);
+
+ else if (pending & STATUSF_IP2) {
+ ath79_ddr_wb_flush(ath79_ip2_flush_reg);
+ do_IRQ(ATH79_CPU_IRQ_IP2);
+ }
+
+ else if (pending & STATUSF_IP4)
+ do_IRQ(ATH79_CPU_IRQ_GE0);
+
+ else if (pending & STATUSF_IP5)
+ do_IRQ(ATH79_CPU_IRQ_GE1);
+
+ else if (pending & STATUSF_IP3) {
+ ath79_ddr_wb_flush(ath79_ip3_flush_reg);
+ do_IRQ(ATH79_CPU_IRQ_USB);
+ }
+
+ else if (pending & STATUSF_IP6)
+ do_IRQ(ATH79_CPU_IRQ_MISC);
+
+ else
+ spurious_interrupt();
+}
+
+void __init arch_init_irq(void)
+{
+ if (soc_is_ar71xx()) {
+ ath79_ip2_flush_reg = AR71XX_DDR_REG_FLUSH_PCI;
+ ath79_ip3_flush_reg = AR71XX_DDR_REG_FLUSH_USB;
+ } else if (soc_is_ar724x()) {
+ ath79_ip2_flush_reg = AR724X_DDR_REG_FLUSH_PCIE;
+ ath79_ip3_flush_reg = AR724X_DDR_REG_FLUSH_USB;
+ } else if (soc_is_ar913x()) {
+ ath79_ip2_flush_reg = AR913X_DDR_REG_FLUSH_WMAC;
+ ath79_ip3_flush_reg = AR913X_DDR_REG_FLUSH_USB;
+ } else
+ BUG();
+
+ cp0_perfcount_irq = ATH79_MISC_IRQ_PERFC;
+ mips_cpu_irq_init();
+ ath79_misc_irq_init();
+}
diff --git a/arch/mips/ath79/prom.c b/arch/mips/ath79/prom.c
new file mode 100644
index 0000000..e9cbd7c
--- /dev/null
+++ b/arch/mips/ath79/prom.c
@@ -0,0 +1,57 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X specific prom routines
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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/init.h>
+#include <linux/io.h>
+#include <linux/string.h>
+
+#include <asm/bootinfo.h>
+#include <asm/addrspace.h>
+
+#include "common.h"
+
+static inline int is_valid_ram_addr(void *addr)
+{
+ if (((u32) addr > KSEG0) &&
+ ((u32) addr < (KSEG0 + ATH79_MEM_SIZE_MAX)))
+ return 1;
+
+ if (((u32) addr > KSEG1) &&
+ ((u32) addr < (KSEG1 + ATH79_MEM_SIZE_MAX)))
+ return 1;
+
+ return 0;
+}
+
+static __init void ath79_prom_init_cmdline(int argc, char **argv)
+{
+ int i;
+
+ if (!is_valid_ram_addr(argv))
+ return;
+
+ for (i = 0; i < argc; i++)
+ if (is_valid_ram_addr(argv[i])) {
+ strlcat(arcs_cmdline, " ", sizeof(arcs_cmdline));
+ strlcat(arcs_cmdline, argv[i], sizeof(arcs_cmdline));
+ }
+}
+
+void __init prom_init(void)
+{
+ ath79_prom_init_cmdline(fw_arg0, (char **)fw_arg1);
+}
+
+void __init prom_free_prom_memory(void)
+{
+ /* We do not have to prom memory to free */
+}
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
new file mode 100644
index 0000000..4157ddc
--- /dev/null
+++ b/arch/mips/ath79/setup.c
@@ -0,0 +1,263 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X specific setup
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * 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/init.h>
+#include <linux/bootmem.h>
+
+#include <asm/bootinfo.h>
+#include <asm/time.h> /* for mips_hpt_frequency */
+#include <asm/reboot.h> /* for _machine_{restart,halt} */
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "common.h"
+#include "dev-common.h"
+
+#define ATH79_SYS_TYPE_LEN 64
+
+#define AR71XX_BASE_FREQ 40000000
+#define AR724X_BASE_FREQ 5000000
+#define AR913X_BASE_FREQ 5000000
+
+static char ath79_sys_type[ATH79_SYS_TYPE_LEN];
+
+static void ath79_restart(char *command)
+{
+ ath79_device_reset_set(AR71XX_RESET_FULL_CHIP);
+ for (;;)
+ if (cpu_wait)
+ cpu_wait();
+}
+
+static void ath79_halt(void)
+{
+ while (1)
+ cpu_wait();
+}
+
+static void __init ath79_detect_mem_size(void)
+{
+ unsigned long size;
+
+ for (size = ATH79_MEM_SIZE_MIN; size < ATH79_MEM_SIZE_MAX;
+ size <<= 1) {
+ if (!memcmp(ath79_detect_mem_size,
+ ath79_detect_mem_size + size, 1024))
+ break;
+ }
+
+ add_memory_region(0, size, BOOT_MEM_RAM);
+}
+
+static void __init ath79_detect_sys_type(void)
+{
+ char *chip = "????";
+ u32 id;
+ u32 major;
+ u32 minor;
+ u32 rev = 0;
+
+ id = ath79_reset_rr(AR71XX_RESET_REG_REV_ID);
+ major = id & REV_ID_MAJOR_MASK;
+
+ switch (major) {
+ case REV_ID_MAJOR_AR71XX:
+ minor = id & AR71XX_REV_ID_MINOR_MASK;
+ rev = id >> AR71XX_REV_ID_REVISION_SHIFT;
+ rev &= AR71XX_REV_ID_REVISION_MASK;
+ switch (minor) {
+ case AR71XX_REV_ID_MINOR_AR7130:
+ ath79_soc = ATH79_SOC_AR7130;
+ chip = "7130";
+ break;
+
+ case AR71XX_REV_ID_MINOR_AR7141:
+ ath79_soc = ATH79_SOC_AR7141;
+ chip = "7141";
+ break;
+
+ case AR71XX_REV_ID_MINOR_AR7161:
+ ath79_soc = ATH79_SOC_AR7161;
+ chip = "7161";
+ break;
+ }
+ break;
+
+ case REV_ID_MAJOR_AR7240:
+ ath79_soc = ATH79_SOC_AR7240;
+ chip = "7240";
+ rev = (id & AR724X_REV_ID_REVISION_MASK);
+ break;
+
+ case REV_ID_MAJOR_AR7241:
+ ath79_soc = ATH79_SOC_AR7241;
+ chip = "7241";
+ rev = (id & AR724X_REV_ID_REVISION_MASK);
+ break;
+
+ case REV_ID_MAJOR_AR7242:
+ ath79_soc = ATH79_SOC_AR7242;
+ chip = "7242";
+ rev = (id & AR724X_REV_ID_REVISION_MASK);
+ break;
+
+ case REV_ID_MAJOR_AR913X:
+ minor = id & AR913X_REV_ID_MINOR_MASK;
+ rev = id >> AR913X_REV_ID_REVISION_SHIFT;
+ rev &= AR913X_REV_ID_REVISION_MASK;
+ switch (minor) {
+ case AR913X_REV_ID_MINOR_AR9130:
+ ath79_soc = ATH79_SOC_AR9130;
+ chip = "9130";
+ break;
+
+ case AR913X_REV_ID_MINOR_AR9132:
+ ath79_soc = ATH79_SOC_AR9132;
+ chip = "9132";
+ break;
+ }
+ break;
+
+ default:
+ panic("ath79: unknown SoC, id:0x%08x\n", id);
+ }
+
+ sprintf(ath79_sys_type, "Atheros AR%s rev %u", chip, rev);
+}
+
+static void __init ar71xx_detect_sys_frequency(void)
+{
+ u32 pll;
+ u32 freq;
+ u32 div;
+
+ pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG);
+
+ div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1;
+ freq = div * AR71XX_BASE_FREQ;
+
+ div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1;
+ ath79_cpu_freq = freq / div;
+
+ div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1;
+ ath79_ddr_freq = freq / div;
+
+ div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2;
+ ath79_ahb_freq = ath79_cpu_freq / div;
+}
+
+static void __init ar724x_detect_sys_frequency(void)
+{
+ u32 pll;
+ u32 freq;
+ u32 div;
+
+ pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG);
+
+ div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK);
+ freq = div * AR724X_BASE_FREQ;
+
+ div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK);
+ freq *= div;
+
+ ath79_cpu_freq = freq;
+
+ div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1;
+ ath79_ddr_freq = freq / div;
+
+ div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2;
+ ath79_ahb_freq = ath79_cpu_freq / div;
+}
+
+static void __init ar913x_detect_sys_frequency(void)
+{
+ u32 pll;
+ u32 freq;
+ u32 div;
+
+ pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG);
+
+ div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK);
+ freq = div * AR913X_BASE_FREQ;
+
+ ath79_cpu_freq = freq;
+
+ div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1;
+ ath79_ddr_freq = freq / div;
+
+ div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2;
+ ath79_ahb_freq = ath79_cpu_freq / div;
+}
+
+static void __init ath79_detect_sys_frequency(void)
+{
+ if (soc_is_ar71xx())
+ ar71xx_detect_sys_frequency();
+ else if (soc_is_ar724x())
+ ar724x_detect_sys_frequency();
+ else if (soc_is_ar913x())
+ ar913x_detect_sys_frequency();
+ else
+ BUG();
+}
+
+const char *get_system_type(void)
+{
+ return ath79_sys_type;
+}
+
+unsigned int __cpuinit get_c0_compare_int(void)
+{
+ return CP0_LEGACY_COMPARE_IRQ;
+}
+
+void __init plat_mem_setup(void)
+{
+ set_io_port_base(KSEG1);
+
+ ath79_reset_base = ioremap_nocache(AR71XX_RESET_BASE,
+ AR71XX_RESET_SIZE);
+ ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
+ AR71XX_PLL_SIZE);
+
+ ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
+ AR71XX_DDR_CTRL_SIZE);
+
+ ath79_detect_sys_type();
+ ath79_detect_mem_size();
+ ath79_detect_sys_frequency();
+
+ pr_info("SoC: %s, CPU:%u.%03u MHz, DDR:%u.%03u MHz, AHB:%u.%03u MHz\n",
+ ath79_sys_type,
+ ath79_cpu_freq / 1000000, (ath79_cpu_freq / 1000) % 1000,
+ ath79_ddr_freq / 1000000, (ath79_ddr_freq / 1000) % 1000,
+ ath79_ahb_freq / 1000000, (ath79_ahb_freq / 1000) % 1000);
+
+ _machine_restart = ath79_restart;
+ _machine_halt = ath79_halt;
+ pm_power_off = ath79_halt;
+}
+
+void __init plat_time_init(void)
+{
+ mips_hpt_frequency = ath79_cpu_freq / 2;
+}
+
+static int __init ath79_setup(void)
+{
+ ath79_register_uart();
+ return 0;
+}
+
+arch_initcall(ath79_setup);
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
new file mode 100644
index 0000000..5a9e5e1
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -0,0 +1,207 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X SoC register definitions
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * 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_AR71XX_REGS_H
+#define __ASM_MACH_AR71XX_REGS_H
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/bitops.h>
+
+#define AR71XX_APB_BASE 0x18000000
+
+#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000)
+#define AR71XX_DDR_CTRL_SIZE 0x100
+#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
+#define AR71XX_UART_SIZE 0x100
+#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
+#define AR71XX_PLL_SIZE 0x100
+#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
+#define AR71XX_RESET_SIZE 0x100
+
+/*
+ * DDR_CTRL block
+ */
+#define AR71XX_DDR_REG_PCI_WIN0 0x7c
+#define AR71XX_DDR_REG_PCI_WIN1 0x80
+#define AR71XX_DDR_REG_PCI_WIN2 0x84
+#define AR71XX_DDR_REG_PCI_WIN3 0x88
+#define AR71XX_DDR_REG_PCI_WIN4 0x8c
+#define AR71XX_DDR_REG_PCI_WIN5 0x90
+#define AR71XX_DDR_REG_PCI_WIN6 0x94
+#define AR71XX_DDR_REG_PCI_WIN7 0x98
+#define AR71XX_DDR_REG_FLUSH_GE0 0x9c
+#define AR71XX_DDR_REG_FLUSH_GE1 0xa0
+#define AR71XX_DDR_REG_FLUSH_USB 0xa4
+#define AR71XX_DDR_REG_FLUSH_PCI 0xa8
+
+#define AR724X_DDR_REG_FLUSH_GE0 0x7c
+#define AR724X_DDR_REG_FLUSH_GE1 0x80
+#define AR724X_DDR_REG_FLUSH_USB 0x84
+#define AR724X_DDR_REG_FLUSH_PCIE 0x88
+
+#define AR913X_DDR_REG_FLUSH_GE0 0x7c
+#define AR913X_DDR_REG_FLUSH_GE1 0x80
+#define AR913X_DDR_REG_FLUSH_USB 0x84
+#define AR913X_DDR_REG_FLUSH_WMAC 0x88
+
+/*
+ * PLL block
+ */
+#define AR71XX_PLL_REG_CPU_CONFIG 0x00
+#define AR71XX_PLL_REG_SEC_CONFIG 0x04
+#define AR71XX_PLL_REG_ETH0_INT_CLOCK 0x10
+#define AR71XX_PLL_REG_ETH1_INT_CLOCK 0x14
+
+#define AR71XX_PLL_DIV_SHIFT 3
+#define AR71XX_PLL_DIV_MASK 0x1f
+#define AR71XX_CPU_DIV_SHIFT 16
+#define AR71XX_CPU_DIV_MASK 0x3
+#define AR71XX_DDR_DIV_SHIFT 18
+#define AR71XX_DDR_DIV_MASK 0x3
+#define AR71XX_AHB_DIV_SHIFT 20
+#define AR71XX_AHB_DIV_MASK 0x7
+
+#define AR724X_PLL_REG_CPU_CONFIG 0x00
+#define AR724X_PLL_REG_PCIE_CONFIG 0x18
+
+#define AR724X_PLL_DIV_SHIFT 0
+#define AR724X_PLL_DIV_MASK 0x3ff
+#define AR724X_PLL_REF_DIV_SHIFT 10
+#define AR724X_PLL_REF_DIV_MASK 0xf
+#define AR724X_AHB_DIV_SHIFT 19
+#define AR724X_AHB_DIV_MASK 0x1
+#define AR724X_DDR_DIV_SHIFT 22
+#define AR724X_DDR_DIV_MASK 0x3
+
+#define AR913X_PLL_REG_CPU_CONFIG 0x00
+#define AR913X_PLL_REG_ETH_CONFIG 0x04
+#define AR913X_PLL_REG_ETH0_INT_CLOCK 0x14
+#define AR913X_PLL_REG_ETH1_INT_CLOCK 0x18
+
+#define AR913X_PLL_DIV_SHIFT 0
+#define AR913X_PLL_DIV_MASK 0x3ff
+#define AR913X_DDR_DIV_SHIFT 22
+#define AR913X_DDR_DIV_MASK 0x3
+#define AR913X_AHB_DIV_SHIFT 19
+#define AR913X_AHB_DIV_MASK 0x1
+
+/*
+ * RESET block
+ */
+#define AR71XX_RESET_REG_TIMER 0x00
+#define AR71XX_RESET_REG_TIMER_RELOAD 0x04
+#define AR71XX_RESET_REG_WDOG_CTRL 0x08
+#define AR71XX_RESET_REG_WDOG 0x0c
+#define AR71XX_RESET_REG_MISC_INT_STATUS 0x10
+#define AR71XX_RESET_REG_MISC_INT_ENABLE 0x14
+#define AR71XX_RESET_REG_PCI_INT_STATUS 0x18
+#define AR71XX_RESET_REG_PCI_INT_ENABLE 0x1c
+#define AR71XX_RESET_REG_GLOBAL_INT_STATUS 0x20
+#define AR71XX_RESET_REG_RESET_MODULE 0x24
+#define AR71XX_RESET_REG_PERFC_CTRL 0x2c
+#define AR71XX_RESET_REG_PERFC0 0x30
+#define AR71XX_RESET_REG_PERFC1 0x34
+#define AR71XX_RESET_REG_REV_ID 0x90
+
+#define AR913X_RESET_REG_GLOBAL_INT_STATUS 0x18
+#define AR913X_RESET_REG_RESET_MODULE 0x1c
+#define AR913X_RESET_REG_PERF_CTRL 0x20
+#define AR913X_RESET_REG_PERFC0 0x24
+#define AR913X_RESET_REG_PERFC1 0x28
+
+#define AR724X_RESET_REG_RESET_MODULE 0x1c
+
+#define MISC_INT_DMA BIT(7)
+#define MISC_INT_OHCI BIT(6)
+#define MISC_INT_PERFC BIT(5)
+#define MISC_INT_WDOG BIT(4)
+#define MISC_INT_UART BIT(3)
+#define MISC_INT_GPIO BIT(2)
+#define MISC_INT_ERROR BIT(1)
+#define MISC_INT_TIMER BIT(0)
+
+#define AR71XX_RESET_EXTERNAL BIT(28)
+#define AR71XX_RESET_FULL_CHIP BIT(24)
+#define AR71XX_RESET_CPU_NMI BIT(21)
+#define AR71XX_RESET_CPU_COLD BIT(20)
+#define AR71XX_RESET_DMA BIT(19)
+#define AR71XX_RESET_SLIC BIT(18)
+#define AR71XX_RESET_STEREO BIT(17)
+#define AR71XX_RESET_DDR BIT(16)
+#define AR71XX_RESET_GE1_MAC BIT(13)
+#define AR71XX_RESET_GE1_PHY BIT(12)
+#define AR71XX_RESET_USBSUS_OVERRIDE BIT(10)
+#define AR71XX_RESET_GE0_MAC BIT(9)
+#define AR71XX_RESET_GE0_PHY BIT(8)
+#define AR71XX_RESET_USB_OHCI_DLL BIT(6)
+#define AR71XX_RESET_USB_HOST BIT(5)
+#define AR71XX_RESET_USB_PHY BIT(4)
+#define AR71XX_RESET_PCI_BUS BIT(1)
+#define AR71XX_RESET_PCI_CORE BIT(0)
+
+#define AR724X_RESET_GE1_MDIO BIT(23)
+#define AR724X_RESET_GE0_MDIO BIT(22)
+#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10)
+#define AR724X_RESET_PCIE_PHY BIT(7)
+#define AR724X_RESET_PCIE BIT(6)
+#define AR724X_RESET_OHCI_DLL BIT(3)
+
+#define AR913X_RESET_AMBA2WMAC BIT(22)
+
+#define REV_ID_MAJOR_MASK 0xfff0
+#define REV_ID_MAJOR_AR71XX 0x00a0
+#define REV_ID_MAJOR_AR913X 0x00b0
+#define REV_ID_MAJOR_AR7240 0x00c0
+#define REV_ID_MAJOR_AR7241 0x0100
+#define REV_ID_MAJOR_AR7242 0x1100
+
+#define AR71XX_REV_ID_MINOR_MASK 0x3
+#define AR71XX_REV_ID_MINOR_AR7130 0x0
+#define AR71XX_REV_ID_MINOR_AR7141 0x1
+#define AR71XX_REV_ID_MINOR_AR7161 0x2
+#define AR71XX_REV_ID_REVISION_MASK 0x3
+#define AR71XX_REV_ID_REVISION_SHIFT 2
+
+#define AR913X_REV_ID_MINOR_MASK 0x3
+#define AR913X_REV_ID_MINOR_AR9130 0x0
+#define AR913X_REV_ID_MINOR_AR9132 0x1
+#define AR913X_REV_ID_REVISION_MASK 0x3
+#define AR913X_REV_ID_REVISION_SHIFT 2
+
+#define AR724X_REV_ID_REVISION_MASK 0x3
+
+/*
+ * SPI block
+ */
+#define AR71XX_SPI_REG_FS 0x00 /* Function Select */
+#define AR71XX_SPI_REG_CTRL 0x04 /* SPI Control */
+#define AR71XX_SPI_REG_IOC 0x08 /* SPI I/O Control */
+#define AR71XX_SPI_REG_RDS 0x0c /* Read Data Shift */
+
+#define AR71XX_SPI_FS_GPIO BIT(0) /* Enable GPIO mode */
+
+#define AR71XX_SPI_CTRL_RD BIT(6) /* Remap Disable */
+#define AR71XX_SPI_CTRL_DIV_MASK 0x3f
+
+#define AR71XX_SPI_IOC_DO BIT(0) /* Data Out pin */
+#define AR71XX_SPI_IOC_CLK BIT(8) /* CLK pin */
+#define AR71XX_SPI_IOC_CS(n) BIT(16 + (n))
+#define AR71XX_SPI_IOC_CS0 AR71XX_SPI_IOC_CS(0)
+#define AR71XX_SPI_IOC_CS1 AR71XX_SPI_IOC_CS(1)
+#define AR71XX_SPI_IOC_CS2 AR71XX_SPI_IOC_CS(2)
+#define AR71XX_SPI_IOC_CS_ALL (AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1 | \
+ AR71XX_SPI_IOC_CS2)
+
+#endif /* __ASM_MACH_AR71XX_REGS_H */
diff --git a/arch/mips/include/asm/mach-ath79/ath79.h b/arch/mips/include/asm/mach-ath79/ath79.h
new file mode 100644
index 0000000..34fa294
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79.h
@@ -0,0 +1,100 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common definitions
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * 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_H
+#define __ASM_MACH_ATH79_H
+
+#include <linux/types.h>
+#include <linux/io.h>
+
+extern u32 ath79_ahb_freq;
+extern u32 ath79_cpu_freq;
+extern u32 ath79_ddr_freq;
+
+enum ath79_soc_type {
+ ATH79_SOC_UNKNOWN,
+ ATH79_SOC_AR7130,
+ ATH79_SOC_AR7141,
+ ATH79_SOC_AR7161,
+ ATH79_SOC_AR7240,
+ ATH79_SOC_AR7241,
+ ATH79_SOC_AR7242,
+ ATH79_SOC_AR9130,
+ ATH79_SOC_AR9132
+};
+
+extern enum ath79_soc_type ath79_soc;
+
+static inline int soc_is_ar71xx(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7130 ||
+ ath79_soc == ATH79_SOC_AR7141 ||
+ ath79_soc == ATH79_SOC_AR7161);
+}
+
+static inline int soc_is_ar724x(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7240 ||
+ ath79_soc == ATH79_SOC_AR7241 ||
+ ath79_soc == ATH79_SOC_AR7242);
+}
+
+static inline int soc_is_ar7240(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7240);
+}
+
+static inline int soc_is_ar7241(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7241);
+}
+
+static inline int soc_is_ar7242(void)
+{
+ return (ath79_soc == ATH79_SOC_AR7242);
+}
+
+static inline int soc_is_ar913x(void)
+{
+ return (ath79_soc == ATH79_SOC_AR9130 ||
+ ath79_soc == ATH79_SOC_AR9132);
+}
+
+extern void __iomem *ath79_ddr_base;
+extern void __iomem *ath79_pll_base;
+extern void __iomem *ath79_reset_base;
+
+static inline void ath79_pll_wr(unsigned reg, u32 val)
+{
+ __raw_writel(val, ath79_pll_base + reg);
+}
+
+static inline u32 ath79_pll_rr(unsigned reg)
+{
+ return __raw_readl(ath79_pll_base + reg);
+}
+
+static inline void ath79_reset_wr(unsigned reg, u32 val)
+{
+ __raw_writel(val, ath79_reset_base + reg);
+}
+
+static inline u32 ath79_reset_rr(unsigned reg)
+{
+ return __raw_readl(ath79_reset_base + reg);
+}
+
+void ath79_device_reset_set(u32 mask);
+void ath79_device_reset_clear(u32 mask);
+
+#endif /* __ASM_MACH_ATH79_H */
diff --git a/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
new file mode 100644
index 0000000..4476fa0
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/cpu-feature-overrides.h
@@ -0,0 +1,56 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X specific CPU feature overrides
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This file was derived from: include/asm-mips/cpu-features.h
+ * Copyright (C) 2003, 2004 Ralf Baechle
+ * Copyright (C) 2004 Maciej W. Rozycki
+ *
+ * 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_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H
+
+#define cpu_has_tlb 1
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 1
+#define cpu_has_tx39_cache 0
+#define cpu_has_sb1_cache 0
+#define cpu_has_fpu 0
+#define cpu_has_32fpr 0
+#define cpu_has_counter 1
+#define cpu_has_watch 1
+#define cpu_has_divec 1
+
+#define cpu_has_prefetch 1
+#define cpu_has_ejtag 1
+#define cpu_has_llsc 1
+
+#define cpu_has_mips16 1
+#define cpu_has_mdmx 0
+#define cpu_has_mips3d 0
+#define cpu_has_smartmips 0
+
+#define cpu_has_mips32r1 1
+#define cpu_has_mips32r2 1
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 0
+
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+
+#define cpu_has_64bits 0
+#define cpu_has_64bit_zero_reg 0
+#define cpu_has_64bit_gp_regs 0
+#define cpu_has_64bit_addresses 0
+
+#define cpu_dcache_line_size() 32
+#define cpu_icache_line_size() 32
+
+#endif /* __ASM_MACH_ATH79_CPU_FEATURE_OVERRIDES_H */
diff --git a/arch/mips/include/asm/mach-ath79/irq.h b/arch/mips/include/asm/mach-ath79/irq.h
new file mode 100644
index 0000000..189bc6e
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/irq.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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.
+ */
+#ifndef __ASM_MACH_ATH79_IRQ_H
+#define __ASM_MACH_ATH79_IRQ_H
+
+#define MIPS_CPU_IRQ_BASE 0
+#define NR_IRQS 16
+
+#define ATH79_MISC_IRQ_BASE 8
+#define ATH79_MISC_IRQ_COUNT 8
+
+#define ATH79_CPU_IRQ_IP2 (MIPS_CPU_IRQ_BASE + 2)
+#define ATH79_CPU_IRQ_USB (MIPS_CPU_IRQ_BASE + 3)
+#define ATH79_CPU_IRQ_GE0 (MIPS_CPU_IRQ_BASE + 4)
+#define ATH79_CPU_IRQ_GE1 (MIPS_CPU_IRQ_BASE + 5)
+#define ATH79_CPU_IRQ_MISC (MIPS_CPU_IRQ_BASE + 6)
+#define ATH79_CPU_IRQ_TIMER (MIPS_CPU_IRQ_BASE + 7)
+
+#define ATH79_MISC_IRQ_TIMER (ATH79_MISC_IRQ_BASE + 0)
+#define ATH79_MISC_IRQ_ERROR (ATH79_MISC_IRQ_BASE + 1)
+#define ATH79_MISC_IRQ_GPIO (ATH79_MISC_IRQ_BASE + 2)
+#define ATH79_MISC_IRQ_UART (ATH79_MISC_IRQ_BASE + 3)
+#define ATH79_MISC_IRQ_WDOG (ATH79_MISC_IRQ_BASE + 4)
+#define ATH79_MISC_IRQ_PERFC (ATH79_MISC_IRQ_BASE + 5)
+#define ATH79_MISC_IRQ_OHCI (ATH79_MISC_IRQ_BASE + 6)
+#define ATH79_MISC_IRQ_DMA (ATH79_MISC_IRQ_BASE + 7)
+
+#include_next <irq.h>
+
+#endif /* __ASM_MACH_ATH79_IRQ_H */
diff --git a/arch/mips/include/asm/mach-ath79/kernel-entry-init.h b/arch/mips/include/asm/mach-ath79/kernel-entry-init.h
new file mode 100644
index 0000000..d8d046b
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/kernel-entry-init.h
@@ -0,0 +1,32 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X specific kernel entry setup
+ *
+ * Copyright (C) 2009 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.
+ *
+ */
+#ifndef __ASM_MACH_ATH79_KERNEL_ENTRY_H
+#define __ASM_MACH_ATH79_KERNEL_ENTRY_H
+
+ /*
+ * Some bootloaders set the 'Kseg0 coherency algorithm' to
+ * 'Cacheable, noncoherent, write-through, no write allocate'
+ * and this cause performance issues. Let's go and change it to
+ * 'Cacheable, noncoherent, write-back, write allocate'
+ */
+ .macro kernel_entry_setup
+ mfc0 t0, CP0_CONFIG
+ li t1, ~CONF_CM_CMASK
+ and t0, t1
+ ori t0, CONF_CM_CACHABLE_NONCOHERENT
+ mtc0 t0, CP0_CONFIG
+ nop
+ .endm
+
+ .macro smp_slave_setup
+ .endm
+
+#endif /* __ASM_MACH_ATH79_KERNEL_ENTRY_H */
diff --git a/arch/mips/include/asm/mach-ath79/war.h b/arch/mips/include/asm/mach-ath79/war.h
new file mode 100644
index 0000000..323d9f1
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MACH_ATH79_WAR_H
+#define __ASM_MACH_ATH79_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MACH_ATH79_WAR_H */
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 02/16] MIPS: ath79: add GPIOLIB support
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 01/16] MIPS: add initial support for the Atheros AR71XX/AR724X/AR931X SoCs Gabor Juhos
@ 2010-12-22 20:30 ` Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 03/16] MIPS: ath79: utilize the MIPS multi-machine support Gabor Juhos
` (13 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos, David Brownell
This patch implements generic GPIO routines for the built-in
GPIO controllers of the Atheros AR71XX/AR724X/AR913X SoCs.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
---
Changes since RFC: ---
Changes since v1:
- rebased against 2.6.37-rc7
arch/mips/Kconfig | 1 +
arch/mips/ath79/Makefile | 2 +-
arch/mips/ath79/common.h | 5 +
arch/mips/ath79/gpio.c | 197 ++++++++++++++++++++++++
arch/mips/ath79/setup.c | 2 +-
arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 21 +++
arch/mips/include/asm/mach-ath79/gpio.h | 26 +++
7 files changed, 252 insertions(+), 2 deletions(-)
create mode 100644 arch/mips/ath79/gpio.c
create mode 100644 arch/mips/include/asm/mach-ath79/gpio.h
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index c0511d6..c3270a4 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -67,6 +67,7 @@ config AR7
config ATH79
bool "Atheros AR71XX/AR724X/AR913X based boards"
+ select ARCH_REQUIRE_GPIOLIB
select BOOT_RAW
select CEVT_R4K
select CSRC_R4K
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index b4ec9c2..facbb70 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -8,7 +8,7 @@
# under the terms of the GNU General Public License version 2 as published
# by the Free Software Foundation.
-obj-y := prom.o setup.o irq.o common.o
+obj-y := prom.o setup.o irq.o common.o gpio.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/mips/ath79/common.h b/arch/mips/ath79/common.h
index a1bcdbb..cb2f3e8 100644
--- a/arch/mips/ath79/common.h
+++ b/arch/mips/ath79/common.h
@@ -22,4 +22,9 @@
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_init(void) __init;
+
#endif /* __ATH79_COMMON_H */
diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c
new file mode 100644
index 0000000..a0c426b
--- /dev/null
+++ b/arch/mips/ath79/gpio.c
@@ -0,0 +1,197 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X GPIO API support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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/init.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+#include <linux/ioport.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79.h>
+#include "common.h"
+
+static void __iomem *ath79_gpio_base;
+static unsigned long ath79_gpio_count;
+static DEFINE_SPINLOCK(ath79_gpio_lock);
+
+static void __ath79_gpio_set_value(unsigned gpio, int value)
+{
+ void __iomem *base = ath79_gpio_base;
+
+ if (value)
+ __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_SET);
+ else
+ __raw_writel(1 << gpio, base + AR71XX_GPIO_REG_CLEAR);
+}
+
+static int __ath79_gpio_get_value(unsigned gpio)
+{
+ return (__raw_readl(ath79_gpio_base + AR71XX_GPIO_REG_IN) >> gpio) & 1;
+}
+
+static int ath79_gpio_get_value(struct gpio_chip *chip, unsigned offset)
+{
+ return __ath79_gpio_get_value(offset);
+}
+
+static void ath79_gpio_set_value(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ __ath79_gpio_set_value(offset, value);
+}
+
+static int ath79_gpio_direction_input(struct gpio_chip *chip,
+ unsigned offset)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) & ~(1 << offset),
+ base + AR71XX_GPIO_REG_OE);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+
+ return 0;
+}
+
+static int ath79_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ if (value)
+ __raw_writel(1 << offset, base + AR71XX_GPIO_REG_SET);
+ else
+ __raw_writel(1 << offset, base + AR71XX_GPIO_REG_CLEAR);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_OE) | (1 << offset),
+ 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,
+ .set = ath79_gpio_set_value,
+ .direction_input = ath79_gpio_direction_input,
+ .direction_output = ath79_gpio_direction_output,
+ .base = 0,
+};
+
+void ath79_gpio_function_enable(u32 mask)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) | mask,
+ base + AR71XX_GPIO_REG_FUNC);
+ /* flush write */
+ __raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void ath79_gpio_function_disable(u32 mask)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ __raw_writel(__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~mask,
+ base + AR71XX_GPIO_REG_FUNC);
+ /* flush write */
+ __raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void ath79_gpio_function_setup(u32 set, u32 clear)
+{
+ void __iomem *base = ath79_gpio_base;
+ unsigned long flags;
+
+ spin_lock_irqsave(&ath79_gpio_lock, flags);
+
+ __raw_writel((__raw_readl(base + AR71XX_GPIO_REG_FUNC) & ~clear) | set,
+ base + AR71XX_GPIO_REG_FUNC);
+ /* flush write */
+ __raw_readl(base + AR71XX_GPIO_REG_FUNC);
+
+ spin_unlock_irqrestore(&ath79_gpio_lock, flags);
+}
+
+void __init ath79_gpio_init(void)
+{
+ int err;
+
+ if (soc_is_ar71xx())
+ ath79_gpio_count = AR71XX_GPIO_COUNT;
+ else if (soc_is_ar724x())
+ ath79_gpio_count = AR724X_GPIO_COUNT;
+ else if (soc_is_ar913x())
+ ath79_gpio_count = AR913X_GPIO_COUNT;
+ else
+ BUG();
+
+ ath79_gpio_base = ioremap_nocache(AR71XX_GPIO_BASE, AR71XX_GPIO_SIZE);
+ ath79_gpio_chip.ngpio = ath79_gpio_count;
+
+ err = gpiochip_add(&ath79_gpio_chip);
+ if (err)
+ panic("cannot add AR71xx GPIO chip, error=%d", err);
+}
+
+int gpio_get_value(unsigned gpio)
+{
+ if (gpio < ath79_gpio_count)
+ return __ath79_gpio_get_value(gpio);
+
+ return __gpio_get_value(gpio);
+}
+EXPORT_SYMBOL(gpio_get_value);
+
+void gpio_set_value(unsigned gpio, int value)
+{
+ if (gpio < ath79_gpio_count)
+ __ath79_gpio_set_value(gpio, value);
+ else
+ __gpio_set_value(gpio, value);
+}
+EXPORT_SYMBOL(gpio_set_value);
+
+int gpio_to_irq(unsigned gpio)
+{
+ /* FIXME */
+ return -EINVAL;
+}
+EXPORT_SYMBOL(gpio_to_irq);
+
+int irq_to_gpio(unsigned irq)
+{
+ /* FIXME */
+ return -EINVAL;
+}
+EXPORT_SYMBOL(irq_to_gpio);
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 4157ddc..83dd855 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -230,7 +230,6 @@ void __init plat_mem_setup(void)
AR71XX_RESET_SIZE);
ath79_pll_base = ioremap_nocache(AR71XX_PLL_BASE,
AR71XX_PLL_SIZE);
-
ath79_ddr_base = ioremap_nocache(AR71XX_DDR_CTRL_BASE,
AR71XX_DDR_CTRL_SIZE);
@@ -256,6 +255,7 @@ void __init plat_time_init(void)
static int __init ath79_setup(void)
{
+ ath79_gpio_init();
ath79_register_uart();
return 0;
}
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index 5a9e5e1..7f2933d 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -25,6 +25,8 @@
#define AR71XX_DDR_CTRL_SIZE 0x100
#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
#define AR71XX_UART_SIZE 0x100
+#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000)
+#define AR71XX_GPIO_SIZE 0x100
#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
#define AR71XX_PLL_SIZE 0x100
#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
@@ -204,4 +206,23 @@
#define AR71XX_SPI_IOC_CS_ALL (AR71XX_SPI_IOC_CS0 | AR71XX_SPI_IOC_CS1 | \
AR71XX_SPI_IOC_CS2)
+/*
+ * GPIO block
+ */
+#define AR71XX_GPIO_REG_OE 0x00
+#define AR71XX_GPIO_REG_IN 0x04
+#define AR71XX_GPIO_REG_OUT 0x08
+#define AR71XX_GPIO_REG_SET 0x0c
+#define AR71XX_GPIO_REG_CLEAR 0x10
+#define AR71XX_GPIO_REG_INT_MODE 0x14
+#define AR71XX_GPIO_REG_INT_TYPE 0x18
+#define AR71XX_GPIO_REG_INT_POLARITY 0x1c
+#define AR71XX_GPIO_REG_INT_PENDING 0x20
+#define AR71XX_GPIO_REG_INT_ENABLE 0x24
+#define AR71XX_GPIO_REG_FUNC 0x28
+
+#define AR71XX_GPIO_COUNT 16
+#define AR724X_GPIO_COUNT 18
+#define AR913X_GPIO_COUNT 22
+
#endif /* __ASM_MACH_AR71XX_REGS_H */
diff --git a/arch/mips/include/asm/mach-ath79/gpio.h b/arch/mips/include/asm/mach-ath79/gpio.h
new file mode 100644
index 0000000..60dcb62
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/gpio.h
@@ -0,0 +1,26 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X GPIO API definitions
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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.
+ *
+ */
+
+#ifndef __ASM_MACH_ATH79_GPIO_H
+#define __ASM_MACH_ATH79_GPIO_H
+
+#define ARCH_NR_GPIOS 64
+#include <asm-generic/gpio.h>
+
+int gpio_to_irq(unsigned gpio);
+int irq_to_gpio(unsigned irq);
+int gpio_get_value(unsigned gpio);
+void gpio_set_value(unsigned gpio, int value);
+
+#define gpio_cansleep __gpio_cansleep
+
+#endif /* __ASM_MACH_ATH79_GPIO_H */
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 03/16] MIPS: ath79: utilize the MIPS multi-machine support
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 01/16] MIPS: add initial support for the Atheros AR71XX/AR724X/AR931X SoCs Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 02/16] MIPS: ath79: add GPIOLIB support Gabor Juhos
@ 2010-12-22 20:30 ` Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 04/16] MIPS: ath79: add initial support for the Atheros PB44 reference board Gabor Juhos
` (12 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since RFC: ---
Changes since v1:
- rebased against 2.6.37-rc7
arch/mips/Kconfig | 1 +
arch/mips/ath79/machtypes.h | 21 +++++++++++++++++++++
arch/mips/ath79/setup.c | 15 +++++++++++++++
3 files changed, 37 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/ath79/machtypes.h
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index c3270a4..feb8de4 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -73,6 +73,7 @@ config ATH79
select CSRC_R4K
select DMA_NONCOHERENT
select IRQ_CPU
+ select MIPS_MACHINE
select SYS_HAS_CPU_MIPS32_R2
select SYS_HAS_EARLY_PRINTK
select SYS_SUPPORTS_32BIT_KERNEL
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
new file mode 100644
index 0000000..fac0e26
--- /dev/null
+++ b/arch/mips/ath79/machtypes.h
@@ -0,0 +1,21 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X machine type definitions
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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.
+ */
+
+#ifndef _ATH79_MACHTYPE_H
+#define _ATH79_MACHTYPE_H
+
+#include <asm/mips_machine.h>
+
+enum ath79_mach_type {
+ ATH79_MACH_GENERIC = 0,
+};
+
+#endif /* _ATH79_MACHTYPE_H */
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 83dd855..5f2b6de 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -18,11 +18,13 @@
#include <asm/bootinfo.h>
#include <asm/time.h> /* for mips_hpt_frequency */
#include <asm/reboot.h> /* for _machine_{restart,halt} */
+#include <asm/mips_machine.h>
#include <asm/mach-ath79/ath79.h>
#include <asm/mach-ath79/ar71xx_regs.h>
#include "common.h"
#include "dev-common.h"
+#include "machtypes.h"
#define ATH79_SYS_TYPE_LEN 64
@@ -257,7 +259,20 @@ static int __init ath79_setup(void)
{
ath79_gpio_init();
ath79_register_uart();
+
+ mips_machine_setup();
+
return 0;
}
arch_initcall(ath79_setup);
+
+static void __init ath79_generic_init(void)
+{
+ /* Nothing to do */
+}
+
+MIPS_MACHINE(ATH79_MACH_GENERIC,
+ "Generic",
+ "Generic AR71XX/AR724X/AR913X based board",
+ ath79_generic_init);
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 04/16] MIPS: ath79: add initial support for the Atheros PB44 reference board
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (2 preceding siblings ...)
2010-12-22 20:30 ` [PATCH v2 03/16] MIPS: ath79: utilize the MIPS multi-machine support Gabor Juhos
@ 2010-12-22 20:30 ` Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 05/16] MIPS: ath79: add common GPIO LEDs device Gabor Juhos
` (11 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since RFC:
- don't use 'default n' for the ATH79_MACH_PB44 Kconfig option
Changes since v1:
- rebased against 2.6.37-rc7
arch/mips/ath79/Kconfig | 11 ++++++++
arch/mips/ath79/Makefile | 5 ++++
arch/mips/ath79/mach-pb44.c | 56 +++++++++++++++++++++++++++++++++++++++++++
arch/mips/ath79/machtypes.h | 1 +
4 files changed, 73 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/ath79/mach-pb44.c
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 50b9334..fabb2b0 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -1,5 +1,16 @@
if ATH79
+menu "Atheros AR71XX/AR724X/AR913X machine selection"
+
+config ATH79_MACH_PB44
+ bool "Atheros PB44 reference board"
+ select SOC_AR71XX
+ help
+ Say 'Y' here if you want your kernel to support the
+ Atheros PB44 reference board.
+
+endmenu
+
config SOC_AR71XX
def_bool n
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index facbb70..a9ba120 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,3 +16,8 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
# Devices
#
obj-y += dev-common.o
+
+#
+# Machines
+#
+obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
new file mode 100644
index 0000000..ffc24d7
--- /dev/null
+++ b/arch/mips/ath79/mach-pb44.c
@@ -0,0 +1,56 @@
+/*
+ * Atheros PB44 reference board support
+ *
+ * Copyright (C) 2009-2010 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/init.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/i2c-gpio.h>
+#include <linux/i2c/pcf857x.h>
+
+#include "machtypes.h"
+
+#define PB44_GPIO_I2C_SCL 0
+#define PB44_GPIO_I2C_SDA 1
+
+#define PB44_GPIO_EXP_BASE 16
+
+static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
+ .sda_pin = PB44_GPIO_I2C_SDA,
+ .scl_pin = PB44_GPIO_I2C_SCL,
+};
+
+static struct platform_device pb44_i2c_gpio_device = {
+ .name = "i2c-gpio",
+ .id = 0,
+ .dev = {
+ .platform_data = &pb44_i2c_gpio_data,
+ }
+};
+
+static struct pcf857x_platform_data pb44_pcf857x_data = {
+ .gpio_base = PB44_GPIO_EXP_BASE,
+};
+
+static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
+ {
+ I2C_BOARD_INFO("pcf8575", 0x20),
+ .platform_data = &pb44_pcf857x_data,
+ },
+};
+
+static void __init pb44_init(void)
+{
+ i2c_register_board_info(0, pb44_i2c_board_info,
+ ARRAY_SIZE(pb44_i2c_board_info));
+ platform_device_register(&pb44_i2c_gpio_device);
+}
+
+MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
+ pb44_init);
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
index fac0e26..a796fa3 100644
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -16,6 +16,7 @@
enum ath79_mach_type {
ATH79_MACH_GENERIC = 0,
+ ATH79_MACH_PB44, /* Atheros PB44 reference board */
};
#endif /* _ATH79_MACHTYPE_H */
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 05/16] MIPS: ath79: add common GPIO LEDs device
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (3 preceding siblings ...)
2010-12-22 20:30 ` [PATCH v2 04/16] MIPS: ath79: add initial support for the Atheros PB44 reference board Gabor Juhos
@ 2010-12-22 20:30 ` Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 06/16] watchdog: add driver for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (10 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos
Almost all boards have one or more LEDs connected to GPIO lines. This
patch adds common code to register a platform_device for them.
The patch also adds support for the LEDs on the PB44 board.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC: ---
Changes since v1:
- rebased against 2.6.37-rc7
arch/mips/ath79/Kconfig | 4 +++
arch/mips/ath79/Makefile | 1 +
arch/mips/ath79/dev-leds-gpio.c | 56 +++++++++++++++++++++++++++++++++++++++
arch/mips/ath79/dev-leds-gpio.h | 21 ++++++++++++++
arch/mips/ath79/mach-pb44.c | 18 ++++++++++++
5 files changed, 100 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/ath79/dev-leds-gpio.c
create mode 100644 arch/mips/ath79/dev-leds-gpio.h
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index fabb2b0..5bc480e 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -5,6 +5,7 @@ menu "Atheros AR71XX/AR724X/AR913X machine selection"
config ATH79_MACH_PB44
bool "Atheros PB44 reference board"
select SOC_AR71XX
+ select ATH79_DEV_LEDS_GPIO
help
Say 'Y' here if you want your kernel to support the
Atheros PB44 reference board.
@@ -20,4 +21,7 @@ config SOC_AR724X
config SOC_AR913X
def_bool n
+config ATH79_DEV_LEDS_GPIO
+ def_bool n
+
endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index a9ba120..d14b597 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
# Devices
#
obj-y += dev-common.o
+obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o
#
# Machines
diff --git a/arch/mips/ath79/dev-leds-gpio.c b/arch/mips/ath79/dev-leds-gpio.c
new file mode 100644
index 0000000..cdade68
--- /dev/null
+++ b/arch/mips/ath79/dev-leds-gpio.c
@@ -0,0 +1,56 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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/init.h>
+#include <linux/slab.h>
+#include <linux/platform_device.h>
+
+#include "dev-leds-gpio.h"
+
+void __init ath79_register_leds_gpio(int id,
+ unsigned num_leds,
+ struct gpio_led *leds)
+{
+ struct platform_device *pdev;
+ struct gpio_led_platform_data pdata;
+ struct gpio_led *p;
+ int err;
+
+ p = kmalloc(num_leds * sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return;
+
+ memcpy(p, leds, num_leds * sizeof(*p));
+
+ pdev = platform_device_alloc("leds-gpio", id);
+ if (!pdev)
+ goto err_free_leds;
+
+ memset(&pdata, 0, sizeof(pdata));
+ pdata.num_leds = num_leds;
+ pdata.leds = p;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto err_put_pdev;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_put_pdev;
+
+ return;
+
+err_put_pdev:
+ platform_device_put(pdev);
+
+err_free_leds:
+ kfree(p);
+}
diff --git a/arch/mips/ath79/dev-leds-gpio.h b/arch/mips/ath79/dev-leds-gpio.h
new file mode 100644
index 0000000..0fb0ed1
--- /dev/null
+++ b/arch/mips/ath79/dev-leds-gpio.h
@@ -0,0 +1,21 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X common GPIO LEDs support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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.
+ */
+
+#ifndef _ATH79_DEV_LEDS_GPIO_H
+#define _ATH79_DEV_LEDS_GPIO_H
+
+#include <linux/leds.h>
+
+void ath79_register_leds_gpio(int id,
+ unsigned num_leds,
+ struct gpio_led *leds) __init;
+
+#endif /* _ATH79_DEV_LEDS_GPIO_H */
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index ffc24d7..e176779 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -15,11 +15,14 @@
#include <linux/i2c/pcf857x.h>
#include "machtypes.h"
+#include "dev-leds-gpio.h"
#define PB44_GPIO_I2C_SCL 0
#define PB44_GPIO_I2C_SDA 1
#define PB44_GPIO_EXP_BASE 16
+#define PB44_GPIO_LED_JUMP1 (PB44_GPIO_EXP_BASE + 9)
+#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + 10)
static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
.sda_pin = PB44_GPIO_I2C_SDA,
@@ -45,11 +48,26 @@ static struct i2c_board_info pb44_i2c_board_info[] __initdata = {
},
};
+static struct gpio_led pb44_leds_gpio[] __initdata = {
+ {
+ .name = "pb44:amber:jump1",
+ .gpio = PB44_GPIO_LED_JUMP1,
+ .active_low = 1,
+ }, {
+ .name = "pb44:green:jump2",
+ .gpio = PB44_GPIO_LED_JUMP2,
+ .active_low = 1,
+ },
+};
+
static void __init pb44_init(void)
{
i2c_register_board_info(0, pb44_i2c_board_info,
ARRAY_SIZE(pb44_i2c_board_info));
platform_device_register(&pb44_i2c_gpio_device);
+
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
+ pb44_leds_gpio);
}
MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 06/16] watchdog: add driver for the Atheros AR71XX/AR724X/AR913X SoCs
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (4 preceding siblings ...)
2010-12-22 20:30 ` [PATCH v2 05/16] MIPS: ath79: add common GPIO LEDs device Gabor Juhos
@ 2010-12-22 20:30 ` Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 07/16] MIPS: ath79: add common watchdog device Gabor Juhos
` (9 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos, Wim Van Sebroeck, linux-watchdog
This patch adds a driver for the built-in hardware watchdog device
of the Atheros AR71XX/AR724X/AR913X SoCs.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: Wim Van Sebroeck <wim@iguana.be>
Cc: linux-watchdog@vger.kernel.org
---
Changes since RFC: ---
Changes since v1:
- rebased against 2.6.37-rc7
drivers/watchdog/Kconfig | 8 +
drivers/watchdog/Makefile | 1 +
drivers/watchdog/ath79_wdt.c | 293 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 302 insertions(+), 0 deletions(-)
create mode 100644 drivers/watchdog/ath79_wdt.c
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index a5ad77e..7833e44 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -930,6 +930,14 @@ config BCM63XX_WDT
To compile this driver as a loadable module, choose M here.
The module will be called bcm63xx_wdt.
+config ATH79_WDT
+ tristate "Atheros AR71XX/AR724X/AR913X hardware watchdog"
+ depends on ATH79
+ help
+ Hardware driver for the built-in watchdog timer on the Atheros
+ AR71XX/AR724X/AR913X SoCs.
+
+
# PARISC Architecture
# POWERPC Architecture
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 4b0ef38..6d7af07 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -117,6 +117,7 @@ obj-$(CONFIG_PNX833X_WDT) += pnx833x_wdt.o
obj-$(CONFIG_SIBYTE_WDOG) += sb_wdog.o
obj-$(CONFIG_AR7_WDT) += ar7_wdt.o
obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
+obj-$(CONFIG_ATH79_WDT) += ath79_wdt.o
obj-$(CONFIG_OCTEON_WDT) += octeon-wdt.o
octeon-wdt-y := octeon-wdt-main.o octeon-wdt-nmi.o
diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c
new file mode 100644
index 0000000..f8e027b
--- /dev/null
+++ b/drivers/watchdog/ath79_wdt.c
@@ -0,0 +1,293 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X built-in hardware watchdog timer.
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * This driver was based on: drivers/watchdog/ixp4xx_wdt.c
+ * Author: Deepak Saxena <dsaxena@plexity.net>
+ * Copyright 2004 (c) MontaVista, Software, Inc.
+ *
+ * which again was based on sa1100 driver,
+ * Copyright (C) 2000 Oleg Drokin <green@crimea.edu>
+ *
+ * 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/bitops.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/reboot.h>
+#include <linux/watchdog.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+
+#define DRIVER_NAME "ath79-wdt"
+#define DRIVER_DESC "Atheros AR71XX/AR724X/AR913X hardware watchdog driver"
+
+#define WDT_TIMEOUT 15 /* seconds */
+
+#define WDOG_CTRL_LAST_RESET BIT(31)
+#define WDOG_CTRL_ACTION_MASK 3
+#define WDOG_CTRL_ACTION_NONE 0 /* no action */
+#define WDOG_CTRL_ACTION_GPI 1 /* general purpose interrupt */
+#define WDOG_CTRL_ACTION_NMI 2 /* NMI */
+#define WDOG_CTRL_ACTION_FCR 3 /* full chip reset */
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+
+#ifdef CONFIG_WATCHDOG_NOWAYOUT
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
+ "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+#endif
+
+static unsigned long wdt_flags;
+
+#define WDT_FLAGS_BUSY 0
+#define WDT_FLAGS_EXPECT_CLOSE 1
+
+static int wdt_timeout = WDT_TIMEOUT;
+static int boot_status;
+static int max_timeout;
+
+static inline void ath79_wdt_keepalive(void)
+{
+ ath79_reset_wr(AR71XX_RESET_REG_WDOG, ath79_ahb_freq * wdt_timeout);
+}
+
+static inline void ath79_wdt_enable(void)
+{
+ ath79_wdt_keepalive();
+ ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_FCR);
+}
+
+static inline void ath79_wdt_disable(void)
+{
+ ath79_reset_wr(AR71XX_RESET_REG_WDOG_CTRL, WDOG_CTRL_ACTION_NONE);
+}
+
+static int ath79_wdt_set_timeout(int val)
+{
+ if (val < 1 || val > max_timeout)
+ return -EINVAL;
+
+ wdt_timeout = val;
+ ath79_wdt_keepalive();
+
+ return 0;
+}
+
+static int ath79_wdt_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(WDT_FLAGS_BUSY, &wdt_flags))
+ return -EBUSY;
+
+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
+ ath79_wdt_enable();
+
+ return nonseekable_open(inode, file);
+}
+
+static int ath79_wdt_release(struct inode *inode, struct file *file)
+{
+ if (test_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags))
+ ath79_wdt_disable();
+ else
+ pr_crit(DRIVER_NAME ": device closed unexpectedly, "
+ "watchdog timer will not stop!\n");
+
+ clear_bit(WDT_FLAGS_BUSY, &wdt_flags);
+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
+
+ return 0;
+}
+
+static ssize_t ath79_wdt_write(struct file *file, const char *data,
+ size_t len, loff_t *ppos)
+{
+ if (len) {
+ if (!nowayout) {
+ size_t i;
+
+ clear_bit(WDT_FLAGS_EXPECT_CLOSE, &wdt_flags);
+
+ for (i = 0; i != len; i++) {
+ char c;
+
+ if (get_user(c, data + i))
+ return -EFAULT;
+
+ if (c == 'V')
+ set_bit(WDT_FLAGS_EXPECT_CLOSE,
+ &wdt_flags);
+ }
+ }
+
+ ath79_wdt_keepalive();
+ }
+
+ return len;
+}
+
+static const struct watchdog_info ath79_wdt_info = {
+ .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE | WDIOF_CARDRESET,
+ .firmware_version = 0,
+ .identity = "ATH79 watchdog",
+};
+
+static long ath79_wdt_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ int err;
+ int t;
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ err = copy_to_user(argp, &ath79_wdt_info,
+ sizeof(ath79_wdt_info)) ? -EFAULT : 0;
+ break;
+
+ case WDIOC_GETSTATUS:
+ err = put_user(0, p);
+ break;
+
+ case WDIOC_GETBOOTSTATUS:
+ err = put_user(boot_status, p);
+ break;
+
+ case WDIOC_KEEPALIVE:
+ ath79_wdt_keepalive();
+ err = 0;
+ break;
+
+ case WDIOC_SETTIMEOUT:
+ err = get_user(t, p);
+ if (err)
+ break;
+
+ err = ath79_wdt_set_timeout(t);
+ if (err)
+ break;
+
+ /* fallthrough */
+ case WDIOC_GETTIMEOUT:
+ err = put_user(wdt_timeout, p);
+ break;
+
+ default:
+ err = -ENOTTY;
+ break;
+ }
+
+ return err;
+}
+
+static const struct file_operations ath79_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = ath79_wdt_write,
+ .unlocked_ioctl = ath79_wdt_ioctl,
+ .open = ath79_wdt_open,
+ .release = ath79_wdt_release,
+};
+
+static int ath79_wdt_notify_sys(struct notifier_block *this,
+ unsigned long code, void *unused)
+{
+ if (code == SYS_DOWN || code == SYS_HALT)
+ ath79_wdt_disable();
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block ath79_wdt_notifier = {
+ .notifier_call = ath79_wdt_notify_sys,
+};
+
+static struct miscdevice ath79_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &ath79_wdt_fops,
+};
+
+static int __init ath79_wdt_probe(struct platform_device *pdev)
+{
+ u32 ctrl;
+ int err;
+
+ max_timeout = (0xfffffffful / ath79_ahb_freq);
+ wdt_timeout = (max_timeout < WDT_TIMEOUT) ? max_timeout : WDT_TIMEOUT;
+
+ ctrl = ath79_reset_rr(AR71XX_RESET_REG_WDOG_CTRL);
+ boot_status = (ctrl & WDOG_CTRL_LAST_RESET) ? WDIOF_CARDRESET : 0;
+
+ err = register_reboot_notifier(&ath79_wdt_notifier);
+ if (err) {
+ dev_err(&pdev->dev,
+ "unable to register reboot notifier, err=%d\n", err);
+ goto err;
+ }
+
+ err = misc_register(&ath79_wdt_miscdev);
+ if (err) {
+ dev_err(&pdev->dev,
+ "unable to register misc device, err=%d\n", err);
+ goto err_unregister;
+ }
+
+ return 0;
+
+err_unregister:
+ unregister_reboot_notifier(&ath79_wdt_notifier);
+
+err:
+ return err;
+}
+
+static int __exit ath79_wdt_remove(struct platform_device *pdev)
+{
+ misc_deregister(&ath79_wdt_miscdev);
+ return 0;
+}
+
+static struct platform_driver ath79_wdt_driver = {
+ .remove = __exit_p(ath79_wdt_remove),
+ .driver = {
+ .name = DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init ath79_wdt_init(void)
+{
+ return platform_driver_probe(&ath79_wdt_driver, ath79_wdt_probe);
+}
+module_init(ath79_wdt_init);
+
+static void __exit ath79_wdt_exit(void)
+{
+ platform_driver_unregister(&ath79_wdt_driver);
+}
+module_exit(ath79_wdt_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org");
+MODULE_AUTHOR("Imre Kaloz <kaloz@openwrt.org");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRIVER_NAME);
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 07/16] MIPS: ath79: add common watchdog device
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (5 preceding siblings ...)
2010-12-22 20:30 ` [PATCH v2 06/16] watchdog: add driver for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
@ 2010-12-22 20:30 ` Gabor Juhos
2010-12-23 10:41 ` Sergei Shtylyov
2010-12-22 20:30 ` [PATCH v2 08/16] MIPS: ath79: add common GPIO buttons device Gabor Juhos
` (8 subsequent siblings)
15 siblings, 1 reply; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos
All supported SoCs have a built-in hardware watchdog driver. This patch
registers a platform_device for that to make it usable.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC:
- remove the ATH79_DEV_WDT Kconfig option, and move the watchdog platform
code into dev-common.[ch]
Changes since v1:
- rebased against 2.6.37-rc7
arch/mips/ath79/dev-common.c | 10 ++++++++++
arch/mips/ath79/dev-common.h | 1 +
arch/mips/ath79/setup.c | 1 +
3 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c
index 897522c..74b1e3b 100644
--- a/arch/mips/ath79/dev-common.c
+++ b/arch/mips/ath79/dev-common.c
@@ -57,3 +57,13 @@ void __init ath79_register_uart(void)
ath79_uart_data[0].uartclk = ath79_ahb_freq;
platform_device_register(&ath79_uart_device);
}
+
+static struct platform_device ath79_wdt_device = {
+ .name = "ath79-wdt",
+ .id = -1,
+};
+
+void __init ath79_register_wdt(void)
+{
+ platform_device_register(&ath79_wdt_device);
+}
diff --git a/arch/mips/ath79/dev-common.h b/arch/mips/ath79/dev-common.h
index 1cec894..65bf400 100644
--- a/arch/mips/ath79/dev-common.h
+++ b/arch/mips/ath79/dev-common.h
@@ -13,5 +13,6 @@
#define _ATH79_DEV_COMMON_H
void ath79_register_uart(void) __init;
+void ath79_register_wdt(void) __init;
#endif /* _ATH79_DEV_COMMON_H */
diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c
index 5f2b6de..ef4207f 100644
--- a/arch/mips/ath79/setup.c
+++ b/arch/mips/ath79/setup.c
@@ -259,6 +259,7 @@ static int __init ath79_setup(void)
{
ath79_gpio_init();
ath79_register_uart();
+ ath79_register_wdt();
mips_machine_setup();
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 08/16] MIPS: ath79: add common GPIO buttons device
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (6 preceding siblings ...)
2010-12-22 20:30 ` [PATCH v2 07/16] MIPS: ath79: add common watchdog device Gabor Juhos
@ 2010-12-22 20:30 ` Gabor Juhos
2010-12-22 20:30 ` Gabor Juhos
` (7 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos
Almost all boards have one or more push buttons connected to GPIO lines.
This patch adds common code to register a platform_device for them.
The patch also adds support for the buttons on the PB44 board.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC: ---
Changes since v1:
- converted to use the gpio_keys_polled driver
- rebased against 2.6.37-rc7
arch/mips/ath79/Kconfig | 4 ++
arch/mips/ath79/Makefile | 1 +
arch/mips/ath79/dev-gpio-buttons.c | 58 ++++++++++++++++++++++++++++++++++++
arch/mips/ath79/dev-gpio-buttons.h | 23 ++++++++++++++
arch/mips/ath79/mach-pb44.c | 27 ++++++++++++++++
5 files changed, 113 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/ath79/dev-gpio-buttons.c
create mode 100644 arch/mips/ath79/dev-gpio-buttons.h
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 5bc480e..185a8d6 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -5,6 +5,7 @@ menu "Atheros AR71XX/AR724X/AR913X machine selection"
config ATH79_MACH_PB44
bool "Atheros PB44 reference board"
select SOC_AR71XX
+ select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO
help
Say 'Y' here if you want your kernel to support the
@@ -21,6 +22,9 @@ config SOC_AR724X
config SOC_AR913X
def_bool n
+config ATH79_DEV_GPIO_BUTTONS
+ def_bool n
+
config ATH79_DEV_LEDS_GPIO
def_bool n
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index d14b597..0ceb45e 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
# Devices
#
obj-y += dev-common.o
+obj-$(CONFIG_ATH79_DEV_GPIO_BUTTONS) += dev-gpio-buttons.o
obj-$(CONFIG_ATH79_DEV_LEDS_GPIO) += dev-leds-gpio.o
#
diff --git a/arch/mips/ath79/dev-gpio-buttons.c b/arch/mips/ath79/dev-gpio-buttons.c
new file mode 100644
index 0000000..4b0168a
--- /dev/null
+++ b/arch/mips/ath79/dev-gpio-buttons.c
@@ -0,0 +1,58 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X GPIO button support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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/init.h"
+#include "linux/slab.h"
+#include <linux/platform_device.h>
+
+#include "dev-gpio-buttons.h"
+
+void __init ath79_register_gpio_keys_polled(int id,
+ unsigned poll_interval,
+ unsigned nbuttons,
+ struct gpio_keys_button *buttons)
+{
+ struct platform_device *pdev;
+ struct gpio_keys_platform_data pdata;
+ struct gpio_keys_button *p;
+ int err;
+
+ p = kmalloc(nbuttons * sizeof(*p), GFP_KERNEL);
+ if (!p)
+ return;
+
+ memcpy(p, buttons, nbuttons * sizeof(*p));
+
+ pdev = platform_device_alloc("gpio-keys-polled", id);
+ if (!pdev)
+ goto err_free_buttons;
+
+ memset(&pdata, 0, sizeof(pdata));
+ pdata.poll_interval = poll_interval;
+ pdata.nbuttons = nbuttons;
+ pdata.buttons = p;
+
+ err = platform_device_add_data(pdev, &pdata, sizeof(pdata));
+ if (err)
+ goto err_put_pdev;
+
+ err = platform_device_add(pdev);
+ if (err)
+ goto err_put_pdev;
+
+ return;
+
+err_put_pdev:
+ platform_device_put(pdev);
+
+err_free_buttons:
+ kfree(p);
+}
diff --git a/arch/mips/ath79/dev-gpio-buttons.h b/arch/mips/ath79/dev-gpio-buttons.h
new file mode 100644
index 0000000..51783af
--- /dev/null
+++ b/arch/mips/ath79/dev-gpio-buttons.h
@@ -0,0 +1,23 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X GPIO button support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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.
+ */
+
+#ifndef _ATH79_DEV_GPIO_BUTTONS_H
+#define _ATH79_DEV_GPIO_BUTTONS_H
+
+#include <linux/input.h>
+#include <linux/gpio_keys.h>
+
+void ath79_register_gpio_keys_polled(int id,
+ unsigned poll_interval,
+ unsigned nbuttons,
+ struct gpio_keys_button *buttons) __init;
+
+#endif /* _ATH79_DEV_GPIO_BUTTONS_H */
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index e176779..3dc5080 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -15,15 +15,21 @@
#include <linux/i2c/pcf857x.h>
#include "machtypes.h"
+#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
#define PB44_GPIO_I2C_SCL 0
#define PB44_GPIO_I2C_SDA 1
#define PB44_GPIO_EXP_BASE 16
+#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)
#define PB44_GPIO_LED_JUMP2 (PB44_GPIO_EXP_BASE + 10)
+#define PB44_KEYS_POLL_INTERVAL 20 /* msecs */
+#define PB44_KEYS_DEBOUNCE_INTERVAL (3 * PB44_KEYS_POLL_INTERVAL)
+
static struct i2c_gpio_platform_data pb44_i2c_gpio_data = {
.sda_pin = PB44_GPIO_I2C_SDA,
.scl_pin = PB44_GPIO_I2C_SCL,
@@ -60,6 +66,24 @@ static struct gpio_led pb44_leds_gpio[] __initdata = {
},
};
+static struct gpio_keys_button pb44_gpio_keys[] __initdata = {
+ {
+ .desc = "soft_reset",
+ .type = EV_KEY,
+ .code = KEY_RESTART,
+ .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = PB44_GPIO_SW_RESET,
+ .active_low = 1,
+ } , {
+ .desc = "jumpstart",
+ .type = EV_KEY,
+ .code = KEY_WPS_BUTTON,
+ .debounce_interval = PB44_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = PB44_GPIO_SW_JUMP,
+ .active_low = 1,
+ }
+};
+
static void __init pb44_init(void)
{
i2c_register_board_info(0, pb44_i2c_board_info,
@@ -68,6 +92,9 @@ static void __init pb44_init(void)
ath79_register_leds_gpio(-1, ARRAY_SIZE(pb44_leds_gpio),
pb44_leds_gpio);
+ ath79_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL,
+ ARRAY_SIZE(pb44_gpio_keys),
+ pb44_gpio_keys);
}
MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 09/16] spi: add SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs
@ 2010-12-22 20:30 ` Gabor Juhos
0 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos, David Brownell, spi-devel-general
The Atheros AR71XX/AR724X/AR913X SoCs have a built-in SPI controller. This
patch implements a driver for that.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: spi-devel-general@lists.sourceforge.net
---
Changes since RFC:
- remove DRV_DESC definition and use its previous value directly in the
MODULE_DESCRIPTION() macro,
- use io{read,write}32 accesors instead of __raw_{read,write}l,
- use __dev{init,exit,exit_p} annotations where in the appropriate places,
- initialize 'master->bus_num' field to -1 if no platform data specified,
so that a bus number can be dynamically assigned,
- rename ath79_spi_drv to ath79_spi_driver to avoid section mismatch
warnings
Changes since v1:
- rebased against 2.6.37-rc7
.../include/asm/mach-ath79/ath79_spi_platform.h | 19 ++
drivers/spi/Kconfig | 8 +
drivers/spi/Makefile | 1 +
drivers/spi/ath79_spi.c | 290 ++++++++++++++++++++
4 files changed, 318 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
create mode 100644 drivers/spi/ath79_spi.c
diff --git a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
new file mode 100644
index 0000000..aa71216
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
@@ -0,0 +1,19 @@
+/*
+ * Platform data definition for Atheros AR71XX/AR724X/AR913X SPI controller
+ *
+ * Copyright (C) 2008-2010 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.
+ */
+
+#ifndef _ATH79_SPI_PLATFORM_H
+#define _ATH79_SPI_PLATFORM_H
+
+struct ath79_spi_platform_data {
+ unsigned bus_num;
+ unsigned num_chipselect;
+};
+
+#endif /* _ATH79_SPI_PLATFORM_H */
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 78f9fd0..f2093e1 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -53,6 +53,14 @@ if SPI_MASTER
comment "SPI Master Controller Drivers"
+config SPI_ATH79
+ tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver"
+ depends on ATH79 && GENERIC_GPIO
+ select SPI_BITBANG
+ help
+ This enables support for the SPI controller present on the
+ Atheros AR71XX/AR724X/AR913X SoCs.
+
config SPI_ATMEL
tristate "Atmel SPI Controller"
depends on (ARCH_AT91 || AVR32)
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 8bc1a5a..875bc3d 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_SPI_MASTER) += spi.o
# SPI master controller drivers (bus)
obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o
+obj-$(CONFIG_SPI_ATH79) += ath79_spi.o
obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o
obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
obj-$(CONFIG_SPI_AU1550) += au1550_spi.o
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
new file mode 100644
index 0000000..96f169a
--- /dev/null
+++ b/drivers/spi/ath79_spi.c
@@ -0,0 +1,290 @@
+/*
+ * SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs
+ *
+ * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
+ *
+ * This driver has been based on the spi-gpio.c:
+ * Copyright (C) 2006,2008 David Brownell
+ *
+ * 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/init.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79_spi_platform.h>
+
+#define DRV_NAME "ath79-spi"
+
+struct ath79_spi {
+ struct spi_bitbang bitbang;
+ u32 ioc_base;
+ u32 reg_ctrl;
+
+ void __iomem *base;
+
+ struct platform_device *pdev;
+};
+
+static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg)
+{
+ return ioread32(sp->base + reg);
+}
+
+static inline void ath79_spi_wr(struct ath79_spi *sp, unsigned reg, u32 val)
+{
+ iowrite32(val, sp->base + reg);
+}
+
+static inline struct ath79_spi *spidev_to_sp(struct spi_device *spi)
+{
+ return spi_master_get_devdata(spi->master);
+}
+
+static void ath79_spi_chipselect(struct spi_device *spi, int is_active)
+{
+ struct ath79_spi *sp = spidev_to_sp(spi);
+ int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
+
+ if (is_active) {
+ /* set initial clock polarity */
+ if (spi->mode & SPI_CPOL)
+ sp->ioc_base |= AR71XX_SPI_IOC_CLK;
+ else
+ sp->ioc_base &= ~AR71XX_SPI_IOC_CLK;
+
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+ }
+
+ if (spi->chip_select) {
+ unsigned long gpio = (unsigned long) spi->controller_data;
+
+ /* SPI is normally active-low */
+ gpio_set_value(gpio, cs_high);
+ } else {
+ if (cs_high)
+ sp->ioc_base |= AR71XX_SPI_IOC_CS0;
+ else
+ sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
+
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+ }
+
+}
+
+static int ath79_spi_setup_cs(struct spi_device *spi)
+{
+ struct ath79_spi *sp = spidev_to_sp(spi);
+
+ /* enable GPIO mode */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
+
+ /* 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);
+
+ if (spi->chip_select) {
+ unsigned long gpio = (unsigned long) spi->controller_data;
+ int status = 0;
+
+ status = gpio_request(gpio, dev_name(&spi->dev));
+ if (status)
+ return status;
+
+ status = gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH);
+ if (status) {
+ gpio_free(gpio);
+ return status;
+ }
+ } else {
+ if (spi->mode & SPI_CS_HIGH)
+ sp->ioc_base |= AR71XX_SPI_IOC_CS0;
+ else
+ sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+ }
+
+ return 0;
+}
+
+static void ath79_spi_cleanup_cs(struct spi_device *spi)
+{
+ struct ath79_spi *sp = spidev_to_sp(spi);
+
+ if (spi->chip_select) {
+ unsigned long gpio = (unsigned long) spi->controller_data;
+ gpio_free(gpio);
+ }
+
+ /* restore CTRL register */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl);
+ /* disable GPIO mode */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
+}
+
+static int ath79_spi_setup(struct spi_device *spi)
+{
+ int status = 0;
+
+ if (spi->bits_per_word > 32)
+ return -EINVAL;
+
+ if (!spi->controller_state) {
+ status = ath79_spi_setup_cs(spi);
+ if (status)
+ return status;
+ }
+
+ status = spi_bitbang_setup(spi);
+ if (status && !spi->controller_state)
+ ath79_spi_cleanup_cs(spi);
+
+ return status;
+}
+
+static void ath79_spi_cleanup(struct spi_device *spi)
+{
+ ath79_spi_cleanup_cs(spi);
+ spi_bitbang_cleanup(spi);
+}
+
+static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
+ u32 word, u8 bits)
+{
+ struct ath79_spi *sp = spidev_to_sp(spi);
+ u32 ioc = sp->ioc_base;
+
+ /* clock starts at inactive polarity */
+ for (word <<= (32 - bits); likely(bits); bits--) {
+ u32 out;
+
+ if (word & (1 << 31))
+ out = ioc | AR71XX_SPI_IOC_DO;
+ else
+ out = ioc & ~AR71XX_SPI_IOC_DO;
+
+ /* setup MSB (to slave) on trailing edge */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out);
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out | AR71XX_SPI_IOC_CLK);
+
+ word <<= 1;
+ }
+
+ return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS);
+}
+
+static __devinit int ath79_spi_probe(struct platform_device *pdev)
+{
+ struct spi_master *master;
+ struct ath79_spi *sp;
+ struct ath79_spi_platform_data *pdata;
+ struct resource *r;
+ int ret;
+
+ master = spi_alloc_master(&pdev->dev, sizeof(*sp));
+ if (master == NULL) {
+ dev_err(&pdev->dev, "failed to allocate spi master\n");
+ return -ENOMEM;
+ }
+
+ sp = spi_master_get_devdata(master);
+ platform_set_drvdata(pdev, sp);
+
+ pdata = pdev->dev.platform_data;
+
+ master->setup = ath79_spi_setup;
+ master->cleanup = ath79_spi_cleanup;
+ if (pdata) {
+ master->bus_num = pdata->bus_num;
+ master->num_chipselect = pdata->num_chipselect;
+ } else {
+ master->bus_num = -1;
+ master->num_chipselect = 1;
+ }
+
+ sp->bitbang.master = spi_master_get(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.flags = SPI_CS_HIGH;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (r == NULL) {
+ ret = -ENOENT;
+ goto err_put_master;
+ }
+
+ sp->base = ioremap(r->start, r->end - r->start + 1);
+ if (!sp->base) {
+ ret = -ENXIO;
+ goto err_put_master;
+ }
+
+ ret = spi_bitbang_start(&sp->bitbang);
+ if (ret)
+ goto err_unmap;
+
+ return 0;
+
+err_unmap:
+ iounmap(sp->base);
+err_put_master:
+ platform_set_drvdata(pdev, NULL);
+ spi_master_put(sp->bitbang.master);
+
+ return ret;
+}
+
+static __devexit int ath79_spi_remove(struct platform_device *pdev)
+{
+ struct ath79_spi *sp = platform_get_drvdata(pdev);
+
+ spi_bitbang_stop(&sp->bitbang);
+ iounmap(sp->base);
+ platform_set_drvdata(pdev, NULL);
+ spi_master_put(sp->bitbang.master);
+
+ return 0;
+}
+
+static struct platform_driver ath79_spi_driver = {
+ .probe = ath79_spi_probe,
+ .remove = __devexit_p(ath79_spi_remove),
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static __init int ath79_spi_init(void)
+{
+ return platform_driver_register(&ath79_spi_driver);
+}
+module_init(ath79_spi_init);
+
+static __exit void ath79_spi_exit(void)
+{
+ platform_driver_unregister(&ath79_spi_driver);
+}
+module_exit(ath79_spi_exit);
+
+MODULE_DESCRIPTION("SPI controller driver for Atheros AR71XX/AR724X/AR91X");
+MODULE_AUTHOR("Gabor Juhos <juhosg@openwrt.org>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 09/16] spi: add SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs
@ 2010-12-22 20:30 ` Gabor Juhos
0 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips-6z/3iImG2C8G8FEW9MqTrA, David Brownell,
Luis R. Rodriguez, Cliff Holden, Gabor Juhos, Kathy Giori,
spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f, Imre Kaloz
The Atheros AR71XX/AR724X/AR913X SoCs have a built-in SPI controller. This
patch implements a driver for that.
Signed-off-by: Gabor Juhos <juhosg-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
Cc: David Brownell <dbrownell-Rn4VEauK+AKRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
Cc: spi-devel-general-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
---
Changes since RFC:
- remove DRV_DESC definition and use its previous value directly in the
MODULE_DESCRIPTION() macro,
- use io{read,write}32 accesors instead of __raw_{read,write}l,
- use __dev{init,exit,exit_p} annotations where in the appropriate places,
- initialize 'master->bus_num' field to -1 if no platform data specified,
so that a bus number can be dynamically assigned,
- rename ath79_spi_drv to ath79_spi_driver to avoid section mismatch
warnings
Changes since v1:
- rebased against 2.6.37-rc7
.../include/asm/mach-ath79/ath79_spi_platform.h | 19 ++
drivers/spi/Kconfig | 8 +
drivers/spi/Makefile | 1 +
drivers/spi/ath79_spi.c | 290 ++++++++++++++++++++
4 files changed, 318 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
create mode 100644 drivers/spi/ath79_spi.c
diff --git a/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
new file mode 100644
index 0000000..aa71216
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79_spi_platform.h
@@ -0,0 +1,19 @@
+/*
+ * Platform data definition for Atheros AR71XX/AR724X/AR913X SPI controller
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg-p3rKhJxN3npAfugRpC6u6w@public.gmane.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.
+ */
+
+#ifndef _ATH79_SPI_PLATFORM_H
+#define _ATH79_SPI_PLATFORM_H
+
+struct ath79_spi_platform_data {
+ unsigned bus_num;
+ unsigned num_chipselect;
+};
+
+#endif /* _ATH79_SPI_PLATFORM_H */
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 78f9fd0..f2093e1 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -53,6 +53,14 @@ if SPI_MASTER
comment "SPI Master Controller Drivers"
+config SPI_ATH79
+ tristate "Atheros AR71XX/AR724X/AR913X SPI controller driver"
+ depends on ATH79 && GENERIC_GPIO
+ select SPI_BITBANG
+ help
+ This enables support for the SPI controller present on the
+ Atheros AR71XX/AR724X/AR913X SoCs.
+
config SPI_ATMEL
tristate "Atmel SPI Controller"
depends on (ARCH_AT91 || AVR32)
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index 8bc1a5a..875bc3d 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_SPI_MASTER) += spi.o
# SPI master controller drivers (bus)
obj-$(CONFIG_SPI_ATMEL) += atmel_spi.o
+obj-$(CONFIG_SPI_ATH79) += ath79_spi.o
obj-$(CONFIG_SPI_BFIN) += spi_bfin5xx.o
obj-$(CONFIG_SPI_BITBANG) += spi_bitbang.o
obj-$(CONFIG_SPI_AU1550) += au1550_spi.o
diff --git a/drivers/spi/ath79_spi.c b/drivers/spi/ath79_spi.c
new file mode 100644
index 0000000..96f169a
--- /dev/null
+++ b/drivers/spi/ath79_spi.c
@@ -0,0 +1,290 @@
+/*
+ * SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs
+ *
+ * Copyright (C) 2009-2010 Gabor Juhos <juhosg-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>
+ *
+ * This driver has been based on the spi-gpio.c:
+ * Copyright (C) 2006,2008 David Brownell
+ *
+ * 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/init.h>
+#include <linux/delay.h>
+#include <linux/spinlock.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/bitops.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79_spi_platform.h>
+
+#define DRV_NAME "ath79-spi"
+
+struct ath79_spi {
+ struct spi_bitbang bitbang;
+ u32 ioc_base;
+ u32 reg_ctrl;
+
+ void __iomem *base;
+
+ struct platform_device *pdev;
+};
+
+static inline u32 ath79_spi_rr(struct ath79_spi *sp, unsigned reg)
+{
+ return ioread32(sp->base + reg);
+}
+
+static inline void ath79_spi_wr(struct ath79_spi *sp, unsigned reg, u32 val)
+{
+ iowrite32(val, sp->base + reg);
+}
+
+static inline struct ath79_spi *spidev_to_sp(struct spi_device *spi)
+{
+ return spi_master_get_devdata(spi->master);
+}
+
+static void ath79_spi_chipselect(struct spi_device *spi, int is_active)
+{
+ struct ath79_spi *sp = spidev_to_sp(spi);
+ int cs_high = (spi->mode & SPI_CS_HIGH) ? is_active : !is_active;
+
+ if (is_active) {
+ /* set initial clock polarity */
+ if (spi->mode & SPI_CPOL)
+ sp->ioc_base |= AR71XX_SPI_IOC_CLK;
+ else
+ sp->ioc_base &= ~AR71XX_SPI_IOC_CLK;
+
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+ }
+
+ if (spi->chip_select) {
+ unsigned long gpio = (unsigned long) spi->controller_data;
+
+ /* SPI is normally active-low */
+ gpio_set_value(gpio, cs_high);
+ } else {
+ if (cs_high)
+ sp->ioc_base |= AR71XX_SPI_IOC_CS0;
+ else
+ sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
+
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+ }
+
+}
+
+static int ath79_spi_setup_cs(struct spi_device *spi)
+{
+ struct ath79_spi *sp = spidev_to_sp(spi);
+
+ /* enable GPIO mode */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, AR71XX_SPI_FS_GPIO);
+
+ /* 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);
+
+ if (spi->chip_select) {
+ unsigned long gpio = (unsigned long) spi->controller_data;
+ int status = 0;
+
+ status = gpio_request(gpio, dev_name(&spi->dev));
+ if (status)
+ return status;
+
+ status = gpio_direction_output(gpio, spi->mode & SPI_CS_HIGH);
+ if (status) {
+ gpio_free(gpio);
+ return status;
+ }
+ } else {
+ if (spi->mode & SPI_CS_HIGH)
+ sp->ioc_base |= AR71XX_SPI_IOC_CS0;
+ else
+ sp->ioc_base &= ~AR71XX_SPI_IOC_CS0;
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, sp->ioc_base);
+ }
+
+ return 0;
+}
+
+static void ath79_spi_cleanup_cs(struct spi_device *spi)
+{
+ struct ath79_spi *sp = spidev_to_sp(spi);
+
+ if (spi->chip_select) {
+ unsigned long gpio = (unsigned long) spi->controller_data;
+ gpio_free(gpio);
+ }
+
+ /* restore CTRL register */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_CTRL, sp->reg_ctrl);
+ /* disable GPIO mode */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_FS, 0);
+}
+
+static int ath79_spi_setup(struct spi_device *spi)
+{
+ int status = 0;
+
+ if (spi->bits_per_word > 32)
+ return -EINVAL;
+
+ if (!spi->controller_state) {
+ status = ath79_spi_setup_cs(spi);
+ if (status)
+ return status;
+ }
+
+ status = spi_bitbang_setup(spi);
+ if (status && !spi->controller_state)
+ ath79_spi_cleanup_cs(spi);
+
+ return status;
+}
+
+static void ath79_spi_cleanup(struct spi_device *spi)
+{
+ ath79_spi_cleanup_cs(spi);
+ spi_bitbang_cleanup(spi);
+}
+
+static u32 ath79_spi_txrx_mode0(struct spi_device *spi, unsigned nsecs,
+ u32 word, u8 bits)
+{
+ struct ath79_spi *sp = spidev_to_sp(spi);
+ u32 ioc = sp->ioc_base;
+
+ /* clock starts at inactive polarity */
+ for (word <<= (32 - bits); likely(bits); bits--) {
+ u32 out;
+
+ if (word & (1 << 31))
+ out = ioc | AR71XX_SPI_IOC_DO;
+ else
+ out = ioc & ~AR71XX_SPI_IOC_DO;
+
+ /* setup MSB (to slave) on trailing edge */
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out);
+ ath79_spi_wr(sp, AR71XX_SPI_REG_IOC, out | AR71XX_SPI_IOC_CLK);
+
+ word <<= 1;
+ }
+
+ return ath79_spi_rr(sp, AR71XX_SPI_REG_RDS);
+}
+
+static __devinit int ath79_spi_probe(struct platform_device *pdev)
+{
+ struct spi_master *master;
+ struct ath79_spi *sp;
+ struct ath79_spi_platform_data *pdata;
+ struct resource *r;
+ int ret;
+
+ master = spi_alloc_master(&pdev->dev, sizeof(*sp));
+ if (master == NULL) {
+ dev_err(&pdev->dev, "failed to allocate spi master\n");
+ return -ENOMEM;
+ }
+
+ sp = spi_master_get_devdata(master);
+ platform_set_drvdata(pdev, sp);
+
+ pdata = pdev->dev.platform_data;
+
+ master->setup = ath79_spi_setup;
+ master->cleanup = ath79_spi_cleanup;
+ if (pdata) {
+ master->bus_num = pdata->bus_num;
+ master->num_chipselect = pdata->num_chipselect;
+ } else {
+ master->bus_num = -1;
+ master->num_chipselect = 1;
+ }
+
+ sp->bitbang.master = spi_master_get(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.flags = SPI_CS_HIGH;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (r == NULL) {
+ ret = -ENOENT;
+ goto err_put_master;
+ }
+
+ sp->base = ioremap(r->start, r->end - r->start + 1);
+ if (!sp->base) {
+ ret = -ENXIO;
+ goto err_put_master;
+ }
+
+ ret = spi_bitbang_start(&sp->bitbang);
+ if (ret)
+ goto err_unmap;
+
+ return 0;
+
+err_unmap:
+ iounmap(sp->base);
+err_put_master:
+ platform_set_drvdata(pdev, NULL);
+ spi_master_put(sp->bitbang.master);
+
+ return ret;
+}
+
+static __devexit int ath79_spi_remove(struct platform_device *pdev)
+{
+ struct ath79_spi *sp = platform_get_drvdata(pdev);
+
+ spi_bitbang_stop(&sp->bitbang);
+ iounmap(sp->base);
+ platform_set_drvdata(pdev, NULL);
+ spi_master_put(sp->bitbang.master);
+
+ return 0;
+}
+
+static struct platform_driver ath79_spi_driver = {
+ .probe = ath79_spi_probe,
+ .remove = __devexit_p(ath79_spi_remove),
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ },
+};
+
+static __init int ath79_spi_init(void)
+{
+ return platform_driver_register(&ath79_spi_driver);
+}
+module_init(ath79_spi_init);
+
+static __exit void ath79_spi_exit(void)
+{
+ platform_driver_unregister(&ath79_spi_driver);
+}
+module_exit(ath79_spi_exit);
+
+MODULE_DESCRIPTION("SPI controller driver for Atheros AR71XX/AR724X/AR91X");
+MODULE_AUTHOR("Gabor Juhos <juhosg-p3rKhJxN3npAfugRpC6u6w@public.gmane.org>");
+MODULE_LICENSE("GPL v2");
+MODULE_ALIAS("platform:" DRV_NAME);
--
1.7.2.1
------------------------------------------------------------------------------
Learn how Oracle Real Application Clusters (RAC) One Node allows customers
to consolidate database storage, standardize their database environment, and,
should the need arise, upgrade to a full multi-node Oracle RAC database
without downtime or disruption
http://p.sf.net/sfu/oracle-sfdevnl
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 10/16] MIPS: ath79: add common SPI controller device
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (8 preceding siblings ...)
2010-12-22 20:30 ` Gabor Juhos
@ 2010-12-22 20:30 ` Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 11/16] USB: ehci: add workaround for Synopsys HC bug Gabor Juhos
` (5 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos
Several boards are using the built-in SPI controller of the
AR71XX/AR724X/AR913X SoCs. This patch adds common platform_device
and helper code to register it. Additionally, the patch registers
the SPI bus on the PB44 board.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since RFC: ---
Changes since v1:
- rebased against 2.6.37-rc7
arch/mips/ath79/Kconfig | 4 ++
arch/mips/ath79/Makefile | 1 +
arch/mips/ath79/dev-spi.c | 38 ++++++++++++++++++++++++
arch/mips/ath79/dev-spi.h | 22 ++++++++++++++
arch/mips/ath79/mach-pb44.c | 17 ++++++++++
arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 2 +
6 files changed, 84 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/ath79/dev-spi.c
create mode 100644 arch/mips/ath79/dev-spi.h
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 185a8d6..cd6c738 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -7,6 +7,7 @@ config ATH79_MACH_PB44
select SOC_AR71XX
select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_SPI
help
Say 'Y' here if you want your kernel to support the
Atheros PB44 reference board.
@@ -28,4 +29,7 @@ config ATH79_DEV_GPIO_BUTTONS
config ATH79_DEV_LEDS_GPIO
def_bool n
+config ATH79_DEV_SPI
+ def_bool n
+
endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index 0ceb45e..a8de078 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += dev-common.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_SPI) += dev-spi.o
#
# Machines
diff --git a/arch/mips/ath79/dev-spi.c b/arch/mips/ath79/dev-spi.c
new file mode 100644
index 0000000..aa30163
--- /dev/null
+++ b/arch/mips/ath79/dev-spi.c
@@ -0,0 +1,38 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X SPI controller device
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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/platform_device.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "dev-spi.h"
+
+static struct resource ath79_spi_resources[] = {
+ {
+ .start = AR71XX_SPI_BASE,
+ .end = AR71XX_SPI_BASE + AR71XX_SPI_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device ath79_spi_device = {
+ .name = "ath79-spi",
+ .id = -1,
+ .resource = ath79_spi_resources,
+ .num_resources = ARRAY_SIZE(ath79_spi_resources),
+};
+
+void __init ath79_register_spi(struct ath79_spi_platform_data *pdata,
+ struct spi_board_info const *info,
+ unsigned n)
+{
+ spi_register_board_info(info, n);
+ ath79_spi_device.dev.platform_data = pdata;
+ platform_device_register(&ath79_spi_device);
+}
diff --git a/arch/mips/ath79/dev-spi.h b/arch/mips/ath79/dev-spi.h
new file mode 100644
index 0000000..9a98333
--- /dev/null
+++ b/arch/mips/ath79/dev-spi.h
@@ -0,0 +1,22 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X SPI controller device
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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.
+ */
+
+#ifndef _ATH79_DEV_SPI_H
+#define _ATH79_DEV_SPI_H
+
+#include <linux/spi/spi.h>
+#include <asm/mach-ath79/ath79_spi_platform.h>
+
+void __init ath79_register_spi(struct ath79_spi_platform_data *pdata,
+ struct spi_board_info const *info,
+ unsigned n);
+
+#endif /* _ATH79_DEV_SPI_H */
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index 3dc5080..ec7b7a1 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -17,6 +17,7 @@
#include "machtypes.h"
#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
+#include "dev-spi.h"
#define PB44_GPIO_I2C_SCL 0
#define PB44_GPIO_I2C_SDA 1
@@ -84,6 +85,20 @@ static struct gpio_keys_button pb44_gpio_keys[] __initdata = {
}
};
+static struct spi_board_info pb44_spi_info[] = {
+ {
+ .bus_num = 0,
+ .chip_select = 0,
+ .max_speed_hz = 25000000,
+ .modalias = "m25p64",
+ },
+};
+
+static struct ath79_spi_platform_data pb44_spi_data = {
+ .bus_num = 0,
+ .num_chipselect = 1,
+};
+
static void __init pb44_init(void)
{
i2c_register_board_info(0, pb44_i2c_board_info,
@@ -95,6 +110,8 @@ static void __init pb44_init(void)
ath79_register_gpio_keys_polled(-1, PB44_KEYS_POLL_INTERVAL,
ARRAY_SIZE(pb44_gpio_keys),
pb44_gpio_keys);
+ ath79_register_spi(&pb44_spi_data, pb44_spi_info,
+ ARRAY_SIZE(pb44_spi_info));
}
MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index 7f2933d..4f2b621 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -20,6 +20,8 @@
#include <linux/bitops.h>
#define AR71XX_APB_BASE 0x18000000
+#define AR71XX_SPI_BASE 0x1f000000
+#define AR71XX_SPI_SIZE 0x01000000
#define AR71XX_DDR_CTRL_BASE (AR71XX_APB_BASE + 0x00000000)
#define AR71XX_DDR_CTRL_SIZE 0x100
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 11/16] USB: ehci: add workaround for Synopsys HC bug
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (9 preceding siblings ...)
2010-12-22 20:30 ` [PATCH v2 10/16] MIPS: ath79: add common SPI controller device Gabor Juhos
@ 2010-12-22 20:30 ` Gabor Juhos
2010-12-23 0:30 ` Greg KH
2010-12-22 20:30 ` [PATCH v2 12/16] USB: ehci: add bus glue for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (4 subsequent siblings)
15 siblings, 1 reply; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos, David Brownell, Greg Kroah-Hartman,
linux-usb
A Synopsys USB core used in various SoCs has a bug which might cause
that the host controller not issuing ping.
When software uses the Doorbell mechanism to remove queue heads, the
host controller still has references to the removed queue head even
after indicating an Interrupt on Async Advance. This happens if the last
executed queue head's Next Link queue head is removed.
Consequences of the defect:
The Host controller fetches the removed queue head, using memory that
would otherwise be deallocated.This results in incorrect transactions on
both the USB and system memory. This may result in undefined behavior.
Workarounds:
1) If no queue head is active (no Status field's Active bit is set)
after removing the queue heads, the software can write one of the valid
queue head addresses to the ASYNCLISTADDR register and deallocate the
removed queue head's memory after 2 microframes.
If one or more of the queue heads is active (the Active bit is set in
the Status field) after removing the queue heads, the software can delay
memory deallocation after time X, where X is the time required for the
Host Controller to go through all the queue heads once. X varies with
the number of queue heads and the time required to process periodic
transactions: if more periodic transactions must be performed, the Host
Controller has less time to process asynchronous transaction processing.
2) Do not use the Doorbell mechanism to remove the queue heads. Disable
the Asynchronous Schedule Enable bit instead.
The bug has been discussed on the linux-usb-devel mailing-list
four years ago, the original thread can be found here:
http://www.mail-archive.com/linux-usb-devel@lists.sourceforge.net/msg45345.html
This patch implements the first workaround as suggested by David Brownell.
The built-in USB host controller of the Atheros AR7130/AR7141/AR7161 SoCs
requires this to work properly.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: linux-usb@vger.kernel.org
---
Changes since RFC: ---
Changes since v1:
- rebased against 2.6.37-rc7
drivers/usb/host/ehci-q.c | 3 +++
drivers/usb/host/ehci.h | 1 +
2 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
index 233c288..343b8de 100644
--- a/drivers/usb/host/ehci-q.c
+++ b/drivers/usb/host/ehci-q.c
@@ -1193,6 +1193,9 @@ static void end_unlink_async (struct ehci_hcd *ehci)
ehci->reclaim = NULL;
start_unlink_async (ehci, next);
}
+
+ if (ehci->has_synopsys_hc_bug)
+ writel((u32)ehci->async->qh_dma, &ehci->regs->async_next);
}
/* makes sure the async qh will become idle */
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index ba8eab3..6da85b2 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -133,6 +133,7 @@ struct ehci_hcd { /* one per controller */
unsigned broken_periodic:1;
unsigned fs_i_thresh:1; /* Intel iso scheduling */
unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/
+ unsigned has_synopsys_hc_bug:1; /* Synopsys HC */
/* required for usb32 quirk */
#define OHCI_CTRL_HCFS (3 << 6)
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 12/16] USB: ehci: add bus glue for the Atheros AR71XX/AR724X/AR913X SoCs
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (10 preceding siblings ...)
2010-12-22 20:30 ` [PATCH v2 11/16] USB: ehci: add workaround for Synopsys HC bug Gabor Juhos
@ 2010-12-22 20:30 ` Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 13/16] USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs Gabor Juhos
` (3 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos, David Brownell, Greg Kroah-Hartman,
linux-usb
The Atheros AR71XX/AR724X/AR913X SoCs have a built-in EHCI controller.
This patch adds the necessary glue code to make the generic EHCI driver
usable for them.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: linux-usb@vger.kernel.org
---
Changes since RFC:
- don't use 'default y if SOC_*', select USB_ARCH_HAS_EHCI option in the
platform specific Kconfig file instead
- add missing 'ath79_ehci_platform.h' file
Changes since v1:
- rebased against 2.6.37-rc7
arch/mips/ath79/Kconfig | 3 +
.../include/asm/mach-ath79/ath79_ehci_platform.h | 18 ++
drivers/usb/host/Kconfig | 8 +
drivers/usb/host/ehci-ath79.c | 176 ++++++++++++++++++++
drivers/usb/host/ehci-hcd.c | 5 +
5 files changed, 210 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h
create mode 100644 drivers/usb/host/ehci-ath79.c
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index cd6c738..647f535 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -15,12 +15,15 @@ config ATH79_MACH_PB44
endmenu
config SOC_AR71XX
+ select USB_ARCH_HAS_EHCI
def_bool n
config SOC_AR724X
+ select USB_ARCH_HAS_EHCI
def_bool n
config SOC_AR913X
+ select USB_ARCH_HAS_EHCI
def_bool n
config ATH79_DEV_GPIO_BUTTONS
diff --git a/arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h b/arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h
new file mode 100644
index 0000000..6ee075f
--- /dev/null
+++ b/arch/mips/include/asm/mach-ath79/ath79_ehci_platform.h
@@ -0,0 +1,18 @@
+/*
+ * Platform data definition for Atheros AR71XX/AR913X EHCI controller
+ *
+ * Copyright (C) 2008-2010 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.
+ */
+
+#ifndef _ATH79_EHCI_PLATFORM_H
+#define _ATH79_EHCI_PLATFORM_H
+
+struct ath79_ehci_platform_data {
+ u8 is_ar913x;
+};
+
+#endif /* _ATH79_EHCI_PLATFORM_H */
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 6f4f8e6..3a2667a 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -147,6 +147,14 @@ config USB_W90X900_EHCI
---help---
Enables support for the W90X900 USB controller
+config USB_EHCI_ATH79
+ bool "EHCI support for AR71XX/AR724X/AR913X SoCs"
+ depends on USB_EHCI_HCD && ATH79
+ select USB_EHCI_ROOT_HUB_TT
+ ---help---
+ Enables support for the built-in EHCI controller present
+ on the Atheros AR71XX/AR724X/AR913X SoCs.
+
config USB_OXU210HP_HCD
tristate "OXU210HP HCD support"
depends on USB
diff --git a/drivers/usb/host/ehci-ath79.c b/drivers/usb/host/ehci-ath79.c
new file mode 100644
index 0000000..43a728f
--- /dev/null
+++ b/drivers/usb/host/ehci-ath79.c
@@ -0,0 +1,176 @@
+/*
+ * Bus Glue for Atheros AR71XX/AR913X built-in EHCI controller.
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ * Copyright (C) 2007 Atheros Communications, Inc.
+ *
+ * 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/platform_device.h>
+#include <asm/mach-ath79/ath79_ehci_platform.h>
+
+static int ehci_ath79_init(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ struct ath79_ehci_platform_data *pdata;
+ int ret;
+
+ pdata = hcd->self.controller->platform_data;
+
+ if (pdata->is_ar913x) {
+ hcd->has_tt = 1;
+
+ ehci->caps = hcd->regs + 0x100;
+ ehci->regs = hcd->regs + 0x100 +
+ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+ } else {
+ ehci->has_synopsys_hc_bug = 1;
+
+ ehci->caps = hcd->regs;
+ ehci->regs = hcd->regs +
+ HC_LENGTH(ehci_readl(ehci, &ehci->caps->hc_capbase));
+ }
+
+ ehci->hcs_params = ehci_readl(ehci, &ehci->caps->hcs_params);
+ ehci->sbrn = 0x20;
+
+ ehci_reset(ehci);
+
+ ret = ehci_init(hcd);
+ if (ret)
+ return ret;
+
+ ehci_port_power(ehci, 0);
+
+ return 0;
+}
+
+static const struct hc_driver ehci_ath79_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "Atheros built-in EHCI controller",
+ .hcd_priv_size = sizeof(struct ehci_hcd),
+ .irq = ehci_irq,
+ .flags = HCD_MEMORY | HCD_USB2,
+
+ .reset = ehci_ath79_init,
+ .start = ehci_run,
+ .stop = ehci_stop,
+ .shutdown = ehci_shutdown,
+
+ .urb_enqueue = ehci_urb_enqueue,
+ .urb_dequeue = ehci_urb_dequeue,
+ .endpoint_disable = ehci_endpoint_disable,
+ .endpoint_reset = ehci_endpoint_reset,
+
+ .get_frame_number = ehci_get_frame,
+
+ .hub_status_data = ehci_hub_status_data,
+ .hub_control = ehci_hub_control,
+#ifdef CONFIG_PM
+ .hub_suspend = ehci_hub_suspend,
+ .hub_resume = ehci_hub_resume,
+#endif
+ .relinquish_port = ehci_relinquish_port,
+ .port_handed_over = ehci_port_handed_over,
+
+ .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+};
+
+static int ehci_ath79_probe(struct platform_device *pdev)
+{
+ struct ath79_ehci_platform_data *pdata;
+ struct usb_hcd *hcd;
+ struct resource *res;
+ int irq;
+ int ret;
+
+ if (usb_disabled())
+ return -ENODEV;
+
+ pdata = pdev->dev.platform_data;
+ if (!pdata) {
+ dev_dbg(&pdev->dev, "no platform data specified for %s\n",
+ dev_name(&pdev->dev));
+ return -EINVAL;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
+ dev_name(&pdev->dev));
+ return -ENODEV;
+ }
+ irq = res->start;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_dbg(&pdev->dev, "no base address specified for %s\n",
+ dev_name(&pdev->dev));
+ return -ENODEV;
+ }
+
+ hcd = usb_create_hcd(&ehci_ath79_hc_driver, &pdev->dev,
+ dev_name(&pdev->dev));
+ if (!hcd)
+ return -ENOMEM;
+
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = res->end - res->start + 1;
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ dev_dbg(&pdev->dev, "controller already in use\n");
+ ret = -EBUSY;
+ goto err_put_hcd;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ dev_dbg(&pdev->dev, "error mapping memory\n");
+ ret = -EFAULT;
+ goto err_release_region;
+ }
+
+ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
+ if (ret)
+ goto err_iounmap;
+
+ return 0;
+
+err_iounmap:
+ iounmap(hcd->regs);
+
+err_release_region:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_put_hcd:
+ usb_put_hcd(hcd);
+ return ret;
+}
+
+static int ehci_ath79_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ usb_put_hcd(hcd);
+
+ return 0;
+}
+
+static struct platform_driver ehci_ath79_driver = {
+ .probe = ehci_ath79_probe,
+ .remove = ehci_ath79_remove,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "ath79-ehci",
+ }
+};
+
+MODULE_ALIAS("platform:ath79-ehci");
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index e906280..b1313af 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -1216,6 +1216,11 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ehci_octeon_driver
#endif
+#ifdef CONFIG_USB_EHCI_ATH79
+#include "ehci-ath79.c"
+#define PLATFORM_DRIVER ehci_ath79_driver
+#endif
+
#if !defined(PCI_DRIVER) && !defined(PLATFORM_DRIVER) && \
!defined(PS3_SYSTEM_BUS_DRIVER) && !defined(OF_PLATFORM_DRIVER) && \
!defined(XILINX_OF_PLATFORM_DRIVER)
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 13/16] USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (11 preceding siblings ...)
2010-12-22 20:30 ` [PATCH v2 12/16] USB: ehci: add bus glue for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
@ 2010-12-22 20:30 ` Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 14/16] MIPS: ath79: add common USB Host Controller device Gabor Juhos
` (2 subsequent siblings)
15 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos, David Brownell, Greg Kroah-Hartman,
linux-usb
The Atheros AR71XX/AR7240 SoCs have a built-in OHCI controller.
This patch adds the necessary glue code to make the generic OHCI
driver usable for them.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
Cc: David Brownell <dbrownell@users.sourceforge.net>
Cc: Greg Kroah-Hartman <gregkh@suse.de>
Cc: linux-usb@vger.kernel.org
---
Changes since RFC:
- don't use 'defauly y if SOC_*', select the USB_ARCH_HAS_OHCI option
in the platform specific Kconfig file instead
- remove ath79_ehci_platform.h, it belongs to the EHCI patch
Changes since v1:
- rebased against 2.6.37-rc7
arch/mips/ath79/Kconfig | 2 +
drivers/usb/host/Kconfig | 8 ++
drivers/usb/host/ohci-ath79.c | 162 +++++++++++++++++++++++++++++++++++++++++
drivers/usb/host/ohci-hcd.c | 5 +
4 files changed, 177 insertions(+), 0 deletions(-)
create mode 100644 drivers/usb/host/ohci-ath79.c
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 647f535..d4456ce 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -16,10 +16,12 @@ endmenu
config SOC_AR71XX
select USB_ARCH_HAS_EHCI
+ select USB_ARCH_HAS_OHCI
def_bool n
config SOC_AR724X
select USB_ARCH_HAS_EHCI
+ select USB_ARCH_HAS_OHCI
def_bool n
config SOC_AR913X
diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig
index 3a2667a..39ed353 100644
--- a/drivers/usb/host/Kconfig
+++ b/drivers/usb/host/Kconfig
@@ -240,6 +240,14 @@ config USB_OHCI_HCD_OMAP3
Enables support for the on-chip OHCI controller on
OMAP3 and later chips.
+config USB_OHCI_ATH79
+ bool "USB OHCI support for the Atheros AR71XX/AR724X SoCs"
+ depends on USB_OHCI_HCD && (SOC_AR71XX || SOC_AR724X)
+ default y
+ help
+ Enables support for the uilt-in OHCI controller present on the
+ Atheros AR71XX/AR724X SoCs.
+
config USB_OHCI_HCD_PPC_SOC
bool "OHCI support for on-chip PPC USB controller"
depends on USB_OHCI_HCD && (STB03xxx || PPC_MPC52xx)
diff --git a/drivers/usb/host/ohci-ath79.c b/drivers/usb/host/ohci-ath79.c
new file mode 100644
index 0000000..6e864bf
--- /dev/null
+++ b/drivers/usb/host/ohci-ath79.c
@@ -0,0 +1,162 @@
+/*
+ * OHCI HCD (Host Controller Driver) for USB.
+ *
+ * Bus Glue for Atheros AR71XX/AR724X built-in OHCI controller.
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ * Copyright (C) 2007 Atheros Communications, Inc.
+ *
+ * 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/platform_device.h>
+
+static int usb_hcd_ath79_probe(const struct hc_driver *driver,
+ struct platform_device *pdev)
+{
+ struct usb_hcd *hcd;
+ struct resource *res;
+ int irq;
+ int ret;
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!res) {
+ dev_dbg(&pdev->dev, "no IRQ specified for %s\n",
+ dev_name(&pdev->dev));
+ return -ENODEV;
+ }
+ irq = res->start;
+
+ hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev));
+ if (!hcd)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_dbg(&pdev->dev, "no base address specified for %s\n",
+ dev_name(&pdev->dev));
+ ret = -ENODEV;
+ goto err_put_hcd;
+ }
+ hcd->rsrc_start = res->start;
+ hcd->rsrc_len = res->end - res->start + 1;
+
+ if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) {
+ dev_dbg(&pdev->dev, "controller already in use\n");
+ ret = -EBUSY;
+ goto err_put_hcd;
+ }
+
+ hcd->regs = ioremap(hcd->rsrc_start, hcd->rsrc_len);
+ if (!hcd->regs) {
+ dev_dbg(&pdev->dev, "error mapping memory\n");
+ ret = -EFAULT;
+ goto err_release_region;
+ }
+
+ ohci_hcd_init(hcd_to_ohci(hcd));
+
+ ret = usb_add_hcd(hcd, irq, IRQF_DISABLED);
+ if (ret)
+ goto err_stop_hcd;
+
+ return 0;
+
+err_stop_hcd:
+ iounmap(hcd->regs);
+err_release_region:
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+err_put_hcd:
+ usb_put_hcd(hcd);
+ return ret;
+}
+
+void usb_hcd_ath79_remove(struct usb_hcd *hcd, struct platform_device *pdev)
+{
+ usb_remove_hcd(hcd);
+ iounmap(hcd->regs);
+ release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
+ usb_put_hcd(hcd);
+}
+
+static int __devinit ohci_ath79_start(struct usb_hcd *hcd)
+{
+ struct ohci_hcd *ohci = hcd_to_ohci(hcd);
+ int ret;
+
+ ret = ohci_init(ohci);
+ if (ret < 0)
+ return ret;
+
+ ret = ohci_run(ohci);
+ if (ret < 0)
+ goto err;
+
+ return 0;
+
+err:
+ ohci_stop(hcd);
+ return ret;
+}
+
+static const struct hc_driver ohci_ath79_hc_driver = {
+ .description = hcd_name,
+ .product_desc = "Atheros built-in OHCI controller",
+ .hcd_priv_size = sizeof(struct ohci_hcd),
+
+ .irq = ohci_irq,
+ .flags = HCD_USB11 | HCD_MEMORY,
+
+ .start = ohci_ath79_start,
+ .stop = ohci_stop,
+ .shutdown = ohci_shutdown,
+
+ .urb_enqueue = ohci_urb_enqueue,
+ .urb_dequeue = ohci_urb_dequeue,
+ .endpoint_disable = ohci_endpoint_disable,
+
+ /*
+ * scheduling support
+ */
+ .get_frame_number = ohci_get_frame,
+
+ /*
+ * root hub support
+ */
+ .hub_status_data = ohci_hub_status_data,
+ .hub_control = ohci_hub_control,
+ .start_port_reset = ohci_start_port_reset,
+};
+
+static int ohci_hcd_ath79_drv_probe(struct platform_device *pdev)
+{
+ if (usb_disabled())
+ return -ENODEV;
+
+ return usb_hcd_ath79_probe(&ohci_ath79_hc_driver, pdev);
+}
+
+static int ohci_hcd_ath79_drv_remove(struct platform_device *pdev)
+{
+ struct usb_hcd *hcd = platform_get_drvdata(pdev);
+
+ usb_hcd_ath79_remove(hcd, pdev);
+ return 0;
+}
+
+static struct platform_driver ohci_hcd_ath79_driver = {
+ .probe = ohci_hcd_ath79_drv_probe,
+ .remove = ohci_hcd_ath79_drv_remove,
+ .shutdown = usb_hcd_platform_shutdown,
+ .driver = {
+ .name = "ath79-ohci",
+ .owner = THIS_MODULE,
+ },
+};
+
+MODULE_ALIAS("platform:ath79-ohci");
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index 5179acb..6daeb68 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -1111,6 +1111,11 @@ MODULE_LICENSE ("GPL");
#define PLATFORM_DRIVER ohci_octeon_driver
#endif
+#ifdef CONFIG_USB_OHCI_ATH79
+#include "ohci-ath79.c"
+#define PLATFORM_DRIVER ohci_hcd_ath79_driver
+#endif
+
#if !defined(PCI_DRIVER) && \
!defined(PLATFORM_DRIVER) && \
!defined(OMAP1_PLATFORM_DRIVER) && \
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 14/16] MIPS: ath79: add common USB Host Controller device
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (12 preceding siblings ...)
2010-12-22 20:30 ` [PATCH v2 13/16] USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs Gabor Juhos
@ 2010-12-22 20:30 ` Gabor Juhos
2010-12-22 20:31 ` [PATCH v2 15/16] MIPS: ath79: add initial support for the Atheros AP81 reference board Gabor Juhos
2010-12-22 20:31 ` [PATCH v2 16/16] MIPS: ath79: add common WMAC device for AR913X based boards Gabor Juhos
15 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:30 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos
Add common platform_device and helper code to make the registration of
the built-in USB controllers easier on the board which are using them.
Also register the USB controller on the PB44 board.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC: ---
Changes since v1:
- rebased against 2.6.37-rc7
arch/mips/ath79/Kconfig | 4 +
arch/mips/ath79/Makefile | 1 +
arch/mips/ath79/dev-usb.c | 194 ++++++++++++++++++++++++
arch/mips/ath79/dev-usb.h | 17 ++
arch/mips/ath79/mach-pb44.c | 2 +
arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 22 +++-
6 files changed, 239 insertions(+), 1 deletions(-)
create mode 100644 arch/mips/ath79/dev-usb.c
create mode 100644 arch/mips/ath79/dev-usb.h
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index d4456ce..5d67942 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -8,6 +8,7 @@ config ATH79_MACH_PB44
select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO
select ATH79_DEV_SPI
+ select ATH79_DEV_USB
help
Say 'Y' here if you want your kernel to support the
Atheros PB44 reference board.
@@ -37,4 +38,7 @@ config ATH79_DEV_LEDS_GPIO
config ATH79_DEV_SPI
def_bool n
+config ATH79_DEV_USB
+ def_bool n
+
endif
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index a8de078..494d106 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -19,6 +19,7 @@ obj-y += dev-common.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_SPI) += dev-spi.o
+obj-$(CONFIG_ATH79_DEV_USB) += dev-usb.o
#
# Machines
diff --git a/arch/mips/ath79/dev-usb.c b/arch/mips/ath79/dev-usb.c
new file mode 100644
index 0000000..fb7033f
--- /dev/null
+++ b/arch/mips/ath79/dev-usb.c
@@ -0,0 +1,194 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X USB Host Controller support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Parts of this file are based on Atheros' 2.6.15 BSP
+ *
+ * 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/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/dma-mapping.h>
+#include <linux/platform_device.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <asm/mach-ath79/ath79_ehci_platform.h>
+#include "common.h"
+#include "dev-usb.h"
+
+static void __iomem *ath79_usb_ctrl_base;
+
+static struct resource ar71xx_ohci_resources[] = {
+ [0] = {
+ .start = AR71XX_OHCI_BASE,
+ .end = AR71XX_OHCI_BASE + AR71XX_OHCI_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = ATH79_MISC_IRQ_OHCI,
+ .end = ATH79_MISC_IRQ_OHCI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct resource ar724x_usb_resources[] = {
+ [0] = {
+ .start = AR7240_OHCI_BASE,
+ .end = AR7240_OHCI_BASE + AR7240_OHCI_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = ATH79_CPU_IRQ_USB,
+ .end = ATH79_CPU_IRQ_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ath79_ohci_dmamask = DMA_BIT_MASK(32);
+static struct platform_device ath79_ohci_device = {
+ .name = "ath79-ohci",
+ .id = -1,
+ .resource = ar71xx_ohci_resources,
+ .num_resources = ARRAY_SIZE(ar71xx_ohci_resources),
+ .dev = {
+ .dma_mask = &ath79_ohci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ },
+};
+
+static struct resource ar71xx_ehci_resources[] = {
+ [0] = {
+ .start = AR71XX_EHCI_BASE,
+ .end = AR71XX_EHCI_BASE + AR71XX_EHCI_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = ATH79_CPU_IRQ_USB,
+ .end = ATH79_CPU_IRQ_USB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static u64 ath79_ehci_dmamask = DMA_BIT_MASK(32);
+static struct ath79_ehci_platform_data ath79_ehci_data;
+
+static struct platform_device ath79_ehci_device = {
+ .name = "ath79-ehci",
+ .id = -1,
+ .resource = ar71xx_ehci_resources,
+ .num_resources = ARRAY_SIZE(ar71xx_ehci_resources),
+ .dev = {
+ .dma_mask = &ath79_ehci_dmamask,
+ .coherent_dma_mask = DMA_BIT_MASK(32),
+ .platform_data = &ath79_ehci_data,
+ },
+};
+
+#define AR71XX_USB_RESET_MASK (AR71XX_RESET_USB_HOST | \
+ AR71XX_RESET_USB_PHY | \
+ AR71XX_RESET_USB_OHCI_DLL)
+
+static void __init ar71xx_usb_setup(void)
+{
+ ath79_device_reset_set(AR71XX_USB_RESET_MASK);
+ mdelay(1000);
+ ath79_device_reset_clear(AR71XX_USB_RESET_MASK);
+
+ /* Turning on the Buff and Desc swap bits */
+ __raw_writel(0xf0000, ath79_usb_ctrl_base + AR71XX_USB_CTRL_REG_CONFIG);
+
+ /* WAR for HW bug. Here it adjusts the duration between two SOFS */
+ __raw_writel(0x20c00, ath79_usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
+
+ mdelay(900);
+
+ platform_device_register(&ath79_ohci_device);
+ platform_device_register(&ath79_ehci_device);
+}
+
+static void __init ar7240_usb_setup(void)
+{
+ ath79_device_reset_clear(AR7240_RESET_OHCI_DLL);
+ ath79_device_reset_set(AR7240_RESET_USB_HOST);
+ mdelay(1000);
+ ath79_device_reset_set(AR7240_RESET_OHCI_DLL);
+ ath79_device_reset_clear(AR7240_RESET_USB_HOST);
+
+ /* WAR for HW bug. Here it adjusts the duration between two SOFS */
+ __raw_writel(0x3, ath79_usb_ctrl_base + AR71XX_USB_CTRL_REG_FLADJ);
+
+ ath79_ohci_device.resource = ar724x_usb_resources;
+ ath79_ohci_device.num_resources = ARRAY_SIZE(ar724x_usb_resources);
+ platform_device_register(&ath79_ohci_device);
+}
+
+static void __init ar724x_usb_setup(void)
+{
+ ath79_device_reset_set(AR724X_RESET_USBSUS_OVERRIDE);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR724X_RESET_USB_HOST);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR724X_RESET_USB_PHY);
+ mdelay(10);
+
+ ath79_ehci_data.is_ar913x = 1;
+ ath79_ehci_device.resource = ar724x_usb_resources;
+ ath79_ehci_device.num_resources = ARRAY_SIZE(ar724x_usb_resources);
+ platform_device_register(&ath79_ehci_device);
+}
+
+static void __init ar913x_usb_setup(void)
+{
+ ath79_device_reset_set(AR71XX_RESET_USBSUS_OVERRIDE);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR71XX_RESET_USB_HOST);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR71XX_RESET_USB_PHY);
+ mdelay(10);
+
+ ath79_ehci_data.is_ar913x = 1;
+ platform_device_register(&ath79_ehci_device);
+}
+
+void __init ath79_register_usb(void)
+{
+ ath79_usb_ctrl_base = ioremap(AR71XX_USB_CTRL_BASE,
+ AR71XX_USB_CTRL_SIZE);
+
+ switch (ath79_soc) {
+ case ATH79_SOC_AR7130:
+ case ATH79_SOC_AR7141:
+ case ATH79_SOC_AR7161:
+ ar71xx_usb_setup();
+ break;
+
+ case ATH79_SOC_AR7240:
+ ar7240_usb_setup();
+ break;
+
+ case ATH79_SOC_AR7241:
+ case ATH79_SOC_AR7242:
+ ar724x_usb_setup();
+ break;
+
+ case ATH79_SOC_AR9130:
+ case ATH79_SOC_AR9132:
+ ar913x_usb_setup();
+ break;
+
+ default:
+ BUG();
+ }
+}
diff --git a/arch/mips/ath79/dev-usb.h b/arch/mips/ath79/dev-usb.h
new file mode 100644
index 0000000..dbe6d3d
--- /dev/null
+++ b/arch/mips/ath79/dev-usb.h
@@ -0,0 +1,17 @@
+/*
+ * Atheros AR71XX/AR724X/AR913X USB Host Controller support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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.
+ */
+
+#ifndef _ATH79_DEV_USB_H
+#define _ATH79_DEV_USB_H
+
+void ath79_register_usb(void) __init;
+
+#endif /* _ATH79_DEV_USB_H */
diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c
index ec7b7a1..fe9701a 100644
--- a/arch/mips/ath79/mach-pb44.c
+++ b/arch/mips/ath79/mach-pb44.c
@@ -18,6 +18,7 @@
#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
#include "dev-spi.h"
+#include "dev-usb.h"
#define PB44_GPIO_I2C_SCL 0
#define PB44_GPIO_I2C_SDA 1
@@ -112,6 +113,7 @@ static void __init pb44_init(void)
pb44_gpio_keys);
ath79_register_spi(&pb44_spi_data, pb44_spi_info,
ARRAY_SIZE(pb44_spi_info));
+ ath79_register_usb();
}
MIPS_MACHINE(ATH79_MACH_PB44, "PB44", "Atheros PB44 reference board",
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index 4f2b621..f125f1e 100644
--- 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_EHCI_BASE 0x1b000000
+#define AR71XX_EHCI_SIZE 0x1000
+#define AR71XX_OHCI_BASE 0x1c000000
+#define AR71XX_OHCI_SIZE 0x1000
#define AR71XX_SPI_BASE 0x1f000000
#define AR71XX_SPI_SIZE 0x01000000
@@ -27,6 +31,8 @@
#define AR71XX_DDR_CTRL_SIZE 0x100
#define AR71XX_UART_BASE (AR71XX_APB_BASE + 0x00020000)
#define AR71XX_UART_SIZE 0x100
+#define AR71XX_USB_CTRL_BASE (AR71XX_APB_BASE + 0x00030000)
+#define AR71XX_USB_CTRL_SIZE 0x100
#define AR71XX_GPIO_BASE (AR71XX_APB_BASE + 0x00040000)
#define AR71XX_GPIO_SIZE 0x100
#define AR71XX_PLL_BASE (AR71XX_APB_BASE + 0x00050000)
@@ -34,6 +40,9 @@
#define AR71XX_RESET_BASE (AR71XX_APB_BASE + 0x00060000)
#define AR71XX_RESET_SIZE 0x100
+#define AR7240_OHCI_BASE 0x1b000000
+#define AR7240_OHCI_SIZE 0x1000
+
/*
* DDR_CTRL block
*/
@@ -102,6 +111,12 @@
#define AR913X_AHB_DIV_MASK 0x1
/*
+ * USB_CONFIG block
+ */
+#define AR71XX_USB_CTRL_REG_FLADJ 0x00
+#define AR71XX_USB_CTRL_REG_CONFIG 0x04
+
+/*
* RESET block
*/
#define AR71XX_RESET_REG_TIMER 0x00
@@ -155,12 +170,17 @@
#define AR71XX_RESET_PCI_BUS BIT(1)
#define AR71XX_RESET_PCI_CORE BIT(0)
+#define AR7240_RESET_USB_HOST BIT(5)
+#define AR7240_RESET_OHCI_DLL BIT(3)
+
#define AR724X_RESET_GE1_MDIO BIT(23)
#define AR724X_RESET_GE0_MDIO BIT(22)
#define AR724X_RESET_PCIE_PHY_SERIAL BIT(10)
#define AR724X_RESET_PCIE_PHY BIT(7)
#define AR724X_RESET_PCIE BIT(6)
-#define AR724X_RESET_OHCI_DLL BIT(3)
+#define AR724X_RESET_USB_HOST BIT(5)
+#define AR724X_RESET_USB_PHY BIT(4)
+#define AR724X_RESET_USBSUS_OVERRIDE BIT(3)
#define AR913X_RESET_AMBA2WMAC BIT(22)
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 15/16] MIPS: ath79: add initial support for the Atheros AP81 reference board
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (13 preceding siblings ...)
2010-12-22 20:30 ` [PATCH v2 14/16] MIPS: ath79: add common USB Host Controller device Gabor Juhos
@ 2010-12-22 20:31 ` Gabor Juhos
2010-12-22 20:31 ` [PATCH v2 16/16] MIPS: ath79: add common WMAC device for AR913X based boards Gabor Juhos
15 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:31 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
Signed-off-by: Imre Kaloz <kaloz@openwrt.org>
---
Changes since RFC:
- don't use 'default n' for the ATH79_MACH_AP81 Kconfig option
Changes since v1:
- rebased against 2.6.37-rc7
arch/mips/ath79/Kconfig | 11 +++++
arch/mips/ath79/Makefile | 1 +
arch/mips/ath79/mach-ap81.c | 94 +++++++++++++++++++++++++++++++++++++++++++
arch/mips/ath79/machtypes.h | 1 +
4 files changed, 107 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/ath79/mach-ap81.c
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 5d67942..1912d54 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -2,6 +2,17 @@ if ATH79
menu "Atheros AR71XX/AR724X/AR913X machine selection"
+config ATH79_MACH_AP81
+ bool "Atheros AP81 reference board"
+ select SOC_AR913X
+ select ATH79_DEV_GPIO_BUTTONS
+ select ATH79_DEV_LEDS_GPIO
+ select ATH79_DEV_SPI
+ select ATH79_DEV_USB
+ help
+ Say 'Y' here if you want your kernel to support the
+ Atheros AP81 reference board.
+
config ATH79_MACH_PB44
bool "Atheros PB44 reference board"
select SOC_AR71XX
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index 494d106..1b111d8 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -24,4 +24,5 @@ obj-$(CONFIG_ATH79_DEV_USB) += dev-usb.o
#
# Machines
#
+obj-$(CONFIG_ATH79_MACH_AP81) += mach-ap81.o
obj-$(CONFIG_ATH79_MACH_PB44) += mach-pb44.o
diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c
new file mode 100644
index 0000000..909ca5d
--- /dev/null
+++ b/arch/mips/ath79/mach-ap81.c
@@ -0,0 +1,94 @@
+/*
+ * Atheros AP81 board support
+ *
+ * Copyright (C) 2009-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2009 Imre Kaloz <kaloz@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-gpio-buttons.h"
+#include "dev-leds-gpio.h"
+#include "dev-spi.h"
+#include "dev-usb.h"
+
+#define AP81_GPIO_LED_STATUS 1
+#define AP81_GPIO_LED_AOSS 3
+#define AP81_GPIO_LED_WLAN 6
+#define AP81_GPIO_LED_POWER 14
+
+#define AP81_GPIO_BTN_SW4 12
+#define AP81_GPIO_BTN_SW1 21
+
+#define AP81_KEYS_POLL_INTERVAL 20 /* msecs */
+#define AP81_KEYS_DEBOUNCE_INTERVAL (3 * AP81_KEYS_POLL_INTERVAL)
+
+static struct gpio_led ap81_leds_gpio[] __initdata = {
+ {
+ .name = "ap81:green:status",
+ .gpio = AP81_GPIO_LED_STATUS,
+ .active_low = 1,
+ }, {
+ .name = "ap81:amber:aoss",
+ .gpio = AP81_GPIO_LED_AOSS,
+ .active_low = 1,
+ }, {
+ .name = "ap81:green:wlan",
+ .gpio = AP81_GPIO_LED_WLAN,
+ .active_low = 1,
+ }, {
+ .name = "ap81:green:power",
+ .gpio = AP81_GPIO_LED_POWER,
+ .active_low = 1,
+ }
+};
+
+static struct gpio_keys_button ap81_gpio_keys[] __initdata = {
+ {
+ .desc = "sw1",
+ .type = EV_KEY,
+ .code = BTN_0,
+ .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = AP81_GPIO_BTN_SW1,
+ .active_low = 1,
+ } , {
+ .desc = "sw4",
+ .type = EV_KEY,
+ .code = BTN_1,
+ .debounce_interval = AP81_KEYS_DEBOUNCE_INTERVAL,
+ .gpio = AP81_GPIO_BTN_SW4,
+ .active_low = 1,
+ }
+};
+
+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)
+{
+ ath79_register_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
+ ap81_leds_gpio);
+ 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_usb();
+}
+
+MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board",
+ ap81_setup);
diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h
index a796fa3..3940fe4 100644
--- a/arch/mips/ath79/machtypes.h
+++ b/arch/mips/ath79/machtypes.h
@@ -16,6 +16,7 @@
enum ath79_mach_type {
ATH79_MACH_GENERIC = 0,
+ ATH79_MACH_AP81, /* Atheros AP81 reference board */
ATH79_MACH_PB44, /* Atheros PB44 reference board */
};
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v2 16/16] MIPS: ath79: add common WMAC device for AR913X based boards
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
` (14 preceding siblings ...)
2010-12-22 20:31 ` [PATCH v2 15/16] MIPS: ath79: add initial support for the Atheros AP81 reference board Gabor Juhos
@ 2010-12-22 20:31 ` Gabor Juhos
15 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-22 20:31 UTC (permalink / raw)
To: Ralf Baechle
Cc: linux-mips, Imre Kaloz, Luis R. Rodriguez, Cliff Holden,
Kathy Giori, Gabor Juhos
Add common platform_device and helper code to make the registration
of the built-in wireless MAC easier on the Atheros AR9130/AR9132
based boards. Also register the WMAC device on the AR81 board.
Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
---
Changes since RFC: ---
Changes since v1:
- rebased against 2.6.37-rc7
arch/mips/ath79/Kconfig | 5 ++
arch/mips/ath79/Makefile | 1 +
arch/mips/ath79/dev-ar913x-wmac.c | 60 ++++++++++++++++++++++++
arch/mips/ath79/dev-ar913x-wmac.h | 17 +++++++
arch/mips/ath79/mach-ap81.c | 6 ++
arch/mips/include/asm/mach-ath79/ar71xx_regs.h | 3 +
6 files changed, 92 insertions(+), 0 deletions(-)
create mode 100644 arch/mips/ath79/dev-ar913x-wmac.c
create mode 100644 arch/mips/ath79/dev-ar913x-wmac.h
diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig
index 1912d54..af01669 100644
--- a/arch/mips/ath79/Kconfig
+++ b/arch/mips/ath79/Kconfig
@@ -5,6 +5,7 @@ menu "Atheros AR71XX/AR724X/AR913X machine selection"
config ATH79_MACH_AP81
bool "Atheros AP81 reference board"
select SOC_AR913X
+ select ATH79_DEV_AR913X_WMAC
select ATH79_DEV_GPIO_BUTTONS
select ATH79_DEV_LEDS_GPIO
select ATH79_DEV_SPI
@@ -40,6 +41,10 @@ config SOC_AR913X
select USB_ARCH_HAS_EHCI
def_bool n
+config ATH79_DEV_AR913X_WMAC
+ depends on SOC_AR913X
+ def_bool n
+
config ATH79_DEV_GPIO_BUTTONS
def_bool n
diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile
index 1b111d8..48398561 100644
--- a/arch/mips/ath79/Makefile
+++ b/arch/mips/ath79/Makefile
@@ -16,6 +16,7 @@ obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
# Devices
#
obj-y += dev-common.o
+obj-$(CONFIG_ATH79_DEV_AR913X_WMAC) += dev-ar913x-wmac.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_SPI) += dev-spi.o
diff --git a/arch/mips/ath79/dev-ar913x-wmac.c b/arch/mips/ath79/dev-ar913x-wmac.c
new file mode 100644
index 0000000..48f425a
--- /dev/null
+++ b/arch/mips/ath79/dev-ar913x-wmac.c
@@ -0,0 +1,60 @@
+/*
+ * Atheros AR913X SoC built-in WMAC device support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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/init.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/platform_device.h>
+#include <linux/ath9k_platform.h>
+
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include "dev-ar913x-wmac.h"
+
+static struct ath9k_platform_data ar913x_wmac_data;
+
+static struct resource ar913x_wmac_resources[] = {
+ {
+ .start = AR913X_WMAC_BASE,
+ .end = AR913X_WMAC_BASE + AR913X_WMAC_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = ATH79_CPU_IRQ_IP2,
+ .end = ATH79_CPU_IRQ_IP2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device ar913x_wmac_device = {
+ .name = "ath9k",
+ .id = -1,
+ .resource = ar913x_wmac_resources,
+ .num_resources = ARRAY_SIZE(ar913x_wmac_resources),
+ .dev = {
+ .platform_data = &ar913x_wmac_data,
+ },
+};
+
+void __init ath79_register_ar913x_wmac(u8 *cal_data)
+{
+ if (cal_data)
+ memcpy(ar913x_wmac_data.eeprom_data, cal_data,
+ sizeof(ar913x_wmac_data.eeprom_data));
+
+ /* reset the WMAC */
+ ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
+ mdelay(10);
+
+ platform_device_register(&ar913x_wmac_device);
+}
diff --git a/arch/mips/ath79/dev-ar913x-wmac.h b/arch/mips/ath79/dev-ar913x-wmac.h
new file mode 100644
index 0000000..5df653f
--- /dev/null
+++ b/arch/mips/ath79/dev-ar913x-wmac.h
@@ -0,0 +1,17 @@
+/*
+ * Atheros AR913X SoC built-in WMAC device support
+ *
+ * Copyright (C) 2008-2010 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (C) 2008 Imre Kaloz <kaloz@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.
+ */
+
+#ifndef _ATH79_DEV_AR913X_WMAC_H
+#define _ATH79_DEV_AR913X_WMAC_H
+
+void ath79_register_ar913x_wmac(u8 *cal_data) __init;
+
+#endif /* _ATH79_DEV_AR913X_WMAC_H */
diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c
index 909ca5d..03719b8 100644
--- a/arch/mips/ath79/mach-ap81.c
+++ b/arch/mips/ath79/mach-ap81.c
@@ -10,6 +10,7 @@
*/
#include "machtypes.h"
+#include "dev-ar913x-wmac.h"
#include "dev-gpio-buttons.h"
#include "dev-leds-gpio.h"
#include "dev-spi.h"
@@ -26,6 +27,8 @@
#define AP81_KEYS_POLL_INTERVAL 20 /* msecs */
#define AP81_KEYS_DEBOUNCE_INTERVAL (3 * AP81_KEYS_POLL_INTERVAL)
+#define AP81_CAL_DATA_ADDR 0x1fff1000
+
static struct gpio_led ap81_leds_gpio[] __initdata = {
{
.name = "ap81:green:status",
@@ -80,6 +83,8 @@ static struct ath79_spi_platform_data ap81_spi_data = {
static void __init ap81_setup(void)
{
+ u8 *cal_data = (u8 *) KSEG1ADDR(AP81_CAL_DATA_ADDR);
+
ath79_register_leds_gpio(-1, ARRAY_SIZE(ap81_leds_gpio),
ap81_leds_gpio);
ath79_register_gpio_keys_polled(-1, AP81_KEYS_POLL_INTERVAL,
@@ -88,6 +93,7 @@ static void __init ap81_setup(void)
ath79_register_spi(&ap81_spi_data, ap81_spi_info,
ARRAY_SIZE(ap81_spi_info));
ath79_register_usb();
+ ath79_register_ar913x_wmac(cal_data);
}
MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board",
diff --git a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
index f125f1e..9beb073 100644
--- a/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
+++ b/arch/mips/include/asm/mach-ath79/ar71xx_regs.h
@@ -43,6 +43,9 @@
#define AR7240_OHCI_BASE 0x1b000000
#define AR7240_OHCI_SIZE 0x1000
+#define AR913X_WMAC_BASE (AR71XX_APB_BASE + 0x000C0000)
+#define AR913X_WMAC_SIZE 0x30000
+
/*
* DDR_CTRL block
*/
--
1.7.2.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* Re: [PATCH v2 11/16] USB: ehci: add workaround for Synopsys HC bug
2010-12-22 20:30 ` [PATCH v2 11/16] USB: ehci: add workaround for Synopsys HC bug Gabor Juhos
@ 2010-12-23 0:30 ` Greg KH
2010-12-23 8:29 ` Gabor Juhos
0 siblings, 1 reply; 21+ messages in thread
From: Greg KH @ 2010-12-23 0:30 UTC (permalink / raw)
To: Gabor Juhos
Cc: Ralf Baechle, linux-mips, Imre Kaloz, Luis R. Rodriguez,
Cliff Holden, Kathy Giori, David Brownell, linux-usb
On Wed, Dec 22, 2010 at 09:30:56PM +0100, Gabor Juhos wrote:
> A Synopsys USB core used in various SoCs has a bug which might cause
> that the host controller not issuing ping.
>
> When software uses the Doorbell mechanism to remove queue heads, the
> host controller still has references to the removed queue head even
> after indicating an Interrupt on Async Advance. This happens if the last
> executed queue head's Next Link queue head is removed.
>
> Consequences of the defect:
> The Host controller fetches the removed queue head, using memory that
> would otherwise be deallocated.This results in incorrect transactions on
> both the USB and system memory. This may result in undefined behavior.
>
> Workarounds:
>
> 1) If no queue head is active (no Status field's Active bit is set)
> after removing the queue heads, the software can write one of the valid
> queue head addresses to the ASYNCLISTADDR register and deallocate the
> removed queue head's memory after 2 microframes.
>
> If one or more of the queue heads is active (the Active bit is set in
> the Status field) after removing the queue heads, the software can delay
> memory deallocation after time X, where X is the time required for the
> Host Controller to go through all the queue heads once. X varies with
> the number of queue heads and the time required to process periodic
> transactions: if more periodic transactions must be performed, the Host
> Controller has less time to process asynchronous transaction processing.
>
> 2) Do not use the Doorbell mechanism to remove the queue heads. Disable
> the Asynchronous Schedule Enable bit instead.
>
> The bug has been discussed on the linux-usb-devel mailing-list
> four years ago, the original thread can be found here:
> http://www.mail-archive.com/linux-usb-devel@lists.sourceforge.net/msg45345.html
>
> This patch implements the first workaround as suggested by David Brownell.
> The built-in USB host controller of the Atheros AR7130/AR7141/AR7161 SoCs
> requires this to work properly.
>
> Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
> Cc: David Brownell <dbrownell@users.sourceforge.net>
> Cc: Greg Kroah-Hartman <gregkh@suse.de>
> Cc: linux-usb@vger.kernel.org
> ---
>
> Changes since RFC: ---
>
> Changes since v1:
> - rebased against 2.6.37-rc7
>
> drivers/usb/host/ehci-q.c | 3 +++
> drivers/usb/host/ehci.h | 1 +
> 2 files changed, 4 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
> index 233c288..343b8de 100644
> --- a/drivers/usb/host/ehci-q.c
> +++ b/drivers/usb/host/ehci-q.c
> @@ -1193,6 +1193,9 @@ static void end_unlink_async (struct ehci_hcd *ehci)
> ehci->reclaim = NULL;
> start_unlink_async (ehci, next);
> }
> +
> + if (ehci->has_synopsys_hc_bug)
> + writel((u32)ehci->async->qh_dma, &ehci->regs->async_next);
> }
>
> /* makes sure the async qh will become idle */
> diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
> index ba8eab3..6da85b2 100644
> --- a/drivers/usb/host/ehci.h
> +++ b/drivers/usb/host/ehci.h
> @@ -133,6 +133,7 @@ struct ehci_hcd { /* one per controller */
> unsigned broken_periodic:1;
> unsigned fs_i_thresh:1; /* Intel iso scheduling */
> unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/
> + unsigned has_synopsys_hc_bug:1; /* Synopsys HC */
That's fine, but who sets this value to 1? I don't see any code that
does that, so why add this at all? :)
thanks,
greg k-h
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 11/16] USB: ehci: add workaround for Synopsys HC bug
2010-12-23 0:30 ` Greg KH
@ 2010-12-23 8:29 ` Gabor Juhos
0 siblings, 0 replies; 21+ messages in thread
From: Gabor Juhos @ 2010-12-23 8:29 UTC (permalink / raw)
To: Greg KH
Cc: Ralf Baechle, linux-mips, Imre Kaloz, Luis R. Rodriguez,
Cliff Holden, Kathy Giori, David Brownell, linux-usb
Hi Greg,
<...>
>> diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
>> index 233c288..343b8de 100644
>> --- a/drivers/usb/host/ehci-q.c
>> +++ b/drivers/usb/host/ehci-q.c
>> @@ -1193,6 +1193,9 @@ static void end_unlink_async (struct ehci_hcd *ehci)
>> ehci->reclaim = NULL;
>> start_unlink_async (ehci, next);
>> }
>> +
>> + if (ehci->has_synopsys_hc_bug)
>> + writel((u32)ehci->async->qh_dma, &ehci->regs->async_next);
>> }
>>
>> /* makes sure the async qh will become idle */
>> diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
>> index ba8eab3..6da85b2 100644
>> --- a/drivers/usb/host/ehci.h
>> +++ b/drivers/usb/host/ehci.h
>> @@ -133,6 +133,7 @@ struct ehci_hcd { /* one per controller */
>> unsigned broken_periodic:1;
>> unsigned fs_i_thresh:1; /* Intel iso scheduling */
>> unsigned use_dummy_qh:1; /* AMD Frame List table quirk*/
>> + unsigned has_synopsys_hc_bug:1; /* Synopsys HC */
>
> That's fine, but who sets this value to 1? I don't see any code that
> does that, so why add this at all? :)
It will be set to 1 by ehci_ath79_init which is in the next patch [1] of this
series.
-Gabor
1. http://marc.info/?l=linux-usb&m=129304988827418&w=2
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v2 07/16] MIPS: ath79: add common watchdog device
2010-12-22 20:30 ` [PATCH v2 07/16] MIPS: ath79: add common watchdog device Gabor Juhos
@ 2010-12-23 10:41 ` Sergei Shtylyov
0 siblings, 0 replies; 21+ messages in thread
From: Sergei Shtylyov @ 2010-12-23 10:41 UTC (permalink / raw)
To: Gabor Juhos
Cc: Ralf Baechle, linux-mips, Imre Kaloz, Luis R. Rodriguez,
Cliff Holden, Kathy Giori
Hello.
On 22-12-2010 23:30, Gabor Juhos wrote:
> All supported SoCs have a built-in hardware watchdog driver. This patch
> registers a platform_device for that to make it usable.
> Signed-off-by: Gabor Juhos<juhosg@openwrt.org>
> Signed-off-by: Imre Kaloz<kaloz@openwrt.org>
[...]
> diff --git a/arch/mips/ath79/dev-common.h b/arch/mips/ath79/dev-common.h
> index 1cec894..65bf400 100644
> --- a/arch/mips/ath79/dev-common.h
> +++ b/arch/mips/ath79/dev-common.h
> @@ -13,5 +13,6 @@
> #define _ATH79_DEV_COMMON_H
>
> void ath79_register_uart(void) __init;
> +void ath79_register_wdt(void) __init;
'__init' not needed with declarations.
WBR, Sergei
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2010-12-23 10:42 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-12-22 20:30 [PATCH v2 00/16] MIPS: initial support for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 01/16] MIPS: add initial support for the Atheros AR71XX/AR724X/AR931X SoCs Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 02/16] MIPS: ath79: add GPIOLIB support Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 03/16] MIPS: ath79: utilize the MIPS multi-machine support Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 04/16] MIPS: ath79: add initial support for the Atheros PB44 reference board Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 05/16] MIPS: ath79: add common GPIO LEDs device Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 06/16] watchdog: add driver for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 07/16] MIPS: ath79: add common watchdog device Gabor Juhos
2010-12-23 10:41 ` Sergei Shtylyov
2010-12-22 20:30 ` [PATCH v2 08/16] MIPS: ath79: add common GPIO buttons device Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 09/16] spi: add SPI controller driver for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
2010-12-22 20:30 ` Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 10/16] MIPS: ath79: add common SPI controller device Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 11/16] USB: ehci: add workaround for Synopsys HC bug Gabor Juhos
2010-12-23 0:30 ` Greg KH
2010-12-23 8:29 ` Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 12/16] USB: ehci: add bus glue for the Atheros AR71XX/AR724X/AR913X SoCs Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 13/16] USB: ohci: add bus glue for the Atheros AR71XX/AR7240 SoCs Gabor Juhos
2010-12-22 20:30 ` [PATCH v2 14/16] MIPS: ath79: add common USB Host Controller device Gabor Juhos
2010-12-22 20:31 ` [PATCH v2 15/16] MIPS: ath79: add initial support for the Atheros AP81 reference board Gabor Juhos
2010-12-22 20:31 ` [PATCH v2 16/16] MIPS: ath79: add common WMAC device for AR913X based boards Gabor Juhos
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.