summaryrefslogtreecommitdiff
path: root/arch/arm/mach-orion5x
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-10-15 13:46:29 +0200
committerIngo Molnar <mingo@elte.hu>2008-10-15 13:46:29 +0200
commitb2aaf8f74cdc84a9182f6cabf198b7763bcb9d40 (patch)
tree53ccb1c2c14751fe69cf93102e76e97021f6df07 /arch/arm/mach-orion5x
parent4f962d4d65923d7b722192e729840cfb79af0a5a (diff)
parent278429cff8809958d25415ba0ed32b59866ab1a8 (diff)
Merge branch 'linus' into stackprotector
Conflicts: arch/x86/kernel/Makefile include/asm-x86/pda.h
Diffstat (limited to 'arch/arm/mach-orion5x')
-rw-r--r--arch/arm/mach-orion5x/Kconfig74
-rw-r--r--arch/arm/mach-orion5x/Makefile16
-rw-r--r--arch/arm/mach-orion5x/addr-map.c49
-rw-r--r--arch/arm/mach-orion5x/common.c488
-rw-r--r--arch/arm/mach-orion5x/common.h42
-rw-r--r--arch/arm/mach-orion5x/db88f5281-setup.c92
-rw-r--r--arch/arm/mach-orion5x/dns323-setup.c135
-rw-r--r--arch/arm/mach-orion5x/edmini_v2-setup.c262
-rw-r--r--arch/arm/mach-orion5x/gpio.c51
-rw-r--r--arch/arm/mach-orion5x/include/mach/debug-macro.S22
-rw-r--r--arch/arm/mach-orion5x/include/mach/dma.h1
-rw-r--r--arch/arm/mach-orion5x/include/mach/entry-macro.S31
-rw-r--r--arch/arm/mach-orion5x/include/mach/gpio.h28
-rw-r--r--arch/arm/mach-orion5x/include/mach/hardware.h21
-rw-r--r--arch/arm/mach-orion5x/include/mach/io.h63
-rw-r--r--arch/arm/mach-orion5x/include/mach/irqs.h62
-rw-r--r--arch/arm/mach-orion5x/include/mach/memory.h16
-rw-r--r--arch/arm/mach-orion5x/include/mach/orion5x.h173
-rw-r--r--arch/arm/mach-orion5x/include/mach/system.h32
-rw-r--r--arch/arm/mach-orion5x/include/mach/timex.h11
-rw-r--r--arch/arm/mach-orion5x/include/mach/uncompress.h49
-rw-r--r--arch/arm/mach-orion5x/include/mach/vmalloc.h5
-rw-r--r--arch/arm/mach-orion5x/irq.c38
-rw-r--r--arch/arm/mach-orion5x/kurobox_pro-setup.c235
-rw-r--r--arch/arm/mach-orion5x/lsmini-setup.c279
-rw-r--r--arch/arm/mach-orion5x/mpp.c163
-rw-r--r--arch/arm/mach-orion5x/mpp.h74
-rw-r--r--arch/arm/mach-orion5x/mss2-setup.c271
-rw-r--r--arch/arm/mach-orion5x/mv2120-setup.c240
-rw-r--r--arch/arm/mach-orion5x/pci.c101
-rw-r--r--arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c164
-rw-r--r--arch/arm/mach-orion5x/rd88f5181l-ge-setup.c175
-rw-r--r--arch/arm/mach-orion5x/rd88f5182-setup.c88
-rw-r--r--arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c117
-rw-r--r--arch/arm/mach-orion5x/terastation_pro2-setup.c369
-rw-r--r--arch/arm/mach-orion5x/ts209-setup.c311
-rw-r--r--arch/arm/mach-orion5x/ts409-setup.c322
-rw-r--r--arch/arm/mach-orion5x/ts78xx-setup.c277
-rw-r--r--arch/arm/mach-orion5x/tsx09-common.c134
-rw-r--r--arch/arm/mach-orion5x/tsx09-common.h20
-rw-r--r--arch/arm/mach-orion5x/wnr854t-setup.c167
-rw-r--r--arch/arm/mach-orion5x/wrt350n-v2-setup.c176
42 files changed, 4767 insertions, 677 deletions
diff --git a/arch/arm/mach-orion5x/Kconfig b/arch/arm/mach-orion5x/Kconfig
index 93debf336155..f59a8d0e0824 100644
--- a/arch/arm/mach-orion5x/Kconfig
+++ b/arch/arm/mach-orion5x/Kconfig
@@ -36,6 +36,12 @@ config MACH_TS209
Say 'Y' here if you want your kernel to support the
QNAP TS-109/TS-209 platform.
+config MACH_TERASTATION_PRO2
+ bool "Buffalo Terastation Pro II/Live"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Buffalo Terastation Pro II/Live platform.
+
config MACH_LINKSTATION_PRO
bool "Buffalo Linkstation Pro/Live"
select I2C_BOARDINFO
@@ -44,6 +50,74 @@ config MACH_LINKSTATION_PRO
Buffalo Linkstation Pro/Live platform. Both v1 and
v2 devices are supported.
+config MACH_LINKSTATION_MINI
+ bool "Buffalo Linkstation Mini"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ Buffalo Linkstation Mini platform.
+
+config MACH_TS409
+ bool "QNAP TS-409"
+ help
+ Say 'Y' here if you want your kernel to support the
+ QNAP TS-409 platform.
+
+config MACH_WRT350N_V2
+ bool "Linksys WRT350N v2"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Linksys WRT350N v2 platform.
+
+config MACH_TS78XX
+ bool "Technologic Systems TS-78xx"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Technologic Systems TS-78xx platform.
+
+config MACH_MV2120
+ bool "HP Media Vault mv2120"
+ help
+ Say 'Y' here if you want your kernel to support the
+ HP Media Vault mv2120 or mv5100.
+
+config MACH_EDMINI_V2
+ bool "LaCie Ethernet Disk mini V2"
+ select I2C_BOARDINFO
+ help
+ Say 'Y' here if you want your kernel to support the
+ LaCie Ethernet Disk mini V2.
+
+config MACH_MSS2
+ bool "Maxtor Shared Storage II"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Maxtor Shared Storage II platform.
+
+config MACH_WNR854T
+ bool "Netgear WNR854T"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Netgear WNR854T platform.
+
+config MACH_RD88F5181L_GE
+ bool "Marvell Orion-VoIP GE Reference Design"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell Orion-VoIP GE (88F5181L) RD.
+
+config MACH_RD88F5181L_FXO
+ bool "Marvell Orion-VoIP FXO Reference Design"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell Orion-VoIP FXO (88F5181L) RD.
+
+config MACH_RD88F6183AP_GE
+ bool "Marvell Orion-1-90 AP GE Reference Design"
+ help
+ Say 'Y' here if you want your kernel to support the
+ Marvell Orion-1-90 (88F6183) AP GE RD.
+
endmenu
endif
diff --git a/arch/arm/mach-orion5x/Makefile b/arch/arm/mach-orion5x/Makefile
index 9301bf55910b..3d4a1bc12355 100644
--- a/arch/arm/mach-orion5x/Makefile
+++ b/arch/arm/mach-orion5x/Makefile
@@ -1,7 +1,19 @@
-obj-y += common.o addr-map.o pci.o gpio.o irq.o
+obj-y += common.o addr-map.o pci.o gpio.o irq.o mpp.o
obj-$(CONFIG_MACH_DB88F5281) += db88f5281-setup.o
obj-$(CONFIG_MACH_RD88F5182) += rd88f5182-setup.o
obj-$(CONFIG_MACH_KUROBOX_PRO) += kurobox_pro-setup.o
+obj-$(CONFIG_MACH_TERASTATION_PRO2) += terastation_pro2-setup.o
obj-$(CONFIG_MACH_LINKSTATION_PRO) += kurobox_pro-setup.o
+obj-$(CONFIG_MACH_LINKSTATION_MINI) += lsmini-setup.o
obj-$(CONFIG_MACH_DNS323) += dns323-setup.o
-obj-$(CONFIG_MACH_TS209) += ts209-setup.o
+obj-$(CONFIG_MACH_TS209) += ts209-setup.o tsx09-common.o
+obj-$(CONFIG_MACH_TS409) += ts409-setup.o tsx09-common.o
+obj-$(CONFIG_MACH_WRT350N_V2) += wrt350n-v2-setup.o
+obj-$(CONFIG_MACH_TS78XX) += ts78xx-setup.o
+obj-$(CONFIG_MACH_MV2120) += mv2120-setup.o
+obj-$(CONFIG_MACH_EDMINI_V2) += edmini_v2-setup.o
+obj-$(CONFIG_MACH_MSS2) += mss2-setup.o
+obj-$(CONFIG_MACH_WNR854T) += wnr854t-setup.o
+obj-$(CONFIG_MACH_RD88F5181L_GE) += rd88f5181l-ge-setup.o
+obj-$(CONFIG_MACH_RD88F5181L_FXO) += rd88f5181l-fxo-setup.o
+obj-$(CONFIG_MACH_RD88F6183AP_GE) += rd88f6183ap-ge-setup.o
diff --git a/arch/arm/mach-orion5x/addr-map.c b/arch/arm/mach-orion5x/addr-map.c
index e63fb05dc893..719957e05d9e 100644
--- a/arch/arm/mach-orion5x/addr-map.c
+++ b/arch/arm/mach-orion5x/addr-map.c
@@ -13,8 +13,8 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/mbus.h>
-#include <asm/hardware.h>
-#include <asm/io.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
#include "common.h"
/*
@@ -70,6 +70,7 @@
struct mbus_dram_target_info orion5x_mbus_dram_info;
+static int __initdata win_alloc_count;
static int __init orion5x_cpu_win_can_remap(int win)
{
@@ -87,16 +88,22 @@ static int __init orion5x_cpu_win_can_remap(int win)
static void __init setup_cpu_win(int win, u32 base, u32 size,
u8 target, u8 attr, int remap)
{
- orion5x_write(CPU_WIN_BASE(win), base & 0xffff0000);
- orion5x_write(CPU_WIN_CTRL(win),
- ((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1);
+ if (win >= 8) {
+ printk(KERN_ERR "setup_cpu_win: trying to allocate "
+ "window %d\n", win);
+ return;
+ }
+
+ writel(base & 0xffff0000, CPU_WIN_BASE(win));
+ writel(((size - 1) & 0xffff0000) | (attr << 8) | (target << 4) | 1,
+ CPU_WIN_CTRL(win));
if (orion5x_cpu_win_can_remap(win)) {
if (remap < 0)
remap = base;
- orion5x_write(CPU_WIN_REMAP_LO(win), remap & 0xffff0000);
- orion5x_write(CPU_WIN_REMAP_HI(win), 0);
+ writel(remap & 0xffff0000, CPU_WIN_REMAP_LO(win));
+ writel(0, CPU_WIN_REMAP_HI(win));
}
}
@@ -109,11 +116,11 @@ void __init orion5x_setup_cpu_mbus_bridge(void)
* First, disable and clear windows.
*/
for (i = 0; i < 8; i++) {
- orion5x_write(CPU_WIN_BASE(i), 0);
- orion5x_write(CPU_WIN_CTRL(i), 0);
+ writel(0, CPU_WIN_BASE(i));
+ writel(0, CPU_WIN_CTRL(i));
if (orion5x_cpu_win_can_remap(i)) {
- orion5x_write(CPU_WIN_REMAP_LO(i), 0);
- orion5x_write(CPU_WIN_REMAP_HI(i), 0);
+ writel(0, CPU_WIN_REMAP_LO(i));
+ writel(0, CPU_WIN_REMAP_HI(i));
}
}
@@ -128,6 +135,7 @@ void __init orion5x_setup_cpu_mbus_bridge(void)
TARGET_PCIE, ATTR_PCIE_MEM, -1);
setup_cpu_win(3, ORION5X_PCI_MEM_PHYS_BASE, ORION5X_PCI_MEM_SIZE,
TARGET_PCI, ATTR_PCI_MEM, -1);
+ win_alloc_count = 4;
/*
* Setup MBUS dram target info.
@@ -147,8 +155,8 @@ void __init orion5x_setup_cpu_mbus_bridge(void)
w = &orion5x_mbus_dram_info.cs[cs++];
w->cs_index = i;
w->mbus_attr = 0xf & ~(1 << i);
- w->base = base & 0xff000000;
- w->size = (size | 0x00ffffff) + 1;
+ w->base = base & 0xffff0000;
+ w->size = (size | 0x0000ffff) + 1;
}
}
orion5x_mbus_dram_info.num_cs = cs;
@@ -156,25 +164,30 @@ void __init orion5x_setup_cpu_mbus_bridge(void)
void __init orion5x_setup_dev_boot_win(u32 base, u32 size)
{
- setup_cpu_win(4, base, size, TARGET_DEV_BUS, ATTR_DEV_BOOT, -1);
+ setup_cpu_win(win_alloc_count++, base, size,
+ TARGET_DEV_BUS, ATTR_DEV_BOOT, -1);
}
void __init orion5x_setup_dev0_win(u32 base, u32 size)
{
- setup_cpu_win(5, base, size, TARGET_DEV_BUS, ATTR_DEV_CS0, -1);
+ setup_cpu_win(win_alloc_count++, base, size,
+ TARGET_DEV_BUS, ATTR_DEV_CS0, -1);
}
void __init orion5x_setup_dev1_win(u32 base, u32 size)
{
- setup_cpu_win(6, base, size, TARGET_DEV_BUS, ATTR_DEV_CS1, -1);
+ setup_cpu_win(win_alloc_count++, base, size,
+ TARGET_DEV_BUS, ATTR_DEV_CS1, -1);
}
void __init orion5x_setup_dev2_win(u32 base, u32 size)
{
- setup_cpu_win(7, base, size, TARGET_DEV_BUS, ATTR_DEV_CS2, -1);
+ setup_cpu_win(win_alloc_count++, base, size,
+ TARGET_DEV_BUS, ATTR_DEV_CS2, -1);
}
void __init orion5x_setup_pcie_wa_win(u32 base, u32 size)
{
- setup_cpu_win(7, base, size, TARGET_PCIE, ATTR_PCIE_WA, -1);
+ setup_cpu_win(win_alloc_count++, base, size,
+ TARGET_PCIE, ATTR_PCIE_WA, -1);
}
diff --git a/arch/arm/mach-orion5x/common.c b/arch/arm/mach-orion5x/common.c
index 4f13fd037f04..9625ef5975d0 100644
--- a/arch/arm/mach-orion5x/common.c
+++ b/arch/arm/mach-orion5x/common.c
@@ -18,17 +18,19 @@
#include <linux/mv643xx_eth.h>
#include <linux/mv643xx_i2c.h>
#include <linux/ata_platform.h>
+#include <linux/spi/orion_spi.h>
#include <asm/page.h>
#include <asm/setup.h>
#include <asm/timex.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
-#include <asm/arch/hardware.h>
-#include <asm/arch/orion5x.h>
-#include <asm/plat-orion/ehci-orion.h>
-#include <asm/plat-orion/orion_nand.h>
-#include <asm/plat-orion/time.h>
+#include <mach/hardware.h>
+#include <mach/orion5x.h>
+#include <plat/ehci-orion.h>
+#include <plat/mv_xor.h>
+#include <plat/orion_nand.h>
+#include <plat/time.h>
#include "common.h"
/*****************************************************************************
@@ -39,25 +41,22 @@ static struct map_desc orion5x_io_desc[] __initdata = {
.virtual = ORION5X_REGS_VIRT_BASE,
.pfn = __phys_to_pfn(ORION5X_REGS_PHYS_BASE),
.length = ORION5X_REGS_SIZE,
- .type = MT_DEVICE
- },
- {
+ .type = MT_DEVICE,
+ }, {
.virtual = ORION5X_PCIE_IO_VIRT_BASE,
.pfn = __phys_to_pfn(ORION5X_PCIE_IO_PHYS_BASE),
.length = ORION5X_PCIE_IO_SIZE,
- .type = MT_DEVICE
- },
- {
+ .type = MT_DEVICE,
+ }, {
.virtual = ORION5X_PCI_IO_VIRT_BASE,
.pfn = __phys_to_pfn(ORION5X_PCI_IO_PHYS_BASE),
.length = ORION5X_PCI_IO_SIZE,
- .type = MT_DEVICE
- },
- {
+ .type = MT_DEVICE,
+ }, {
.virtual = ORION5X_PCIE_WA_VIRT_BASE,
.pfn = __phys_to_pfn(ORION5X_PCIE_WA_PHYS_BASE),
.length = ORION5X_PCIE_WA_SIZE,
- .type = MT_DEVICE
+ .type = MT_DEVICE,
},
};
@@ -66,101 +65,32 @@ void __init orion5x_map_io(void)
iotable_init(orion5x_io_desc, ARRAY_SIZE(orion5x_io_desc));
}
+
/*****************************************************************************
- * UART
+ * EHCI
****************************************************************************/
-
-static struct resource orion5x_uart_resources[] = {
- {
- .start = UART0_PHYS_BASE,
- .end = UART0_PHYS_BASE + 0xff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IRQ_ORION5X_UART0,
- .end = IRQ_ORION5X_UART0,
- .flags = IORESOURCE_IRQ,
- },
- {
- .start = UART1_PHYS_BASE,
- .end = UART1_PHYS_BASE + 0xff,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IRQ_ORION5X_UART1,
- .end = IRQ_ORION5X_UART1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct plat_serial8250_port orion5x_uart_data[] = {
- {
- .mapbase = UART0_PHYS_BASE,
- .membase = (char *)UART0_VIRT_BASE,
- .irq = IRQ_ORION5X_UART0,
- .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = ORION5X_TCLK,
- },
- {
- .mapbase = UART1_PHYS_BASE,
- .membase = (char *)UART1_VIRT_BASE,
- .irq = IRQ_ORION5X_UART1,
- .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
- .iotype = UPIO_MEM,
- .regshift = 2,
- .uartclk = ORION5X_TCLK,
- },
- { },
+static struct orion_ehci_data orion5x_ehci_data = {
+ .dram = &orion5x_mbus_dram_info,
};
-static struct platform_device orion5x_uart = {
- .name = "serial8250",
- .id = PLAT8250_DEV_PLATFORM,
- .dev = {
- .platform_data = orion5x_uart_data,
- },
- .resource = orion5x_uart_resources,
- .num_resources = ARRAY_SIZE(orion5x_uart_resources),
-};
+static u64 ehci_dmamask = 0xffffffffUL;
-/*******************************************************************************
- * USB Controller - 2 interfaces
- ******************************************************************************/
+/*****************************************************************************
+ * EHCI0
+ ****************************************************************************/
static struct resource orion5x_ehci0_resources[] = {
{
.start = ORION5X_USB0_PHYS_BASE,
.end = ORION5X_USB0_PHYS_BASE + SZ_4K - 1,
.flags = IORESOURCE_MEM,
- },
- {
+ }, {
.start = IRQ_ORION5X_USB0_CTRL,
.end = IRQ_ORION5X_USB0_CTRL,
.flags = IORESOURCE_IRQ,
},
};
-static struct resource orion5x_ehci1_resources[] = {
- {
- .start = ORION5X_USB1_PHYS_BASE,
- .end = ORION5X_USB1_PHYS_BASE + SZ_4K - 1,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = IRQ_ORION5X_USB1_CTRL,
- .end = IRQ_ORION5X_USB1_CTRL,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct orion_ehci_data orion5x_ehci_data = {
- .dram = &orion5x_mbus_dram_info,
-};
-
-static u64 ehci_dmamask = 0xffffffffUL;
-
static struct platform_device orion5x_ehci0 = {
.name = "orion-ehci",
.id = 0,
@@ -173,6 +103,27 @@ static struct platform_device orion5x_ehci0 = {
.num_resources = ARRAY_SIZE(orion5x_ehci0_resources),
};
+void __init orion5x_ehci0_init(void)
+{
+ platform_device_register(&orion5x_ehci0);
+}
+
+
+/*****************************************************************************
+ * EHCI1
+ ****************************************************************************/
+static struct resource orion5x_ehci1_resources[] = {
+ {
+ .start = ORION5X_USB1_PHYS_BASE,
+ .end = ORION5X_USB1_PHYS_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_ORION5X_USB1_CTRL,
+ .end = IRQ_ORION5X_USB1_CTRL,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
static struct platform_device orion5x_ehci1 = {
.name = "orion-ehci",
.id = 1,
@@ -185,14 +136,17 @@ static struct platform_device orion5x_ehci1 = {
.num_resources = ARRAY_SIZE(orion5x_ehci1_resources),
};
+void __init orion5x_ehci1_init(void)
+{
+ platform_device_register(&orion5x_ehci1);
+}
+
+
/*****************************************************************************
- * Gigabit Ethernet port
- * (The Orion and Discovery (MV643xx) families use the same Ethernet driver)
+ * GigE
****************************************************************************/
-
struct mv643xx_eth_shared_platform_data orion5x_eth_shared_data = {
.dram = &orion5x_mbus_dram_info,
- .t_clk = ORION5X_TCLK,
};
static struct resource orion5x_eth_shared_resources[] = {
@@ -200,6 +154,10 @@ static struct resource orion5x_eth_shared_resources[] = {
.start = ORION5X_ETH_PHYS_BASE + 0x2000,
.end = ORION5X_ETH_PHYS_BASE + 0x3fff,
.flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_ORION5X_ETH_ERR,
+ .end = IRQ_ORION5X_ETH_ERR,
+ .flags = IORESOURCE_IRQ,
},
};
@@ -209,7 +167,7 @@ static struct platform_device orion5x_eth_shared = {
.dev = {
.platform_data = &orion5x_eth_shared_data,
},
- .num_resources = 1,
+ .num_resources = ARRAY_SIZE(orion5x_eth_shared_resources),
.resource = orion5x_eth_shared_resources,
};
@@ -219,7 +177,7 @@ static struct resource orion5x_eth_resources[] = {
.start = IRQ_ORION5X_ETH_SUM,
.end = IRQ_ORION5X_ETH_SUM,
.flags = IORESOURCE_IRQ,
- }
+ },
};
static struct platform_device orion5x_eth = {
@@ -238,11 +196,10 @@ void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
platform_device_register(&orion5x_eth);
}
+
/*****************************************************************************
- * I2C controller
- * (The Orion and Discovery (MV643xx) families share the same I2C controller)
+ * I2C
****************************************************************************/
-
static struct mv64xxx_i2c_pdata orion5x_i2c_pdata = {
.freq_m = 8, /* assumes 166 MHz TCLK */
.freq_n = 3,
@@ -251,16 +208,15 @@ static struct mv64xxx_i2c_pdata orion5x_i2c_pdata = {
static struct resource orion5x_i2c_resources[] = {
{
- .name = "i2c base",
- .start = I2C_PHYS_BASE,
- .end = I2C_PHYS_BASE + 0x20 -1,
- .flags = IORESOURCE_MEM,
- },
- {
- .name = "i2c irq",
- .start = IRQ_ORION5X_I2C,
- .end = IRQ_ORION5X_I2C,
- .flags = IORESOURCE_IRQ,
+ .name = "i2c base",
+ .start = I2C_PHYS_BASE,
+ .end = I2C_PHYS_BASE + 0x1f,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "i2c irq",
+ .start = IRQ_ORION5X_I2C,
+ .end = IRQ_ORION5X_I2C,
+ .flags = IORESOURCE_IRQ,
},
};
@@ -270,36 +226,41 @@ static struct platform_device orion5x_i2c = {
.num_resources = ARRAY_SIZE(orion5x_i2c_resources),
.resource = orion5x_i2c_resources,
.dev = {
- .platform_data = &orion5x_i2c_pdata,
+ .platform_data = &orion5x_i2c_pdata,
},
};
+void __init orion5x_i2c_init(void)
+{
+ platform_device_register(&orion5x_i2c);
+}
+
+
/*****************************************************************************
- * Sata port
+ * SATA
****************************************************************************/
static struct resource orion5x_sata_resources[] = {
- {
- .name = "sata base",
- .start = ORION5X_SATA_PHYS_BASE,
- .end = ORION5X_SATA_PHYS_BASE + 0x5000 - 1,
- .flags = IORESOURCE_MEM,
- },
{
- .name = "sata irq",
- .start = IRQ_ORION5X_SATA,
- .end = IRQ_ORION5X_SATA,
- .flags = IORESOURCE_IRQ,
- },
+ .name = "sata base",
+ .start = ORION5X_SATA_PHYS_BASE,
+ .end = ORION5X_SATA_PHYS_BASE + 0x5000 - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "sata irq",
+ .start = IRQ_ORION5X_SATA,
+ .end = IRQ_ORION5X_SATA,
+ .flags = IORESOURCE_IRQ,
+ },
};
static struct platform_device orion5x_sata = {
- .name = "sata_mv",
- .id = 0,
+ .name = "sata_mv",
+ .id = 0,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
- .num_resources = ARRAY_SIZE(orion5x_sata_resources),
- .resource = orion5x_sata_resources,
+ .num_resources = ARRAY_SIZE(orion5x_sata_resources),
+ .resource = orion5x_sata_resources,
};
void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
@@ -309,23 +270,255 @@ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
platform_device_register(&orion5x_sata);
}
+
+/*****************************************************************************
+ * SPI
+ ****************************************************************************/
+static struct orion_spi_info orion5x_spi_plat_data = {
+ .tclk = 0,
+};
+
+static struct resource orion5x_spi_resources[] = {
+ {
+ .name = "spi base",
+ .start = SPI_PHYS_BASE,
+ .end = SPI_PHYS_BASE + 0x1f,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device orion5x_spi = {
+ .name = "orion_spi",
+ .id = 0,
+ .dev = {
+ .platform_data = &orion5x_spi_plat_data,
+ },
+ .num_resources = ARRAY_SIZE(orion5x_spi_resources),
+ .resource = orion5x_spi_resources,
+};
+
+void __init orion5x_spi_init()
+{
+ platform_device_register(&orion5x_spi);
+}
+
+
+/*****************************************************************************
+ * UART0
+ ****************************************************************************/
+static struct plat_serial8250_port orion5x_uart0_data[] = {
+ {
+ .mapbase = UART0_PHYS_BASE,
+ .membase = (char *)UART0_VIRT_BASE,
+ .irq = IRQ_ORION5X_UART0,
+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 0,
+ }, {
+ },
+};
+
+static struct resource orion5x_uart0_resources[] = {
+ {
+ .start = UART0_PHYS_BASE,
+ .end = UART0_PHYS_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_ORION5X_UART0,
+ .end = IRQ_ORION5X_UART0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device orion5x_uart0 = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = orion5x_uart0_data,
+ },
+ .resource = orion5x_uart0_resources,
+ .num_resources = ARRAY_SIZE(orion5x_uart0_resources),
+};
+
+void __init orion5x_uart0_init(void)
+{
+ platform_device_register(&orion5x_uart0);
+}
+
+
+/*****************************************************************************
+ * UART1
+ ****************************************************************************/
+static struct plat_serial8250_port orion5x_uart1_data[] = {
+ {
+ .mapbase = UART1_PHYS_BASE,
+ .membase = (char *)UART1_VIRT_BASE,
+ .irq = IRQ_ORION5X_UART1,
+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+ .iotype = UPIO_MEM,
+ .regshift = 2,
+ .uartclk = 0,
+ }, {
+ },
+};
+
+static struct resource orion5x_uart1_resources[] = {
+ {
+ .start = UART1_PHYS_BASE,
+ .end = UART1_PHYS_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = IRQ_ORION5X_UART1,
+ .end = IRQ_ORION5X_UART1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device orion5x_uart1 = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM1,
+ .dev = {
+ .platform_data = orion5x_uart1_data,
+ },
+ .resource = orion5x_uart1_resources,
+ .num_resources = ARRAY_SIZE(orion5x_uart1_resources),
+};
+
+void __init orion5x_uart1_init(void)
+{
+ platform_device_register(&orion5x_uart1);
+}
+
+
+/*****************************************************************************
+ * XOR engine
+ ****************************************************************************/
+static struct resource orion5x_xor_shared_resources[] = {
+ {
+ .name = "xor low",
+ .start = ORION5X_XOR_PHYS_BASE,
+ .end = ORION5X_XOR_PHYS_BASE + 0xff,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .name = "xor high",
+ .start = ORION5X_XOR_PHYS_BASE + 0x200,
+ .end = ORION5X_XOR_PHYS_BASE + 0x2ff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device orion5x_xor_shared = {
+ .name = MV_XOR_SHARED_NAME,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(orion5x_xor_shared_resources),
+ .resource = orion5x_xor_shared_resources,
+};
+
+static u64 orion5x_xor_dmamask = DMA_32BIT_MASK;
+
+static struct resource orion5x_xor0_resources[] = {
+ [0] = {
+ .start = IRQ_ORION5X_XOR0,
+ .end = IRQ_ORION5X_XOR0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mv_xor_platform_data orion5x_xor0_data = {
+ .shared = &orion5x_xor_shared,
+ .hw_id = 0,
+ .pool_size = PAGE_SIZE,
+};
+
+static struct platform_device orion5x_xor0_channel = {
+ .name = MV_XOR_NAME,
+ .id = 0,
+ .num_resources = ARRAY_SIZE(orion5x_xor0_resources),
+ .resource = orion5x_xor0_resources,
+ .dev = {
+ .dma_mask = &orion5x_xor_dmamask,
+ .coherent_dma_mask = DMA_64BIT_MASK,
+ .platform_data = (void *)&orion5x_xor0_data,
+ },
+};
+
+static struct resource orion5x_xor1_resources[] = {
+ [0] = {
+ .start = IRQ_ORION5X_XOR1,
+ .end = IRQ_ORION5X_XOR1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mv_xor_platform_data orion5x_xor1_data = {
+ .shared = &orion5x_xor_shared,
+ .hw_id = 1,
+ .pool_size = PAGE_SIZE,
+};
+
+static struct platform_device orion5x_xor1_channel = {
+ .name = MV_XOR_NAME,
+ .id = 1,
+ .num_resources = ARRAY_SIZE(orion5x_xor1_resources),
+ .resource = orion5x_xor1_resources,
+ .dev = {
+ .dma_mask = &orion5x_xor_dmamask,
+ .coherent_dma_mask = DMA_64BIT_MASK,
+ .platform_data = (void *)&orion5x_xor1_data,
+ },
+};
+
+void __init orion5x_xor_init(void)
+{
+ platform_device_register(&orion5x_xor_shared);
+
+ /*
+ * two engines can't do memset simultaneously, this limitation
+ * satisfied by removing memset support from one of the engines.
+ */
+ dma_cap_set(DMA_MEMCPY, orion5x_xor0_data.cap_mask);
+ dma_cap_set(DMA_XOR, orion5x_xor0_data.cap_mask);
+ platform_device_register(&orion5x_xor0_channel);
+
+ dma_cap_set(DMA_MEMCPY, orion5x_xor1_data.cap_mask);
+ dma_cap_set(DMA_MEMSET, orion5x_xor1_data.cap_mask);
+ dma_cap_set(DMA_XOR, orion5x_xor1_data.cap_mask);
+ platform_device_register(&orion5x_xor1_channel);
+}
+
+
/*****************************************************************************
* Time handling
****************************************************************************/
+int orion5x_tclk;
+
+int __init orion5x_find_tclk(void)
+{
+ u32 dev, rev;
+
+ orion5x_pcie_id(&dev, &rev);
+ if (dev == MV88F6183_DEV_ID &&
+ (readl(MPP_RESET_SAMPLE) & 0x00000200) == 0)
+ return 133333333;
+
+ return 166666667;
+}
static void orion5x_timer_init(void)
{
- orion_time_init(IRQ_ORION5X_BRIDGE, ORION5X_TCLK);
+ orion5x_tclk = orion5x_find_tclk();
+ orion_time_init(IRQ_ORION5X_BRIDGE, orion5x_tclk);
}
struct sys_timer orion5x_timer = {
- .init = orion5x_timer_init,
+ .init = orion5x_timer_init,
};
+
/*****************************************************************************
* General
****************************************************************************/
-
/*
* Identify device ID and rev from PCIe configuration header space '0'.
*/
@@ -338,6 +531,8 @@ static void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name)
*dev_name = "MV88F5281-D2";
} else if (*rev == MV88F5281_REV_D1) {
*dev_name = "MV88F5281-D1";
+ } else if (*rev == MV88F5281_REV_D0) {
+ *dev_name = "MV88F5281-D0";
} else {
*dev_name = "MV88F5281-Rev-Unsupported";
}
@@ -350,8 +545,16 @@ static void __init orion5x_id(u32 *dev, u32 *rev, char **dev_name)
} else if (*dev == MV88F5181_DEV_ID) {
if (*rev == MV88F5181_REV_B1) {
*dev_name = "MV88F5181-Rev-B1";
+ } else if (*rev == MV88F5181L_REV_A1) {
+ *dev_name = "MV88F5181L-Rev-A1";
+ } else {
+ *dev_name = "MV88F5181(L)-Rev-Unsupported";
+ }
+ } else if (*dev == MV88F6183_DEV_ID) {
+ if (*rev == MV88F6183_REV_B0) {
+ *dev_name = "MV88F6183-Rev-B0";
} else {
- *dev_name = "MV88F5181-Rev-Unsupported";
+ *dev_name = "MV88F6183-Rev-Unsupported";
}
} else {
*dev_name = "Device-Unknown";
@@ -364,7 +567,12 @@ void __init orion5x_init(void)
u32 dev, rev;
orion5x_id(&dev, &rev, &dev_name);
- printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, ORION5X_TCLK);
+ printk(KERN_INFO "Orion ID: %s. TCLK=%d.\n", dev_name, orion5x_tclk);
+
+ orion5x_eth_shared_data.t_clk = orion5x_tclk;
+ orion5x_spi_plat_data.tclk = orion5x_tclk;
+ orion5x_uart0_data[0].uartclk = orion5x_tclk;
+ orion5x_uart1_data[0].uartclk = orion5x_tclk;
/*
* Setup Orion address map
@@ -372,13 +580,13 @@ void __init orion5x_init(void)
orion5x_setup_cpu_mbus_bridge();
/*
- * Register devices.
+ * Don't issue "Wait for Interrupt" instruction if we are
+ * running on D0 5281 silicon.
*/
- platform_device_register(&orion5x_uart);
- platform_device_register(&orion5x_ehci0);
- if (dev == MV88F5182_DEV_ID)
- platform_device_register(&orion5x_ehci1);
- platform_device_register(&orion5x_i2c);
+ if (dev == MV88F5281_DEV_ID && rev == MV88F5281_REV_D0) {
+ printk(KERN_INFO "Orion: Applying 5281 D0 WFI workaround.\n");
+ disable_hlt();
+ }
}
/*
diff --git a/arch/arm/mach-orion5x/common.h b/arch/arm/mach-orion5x/common.h
index bd0f05de6e18..1f8b2da676a5 100644
--- a/arch/arm/mach-orion5x/common.h
+++ b/arch/arm/mach-orion5x/common.h
@@ -1,13 +1,16 @@
#ifndef __ARCH_ORION5X_COMMON_H
#define __ARCH_ORION5X_COMMON_H
+struct mv643xx_eth_platform_data;
+struct mv_sata_platform_data;
+
/*
* Basic Orion init functions used early by machine-setup.
*/
-
void orion5x_map_io(void);
void orion5x_init_irq(void);
void orion5x_init(void);
+extern int orion5x_tclk;
extern struct sys_timer orion5x_timer;
/*
@@ -23,15 +26,25 @@ void orion5x_setup_dev1_win(u32 base, u32 size);
void orion5x_setup_dev2_win(u32 base, u32 size);
void orion5x_setup_pcie_wa_win(u32 base, u32 size);
+void orion5x_ehci0_init(void);
+void orion5x_ehci1_init(void);
+void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data);
+void orion5x_i2c_init(void);
+void orion5x_sata_init(struct mv_sata_platform_data *sata_data);
+void orion5x_spi_init(void);
+void orion5x_uart0_init(void);
+void orion5x_uart1_init(void);
+void orion5x_xor_init(void);
+
/*
- * Shared code used internally by other Orion core functions.
- * (/mach-orion/pci.c)
+ * PCIe/PCI functions.
*/
-
-struct pci_sys_data;
struct pci_bus;
+struct pci_sys_data;
void orion5x_pcie_id(u32 *dev, u32 *rev);
+void orion5x_pci_disable(void);
+void orion5x_pci_set_cardbus_mode(void);
int orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys);
struct pci_bus *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys);
int orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin);
@@ -40,26 +53,9 @@ int orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin);
* Valid GPIO pins according to MPP setup, used by machine-setup.
* (/mach-orion/gpio.c).
*/
-
-void orion5x_gpio_set_valid_pins(u32 pins);
+void orion5x_gpio_set_valid(unsigned pin, int valid);
void gpio_display(void); /* debug */
-/*
- * Pull in Orion Ethernet platform_data, used by machine-setup
- */
-
-struct mv643xx_eth_platform_data;
-
-void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data);
-
-/*
- * Orion Sata platform_data, used by machine-setup
- */
-
-struct mv_sata_platform_data;
-
-void orion5x_sata_init(struct mv_sata_platform_data *sata_data);
-
struct machine_desc;
struct meminfo;
struct tag;
diff --git a/arch/arm/mach-orion5x/db88f5281-setup.c b/arch/arm/mach-orion5x/db88f5281-setup.c
index 44c64342dacb..d318bea2af91 100644
--- a/arch/arm/mach-orion5x/db88f5281-setup.c
+++ b/arch/arm/mach-orion5x/db88f5281-setup.c
@@ -24,9 +24,10 @@
#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
-#include <asm/arch/orion5x.h>
-#include <asm/plat-orion/orion_nand.h>
+#include <mach/orion5x.h>
+#include <plat/orion_nand.h>
#include "common.h"
+#include "mpp.h"
/*****************************************************************************
* DB-88F5281 on board devices
@@ -86,7 +87,7 @@ static struct platform_device db88f5281_boot_flash = {
.name = "physmap-flash",
.id = 0,
.dev = {
- .platform_data = &db88f5281_boot_flash_data,
+ .platform_data = &db88f5281_boot_flash_data,
},
.num_resources = 1,
.resource = &db88f5281_boot_flash_resource,
@@ -110,7 +111,7 @@ static struct platform_device db88f5281_nor_flash = {
.name = "physmap-flash",
.id = 1,
.dev = {
- .platform_data = &db88f5281_nor_flash_data,
+ .platform_data = &db88f5281_nor_flash_data,
},
.num_resources = 1,
.resource = &db88f5281_nor_flash_resource,
@@ -125,18 +126,15 @@ static struct mtd_partition db88f5281_nand_parts[] = {
.name = "kernel",
.offset = 0,
.size = SZ_2M,
- },
- {
+ }, {
.name = "root",
.offset = SZ_2M,
.size = (SZ_16M - SZ_2M),
- },
- {
+ }, {
.name = "user",
.offset = SZ_16M,
.size = SZ_8M,
- },
- {
+ }, {
.name = "recovery",
.offset = (SZ_16M + SZ_8M),
.size = SZ_8M,
@@ -215,7 +213,7 @@ void __init db88f5281_pci_preinit(void)
pin = DB88F5281_PCI_SLOT0_IRQ_PIN;
if (gpio_request(pin, "PCI Int1") == 0) {
if (gpio_direction_input(pin) == 0) {
- set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+ set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "db88f5281_pci_preinit faield to "
"set_irq_type pin %d\n", pin);
@@ -228,7 +226,7 @@ void __init db88f5281_pci_preinit(void)
pin = DB88F5281_PCI_SLOT1_SLOT2_IRQ_PIN;
if (gpio_request(pin, "PCI Int2") == 0) {
if (gpio_direction_input(pin) == 0) {
- set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+ set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "db88f5281_pci_preinit faield "
"to set_irq_type pin %d\n", pin);
@@ -287,8 +285,7 @@ subsys_initcall(db88f5281_pci_init);
* Ethernet
****************************************************************************/
static struct mv643xx_eth_platform_data db88f5281_eth_data = {
- .phy_addr = 8,
- .force_phy_addr = 1,
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
};
/*****************************************************************************
@@ -301,11 +298,28 @@ static struct i2c_board_info __initdata db88f5281_i2c_rtc = {
/*****************************************************************************
* General Setup
****************************************************************************/
-
-static struct platform_device *db88f5281_devs[] __initdata = {
- &db88f5281_boot_flash,
- &db88f5281_nor_flash,
- &db88f5281_nand_flash,
+static struct orion5x_mpp_mode db88f5281_mpp_modes[] __initdata = {
+ { 0, MPP_GPIO }, /* USB Over Current */
+ { 1, MPP_GPIO }, /* USB Vbat input */
+ { 2, MPP_PCI_ARB }, /* PCI_REQn[2] */
+ { 3, MPP_PCI_ARB }, /* PCI_GNTn[2] */
+ { 4, MPP_PCI_ARB }, /* PCI_REQn[3] */
+ { 5, MPP_PCI_ARB }, /* PCI_GNTn[3] */
+ { 6, MPP_GPIO }, /* JP0, CON17.2 */
+ { 7, MPP_GPIO }, /* JP1, CON17.1 */
+ { 8, MPP_GPIO }, /* JP2, CON11.2 */
+ { 9, MPP_GPIO }, /* JP3, CON11.3 */
+ { 10, MPP_GPIO }, /* RTC int */
+ { 11, MPP_GPIO }, /* Baud Rate Generator */
+ { 12, MPP_GPIO }, /* PCI int 1 */
+ { 13, MPP_GPIO }, /* PCI int 2 */
+ { 14, MPP_NAND }, /* NAND_REn[2] */
+ { 15, MPP_NAND }, /* NAND_WEn[2] */
+ { 16, MPP_UART }, /* UART1_RX */
+ { 17, MPP_UART }, /* UART1_TX */
+ { 18, MPP_UART }, /* UART1_CTSn */
+ { 19, MPP_UART }, /* UART1_RTSn */
+ { -1 },
};
static void __init db88f5281_init(void)
@@ -315,39 +329,31 @@ static void __init db88f5281_init(void)
*/
orion5x_init();
+ orion5x_mpp_conf(db88f5281_mpp_modes);
+ writel(0, MPP_DEV_CTRL); /* DEV_D[31:16] */
+
/*
- * Setup the CPU address decode windows for our on-board devices
+ * Configure peripherals.
*/
+ orion5x_ehci0_init();
+ orion5x_eth_init(&db88f5281_eth_data);
+ orion5x_i2c_init();
+ orion5x_uart0_init();
+ orion5x_uart1_init();
+
orion5x_setup_dev_boot_win(DB88F5281_NOR_BOOT_BASE,
DB88F5281_NOR_BOOT_SIZE);
+ platform_device_register(&db88f5281_boot_flash);
+
orion5x_setup_dev0_win(DB88F5281_7SEG_BASE, DB88F5281_7SEG_SIZE);
- orion5x_setup_dev1_win(DB88F5281_NOR_BASE, DB88F5281_NOR_SIZE);
- orion5x_setup_dev2_win(DB88F5281_NAND_BASE, DB88F5281_NAND_SIZE);
- /*
- * Setup Multiplexing Pins:
- * MPP0: GPIO (USB Over Current) MPP1: GPIO (USB Vbat input)
- * MPP2: PCI_REQn[2] MPP3: PCI_GNTn[2]
- * MPP4: PCI_REQn[3] MPP5: PCI_GNTn[3]
- * MPP6: GPIO (JP0, CON17.2) MPP7: GPIO (JP1, CON17.1)
- * MPP8: GPIO (JP2, CON11.2) MPP9: GPIO (JP3, CON11.3)
- * MPP10: GPIO (RTC int) MPP11: GPIO (Baud Rate Generator)
- * MPP12: GPIO (PCI int 1) MPP13: GPIO (PCI int 2)
- * MPP14: NAND_REn[2] MPP15: NAND_WEn[2]
- * MPP16: UART1_RX MPP17: UART1_TX
- * MPP18: UART1_CTS MPP19: UART1_RTS
- * MPP-DEV: DEV_D[16:31]
- */
- orion5x_write(MPP_0_7_CTRL, 0x00222203);
- orion5x_write(MPP_8_15_CTRL, 0x44000000);
- orion5x_write(MPP_16_19_CTRL, 0);
- orion5x_write(MPP_DEV_CTRL, 0);
+ orion5x_setup_dev1_win(DB88F5281_NOR_BASE, DB88F5281_NOR_SIZE);
+ platform_device_register(&db88f5281_nor_flash);
- orion5x_gpio_set_valid_pins(0x00003fc3);
+ orion5x_setup_dev2_win(DB88F5281_NAND_BASE, DB88F5281_NAND_SIZE);
+ platform_device_register(&db88f5281_nand_flash);
- platform_add_devices(db88f5281_devs, ARRAY_SIZE(db88f5281_devs));
i2c_register_board_info(0, &db88f5281_i2c_rtc, 1);
- orion5x_eth_init(&db88f5281_eth_data);
}
MACHINE_START(DB88F5281, "Marvell Orion-2 Development Board")
diff --git a/arch/arm/mach-orion5x/dns323-setup.c b/arch/arm/mach-orion5x/dns323-setup.c
index 27ce967ab9e5..3e66098340a5 100644
--- a/arch/arm/mach-orion5x/dns323-setup.c
+++ b/arch/arm/mach-orion5x/dns323-setup.c
@@ -25,8 +25,9 @@
#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
-#include <asm/arch/orion5x.h>
+#include <mach/orion5x.h>
#include "common.h"
+#include "mpp.h"
#define DNS323_GPIO_LED_RIGHT_AMBER 1
#define DNS323_GPIO_LED_LEFT_AMBER 2
@@ -52,8 +53,6 @@ static int __init dns323_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
if (irq != -1)
return irq;
- pr_err("%s: requested mapping for unknown device\n", __func__);
-
return -1;
}
@@ -80,8 +79,7 @@ subsys_initcall(dns323_pci_init);
*/
static struct mv643xx_eth_platform_data dns323_eth_data = {
- .phy_addr = 8,
- .force_phy_addr = 1,
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
};
/****************************************************************************
@@ -119,7 +117,7 @@ static struct mtd_partition dns323_partitions[] = {
.name = "u-boot",
.size = 0x00030000,
.offset = 0x007d0000,
- }
+ },
};
static struct physmap_flash_data dns323_nor_flash_data = {
@@ -137,7 +135,9 @@ static struct resource dns323_nor_flash_resource = {
static struct platform_device dns323_nor_flash = {
.name = "physmap-flash",
.id = 0,
- .dev = { .platform_data = &dns323_nor_flash_data, },
+ .dev = {
+ .platform_data = &dns323_nor_flash_data,
+ },
.resource = &dns323_nor_flash_resource,
.num_resources = 1,
};
@@ -170,7 +170,9 @@ static struct gpio_led_platform_data dns323_led_data = {
static struct platform_device dns323_gpio_leds = {
.name = "leds-gpio",
.id = -1,
- .dev = { .platform_data = &dns323_led_data, },
+ .dev = {
+ .platform_data = &dns323_led_data,
+ },
};
/****************************************************************************
@@ -183,35 +185,53 @@ static struct gpio_keys_button dns323_buttons[] = {
.gpio = DNS323_GPIO_KEY_RESET,
.desc = "Reset Button",
.active_low = 1,
- },
- {
+ }, {
.code = KEY_POWER,
.gpio = DNS323_GPIO_KEY_POWER,
.desc = "Power Button",
.active_low = 1,
- }
+ },
};
static struct gpio_keys_platform_data dns323_button_data = {
.buttons = dns323_buttons,
- .nbuttons = ARRAY_SIZE(dns323_buttons),
+ .nbuttons = ARRAY_SIZE(dns323_buttons),
};
static struct platform_device dns323_button_device = {
.name = "gpio-keys",
.id = -1,
.num_resources = 0,
- .dev = { .platform_data = &dns323_button_data, },
+ .dev = {
+ .platform_data = &dns323_button_data,
+ },
};
/****************************************************************************
* General Setup
*/
-
-static struct platform_device *dns323_plat_devices[] __initdata = {
- &dns323_nor_flash,
- &dns323_gpio_leds,
- &dns323_button_device,
+static struct orion5x_mpp_mode dns323_mpp_modes[] __initdata = {
+ { 0, MPP_PCIE_RST_OUTn },
+ { 1, MPP_GPIO }, /* right amber LED (sata ch0) */
+ { 2, MPP_GPIO }, /* left amber LED (sata ch1) */
+ { 3, MPP_UNUSED },
+ { 4, MPP_GPIO }, /* power button LED */
+ { 5, MPP_GPIO }, /* power button LED */
+ { 6, MPP_GPIO }, /* GMT G751-2f overtemp */
+ { 7, MPP_GPIO }, /* M41T80 nIRQ/OUT/SQW */
+ { 8, MPP_GPIO }, /* triggers power off */
+ { 9, MPP_GPIO }, /* power button switch */
+ { 10, MPP_GPIO }, /* reset button switch */
+ { 11, MPP_UNUSED },
+ { 12, MPP_UNUSED },
+ { 13, MPP_UNUSED },
+ { 14, MPP_UNUSED },
+ { 15, MPP_UNUSED },
+ { 16, MPP_UNUSED },
+ { 17, MPP_UNUSED },
+ { 18, MPP_UNUSED },
+ { 19, MPP_UNUSED },
+ { -1 },
};
/*
@@ -225,17 +245,11 @@ static struct platform_device *dns323_plat_devices[] __initdata = {
static struct i2c_board_info __initdata dns323_i2c_devices[] = {
{
I2C_BOARD_INFO("g760a", 0x3e),
- },
-#if 0
- /* this entry requires the new-style driver model lm75 driver,
- * for the meantime "insmod lm75.ko force_lm75=0,0x48" is needed */
- {
- I2C_BOARD_INFO("g751", 0x48),
- },
-#endif
- {
+ }, {
+ I2C_BOARD_INFO("lm75", 0x48),
+ }, {
I2C_BOARD_INFO("m41t80", 0x68),
- }
+ },
};
/* DNS-323 specific power off method */
@@ -250,62 +264,35 @@ static void __init dns323_init(void)
/* Setup basic Orion functions. Need to be called early. */
orion5x_init();
+ orion5x_mpp_conf(dns323_mpp_modes);
+ writel(0, MPP_DEV_CTRL); /* DEV_D[31:16] */
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_eth_init(&dns323_eth_data);
+ orion5x_i2c_init();
+ orion5x_uart0_init();
+
/* setup flash mapping
* CS3 holds a 8 MB Spansion S29GL064M90TFIR4
*/
orion5x_setup_dev_boot_win(DNS323_NOR_BOOT_BASE, DNS323_NOR_BOOT_SIZE);
+ platform_device_register(&dns323_nor_flash);
- /* DNS-323 has a Marvell 88X7042 SATA controller attached via PCIe
- *
- * Open a special address decode windows for the PCIe WA.
- */
- orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE,
- ORION5X_PCIE_WA_SIZE);
-
- /* set MPP to 0 as D-Link's 2.6.12.6 kernel did */
- orion5x_write(MPP_0_7_CTRL, 0);
- orion5x_write(MPP_8_15_CTRL, 0);
- orion5x_write(MPP_16_19_CTRL, 0);
- orion5x_write(MPP_DEV_CTRL, 0);
-
- /* Define used GPIO pins
-
- GPIO Map:
-
- | 0 | | PEX_RST_OUT (not controlled by GPIO)
- | 1 | Out | right amber LED (= sata ch0 LED) (low-active)
- | 2 | Out | left amber LED (= sata ch1 LED) (low-active)
- | 3 | Out | //unknown//
- | 4 | Out | power button LED (low-active, together with pin #5)
- | 5 | Out | power button LED (low-active, together with pin #4)
- | 6 | In | GMT G751-2f overtemp. shutdown signal (low-active)
- | 7 | In | M41T80 nIRQ/OUT/SQW signal
- | 8 | Out | triggers power off (high-active)
- | 9 | In | power button switch (low-active)
- | 10 | In | reset button switch (low-active)
- | 11 | Out | //unknown//
- | 12 | Out | //unknown//
- | 13 | Out | //unknown//
- | 14 | Out | //unknown//
- | 15 | Out | //unknown//
- */
- orion5x_gpio_set_valid_pins(0x07f6);
-
- /* register dns323 specific power-off method */
- if ((gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0)
- || (gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0))
- pr_err("DNS323: failed to setup power-off GPIO\n");
-
- pm_power_off = dns323_power_off;
+ platform_device_register(&dns323_gpio_leds);
- /* register flash and other platform devices */
- platform_add_devices(dns323_plat_devices,
- ARRAY_SIZE(dns323_plat_devices));
+ platform_device_register(&dns323_button_device);
i2c_register_board_info(0, dns323_i2c_devices,
ARRAY_SIZE(dns323_i2c_devices));
- orion5x_eth_init(&dns323_eth_data);
+ /* register dns323 specific power-off method */
+ if (gpio_request(DNS323_GPIO_POWER_OFF, "POWEROFF") != 0 ||
+ gpio_direction_output(DNS323_GPIO_POWER_OFF, 0) != 0)
+ pr_err("DNS323: failed to setup power-off GPIO\n");
+ pm_power_off = dns323_power_off;
}
/* Warning: D-Link uses a wrong mach-type (=526) in their bootloader */
diff --git a/arch/arm/mach-orion5x/edmini_v2-setup.c b/arch/arm/mach-orion5x/edmini_v2-setup.c
new file mode 100644
index 000000000000..b24ee0c2cd61
--- /dev/null
+++ b/arch/arm/mach-orion5x/edmini_v2-setup.c
@@ -0,0 +1,262 @@
+/*
+ * arch/arm/mach-orion5x/edmini_v2-setup.c
+ *
+ * LaCie Ethernet Disk mini V2 Setup
+ *
+ * Copyright (C) 2008 Christopher Moore <moore@free.fr>
+ * Copyright (C) 2008 Albert Aribaud <albert.aribaud@free.fr>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+/*
+ * TODO: add Orion USB device port init when kernel.org support is added.
+ * TODO: add flash write support: see below.
+ * TODO: add power-off support.
+ * TODO: add I2C EEPROM support.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * EDMINI_V2 Info
+ ****************************************************************************/
+
+/*
+ * 512KB NOR flash Device bus boot chip select
+ */
+
+#define EDMINI_V2_NOR_BOOT_BASE 0xfff80000
+#define EDMINI_V2_NOR_BOOT_SIZE SZ_512K
+
+/*****************************************************************************
+ * 512KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+/*
+ * Currently the MTD code does not recognize the MX29LV400CBCT as a bottom
+ * -type device. This could cause risks of accidentally erasing critical
+ * flash sectors. We thus define a single, write-protected partition covering
+ * the whole flash.
+ * TODO: once the flash part TOP/BOTTOM detection issue is sorted out in the MTD
+ * code, break this into at least three partitions: 'u-boot code', 'u-boot
+ * environment' and 'whatever is left'.
+ */
+
+static struct mtd_partition edmini_v2_partitions[] = {
+ {
+ .name = "Full512kb",
+ .size = 0x00080000,
+ .offset = 0x00000000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct physmap_flash_data edmini_v2_nor_flash_data = {
+ .width = 1,
+ .parts = edmini_v2_partitions,
+ .nr_parts = ARRAY_SIZE(edmini_v2_partitions),
+};
+
+static struct resource edmini_v2_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = EDMINI_V2_NOR_BOOT_BASE,
+ .end = EDMINI_V2_NOR_BOOT_BASE
+ + EDMINI_V2_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device edmini_v2_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &edmini_v2_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &edmini_v2_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data edmini_v2_eth_data = {
+ .phy_addr = 8,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+#define EDMINIV2_RTC_GPIO 3
+
+static struct i2c_board_info __initdata edmini_v2_i2c_rtc = {
+ I2C_BOARD_INFO("rs5c372a", 0x32),
+ .irq = 0,
+};
+
+/*****************************************************************************
+ * Sata
+ ****************************************************************************/
+
+static struct mv_sata_platform_data edmini_v2_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * GPIO LED (simple - doesn't use hardware blinking support)
+ ****************************************************************************/
+
+#define EDMINI_V2_GPIO_LED_POWER 16
+
+static struct gpio_led edmini_v2_leds[] = {
+ {
+ .name = "power:blue",
+ .gpio = EDMINI_V2_GPIO_LED_POWER,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data edmini_v2_led_data = {
+ .num_leds = ARRAY_SIZE(edmini_v2_leds),
+ .leds = edmini_v2_leds,
+};
+
+static struct platform_device edmini_v2_gpio_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &edmini_v2_led_data,
+ },
+};
+
+/****************************************************************************
+ * GPIO key
+ ****************************************************************************/
+
+#define EDMINI_V2_GPIO_KEY_POWER 18
+
+static struct gpio_keys_button edmini_v2_buttons[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = EDMINI_V2_GPIO_KEY_POWER,
+ .desc = "Power Button",
+ .active_low = 0,
+ },
+};
+
+static struct gpio_keys_platform_data edmini_v2_button_data = {
+ .buttons = edmini_v2_buttons,
+ .nbuttons = ARRAY_SIZE(edmini_v2_buttons),
+};
+
+static struct platform_device edmini_v2_gpio_buttons = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &edmini_v2_button_data,
+ },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static struct orion5x_mpp_mode edminiv2_mpp_modes[] __initdata = {
+ { 0, MPP_UNUSED },
+ { 1, MPP_UNUSED },
+ { 2, MPP_UNUSED },
+ { 3, MPP_GPIO }, /* RTC interrupt */
+ { 4, MPP_UNUSED },
+ { 5, MPP_UNUSED },
+ { 6, MPP_UNUSED },
+ { 7, MPP_UNUSED },
+ { 8, MPP_UNUSED },
+ { 9, MPP_UNUSED },
+ { 10, MPP_UNUSED },
+ { 11, MPP_UNUSED },
+ { 12, MPP_SATA_LED }, /* SATA 0 presence */
+ { 13, MPP_SATA_LED }, /* SATA 1 presence */
+ { 14, MPP_SATA_LED }, /* SATA 0 active */
+ { 15, MPP_SATA_LED }, /* SATA 1 active */
+ /* 16: Power LED control (0 = On, 1 = Off) */
+ { 16, MPP_GPIO },
+ /* 17: Power LED control select (0 = CPLD, 1 = GPIO16) */
+ { 17, MPP_GPIO },
+ /* 18: Power button status (0 = Released, 1 = Pressed) */
+ { 18, MPP_GPIO },
+ { 19, MPP_UNUSED },
+ { -1 }
+};
+
+static void __init edmini_v2_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(edminiv2_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_eth_init(&edmini_v2_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&edmini_v2_sata_data);
+ orion5x_uart0_init();
+
+ orion5x_setup_dev_boot_win(EDMINI_V2_NOR_BOOT_BASE,
+ EDMINI_V2_NOR_BOOT_SIZE);
+ platform_device_register(&edmini_v2_nor_flash);
+ platform_device_register(&edmini_v2_gpio_leds);
+ platform_device_register(&edmini_v2_gpio_buttons);
+
+ pr_notice("edmini_v2: USB device port, flash write and power-off "
+ "are not yet supported.\n");
+
+ /* Get RTC IRQ and register the chip */
+ if (gpio_request(EDMINIV2_RTC_GPIO, "rtc") == 0) {
+ if (gpio_direction_input(EDMINIV2_RTC_GPIO) == 0)
+ edmini_v2_i2c_rtc.irq = gpio_to_irq(EDMINIV2_RTC_GPIO);
+ else
+ gpio_free(EDMINIV2_RTC_GPIO);
+ }
+
+ if (edmini_v2_i2c_rtc.irq == 0)
+ pr_warning("edmini_v2: failed to get RTC IRQ\n");
+
+ i2c_register_board_info(0, &edmini_v2_i2c_rtc, 1);
+}
+
+/* Warning: LaCie use a wrong mach-type (0x20e=526) in their bootloader. */
+MACHINE_START(EDMINI_V2, "LaCie Ethernet Disk mini V2")
+ /* Maintainer: Christopher Moore <moore@free.fr> */
+ .phys_io = ORION5X_REGS_PHYS_BASE,
+ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .init_machine = edmini_v2_init,
+ .map_io = orion5x_map_io,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/gpio.c b/arch/arm/mach-orion5x/gpio.c
index 8108c316c426..fc419868e39f 100644
--- a/arch/arm/mach-orion5x/gpio.c
+++ b/arch/arm/mach-orion5x/gpio.c
@@ -15,18 +15,21 @@
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>
+#include <linux/io.h>
#include <asm/gpio.h>
-#include <asm/io.h>
-#include <asm/arch/orion5x.h>
+#include <mach/orion5x.h>
#include "common.h"
static DEFINE_SPINLOCK(gpio_lock);
static unsigned long gpio_valid[BITS_TO_LONGS(GPIO_MAX)];
static const char *gpio_label[GPIO_MAX]; /* non null for allocated GPIOs */
-void __init orion5x_gpio_set_valid_pins(u32 pins)
+void __init orion5x_gpio_set_valid(unsigned pin, int valid)
{
- gpio_valid[0] = pins;
+ if (valid)
+ __set_bit(pin, gpio_valid);
+ else
+ __clear_bit(pin, gpio_valid);
}
/*
@@ -93,10 +96,10 @@ int gpio_get_value(unsigned pin)
{
int val, mask = 1 << pin;
- if (orion5x_read(GPIO_IO_CONF) & mask)
- val = orion5x_read(GPIO_DATA_IN) ^ orion5x_read(GPIO_IN_POL);
+ if (readl(GPIO_IO_CONF) & mask)
+ val = readl(GPIO_DATA_IN) ^ readl(GPIO_IN_POL);
else
- val = orion5x_read(GPIO_OUT);
+ val = readl(GPIO_OUT);
return val & mask;
}
@@ -188,39 +191,39 @@ void gpio_display(void)
printk("GPIO, free\n");
} else {
printk("GPIO, used by %s, ", gpio_label[i]);
- if (orion5x_read(GPIO_IO_CONF) & (1 << i)) {
+ if (readl(GPIO_IO_CONF) & (1 << i)) {
printk("input, active %s, level %s, edge %s\n",
- ((orion5x_read(GPIO_IN_POL) >> i) & 1) ? "low" : "high",
- ((orion5x_read(GPIO_LEVEL_MASK) >> i) & 1) ? "enabled" : "masked",
- ((orion5x_read(GPIO_EDGE_MASK) >> i) & 1) ? "enabled" : "masked");
+ ((readl(GPIO_IN_POL) >> i) & 1) ? "low" : "high",
+ ((readl(GPIO_LEVEL_MASK) >> i) & 1) ? "enabled" : "masked",
+ ((readl(GPIO_EDGE_MASK) >> i) & 1) ? "enabled" : "masked");
} else {
- printk("output, val=%d\n", (orion5x_read(GPIO_OUT) >> i) & 1);
+ printk("output, val=%d\n", (readl(GPIO_OUT) >> i) & 1);
}
}
}
printk(KERN_DEBUG "MPP_0_7_CTRL (0x%08x) = 0x%08x\n",
- MPP_0_7_CTRL, orion5x_read(MPP_0_7_CTRL));
+ MPP_0_7_CTRL, readl(MPP_0_7_CTRL));
printk(KERN_DEBUG "MPP_8_15_CTRL (0x%08x) = 0x%08x\n",
- MPP_8_15_CTRL, orion5x_read(MPP_8_15_CTRL));
+ MPP_8_15_CTRL, readl(MPP_8_15_CTRL));
printk(KERN_DEBUG "MPP_16_19_CTRL (0x%08x) = 0x%08x\n",
- MPP_16_19_CTRL, orion5x_read(MPP_16_19_CTRL));
+ MPP_16_19_CTRL, readl(MPP_16_19_CTRL));
printk(KERN_DEBUG "MPP_DEV_CTRL (0x%08x) = 0x%08x\n",
- MPP_DEV_CTRL, orion5x_read(MPP_DEV_CTRL));
+ MPP_DEV_CTRL, readl(MPP_DEV_CTRL));
printk(KERN_DEBUG "GPIO_OUT (0x%08x) = 0x%08x\n",
- GPIO_OUT, orion5x_read(GPIO_OUT));
+ GPIO_OUT, readl(GPIO_OUT));
printk(KERN_DEBUG "GPIO_IO_CONF (0x%08x) = 0x%08x\n",
- GPIO_IO_CONF, orion5x_read(GPIO_IO_CONF));
+ GPIO_IO_CONF, readl(GPIO_IO_CONF));
printk(KERN_DEBUG "GPIO_BLINK_EN (0x%08x) = 0x%08x\n",
- GPIO_BLINK_EN, orion5x_read(GPIO_BLINK_EN));
+ GPIO_BLINK_EN, readl(GPIO_BLINK_EN));
printk(KERN_DEBUG "GPIO_IN_POL (0x%08x) = 0x%08x\n",
- GPIO_IN_POL, orion5x_read(GPIO_IN_POL));
+ GPIO_IN_POL, readl(GPIO_IN_POL));
printk(KERN_DEBUG "GPIO_DATA_IN (0x%08x) = 0x%08x\n",
- GPIO_DATA_IN, orion5x_read(GPIO_DATA_IN));
+ GPIO_DATA_IN, readl(GPIO_DATA_IN));
printk(KERN_DEBUG "GPIO_LEVEL_MASK (0x%08x) = 0x%08x\n",
- GPIO_LEVEL_MASK, orion5x_read(GPIO_LEVEL_MASK));
+ GPIO_LEVEL_MASK, readl(GPIO_LEVEL_MASK));
printk(KERN_DEBUG "GPIO_EDGE_CAUSE (0x%08x) = 0x%08x\n",
- GPIO_EDGE_CAUSE, orion5x_read(GPIO_EDGE_CAUSE));
+ GPIO_EDGE_CAUSE, readl(GPIO_EDGE_CAUSE));
printk(KERN_DEBUG "GPIO_EDGE_MASK (0x%08x) = 0x%08x\n",
- GPIO_EDGE_MASK, orion5x_read(GPIO_EDGE_MASK));
+ GPIO_EDGE_MASK, readl(GPIO_EDGE_MASK));
}
diff --git a/arch/arm/mach-orion5x/include/mach/debug-macro.S b/arch/arm/mach-orion5x/include/mach/debug-macro.S
new file mode 100644
index 000000000000..c7f808bfe272
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/debug-macro.S
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * 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 <mach/orion5x.h>
+
+ .macro addruart,rx
+ mrc p15, 0, \rx, c1, c0
+ tst \rx, #1 @ MMU enabled?
+ ldreq \rx, =ORION5X_REGS_PHYS_BASE
+ ldrne \rx, =ORION5X_REGS_VIRT_BASE
+ orr \rx, \rx, #0x00012000
+ .endm
+
+#define UART_SHIFT 2
+#include <asm/hardware/debug-8250.S>
diff --git a/arch/arm/mach-orion5x/include/mach/dma.h b/arch/arm/mach-orion5x/include/mach/dma.h
new file mode 100644
index 000000000000..40a8c178f10d
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/dma.h
@@ -0,0 +1 @@
+/* empty */
diff --git a/arch/arm/mach-orion5x/include/mach/entry-macro.S b/arch/arm/mach-orion5x/include/mach/entry-macro.S
new file mode 100644
index 000000000000..4351937035cd
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/entry-macro.S
@@ -0,0 +1,31 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/entry-macro.S
+ *
+ * Low-level IRQ helper macros for Orion platforms
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <mach/orion5x.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =MAIN_IRQ_CAUSE
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqstat, [\base, #0] @ main cause
+ ldr \tmp, [\base, #(MAIN_IRQ_MASK - MAIN_IRQ_CAUSE)] @ main mask
+ mov \irqnr, #0 @ default irqnr
+ @ find cause bits that are unmasked
+ ands \irqstat, \irqstat, \tmp @ clear Z flag if any
+ clzne \irqnr, \irqstat @ calc irqnr
+ rsbne \irqnr, \irqnr, #31
+ .endm
diff --git a/arch/arm/mach-orion5x/include/mach/gpio.h b/arch/arm/mach-orion5x/include/mach/gpio.h
new file mode 100644
index 000000000000..65dc136a86f7
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/gpio.h
@@ -0,0 +1,28 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/gpio.h
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+extern int gpio_request(unsigned pin, const char *label);
+extern void gpio_free(unsigned pin);
+extern int gpio_direction_input(unsigned pin);
+extern int gpio_direction_output(unsigned pin, int value);
+extern int gpio_get_value(unsigned pin);
+extern void gpio_set_value(unsigned pin, int value);
+extern void orion5x_gpio_set_blink(unsigned pin, int blink);
+extern void gpio_display(void); /* debug */
+
+static inline int gpio_to_irq(int pin)
+{
+ return pin + IRQ_ORION5X_GPIO_START;
+}
+
+static inline int irq_to_gpio(int irq)
+{
+ return irq - IRQ_ORION5X_GPIO_START;
+}
+
+#include <asm-generic/gpio.h> /* cansleep wrappers */
diff --git a/arch/arm/mach-orion5x/include/mach/hardware.h b/arch/arm/mach-orion5x/include/mach/hardware.h
new file mode 100644
index 000000000000..e51aaf4bf2b5
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/hardware.h
@@ -0,0 +1,21 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/hardware.h
+ *
+ * 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_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+#include "orion5x.h"
+
+#define pcibios_assign_all_busses() 1
+
+#define PCIBIOS_MIN_IO 0x00001000
+#define PCIBIOS_MIN_MEM 0x01000000
+#define PCIMEM_BASE ORION5X_PCIE_MEM_PHYS_BASE
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/include/mach/io.h b/arch/arm/mach-orion5x/include/mach/io.h
new file mode 100644
index 000000000000..f24b2513f7f3
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/io.h
@@ -0,0 +1,63 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/io.h
+ *
+ * Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IO_H
+#define __ASM_ARCH_IO_H
+
+#include "orion5x.h"
+
+#define IO_SPACE_LIMIT 0xffffffff
+
+static inline void __iomem *
+__arch_ioremap(unsigned long paddr, size_t size, unsigned int mtype)
+{
+ void __iomem *retval;
+ unsigned long offs = paddr - ORION5X_REGS_PHYS_BASE;
+ if (mtype == MT_DEVICE && size && offs < ORION5X_REGS_SIZE &&
+ size <= ORION5X_REGS_SIZE && offs + size <= ORION5X_REGS_SIZE) {
+ retval = (void __iomem *)ORION5X_REGS_VIRT_BASE + offs;
+ } else {
+ retval = __arm_ioremap(paddr, size, mtype);
+ }
+
+ return retval;
+}
+
+static inline void
+__arch_iounmap(void __iomem *addr)
+{
+ if (addr < (void __iomem *)ORION5X_REGS_VIRT_BASE ||
+ addr >= (void __iomem *)(ORION5X_REGS_VIRT_BASE + ORION5X_REGS_SIZE))
+ __iounmap(addr);
+}
+
+static inline void __iomem *__io(unsigned long addr)
+{
+ return (void __iomem *)addr;
+}
+
+#define __arch_ioremap(p, s, m) __arch_ioremap(p, s, m)
+#define __arch_iounmap(a) __arch_iounmap(a)
+#define __io(a) __io(a)
+#define __mem_pci(a) (a)
+
+
+/*****************************************************************************
+ * Helpers to access Orion registers
+ ****************************************************************************/
+/*
+ * These are not preempt-safe. Locks, if needed, must be taken
+ * care of by the caller.
+ */
+#define orion5x_setbits(r, mask) writel(readl(r) | (mask), (r))
+#define orion5x_clrbits(r, mask) writel(readl(r) & ~(mask), (r))
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/include/mach/irqs.h b/arch/arm/mach-orion5x/include/mach/irqs.h
new file mode 100644
index 000000000000..d5b0fbf6b965
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/irqs.h
@@ -0,0 +1,62 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/irqs.h
+ *
+ * IRQ definitions for Orion SoC
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_IRQS_H
+#define __ASM_ARCH_IRQS_H
+
+#include "orion5x.h" /* need GPIO_MAX */
+
+/*
+ * Orion Main Interrupt Controller
+ */
+#define IRQ_ORION5X_BRIDGE 0
+#define IRQ_ORION5X_DOORBELL_H2C 1
+#define IRQ_ORION5X_DOORBELL_C2H 2
+#define IRQ_ORION5X_UART0 3
+#define IRQ_ORION5X_UART1 4
+#define IRQ_ORION5X_I2C 5
+#define IRQ_ORION5X_GPIO_0_7 6
+#define IRQ_ORION5X_GPIO_8_15 7
+#define IRQ_ORION5X_GPIO_16_23 8
+#define IRQ_ORION5X_GPIO_24_31 9
+#define IRQ_ORION5X_PCIE0_ERR 10
+#define IRQ_ORION5X_PCIE0_INT 11
+#define IRQ_ORION5X_USB1_CTRL 12
+#define IRQ_ORION5X_DEV_BUS_ERR 14
+#define IRQ_ORION5X_PCI_ERR 15
+#define IRQ_ORION5X_USB_BR_ERR 16
+#define IRQ_ORION5X_USB0_CTRL 17
+#define IRQ_ORION5X_ETH_RX 18
+#define IRQ_ORION5X_ETH_TX 19
+#define IRQ_ORION5X_ETH_MISC 20
+#define IRQ_ORION5X_ETH_SUM 21
+#define IRQ_ORION5X_ETH_ERR 22
+#define IRQ_ORION5X_IDMA_ERR 23
+#define IRQ_ORION5X_IDMA_0 24
+#define IRQ_ORION5X_IDMA_1 25
+#define IRQ_ORION5X_IDMA_2 26
+#define IRQ_ORION5X_IDMA_3 27
+#define IRQ_ORION5X_CESA 28
+#define IRQ_ORION5X_SATA 29
+#define IRQ_ORION5X_XOR0 30
+#define IRQ_ORION5X_XOR1 31
+
+/*
+ * Orion General Purpose Pins
+ */
+#define IRQ_ORION5X_GPIO_START 32
+#define NR_GPIO_IRQS GPIO_MAX
+
+#define NR_IRQS (IRQ_ORION5X_GPIO_START + NR_GPIO_IRQS)
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/include/mach/memory.h b/arch/arm/mach-orion5x/include/mach/memory.h
new file mode 100644
index 000000000000..54dd76b013f2
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/memory.h
@@ -0,0 +1,16 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/memory.h
+ *
+ * Marvell Orion memory definitions
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#define PHYS_OFFSET UL(0x00000000)
+
+#define __virt_to_bus(x) __virt_to_phys(x)
+#define __bus_to_virt(x) __phys_to_virt(x)
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/include/mach/orion5x.h b/arch/arm/mach-orion5x/include/mach/orion5x.h
new file mode 100644
index 000000000000..9f5ce1ce5840
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/orion5x.h
@@ -0,0 +1,173 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/orion5x.h
+ *
+ * Generic definitions of Orion SoC flavors:
+ * Orion-1, Orion-VoIP, Orion-NAS, Orion-2, and Orion-1-90.
+ *
+ * Maintainer: Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_ORION5X_H
+#define __ASM_ARCH_ORION5X_H
+
+/*****************************************************************************
+ * Orion Address Maps
+ *
+ * phys
+ * e0000000 PCIe MEM space
+ * e8000000 PCI MEM space
+ * f0000000 PCIe WA space (Orion-1/Orion-NAS only)
+ * f1000000 on-chip peripheral registers
+ * f2000000 PCIe I/O space
+ * f2100000 PCI I/O space
+ * f4000000 device bus mappings (boot)
+ * fa000000 device bus mappings (cs0)
+ * fa800000 device bus mappings (cs2)
+ * fc000000 device bus mappings (cs0/cs1)
+ *
+ * virt phys size
+ * fdd00000 f1000000 1M on-chip peripheral registers
+ * fde00000 f2000000 1M PCIe I/O space
+ * fdf00000 f2100000 1M PCI I/O space
+ * fe000000 f0000000 16M PCIe WA space (Orion-1/Orion-NAS only)
+ ****************************************************************************/
+#define ORION5X_REGS_PHYS_BASE 0xf1000000
+#define ORION5X_REGS_VIRT_BASE 0xfdd00000
+#define ORION5X_REGS_SIZE SZ_1M
+
+#define ORION5X_PCIE_IO_PHYS_BASE 0xf2000000
+#define ORION5X_PCIE_IO_VIRT_BASE 0xfde00000
+#define ORION5X_PCIE_IO_BUS_BASE 0x00000000
+#define ORION5X_PCIE_IO_SIZE SZ_1M
+
+#define ORION5X_PCI_IO_PHYS_BASE 0xf2100000
+#define ORION5X_PCI_IO_VIRT_BASE 0xfdf00000
+#define ORION5X_PCI_IO_BUS_BASE 0x00100000
+#define ORION5X_PCI_IO_SIZE SZ_1M
+
+/* Relevant only for Orion-1/Orion-NAS */
+#define ORION5X_PCIE_WA_PHYS_BASE 0xf0000000
+#define ORION5X_PCIE_WA_VIRT_BASE 0xfe000000
+#define ORION5X_PCIE_WA_SIZE SZ_16M
+
+#define ORION5X_PCIE_MEM_PHYS_BASE 0xe0000000
+#define ORION5X_PCIE_MEM_SIZE SZ_128M
+
+#define ORION5X_PCI_MEM_PHYS_BASE 0xe8000000
+#define ORION5X_PCI_MEM_SIZE SZ_128M
+
+/*******************************************************************************
+ * Supported Devices & Revisions
+ ******************************************************************************/
+/* Orion-1 (88F5181) and Orion-VoIP (88F5181L) */
+#define MV88F5181_DEV_ID 0x5181
+#define MV88F5181_REV_B1 3
+#define MV88F5181L_REV_A0 8
+#define MV88F5181L_REV_A1 9
+/* Orion-NAS (88F5182) */
+#define MV88F5182_DEV_ID 0x5182
+#define MV88F5182_REV_A2 2
+/* Orion-2 (88F5281) */
+#define MV88F5281_DEV_ID 0x5281
+#define MV88F5281_REV_D0 4
+#define MV88F5281_REV_D1 5
+#define MV88F5281_REV_D2 6
+/* Orion-1-90 (88F6183) */
+#define MV88F6183_DEV_ID 0x6183
+#define MV88F6183_REV_B0 3
+
+/*******************************************************************************
+ * Orion Registers Map
+ ******************************************************************************/
+#define ORION5X_DDR_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x00000)
+#define ORION5X_DDR_REG(x) (ORION5X_DDR_VIRT_BASE | (x))
+
+#define ORION5X_DEV_BUS_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x10000)
+#define ORION5X_DEV_BUS_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x10000)
+#define ORION5X_DEV_BUS_REG(x) (ORION5X_DEV_BUS_VIRT_BASE | (x))
+#define SPI_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x0600)
+#define I2C_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x1000)
+#define UART0_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x2000)
+#define UART0_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE | 0x2000)
+#define UART1_PHYS_BASE (ORION5X_DEV_BUS_PHYS_BASE | 0x2100)
+#define UART1_VIRT_BASE (ORION5X_DEV_BUS_VIRT_BASE | 0x2100)
+
+#define ORION5X_BRIDGE_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x20000)
+#define ORION5X_BRIDGE_REG(x) (ORION5X_BRIDGE_VIRT_BASE | (x))
+#define TIMER_VIRT_BASE (ORION5X_BRIDGE_VIRT_BASE | 0x300)
+
+#define ORION5X_PCI_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x30000)
+#define ORION5X_PCI_REG(x) (ORION5X_PCI_VIRT_BASE | (x))
+
+#define ORION5X_PCIE_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x40000)
+#define ORION5X_PCIE_REG(x) (ORION5X_PCIE_VIRT_BASE | (x))
+
+#define ORION5X_USB0_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x50000)
+#define ORION5X_USB0_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x50000)
+#define ORION5X_USB0_REG(x) (ORION5X_USB0_VIRT_BASE | (x))
+
+#define ORION5X_XOR_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x60900)
+#define ORION5X_XOR_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x60900)
+#define ORION5X_XOR_REG(x) (ORION5X_XOR_VIRT_BASE | (x))
+
+#define ORION5X_ETH_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x70000)
+#define ORION5X_ETH_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x70000)
+#define ORION5X_ETH_REG(x) (ORION5X_ETH_VIRT_BASE | (x))
+
+#define ORION5X_SATA_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0x80000)
+#define ORION5X_SATA_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0x80000)
+#define ORION5X_SATA_REG(x) (ORION5X_SATA_VIRT_BASE | (x))
+
+#define ORION5X_USB1_PHYS_BASE (ORION5X_REGS_PHYS_BASE | 0xa0000)
+#define ORION5X_USB1_VIRT_BASE (ORION5X_REGS_VIRT_BASE | 0xa0000)
+#define ORION5X_USB1_REG(x) (ORION5X_USB1_VIRT_BASE | (x))
+
+/*******************************************************************************
+ * Device Bus Registers
+ ******************************************************************************/
+#define MPP_0_7_CTRL ORION5X_DEV_BUS_REG(0x000)
+#define MPP_8_15_CTRL ORION5X_DEV_BUS_REG(0x004)
+#define MPP_16_19_CTRL ORION5X_DEV_BUS_REG(0x050)
+#define MPP_DEV_CTRL ORION5X_DEV_BUS_REG(0x008)
+#define MPP_RESET_SAMPLE ORION5X_DEV_BUS_REG(0x010)
+#define GPIO_OUT ORION5X_DEV_BUS_REG(0x100)
+#define GPIO_IO_CONF ORION5X_DEV_BUS_REG(0x104)
+#define GPIO_BLINK_EN ORION5X_DEV_BUS_REG(0x108)
+#define GPIO_IN_POL ORION5X_DEV_BUS_REG(0x10c)
+#define GPIO_DATA_IN ORION5X_DEV_BUS_REG(0x110)
+#define GPIO_EDGE_CAUSE ORION5X_DEV_BUS_REG(0x114)
+#define GPIO_EDGE_MASK ORION5X_DEV_BUS_REG(0x118)
+#define GPIO_LEVEL_MASK ORION5X_DEV_BUS_REG(0x11c)
+#define DEV_BANK_0_PARAM ORION5X_DEV_BUS_REG(0x45c)
+#define DEV_BANK_1_PARAM ORION5X_DEV_BUS_REG(0x460)
+#define DEV_BANK_2_PARAM ORION5X_DEV_BUS_REG(0x464)
+#define DEV_BANK_BOOT_PARAM ORION5X_DEV_BUS_REG(0x46c)
+#define DEV_BUS_CTRL ORION5X_DEV_BUS_REG(0x4c0)
+#define DEV_BUS_INT_CAUSE ORION5X_DEV_BUS_REG(0x4d0)
+#define DEV_BUS_INT_MASK ORION5X_DEV_BUS_REG(0x4d4)
+#define GPIO_MAX 32
+
+/***************************************************************************
+ * Orion CPU Bridge Registers
+ **************************************************************************/
+#define CPU_CONF ORION5X_BRIDGE_REG(0x100)
+#define CPU_CTRL ORION5X_BRIDGE_REG(0x104)
+#define CPU_RESET_MASK ORION5X_BRIDGE_REG(0x108)
+#define WDT_RESET 0x0002
+#define CPU_SOFT_RESET ORION5X_BRIDGE_REG(0x10c)
+#define POWER_MNG_CTRL_REG ORION5X_BRIDGE_REG(0x11C)
+#define BRIDGE_CAUSE ORION5X_BRIDGE_REG(0x110)
+#define WDT_INT_REQ 0x0008
+#define BRIDGE_MASK ORION5X_BRIDGE_REG(0x114)
+#define BRIDGE_INT_TIMER0 0x0002
+#define BRIDGE_INT_TIMER1 0x0004
+#define BRIDGE_INT_TIMER1_CLR (~0x0004)
+#define MAIN_IRQ_CAUSE ORION5X_BRIDGE_REG(0x200)
+#define MAIN_IRQ_MASK ORION5X_BRIDGE_REG(0x204)
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/include/mach/system.h b/arch/arm/mach-orion5x/include/mach/system.h
new file mode 100644
index 000000000000..08e430757890
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/system.h
@@ -0,0 +1,32 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/system.h
+ *
+ * Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#ifndef __ASM_ARCH_SYSTEM_H
+#define __ASM_ARCH_SYSTEM_H
+
+#include <mach/hardware.h>
+#include <mach/orion5x.h>
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+static inline void arch_reset(char mode)
+{
+ /*
+ * Enable and issue soft reset
+ */
+ orion5x_setbits(CPU_RESET_MASK, (1 << 2));
+ orion5x_setbits(CPU_SOFT_RESET, 1);
+}
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/include/mach/timex.h b/arch/arm/mach-orion5x/include/mach/timex.h
new file mode 100644
index 000000000000..4c69820e0810
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/timex.h
@@ -0,0 +1,11 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/timex.h
+ *
+ * Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#define CLOCK_TICK_RATE (100 * HZ)
diff --git a/arch/arm/mach-orion5x/include/mach/uncompress.h b/arch/arm/mach-orion5x/include/mach/uncompress.h
new file mode 100644
index 000000000000..4322dba468a4
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/uncompress.h
@@ -0,0 +1,49 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/uncompress.h
+ *
+ * Tzachi Perelstein <tzachi@marvell.com>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/serial_reg.h>
+#include <mach/orion5x.h>
+
+#define SERIAL_BASE ((unsigned char *)UART0_PHYS_BASE)
+
+static void putc(const char c)
+{
+ unsigned char *base = SERIAL_BASE;
+ int i;
+
+ for (i = 0; i < 0x1000; i++) {
+ if (base[UART_LSR << 2] & UART_LSR_THRE)
+ break;
+ barrier();
+ }
+
+ base[UART_TX << 2] = c;
+}
+
+static void flush(void)
+{
+ unsigned char *base = SERIAL_BASE;
+ unsigned char mask;
+ int i;
+
+ mask = UART_LSR_TEMT | UART_LSR_THRE;
+
+ for (i = 0; i < 0x1000; i++) {
+ if ((base[UART_LSR << 2] & mask) == mask)
+ break;
+ barrier();
+ }
+}
+
+/*
+ * nothing to do
+ */
+#define arch_decomp_setup()
+#define arch_decomp_wdog()
diff --git a/arch/arm/mach-orion5x/include/mach/vmalloc.h b/arch/arm/mach-orion5x/include/mach/vmalloc.h
new file mode 100644
index 000000000000..7147a297e97f
--- /dev/null
+++ b/arch/arm/mach-orion5x/include/mach/vmalloc.h
@@ -0,0 +1,5 @@
+/*
+ * arch/arm/mach-orion5x/include/mach/vmalloc.h
+ */
+
+#define VMALLOC_END 0xfd800000
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c
index dd21f38c5d37..632a36f5cf14 100644
--- a/arch/arm/mach-orion5x/irq.c
+++ b/arch/arm/mach-orion5x/irq.c
@@ -13,10 +13,10 @@
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/io.h>
#include <asm/gpio.h>
-#include <asm/io.h>
-#include <asm/arch/orion5x.h>
-#include <asm/plat-orion/irq.h>
+#include <mach/orion5x.h>
+#include <plat/irq.h>
#include "common.h"
/*****************************************************************************
@@ -82,7 +82,7 @@ static int orion5x_gpio_set_irq_type(u32 irq, u32 type)
int pin = irq_to_gpio(irq);
struct irq_desc *desc;
- if ((orion5x_read(GPIO_IO_CONF) & (1 << pin)) == 0) {
+ if ((readl(GPIO_IO_CONF) & (1 << pin)) == 0) {
printk(KERN_ERR "orion5x_gpio_set_irq_type failed "
"(irq %d, pin %d).\n", irq, pin);
return -EINVAL;
@@ -91,33 +91,33 @@ static int orion5x_gpio_set_irq_type(u32 irq, u32 type)
desc = irq_desc + irq;
switch (type) {
- case IRQT_HIGH:
+ case IRQ_TYPE_LEVEL_HIGH:
desc->handle_irq = handle_level_irq;
desc->status |= IRQ_LEVEL;
orion5x_clrbits(GPIO_IN_POL, (1 << pin));
break;
- case IRQT_LOW:
+ case IRQ_TYPE_LEVEL_LOW:
desc->handle_irq = handle_level_irq;
desc->status |= IRQ_LEVEL;
orion5x_setbits(GPIO_IN_POL, (1 << pin));
break;
- case IRQT_RISING:
+ case IRQ_TYPE_EDGE_RISING:
desc->handle_irq = handle_edge_irq;
desc->status &= ~IRQ_LEVEL;
orion5x_clrbits(GPIO_IN_POL, (1 << pin));
break;
- case IRQT_FALLING:
+ case IRQ_TYPE_EDGE_FALLING:
desc->handle_irq = handle_edge_irq;
desc->status &= ~IRQ_LEVEL;
orion5x_setbits(GPIO_IN_POL, (1 << pin));
break;
- case IRQT_BOTHEDGE:
+ case IRQ_TYPE_EDGE_BOTH:
desc->handle_irq = handle_edge_irq;
desc->status &= ~IRQ_LEVEL;
/*
* set initial polarity based on current input level
*/
- if ((orion5x_read(GPIO_IN_POL) ^ orion5x_read(GPIO_DATA_IN))
+ if ((readl(GPIO_IN_POL) ^ readl(GPIO_DATA_IN))
& (1 << pin))
orion5x_setbits(GPIO_IN_POL, (1 << pin)); /* falling */
else
@@ -149,20 +149,20 @@ static void orion5x_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31);
offs = (irq - IRQ_ORION5X_GPIO_0_7) * 8;
- cause = (orion5x_read(GPIO_DATA_IN) & orion5x_read(GPIO_LEVEL_MASK)) |
- (orion5x_read(GPIO_EDGE_CAUSE) & orion5x_read(GPIO_EDGE_MASK));
+ cause = (readl(GPIO_DATA_IN) & readl(GPIO_LEVEL_MASK)) |
+ (readl(GPIO_EDGE_CAUSE) & readl(GPIO_EDGE_MASK));
for (pin = offs; pin < offs + 8; pin++) {
if (cause & (1 << pin)) {
irq = gpio_to_irq(pin);
desc = irq_desc + irq;
- if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQT_BOTHEDGE) {
+ if ((desc->status & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) {
/* Swap polarity (race with GPIO line) */
- u32 polarity = orion5x_read(GPIO_IN_POL);
+ u32 polarity = readl(GPIO_IN_POL);
polarity ^= 1 << pin;
- orion5x_write(GPIO_IN_POL, polarity);
+ writel(polarity, GPIO_IN_POL);
}
- desc_handle_irq(irq, desc);
+ generic_handle_irq(irq);
}
}
}
@@ -175,9 +175,9 @@ static void __init orion5x_init_gpio_irq(void)
/*
* Mask and clear GPIO IRQ interrupts
*/
- orion5x_write(GPIO_LEVEL_MASK, 0x0);
- orion5x_write(GPIO_EDGE_MASK, 0x0);
- orion5x_write(GPIO_EDGE_CAUSE, 0x0);
+ writel(0x0, GPIO_LEVEL_MASK);
+ writel(0x0, GPIO_EDGE_MASK);
+ writel(0x0, GPIO_EDGE_CAUSE);
/*
* Register chained level handlers for GPIO IRQs by default.
diff --git a/arch/arm/mach-orion5x/kurobox_pro-setup.c b/arch/arm/mach-orion5x/kurobox_pro-setup.c
index f5074b877b7f..dfbb68df7b09 100644
--- a/arch/arm/mach-orion5x/kurobox_pro-setup.c
+++ b/arch/arm/mach-orion5x/kurobox_pro-setup.c
@@ -13,18 +13,21 @@
#include <linux/platform_device.h>
#include <linux/pci.h>
#include <linux/irq.h>
+#include <linux/delay.h>
#include <linux/mtd/physmap.h>
#include <linux/mtd/nand.h>
#include <linux/mv643xx_eth.h>
#include <linux/i2c.h>
+#include <linux/serial_reg.h>
#include <linux/ata_platform.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
-#include <asm/arch/orion5x.h>
-#include <asm/plat-orion/orion_nand.h>
+#include <mach/orion5x.h>
+#include <plat/orion_nand.h>
#include "common.h"
+#include "mpp.h"
/*****************************************************************************
* KUROBOX-PRO Info
@@ -53,13 +56,11 @@ static struct mtd_partition kurobox_pro_nand_parts[] = {
.name = "uImage",
.offset = 0,
.size = SZ_4M,
- },
- {
+ }, {
.name = "rootfs",
.offset = SZ_4M,
.size = SZ_64M,
- },
- {
+ }, {
.name = "extra",
.offset = SZ_4M + SZ_64M,
.size = SZ_256M - (SZ_4M + SZ_64M),
@@ -132,8 +133,6 @@ static int __init kurobox_pro_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
/*
* PCI isn't used on the Kuro
*/
- printk(KERN_ERR "kurobox_pro_pci_map_irq failed, unknown bus\n");
-
return -1;
}
@@ -147,8 +146,10 @@ static struct hw_pci kurobox_pro_pci __initdata = {
static int __init kurobox_pro_pci_init(void)
{
- if (machine_is_kurobox_pro())
+ if (machine_is_kurobox_pro()) {
+ orion5x_pci_disable();
pci_common_init(&kurobox_pro_pci);
+ }
return 0;
}
@@ -160,8 +161,7 @@ subsys_initcall(kurobox_pro_pci_init);
****************************************************************************/
static struct mv643xx_eth_platform_data kurobox_pro_eth_data = {
- .phy_addr = 8,
- .force_phy_addr = 1,
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
};
/*****************************************************************************
@@ -175,12 +175,169 @@ static struct i2c_board_info __initdata kurobox_pro_i2c_rtc = {
* SATA
****************************************************************************/
static struct mv_sata_platform_data kurobox_pro_sata_data = {
- .n_ports = 2,
+ .n_ports = 2,
};
/*****************************************************************************
+ * Kurobox Pro specific power off method via UART1-attached microcontroller
+ ****************************************************************************/
+
+#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
+
+static int kurobox_pro_miconread(unsigned char *buf, int count)
+{
+ int i;
+ int timeout;
+
+ for (i = 0; i < count; i++) {
+ timeout = 10;
+
+ while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) {
+ if (--timeout == 0)
+ break;
+ udelay(1000);
+ }
+
+ if (timeout == 0)
+ break;
+ buf[i] = readl(UART1_REG(RX));
+ }
+
+ /* return read bytes */
+ return i;
+}
+
+static int kurobox_pro_miconwrite(const unsigned char *buf, int count)
+{
+ int i = 0;
+
+ while (count--) {
+ while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE))
+ barrier();
+ writel(buf[i++], UART1_REG(TX));
+ }
+
+ return 0;
+}
+
+static int kurobox_pro_miconsend(const unsigned char *data, int count)
+{
+ int i;
+ unsigned char checksum = 0;
+ unsigned char recv_buf[40];
+ unsigned char send_buf[40];
+ unsigned char correct_ack[3];
+ int retry = 2;
+
+ /* Generate checksum */
+ for (i = 0; i < count; i++)
+ checksum -= data[i];
+
+ do {
+ /* Send data */
+ kurobox_pro_miconwrite(data, count);
+
+ /* send checksum */
+ kurobox_pro_miconwrite(&checksum, 1);
+
+ if (kurobox_pro_miconread(recv_buf, sizeof(recv_buf)) <= 3) {
+ printk(KERN_ERR ">%s: receive failed.\n", __func__);
+
+ /* send preamble to clear the receive buffer */
+ memset(&send_buf, 0xff, sizeof(send_buf));
+ kurobox_pro_miconwrite(send_buf, sizeof(send_buf));
+
+ /* make dummy reads */
+ mdelay(100);
+ kurobox_pro_miconread(recv_buf, sizeof(recv_buf));
+ } else {
+ /* Generate expected ack */
+ correct_ack[0] = 0x01;
+ correct_ack[1] = data[1];
+ correct_ack[2] = 0x00;
+
+ /* checksum Check */
+ if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +
+ recv_buf[3]) & 0xFF) {
+ printk(KERN_ERR ">%s: Checksum Error : "
+ "Received data[%02x, %02x, %02x, %02x]"
+ "\n", __func__, recv_buf[0],
+ recv_buf[1], recv_buf[2], recv_buf[3]);
+ } else {
+ /* Check Received Data */
+ if (correct_ack[0] == recv_buf[0] &&
+ correct_ack[1] == recv_buf[1] &&
+ correct_ack[2] == recv_buf[2]) {
+ /* Interval for next command */
+ mdelay(10);
+
+ /* Receive ACK */
+ return 0;
+ }
+ }
+ /* Received NAK or illegal Data */
+ printk(KERN_ERR ">%s: Error : NAK or Illegal Data "
+ "Received\n", __func__);
+ }
+ } while (retry--);
+
+ /* Interval for next command */
+ mdelay(10);
+
+ return -1;
+}
+
+static void kurobox_pro_power_off(void)
+{
+ const unsigned char watchdogkill[] = {0x01, 0x35, 0x00};
+ const unsigned char shutdownwait[] = {0x00, 0x0c};
+ const unsigned char poweroff[] = {0x00, 0x06};
+ /* 38400 baud divisor */
+ const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));
+
+ pr_info("%s: triggering power-off...\n", __func__);
+
+ /* hijack uart1 and reset into sane state (38400,8n1,even parity) */
+ writel(0x83, UART1_REG(LCR));
+ writel(divisor & 0xff, UART1_REG(DLL));
+ writel((divisor >> 8) & 0xff, UART1_REG(DLM));
+ writel(0x1b, UART1_REG(LCR));
+ writel(0x00, UART1_REG(IER));
+ writel(0x07, UART1_REG(FCR));
+ writel(0x00, UART1_REG(MCR));
+
+ /* Send the commands to shutdown the Kurobox Pro */
+ kurobox_pro_miconsend(watchdogkill, sizeof(watchdogkill)) ;
+ kurobox_pro_miconsend(shutdownwait, sizeof(shutdownwait)) ;
+ kurobox_pro_miconsend(poweroff, sizeof(poweroff));
+}
+
+/*****************************************************************************
* General Setup
****************************************************************************/
+static struct orion5x_mpp_mode kurobox_pro_mpp_modes[] __initdata = {
+ { 0, MPP_UNUSED },
+ { 1, MPP_UNUSED },
+ { 2, MPP_GPIO }, /* GPIO Micon */
+ { 3, MPP_GPIO }, /* GPIO Rtc */
+ { 4, MPP_UNUSED },
+ { 5, MPP_UNUSED },
+ { 6, MPP_NAND }, /* NAND Flash REn */
+ { 7, MPP_NAND }, /* NAND Flash WEn */
+ { 8, MPP_UNUSED },
+ { 9, MPP_UNUSED },
+ { 10, MPP_UNUSED },
+ { 11, MPP_UNUSED },
+ { 12, MPP_SATA_LED }, /* SATA 0 presence */
+ { 13, MPP_SATA_LED }, /* SATA 1 presence */
+ { 14, MPP_SATA_LED }, /* SATA 0 active */
+ { 15, MPP_SATA_LED }, /* SATA 1 active */
+ { 16, MPP_UART }, /* UART1 RXD */
+ { 17, MPP_UART }, /* UART1 TXD */
+ { 18, MPP_UART }, /* UART1 CTSn */
+ { 19, MPP_UART }, /* UART1 RTSn */
+ { -1 },
+};
static void __init kurobox_pro_init(void)
{
@@ -189,46 +346,34 @@ static void __init kurobox_pro_init(void)
*/
orion5x_init();
- /*
- * Setup the CPU address decode windows for our devices
- */
- orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE,
- KUROBOX_PRO_NOR_BOOT_SIZE);
- orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE, KUROBOX_PRO_NAND_SIZE);
+ orion5x_mpp_conf(kurobox_pro_mpp_modes);
/*
- * Open a special address decode windows for the PCIe WA.
+ * Configure peripherals.
*/
- orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE,
- ORION5X_PCIE_WA_SIZE);
-
- /*
- * Setup Multiplexing Pins --
- * MPP[0-1] Not used
- * MPP[2] GPIO Micon
- * MPP[3] GPIO RTC
- * MPP[4-5] Not used
- * MPP[6] Nand Flash REn
- * MPP[7] Nand Flash WEn
- * MPP[8-11] Not used
- * MPP[12] SATA 0 presence Indication
- * MPP[13] SATA 1 presence Indication
- * MPP[14] SATA 0 active Indication
- * MPP[15] SATA 1 active indication
- * MPP[16-19] Not used
- */
- orion5x_write(MPP_0_7_CTRL, 0x44220003);
- orion5x_write(MPP_8_15_CTRL, 0x55550000);
- orion5x_write(MPP_16_19_CTRL, 0x0);
-
- orion5x_gpio_set_valid_pins(0x0000000c);
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&kurobox_pro_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&kurobox_pro_sata_data);
+ orion5x_uart0_init();
+ orion5x_uart1_init();
+ orion5x_xor_init();
+ orion5x_setup_dev_boot_win(KUROBOX_PRO_NOR_BOOT_BASE,
+ KUROBOX_PRO_NOR_BOOT_SIZE);
platform_device_register(&kurobox_pro_nor_flash);
- if (machine_is_kurobox_pro())
+
+ if (machine_is_kurobox_pro()) {
+ orion5x_setup_dev0_win(KUROBOX_PRO_NAND_BASE,
+ KUROBOX_PRO_NAND_SIZE);
platform_device_register(&kurobox_pro_nand_flash);
+ }
+
i2c_register_board_info(0, &kurobox_pro_i2c_rtc, 1);
- orion5x_eth_init(&kurobox_pro_eth_data);
- orion5x_sata_init(&kurobox_pro_sata_data);
+
+ /* register Kurobox Pro specific power-off method */
+ pm_power_off = kurobox_pro_power_off;
}
#ifdef CONFIG_MACH_KUROBOX_PRO
diff --git a/arch/arm/mach-orion5x/lsmini-setup.c b/arch/arm/mach-orion5x/lsmini-setup.c
new file mode 100644
index 000000000000..e0c43b8beb72
--- /dev/null
+++ b/arch/arm/mach-orion5x/lsmini-setup.c
@@ -0,0 +1,279 @@
+/*
+ * arch/arm/mach-orion5x/lsmini-setup.c
+ *
+ * Maintainer: Alexey Kopytko <alexey@kopytko.ru>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <asm/mach-types.h>
+#include <linux/gpio.h>
+#include <asm/mach/arch.h>
+#include "common.h"
+#include "mpp.h"
+#include "include/mach/system.h"
+
+/*****************************************************************************
+ * Linkstation Mini Info
+ ****************************************************************************/
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define LSMINI_NOR_BOOT_BASE 0xf4000000
+#define LSMINI_NOR_BOOT_SIZE SZ_256K
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data lsmini_nor_flash_data = {
+ .width = 1,
+};
+
+static struct resource lsmini_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = LSMINI_NOR_BOOT_BASE,
+ .end = LSMINI_NOR_BOOT_BASE + LSMINI_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device lsmini_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &lsmini_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &lsmini_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data lsmini_eth_data = {
+ .phy_addr = 8,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+static struct i2c_board_info __initdata lsmini_i2c_rtc = {
+ I2C_BOARD_INFO("rs5c372a", 0x32),
+};
+
+/*****************************************************************************
+ * LEDs attached to GPIO
+ ****************************************************************************/
+
+#define LSMINI_GPIO_LED_ALARM 2
+#define LSMINI_GPIO_LED_INFO 3
+#define LSMINI_GPIO_LED_FUNC 9
+#define LSMINI_GPIO_LED_PWR 14
+
+static struct gpio_led lsmini_led_pins[] = {
+ {
+ .name = "alarm:red",
+ .gpio = LSMINI_GPIO_LED_ALARM,
+ .active_low = 1,
+ }, {
+ .name = "info:amber",
+ .gpio = LSMINI_GPIO_LED_INFO,
+ .active_low = 1,
+ }, {
+ .name = "func:blue:top",
+ .gpio = LSMINI_GPIO_LED_FUNC,
+ .active_low = 1,
+ }, {
+ .name = "power:blue:bottom",
+ .gpio = LSMINI_GPIO_LED_PWR,
+ },
+};
+
+static struct gpio_led_platform_data lsmini_led_data = {
+ .leds = lsmini_led_pins,
+ .num_leds = ARRAY_SIZE(lsmini_led_pins),
+};
+
+static struct platform_device lsmini_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &lsmini_led_data,
+ },
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ ****************************************************************************/
+
+#define LSMINI_GPIO_KEY_FUNC 15
+#define LSMINI_GPIO_KEY_POWER 18
+#define LSMINI_GPIO_KEY_AUTOPOWER 17
+
+#define LSMINI_SW_POWER 0x00
+#define LSMINI_SW_AUTOPOWER 0x01
+
+static struct gpio_keys_button lsmini_buttons[] = {
+ {
+ .code = KEY_OPTION,
+ .gpio = LSMINI_GPIO_KEY_FUNC,
+ .desc = "Function Button",
+ .active_low = 1,
+ }, {
+ .type = EV_SW,
+ .code = LSMINI_SW_POWER,
+ .gpio = LSMINI_GPIO_KEY_POWER,
+ .desc = "Power-on Switch",
+ .active_low = 1,
+ }, {
+ .type = EV_SW,
+ .code = LSMINI_SW_AUTOPOWER,
+ .gpio = LSMINI_GPIO_KEY_AUTOPOWER,
+ .desc = "Power-auto Switch",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data lsmini_button_data = {
+ .buttons = lsmini_buttons,
+ .nbuttons = ARRAY_SIZE(lsmini_buttons),
+};
+
+static struct platform_device lsmini_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &lsmini_button_data,
+ },
+};
+
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct mv_sata_platform_data lsmini_sata_data = {
+ .n_ports = 2,
+};
+
+
+/*****************************************************************************
+ * Linkstation Mini specific power off method: reboot
+ ****************************************************************************/
+/*
+ * On the Linkstation Mini, the shutdown process is following:
+ * - Userland monitors key events until the power switch goes to off position
+ * - The board reboots
+ * - U-boot starts and goes into an idle mode waiting for the user
+ * to move the switch to ON position
+ */
+
+static void lsmini_power_off(void)
+{
+ arch_reset(0);
+}
+
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+
+#define LSMINI_GPIO_USB_POWER 16
+#define LSMINI_GPIO_AUTO_POWER 17
+#define LSMINI_GPIO_POWER 18
+
+#define LSMINI_GPIO_HDD_POWER0 1
+#define LSMINI_GPIO_HDD_POWER1 19
+
+static struct orion5x_mpp_mode lsmini_mpp_modes[] __initdata = {
+ { 0, MPP_UNUSED }, /* LED_RESERVE1 (unused) */
+ { 1, MPP_GPIO }, /* HDD_PWR */
+ { 2, MPP_GPIO }, /* LED_ALARM */
+ { 3, MPP_GPIO }, /* LED_INFO */
+ { 4, MPP_UNUSED },
+ { 5, MPP_UNUSED },
+ { 6, MPP_UNUSED },
+ { 7, MPP_UNUSED },
+ { 8, MPP_UNUSED },
+ { 9, MPP_GPIO }, /* LED_FUNC */
+ { 10, MPP_UNUSED },
+ { 11, MPP_UNUSED }, /* LED_ETH (dummy) */
+ { 12, MPP_UNUSED },
+ { 13, MPP_UNUSED },
+ { 14, MPP_GPIO }, /* LED_PWR */
+ { 15, MPP_GPIO }, /* FUNC */
+ { 16, MPP_GPIO }, /* USB_PWR */
+ { 17, MPP_GPIO }, /* AUTO_POWER */
+ { 18, MPP_GPIO }, /* POWER */
+ { 19, MPP_GPIO }, /* HDD_PWR1 */
+ { -1 },
+};
+
+static void __init lsmini_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(lsmini_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&lsmini_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&lsmini_sata_data);
+ orion5x_uart0_init();
+ orion5x_xor_init();
+
+ orion5x_setup_dev_boot_win(LSMINI_NOR_BOOT_BASE,
+ LSMINI_NOR_BOOT_SIZE);
+ platform_device_register(&lsmini_nor_flash);
+
+ platform_device_register(&lsmini_button_device);
+
+ platform_device_register(&lsmini_leds);
+
+ i2c_register_board_info(0, &lsmini_i2c_rtc, 1);
+
+ /* enable USB power */
+ gpio_set_value(LSMINI_GPIO_USB_POWER, 1);
+
+ /* register power-off method */
+ pm_power_off = lsmini_power_off;
+
+ pr_info("%s: finished\n", __func__);
+}
+
+#ifdef CONFIG_MACH_LINKSTATION_MINI
+MACHINE_START(LINKSTATION_MINI, "Buffalo Linkstation Mini")
+ /* Maintainer: Alexey Kopytko <alexey@kopytko.ru> */
+ .phys_io = ORION5X_REGS_PHYS_BASE,
+ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .init_machine = lsmini_init,
+ .map_io = orion5x_map_io,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
+#endif
diff --git a/arch/arm/mach-orion5x/mpp.c b/arch/arm/mach-orion5x/mpp.c
new file mode 100644
index 000000000000..640ea2a3fc6c
--- /dev/null
+++ b/arch/arm/mach-orion5x/mpp.c
@@ -0,0 +1,163 @@
+/*
+ * arch/arm/mach-orion5x/mpp.c
+ *
+ * MPP functions for Marvell Orion 5x SoCs
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/mbus.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include "common.h"
+#include "mpp.h"
+
+static int is_5181l(void)
+{
+ u32 dev;
+ u32 rev;
+
+ orion5x_pcie_id(&dev, &rev);
+
+ return !!(dev == MV88F5181_DEV_ID && rev >= MV88F5181L_REV_A0);
+}
+
+static int is_5182(void)
+{
+ u32 dev;
+ u32 rev;
+
+ orion5x_pcie_id(&dev, &rev);
+
+ return !!(dev == MV88F5182_DEV_ID);
+}
+
+static int is_5281(void)
+{
+ u32 dev;
+ u32 rev;
+
+ orion5x_pcie_id(&dev, &rev);
+
+ return !!(dev == MV88F5281_DEV_ID);
+}
+
+static int __init determine_type_encoding(int mpp, enum orion5x_mpp_type type)
+{
+ switch (type) {
+ case MPP_UNUSED:
+ case MPP_GPIO:
+ if (mpp == 0)
+ return 3;
+ if (mpp >= 1 && mpp <= 15)
+ return 0;
+ if (mpp >= 16 && mpp <= 19) {
+ if (is_5182())
+ return 5;
+ if (type == MPP_UNUSED)
+ return 0;
+ }
+ return -1;
+
+ case MPP_PCIE_RST_OUTn:
+ if (mpp == 0)
+ return 0;
+ return -1;
+
+ case MPP_PCI_ARB:
+ if (mpp >= 0 && mpp <= 7)
+ return 2;
+ return -1;
+
+ case MPP_PCI_PMEn:
+ if (mpp == 2)
+ return 3;
+ return -1;
+
+ case MPP_GIGE:
+ if (mpp >= 8 && mpp <= 19)
+ return 1;
+ return -1;
+
+ case MPP_NAND:
+ if (is_5182() || is_5281()) {
+ if (mpp >= 4 && mpp <= 7)
+ return 4;
+ if (mpp >= 12 && mpp <= 17)
+ return 4;
+ }
+ return -1;
+
+ case MPP_PCI_CLK:
+ if (is_5181l() && mpp >= 6 && mpp <= 7)
+ return 5;
+ return -1;
+
+ case MPP_SATA_LED:
+ if (is_5182()) {
+ if (mpp >= 4 && mpp <= 7)
+ return 5;
+ if (mpp >= 12 && mpp <= 15)
+ return 5;
+ }
+ return -1;
+
+ case MPP_UART:
+ if (mpp >= 16 && mpp <= 19)
+ return 0;
+ return -1;
+ }
+
+ printk(KERN_INFO "unknown MPP type %d\n", type);
+
+ return -1;
+}
+
+void __init orion5x_mpp_conf(struct orion5x_mpp_mode *mode)
+{
+ u32 mpp_0_7_ctrl = readl(MPP_0_7_CTRL);
+ u32 mpp_8_15_ctrl = readl(MPP_8_15_CTRL);
+ u32 mpp_16_19_ctrl = readl(MPP_16_19_CTRL);
+
+ while (mode->mpp >= 0) {
+ u32 *reg;
+ int num_type;
+ int shift;
+
+ if (mode->mpp >= 0 && mode->mpp <= 7)
+ reg = &mpp_0_7_ctrl;
+ else if (mode->mpp >= 8 && mode->mpp <= 15)
+ reg = &mpp_8_15_ctrl;
+ else if (mode->mpp >= 16 && mode->mpp <= 19)
+ reg = &mpp_16_19_ctrl;
+ else {
+ printk(KERN_ERR "orion5x_mpp_conf: invalid MPP "
+ "(%d)\n", mode->mpp);
+ continue;
+ }
+
+ num_type = determine_type_encoding(mode->mpp, mode->type);
+ if (num_type < 0) {
+ printk(KERN_ERR "orion5x_mpp_conf: invalid MPP "
+ "combination (%d, %d)\n", mode->mpp,
+ mode->type);
+ continue;
+ }
+
+ shift = (mode->mpp & 7) << 2;
+ *reg &= ~(0xf << shift);
+ *reg |= (num_type & 0xf) << shift;
+
+ orion5x_gpio_set_valid(mode->mpp, !!(mode->type == MPP_GPIO));
+
+ mode++;
+ }
+
+ writel(mpp_0_7_ctrl, MPP_0_7_CTRL);
+ writel(mpp_8_15_ctrl, MPP_8_15_CTRL);
+ writel(mpp_16_19_ctrl, MPP_16_19_CTRL);
+}
diff --git a/arch/arm/mach-orion5x/mpp.h b/arch/arm/mach-orion5x/mpp.h
new file mode 100644
index 000000000000..290e610dc012
--- /dev/null
+++ b/arch/arm/mach-orion5x/mpp.h
@@ -0,0 +1,74 @@
+#ifndef __ARCH_ORION5X_MPP_H
+#define __ARCH_ORION5X_MPP_H
+
+enum orion5x_mpp_type {
+ /*
+ * This MPP is unused.
+ */
+ MPP_UNUSED,
+
+ /*
+ * This MPP pin is used as a generic GPIO pin. Valid for
+ * MPPs 0-15 and device bus data pins 16-31. On 5182, also
+ * valid for MPPs 16-19.
+ */
+ MPP_GPIO,
+
+ /*
+ * This MPP is used as PCIe_RST_OUTn pin. Valid for
+ * MPP 0 only.
+ */
+ MPP_PCIE_RST_OUTn,
+
+ /*
+ * This MPP is used as PCI arbiter pin (REQn/GNTn).
+ * Valid for MPPs 0-7 only.
+ */
+ MPP_PCI_ARB,
+
+ /*
+ * This MPP is used as PCI_PMEn pin. Valid for MPP 2 only.
+ */
+ MPP_PCI_PMEn,
+
+ /*
+ * This MPP is used as GigE half-duplex (COL, CRS) or GMII
+ * (RXERR, CRS, TXERR, TXD[7:4], RXD[7:4]) pin. Valid for
+ * MPPs 8-19 only.
+ */
+ MPP_GIGE,
+
+ /*
+ * This MPP is used as NAND REn/WEn pin. Valid for MPPs
+ * 4-7 and 12-17 only, and only on the 5181l/5182/5281.
+ */
+ MPP_NAND,
+
+ /*
+ * This MPP is used as a PCI clock output pin. Valid for
+ * MPPs 6-7 only, and only on the 5181l.
+ */
+ MPP_PCI_CLK,
+
+ /*
+ * This MPP is used as a SATA presence/activity LED.
+ * Valid for MPPs 4-7 and 12-15 only, and only on the 5182.
+ */
+ MPP_SATA_LED,
+
+ /*
+ * This MPP is used as UART1 RXD/TXD/CTSn/RTSn pin.
+ * Valid for MPPs 16-19 only.
+ */
+ MPP_UART,
+};
+
+struct orion5x_mpp_mode {
+ int mpp;
+ enum orion5x_mpp_type type;
+};
+
+void orion5x_mpp_conf(struct orion5x_mpp_mode *mode);
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/mss2-setup.c b/arch/arm/mach-orion5x/mss2-setup.c
new file mode 100644
index 000000000000..68acca98e638
--- /dev/null
+++ b/arch/arm/mach-orion5x/mss2-setup.c
@@ -0,0 +1,271 @@
+/*
+ * Maxtor Shared Storage II Board Setup
+ *
+ * Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <linux/gpio.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+#define MSS2_NOR_BOOT_BASE 0xff800000
+#define MSS2_NOR_BOOT_SIZE SZ_256K
+
+/*****************************************************************************
+ * Maxtor Shared Storage II Info
+ ****************************************************************************/
+
+/*
+ * Maxtor Shared Storage II hardware :
+ * - Marvell 88F5182-A2 C500
+ * - Marvell 88E1111 Gigabit Ethernet PHY
+ * - RTC M41T81 (@0x68) on I2C bus
+ * - 256KB NOR flash
+ * - 64MB of RAM
+ */
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data mss2_nor_flash_data = {
+ .width = 1,
+};
+
+static struct resource mss2_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = MSS2_NOR_BOOT_BASE,
+ .end = MSS2_NOR_BOOT_BASE + MSS2_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device mss2_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mss2_nor_flash_data,
+ },
+ .resource = &mss2_nor_flash_resource,
+ .num_resources = 1,
+};
+
+/****************************************************************************
+ * PCI setup
+ ****************************************************************************/
+static int __init mss2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ return -1;
+}
+
+static struct hw_pci mss2_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = mss2_pci_map_irq,
+};
+
+static int __init mss2_pci_init(void)
+{
+ if (machine_is_mss2())
+ pci_common_init(&mss2_pci);
+
+ return 0;
+}
+subsys_initcall(mss2_pci_init);
+
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data mss2_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+
+static struct mv_sata_platform_data mss2_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * GPIO buttons
+ ****************************************************************************/
+
+#define MSS2_GPIO_KEY_RESET 12
+#define MSS2_GPIO_KEY_POWER 11
+
+static struct gpio_keys_button mss2_buttons[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = MSS2_GPIO_KEY_POWER,
+ .desc = "Power",
+ .active_low = 1,
+ }, {
+ .code = KEY_RESTART,
+ .gpio = MSS2_GPIO_KEY_RESET,
+ .desc = "Reset",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data mss2_button_data = {
+ .buttons = mss2_buttons,
+ .nbuttons = ARRAY_SIZE(mss2_buttons),
+};
+
+static struct platform_device mss2_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &mss2_button_data,
+ },
+};
+
+/*****************************************************************************
+ * RTC m41t81 on I2C bus
+ ****************************************************************************/
+
+#define MSS2_GPIO_RTC_IRQ 3
+
+static struct i2c_board_info __initdata mss2_i2c_rtc = {
+ I2C_BOARD_INFO("m41t81", 0x68),
+};
+
+/*****************************************************************************
+ * MSS2 power off method
+ ****************************************************************************/
+/*
+ * On the Maxtor Shared Storage II, the shutdown process is the following :
+ * - Userland modifies U-boot env to tell U-boot to go idle at next boot
+ * - The board reboots
+ * - U-boot starts and go into an idle mode until the user press "power"
+ */
+static void mss2_power_off(void)
+{
+ u32 reg;
+
+ /*
+ * Enable and issue soft reset
+ */
+ reg = readl(CPU_RESET_MASK);
+ reg |= 1 << 2;
+ writel(reg, CPU_RESET_MASK);
+
+ reg = readl(CPU_SOFT_RESET);
+ reg |= 1;
+ writel(reg, CPU_SOFT_RESET);
+}
+
+/****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static struct orion5x_mpp_mode mss2_mpp_modes[] __initdata = {
+ { 0, MPP_GPIO }, /* Power LED */
+ { 1, MPP_GPIO }, /* Error LED */
+ { 2, MPP_UNUSED },
+ { 3, MPP_GPIO }, /* RTC interrupt */
+ { 4, MPP_GPIO }, /* HDD ind. (Single/Dual)*/
+ { 5, MPP_GPIO }, /* HD0 5V control */
+ { 6, MPP_GPIO }, /* HD0 12V control */
+ { 7, MPP_GPIO }, /* HD1 5V control */
+ { 8, MPP_GPIO }, /* HD1 12V control */
+ { 9, MPP_UNUSED },
+ { 10, MPP_GPIO }, /* Fan control */
+ { 11, MPP_GPIO }, /* Power button */
+ { 12, MPP_GPIO }, /* Reset button */
+ { 13, MPP_UNUSED },
+ { 14, MPP_SATA_LED }, /* SATA 0 active */
+ { 15, MPP_SATA_LED }, /* SATA 1 active */
+ { 16, MPP_UNUSED },
+ { 17, MPP_UNUSED },
+ { 18, MPP_UNUSED },
+ { 19, MPP_UNUSED },
+ { -1 },
+};
+
+static void __init mss2_init(void)
+{
+ /* Setup basic Orion functions. Need to be called early. */
+ orion5x_init();
+
+ orion5x_mpp_conf(mss2_mpp_modes);
+
+ /*
+ * MPP[20] Unused
+ * MPP[21] PCI clock
+ * MPP[22] USB 0 over current
+ * MPP[23] USB 1 over current
+ */
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&mss2_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&mss2_sata_data);
+ orion5x_uart0_init();
+ orion5x_xor_init();
+
+ orion5x_setup_dev_boot_win(MSS2_NOR_BOOT_BASE, MSS2_NOR_BOOT_SIZE);
+ platform_device_register(&mss2_nor_flash);
+
+ platform_device_register(&mss2_button_device);
+
+ if (gpio_request(MSS2_GPIO_RTC_IRQ, "rtc") == 0) {
+ if (gpio_direction_input(MSS2_GPIO_RTC_IRQ) == 0)
+ mss2_i2c_rtc.irq = gpio_to_irq(MSS2_GPIO_RTC_IRQ);
+ else
+ gpio_free(MSS2_GPIO_RTC_IRQ);
+ }
+ i2c_register_board_info(0, &mss2_i2c_rtc, 1);
+
+ /* register mss2 specific power-off method */
+ pm_power_off = mss2_power_off;
+}
+
+MACHINE_START(MSS2, "Maxtor Shared Storage II")
+ /* Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com> */
+ .phys_io = ORION5X_REGS_PHYS_BASE,
+ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .init_machine = mss2_init,
+ .map_io = orion5x_map_io,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/mv2120-setup.c b/arch/arm/mach-orion5x/mv2120-setup.c
new file mode 100644
index 000000000000..97c9ccb2ac60
--- /dev/null
+++ b/arch/arm/mach-orion5x/mv2120-setup.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2007 Herbert Valerio Riedel <hvr@gnu.org>
+ * Copyright (C) 2008 Martin Michlmayr <tbm@cyrius.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/ata_platform.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+#define MV2120_NOR_BOOT_BASE 0xf4000000
+#define MV2120_NOR_BOOT_SIZE SZ_512K
+
+#define MV2120_GPIO_RTC_IRQ 3
+#define MV2120_GPIO_KEY_RESET 17
+#define MV2120_GPIO_KEY_POWER 18
+#define MV2120_GPIO_POWER_OFF 19
+
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+static struct mv643xx_eth_platform_data mv2120_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static struct mv_sata_platform_data mv2120_sata_data = {
+ .n_ports = 2,
+};
+
+static struct mtd_partition mv2120_partitions[] = {
+ {
+ .name = "firmware",
+ .size = 0x00080000,
+ .offset = 0,
+ },
+};
+
+static struct physmap_flash_data mv2120_nor_flash_data = {
+ .width = 1,
+ .parts = mv2120_partitions,
+ .nr_parts = ARRAY_SIZE(mv2120_partitions)
+};
+
+static struct resource mv2120_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = MV2120_NOR_BOOT_BASE,
+ .end = MV2120_NOR_BOOT_BASE + MV2120_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device mv2120_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &mv2120_nor_flash_data,
+ },
+ .resource = &mv2120_nor_flash_resource,
+ .num_resources = 1,
+};
+
+static struct gpio_keys_button mv2120_buttons[] = {
+ {
+ .code = KEY_RESTART,
+ .gpio = MV2120_GPIO_KEY_RESET,
+ .desc = "reset",
+ .active_low = 1,
+ }, {
+ .code = KEY_POWER,
+ .gpio = MV2120_GPIO_KEY_POWER,
+ .desc = "power",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data mv2120_button_data = {
+ .buttons = mv2120_buttons,
+ .nbuttons = ARRAY_SIZE(mv2120_buttons),
+};
+
+static struct platform_device mv2120_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &mv2120_button_data,
+ },
+};
+
+
+/****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static struct orion5x_mpp_mode mv2120_mpp_modes[] __initdata = {
+ { 0, MPP_GPIO }, /* Sys status LED */
+ { 1, MPP_GPIO }, /* Sys error LED */
+ { 2, MPP_GPIO }, /* OverTemp interrupt */
+ { 3, MPP_GPIO }, /* RTC interrupt */
+ { 4, MPP_GPIO }, /* V_LED 5V */
+ { 5, MPP_GPIO }, /* V_LED 3.3V */
+ { 6, MPP_UNUSED },
+ { 7, MPP_UNUSED },
+ { 8, MPP_GPIO }, /* SATA 0 fail LED */
+ { 9, MPP_GPIO }, /* SATA 1 fail LED */
+ { 10, MPP_UNUSED },
+ { 11, MPP_UNUSED },
+ { 12, MPP_SATA_LED }, /* SATA 0 presence */
+ { 13, MPP_SATA_LED }, /* SATA 1 presence */
+ { 14, MPP_SATA_LED }, /* SATA 0 active */
+ { 15, MPP_SATA_LED }, /* SATA 1 active */
+ { 16, MPP_UNUSED },
+ { 17, MPP_GPIO }, /* Reset button */
+ { 18, MPP_GPIO }, /* Power button */
+ { 19, MPP_GPIO }, /* Power off */
+ { -1 },
+};
+
+static struct i2c_board_info __initdata mv2120_i2c_rtc = {
+ I2C_BOARD_INFO("pcf8563", 0x51),
+ .irq = 0,
+};
+
+static struct gpio_led mv2120_led_pins[] = {
+ {
+ .name = "mv2120:blue:health",
+ .gpio = 0,
+ },
+ {
+ .name = "mv2120:red:health",
+ .gpio = 1,
+ },
+ {
+ .name = "mv2120:led:bright",
+ .gpio = 4,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "mv2120:led:dimmed",
+ .gpio = 5,
+ },
+ {
+ .name = "mv2120:red:sata0",
+ .gpio = 8,
+ .active_low = 1,
+ },
+ {
+ .name = "mv2120:red:sata1",
+ .gpio = 9,
+ .active_low = 1,
+ },
+
+};
+
+static struct gpio_led_platform_data mv2120_led_data = {
+ .leds = mv2120_led_pins,
+ .num_leds = ARRAY_SIZE(mv2120_led_pins),
+};
+
+static struct platform_device mv2120_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &mv2120_led_data,
+ }
+};
+
+static void mv2120_power_off(void)
+{
+ pr_info("%s: triggering power-off...\n", __func__);
+ gpio_set_value(MV2120_GPIO_POWER_OFF, 0);
+}
+
+static void __init mv2120_init(void)
+{
+ /* Setup basic Orion functions. Need to be called early. */
+ orion5x_init();
+
+ orion5x_mpp_conf(mv2120_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&mv2120_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&mv2120_sata_data);
+ orion5x_uart0_init();
+ orion5x_xor_init();
+
+ orion5x_setup_dev_boot_win(MV2120_NOR_BOOT_BASE, MV2120_NOR_BOOT_SIZE);
+ platform_device_register(&mv2120_nor_flash);
+
+ platform_device_register(&mv2120_button_device);
+
+ if (gpio_request(MV2120_GPIO_RTC_IRQ, "rtc") == 0) {
+ if (gpio_direction_input(MV2120_GPIO_RTC_IRQ) == 0)
+ mv2120_i2c_rtc.irq = gpio_to_irq(MV2120_GPIO_RTC_IRQ);
+ else
+ gpio_free(MV2120_GPIO_RTC_IRQ);
+ }
+ i2c_register_board_info(0, &mv2120_i2c_rtc, 1);
+ platform_device_register(&mv2120_leds);
+
+ /* register mv2120 specific power-off method */
+ if (gpio_request(MV2120_GPIO_POWER_OFF, "POWEROFF") != 0 ||
+ gpio_direction_output(MV2120_GPIO_POWER_OFF, 1) != 0)
+ pr_err("mv2120: failed to setup power-off GPIO\n");
+ pm_power_off = mv2120_power_off;
+}
+
+/* Warning: HP uses a wrong mach-type (=526) in their bootloader */
+MACHINE_START(MV2120, "HP Media Vault mv2120")
+ /* Maintainer: Martin Michlmayr <tbm@cyrius.com> */
+ .phys_io = ORION5X_REGS_PHYS_BASE,
+ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .init_machine = mv2120_init,
+ .map_io = orion5x_map_io,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/pci.c b/arch/arm/mach-orion5x/pci.c
index 9d5d39fa19c3..a7b7d77b1b09 100644
--- a/arch/arm/mach-orion5x/pci.c
+++ b/arch/arm/mach-orion5x/pci.c
@@ -14,7 +14,7 @@
#include <linux/pci.h>
#include <linux/mbus.h>
#include <asm/mach/pci.h>
-#include <asm/plat-orion/pcie.h>
+#include <plat/pcie.h>
#include "common.h"
/*****************************************************************************
@@ -152,6 +152,8 @@ static int __init pcie_setup(struct pci_sys_data *sys)
if (dev == MV88F5181_DEV_ID || dev == MV88F5182_DEV_ID) {
printk(KERN_NOTICE "Applying Orion-1/Orion-NAS PCIe config "
"read transaction workaround\n");
+ orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE,
+ ORION5X_PCIE_WA_SIZE);
pcie_ops.read = pcie_rd_conf_wa;
}
@@ -240,13 +242,13 @@ static int __init pcie_setup(struct pci_sys_data *sys)
* PCI Address Decode Windows registers
*/
#define PCI_BAR_SIZE_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc08) : \
- ((n) == 1) ? ORION5X_PCI_REG(0xd08) : \
- ((n) == 2) ? ORION5X_PCI_REG(0xc0c) : \
- ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : 0)
-#define PCI_BAR_REMAP_DDR_CS(n) (((n) ==0) ? ORION5X_PCI_REG(0xc48) : \
- ((n) == 1) ? ORION5X_PCI_REG(0xd48) : \
- ((n) == 2) ? ORION5X_PCI_REG(0xc4c) : \
- ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : 0)
+ ((n) == 1) ? ORION5X_PCI_REG(0xd08) : \
+ ((n) == 2) ? ORION5X_PCI_REG(0xc0c) : \
+ ((n) == 3) ? ORION5X_PCI_REG(0xd0c) : 0)
+#define PCI_BAR_REMAP_DDR_CS(n) (((n) == 0) ? ORION5X_PCI_REG(0xc48) : \
+ ((n) == 1) ? ORION5X_PCI_REG(0xd48) : \
+ ((n) == 2) ? ORION5X_PCI_REG(0xc4c) : \
+ ((n) == 3) ? ORION5X_PCI_REG(0xd4c) : 0)
#define PCI_BAR_ENABLE ORION5X_PCI_REG(0xc3c)
#define PCI_ADDR_DECODE_CTRL ORION5X_PCI_REG(0xd3c)
@@ -264,9 +266,11 @@ static int __init pcie_setup(struct pci_sys_data *sys)
*/
static DEFINE_SPINLOCK(orion5x_pci_lock);
+static int orion5x_pci_cardbus_mode;
+
static int orion5x_pci_local_bus_nr(void)
{
- u32 conf = orion5x_read(PCI_P2P_CONF);
+ u32 conf = readl(PCI_P2P_CONF);
return((conf & PCI_P2P_BUS_MASK) >> PCI_P2P_BUS_OFFS);
}
@@ -276,11 +280,11 @@ static int orion5x_pci_hw_rd_conf(int bus, int dev, u32 func,
unsigned long flags;
spin_lock_irqsave(&orion5x_pci_lock, flags);
- orion5x_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) |
- PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
- PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN);
+ writel(PCI_CONF_BUS(bus) |
+ PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
+ PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN, PCI_CONF_ADDR);
- *val = orion5x_read(PCI_CONF_DATA);
+ *val = readl(PCI_CONF_DATA);
if (size == 1)
*val = (*val >> (8*(where & 0x3))) & 0xff;
@@ -300,9 +304,9 @@ static int orion5x_pci_hw_wr_conf(int bus, int dev, u32 func,
spin_lock_irqsave(&orion5x_pci_lock, flags);
- orion5x_write(PCI_CONF_ADDR, PCI_CONF_BUS(bus) |
- PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
- PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN);
+ writel(PCI_CONF_BUS(bus) |
+ PCI_CONF_DEV(dev) | PCI_CONF_REG(where) |
+ PCI_CONF_FUNC(func) | PCI_CONF_ADDR_EN, PCI_CONF_ADDR);
if (size == 4) {
__raw_writel(val, PCI_CONF_DATA);
@@ -319,14 +323,30 @@ static int orion5x_pci_hw_wr_conf(int bus, int dev, u32 func,
return ret;
}
+static int orion5x_pci_valid_config(int bus, u32 devfn)
+{
+ if (bus == orion5x_pci_local_bus_nr()) {
+ /*
+ * Don't go out for local device
+ */
+ if (PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0)
+ return 0;
+
+ /*
+ * When the PCI signals are directly connected to a
+ * Cardbus slot, ignore all but device IDs 0 and 1.
+ */
+ if (orion5x_pci_cardbus_mode && PCI_SLOT(devfn) > 1)
+ return 0;
+ }
+
+ return 1;
+}
+
static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn,
int where, int size, u32 *val)
{
- /*
- * Don't go out for local device
- */
- if (bus->number == orion5x_pci_local_bus_nr() &&
- PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0) {
+ if (!orion5x_pci_valid_config(bus->number, devfn)) {
*val = 0xffffffff;
return PCIBIOS_DEVICE_NOT_FOUND;
}
@@ -338,8 +358,7 @@ static int orion5x_pci_rd_conf(struct pci_bus *bus, u32 devfn,
static int orion5x_pci_wr_conf(struct pci_bus *bus, u32 devfn,
int where, int size, u32 val)
{
- if (bus->number == orion5x_pci_local_bus_nr() &&
- PCI_SLOT(devfn) == 0 && PCI_FUNC(devfn) != 0)
+ if (!orion5x_pci_valid_config(bus->number, devfn))
return PCIBIOS_DEVICE_NOT_FOUND;
return orion5x_pci_hw_wr_conf(bus->number, PCI_SLOT(devfn),
@@ -353,9 +372,9 @@ static struct pci_ops pci_ops = {
static void __init orion5x_pci_set_bus_nr(int nr)
{
- u32 p2p = orion5x_read(PCI_P2P_CONF);
+ u32 p2p = readl(PCI_P2P_CONF);
- if (orion5x_read(PCI_MODE) & PCI_MODE_PCIX) {
+ if (readl(PCI_MODE) & PCI_MODE_PCIX) {
/*
* PCI-X mode
*/
@@ -372,7 +391,7 @@ static void __init orion5x_pci_set_bus_nr(int nr)
*/
p2p &= ~PCI_P2P_BUS_MASK;
p2p |= (nr << PCI_P2P_BUS_OFFS);
- orion5x_write(PCI_P2P_CONF, p2p);
+ writel(p2p, PCI_P2P_CONF);
}
}
@@ -399,7 +418,7 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram)
* First, disable windows.
*/
win_enable = 0xffffffff;
- orion5x_write(PCI_BAR_ENABLE, win_enable);
+ writel(win_enable, PCI_BAR_ENABLE);
/*
* Setup windows for DDR banks.
@@ -425,10 +444,10 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram)
*/
reg = PCI_CONF_REG_BAR_HI_CS(cs->cs_index);
orion5x_pci_hw_wr_conf(bus, 0, func, reg, 4, 0);
- orion5x_write(PCI_BAR_SIZE_DDR_CS(cs->cs_index),
- (cs->size - 1) & 0xfffff000);
- orion5x_write(PCI_BAR_REMAP_DDR_CS(cs->cs_index),
- cs->base & 0xfffff000);
+ writel((cs->size - 1) & 0xfffff000,
+ PCI_BAR_SIZE_DDR_CS(cs->cs_index));
+ writel(cs->base & 0xfffff000,
+ PCI_BAR_REMAP_DDR_CS(cs->cs_index));
/*
* Enable decode window for this chip select.
@@ -439,7 +458,7 @@ static void __init orion5x_setup_pci_wins(struct mbus_dram_target_info *dram)
/*
* Re-enable decode windows.
*/
- orion5x_write(PCI_BAR_ENABLE, win_enable);
+ writel(win_enable, PCI_BAR_ENABLE);
/*
* Disable automatic update of address remaping when writing to BARs.
@@ -522,6 +541,18 @@ static void __devinit rc_pci_fixup(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_ANY_ID, rc_pci_fixup);
+static int orion5x_pci_disabled __initdata;
+
+void __init orion5x_pci_disable(void)
+{
+ orion5x_pci_disabled = 1;
+}
+
+void __init orion5x_pci_set_cardbus_mode(void)
+{
+ orion5x_pci_cardbus_mode = 1;
+}
+
int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys)
{
int ret = 0;
@@ -529,7 +560,7 @@ int __init orion5x_pci_sys_setup(int nr, struct pci_sys_data *sys)
if (nr == 0) {
orion_pcie_set_local_bus_nr(PCIE_BASE, sys->busnr);
ret = pcie_setup(sys);
- } else if (nr == 1) {
+ } else if (nr == 1 && !orion5x_pci_disabled) {
orion5x_pci_set_bus_nr(sys->busnr);
ret = pci_setup(sys);
}
@@ -543,7 +574,7 @@ struct pci_bus __init *orion5x_pci_sys_scan_bus(int nr, struct pci_sys_data *sys
if (nr == 0) {
bus = pci_scan_bus(sys->busnr, &pcie_ops, sys);
- } else if (nr == 1) {
+ } else if (nr == 1 && !orion5x_pci_disabled) {
bus = pci_scan_bus(sys->busnr, &pci_ops, sys);
} else {
bus = NULL;
@@ -560,7 +591,7 @@ int __init orion5x_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
/*
* PCIe endpoint?
*/
- if (bus < orion5x_pci_local_bus_nr())
+ if (orion5x_pci_disabled || bus < orion5x_pci_local_bus_nr())
return IRQ_ORION5X_PCIE0_INT;
return -1;
diff --git a/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
new file mode 100644
index 000000000000..500cdadaf09c
--- /dev/null
+++ b/arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
@@ -0,0 +1,164 @@
+/*
+ * arch/arm/mach-orion5x/rd88f5181l-fxo-setup.c
+ *
+ * Marvell Orion-VoIP FXO Reference Design Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/leds.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * RD-88F5181L FXO Info
+ ****************************************************************************/
+/*
+ * 8M NOR flash Device bus boot chip select
+ */
+#define RD88F5181L_FXO_NOR_BOOT_BASE 0xff800000
+#define RD88F5181L_FXO_NOR_BOOT_SIZE SZ_8M
+
+
+/*****************************************************************************
+ * 8M NOR Flash on Device bus Boot chip select
+ ****************************************************************************/
+static struct physmap_flash_data rd88f5181l_fxo_nor_boot_flash_data = {
+ .width = 1,
+};
+
+static struct resource rd88f5181l_fxo_nor_boot_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = RD88F5181L_FXO_NOR_BOOT_BASE,
+ .end = RD88F5181L_FXO_NOR_BOOT_BASE +
+ RD88F5181L_FXO_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device rd88f5181l_fxo_nor_boot_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &rd88f5181l_fxo_nor_boot_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &rd88f5181l_fxo_nor_boot_flash_resource,
+};
+
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static struct orion5x_mpp_mode rd88f5181l_fxo_mpp_modes[] __initdata = {
+ { 0, MPP_GPIO }, /* LED1 CardBus LED (front panel) */
+ { 1, MPP_GPIO }, /* PCI_intA */
+ { 2, MPP_GPIO }, /* Hard Reset / Factory Init*/
+ { 3, MPP_GPIO }, /* FXS or DAA select */
+ { 4, MPP_GPIO }, /* LED6 - phone LED (front panel) */
+ { 5, MPP_GPIO }, /* LED5 - phone LED (front panel) */
+ { 6, MPP_PCI_CLK }, /* CPU PCI refclk */
+ { 7, MPP_PCI_CLK }, /* PCI/PCIe refclk */
+ { 8, MPP_GPIO }, /* CardBus reset */
+ { 9, MPP_GPIO }, /* GE_RXERR */
+ { 10, MPP_GPIO }, /* LED2 MiniPCI LED (front panel) */
+ { 11, MPP_GPIO }, /* Lifeline control */
+ { 12, MPP_GIGE }, /* GE_TXD[4] */
+ { 13, MPP_GIGE }, /* GE_TXD[5] */
+ { 14, MPP_GIGE }, /* GE_TXD[6] */
+ { 15, MPP_GIGE }, /* GE_TXD[7] */
+ { 16, MPP_GIGE }, /* GE_RXD[4] */
+ { 17, MPP_GIGE }, /* GE_RXD[5] */
+ { 18, MPP_GIGE }, /* GE_RXD[6] */
+ { 19, MPP_GIGE }, /* GE_RXD[7] */
+ { -1 },
+};
+
+static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_NONE,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static void __init rd88f5181l_fxo_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(rd88f5181l_fxo_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_eth_init(&rd88f5181l_fxo_eth_data);
+ orion5x_uart0_init();
+
+ orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE,
+ RD88F5181L_FXO_NOR_BOOT_SIZE);
+ platform_device_register(&rd88f5181l_fxo_nor_boot_flash);
+}
+
+static int __init
+rd88f5181l_fxo_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * Mini-PCI / Cardbus slot.
+ */
+ return gpio_to_irq(1);
+}
+
+static struct hw_pci rd88f5181l_fxo_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = rd88f5181l_fxo_pci_map_irq,
+};
+
+static int __init rd88f5181l_fxo_pci_init(void)
+{
+ if (machine_is_rd88f5181l_fxo()) {
+ orion5x_pci_set_cardbus_mode();
+ pci_common_init(&rd88f5181l_fxo_pci);
+ }
+
+ return 0;
+}
+subsys_initcall(rd88f5181l_fxo_pci_init);
+
+MACHINE_START(RD88F5181L_FXO, "Marvell Orion-VoIP FXO Reference Design")
+ /* Maintainer: Nicolas Pitre <nico@marvell.com> */
+ .phys_io = ORION5X_REGS_PHYS_BASE,
+ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .init_machine = rd88f5181l_fxo_init,
+ .map_io = orion5x_map_io,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
new file mode 100644
index 000000000000..ebde81416499
--- /dev/null
+++ b/arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
@@ -0,0 +1,175 @@
+/*
+ * arch/arm/mach-orion5x/rd88f5181l-ge-setup.c
+ *
+ * Marvell Orion-VoIP GE Reference Design Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <linux/i2c.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/leds.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * RD-88F5181L GE Info
+ ****************************************************************************/
+/*
+ * 16M NOR flash Device bus boot chip select
+ */
+#define RD88F5181L_GE_NOR_BOOT_BASE 0xff000000
+#define RD88F5181L_GE_NOR_BOOT_SIZE SZ_16M
+
+
+/*****************************************************************************
+ * 16M NOR Flash on Device bus Boot chip select
+ ****************************************************************************/
+static struct physmap_flash_data rd88f5181l_ge_nor_boot_flash_data = {
+ .width = 1,
+};
+
+static struct resource rd88f5181l_ge_nor_boot_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = RD88F5181L_GE_NOR_BOOT_BASE,
+ .end = RD88F5181L_GE_NOR_BOOT_BASE +
+ RD88F5181L_GE_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device rd88f5181l_ge_nor_boot_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &rd88f5181l_ge_nor_boot_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &rd88f5181l_ge_nor_boot_flash_resource,
+};
+
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static struct orion5x_mpp_mode rd88f5181l_ge_mpp_modes[] __initdata = {
+ { 0, MPP_GPIO }, /* LED1 */
+ { 1, MPP_GPIO }, /* LED5 */
+ { 2, MPP_GPIO }, /* LED4 */
+ { 3, MPP_GPIO }, /* LED3 */
+ { 4, MPP_GPIO }, /* PCI_intA */
+ { 5, MPP_GPIO }, /* RTC interrupt */
+ { 6, MPP_PCI_CLK }, /* CPU PCI refclk */
+ { 7, MPP_PCI_CLK }, /* PCI/PCIe refclk */
+ { 8, MPP_GPIO }, /* 88e6131 interrupt */
+ { 9, MPP_GPIO }, /* GE_RXERR */
+ { 10, MPP_GPIO }, /* PCI_intB */
+ { 11, MPP_GPIO }, /* LED2 */
+ { 12, MPP_GIGE }, /* GE_TXD[4] */
+ { 13, MPP_GIGE }, /* GE_TXD[5] */
+ { 14, MPP_GIGE }, /* GE_TXD[6] */
+ { 15, MPP_GIGE }, /* GE_TXD[7] */
+ { 16, MPP_GIGE }, /* GE_RXD[4] */
+ { 17, MPP_GIGE }, /* GE_RXD[5] */
+ { 18, MPP_GIGE }, /* GE_RXD[6] */
+ { 19, MPP_GIGE }, /* GE_RXD[7] */
+ { -1 },
+};
+
+static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_NONE,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {
+ I2C_BOARD_INFO("ds1338", 0x68),
+};
+
+static void __init rd88f5181l_ge_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(rd88f5181l_ge_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_eth_init(&rd88f5181l_ge_eth_data);
+ orion5x_i2c_init();
+ orion5x_uart0_init();
+
+ orion5x_setup_dev_boot_win(RD88F5181L_GE_NOR_BOOT_BASE,
+ RD88F5181L_GE_NOR_BOOT_SIZE);
+ platform_device_register(&rd88f5181l_ge_nor_boot_flash);
+
+ i2c_register_board_info(0, &rd88f5181l_ge_i2c_rtc, 1);
+}
+
+static int __init
+rd88f5181l_ge_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * Cardbus slot.
+ */
+ if (pin == 1)
+ return gpio_to_irq(4);
+ else
+ return gpio_to_irq(10);
+}
+
+static struct hw_pci rd88f5181l_ge_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = rd88f5181l_ge_pci_map_irq,
+};
+
+static int __init rd88f5181l_ge_pci_init(void)
+{
+ if (machine_is_rd88f5181l_ge()) {
+ orion5x_pci_set_cardbus_mode();
+ pci_common_init(&rd88f5181l_ge_pci);
+ }
+
+ return 0;
+}
+subsys_initcall(rd88f5181l_ge_pci_init);
+
+MACHINE_START(RD88F5181L_GE, "Marvell Orion-VoIP GE Reference Design")
+ /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+ .phys_io = ORION5X_REGS_PHYS_BASE,
+ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .init_machine = rd88f5181l_ge_init,
+ .map_io = orion5x_map_io,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/rd88f5182-setup.c b/arch/arm/mach-orion5x/rd88f5182-setup.c
index 81abc1003aae..a04f9e4b633a 100644
--- a/arch/arm/mach-orion5x/rd88f5182-setup.c
+++ b/arch/arm/mach-orion5x/rd88f5182-setup.c
@@ -24,8 +24,9 @@
#include <asm/leds.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
-#include <asm/arch/orion5x.h>
+#include <mach/orion5x.h>
#include "common.h"
+#include "mpp.h"
/*****************************************************************************
* RD-88F5182 Info
@@ -125,6 +126,7 @@ static int __init rd88f5182_dbgled_init(void)
leds_event = rd88f5182_dbgled_event;
}
+
return 0;
}
@@ -146,7 +148,7 @@ void __init rd88f5182_pci_preinit(void)
pin = RD88F5182_PCI_SLOT0_IRQ_A_PIN;
if (gpio_request(pin, "PCI IntA") == 0) {
if (gpio_direction_input(pin) == 0) {
- set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+ set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "rd88f5182_pci_preinit faield to "
"set_irq_type pin %d\n", pin);
@@ -159,7 +161,7 @@ void __init rd88f5182_pci_preinit(void)
pin = RD88F5182_PCI_SLOT0_IRQ_B_PIN;
if (gpio_request(pin, "PCI IntB") == 0) {
if (gpio_direction_input(pin) == 0) {
- set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+ set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "rd88f5182_pci_preinit faield to "
"set_irq_type pin %d\n", pin);
@@ -219,8 +221,7 @@ subsys_initcall(rd88f5182_pci_init);
****************************************************************************/
static struct mv643xx_eth_platform_data rd88f5182_eth_data = {
- .phy_addr = 8,
- .force_phy_addr = 1,
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
};
/*****************************************************************************
@@ -234,15 +235,34 @@ static struct i2c_board_info __initdata rd88f5182_i2c_rtc = {
* Sata
****************************************************************************/
static struct mv_sata_platform_data rd88f5182_sata_data = {
- .n_ports = 2,
+ .n_ports = 2,
};
/*****************************************************************************
* General Setup
****************************************************************************/
-
-static struct platform_device *rd88f5182_devices[] __initdata = {
- &rd88f5182_nor_flash,
+static struct orion5x_mpp_mode rd88f5182_mpp_modes[] __initdata = {
+ { 0, MPP_GPIO }, /* Debug Led */
+ { 1, MPP_GPIO }, /* Reset Switch */
+ { 2, MPP_UNUSED },
+ { 3, MPP_GPIO }, /* RTC Int */
+ { 4, MPP_GPIO },
+ { 5, MPP_GPIO },
+ { 6, MPP_GPIO }, /* PCI_intA */
+ { 7, MPP_GPIO }, /* PCI_intB */
+ { 8, MPP_UNUSED },
+ { 9, MPP_UNUSED },
+ { 10, MPP_UNUSED },
+ { 11, MPP_UNUSED },
+ { 12, MPP_SATA_LED }, /* SATA 0 presence */
+ { 13, MPP_SATA_LED }, /* SATA 1 presence */
+ { 14, MPP_SATA_LED }, /* SATA 0 active */
+ { 15, MPP_SATA_LED }, /* SATA 1 active */
+ { 16, MPP_UNUSED },
+ { 17, MPP_UNUSED },
+ { 18, MPP_UNUSED },
+ { 19, MPP_UNUSED },
+ { -1 },
};
static void __init rd88f5182_init(void)
@@ -252,35 +272,9 @@ static void __init rd88f5182_init(void)
*/
orion5x_init();
- /*
- * Setup the CPU address decode windows for our devices
- */
- orion5x_setup_dev_boot_win(RD88F5182_NOR_BOOT_BASE,
- RD88F5182_NOR_BOOT_SIZE);
- orion5x_setup_dev1_win(RD88F5182_NOR_BASE, RD88F5182_NOR_SIZE);
-
- /*
- * Open a special address decode windows for the PCIe WA.
- */
- orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE,
- ORION5X_PCIE_WA_SIZE);
+ orion5x_mpp_conf(rd88f5182_mpp_modes);
/*
- * Setup Multiplexing Pins --
- * MPP[0] Debug Led (GPIO - Out)
- * MPP[1] Debug Led (GPIO - Out)
- * MPP[2] N/A
- * MPP[3] RTC_Int (GPIO - In)
- * MPP[4] GPIO
- * MPP[5] GPIO
- * MPP[6] PCI_intA (GPIO - In)
- * MPP[7] PCI_intB (GPIO - In)
- * MPP[8-11] N/A
- * MPP[12] SATA 0 presence Indication
- * MPP[13] SATA 1 presence Indication
- * MPP[14] SATA 0 active Indication
- * MPP[15] SATA 1 active indication
- * MPP[16-19] Not used
* MPP[20] PCI Clock to MV88F5182
* MPP[21] PCI Clock to mini PCI CON11
* MPP[22] USB 0 over current indication
@@ -289,16 +283,24 @@ static void __init rd88f5182_init(void)
* MPP[25] USB 0 over current enable
*/
- orion5x_write(MPP_0_7_CTRL, 0x00000003);
- orion5x_write(MPP_8_15_CTRL, 0x55550000);
- orion5x_write(MPP_16_19_CTRL, 0x5555);
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&rd88f5182_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&rd88f5182_sata_data);
+ orion5x_uart0_init();
+ orion5x_xor_init();
- orion5x_gpio_set_valid_pins(0x000000fb);
+ orion5x_setup_dev_boot_win(RD88F5182_NOR_BOOT_BASE,
+ RD88F5182_NOR_BOOT_SIZE);
+
+ orion5x_setup_dev1_win(RD88F5182_NOR_BASE, RD88F5182_NOR_SIZE);
+ platform_device_register(&rd88f5182_nor_flash);
- platform_add_devices(rd88f5182_devices, ARRAY_SIZE(rd88f5182_devices));
i2c_register_board_info(0, &rd88f5182_i2c_rtc, 1);
- orion5x_eth_init(&rd88f5182_eth_data);
- orion5x_sata_init(&rd88f5182_sata_data);
}
MACHINE_START(RD88F5182, "Marvell Orion-NAS Reference Design")
diff --git a/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
new file mode 100644
index 000000000000..40e049539091
--- /dev/null
+++ b/arch/arm/mach-orion5x/rd88f6183ap-ge-setup.c
@@ -0,0 +1,117 @@
+/*
+ * arch/arm/mach-orion5x/rd88f6183-ap-ge-setup.c
+ *
+ * Marvell Orion-1-90 AP GE Reference Design Setup
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/orion_spi.h>
+#include <linux/spi/flash.h>
+#include <linux/ethtool.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/leds.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = {
+ .phy_addr = -1,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static struct mtd_partition rd88f6183ap_ge_partitions[] = {
+ {
+ .name = "kernel",
+ .offset = 0x00000000,
+ .size = 0x00200000,
+ }, {
+ .name = "rootfs",
+ .offset = 0x00200000,
+ .size = 0x00500000,
+ }, {
+ .name = "nvram",
+ .offset = 0x00700000,
+ .size = 0x00080000,
+ },
+};
+
+static struct flash_platform_data rd88f6183ap_ge_spi_slave_data = {
+ .type = "m25p64",
+ .nr_parts = ARRAY_SIZE(rd88f6183ap_ge_partitions),
+ .parts = rd88f6183ap_ge_partitions,
+};
+
+static struct spi_board_info __initdata rd88f6183ap_ge_spi_slave_info[] = {
+ {
+ .modalias = "m25p80",
+ .platform_data = &rd88f6183ap_ge_spi_slave_data,
+ .irq = NO_IRQ,
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 0,
+ },
+};
+
+static void __init rd88f6183ap_ge_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_eth_init(&rd88f6183ap_ge_eth_data);
+ spi_register_board_info(rd88f6183ap_ge_spi_slave_info,
+ ARRAY_SIZE(rd88f6183ap_ge_spi_slave_info));
+ orion5x_spi_init();
+ orion5x_uart0_init();
+}
+
+static struct hw_pci rd88f6183ap_ge_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = orion5x_pci_map_irq,
+};
+
+static int __init rd88f6183ap_ge_pci_init(void)
+{
+ if (machine_is_rd88f6183ap_ge()) {
+ orion5x_pci_disable();
+ pci_common_init(&rd88f6183ap_ge_pci);
+ }
+
+ return 0;
+}
+subsys_initcall(rd88f6183ap_ge_pci_init);
+
+MACHINE_START(RD88F6183AP_GE, "Marvell Orion-1-90 AP GE Reference Design")
+ /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+ .phys_io = ORION5X_REGS_PHYS_BASE,
+ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .init_machine = rd88f6183ap_ge_init,
+ .map_io = orion5x_map_io,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/terastation_pro2-setup.c b/arch/arm/mach-orion5x/terastation_pro2-setup.c
new file mode 100644
index 000000000000..0b101d7d41c2
--- /dev/null
+++ b/arch/arm/mach-orion5x/terastation_pro2-setup.c
@@ -0,0 +1,369 @@
+/*
+ * Buffalo Terastation Pro II/Live Board Setup
+ *
+ * Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/i2c.h>
+#include <linux/serial_reg.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * Terastation Pro 2/Live Info
+ ****************************************************************************/
+
+/*
+ * Terastation Pro 2 hardware :
+ * - Marvell 88F5281-D0
+ * - Marvell 88SX6042 SATA controller (PCI)
+ * - Marvell 88E1118 Gigabit Ethernet PHY
+ * - 256KB NOR flash
+ * - 128MB of DDR RAM
+ * - PCIe port (not equipped)
+ */
+
+/*
+ * 256K NOR flash Device bus boot chip select
+ */
+
+#define TSP2_NOR_BOOT_BASE 0xf4000000
+#define TSP2_NOR_BOOT_SIZE SZ_256K
+
+/*****************************************************************************
+ * 256KB NOR Flash on BOOT Device
+ ****************************************************************************/
+
+static struct physmap_flash_data tsp2_nor_flash_data = {
+ .width = 1,
+};
+
+static struct resource tsp2_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = TSP2_NOR_BOOT_BASE,
+ .end = TSP2_NOR_BOOT_BASE + TSP2_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device tsp2_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &tsp2_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &tsp2_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+#define TSP2_PCI_SLOT0_OFFS 7
+#define TSP2_PCI_SLOT0_IRQ_PIN 11
+
+void __init tsp2_pci_preinit(void)
+{
+ int pin;
+
+ /*
+ * Configure PCI GPIO IRQ pins
+ */
+ pin = TSP2_PCI_SLOT0_IRQ_PIN;
+ if (gpio_request(pin, "PCI Int1") == 0) {
+ if (gpio_direction_input(pin) == 0) {
+ set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
+ } else {
+ printk(KERN_ERR "tsp2_pci_preinit failed "
+ "to set_irq_type pin %d\n", pin);
+ gpio_free(pin);
+ }
+ } else {
+ printk(KERN_ERR "tsp2_pci_preinit failed to "
+ "gpio_request %d\n", pin);
+ }
+}
+
+static int __init tsp2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * PCI IRQs are connected via GPIOs.
+ */
+ if (slot == TSP2_PCI_SLOT0_OFFS)
+ return gpio_to_irq(TSP2_PCI_SLOT0_IRQ_PIN);
+
+ return -1;
+}
+
+static struct hw_pci tsp2_pci __initdata = {
+ .nr_controllers = 2,
+ .preinit = tsp2_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = tsp2_pci_map_irq,
+};
+
+static int __init tsp2_pci_init(void)
+{
+ if (machine_is_terastation_pro2())
+ pci_common_init(&tsp2_pci);
+
+ return 0;
+}
+
+subsys_initcall(tsp2_pci_init);
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+static struct mv643xx_eth_platform_data tsp2_eth_data = {
+ .phy_addr = 0,
+};
+
+/*****************************************************************************
+ * RTC 5C372a on I2C bus
+ ****************************************************************************/
+
+#define TSP2_RTC_GPIO 9
+
+static struct i2c_board_info __initdata tsp2_i2c_rtc = {
+ I2C_BOARD_INFO("rs5c372a", 0x32),
+};
+
+/*****************************************************************************
+ * Terastation Pro II specific power off method via UART1-attached
+ * microcontroller
+ ****************************************************************************/
+
+#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
+
+static int tsp2_miconread(unsigned char *buf, int count)
+{
+ int i;
+ int timeout;
+
+ for (i = 0; i < count; i++) {
+ timeout = 10;
+
+ while (!(readl(UART1_REG(LSR)) & UART_LSR_DR)) {
+ if (--timeout == 0)
+ break;
+ udelay(1000);
+ }
+
+ if (timeout == 0)
+ break;
+ buf[i] = readl(UART1_REG(RX));
+ }
+
+ /* return read bytes */
+ return i;
+}
+
+static int tsp2_miconwrite(const unsigned char *buf, int count)
+{
+ int i = 0;
+
+ while (count--) {
+ while (!(readl(UART1_REG(LSR)) & UART_LSR_THRE))
+ barrier();
+ writel(buf[i++], UART1_REG(TX));
+ }
+
+ return 0;
+}
+
+static int tsp2_miconsend(const unsigned char *data, int count)
+{
+ int i;
+ unsigned char checksum = 0;
+ unsigned char recv_buf[40];
+ unsigned char send_buf[40];
+ unsigned char correct_ack[3];
+ int retry = 2;
+
+ /* Generate checksum */
+ for (i = 0; i < count; i++)
+ checksum -= data[i];
+
+ do {
+ /* Send data */
+ tsp2_miconwrite(data, count);
+
+ /* send checksum */
+ tsp2_miconwrite(&checksum, 1);
+
+ if (tsp2_miconread(recv_buf, sizeof(recv_buf)) <= 3) {
+ printk(KERN_ERR ">%s: receive failed.\n", __func__);
+
+ /* send preamble to clear the receive buffer */
+ memset(&send_buf, 0xff, sizeof(send_buf));
+ tsp2_miconwrite(send_buf, sizeof(send_buf));
+
+ /* make dummy reads */
+ mdelay(100);
+ tsp2_miconread(recv_buf, sizeof(recv_buf));
+ } else {
+ /* Generate expected ack */
+ correct_ack[0] = 0x01;
+ correct_ack[1] = data[1];
+ correct_ack[2] = 0x00;
+
+ /* checksum Check */
+ if ((recv_buf[0] + recv_buf[1] + recv_buf[2] +
+ recv_buf[3]) & 0xFF) {
+ printk(KERN_ERR ">%s: Checksum Error : "
+ "Received data[%02x, %02x, %02x, %02x]"
+ "\n", __func__, recv_buf[0],
+ recv_buf[1], recv_buf[2], recv_buf[3]);
+ } else {
+ /* Check Received Data */
+ if (correct_ack[0] == recv_buf[0] &&
+ correct_ack[1] == recv_buf[1] &&
+ correct_ack[2] == recv_buf[2]) {
+ /* Interval for next command */
+ mdelay(10);
+
+ /* Receive ACK */
+ return 0;
+ }
+ }
+ /* Received NAK or illegal Data */
+ printk(KERN_ERR ">%s: Error : NAK or Illegal Data "
+ "Received\n", __func__);
+ }
+ } while (retry--);
+
+ /* Interval for next command */
+ mdelay(10);
+
+ return -1;
+}
+
+static void tsp2_power_off(void)
+{
+ const unsigned char watchdogkill[] = {0x01, 0x35, 0x00};
+ const unsigned char shutdownwait[] = {0x00, 0x0c};
+ const unsigned char poweroff[] = {0x00, 0x06};
+ /* 38400 baud divisor */
+ const unsigned divisor = ((orion5x_tclk + (8 * 38400)) / (16 * 38400));
+
+ pr_info("%s: triggering power-off...\n", __func__);
+
+ /* hijack uart1 and reset into sane state (38400,8n1,even parity) */
+ writel(0x83, UART1_REG(LCR));
+ writel(divisor & 0xff, UART1_REG(DLL));
+ writel((divisor >> 8) & 0xff, UART1_REG(DLM));
+ writel(0x1b, UART1_REG(LCR));
+ writel(0x00, UART1_REG(IER));
+ writel(0x07, UART1_REG(FCR));
+ writel(0x00, UART1_REG(MCR));
+
+ /* Send the commands to shutdown the Terastation Pro II */
+ tsp2_miconsend(watchdogkill, sizeof(watchdogkill)) ;
+ tsp2_miconsend(shutdownwait, sizeof(shutdownwait)) ;
+ tsp2_miconsend(poweroff, sizeof(poweroff));
+}
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static struct orion5x_mpp_mode tsp2_mpp_modes[] __initdata = {
+ { 0, MPP_PCIE_RST_OUTn },
+ { 1, MPP_UNUSED },
+ { 2, MPP_UNUSED },
+ { 3, MPP_UNUSED },
+ { 4, MPP_NAND }, /* BOOT NAND Flash REn */
+ { 5, MPP_NAND }, /* BOOT NAND Flash WEn */
+ { 6, MPP_NAND }, /* BOOT NAND Flash HREn[0] */
+ { 7, MPP_NAND }, /* BOOT NAND Flash WEn[0] */
+ { 8, MPP_GPIO }, /* MICON int */
+ { 9, MPP_GPIO }, /* RTC int */
+ { 10, MPP_UNUSED },
+ { 11, MPP_GPIO }, /* PCI Int A */
+ { 12, MPP_UNUSED },
+ { 13, MPP_GPIO }, /* UPS on UART0 enable */
+ { 14, MPP_GPIO }, /* UPS low battery detection */
+ { 15, MPP_UNUSED },
+ { 16, MPP_UART }, /* UART1 RXD */
+ { 17, MPP_UART }, /* UART1 TXD */
+ { 18, MPP_UART }, /* UART1 CTSn */
+ { 19, MPP_UART }, /* UART1 RTSn */
+ { -1 },
+};
+
+static void __init tsp2_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(tsp2_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_setup_dev_boot_win(TSP2_NOR_BOOT_BASE,
+ TSP2_NOR_BOOT_SIZE);
+ platform_device_register(&tsp2_nor_flash);
+
+ orion5x_ehci0_init();
+ orion5x_eth_init(&tsp2_eth_data);
+ orion5x_i2c_init();
+ orion5x_uart0_init();
+ orion5x_uart1_init();
+
+ /* Get RTC IRQ and register the chip */
+ if (gpio_request(TSP2_RTC_GPIO, "rtc") == 0) {
+ if (gpio_direction_input(TSP2_RTC_GPIO) == 0)
+ tsp2_i2c_rtc.irq = gpio_to_irq(TSP2_RTC_GPIO);
+ else
+ gpio_free(TSP2_RTC_GPIO);
+ }
+ if (tsp2_i2c_rtc.irq == 0)
+ pr_warning("tsp2_init: failed to get RTC IRQ\n");
+ i2c_register_board_info(0, &tsp2_i2c_rtc, 1);
+
+ /* register Terastation Pro II specific power-off method */
+ pm_power_off = tsp2_power_off;
+}
+
+MACHINE_START(TERASTATION_PRO2, "Buffalo Terastation Pro II/Live")
+ /* Maintainer: Sylver Bruneau <sylver.bruneau@googlemail.com> */
+ .phys_io = ORION5X_REGS_PHYS_BASE,
+ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .init_machine = tsp2_init,
+ .map_io = orion5x_map_io,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/ts209-setup.c b/arch/arm/mach-orion5x/ts209-setup.c
index 9afb41ee6e07..9d6890514199 100644
--- a/arch/arm/mach-orion5x/ts209-setup.c
+++ b/arch/arm/mach-orion5x/ts209-setup.c
@@ -26,8 +26,10 @@
#include <asm/gpio.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
-#include <asm/arch/orion5x.h>
+#include <mach/orion5x.h>
#include "common.h"
+#include "mpp.h"
+#include "tsx09-common.h"
#define QNAP_TS209_NOR_BOOT_BASE 0xf4000000
#define QNAP_TS209_NOR_BOOT_SIZE SZ_8M
@@ -47,52 +49,54 @@
***************************************************************************/
static struct mtd_partition qnap_ts209_partitions[] = {
{
- .name = "U-Boot",
- .size = 0x00080000,
- .offset = 0x00780000,
- .mask_flags = MTD_WRITEABLE,
+ .name = "U-Boot",
+ .size = 0x00080000,
+ .offset = 0x00780000,
+ .mask_flags = MTD_WRITEABLE,
}, {
- .name = "Kernel",
- .size = 0x00200000,
- .offset = 0,
+ .name = "Kernel",
+ .size = 0x00200000,
+ .offset = 0,
}, {
- .name = "RootFS1",
- .size = 0x00400000,
- .offset = 0x00200000,
+ .name = "RootFS1",
+ .size = 0x00400000,
+ .offset = 0x00200000,
}, {
- .name = "RootFS2",
- .size = 0x00100000,
- .offset = 0x00600000,
+ .name = "RootFS2",
+ .size = 0x00100000,
+ .offset = 0x00600000,
}, {
- .name = "U-Boot Config",
- .size = 0x00020000,
- .offset = 0x00760000,
+ .name = "U-Boot Config",
+ .size = 0x00020000,
+ .offset = 0x00760000,
}, {
- .name = "NAS Config",
- .size = 0x00060000,
- .offset = 0x00700000,
- .mask_flags = MTD_WRITEABLE,
- }
+ .name = "NAS Config",
+ .size = 0x00060000,
+ .offset = 0x00700000,
+ .mask_flags = MTD_WRITEABLE,
+ },
};
static struct physmap_flash_data qnap_ts209_nor_flash_data = {
- .width = 1,
- .parts = qnap_ts209_partitions,
- .nr_parts = ARRAY_SIZE(qnap_ts209_partitions)
+ .width = 1,
+ .parts = qnap_ts209_partitions,
+ .nr_parts = ARRAY_SIZE(qnap_ts209_partitions)
};
static struct resource qnap_ts209_nor_flash_resource = {
- .flags = IORESOURCE_MEM,
- .start = QNAP_TS209_NOR_BOOT_BASE,
- .end = QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1,
+ .flags = IORESOURCE_MEM,
+ .start = QNAP_TS209_NOR_BOOT_BASE,
+ .end = QNAP_TS209_NOR_BOOT_BASE + QNAP_TS209_NOR_BOOT_SIZE - 1,
};
static struct platform_device qnap_ts209_nor_flash = {
- .name = "physmap-flash",
- .id = 0,
- .dev = { .platform_data = &qnap_ts209_nor_flash_data, },
- .resource = &qnap_ts209_nor_flash_resource,
- .num_resources = 1,
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &qnap_ts209_nor_flash_data,
+ },
+ .resource = &qnap_ts209_nor_flash_resource,
+ .num_resources = 1,
};
/*****************************************************************************
@@ -113,7 +117,7 @@ void __init qnap_ts209_pci_preinit(void)
pin = QNAP_TS209_PCI_SLOT0_IRQ_PIN;
if (gpio_request(pin, "PCI Int1") == 0) {
if (gpio_direction_input(pin) == 0) {
- set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+ set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "qnap_ts209_pci_preinit failed to "
"set_irq_type pin %d\n", pin);
@@ -127,7 +131,7 @@ void __init qnap_ts209_pci_preinit(void)
pin = QNAP_TS209_PCI_SLOT1_IRQ_PIN;
if (gpio_request(pin, "PCI Int2") == 0) {
if (gpio_direction_input(pin) == 0) {
- set_irq_type(gpio_to_irq(pin), IRQT_LOW);
+ set_irq_type(gpio_to_irq(pin), IRQ_TYPE_LEVEL_LOW);
} else {
printk(KERN_ERR "qnap_ts209_pci_preinit failed "
"to set_irq_type pin %d\n", pin);
@@ -164,12 +168,12 @@ static int __init qnap_ts209_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
}
static struct hw_pci qnap_ts209_pci __initdata = {
- .nr_controllers = 2,
- .preinit = qnap_ts209_pci_preinit,
- .swizzle = pci_std_swizzle,
- .setup = orion5x_pci_sys_setup,
- .scan = orion5x_pci_sys_scan_bus,
- .map_irq = qnap_ts209_pci_map_irq,
+ .nr_controllers = 2,
+ .preinit = qnap_ts209_pci_preinit,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = qnap_ts209_pci_map_irq,
};
static int __init qnap_ts209_pci_init(void)
@@ -183,96 +187,6 @@ static int __init qnap_ts209_pci_init(void)
subsys_initcall(qnap_ts209_pci_init);
/*****************************************************************************
- * Ethernet
- ****************************************************************************/
-
-static struct mv643xx_eth_platform_data qnap_ts209_eth_data = {
- .phy_addr = 8,
- .force_phy_addr = 1,
-};
-
-static int __init parse_hex_nibble(char n)
-{
- if (n >= '0' && n <= '9')
- return n - '0';
-
- if (n >= 'A' && n <= 'F')
- return n - 'A' + 10;
-
- if (n >= 'a' && n <= 'f')
- return n - 'a' + 10;
-
- return -1;
-}
-
-static int __init parse_hex_byte(const char *b)
-{
- int hi;
- int lo;
-
- hi = parse_hex_nibble(b[0]);
- lo = parse_hex_nibble(b[1]);
-
- if (hi < 0 || lo < 0)
- return -1;
-
- return (hi << 4) | lo;
-}
-
-static int __init check_mac_addr(const char *addr_str)
-{
- u_int8_t addr[6];
- int i;
-
- for (i = 0; i < 6; i++) {
- int byte;
-
- /*
- * Enforce "xx:xx:xx:xx:xx:xx\n" format.
- */
- if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n'))
- return -1;
-
- byte = parse_hex_byte(addr_str + (i * 3));
- if (byte < 0)
- return -1;
- addr[i] = byte;
- }
-
- printk(KERN_INFO "ts209: found ethernet mac address ");
- for (i = 0; i < 6; i++)
- printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n");
-
- memcpy(qnap_ts209_eth_data.mac_addr, addr, 6);
-
- return 0;
-}
-
-/*
- * The 'NAS Config' flash partition has an ext2 filesystem which
- * contains a file that has the ethernet MAC address in plain text
- * (format "xx:xx:xx:xx:xx:xx\n".)
- */
-static void __init ts209_find_mac_addr(void)
-{
- unsigned long addr;
-
- for (addr = 0x00700000; addr < 0x00760000; addr += 1024) {
- char *nor_page;
- int ret = 0;
-
- nor_page = ioremap(QNAP_TS209_NOR_BOOT_BASE + addr, 1024);
- if (nor_page != NULL) {
- ret = check_mac_addr(nor_page);
- iounmap(nor_page);
- }
-
- if (ret == 0)
- break;
- }
-}
-
-/*****************************************************************************
* RTC S35390A on I2C bus
****************************************************************************/
@@ -280,7 +194,7 @@ static void __init ts209_find_mac_addr(void)
static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = {
I2C_BOARD_INFO("s35390a", 0x30),
- .irq = 0,
+ .irq = 0,
};
/****************************************************************************
@@ -293,74 +207,67 @@ static struct i2c_board_info __initdata qnap_ts209_i2c_rtc = {
static struct gpio_keys_button qnap_ts209_buttons[] = {
{
- .code = KEY_RESTART,
+ .code = KEY_COPY,
.gpio = QNAP_TS209_GPIO_KEY_MEDIA,
.desc = "USB Copy Button",
.active_low = 1,
- },
- {
- .code = KEY_POWER,
+ }, {
+ .code = KEY_RESTART,
.gpio = QNAP_TS209_GPIO_KEY_RESET,
.desc = "Reset Button",
.active_low = 1,
- }
+ },
};
static struct gpio_keys_platform_data qnap_ts209_button_data = {
.buttons = qnap_ts209_buttons,
- .nbuttons = ARRAY_SIZE(qnap_ts209_buttons),
+ .nbuttons = ARRAY_SIZE(qnap_ts209_buttons),
};
static struct platform_device qnap_ts209_button_device = {
.name = "gpio-keys",
.id = -1,
.num_resources = 0,
- .dev = { .platform_data = &qnap_ts209_button_data, },
+ .dev = {
+ .platform_data = &qnap_ts209_button_data,
+ },
};
/*****************************************************************************
* SATA
****************************************************************************/
static struct mv_sata_platform_data qnap_ts209_sata_data = {
- .n_ports = 2,
+ .n_ports = 2,
};
/*****************************************************************************
* General Setup
****************************************************************************/
-
-static struct platform_device *qnap_ts209_devices[] __initdata = {
- &qnap_ts209_nor_flash,
- &qnap_ts209_button_device,
+static struct orion5x_mpp_mode ts209_mpp_modes[] __initdata = {
+ { 0, MPP_UNUSED },
+ { 1, MPP_GPIO }, /* USB copy button */
+ { 2, MPP_GPIO }, /* Load defaults button */
+ { 3, MPP_GPIO }, /* GPIO RTC */
+ { 4, MPP_UNUSED },
+ { 5, MPP_UNUSED },
+ { 6, MPP_GPIO }, /* PCI Int A */
+ { 7, MPP_GPIO }, /* PCI Int B */
+ { 8, MPP_UNUSED },
+ { 9, MPP_UNUSED },
+ { 10, MPP_UNUSED },
+ { 11, MPP_UNUSED },
+ { 12, MPP_SATA_LED }, /* SATA 0 presence */
+ { 13, MPP_SATA_LED }, /* SATA 1 presence */
+ { 14, MPP_SATA_LED }, /* SATA 0 active */
+ { 15, MPP_SATA_LED }, /* SATA 1 active */
+ { 16, MPP_UART }, /* UART1 RXD */
+ { 17, MPP_UART }, /* UART1 TXD */
+ { 18, MPP_GPIO }, /* SW_RST */
+ { 19, MPP_UNUSED },
+ { -1 },
};
-/*
- * QNAP TS-[12]09 specific power off method via UART1-attached PIC
- */
-
-#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
-
-static void qnap_ts209_power_off(void)
-{
- /* 19200 baud divisor */
- const unsigned divisor = ((ORION5X_TCLK + (8 * 19200)) / (16 * 19200));
-
- pr_info("%s: triggering power-off...\n", __func__);
-
- /* hijack uart1 and reset into sane state (19200,8n1) */
- orion5x_write(UART1_REG(LCR), 0x83);
- orion5x_write(UART1_REG(DLL), divisor & 0xff);
- orion5x_write(UART1_REG(DLM), (divisor >> 8) & 0xff);
- orion5x_write(UART1_REG(LCR), 0x03);
- orion5x_write(UART1_REG(IER), 0x00);
- orion5x_write(UART1_REG(FCR), 0x00);
- orion5x_write(UART1_REG(MCR), 0x00);
-
- /* send the power-off command 'A' to PIC */
- orion5x_write(UART1_REG(TX), 'A');
-}
-
static void __init qnap_ts209_init(void)
{
/*
@@ -368,51 +275,35 @@ static void __init qnap_ts209_init(void)
*/
orion5x_init();
- /*
- * Setup flash mapping
- */
- orion5x_setup_dev_boot_win(QNAP_TS209_NOR_BOOT_BASE,
- QNAP_TS209_NOR_BOOT_SIZE);
-
- /*
- * Open a special address decode windows for the PCIe WA.
- */
- orion5x_setup_pcie_wa_win(ORION5X_PCIE_WA_PHYS_BASE,
- ORION5X_PCIE_WA_SIZE);
+ orion5x_mpp_conf(ts209_mpp_modes);
/*
- * Setup Multiplexing Pins --
- * MPP[0] Reserved
- * MPP[1] USB copy button (0 active)
- * MPP[2] Load defaults button (0 active)
- * MPP[3] GPIO RTC
- * MPP[4-5] Reserved
- * MPP[6] PCI Int A
- * MPP[7] PCI Int B
- * MPP[8-11] Reserved
- * MPP[12] SATA 0 presence
- * MPP[13] SATA 1 presence
- * MPP[14] SATA 0 active
- * MPP[15] SATA 1 active
- * MPP[16] UART1 RXD
- * MPP[17] UART1 TXD
- * MPP[18] SW_RST (0 active)
- * MPP[19] Reserved
* MPP[20] PCI clock 0
* MPP[21] PCI clock 1
* MPP[22] USB 0 over current
* MPP[23-25] Reserved
*/
- orion5x_write(MPP_0_7_CTRL, 0x3);
- orion5x_write(MPP_8_15_CTRL, 0x55550000);
- orion5x_write(MPP_16_19_CTRL, 0x5500);
- orion5x_gpio_set_valid_pins(0x3cc0fff);
- /* register ts209 specific power-off method */
- pm_power_off = qnap_ts209_power_off;
+ /*
+ * Configure peripherals.
+ */
+ orion5x_setup_dev_boot_win(QNAP_TS209_NOR_BOOT_BASE,
+ QNAP_TS209_NOR_BOOT_SIZE);
+ platform_device_register(&qnap_ts209_nor_flash);
+
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ qnap_tsx09_find_mac_addr(QNAP_TS209_NOR_BOOT_BASE +
+ qnap_ts209_partitions[5].offset,
+ qnap_ts209_partitions[5].size);
+ orion5x_eth_init(&qnap_tsx09_eth_data);
+ orion5x_i2c_init();
+ orion5x_sata_init(&qnap_ts209_sata_data);
+ orion5x_uart0_init();
+ orion5x_uart1_init();
+ orion5x_xor_init();
- platform_add_devices(qnap_ts209_devices,
- ARRAY_SIZE(qnap_ts209_devices));
+ platform_device_register(&qnap_ts209_button_device);
/* Get RTC IRQ and register the chip */
if (gpio_request(TS209_RTC_GPIO, "rtc") == 0) {
@@ -425,14 +316,12 @@ static void __init qnap_ts209_init(void)
pr_warning("qnap_ts209_init: failed to get RTC IRQ\n");
i2c_register_board_info(0, &qnap_ts209_i2c_rtc, 1);
- ts209_find_mac_addr();
- orion5x_eth_init(&qnap_ts209_eth_data);
-
- orion5x_sata_init(&qnap_ts209_sata_data);
+ /* register tsx09 specific power-off method */
+ pm_power_off = qnap_tsx09_power_off;
}
MACHINE_START(TS209, "QNAP TS-109/TS-209")
- /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
+ /* Maintainer: Byron Bradley <byron.bbradley@gmail.com> */
.phys_io = ORION5X_REGS_PHYS_BASE,
.io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
.boot_params = 0x00000100,
diff --git a/arch/arm/mach-orion5x/ts409-setup.c b/arch/arm/mach-orion5x/ts409-setup.c
new file mode 100644
index 000000000000..d85588ac7ef8
--- /dev/null
+++ b/arch/arm/mach-orion5x/ts409-setup.c
@@ -0,0 +1,322 @@
+/*
+ * QNAP TS-409 Board Setup
+ *
+ * Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com>
+ *
+ * Copyright (C) 2008 Sylver Bruneau <sylver.bruneau@gmail.com>
+ * Copyright (C) 2008 Martin Michlmayr <tbm@cyrius.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/leds.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/serial_reg.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+#include "tsx09-common.h"
+
+/*****************************************************************************
+ * QNAP TS-409 Info
+ ****************************************************************************/
+
+/*
+ * QNAP TS-409 hardware :
+ * - Marvell 88F5281-D0
+ * - Marvell 88SX7042 SATA controller (PCIe)
+ * - Marvell 88E1118 Gigabit Ethernet PHY
+ * - RTC S35390A (@0x30) on I2C bus
+ * - 8MB NOR flash
+ * - 256MB of DDR-2 RAM
+ */
+
+/*
+ * 8MB NOR flash Device bus boot chip select
+ */
+
+#define QNAP_TS409_NOR_BOOT_BASE 0xff800000
+#define QNAP_TS409_NOR_BOOT_SIZE SZ_8M
+
+/****************************************************************************
+ * 8MiB NOR flash. The struct mtd_partition is not in the same order as the
+ * partitions on the device because we want to keep compatability with
+ * existing QNAP firmware.
+ *
+ * Layout as used by QNAP:
+ * [2] 0x00000000-0x00200000 : "Kernel"
+ * [3] 0x00200000-0x00600000 : "RootFS1"
+ * [4] 0x00600000-0x00700000 : "RootFS2"
+ * [6] 0x00700000-0x00760000 : "NAS Config" (read-only)
+ * [5] 0x00760000-0x00780000 : "U-Boot Config"
+ * [1] 0x00780000-0x00800000 : "U-Boot" (read-only)
+ ***************************************************************************/
+static struct mtd_partition qnap_ts409_partitions[] = {
+ {
+ .name = "U-Boot",
+ .size = 0x00080000,
+ .offset = 0x00780000,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "Kernel",
+ .size = 0x00200000,
+ .offset = 0,
+ }, {
+ .name = "RootFS1",
+ .size = 0x00400000,
+ .offset = 0x00200000,
+ }, {
+ .name = "RootFS2",
+ .size = 0x00100000,
+ .offset = 0x00600000,
+ }, {
+ .name = "U-Boot Config",
+ .size = 0x00020000,
+ .offset = 0x00760000,
+ }, {
+ .name = "NAS Config",
+ .size = 0x00060000,
+ .offset = 0x00700000,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct physmap_flash_data qnap_ts409_nor_flash_data = {
+ .width = 1,
+ .parts = qnap_ts409_partitions,
+ .nr_parts = ARRAY_SIZE(qnap_ts409_partitions)
+};
+
+static struct resource qnap_ts409_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = QNAP_TS409_NOR_BOOT_BASE,
+ .end = QNAP_TS409_NOR_BOOT_BASE + QNAP_TS409_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device qnap_ts409_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = { .platform_data = &qnap_ts409_nor_flash_data, },
+ .num_resources = 1,
+ .resource = &qnap_ts409_nor_flash_resource,
+};
+
+/*****************************************************************************
+ * PCI
+ ****************************************************************************/
+
+static int __init qnap_ts409_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * PCI isn't used on the TS-409
+ */
+ return -1;
+}
+
+static struct hw_pci qnap_ts409_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = qnap_ts409_pci_map_irq,
+};
+
+static int __init qnap_ts409_pci_init(void)
+{
+ if (machine_is_ts409())
+ pci_common_init(&qnap_ts409_pci);
+
+ return 0;
+}
+
+subsys_initcall(qnap_ts409_pci_init);
+
+/*****************************************************************************
+ * RTC S35390A on I2C bus
+ ****************************************************************************/
+
+#define TS409_RTC_GPIO 10
+
+static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = {
+ I2C_BOARD_INFO("s35390a", 0x30),
+};
+
+/*****************************************************************************
+ * LEDs attached to GPIO
+ ****************************************************************************/
+
+static struct gpio_led ts409_led_pins[] = {
+ {
+ .name = "ts409:red:sata1",
+ .gpio = 4,
+ .active_low = 1,
+ }, {
+ .name = "ts409:red:sata2",
+ .gpio = 5,
+ .active_low = 1,
+ }, {
+ .name = "ts409:red:sata3",
+ .gpio = 6,
+ .active_low = 1,
+ }, {
+ .name = "ts409:red:sata4",
+ .gpio = 7,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_led_platform_data ts409_led_data = {
+ .leds = ts409_led_pins,
+ .num_leds = ARRAY_SIZE(ts409_led_pins),
+};
+
+static struct platform_device ts409_leds = {
+ .name = "leds-gpio",
+ .id = -1,
+ .dev = {
+ .platform_data = &ts409_led_data,
+ },
+};
+
+/****************************************************************************
+ * GPIO Attached Keys
+ * Power button is attached to the PIC microcontroller
+ ****************************************************************************/
+
+#define QNAP_TS409_GPIO_KEY_RESET 14
+#define QNAP_TS409_GPIO_KEY_MEDIA 15
+
+static struct gpio_keys_button qnap_ts409_buttons[] = {
+ {
+ .code = KEY_RESTART,
+ .gpio = QNAP_TS409_GPIO_KEY_RESET,
+ .desc = "Reset Button",
+ .active_low = 1,
+ }, {
+ .code = KEY_COPY,
+ .gpio = QNAP_TS409_GPIO_KEY_MEDIA,
+ .desc = "USB Copy Button",
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data qnap_ts409_button_data = {
+ .buttons = qnap_ts409_buttons,
+ .nbuttons = ARRAY_SIZE(qnap_ts409_buttons),
+};
+
+static struct platform_device qnap_ts409_button_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .num_resources = 0,
+ .dev = {
+ .platform_data = &qnap_ts409_button_data,
+ },
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static struct orion5x_mpp_mode ts409_mpp_modes[] __initdata = {
+ { 0, MPP_UNUSED },
+ { 1, MPP_UNUSED },
+ { 2, MPP_UNUSED },
+ { 3, MPP_UNUSED },
+ { 4, MPP_GPIO }, /* HDD 1 status */
+ { 5, MPP_GPIO }, /* HDD 2 status */
+ { 6, MPP_GPIO }, /* HDD 3 status */
+ { 7, MPP_GPIO }, /* HDD 4 status */
+ { 8, MPP_UNUSED },
+ { 9, MPP_UNUSED },
+ { 10, MPP_GPIO }, /* RTC int */
+ { 11, MPP_UNUSED },
+ { 12, MPP_UNUSED },
+ { 13, MPP_UNUSED },
+ { 14, MPP_GPIO }, /* SW_RST */
+ { 15, MPP_GPIO }, /* USB copy button */
+ { 16, MPP_UART }, /* UART1 RXD */
+ { 17, MPP_UART }, /* UART1 TXD */
+ { 18, MPP_UNUSED },
+ { 19, MPP_UNUSED },
+ { -1 },
+};
+
+static void __init qnap_ts409_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(ts409_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_setup_dev_boot_win(QNAP_TS409_NOR_BOOT_BASE,
+ QNAP_TS409_NOR_BOOT_SIZE);
+ platform_device_register(&qnap_ts409_nor_flash);
+
+ orion5x_ehci0_init();
+ qnap_tsx09_find_mac_addr(QNAP_TS409_NOR_BOOT_BASE +
+ qnap_ts409_partitions[5].offset,
+ qnap_ts409_partitions[5].size);
+ orion5x_eth_init(&qnap_tsx09_eth_data);
+ orion5x_i2c_init();
+ orion5x_uart0_init();
+ orion5x_uart1_init();
+
+ platform_device_register(&qnap_ts409_button_device);
+
+ /* Get RTC IRQ and register the chip */
+ if (gpio_request(TS409_RTC_GPIO, "rtc") == 0) {
+ if (gpio_direction_input(TS409_RTC_GPIO) == 0)
+ qnap_ts409_i2c_rtc.irq = gpio_to_irq(TS409_RTC_GPIO);
+ else
+ gpio_free(TS409_RTC_GPIO);
+ }
+ if (qnap_ts409_i2c_rtc.irq == 0)
+ pr_warning("qnap_ts409_init: failed to get RTC IRQ\n");
+ i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1);
+ platform_device_register(&ts409_leds);
+
+ /* register tsx09 specific power-off method */
+ pm_power_off = qnap_tsx09_power_off;
+}
+
+MACHINE_START(TS409, "QNAP TS-409")
+ /* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> */
+ .phys_io = ORION5X_REGS_PHYS_BASE,
+ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .init_machine = qnap_ts409_init,
+ .map_io = orion5x_map_io,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/ts78xx-setup.c b/arch/arm/mach-orion5x/ts78xx-setup.c
new file mode 100644
index 000000000000..1368e9fd1a06
--- /dev/null
+++ b/arch/arm/mach-orion5x/ts78xx-setup.c
@@ -0,0 +1,277 @@
+/*
+ * arch/arm/mach-orion5x/ts78xx-setup.c
+ *
+ * Maintainer: Alexander Clouter <alex@digriz.org.uk>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ata_platform.h>
+#include <linux/m48t86.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+/*****************************************************************************
+ * TS-78xx Info
+ ****************************************************************************/
+
+/*
+ * FPGA - lives where the PCI bus would be at ORION5X_PCI_MEM_PHYS_BASE
+ */
+#define TS78XX_FPGA_REGS_PHYS_BASE 0xe8000000
+#define TS78XX_FPGA_REGS_VIRT_BASE 0xff900000
+#define TS78XX_FPGA_REGS_SIZE SZ_1M
+
+#define TS78XX_FPGA_REGS_SYSCON_ID (TS78XX_FPGA_REGS_VIRT_BASE | 0x000)
+#define TS78XX_FPGA_REGS_SYSCON_LCDI (TS78XX_FPGA_REGS_VIRT_BASE | 0x004)
+#define TS78XX_FPGA_REGS_SYSCON_LCDO (TS78XX_FPGA_REGS_VIRT_BASE | 0x008)
+
+#define TS78XX_FPGA_REGS_RTC_CTRL (TS78XX_FPGA_REGS_VIRT_BASE | 0x808)
+#define TS78XX_FPGA_REGS_RTC_DATA (TS78XX_FPGA_REGS_VIRT_BASE | 0x80c)
+
+/*
+ * 512kB NOR flash Device
+ */
+#define TS78XX_NOR_BOOT_BASE 0xff800000
+#define TS78XX_NOR_BOOT_SIZE SZ_512K
+
+/*****************************************************************************
+ * I/O Address Mapping
+ ****************************************************************************/
+static struct map_desc ts78xx_io_desc[] __initdata = {
+ {
+ .virtual = TS78XX_FPGA_REGS_VIRT_BASE,
+ .pfn = __phys_to_pfn(TS78XX_FPGA_REGS_PHYS_BASE),
+ .length = TS78XX_FPGA_REGS_SIZE,
+ .type = MT_DEVICE,
+ },
+};
+
+void __init ts78xx_map_io(void)
+{
+ orion5x_map_io();
+ iotable_init(ts78xx_io_desc, ARRAY_SIZE(ts78xx_io_desc));
+}
+
+/*****************************************************************************
+ * 512kB NOR Boot Flash - the chip is a M25P40
+ ****************************************************************************/
+static struct mtd_partition ts78xx_nor_boot_flash_resources[] = {
+ {
+ .name = "ts-bootrom",
+ .offset = 0,
+ /* only the first 256kB is used */
+ .size = SZ_256K,
+ .mask_flags = MTD_WRITEABLE,
+ },
+};
+
+static struct physmap_flash_data ts78xx_nor_boot_flash_data = {
+ .width = 1,
+ .parts = ts78xx_nor_boot_flash_resources,
+ .nr_parts = ARRAY_SIZE(ts78xx_nor_boot_flash_resources),
+};
+
+static struct resource ts78xx_nor_boot_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = TS78XX_NOR_BOOT_BASE,
+ .end = TS78XX_NOR_BOOT_BASE + TS78XX_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device ts78xx_nor_boot_flash = {
+ .name = "physmap-flash",
+ .id = -1,
+ .dev = {
+ .platform_data = &ts78xx_nor_boot_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &ts78xx_nor_boot_flash_resource,
+};
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+static struct mv643xx_eth_platform_data ts78xx_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(0),
+};
+
+/*****************************************************************************
+ * RTC M48T86 - nicked^Wborrowed from arch/arm/mach-ep93xx/ts72xx.c
+ ****************************************************************************/
+#ifdef CONFIG_RTC_DRV_M48T86
+static unsigned char ts78xx_rtc_readbyte(unsigned long addr)
+{
+ writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL);
+ return readb(TS78XX_FPGA_REGS_RTC_DATA);
+}
+
+static void ts78xx_rtc_writebyte(unsigned char value, unsigned long addr)
+{
+ writeb(addr, TS78XX_FPGA_REGS_RTC_CTRL);
+ writeb(value, TS78XX_FPGA_REGS_RTC_DATA);
+}
+
+static struct m48t86_ops ts78xx_rtc_ops = {
+ .readbyte = ts78xx_rtc_readbyte,
+ .writebyte = ts78xx_rtc_writebyte,
+};
+
+static struct platform_device ts78xx_rtc_device = {
+ .name = "rtc-m48t86",
+ .id = -1,
+ .dev = {
+ .platform_data = &ts78xx_rtc_ops,
+ },
+ .num_resources = 0,
+};
+
+/*
+ * TS uses some of the user storage space on the RTC chip so see if it is
+ * present; as it's an optional feature at purchase time and not all boards
+ * will have it present
+ *
+ * I've used the method TS use in their rtc7800.c example for the detection
+ *
+ * TODO: track down a guinea pig without an RTC to see if we can work out a
+ * better RTC detection routine
+ */
+static int __init ts78xx_rtc_init(void)
+{
+ unsigned char tmp_rtc0, tmp_rtc1;
+
+ tmp_rtc0 = ts78xx_rtc_readbyte(126);
+ tmp_rtc1 = ts78xx_rtc_readbyte(127);
+
+ ts78xx_rtc_writebyte(0x00, 126);
+ ts78xx_rtc_writebyte(0x55, 127);
+ if (ts78xx_rtc_readbyte(127) == 0x55) {
+ ts78xx_rtc_writebyte(0xaa, 127);
+ if (ts78xx_rtc_readbyte(127) == 0xaa
+ && ts78xx_rtc_readbyte(126) == 0x00) {
+ ts78xx_rtc_writebyte(tmp_rtc0, 126);
+ ts78xx_rtc_writebyte(tmp_rtc1, 127);
+ platform_device_register(&ts78xx_rtc_device);
+ return 1;
+ }
+ }
+
+ return 0;
+};
+#else
+static int __init ts78xx_rtc_init(void)
+{
+ return 0;
+}
+#endif
+
+/*****************************************************************************
+ * SATA
+ ****************************************************************************/
+static struct mv_sata_platform_data ts78xx_sata_data = {
+ .n_ports = 2,
+};
+
+/*****************************************************************************
+ * print some information regarding the board
+ ****************************************************************************/
+static void __init ts78xx_print_board_id(void)
+{
+ unsigned int board_info;
+
+ board_info = readl(TS78XX_FPGA_REGS_SYSCON_ID);
+ printk(KERN_INFO "TS-78xx Info: FPGA rev=%.2x, Board Magic=%.6x, ",
+ board_info & 0xff,
+ (board_info >> 8) & 0xffffff);
+ board_info = readl(TS78XX_FPGA_REGS_SYSCON_LCDI);
+ printk("JP1=%d, JP2=%d\n",
+ (board_info >> 30) & 0x1,
+ (board_info >> 31) & 0x1);
+};
+
+/*****************************************************************************
+ * General Setup
+ ****************************************************************************/
+static struct orion5x_mpp_mode ts78xx_mpp_modes[] __initdata = {
+ { 0, MPP_UNUSED },
+ { 1, MPP_GPIO }, /* JTAG Clock */
+ { 2, MPP_GPIO }, /* JTAG Data In */
+ { 3, MPP_GPIO }, /* Lat ECP2 256 FPGA - PB2B */
+ { 4, MPP_GPIO }, /* JTAG Data Out */
+ { 5, MPP_GPIO }, /* JTAG TMS */
+ { 6, MPP_GPIO }, /* Lat ECP2 256 FPGA - PB31A_CLK4+ */
+ { 7, MPP_GPIO }, /* Lat ECP2 256 FPGA - PB22B */
+ { 8, MPP_UNUSED },
+ { 9, MPP_UNUSED },
+ { 10, MPP_UNUSED },
+ { 11, MPP_UNUSED },
+ { 12, MPP_UNUSED },
+ { 13, MPP_UNUSED },
+ { 14, MPP_UNUSED },
+ { 15, MPP_UNUSED },
+ { 16, MPP_UART },
+ { 17, MPP_UART },
+ { 18, MPP_UART },
+ { 19, MPP_UART },
+ { -1 },
+};
+
+static void __init ts78xx_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ ts78xx_print_board_id();
+
+ orion5x_mpp_conf(ts78xx_mpp_modes);
+
+ /*
+ * MPP[20] PCI Clock Out 1
+ * MPP[21] PCI Clock Out 0
+ * MPP[22] Unused
+ * MPP[23] Unused
+ * MPP[24] Unused
+ * MPP[25] Unused
+ */
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_ehci1_init();
+ orion5x_eth_init(&ts78xx_eth_data);
+ orion5x_sata_init(&ts78xx_sata_data);
+ orion5x_uart0_init();
+ orion5x_uart1_init();
+ orion5x_xor_init();
+
+ orion5x_setup_dev_boot_win(TS78XX_NOR_BOOT_BASE,
+ TS78XX_NOR_BOOT_SIZE);
+ platform_device_register(&ts78xx_nor_boot_flash);
+
+ if (!ts78xx_rtc_init())
+ printk(KERN_INFO "TS-78xx RTC not detected or enabled\n");
+}
+
+MACHINE_START(TS78XX, "Technologic Systems TS-78xx SBC")
+ /* Maintainer: Alexander Clouter <alex@digriz.org.uk> */
+ .phys_io = ORION5X_REGS_PHYS_BASE,
+ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .init_machine = ts78xx_init,
+ .map_io = ts78xx_map_io,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/tsx09-common.c b/arch/arm/mach-orion5x/tsx09-common.c
new file mode 100644
index 000000000000..c9abb8fbfa70
--- /dev/null
+++ b/arch/arm/mach-orion5x/tsx09-common.c
@@ -0,0 +1,134 @@
+/*
+ * QNAP TS-x09 Boards common functions
+ *
+ * Maintainers: Lennert Buytenhek <buytenh@marvell.com>
+ * Byron Bradley <byron.bbradley@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/timex.h>
+#include <linux/serial_reg.h>
+#include "tsx09-common.h"
+#include "common.h"
+
+/*****************************************************************************
+ * QNAP TS-x09 specific power off method via UART1-attached PIC
+ ****************************************************************************/
+
+#define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2))
+
+void qnap_tsx09_power_off(void)
+{
+ /* 19200 baud divisor */
+ const unsigned divisor = ((orion5x_tclk + (8 * 19200)) / (16 * 19200));
+
+ pr_info("%s: triggering power-off...\n", __func__);
+
+ /* hijack uart1 and reset into sane state (19200,8n1) */
+ writel(0x83, UART1_REG(LCR));
+ writel(divisor & 0xff, UART1_REG(DLL));
+ writel((divisor >> 8) & 0xff, UART1_REG(DLM));
+ writel(0x03, UART1_REG(LCR));
+ writel(0x00, UART1_REG(IER));
+ writel(0x00, UART1_REG(FCR));
+ writel(0x00, UART1_REG(MCR));
+
+ /* send the power-off command 'A' to PIC */
+ writel('A', UART1_REG(TX));
+}
+
+/*****************************************************************************
+ * Ethernet
+ ****************************************************************************/
+
+struct mv643xx_eth_platform_data qnap_tsx09_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_ADDR(8),
+};
+
+static int __init qnap_tsx09_parse_hex_nibble(char n)
+{
+ if (n >= '0' && n <= '9')
+ return n - '0';
+
+ if (n >= 'A' && n <= 'F')
+ return n - 'A' + 10;
+
+ if (n >= 'a' && n <= 'f')
+ return n - 'a' + 10;
+
+ return -1;
+}
+
+static int __init qnap_tsx09_parse_hex_byte(const char *b)
+{
+ int hi;
+ int lo;
+
+ hi = qnap_tsx09_parse_hex_nibble(b[0]);
+ lo = qnap_tsx09_parse_hex_nibble(b[1]);
+
+ if (hi < 0 || lo < 0)
+ return -1;
+
+ return (hi << 4) | lo;
+}
+
+static int __init qnap_tsx09_check_mac_addr(const char *addr_str)
+{
+ u_int8_t addr[6];
+ int i;
+
+ for (i = 0; i < 6; i++) {
+ int byte;
+
+ /*
+ * Enforce "xx:xx:xx:xx:xx:xx\n" format.
+ */
+ if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n'))
+ return -1;
+
+ byte = qnap_tsx09_parse_hex_byte(addr_str + (i * 3));
+ if (byte < 0)
+ return -1;
+ addr[i] = byte;
+ }
+
+ printk(KERN_INFO "tsx09: found ethernet mac address ");
+ for (i = 0; i < 6; i++)
+ printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n");
+
+ memcpy(qnap_tsx09_eth_data.mac_addr, addr, 6);
+
+ return 0;
+}
+
+/*
+ * The 'NAS Config' flash partition has an ext2 filesystem which
+ * contains a file that has the ethernet MAC address in plain text
+ * (format "xx:xx:xx:xx:xx:xx\n").
+ */
+void __init qnap_tsx09_find_mac_addr(u32 mem_base, u32 size)
+{
+ unsigned long addr;
+
+ for (addr = mem_base; addr < (mem_base + size); addr += 1024) {
+ char *nor_page;
+ int ret = 0;
+
+ nor_page = ioremap(addr, 1024);
+ if (nor_page != NULL) {
+ ret = qnap_tsx09_check_mac_addr(nor_page);
+ iounmap(nor_page);
+ }
+
+ if (ret == 0)
+ break;
+ }
+}
diff --git a/arch/arm/mach-orion5x/tsx09-common.h b/arch/arm/mach-orion5x/tsx09-common.h
new file mode 100644
index 000000000000..0984264616f0
--- /dev/null
+++ b/arch/arm/mach-orion5x/tsx09-common.h
@@ -0,0 +1,20 @@
+#ifndef __ARCH_ORION5X_TSX09_COMMON_H
+#define __ARCH_ORION5X_TSX09_COMMON_H
+
+/*
+ * QNAP TS-x09 Boards power-off function
+ */
+extern void qnap_tsx09_power_off(void);
+
+/*
+ * QNAP TS-x09 Boards function to find Ethernet MAC address in flash memory
+ */
+extern void __init qnap_tsx09_find_mac_addr(u32 mem_base, u32 size);
+
+/*
+ * QNAP TS-x09 Boards ethernet declaration
+ */
+extern struct mv643xx_eth_platform_data qnap_tsx09_eth_data;
+
+
+#endif
diff --git a/arch/arm/mach-orion5x/wnr854t-setup.c b/arch/arm/mach-orion5x/wnr854t-setup.c
new file mode 100644
index 000000000000..7ddc22c2bb54
--- /dev/null
+++ b/arch/arm/mach-orion5x/wnr854t-setup.c
@@ -0,0 +1,167 @@
+/*
+ * arch/arm/mach-orion5x/wnr854t-setup.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct orion5x_mpp_mode wnr854t_mpp_modes[] __initdata = {
+ { 0, MPP_GPIO }, /* Power LED green (0=on) */
+ { 1, MPP_GPIO }, /* Reset Button (0=off) */
+ { 2, MPP_GPIO }, /* Power LED blink (0=off) */
+ { 3, MPP_GPIO }, /* WAN Status LED amber (0=off) */
+ { 4, MPP_GPIO }, /* PCI int */
+ { 5, MPP_GPIO }, /* ??? */
+ { 6, MPP_GPIO }, /* ??? */
+ { 7, MPP_GPIO }, /* ??? */
+ { 8, MPP_UNUSED }, /* ??? */
+ { 9, MPP_GIGE }, /* GE_RXERR */
+ { 10, MPP_UNUSED }, /* ??? */
+ { 11, MPP_UNUSED }, /* ??? */
+ { 12, MPP_GIGE }, /* GE_TXD[4] */
+ { 13, MPP_GIGE }, /* GE_TXD[5] */
+ { 14, MPP_GIGE }, /* GE_TXD[6] */
+ { 15, MPP_GIGE }, /* GE_TXD[7] */
+ { 16, MPP_GIGE }, /* GE_RXD[4] */
+ { 17, MPP_GIGE }, /* GE_RXD[5] */
+ { 18, MPP_GIGE }, /* GE_RXD[6] */
+ { 19, MPP_GIGE }, /* GE_RXD[7] */
+ { -1 },
+};
+
+/*
+ * 8M NOR flash Device bus boot chip select
+ */
+#define WNR854T_NOR_BOOT_BASE 0xf4000000
+#define WNR854T_NOR_BOOT_SIZE SZ_8M
+
+static struct mtd_partition wnr854t_nor_flash_partitions[] = {
+ {
+ .name = "kernel",
+ .offset = 0x00000000,
+ .size = 0x00100000,
+ }, {
+ .name = "rootfs",
+ .offset = 0x00100000,
+ .size = 0x00660000,
+ }, {
+ .name = "uboot",
+ .offset = 0x00760000,
+ .size = 0x00040000,
+ },
+};
+
+static struct physmap_flash_data wnr854t_nor_flash_data = {
+ .width = 2,
+ .parts = wnr854t_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(wnr854t_nor_flash_partitions),
+};
+
+static struct resource wnr854t_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = WNR854T_NOR_BOOT_BASE,
+ .end = WNR854T_NOR_BOOT_BASE + WNR854T_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device wnr854t_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &wnr854t_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &wnr854t_nor_flash_resource,
+};
+
+static struct mv643xx_eth_platform_data wnr854t_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_NONE,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static void __init wnr854t_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(wnr854t_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_eth_init(&wnr854t_eth_data);
+ orion5x_uart0_init();
+
+ orion5x_setup_dev_boot_win(WNR854T_NOR_BOOT_BASE,
+ WNR854T_NOR_BOOT_SIZE);
+ platform_device_register(&wnr854t_nor_flash);
+}
+
+static int __init wnr854t_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * Mini-PCI slot.
+ */
+ if (slot == 7)
+ return gpio_to_irq(4);
+
+ return -1;
+}
+
+static struct hw_pci wnr854t_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = wnr854t_pci_map_irq,
+};
+
+static int __init wnr854t_pci_init(void)
+{
+ if (machine_is_wnr854t())
+ pci_common_init(&wnr854t_pci);
+
+ return 0;
+}
+subsys_initcall(wnr854t_pci_init);
+
+MACHINE_START(WNR854T, "Netgear WNR854T")
+ /* Maintainer: Imre Kaloz <kaloz@openwrt.org> */
+ .phys_io = ORION5X_REGS_PHYS_BASE,
+ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .init_machine = wnr854t_init,
+ .map_io = orion5x_map_io,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END
diff --git a/arch/arm/mach-orion5x/wrt350n-v2-setup.c b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
new file mode 100644
index 000000000000..9a4fd5256462
--- /dev/null
+++ b/arch/arm/mach-orion5x/wrt350n-v2-setup.c
@@ -0,0 +1,176 @@
+/*
+ * arch/arm/mach-orion5x/wrt350n-v2-setup.c
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/pci.h>
+#include <linux/irq.h>
+#include <linux/delay.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mv643xx_eth.h>
+#include <linux/ethtool.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/pci.h>
+#include <mach/orion5x.h>
+#include "common.h"
+#include "mpp.h"
+
+static struct orion5x_mpp_mode wrt350n_v2_mpp_modes[] __initdata = {
+ { 0, MPP_GPIO }, /* Power LED green (0=on) */
+ { 1, MPP_GPIO }, /* Security LED (0=on) */
+ { 2, MPP_GPIO }, /* Internal Button (0=on) */
+ { 3, MPP_GPIO }, /* Reset Button (0=on) */
+ { 4, MPP_GPIO }, /* PCI int */
+ { 5, MPP_GPIO }, /* Power LED orange (0=on) */
+ { 6, MPP_GPIO }, /* USB LED (0=on) */
+ { 7, MPP_GPIO }, /* Wireless LED (0=on) */
+ { 8, MPP_UNUSED }, /* ??? */
+ { 9, MPP_GIGE }, /* GE_RXERR */
+ { 10, MPP_UNUSED }, /* ??? */
+ { 11, MPP_UNUSED }, /* ??? */
+ { 12, MPP_GIGE }, /* GE_TXD[4] */
+ { 13, MPP_GIGE }, /* GE_TXD[5] */
+ { 14, MPP_GIGE }, /* GE_TXD[6] */
+ { 15, MPP_GIGE }, /* GE_TXD[7] */
+ { 16, MPP_GIGE }, /* GE_RXD[4] */
+ { 17, MPP_GIGE }, /* GE_RXD[5] */
+ { 18, MPP_GIGE }, /* GE_RXD[6] */
+ { 19, MPP_GIGE }, /* GE_RXD[7] */
+ { -1 },
+};
+
+/*
+ * 8M NOR flash Device bus boot chip select
+ */
+#define WRT350N_V2_NOR_BOOT_BASE 0xf4000000
+#define WRT350N_V2_NOR_BOOT_SIZE SZ_8M
+
+static struct mtd_partition wrt350n_v2_nor_flash_partitions[] = {
+ {
+ .name = "kernel",
+ .offset = 0x00000000,
+ .size = 0x00760000,
+ }, {
+ .name = "rootfs",
+ .offset = 0x001a0000,
+ .size = 0x005c0000,
+ }, {
+ .name = "lang",
+ .offset = 0x00760000,
+ .size = 0x00040000,
+ }, {
+ .name = "nvram",
+ .offset = 0x007a0000,
+ .size = 0x00020000,
+ }, {
+ .name = "u-boot",
+ .offset = 0x007c0000,
+ .size = 0x00040000,
+ },
+};
+
+static struct physmap_flash_data wrt350n_v2_nor_flash_data = {
+ .width = 1,
+ .parts = wrt350n_v2_nor_flash_partitions,
+ .nr_parts = ARRAY_SIZE(wrt350n_v2_nor_flash_partitions),
+};
+
+static struct resource wrt350n_v2_nor_flash_resource = {
+ .flags = IORESOURCE_MEM,
+ .start = WRT350N_V2_NOR_BOOT_BASE,
+ .end = WRT350N_V2_NOR_BOOT_BASE + WRT350N_V2_NOR_BOOT_SIZE - 1,
+};
+
+static struct platform_device wrt350n_v2_nor_flash = {
+ .name = "physmap-flash",
+ .id = 0,
+ .dev = {
+ .platform_data = &wrt350n_v2_nor_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &wrt350n_v2_nor_flash_resource,
+};
+
+static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = {
+ .phy_addr = MV643XX_ETH_PHY_NONE,
+ .speed = SPEED_1000,
+ .duplex = DUPLEX_FULL,
+};
+
+static void __init wrt350n_v2_init(void)
+{
+ /*
+ * Setup basic Orion functions. Need to be called early.
+ */
+ orion5x_init();
+
+ orion5x_mpp_conf(wrt350n_v2_mpp_modes);
+
+ /*
+ * Configure peripherals.
+ */
+ orion5x_ehci0_init();
+ orion5x_eth_init(&wrt350n_v2_eth_data);
+ orion5x_uart0_init();
+
+ orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE,
+ WRT350N_V2_NOR_BOOT_SIZE);
+ platform_device_register(&wrt350n_v2_nor_flash);
+}
+
+static int __init wrt350n_v2_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ int irq;
+
+ /*
+ * Check for devices with hard-wired IRQs.
+ */
+ irq = orion5x_pci_map_irq(dev, slot, pin);
+ if (irq != -1)
+ return irq;
+
+ /*
+ * Mini-PCI slot.
+ */
+ if (slot == 7)
+ return gpio_to_irq(4);
+
+ return -1;
+}
+
+static struct hw_pci wrt350n_v2_pci __initdata = {
+ .nr_controllers = 2,
+ .swizzle = pci_std_swizzle,
+ .setup = orion5x_pci_sys_setup,
+ .scan = orion5x_pci_sys_scan_bus,
+ .map_irq = wrt350n_v2_pci_map_irq,
+};
+
+static int __init wrt350n_v2_pci_init(void)
+{
+ if (machine_is_wrt350n_v2())
+ pci_common_init(&wrt350n_v2_pci);
+
+ return 0;
+}
+subsys_initcall(wrt350n_v2_pci_init);
+
+MACHINE_START(WRT350N_V2, "Linksys WRT350N v2")
+ /* Maintainer: Lennert Buytenhek <buytenh@marvell.com> */
+ .phys_io = ORION5X_REGS_PHYS_BASE,
+ .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC,
+ .boot_params = 0x00000100,
+ .init_machine = wrt350n_v2_init,
+ .map_io = orion5x_map_io,
+ .init_irq = orion5x_init_irq,
+ .timer = &orion5x_timer,
+ .fixup = tag_fixup_mem32,
+MACHINE_END