004-extended_irq_controller.patch 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. From a729672f117df3602b6d3171d8ab7a84bf53b053 Mon Sep 17 00:00:00 2001
  2. From: Daniel Hellstrom <[email protected]>
  3. Date: Thu, 16 Sep 2010 11:12:41 +0200
  4. Subject: [PATCH] SPARC/LEON: added support for Extended IRQ controller, partial patches are already in git tree.
  5. Signed-off-by: Daniel Hellstrom <[email protected]>
  6. ---
  7. arch/sparc/include/asm/irq_32.h | 4 ++++
  8. arch/sparc/kernel/irq_32.c | 32 ++++++++++++++++++++++++++------
  9. arch/sparc/kernel/leon_kernel.c | 8 +++++++-
  10. 3 files changed, 37 insertions(+), 7 deletions(-)
  11. --- a/arch/sparc/include/asm/irq_32.h
  12. +++ b/arch/sparc/include/asm/irq_32.h
  13. @@ -6,7 +6,11 @@
  14. #ifndef _SPARC_IRQ_H
  15. #define _SPARC_IRQ_H
  16. +#ifdef CONFIG_SPARC_LEON
  17. +#define NR_IRQS 32
  18. +#else
  19. #define NR_IRQS 16
  20. +#endif
  21. #include <linux/interrupt.h>
  22. --- a/arch/sparc/kernel/irq_32.c
  23. +++ b/arch/sparc/kernel/irq_32.c
  24. @@ -110,6 +110,11 @@ EXPORT_SYMBOL(__raw_local_irq_save);
  25. EXPORT_SYMBOL(raw_local_irq_enable);
  26. EXPORT_SYMBOL(raw_local_irq_restore);
  27. +#ifdef CONFIG_SPARC_LEON
  28. +extern unsigned int sparc_leon_eirq;
  29. +extern int sparc_leon_eirq_get(int eirq, int cpu);
  30. +#endif
  31. +
  32. /*
  33. * Dave Redman ([email protected])
  34. *
  35. @@ -222,10 +227,11 @@ void free_irq(unsigned int irq, void *de
  36. return;
  37. }
  38. cpu_irq = irq & (NR_IRQS - 1);
  39. - if (cpu_irq > 14) { /* 14 irq levels on the sparc */
  40. - printk("Trying to free bogus IRQ %d\n", irq);
  41. - return;
  42. - }
  43. + /* 14 irq levels on the sparc, however some LEON systems have 31 IRQs */
  44. + if ((cpu_irq == 15) || (cpu_irq >= NR_IRQS)) {
  45. + printk("Trying to free bogus IRQ %d\n", irq);
  46. + return;
  47. + }
  48. spin_lock_irqsave(&irq_action_lock, flags);
  49. @@ -303,7 +309,14 @@ void unexpected_irq(int irq, void *dev_i
  50. int i;
  51. struct irqaction * action;
  52. unsigned int cpu_irq;
  53. -
  54. +
  55. +#ifdef CONFIG_SPARC_LEON
  56. + /* LEON Extended IRQ requires one extra IRQ Number fetch stage */
  57. + if ( sparc_leon_eirq == irq ) {
  58. + irq = sparc_leon_eirq_get(irq, smp_processor_id());
  59. + }
  60. +#endif
  61. +
  62. cpu_irq = irq & (NR_IRQS - 1);
  63. action = sparc_irq[cpu_irq].action;
  64. @@ -330,6 +343,13 @@ void handler_irq(int irq, struct pt_regs
  65. extern void smp4m_irq_rotate(int cpu);
  66. #endif
  67. +#ifdef CONFIG_SPARC_LEON
  68. + /* LEON Extended IRQ requires one extra IRQ Number fetch stage */
  69. + if ( sparc_leon_eirq == irq ) {
  70. + irq = sparc_leon_eirq_get(irq, cpu);
  71. + }
  72. +#endif
  73. +
  74. old_regs = set_irq_regs(regs);
  75. irq_enter();
  76. disable_pil_irq(irq);
  77. @@ -526,7 +546,7 @@ int request_irq(unsigned int irq,
  78. return sun4d_request_irq(irq, handler, irqflags, devname, dev_id);
  79. }
  80. cpu_irq = irq & (NR_IRQS - 1);
  81. - if(cpu_irq > 14) {
  82. + if(cpu_irq == 15) {
  83. ret = -EINVAL;
  84. goto out;
  85. }
  86. --- a/arch/sparc/kernel/leon_kernel.c
  87. +++ b/arch/sparc/kernel/leon_kernel.c
  88. @@ -104,7 +104,7 @@ static void leon_disable_irq(unsigned in
  89. void __init leon_init_timers(irq_handler_t counter_fn)
  90. {
  91. - int irq;
  92. + int irq, eirq;
  93. struct device_node *rootnp, *np;
  94. struct property *pp;
  95. int len;
  96. @@ -153,6 +153,12 @@ void __init leon_init_timers(irq_handler
  97. LEON3_BYPASS_STORE_PA(&leon3_gptimer_regs->e[1].ctrl, 0);
  98. # endif
  99. + LEON3_BYPASS_STORE_PA(&(leon3_irqctrl_regs->mask[0]), 0);
  100. + eirq = (LEON3_BYPASS_LOAD_PA(&leon3_irqctrl_regs->mpstatus) >> 16) & 0xf;
  101. + if ( eirq != 0 ) {
  102. + /* Extended IRQ controller available */
  103. + sparc_leon_eirq_register(eirq);
  104. + }
  105. } else {
  106. printk(KERN_ERR "No Timer/irqctrl found\n");
  107. BUG();