1 // SPDX-License-Identifier: GPL-2.0-or-later 2 /* 3 * arch/xtensa/platforms/xt2000/setup.c 4 * 5 * Platform specific functions for the XT2000 board. 6 * 7 * Authors: Chris Zankel <chris@zankel.net> 8 * Joe Taylor <joe@tensilica.com> 9 * 10 * Copyright 2001 - 2004 Tensilica Inc. 11 */ 12 #include <linux/stddef.h> 13 #include <linux/kernel.h> 14 #include <linux/init.h> 15 #include <linux/errno.h> 16 #include <linux/reboot.h> 17 #include <linux/kdev_t.h> 18 #include <linux/types.h> 19 #include <linux/major.h> 20 #include <linux/console.h> 21 #include <linux/delay.h> 22 #include <linux/stringify.h> 23 #include <linux/platform_device.h> 24 #include <linux/serial.h> 25 #include <linux/serial_8250.h> 26 #include <linux/timer.h> 27 28 #include <asm/processor.h> 29 #include <asm/platform.h> 30 #include <asm/bootparam.h> 31 #include <platform/hardware.h> 32 #include <platform/serial.h> 33 34 /* Assumes s points to an 8-chr string. No checking for NULL. */ 35 36 static void led_print (int f, char *s) 37 { 38 unsigned long* led_addr = (unsigned long*) (XT2000_LED_ADDR + 0xE0) + f; 39 int i; 40 for (i = f; i < 8; i++) 41 if ((*led_addr++ = *s++) == 0) 42 break; 43 } 44 45 void platform_halt(void) 46 { 47 led_print (0, " HALT "); 48 local_irq_disable(); 49 while (1); 50 } 51 52 void platform_power_off(void) 53 { 54 led_print (0, "POWEROFF"); 55 local_irq_disable(); 56 while (1); 57 } 58 59 static int xt2000_restart(struct notifier_block *this, 60 unsigned long event, void *ptr) 61 { 62 /* Flush and reset the mmu, simulate a processor reset, and 63 * jump to the reset vector. */ 64 cpu_reset(); 65 66 return NOTIFY_DONE; 67 } 68 69 static struct notifier_block xt2000_restart_block = { 70 .notifier_call = xt2000_restart, 71 }; 72 73 void __init platform_setup(char** cmdline) 74 { 75 led_print (0, "LINUX "); 76 } 77 78 /* Heartbeat. Let the LED blink. */ 79 80 static void xt2000_heartbeat(struct timer_list *unused); 81 82 static DEFINE_TIMER(heartbeat_timer, xt2000_heartbeat); 83 84 static void xt2000_heartbeat(struct timer_list *unused) 85 { 86 static int i; 87 88 led_print(7, i ? "." : " "); 89 i ^= 1; 90 mod_timer(&heartbeat_timer, jiffies + HZ / 2); 91 } 92 93 //#define RS_TABLE_SIZE 2 94 95 #define _SERIAL_PORT(_base,_irq) \ 96 { \ 97 .mapbase = (_base), \ 98 .membase = (void*)(_base), \ 99 .irq = (_irq), \ 100 .uartclk = DUART16552_XTAL_FREQ, \ 101 .iotype = UPIO_MEM, \ 102 .flags = UPF_BOOT_AUTOCONF, \ 103 .regshift = 2, \ 104 } 105 106 static struct plat_serial8250_port xt2000_serial_data[] = { 107 #if XCHAL_HAVE_BE 108 _SERIAL_PORT(DUART16552_1_ADDR + 3, DUART16552_1_INTNUM), 109 _SERIAL_PORT(DUART16552_2_ADDR + 3, DUART16552_2_INTNUM), 110 #else 111 _SERIAL_PORT(DUART16552_1_ADDR, DUART16552_1_INTNUM), 112 _SERIAL_PORT(DUART16552_2_ADDR, DUART16552_2_INTNUM), 113 #endif 114 { } 115 }; 116 117 static struct platform_device xt2000_serial8250_device = { 118 .name = "serial8250", 119 .id = PLAT8250_DEV_PLATFORM, 120 .dev = { 121 .platform_data = xt2000_serial_data, 122 }, 123 }; 124 125 static struct resource xt2000_sonic_res[] = { 126 { 127 .start = SONIC83934_ADDR, 128 .end = SONIC83934_ADDR + 0xff, 129 .flags = IORESOURCE_MEM, 130 }, 131 { 132 .start = SONIC83934_INTNUM, 133 .end = SONIC83934_INTNUM, 134 .flags = IORESOURCE_IRQ, 135 }, 136 }; 137 138 static struct platform_device xt2000_sonic_device = { 139 .name = "xtsonic", 140 .num_resources = ARRAY_SIZE(xt2000_sonic_res), 141 .resource = xt2000_sonic_res, 142 }; 143 144 static int __init xt2000_setup_devinit(void) 145 { 146 platform_device_register(&xt2000_serial8250_device); 147 platform_device_register(&xt2000_sonic_device); 148 mod_timer(&heartbeat_timer, jiffies + HZ / 2); 149 register_restart_handler(&xt2000_restart_block); 150 return 0; 151 } 152 153 device_initcall(xt2000_setup_devinit); 154