smp.c 1.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. /*
  2. * drivers/power/smp.c - Functions for stopping other CPUs.
  3. *
  4. * Copyright 2004 Pavel Machek <pavel@suse.cz>
  5. * Copyright (C) 2002-2003 Nigel Cunningham <ncunningham@clear.net.nz>
  6. *
  7. * This file is released under the GPLv2.
  8. */
  9. #undef DEBUG
  10. #include <linux/smp_lock.h>
  11. #include <linux/interrupt.h>
  12. #include <linux/suspend.h>
  13. #include <linux/module.h>
  14. #include <linux/cpu.h>
  15. #include <asm/atomic.h>
  16. #include <asm/tlbflush.h>
  17. /* This is protected by pm_sem semaphore */
  18. static cpumask_t frozen_cpus;
  19. void disable_nonboot_cpus(void)
  20. {
  21. int cpu, error;
  22. error = 0;
  23. cpus_clear(frozen_cpus);
  24. printk("Freezing cpus ...\n");
  25. for_each_online_cpu(cpu) {
  26. if (cpu == 0)
  27. continue;
  28. error = cpu_down(cpu);
  29. if (!error) {
  30. cpu_set(cpu, frozen_cpus);
  31. printk("CPU%d is down\n", cpu);
  32. continue;
  33. }
  34. printk("Error taking cpu %d down: %d\n", cpu, error);
  35. }
  36. BUG_ON(raw_smp_processor_id() != 0);
  37. if (error)
  38. panic("cpus not sleeping");
  39. }
  40. void enable_nonboot_cpus(void)
  41. {
  42. int cpu, error;
  43. printk("Thawing cpus ...\n");
  44. for_each_cpu_mask(cpu, frozen_cpus) {
  45. error = smp_prepare_cpu(cpu);
  46. if (!error)
  47. error = cpu_up(cpu);
  48. if (!error) {
  49. printk("CPU%d is up\n", cpu);
  50. continue;
  51. }
  52. printk("Error taking cpu %d up: %d\n", cpu, error);
  53. panic("Not enough cpus");
  54. }
  55. cpus_clear(frozen_cpus);
  56. }