reset.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * Copyright (C) 2007 Lemote, Inc. & Institute of Computing Technology
  5. * Author: Fuxin Zhang, [email protected]
  6. * Copyright (C) 2009 Lemote, Inc.
  7. * Author: Zhangjin Wu, [email protected]
  8. */
  9. #include <linux/init.h>
  10. #include <linux/pm.h>
  11. #include <asm/idle.h>
  12. #include <asm/reboot.h>
  13. #include <loongson.h>
  14. static inline void loongson_reboot(void)
  15. {
  16. #ifndef CONFIG_CPU_JUMP_WORKAROUNDS
  17. ((void (*)(void))ioremap(LOONGSON_BOOT_BASE, 4)) ();
  18. #else
  19. void (*func)(void);
  20. func = (void *)ioremap(LOONGSON_BOOT_BASE, 4);
  21. __asm__ __volatile__(
  22. " .set noat \n"
  23. " jr %[func] \n"
  24. " .set at \n"
  25. : /* No outputs */
  26. : [func] "r" (func));
  27. #endif
  28. }
  29. static void loongson_restart(char *command)
  30. {
  31. /* do preparation for reboot */
  32. mach_prepare_reboot();
  33. /* reboot via jumping to boot base address */
  34. loongson_reboot();
  35. }
  36. static void loongson_poweroff(void)
  37. {
  38. mach_prepare_shutdown();
  39. /*
  40. * It needs a wait loop here, but mips/kernel/reset.c already calls
  41. * a generic delay loop, machine_hang(), so simply return.
  42. */
  43. return;
  44. }
  45. static void loongson_halt(void)
  46. {
  47. pr_notice("\n\n** You can safely turn off the power now **\n\n");
  48. while (1) {
  49. if (cpu_wait)
  50. cpu_wait();
  51. }
  52. }
  53. static int __init mips_reboot_setup(void)
  54. {
  55. _machine_restart = loongson_restart;
  56. _machine_halt = loongson_halt;
  57. pm_power_off = loongson_poweroff;
  58. return 0;
  59. }
  60. arch_initcall(mips_reboot_setup);