diff -uNr linux-3.2.34-go.orig/arch/arm/mach-kirkwood/Kconfig linux-3.2.34-go/arch/arm/mach-kirkwood/Kconfig --- linux-3.2.34-go.orig/arch/arm/mach-kirkwood/Kconfig 2012-11-19 21:03:42.654743005 +0100 +++ linux-3.2.34-go/arch/arm/mach-kirkwood/Kconfig 2012-11-19 21:04:02.744505974 +0100 @@ -148,6 +148,12 @@ Say 'Y' here if you want your kernel to support the Buffalo LS-CHLv2 Series. +config MACH_LSWVL + bool "Buffalo LS-WVL Series" + help + Say 'Y' here if you want your kernel to support the + Buffalo LS-WVL/E-AP NAS + endmenu endif diff -uNr linux-3.2.34-go.orig/arch/arm/mach-kirkwood/lswvl-setup.c linux-3.2.34-go/arch/arm/mach-kirkwood/lswvl-setup.c --- linux-3.2.34-go.orig/arch/arm/mach-kirkwood/lswvl-setup.c 1970-01-01 01:00:00.000000000 +0100 +++ linux-3.2.34-go/arch/arm/mach-kirkwood/lswvl-setup.c 2012-11-19 21:04:02.745505962 +0100 @@ -0,0 +1,366 @@ +/* + * arch/arm/mach-kirkwood/lswvl-setup.c + * + * Buffalo LS-WVL Series 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 "common.h" +#include "mpp.h" + + +/***************************************************************************** + * 512MB NAND Flash on Device bus CS0 + ****************************************************************************/ +static struct mtd_partition lswvl_nand_parts[] = { + { + .name = "boot", + .offset = 0, + .size = 16 * 1024 * 1024, + }, { + .name = "rootfs", + .offset = MTDPART_OFS_NXTBLK, + .size = 488 * 1024 * 1024, + }, { + .name = "reserve", + .offset = MTDPART_OFS_NXTBLK, + .size = MTDPART_SIZ_FULL, + }, +}; + +/***************************************************************************** + * 512KB NOR Flash on BOOT Device + ****************************************************************************/ +static struct mtd_partition lswvl_partitions[] = { + { + .name = "u-boot", + .size = 0x80000, + .offset = 0x00000, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, +}; + +static struct flash_platform_data lswvl_spi_slave_data = { + .parts = lswvl_partitions, + .nr_parts = ARRAY_SIZE(lswvl_partitions), +}; + +static struct spi_board_info __initdata lswvl_spi_slave_info[] = { + { + .modalias = "m25p80", + .platform_data = &lswvl_spi_slave_data, + .irq = -1, + .max_speed_hz = 20000000, + .bus_num = 0, + .chip_select = 0, + }, +}; + +/***************************************************************************** + * Ethernet + ****************************************************************************/ +static struct mv643xx_eth_platform_data lswvl_ge00_data = { + .phy_addr = MV643XX_ETH_PHY_ADDR(0), +}; + +/***************************************************************************** + * SATA + ****************************************************************************/ +static struct mv_sata_platform_data lswvl_sata_data = { + .n_ports = 2, +}; + +/***************************************************************************** + * LEDs attached to GPIO + ****************************************************************************/ +#define LSWVL_GPIO_LED_HDDERR0 34 +#define LSWVL_GPIO_LED_HDDERR1 35 +#define LSWVL_GPIO_LED_ALARM 36 +#define LSWVL_GPIO_LED_FUNC_RED 37 +#define LSWVL_GPIO_LED_INFO 38 +#define LSWVL_GPIO_LED_FUNC_BLUE 39 +#define LSWVL_GPIO_LED_PWR 40 + +static struct gpio_led lswvl_led_pins[] = { + { + .name = "lswvl:hdderr:0", + .gpio = LSWVL_GPIO_LED_HDDERR0, + }, { + .name = "lswvl:hdderr:1", + .gpio = LSWVL_GPIO_LED_HDDERR1, + }, { + .name = "lswvl:alarm:red", + .gpio = LSWVL_GPIO_LED_ALARM, + }, { + .name = "lswvl:func:red", + .gpio = LSWVL_GPIO_LED_FUNC_RED, + }, { + .name = "lswvl:info:amber", + .gpio = LSWVL_GPIO_LED_INFO, + }, { + .name = "lswvl:func:blue", + .gpio = LSWVL_GPIO_LED_FUNC_BLUE, + }, { + .name = "lswvl:power:blue", + .default_trigger = "default-on", + .gpio = LSWVL_GPIO_LED_PWR, + .active_low = 1, + }, +}; + +static struct gpio_led_platform_data lswvl_led_data = { + .leds = lswvl_led_pins, + .num_leds = ARRAY_SIZE(lswvl_led_pins), +}; + +static struct platform_device lswvl_leds = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &lswvl_led_data, + } +}; + +/***************************************************************************** + * General Setup + ****************************************************************************/ +#define LSWVL_GPIO_HDD0_POWER 8 +#define LSWVL_GPIO_HDD1_POWER 9 +#define LSWVL_GPIO_USB_POWER 12 + +/***************************************************************************** + * GPIO Attached Keys + ****************************************************************************/ +#define LSWVL_GPIO_KEY_FUNC 45 +#define LSWVL_GPIO_KEY_POWER 46 +#define LSWVL_GPIO_KEY_AUTOPOWER 47 +#define LSWVL_SW_POWER 0x00 +#define LSWVL_SW_AUTOPOWER 0x01 +#define LSWVL_SW_FUNC 0x02 + +static struct gpio_keys_button lswvl_buttons[] = { + { + .type = EV_KEY, + .code = BTN_1, + .gpio = LSWVL_GPIO_KEY_POWER, + .desc = "power-on", + .active_low = 1, + }, { + .type = EV_KEY, + .code = BTN_2, + .gpio = LSWVL_GPIO_KEY_AUTOPOWER, + .desc = "power-auto", + .active_low = 1, + }, { + .type = EV_KEY, + .code = BTN_0, + .gpio = LSWVL_GPIO_KEY_FUNC, + .desc = "function", + .active_low = 1, + }, +}; + +static struct gpio_keys_platform_data lswvl_button_data = { + .buttons = lswvl_buttons, + .nbuttons = ARRAY_SIZE(lswvl_buttons), +}; + +static struct platform_device lswvl_button_device = { + .name = "gpio-keys", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &lswvl_button_data, + }, +}; + +/***************************************************************************** + * GPIO Fan + ****************************************************************************/ +#define LSWVL_GPIO_FAN_HIGH 16 +#define LSWVL_GPIO_FAN_LOW 17 +#define LSWVL_GPIO_FAN_LOCK 43 + +static struct gpio_fan_alarm lswvl_alarm = { + .gpio = LSWVL_GPIO_FAN_LOCK, +}; + +static struct gpio_fan_speed lswvl_speeds[] = { + { + .rpm = 0, + .ctrl_val = 3, + }, { + .rpm = 1500, + .ctrl_val = 1, + }, { + .rpm = 3250, + .ctrl_val = 2, + }, { + .rpm = 5000, + .ctrl_val = 0, + } +}; + +static int lswvl_gpio_list[] = { + LSWVL_GPIO_FAN_HIGH, LSWVL_GPIO_FAN_LOW, +}; + +static struct gpio_fan_platform_data lswvl_fan_data = { + .num_ctrl = ARRAY_SIZE(lswvl_gpio_list), + .ctrl = lswvl_gpio_list, + .alarm = &lswvl_alarm, + .num_speed = ARRAY_SIZE(lswvl_speeds), + .speed = lswvl_speeds, +}; + +static struct platform_device lswvl_fan_device = { + .name = "gpio-fan", + .id = -1, + .num_resources = 0, + .dev = { + .platform_data = &lswvl_fan_data, + }, +}; + +/***************************************************************************** + * GPIO Data + ****************************************************************************/ + +static unsigned int lswvl_mpp_config[] __initdata = { + MPP0_NF_IO2, + MPP1_NF_IO3, + MPP2_NF_IO4, + MPP3_NF_IO5, + MPP4_NF_IO6, + MPP5_NF_IO7, + MPP6_SYSRST_OUTn, + MPP7_SPI_SCn, + MPP8_GPIO, /* HDD Power */ + MPP9_GPIO, /* HDD Power */ + MPP10_UART0_TXD, + MPP11_UART0_RXD, + MPP12_GPO, /* USB VBUS EN */ + MPP13_GPIO, + MPP14_GPIO, + MPP15_GPIO, + MPP16_GPIO, /* FAN HIGH: on:0, off:1 */ + MPP17_GPIO, /* FAN LOW: on:0, off:1 */ + MPP18_NF_IO0, + MPP19_NF_IO1, + MPP20_GPIO, + MPP21_GPIO, + MPP22_GPIO, + MPP23_GPIO, + MPP24_GPIO, + MPP25_GPIO, + MPP26_GPIO, + MPP27_GPIO, + MPP28_GPIO, + MPP29_GPIO, + MPP30_GPIO, + MPP31_GPIO, + MPP32_GPIO, + MPP33_GPO, + MPP34_GPIO, /*HDD ERROR LED 0*/ + MPP35_GPIO, /*HDD ERROR LED 1*/ + MPP36_GPIO, /* ALARM LED */ + MPP37_GPIO, /* FUNC RED LED */ + MPP38_GPIO, /* INFO LED */ + MPP39_GPIO, /* FUNC LED */ + MPP40_GPIO, /* POWER LED */ + MPP41_GPIO, + MPP42_GPIO, + MPP43_GPIO, /* FAN LOCK */ + MPP44_GPIO, + MPP45_GPIO, /* FUNC SW */ + MPP46_GPIO, /* POWER SW */ + MPP47_GPIO, /* POWER AUTO SW */ + MPP48_GPIO, /* UART EN */ + MPP49_GPIO, + 0 +}; + +/***************************************************************************** + * LS-WVL specific power off method: reboot + ****************************************************************************/ +/* + * On the LS-WVL, the shutdown process is following: + * - Userland monitors key events until the power switch goes to off position + * - The board reboots + * - U-boot starts and goes into an idle mode waiting for the user + * to move the switch to ON position + * + */ + +static void lswvl_power_off(void) +{ + kirkwood_restart('h', NULL); //arm_machine_restart('h', NULL); +} + +static void __init lswvl_init(void) +{ + /* + * Basic setup. Needs to be called early. + */ + kirkwood_init(); + kirkwood_mpp_conf(lswvl_mpp_config); + + /* + * Configure peripherals. + */ + kirkwood_ge00_init(&lswvl_ge00_data); + kirkwood_uart0_init(); + kirkwood_uart1_init(); + kirkwood_ehci_init(); + kirkwood_sata_init(&lswvl_sata_data); + + spi_register_board_info(lswvl_spi_slave_info, + ARRAY_SIZE(lswvl_spi_slave_info)); + kirkwood_spi_init(); + kirkwood_nand_init(ARRAY_AND_SIZE(lswvl_nand_parts), 25); + + platform_device_register(&lswvl_leds); + platform_device_register(&lswvl_button_device); + platform_device_register(&lswvl_fan_device); + + /* usb power on */ + gpio_set_value(LSWVL_GPIO_USB_POWER, 1); + + /* register power-off method */ + pm_power_off = lswvl_power_off; + + pr_info("%s: finished\n", __func__); +} + +MACHINE_START(LSWVL, "Buffalo LS-WVL Series") + .atag_offset = 0x100, + .map_io = kirkwood_map_io, + .init_early = kirkwood_init_early, + .init_irq = kirkwood_init_irq, + .timer = &kirkwood_timer, + .init_machine = lswvl_init, + .restart = kirkwood_restart, +MACHINE_END + diff -uNr linux-3.2.34-go.orig/arch/arm/mach-kirkwood/Makefile linux-3.2.34-go/arch/arm/mach-kirkwood/Makefile --- linux-3.2.34-go.orig/arch/arm/mach-kirkwood/Makefile 2012-11-19 21:03:42.653743017 +0100 +++ linux-3.2.34-go/arch/arm/mach-kirkwood/Makefile 2012-11-19 21:04:42.686036907 +0100 @@ -21,5 +21,6 @@ obj-$(CONFIG_MACH_LINKSTATION_CHLV2) += lschlv2-setup.o obj-$(CONFIG_MACH_LSXHL) += lsxhl-setup.o obj-$(CONFIG_MACH_LSVL) += lsvl-setup.o +obj-$(CONFIG_MACH_LSWVL) += lswvl-setup.o obj-$(CONFIG_CPU_IDLE) += cpuidle.o diff -uNr linux-3.2.34-go.orig/arch/arm/plat-orion/mpp.c linux-3.2.34-go/arch/arm/plat-orion/mpp.c --- linux-3.2.34-go.orig/arch/arm/plat-orion/mpp.c 2012-11-19 21:03:42.766741717 +0100 +++ linux-3.2.34-go/arch/arm/plat-orion/mpp.c 2012-11-19 21:04:02.747505938 +0100 @@ -15,6 +15,7 @@ #include #include #include +#include /* Address of the ith MPP control register */ static __init unsigned long mpp_ctrl_addr(unsigned int i, @@ -75,3 +76,37 @@ } printk("\n"); } + +#ifdef CONFIG_MACH_LSWVL + +static u32 boot_mpp_value = 0x21111111; +/* + * change MPP[3:1] to SPI mode + */ +void lswvl_setup_spi_mpp(void) +{ + u32 spival = 0; + u32 bootval = 0; + + spival = 0x00002220; + boot_mpp_value = bootval = readl(mpp_ctrl_addr(0, DEV_BUS_VIRT_BASE)); + bootval &= 0xffff000f; + writel(spival | bootval, mpp_ctrl_addr(0, DEV_BUS_VIRT_BASE)); +} + +/* + * change back MPP[3:1] to default configuration + */ +void lswvl_reset_mpp(void) +{ + u32 spival = 0; + u32 bootval = 0; + + spival = readl(mpp_ctrl_addr(0, DEV_BUS_VIRT_BASE)); + spival &= 0xffff000f; + bootval = boot_mpp_value & ~0xffff000f; + writel(spival | bootval, mpp_ctrl_addr(0, DEV_BUS_VIRT_BASE)); +} + +#endif + diff -uNr linux-3.2.34-go.orig/arch/arm/tools/mach-types linux-3.2.34-go/arch/arm/tools/mach-types --- linux-3.2.34-go.orig/arch/arm/tools/mach-types 2012-11-19 21:03:42.675742765 +0100 +++ linux-3.2.34-go/arch/arm/tools/mach-types 2012-11-19 21:22:29.653445807 +0100 @@ -119,6 +119,7 @@ tosa MACH_TOSA TOSA 520 avila MACH_AVILA AVILA 526 lsvl MACH_LSVL LSVL 5277 +lswvl MACH_LSWVL LSWVL 5278 edb9302 MACH_EDB9302 EDB9302 538 husky MACH_HUSKY HUSKY 543 shepherd MACH_SHEPHERD SHEPHERD 545 diff -uNr linux-3.2.34-go.orig/drivers/spi/spi-orion.c linux-3.2.34-go/drivers/spi/spi-orion.c --- linux-3.2.34-go.orig/drivers/spi/spi-orion.c 2012-11-19 21:03:41.809752734 +0100 +++ linux-3.2.34-go/drivers/spi/spi-orion.c 2012-11-19 21:20:55.123558883 +0100 @@ -19,6 +19,12 @@ #include #include #include +#include + +#ifdef CONFIG_MACH_LSWVL +void lswvl_setup_spi_mpp(void); +void lswvl_reset_mpp(void); +#endif #define DRIVER_NAME "orion_spi" @@ -141,6 +147,9 @@ unsigned int bits_per_word = spi->bits_per_word; int rc; +#ifdef CONFIG_MACH_LSWVL + lswvl_setup_spi_mpp(); +#endif orion_spi = spi_master_get_devdata(spi->master); if ((t != NULL) && t->speed_hz) @@ -153,15 +162,37 @@ if (rc) return rc; +#ifdef CONFIG_MACH_LSWVL + rc = orion_spi_set_transfer_size(orion_spi, bits_per_word); + lswvl_reset_mpp(); + return rc; +#else return orion_spi_set_transfer_size(orion_spi, bits_per_word); +#endif } static void orion_spi_set_cs(struct orion_spi *orion_spi, int enable) { if (enable) +#ifdef CONFIG_MACH_LSWVL + { + lswvl_setup_spi_mpp(); + udelay(1); + orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1); + } +#else orion_spi_setbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1); +#endif else orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1); +#ifdef CONFIG_MACH_LSWVL + { + orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1); + lswvl_reset_mpp(); + } +#else + orion_spi_clrbits(orion_spi, ORION_SPI_IF_CTRL_REG, 0x1); +#endif } static inline int orion_spi_wait_till_ready(struct orion_spi *orion_spi) @@ -361,8 +392,17 @@ /* Fix ac timing if required. */ if (orion_spi->spi_info->enable_clock_fix) +#ifdef CONFIG_MACH_LSWVL + { + lswvl_setup_spi_mpp(); + orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG, + (1 << 14)); + lswvl_reset_mpp(); + } +#else orion_spi_setbits(orion_spi, ORION_SPI_IF_CONFIG_REG, (1 << 14)); +#endif if ((spi->max_speed_hz == 0) || (spi->max_speed_hz > orion_spi->max_speed))