From d4a67d9dc8a5a80c4ec1814791af8c0252c158b8 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 4 Jan 2011 21:28:14 +0100 Subject: MIPS: Add initial support for the Atheros AR71XX/AR724X/AR931X SoCs 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 Signed-off-by: Imre Kaloz Cc: linux-mips@linux-mips.org Cc: Luis R. Rodriguez Cc: Cliff Holden Cc: Kathy Giori Patchwork: https://patchwork.linux-mips.org/patch/1947/ Signed-off-by: Ralf Baechle --- arch/mips/ath79/Kconfig | 12 +++ arch/mips/ath79/Makefile | 18 ++++ arch/mips/ath79/Platform | 7 ++ arch/mips/ath79/clock.c | 183 +++++++++++++++++++++++++++++++++++++++ arch/mips/ath79/common.c | 97 +++++++++++++++++++++ arch/mips/ath79/common.h | 26 ++++++ arch/mips/ath79/dev-common.c | 67 +++++++++++++++ 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 | 190 +++++++++++++++++++++++++++++++++++++++++ 12 files changed, 897 insertions(+) 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/clock.c 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 (limited to 'arch/mips/ath79') diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig new file mode 100644 index 000000000000..50b933446cc0 --- /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 000000000000..31e0f83ddf68 --- /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-2011 Gabor Juhos +# Copyright (C) 2008 Imre Kaloz +# +# 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 clock.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 000000000000..2bd663647d27 --- /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/clock.c b/arch/mips/ath79/clock.c new file mode 100644 index 000000000000..680bde99a26c --- /dev/null +++ b/arch/mips/ath79/clock.c @@ -0,0 +1,183 @@ +/* + * Atheros AR71XX/AR724X/AR913X common routines + * + * Copyright (C) 2011 Gabor Juhos + * + * 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 +#include +#include +#include +#include + +#include +#include +#include "common.h" + +#define AR71XX_BASE_FREQ 40000000 +#define AR724X_BASE_FREQ 5000000 +#define AR913X_BASE_FREQ 5000000 + +struct clk { + unsigned long rate; +}; + +static struct clk ath79_ref_clk; +static struct clk ath79_cpu_clk; +static struct clk ath79_ddr_clk; +static struct clk ath79_ahb_clk; +static struct clk ath79_wdt_clk; +static struct clk ath79_uart_clk; + +static void __init ar71xx_clocks_init(void) +{ + u32 pll; + u32 freq; + u32 div; + + ath79_ref_clk.rate = AR71XX_BASE_FREQ; + + pll = ath79_pll_rr(AR71XX_PLL_REG_CPU_CONFIG); + + div = ((pll >> AR71XX_PLL_DIV_SHIFT) & AR71XX_PLL_DIV_MASK) + 1; + freq = div * ath79_ref_clk.rate; + + div = ((pll >> AR71XX_CPU_DIV_SHIFT) & AR71XX_CPU_DIV_MASK) + 1; + ath79_cpu_clk.rate = freq / div; + + div = ((pll >> AR71XX_DDR_DIV_SHIFT) & AR71XX_DDR_DIV_MASK) + 1; + ath79_ddr_clk.rate = freq / div; + + div = (((pll >> AR71XX_AHB_DIV_SHIFT) & AR71XX_AHB_DIV_MASK) + 1) * 2; + ath79_ahb_clk.rate = ath79_cpu_clk.rate / div; + + ath79_wdt_clk.rate = ath79_ahb_clk.rate; + ath79_uart_clk.rate = ath79_ahb_clk.rate; +} + +static void __init ar724x_clocks_init(void) +{ + u32 pll; + u32 freq; + u32 div; + + ath79_ref_clk.rate = AR724X_BASE_FREQ; + pll = ath79_pll_rr(AR724X_PLL_REG_CPU_CONFIG); + + div = ((pll >> AR724X_PLL_DIV_SHIFT) & AR724X_PLL_DIV_MASK); + freq = div * ath79_ref_clk.rate; + + div = ((pll >> AR724X_PLL_REF_DIV_SHIFT) & AR724X_PLL_REF_DIV_MASK); + freq *= div; + + ath79_cpu_clk.rate = freq; + + div = ((pll >> AR724X_DDR_DIV_SHIFT) & AR724X_DDR_DIV_MASK) + 1; + ath79_ddr_clk.rate = freq / div; + + div = (((pll >> AR724X_AHB_DIV_SHIFT) & AR724X_AHB_DIV_MASK) + 1) * 2; + ath79_ahb_clk.rate = ath79_cpu_clk.rate / div; + + ath79_wdt_clk.rate = ath79_ahb_clk.rate; + ath79_uart_clk.rate = ath79_ahb_clk.rate; +} + +static void __init ar913x_clocks_init(void) +{ + u32 pll; + u32 freq; + u32 div; + + ath79_ref_clk.rate = AR913X_BASE_FREQ; + pll = ath79_pll_rr(AR913X_PLL_REG_CPU_CONFIG); + + div = ((pll >> AR913X_PLL_DIV_SHIFT) & AR913X_PLL_DIV_MASK); + freq = div * ath79_ref_clk.rate; + + ath79_cpu_clk.rate = freq; + + div = ((pll >> AR913X_DDR_DIV_SHIFT) & AR913X_DDR_DIV_MASK) + 1; + ath79_ddr_clk.rate = freq / div; + + div = (((pll >> AR913X_AHB_DIV_SHIFT) & AR913X_AHB_DIV_MASK) + 1) * 2; + ath79_ahb_clk.rate = ath79_cpu_clk.rate / div; + + ath79_wdt_clk.rate = ath79_ahb_clk.rate; + ath79_uart_clk.rate = ath79_ahb_clk.rate; +} + +void __init ath79_clocks_init(void) +{ + if (soc_is_ar71xx()) + ar71xx_clocks_init(); + else if (soc_is_ar724x()) + ar724x_clocks_init(); + else if (soc_is_ar913x()) + ar913x_clocks_init(); + else + BUG(); + + pr_info("Clocks: CPU:%lu.%03luMHz, DDR:%lu.%03luMHz, AHB:%lu.%03luMHz, " + "Ref:%lu.%03luMHz", + ath79_cpu_clk.rate / 1000000, + (ath79_cpu_clk.rate / 1000) % 1000, + ath79_ddr_clk.rate / 1000000, + (ath79_ddr_clk.rate / 1000) % 1000, + ath79_ahb_clk.rate / 1000000, + (ath79_ahb_clk.rate / 1000) % 1000, + ath79_ref_clk.rate / 1000000, + (ath79_ref_clk.rate / 1000) % 1000); +} + +/* + * Linux clock API + */ +struct clk *clk_get(struct device *dev, const char *id) +{ + if (!strcmp(id, "ref")) + return &ath79_ref_clk; + + if (!strcmp(id, "cpu")) + return &ath79_cpu_clk; + + if (!strcmp(id, "ddr")) + return &ath79_ddr_clk; + + if (!strcmp(id, "ahb")) + return &ath79_ahb_clk; + + if (!strcmp(id, "wdt")) + return &ath79_wdt_clk; + + if (!strcmp(id, "uart")) + return &ath79_uart_clk; + + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL(clk_get); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return clk->rate; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); diff --git a/arch/mips/ath79/common.c b/arch/mips/ath79/common.c new file mode 100644 index 000000000000..58f60e722a03 --- /dev/null +++ b/arch/mips/ath79/common.c @@ -0,0 +1,97 @@ +/* + * Atheros AR71XX/AR724X/AR913X common routines + * + * Copyright (C) 2008-2010 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#include +#include + +#include +#include +#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 000000000000..612a6b5d8702 --- /dev/null +++ b/arch/mips/ath79/common.h @@ -0,0 +1,26 @@ +/* + * Atheros AR71XX/AR724X/AR913X common definitions + * + * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include + +#define ATH79_MEM_SIZE_MIN (2 * 1024 * 1024) +#define ATH79_MEM_SIZE_MAX (128 * 1024 * 1024) + +void ath79_clocks_init(void); +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 000000000000..3cfa10065d68 --- /dev/null +++ b/arch/mips/ath79/dev-common.c @@ -0,0 +1,67 @@ +/* + * Atheros AR71XX/AR724X/AR913X common devices + * + * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#include +#include +#include +#include + +#include +#include +#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) +{ + struct clk *clk; + + clk = clk_get(NULL, "uart"); + if (IS_ERR(clk)) + panic("unable to get UART clock, err=%ld", PTR_ERR(clk)); + + ath79_uart_data[0].uartclk = clk_get_rate(clk); + 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 000000000000..248622cc7cd6 --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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); + +#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 000000000000..7499b0e9df26 --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#include + +#include + +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 000000000000..1bf7f719ba53 --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#include +#include + +#include +#include + +#include +#include +#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 000000000000..e9cbd7c2918f --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#include +#include + +#include +#include + +#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 000000000000..175def860165 --- /dev/null +++ b/arch/mips/ath79/setup.c @@ -0,0 +1,190 @@ +/* + * Atheros AR71XX/AR724X/AR913X specific setup + * + * Copyright (C) 2008-2011 Gabor Juhos + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#include +#include +#include + +#include +#include /* for mips_hpt_frequency */ +#include /* for _machine_{restart,halt} */ + +#include +#include +#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); + pr_info("SoC: %s\n", ath79_sys_type); +} + +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_clocks_init(); + + _machine_restart = ath79_restart; + _machine_halt = ath79_halt; + pm_power_off = ath79_halt; +} + +void __init plat_time_init(void) +{ + struct clk *clk; + + clk = clk_get(NULL, "cpu"); + if (IS_ERR(clk)) + panic("unable to get CPU clock, err=%ld", PTR_ERR(clk)); + + mips_hpt_frequency = clk_get_rate(clk) / 2; +} + +static int __init ath79_setup(void) +{ + ath79_register_uart(); + return 0; +} + +arch_initcall(ath79_setup); -- cgit v1.2.1 From 6eae43c57ee92de91f6cc7c391cea97c43295da0 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 4 Jan 2011 21:28:15 +0100 Subject: MIPS: ath79: add GPIOLIB support This patch implements generic GPIO routines for the built-in GPIO controllers of the Atheros AR71XX/AR724X/AR913X SoCs. Signed-off-by: Gabor Juhos Signed-off-by: Imre Kaloz Cc: David Brownell Cc: linux-mips@linux-mips.org Cc: Luis R. Rodriguez Cc: Cliff Holden Cc: Kathy Giori Patchwork: https://patchwork.linux-mips.org/patch/1948/ Signed-off-by: Ralf Baechle --- arch/mips/ath79/Makefile | 2 +- arch/mips/ath79/common.h | 5 ++ arch/mips/ath79/gpio.c | 197 +++++++++++++++++++++++++++++++++++++++++++++++ arch/mips/ath79/setup.c | 2 +- 4 files changed, 204 insertions(+), 2 deletions(-) create mode 100644 arch/mips/ath79/gpio.c (limited to 'arch/mips/ath79') diff --git a/arch/mips/ath79/Makefile b/arch/mips/ath79/Makefile index 31e0f83ddf68..e621d6c464c1 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 clock.o +obj-y := prom.o setup.o irq.o common.o clock.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 612a6b5d8702..561906c2345e 100644 --- a/arch/mips/ath79/common.h +++ b/arch/mips/ath79/common.h @@ -23,4 +23,9 @@ void ath79_clocks_init(void); 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); + #endif /* __ATH79_COMMON_H */ diff --git a/arch/mips/ath79/gpio.c b/arch/mips/ath79/gpio.c new file mode 100644 index 000000000000..a0c426b82123 --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#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 175def860165..29dde98f49ed 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c @@ -157,7 +157,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); @@ -183,6 +182,7 @@ void __init plat_time_init(void) static int __init ath79_setup(void) { + ath79_gpio_init(); ath79_register_uart(); return 0; } -- cgit v1.2.1 From 0aabf1a4d9b6b2d2371f641ec19fb7551cea4a90 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 4 Jan 2011 21:28:16 +0100 Subject: MIPS: ath79: utilize the MIPS multi-machine support Signed-off-by: Gabor Juhos Cc: Imre Kaloz Cc: linux-mips@linux-mips.org Cc: Luis R. Rodriguez Cc: Cliff Holden Cc: Kathy Giori Patchwork: https://patchwork.linux-mips.org/patch/1949/ Signed-off-by: Ralf Baechle --- arch/mips/ath79/machtypes.h | 21 +++++++++++++++++++++ arch/mips/ath79/setup.c | 15 +++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 arch/mips/ath79/machtypes.h (limited to 'arch/mips/ath79') diff --git a/arch/mips/ath79/machtypes.h b/arch/mips/ath79/machtypes.h new file mode 100644 index 000000000000..fac0e26a2433 --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 + +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 29dde98f49ed..5e5740298709 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c @@ -20,11 +20,13 @@ #include #include /* for mips_hpt_frequency */ #include /* for _machine_{restart,halt} */ +#include #include #include #include "common.h" #include "dev-common.h" +#include "machtypes.h" #define ATH79_SYS_TYPE_LEN 64 @@ -184,7 +186,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); -- cgit v1.2.1 From 0cde72284c9c7d4b348ece9e1fe136f787185cd7 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 4 Jan 2011 21:28:17 +0100 Subject: MIPS: ath79: add initial support for the Atheros PB44 reference board Signed-off-by: Gabor Juhos Cc: Imre Kaloz Cc: linux-mips@linux-mips.org Cc: Luis R. Rodriguez Cc: Cliff Holden Cc: Kathy Giori Patchwork: https://patchwork.linux-mips.org/patch/1950/ Signed-off-by: Ralf Baechle --- 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(+) create mode 100644 arch/mips/ath79/mach-pb44.c (limited to 'arch/mips/ath79') diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index 50b933446cc0..fabb2b0412d7 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 e621d6c464c1..c3093f7d401f 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 000000000000..ffc24d7a2552 --- /dev/null +++ b/arch/mips/ath79/mach-pb44.c @@ -0,0 +1,56 @@ +/* + * Atheros PB44 reference board support + * + * Copyright (C) 2009-2010 Gabor Juhos + * + * 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 +#include +#include +#include +#include + +#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 fac0e26a2433..a796fa3f92a3 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 */ -- cgit v1.2.1 From d8fec1fc80cd8639449e2b5012688f5be109eeaf Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 4 Jan 2011 21:28:18 +0100 Subject: MIPS: ath79: add common GPIO LEDs device 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 Signed-off-by: Imre Kaloz Cc: linux-mips@linux-mips.org Cc: Luis R. Rodriguez Cc: Cliff Holden Cc: Kathy Giori Patchwork: https://patchwork.linux-mips.org/patch/1953/ Signed-off-by: Ralf Baechle --- 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(+) create mode 100644 arch/mips/ath79/dev-leds-gpio.c create mode 100644 arch/mips/ath79/dev-leds-gpio.h (limited to 'arch/mips/ath79') diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index fabb2b0412d7..5bc480e28b0c 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 c3093f7d401f..f41c0296aa20 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 000000000000..cdade68dcd17 --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#include + +#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 000000000000..6e5d8851ebcf --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 + +void ath79_register_leds_gpio(int id, + unsigned num_leds, + struct gpio_led *leds); + +#endif /* _ATH79_DEV_LEDS_GPIO_H */ diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c index ffc24d7a2552..e176779af660 100644 --- a/arch/mips/ath79/mach-pb44.c +++ b/arch/mips/ath79/mach-pb44.c @@ -15,11 +15,14 @@ #include #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", -- cgit v1.2.1 From 858f763c1cc37ecc6ab39dec60bb3a46606dcac4 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 4 Jan 2011 21:28:20 +0100 Subject: MIPS: ath79: add common watchdog device 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 Signed-off-by: Imre Kaloz Cc: linux-mips@linux-mips.org Cc: Luis R. Rodriguez Cc: Cliff Holden Cc: Kathy Giori Patchwork: https://patchwork.linux-mips.org/patch/1955/ Signed-off-by: Ralf Baechle --- 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(+) (limited to 'arch/mips/ath79') diff --git a/arch/mips/ath79/dev-common.c b/arch/mips/ath79/dev-common.c index 3cfa10065d68..3b82e325bebf 100644 --- a/arch/mips/ath79/dev-common.c +++ b/arch/mips/ath79/dev-common.c @@ -65,3 +65,13 @@ void __init ath79_register_uart(void) ath79_uart_data[0].uartclk = clk_get_rate(clk); 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 248622cc7cd6..0f514e1affce 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); +void ath79_register_wdt(void); #endif /* _ATH79_DEV_COMMON_H */ diff --git a/arch/mips/ath79/setup.c b/arch/mips/ath79/setup.c index 5e5740298709..159b42f106b0 100644 --- a/arch/mips/ath79/setup.c +++ b/arch/mips/ath79/setup.c @@ -186,6 +186,7 @@ static int __init ath79_setup(void) { ath79_gpio_init(); ath79_register_uart(); + ath79_register_wdt(); mips_machine_setup(); -- cgit v1.2.1 From 3f348c5d1aaa0b8b2563f50d2d9a0c64e7d649fb Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 4 Jan 2011 21:28:21 +0100 Subject: MIPS: ath79: add common GPIO buttons device 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 Signed-off-by: Imre Kaloz Cc: linux-mips@linux-mips.org Cc: Luis R. Rodriguez Cc: Cliff Holden Cc: Kathy Giori Patchwork: https://patchwork.linux-mips.org/patch/1954/ Signed-off-by: Ralf Baechle --- 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(+) create mode 100644 arch/mips/ath79/dev-gpio-buttons.c create mode 100644 arch/mips/ath79/dev-gpio-buttons.h (limited to 'arch/mips/ath79') diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index 5bc480e28b0c..185a8d6c73de 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 f41c0296aa20..344e9ab1e106 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 000000000000..4b0168a11c01 --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 + +#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 000000000000..481847ac1cba --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include + +void ath79_register_gpio_keys_polled(int id, + unsigned poll_interval, + unsigned nbuttons, + struct gpio_keys_button *buttons); + +#endif /* _ATH79_DEV_GPIO_BUTTONS_H */ diff --git a/arch/mips/ath79/mach-pb44.c b/arch/mips/ath79/mach-pb44.c index e176779af660..3dc5080185cb 100644 --- a/arch/mips/ath79/mach-pb44.c +++ b/arch/mips/ath79/mach-pb44.c @@ -15,15 +15,21 @@ #include #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", -- cgit v1.2.1 From 68a1d3163678a42ad2d0a9013672083c4fb613be Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 4 Jan 2011 21:28:23 +0100 Subject: MIPS: ath79: add common SPI controller device 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 Cc: linux-mips@linux-mips.org Cc: Imre Kaloz Cc: Luis R. Rodriguez Cc: Cliff Holden Cc: Kathy Giori Patchwork: https://patchwork.linux-mips.org/patch/1956/ Signed-off-by: Ralf Baechle --- 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 +++++++++++++++++ 5 files changed, 82 insertions(+) create mode 100644 arch/mips/ath79/dev-spi.c create mode 100644 arch/mips/ath79/dev-spi.h (limited to 'arch/mips/ath79') diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index 185a8d6c73de..cd6c738a916c 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 344e9ab1e106..42f4295e650a 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 000000000000..aa30163efbfd --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#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 000000000000..d732565ca736 --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include + +void 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 3dc5080185cb..ec7b7a135d53 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", -- cgit v1.2.1 From aa6695ec8b51da7aaa245310073ddd39a306a77f Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 4 Jan 2011 21:28:28 +0100 Subject: MIPS: ath79: Add initial support for the Atheros AP81 reference board Signed-off-by: Gabor Juhos Signed-off-by: Imre Kaloz Cc: linux-mips@linux-mips.org Cc: Luis R. Rodriguez Cc: Cliff Holden Cc: Kathy Giori Patchwork: https://patchwork.linux-mips.org/patch/1952/ Signed-off-by: Ralf Baechle --- arch/mips/ath79/Kconfig | 10 +++++ arch/mips/ath79/Makefile | 1 + arch/mips/ath79/mach-ap81.c | 92 +++++++++++++++++++++++++++++++++++++++++++++ arch/mips/ath79/machtypes.h | 1 + 4 files changed, 104 insertions(+) create mode 100644 arch/mips/ath79/mach-ap81.c (limited to 'arch/mips/ath79') diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index cd6c738a916c..2e397708e2f7 100644 --- a/arch/mips/ath79/Kconfig +++ b/arch/mips/ath79/Kconfig @@ -2,6 +2,16 @@ 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 + 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 42f4295e650a..a245e3645271 100644 --- a/arch/mips/ath79/Makefile +++ b/arch/mips/ath79/Makefile @@ -23,4 +23,5 @@ obj-$(CONFIG_ATH79_DEV_SPI) += dev-spi.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 000000000000..4e4ccd4f80d9 --- /dev/null +++ b/arch/mips/ath79/mach-ap81.c @@ -0,0 +1,92 @@ +/* + * Atheros AP81 board support + * + * Copyright (C) 2009-2010 Gabor Juhos + * Copyright (C) 2009 Imre Kaloz + * + * 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" + +#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)); +} + +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 a796fa3f92a3..3940fe470b2d 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 */ }; -- cgit v1.2.1 From f5b35d0b16a08e6c1e7c8a41fa87ad10cf9aefa4 Mon Sep 17 00:00:00 2001 From: Gabor Juhos Date: Tue, 4 Jan 2011 21:28:29 +0100 Subject: MIPS: ath79: add common WMAC device for AR913X based boards 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 Cc: linux-mips@linux-mips.org Cc: Imre Kaloz , Cc: Luis R. Rodriguez Cc: Cliff Holden Cc: Kathy Giori Patchwork: https://patchwork.linux-mips.org/patch/1962/ Signed-off-by: Ralf Baechle --- 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 ++++ 5 files changed, 89 insertions(+) create mode 100644 arch/mips/ath79/dev-ar913x-wmac.c create mode 100644 arch/mips/ath79/dev-ar913x-wmac.h (limited to 'arch/mips/ath79') diff --git a/arch/mips/ath79/Kconfig b/arch/mips/ath79/Kconfig index 2e397708e2f7..b05828260f7f 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 @@ -33,6 +34,10 @@ config SOC_AR724X config SOC_AR913X 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 a245e3645271..c33d4653007c 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 000000000000..48f425a5ba28 --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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 +#include +#include +#include +#include + +#include +#include +#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 000000000000..579d562bbda8 --- /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 + * Copyright (C) 2008 Imre Kaloz + * + * 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); + +#endif /* _ATH79_DEV_AR913X_WMAC_H */ diff --git a/arch/mips/ath79/mach-ap81.c b/arch/mips/ath79/mach-ap81.c index 4e4ccd4f80d9..eee4c121deb4 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" @@ -25,6 +26,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", @@ -79,6 +82,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, @@ -86,6 +91,7 @@ static void __init ap81_setup(void) ap81_gpio_keys); ath79_register_spi(&ap81_spi_data, ap81_spi_info, ARRAY_SIZE(ap81_spi_info)); + ath79_register_ar913x_wmac(cal_data); } MIPS_MACHINE(ATH79_MACH_AP81, "AP81", "Atheros AP81 reference board", -- cgit v1.2.1