cpu-hotplug.c 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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/cpuhotplug.h>
  11. #include <linux/cpu.h>
  12. #include <linux/sched/hotplug.h>
  13. #include <asm/irq.h>
  14. #include <asm/cpu_ops.h>
  15. #include <asm/numa.h>
  16. #include <asm/smp.h>
  17. bool cpu_has_hotplug(unsigned int cpu)
  18. {
  19. if (cpu_ops->cpu_stop)
  20. return true;
  21. return false;
  22. }
  23. /*
  24. * __cpu_disable runs on the processor to be shutdown.
  25. */
  26. int __cpu_disable(void)
  27. {
  28. unsigned int cpu = smp_processor_id();
  29. if (!cpu_ops->cpu_stop)
  30. return -EOPNOTSUPP;
  31. remove_cpu_topology(cpu);
  32. numa_remove_cpu(cpu);
  33. set_cpu_online(cpu, false);
  34. riscv_ipi_disable();
  35. irq_migrate_all_off_this_cpu();
  36. return 0;
  37. }
  38. #ifdef CONFIG_HOTPLUG_CPU
  39. /*
  40. * Called on the thread which is asking for a CPU to be shutdown, if the
  41. * CPU reported dead to the hotplug core.
  42. */
  43. void arch_cpuhp_cleanup_dead_cpu(unsigned int cpu)
  44. {
  45. int ret = 0;
  46. pr_notice("CPU%u: off\n", cpu);
  47. /* Verify from the firmware if the cpu is really stopped*/
  48. if (cpu_ops->cpu_is_stopped)
  49. ret = cpu_ops->cpu_is_stopped(cpu);
  50. if (ret)
  51. pr_warn("CPU%u may not have stopped: %d\n", cpu, ret);
  52. }
  53. /*
  54. * Called from the idle thread for the CPU which has been shutdown.
  55. */
  56. void __noreturn arch_cpu_idle_dead(void)
  57. {
  58. idle_task_exit();
  59. cpuhp_ap_report_dead();
  60. cpu_ops->cpu_stop();
  61. /* It should never reach here */
  62. BUG();
  63. }
  64. #endif