147e9cffdSSylver Bruneau /* 247e9cffdSSylver Bruneau * QNAP TS-409 Board Setup 347e9cffdSSylver Bruneau * 447e9cffdSSylver Bruneau * Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> 547e9cffdSSylver Bruneau * 647e9cffdSSylver Bruneau * This program is free software; you can redistribute it and/or 747e9cffdSSylver Bruneau * modify it under the terms of the GNU General Public License 847e9cffdSSylver Bruneau * as published by the Free Software Foundation; either version 947e9cffdSSylver Bruneau * 2 of the License, or (at your option) any later version. 1047e9cffdSSylver Bruneau */ 1147e9cffdSSylver Bruneau 1247e9cffdSSylver Bruneau #include <linux/kernel.h> 1347e9cffdSSylver Bruneau #include <linux/init.h> 1447e9cffdSSylver Bruneau #include <linux/platform_device.h> 1547e9cffdSSylver Bruneau #include <linux/pci.h> 1647e9cffdSSylver Bruneau #include <linux/irq.h> 1747e9cffdSSylver Bruneau #include <linux/mtd/physmap.h> 1847e9cffdSSylver Bruneau #include <linux/mv643xx_eth.h> 1947e9cffdSSylver Bruneau #include <linux/gpio_keys.h> 2047e9cffdSSylver Bruneau #include <linux/input.h> 2147e9cffdSSylver Bruneau #include <linux/i2c.h> 2247e9cffdSSylver Bruneau #include <linux/serial_reg.h> 2347e9cffdSSylver Bruneau #include <asm/mach-types.h> 2447e9cffdSSylver Bruneau #include <asm/gpio.h> 2547e9cffdSSylver Bruneau #include <asm/mach/arch.h> 2647e9cffdSSylver Bruneau #include <asm/mach/pci.h> 2747e9cffdSSylver Bruneau #include <asm/arch/orion5x.h> 2847e9cffdSSylver Bruneau #include "common.h" 2947e9cffdSSylver Bruneau #include "mpp.h" 3047e9cffdSSylver Bruneau 3147e9cffdSSylver Bruneau /***************************************************************************** 3247e9cffdSSylver Bruneau * QNAP TS-409 Info 3347e9cffdSSylver Bruneau ****************************************************************************/ 3447e9cffdSSylver Bruneau 3547e9cffdSSylver Bruneau /* 3647e9cffdSSylver Bruneau * QNAP TS-409 hardware : 3747e9cffdSSylver Bruneau * - Marvell 88F5281-D0 3847e9cffdSSylver Bruneau * - Marvell 88SX7042 SATA controller (PCIe) 3947e9cffdSSylver Bruneau * - Marvell 88E1118 Gigabit Ethernet PHY 4047e9cffdSSylver Bruneau * - RTC S35390A (@0x30) on I2C bus 4147e9cffdSSylver Bruneau * - 8MB NOR flash 4247e9cffdSSylver Bruneau * - 256MB of DDR-2 RAM 4347e9cffdSSylver Bruneau */ 4447e9cffdSSylver Bruneau 4547e9cffdSSylver Bruneau /* 4647e9cffdSSylver Bruneau * 8MB NOR flash Device bus boot chip select 4747e9cffdSSylver Bruneau */ 4847e9cffdSSylver Bruneau 4947e9cffdSSylver Bruneau #define QNAP_TS409_NOR_BOOT_BASE 0xff800000 5047e9cffdSSylver Bruneau #define QNAP_TS409_NOR_BOOT_SIZE SZ_8M 5147e9cffdSSylver Bruneau 5247e9cffdSSylver Bruneau /**************************************************************************** 5347e9cffdSSylver Bruneau * 8MiB NOR flash. The struct mtd_partition is not in the same order as the 5447e9cffdSSylver Bruneau * partitions on the device because we want to keep compatability with 5547e9cffdSSylver Bruneau * existing QNAP firmware. 5647e9cffdSSylver Bruneau * 5747e9cffdSSylver Bruneau * Layout as used by QNAP: 5847e9cffdSSylver Bruneau * [2] 0x00000000-0x00200000 : "Kernel" 5947e9cffdSSylver Bruneau * [3] 0x00200000-0x00600000 : "RootFS1" 6047e9cffdSSylver Bruneau * [4] 0x00600000-0x00700000 : "RootFS2" 6147e9cffdSSylver Bruneau * [6] 0x00700000-0x00760000 : "NAS Config" (read-only) 6247e9cffdSSylver Bruneau * [5] 0x00760000-0x00780000 : "U-Boot Config" 6347e9cffdSSylver Bruneau * [1] 0x00780000-0x00800000 : "U-Boot" (read-only) 6447e9cffdSSylver Bruneau ***************************************************************************/ 6547e9cffdSSylver Bruneau static struct mtd_partition qnap_ts409_partitions[] = { 6647e9cffdSSylver Bruneau { 6747e9cffdSSylver Bruneau .name = "U-Boot", 6847e9cffdSSylver Bruneau .size = 0x00080000, 6947e9cffdSSylver Bruneau .offset = 0x00780000, 7047e9cffdSSylver Bruneau .mask_flags = MTD_WRITEABLE, 7147e9cffdSSylver Bruneau }, { 7247e9cffdSSylver Bruneau .name = "Kernel", 7347e9cffdSSylver Bruneau .size = 0x00200000, 7447e9cffdSSylver Bruneau .offset = 0, 7547e9cffdSSylver Bruneau }, { 7647e9cffdSSylver Bruneau .name = "RootFS1", 7747e9cffdSSylver Bruneau .size = 0x00400000, 7847e9cffdSSylver Bruneau .offset = 0x00200000, 7947e9cffdSSylver Bruneau }, { 8047e9cffdSSylver Bruneau .name = "RootFS2", 8147e9cffdSSylver Bruneau .size = 0x00100000, 8247e9cffdSSylver Bruneau .offset = 0x00600000, 8347e9cffdSSylver Bruneau }, { 8447e9cffdSSylver Bruneau .name = "U-Boot Config", 8547e9cffdSSylver Bruneau .size = 0x00020000, 8647e9cffdSSylver Bruneau .offset = 0x00760000, 8747e9cffdSSylver Bruneau }, { 8847e9cffdSSylver Bruneau .name = "NAS Config", 8947e9cffdSSylver Bruneau .size = 0x00060000, 9047e9cffdSSylver Bruneau .offset = 0x00700000, 9147e9cffdSSylver Bruneau .mask_flags = MTD_WRITEABLE, 9247e9cffdSSylver Bruneau }, 9347e9cffdSSylver Bruneau }; 9447e9cffdSSylver Bruneau 9547e9cffdSSylver Bruneau static struct physmap_flash_data qnap_ts409_nor_flash_data = { 9647e9cffdSSylver Bruneau .width = 1, 9747e9cffdSSylver Bruneau .parts = qnap_ts409_partitions, 9847e9cffdSSylver Bruneau .nr_parts = ARRAY_SIZE(qnap_ts409_partitions) 9947e9cffdSSylver Bruneau }; 10047e9cffdSSylver Bruneau 10147e9cffdSSylver Bruneau static struct resource qnap_ts409_nor_flash_resource = { 10247e9cffdSSylver Bruneau .flags = IORESOURCE_MEM, 10347e9cffdSSylver Bruneau .start = QNAP_TS409_NOR_BOOT_BASE, 10447e9cffdSSylver Bruneau .end = QNAP_TS409_NOR_BOOT_BASE + QNAP_TS409_NOR_BOOT_SIZE - 1, 10547e9cffdSSylver Bruneau }; 10647e9cffdSSylver Bruneau 10747e9cffdSSylver Bruneau static struct platform_device qnap_ts409_nor_flash = { 10847e9cffdSSylver Bruneau .name = "physmap-flash", 10947e9cffdSSylver Bruneau .id = 0, 11047e9cffdSSylver Bruneau .dev = { .platform_data = &qnap_ts409_nor_flash_data, }, 11147e9cffdSSylver Bruneau .num_resources = 1, 11247e9cffdSSylver Bruneau .resource = &qnap_ts409_nor_flash_resource, 11347e9cffdSSylver Bruneau }; 11447e9cffdSSylver Bruneau 11547e9cffdSSylver Bruneau /***************************************************************************** 11647e9cffdSSylver Bruneau * PCI 11747e9cffdSSylver Bruneau ****************************************************************************/ 11847e9cffdSSylver Bruneau 11947e9cffdSSylver Bruneau static int __init qnap_ts409_pci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) 12047e9cffdSSylver Bruneau { 12147e9cffdSSylver Bruneau int irq; 12247e9cffdSSylver Bruneau 12347e9cffdSSylver Bruneau /* 12447e9cffdSSylver Bruneau * Check for devices with hard-wired IRQs. 12547e9cffdSSylver Bruneau */ 12647e9cffdSSylver Bruneau irq = orion5x_pci_map_irq(dev, slot, pin); 12747e9cffdSSylver Bruneau if (irq != -1) 12847e9cffdSSylver Bruneau return irq; 12947e9cffdSSylver Bruneau 13047e9cffdSSylver Bruneau /* 13147e9cffdSSylver Bruneau * PCI isn't used on the TS-409 13247e9cffdSSylver Bruneau */ 13347e9cffdSSylver Bruneau return -1; 13447e9cffdSSylver Bruneau } 13547e9cffdSSylver Bruneau 13647e9cffdSSylver Bruneau static struct hw_pci qnap_ts409_pci __initdata = { 13747e9cffdSSylver Bruneau .nr_controllers = 2, 13847e9cffdSSylver Bruneau .swizzle = pci_std_swizzle, 13947e9cffdSSylver Bruneau .setup = orion5x_pci_sys_setup, 14047e9cffdSSylver Bruneau .scan = orion5x_pci_sys_scan_bus, 14147e9cffdSSylver Bruneau .map_irq = qnap_ts409_pci_map_irq, 14247e9cffdSSylver Bruneau }; 14347e9cffdSSylver Bruneau 14447e9cffdSSylver Bruneau static int __init qnap_ts409_pci_init(void) 14547e9cffdSSylver Bruneau { 14647e9cffdSSylver Bruneau if (machine_is_ts409()) 14747e9cffdSSylver Bruneau pci_common_init(&qnap_ts409_pci); 14847e9cffdSSylver Bruneau 14947e9cffdSSylver Bruneau return 0; 15047e9cffdSSylver Bruneau } 15147e9cffdSSylver Bruneau 15247e9cffdSSylver Bruneau subsys_initcall(qnap_ts409_pci_init); 15347e9cffdSSylver Bruneau 15447e9cffdSSylver Bruneau /***************************************************************************** 15547e9cffdSSylver Bruneau * Ethernet 15647e9cffdSSylver Bruneau ****************************************************************************/ 15747e9cffdSSylver Bruneau 15847e9cffdSSylver Bruneau static struct mv643xx_eth_platform_data qnap_ts409_eth_data = { 15947e9cffdSSylver Bruneau .phy_addr = 8, 16047e9cffdSSylver Bruneau }; 16147e9cffdSSylver Bruneau 16247e9cffdSSylver Bruneau static int __init parse_hex_nibble(char n) 16347e9cffdSSylver Bruneau { 16447e9cffdSSylver Bruneau if (n >= '0' && n <= '9') 16547e9cffdSSylver Bruneau return n - '0'; 16647e9cffdSSylver Bruneau 16747e9cffdSSylver Bruneau if (n >= 'A' && n <= 'F') 16847e9cffdSSylver Bruneau return n - 'A' + 10; 16947e9cffdSSylver Bruneau 17047e9cffdSSylver Bruneau if (n >= 'a' && n <= 'f') 17147e9cffdSSylver Bruneau return n - 'a' + 10; 17247e9cffdSSylver Bruneau 17347e9cffdSSylver Bruneau return -1; 17447e9cffdSSylver Bruneau } 17547e9cffdSSylver Bruneau 17647e9cffdSSylver Bruneau static int __init parse_hex_byte(const char *b) 17747e9cffdSSylver Bruneau { 17847e9cffdSSylver Bruneau int hi; 17947e9cffdSSylver Bruneau int lo; 18047e9cffdSSylver Bruneau 18147e9cffdSSylver Bruneau hi = parse_hex_nibble(b[0]); 18247e9cffdSSylver Bruneau lo = parse_hex_nibble(b[1]); 18347e9cffdSSylver Bruneau 18447e9cffdSSylver Bruneau if (hi < 0 || lo < 0) 18547e9cffdSSylver Bruneau return -1; 18647e9cffdSSylver Bruneau 18747e9cffdSSylver Bruneau return (hi << 4) | lo; 18847e9cffdSSylver Bruneau } 18947e9cffdSSylver Bruneau 19047e9cffdSSylver Bruneau static int __init check_mac_addr(const char *addr_str) 19147e9cffdSSylver Bruneau { 19247e9cffdSSylver Bruneau u_int8_t addr[6]; 19347e9cffdSSylver Bruneau int i; 19447e9cffdSSylver Bruneau 19547e9cffdSSylver Bruneau for (i = 0; i < 6; i++) { 19647e9cffdSSylver Bruneau int byte; 19747e9cffdSSylver Bruneau 19847e9cffdSSylver Bruneau /* 19947e9cffdSSylver Bruneau * Enforce "xx:xx:xx:xx:xx:xx\n" format. 20047e9cffdSSylver Bruneau */ 20147e9cffdSSylver Bruneau if (addr_str[(i * 3) + 2] != ((i < 5) ? ':' : '\n')) 20247e9cffdSSylver Bruneau return -1; 20347e9cffdSSylver Bruneau 20447e9cffdSSylver Bruneau byte = parse_hex_byte(addr_str + (i * 3)); 20547e9cffdSSylver Bruneau if (byte < 0) 20647e9cffdSSylver Bruneau return -1; 20747e9cffdSSylver Bruneau addr[i] = byte; 20847e9cffdSSylver Bruneau } 20947e9cffdSSylver Bruneau 21047e9cffdSSylver Bruneau printk(KERN_INFO "ts409: found ethernet mac address "); 21147e9cffdSSylver Bruneau for (i = 0; i < 6; i++) 21247e9cffdSSylver Bruneau printk("%.2x%s", addr[i], (i < 5) ? ":" : ".\n"); 21347e9cffdSSylver Bruneau 21447e9cffdSSylver Bruneau memcpy(qnap_ts409_eth_data.mac_addr, addr, 6); 21547e9cffdSSylver Bruneau 21647e9cffdSSylver Bruneau return 0; 21747e9cffdSSylver Bruneau } 21847e9cffdSSylver Bruneau 21947e9cffdSSylver Bruneau /* 22047e9cffdSSylver Bruneau * The 'NAS Config' flash partition has an ext2 filesystem which 22147e9cffdSSylver Bruneau * contains a file that has the ethernet MAC address in plain text 22247e9cffdSSylver Bruneau * (format "xx:xx:xx:xx:xx:xx\n"). 22347e9cffdSSylver Bruneau */ 22447e9cffdSSylver Bruneau static void __init ts409_find_mac_addr(void) 22547e9cffdSSylver Bruneau { 22647e9cffdSSylver Bruneau unsigned long addr; 22747e9cffdSSylver Bruneau 22847e9cffdSSylver Bruneau for (addr = 0x00700000; addr < 0x00760000; addr += 1024) { 22947e9cffdSSylver Bruneau char *nor_page; 23047e9cffdSSylver Bruneau int ret = 0; 23147e9cffdSSylver Bruneau 23247e9cffdSSylver Bruneau nor_page = ioremap(QNAP_TS409_NOR_BOOT_BASE + addr, 1024); 23347e9cffdSSylver Bruneau if (nor_page != NULL) { 23447e9cffdSSylver Bruneau ret = check_mac_addr(nor_page); 23547e9cffdSSylver Bruneau iounmap(nor_page); 23647e9cffdSSylver Bruneau } 23747e9cffdSSylver Bruneau 23847e9cffdSSylver Bruneau if (ret == 0) 23947e9cffdSSylver Bruneau break; 24047e9cffdSSylver Bruneau } 24147e9cffdSSylver Bruneau } 24247e9cffdSSylver Bruneau 24347e9cffdSSylver Bruneau /***************************************************************************** 24447e9cffdSSylver Bruneau * RTC S35390A on I2C bus 24547e9cffdSSylver Bruneau ****************************************************************************/ 24647e9cffdSSylver Bruneau 24747e9cffdSSylver Bruneau #define TS409_RTC_GPIO 10 24847e9cffdSSylver Bruneau 24947e9cffdSSylver Bruneau static struct i2c_board_info __initdata qnap_ts409_i2c_rtc = { 25047e9cffdSSylver Bruneau I2C_BOARD_INFO("s35390a", 0x30), 25147e9cffdSSylver Bruneau }; 25247e9cffdSSylver Bruneau 25347e9cffdSSylver Bruneau /**************************************************************************** 25447e9cffdSSylver Bruneau * GPIO Attached Keys 25547e9cffdSSylver Bruneau * Power button is attached to the PIC microcontroller 25647e9cffdSSylver Bruneau ****************************************************************************/ 25747e9cffdSSylver Bruneau 25847e9cffdSSylver Bruneau #define QNAP_TS409_GPIO_KEY_MEDIA 15 25947e9cffdSSylver Bruneau 26047e9cffdSSylver Bruneau static struct gpio_keys_button qnap_ts409_buttons[] = { 26147e9cffdSSylver Bruneau { 26247e9cffdSSylver Bruneau .code = KEY_RESTART, 26347e9cffdSSylver Bruneau .gpio = QNAP_TS409_GPIO_KEY_MEDIA, 26447e9cffdSSylver Bruneau .desc = "USB Copy Button", 26547e9cffdSSylver Bruneau .active_low = 1, 26647e9cffdSSylver Bruneau }, 26747e9cffdSSylver Bruneau }; 26847e9cffdSSylver Bruneau 26947e9cffdSSylver Bruneau static struct gpio_keys_platform_data qnap_ts409_button_data = { 27047e9cffdSSylver Bruneau .buttons = qnap_ts409_buttons, 27147e9cffdSSylver Bruneau .nbuttons = ARRAY_SIZE(qnap_ts409_buttons), 27247e9cffdSSylver Bruneau }; 27347e9cffdSSylver Bruneau 27447e9cffdSSylver Bruneau static struct platform_device qnap_ts409_button_device = { 27547e9cffdSSylver Bruneau .name = "gpio-keys", 27647e9cffdSSylver Bruneau .id = -1, 27747e9cffdSSylver Bruneau .num_resources = 0, 27847e9cffdSSylver Bruneau .dev = { 27947e9cffdSSylver Bruneau .platform_data = &qnap_ts409_button_data, 28047e9cffdSSylver Bruneau }, 28147e9cffdSSylver Bruneau }; 28247e9cffdSSylver Bruneau 28347e9cffdSSylver Bruneau /***************************************************************************** 28447e9cffdSSylver Bruneau * General Setup 28547e9cffdSSylver Bruneau ****************************************************************************/ 28647e9cffdSSylver Bruneau static struct orion5x_mpp_mode ts409_mpp_modes[] __initdata = { 28747e9cffdSSylver Bruneau { 0, MPP_UNUSED }, 28847e9cffdSSylver Bruneau { 1, MPP_UNUSED }, 28947e9cffdSSylver Bruneau { 2, MPP_UNUSED }, 29047e9cffdSSylver Bruneau { 3, MPP_UNUSED }, 29147e9cffdSSylver Bruneau { 4, MPP_GPIO }, /* HDD 1 status */ 29247e9cffdSSylver Bruneau { 5, MPP_GPIO }, /* HDD 2 status */ 29347e9cffdSSylver Bruneau { 6, MPP_GPIO }, /* HDD 3 status */ 29447e9cffdSSylver Bruneau { 7, MPP_GPIO }, /* HDD 4 status */ 29547e9cffdSSylver Bruneau { 8, MPP_UNUSED }, 29647e9cffdSSylver Bruneau { 9, MPP_UNUSED }, 29747e9cffdSSylver Bruneau { 10, MPP_GPIO }, /* RTC int */ 29847e9cffdSSylver Bruneau { 11, MPP_UNUSED }, 29947e9cffdSSylver Bruneau { 12, MPP_UNUSED }, 30047e9cffdSSylver Bruneau { 13, MPP_UNUSED }, 30147e9cffdSSylver Bruneau { 14, MPP_GPIO }, /* SW_RST */ 30247e9cffdSSylver Bruneau { 15, MPP_GPIO }, /* USB copy button */ 30347e9cffdSSylver Bruneau { 16, MPP_UART }, /* UART1 RXD */ 30447e9cffdSSylver Bruneau { 17, MPP_UART }, /* UART1 TXD */ 30547e9cffdSSylver Bruneau { 18, MPP_UNUSED }, 30647e9cffdSSylver Bruneau { 19, MPP_UNUSED }, 30747e9cffdSSylver Bruneau { -1 }, 30847e9cffdSSylver Bruneau }; 30947e9cffdSSylver Bruneau 31047e9cffdSSylver Bruneau /* 31147e9cffdSSylver Bruneau * QNAP TS-409 specific power off method via UART1-attached PIC 31247e9cffdSSylver Bruneau */ 31347e9cffdSSylver Bruneau 31447e9cffdSSylver Bruneau #define UART1_REG(x) (UART1_VIRT_BASE + ((UART_##x) << 2)) 31547e9cffdSSylver Bruneau 31647e9cffdSSylver Bruneau static void qnap_ts409_power_off(void) 31747e9cffdSSylver Bruneau { 31847e9cffdSSylver Bruneau /* 19200 baud divisor */ 31947e9cffdSSylver Bruneau const unsigned divisor = ((ORION5X_TCLK + (8 * 19200)) / (16 * 19200)); 32047e9cffdSSylver Bruneau 32147e9cffdSSylver Bruneau pr_info("%s: triggering power-off...\n", __func__); 32247e9cffdSSylver Bruneau 32347e9cffdSSylver Bruneau /* hijack uart1 and reset into sane state (19200,8n1) */ 32447e9cffdSSylver Bruneau writel(0x83, UART1_REG(LCR)); 32547e9cffdSSylver Bruneau writel(divisor & 0xff, UART1_REG(DLL)); 32647e9cffdSSylver Bruneau writel((divisor >> 8) & 0xff, UART1_REG(DLM)); 32747e9cffdSSylver Bruneau writel(0x03, UART1_REG(LCR)); 32847e9cffdSSylver Bruneau writel(0x00, UART1_REG(IER)); 32947e9cffdSSylver Bruneau writel(0x00, UART1_REG(FCR)); 33047e9cffdSSylver Bruneau writel(0x00, UART1_REG(MCR)); 33147e9cffdSSylver Bruneau 33247e9cffdSSylver Bruneau /* send the power-off command 'A' to PIC */ 33347e9cffdSSylver Bruneau writel('A', UART1_REG(TX)); 33447e9cffdSSylver Bruneau } 33547e9cffdSSylver Bruneau 33647e9cffdSSylver Bruneau static void __init qnap_ts409_init(void) 33747e9cffdSSylver Bruneau { 33847e9cffdSSylver Bruneau /* 33947e9cffdSSylver Bruneau * Setup basic Orion functions. Need to be called early. 34047e9cffdSSylver Bruneau */ 34147e9cffdSSylver Bruneau orion5x_init(); 34247e9cffdSSylver Bruneau 34347e9cffdSSylver Bruneau orion5x_mpp_conf(ts409_mpp_modes); 34447e9cffdSSylver Bruneau 34547e9cffdSSylver Bruneau /* 34647e9cffdSSylver Bruneau * Configure peripherals. 34747e9cffdSSylver Bruneau */ 34847e9cffdSSylver Bruneau orion5x_ehci0_init(); 34947e9cffdSSylver Bruneau ts409_find_mac_addr(); 35047e9cffdSSylver Bruneau orion5x_eth_init(&qnap_ts409_eth_data); 35147e9cffdSSylver Bruneau orion5x_i2c_init(); 35247e9cffdSSylver Bruneau orion5x_uart0_init(); 35347e9cffdSSylver Bruneau 35447e9cffdSSylver Bruneau orion5x_setup_dev_boot_win(QNAP_TS409_NOR_BOOT_BASE, 35547e9cffdSSylver Bruneau QNAP_TS409_NOR_BOOT_SIZE); 35647e9cffdSSylver Bruneau platform_device_register(&qnap_ts409_nor_flash); 35747e9cffdSSylver Bruneau 35847e9cffdSSylver Bruneau platform_device_register(&qnap_ts409_button_device); 35947e9cffdSSylver Bruneau 36047e9cffdSSylver Bruneau /* Get RTC IRQ and register the chip */ 36147e9cffdSSylver Bruneau if (gpio_request(TS409_RTC_GPIO, "rtc") == 0) { 36247e9cffdSSylver Bruneau if (gpio_direction_input(TS409_RTC_GPIO) == 0) 36347e9cffdSSylver Bruneau qnap_ts409_i2c_rtc.irq = gpio_to_irq(TS409_RTC_GPIO); 36447e9cffdSSylver Bruneau else 36547e9cffdSSylver Bruneau gpio_free(TS409_RTC_GPIO); 36647e9cffdSSylver Bruneau } 36747e9cffdSSylver Bruneau if (qnap_ts409_i2c_rtc.irq == 0) 36847e9cffdSSylver Bruneau pr_warning("qnap_ts409_init: failed to get RTC IRQ\n"); 36947e9cffdSSylver Bruneau i2c_register_board_info(0, &qnap_ts409_i2c_rtc, 1); 37047e9cffdSSylver Bruneau 37147e9cffdSSylver Bruneau /* register ts409 specific power-off method */ 37247e9cffdSSylver Bruneau pm_power_off = qnap_ts409_power_off; 37347e9cffdSSylver Bruneau } 37447e9cffdSSylver Bruneau 37547e9cffdSSylver Bruneau MACHINE_START(TS409, "QNAP TS-409") 37647e9cffdSSylver Bruneau /* Maintainer: Sylver Bruneau <sylver.bruneau@gmail.com> */ 37747e9cffdSSylver Bruneau .phys_io = ORION5X_REGS_PHYS_BASE, 37847e9cffdSSylver Bruneau .io_pg_offst = ((ORION5X_REGS_VIRT_BASE) >> 18) & 0xFFFC, 37947e9cffdSSylver Bruneau .boot_params = 0x00000100, 38047e9cffdSSylver Bruneau .init_machine = qnap_ts409_init, 38147e9cffdSSylver Bruneau .map_io = orion5x_map_io, 38247e9cffdSSylver Bruneau .init_irq = orion5x_init_irq, 38347e9cffdSSylver Bruneau .timer = &orion5x_timer, 38447e9cffdSSylver Bruneau .fixup = tag_fixup_mem32, 38547e9cffdSSylver Bruneau MACHINE_END 386