paravirt-irq.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368
  1. /*
  2. * This file is subject to the terms and conditions of the GNU General Public
  3. * License. See the file "COPYING" in the main directory of this archive
  4. * for more details.
  5. *
  6. * Copyright (C) 2013 Cavium, Inc.
  7. */
  8. #include <linux/interrupt.h>
  9. #include <linux/cpumask.h>
  10. #include <linux/kernel.h>
  11. #include <linux/mutex.h>
  12. #include <asm/io.h>
  13. #define MBOX_BITS_PER_CPU 2
  14. static int cpunum_for_cpu(int cpu)
  15. {
  16. #ifdef CONFIG_SMP
  17. return cpu_logical_map(cpu);
  18. #else
  19. return get_ebase_cpunum();
  20. #endif
  21. }
  22. struct core_chip_data {
  23. struct mutex core_irq_mutex;
  24. bool current_en;
  25. bool desired_en;
  26. u8 bit;
  27. };
  28. static struct core_chip_data irq_core_chip_data[8];
  29. static void irq_core_ack(struct irq_data *data)
  30. {
  31. struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
  32. unsigned int bit = cd->bit;
  33. /*
  34. * We don't need to disable IRQs to make these atomic since
  35. * they are already disabled earlier in the low level
  36. * interrupt code.
  37. */
  38. clear_c0_status(0x100 << bit);
  39. /* The two user interrupts must be cleared manually. */
  40. if (bit < 2)
  41. clear_c0_cause(0x100 << bit);
  42. }
  43. static void irq_core_eoi(struct irq_data *data)
  44. {
  45. struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
  46. /*
  47. * We don't need to disable IRQs to make these atomic since
  48. * they are already disabled earlier in the low level
  49. * interrupt code.
  50. */
  51. set_c0_status(0x100 << cd->bit);
  52. }
  53. static void irq_core_set_enable_local(void *arg)
  54. {
  55. struct irq_data *data = arg;
  56. struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
  57. unsigned int mask = 0x100 << cd->bit;
  58. /*
  59. * Interrupts are already disabled, so these are atomic.
  60. */
  61. if (cd->desired_en)
  62. set_c0_status(mask);
  63. else
  64. clear_c0_status(mask);
  65. }
  66. static void irq_core_disable(struct irq_data *data)
  67. {
  68. struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
  69. cd->desired_en = false;
  70. }
  71. static void irq_core_enable(struct irq_data *data)
  72. {
  73. struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
  74. cd->desired_en = true;
  75. }
  76. static void irq_core_bus_lock(struct irq_data *data)
  77. {
  78. struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
  79. mutex_lock(&cd->core_irq_mutex);
  80. }
  81. static void irq_core_bus_sync_unlock(struct irq_data *data)
  82. {
  83. struct core_chip_data *cd = irq_data_get_irq_chip_data(data);
  84. if (cd->desired_en != cd->current_en) {
  85. on_each_cpu(irq_core_set_enable_local, data, 1);
  86. cd->current_en = cd->desired_en;
  87. }
  88. mutex_unlock(&cd->core_irq_mutex);
  89. }
  90. static struct irq_chip irq_chip_core = {
  91. .name = "Core",
  92. .irq_enable = irq_core_enable,
  93. .irq_disable = irq_core_disable,
  94. .irq_ack = irq_core_ack,
  95. .irq_eoi = irq_core_eoi,
  96. .irq_bus_lock = irq_core_bus_lock,
  97. .irq_bus_sync_unlock = irq_core_bus_sync_unlock,
  98. .irq_cpu_online = irq_core_eoi,
  99. .irq_cpu_offline = irq_core_ack,
  100. .flags = IRQCHIP_ONOFFLINE_ENABLED,
  101. };
  102. static void __init irq_init_core(void)
  103. {
  104. int i;
  105. int irq;
  106. struct core_chip_data *cd;
  107. /* Start with a clean slate */
  108. clear_c0_status(ST0_IM);
  109. clear_c0_cause(CAUSEF_IP0 | CAUSEF_IP1);
  110. for (i = 0; i < ARRAY_SIZE(irq_core_chip_data); i++) {
  111. cd = irq_core_chip_data + i;
  112. cd->current_en = false;
  113. cd->desired_en = false;
  114. cd->bit = i;
  115. mutex_init(&cd->core_irq_mutex);
  116. irq = MIPS_CPU_IRQ_BASE + i;
  117. switch (i) {
  118. case 0: /* SW0 */
  119. case 1: /* SW1 */
  120. case 5: /* IP5 */
  121. case 6: /* IP6 */
  122. case 7: /* IP7 */
  123. irq_set_chip_data(irq, cd);
  124. irq_set_chip_and_handler(irq, &irq_chip_core,
  125. handle_percpu_irq);
  126. break;
  127. default:
  128. break;
  129. }
  130. }
  131. }
  132. static void __iomem *mips_irq_chip;
  133. #define MIPS_IRQ_CHIP_NUM_BITS 0
  134. #define MIPS_IRQ_CHIP_REGS 8
  135. static int mips_irq_cpu_stride;
  136. static int mips_irq_chip_reg_raw;
  137. static int mips_irq_chip_reg_src;
  138. static int mips_irq_chip_reg_en;
  139. static int mips_irq_chip_reg_raw_w1s;
  140. static int mips_irq_chip_reg_raw_w1c;
  141. static int mips_irq_chip_reg_en_w1s;
  142. static int mips_irq_chip_reg_en_w1c;
  143. static void irq_pci_enable(struct irq_data *data)
  144. {
  145. u32 mask = 1u << data->irq;
  146. __raw_writel(mask, mips_irq_chip + mips_irq_chip_reg_en_w1s);
  147. }
  148. static void irq_pci_disable(struct irq_data *data)
  149. {
  150. u32 mask = 1u << data->irq;
  151. __raw_writel(mask, mips_irq_chip + mips_irq_chip_reg_en_w1c);
  152. }
  153. static void irq_pci_ack(struct irq_data *data)
  154. {
  155. }
  156. static void irq_pci_mask(struct irq_data *data)
  157. {
  158. u32 mask = 1u << data->irq;
  159. __raw_writel(mask, mips_irq_chip + mips_irq_chip_reg_en_w1c);
  160. }
  161. static void irq_pci_unmask(struct irq_data *data)
  162. {
  163. u32 mask = 1u << data->irq;
  164. __raw_writel(mask, mips_irq_chip + mips_irq_chip_reg_en_w1s);
  165. }
  166. static struct irq_chip irq_chip_pci = {
  167. .name = "PCI",
  168. .irq_enable = irq_pci_enable,
  169. .irq_disable = irq_pci_disable,
  170. .irq_ack = irq_pci_ack,
  171. .irq_mask = irq_pci_mask,
  172. .irq_unmask = irq_pci_unmask,
  173. };
  174. static void irq_mbox_all(struct irq_data *data, void __iomem *base)
  175. {
  176. int cpu;
  177. unsigned int mbox = data->irq - MIPS_IRQ_MBOX0;
  178. u32 mask;
  179. WARN_ON(mbox >= MBOX_BITS_PER_CPU);
  180. for_each_online_cpu(cpu) {
  181. unsigned int cpuid = cpunum_for_cpu(cpu);
  182. mask = 1 << (cpuid * MBOX_BITS_PER_CPU + mbox);
  183. __raw_writel(mask, base + (cpuid * mips_irq_cpu_stride));
  184. }
  185. }
  186. static void irq_mbox_enable(struct irq_data *data)
  187. {
  188. irq_mbox_all(data, mips_irq_chip + mips_irq_chip_reg_en_w1s + sizeof(u32));
  189. }
  190. static void irq_mbox_disable(struct irq_data *data)
  191. {
  192. irq_mbox_all(data, mips_irq_chip + mips_irq_chip_reg_en_w1c + sizeof(u32));
  193. }
  194. static void irq_mbox_ack(struct irq_data *data)
  195. {
  196. u32 mask;
  197. unsigned int mbox = data->irq - MIPS_IRQ_MBOX0;
  198. WARN_ON(mbox >= MBOX_BITS_PER_CPU);
  199. mask = 1 << (get_ebase_cpunum() * MBOX_BITS_PER_CPU + mbox);
  200. __raw_writel(mask, mips_irq_chip + mips_irq_chip_reg_raw_w1c + sizeof(u32));
  201. }
  202. void irq_mbox_ipi(int cpu, unsigned int actions)
  203. {
  204. unsigned int cpuid = cpunum_for_cpu(cpu);
  205. u32 mask;
  206. WARN_ON(actions >= (1 << MBOX_BITS_PER_CPU));
  207. mask = actions << (cpuid * MBOX_BITS_PER_CPU);
  208. __raw_writel(mask, mips_irq_chip + mips_irq_chip_reg_raw_w1s + sizeof(u32));
  209. }
  210. static void irq_mbox_cpu_onoffline(struct irq_data *data, void __iomem *base)
  211. {
  212. unsigned int mbox = data->irq - MIPS_IRQ_MBOX0;
  213. unsigned int cpuid = get_ebase_cpunum();
  214. u32 mask;
  215. WARN_ON(mbox >= MBOX_BITS_PER_CPU);
  216. mask = 1 << (cpuid * MBOX_BITS_PER_CPU + mbox);
  217. __raw_writel(mask, base + (cpuid * mips_irq_cpu_stride));
  218. }
  219. static void irq_mbox_cpu_online(struct irq_data *data)
  220. {
  221. irq_mbox_cpu_onoffline(data, mips_irq_chip + mips_irq_chip_reg_en_w1s + sizeof(u32));
  222. }
  223. static void irq_mbox_cpu_offline(struct irq_data *data)
  224. {
  225. irq_mbox_cpu_onoffline(data, mips_irq_chip + mips_irq_chip_reg_en_w1c + sizeof(u32));
  226. }
  227. static struct irq_chip irq_chip_mbox = {
  228. .name = "MBOX",
  229. .irq_enable = irq_mbox_enable,
  230. .irq_disable = irq_mbox_disable,
  231. .irq_ack = irq_mbox_ack,
  232. .irq_cpu_online = irq_mbox_cpu_online,
  233. .irq_cpu_offline = irq_mbox_cpu_offline,
  234. .flags = IRQCHIP_ONOFFLINE_ENABLED,
  235. };
  236. static void __init irq_pci_init(void)
  237. {
  238. int i, stride;
  239. u32 num_bits;
  240. mips_irq_chip = ioremap(0x1e010000, 4096);
  241. num_bits = __raw_readl(mips_irq_chip + MIPS_IRQ_CHIP_NUM_BITS);
  242. stride = 8 * (1 + ((num_bits - 1) / 64));
  243. pr_notice("mips_irq_chip: %u bits, reg stride: %d\n", num_bits, stride);
  244. mips_irq_chip_reg_raw = MIPS_IRQ_CHIP_REGS + 0 * stride;
  245. mips_irq_chip_reg_raw_w1s = MIPS_IRQ_CHIP_REGS + 1 * stride;
  246. mips_irq_chip_reg_raw_w1c = MIPS_IRQ_CHIP_REGS + 2 * stride;
  247. mips_irq_chip_reg_src = MIPS_IRQ_CHIP_REGS + 3 * stride;
  248. mips_irq_chip_reg_en = MIPS_IRQ_CHIP_REGS + 4 * stride;
  249. mips_irq_chip_reg_en_w1s = MIPS_IRQ_CHIP_REGS + 5 * stride;
  250. mips_irq_chip_reg_en_w1c = MIPS_IRQ_CHIP_REGS + 6 * stride;
  251. mips_irq_cpu_stride = stride * 4;
  252. for (i = 0; i < 4; i++)
  253. irq_set_chip_and_handler(i + MIPS_IRQ_PCIA, &irq_chip_pci, handle_level_irq);
  254. for (i = 0; i < 2; i++)
  255. irq_set_chip_and_handler(i + MIPS_IRQ_MBOX0, &irq_chip_mbox, handle_percpu_irq);
  256. set_c0_status(STATUSF_IP2);
  257. }
  258. static void irq_pci_dispatch(void)
  259. {
  260. unsigned int cpuid = get_ebase_cpunum();
  261. u32 en;
  262. en = __raw_readl(mips_irq_chip + mips_irq_chip_reg_src +
  263. (cpuid * mips_irq_cpu_stride));
  264. if (!en) {
  265. en = __raw_readl(mips_irq_chip + mips_irq_chip_reg_src + (cpuid * mips_irq_cpu_stride) + sizeof(u32));
  266. en = (en >> (2 * cpuid)) & 3;
  267. if (!en)
  268. spurious_interrupt();
  269. else
  270. do_IRQ(__ffs(en) + MIPS_IRQ_MBOX0); /* MBOX type */
  271. } else {
  272. do_IRQ(__ffs(en));
  273. }
  274. }
  275. void __init arch_init_irq(void)
  276. {
  277. irq_init_core();
  278. irq_pci_init();
  279. }
  280. asmlinkage void plat_irq_dispatch(void)
  281. {
  282. unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM;
  283. int ip;
  284. if (unlikely(!pending)) {
  285. spurious_interrupt();
  286. return;
  287. }
  288. ip = ffs(pending) - 1 - STATUSB_IP0;
  289. if (ip == 2)
  290. irq_pci_dispatch();
  291. else
  292. do_IRQ(MIPS_CPU_IRQ_BASE + ip);
  293. }