12874c5fdSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2b26d0ab0SChris Zankel /*
3b26d0ab0SChris Zankel *
4b26d0ab0SChris Zankel * arch/xtensa/platform-iss/setup.c
5b26d0ab0SChris Zankel *
6b26d0ab0SChris Zankel * Platform specific initialization.
7b26d0ab0SChris Zankel *
8b26d0ab0SChris Zankel * Authors: Chris Zankel <chris@zankel.net>
9b26d0ab0SChris Zankel * Joe Taylor <joe@tensilica.com>
10b26d0ab0SChris Zankel *
11b26d0ab0SChris Zankel * Copyright 2001 - 2005 Tensilica Inc.
12fbe22d28SMax Filippov * Copyright 2017 Cadence Design Systems Inc.
13b26d0ab0SChris Zankel */
14b26d0ab0SChris Zankel #include <linux/init.h>
15e7253313SMax Filippov #include <linux/kernel.h>
16b26d0ab0SChris Zankel #include <linux/notifier.h>
17f39650deSAndy Shevchenko #include <linux/panic_notifier.h>
18e7253313SMax Filippov #include <linux/printk.h>
1911976fe2SMax Filippov #include <linux/reboot.h>
20e7253313SMax Filippov #include <linux/string.h>
21b26d0ab0SChris Zankel
22b26d0ab0SChris Zankel #include <asm/platform.h>
233ced9730SMax Filippov #include <asm/setup.h>
24b26d0ab0SChris Zankel
25feec273aSMax Filippov #include <platform/simcall.h>
26feec273aSMax Filippov
27b26d0ab0SChris Zankel
iss_power_off(struct sys_off_data * unused)28*7561dfbfSMax Filippov static int iss_power_off(struct sys_off_data *unused)
29b26d0ab0SChris Zankel {
3023753171SMax Filippov pr_info(" ** Called platform_power_off() **\n");
31feec273aSMax Filippov simc_exit(0);
32*7561dfbfSMax Filippov return NOTIFY_DONE;
33b26d0ab0SChris Zankel }
3464716b9eSMax Filippov
iss_restart(struct notifier_block * this,unsigned long event,void * ptr)3511976fe2SMax Filippov static int iss_restart(struct notifier_block *this,
3611976fe2SMax Filippov unsigned long event, void *ptr)
37b26d0ab0SChris Zankel {
38b26d0ab0SChris Zankel /* Flush and reset the mmu, simulate a processor reset, and
39b26d0ab0SChris Zankel * jump to the reset vector. */
404f205687SMax Filippov cpu_reset();
4111976fe2SMax Filippov
4211976fe2SMax Filippov return NOTIFY_DONE;
43b26d0ab0SChris Zankel }
44b26d0ab0SChris Zankel
4511976fe2SMax Filippov static struct notifier_block iss_restart_block = {
4611976fe2SMax Filippov .notifier_call = iss_restart,
4711976fe2SMax Filippov };
4811976fe2SMax Filippov
49b26d0ab0SChris Zankel static int
iss_panic_event(struct notifier_block * this,unsigned long event,void * ptr)50b26d0ab0SChris Zankel iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
51b26d0ab0SChris Zankel {
52feec273aSMax Filippov simc_exit(1);
53b26d0ab0SChris Zankel return NOTIFY_DONE;
54b26d0ab0SChris Zankel }
55b26d0ab0SChris Zankel
56b26d0ab0SChris Zankel static struct notifier_block iss_panic_block = {
573ced9730SMax Filippov .notifier_call = iss_panic_event,
58b26d0ab0SChris Zankel };
59b26d0ab0SChris Zankel
platform_setup(char ** p_cmdline)60b26d0ab0SChris Zankel void __init platform_setup(char **p_cmdline)
61b26d0ab0SChris Zankel {
62ef439d49SMax Filippov static void *argv[COMMAND_LINE_SIZE / sizeof(void *)] __initdata;
63ef439d49SMax Filippov static char cmdline[COMMAND_LINE_SIZE] __initdata;
64fbe22d28SMax Filippov int argc = simc_argc();
65fbe22d28SMax Filippov int argv_size = simc_argv_size();
66fbe22d28SMax Filippov
67fbe22d28SMax Filippov if (argc > 1) {
68ef439d49SMax Filippov if (argv_size > sizeof(argv)) {
69ef439d49SMax Filippov pr_err("%s: command line too long: argv_size = %d\n",
70ef439d49SMax Filippov __func__, argv_size);
71ef439d49SMax Filippov } else {
72fbe22d28SMax Filippov int i;
73fbe22d28SMax Filippov
74fbe22d28SMax Filippov cmdline[0] = 0;
75fbe22d28SMax Filippov simc_argv((void *)argv);
76fbe22d28SMax Filippov
77fbe22d28SMax Filippov for (i = 1; i < argc; ++i) {
78fbe22d28SMax Filippov if (i > 1)
79fbe22d28SMax Filippov strcat(cmdline, " ");
80fbe22d28SMax Filippov strcat(cmdline, argv[i]);
81fbe22d28SMax Filippov }
82fbe22d28SMax Filippov *p_cmdline = cmdline;
83fbe22d28SMax Filippov }
84ef439d49SMax Filippov }
85fbe22d28SMax Filippov
86b26d0ab0SChris Zankel atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block);
8711976fe2SMax Filippov register_restart_handler(&iss_restart_block);
88*7561dfbfSMax Filippov register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
89*7561dfbfSMax Filippov SYS_OFF_PRIO_PLATFORM,
90*7561dfbfSMax Filippov iss_power_off, NULL);
91b26d0ab0SChris Zankel }
92