18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * arch/arm/mach-iop32x/n2100.c 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Board support code for the Thecus N2100 platform. 68c2ecf20Sopenharmony_ci * 78c2ecf20Sopenharmony_ci * Author: Rory Bolt <rorybolt@pacbell.net> 88c2ecf20Sopenharmony_ci * Copyright (C) 2002 Rory Bolt 98c2ecf20Sopenharmony_ci * Copyright 2003 (c) MontaVista, Software, Inc. 108c2ecf20Sopenharmony_ci * Copyright (C) 2004 Intel Corp. 118c2ecf20Sopenharmony_ci */ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/mm.h> 148c2ecf20Sopenharmony_ci#include <linux/init.h> 158c2ecf20Sopenharmony_ci#include <linux/f75375s.h> 168c2ecf20Sopenharmony_ci#include <linux/leds-pca9532.h> 178c2ecf20Sopenharmony_ci#include <linux/delay.h> 188c2ecf20Sopenharmony_ci#include <linux/kernel.h> 198c2ecf20Sopenharmony_ci#include <linux/pci.h> 208c2ecf20Sopenharmony_ci#include <linux/pm.h> 218c2ecf20Sopenharmony_ci#include <linux/string.h> 228c2ecf20Sopenharmony_ci#include <linux/serial_core.h> 238c2ecf20Sopenharmony_ci#include <linux/serial_8250.h> 248c2ecf20Sopenharmony_ci#include <linux/mtd/physmap.h> 258c2ecf20Sopenharmony_ci#include <linux/i2c.h> 268c2ecf20Sopenharmony_ci#include <linux/platform_device.h> 278c2ecf20Sopenharmony_ci#include <linux/reboot.h> 288c2ecf20Sopenharmony_ci#include <linux/io.h> 298c2ecf20Sopenharmony_ci#include <linux/gpio.h> 308c2ecf20Sopenharmony_ci#include <linux/gpio/machine.h> 318c2ecf20Sopenharmony_ci#include <asm/irq.h> 328c2ecf20Sopenharmony_ci#include <asm/mach/arch.h> 338c2ecf20Sopenharmony_ci#include <asm/mach/map.h> 348c2ecf20Sopenharmony_ci#include <asm/mach/pci.h> 358c2ecf20Sopenharmony_ci#include <asm/mach/time.h> 368c2ecf20Sopenharmony_ci#include <asm/mach-types.h> 378c2ecf20Sopenharmony_ci#include <asm/page.h> 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci#include "hardware.h" 408c2ecf20Sopenharmony_ci#include "irqs.h" 418c2ecf20Sopenharmony_ci#include "gpio-iop32x.h" 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci/* 448c2ecf20Sopenharmony_ci * N2100 timer tick configuration. 458c2ecf20Sopenharmony_ci */ 468c2ecf20Sopenharmony_cistatic void __init n2100_timer_init(void) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci /* 33.000 MHz crystal. */ 498c2ecf20Sopenharmony_ci iop_init_time(198000000); 508c2ecf20Sopenharmony_ci} 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci/* 548c2ecf20Sopenharmony_ci * N2100 I/O. 558c2ecf20Sopenharmony_ci */ 568c2ecf20Sopenharmony_cistatic struct map_desc n2100_io_desc[] __initdata = { 578c2ecf20Sopenharmony_ci { /* on-board devices */ 588c2ecf20Sopenharmony_ci .virtual = N2100_UART, 598c2ecf20Sopenharmony_ci .pfn = __phys_to_pfn(N2100_UART), 608c2ecf20Sopenharmony_ci .length = 0x00100000, 618c2ecf20Sopenharmony_ci .type = MT_DEVICE 628c2ecf20Sopenharmony_ci }, 638c2ecf20Sopenharmony_ci}; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_civoid __init n2100_map_io(void) 668c2ecf20Sopenharmony_ci{ 678c2ecf20Sopenharmony_ci iop3xx_map_io(); 688c2ecf20Sopenharmony_ci iotable_init(n2100_io_desc, ARRAY_SIZE(n2100_io_desc)); 698c2ecf20Sopenharmony_ci} 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci/* 738c2ecf20Sopenharmony_ci * N2100 PCI. 748c2ecf20Sopenharmony_ci */ 758c2ecf20Sopenharmony_cistatic int n2100_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin) 768c2ecf20Sopenharmony_ci{ 778c2ecf20Sopenharmony_ci int irq; 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci if (PCI_SLOT(dev->devfn) == 1) { 808c2ecf20Sopenharmony_ci /* RTL8110SB #1 */ 818c2ecf20Sopenharmony_ci irq = IRQ_IOP32X_XINT0; 828c2ecf20Sopenharmony_ci } else if (PCI_SLOT(dev->devfn) == 2) { 838c2ecf20Sopenharmony_ci /* RTL8110SB #2 */ 848c2ecf20Sopenharmony_ci irq = IRQ_IOP32X_XINT3; 858c2ecf20Sopenharmony_ci } else if (PCI_SLOT(dev->devfn) == 3) { 868c2ecf20Sopenharmony_ci /* Sil3512 */ 878c2ecf20Sopenharmony_ci irq = IRQ_IOP32X_XINT2; 888c2ecf20Sopenharmony_ci } else if (PCI_SLOT(dev->devfn) == 4 && pin == 1) { 898c2ecf20Sopenharmony_ci /* VT6212 INTA */ 908c2ecf20Sopenharmony_ci irq = IRQ_IOP32X_XINT1; 918c2ecf20Sopenharmony_ci } else if (PCI_SLOT(dev->devfn) == 4 && pin == 2) { 928c2ecf20Sopenharmony_ci /* VT6212 INTB */ 938c2ecf20Sopenharmony_ci irq = IRQ_IOP32X_XINT0; 948c2ecf20Sopenharmony_ci } else if (PCI_SLOT(dev->devfn) == 4 && pin == 3) { 958c2ecf20Sopenharmony_ci /* VT6212 INTC */ 968c2ecf20Sopenharmony_ci irq = IRQ_IOP32X_XINT2; 978c2ecf20Sopenharmony_ci } else if (PCI_SLOT(dev->devfn) == 5) { 988c2ecf20Sopenharmony_ci /* Mini-PCI slot */ 998c2ecf20Sopenharmony_ci irq = IRQ_IOP32X_XINT3; 1008c2ecf20Sopenharmony_ci } else { 1018c2ecf20Sopenharmony_ci printk(KERN_ERR "n2100_pci_map_irq() called for unknown " 1028c2ecf20Sopenharmony_ci "device PCI:%d:%d:%d\n", dev->bus->number, 1038c2ecf20Sopenharmony_ci PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); 1048c2ecf20Sopenharmony_ci irq = -1; 1058c2ecf20Sopenharmony_ci } 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci return irq; 1088c2ecf20Sopenharmony_ci} 1098c2ecf20Sopenharmony_ci 1108c2ecf20Sopenharmony_cistatic struct hw_pci n2100_pci __initdata = { 1118c2ecf20Sopenharmony_ci .nr_controllers = 1, 1128c2ecf20Sopenharmony_ci .ops = &iop3xx_ops, 1138c2ecf20Sopenharmony_ci .setup = iop3xx_pci_setup, 1148c2ecf20Sopenharmony_ci .preinit = iop3xx_pci_preinit, 1158c2ecf20Sopenharmony_ci .map_irq = n2100_pci_map_irq, 1168c2ecf20Sopenharmony_ci}; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci/* 1198c2ecf20Sopenharmony_ci * Both r8169 chips on the n2100 exhibit PCI parity problems. Set 1208c2ecf20Sopenharmony_ci * the ->broken_parity_status flag for both ports so that the r8169 1218c2ecf20Sopenharmony_ci * driver knows it should ignore error interrupts. 1228c2ecf20Sopenharmony_ci */ 1238c2ecf20Sopenharmony_cistatic void n2100_fixup_r8169(struct pci_dev *dev) 1248c2ecf20Sopenharmony_ci{ 1258c2ecf20Sopenharmony_ci if (dev->bus->number == 0 && 1268c2ecf20Sopenharmony_ci (dev->devfn == PCI_DEVFN(1, 0) || 1278c2ecf20Sopenharmony_ci dev->devfn == PCI_DEVFN(2, 0))) 1288c2ecf20Sopenharmony_ci dev->broken_parity_status = 1; 1298c2ecf20Sopenharmony_ci} 1308c2ecf20Sopenharmony_ciDECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REALTEK, PCI_ANY_ID, n2100_fixup_r8169); 1318c2ecf20Sopenharmony_ci 1328c2ecf20Sopenharmony_cistatic int __init n2100_pci_init(void) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci if (machine_is_n2100()) 1358c2ecf20Sopenharmony_ci pci_common_init(&n2100_pci); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci return 0; 1388c2ecf20Sopenharmony_ci} 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cisubsys_initcall(n2100_pci_init); 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci/* 1448c2ecf20Sopenharmony_ci * N2100 machine initialisation. 1458c2ecf20Sopenharmony_ci */ 1468c2ecf20Sopenharmony_cistatic struct physmap_flash_data n2100_flash_data = { 1478c2ecf20Sopenharmony_ci .width = 2, 1488c2ecf20Sopenharmony_ci}; 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_cistatic struct resource n2100_flash_resource = { 1518c2ecf20Sopenharmony_ci .start = 0xf0000000, 1528c2ecf20Sopenharmony_ci .end = 0xf0ffffff, 1538c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1548c2ecf20Sopenharmony_ci}; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cistatic struct platform_device n2100_flash_device = { 1578c2ecf20Sopenharmony_ci .name = "physmap-flash", 1588c2ecf20Sopenharmony_ci .id = 0, 1598c2ecf20Sopenharmony_ci .dev = { 1608c2ecf20Sopenharmony_ci .platform_data = &n2100_flash_data, 1618c2ecf20Sopenharmony_ci }, 1628c2ecf20Sopenharmony_ci .num_resources = 1, 1638c2ecf20Sopenharmony_ci .resource = &n2100_flash_resource, 1648c2ecf20Sopenharmony_ci}; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci 1678c2ecf20Sopenharmony_cistatic struct plat_serial8250_port n2100_serial_port[] = { 1688c2ecf20Sopenharmony_ci { 1698c2ecf20Sopenharmony_ci .mapbase = N2100_UART, 1708c2ecf20Sopenharmony_ci .membase = (char *)N2100_UART, 1718c2ecf20Sopenharmony_ci .irq = 0, 1728c2ecf20Sopenharmony_ci .flags = UPF_SKIP_TEST | UPF_AUTO_IRQ | UPF_SHARE_IRQ, 1738c2ecf20Sopenharmony_ci .iotype = UPIO_MEM, 1748c2ecf20Sopenharmony_ci .regshift = 0, 1758c2ecf20Sopenharmony_ci .uartclk = 1843200, 1768c2ecf20Sopenharmony_ci }, 1778c2ecf20Sopenharmony_ci { }, 1788c2ecf20Sopenharmony_ci}; 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_cistatic struct resource n2100_uart_resource = { 1818c2ecf20Sopenharmony_ci .start = N2100_UART, 1828c2ecf20Sopenharmony_ci .end = N2100_UART + 7, 1838c2ecf20Sopenharmony_ci .flags = IORESOURCE_MEM, 1848c2ecf20Sopenharmony_ci}; 1858c2ecf20Sopenharmony_ci 1868c2ecf20Sopenharmony_cistatic struct platform_device n2100_serial_device = { 1878c2ecf20Sopenharmony_ci .name = "serial8250", 1888c2ecf20Sopenharmony_ci .id = PLAT8250_DEV_PLATFORM, 1898c2ecf20Sopenharmony_ci .dev = { 1908c2ecf20Sopenharmony_ci .platform_data = n2100_serial_port, 1918c2ecf20Sopenharmony_ci }, 1928c2ecf20Sopenharmony_ci .num_resources = 1, 1938c2ecf20Sopenharmony_ci .resource = &n2100_uart_resource, 1948c2ecf20Sopenharmony_ci}; 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_cistatic struct f75375s_platform_data n2100_f75375s = { 1978c2ecf20Sopenharmony_ci .pwm = { 255, 255 }, 1988c2ecf20Sopenharmony_ci .pwm_enable = { 0, 0 }, 1998c2ecf20Sopenharmony_ci}; 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_cistatic struct pca9532_platform_data n2100_leds = { 2028c2ecf20Sopenharmony_ci .leds = { 2038c2ecf20Sopenharmony_ci { .name = "n2100:red:satafail0", 2048c2ecf20Sopenharmony_ci .state = PCA9532_OFF, 2058c2ecf20Sopenharmony_ci .type = PCA9532_TYPE_LED, 2068c2ecf20Sopenharmony_ci }, 2078c2ecf20Sopenharmony_ci { .name = "n2100:red:satafail1", 2088c2ecf20Sopenharmony_ci .state = PCA9532_OFF, 2098c2ecf20Sopenharmony_ci .type = PCA9532_TYPE_LED, 2108c2ecf20Sopenharmony_ci }, 2118c2ecf20Sopenharmony_ci { .name = "n2100:blue:usb", 2128c2ecf20Sopenharmony_ci .state = PCA9532_OFF, 2138c2ecf20Sopenharmony_ci .type = PCA9532_TYPE_LED, 2148c2ecf20Sopenharmony_ci }, 2158c2ecf20Sopenharmony_ci { .type = PCA9532_TYPE_NONE }, 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci { .type = PCA9532_TYPE_NONE }, 2188c2ecf20Sopenharmony_ci { .type = PCA9532_TYPE_NONE }, 2198c2ecf20Sopenharmony_ci { .type = PCA9532_TYPE_NONE }, 2208c2ecf20Sopenharmony_ci { .name = "n2100:red:usb", 2218c2ecf20Sopenharmony_ci .state = PCA9532_OFF, 2228c2ecf20Sopenharmony_ci .type = PCA9532_TYPE_LED, 2238c2ecf20Sopenharmony_ci }, 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ci { .type = PCA9532_TYPE_NONE }, /* power OFF gpio */ 2268c2ecf20Sopenharmony_ci { .type = PCA9532_TYPE_NONE }, /* reset gpio */ 2278c2ecf20Sopenharmony_ci { .type = PCA9532_TYPE_NONE }, 2288c2ecf20Sopenharmony_ci { .type = PCA9532_TYPE_NONE }, 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci { .type = PCA9532_TYPE_NONE }, 2318c2ecf20Sopenharmony_ci { .name = "n2100:orange:system", 2328c2ecf20Sopenharmony_ci .state = PCA9532_OFF, 2338c2ecf20Sopenharmony_ci .type = PCA9532_TYPE_LED, 2348c2ecf20Sopenharmony_ci }, 2358c2ecf20Sopenharmony_ci { .name = "n2100:red:system", 2368c2ecf20Sopenharmony_ci .state = PCA9532_OFF, 2378c2ecf20Sopenharmony_ci .type = PCA9532_TYPE_LED, 2388c2ecf20Sopenharmony_ci }, 2398c2ecf20Sopenharmony_ci { .name = "N2100 beeper" , 2408c2ecf20Sopenharmony_ci .state = PCA9532_OFF, 2418c2ecf20Sopenharmony_ci .type = PCA9532_TYPE_N2100_BEEP, 2428c2ecf20Sopenharmony_ci }, 2438c2ecf20Sopenharmony_ci }, 2448c2ecf20Sopenharmony_ci .psc = { 0, 0 }, 2458c2ecf20Sopenharmony_ci .pwm = { 0, 0 }, 2468c2ecf20Sopenharmony_ci}; 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_cistatic struct i2c_board_info __initdata n2100_i2c_devices[] = { 2498c2ecf20Sopenharmony_ci { 2508c2ecf20Sopenharmony_ci I2C_BOARD_INFO("rs5c372b", 0x32), 2518c2ecf20Sopenharmony_ci }, 2528c2ecf20Sopenharmony_ci { 2538c2ecf20Sopenharmony_ci I2C_BOARD_INFO("f75375", 0x2e), 2548c2ecf20Sopenharmony_ci .platform_data = &n2100_f75375s, 2558c2ecf20Sopenharmony_ci }, 2568c2ecf20Sopenharmony_ci { 2578c2ecf20Sopenharmony_ci I2C_BOARD_INFO("pca9532", 0x60), 2588c2ecf20Sopenharmony_ci .platform_data = &n2100_leds, 2598c2ecf20Sopenharmony_ci }, 2608c2ecf20Sopenharmony_ci}; 2618c2ecf20Sopenharmony_ci 2628c2ecf20Sopenharmony_ci/* 2638c2ecf20Sopenharmony_ci * Pull PCA9532 GPIO #8 low to power off the machine. 2648c2ecf20Sopenharmony_ci */ 2658c2ecf20Sopenharmony_cistatic void n2100_power_off(void) 2668c2ecf20Sopenharmony_ci{ 2678c2ecf20Sopenharmony_ci local_irq_disable(); 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci /* Start condition, I2C address of PCA9532, write transaction. */ 2708c2ecf20Sopenharmony_ci *IOP3XX_IDBR0 = 0xc0; 2718c2ecf20Sopenharmony_ci *IOP3XX_ICR0 = 0xe9; 2728c2ecf20Sopenharmony_ci mdelay(1); 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci /* Write address 0x08. */ 2758c2ecf20Sopenharmony_ci *IOP3XX_IDBR0 = 0x08; 2768c2ecf20Sopenharmony_ci *IOP3XX_ICR0 = 0xe8; 2778c2ecf20Sopenharmony_ci mdelay(1); 2788c2ecf20Sopenharmony_ci 2798c2ecf20Sopenharmony_ci /* Write data 0x01, stop condition. */ 2808c2ecf20Sopenharmony_ci *IOP3XX_IDBR0 = 0x01; 2818c2ecf20Sopenharmony_ci *IOP3XX_ICR0 = 0xea; 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci while (1) 2848c2ecf20Sopenharmony_ci ; 2858c2ecf20Sopenharmony_ci} 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_cistatic void n2100_restart(enum reboot_mode mode, const char *cmd) 2888c2ecf20Sopenharmony_ci{ 2898c2ecf20Sopenharmony_ci int ret; 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci ret = gpio_direction_output(N2100_HARDWARE_RESET, 0); 2928c2ecf20Sopenharmony_ci if (ret) { 2938c2ecf20Sopenharmony_ci pr_crit("could not drive reset GPIO low\n"); 2948c2ecf20Sopenharmony_ci return; 2958c2ecf20Sopenharmony_ci } 2968c2ecf20Sopenharmony_ci /* Wait for reset to happen */ 2978c2ecf20Sopenharmony_ci while (1) 2988c2ecf20Sopenharmony_ci ; 2998c2ecf20Sopenharmony_ci} 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_cistatic struct timer_list power_button_poll_timer; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_cistatic void power_button_poll(struct timer_list *unused) 3058c2ecf20Sopenharmony_ci{ 3068c2ecf20Sopenharmony_ci if (gpio_get_value(N2100_POWER_BUTTON) == 0) { 3078c2ecf20Sopenharmony_ci ctrl_alt_del(); 3088c2ecf20Sopenharmony_ci return; 3098c2ecf20Sopenharmony_ci } 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_ci power_button_poll_timer.expires = jiffies + (HZ / 10); 3128c2ecf20Sopenharmony_ci add_timer(&power_button_poll_timer); 3138c2ecf20Sopenharmony_ci} 3148c2ecf20Sopenharmony_ci 3158c2ecf20Sopenharmony_cistatic int __init n2100_request_gpios(void) 3168c2ecf20Sopenharmony_ci{ 3178c2ecf20Sopenharmony_ci int ret; 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_ci if (!machine_is_n2100()) 3208c2ecf20Sopenharmony_ci return 0; 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci ret = gpio_request(N2100_HARDWARE_RESET, "reset"); 3238c2ecf20Sopenharmony_ci if (ret) 3248c2ecf20Sopenharmony_ci pr_err("could not request reset GPIO\n"); 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_ci ret = gpio_request(N2100_POWER_BUTTON, "power"); 3278c2ecf20Sopenharmony_ci if (ret) 3288c2ecf20Sopenharmony_ci pr_err("could not request power GPIO\n"); 3298c2ecf20Sopenharmony_ci else { 3308c2ecf20Sopenharmony_ci ret = gpio_direction_input(N2100_POWER_BUTTON); 3318c2ecf20Sopenharmony_ci if (ret) 3328c2ecf20Sopenharmony_ci pr_err("could not set power GPIO as input\n"); 3338c2ecf20Sopenharmony_ci } 3348c2ecf20Sopenharmony_ci /* Set up power button poll timer */ 3358c2ecf20Sopenharmony_ci timer_setup(&power_button_poll_timer, power_button_poll, 0); 3368c2ecf20Sopenharmony_ci power_button_poll_timer.expires = jiffies + (HZ / 10); 3378c2ecf20Sopenharmony_ci add_timer(&power_button_poll_timer); 3388c2ecf20Sopenharmony_ci return 0; 3398c2ecf20Sopenharmony_ci} 3408c2ecf20Sopenharmony_cidevice_initcall(n2100_request_gpios); 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_cistatic void __init n2100_init_machine(void) 3438c2ecf20Sopenharmony_ci{ 3448c2ecf20Sopenharmony_ci register_iop32x_gpio(); 3458c2ecf20Sopenharmony_ci gpiod_add_lookup_table(&iop3xx_i2c0_gpio_lookup); 3468c2ecf20Sopenharmony_ci platform_device_register(&iop3xx_i2c0_device); 3478c2ecf20Sopenharmony_ci platform_device_register(&n2100_flash_device); 3488c2ecf20Sopenharmony_ci platform_device_register(&n2100_serial_device); 3498c2ecf20Sopenharmony_ci platform_device_register(&iop3xx_dma_0_channel); 3508c2ecf20Sopenharmony_ci platform_device_register(&iop3xx_dma_1_channel); 3518c2ecf20Sopenharmony_ci 3528c2ecf20Sopenharmony_ci i2c_register_board_info(0, n2100_i2c_devices, 3538c2ecf20Sopenharmony_ci ARRAY_SIZE(n2100_i2c_devices)); 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci pm_power_off = n2100_power_off; 3568c2ecf20Sopenharmony_ci} 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ciMACHINE_START(N2100, "Thecus N2100") 3598c2ecf20Sopenharmony_ci /* Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> */ 3608c2ecf20Sopenharmony_ci .atag_offset = 0x100, 3618c2ecf20Sopenharmony_ci .map_io = n2100_map_io, 3628c2ecf20Sopenharmony_ci .init_irq = iop32x_init_irq, 3638c2ecf20Sopenharmony_ci .init_time = n2100_timer_init, 3648c2ecf20Sopenharmony_ci .init_machine = n2100_init_machine, 3658c2ecf20Sopenharmony_ci .restart = n2100_restart, 3668c2ecf20Sopenharmony_ciMACHINE_END 367