gpio-idt3243x.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Driver for IDT/Renesas 79RC3243x Interrupt Controller */
  3. #include <linux/bitops.h>
  4. #include <linux/gpio/driver.h>
  5. #include <linux/irq.h>
  6. #include <linux/module.h>
  7. #include <linux/mod_devicetable.h>
  8. #include <linux/platform_device.h>
  9. #include <linux/spinlock.h>
  10. #define IDT_PIC_IRQ_PEND 0x00
  11. #define IDT_PIC_IRQ_MASK 0x08
  12. #define IDT_GPIO_DIR 0x00
  13. #define IDT_GPIO_DATA 0x04
  14. #define IDT_GPIO_ILEVEL 0x08
  15. #define IDT_GPIO_ISTAT 0x0C
  16. struct idt_gpio_ctrl {
  17. struct gpio_chip gc;
  18. void __iomem *pic;
  19. void __iomem *gpio;
  20. u32 mask_cache;
  21. };
  22. static void idt_gpio_dispatch(struct irq_desc *desc)
  23. {
  24. struct gpio_chip *gc = irq_desc_get_handler_data(desc);
  25. struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
  26. struct irq_chip *host_chip = irq_desc_get_chip(desc);
  27. unsigned int bit, virq;
  28. unsigned long pending;
  29. chained_irq_enter(host_chip, desc);
  30. pending = readl(ctrl->pic + IDT_PIC_IRQ_PEND);
  31. pending &= ~ctrl->mask_cache;
  32. for_each_set_bit(bit, &pending, gc->ngpio) {
  33. virq = irq_linear_revmap(gc->irq.domain, bit);
  34. if (virq)
  35. generic_handle_irq(virq);
  36. }
  37. chained_irq_exit(host_chip, desc);
  38. }
  39. static int idt_gpio_irq_set_type(struct irq_data *d, unsigned int flow_type)
  40. {
  41. struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
  42. struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
  43. unsigned int sense = flow_type & IRQ_TYPE_SENSE_MASK;
  44. unsigned long flags;
  45. u32 ilevel;
  46. /* hardware only supports level triggered */
  47. if (sense == IRQ_TYPE_NONE || (sense & IRQ_TYPE_EDGE_BOTH))
  48. return -EINVAL;
  49. raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
  50. ilevel = readl(ctrl->gpio + IDT_GPIO_ILEVEL);
  51. if (sense & IRQ_TYPE_LEVEL_HIGH)
  52. ilevel |= BIT(d->hwirq);
  53. else if (sense & IRQ_TYPE_LEVEL_LOW)
  54. ilevel &= ~BIT(d->hwirq);
  55. writel(ilevel, ctrl->gpio + IDT_GPIO_ILEVEL);
  56. irq_set_handler_locked(d, handle_level_irq);
  57. raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
  58. return 0;
  59. }
  60. static void idt_gpio_ack(struct irq_data *d)
  61. {
  62. struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
  63. struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
  64. writel(~BIT(d->hwirq), ctrl->gpio + IDT_GPIO_ISTAT);
  65. }
  66. static void idt_gpio_mask(struct irq_data *d)
  67. {
  68. struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
  69. struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
  70. unsigned long flags;
  71. raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
  72. ctrl->mask_cache |= BIT(d->hwirq);
  73. writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
  74. raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
  75. }
  76. static void idt_gpio_unmask(struct irq_data *d)
  77. {
  78. struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
  79. struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
  80. unsigned long flags;
  81. raw_spin_lock_irqsave(&gc->bgpio_lock, flags);
  82. ctrl->mask_cache &= ~BIT(d->hwirq);
  83. writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
  84. raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags);
  85. }
  86. static int idt_gpio_irq_init_hw(struct gpio_chip *gc)
  87. {
  88. struct idt_gpio_ctrl *ctrl = gpiochip_get_data(gc);
  89. /* Mask interrupts. */
  90. ctrl->mask_cache = 0xffffffff;
  91. writel(ctrl->mask_cache, ctrl->pic + IDT_PIC_IRQ_MASK);
  92. return 0;
  93. }
  94. static struct irq_chip idt_gpio_irqchip = {
  95. .name = "IDTGPIO",
  96. .irq_mask = idt_gpio_mask,
  97. .irq_ack = idt_gpio_ack,
  98. .irq_unmask = idt_gpio_unmask,
  99. .irq_set_type = idt_gpio_irq_set_type
  100. };
  101. static int idt_gpio_probe(struct platform_device *pdev)
  102. {
  103. struct device *dev = &pdev->dev;
  104. struct gpio_irq_chip *girq;
  105. struct idt_gpio_ctrl *ctrl;
  106. int parent_irq;
  107. int ngpios;
  108. int ret;
  109. ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
  110. if (!ctrl)
  111. return -ENOMEM;
  112. ctrl->gpio = devm_platform_ioremap_resource_byname(pdev, "gpio");
  113. if (IS_ERR(ctrl->gpio))
  114. return PTR_ERR(ctrl->gpio);
  115. ctrl->gc.parent = dev;
  116. ret = bgpio_init(&ctrl->gc, &pdev->dev, 4, ctrl->gpio + IDT_GPIO_DATA,
  117. NULL, NULL, ctrl->gpio + IDT_GPIO_DIR, NULL, 0);
  118. if (ret) {
  119. dev_err(dev, "bgpio_init failed\n");
  120. return ret;
  121. }
  122. ret = device_property_read_u32(dev, "ngpios", &ngpios);
  123. if (!ret)
  124. ctrl->gc.ngpio = ngpios;
  125. if (device_property_read_bool(dev, "interrupt-controller")) {
  126. ctrl->pic = devm_platform_ioremap_resource_byname(pdev, "pic");
  127. if (IS_ERR(ctrl->pic))
  128. return PTR_ERR(ctrl->pic);
  129. parent_irq = platform_get_irq(pdev, 0);
  130. if (parent_irq < 0)
  131. return parent_irq;
  132. girq = &ctrl->gc.irq;
  133. girq->chip = &idt_gpio_irqchip;
  134. girq->init_hw = idt_gpio_irq_init_hw;
  135. girq->parent_handler = idt_gpio_dispatch;
  136. girq->num_parents = 1;
  137. girq->parents = devm_kcalloc(dev, girq->num_parents,
  138. sizeof(*girq->parents),
  139. GFP_KERNEL);
  140. if (!girq->parents)
  141. return -ENOMEM;
  142. girq->parents[0] = parent_irq;
  143. girq->default_type = IRQ_TYPE_NONE;
  144. girq->handler = handle_bad_irq;
  145. }
  146. return devm_gpiochip_add_data(&pdev->dev, &ctrl->gc, ctrl);
  147. }
  148. static const struct of_device_id idt_gpio_of_match[] = {
  149. { .compatible = "idt,32434-gpio" },
  150. { }
  151. };
  152. MODULE_DEVICE_TABLE(of, idt_gpio_of_match);
  153. static struct platform_driver idt_gpio_driver = {
  154. .probe = idt_gpio_probe,
  155. .driver = {
  156. .name = "idt3243x-gpio",
  157. .of_match_table = idt_gpio_of_match,
  158. },
  159. };
  160. module_platform_driver(idt_gpio_driver);
  161. MODULE_DESCRIPTION("IDT 79RC3243x GPIO/PIC Driver");
  162. MODULE_AUTHOR("Thomas Bogendoerfer <[email protected]>");
  163. MODULE_LICENSE("GPL");