162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * arch/xtensa/platform-iss/setup.c 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Platform specific initialization. 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Authors: Chris Zankel <chris@zankel.net> 962306a36Sopenharmony_ci * Joe Taylor <joe@tensilica.com> 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * Copyright 2001 - 2005 Tensilica Inc. 1262306a36Sopenharmony_ci * Copyright 2017 Cadence Design Systems Inc. 1362306a36Sopenharmony_ci */ 1462306a36Sopenharmony_ci#include <linux/init.h> 1562306a36Sopenharmony_ci#include <linux/kernel.h> 1662306a36Sopenharmony_ci#include <linux/notifier.h> 1762306a36Sopenharmony_ci#include <linux/panic_notifier.h> 1862306a36Sopenharmony_ci#include <linux/printk.h> 1962306a36Sopenharmony_ci#include <linux/reboot.h> 2062306a36Sopenharmony_ci#include <linux/string.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#include <asm/platform.h> 2362306a36Sopenharmony_ci#include <asm/setup.h> 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci#include <platform/simcall.h> 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistatic int iss_power_off(struct sys_off_data *unused) 2962306a36Sopenharmony_ci{ 3062306a36Sopenharmony_ci pr_info(" ** Called platform_power_off() **\n"); 3162306a36Sopenharmony_ci simc_exit(0); 3262306a36Sopenharmony_ci return NOTIFY_DONE; 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic int iss_restart(struct notifier_block *this, 3662306a36Sopenharmony_ci unsigned long event, void *ptr) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci /* Flush and reset the mmu, simulate a processor reset, and 3962306a36Sopenharmony_ci * jump to the reset vector. */ 4062306a36Sopenharmony_ci cpu_reset(); 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci return NOTIFY_DONE; 4362306a36Sopenharmony_ci} 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_cistatic struct notifier_block iss_restart_block = { 4662306a36Sopenharmony_ci .notifier_call = iss_restart, 4762306a36Sopenharmony_ci}; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_cistatic int 5062306a36Sopenharmony_ciiss_panic_event(struct notifier_block *this, unsigned long event, void *ptr) 5162306a36Sopenharmony_ci{ 5262306a36Sopenharmony_ci simc_exit(1); 5362306a36Sopenharmony_ci return NOTIFY_DONE; 5462306a36Sopenharmony_ci} 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_cistatic struct notifier_block iss_panic_block = { 5762306a36Sopenharmony_ci .notifier_call = iss_panic_event, 5862306a36Sopenharmony_ci}; 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_civoid __init platform_setup(char **p_cmdline) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci static void *argv[COMMAND_LINE_SIZE / sizeof(void *)] __initdata; 6362306a36Sopenharmony_ci static char cmdline[COMMAND_LINE_SIZE] __initdata; 6462306a36Sopenharmony_ci int argc = simc_argc(); 6562306a36Sopenharmony_ci int argv_size = simc_argv_size(); 6662306a36Sopenharmony_ci 6762306a36Sopenharmony_ci if (argc > 1) { 6862306a36Sopenharmony_ci if (argv_size > sizeof(argv)) { 6962306a36Sopenharmony_ci pr_err("%s: command line too long: argv_size = %d\n", 7062306a36Sopenharmony_ci __func__, argv_size); 7162306a36Sopenharmony_ci } else { 7262306a36Sopenharmony_ci int i; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci cmdline[0] = 0; 7562306a36Sopenharmony_ci simc_argv((void *)argv); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci for (i = 1; i < argc; ++i) { 7862306a36Sopenharmony_ci if (i > 1) 7962306a36Sopenharmony_ci strcat(cmdline, " "); 8062306a36Sopenharmony_ci strcat(cmdline, argv[i]); 8162306a36Sopenharmony_ci } 8262306a36Sopenharmony_ci *p_cmdline = cmdline; 8362306a36Sopenharmony_ci } 8462306a36Sopenharmony_ci } 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block); 8762306a36Sopenharmony_ci register_restart_handler(&iss_restart_block); 8862306a36Sopenharmony_ci register_sys_off_handler(SYS_OFF_MODE_POWER_OFF, 8962306a36Sopenharmony_ci SYS_OFF_PRIO_PLATFORM, 9062306a36Sopenharmony_ci iss_power_off, NULL); 9162306a36Sopenharmony_ci} 92