irq-gt641xx.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * GT641xx IRQ routines.
  4. *
  5. * Copyright (C) 2007 Yoichi Yuasa <[email protected]>
  6. */
  7. #include <linux/hardirq.h>
  8. #include <linux/init.h>
  9. #include <linux/irq.h>
  10. #include <linux/spinlock.h>
  11. #include <linux/types.h>
  12. #include <asm/gt64120.h>
  13. #define GT641XX_IRQ_TO_BIT(irq) (1U << (irq - GT641XX_IRQ_BASE))
  14. static DEFINE_RAW_SPINLOCK(gt641xx_irq_lock);
  15. static void ack_gt641xx_irq(struct irq_data *d)
  16. {
  17. unsigned long flags;
  18. u32 cause;
  19. raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
  20. cause = GT_READ(GT_INTRCAUSE_OFS);
  21. cause &= ~GT641XX_IRQ_TO_BIT(d->irq);
  22. GT_WRITE(GT_INTRCAUSE_OFS, cause);
  23. raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
  24. }
  25. static void mask_gt641xx_irq(struct irq_data *d)
  26. {
  27. unsigned long flags;
  28. u32 mask;
  29. raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
  30. mask = GT_READ(GT_INTRMASK_OFS);
  31. mask &= ~GT641XX_IRQ_TO_BIT(d->irq);
  32. GT_WRITE(GT_INTRMASK_OFS, mask);
  33. raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
  34. }
  35. static void mask_ack_gt641xx_irq(struct irq_data *d)
  36. {
  37. unsigned long flags;
  38. u32 cause, mask;
  39. raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
  40. mask = GT_READ(GT_INTRMASK_OFS);
  41. mask &= ~GT641XX_IRQ_TO_BIT(d->irq);
  42. GT_WRITE(GT_INTRMASK_OFS, mask);
  43. cause = GT_READ(GT_INTRCAUSE_OFS);
  44. cause &= ~GT641XX_IRQ_TO_BIT(d->irq);
  45. GT_WRITE(GT_INTRCAUSE_OFS, cause);
  46. raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
  47. }
  48. static void unmask_gt641xx_irq(struct irq_data *d)
  49. {
  50. unsigned long flags;
  51. u32 mask;
  52. raw_spin_lock_irqsave(&gt641xx_irq_lock, flags);
  53. mask = GT_READ(GT_INTRMASK_OFS);
  54. mask |= GT641XX_IRQ_TO_BIT(d->irq);
  55. GT_WRITE(GT_INTRMASK_OFS, mask);
  56. raw_spin_unlock_irqrestore(&gt641xx_irq_lock, flags);
  57. }
  58. static struct irq_chip gt641xx_irq_chip = {
  59. .name = "GT641xx",
  60. .irq_ack = ack_gt641xx_irq,
  61. .irq_mask = mask_gt641xx_irq,
  62. .irq_mask_ack = mask_ack_gt641xx_irq,
  63. .irq_unmask = unmask_gt641xx_irq,
  64. };
  65. void gt641xx_irq_dispatch(void)
  66. {
  67. u32 cause, mask;
  68. int i;
  69. cause = GT_READ(GT_INTRCAUSE_OFS);
  70. mask = GT_READ(GT_INTRMASK_OFS);
  71. cause &= mask;
  72. /*
  73. * bit0 : logical or of all the interrupt bits.
  74. * bit30: logical or of bits[29:26,20:1].
  75. * bit31: logical or of bits[25:1].
  76. */
  77. for (i = 1; i < 30; i++) {
  78. if (cause & (1U << i)) {
  79. do_IRQ(GT641XX_IRQ_BASE + i);
  80. return;
  81. }
  82. }
  83. atomic_inc(&irq_err_count);
  84. }
  85. void __init gt641xx_irq_init(void)
  86. {
  87. int i;
  88. GT_WRITE(GT_INTRMASK_OFS, 0);
  89. GT_WRITE(GT_INTRCAUSE_OFS, 0);
  90. /*
  91. * bit0 : logical or of all the interrupt bits.
  92. * bit30: logical or of bits[29:26,20:1].
  93. * bit31: logical or of bits[25:1].
  94. */
  95. for (i = 1; i < 30; i++)
  96. irq_set_chip_and_handler(GT641XX_IRQ_BASE + i,
  97. &gt641xx_irq_chip, handle_level_irq);
  98. }