0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <linux/of_irq.h>
0014 #include <linux/of_address.h>
0015 #include <linux/kernel.h>
0016 #include <linux/init.h>
0017 #include <linux/errno.h>
0018 #include <linux/irq.h>
0019 #include <linux/reboot.h>
0020 #include <linux/slab.h>
0021 #include <linux/stddef.h>
0022 #include <linux/sched.h>
0023 #include <linux/signal.h>
0024 #include <linux/device.h>
0025 #include <linux/spinlock.h>
0026 #include <linux/platform_device.h>
0027 #include <asm/irq.h>
0028 #include <asm/io.h>
0029 #include <soc/fsl/qe/qe.h>
0030
0031 #define NR_QE_IC_INTS 64
0032
0033
0034 #define QEIC_CICR 0x00
0035 #define QEIC_CIVEC 0x04
0036 #define QEIC_CIPXCC 0x10
0037 #define QEIC_CIPYCC 0x14
0038 #define QEIC_CIPWCC 0x18
0039 #define QEIC_CIPZCC 0x1c
0040 #define QEIC_CIMR 0x20
0041 #define QEIC_CRIMR 0x24
0042 #define QEIC_CIPRTA 0x30
0043 #define QEIC_CIPRTB 0x34
0044 #define QEIC_CHIVEC 0x60
0045
0046 struct qe_ic {
0047
0048 __be32 __iomem *regs;
0049
0050
0051 struct irq_domain *irqhost;
0052
0053
0054 struct irq_chip hc_irq;
0055
0056
0057 int virq_high;
0058 int virq_low;
0059 };
0060
0061
0062
0063
0064 struct qe_ic_info {
0065
0066 u32 mask;
0067
0068
0069 u32 mask_reg;
0070
0071
0072
0073
0074
0075 u8 pri_code;
0076
0077
0078 u32 pri_reg;
0079 };
0080
0081 static DEFINE_RAW_SPINLOCK(qe_ic_lock);
0082
0083 static struct qe_ic_info qe_ic_info[] = {
0084 [1] = {
0085 .mask = 0x00008000,
0086 .mask_reg = QEIC_CIMR,
0087 .pri_code = 0,
0088 .pri_reg = QEIC_CIPWCC,
0089 },
0090 [2] = {
0091 .mask = 0x00004000,
0092 .mask_reg = QEIC_CIMR,
0093 .pri_code = 1,
0094 .pri_reg = QEIC_CIPWCC,
0095 },
0096 [3] = {
0097 .mask = 0x00002000,
0098 .mask_reg = QEIC_CIMR,
0099 .pri_code = 2,
0100 .pri_reg = QEIC_CIPWCC,
0101 },
0102 [10] = {
0103 .mask = 0x00000040,
0104 .mask_reg = QEIC_CIMR,
0105 .pri_code = 1,
0106 .pri_reg = QEIC_CIPZCC,
0107 },
0108 [11] = {
0109 .mask = 0x00000020,
0110 .mask_reg = QEIC_CIMR,
0111 .pri_code = 2,
0112 .pri_reg = QEIC_CIPZCC,
0113 },
0114 [12] = {
0115 .mask = 0x00000010,
0116 .mask_reg = QEIC_CIMR,
0117 .pri_code = 3,
0118 .pri_reg = QEIC_CIPZCC,
0119 },
0120 [13] = {
0121 .mask = 0x00000008,
0122 .mask_reg = QEIC_CIMR,
0123 .pri_code = 4,
0124 .pri_reg = QEIC_CIPZCC,
0125 },
0126 [14] = {
0127 .mask = 0x00000004,
0128 .mask_reg = QEIC_CIMR,
0129 .pri_code = 5,
0130 .pri_reg = QEIC_CIPZCC,
0131 },
0132 [15] = {
0133 .mask = 0x00000002,
0134 .mask_reg = QEIC_CIMR,
0135 .pri_code = 6,
0136 .pri_reg = QEIC_CIPZCC,
0137 },
0138 [20] = {
0139 .mask = 0x10000000,
0140 .mask_reg = QEIC_CRIMR,
0141 .pri_code = 3,
0142 .pri_reg = QEIC_CIPRTA,
0143 },
0144 [25] = {
0145 .mask = 0x00800000,
0146 .mask_reg = QEIC_CRIMR,
0147 .pri_code = 0,
0148 .pri_reg = QEIC_CIPRTB,
0149 },
0150 [26] = {
0151 .mask = 0x00400000,
0152 .mask_reg = QEIC_CRIMR,
0153 .pri_code = 1,
0154 .pri_reg = QEIC_CIPRTB,
0155 },
0156 [27] = {
0157 .mask = 0x00200000,
0158 .mask_reg = QEIC_CRIMR,
0159 .pri_code = 2,
0160 .pri_reg = QEIC_CIPRTB,
0161 },
0162 [28] = {
0163 .mask = 0x00100000,
0164 .mask_reg = QEIC_CRIMR,
0165 .pri_code = 3,
0166 .pri_reg = QEIC_CIPRTB,
0167 },
0168 [32] = {
0169 .mask = 0x80000000,
0170 .mask_reg = QEIC_CIMR,
0171 .pri_code = 0,
0172 .pri_reg = QEIC_CIPXCC,
0173 },
0174 [33] = {
0175 .mask = 0x40000000,
0176 .mask_reg = QEIC_CIMR,
0177 .pri_code = 1,
0178 .pri_reg = QEIC_CIPXCC,
0179 },
0180 [34] = {
0181 .mask = 0x20000000,
0182 .mask_reg = QEIC_CIMR,
0183 .pri_code = 2,
0184 .pri_reg = QEIC_CIPXCC,
0185 },
0186 [35] = {
0187 .mask = 0x10000000,
0188 .mask_reg = QEIC_CIMR,
0189 .pri_code = 3,
0190 .pri_reg = QEIC_CIPXCC,
0191 },
0192 [36] = {
0193 .mask = 0x08000000,
0194 .mask_reg = QEIC_CIMR,
0195 .pri_code = 4,
0196 .pri_reg = QEIC_CIPXCC,
0197 },
0198 [40] = {
0199 .mask = 0x00800000,
0200 .mask_reg = QEIC_CIMR,
0201 .pri_code = 0,
0202 .pri_reg = QEIC_CIPYCC,
0203 },
0204 [41] = {
0205 .mask = 0x00400000,
0206 .mask_reg = QEIC_CIMR,
0207 .pri_code = 1,
0208 .pri_reg = QEIC_CIPYCC,
0209 },
0210 [42] = {
0211 .mask = 0x00200000,
0212 .mask_reg = QEIC_CIMR,
0213 .pri_code = 2,
0214 .pri_reg = QEIC_CIPYCC,
0215 },
0216 [43] = {
0217 .mask = 0x00100000,
0218 .mask_reg = QEIC_CIMR,
0219 .pri_code = 3,
0220 .pri_reg = QEIC_CIPYCC,
0221 },
0222 };
0223
0224 static inline u32 qe_ic_read(__be32 __iomem *base, unsigned int reg)
0225 {
0226 return ioread32be(base + (reg >> 2));
0227 }
0228
0229 static inline void qe_ic_write(__be32 __iomem *base, unsigned int reg,
0230 u32 value)
0231 {
0232 iowrite32be(value, base + (reg >> 2));
0233 }
0234
0235 static inline struct qe_ic *qe_ic_from_irq(unsigned int virq)
0236 {
0237 return irq_get_chip_data(virq);
0238 }
0239
0240 static inline struct qe_ic *qe_ic_from_irq_data(struct irq_data *d)
0241 {
0242 return irq_data_get_irq_chip_data(d);
0243 }
0244
0245 static void qe_ic_unmask_irq(struct irq_data *d)
0246 {
0247 struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
0248 unsigned int src = irqd_to_hwirq(d);
0249 unsigned long flags;
0250 u32 temp;
0251
0252 raw_spin_lock_irqsave(&qe_ic_lock, flags);
0253
0254 temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
0255 qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
0256 temp | qe_ic_info[src].mask);
0257
0258 raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
0259 }
0260
0261 static void qe_ic_mask_irq(struct irq_data *d)
0262 {
0263 struct qe_ic *qe_ic = qe_ic_from_irq_data(d);
0264 unsigned int src = irqd_to_hwirq(d);
0265 unsigned long flags;
0266 u32 temp;
0267
0268 raw_spin_lock_irqsave(&qe_ic_lock, flags);
0269
0270 temp = qe_ic_read(qe_ic->regs, qe_ic_info[src].mask_reg);
0271 qe_ic_write(qe_ic->regs, qe_ic_info[src].mask_reg,
0272 temp & ~qe_ic_info[src].mask);
0273
0274
0275
0276
0277
0278
0279
0280
0281
0282 mb();
0283
0284 raw_spin_unlock_irqrestore(&qe_ic_lock, flags);
0285 }
0286
0287 static struct irq_chip qe_ic_irq_chip = {
0288 .name = "QEIC",
0289 .irq_unmask = qe_ic_unmask_irq,
0290 .irq_mask = qe_ic_mask_irq,
0291 .irq_mask_ack = qe_ic_mask_irq,
0292 };
0293
0294 static int qe_ic_host_match(struct irq_domain *h, struct device_node *node,
0295 enum irq_domain_bus_token bus_token)
0296 {
0297
0298 struct device_node *of_node = irq_domain_get_of_node(h);
0299 return of_node == NULL || of_node == node;
0300 }
0301
0302 static int qe_ic_host_map(struct irq_domain *h, unsigned int virq,
0303 irq_hw_number_t hw)
0304 {
0305 struct qe_ic *qe_ic = h->host_data;
0306 struct irq_chip *chip;
0307
0308 if (hw >= ARRAY_SIZE(qe_ic_info)) {
0309 pr_err("%s: Invalid hw irq number for QEIC\n", __func__);
0310 return -EINVAL;
0311 }
0312
0313 if (qe_ic_info[hw].mask == 0) {
0314 printk(KERN_ERR "Can't map reserved IRQ\n");
0315 return -EINVAL;
0316 }
0317
0318 chip = &qe_ic->hc_irq;
0319
0320 irq_set_chip_data(virq, qe_ic);
0321 irq_set_status_flags(virq, IRQ_LEVEL);
0322
0323 irq_set_chip_and_handler(virq, chip, handle_level_irq);
0324
0325 return 0;
0326 }
0327
0328 static const struct irq_domain_ops qe_ic_host_ops = {
0329 .match = qe_ic_host_match,
0330 .map = qe_ic_host_map,
0331 .xlate = irq_domain_xlate_onetwocell,
0332 };
0333
0334
0335 static unsigned int qe_ic_get_low_irq(struct qe_ic *qe_ic)
0336 {
0337 int irq;
0338
0339 BUG_ON(qe_ic == NULL);
0340
0341
0342 irq = qe_ic_read(qe_ic->regs, QEIC_CIVEC) >> 26;
0343
0344 if (irq == 0)
0345 return 0;
0346
0347 return irq_linear_revmap(qe_ic->irqhost, irq);
0348 }
0349
0350
0351 static unsigned int qe_ic_get_high_irq(struct qe_ic *qe_ic)
0352 {
0353 int irq;
0354
0355 BUG_ON(qe_ic == NULL);
0356
0357
0358 irq = qe_ic_read(qe_ic->regs, QEIC_CHIVEC) >> 26;
0359
0360 if (irq == 0)
0361 return 0;
0362
0363 return irq_linear_revmap(qe_ic->irqhost, irq);
0364 }
0365
0366 static void qe_ic_cascade_low(struct irq_desc *desc)
0367 {
0368 struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
0369 unsigned int cascade_irq = qe_ic_get_low_irq(qe_ic);
0370 struct irq_chip *chip = irq_desc_get_chip(desc);
0371
0372 if (cascade_irq != 0)
0373 generic_handle_irq(cascade_irq);
0374
0375 if (chip->irq_eoi)
0376 chip->irq_eoi(&desc->irq_data);
0377 }
0378
0379 static void qe_ic_cascade_high(struct irq_desc *desc)
0380 {
0381 struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
0382 unsigned int cascade_irq = qe_ic_get_high_irq(qe_ic);
0383 struct irq_chip *chip = irq_desc_get_chip(desc);
0384
0385 if (cascade_irq != 0)
0386 generic_handle_irq(cascade_irq);
0387
0388 if (chip->irq_eoi)
0389 chip->irq_eoi(&desc->irq_data);
0390 }
0391
0392 static void qe_ic_cascade_muxed_mpic(struct irq_desc *desc)
0393 {
0394 struct qe_ic *qe_ic = irq_desc_get_handler_data(desc);
0395 unsigned int cascade_irq;
0396 struct irq_chip *chip = irq_desc_get_chip(desc);
0397
0398 cascade_irq = qe_ic_get_high_irq(qe_ic);
0399 if (cascade_irq == 0)
0400 cascade_irq = qe_ic_get_low_irq(qe_ic);
0401
0402 if (cascade_irq != 0)
0403 generic_handle_irq(cascade_irq);
0404
0405 chip->irq_eoi(&desc->irq_data);
0406 }
0407
0408 static int qe_ic_init(struct platform_device *pdev)
0409 {
0410 struct device *dev = &pdev->dev;
0411 void (*low_handler)(struct irq_desc *desc);
0412 void (*high_handler)(struct irq_desc *desc);
0413 struct qe_ic *qe_ic;
0414 struct resource *res;
0415 struct device_node *node = pdev->dev.of_node;
0416
0417 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0418 if (res == NULL) {
0419 dev_err(dev, "no memory resource defined\n");
0420 return -ENODEV;
0421 }
0422
0423 qe_ic = devm_kzalloc(dev, sizeof(*qe_ic), GFP_KERNEL);
0424 if (qe_ic == NULL)
0425 return -ENOMEM;
0426
0427 qe_ic->regs = devm_ioremap(dev, res->start, resource_size(res));
0428 if (qe_ic->regs == NULL) {
0429 dev_err(dev, "failed to ioremap() registers\n");
0430 return -ENODEV;
0431 }
0432
0433 qe_ic->hc_irq = qe_ic_irq_chip;
0434
0435 qe_ic->virq_high = platform_get_irq(pdev, 0);
0436 qe_ic->virq_low = platform_get_irq(pdev, 1);
0437
0438 if (qe_ic->virq_low <= 0)
0439 return -ENODEV;
0440
0441 if (qe_ic->virq_high > 0 && qe_ic->virq_high != qe_ic->virq_low) {
0442 low_handler = qe_ic_cascade_low;
0443 high_handler = qe_ic_cascade_high;
0444 } else {
0445 low_handler = qe_ic_cascade_muxed_mpic;
0446 high_handler = NULL;
0447 }
0448
0449 qe_ic->irqhost = irq_domain_add_linear(node, NR_QE_IC_INTS,
0450 &qe_ic_host_ops, qe_ic);
0451 if (qe_ic->irqhost == NULL) {
0452 dev_err(dev, "failed to add irq domain\n");
0453 return -ENODEV;
0454 }
0455
0456 qe_ic_write(qe_ic->regs, QEIC_CICR, 0);
0457
0458 irq_set_handler_data(qe_ic->virq_low, qe_ic);
0459 irq_set_chained_handler(qe_ic->virq_low, low_handler);
0460
0461 if (high_handler) {
0462 irq_set_handler_data(qe_ic->virq_high, qe_ic);
0463 irq_set_chained_handler(qe_ic->virq_high, high_handler);
0464 }
0465 return 0;
0466 }
0467 static const struct of_device_id qe_ic_ids[] = {
0468 { .compatible = "fsl,qe-ic"},
0469 { .type = "qeic"},
0470 {},
0471 };
0472
0473 static struct platform_driver qe_ic_driver =
0474 {
0475 .driver = {
0476 .name = "qe-ic",
0477 .of_match_table = qe_ic_ids,
0478 },
0479 .probe = qe_ic_init,
0480 };
0481
0482 static int __init qe_ic_of_init(void)
0483 {
0484 platform_driver_register(&qe_ic_driver);
0485 return 0;
0486 }
0487 subsys_initcall(qe_ic_of_init);