irq-ath79-misc.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Atheros AR71xx/AR724x/AR913x MISC interrupt controller
  4. *
  5. * Copyright (C) 2015 Alban Bedel <albeu@free.fr>
  6. * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
  7. * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
  8. * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
  9. *
  10. * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
  11. */
  12. #include <linux/irqchip.h>
  13. #include <linux/irqchip/chained_irq.h>
  14. #include <linux/of_address.h>
  15. #include <linux/of_irq.h>
  16. #include <asm/time.h>
  17. #define AR71XX_RESET_REG_MISC_INT_STATUS 0
  18. #define AR71XX_RESET_REG_MISC_INT_ENABLE 4
  19. #define ATH79_MISC_IRQ_COUNT 32
  20. #define ATH79_MISC_PERF_IRQ 5
  21. static int ath79_perfcount_irq;
  22. int get_c0_perfcount_int(void)
  23. {
  24. return ath79_perfcount_irq;
  25. }
  26. EXPORT_SYMBOL_GPL(get_c0_perfcount_int);
  27. static void ath79_misc_irq_handler(struct irq_desc *desc)
  28. {
  29. struct irq_domain *domain = irq_desc_get_handler_data(desc);
  30. struct irq_chip *chip = irq_desc_get_chip(desc);
  31. void __iomem *base = domain->host_data;
  32. u32 pending;
  33. chained_irq_enter(chip, desc);
  34. pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
  35. __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  36. if (!pending) {
  37. spurious_interrupt();
  38. chained_irq_exit(chip, desc);
  39. return;
  40. }
  41. while (pending) {
  42. int bit = __ffs(pending);
  43. generic_handle_domain_irq(domain, bit);
  44. pending &= ~BIT(bit);
  45. }
  46. chained_irq_exit(chip, desc);
  47. }
  48. static void ar71xx_misc_irq_unmask(struct irq_data *d)
  49. {
  50. void __iomem *base = irq_data_get_irq_chip_data(d);
  51. unsigned int irq = d->hwirq;
  52. u32 t;
  53. t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  54. __raw_writel(t | BIT(irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  55. /* flush write */
  56. __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  57. }
  58. static void ar71xx_misc_irq_mask(struct irq_data *d)
  59. {
  60. void __iomem *base = irq_data_get_irq_chip_data(d);
  61. unsigned int irq = d->hwirq;
  62. u32 t;
  63. t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  64. __raw_writel(t & ~BIT(irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  65. /* flush write */
  66. __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  67. }
  68. static void ar724x_misc_irq_ack(struct irq_data *d)
  69. {
  70. void __iomem *base = irq_data_get_irq_chip_data(d);
  71. unsigned int irq = d->hwirq;
  72. u32 t;
  73. t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
  74. __raw_writel(t & ~BIT(irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
  75. /* flush write */
  76. __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
  77. }
  78. static struct irq_chip ath79_misc_irq_chip = {
  79. .name = "MISC",
  80. .irq_unmask = ar71xx_misc_irq_unmask,
  81. .irq_mask = ar71xx_misc_irq_mask,
  82. };
  83. static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
  84. {
  85. irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq);
  86. irq_set_chip_data(irq, d->host_data);
  87. return 0;
  88. }
  89. static const struct irq_domain_ops misc_irq_domain_ops = {
  90. .xlate = irq_domain_xlate_onecell,
  91. .map = misc_map,
  92. };
  93. static void __init ath79_misc_intc_domain_init(
  94. struct irq_domain *domain, int irq)
  95. {
  96. void __iomem *base = domain->host_data;
  97. ath79_perfcount_irq = irq_create_mapping(domain, ATH79_MISC_PERF_IRQ);
  98. /* Disable and clear all interrupts */
  99. __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
  100. __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
  101. irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain);
  102. }
  103. static int __init ath79_misc_intc_of_init(
  104. struct device_node *node, struct device_node *parent)
  105. {
  106. struct irq_domain *domain;
  107. void __iomem *base;
  108. int irq;
  109. irq = irq_of_parse_and_map(node, 0);
  110. if (!irq) {
  111. pr_err("Failed to get MISC IRQ\n");
  112. return -EINVAL;
  113. }
  114. base = of_iomap(node, 0);
  115. if (!base) {
  116. pr_err("Failed to get MISC IRQ registers\n");
  117. return -ENOMEM;
  118. }
  119. domain = irq_domain_create_linear(of_fwnode_handle(node), ATH79_MISC_IRQ_COUNT,
  120. &misc_irq_domain_ops, base);
  121. if (!domain) {
  122. pr_err("Failed to add MISC irqdomain\n");
  123. return -EINVAL;
  124. }
  125. ath79_misc_intc_domain_init(domain, irq);
  126. return 0;
  127. }
  128. static int __init ar7100_misc_intc_of_init(
  129. struct device_node *node, struct device_node *parent)
  130. {
  131. ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
  132. return ath79_misc_intc_of_init(node, parent);
  133. }
  134. IRQCHIP_DECLARE(ar7100_misc_intc, "qca,ar7100-misc-intc",
  135. ar7100_misc_intc_of_init);
  136. static int __init ar7240_misc_intc_of_init(
  137. struct device_node *node, struct device_node *parent)
  138. {
  139. ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
  140. return ath79_misc_intc_of_init(node, parent);
  141. }
  142. IRQCHIP_DECLARE(ar7240_misc_intc, "qca,ar7240-misc-intc",
  143. ar7240_misc_intc_of_init);