smp-j2.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * SMP support for J2 processor
  4. *
  5. * Copyright (C) 2015-2016 Smart Energy Instruments, Inc.
  6. */
  7. #include <linux/smp.h>
  8. #include <linux/interrupt.h>
  9. #include <linux/io.h>
  10. #include <linux/of_address.h>
  11. #include <linux/of_irq.h>
  12. #include <asm/cmpxchg.h>
  13. DEFINE_PER_CPU(unsigned, j2_ipi_messages);
  14. extern u32 *sh2_cpuid_addr;
  15. static u32 *j2_ipi_trigger;
  16. static int j2_ipi_irq;
  17. static irqreturn_t j2_ipi_interrupt_handler(int irq, void *arg)
  18. {
  19. unsigned cpu = hard_smp_processor_id();
  20. volatile unsigned *pmsg = &per_cpu(j2_ipi_messages, cpu);
  21. unsigned messages, i;
  22. do messages = *pmsg;
  23. while (cmpxchg(pmsg, messages, 0) != messages);
  24. if (!messages) return IRQ_NONE;
  25. for (i=0; i<SMP_MSG_NR; i++)
  26. if (messages & (1U<<i))
  27. smp_message_recv(i);
  28. return IRQ_HANDLED;
  29. }
  30. static void j2_smp_setup(void)
  31. {
  32. }
  33. static void j2_prepare_cpus(unsigned int max_cpus)
  34. {
  35. struct device_node *np;
  36. unsigned i, max = 1;
  37. np = of_find_compatible_node(NULL, NULL, "jcore,ipi-controller");
  38. if (!np)
  39. goto out;
  40. j2_ipi_irq = irq_of_parse_and_map(np, 0);
  41. j2_ipi_trigger = of_iomap(np, 0);
  42. if (!j2_ipi_irq || !j2_ipi_trigger)
  43. goto out;
  44. np = of_find_compatible_node(NULL, NULL, "jcore,cpuid-mmio");
  45. if (!np)
  46. goto out;
  47. sh2_cpuid_addr = of_iomap(np, 0);
  48. if (!sh2_cpuid_addr)
  49. goto out;
  50. if (request_irq(j2_ipi_irq, j2_ipi_interrupt_handler, IRQF_PERCPU,
  51. "ipi", (void *)j2_ipi_interrupt_handler) != 0)
  52. goto out;
  53. max = max_cpus;
  54. out:
  55. /* Disable any cpus past max_cpus, or all secondaries if we didn't
  56. * get the necessary resources to support SMP. */
  57. for (i=max; i<NR_CPUS; i++) {
  58. set_cpu_possible(i, false);
  59. set_cpu_present(i, false);
  60. }
  61. }
  62. static void j2_start_cpu(unsigned int cpu, unsigned long entry_point)
  63. {
  64. struct device_node *np;
  65. u32 regs[2];
  66. void __iomem *release, *initpc;
  67. if (!cpu) return;
  68. np = of_get_cpu_node(cpu, NULL);
  69. if (!np) return;
  70. if (of_property_read_u32_array(np, "cpu-release-addr", regs, 2)) return;
  71. release = ioremap(regs[0], sizeof(u32));
  72. initpc = ioremap(regs[1], sizeof(u32));
  73. __raw_writel(entry_point, initpc);
  74. __raw_writel(1, release);
  75. iounmap(initpc);
  76. iounmap(release);
  77. pr_info("J2 SMP: requested start of cpu %u\n", cpu);
  78. }
  79. static unsigned int j2_smp_processor_id(void)
  80. {
  81. return __raw_readl(sh2_cpuid_addr);
  82. }
  83. static void j2_send_ipi(unsigned int cpu, unsigned int message)
  84. {
  85. volatile unsigned *pmsg;
  86. unsigned old;
  87. unsigned long val;
  88. /* There is only one IPI interrupt shared by all messages, so
  89. * we keep a separate interrupt flag per message type in sw. */
  90. pmsg = &per_cpu(j2_ipi_messages, cpu);
  91. do old = *pmsg;
  92. while (cmpxchg(pmsg, old, old|(1U<<message)) != old);
  93. /* Generate the actual interrupt by writing to CCRn bit 28. */
  94. val = __raw_readl(j2_ipi_trigger + cpu);
  95. __raw_writel(val | (1U<<28), j2_ipi_trigger + cpu);
  96. }
  97. static struct plat_smp_ops j2_smp_ops = {
  98. .smp_setup = j2_smp_setup,
  99. .prepare_cpus = j2_prepare_cpus,
  100. .start_cpu = j2_start_cpu,
  101. .smp_processor_id = j2_smp_processor_id,
  102. .send_ipi = j2_send_ipi,
  103. .cpu_die = native_cpu_die,
  104. .cpu_disable = native_cpu_disable,
  105. .play_dead = native_play_dead,
  106. };
  107. CPU_METHOD_OF_DECLARE(j2_cpu_method, "jcore,spin-table", &j2_smp_ops);