0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/interrupt.h>
0016 #include <linux/irqdomain.h>
0017 #include <linux/irq.h>
0018 #include <linux/irqchip.h>
0019 #include <linux/of.h>
0020
0021 unsigned int cached_irq_mask;
0022
0023
0024
0025
0026
0027
0028
0029 static int xtensa_pic_irq_domain_xlate(struct irq_domain *d,
0030 struct device_node *ctrlr,
0031 const u32 *intspec, unsigned int intsize,
0032 unsigned long *out_hwirq, unsigned int *out_type)
0033 {
0034 return xtensa_irq_domain_xlate(intspec, intsize,
0035 intspec[0], intspec[0],
0036 out_hwirq, out_type);
0037 }
0038
0039 static const struct irq_domain_ops xtensa_irq_domain_ops = {
0040 .xlate = xtensa_pic_irq_domain_xlate,
0041 .map = xtensa_irq_map,
0042 };
0043
0044 static void xtensa_irq_mask(struct irq_data *d)
0045 {
0046 cached_irq_mask &= ~(1 << d->hwirq);
0047 xtensa_set_sr(cached_irq_mask, intenable);
0048 }
0049
0050 static void xtensa_irq_unmask(struct irq_data *d)
0051 {
0052 cached_irq_mask |= 1 << d->hwirq;
0053 xtensa_set_sr(cached_irq_mask, intenable);
0054 }
0055
0056 static void xtensa_irq_enable(struct irq_data *d)
0057 {
0058 xtensa_irq_unmask(d);
0059 }
0060
0061 static void xtensa_irq_disable(struct irq_data *d)
0062 {
0063 xtensa_irq_mask(d);
0064 }
0065
0066 static void xtensa_irq_ack(struct irq_data *d)
0067 {
0068 xtensa_set_sr(1 << d->hwirq, intclear);
0069 }
0070
0071 static int xtensa_irq_retrigger(struct irq_data *d)
0072 {
0073 unsigned int mask = 1u << d->hwirq;
0074
0075 if (WARN_ON(mask & ~XCHAL_INTTYPE_MASK_SOFTWARE))
0076 return 0;
0077 xtensa_set_sr(mask, intset);
0078 return 1;
0079 }
0080
0081 static struct irq_chip xtensa_irq_chip = {
0082 .name = "xtensa",
0083 .irq_enable = xtensa_irq_enable,
0084 .irq_disable = xtensa_irq_disable,
0085 .irq_mask = xtensa_irq_mask,
0086 .irq_unmask = xtensa_irq_unmask,
0087 .irq_ack = xtensa_irq_ack,
0088 .irq_retrigger = xtensa_irq_retrigger,
0089 };
0090
0091 int __init xtensa_pic_init_legacy(struct device_node *interrupt_parent)
0092 {
0093 struct irq_domain *root_domain =
0094 irq_domain_add_legacy(NULL, NR_IRQS - 1, 1, 0,
0095 &xtensa_irq_domain_ops, &xtensa_irq_chip);
0096 irq_set_default_host(root_domain);
0097 return 0;
0098 }
0099
0100 static int __init xtensa_pic_init(struct device_node *np,
0101 struct device_node *interrupt_parent)
0102 {
0103 struct irq_domain *root_domain =
0104 irq_domain_add_linear(np, NR_IRQS, &xtensa_irq_domain_ops,
0105 &xtensa_irq_chip);
0106 irq_set_default_host(root_domain);
0107 return 0;
0108 }
0109 IRQCHIP_DECLARE(xtensa_irq_chip, "cdns,xtensa-pic", xtensa_pic_init);