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