cpu-hotplug.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (C) 2020 Western Digital Corporation or its affiliates.
  4. */
  5. #include <linux/kernel.h>
  6. #include <linux/mm.h>
  7. #include <linux/sched.h>
  8. #include <linux/err.h>
  9. #include <linux/irq.h>
  10. #include <linux/cpu.h>
  11. #include <linux/sched/hotplug.h>
  12. #include <asm/irq.h>
  13. #include <asm/cpu_ops.h>
  14. #include <asm/sbi.h>
  15. void cpu_stop(void);
  16. void arch_cpu_idle_dead(void)
  17. {
  18. cpu_stop();
  19. }
  20. bool cpu_has_hotplug(unsigned int cpu)
  21. {
  22. if (cpu_ops[cpu]->cpu_stop)
  23. return true;
  24. return false;
  25. }
  26. /*
  27. * __cpu_disable runs on the processor to be shutdown.
  28. */
  29. int __cpu_disable(void)
  30. {
  31. int ret = 0;
  32. unsigned int cpu = smp_processor_id();
  33. if (!cpu_ops[cpu] || !cpu_ops[cpu]->cpu_stop)
  34. return -EOPNOTSUPP;
  35. if (cpu_ops[cpu]->cpu_disable)
  36. ret = cpu_ops[cpu]->cpu_disable(cpu);
  37. if (ret)
  38. return ret;
  39. remove_cpu_topology(cpu);
  40. set_cpu_online(cpu, false);
  41. irq_migrate_all_off_this_cpu();
  42. return ret;
  43. }
  44. /*
  45. * Called on the thread which is asking for a CPU to be shutdown.
  46. */
  47. void __cpu_die(unsigned int cpu)
  48. {
  49. int ret = 0;
  50. if (!cpu_wait_death(cpu, 5)) {
  51. pr_err("CPU %u: didn't die\n", cpu);
  52. return;
  53. }
  54. pr_notice("CPU%u: off\n", cpu);
  55. /* Verify from the firmware if the cpu is really stopped*/
  56. if (cpu_ops[cpu]->cpu_is_stopped)
  57. ret = cpu_ops[cpu]->cpu_is_stopped(cpu);
  58. if (ret)
  59. pr_warn("CPU%d may not have stopped: %d\n", cpu, ret);
  60. }
  61. /*
  62. * Called from the idle thread for the CPU which has been shutdown.
  63. */
  64. void cpu_stop(void)
  65. {
  66. idle_task_exit();
  67. (void)cpu_report_death();
  68. cpu_ops[smp_processor_id()]->cpu_stop();
  69. /* It should never reach here */
  70. BUG();
  71. }