setup.c 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * arch/xtensa/platform-iss/setup.c
  5. *
  6. * Platform specific initialization.
  7. *
  8. * Authors: Chris Zankel <chris@zankel.net>
  9. * Joe Taylor <joe@tensilica.com>
  10. *
  11. * Copyright 2001 - 2005 Tensilica Inc.
  12. * Copyright 2017 Cadence Design Systems Inc.
  13. */
  14. #include <linux/init.h>
  15. #include <linux/kernel.h>
  16. #include <linux/notifier.h>
  17. #include <linux/panic_notifier.h>
  18. #include <linux/printk.h>
  19. #include <linux/reboot.h>
  20. #include <linux/string.h>
  21. #include <asm/platform.h>
  22. #include <asm/setup.h>
  23. #include <platform/simcall.h>
  24. static int iss_power_off(struct sys_off_data *unused)
  25. {
  26. pr_info(" ** Called platform_power_off() **\n");
  27. simc_exit(0);
  28. return NOTIFY_DONE;
  29. }
  30. static int iss_restart(struct notifier_block *this,
  31. unsigned long event, void *ptr)
  32. {
  33. /* Flush and reset the mmu, simulate a processor reset, and
  34. * jump to the reset vector. */
  35. cpu_reset();
  36. return NOTIFY_DONE;
  37. }
  38. static struct notifier_block iss_restart_block = {
  39. .notifier_call = iss_restart,
  40. };
  41. static int
  42. iss_panic_event(struct notifier_block *this, unsigned long event, void *ptr)
  43. {
  44. simc_exit(1);
  45. return NOTIFY_DONE;
  46. }
  47. static struct notifier_block iss_panic_block = {
  48. .notifier_call = iss_panic_event,
  49. };
  50. void __init platform_setup(char **p_cmdline)
  51. {
  52. static void *argv[COMMAND_LINE_SIZE / sizeof(void *)] __initdata;
  53. static char cmdline[COMMAND_LINE_SIZE] __initdata;
  54. int argc = simc_argc();
  55. int argv_size = simc_argv_size();
  56. if (argc > 1) {
  57. if (argv_size > sizeof(argv)) {
  58. pr_err("%s: command line too long: argv_size = %d\n",
  59. __func__, argv_size);
  60. } else {
  61. int i;
  62. cmdline[0] = 0;
  63. simc_argv((void *)argv);
  64. for (i = 1; i < argc; ++i) {
  65. if (i > 1)
  66. strcat(cmdline, " ");
  67. strcat(cmdline, argv[i]);
  68. }
  69. *p_cmdline = cmdline;
  70. }
  71. }
  72. atomic_notifier_chain_register(&panic_notifier_list, &iss_panic_block);
  73. register_restart_handler(&iss_restart_block);
  74. register_sys_off_handler(SYS_OFF_MODE_POWER_OFF,
  75. SYS_OFF_PRIO_PLATFORM,
  76. iss_power_off, NULL);
  77. }