0001
0002
0003
0004
0005
0006 #include <linux/irq.h>
0007 #include <linux/of_address.h>
0008 #include <linux/of_irq.h>
0009 #include <linux/of_platform.h>
0010 #include <linux/io.h>
0011
0012
0013
0014
0015
0016
0017
0018 #define SOCRATES_FPGA_NUM_IRQS 9
0019
0020 #define FPGA_PIC_IRQCFG (0x0)
0021 #define FPGA_PIC_IRQMASK(n) (0x4 + 0x4 * (n))
0022
0023 #define SOCRATES_FPGA_IRQ_MASK ((1 << SOCRATES_FPGA_NUM_IRQS) - 1)
0024
0025 struct socrates_fpga_irq_info {
0026 unsigned int irq_line;
0027 int type;
0028 };
0029
0030
0031
0032
0033
0034
0035
0036 static struct socrates_fpga_irq_info fpga_irqs[SOCRATES_FPGA_NUM_IRQS] = {
0037 [0] = {0, IRQ_TYPE_NONE},
0038 [1] = {0, IRQ_TYPE_LEVEL_HIGH},
0039 [2] = {0, IRQ_TYPE_LEVEL_LOW},
0040 [3] = {0, IRQ_TYPE_NONE},
0041 [4] = {0, IRQ_TYPE_NONE},
0042 [5] = {0, IRQ_TYPE_NONE},
0043 [6] = {0, IRQ_TYPE_NONE},
0044 [7] = {0, IRQ_TYPE_NONE},
0045 [8] = {0, IRQ_TYPE_LEVEL_HIGH},
0046 };
0047
0048 static DEFINE_RAW_SPINLOCK(socrates_fpga_pic_lock);
0049
0050 static void __iomem *socrates_fpga_pic_iobase;
0051 static struct irq_domain *socrates_fpga_pic_irq_host;
0052 static unsigned int socrates_fpga_irqs[3];
0053
0054 static inline uint32_t socrates_fpga_pic_read(int reg)
0055 {
0056 return in_be32(socrates_fpga_pic_iobase + reg);
0057 }
0058
0059 static inline void socrates_fpga_pic_write(int reg, uint32_t val)
0060 {
0061 out_be32(socrates_fpga_pic_iobase + reg, val);
0062 }
0063
0064 static inline unsigned int socrates_fpga_pic_get_irq(unsigned int irq)
0065 {
0066 uint32_t cause;
0067 unsigned long flags;
0068 int i;
0069
0070
0071 for (i = 0; i < 3; i++) {
0072 if (irq == socrates_fpga_irqs[i])
0073 break;
0074 }
0075 if (i == 3)
0076 return 0;
0077
0078 raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
0079 cause = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(i));
0080 raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
0081 for (i = SOCRATES_FPGA_NUM_IRQS - 1; i >= 0; i--) {
0082 if (cause >> (i + 16))
0083 break;
0084 }
0085 return irq_linear_revmap(socrates_fpga_pic_irq_host,
0086 (irq_hw_number_t)i);
0087 }
0088
0089 static void socrates_fpga_pic_cascade(struct irq_desc *desc)
0090 {
0091 struct irq_chip *chip = irq_desc_get_chip(desc);
0092 unsigned int irq = irq_desc_get_irq(desc);
0093 unsigned int cascade_irq;
0094
0095
0096
0097
0098
0099 cascade_irq = socrates_fpga_pic_get_irq(irq);
0100
0101 if (cascade_irq)
0102 generic_handle_irq(cascade_irq);
0103 chip->irq_eoi(&desc->irq_data);
0104 }
0105
0106 static void socrates_fpga_pic_ack(struct irq_data *d)
0107 {
0108 unsigned long flags;
0109 unsigned int irq_line, hwirq = irqd_to_hwirq(d);
0110 uint32_t mask;
0111
0112 irq_line = fpga_irqs[hwirq].irq_line;
0113 raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
0114 mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
0115 & SOCRATES_FPGA_IRQ_MASK;
0116 mask |= (1 << (hwirq + 16));
0117 socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
0118 raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
0119 }
0120
0121 static void socrates_fpga_pic_mask(struct irq_data *d)
0122 {
0123 unsigned long flags;
0124 unsigned int hwirq = irqd_to_hwirq(d);
0125 int irq_line;
0126 u32 mask;
0127
0128 irq_line = fpga_irqs[hwirq].irq_line;
0129 raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
0130 mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
0131 & SOCRATES_FPGA_IRQ_MASK;
0132 mask &= ~(1 << hwirq);
0133 socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
0134 raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
0135 }
0136
0137 static void socrates_fpga_pic_mask_ack(struct irq_data *d)
0138 {
0139 unsigned long flags;
0140 unsigned int hwirq = irqd_to_hwirq(d);
0141 int irq_line;
0142 u32 mask;
0143
0144 irq_line = fpga_irqs[hwirq].irq_line;
0145 raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
0146 mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
0147 & SOCRATES_FPGA_IRQ_MASK;
0148 mask &= ~(1 << hwirq);
0149 mask |= (1 << (hwirq + 16));
0150 socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
0151 raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
0152 }
0153
0154 static void socrates_fpga_pic_unmask(struct irq_data *d)
0155 {
0156 unsigned long flags;
0157 unsigned int hwirq = irqd_to_hwirq(d);
0158 int irq_line;
0159 u32 mask;
0160
0161 irq_line = fpga_irqs[hwirq].irq_line;
0162 raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
0163 mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
0164 & SOCRATES_FPGA_IRQ_MASK;
0165 mask |= (1 << hwirq);
0166 socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
0167 raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
0168 }
0169
0170 static void socrates_fpga_pic_eoi(struct irq_data *d)
0171 {
0172 unsigned long flags;
0173 unsigned int hwirq = irqd_to_hwirq(d);
0174 int irq_line;
0175 u32 mask;
0176
0177 irq_line = fpga_irqs[hwirq].irq_line;
0178 raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
0179 mask = socrates_fpga_pic_read(FPGA_PIC_IRQMASK(irq_line))
0180 & SOCRATES_FPGA_IRQ_MASK;
0181 mask |= (1 << (hwirq + 16));
0182 socrates_fpga_pic_write(FPGA_PIC_IRQMASK(irq_line), mask);
0183 raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
0184 }
0185
0186 static int socrates_fpga_pic_set_type(struct irq_data *d,
0187 unsigned int flow_type)
0188 {
0189 unsigned long flags;
0190 unsigned int hwirq = irqd_to_hwirq(d);
0191 int polarity;
0192 u32 mask;
0193
0194 if (fpga_irqs[hwirq].type != IRQ_TYPE_NONE)
0195 return -EINVAL;
0196
0197 switch (flow_type & IRQ_TYPE_SENSE_MASK) {
0198 case IRQ_TYPE_LEVEL_HIGH:
0199 polarity = 1;
0200 break;
0201 case IRQ_TYPE_LEVEL_LOW:
0202 polarity = 0;
0203 break;
0204 default:
0205 return -EINVAL;
0206 }
0207 raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
0208 mask = socrates_fpga_pic_read(FPGA_PIC_IRQCFG);
0209 if (polarity)
0210 mask |= (1 << hwirq);
0211 else
0212 mask &= ~(1 << hwirq);
0213 socrates_fpga_pic_write(FPGA_PIC_IRQCFG, mask);
0214 raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
0215 return 0;
0216 }
0217
0218 static struct irq_chip socrates_fpga_pic_chip = {
0219 .name = "FPGA-PIC",
0220 .irq_ack = socrates_fpga_pic_ack,
0221 .irq_mask = socrates_fpga_pic_mask,
0222 .irq_mask_ack = socrates_fpga_pic_mask_ack,
0223 .irq_unmask = socrates_fpga_pic_unmask,
0224 .irq_eoi = socrates_fpga_pic_eoi,
0225 .irq_set_type = socrates_fpga_pic_set_type,
0226 };
0227
0228 static int socrates_fpga_pic_host_map(struct irq_domain *h, unsigned int virq,
0229 irq_hw_number_t hwirq)
0230 {
0231
0232 irq_set_status_flags(virq, IRQ_LEVEL);
0233 irq_set_chip_and_handler(virq, &socrates_fpga_pic_chip,
0234 handle_fasteoi_irq);
0235
0236 return 0;
0237 }
0238
0239 static int socrates_fpga_pic_host_xlate(struct irq_domain *h,
0240 struct device_node *ct, const u32 *intspec, unsigned int intsize,
0241 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
0242 {
0243 struct socrates_fpga_irq_info *fpga_irq = &fpga_irqs[intspec[0]];
0244
0245 *out_hwirq = intspec[0];
0246 if (fpga_irq->type == IRQ_TYPE_NONE) {
0247
0248 if (intspec[1] != IRQ_TYPE_LEVEL_LOW &&
0249 intspec[1] != IRQ_TYPE_LEVEL_HIGH) {
0250 pr_warn("FPGA PIC: invalid irq type, setting default active low\n");
0251 *out_flags = IRQ_TYPE_LEVEL_LOW;
0252 } else {
0253 *out_flags = intspec[1];
0254 }
0255 } else {
0256
0257 *out_flags = fpga_irq->type;
0258 }
0259
0260
0261 if (intspec[2] <= 2)
0262 fpga_irq->irq_line = intspec[2];
0263 else
0264 pr_warn("FPGA PIC: invalid irq routing\n");
0265
0266 return 0;
0267 }
0268
0269 static const struct irq_domain_ops socrates_fpga_pic_host_ops = {
0270 .map = socrates_fpga_pic_host_map,
0271 .xlate = socrates_fpga_pic_host_xlate,
0272 };
0273
0274 void __init socrates_fpga_pic_init(struct device_node *pic)
0275 {
0276 unsigned long flags;
0277 int i;
0278
0279
0280 socrates_fpga_pic_irq_host = irq_domain_add_linear(pic,
0281 SOCRATES_FPGA_NUM_IRQS, &socrates_fpga_pic_host_ops, NULL);
0282 if (socrates_fpga_pic_irq_host == NULL) {
0283 pr_err("FPGA PIC: Unable to allocate host\n");
0284 return;
0285 }
0286
0287 for (i = 0; i < 3; i++) {
0288 socrates_fpga_irqs[i] = irq_of_parse_and_map(pic, i);
0289 if (!socrates_fpga_irqs[i]) {
0290 pr_warn("FPGA PIC: can't get irq%d\n", i);
0291 continue;
0292 }
0293 irq_set_chained_handler(socrates_fpga_irqs[i],
0294 socrates_fpga_pic_cascade);
0295 }
0296
0297 socrates_fpga_pic_iobase = of_iomap(pic, 0);
0298
0299 raw_spin_lock_irqsave(&socrates_fpga_pic_lock, flags);
0300 socrates_fpga_pic_write(FPGA_PIC_IRQMASK(0),
0301 SOCRATES_FPGA_IRQ_MASK << 16);
0302 socrates_fpga_pic_write(FPGA_PIC_IRQMASK(1),
0303 SOCRATES_FPGA_IRQ_MASK << 16);
0304 socrates_fpga_pic_write(FPGA_PIC_IRQMASK(2),
0305 SOCRATES_FPGA_IRQ_MASK << 16);
0306 raw_spin_unlock_irqrestore(&socrates_fpga_pic_lock, flags);
0307
0308 pr_info("FPGA PIC: Setting up Socrates FPGA PIC\n");
0309 }