322-MIPS-BCM63XX-switch-to-IRQ_DOMAIN.patch 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. From d2d2489e0a4b740abd980e9d1cad952d15bc2d9e Mon Sep 17 00:00:00 2001
  2. From: Jonas Gorski <jogo@openwrt.org>
  3. Date: Sun, 30 Nov 2014 14:55:02 +0100
  4. Subject: [PATCH] MIPS: BCM63XX: switch to IRQ_DOMAIN
  5. Now that we have working IRQ_DOMAIN drivers for both interrupt controllers,
  6. switch to using them.
  7. Signed-off-by: Jonas Gorski <jogo@openwrt.org>
  8. ---
  9. arch/mips/Kconfig | 3 +
  10. arch/mips/bcm63xx/irq.c | 612 +++++++++---------------------------------------
  11. 2 files changed, 108 insertions(+), 507 deletions(-)
  12. --- a/arch/mips/Kconfig
  13. +++ b/arch/mips/Kconfig
  14. @@ -208,6 +208,9 @@ config BCM63XX
  15. select SYNC_R4K
  16. select DMA_NONCOHERENT
  17. select IRQ_MIPS_CPU
  18. + select BCM6345_EXT_IRQ
  19. + select BCM6345_PERIPH_IRQ
  20. + select IRQ_DOMAIN
  21. select SYS_SUPPORTS_32BIT_KERNEL
  22. select SYS_SUPPORTS_BIG_ENDIAN
  23. select SYS_HAS_EARLY_PRINTK
  24. --- a/arch/mips/bcm63xx/irq.c
  25. +++ b/arch/mips/bcm63xx/irq.c
  26. @@ -12,7 +12,9 @@
  27. #include <linux/interrupt.h>
  28. #include <linux/module.h>
  29. #include <linux/irq.h>
  30. -#include <linux/spinlock.h>
  31. +#include <linux/irqchip.h>
  32. +#include <linux/irqchip/irq-bcm6345-ext.h>
  33. +#include <linux/irqchip/irq-bcm6345-periph.h>
  34. #include <asm/irq_cpu.h>
  35. #include <asm/mipsregs.h>
  36. #include <bcm63xx_cpu.h>
  37. @@ -20,544 +22,140 @@
  38. #include <bcm63xx_io.h>
  39. #include <bcm63xx_irq.h>
  40. -
  41. -static DEFINE_SPINLOCK(ipic_lock);
  42. -static DEFINE_SPINLOCK(epic_lock);
  43. -
  44. -static u32 irq_stat_addr[2];
  45. -static u32 irq_mask_addr[2];
  46. -static void (*dispatch_internal)(int cpu);
  47. -static int is_ext_irq_cascaded;
  48. -static unsigned int ext_irq_count;
  49. -static unsigned int ext_irq_start, ext_irq_end;
  50. -static unsigned int ext_irq_cfg_reg1, ext_irq_cfg_reg2;
  51. -static void (*internal_irq_mask)(struct irq_data *d);
  52. -static void (*internal_irq_unmask)(struct irq_data *d, const struct cpumask *m);
  53. -
  54. -
  55. -static inline u32 get_ext_irq_perf_reg(int irq)
  56. -{
  57. - if (irq < 4)
  58. - return ext_irq_cfg_reg1;
  59. - return ext_irq_cfg_reg2;
  60. -}
  61. -
  62. -static inline void handle_internal(int intbit)
  63. -{
  64. - if (is_ext_irq_cascaded &&
  65. - intbit >= ext_irq_start && intbit <= ext_irq_end)
  66. - do_IRQ(intbit - ext_irq_start + IRQ_EXTERNAL_BASE);
  67. - else
  68. - do_IRQ(intbit + IRQ_INTERNAL_BASE);
  69. -}
  70. -
  71. -static inline int enable_irq_for_cpu(int cpu, struct irq_data *d,
  72. - const struct cpumask *m)
  73. -{
  74. - bool enable = cpu_online(cpu);
  75. -
  76. -#ifdef CONFIG_SMP
  77. - if (m)
  78. - enable &= cpumask_test_cpu(cpu, m);
  79. - else if (irqd_affinity_was_set(d))
  80. - enable &= cpumask_test_cpu(cpu, irq_data_get_affinity_mask(d));
  81. -#endif
  82. - return enable;
  83. -}
  84. -
  85. -/*
  86. - * dispatch internal devices IRQ (uart, enet, watchdog, ...). do not
  87. - * prioritize any interrupt relatively to another. the static counter
  88. - * will resume the loop where it ended the last time we left this
  89. - * function.
  90. - */
  91. -
  92. -#define BUILD_IPIC_INTERNAL(width) \
  93. -void __dispatch_internal_##width(int cpu) \
  94. -{ \
  95. - u32 pending[width / 32]; \
  96. - unsigned int src, tgt; \
  97. - bool irqs_pending = false; \
  98. - static unsigned int i[2]; \
  99. - unsigned int *next = &i[cpu]; \
  100. - unsigned long flags; \
  101. - \
  102. - /* read registers in reverse order */ \
  103. - spin_lock_irqsave(&ipic_lock, flags); \
  104. - for (src = 0, tgt = (width / 32); src < (width / 32); src++) { \
  105. - u32 val; \
  106. - \
  107. - val = bcm_readl(irq_stat_addr[cpu] + src * sizeof(u32)); \
  108. - val &= bcm_readl(irq_mask_addr[cpu] + src * sizeof(u32)); \
  109. - pending[--tgt] = val; \
  110. - \
  111. - if (val) \
  112. - irqs_pending = true; \
  113. - } \
  114. - spin_unlock_irqrestore(&ipic_lock, flags); \
  115. - \
  116. - if (!irqs_pending) \
  117. - return; \
  118. - \
  119. - while (1) { \
  120. - unsigned int to_call = *next; \
  121. - \
  122. - *next = (*next + 1) & (width - 1); \
  123. - if (pending[to_call / 32] & (1 << (to_call & 0x1f))) { \
  124. - handle_internal(to_call); \
  125. - break; \
  126. - } \
  127. - } \
  128. -} \
  129. - \
  130. -static void __internal_irq_mask_##width(struct irq_data *d) \
  131. -{ \
  132. - u32 val; \
  133. - unsigned irq = d->irq - IRQ_INTERNAL_BASE; \
  134. - unsigned reg = (irq / 32) ^ (width/32 - 1); \
  135. - unsigned bit = irq & 0x1f; \
  136. - unsigned long flags; \
  137. - int cpu; \
  138. - \
  139. - spin_lock_irqsave(&ipic_lock, flags); \
  140. - for_each_present_cpu(cpu) { \
  141. - if (!irq_mask_addr[cpu]) \
  142. - break; \
  143. - \
  144. - val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\
  145. - val &= ~(1 << bit); \
  146. - bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\
  147. - } \
  148. - spin_unlock_irqrestore(&ipic_lock, flags); \
  149. -} \
  150. - \
  151. -static void __internal_irq_unmask_##width(struct irq_data *d, \
  152. - const struct cpumask *m) \
  153. -{ \
  154. - u32 val; \
  155. - unsigned irq = d->irq - IRQ_INTERNAL_BASE; \
  156. - unsigned reg = (irq / 32) ^ (width/32 - 1); \
  157. - unsigned bit = irq & 0x1f; \
  158. - unsigned long flags; \
  159. - int cpu; \
  160. - \
  161. - spin_lock_irqsave(&ipic_lock, flags); \
  162. - for_each_present_cpu(cpu) { \
  163. - if (!irq_mask_addr[cpu]) \
  164. - break; \
  165. - \
  166. - val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\
  167. - if (enable_irq_for_cpu(cpu, d, m)) \
  168. - val |= (1 << bit); \
  169. - else \
  170. - val &= ~(1 << bit); \
  171. - bcm_writel(val, irq_mask_addr[cpu] + reg * sizeof(u32));\
  172. - } \
  173. - spin_unlock_irqrestore(&ipic_lock, flags); \
  174. -}
  175. -
  176. -BUILD_IPIC_INTERNAL(32);
  177. -BUILD_IPIC_INTERNAL(64);
  178. -
  179. -asmlinkage void plat_irq_dispatch(void)
  180. -{
  181. - u32 cause;
  182. -
  183. - do {
  184. - cause = read_c0_cause() & read_c0_status() & ST0_IM;
  185. -
  186. - if (!cause)
  187. - break;
  188. -
  189. - if (cause & CAUSEF_IP7)
  190. - do_IRQ(7);
  191. - if (cause & CAUSEF_IP0)
  192. - do_IRQ(0);
  193. - if (cause & CAUSEF_IP1)
  194. - do_IRQ(1);
  195. - if (cause & CAUSEF_IP2)
  196. - dispatch_internal(0);
  197. - if (is_ext_irq_cascaded) {
  198. - if (cause & CAUSEF_IP3)
  199. - dispatch_internal(1);
  200. - } else {
  201. - if (cause & CAUSEF_IP3)
  202. - do_IRQ(IRQ_EXT_0);
  203. - if (cause & CAUSEF_IP4)
  204. - do_IRQ(IRQ_EXT_1);
  205. - if (cause & CAUSEF_IP5)
  206. - do_IRQ(IRQ_EXT_2);
  207. - if (cause & CAUSEF_IP6)
  208. - do_IRQ(IRQ_EXT_3);
  209. - }
  210. - } while (1);
  211. -}
  212. -
  213. -/*
  214. - * internal IRQs operations: only mask/unmask on PERF irq mask
  215. - * register.
  216. - */
  217. -static void bcm63xx_internal_irq_mask(struct irq_data *d)
  218. -{
  219. - internal_irq_mask(d);
  220. -}
  221. -
  222. -static void bcm63xx_internal_irq_unmask(struct irq_data *d)
  223. -{
  224. - internal_irq_unmask(d, NULL);
  225. -}
  226. -
  227. -/*
  228. - * external IRQs operations: mask/unmask and clear on PERF external
  229. - * irq control register.
  230. - */
  231. -static void bcm63xx_external_irq_mask(struct irq_data *d)
  232. -{
  233. - unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
  234. - u32 reg, regaddr;
  235. - unsigned long flags;
  236. -
  237. - regaddr = get_ext_irq_perf_reg(irq);
  238. - spin_lock_irqsave(&epic_lock, flags);
  239. - reg = bcm_perf_readl(regaddr);
  240. -
  241. - if (BCMCPU_IS_6348())
  242. - reg &= ~EXTIRQ_CFG_MASK_6348(irq % 4);
  243. - else
  244. - reg &= ~EXTIRQ_CFG_MASK(irq % 4);
  245. -
  246. - bcm_perf_writel(reg, regaddr);
  247. - spin_unlock_irqrestore(&epic_lock, flags);
  248. -
  249. - if (is_ext_irq_cascaded)
  250. - internal_irq_mask(irq_get_irq_data(irq + ext_irq_start));
  251. -}
  252. -
  253. -static void bcm63xx_external_irq_unmask(struct irq_data *d)
  254. -{
  255. - unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
  256. - u32 reg, regaddr;
  257. - unsigned long flags;
  258. -
  259. - regaddr = get_ext_irq_perf_reg(irq);
  260. - spin_lock_irqsave(&epic_lock, flags);
  261. - reg = bcm_perf_readl(regaddr);
  262. -
  263. - if (BCMCPU_IS_6348())
  264. - reg |= EXTIRQ_CFG_MASK_6348(irq % 4);
  265. - else
  266. - reg |= EXTIRQ_CFG_MASK(irq % 4);
  267. -
  268. - bcm_perf_writel(reg, regaddr);
  269. - spin_unlock_irqrestore(&epic_lock, flags);
  270. -
  271. - if (is_ext_irq_cascaded)
  272. - internal_irq_unmask(irq_get_irq_data(irq + ext_irq_start),
  273. - NULL);
  274. -}
  275. -
  276. -static void bcm63xx_external_irq_clear(struct irq_data *d)
  277. -{
  278. - unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
  279. - u32 reg, regaddr;
  280. - unsigned long flags;
  281. -
  282. - regaddr = get_ext_irq_perf_reg(irq);
  283. - spin_lock_irqsave(&epic_lock, flags);
  284. - reg = bcm_perf_readl(regaddr);
  285. -
  286. - if (BCMCPU_IS_6348())
  287. - reg |= EXTIRQ_CFG_CLEAR_6348(irq % 4);
  288. - else
  289. - reg |= EXTIRQ_CFG_CLEAR(irq % 4);
  290. -
  291. - bcm_perf_writel(reg, regaddr);
  292. - spin_unlock_irqrestore(&epic_lock, flags);
  293. -}
  294. -
  295. -static int bcm63xx_external_irq_set_type(struct irq_data *d,
  296. - unsigned int flow_type)
  297. -{
  298. - unsigned int irq = d->irq - IRQ_EXTERNAL_BASE;
  299. - u32 reg, regaddr;
  300. - int levelsense, sense, bothedge;
  301. - unsigned long flags;
  302. -
  303. - flow_type &= IRQ_TYPE_SENSE_MASK;
  304. -
  305. - if (flow_type == IRQ_TYPE_NONE)
  306. - flow_type = IRQ_TYPE_LEVEL_LOW;
  307. -
  308. - levelsense = sense = bothedge = 0;
  309. - switch (flow_type) {
  310. - case IRQ_TYPE_EDGE_BOTH:
  311. - bothedge = 1;
  312. - break;
  313. -
  314. - case IRQ_TYPE_EDGE_RISING:
  315. - sense = 1;
  316. - break;
  317. -
  318. - case IRQ_TYPE_EDGE_FALLING:
  319. - break;
  320. -
  321. - case IRQ_TYPE_LEVEL_HIGH:
  322. - levelsense = 1;
  323. - sense = 1;
  324. - break;
  325. -
  326. - case IRQ_TYPE_LEVEL_LOW:
  327. - levelsense = 1;
  328. - break;
  329. -
  330. - default:
  331. - pr_err("bogus flow type combination given !\n");
  332. - return -EINVAL;
  333. - }
  334. -
  335. - regaddr = get_ext_irq_perf_reg(irq);
  336. - spin_lock_irqsave(&epic_lock, flags);
  337. - reg = bcm_perf_readl(regaddr);
  338. - irq %= 4;
  339. -
  340. - switch (bcm63xx_get_cpu_id()) {
  341. - case BCM6348_CPU_ID:
  342. - if (levelsense)
  343. - reg |= EXTIRQ_CFG_LEVELSENSE_6348(irq);
  344. - else
  345. - reg &= ~EXTIRQ_CFG_LEVELSENSE_6348(irq);
  346. - if (sense)
  347. - reg |= EXTIRQ_CFG_SENSE_6348(irq);
  348. - else
  349. - reg &= ~EXTIRQ_CFG_SENSE_6348(irq);
  350. - if (bothedge)
  351. - reg |= EXTIRQ_CFG_BOTHEDGE_6348(irq);
  352. - else
  353. - reg &= ~EXTIRQ_CFG_BOTHEDGE_6348(irq);
  354. - break;
  355. -
  356. - case BCM3368_CPU_ID:
  357. - case BCM6328_CPU_ID:
  358. - case BCM6338_CPU_ID:
  359. - case BCM6345_CPU_ID:
  360. - case BCM6358_CPU_ID:
  361. - case BCM6362_CPU_ID:
  362. - case BCM6368_CPU_ID:
  363. - if (levelsense)
  364. - reg |= EXTIRQ_CFG_LEVELSENSE(irq);
  365. - else
  366. - reg &= ~EXTIRQ_CFG_LEVELSENSE(irq);
  367. - if (sense)
  368. - reg |= EXTIRQ_CFG_SENSE(irq);
  369. - else
  370. - reg &= ~EXTIRQ_CFG_SENSE(irq);
  371. - if (bothedge)
  372. - reg |= EXTIRQ_CFG_BOTHEDGE(irq);
  373. - else
  374. - reg &= ~EXTIRQ_CFG_BOTHEDGE(irq);
  375. - break;
  376. - default:
  377. - BUG();
  378. - }
  379. -
  380. - bcm_perf_writel(reg, regaddr);
  381. - spin_unlock_irqrestore(&epic_lock, flags);
  382. -
  383. - irqd_set_trigger_type(d, flow_type);
  384. - if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH))
  385. - irq_set_handler_locked(d, handle_level_irq);
  386. - else
  387. - irq_set_handler_locked(d, handle_edge_irq);
  388. -
  389. - return IRQ_SET_MASK_OK_NOCOPY;
  390. -}
  391. -
  392. -#ifdef CONFIG_SMP
  393. -static int bcm63xx_internal_set_affinity(struct irq_data *data,
  394. - const struct cpumask *dest,
  395. - bool force)
  396. -{
  397. - if (!irqd_irq_disabled(data))
  398. - internal_irq_unmask(data, dest);
  399. -
  400. - return 0;
  401. -}
  402. -#endif
  403. -
  404. -static struct irq_chip bcm63xx_internal_irq_chip = {
  405. - .name = "bcm63xx_ipic",
  406. - .irq_mask = bcm63xx_internal_irq_mask,
  407. - .irq_unmask = bcm63xx_internal_irq_unmask,
  408. -};
  409. -
  410. -static struct irq_chip bcm63xx_external_irq_chip = {
  411. - .name = "bcm63xx_epic",
  412. - .irq_ack = bcm63xx_external_irq_clear,
  413. -
  414. - .irq_mask = bcm63xx_external_irq_mask,
  415. - .irq_unmask = bcm63xx_external_irq_unmask,
  416. -
  417. - .irq_set_type = bcm63xx_external_irq_set_type,
  418. -};
  419. -
  420. -static struct irqaction cpu_ip2_cascade_action = {
  421. - .handler = no_action,
  422. - .name = "cascade_ip2",
  423. - .flags = IRQF_NO_THREAD,
  424. -};
  425. -
  426. -#ifdef CONFIG_SMP
  427. -static struct irqaction cpu_ip3_cascade_action = {
  428. - .handler = no_action,
  429. - .name = "cascade_ip3",
  430. - .flags = IRQF_NO_THREAD,
  431. -};
  432. -#endif
  433. -
  434. -static struct irqaction cpu_ext_cascade_action = {
  435. - .handler = no_action,
  436. - .name = "cascade_extirq",
  437. - .flags = IRQF_NO_THREAD,
  438. -};
  439. -
  440. -static void bcm63xx_init_irq(void)
  441. +void __init arch_init_irq(void)
  442. {
  443. - int irq_bits;
  444. -
  445. - irq_stat_addr[0] = bcm63xx_regset_address(RSET_PERF);
  446. - irq_mask_addr[0] = bcm63xx_regset_address(RSET_PERF);
  447. - irq_stat_addr[1] = bcm63xx_regset_address(RSET_PERF);
  448. - irq_mask_addr[1] = bcm63xx_regset_address(RSET_PERF);
  449. + void __iomem *periph_bases[2];
  450. + void __iomem *ext_intc_bases[2];
  451. + int periph_irq_count, periph_width, ext_irq_count, ext_shift;
  452. + int periph_irqs[2] = { 2, 3 };
  453. + int ext_irqs[6];
  454. +
  455. + periph_bases[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
  456. + periph_bases[1] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
  457. + ext_intc_bases[0] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
  458. + ext_intc_bases[1] = (void __iomem *)bcm63xx_regset_address(RSET_PERF);
  459. switch (bcm63xx_get_cpu_id()) {
  460. case BCM3368_CPU_ID:
  461. - irq_stat_addr[0] += PERF_IRQSTAT_3368_REG;
  462. - irq_mask_addr[0] += PERF_IRQMASK_3368_REG;
  463. - irq_stat_addr[1] = 0;
  464. - irq_mask_addr[1] = 0;
  465. - irq_bits = 32;
  466. - ext_irq_count = 4;
  467. - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_3368;
  468. + periph_bases[0] += PERF_IRQMASK_3368_REG;
  469. + periph_irq_count = 1;
  470. + periph_width = 1;
  471. +
  472. + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_3368;
  473. + ext_irq_count = 4;
  474. + ext_irqs[0] = BCM_3368_EXT_IRQ0;
  475. + ext_irqs[1] = BCM_3368_EXT_IRQ1;
  476. + ext_irqs[2] = BCM_3368_EXT_IRQ2;
  477. + ext_irqs[3] = BCM_3368_EXT_IRQ3;
  478. + ext_shift = 4;
  479. break;
  480. case BCM6328_CPU_ID:
  481. - irq_stat_addr[0] += PERF_IRQSTAT_6328_REG(0);
  482. - irq_mask_addr[0] += PERF_IRQMASK_6328_REG(0);
  483. - irq_stat_addr[1] += PERF_IRQSTAT_6328_REG(1);
  484. - irq_mask_addr[1] += PERF_IRQMASK_6328_REG(1);
  485. - irq_bits = 64;
  486. - ext_irq_count = 4;
  487. - is_ext_irq_cascaded = 1;
  488. - ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE;
  489. - ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE;
  490. - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328;
  491. + periph_bases[0] += PERF_IRQMASK_6328_REG(0);
  492. + periph_bases[1] += PERF_IRQMASK_6328_REG(1);
  493. + periph_irq_count = 2;
  494. + periph_width = 2;
  495. +
  496. + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6328;
  497. + ext_irq_count = 4;
  498. + ext_irqs[0] = BCM_6328_EXT_IRQ0;
  499. + ext_irqs[1] = BCM_6328_EXT_IRQ1;
  500. + ext_irqs[2] = BCM_6328_EXT_IRQ2;
  501. + ext_irqs[3] = BCM_6328_EXT_IRQ3;
  502. + ext_shift = 4;
  503. break;
  504. case BCM6338_CPU_ID:
  505. - irq_stat_addr[0] += PERF_IRQSTAT_6338_REG;
  506. - irq_mask_addr[0] += PERF_IRQMASK_6338_REG;
  507. - irq_stat_addr[1] = 0;
  508. - irq_mask_addr[1] = 0;
  509. - irq_bits = 32;
  510. - ext_irq_count = 4;
  511. - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6338;
  512. + periph_bases[0] += PERF_IRQMASK_6338_REG;
  513. + periph_irq_count = 1;
  514. + periph_width = 1;
  515. +
  516. + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6338;
  517. + ext_irq_count = 4;
  518. + ext_irqs[0] = 3;
  519. + ext_irqs[1] = 4;
  520. + ext_irqs[2] = 5;
  521. + ext_irqs[3] = 6;
  522. + ext_shift = 4;
  523. break;
  524. case BCM6345_CPU_ID:
  525. - irq_stat_addr[0] += PERF_IRQSTAT_6345_REG;
  526. - irq_mask_addr[0] += PERF_IRQMASK_6345_REG;
  527. - irq_stat_addr[1] = 0;
  528. - irq_mask_addr[1] = 0;
  529. - irq_bits = 32;
  530. - ext_irq_count = 4;
  531. - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6345;
  532. + periph_bases[0] += PERF_IRQMASK_6345_REG;
  533. + periph_irq_count = 1;
  534. + periph_width = 1;
  535. +
  536. + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6345;
  537. + ext_irq_count = 4;
  538. + ext_irqs[0] = 3;
  539. + ext_irqs[1] = 4;
  540. + ext_irqs[2] = 5;
  541. + ext_irqs[3] = 6;
  542. + ext_shift = 4;
  543. break;
  544. case BCM6348_CPU_ID:
  545. - irq_stat_addr[0] += PERF_IRQSTAT_6348_REG;
  546. - irq_mask_addr[0] += PERF_IRQMASK_6348_REG;
  547. - irq_stat_addr[1] = 0;
  548. - irq_mask_addr[1] = 0;
  549. - irq_bits = 32;
  550. - ext_irq_count = 4;
  551. - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6348;
  552. + periph_bases[0] += PERF_IRQMASK_6348_REG;
  553. + periph_irq_count = 1;
  554. + periph_width = 1;
  555. +
  556. + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6348;
  557. + ext_irq_count = 4;
  558. + ext_irqs[0] = 3;
  559. + ext_irqs[1] = 4;
  560. + ext_irqs[2] = 5;
  561. + ext_irqs[3] = 6;
  562. + ext_shift = 5;
  563. break;
  564. case BCM6358_CPU_ID:
  565. - irq_stat_addr[0] += PERF_IRQSTAT_6358_REG(0);
  566. - irq_mask_addr[0] += PERF_IRQMASK_6358_REG(0);
  567. - irq_stat_addr[1] += PERF_IRQSTAT_6358_REG(1);
  568. - irq_mask_addr[1] += PERF_IRQMASK_6358_REG(1);
  569. - irq_bits = 32;
  570. - ext_irq_count = 4;
  571. - is_ext_irq_cascaded = 1;
  572. - ext_irq_start = BCM_6358_EXT_IRQ0 - IRQ_INTERNAL_BASE;
  573. - ext_irq_end = BCM_6358_EXT_IRQ3 - IRQ_INTERNAL_BASE;
  574. - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6358;
  575. + periph_bases[0] += PERF_IRQMASK_6358_REG(0);
  576. + periph_bases[1] += PERF_IRQMASK_6358_REG(1);
  577. + periph_irq_count = 2;
  578. + periph_width = 1;
  579. +
  580. + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6358;
  581. + ext_irq_count = 4;
  582. + ext_irqs[0] = BCM_6358_EXT_IRQ0;
  583. + ext_irqs[1] = BCM_6358_EXT_IRQ1;
  584. + ext_irqs[2] = BCM_6358_EXT_IRQ2;
  585. + ext_irqs[3] = BCM_6358_EXT_IRQ3;
  586. + ext_shift = 4;
  587. break;
  588. case BCM6362_CPU_ID:
  589. - irq_stat_addr[0] += PERF_IRQSTAT_6362_REG(0);
  590. - irq_mask_addr[0] += PERF_IRQMASK_6362_REG(0);
  591. - irq_stat_addr[1] += PERF_IRQSTAT_6362_REG(1);
  592. - irq_mask_addr[1] += PERF_IRQMASK_6362_REG(1);
  593. - irq_bits = 64;
  594. - ext_irq_count = 4;
  595. - is_ext_irq_cascaded = 1;
  596. - ext_irq_start = BCM_6362_EXT_IRQ0 - IRQ_INTERNAL_BASE;
  597. - ext_irq_end = BCM_6362_EXT_IRQ3 - IRQ_INTERNAL_BASE;
  598. - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6362;
  599. + periph_bases[0] += PERF_IRQMASK_6362_REG(0);
  600. + periph_bases[1] += PERF_IRQMASK_6362_REG(1);
  601. + periph_irq_count = 2;
  602. + periph_width = 2;
  603. +
  604. + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6362;
  605. + ext_irq_count = 4;
  606. + ext_irqs[0] = BCM_6362_EXT_IRQ0;
  607. + ext_irqs[1] = BCM_6362_EXT_IRQ1;
  608. + ext_irqs[2] = BCM_6362_EXT_IRQ2;
  609. + ext_irqs[3] = BCM_6362_EXT_IRQ3;
  610. + ext_shift = 4;
  611. break;
  612. case BCM6368_CPU_ID:
  613. - irq_stat_addr[0] += PERF_IRQSTAT_6368_REG(0);
  614. - irq_mask_addr[0] += PERF_IRQMASK_6368_REG(0);
  615. - irq_stat_addr[1] += PERF_IRQSTAT_6368_REG(1);
  616. - irq_mask_addr[1] += PERF_IRQMASK_6368_REG(1);
  617. - irq_bits = 64;
  618. + periph_bases[0] += PERF_IRQMASK_6368_REG(0);
  619. + periph_bases[1] += PERF_IRQMASK_6368_REG(1);
  620. + periph_irq_count = 2;
  621. + periph_width = 2;
  622. +
  623. + ext_intc_bases[0] += PERF_EXTIRQ_CFG_REG_6368;
  624. + ext_intc_bases[1] += PERF_EXTIRQ_CFG_REG2_6368;
  625. ext_irq_count = 6;
  626. - is_ext_irq_cascaded = 1;
  627. - ext_irq_start = BCM_6368_EXT_IRQ0 - IRQ_INTERNAL_BASE;
  628. - ext_irq_end = BCM_6368_EXT_IRQ5 - IRQ_INTERNAL_BASE;
  629. - ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6368;
  630. - ext_irq_cfg_reg2 = PERF_EXTIRQ_CFG_REG2_6368;
  631. + ext_irqs[0] = BCM_6368_EXT_IRQ0;
  632. + ext_irqs[1] = BCM_6368_EXT_IRQ1;
  633. + ext_irqs[2] = BCM_6368_EXT_IRQ2;
  634. + ext_irqs[3] = BCM_6368_EXT_IRQ3;
  635. + ext_irqs[4] = BCM_6368_EXT_IRQ4;
  636. + ext_irqs[5] = BCM_6368_EXT_IRQ5;
  637. + ext_shift = 4;
  638. break;
  639. default:
  640. BUG();
  641. }
  642. - if (irq_bits == 32) {
  643. - dispatch_internal = __dispatch_internal_32;
  644. - internal_irq_mask = __internal_irq_mask_32;
  645. - internal_irq_unmask = __internal_irq_unmask_32;
  646. - } else {
  647. - dispatch_internal = __dispatch_internal_64;
  648. - internal_irq_mask = __internal_irq_mask_64;
  649. - internal_irq_unmask = __internal_irq_unmask_64;
  650. - }
  651. -}
  652. -
  653. -void __init arch_init_irq(void)
  654. -{
  655. - int i;
  656. -
  657. - bcm63xx_init_irq();
  658. mips_cpu_irq_init();
  659. - for (i = IRQ_INTERNAL_BASE; i < NR_IRQS; ++i)
  660. - irq_set_chip_and_handler(i, &bcm63xx_internal_irq_chip,
  661. - handle_level_irq);
  662. -
  663. - for (i = IRQ_EXTERNAL_BASE; i < IRQ_EXTERNAL_BASE + ext_irq_count; ++i)
  664. - irq_set_chip_and_handler(i, &bcm63xx_external_irq_chip,
  665. - handle_edge_irq);
  666. -
  667. - if (!is_ext_irq_cascaded) {
  668. - for (i = 3; i < 3 + ext_irq_count; ++i)
  669. - setup_irq(MIPS_CPU_IRQ_BASE + i, &cpu_ext_cascade_action);
  670. - }
  671. -
  672. - setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action);
  673. -#ifdef CONFIG_SMP
  674. - if (is_ext_irq_cascaded) {
  675. - setup_irq(MIPS_CPU_IRQ_BASE + 3, &cpu_ip3_cascade_action);
  676. - bcm63xx_internal_irq_chip.irq_set_affinity =
  677. - bcm63xx_internal_set_affinity;
  678. -
  679. - cpumask_clear(irq_default_affinity);
  680. - cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
  681. - }
  682. -#endif
  683. + bcm6345_periph_intc_init(periph_irq_count, periph_irqs, periph_bases,
  684. + periph_width);
  685. + bcm6345_ext_intc_init(4, ext_irqs, ext_intc_bases[0], ext_shift);
  686. + if (ext_irq_count > 4)
  687. + bcm6345_ext_intc_init(2, &ext_irqs[4], ext_intc_bases[1],
  688. + ext_shift);
  689. }