diff -ruN a/arch/arm/Kconfig b/arch/arm/Kconfig --- a/arch/arm/Kconfig 2018-10-20 01:52:38.000000000 -0600 +++ b/arch/arm/Kconfig 2018-10-27 18:30:55.998359333 -0600 @@ -519,6 +519,21 @@ help Support for the Marvell Dove SoC 88AP510 +config ARCH_KIRKWOOD + bool "Marvell Kirkwood" + select ARCH_REQUIRE_GPIOLIB + select CPU_FEROCEON + select GENERIC_CLOCKEVENTS + select MVEBU_MBUS + select PCI + select PCI_QUIRKS + select PINCTRL + select PINCTRL_KIRKWOOD + select PLAT_ORION_LEGACY + help + Support for the following Marvell Kirkwood series SoCs: + 88F6180, 88F6192 and 88F6281. + config ARCH_MV78XX0 bool "Marvell MV78xx0" select ARCH_REQUIRE_GPIOLIB @@ -854,6 +869,8 @@ source "arch/arm/mach-keystone/Kconfig" +source "arch/arm/mach-kirkwood/Kconfig" + source "arch/arm/mach-ks8695/Kconfig" source "arch/arm/mach-meson/Kconfig" diff -ruN a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug --- a/arch/arm/Kconfig.debug 2018-10-20 01:52:38.000000000 -0600 +++ b/arch/arm/Kconfig.debug 2018-10-27 18:30:56.002359313 -0600 @@ -1360,7 +1360,7 @@ def_bool ARCH_DOVE || ARCH_EBSA110 || \ (FOOTBRIDGE && !DEBUG_DC21285_PORT) || \ ARCH_GEMINI || ARCH_IOP13XX || ARCH_IOP32X || \ - ARCH_IOP33X || ARCH_IXP4XX || \ + ARCH_IOP33X || ARCH_IXP4XX || ARCH_KIRKWOOD || \ ARCH_LPC32XX || ARCH_MV78XX0 || ARCH_ORION5X || ARCH_RPC config DEBUG_UART_PHYS @@ -1439,7 +1439,7 @@ default 0xf040ab00 if DEBUG_BRCMSTB_UART default 0xf1012000 if DEBUG_MVEBU_UART0_ALTERNATE default 0xf1012100 if DEBUG_MVEBU_UART1_ALTERNATE - default 0xf1012000 if ARCH_DOVE || ARCH_MV78XX0 || \ + default 0xf1012000 if ARCH_DOVE || ARCH_KIRKWOOD || ARCH_MV78XX0 || \ ARCH_ORION5X default 0xf7fc9000 if DEBUG_BERLIN_UART default 0xf8b00000 if DEBUG_HIX5HD2_UART @@ -1540,6 +1540,7 @@ default 0xfec90000 if DEBUG_RK32_UART2 default 0xfed0c000 if DEBUG_DAVINCI_DA8XX_UART1 default 0xfed0d000 if DEBUG_DAVINCI_DA8XX_UART2 + default 0xfed12000 if ARCH_KIRKWOOD default 0xfed60000 if DEBUG_RK29_UART0 default 0xfed64000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2 default 0xfed68000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3 diff -ruN a/arch/arm/Makefile b/arch/arm/Makefile --- a/arch/arm/Makefile 2018-10-20 01:52:38.000000000 -0600 +++ b/arch/arm/Makefile 2018-10-27 18:30:56.002359313 -0600 @@ -178,6 +178,7 @@ machine-$(CONFIG_ARCH_IOP33X) += iop33x machine-$(CONFIG_ARCH_IXP4XX) += ixp4xx machine-$(CONFIG_ARCH_KEYSTONE) += keystone +machine-$(CONFIG_ARCH_KIRKWOOD) += kirkwood machine-$(CONFIG_ARCH_KS8695) += ks8695 machine-$(CONFIG_ARCH_LPC18XX) += lpc18xx machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx diff -ruN a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig --- a/arch/arm/mach-kirkwood/Kconfig 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/Kconfig 2018-10-27 18:30:56.002359313 -0600 @@ -0,0 +1,258 @@ +if ARCH_KIRKWOOD + +menu "Marvell Kirkwood Implementations" + +config KIRKWOOD_LEGACY + bool + +config MACH_D2NET_V2 + bool "LaCie d2 Network v2 NAS Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + LaCie d2 Network v2 NAS. + +config MACH_DOCKSTAR + bool "Seagate FreeAgent DockStar" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Seagate FreeAgent DockStar. + +config MACH_ESATA_SHEEVAPLUG + bool "Marvell eSATA SheevaPlug Reference Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Marvell eSATA SheevaPlug Reference Board. + +config MACH_GURUPLUG + bool "Marvell GuruPlug Reference Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Marvell GuruPlug Reference Board. + +config MACH_DREAMPLUG + bool "Marvell DreamPlug Reference Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Marvell DreamPlug Reference Board. + +config MACH_INETSPACE_V2 + bool "LaCie Internet Space v2 NAS Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + LaCie Internet Space v2 NAS. + +config MACH_MV88F6281GTW_GE + bool "Marvell 88F6281 GTW GE Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Marvell 88F6281 GTW GE Board. + +config MACH_NET2BIG_V2 + bool "LaCie 2Big Network v2 NAS Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + LaCie 2Big Network v2 NAS. + +config MACH_NET5BIG_V2 + bool "LaCie 5Big Network v2 NAS Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + LaCie 5Big Network v2 NAS. + +config MACH_NETSPACE_MAX_V2 + bool "LaCie Network Space Max v2 NAS Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + LaCie Network Space Max v2 NAS. + +config MACH_NETSPACE_V2 + bool "LaCie Network Space v2 NAS Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + LaCie Network Space v2 NAS. + +config MACH_OPENRD + select KIRKWOOD_LEGACY + bool + +config MACH_OPENRD_BASE + bool "Marvell OpenRD Base Board" + select MACH_OPENRD + help + Say 'Y' here if you want your kernel to support the + Marvell OpenRD Base Board. + +config MACH_OPENRD_CLIENT + bool "Marvell OpenRD Client Board" + select MACH_OPENRD + help + Say 'Y' here if you want your kernel to support the + Marvell OpenRD Client Board. + +config MACH_OPENRD_ULTIMATE + bool "Marvell OpenRD Ultimate Board" + select MACH_OPENRD + help + Say 'Y' here if you want your kernel to support the + Marvell OpenRD Ultimate Board. + +config MACH_BUBBA3 + bool "Bubba3 miniserver" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Bubba3 miniserver. + +config MACH_RD88F6192_NAS + bool "Marvell RD-88F6192-NAS Reference Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Marvell RD-88F6192-NAS Reference Board. + +config MACH_RD88F6281 + bool "Marvell RD-88F6281 Reference Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Marvell RD-88F6281 Reference Board. + +config MACH_SHEEVAPLUG + bool "Marvell SheevaPlug Reference Board" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Marvell SheevaPlug Reference Board. + +config MACH_T5325 + bool "HP t5325 Thin Client" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + HP t5325 Thin Client. + +config MACH_TS219 + bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and + TS-219P+ Turbo NAS devices. + +config MACH_TS41X + bool "QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo NAS" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + QNAP TS-410, TS-410U, TS-419P, TS-419P+ and TS-419U Turbo + NAS devices. + +config MACH_GOFLEXNET + bool "Seagate GoFlex Net" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Seagate GoFlex Net. + +config MACH_GOFLEXHOME + bool "Seagate GoFlex Home" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Seagate GoFlex Home. + +config MACH_ICONNECT + bool "Iomega iConnect Wireless" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Iomega iConnect Wireless. + +config MACH_POGOPLUGV4 + bool "Pogoplug Series 4" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Pogoplug Series 4. + +config MACH_POGO_E02 + bool "CE Pogoplug E02" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + CloudEngines Pogoplug e02. + +config MACH_NAS6210 + bool "RaidSonic ICY BOX IB-NAS6210" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + RaidSonic ICY BOX IB-NAS6210 device. + +config MACH_TOPKICK + bool "USI Topkick" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + USI Topkick. + +config MACH_IONICS_STRATUS + bool "Ionics Stratus" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + Ionics Stratus. + +config MACH_NSA310 + bool "ZyXEL NSA310 1-Bay Power Media Server" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + ZyXEL NSA310. + +config MACH_NSA320 + bool "ZyXEL NSA320 2-Bay Power Media Server" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + ZyXel NSA320. + +config MACH_NSA325 + bool "ZyXEL NSA325 2-Bay Power Media Server" + select KIRKWOOD_LEGACY + help + Say 'Y' here if you want your kernel to support the + ZyXel NSA325. + +comment "Device tree entries" + +config ARCH_KIRKWOOD_DT + bool "Marvell Kirkwood Flattened Device Tree" + select KIRKWOOD_CLK + select OF_IRQ + select ORION_IRQCHIP + select ORION_TIMER + select POWER_SUPPLY + select POWER_RESET + select POWER_RESET_GPIO + select REGULATOR + select REGULATOR_FIXED_VOLTAGE + select USE_OF + help + Say 'Y' here if you want your kernel to support the + Marvell Kirkwood using flattened device tree. + +endmenu + +endif diff -ruN a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile --- a/arch/arm/mach-kirkwood/Makefile 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/Makefile 2018-10-27 18:30:56.002359313 -0600 @@ -0,0 +1,35 @@ +obj-$(CONFIG_KIRKWOOD_LEGACY) += irq.o mpp.o common.o pcie.o +obj-$(CONFIG_PM) += pm.o + +obj-$(CONFIG_MACH_D2NET_V2) += d2net_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_DOCKSTAR) += dockstar-setup.o +obj-$(CONFIG_MACH_ESATA_SHEEVAPLUG) += sheevaplug-setup.o +obj-$(CONFIG_MACH_GURUPLUG) += guruplug-setup.o +obj-$(CONFIG_MACH_DREAMPLUG) += guruplug-setup.o +obj-$(CONFIG_MACH_INETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_MV88F6281GTW_GE) += mv88f6281gtw_ge-setup.o +obj-$(CONFIG_MACH_NET2BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_NET5BIG_V2) += netxbig_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_OPENRD) += openrd-setup.o +obj-$(CONFIG_MACH_NETSPACE_MAX_V2) += netspace_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_NETSPACE_V2) += netspace_v2-setup.o lacie_v2-common.o +obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6192-nas-setup.o +obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o +obj-$(CONFIG_MACH_SHEEVAPLUG) += sheevaplug-setup.o +obj-$(CONFIG_MACH_T5325) += t5325-setup.o +obj-$(CONFIG_MACH_TS219) += ts219-setup.o tsx1x-common.o +obj-$(CONFIG_MACH_TS41X) += ts41x-setup.o tsx1x-common.o +obj-$(CONFIG_MACH_GOFLEXNET) += goflexnet-setup.o +obj-$(CONFIG_MACH_GOFLEXHOME) += goflexhome-setup.o +obj-$(CONFIG_MACH_ICONNECT) += iconnect-setup.o +obj-$(CONFIG_MACH_POGOPLUGV4) += pogoplugv4-setup.o +obj-$(CONFIG_MACH_POGO_E02) += pogo_e02-setup.o +obj-$(CONFIG_MACH_NAS6210) += nas6210-setup.o +obj-$(CONFIG_MACH_TOPKICK) += topkick-setup.o +obj-$(CONFIG_MACH_IONICS_STRATUS) += ionics-stratus-setup.o +obj-$(CONFIG_MACH_BUBBA3) += bubba3-setup.o bubba3-gpio.o +obj-$(CONFIG_MACH_NSA310) += nsa310-setup.o +obj-$(CONFIG_MACH_NSA320) += nsa320-setup.o +obj-$(CONFIG_MACH_NSA325) += nsa325-setup.o + +obj-$(CONFIG_ARCH_KIRKWOOD_DT) += board-dt.o diff -ruN a/arch/arm/mach-kirkwood/Makefile.boot b/arch/arm/mach-kirkwood/Makefile.boot --- a/arch/arm/mach-kirkwood/Makefile.boot 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/Makefile.boot 2018-10-27 18:30:56.002359313 -0600 @@ -0,0 +1,3 @@ + zreladdr-y += 0x00008000 +params_phys-y := 0x00000100 +initrd_phys-y := 0x00800000 diff -ruN a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c --- a/arch/arm/mach-kirkwood/board-dt.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/board-dt.c 2018-10-27 18:30:56.002359313 -0600 @@ -0,0 +1,223 @@ +/* + * Copyright 2012 (C), Jason Cooper + * + * arch/arm/mach-kirkwood/board-dt.c + * + * Flattened Device Tree board initialization + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "pm.h" + +static struct map_desc kirkwood_io_desc[] __initdata = { + { + .virtual = (unsigned long) KIRKWOOD_REGS_VIRT_BASE, + .pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE), + .length = KIRKWOOD_REGS_SIZE, + .type = MT_DEVICE, + }, +}; + +static void __init kirkwood_map_io(void) +{ + iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc)); +} + +static struct resource kirkwood_cpufreq_resources[] = { + [0] = { + .start = CPU_CONTROL_PHYS, + .end = CPU_CONTROL_PHYS + 3, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device kirkwood_cpufreq_device = { + .name = "kirkwood-cpufreq", + .id = -1, + .num_resources = ARRAY_SIZE(kirkwood_cpufreq_resources), + .resource = kirkwood_cpufreq_resources, +}; + +static void __init kirkwood_cpufreq_init(void) +{ + platform_device_register(&kirkwood_cpufreq_device); +} + +static struct resource kirkwood_cpuidle_resource[] = { + { + .flags = IORESOURCE_MEM, + .start = DDR_OPERATION_BASE, + .end = DDR_OPERATION_BASE + 3, + }, +}; + +static struct platform_device kirkwood_cpuidle = { + .name = "kirkwood_cpuidle", + .id = -1, + .resource = kirkwood_cpuidle_resource, + .num_resources = 1, +}; + +static void __init kirkwood_cpuidle_init(void) +{ + platform_device_register(&kirkwood_cpuidle); +} + +/* Temporary here since mach-mvebu has a function we can use */ +static void kirkwood_restart(enum reboot_mode mode, const char *cmd) +{ + /* + * Enable soft reset to assert RSTOUTn. + */ + writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK); + + /* + * Assert soft reset. + */ + writel(SOFT_RESET, SYSTEM_SOFT_RESET); + + while (1) + ; +} + +#define MV643XX_ETH_MAC_ADDR_LOW 0x0414 +#define MV643XX_ETH_MAC_ADDR_HIGH 0x0418 + +static void __init kirkwood_dt_eth_fixup(void) +{ + struct device_node *np; + + /* + * The ethernet interfaces forget the MAC address assigned by u-boot + * if the clocks are turned off. Usually, u-boot on kirkwood boards + * has no DT support to properly set local-mac-address property. + * As a workaround, we get the MAC address from mv643xx_eth registers + * and update the port device node if no valid MAC address is set. + */ + for_each_compatible_node(np, NULL, "marvell,kirkwood-eth-port") { + struct device_node *pnp = of_get_parent(np); + struct clk *clk; + struct property *pmac; + void __iomem *io; + u8 *macaddr; + u32 reg; + + if (!pnp) + continue; + + /* skip disabled nodes or nodes with valid MAC address*/ + if (!of_device_is_available(pnp) || of_get_mac_address(np)) + goto eth_fixup_skip; + + clk = of_clk_get(pnp, 0); + if (IS_ERR(clk)) + goto eth_fixup_skip; + + io = of_iomap(pnp, 0); + if (!io) + goto eth_fixup_no_map; + + /* ensure port clock is not gated to not hang CPU */ + clk_prepare_enable(clk); + + /* store MAC address register contents in local-mac-address */ + pr_err(FW_INFO "%s: local-mac-address is not set\n", + np->full_name); + + pmac = kzalloc(sizeof(*pmac) + 6, GFP_KERNEL); + if (!pmac) + goto eth_fixup_no_mem; + + pmac->value = pmac + 1; + pmac->length = 6; + pmac->name = kstrdup("local-mac-address", GFP_KERNEL); + if (!pmac->name) { + kfree(pmac); + goto eth_fixup_no_mem; + } + + macaddr = pmac->value; + reg = readl(io + MV643XX_ETH_MAC_ADDR_HIGH); + macaddr[0] = (reg >> 24) & 0xff; + macaddr[1] = (reg >> 16) & 0xff; + macaddr[2] = (reg >> 8) & 0xff; + macaddr[3] = reg & 0xff; + + reg = readl(io + MV643XX_ETH_MAC_ADDR_LOW); + macaddr[4] = (reg >> 8) & 0xff; + macaddr[5] = reg & 0xff; + + of_update_property(np, pmac); + +eth_fixup_no_mem: + iounmap(io); + clk_disable_unprepare(clk); +eth_fixup_no_map: + clk_put(clk); +eth_fixup_skip: + of_node_put(pnp); + } +} + +/* + * Disable propagation of mbus errors to the CPU local bus, as this + * causes mbus errors (which can occur for example for PCI aborts) to + * throw CPU aborts, which we're not set up to deal with. + */ +static void __init kirkwood_disable_mbus_error_propagation(void) +{ + void __iomem *cpu_config; + + cpu_config = ioremap(CPU_CONFIG_PHYS, 4); + writel(readl(cpu_config) & ~CPU_CONFIG_ERROR_PROP, cpu_config); + iounmap(cpu_config); +} + +static void __init kirkwood_dt_init(void) +{ + kirkwood_disable_mbus_error_propagation(); + + BUG_ON(mvebu_mbus_dt_init(false)); + +#ifdef CONFIG_CACHE_FEROCEON_L2 + feroceon_of_init(); +#endif + kirkwood_cpufreq_init(); + kirkwood_cpuidle_init(); + + kirkwood_pm_init(); + kirkwood_dt_eth_fixup(); + + of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); +} + +static const char * const kirkwood_dt_board_compat[] = { + "marvell,kirkwood", + NULL +}; + +DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)") + /* Maintainer: Jason Cooper */ + .map_io = kirkwood_map_io, + .init_machine = kirkwood_dt_init, + .restart = kirkwood_restart, + .dt_compat = kirkwood_dt_board_compat, +MACHINE_END diff -ruN a/arch/arm/mach-kirkwood/bubba3-gpio.c b/arch/arm/mach-kirkwood/bubba3-gpio.c --- a/arch/arm/mach-kirkwood/bubba3-gpio.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/bubba3-gpio.c 2018-10-27 18:30:56.006359292 -0600 @@ -0,0 +1,392 @@ +/* + * Excito BUBBA|3 led driver. + * + * Copyright (C) 2010 Excito Elektronik i Skåne AB + * Author: "Tor Krill" + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This driver provides an interface to the GPIO functionality on BUBBA|3 + */ + +#include +#include +#include +#include +#include +#include +#include + +/* Mark this file for ident */ +static char* ver="0.1"; +//static char* build=__DATE__ " " __TIME__; + +#define DEVNAME "bubbatwo" +#define LED_DEFAULT_FREQ 0x8000 + +/* Meta information for this module */ +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Tor Krill "); +MODULE_DESCRIPTION("BUBBA|3 led driver"); + +/* Forwards */ +static int b3_probe(struct platform_device *dev); +static int b3_remove(struct platform_device *dev); +static void b3_led_on(void); + +#define MODE_OFF 0 +#define MODE_BLINK 1 +#define MODE_LIT 2 +#define BUZZ_OFF 0 +#define BUZZ_ON 1 +#define LED_BLUE 0 +#define LED_RED 1 +#define LED_GREEN 2 +#define LED_BOOT 3 +#define LED_INSTALL LED_GREEN + +struct b3_stateinfo{ + u32 mode; + u32 freq; + u32 buzz; + u32 color; +}; + +static struct b3_stateinfo b3_data; + +static void b3_led_reset(void) +{ + gpio_set_value(B3_LED_INTERVAL,0); + udelay(1800); + gpio_set_value(B3_LED_INTERVAL,1); + udelay(10); + gpio_set_value(B3_LED_INTERVAL,0); + udelay(1800); +} + +static void b3_led_train_start(void) +{ + gpio_set_value(B3_LED_INTERVAL,1); + udelay(10); + gpio_set_value(B3_LED_INTERVAL,0); + udelay(10); + gpio_set_value(B3_LED_INTERVAL,1); + udelay(10); + gpio_set_value(B3_LED_INTERVAL,0); + udelay(1800); +} + +static void b3_led_train_end(void) +{ + gpio_set_value(B3_LED_INTERVAL,1); + udelay(10); + gpio_set_value(B3_LED_INTERVAL,0); + udelay(10); + gpio_set_value(B3_LED_INTERVAL,1); + udelay(10); + gpio_set_value(B3_LED_INTERVAL,0); + udelay(10); + gpio_set_value(B3_LED_INTERVAL,1); + udelay(10); + gpio_set_value(B3_LED_INTERVAL,0); + udelay(1800); +} + +static void b3_led_color(u32 color){ + gpio_set_value(B3_FRONT_LED_RED,0); + gpio_set_value(B3_FRONT_LED_BLUE,0); + gpio_set_value(B3_FRONT_LED_GREEN,0); + + switch(color){ + case LED_BOOT: + gpio_set_value(B3_FRONT_LED_RED,1); + gpio_set_value(B3_FRONT_LED_BLUE,1); + break; + case LED_RED: + gpio_set_value(B3_FRONT_LED_RED,1); + break; + case LED_GREEN: + gpio_set_value(B3_FRONT_LED_GREEN,1); + break; + case LED_BLUE: + default: + gpio_set_value(B3_FRONT_LED_BLUE,1); + break; + } +} + +static void b3_led_on(void) +{ + b3_led_color(b3_data.color); + + b3_led_reset(); + + b3_led_train_start(); + /* NOOP, pass through mode */ + b3_led_train_end(); + + gpio_set_value(B3_LED_INTERVAL,1); +} + +static void b3_led_off(void) +{ + gpio_set_value(B3_FRONT_LED_RED,0); + gpio_set_value(B3_FRONT_LED_BLUE,0); + gpio_set_value(B3_FRONT_LED_GREEN,0); + + b3_led_reset(); +} + +static void b3_buzz_on(void) +{ + gpio_set_value(B3_BUZZER_ENABLE,1); +} + +static void b3_buzz_off(void) +{ + gpio_set_value(B3_BUZZER_ENABLE,0); +} + + +static struct platform_device *b3_device; + +static struct platform_driver b3_driver = { + .driver = { + .name = DEVNAME, + .owner = THIS_MODULE, + }, + .probe = b3_probe, + .remove = b3_remove, +}; + +static ssize_t b3_show_ledmode(struct device *dev, struct device_attribute *attr, char *buffer) +{ + ssize_t len = 0; + switch(b3_data.mode){ + case MODE_OFF: + len = sprintf (buffer+len, "off"); + break; + case MODE_BLINK: + len = sprintf (buffer+len, "blink"); + break; + case MODE_LIT: + len = sprintf (buffer+len, "lit"); + break; + default: + len = sprintf (buffer+len, "unknown"); + } + + return len; +} + +static ssize_t b3_store_ledmode(struct device *dev, struct device_attribute *attr,const char *buffer, size_t size) +{ + + if(size<1){ + return -EINVAL; + } + /* Do a nasty shortcut here only look at first char */ + switch(buffer[0]){ + case 'o': + b3_data.mode=MODE_OFF; + b3_led_off (); + break; + case 'b': + /* For now we dont allow blink. */ + case 'l': + b3_data.mode=MODE_LIT; + b3_led_on (); + break; + default: + return -EINVAL; + } + + return size; +} + +static ssize_t b3_show_ledfreq(struct device *dev, struct device_attribute *attr, char *buffer) +{ + ssize_t len = 0; + + len = sprintf (buffer+len, "%u", b3_data.freq); + + return len; +} + +static ssize_t b3_store_ledfreq(struct device *dev, struct device_attribute *attr,const char *buffer, size_t size) +{ + + b3_data.freq = simple_strtoul(buffer,NULL,0); + + return size; +} + +static ssize_t b3_show_buzzer(struct device *dev, struct device_attribute *attr, char *buffer) +{ + ssize_t len = 0; + + len = sprintf (buffer+len, "%u", b3_data.buzz); + + return len; +} + +static ssize_t b3_store_buzzer(struct device *dev, struct device_attribute *attr,const char *buffer, size_t size) +{ + + b3_data.buzz = simple_strtoul(buffer,NULL,0); + + b3_data.buzz = (b3_data.buzz>0) ? BUZZ_ON : BUZZ_OFF; + + if(b3_data.buzz==BUZZ_ON){ + b3_buzz_on(); + }else{ + b3_buzz_off(); + } + + return size; +} + +static ssize_t b3_show_color(struct device *dev, struct device_attribute *attr, char *buffer) +{ + ssize_t len = 0; + + len = sprintf (buffer+len, "%u", b3_data.color); + + return len; +} + +static ssize_t b3_store_color(struct device *dev, struct device_attribute *attr,const char *buffer, size_t size) +{ + + b3_data.color = simple_strtoul(buffer,NULL,0); + + b3_data.color = (b3_data.color>LED_BOOT) ? LED_BOOT : b3_data.color; + + b3_led_color(b3_data.color); + + return size; +} + +static struct gpio bubba_gpios[] = { +#ifdef CONFIG_BUBBA3_INSTALL + { B3_FRONT_LED_RED, GPIOF_OUT_INIT_LOW, "Red LED"}, + { B3_FRONT_LED_BLUE, GPIOF_OUT_INIT_LOW, "Blue LED"}, + { B3_FRONT_LED_GREEN, GPIOF_OUT_INIT_HIGH, "Green LED"}, +#else + { B3_FRONT_LED_RED, GPIOF_OUT_INIT_HIGH, "Red LED"}, + { B3_FRONT_LED_BLUE, GPIOF_OUT_INIT_HIGH, "Blue LED"}, + { B3_FRONT_LED_GREEN, GPIOF_OUT_INIT_LOW, "Green LED"}, +#endif + { B3_LED_INTERVAL, GPIOF_OUT_INIT_HIGH, "LED interval"}, + { B3_BUZZER_ENABLE, GPIOF_OUT_INIT_LOW, "Buzzer"} +}; + +static int request_ioresources(void) +{ + + if(gpio_request_array(bubba_gpios, ARRAY_SIZE(bubba_gpios))<0){ + return -EINVAL; + } + + return 0; +} + +DEVICE_ATTR(ledmode, 0644, b3_show_ledmode, b3_store_ledmode); +DEVICE_ATTR(ledfreq, 0644, b3_show_ledfreq, b3_store_ledfreq); +DEVICE_ATTR(buzzer, 0644, b3_show_buzzer, b3_store_buzzer); +DEVICE_ATTR(color, 0644, b3_show_color, b3_store_color); + +static int b3_probe(struct platform_device *dev) +{ + int ret=0; + + if(request_ioresources()){ + return -EINVAL; + } + + ret = device_create_file(&b3_device->dev, &dev_attr_ledmode); + if(ret){ + return -EINVAL; + } + + ret = device_create_file(&b3_device->dev, &dev_attr_ledfreq); + if(ret){ + device_remove_file(&b3_device->dev, &dev_attr_ledmode); + return -EINVAL; + } + + ret = device_create_file(&b3_device->dev, &dev_attr_buzzer); + if(ret){ + device_remove_file(&b3_device->dev, &dev_attr_ledfreq); + device_remove_file(&b3_device->dev, &dev_attr_ledmode); + return -EINVAL; + } + + ret = device_create_file(&b3_device->dev, &dev_attr_color); + if(ret){ + device_remove_file(&b3_device->dev, &dev_attr_buzzer); + device_remove_file(&b3_device->dev, &dev_attr_ledfreq); + device_remove_file(&b3_device->dev, &dev_attr_ledmode); + return -EINVAL; + } + + b3_data.mode = MODE_LIT; + b3_data.freq = LED_DEFAULT_FREQ; + b3_data.buzz = BUZZ_OFF; +#ifdef CONFIG_BUBBA3_INSTALL + b3_data.color = LED_INSTALL; +#else + b3_data.color = LED_BOOT; +#endif + return ret; +} + +static int b3_remove(struct platform_device *dev) +{ + + device_remove_file (&b3_device->dev, &dev_attr_ledmode); + device_remove_file (&b3_device->dev, &dev_attr_ledfreq); + device_remove_file(&b3_device->dev, &dev_attr_buzzer); + device_remove_file(&b3_device->dev, &dev_attr_color); + + gpio_free_array(bubba_gpios, ARRAY_SIZE(bubba_gpios)); + return 0; +} + +static int __init bubba3_init(void){ + int result; + + if(!machine_is_bubba3()){ + return -EINVAL; + } + + + result = platform_driver_register(&b3_driver); + if (result < 0) { + printk(KERN_ERR "bubba3: Failed to register driver\n"); + return result; + } + + b3_device = platform_device_alloc(DEVNAME,-1); + platform_device_add(b3_device); + + printk(KERN_INFO "BUBBA3: driver ver %s loaded\n",ver); + + return result; + +} + +static void __exit bubba3_cleanup(void){ + + platform_device_del(b3_device); + platform_driver_unregister(&b3_driver); + + printk(KERN_INFO "bubba3 driver removed\n"); + +} +/* register init and cleanup functions */ +module_init(bubba3_init); +module_exit(bubba3_cleanup); diff -ruN a/arch/arm/mach-kirkwood/bubba3-setup.c b/arch/arm/mach-kirkwood/bubba3-setup.c --- a/arch/arm/mach-kirkwood/bubba3-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/bubba3-setup.c 2018-10-27 18:30:56.006359292 -0600 @@ -0,0 +1,234 @@ +/* + * arch/arm/mach-kirkwood/bubba3-setup.c + * based on + * arch/arm/mach-kirkwood/rd88f6281-setup.c + * + * For Bubba3 miniserver from Excito + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +/***************************************************************************** + * 2048KB SPI Flash on Boot Device (Numonyx MP25P16) + ****************************************************************************/ + +static struct mtd_partition bubba3_flash_parts[] = { + { + .name = "u-boot", + .size = SZ_512K+SZ_256K, + .offset = 0, + }, + { + .name = "env", + .size = SZ_128K, + .offset = MTDPART_OFS_NXTBLK, + }, + { + .name = "data", + .size = MTDPART_SIZ_FULL, + .offset = MTDPART_OFS_NXTBLK, + }, +}; + +static const struct flash_platform_data bubba3_flash = { + .type = "m25p16", + .name = "spi_flash", + .parts = bubba3_flash_parts, + .nr_parts = ARRAY_SIZE(bubba3_flash_parts), +}; + +static struct spi_board_info __initdata bubba3_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &bubba3_flash, + .irq = -1, + .max_speed_hz = 40000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +/***************************************************************************** + * GPIO and keys + ****************************************************************************/ + +static struct gpio_keys_button bubba3_buttons[] = { + [0] = { + .code = KEY_POWER, + .gpio = B3_POWER_BUTTON, + .desc = "Power button", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data bubba3_button_data = { + .buttons = bubba3_buttons, + .nbuttons = ARRAY_SIZE(bubba3_buttons), +}; + +static struct platform_device bubba3_gpio_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &bubba3_button_data, + }, +}; + + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data bubba3_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0x08), + /* in case a hardcoded MAC address is needed uncomment next line */ + /* .mac_addr = {0x00, 0x0c, 0xc6, 0x76, 0x76, 0x2b}, */ +}; + +static struct mv643xx_eth_platform_data bubba3_ge01_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0x18), + /* in case a hardcoded MAC address is needed uncomment next line */ + /* .mac_addr = {0x00, 0x0c, 0xc6, 0x76, 0x76, 0x2c}, */ +}; + +static struct mv_sata_platform_data bubba3_sata_data = { + .n_ports = 2, +}; + +/***************************************************************************** + * Timer + ****************************************************************************/ + +static unsigned int bubba3_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP4_NF_IO6, + MPP5_NF_IO7, + MPP6_SYSRST_OUTn, + MPP7_PEX_RST_OUTn, + MPP8_TW0_SDA, + MPP9_TW0_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP12_GPO, + MPP13_UART1_TXD, + MPP14_UART1_RXD, + MPP15_SATA0_ACTn, + MPP16_SATA1_ACTn, + MPP17_SATA0_PRESENTn, + MPP18_GPO, + MPP19_GPO, + MPP20_GE1_TXD0, + MPP21_GE1_TXD1, + MPP22_GE1_TXD2, + MPP23_GE1_TXD3, + MPP24_GE1_RXD0, + MPP25_GE1_RXD1, + MPP26_GE1_RXD2, + MPP27_GE1_RXD3, + MPP28_GPIO, + MPP29_GPIO, + MPP30_GE1_RXCTL, + MPP31_GE1_RXCLK, + MPP32_GE1_TCLKOUT, + MPP33_GE1_TXCTL, + MPP34_GPIO, + MPP35_GPIO, + MPP36_GPIO, + MPP37_GPIO, + MPP38_GPIO, + MPP39_GPIO, + MPP40_GPIO, + MPP41_GPIO, + MPP42_GPIO, + MPP43_GPIO, + MPP44_GPIO, + MPP45_GPIO, + MPP46_GPIO, + MPP47_GPIO, + MPP48_GPIO, + MPP49_GPIO, + 0 +}; + +static void __init bubba3_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + + kirkwood_mpp_conf(bubba3_mpp_config); + + kirkwood_uart0_init(); + + spi_register_board_info(bubba3_spi_slave_info, + ARRAY_SIZE(bubba3_spi_slave_info)); + kirkwood_spi_init(); + + kirkwood_i2c_init(); + + platform_device_register(&bubba3_gpio_buttons); + + /* eth0 */ + kirkwood_ge00_init(&bubba3_ge00_data); + + /* eth1 */ + if (gpio_request(28, "PHY2 reset") != 0 || + gpio_direction_input(28) != 0) // high-z + printk(KERN_ERR "can't deassert GPIO 28 (PHY2 reset)\n"); + else + kirkwood_ge01_init(&bubba3_ge01_data); + + kirkwood_sata_init(&bubba3_sata_data); + + kirkwood_ehci_init(); + +} + +static int __init bubba3_pci_init(void) +{ + if (machine_is_bubba3()) + kirkwood_pcie_init( KW_PCIE0 | KW_PCIE1 ); + + return 0; +} +subsys_initcall(bubba3_pci_init); + +MACHINE_START(BUBBA3, "BUBBA3 Kirkwood based miniserver") + /* Maintainer: Tor Krill */ + .atag_offset = 0x100, + .init_machine = bubba3_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff -ruN a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c --- a/arch/arm/mach-kirkwood/common.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/common.c 2018-10-27 18:30:56.006359292 -0600 @@ -0,0 +1,747 @@ +/* + * arch/arm/mach-kirkwood/common.c + * + * Core functions for Marvell Kirkwood 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "pm.h" + +/* These can go away once Kirkwood uses the mvebu-mbus DT binding */ +#define KIRKWOOD_MBUS_NAND_TARGET 0x01 +#define KIRKWOOD_MBUS_NAND_ATTR 0x2f +#define KIRKWOOD_MBUS_SRAM_TARGET 0x03 +#define KIRKWOOD_MBUS_SRAM_ATTR 0x01 + +/***************************************************************************** + * I/O Address Mapping + ****************************************************************************/ +static struct map_desc kirkwood_io_desc[] __initdata = { + { + .virtual = (unsigned long) KIRKWOOD_REGS_VIRT_BASE, + .pfn = __phys_to_pfn(KIRKWOOD_REGS_PHYS_BASE), + .length = KIRKWOOD_REGS_SIZE, + .type = MT_DEVICE, + }, +}; + +void __init kirkwood_map_io(void) +{ + iotable_init(kirkwood_io_desc, ARRAY_SIZE(kirkwood_io_desc)); +} + +/***************************************************************************** + * CLK tree + ****************************************************************************/ + +static void enable_sata0(void) +{ + /* Enable PLL and IVREF */ + writel(readl(SATA0_PHY_MODE_2) | 0xf, SATA0_PHY_MODE_2); + /* Enable PHY */ + writel(readl(SATA0_IF_CTRL) & ~0x200, SATA0_IF_CTRL); +} + +static void disable_sata0(void) +{ + /* Disable PLL and IVREF */ + writel(readl(SATA0_PHY_MODE_2) & ~0xf, SATA0_PHY_MODE_2); + /* Disable PHY */ + writel(readl(SATA0_IF_CTRL) | 0x200, SATA0_IF_CTRL); +} + +static void enable_sata1(void) +{ + /* Enable PLL and IVREF */ + writel(readl(SATA1_PHY_MODE_2) | 0xf, SATA1_PHY_MODE_2); + /* Enable PHY */ + writel(readl(SATA1_IF_CTRL) & ~0x200, SATA1_IF_CTRL); +} + +static void disable_sata1(void) +{ + /* Disable PLL and IVREF */ + writel(readl(SATA1_PHY_MODE_2) & ~0xf, SATA1_PHY_MODE_2); + /* Disable PHY */ + writel(readl(SATA1_IF_CTRL) | 0x200, SATA1_IF_CTRL); +} + +static void disable_pcie0(void) +{ + writel(readl(PCIE_LINK_CTRL) | 0x10, PCIE_LINK_CTRL); + while (1) + if (readl(PCIE_STATUS) & 0x1) + break; + writel(readl(PCIE_LINK_CTRL) & ~0x10, PCIE_LINK_CTRL); +} + +static void disable_pcie1(void) +{ + u32 dev, rev; + + kirkwood_pcie_id(&dev, &rev); + + if (dev == MV88F6282_DEV_ID) { + writel(readl(PCIE1_LINK_CTRL) | 0x10, PCIE1_LINK_CTRL); + while (1) + if (readl(PCIE1_STATUS) & 0x1) + break; + writel(readl(PCIE1_LINK_CTRL) & ~0x10, PCIE1_LINK_CTRL); + } +} + +/* An extended version of the gated clk. This calls fn_en()/fn_dis + * before enabling/disabling the clock. We use this to turn on/off + * PHYs etc. */ +struct clk_gate_fn { + struct clk_gate gate; + void (*fn_en)(void); + void (*fn_dis)(void); +}; + +#define to_clk_gate_fn(_gate) container_of(_gate, struct clk_gate_fn, gate) +#define to_clk_gate(_hw) container_of(_hw, struct clk_gate, hw) + +static int clk_gate_fn_enable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); + int ret; + + ret = clk_gate_ops.enable(hw); + if (!ret && gate_fn->fn_en) + gate_fn->fn_en(); + + return ret; +} + +static void clk_gate_fn_disable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + struct clk_gate_fn *gate_fn = to_clk_gate_fn(gate); + + if (gate_fn->fn_dis) + gate_fn->fn_dis(); + + clk_gate_ops.disable(hw); +} + +static struct clk_ops clk_gate_fn_ops; + +static struct clk __init *clk_register_gate_fn(struct device *dev, + const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 bit_idx, + u8 clk_gate_flags, spinlock_t *lock, + void (*fn_en)(void), void (*fn_dis)(void)) +{ + struct clk_gate_fn *gate_fn; + struct clk *clk; + struct clk_init_data init; + + gate_fn = kzalloc(sizeof(struct clk_gate_fn), GFP_KERNEL); + if (!gate_fn) { + pr_err("%s: could not allocate gated clk\n", __func__); + return ERR_PTR(-ENOMEM); + } + + init.name = name; + init.ops = &clk_gate_fn_ops; + init.flags = flags; + init.parent_names = (parent_name ? &parent_name : NULL); + init.num_parents = (parent_name ? 1 : 0); + + /* struct clk_gate assignments */ + gate_fn->gate.reg = reg; + gate_fn->gate.bit_idx = bit_idx; + gate_fn->gate.flags = clk_gate_flags; + gate_fn->gate.lock = lock; + gate_fn->gate.hw.init = &init; + gate_fn->fn_en = fn_en; + gate_fn->fn_dis = fn_dis; + + /* ops is the gate ops, but with our enable/disable functions */ + if (clk_gate_fn_ops.enable != clk_gate_fn_enable || + clk_gate_fn_ops.disable != clk_gate_fn_disable) { + clk_gate_fn_ops = clk_gate_ops; + clk_gate_fn_ops.enable = clk_gate_fn_enable; + clk_gate_fn_ops.disable = clk_gate_fn_disable; + } + + clk = clk_register(dev, &gate_fn->gate.hw); + + if (IS_ERR(clk)) + kfree(gate_fn); + + return clk; +} + +static DEFINE_SPINLOCK(gating_lock); +static struct clk *tclk; + +static struct clk __init *kirkwood_register_gate(const char *name, u8 bit_idx) +{ + return clk_register_gate(NULL, name, "tclk", 0, CLOCK_GATING_CTRL, + bit_idx, 0, &gating_lock); +} + +static struct clk __init *kirkwood_register_gate_fn(const char *name, + u8 bit_idx, + void (*fn_en)(void), + void (*fn_dis)(void)) +{ + return clk_register_gate_fn(NULL, name, "tclk", 0, CLOCK_GATING_CTRL, + bit_idx, 0, &gating_lock, fn_en, fn_dis); +} + +static struct clk *ge0, *ge1; + +void __init kirkwood_clk_init(void) +{ + struct clk *runit, *sata0, *sata1, *usb0, *sdio; + struct clk *crypto, *xor0, *xor1, *pex0, *pex1, *audio; + + tclk = clk_register_fixed_rate(NULL, "tclk", NULL, + CLK_IS_ROOT, kirkwood_tclk); + + runit = kirkwood_register_gate("runit", CGC_BIT_RUNIT); + ge0 = kirkwood_register_gate("ge0", CGC_BIT_GE0); + ge1 = kirkwood_register_gate("ge1", CGC_BIT_GE1); + sata0 = kirkwood_register_gate_fn("sata0", CGC_BIT_SATA0, + enable_sata0, disable_sata0); + sata1 = kirkwood_register_gate_fn("sata1", CGC_BIT_SATA1, + enable_sata1, disable_sata1); + usb0 = kirkwood_register_gate("usb0", CGC_BIT_USB0); + sdio = kirkwood_register_gate("sdio", CGC_BIT_SDIO); + crypto = kirkwood_register_gate("crypto", CGC_BIT_CRYPTO); + xor0 = kirkwood_register_gate("xor0", CGC_BIT_XOR0); + xor1 = kirkwood_register_gate("xor1", CGC_BIT_XOR1); + pex0 = kirkwood_register_gate_fn("pex0", CGC_BIT_PEX0, + NULL, disable_pcie0); + pex1 = kirkwood_register_gate_fn("pex1", CGC_BIT_PEX1, + NULL, disable_pcie1); + audio = kirkwood_register_gate("audio", CGC_BIT_AUDIO); + kirkwood_register_gate("tdm", CGC_BIT_TDM); + kirkwood_register_gate("tsu", CGC_BIT_TSU); + + /* clkdev entries, mapping clks to devices */ + orion_clkdev_add(NULL, "orion_spi.0", runit); + orion_clkdev_add(NULL, "orion_spi.1", runit); + orion_clkdev_add(NULL, MV643XX_ETH_NAME ".0", ge0); + orion_clkdev_add(NULL, MV643XX_ETH_NAME ".1", ge1); + orion_clkdev_add(NULL, "orion_wdt", tclk); + orion_clkdev_add("0", "sata_mv.0", sata0); + orion_clkdev_add("1", "sata_mv.0", sata1); + orion_clkdev_add(NULL, "orion-ehci.0", usb0); + orion_clkdev_add(NULL, "orion_nand", runit); + orion_clkdev_add(NULL, "mvsdio", sdio); + orion_clkdev_add(NULL, "mv_crypto", crypto); + orion_clkdev_add(NULL, MV_XOR_NAME ".0", xor0); + orion_clkdev_add(NULL, MV_XOR_NAME ".1", xor1); + orion_clkdev_add("0", "pcie", pex0); + orion_clkdev_add("1", "pcie", pex1); + orion_clkdev_add(NULL, "mvebu-audio", audio); + orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", runit); + orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".1", runit); + + /* Marvell says runit is used by SPI, UART, NAND, TWSI, ..., + * so should never be gated. + */ + clk_prepare_enable(runit); +} + +/***************************************************************************** + * EHCI0 + ****************************************************************************/ +void __init kirkwood_ehci_init(void) +{ + orion_ehci_init(USB_PHYS_BASE, IRQ_KIRKWOOD_USB, EHCI_PHY_NA); +} + + +/***************************************************************************** + * GE00 + ****************************************************************************/ +void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data) +{ + orion_ge00_init(eth_data, + GE00_PHYS_BASE, IRQ_KIRKWOOD_GE00_SUM, + IRQ_KIRKWOOD_GE00_ERR, 1600); + /* The interface forgets the MAC address assigned by u-boot if + the clock is turned off, so claim the clk now. */ + clk_prepare_enable(ge0); +} + + +/***************************************************************************** + * GE01 + ****************************************************************************/ +void __init kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data) +{ + orion_ge01_init(eth_data, + GE01_PHYS_BASE, IRQ_KIRKWOOD_GE01_SUM, + IRQ_KIRKWOOD_GE01_ERR, 1600); + clk_prepare_enable(ge1); +} + + +/***************************************************************************** + * Ethernet switch + ****************************************************************************/ +void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq) +{ + orion_ge00_switch_init(d, irq); +} + + +/***************************************************************************** + * NAND flash + ****************************************************************************/ +static struct resource kirkwood_nand_resource = { + .flags = IORESOURCE_MEM, + .start = KIRKWOOD_NAND_MEM_PHYS_BASE, + .end = KIRKWOOD_NAND_MEM_PHYS_BASE + + KIRKWOOD_NAND_MEM_SIZE - 1, +}; + +static struct orion_nand_data kirkwood_nand_data = { + .cle = 0, + .ale = 1, + .width = 8, +}; + +static struct platform_device kirkwood_nand_flash = { + .name = "orion_nand", + .id = -1, + .dev = { + .platform_data = &kirkwood_nand_data, + }, + .resource = &kirkwood_nand_resource, + .num_resources = 1, +}; + +void __init kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, + int chip_delay) +{ + kirkwood_nand_data.parts = parts; + kirkwood_nand_data.nr_parts = nr_parts; + kirkwood_nand_data.chip_delay = chip_delay; + platform_device_register(&kirkwood_nand_flash); +} + +void __init kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, + int (*dev_ready)(struct mtd_info *)) +{ + kirkwood_nand_data.parts = parts; + kirkwood_nand_data.nr_parts = nr_parts; + kirkwood_nand_data.dev_ready = dev_ready; + platform_device_register(&kirkwood_nand_flash); +} + +/***************************************************************************** + * SoC RTC + ****************************************************************************/ +static void __init kirkwood_rtc_init(void) +{ + orion_rtc_init(RTC_PHYS_BASE, IRQ_KIRKWOOD_RTC); +} + + +/***************************************************************************** + * SATA + ****************************************************************************/ +void __init kirkwood_sata_init(struct mv_sata_platform_data *sata_data) +{ + orion_sata_init(sata_data, SATA_PHYS_BASE, IRQ_KIRKWOOD_SATA); +} + + +/***************************************************************************** + * SD/SDIO/MMC + ****************************************************************************/ +static struct resource mvsdio_resources[] = { + [0] = { + .start = SDIO_PHYS_BASE, + .end = SDIO_PHYS_BASE + SZ_1K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_KIRKWOOD_SDIO, + .end = IRQ_KIRKWOOD_SDIO, + .flags = IORESOURCE_IRQ, + }, +}; + +static u64 mvsdio_dmamask = DMA_BIT_MASK(32); + +static struct platform_device kirkwood_sdio = { + .name = "mvsdio", + .id = -1, + .dev = { + .dma_mask = &mvsdio_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, + .num_resources = ARRAY_SIZE(mvsdio_resources), + .resource = mvsdio_resources, +}; + +void __init kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data) +{ + u32 dev, rev; + + kirkwood_pcie_id(&dev, &rev); + if (rev == 0 && dev != MV88F6282_DEV_ID) /* catch all Kirkwood Z0's */ + mvsdio_data->clock = 100000000; + else + mvsdio_data->clock = 200000000; + kirkwood_sdio.dev.platform_data = mvsdio_data; + platform_device_register(&kirkwood_sdio); +} + + +/***************************************************************************** + * SPI + ****************************************************************************/ +void __init kirkwood_spi_init(void) +{ + orion_spi_init(SPI_PHYS_BASE); +} + + +/***************************************************************************** + * I2C + ****************************************************************************/ +void __init kirkwood_i2c_init(void) +{ + orion_i2c_init(I2C_PHYS_BASE, IRQ_KIRKWOOD_TWSI, 8); +} + + +/***************************************************************************** + * UART0 + ****************************************************************************/ + +void __init kirkwood_uart0_init(void) +{ + orion_uart0_init(UART0_VIRT_BASE, UART0_PHYS_BASE, + IRQ_KIRKWOOD_UART_0, tclk); +} + + +/***************************************************************************** + * UART1 + ****************************************************************************/ +void __init kirkwood_uart1_init(void) +{ + orion_uart1_init(UART1_VIRT_BASE, UART1_PHYS_BASE, + IRQ_KIRKWOOD_UART_1, tclk); +} + +/***************************************************************************** + * Cryptographic Engines and Security Accelerator (CESA) + ****************************************************************************/ +void __init kirkwood_crypto_init(void) +{ + orion_crypto_init(CRYPTO_PHYS_BASE, KIRKWOOD_SRAM_PHYS_BASE, + KIRKWOOD_SRAM_SIZE, IRQ_KIRKWOOD_CRYPTO); +} + + +/***************************************************************************** + * XOR0 + ****************************************************************************/ +void __init kirkwood_xor0_init(void) +{ + orion_xor0_init(XOR0_PHYS_BASE, XOR0_HIGH_PHYS_BASE, + IRQ_KIRKWOOD_XOR_00, IRQ_KIRKWOOD_XOR_01); +} + + +/***************************************************************************** + * XOR1 + ****************************************************************************/ +void __init kirkwood_xor1_init(void) +{ + orion_xor1_init(XOR1_PHYS_BASE, XOR1_HIGH_PHYS_BASE, + IRQ_KIRKWOOD_XOR_10, IRQ_KIRKWOOD_XOR_11); +} + + +/***************************************************************************** + * Watchdog + ****************************************************************************/ +void __init kirkwood_wdt_init(void) +{ + orion_wdt_init(); +} + +/***************************************************************************** + * CPU idle + ****************************************************************************/ +static struct resource kirkwood_cpuidle_resource[] = { + { + .flags = IORESOURCE_MEM, + .start = DDR_OPERATION_BASE, + .end = DDR_OPERATION_BASE + 3, + }, +}; + +static struct platform_device kirkwood_cpuidle = { + .name = "kirkwood_cpuidle", + .id = -1, + .resource = kirkwood_cpuidle_resource, + .num_resources = 1, +}; + +void __init kirkwood_cpuidle_init(void) +{ + platform_device_register(&kirkwood_cpuidle); +} + +/***************************************************************************** + * Time handling + ****************************************************************************/ +void __init kirkwood_init_early(void) +{ + orion_time_set_base(TIMER_VIRT_BASE); +} + +int kirkwood_tclk; + +static int __init kirkwood_find_tclk(void) +{ + u32 dev, rev; + + kirkwood_pcie_id(&dev, &rev); + + if (dev == MV88F6281_DEV_ID || dev == MV88F6282_DEV_ID) + if (((readl(SAMPLE_AT_RESET) >> 21) & 1) == 0) + return 200000000; + + return 166666667; +} + +void __init kirkwood_timer_init(void) +{ + kirkwood_tclk = kirkwood_find_tclk(); + + orion_time_init(BRIDGE_VIRT_BASE, BRIDGE_INT_TIMER1_CLR, + IRQ_KIRKWOOD_BRIDGE, kirkwood_tclk); +} + +/***************************************************************************** + * Audio + ****************************************************************************/ +static struct resource kirkwood_audio_resources[] = { + [0] = { + .start = AUDIO_PHYS_BASE, + .end = AUDIO_PHYS_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_KIRKWOOD_I2S, + .end = IRQ_KIRKWOOD_I2S, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct kirkwood_asoc_platform_data kirkwood_audio_data = { + .burst = 128, +}; + +static struct platform_device kirkwood_audio_device = { + .name = "mvebu-audio", + .id = -1, + .num_resources = ARRAY_SIZE(kirkwood_audio_resources), + .resource = kirkwood_audio_resources, + .dev = { + .platform_data = &kirkwood_audio_data, + }, +}; + +void __init kirkwood_audio_init(void) +{ + platform_device_register(&kirkwood_audio_device); +} + +/***************************************************************************** + * CPU Frequency + ****************************************************************************/ +static struct resource kirkwood_cpufreq_resources[] = { + [0] = { + .start = CPU_CONTROL_PHYS, + .end = CPU_CONTROL_PHYS + 3, + .flags = IORESOURCE_MEM, + }, +}; + +static struct platform_device kirkwood_cpufreq_device = { + .name = "kirkwood-cpufreq", + .id = -1, + .num_resources = ARRAY_SIZE(kirkwood_cpufreq_resources), + .resource = kirkwood_cpufreq_resources, +}; + +void __init kirkwood_cpufreq_init(void) +{ + platform_device_register(&kirkwood_cpufreq_device); +} + +/***************************************************************************** + * General + ****************************************************************************/ +/* + * Identify device ID and revision. + */ +char * __init kirkwood_id(void) +{ + u32 dev, rev; + + kirkwood_pcie_id(&dev, &rev); + + if (dev == MV88F6281_DEV_ID) { + if (rev == MV88F6281_REV_Z0) + return "MV88F6281-Z0"; + else if (rev == MV88F6281_REV_A0) + return "MV88F6281-A0"; + else if (rev == MV88F6281_REV_A1) + return "MV88F6281-A1"; + else + return "MV88F6281-Rev-Unsupported"; + } else if (dev == MV88F6192_DEV_ID) { + if (rev == MV88F6192_REV_Z0) + return "MV88F6192-Z0"; + else if (rev == MV88F6192_REV_A0) + return "MV88F6192-A0"; + else if (rev == MV88F6192_REV_A1) + return "MV88F6192-A1"; + else + return "MV88F6192-Rev-Unsupported"; + } else if (dev == MV88F6180_DEV_ID) { + if (rev == MV88F6180_REV_A0) + return "MV88F6180-Rev-A0"; + else if (rev == MV88F6180_REV_A1) + return "MV88F6180-Rev-A1"; + else + return "MV88F6180-Rev-Unsupported"; + } else if (dev == MV88F6282_DEV_ID) { + if (rev == MV88F6282_REV_A0) + return "MV88F6282-Rev-A0"; + else if (rev == MV88F6282_REV_A1) + return "MV88F6282-Rev-A1"; + else + return "MV88F6282-Rev-Unsupported"; + } else { + return "Device-Unknown"; + } +} + +void __init kirkwood_setup_wins(void) +{ + mvebu_mbus_add_window_by_id(KIRKWOOD_MBUS_NAND_TARGET, + KIRKWOOD_MBUS_NAND_ATTR, + KIRKWOOD_NAND_MEM_PHYS_BASE, + KIRKWOOD_NAND_MEM_SIZE); + mvebu_mbus_add_window_by_id(KIRKWOOD_MBUS_SRAM_TARGET, + KIRKWOOD_MBUS_SRAM_ATTR, + KIRKWOOD_SRAM_PHYS_BASE, + KIRKWOOD_SRAM_SIZE); +} + +void __init kirkwood_l2_init(void) +{ +#ifdef CONFIG_CACHE_FEROCEON_L2 +#ifdef CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH + writel(readl(L2_CONFIG_REG) | L2_WRITETHROUGH, L2_CONFIG_REG); + feroceon_l2_init(1); +#else + writel(readl(L2_CONFIG_REG) & ~L2_WRITETHROUGH, L2_CONFIG_REG); + feroceon_l2_init(0); +#endif +#endif +} + +void __init kirkwood_init(void) +{ + pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk); + + /* + * Disable propagation of mbus errors to the CPU local bus, + * as this causes mbus errors (which can occur for example + * for PCI aborts) to throw CPU aborts, which we're not set + * up to deal with. + */ + writel(readl(CPU_CONFIG) & ~CPU_CONFIG_ERROR_PROP, CPU_CONFIG); + + BUG_ON(mvebu_mbus_init("marvell,kirkwood-mbus", + BRIDGE_WINS_BASE, BRIDGE_WINS_SZ, + DDR_WINDOW_CPU_BASE, DDR_WINDOW_CPU_SZ)); + + kirkwood_setup_wins(); + + kirkwood_l2_init(); + + /* Setup root of clk tree */ + kirkwood_clk_init(); + + /* internal devices that every board has */ + kirkwood_rtc_init(); + kirkwood_wdt_init(); + kirkwood_xor0_init(); + kirkwood_xor1_init(); + kirkwood_crypto_init(); + + kirkwood_pm_init(); + kirkwood_cpuidle_init(); +#ifdef CONFIG_KEXEC + kexec_reinit = kirkwood_enable_pcie; +#endif +} + +void kirkwood_restart(enum reboot_mode mode, const char *cmd) +{ + /* + * Enable soft reset to assert RSTOUTn. + */ + writel(SOFT_RESET_OUT_EN, RSTOUTn_MASK); + + /* + * Assert soft reset. + */ + writel(SOFT_RESET, SYSTEM_SOFT_RESET); + + while (1) + ; +} diff -ruN a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h --- a/arch/arm/mach-kirkwood/common.h 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/common.h 2018-10-27 18:30:56.006359292 -0600 @@ -0,0 +1,74 @@ +/* + * arch/arm/mach-kirkwood/common.h + * + * Core functions for Marvell Kirkwood 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. + */ + +#ifndef __ARCH_KIRKWOOD_COMMON_H +#define __ARCH_KIRKWOOD_COMMON_H + +#include + +struct dsa_platform_data; +struct mv643xx_eth_platform_data; +struct mv_sata_platform_data; +struct mvsdio_platform_data; +struct mtd_partition; +struct mtd_info; +struct kirkwood_asoc_platform_data; + +#define KW_PCIE0 (1 << 0) +#define KW_PCIE1 (1 << 1) + +/* + * Basic Kirkwood init functions used early by machine-setup. + */ +void kirkwood_map_io(void); +void kirkwood_init(void); +void kirkwood_init_early(void); +void kirkwood_init_irq(void); + +void kirkwood_setup_wins(void); + +void kirkwood_enable_pcie(void); +void kirkwood_pcie_id(u32 *dev, u32 *rev); + +void kirkwood_ehci_init(void); +void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data); +void kirkwood_ge01_init(struct mv643xx_eth_platform_data *eth_data); +void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq); +void kirkwood_pcie_init(unsigned int portmask); +void kirkwood_sata_init(struct mv_sata_platform_data *sata_data); +void kirkwood_sdio_init(struct mvsdio_platform_data *mvsdio_data); +void kirkwood_spi_init(void); +void kirkwood_i2c_init(void); +void kirkwood_uart0_init(void); +void kirkwood_uart1_init(void); +void kirkwood_nand_init(struct mtd_partition *parts, int nr_parts, int delay); +void kirkwood_nand_init_rnb(struct mtd_partition *parts, int nr_parts, + int (*dev_ready)(struct mtd_info *)); +void kirkwood_audio_init(void); +void kirkwood_cpuidle_init(void); +void kirkwood_cpufreq_init(void); + +void kirkwood_restart(enum reboot_mode, const char *); +void kirkwood_clk_init(void); + +/* early init functions not converted to fdt yet */ +char *kirkwood_id(void); +void kirkwood_l2_init(void); +void kirkwood_wdt_init(void); +void kirkwood_xor0_init(void); +void kirkwood_xor1_init(void); +void kirkwood_crypto_init(void); + +extern int kirkwood_tclk; +extern void kirkwood_timer_init(void); + +#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) + +#endif diff -ruN a/arch/arm/mach-kirkwood/d2net_v2-setup.c b/arch/arm/mach-kirkwood/d2net_v2-setup.c --- a/arch/arm/mach-kirkwood/d2net_v2-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/d2net_v2-setup.c 2018-10-27 18:30:56.006359292 -0600 @@ -0,0 +1,231 @@ +/* + * arch/arm/mach-kirkwood/d2net_v2-setup.c + * + * LaCie d2 Network Space v2 Board Setup + * + * Copyright (C) 2010 Simon Guinot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" +#include "lacie_v2-common.h" + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data d2net_v2_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +/***************************************************************************** + * SATA + ****************************************************************************/ + +static struct mv_sata_platform_data d2net_v2_sata_data = { + .n_ports = 2, +}; + +/***************************************************************************** + * GPIO keys + ****************************************************************************/ + +#define D2NET_V2_GPIO_PUSH_BUTTON 34 +#define D2NET_V2_GPIO_POWER_SWITCH_ON 13 +#define D2NET_V2_GPIO_POWER_SWITCH_OFF 15 + +#define D2NET_V2_SWITCH_POWER_ON 0x1 +#define D2NET_V2_SWITCH_POWER_OFF 0x2 + +static struct gpio_keys_button d2net_v2_buttons[] = { + [0] = { + .type = EV_SW, + .code = D2NET_V2_SWITCH_POWER_ON, + .gpio = D2NET_V2_GPIO_POWER_SWITCH_ON, + .desc = "Back power switch (on|auto)", + .active_low = 0, + }, + [1] = { + .type = EV_SW, + .code = D2NET_V2_SWITCH_POWER_OFF, + .gpio = D2NET_V2_GPIO_POWER_SWITCH_OFF, + .desc = "Back power switch (auto|off)", + .active_low = 0, + }, + [2] = { + .code = KEY_POWER, + .gpio = D2NET_V2_GPIO_PUSH_BUTTON, + .desc = "Front Push Button", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data d2net_v2_button_data = { + .buttons = d2net_v2_buttons, + .nbuttons = ARRAY_SIZE(d2net_v2_buttons), +}; + +static struct platform_device d2net_v2_gpio_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &d2net_v2_button_data, + }, +}; + +/***************************************************************************** + * GPIO LEDs + ****************************************************************************/ + +#define D2NET_V2_GPIO_RED_LED 12 + +static struct gpio_led d2net_v2_gpio_led_pins[] = { + { + .name = "d2net_v2:red:fail", + .gpio = D2NET_V2_GPIO_RED_LED, + }, +}; + +static struct gpio_led_platform_data d2net_v2_gpio_leds_data = { + .num_leds = ARRAY_SIZE(d2net_v2_gpio_led_pins), + .leds = d2net_v2_gpio_led_pins, +}; + +static struct platform_device d2net_v2_gpio_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &d2net_v2_gpio_leds_data, + }, +}; + +/***************************************************************************** + * Dual-GPIO CPLD LEDs + ****************************************************************************/ + +#define D2NET_V2_GPIO_BLUE_LED_SLOW 29 +#define D2NET_V2_GPIO_BLUE_LED_CMD 30 + +static struct ns2_led d2net_v2_led_pins[] = { + { + .name = "d2net_v2:blue:sata", + .cmd = D2NET_V2_GPIO_BLUE_LED_CMD, + .slow = D2NET_V2_GPIO_BLUE_LED_SLOW, + }, +}; + +static struct ns2_led_platform_data d2net_v2_leds_data = { + .num_leds = ARRAY_SIZE(d2net_v2_led_pins), + .leds = d2net_v2_led_pins, +}; + +static struct platform_device d2net_v2_leds = { + .name = "leds-ns2", + .id = -1, + .dev = { + .platform_data = &d2net_v2_leds_data, + }, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static unsigned int d2net_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP6_SYSRST_OUTn, + MPP7_GPO, /* Request power-off */ + MPP8_TW0_SDA, + MPP9_TW0_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP12_GPO, /* Red led */ + MPP13_GPIO, /* Rear power switch (on|auto) */ + MPP14_GPIO, /* USB fuse */ + MPP15_GPIO, /* Rear power switch (auto|off) */ + MPP16_GPIO, /* SATA 0 power */ + MPP21_SATA0_ACTn, + MPP24_GPIO, /* USB mode select */ + MPP26_GPIO, /* USB device vbus */ + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* Blue led (slow register) */ + MPP30_GPIO, /* Blue led (command register) */ + MPP34_GPIO, /* Power button (1 = Released, 0 = Pushed) */ + MPP35_GPIO, /* Inhibit power-off */ + 0 +}; + +#define D2NET_V2_GPIO_POWER_OFF 7 + +static void d2net_v2_power_off(void) +{ + gpio_set_value(D2NET_V2_GPIO_POWER_OFF, 1); +} + +static void __init d2net_v2_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(d2net_v2_mpp_config); + + lacie_v2_hdd_power_init(1); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&d2net_v2_ge00_data); + kirkwood_sata_init(&d2net_v2_sata_data); + kirkwood_uart0_init(); + lacie_v2_register_flash(); + lacie_v2_register_i2c_devices(); + + platform_device_register(&d2net_v2_leds); + platform_device_register(&d2net_v2_gpio_leds); + platform_device_register(&d2net_v2_gpio_buttons); + + if (gpio_request(D2NET_V2_GPIO_POWER_OFF, "power-off") == 0 && + gpio_direction_output(D2NET_V2_GPIO_POWER_OFF, 0) == 0) + pm_power_off = d2net_v2_power_off; + else + pr_err("d2net_v2: failed to configure power-off GPIO\n"); +} + +MACHINE_START(D2NET_V2, "LaCie d2 Network v2") + .atag_offset = 0x100, + .init_machine = d2net_v2_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff -ruN a/arch/arm/mach-kirkwood/dockstar-setup.c b/arch/arm/mach-kirkwood/dockstar-setup.c --- a/arch/arm/mach-kirkwood/dockstar-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/dockstar-setup.c 2018-10-27 18:30:56.006359292 -0600 @@ -0,0 +1,115 @@ +/* + * arch/arm/mach-kirkwood/dockstar-setup.c + * + * Seagate FreeAgent DockStar 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static struct mtd_partition dockstar_nand_parts[] = { + { + .name = "u-boot", + .offset = 0, + .size = SZ_1M + }, { + .name = "pogoplug", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_32M + }, { + .name = "uImage", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_4M + }, { + .name = "root", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + }, +}; + +static struct mv643xx_eth_platform_data dockstar_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +static struct gpio_led dockstar_led_pins[] = { + { + .name = "status:green:health", + .default_trigger = "default-on", + .gpio = 46, + .active_low = 1, + }, + { + .name = "status:orange:fault", + .default_trigger = "none", + .gpio = 47, + .active_low = 1, + } +}; + +static struct gpio_led_platform_data dockstar_led_data = { + .leds = dockstar_led_pins, + .num_leds = ARRAY_SIZE(dockstar_led_pins), +}; + +static struct platform_device dockstar_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &dockstar_led_data, + } +}; + +static unsigned int dockstar_mpp_config[] __initdata = { + MPP29_GPIO, /* USB Power Enable */ + MPP46_GPIO, /* LED Green */ + MPP47_GPIO, /* LED Orange */ + 0 +}; + +static void __init dockstar_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + + /* setup gpio pin select */ + kirkwood_mpp_conf(dockstar_mpp_config); + + kirkwood_uart0_init(); + kirkwood_nand_init(ARRAY_AND_SIZE(dockstar_nand_parts), 25); + + if (gpio_request(29, "USB Power Enable") != 0 || + gpio_direction_output(29, 1) != 0) + pr_err("can't set up GPIO 29 (USB Power Enable)\n"); + kirkwood_ehci_init(); + + kirkwood_ge00_init(&dockstar_ge00_data); + + platform_device_register(&dockstar_leds); +} + +MACHINE_START(DOCKSTAR, "Seagate FreeAgent DockStar") + .atag_offset = 0x100, + .init_machine = dockstar_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff -ruN a/arch/arm/mach-kirkwood/goflexhome-setup.c b/arch/arm/mach-kirkwood/goflexhome-setup.c --- a/arch/arm/mach-kirkwood/goflexhome-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/goflexhome-setup.c 2018-10-27 18:30:56.006359292 -0600 @@ -0,0 +1,124 @@ +/* + * arch/arm/mach-kirkwood/goflexhome-setup.c + * + * Seagate GoFlex Home 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static struct mtd_partition goflexhome_nand_parts[] = { + { + .name = "u-boot", + .offset = 0, + .size = SZ_1M + }, { + .name = "uImage", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_2M + SZ_4M + }, { + .name = "root", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + }, +}; + +static struct mv643xx_eth_platform_data goflexhome_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +static struct mv_sata_platform_data goflexhome_sata_data = { + .n_ports = 1, +}; + +static struct gpio_led goflexhome_led_pins[] = { + { + .name = "status:green:health", + .default_trigger = "default-on", + .gpio = 46, + .active_low = 1, + }, + { + .name = "status:orange:fault", + .default_trigger = "none", + .gpio = 47, + .active_low = 1, + }, + { + .name = "status:white:misc", + .default_trigger = "ide-disk1", + .gpio = 40, + .active_low = 0, + } +}; + +static struct gpio_led_platform_data goflexhome_led_data = { + .leds = goflexhome_led_pins, + .num_leds = ARRAY_SIZE(goflexhome_led_pins), +}; + +static struct platform_device goflexhome_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &goflexhome_led_data, + } +}; + +static unsigned int goflexhome_mpp_config[] __initdata = { + MPP29_GPIO, /* USB Power Enable */ + MPP47_GPIO, /* LED Orange */ + MPP46_GPIO, /* LED Green */ + MPP40_GPIO, /* LED White */ + 0 +}; + +static void __init goflexhome_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + + /* setup gpio pin select */ + kirkwood_mpp_conf(goflexhome_mpp_config); + + kirkwood_uart0_init(); + kirkwood_nand_init(ARRAY_AND_SIZE(goflexhome_nand_parts), 40); + + if (gpio_request(29, "USB Power Enable") != 0 || + gpio_direction_output(29, 1) != 0) + printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n"); + kirkwood_ehci_init(); + kirkwood_ge00_init(&goflexhome_ge00_data); + kirkwood_sata_init(&goflexhome_sata_data); + + platform_device_register(&goflexhome_leds); +} + +MACHINE_START(GOFLEXHOME, "Seagate GoFlex Home") + /* Maintainer: Peter Carmichael */ + .atag_offset = 0x100, + .init_machine = goflexhome_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END + diff -ruN a/arch/arm/mach-kirkwood/goflexnet-setup.c b/arch/arm/mach-kirkwood/goflexnet-setup.c --- a/arch/arm/mach-kirkwood/goflexnet-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/goflexnet-setup.c 2018-10-27 18:30:56.006359292 -0600 @@ -0,0 +1,177 @@ +/* + * arch/arm/mach-kirkwood/goflexnet-setup.c + * + * Seagate GoFlex Net 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static struct mtd_partition goflexnet_nand_parts[] = { + { + .name = "u-boot", + .offset = 0, + .size = SZ_1M + }, { + .name = "uImage", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_4M + }, { + .name = "pogoplug", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_32M + }, { + .name = "root", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + }, +}; + +static struct mv643xx_eth_platform_data goflexnet_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +static struct mv_sata_platform_data goflexnet_sata_data = { + .n_ports = 2, +}; + +static struct gpio_led goflexnet_led_pins[] = { + { + .name = "status:green:health", + .default_trigger = "default-on", + .gpio = 46, // 0x4000 + .active_low = 1, + }, + { + .name = "status:orange:fault", + .default_trigger = "none", + .gpio = 47, // 0x8000 + .active_low = 1, + }, + { + .name = "status:white:left0", + .default_trigger = "none", + .gpio = 42, // 0x0400 + .active_low = 0, + }, + { + .name = "status:white:left1", + .default_trigger = "none", + .gpio = 43, // 0x0800 + .active_low = 0, + }, + { + .name = "status:white:left2", + .default_trigger = "none", + .gpio = 44, // 0x1000 + .active_low = 0, + }, + { + .name = "status:white:left3", + .default_trigger = "none", + .gpio = 45, // 0x2000 + .active_low = 0, + }, + { + .name = "status:white:right0", + .default_trigger = "none", + .gpio = 38, // 0x0040 + .active_low = 0, + }, + { + .name = "status:white:right1", + .default_trigger = "none", + .gpio = 39, // 0x0080 + .active_low = 0, + }, + { + .name = "status:white:right2", + .default_trigger = "none", + .gpio = 40, // 0x0100 + .active_low = 0, + }, + { + .name = "status:white:right3", + .default_trigger = "none", + .gpio = 41, // 0x0200 + .active_low = 0, + } +}; + +static struct gpio_led_platform_data goflexnet_led_data = { + .leds = goflexnet_led_pins, + .num_leds = ARRAY_SIZE(goflexnet_led_pins), +}; + +static struct platform_device goflexnet_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &goflexnet_led_data, + } +}; + +static unsigned int goflexnet_mpp_config[] __initdata = { + MPP29_GPIO, /* USB Power Enable */ + MPP47_GPIO, /* LED Orange */ + MPP46_GPIO, /* LED Green */ + MPP45_GPIO, /* LED Left Capacity 3 */ + MPP44_GPIO, /* LED Left Capacity 2 */ + MPP43_GPIO, /* LED Left Capacity 1 */ + MPP42_GPIO, /* LED Left Capacity 0 */ + MPP41_GPIO, /* LED Right Capacity 3 */ + MPP40_GPIO, /* LED Right Capacity 2 */ + MPP39_GPIO, /* LED Right Capacity 1 */ + MPP38_GPIO, /* LED Right Capacity 0 */ + 0 +}; + +static void __init goflexnet_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + + /* setup gpio pin select */ + kirkwood_mpp_conf(goflexnet_mpp_config); + + kirkwood_uart0_init(); + kirkwood_nand_init(ARRAY_AND_SIZE(goflexnet_nand_parts), 40); + + if (gpio_request(29, "USB Power Enable") != 0 || + gpio_direction_output(29, 1) != 0) + printk(KERN_ERR "can't set up GPIO 29 (USB Power Enable)\n"); + kirkwood_ehci_init(); + kirkwood_ge00_init(&goflexnet_ge00_data); + kirkwood_sata_init(&goflexnet_sata_data); + + platform_device_register(&goflexnet_leds); +} + +MACHINE_START(GOFLEXNET, "Seagate GoFlex Net") + /* Maintainer: Peter Carmichael */ + .atag_offset = 0x100, + .init_machine = goflexnet_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END + diff -ruN a/arch/arm/mach-kirkwood/guruplug-setup.c b/arch/arm/mach-kirkwood/guruplug-setup.c --- a/arch/arm/mach-kirkwood/guruplug-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/guruplug-setup.c 2018-10-27 18:30:56.006359292 -0600 @@ -0,0 +1,228 @@ +/* + * arch/arm/mach-kirkwood/guruplug-setup.c + * + * Marvell GuruPlug Reference Board 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static struct mtd_partition dreamplug_partitions[] = { + { + .name = "u-boot", + .size = SZ_512K, + .offset = 0, + }, { + .name = "u-boot env", + .size = SZ_64K, + .offset = SZ_512K + SZ_512K, + }, +}; + +static const struct flash_platform_data dreamplug_spi_slave_data = { + .type = "mx25l1606e", + .name = "spi_flash", + .parts = dreamplug_partitions, + .nr_parts = ARRAY_SIZE(dreamplug_partitions), +}; + +static struct spi_board_info __initdata dreamplug_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &dreamplug_spi_slave_data, + .irq = -1, + .max_speed_hz = 50000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +static struct mtd_partition guruplug_nand_parts[] = { + { + .name = "u-boot", + .offset = 0, + .size = SZ_1M + }, { + .name = "uImage", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_4M + }, { + .name = "root", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + }, +}; + +static struct mv643xx_eth_platform_data guruplug_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +static struct mv643xx_eth_platform_data guruplug_ge01_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(1), +}; + +static struct mv_sata_platform_data guruplug_sata_data = { + .n_ports = 1, +}; + +static struct mvsdio_platform_data guruplug_mvsdio_data = { + /* unfortunately the CD signal has not been connected */ + .gpio_card_detect = -1, + .gpio_write_protect = -1, +}; + +static struct gpio_led guruplug_led_pins[] = { + { + .name = "status:red:fault", + .default_trigger = "none", + .gpio = 46, + .active_low = 1, + }, + { + .name = "status:green:health", + .default_trigger = "default-on", + .gpio = 47, + .active_low = 1, + }, + { + .name = "status:red:wmode", + .gpio = 48, + .active_low = 1, + }, + { + .name = "status:green:wmode", + .gpio = 49, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data guruplug_led_data = { + .leds = guruplug_led_pins, + .num_leds = ARRAY_SIZE(guruplug_led_pins), +}; + +static struct platform_device guruplug_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &guruplug_led_data, + } +}; + +static struct gpio_led dreamplug_led_pins[] = { + { + .name = "status:blue:bt", + .gpio = 47, + .active_low = 1, + }, + { + .name = "status:green:wifi", + .gpio = 48, + .active_low = 1, + }, + { + .name = "status:blue:ap", + .gpio = 49, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data dreamplug_led_data = { + .leds = dreamplug_led_pins, + .num_leds = ARRAY_SIZE(dreamplug_led_pins), +}; + +static unsigned int dreamplug_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP47_GPIO, /* Bluetooth LED */ + MPP48_GPIO, /* Wifi LED */ + MPP49_GPIO, /* Wifi AP LED */ + 0 +}; + + +static unsigned int guruplug_mpp_config[] __initdata = { + MPP46_GPIO, /* M_RLED */ + MPP47_GPIO, /* M_GLED */ + MPP48_GPIO, /* B_RLED */ + MPP49_GPIO, /* B_GLED */ + 0 +}; + +static void __init guruplug_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + + if (machine_is_guruplug()) { + kirkwood_mpp_conf(guruplug_mpp_config); + kirkwood_uart0_init(); + kirkwood_nand_init(ARRAY_AND_SIZE(guruplug_nand_parts), 25); + } + + if (machine_is_dreamplug()) { + kirkwood_mpp_conf(dreamplug_mpp_config); + kirkwood_uart0_init(); + spi_register_board_info(dreamplug_spi_slave_info, + ARRAY_SIZE(dreamplug_spi_slave_info)); + kirkwood_spi_init(); + guruplug_leds.dev.platform_data = &dreamplug_led_data; + } + + kirkwood_ehci_init(); + kirkwood_ge00_init(&guruplug_ge00_data); + kirkwood_ge01_init(&guruplug_ge01_data); + kirkwood_sata_init(&guruplug_sata_data); + kirkwood_sdio_init(&guruplug_mvsdio_data); + + platform_device_register(&guruplug_leds); +} + +#ifdef CONFIG_MACH_GURUPLUG +MACHINE_START(GURUPLUG, "Marvell GuruPlug Reference Board") + /* Maintainer: Siddarth Gore */ + .atag_offset = 0x100, + .init_machine = guruplug_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_DREAMPLUG +MACHINE_START(DREAMPLUG, "Marvell DreamPlug Reference Board") + /* Maintainer: ? */ + .atag_offset = 0x100, + .init_machine = guruplug_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif diff -ruN a/arch/arm/mach-kirkwood/iconnect-setup.c b/arch/arm/mach-kirkwood/iconnect-setup.c --- a/arch/arm/mach-kirkwood/iconnect-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/iconnect-setup.c 2018-10-27 18:30:56.010359272 -0600 @@ -0,0 +1,204 @@ +/* + * arch/arm/mach-kirkwood/iconnect-setup.c + * + * Iomega iConnect Wireless + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static struct mtd_partition iconnect_nand_parts[] = { + { + .name = "u-boot", + .offset = 0, + .size = SZ_1M + }, { + .name = "uImage", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_1M + SZ_2M + }, { + .name = "rootfs", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_32M, + }, { + .name = "data", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + }, +}; + +static struct mv643xx_eth_platform_data iconnect_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(11), +}; + +static struct gpio_led iconnect_led_pins[] = { + { + .name = "iconnect:led_level", + .default_trigger = "default-on", + .gpio = 41, + }, + { + .name = "iconnect:blue:power", + .default_trigger = "default-on", + .gpio = 42, + }, + { + .name = "iconnect:red:power", + .gpio = 43, + }, + { + .name = "iconnect:blue:usb1", + .gpio = 44, + }, + { + .name = "iconnect:blue:usb2", + .gpio = 45, + }, + { + .name = "iconnect:blue:usb3", + .gpio = 46, + }, + { + .name = "iconnect:blue:usb4", + .gpio = 47, + }, + { + .name = "iconnect:blue:otb", + .gpio = 48, + }, +}; + +static struct gpio_led_platform_data iconnect_led_data = { + .leds = iconnect_led_pins, + .num_leds = ARRAY_SIZE(iconnect_led_pins), +}; + +static struct platform_device iconnect_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &iconnect_led_data, + } +}; + +#define ICONNECT_GPIO_KEY_RESET 12 +#define ICONNECT_GPIO_KEY_OTB 35 + +#define ICONNECT_SW_RESET 0x00 +#define ICONNECT_SW_OTB 0x01 + +static struct gpio_keys_button iconnect_buttons[] = { + { + .type = EV_SW, + .code = ICONNECT_SW_RESET, + .gpio = ICONNECT_GPIO_KEY_RESET, + .desc = "Reset Button", + .active_low = 1, + .debounce_interval = 100, + }, + { + .type = EV_SW, + .code = ICONNECT_SW_OTB, + .gpio = ICONNECT_GPIO_KEY_OTB, + .desc = "OTB Button", + .active_low = 1, + .debounce_interval = 100, + }, +}; + +static struct gpio_keys_platform_data iconnect_button_data = { + .buttons = iconnect_buttons, + .nbuttons = ARRAY_SIZE(iconnect_buttons), +}; + +static struct platform_device iconnect_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &iconnect_button_data, + }, +}; + +static unsigned int iconnect_mpp_config[] __initdata = { + MPP12_GPIO, /*Input for reset button*/ + MPP35_GPIO, /*Input for OTB button*/ + MPP41_GPIO, + MPP42_GPIO, + MPP43_GPIO, + MPP44_GPIO, + MPP45_GPIO, + MPP46_GPIO, + MPP47_GPIO, + MPP48_GPIO, + 0 +}; + +static struct i2c_board_info __initdata iconnect_i2c_rtc = { + I2C_BOARD_INFO("lm63", 0x4c), +}; + +static void __init iconnect_init(void) +{ + u32 dev, rev; + + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(iconnect_mpp_config); + + kirkwood_nand_init(ARRAY_AND_SIZE(iconnect_nand_parts), 40); + kirkwood_ehci_init(); + + kirkwood_ge00_init(&iconnect_ge00_data); + kirkwood_pcie_id(&dev, &rev); + + kirkwood_uart0_init(); + + platform_device_register(&iconnect_leds); + platform_device_register(&iconnect_button_device); + + kirkwood_i2c_init(); + i2c_register_board_info(0, &iconnect_i2c_rtc, 1); + +} + +static int __init iconnect_pci_init(void) +{ + if (machine_is_iconnect()) + kirkwood_pcie_init(KW_PCIE0); + + return 0; +} +subsys_initcall(iconnect_pci_init); + + +MACHINE_START(ICONNECT, "Iomega iConnect Wireless") + .atag_offset = 0x100, + .init_machine = iconnect_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff -ruN a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h --- a/arch/arm/mach-kirkwood/include/mach/bridge-regs.h 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/include/mach/bridge-regs.h 2018-10-27 18:30:56.010359272 -0600 @@ -0,0 +1,86 @@ +/* + * arch/arm/mach-kirkwood/include/mach/bridge-regs.h + * + * Mbus-L to Mbus Bridge Registers + * + * 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_BRIDGE_REGS_H +#define __ASM_ARCH_BRIDGE_REGS_H + +#include + +#define CPU_CONFIG (BRIDGE_VIRT_BASE + 0x0100) +#define CPU_CONFIG_PHYS (BRIDGE_PHYS_BASE + 0x0100) +#define CPU_CONFIG_ERROR_PROP 0x00000004 + +#define CPU_CONTROL (BRIDGE_VIRT_BASE + 0x0104) +#define CPU_CONTROL_PHYS (BRIDGE_PHYS_BASE + 0x0104) +#define CPU_RESET 0x00000002 + +#define RSTOUTn_MASK (BRIDGE_VIRT_BASE + 0x0108) +#define RSTOUTn_MASK_PHYS (BRIDGE_PHYS_BASE + 0x0108) +#define SOFT_RESET_OUT_EN 0x00000004 + +#define SYSTEM_SOFT_RESET (BRIDGE_VIRT_BASE + 0x010c) +#define SOFT_RESET 0x00000001 + +#define BRIDGE_CAUSE (BRIDGE_VIRT_BASE + 0x0110) + +#define BRIDGE_INT_TIMER1_CLR (~0x0004) + +#define IRQ_VIRT_BASE (BRIDGE_VIRT_BASE + 0x0200) +#define IRQ_CAUSE_LOW_OFF 0x0000 +#define IRQ_MASK_LOW_OFF 0x0004 +#define IRQ_CAUSE_HIGH_OFF 0x0010 +#define IRQ_MASK_HIGH_OFF 0x0014 + +#define TIMER_VIRT_BASE (BRIDGE_VIRT_BASE + 0x0300) +#define TIMER_PHYS_BASE (BRIDGE_PHYS_BASE + 0x0300) + +#define L2_CONFIG_REG (BRIDGE_VIRT_BASE + 0x0128) +#define L2_WRITETHROUGH 0x00000010 + +#define CLOCK_GATING_CTRL (BRIDGE_VIRT_BASE + 0x11c) +#define CGC_BIT_GE0 (0) +#define CGC_BIT_PEX0 (2) +#define CGC_BIT_USB0 (3) +#define CGC_BIT_SDIO (4) +#define CGC_BIT_TSU (5) +#define CGC_BIT_DUNIT (6) +#define CGC_BIT_RUNIT (7) +#define CGC_BIT_XOR0 (8) +#define CGC_BIT_AUDIO (9) +#define CGC_BIT_SATA0 (14) +#define CGC_BIT_SATA1 (15) +#define CGC_BIT_XOR1 (16) +#define CGC_BIT_CRYPTO (17) +#define CGC_BIT_PEX1 (18) +#define CGC_BIT_GE1 (19) +#define CGC_BIT_TDM (20) +#define CGC_GE0 (1 << 0) +#define CGC_PEX0 (1 << 2) +#define CGC_USB0 (1 << 3) +#define CGC_SDIO (1 << 4) +#define CGC_TSU (1 << 5) +#define CGC_DUNIT (1 << 6) +#define CGC_RUNIT (1 << 7) +#define CGC_XOR0 (1 << 8) +#define CGC_AUDIO (1 << 9) +#define CGC_POWERSAVE (1 << 11) +#define CGC_SATA0 (1 << 14) +#define CGC_SATA1 (1 << 15) +#define CGC_XOR1 (1 << 16) +#define CGC_CRYPTO (1 << 17) +#define CGC_PEX1 (1 << 18) +#define CGC_GE1 (1 << 19) +#define CGC_TDM (1 << 20) +#define CGC_RESERVED (0x6 << 21) + +#define MEMORY_PM_CTRL (BRIDGE_VIRT_BASE + 0x118) +#define MEMORY_PM_CTRL_PHYS (BRIDGE_PHYS_BASE + 0x118) + +#endif diff -ruN a/arch/arm/mach-kirkwood/include/mach/entry-macro.S b/arch/arm/mach-kirkwood/include/mach/entry-macro.S --- a/arch/arm/mach-kirkwood/include/mach/entry-macro.S 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/include/mach/entry-macro.S 2018-10-27 18:30:56.010359272 -0600 @@ -0,0 +1,34 @@ +/* + * arch/arm/mach-kirkwood/include/mach/entry-macro.S + * + * Low-level IRQ helper macros for Marvell Kirkwood 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 + + .macro get_irqnr_preamble, base, tmp + ldr \base, =IRQ_VIRT_BASE + .endm + + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp + @ check low interrupts + ldr \irqstat, [\base, #IRQ_CAUSE_LOW_OFF] + ldr \tmp, [\base, #IRQ_MASK_LOW_OFF] + mov \irqnr, #31 + ands \irqstat, \irqstat, \tmp + bne 1001f + + @ if no low interrupts set, check high interrupts + ldr \irqstat, [\base, #IRQ_CAUSE_HIGH_OFF] + ldr \tmp, [\base, #IRQ_MASK_HIGH_OFF] + mov \irqnr, #63 + ands \irqstat, \irqstat, \tmp + + @ find first active interrupt source +1001: clzne \irqstat, \irqstat + subne \irqnr, \irqnr, \irqstat + .endm diff -ruN a/arch/arm/mach-kirkwood/include/mach/hardware.h b/arch/arm/mach-kirkwood/include/mach/hardware.h --- a/arch/arm/mach-kirkwood/include/mach/hardware.h 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/include/mach/hardware.h 2018-10-27 18:30:56.010359272 -0600 @@ -0,0 +1,14 @@ +/* + * arch/arm/mach-kirkwood/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 "kirkwood.h" + +#endif diff -ruN a/arch/arm/mach-kirkwood/include/mach/irqs.h b/arch/arm/mach-kirkwood/include/mach/irqs.h --- a/arch/arm/mach-kirkwood/include/mach/irqs.h 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/include/mach/irqs.h 2018-10-27 18:30:56.010359272 -0600 @@ -0,0 +1,65 @@ +/* + * arch/arm/mach-kirkwood/include/mach/irqs.h + * + * IRQ definitions for Marvell Kirkwood 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. + */ + +#ifndef __ASM_ARCH_IRQS_H +#define __ASM_ARCH_IRQS_H + +/* + * Low Interrupt Controller + */ +#define IRQ_KIRKWOOD_HIGH_SUM 0 +#define IRQ_KIRKWOOD_BRIDGE 1 +#define IRQ_KIRKWOOD_HOST2CPU 2 +#define IRQ_KIRKWOOD_CPU2HOST 3 +#define IRQ_KIRKWOOD_XOR_00 5 +#define IRQ_KIRKWOOD_XOR_01 6 +#define IRQ_KIRKWOOD_XOR_10 7 +#define IRQ_KIRKWOOD_XOR_11 8 +#define IRQ_KIRKWOOD_PCIE 9 +#define IRQ_KIRKWOOD_PCIE1 10 +#define IRQ_KIRKWOOD_GE00_SUM 11 +#define IRQ_KIRKWOOD_GE01_SUM 15 +#define IRQ_KIRKWOOD_USB 19 +#define IRQ_KIRKWOOD_SATA 21 +#define IRQ_KIRKWOOD_CRYPTO 22 +#define IRQ_KIRKWOOD_SPI 23 +#define IRQ_KIRKWOOD_I2S 24 +#define IRQ_KIRKWOOD_TS_0 26 +#define IRQ_KIRKWOOD_SDIO 28 +#define IRQ_KIRKWOOD_TWSI 29 +#define IRQ_KIRKWOOD_AVB 30 +#define IRQ_KIRKWOOD_TDMI 31 + +/* + * High Interrupt Controller + */ +#define IRQ_KIRKWOOD_UART_0 33 +#define IRQ_KIRKWOOD_UART_1 34 +#define IRQ_KIRKWOOD_GPIO_LOW_0_7 35 +#define IRQ_KIRKWOOD_GPIO_LOW_8_15 36 +#define IRQ_KIRKWOOD_GPIO_LOW_16_23 37 +#define IRQ_KIRKWOOD_GPIO_LOW_24_31 38 +#define IRQ_KIRKWOOD_GPIO_HIGH_0_7 39 +#define IRQ_KIRKWOOD_GPIO_HIGH_8_15 40 +#define IRQ_KIRKWOOD_GPIO_HIGH_16_23 41 +#define IRQ_KIRKWOOD_GE00_ERR 46 +#define IRQ_KIRKWOOD_GE01_ERR 47 +#define IRQ_KIRKWOOD_RTC 53 + +/* + * KIRKWOOD General Purpose Pins + */ +#define IRQ_KIRKWOOD_GPIO_START 64 +#define NR_GPIO_IRQS 50 + +#define NR_IRQS (IRQ_KIRKWOOD_GPIO_START + NR_GPIO_IRQS) + + +#endif diff -ruN a/arch/arm/mach-kirkwood/include/mach/kirkwood.h b/arch/arm/mach-kirkwood/include/mach/kirkwood.h --- a/arch/arm/mach-kirkwood/include/mach/kirkwood.h 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/include/mach/kirkwood.h 2018-10-27 18:30:56.010359272 -0600 @@ -0,0 +1,142 @@ +/* + * arch/arm/mach-kirkwood/include/mach/kirkwood.h + * + * Generic definitions for Marvell Kirkwood SoC flavors: + * 88F6180, 88F6192 and 88F6281. + * + * 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_KIRKWOOD_H +#define __ASM_ARCH_KIRKWOOD_H + +/* + * Marvell Kirkwood address maps. + * + * phys + * e0000000 PCIe #0 Memory space + * e8000000 PCIe #1 Memory space + * f1000000 on-chip peripheral registers + * f2000000 PCIe #0 I/O space + * f3000000 PCIe #1 I/O space + * f4000000 NAND controller address window + * f5000000 Security Accelerator SRAM + * + * virt phys size + * fed00000 f1000000 1M on-chip peripheral registers + * fee00000 f2000000 1M PCIe #0 I/O space + * fef00000 f3000000 1M PCIe #1 I/O space + */ + +#define KIRKWOOD_SRAM_PHYS_BASE 0xf5000000 +#define KIRKWOOD_SRAM_SIZE SZ_2K + +#define KIRKWOOD_NAND_MEM_PHYS_BASE 0xf4000000 +#define KIRKWOOD_NAND_MEM_SIZE SZ_1K + +#define KIRKWOOD_PCIE1_IO_PHYS_BASE 0xf3000000 +#define KIRKWOOD_PCIE1_IO_BUS_BASE 0x00010000 +#define KIRKWOOD_PCIE1_IO_SIZE SZ_64K + +#define KIRKWOOD_PCIE_IO_PHYS_BASE 0xf2000000 +#define KIRKWOOD_PCIE_IO_BUS_BASE 0x00000000 +#define KIRKWOOD_PCIE_IO_SIZE SZ_64K + +#define KIRKWOOD_REGS_PHYS_BASE 0xf1000000 +#define KIRKWOOD_REGS_VIRT_BASE IOMEM(0xfed00000) +#define KIRKWOOD_REGS_SIZE SZ_1M + +#define KIRKWOOD_PCIE_MEM_PHYS_BASE 0xe0000000 +#define KIRKWOOD_PCIE_MEM_BUS_BASE 0xe0000000 +#define KIRKWOOD_PCIE_MEM_SIZE SZ_128M + +#define KIRKWOOD_PCIE1_MEM_PHYS_BASE 0xe8000000 +#define KIRKWOOD_PCIE1_MEM_BUS_BASE 0xe8000000 +#define KIRKWOOD_PCIE1_MEM_SIZE SZ_128M + +/* + * Register Map + */ +#define DDR_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x00000) +#define DDR_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x00000) +#define DDR_WINDOW_CPU_BASE (DDR_PHYS_BASE + 0x1500) +#define DDR_WINDOW_CPU_SZ (0x20) +#define DDR_OPERATION_BASE (DDR_PHYS_BASE + 0x1418) + +#define DEV_BUS_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x10000) +#define DEV_BUS_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x10000) +#define SAMPLE_AT_RESET (DEV_BUS_VIRT_BASE + 0x0030) +#define DEVICE_ID (DEV_BUS_VIRT_BASE + 0x0034) +#define GPIO_LOW_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x0100) +#define GPIO_HIGH_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x0140) +#define RTC_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x0300) +#define SPI_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x0600) +#define I2C_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x1000) +#define UART0_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x2000) +#define UART0_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x2000) +#define UART1_PHYS_BASE (DEV_BUS_PHYS_BASE + 0x2100) +#define UART1_VIRT_BASE (DEV_BUS_VIRT_BASE + 0x2100) + +#define BRIDGE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x20000) +#define BRIDGE_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x20000) +#define BRIDGE_WINS_BASE (BRIDGE_PHYS_BASE) +#define BRIDGE_WINS_SZ (0x80) + +#define CRYPTO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x30000) + +#define PCIE_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x40000) +#define PCIE_LINK_CTRL (PCIE_VIRT_BASE + 0x70) +#define PCIE_STATUS (PCIE_VIRT_BASE + 0x1a04) +#define PCIE1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x44000) +#define PCIE1_LINK_CTRL (PCIE1_VIRT_BASE + 0x70) +#define PCIE1_STATUS (PCIE1_VIRT_BASE + 0x1a04) + +#define USB_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x50000) + +#define XOR0_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x60800) +#define XOR0_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x60800) +#define XOR1_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x60900) +#define XOR1_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x60900) +#define XOR0_HIGH_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x60A00) +#define XOR0_HIGH_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x60A00) +#define XOR1_HIGH_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x60B00) +#define XOR1_HIGH_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x60B00) + +#define GE00_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x70000) +#define GE01_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x74000) + +#define SATA_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x80000) +#define SATA_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0x80000) +#define SATA0_IF_CTRL (SATA_VIRT_BASE + 0x2050) +#define SATA0_PHY_MODE_2 (SATA_VIRT_BASE + 0x2330) +#define SATA1_IF_CTRL (SATA_VIRT_BASE + 0x4050) +#define SATA1_PHY_MODE_2 (SATA_VIRT_BASE + 0x4330) + +#define SDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0x90000) + +#define AUDIO_PHYS_BASE (KIRKWOOD_REGS_PHYS_BASE + 0xA0000) +#define AUDIO_VIRT_BASE (KIRKWOOD_REGS_VIRT_BASE + 0xA0000) + +/* + * Supported devices and revisions. + */ +#define MV88F6281_DEV_ID 0x6281 +#define MV88F6281_REV_Z0 0 +#define MV88F6281_REV_A0 2 +#define MV88F6281_REV_A1 3 + +#define MV88F6192_DEV_ID 0x6192 +#define MV88F6192_REV_Z0 0 +#define MV88F6192_REV_A0 2 +#define MV88F6192_REV_A1 3 + +#define MV88F6180_DEV_ID 0x6180 +#define MV88F6180_REV_A0 2 +#define MV88F6180_REV_A1 3 + +#define MV88F6282_DEV_ID 0x6282 +#define MV88F6282_REV_A0 0 +#define MV88F6282_REV_A1 1 +#endif diff -ruN a/arch/arm/mach-kirkwood/include/mach/uncompress.h b/arch/arm/mach-kirkwood/include/mach/uncompress.h --- a/arch/arm/mach-kirkwood/include/mach/uncompress.h 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/include/mach/uncompress.h 2018-10-27 18:30:56.010359272 -0600 @@ -0,0 +1,46 @@ +/* + * arch/arm/mach-kirkwood/include/mach/uncompress.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. + */ + +#include +#include + +#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() diff -ruN a/arch/arm/mach-kirkwood/ionics-stratus-setup.c b/arch/arm/mach-kirkwood/ionics-stratus-setup.c --- a/arch/arm/mach-kirkwood/ionics-stratus-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/ionics-stratus-setup.c 2018-10-27 18:30:56.010359272 -0600 @@ -0,0 +1,137 @@ +/* + * arch/arm/mach-kirkwood/ionics-stratus-setup.c + * + * Ionics Stratus Board Setup arcNumber 4184 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static struct mtd_partition ionics_stratus_nand_parts[] = { + { + .name = "u-boot", + .offset = 0, + .size = SZ_1M + }, { + .name = "uImage", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_4M + }, { + .name = "root", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + }, +}; + +static struct mv643xx_eth_platform_data ionics_stratus_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +static struct mvsdio_platform_data ionics_stratus_mvsdio_data = { + /* unfortunately the CD signal has not been connected */ +}; + +static struct gpio_led ionics_stratus_led_pins[] = { + { + .name = "status:green:led1", + .default_trigger = "none", + .gpio = 44, + .active_low = 1, + }, + { + .name = "status:green:led2", + .default_trigger = "none", + .gpio = 40, + .active_low = 1, + }, + { + .name = "status:green:led3", + .default_trigger = "default-on", + .gpio = 36, + .active_low = 1, + }, + { + .name = "status:green:led4", + .default_trigger = "default-on", + .gpio = 39, + .active_low = 1, + }, + +}; + +static struct gpio_led_platform_data ionics_stratus_led_data = { + .leds = ionics_stratus_led_pins, + .num_leds = ARRAY_SIZE(ionics_stratus_led_pins), +}; + +static struct platform_device ionics_stratus_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &ionics_stratus_led_data, + } +}; + +static unsigned int ionics_stratus_mpp_config[] __initdata = { + MPP21_GPIO, /* USB PORT 1 Pw Enable */ + MPP32_GPIO, /* USB PORT 2 Pw Enable */ + MPP48_GPIO, /* WIFI Power Down */ + MPP49_GPIO, /* WIFI Host Wakeup */ + MPP42_GPIO, /* WIFI MAC Wakeup */ + MPP44_GPIO, /* LED 1 */ + MPP40_GPIO, /* LED 2 */ + MPP36_GPIO, /* LED 3 */ + MPP39_GPIO, /* LED 4 */ + MPP23_GPIO, /* BTN 1 */ + MPP37_GPIO, /* BTN 2 */ + MPP38_GPIO, /* BTN 3 */ + 0 +}; + +static void __init ionics_stratus_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + + /* setup gpio pin select */ + kirkwood_mpp_conf(ionics_stratus_mpp_config); + + kirkwood_uart0_init(); + kirkwood_nand_init(ARRAY_AND_SIZE(ionics_stratus_nand_parts), 25); + + kirkwood_ehci_init(); + + kirkwood_ge00_init(&ionics_stratus_ge00_data); + kirkwood_sdio_init(&ionics_stratus_mvsdio_data); + + platform_device_register(&ionics_stratus_leds); +} + +MACHINE_START(IONICS_STRATUS, "Ionics Plug Computer Plus - Stratus") + /* Maintainer: Mike Brown */ + .atag_offset = 0x100, + .init_machine = ionics_stratus_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff -ruN a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c --- a/arch/arm/mach-kirkwood/irq.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/irq.c 2018-10-27 18:30:56.010359272 -0600 @@ -0,0 +1,82 @@ +/* + * arch/arm/mach-kirkwood/irq.c + * + * Kirkwood IRQ handling. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include "common.h" + +static int __initdata gpio0_irqs[4] = { + IRQ_KIRKWOOD_GPIO_LOW_0_7, + IRQ_KIRKWOOD_GPIO_LOW_8_15, + IRQ_KIRKWOOD_GPIO_LOW_16_23, + IRQ_KIRKWOOD_GPIO_LOW_24_31, +}; + +static int __initdata gpio1_irqs[4] = { + IRQ_KIRKWOOD_GPIO_HIGH_0_7, + IRQ_KIRKWOOD_GPIO_HIGH_8_15, + IRQ_KIRKWOOD_GPIO_HIGH_16_23, + 0, +}; + +#ifdef CONFIG_MULTI_IRQ_HANDLER +/* + * Compiling with both non-DT and DT support enabled, will + * break asm irq handler used by non-DT boards. Therefore, + * we provide a C-style irq handler even for non-DT boards, + * if MULTI_IRQ_HANDLER is set. + */ + +static void __iomem *kirkwood_irq_base = IRQ_VIRT_BASE; + +asmlinkage void +__exception_irq_entry kirkwood_legacy_handle_irq(struct pt_regs *regs) +{ + u32 stat; + + stat = readl_relaxed(kirkwood_irq_base + IRQ_CAUSE_LOW_OFF); + stat &= readl_relaxed(kirkwood_irq_base + IRQ_MASK_LOW_OFF); + if (stat) { + unsigned int hwirq = __fls(stat); + handle_IRQ(hwirq, regs); + return; + } + stat = readl_relaxed(kirkwood_irq_base + IRQ_CAUSE_HIGH_OFF); + stat &= readl_relaxed(kirkwood_irq_base + IRQ_MASK_HIGH_OFF); + if (stat) { + unsigned int hwirq = 32 + __fls(stat); + handle_IRQ(hwirq, regs); + return; + } +} +#endif + +void __init kirkwood_init_irq(void) +{ + orion_irq_init(0, IRQ_VIRT_BASE + IRQ_MASK_LOW_OFF); + orion_irq_init(32, IRQ_VIRT_BASE + IRQ_MASK_HIGH_OFF); + +#ifdef CONFIG_MULTI_IRQ_HANDLER + set_handle_irq(kirkwood_legacy_handle_irq); +#endif + + /* + * Initialize gpiolib for GPIOs 0-49. + */ + orion_gpio_init(NULL, 0, 32, GPIO_LOW_VIRT_BASE, 0, + IRQ_KIRKWOOD_GPIO_START, gpio0_irqs); + orion_gpio_init(NULL, 32, 18, GPIO_HIGH_VIRT_BASE, 0, + IRQ_KIRKWOOD_GPIO_START + 32, gpio1_irqs); +} diff -ruN a/arch/arm/mach-kirkwood/lacie_v2-common.c b/arch/arm/mach-kirkwood/lacie_v2-common.c --- a/arch/arm/mach-kirkwood/lacie_v2-common.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/lacie_v2-common.c 2018-10-27 18:30:56.010359272 -0600 @@ -0,0 +1,114 @@ +/* + * arch/arm/mach-kirkwood/lacie_v2-common.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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "lacie_v2-common.h" + +/***************************************************************************** + * 512KB SPI Flash on Boot Device (MACRONIX MX25L4005) + ****************************************************************************/ + +static struct mtd_partition lacie_v2_flash_parts[] = { + { + .name = "u-boot", + .size = MTDPART_SIZ_FULL, + .offset = 0, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, +}; + +static const struct flash_platform_data lacie_v2_flash = { + .type = "mx25l4005a", + .name = "spi_flash", + .parts = lacie_v2_flash_parts, + .nr_parts = ARRAY_SIZE(lacie_v2_flash_parts), +}; + +static struct spi_board_info __initdata lacie_v2_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &lacie_v2_flash, + .irq = -1, + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +void __init lacie_v2_register_flash(void) +{ + spi_register_board_info(lacie_v2_spi_slave_info, + ARRAY_SIZE(lacie_v2_spi_slave_info)); + kirkwood_spi_init(); +} + +/***************************************************************************** + * I2C devices + ****************************************************************************/ + +static struct at24_platform_data at24c04 = { + .byte_len = SZ_4K / 8, + .page_size = 16, +}; + +/* + * i2c addr | chip | description + * 0x50 | HT24LC04 | eeprom (512B) + */ + +static struct i2c_board_info __initdata lacie_v2_i2c_info[] = { + { + I2C_BOARD_INFO("24c04", 0x50), + .platform_data = &at24c04, + } +}; + +void __init lacie_v2_register_i2c_devices(void) +{ + kirkwood_i2c_init(); + i2c_register_board_info(0, lacie_v2_i2c_info, + ARRAY_SIZE(lacie_v2_i2c_info)); +} + +/***************************************************************************** + * Hard Disk power + ****************************************************************************/ + +static int __initdata lacie_v2_gpio_hdd_power[] = { 16, 17, 41, 42, 43 }; + +void __init lacie_v2_hdd_power_init(int hdd_num) +{ + int i; + int err; + + /* Power up all hard disks. */ + for (i = 0; i < hdd_num; i++) { + err = gpio_request(lacie_v2_gpio_hdd_power[i], NULL); + if (err == 0) { + err = gpio_direction_output( + lacie_v2_gpio_hdd_power[i], 1); + /* Free the HDD power GPIOs. This allow user-space to + * configure them via the gpiolib sysfs interface. */ + gpio_free(lacie_v2_gpio_hdd_power[i]); + } + if (err) + pr_err("Failed to power up HDD%d\n", i + 1); + } +} diff -ruN a/arch/arm/mach-kirkwood/lacie_v2-common.h b/arch/arm/mach-kirkwood/lacie_v2-common.h --- a/arch/arm/mach-kirkwood/lacie_v2-common.h 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/lacie_v2-common.h 2018-10-27 18:30:56.010359272 -0600 @@ -0,0 +1,16 @@ +/* + * arch/arm/mach-kirkwood/lacie_v2-common.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. + */ + +#ifndef __ARCH_KIRKWOOD_LACIE_V2_COMMON_H +#define __ARCH_KIRKWOOD_LACIE_V2_COMMON_H + +void lacie_v2_register_flash(void); +void lacie_v2_register_i2c_devices(void); +void lacie_v2_hdd_power_init(int hdd_num); + +#endif diff -ruN a/arch/arm/mach-kirkwood/mpp.c b/arch/arm/mach-kirkwood/mpp.c --- a/arch/arm/mach-kirkwood/mpp.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/mpp.c 2018-10-27 18:30:56.014359252 -0600 @@ -0,0 +1,43 @@ +/* + * arch/arm/mach-kirkwood/mpp.c + * + * MPP functions for Marvell Kirkwood 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 +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static unsigned int __init kirkwood_variant(void) +{ + u32 dev, rev; + + kirkwood_pcie_id(&dev, &rev); + + if (dev == MV88F6281_DEV_ID && rev >= MV88F6281_REV_A0) + return MPP_F6281_MASK; + if (dev == MV88F6282_DEV_ID) + return MPP_F6282_MASK; + if (dev == MV88F6192_DEV_ID && rev >= MV88F6192_REV_A0) + return MPP_F6192_MASK; + if (dev == MV88F6180_DEV_ID) + return MPP_F6180_MASK; + + pr_err("MPP setup: unknown kirkwood variant (dev %#x rev %#x)\n", + dev, rev); + return 0; +} + +void __init kirkwood_mpp_conf(unsigned int *mpp_list) +{ + orion_mpp_conf(mpp_list, kirkwood_variant(), + MPP_MAX, DEV_BUS_VIRT_BASE); +} diff -ruN a/arch/arm/mach-kirkwood/mpp.h b/arch/arm/mach-kirkwood/mpp.h --- a/arch/arm/mach-kirkwood/mpp.h 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/mpp.h 2018-10-27 18:30:56.014359252 -0600 @@ -0,0 +1,348 @@ +/* + * linux/arch/arm/mach-kirkwood/mpp.h -- Multi Purpose Pins + * + * Copyright 2009: Marvell Technology Group Ltd. + * + * 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 __KIRKWOOD_MPP_H +#define __KIRKWOOD_MPP_H + +#define MPP(_num, _sel, _in, _out, _F6180, _F6190, _F6192, _F6281, _F6282) ( \ + /* MPP number */ ((_num) & 0xff) | \ + /* MPP select value */ (((_sel) & 0xf) << 8) | \ + /* may be input signal */ ((!!(_in)) << 12) | \ + /* may be output signal */ ((!!(_out)) << 13) | \ + /* available on F6180 */ ((!!(_F6180)) << 14) | \ + /* available on F6190 */ ((!!(_F6190)) << 15) | \ + /* available on F6192 */ ((!!(_F6192)) << 16) | \ + /* available on F6281 */ ((!!(_F6281)) << 17) | \ + /* available on F6282 */ ((!!(_F6282)) << 18)) + + /* num sel i o 6180 6190 6192 6281 6282 */ + +#define MPP_F6180_MASK MPP( 0, 0x0, 0, 0, 1, 0, 0, 0, 0 ) +#define MPP_F6190_MASK MPP( 0, 0x0, 0, 0, 0, 1, 0, 0, 0 ) +#define MPP_F6192_MASK MPP( 0, 0x0, 0, 0, 0, 0, 1, 0, 0 ) +#define MPP_F6281_MASK MPP( 0, 0x0, 0, 0, 0, 0, 0, 1, 0 ) +#define MPP_F6282_MASK MPP( 0, 0x0, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP0_GPIO MPP( 0, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP0_NF_IO2 MPP( 0, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP0_SPI_SCn MPP( 0, 0x2, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP1_GPO MPP( 1, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP1_NF_IO3 MPP( 1, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP1_SPI_MOSI MPP( 1, 0x2, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP2_GPO MPP( 2, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP2_NF_IO4 MPP( 2, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP2_SPI_SCK MPP( 2, 0x2, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP3_GPO MPP( 3, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP3_NF_IO5 MPP( 3, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP3_SPI_MISO MPP( 3, 0x2, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP4_GPIO MPP( 4, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP4_NF_IO6 MPP( 4, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP4_UART0_RXD MPP( 4, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP4_SATA1_ACTn MPP( 4, 0x5, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP4_LCD_VGA_HSYNC MPP( 4, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP4_PTP_CLK MPP( 4, 0xd, 0, 0, 1, 1, 1, 1, 0 ) + +#define MPP5_GPO MPP( 5, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP5_NF_IO7 MPP( 5, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP5_UART0_TXD MPP( 5, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP5_PTP_TRIG_GEN MPP( 5, 0x4, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP5_SATA0_ACTn MPP( 5, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP5_LCD_VGA_VSYNC MPP( 5, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP6_SYSRST_OUTn MPP( 6, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP6_SPI_MOSI MPP( 6, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP6_PTP_TRIG_GEN MPP( 6, 0x3, 0, 0, 1, 1, 1, 1, 0 ) + +#define MPP7_GPO MPP( 7, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP7_PEX_RST_OUTn MPP( 7, 0x1, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP7_SPI_SCn MPP( 7, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP7_PTP_TRIG_GEN MPP( 7, 0x3, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP7_LCD_PWM MPP( 7, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP8_GPIO MPP( 8, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP8_TW0_SDA MPP( 8, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP8_UART0_RTS MPP( 8, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP8_UART1_RTS MPP( 8, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP8_MII0_RXERR MPP( 8, 0x4, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP8_SATA1_PRESENTn MPP( 8, 0x5, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP8_PTP_CLK MPP( 8, 0xc, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP8_MII0_COL MPP( 8, 0xd, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP9_GPIO MPP( 9, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP9_TW0_SCK MPP( 9, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP9_UART0_CTS MPP( 9, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP9_UART1_CTS MPP( 9, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP9_SATA0_PRESENTn MPP( 9, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP9_PTP_EVENT_REQ MPP( 9, 0xc, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP9_MII0_CRS MPP( 9, 0xd, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP10_GPO MPP( 10, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP10_SPI_SCK MPP( 10, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP10_UART0_TXD MPP( 10, 0X3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP10_SATA1_ACTn MPP( 10, 0x5, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP10_PTP_TRIG_GEN MPP( 10, 0xc, 0, 0, 1, 1, 1, 1, 0 ) + +#define MPP11_GPIO MPP( 11, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP11_SPI_MISO MPP( 11, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP11_UART0_RXD MPP( 11, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP11_PTP_EVENT_REQ MPP( 11, 0x4, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP11_PTP_TRIG_GEN MPP( 11, 0xc, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP11_PTP_CLK MPP( 11, 0xd, 0, 0, 1, 1, 1, 1, 0 ) +#define MPP11_SATA0_ACTn MPP( 11, 0x5, 0, 0, 0, 1, 1, 1, 1 ) + +#define MPP12_GPO MPP( 12, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP12_GPIO MPP( 12, 0x0, 1, 1, 0, 0, 0, 1, 0 ) +#define MPP12_SD_CLK MPP( 12, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP12_AU_SPDIF0 MPP( 12, 0xa, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP12_SPI_MOSI MPP( 12, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP12_TW1_SDA MPP( 12, 0xd, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP13_GPIO MPP( 13, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP13_SD_CMD MPP( 13, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP13_UART1_TXD MPP( 13, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP13_AU_SPDIFRMCLK MPP( 13, 0xa, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP13_LCDPWM MPP( 13, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP14_GPIO MPP( 14, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP14_SD_D0 MPP( 14, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP14_UART1_RXD MPP( 14, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP14_SATA1_PRESENTn MPP( 14, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP14_AU_SPDIFI MPP( 14, 0xa, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP14_AU_I2SDI MPP( 14, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP14_MII0_COL MPP( 14, 0xd, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP15_GPIO MPP( 15, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP15_SD_D1 MPP( 15, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP15_UART0_RTS MPP( 15, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP15_UART1_TXD MPP( 15, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP15_SATA0_ACTn MPP( 15, 0x4, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP15_SPI_CSn MPP( 15, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP16_GPIO MPP( 16, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP16_SD_D2 MPP( 16, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP16_UART0_CTS MPP( 16, 0x2, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP16_UART1_RXD MPP( 16, 0x3, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP16_SATA1_ACTn MPP( 16, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP16_LCD_EXT_REF_CLK MPP( 16, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP16_MII0_CRS MPP( 16, 0xd, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP17_GPIO MPP( 17, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP17_SD_D3 MPP( 17, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP17_SATA0_PRESENTn MPP( 17, 0x4, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP17_SATA1_ACTn MPP( 17, 0xa, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP17_TW1_SCK MPP( 17, 0xd, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP18_GPO MPP( 18, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP18_NF_IO0 MPP( 18, 0x1, 0, 0, 1, 1, 1, 1, 1 ) +#define MPP18_PEX0_CLKREQ MPP( 18, 0x2, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP19_GPO MPP( 19, 0x0, 0, 1, 1, 1, 1, 1, 1 ) +#define MPP19_NF_IO1 MPP( 19, 0x1, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP20_GPIO MPP( 20, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP20_TSMP0 MPP( 20, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP20_TDM_CH0_TX_QL MPP( 20, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP20_GE1_TXD0 MPP( 20, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP20_AU_SPDIFI MPP( 20, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP20_SATA1_ACTn MPP( 20, 0x5, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP20_LCD_D0 MPP( 20, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP21_GPIO MPP( 21, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP21_TSMP1 MPP( 21, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP21_TDM_CH0_RX_QL MPP( 21, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP21_GE1_TXD1 MPP( 21, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP21_AU_SPDIFO MPP( 21, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP21_SATA0_ACTn MPP( 21, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP21_LCD_D1 MPP( 21, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP22_GPIO MPP( 22, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP22_TSMP2 MPP( 22, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP22_TDM_CH2_TX_QL MPP( 22, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP22_GE1_TXD2 MPP( 22, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP22_AU_SPDIFRMKCLK MPP( 22, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP22_SATA1_PRESENTn MPP( 22, 0x5, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP22_LCD_D2 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP23_GPIO MPP( 23, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP23_TSMP3 MPP( 23, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP23_TDM_CH2_RX_QL MPP( 23, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP23_GE1_TXD3 MPP( 23, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP23_AU_I2SBCLK MPP( 23, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP23_SATA0_PRESENTn MPP( 23, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP23_LCD_D3 MPP( 23, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP24_GPIO MPP( 24, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP24_TSMP4 MPP( 24, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP24_TDM_SPI_CS0 MPP( 24, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP24_GE1_RXD0 MPP( 24, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP24_AU_I2SDO MPP( 24, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP24_LCD_D4 MPP( 24, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP25_GPIO MPP( 25, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP25_TSMP5 MPP( 25, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP25_TDM_SPI_SCK MPP( 25, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP25_GE1_RXD1 MPP( 25, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP25_AU_I2SLRCLK MPP( 25, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP25_LCD_D5 MPP( 25, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP26_GPIO MPP( 26, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP26_TSMP6 MPP( 26, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP26_TDM_SPI_MISO MPP( 26, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP26_GE1_RXD2 MPP( 26, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP26_AU_I2SMCLK MPP( 26, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP26_LCD_D6 MPP( 26, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP27_GPIO MPP( 27, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP27_TSMP7 MPP( 27, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP27_TDM_SPI_MOSI MPP( 27, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP27_GE1_RXD3 MPP( 27, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP27_AU_I2SDI MPP( 27, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP27_LCD_D7 MPP( 27, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP28_GPIO MPP( 28, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP28_TSMP8 MPP( 28, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP28_TDM_CODEC_INTn MPP( 28, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP28_GE1_COL MPP( 28, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP28_AU_EXTCLK MPP( 28, 0x4, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP28_LCD_D8 MPP( 28, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP29_GPIO MPP( 29, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP29_TSMP9 MPP( 29, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP29_TDM_CODEC_RSTn MPP( 29, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP29_GE1_TCLK MPP( 29, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP29_LCD_D9 MPP( 29, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP30_GPIO MPP( 30, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP30_TSMP10 MPP( 30, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP30_TDM_PCLK MPP( 30, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP30_GE1_RXCTL MPP( 30, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP30_LCD_D10 MPP( 30, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP31_GPIO MPP( 31, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP31_TSMP11 MPP( 31, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP31_TDM_FS MPP( 31, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP31_GE1_RXCLK MPP( 31, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP31_LCD_D11 MPP( 31, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP32_GPIO MPP( 32, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP32_TSMP12 MPP( 32, 0x1, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP32_TDM_DRX MPP( 32, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP32_GE1_TCLKOUT MPP( 32, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP32_LCD_D12 MPP( 32, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP33_GPO MPP( 33, 0x0, 0, 1, 0, 1, 1, 1, 1 ) +#define MPP33_TDM_DTX MPP( 33, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP33_GE1_TXCTL MPP( 33, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP33_LCD_D13 MPP( 33, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP34_GPIO MPP( 34, 0x0, 1, 1, 0, 1, 1, 1, 1 ) +#define MPP34_TDM_SPI_CS1 MPP( 34, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP34_GE1_TXEN MPP( 34, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP34_SATA1_ACTn MPP( 34, 0x5, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP34_LCD_D14 MPP( 34, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP35_GPIO MPP( 35, 0x0, 1, 1, 1, 1, 1, 1, 1 ) +#define MPP35_TDM_CH0_TX_QL MPP( 35, 0x2, 0, 0, 0, 0, 1, 1, 1 ) +#define MPP35_GE1_RXERR MPP( 35, 0x3, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP35_SATA0_ACTn MPP( 35, 0x5, 0, 0, 0, 1, 1, 1, 1 ) +#define MPP35_LCD_D15 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP35_MII0_RXERR MPP( 35, 0xc, 0, 0, 1, 1, 1, 1, 1 ) + +#define MPP36_GPIO MPP( 36, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP36_TSMP0 MPP( 36, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP36_TDM_SPI_CS1 MPP( 36, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP36_AU_SPDIFI MPP( 36, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP36_TW1_SDA MPP( 36, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP37_GPIO MPP( 37, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP37_TSMP1 MPP( 37, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP37_TDM_CH2_TX_QL MPP( 37, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP37_AU_SPDIFO MPP( 37, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP37_TW1_SCK MPP( 37, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP38_GPIO MPP( 38, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP38_TSMP2 MPP( 38, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP38_TDM_CH2_RX_QL MPP( 38, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP38_AU_SPDIFRMLCLK MPP( 38, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP38_LCD_D18 MPP( 38, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP39_GPIO MPP( 39, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP39_TSMP3 MPP( 39, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP39_TDM_SPI_CS0 MPP( 39, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP39_AU_I2SBCLK MPP( 39, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP39_LCD_D19 MPP( 39, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP40_GPIO MPP( 40, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP40_TSMP4 MPP( 40, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP40_TDM_SPI_SCK MPP( 40, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP40_AU_I2SDO MPP( 40, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP40_LCD_D20 MPP( 40, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP41_GPIO MPP( 41, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP41_TSMP5 MPP( 41, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP41_TDM_SPI_MISO MPP( 41, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP41_AU_I2SLRCLK MPP( 41, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP41_LCD_D21 MPP( 41, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP42_GPIO MPP( 42, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP42_TSMP6 MPP( 42, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP42_TDM_SPI_MOSI MPP( 42, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP42_AU_I2SMCLK MPP( 42, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP42_LCD_D22 MPP( 42, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP43_GPIO MPP( 43, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP43_TSMP7 MPP( 43, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP43_TDM_CODEC_INTn MPP( 43, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP43_AU_I2SDI MPP( 43, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP43_LCD_D23 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP44_GPIO MPP( 44, 0x0, 1, 1, 1, 0, 0, 1, 1 ) +#define MPP44_TSMP8 MPP( 44, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP44_TDM_CODEC_RSTn MPP( 44, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP44_AU_EXTCLK MPP( 44, 0x4, 0, 0, 1, 0, 0, 1, 1 ) +#define MPP44_LCD_CLK MPP( 44, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP45_GPIO MPP( 45, 0x0, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP45_TSMP9 MPP( 45, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP45_TDM_PCLK MPP( 45, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP245_LCD_E MPP( 45, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP46_GPIO MPP( 46, 0x0, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP46_TSMP10 MPP( 46, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP46_TDM_FS MPP( 46, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP46_LCD_HSYNC MPP( 46, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP47_GPIO MPP( 47, 0x0, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP47_TSMP11 MPP( 47, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP47_TDM_DRX MPP( 47, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP47_LCD_VSYNC MPP( 47, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP48_GPIO MPP( 48, 0x0, 1, 1, 0, 0, 0, 1, 1 ) +#define MPP48_TSMP12 MPP( 48, 0x1, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP48_TDM_DTX MPP( 48, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP48_LCD_D16 MPP( 22, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP49_GPIO MPP( 49, 0x0, 1, 1, 0, 0, 0, 1, 0 ) +#define MPP49_GPO MPP( 49, 0x0, 0, 1, 0, 0, 0, 0, 1 ) +#define MPP49_TSMP9 MPP( 49, 0x1, 0, 0, 0, 0, 0, 1, 0 ) +#define MPP49_TDM_CH0_RX_QL MPP( 49, 0x2, 0, 0, 0, 0, 0, 1, 1 ) +#define MPP49_PTP_CLK MPP( 49, 0x5, 0, 0, 0, 0, 0, 1, 0 ) +#define MPP49_PEX0_CLKREQ MPP( 49, 0xa, 0, 0, 0, 0, 0, 0, 1 ) +#define MPP49_LCD_D17 MPP( 49, 0xb, 0, 0, 0, 0, 0, 0, 1 ) + +#define MPP_MAX 49 + +void kirkwood_mpp_conf(unsigned int *mpp_list); + +#endif diff -ruN a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c --- a/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c 2018-10-27 18:30:56.014359252 -0600 @@ -0,0 +1,172 @@ +/* + * arch/arm/mach-kirkwood/mv88f6281gtw_ge-setup.c + * + * Marvell 88F6281 GTW GE Board 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static struct mv643xx_eth_platform_data mv88f6281gtw_ge_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_NONE, + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, +}; + +static struct dsa_chip_data mv88f6281gtw_ge_switch_chip_data = { + .port_names[0] = "lan1", + .port_names[1] = "lan2", + .port_names[2] = "lan3", + .port_names[3] = "lan4", + .port_names[4] = "wan", + .port_names[5] = "cpu", +}; + +static struct dsa_platform_data mv88f6281gtw_ge_switch_plat_data = { + .nr_chips = 1, + .chip = &mv88f6281gtw_ge_switch_chip_data, +}; + +static const struct flash_platform_data mv88f6281gtw_ge_spi_slave_data = { + .type = "mx25l12805d", +}; + +static struct spi_board_info __initdata mv88f6281gtw_ge_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &mv88f6281gtw_ge_spi_slave_data, + .irq = -1, + .max_speed_hz = 50000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +static struct gpio_keys_button mv88f6281gtw_ge_button_pins[] = { + { + .code = KEY_RESTART, + .gpio = 47, + .desc = "SWR Button", + .active_low = 1, + }, { + .code = KEY_WPS_BUTTON, + .gpio = 46, + .desc = "WPS Button", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data mv88f6281gtw_ge_button_data = { + .buttons = mv88f6281gtw_ge_button_pins, + .nbuttons = ARRAY_SIZE(mv88f6281gtw_ge_button_pins), +}; + +static struct platform_device mv88f6281gtw_ge_buttons = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &mv88f6281gtw_ge_button_data, + }, +}; + +static struct gpio_led mv88f6281gtw_ge_led_pins[] = { + { + .name = "gtw:green:Status", + .gpio = 20, + .active_low = 0, + }, { + .name = "gtw:red:Status", + .gpio = 21, + .active_low = 0, + }, { + .name = "gtw:green:USB", + .gpio = 12, + .active_low = 0, + }, +}; + +static struct gpio_led_platform_data mv88f6281gtw_ge_led_data = { + .leds = mv88f6281gtw_ge_led_pins, + .num_leds = ARRAY_SIZE(mv88f6281gtw_ge_led_pins), +}; + +static struct platform_device mv88f6281gtw_ge_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &mv88f6281gtw_ge_led_data, + }, +}; + +static unsigned int mv88f6281gtw_ge_mpp_config[] __initdata = { + MPP12_GPO, /* Status#_USB pin */ + MPP20_GPIO, /* Status#_GLED pin */ + MPP21_GPIO, /* Status#_RLED pin */ + MPP46_GPIO, /* WPS_Switch pin */ + MPP47_GPIO, /* SW_Init pin */ + 0 +}; + +static void __init mv88f6281gtw_ge_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(mv88f6281gtw_ge_mpp_config); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&mv88f6281gtw_ge_ge00_data); + kirkwood_ge00_switch_init(&mv88f6281gtw_ge_switch_plat_data, NO_IRQ); + spi_register_board_info(mv88f6281gtw_ge_spi_slave_info, + ARRAY_SIZE(mv88f6281gtw_ge_spi_slave_info)); + kirkwood_spi_init(); + kirkwood_uart0_init(); + platform_device_register(&mv88f6281gtw_ge_leds); + platform_device_register(&mv88f6281gtw_ge_buttons); +} + +static int __init mv88f6281gtw_ge_pci_init(void) +{ + if (machine_is_mv88f6281gtw_ge()) + kirkwood_pcie_init(KW_PCIE0); + + return 0; +} +subsys_initcall(mv88f6281gtw_ge_pci_init); + +MACHINE_START(MV88F6281GTW_GE, "Marvell 88F6281 GTW GE Board") + /* Maintainer: Lennert Buytenhek */ + .atag_offset = 0x100, + .init_machine = mv88f6281gtw_ge_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff -ruN a/arch/arm/mach-kirkwood/nas6210-setup.c b/arch/arm/mach-kirkwood/nas6210-setup.c --- a/arch/arm/mach-kirkwood/nas6210-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/nas6210-setup.c 2018-10-27 18:30:56.014359252 -0600 @@ -0,0 +1,186 @@ +/* + * arch/arm/mach-kirkwood/nas6210-setup.c + * + * Raidsonic ICYBOX NAS6210 Board 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +#define NAS6210_GPIO_POWER_OFF 24 + +static struct mtd_partition nas6210_nand_parts[] = { + { + .name = "u-boot", + .offset = 0, + .size = SZ_1M + }, { + .name = "uImage", + .offset = MTDPART_OFS_NXTBLK, + .size = 6*SZ_1M + }, { + .name = "root", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + }, +}; + +static struct mv643xx_eth_platform_data nas6210_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +static struct mv_sata_platform_data nas6210_sata_data = { + .n_ports = 2, +}; + +static struct gpio_led nas6210_led_pins[] = { + { + .name = "status:green:power", + .default_trigger = "default-on", + .gpio = 25, + .active_low = 0, + }, + { + .name = "status:red:power", + .default_trigger = "none", + .gpio = 22, + .active_low = 0, + }, + { + .name = "status:red:usb_copy", + .default_trigger = "none", + .gpio = 27, + .active_low = 0, + }, +}; + +static struct gpio_led_platform_data nas6210_led_data = { + .leds = nas6210_led_pins, + .num_leds = ARRAY_SIZE(nas6210_led_pins), +}; + +static struct platform_device nas6210_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &nas6210_led_data, + } +}; + +static struct gpio_keys_button nas6210_buttons[] = { + { + .code = KEY_COPY, + .gpio = 29, + .desc = "USB Copy", + .active_low = 1, + }, + { + .code = KEY_RESTART, + .gpio = 28, + .desc = "Reset", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data nas6210_button_data = { + .buttons = nas6210_buttons, + .nbuttons = ARRAY_SIZE(nas6210_buttons), +}; + +static struct platform_device nas6210_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &nas6210_button_data, + } +}; + +static unsigned int nas6210_mpp_config[] __initdata = { + MPP0_NF_IO2, + MPP1_NF_IO3, + MPP2_NF_IO4, + MPP3_NF_IO5, + MPP4_NF_IO6, + MPP5_NF_IO7, + MPP18_NF_IO0, + MPP19_NF_IO1, + MPP22_GPIO, /* Power LED red */ + MPP24_GPIO, /* Power off device */ + MPP25_GPIO, /* Power LED green */ + MPP27_GPIO, /* USB transfer LED */ + MPP28_GPIO, /* Reset button */ + MPP29_GPIO, /* USB Copy button */ + 0 +}; + +static void nas6210_power_off(void) +{ + gpio_set_value(NAS6210_GPIO_POWER_OFF, 1); +} + +static void __init nas6210_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(nas6210_mpp_config); + + kirkwood_nand_init(ARRAY_AND_SIZE(nas6210_nand_parts), 25); + kirkwood_ehci_init(); + kirkwood_ge00_init(&nas6210_ge00_data); + kirkwood_sata_init(&nas6210_sata_data); + kirkwood_uart0_init(); + platform_device_register(&nas6210_leds); + platform_device_register(&nas6210_button_device); + if (gpio_request(NAS6210_GPIO_POWER_OFF, "power-off") == 0 && + gpio_direction_output(NAS6210_GPIO_POWER_OFF, 0) == 0) + pm_power_off = nas6210_power_off; + else + pr_err("nas6210: failed to configure power-off GPIO\n"); +} + +static int __init nas6210_pci_init(void) +{ + if (machine_is_nas6210()) { + u32 dev, rev; + + kirkwood_pcie_id(&dev, &rev); + if (dev == MV88F6282_DEV_ID) + kirkwood_pcie_init(KW_PCIE1 | KW_PCIE0); + else + kirkwood_pcie_init(KW_PCIE0); + } + + return 0; +} +subsys_initcall(nas6210_pci_init); + +MACHINE_START(NAS6210, "RaidSonic ICY BOX IB-NAS6210") + /* Maintainer: */ + .atag_offset = 0x100, + .init_machine = nas6210_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff -ruN a/arch/arm/mach-kirkwood/netspace_v2-setup.c b/arch/arm/mach-kirkwood/netspace_v2-setup.c --- a/arch/arm/mach-kirkwood/netspace_v2-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/netspace_v2-setup.c 2018-10-27 18:30:56.014359252 -0600 @@ -0,0 +1,293 @@ +/* + * arch/arm/mach-kirkwood/netspace_v2-setup.c + * + * LaCie Network Space v2 board setup + * + * Copyright (C) 2009 Simon Guinot + * Copyright (C) 2009 Benoît Canet + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" +#include "lacie_v2-common.h" + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data netspace_v2_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +/***************************************************************************** + * SATA + ****************************************************************************/ + +static struct mv_sata_platform_data netspace_v2_sata_data = { + .n_ports = 2, +}; + +/***************************************************************************** + * GPIO keys + ****************************************************************************/ + +#define NETSPACE_V2_PUSH_BUTTON 32 + +static struct gpio_keys_button netspace_v2_buttons[] = { + [0] = { + .code = KEY_POWER, + .gpio = NETSPACE_V2_PUSH_BUTTON, + .desc = "Power push button", + .active_low = 0, + }, +}; + +static struct gpio_keys_platform_data netspace_v2_button_data = { + .buttons = netspace_v2_buttons, + .nbuttons = ARRAY_SIZE(netspace_v2_buttons), +}; + +static struct platform_device netspace_v2_gpio_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &netspace_v2_button_data, + }, +}; + +/***************************************************************************** + * GPIO LEDs + ****************************************************************************/ + +#define NETSPACE_V2_GPIO_RED_LED 12 + +static struct gpio_led netspace_v2_gpio_led_pins[] = { + { + .name = "ns_v2:red:fail", + .gpio = NETSPACE_V2_GPIO_RED_LED, + }, +}; + +static struct gpio_led_platform_data netspace_v2_gpio_leds_data = { + .num_leds = ARRAY_SIZE(netspace_v2_gpio_led_pins), + .leds = netspace_v2_gpio_led_pins, +}; + +static struct platform_device netspace_v2_gpio_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &netspace_v2_gpio_leds_data, + }, +}; + +/***************************************************************************** + * Dual-GPIO CPLD LEDs + ****************************************************************************/ + +#define NETSPACE_V2_GPIO_BLUE_LED_SLOW 29 +#define NETSPACE_V2_GPIO_BLUE_LED_CMD 30 + +static struct ns2_led netspace_v2_led_pins[] = { + { + .name = "ns_v2:blue:sata", + .cmd = NETSPACE_V2_GPIO_BLUE_LED_CMD, + .slow = NETSPACE_V2_GPIO_BLUE_LED_SLOW, + }, +}; + +static struct ns2_led_platform_data netspace_v2_leds_data = { + .num_leds = ARRAY_SIZE(netspace_v2_led_pins), + .leds = netspace_v2_led_pins, +}; + +static struct platform_device netspace_v2_leds = { + .name = "leds-ns2", + .id = -1, + .dev = { + .platform_data = &netspace_v2_leds_data, + }, +}; + +/***************************************************************************** + * GPIO fan + ****************************************************************************/ + +/* Designed for fan 40x40x16: ADDA AD0412LB-D50 6000rpm@12v */ +static struct gpio_fan_speed netspace_max_v2_fan_speed[] = { + { 0, 0 }, + { 1500, 15 }, + { 1700, 14 }, + { 1800, 13 }, + { 2100, 12 }, + { 3100, 11 }, + { 3300, 10 }, + { 4300, 9 }, + { 5500, 8 }, +}; + +static unsigned netspace_max_v2_fan_ctrl[] = { 22, 7, 33, 23 }; + +static struct gpio_fan_alarm netspace_max_v2_fan_alarm = { + .gpio = 25, + .active_low = 1, +}; + +static struct gpio_fan_platform_data netspace_max_v2_fan_data = { + .num_ctrl = ARRAY_SIZE(netspace_max_v2_fan_ctrl), + .ctrl = netspace_max_v2_fan_ctrl, + .alarm = &netspace_max_v2_fan_alarm, + .num_speed = ARRAY_SIZE(netspace_max_v2_fan_speed), + .speed = netspace_max_v2_fan_speed, +}; + +static struct platform_device netspace_max_v2_gpio_fan = { + .name = "gpio-fan", + .id = -1, + .dev = { + .platform_data = &netspace_max_v2_fan_data, + }, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static unsigned int netspace_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP4_NF_IO6, + MPP5_NF_IO7, + MPP6_SYSRST_OUTn, + MPP7_GPO, /* Fan speed (bit 1) */ + MPP8_TW0_SDA, + MPP9_TW0_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP12_GPO, /* Red led */ + MPP14_GPIO, /* USB fuse */ + MPP16_GPIO, /* SATA 0 power */ + MPP17_GPIO, /* SATA 1 power */ + MPP18_NF_IO0, + MPP19_NF_IO1, + MPP20_SATA1_ACTn, + MPP21_SATA0_ACTn, + MPP22_GPIO, /* Fan speed (bit 0) */ + MPP23_GPIO, /* Fan power */ + MPP24_GPIO, /* USB mode select */ + MPP25_GPIO, /* Fan rotation fail */ + MPP26_GPIO, /* USB device vbus */ + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* Blue led (slow register) */ + MPP30_GPIO, /* Blue led (command register) */ + MPP31_GPIO, /* Board power off */ + MPP32_GPIO, /* Power button (0 = Released, 1 = Pushed) */ + MPP33_GPO, /* Fan speed (bit 2) */ + 0 +}; + +#define NETSPACE_V2_GPIO_POWER_OFF 31 + +static void netspace_v2_power_off(void) +{ + gpio_set_value(NETSPACE_V2_GPIO_POWER_OFF, 1); +} + +static void __init netspace_v2_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(netspace_v2_mpp_config); + + if (machine_is_netspace_max_v2()) + lacie_v2_hdd_power_init(2); + else + lacie_v2_hdd_power_init(1); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&netspace_v2_ge00_data); + kirkwood_sata_init(&netspace_v2_sata_data); + kirkwood_uart0_init(); + lacie_v2_register_flash(); + lacie_v2_register_i2c_devices(); + + platform_device_register(&netspace_v2_leds); + platform_device_register(&netspace_v2_gpio_leds); + platform_device_register(&netspace_v2_gpio_buttons); + if (machine_is_netspace_max_v2()) + platform_device_register(&netspace_max_v2_gpio_fan); + + if (gpio_request(NETSPACE_V2_GPIO_POWER_OFF, "power-off") == 0 && + gpio_direction_output(NETSPACE_V2_GPIO_POWER_OFF, 0) == 0) + pm_power_off = netspace_v2_power_off; + else + pr_err("netspace_v2: failed to configure power-off GPIO\n"); +} + +#ifdef CONFIG_MACH_NETSPACE_V2 +MACHINE_START(NETSPACE_V2, "LaCie Network Space v2") + .atag_offset = 0x100, + .init_machine = netspace_v2_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_INETSPACE_V2 +MACHINE_START(INETSPACE_V2, "LaCie Internet Space v2") + .atag_offset = 0x100, + .init_machine = netspace_v2_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_NETSPACE_MAX_V2 +MACHINE_START(NETSPACE_MAX_V2, "LaCie Network Space Max v2") + .atag_offset = 0x100, + .init_machine = netspace_v2_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif diff -ruN a/arch/arm/mach-kirkwood/netxbig_v2-setup.c b/arch/arm/mach-kirkwood/netxbig_v2-setup.c --- a/arch/arm/mach-kirkwood/netxbig_v2-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/netxbig_v2-setup.c 2018-10-27 18:30:56.014359252 -0600 @@ -0,0 +1,422 @@ +/* + * arch/arm/mach-kirkwood/netxbig_v2-setup.c + * + * LaCie 2Big and 5Big Network v2 board setup + * + * Copyright (C) 2010 Simon Guinot + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" +#include "lacie_v2-common.h" + +/***************************************************************************** + * Ethernet + ****************************************************************************/ + +static struct mv643xx_eth_platform_data netxbig_v2_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +static struct mv643xx_eth_platform_data netxbig_v2_ge01_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +/***************************************************************************** + * SATA + ****************************************************************************/ + +static struct mv_sata_platform_data netxbig_v2_sata_data = { + .n_ports = 2, +}; + +/***************************************************************************** + * GPIO keys + ****************************************************************************/ + +#define NETXBIG_V2_GPIO_SWITCH_POWER_ON 13 +#define NETXBIG_V2_GPIO_SWITCH_POWER_OFF 15 +#define NETXBIG_V2_GPIO_FUNC_BUTTON 34 + +#define NETXBIG_V2_SWITCH_POWER_ON 0x1 +#define NETXBIG_V2_SWITCH_POWER_OFF 0x2 + +static struct gpio_keys_button netxbig_v2_buttons[] = { + [0] = { + .type = EV_SW, + .code = NETXBIG_V2_SWITCH_POWER_ON, + .gpio = NETXBIG_V2_GPIO_SWITCH_POWER_ON, + .desc = "Back power switch (on|auto)", + .active_low = 1, + }, + [1] = { + .type = EV_SW, + .code = NETXBIG_V2_SWITCH_POWER_OFF, + .gpio = NETXBIG_V2_GPIO_SWITCH_POWER_OFF, + .desc = "Back power switch (auto|off)", + .active_low = 1, + }, + [2] = { + .code = KEY_OPTION, + .gpio = NETXBIG_V2_GPIO_FUNC_BUTTON, + .desc = "Function button", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data netxbig_v2_button_data = { + .buttons = netxbig_v2_buttons, + .nbuttons = ARRAY_SIZE(netxbig_v2_buttons), +}; + +static struct platform_device netxbig_v2_gpio_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { + .platform_data = &netxbig_v2_button_data, + }, +}; + +/***************************************************************************** + * GPIO extension LEDs + ****************************************************************************/ + +/* + * The LEDs are controlled by a CPLD and can be configured through a GPIO + * extension bus: + * + * - address register : bit [0-2] -> GPIO [47-49] + * - data register : bit [0-2] -> GPIO [44-46] + * - enable register : GPIO 29 + */ + +static int netxbig_v2_gpio_ext_addr[] = { 47, 48, 49 }; +static int netxbig_v2_gpio_ext_data[] = { 44, 45, 46 }; + +static struct netxbig_gpio_ext netxbig_v2_gpio_ext = { + .addr = netxbig_v2_gpio_ext_addr, + .num_addr = ARRAY_SIZE(netxbig_v2_gpio_ext_addr), + .data = netxbig_v2_gpio_ext_data, + .num_data = ARRAY_SIZE(netxbig_v2_gpio_ext_data), + .enable = 29, +}; + +/* + * Address register selection: + * + * addr | register + * ---------------------------- + * 0 | front LED + * 1 | front LED brightness + * 2 | SATA LED brightness + * 3 | SATA0 LED + * 4 | SATA1 LED + * 5 | SATA2 LED + * 6 | SATA3 LED + * 7 | SATA4 LED + * + * Data register configuration: + * + * data | LED brightness + * ------------------------------------------------- + * 0 | min (off) + * - | - + * 7 | max + * + * data | front LED mode + * ------------------------------------------------- + * 0 | fix off + * 1 | fix blue on + * 2 | fix red on + * 3 | blink blue on=1 sec and blue off=1 sec + * 4 | blink red on=1 sec and red off=1 sec + * 5 | blink blue on=2.5 sec and red on=0.5 sec + * 6 | blink blue on=1 sec and red on=1 sec + * 7 | blink blue on=0.5 sec and blue off=2.5 sec + * + * data | SATA LED mode + * ------------------------------------------------- + * 0 | fix off + * 1 | SATA activity blink + * 2 | fix red on + * 3 | blink blue on=1 sec and blue off=1 sec + * 4 | blink red on=1 sec and red off=1 sec + * 5 | blink blue on=2.5 sec and red on=0.5 sec + * 6 | blink blue on=1 sec and red on=1 sec + * 7 | fix blue on + */ + +static int netxbig_v2_red_mled[NETXBIG_LED_MODE_NUM] = { + [NETXBIG_LED_OFF] = 0, + [NETXBIG_LED_ON] = 2, + [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE, + [NETXBIG_LED_TIMER1] = 4, + [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE, +}; + +static int netxbig_v2_blue_pwr_mled[NETXBIG_LED_MODE_NUM] = { + [NETXBIG_LED_OFF] = 0, + [NETXBIG_LED_ON] = 1, + [NETXBIG_LED_SATA] = NETXBIG_LED_INVALID_MODE, + [NETXBIG_LED_TIMER1] = 3, + [NETXBIG_LED_TIMER2] = 7, +}; + +static int netxbig_v2_blue_sata_mled[NETXBIG_LED_MODE_NUM] = { + [NETXBIG_LED_OFF] = 0, + [NETXBIG_LED_ON] = 7, + [NETXBIG_LED_SATA] = 1, + [NETXBIG_LED_TIMER1] = 3, + [NETXBIG_LED_TIMER2] = NETXBIG_LED_INVALID_MODE, +}; + +static struct netxbig_led_timer netxbig_v2_led_timer[] = { + [0] = { + .delay_on = 500, + .delay_off = 500, + .mode = NETXBIG_LED_TIMER1, + }, + [1] = { + .delay_on = 500, + .delay_off = 1000, + .mode = NETXBIG_LED_TIMER2, + }, +}; + +#define NETXBIG_LED(_name, maddr, mval, baddr) \ + { .name = _name, \ + .mode_addr = maddr, \ + .mode_val = mval, \ + .bright_addr = baddr } + +static struct netxbig_led net2big_v2_leds_ctrl[] = { + NETXBIG_LED("net2big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1), + NETXBIG_LED("net2big-v2:red:power", 0, netxbig_v2_red_mled, 1), + NETXBIG_LED("net2big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net2big-v2:red:sata0", 3, netxbig_v2_red_mled, 2), + NETXBIG_LED("net2big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net2big-v2:red:sata1", 4, netxbig_v2_red_mled, 2), +}; + +static struct netxbig_led_platform_data net2big_v2_leds_data = { + .gpio_ext = &netxbig_v2_gpio_ext, + .timer = netxbig_v2_led_timer, + .num_timer = ARRAY_SIZE(netxbig_v2_led_timer), + .leds = net2big_v2_leds_ctrl, + .num_leds = ARRAY_SIZE(net2big_v2_leds_ctrl), +}; + +static struct netxbig_led net5big_v2_leds_ctrl[] = { + NETXBIG_LED("net5big-v2:blue:power", 0, netxbig_v2_blue_pwr_mled, 1), + NETXBIG_LED("net5big-v2:red:power", 0, netxbig_v2_red_mled, 1), + NETXBIG_LED("net5big-v2:blue:sata0", 3, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata0", 3, netxbig_v2_red_mled, 2), + NETXBIG_LED("net5big-v2:blue:sata1", 4, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata1", 4, netxbig_v2_red_mled, 2), + NETXBIG_LED("net5big-v2:blue:sata2", 5, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata2", 5, netxbig_v2_red_mled, 2), + NETXBIG_LED("net5big-v2:blue:sata3", 6, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata3", 6, netxbig_v2_red_mled, 2), + NETXBIG_LED("net5big-v2:blue:sata4", 7, netxbig_v2_blue_sata_mled, 2), + NETXBIG_LED("net5big-v2:red:sata5", 7, netxbig_v2_red_mled, 2), +}; + +static struct netxbig_led_platform_data net5big_v2_leds_data = { + .gpio_ext = &netxbig_v2_gpio_ext, + .timer = netxbig_v2_led_timer, + .num_timer = ARRAY_SIZE(netxbig_v2_led_timer), + .leds = net5big_v2_leds_ctrl, + .num_leds = ARRAY_SIZE(net5big_v2_leds_ctrl), +}; + +static struct platform_device netxbig_v2_leds = { + .name = "leds-netxbig", + .id = -1, + .dev = { + .platform_data = &net2big_v2_leds_data, + }, +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ + +static unsigned int net2big_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP6_SYSRST_OUTn, + MPP7_GPO, /* Request power-off */ + MPP8_TW0_SDA, + MPP9_TW0_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP13_GPIO, /* Rear power switch (on|auto) */ + MPP14_GPIO, /* USB fuse alarm */ + MPP15_GPIO, /* Rear power switch (auto|off) */ + MPP16_GPIO, /* SATA HDD1 power */ + MPP17_GPIO, /* SATA HDD2 power */ + MPP20_SATA1_ACTn, + MPP21_SATA0_ACTn, + MPP24_GPIO, /* USB mode select */ + MPP26_GPIO, /* USB device vbus */ + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* GPIO extension ALE */ + MPP34_GPIO, /* Rear Push button */ + MPP35_GPIO, /* Inhibit switch power-off */ + MPP36_GPIO, /* SATA HDD1 presence */ + MPP37_GPIO, /* SATA HDD2 presence */ + MPP40_GPIO, /* eSATA presence */ + MPP44_GPIO, /* GPIO extension (data 0) */ + MPP45_GPIO, /* GPIO extension (data 1) */ + MPP46_GPIO, /* GPIO extension (data 2) */ + MPP47_GPIO, /* GPIO extension (addr 0) */ + MPP48_GPIO, /* GPIO extension (addr 1) */ + MPP49_GPIO, /* GPIO extension (addr 2) */ + 0 +}; + +static unsigned int net5big_v2_mpp_config[] __initdata = { + MPP0_SPI_SCn, + MPP1_SPI_MOSI, + MPP2_SPI_SCK, + MPP3_SPI_MISO, + MPP6_SYSRST_OUTn, + MPP7_GPO, /* Request power-off */ + MPP8_TW0_SDA, + MPP9_TW0_SCK, + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP13_GPIO, /* Rear power switch (on|auto) */ + MPP14_GPIO, /* USB fuse alarm */ + MPP15_GPIO, /* Rear power switch (auto|off) */ + MPP16_GPIO, /* SATA HDD1 power */ + MPP17_GPIO, /* SATA HDD2 power */ + MPP20_GE1_TXD0, + MPP21_GE1_TXD1, + MPP22_GE1_TXD2, + MPP23_GE1_TXD3, + MPP24_GE1_RXD0, + MPP25_GE1_RXD1, + MPP26_GE1_RXD2, + MPP27_GE1_RXD3, + MPP28_GPIO, /* USB enable host vbus */ + MPP29_GPIO, /* GPIO extension ALE */ + MPP30_GE1_RXCTL, + MPP31_GE1_RXCLK, + MPP32_GE1_TCLKOUT, + MPP33_GE1_TXCTL, + MPP34_GPIO, /* Rear Push button */ + MPP35_GPIO, /* Inhibit switch power-off */ + MPP36_GPIO, /* SATA HDD1 presence */ + MPP37_GPIO, /* SATA HDD2 presence */ + MPP38_GPIO, /* SATA HDD3 presence */ + MPP39_GPIO, /* SATA HDD4 presence */ + MPP40_GPIO, /* SATA HDD5 presence */ + MPP41_GPIO, /* SATA HDD3 power */ + MPP42_GPIO, /* SATA HDD4 power */ + MPP43_GPIO, /* SATA HDD5 power */ + MPP44_GPIO, /* GPIO extension (data 0) */ + MPP45_GPIO, /* GPIO extension (data 1) */ + MPP46_GPIO, /* GPIO extension (data 2) */ + MPP47_GPIO, /* GPIO extension (addr 0) */ + MPP48_GPIO, /* GPIO extension (addr 1) */ + MPP49_GPIO, /* GPIO extension (addr 2) */ + 0 +}; + +#define NETXBIG_V2_GPIO_POWER_OFF 7 + +static void netxbig_v2_power_off(void) +{ + gpio_set_value(NETXBIG_V2_GPIO_POWER_OFF, 1); +} + +static void __init netxbig_v2_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + if (machine_is_net2big_v2()) + kirkwood_mpp_conf(net2big_v2_mpp_config); + else + kirkwood_mpp_conf(net5big_v2_mpp_config); + + if (machine_is_net2big_v2()) + lacie_v2_hdd_power_init(2); + else + lacie_v2_hdd_power_init(5); + + kirkwood_ehci_init(); + kirkwood_ge00_init(&netxbig_v2_ge00_data); + if (machine_is_net5big_v2()) + kirkwood_ge01_init(&netxbig_v2_ge01_data); + kirkwood_sata_init(&netxbig_v2_sata_data); + kirkwood_uart0_init(); + lacie_v2_register_flash(); + lacie_v2_register_i2c_devices(); + + if (machine_is_net5big_v2()) + netxbig_v2_leds.dev.platform_data = &net5big_v2_leds_data; + platform_device_register(&netxbig_v2_leds); + platform_device_register(&netxbig_v2_gpio_buttons); + + if (gpio_request(NETXBIG_V2_GPIO_POWER_OFF, "power-off") == 0 && + gpio_direction_output(NETXBIG_V2_GPIO_POWER_OFF, 0) == 0) + pm_power_off = netxbig_v2_power_off; + else + pr_err("netxbig_v2: failed to configure power-off GPIO\n"); +} + +#ifdef CONFIG_MACH_NET2BIG_V2 +MACHINE_START(NET2BIG_V2, "LaCie 2Big Network v2") + .atag_offset = 0x100, + .init_machine = netxbig_v2_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_NET5BIG_V2 +MACHINE_START(NET5BIG_V2, "LaCie 5Big Network v2") + .atag_offset = 0x100, + .init_machine = netxbig_v2_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif diff -ruN a/arch/arm/mach-kirkwood/nsa310-setup.c b/arch/arm/mach-kirkwood/nsa310-setup.c --- a/arch/arm/mach-kirkwood/nsa310-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/nsa310-setup.c 2018-10-27 18:30:56.014359252 -0600 @@ -0,0 +1,359 @@ +/* + * arch/arm/mach-kirkwood/nsa310-setup.c + * + * Zyxel NSA-310 Setup, by AA666 and Peeter123 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" +#include +#include + +static void nsa310_timerfunc(unsigned long data); +static DEFINE_TIMER(timer, nsa310_timerfunc, 0, 0); + +static struct mtd_partition nsa310_nand_parts[] = { + { + .name = "uboot", + .offset = 0, + .size = 0x100000, + .mask_flags = MTD_WRITEABLE + }, { + .name = "uboot_env", + .offset = MTDPART_OFS_NXTBLK, + .size = 0x80000 + }, { + .name = "key_store", + .offset = MTDPART_OFS_NXTBLK, + .size = 0x80000 + }, { + .name = "info", + .offset = MTDPART_OFS_NXTBLK, + .size = 0x80000 + }, { + .name = "etc", + .offset = MTDPART_OFS_NXTBLK, + .size = 0xA00000 + }, { + .name = "kernel_1", + .offset = MTDPART_OFS_NXTBLK, + .size = 0xA00000 + }, { + .name = "rootfs1", + .offset = MTDPART_OFS_NXTBLK, + .size = 0x2FC0000 + }, { + .name = "kernel_2", + .offset = MTDPART_OFS_NXTBLK, + .size = 0xA00000 + }, { + .name = "rootfs2", + .offset = MTDPART_OFS_NXTBLK, + .size = 0x2FC0000 + }, +}; + +static struct i2c_board_info __initdata nsa310_i2c_rtc = { + I2C_BOARD_INFO("pcf8563", 0x51), +}; + +static struct mv643xx_eth_platform_data nsa310_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), + .speed = SPEED_1000, + .duplex = DUPLEX_FULL, +}; + +static struct mv_sata_platform_data nsa310_sata_data = { + .n_ports = 2, +}; + +static unsigned int nsa310_mpp_config[] __initdata = { + MPP36_GPIO, // Reset button + MPP37_GPIO, // Copy button + MPP46_GPIO, // Power button + + MPP48_GPIO, // Power Off + MPP21_GPIO, // USB Power Off + + MPP28_GPIO, // Sys LED Green + MPP29_GPIO, // Sys LED Yellow + MPP41_GPIO, // SATA1 LED Green + MPP42_GPIO, // SATA1 LED Red + MPP12_GPO, // SATA2 LED Green + MPP13_GPIO, // SATA2 LED Red + MPP39_GPIO, // Copy LED Green + MPP40_GPIO, // Copy LED Red + MPP15_GPIO, // USB LED Green + + MPP14_GPIO, // MCU Data + MPP16_GPIO, // MCU Clk + MPP17_GPIO, // MCU Act + + MPP38_GPIO, // VID B0 + MPP45_GPIO, // VID B1 + + MPP44_GPIO, // Buzzer + MPP43_GPIO, // HTP + + MPP47_GPIO, // Power Resume Data + MPP49_GPIO, // Power Resume Clock + + 0 +}; + +static struct gpio_led nsa310_gpio_led[] = { + { + .name = "nsa310:green:System", + .default_trigger = "timer", + .gpio = 28, + .active_low = 0, + + }, + { + .name = "nsa310:red:System", + .default_trigger = "none", + .gpio = 29, + .active_low = 0, + }, + { + .name = "nsa310:green:SATA1", + .default_trigger = "none", + .gpio = 41, + .active_low = 0, + }, + { + .name = "nsa310:red:SATA1", + .default_trigger = "sata-disk", + .gpio = 42, + .active_low = 0, + }, + { + .name = "nsa310:green:SATA2", + .default_trigger = "none", + .gpio = 12, + .active_low = 0, + }, + { + .name = "nsa310:red:SATA2", + .default_trigger = "none", + .gpio = 13, + .active_low = 0, + }, + { + .name = "nsa310:green:USB", + .default_trigger = "none", + .gpio = 15, + .active_low = 0, + }, + { + .name = "nsa310:green:Copy", + .default_trigger = "none", + .gpio = 39, + .active_low = 0, + }, + { + .name = "nsa310:red:Copy", + .default_trigger = "none", + .gpio = 40, + .active_low = 0, + }, +}; + + +static int nsa310_gpio_blink_set(unsigned gpio, int state, + unsigned long *delay_on, unsigned long *delay_off) +{ + +// Use hardware acceleration +// if (delay_on && delay_off && !*delay_on && !*delay_off) +// *delay_on = *delay_off = 100; + + switch(state) { + case GPIO_LED_NO_BLINK_LOW: + case GPIO_LED_NO_BLINK_HIGH: + orion_gpio_set_blink(gpio, 0); + gpio_set_value(gpio, state); + break; + case GPIO_LED_BLINK: + orion_gpio_set_blink(gpio, 1); + break; + } + return 0; +} + + +static struct gpio_led_platform_data nsa310_led_data = { + .leds = nsa310_gpio_led, + .num_leds = ARRAY_SIZE(nsa310_gpio_led), + .gpio_blink_set = nsa310_gpio_blink_set, +}; + +static struct platform_device nsa310_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { .platform_data = &nsa310_led_data, } +}; + +static struct gpio_keys_button nsa310_gpio_keys_button[] = { + { + .code = KEY_POWER, + .type = EV_KEY, + .gpio = 46, + .desc = "Power Button", + .active_low = 0, + .debounce_interval = 1000, + }, + { + .code = KEY_COPY, + .type = EV_KEY, + .gpio = 37, + .desc = "USB Copy", + .active_low = 1, + .debounce_interval = 1000, + }, + { + .code = KEY_OPTION, + .type = EV_KEY, + .gpio = 36, + .desc = "Reset", + .active_low = 1, + .debounce_interval = 1000, + }, +}; + +static struct gpio_keys_platform_data nsa310_keys_data = { + .buttons = nsa310_gpio_keys_button, + .nbuttons = ARRAY_SIZE(nsa310_gpio_keys_button), +}; + + +static struct platform_device nsa310_buttons = { + .name = "gpio-keys", + .id = -1, + .dev = { .platform_data = &nsa310_keys_data, } +}; + +static void nsa310_power_off(void) +{ +// +//don't work with sysfs + printk(KERN_INFO "Activating power off GPIO pin...\n"); + gpio_set_value(48, 1); + +// If machine goes to restart, uncomment next lines for infinite loop +/* printk(KERN_INFO "System halted, please turn off power manually\n"); + gpio_set_value(28, 0); + do { + mdelay(1000); + } while(1); +*/ +} + +static void nsa310_timerfunc(unsigned long data) +{ +// Activate USB Power + if (gpio_request(21, "USB Power") != 0 || gpio_direction_output(21, 1) != 0) + printk(KERN_ERR "failed to setup USB power GPIO\n"); + else + printk(KERN_INFO "USB power enabled\n"); + gpio_free(21); +} + +static void __init nsa310_init(void) +{ + u32 dev, rev; + + kirkwood_init(); + + kirkwood_mpp_conf(nsa310_mpp_config); + kirkwood_nand_init(ARRAY_AND_SIZE(nsa310_nand_parts), 25); + kirkwood_ge00_init(&nsa310_ge00_data); + kirkwood_pcie_id(&dev, &rev); + + kirkwood_sata_init(&nsa310_sata_data); + kirkwood_uart0_init(); + kirkwood_i2c_init(); + i2c_register_board_info(0, &nsa310_i2c_rtc, 1); + + platform_device_register(&nsa310_leds); + platform_device_register(&nsa310_buttons); + + kirkwood_ehci_init(); +// USB Power delay for 20 sec + timer.function = nsa310_timerfunc; + timer.data = 0; + timer.expires = jiffies + msecs_to_jiffies(20000); + add_timer(&timer); + + +/* Power resume control */ + gpio_request(49, "Power-clk"); + gpio_direction_output(49, 1); + gpio_request(47, "Power-data"); +// Clear power resume +// gpio_direction_output(47, 0); +// Set power resume + gpio_direction_output(47, 1); + udelay(1000); +// gpio_direction_output(49, 0); + gpio_set_value(49, 0); +// release GPIO? +//test + gpio_free(47); + gpio_free(49); + printk(KERN_INFO "Power resume enabled\n"); + + +// Activate Power-off GPIO + if (gpio_request(48, "Power-off") == 0 && gpio_direction_output(48, 0) == 0) { +// gpio_free(48); + pm_power_off = nsa310_power_off; + printk(KERN_INFO "Power-off GPIO enabled\n"); + } else + printk(KERN_ERR "failed to configure Power-off GPIO\n"); + +}; + +static int __init nsa310_pci_init(void) +{ + if (machine_is_nsa310()) + kirkwood_pcie_init(KW_PCIE0); + return 0; +} + +subsys_initcall(nsa310_pci_init); + +MACHINE_START(NSA310, "Zyxel NSA-310") + .atag_offset = 0x100, + .init_machine = nsa310_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff -ruN a/arch/arm/mach-kirkwood/nsa320-setup.c b/arch/arm/mach-kirkwood/nsa320-setup.c --- a/arch/arm/mach-kirkwood/nsa320-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/nsa320-setup.c 2018-10-27 18:30:56.018359231 -0600 @@ -0,0 +1,305 @@ +/* + * arch/arm/mach-kirkwood/nsa320-setup.c + * + * ZyXEL NSA320 2-Bay Power Media Server 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static struct mtd_partition nsa320_nand_parts[] = { + { + .name = "uboot", + .offset = 0, + .size = SZ_1M, + .mask_flags = MTD_WRITEABLE + }, { + .name = "uboot_env", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_512K + }, { + .name = "key_store", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_512K + }, { + .name = "info", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_512K + }, { + .name = "etc", + .offset = MTDPART_OFS_NXTBLK, + .size = 10 * SZ_1M + }, { + .name = "kernel_1", + .offset = MTDPART_OFS_NXTBLK, + .size = 10 * SZ_1M + }, { + .name = "rootfs1", + .offset = MTDPART_OFS_NXTBLK, + .size = 48 * SZ_1M - SZ_256K + }, { + .name = "kernel_2", + .offset = MTDPART_OFS_NXTBLK, + .size = 10 * SZ_1M + }, { + .name = "rootfs2", + .offset = MTDPART_OFS_NXTBLK, + .size = 48 * SZ_1M - SZ_256K + }, +}; + +static struct i2c_board_info __initdata nsa320_i2c_rtc = { + I2C_BOARD_INFO("pcf8563", 0x51), +}; + +static struct mv643xx_eth_platform_data nsa320_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(1), +}; + +static struct mv_sata_platform_data nsa320_sata_data = { + .n_ports = 2, +}; + +static struct gpio_keys_button nsa320_button_pins[] = { + { + .code = KEY_RESTART, + .gpio = 36, + .desc = "Reset", + .active_low = 1, + .debounce_interval = 1000, + }, { + .code = KEY_COPY, + .gpio = 37, + .desc = "Copy", + .active_low = 1, + .debounce_interval = 1000, + }, { + .code = KEY_POWER, + .gpio = 46, + .desc = "Power", + .active_low = 0, + .debounce_interval = 1000, + }, +}; + +static struct gpio_keys_platform_data nsa320_button_data = { + .buttons = nsa320_button_pins, + .nbuttons = ARRAY_SIZE(nsa320_button_pins), +}; + +static struct platform_device nsa320_buttons = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &nsa320_button_data, + }, +}; + +static struct gpio_led nsa320_led_pins[] = { + { + .name = "nsa320:green:hdd2", + .default_trigger = "ide-disk2", + .gpio = 12, + .active_low = 0, + }, { + .name = "nsa320:red:hdd2", + .default_trigger = "default-off", + .gpio = 13, + .active_low = 0, + }, { + .name = "nsa320:green:usb", + .default_trigger = "default-off", + .gpio = 15, + .active_low = 0, + }, { + .name = "nsa320:green:sys", + .default_trigger = "default-off", + .gpio = 28, + .active_low = 0, + }, { + .name = "nsa320:orange:sys", + .default_trigger = "default-on", + .gpio = 29, + .active_low = 0, + }, { + .name = "nsa320:green:copy", + .default_trigger = "default-off", + .gpio = 39, + .active_low = 0, + }, { + .name = "nsa320:red:copy", + .default_trigger = "default-off", + .gpio = 40, + .active_low = 0, + }, { + .name = "nsa320:green:hdd1", + .default_trigger = "ide-disk1", + .gpio = 41, + .active_low = 0, + }, { + .name = "nsa320:red:hdd1", + .default_trigger = "default-off", + .gpio = 42, + .active_low = 0, + }, +}; + +static int nsa320_gpio_blink_set(unsigned gpio, int state, + unsigned long *delay_on, unsigned long *delay_off) +{ + switch(state) { + case GPIO_LED_NO_BLINK_LOW: + case GPIO_LED_NO_BLINK_HIGH: + orion_gpio_set_blink(gpio, 0); + gpio_set_value(gpio, state); + break; + case GPIO_LED_BLINK: + orion_gpio_set_blink(gpio, 1); + break; + } + return 0; +} + +static struct gpio_led_platform_data nsa320_led_data = { + .leds = nsa320_led_pins, + .num_leds = ARRAY_SIZE(nsa320_led_pins), + .gpio_blink_set = nsa320_gpio_blink_set, +}; + +static struct platform_device nsa320_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &nsa320_led_data, + }, +}; + +static struct nsa3xx_hwmon_platform_data nsa320_hwmon_data = { + /* GPIOs connected to Holtek HT46R065 MCU */ + .act_pin = 17, + .clk_pin = 16, + .data_pin = 14, +}; + +static struct platform_device nsa320_hwmon = { + .name = "nsa3xx-hwmon", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &nsa320_hwmon_data, + }, +}; + +static unsigned int nsa320_mpp_config[] __initdata = { + MPP8_TW0_SDA, /* PCF8563 RTC chip */ + MPP9_TW0_SCK, /* connected to TWSI */ + MPP12_GPO, /* HDD2 LED (green) */ + MPP13_GPIO, /* HDD2 LED (red) */ + MPP14_GPIO, /* MCU DATA pin (in) */ + MPP15_GPIO, /* USB LED (green) */ + MPP16_GPIO, /* MCU CLK pin (out) */ + MPP17_GPIO, /* MCU ACT pin (out) */ + MPP21_GPIO, /* USB power */ + MPP28_GPIO, /* SYS LED (green) */ + MPP29_GPIO, /* SYS LED (orange) */ + MPP36_GPIO, /* reset button */ + MPP37_GPIO, /* copy button */ + MPP38_GPIO, /* VID B0 */ + MPP39_GPIO, /* COPY LED (green) */ + MPP40_GPIO, /* COPY LED (red) */ + MPP41_GPIO, /* HDD1 LED (green) */ + MPP42_GPIO, /* HDD1 LED (red) */ + MPP43_GPIO, /* HTP pin */ + MPP44_GPIO, /* buzzer */ + MPP45_GPIO, /* VID B1 */ + MPP46_GPIO, /* power button */ + MPP47_GPIO, /* power resume data */ + MPP48_GPIO, /* power off */ + MPP49_GPIO, /* power resume clock */ + 0 +}; + +#define NSA320_GPIO_USB_POWER 21 +#define NSA320_GPIO_POWER_OFF 48 + +static void nsa320_power_off(void) +{ + gpio_set_value(NSA320_GPIO_POWER_OFF, 1); +} + +static int __initdata usb_power = 1; /* default "on" */ + +static int __init nsa320_usb_power(char *str) +{ + usb_power = strncmp(str, "off", 3) ? 1 : 0; + return 1; +} +/* Parse boot_command_line string nsa320_usb_power=on|off */ +__setup("nsa320_usb_power=", nsa320_usb_power); + +static void __init nsa320_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + + kirkwood_mpp_conf(nsa320_mpp_config); + kirkwood_uart0_init(); + kirkwood_nand_init(ARRAY_AND_SIZE(nsa320_nand_parts), 40); + kirkwood_ge00_init(&nsa320_ge00_data); + kirkwood_sata_init(&nsa320_sata_data); + + platform_device_register(&nsa320_leds); + platform_device_register(&nsa320_buttons); + platform_device_register(&nsa320_hwmon); + + kirkwood_i2c_init(); + i2c_register_board_info(0, &nsa320_i2c_rtc, 1); + + if (gpio_request(NSA320_GPIO_USB_POWER, "USB Power Enable") || + gpio_direction_output(NSA320_GPIO_USB_POWER, usb_power)) + pr_err("nsa320: failed to configure USB power enable GPIO\n"); + gpio_free(NSA320_GPIO_USB_POWER); + + kirkwood_ehci_init(); + + if (gpio_request(NSA320_GPIO_POWER_OFF, "power-off") || + gpio_direction_output(NSA320_GPIO_POWER_OFF, 0)) + pr_err("nsa320: failed to configure power-off GPIO\n"); + else + pm_power_off = nsa320_power_off; +} + +MACHINE_START(NSA320, "ZyXEL NSA320 2-Bay Power Media Server") + /* Maintainer: Peter Schildmann */ + .atag_offset = 0x100, + .init_machine = nsa320_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff -ruN a/arch/arm/mach-kirkwood/nsa325-setup.c b/arch/arm/mach-kirkwood/nsa325-setup.c --- a/arch/arm/mach-kirkwood/nsa325-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/nsa325-setup.c 2018-10-27 18:30:56.018359231 -0600 @@ -0,0 +1,359 @@ +/* + * arch/arm/mach-kirkwood/nsa325-setup.c + * + * ZyXEL NSA325 2-Bay Power Media Server 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static struct mtd_partition nsa325_nand_parts[] = { + { + .name = "uboot", + .offset = 0, + .size = SZ_1M, + .mask_flags = MTD_WRITEABLE + }, { + .name = "uboot_env", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_512K + }, { + .name = "key_store", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_512K + }, { + .name = "info", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_512K + }, { + .name = "etc", + .offset = MTDPART_OFS_NXTBLK, + .size = 10 * SZ_1M + }, { + .name = "kernel_1", + .offset = MTDPART_OFS_NXTBLK, + .size = 10 * SZ_1M + }, { + .name = "rootfs1", + .offset = MTDPART_OFS_NXTBLK, + .size = 48 * SZ_1M - SZ_256K + }, { + .name = "kernel_2", + .offset = MTDPART_OFS_NXTBLK, + .size = 10 * SZ_1M + }, { + .name = "rootfs2", + .offset = MTDPART_OFS_NXTBLK, + .size = 48 * SZ_1M - SZ_256K + }, +}; + +static struct i2c_board_info __initdata nsa325_i2c_rtc = { + I2C_BOARD_INFO("pcf8563", 0x51), +}; + +static struct mv643xx_eth_platform_data nsa325_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(1), +}; + +static struct mv_sata_platform_data nsa325_sata_data = { + .n_ports = 2, +}; + +static struct gpio_keys_button nsa325_button_pins[] = { + { + .code = KEY_RESTART, + .gpio = 36, + .desc = "Reset", + .active_low = 1, + .debounce_interval = 1000, + }, { + .code = KEY_COPY, + .gpio = 37, + .desc = "Copy", + .active_low = 1, + .debounce_interval = 1000, + }, { + .code = KEY_POWER, + .gpio = 46, + .desc = "Power", + .active_low = 0, + .debounce_interval = 1000, + }, +}; + +static struct gpio_keys_platform_data nsa325_button_data = { + .buttons = nsa325_button_pins, + .nbuttons = ARRAY_SIZE(nsa325_button_pins), +}; + +static struct platform_device nsa325_buttons = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &nsa325_button_data, + }, +}; + +static struct gpio_led nsa325_led_pins[] = { + { + .name = "nsa325:green:hdd2", + .default_trigger = "ide-disk2", + .gpio = 12, + .active_low = 0, + }, { + .name = "nsa325:red:hdd2", + .default_trigger = "default-off", + .gpio = 13, + .active_low = 0, + }, { + .name = "nsa325:green:usb", + .default_trigger = "usb-host", + .gpio = 15, + .active_low = 0, + }, { + .name = "nsa325:green:sys", + .default_trigger = "default-off", + .gpio = 28, + .active_low = 0, + }, { + .name = "nsa325:orange:sys", + .default_trigger = "default-on", + .gpio = 29, + .active_low = 0, + }, { + .name = "nsa325:green:copy", + .default_trigger = "default-off", + .gpio = 39, + .active_low = 0, + }, { + .name = "nsa325:red:copy", + .default_trigger = "default-off", + .gpio = 40, + .active_low = 0, + }, { + .name = "nsa325:green:hdd1", + .default_trigger = "ide-disk1", + .gpio = 41, + .active_low = 0, + }, { + .name = "nsa325:red:hdd1", + .default_trigger = "default-off", + .gpio = 42, + .active_low = 0, + }, +}; + +static int nsa325_gpio_blink_set(unsigned gpio, int state, + unsigned long *delay_on, unsigned long *delay_off) +{ + switch(state) { + case GPIO_LED_NO_BLINK_LOW: + case GPIO_LED_NO_BLINK_HIGH: + orion_gpio_set_blink(gpio, 0); + gpio_set_value(gpio, state); + break; + case GPIO_LED_BLINK: + orion_gpio_set_blink(gpio, 1); + break; + } + return 0; +} + +static struct gpio_led_platform_data nsa325_led_data = { + .leds = nsa325_led_pins, + .num_leds = ARRAY_SIZE(nsa325_led_pins), + .gpio_blink_set = nsa325_gpio_blink_set, +}; + +static struct platform_device nsa325_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &nsa325_led_data, + }, +}; + +static struct nsa3xx_hwmon_platform_data nsa325_hwmon_data = { + /* GPIOs connected to Holtek HT46R065 MCU */ + .act_pin = 17, + .clk_pin = 16, + .data_pin = 14, +}; + +static struct platform_device nsa325_hwmon = { + .name = "nsa3xx-hwmon", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &nsa325_hwmon_data, + }, +}; + +static unsigned int nsa325_mpp_config[] __initdata = { + MPP8_TW0_SDA, /* PCF8563 RTC chip */ + MPP9_TW0_SCK, /* connected to TWSI */ + MPP12_GPO, /* HDD2 LED (green) */ + MPP13_GPIO, /* ? HDD2 LED (red) ? */ + MPP14_GPIO, /* MCU DATA pin (in) */ + MPP15_GPIO, /* USB LED (green) */ + MPP16_GPIO, /* MCU CLK pin (out) */ + MPP17_GPIO, /* MCU ACT pin (out) */ + MPP21_GPIO, /* USB power */ + MPP28_GPIO, /* SYS LED (green) */ + MPP29_GPIO, /* SYS LED (orange) */ + MPP36_GPIO, /* reset button */ + MPP37_GPIO, /* copy button */ + MPP38_GPIO, /* VID B0 */ + MPP39_GPIO, /* COPY LED (green) */ + MPP40_GPIO, /* COPY LED (red) */ + MPP41_GPIO, /* HDD1 LED (green) */ + MPP42_GPIO, /* HDD1 LED (red) */ + MPP43_GPIO, /* HTP pin */ + MPP44_GPIO, /* buzzer */ + MPP45_GPIO, /* VID B1 */ + MPP46_GPIO, /* power button */ + MPP47_GPIO, /* HDD2 power */ + MPP48_GPIO, /* power off */ + 0 +}; + +#define NSA325_GPIO_WATCHDOG 14 +#define NSA325_GPIO_USB_POWER 21 +#define NSA325_GPIO_HDD2_POWER 47 +#define NSA325_GPIO_POWER_OFF 48 + +static void nsa325_power_off(void) +{ + gpio_set_value(NSA325_GPIO_POWER_OFF, 1); +} + +static int __initdata usb_power = 1; /* default "on" */ + +static int __init nsa325_usb_power(char *str) +{ + usb_power = strncmp(str, "off", 3) ? 1 : 0; + return 1; +} +/* Parse boot_command_line string nsa325_usb_power=on|off */ +__setup("nsa325_usb_power=", nsa325_usb_power); + +/* the nsa325 uses the 88E1310S Alaska, and has an MCU attached to the LED[2] via tristate interrupt */ +static int nsa325_phy_fixup(struct phy_device *phydev) +{ + int err; + int temp; + /* go to page 3 */ + err = phy_write(phydev, 22, 3); + if (err < 0) + return err; + /* read page 3, register 17 */ + temp = phy_read(phydev, 17); + /* clear bit 4, set bit 5 */ + temp &= ~(1<<4); + temp |= (1<<5); + /* write page 3, register 17 */ + err = phy_write(phydev, 17, temp); + if (err < 0) + return err; + /* go to page 0 */ + err = phy_write(phydev, 22, 0); + if (err < 0) + return err; + + return 0; +} + +static void __init nsa325_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + + kirkwood_mpp_conf(nsa325_mpp_config); + + /* setup the phy fixup */ + phy_register_fixup_for_uid(MARVELL_PHY_ID_88E1318S,MARVELL_PHY_ID_MASK,nsa325_phy_fixup); + kirkwood_ge00_init(&nsa325_ge00_data); + + kirkwood_uart0_init(); + kirkwood_nand_init(ARRAY_AND_SIZE(nsa325_nand_parts), 40); + + /* turn off the watchdog */ + gpio_set_value(NSA325_GPIO_WATCHDOG, 1); + + /* turn on the second drive bay */ + if (gpio_request(NSA325_GPIO_HDD2_POWER, "HDD2 Power Enable") || + gpio_direction_output(NSA325_GPIO_HDD2_POWER,1)) + pr_err("nsa325: failed to configure HDD2 power enable GPIO\n"); + gpio_free(NSA325_GPIO_HDD2_POWER); + + kirkwood_sata_init(&nsa325_sata_data); + + platform_device_register(&nsa325_leds); + platform_device_register(&nsa325_buttons); + platform_device_register(&nsa325_hwmon); + + kirkwood_i2c_init(); + i2c_register_board_info(0, &nsa325_i2c_rtc, 1); + + if (gpio_request(NSA325_GPIO_USB_POWER, "USB Power Enable") || + gpio_direction_output(NSA325_GPIO_USB_POWER, usb_power)) + pr_err("nsa325: failed to configure USB power enable GPIO\n"); + gpio_free(NSA325_GPIO_USB_POWER); + + kirkwood_ehci_init(); + + if (gpio_request(NSA325_GPIO_POWER_OFF, "power-off") || + gpio_direction_output(NSA325_GPIO_POWER_OFF, 0)) + pr_err("nsa325: failed to configure power-off GPIO\n"); + else + pm_power_off = nsa325_power_off; +} + +static int __init nsa325_pci_init(void) +{ + if (machine_is_nsa325()) + kirkwood_pcie_init(KW_PCIE0); + + return 0; +} +subsys_initcall(nsa325_pci_init); + +MACHINE_START(NSA325, "ZyXEL NSA325 2-Bay Power Media Server") + /* Maintainer: Jason Plum */ + .atag_offset = 0x100, + .init_machine = nsa325_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END diff -ruN a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c --- a/arch/arm/mach-kirkwood/openrd-setup.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/openrd-setup.c 2018-10-27 18:30:56.018359231 -0600 @@ -0,0 +1,255 @@ +/* + * arch/arm/mach-kirkwood/openrd-setup.c + * + * Marvell OpenRD (Base|Client|Ultimate) Board 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "common.h" +#include "mpp.h" + +static struct mtd_partition openrd_nand_parts[] = { + { + .name = "u-boot", + .offset = 0, + .size = SZ_1M, + .mask_flags = MTD_WRITEABLE + }, { + .name = "uImage", + .offset = MTDPART_OFS_NXTBLK, + .size = SZ_4M + }, { + .name = "root", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL + }, +}; + +static struct mv643xx_eth_platform_data openrd_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(8), +}; + +static struct mv643xx_eth_platform_data openrd_ge01_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(24), +}; + +static struct mv_sata_platform_data openrd_sata_data = { + .n_ports = 2, +}; + +static struct mvsdio_platform_data openrd_mvsdio_data = { + .gpio_card_detect = 29, /* MPP29 used as SD card detect */ + .gpio_write_protect = -1, +}; + +static unsigned int openrd_mpp_config[] __initdata = { + MPP12_SD_CLK, + MPP13_SD_CMD, + MPP14_SD_D0, + MPP15_SD_D1, + MPP16_SD_D2, + MPP17_SD_D3, + MPP28_GPIO, + MPP29_GPIO, + MPP34_GPIO, + 0 +}; + +/* Configure MPP for UART1 */ +static unsigned int openrd_uart1_mpp_config[] __initdata = { + MPP13_UART1_TXD, + MPP14_UART1_RXD, + 0 +}; + +static struct i2c_board_info i2c_board_info[] __initdata = { + { + I2C_BOARD_INFO("cs42l51", 0x4a), + }, +}; + +static struct platform_device openrd_client_audio_device = { + .name = "openrd-client-audio", + .id = -1, +}; + +static int __initdata uart1; + +static int __init sd_uart_selection(char *str) +{ + uart1 = -EINVAL; + + /* Default is SD. Change if required, for UART */ + if (!str) + return 0; + + if (!strncmp(str, "232", 3)) { + uart1 = 232; + } else if (!strncmp(str, "485", 3)) { + /* OpenRD-Base doesn't have RS485. Treat is as an + * unknown argument & just have default setting - + * which is SD */ + if (machine_is_openrd_base()) { + uart1 = -ENODEV; + return 1; + } + + uart1 = 485; + } + return 1; +} +/* Parse boot_command_line string kw_openrd_init_uart1=232/485 */ +__setup("kw_openrd_init_uart1=", sd_uart_selection); + +static int __init uart1_mpp_config(void) +{ + kirkwood_mpp_conf(openrd_uart1_mpp_config); + + if (gpio_request(34, "SD_UART1_SEL")) { + pr_err("GPIO request 34 failed for SD/UART1 selection\n"); + return -EIO; + } + + if (gpio_request(28, "RS232_RS485_SEL")) { + pr_err("GPIO request 28 failed for RS232/RS485 selection\n"); + gpio_free(34); + return -EIO; + } + + /* Select UART1 + * Pin # 34: 0 => UART1, 1 => SD */ + gpio_direction_output(34, 0); + + /* Select RS232 OR RS485 + * Pin # 28: 0 => RS232, 1 => RS485 */ + if (uart1 == 232) + gpio_direction_output(28, 0); + else + gpio_direction_output(28, 1); + + gpio_free(34); + gpio_free(28); + + return 0; +} + +static void __init openrd_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(openrd_mpp_config); + + kirkwood_uart0_init(); + kirkwood_nand_init(openrd_nand_parts, ARRAY_SIZE(openrd_nand_parts), + 25); + + kirkwood_ehci_init(); + + if (machine_is_openrd_ultimate()) { + openrd_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0); + openrd_ge01_data.phy_addr = MV643XX_ETH_PHY_ADDR(1); + } + + kirkwood_ge00_init(&openrd_ge00_data); + if (!machine_is_openrd_base()) + kirkwood_ge01_init(&openrd_ge01_data); + + kirkwood_sata_init(&openrd_sata_data); + + kirkwood_i2c_init(); + + if (machine_is_openrd_client() || machine_is_openrd_ultimate()) { + platform_device_register(&openrd_client_audio_device); + i2c_register_board_info(0, i2c_board_info, + ARRAY_SIZE(i2c_board_info)); + kirkwood_audio_init(); + } + + if (uart1 <= 0) { + if (uart1 < 0) + pr_err("Invalid kernel parameter to select UART1. Defaulting to SD. ERROR CODE: %d\n", + uart1); + + /* Select SD + * Pin # 34: 0 => UART1, 1 => SD */ + if (gpio_request(34, "SD_UART1_SEL")) { + pr_err("GPIO request 34 failed for SD/UART1 selection\n"); + } else { + + gpio_direction_output(34, 1); + gpio_free(34); + kirkwood_sdio_init(&openrd_mvsdio_data); + } + } else { + if (!uart1_mpp_config()) + kirkwood_uart1_init(); + } +} + +static int __init openrd_pci_init(void) +{ + if (machine_is_openrd_base() || + machine_is_openrd_client() || + machine_is_openrd_ultimate()) + kirkwood_pcie_init(KW_PCIE0); + + return 0; +} +subsys_initcall(openrd_pci_init); + +#ifdef CONFIG_MACH_OPENRD_BASE +MACHINE_START(OPENRD_BASE, "Marvell OpenRD Base Board") + /* Maintainer: Dhaval Vasa */ + .atag_offset = 0x100, + .init_machine = openrd_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_OPENRD_CLIENT +MACHINE_START(OPENRD_CLIENT, "Marvell OpenRD Client Board") + /* Maintainer: Dhaval Vasa */ + .atag_offset = 0x100, + .init_machine = openrd_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif + +#ifdef CONFIG_MACH_OPENRD_ULTIMATE +MACHINE_START(OPENRD_ULTIMATE, "Marvell OpenRD Ultimate Board") + /* Maintainer: Dhaval Vasa */ + .atag_offset = 0x100, + .init_machine = openrd_init, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .init_time = kirkwood_timer_init, + .restart = kirkwood_restart, +MACHINE_END +#endif diff -ruN a/arch/arm/mach-kirkwood/pcie.c b/arch/arm/mach-kirkwood/pcie.c --- a/arch/arm/mach-kirkwood/pcie.c 1969-12-31 17:00:00.000000000 -0700 +++ b/arch/arm/mach-kirkwood/pcie.c 2018-10-27 18:30:56.018359231 -0600 @@ -0,0 +1,296 @@ +/* + * arch/arm/mach-kirkwood/pcie.c + * + * PCIe functions for Marvell Kirkwood 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 +#include +#include +#include +#include +#include