0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017 #include <linux/export.h>
0018 #include <linux/interrupt.h>
0019 #include <linux/irq.h>
0020 #include <linux/slab.h>
0021 #include <linux/of.h>
0022 #include <linux/irqdomain.h>
0023 #include <linux/mfd/twl.h>
0024
0025 #include "twl-core.h"
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044 #define TWL4030_CORE_NR_IRQS 8
0045 #define TWL4030_PWR_NR_IRQS 8
0046
0047
0048 #define REG_PIH_ISR_P1 0x01
0049 #define REG_PIH_ISR_P2 0x02
0050 #define REG_PIH_SIR 0x03
0051
0052
0053 static int irq_line;
0054
0055 struct sih {
0056 char name[8];
0057 u8 module;
0058 u8 control_offset;
0059 bool set_cor;
0060
0061 u8 bits;
0062 u8 bytes_ixr;
0063
0064 u8 edr_offset;
0065 u8 bytes_edr;
0066
0067 u8 irq_lines;
0068
0069
0070 struct sih_irq_data {
0071 u8 isr_offset;
0072 u8 imr_offset;
0073 } mask[2];
0074
0075 };
0076
0077 static const struct sih *sih_modules;
0078 static int nr_sih_modules;
0079
0080 #define SIH_INITIALIZER(modname, nbits) \
0081 .module = TWL4030_MODULE_ ## modname, \
0082 .control_offset = TWL4030_ ## modname ## _SIH_CTRL, \
0083 .bits = nbits, \
0084 .bytes_ixr = DIV_ROUND_UP(nbits, 8), \
0085 .edr_offset = TWL4030_ ## modname ## _EDR, \
0086 .bytes_edr = DIV_ROUND_UP((2*(nbits)), 8), \
0087 .irq_lines = 2, \
0088 .mask = { { \
0089 .isr_offset = TWL4030_ ## modname ## _ISR1, \
0090 .imr_offset = TWL4030_ ## modname ## _IMR1, \
0091 }, \
0092 { \
0093 .isr_offset = TWL4030_ ## modname ## _ISR2, \
0094 .imr_offset = TWL4030_ ## modname ## _IMR2, \
0095 }, },
0096
0097
0098 #define TWL4030_INT_PWR_EDR TWL4030_INT_PWR_EDR1
0099 #define TWL4030_MODULE_KEYPAD_KEYP TWL4030_MODULE_KEYPAD
0100 #define TWL4030_MODULE_INT_PWR TWL4030_MODULE_INT
0101
0102
0103
0104
0105
0106
0107
0108 static const struct sih sih_modules_twl4030[6] = {
0109 [0] = {
0110 .name = "gpio",
0111 .module = TWL4030_MODULE_GPIO,
0112 .control_offset = REG_GPIO_SIH_CTRL,
0113 .set_cor = true,
0114 .bits = TWL4030_GPIO_MAX,
0115 .bytes_ixr = 3,
0116
0117 .edr_offset = REG_GPIO_EDR1,
0118 .bytes_edr = 5,
0119 .irq_lines = 2,
0120 .mask = { {
0121 .isr_offset = REG_GPIO_ISR1A,
0122 .imr_offset = REG_GPIO_IMR1A,
0123 }, {
0124 .isr_offset = REG_GPIO_ISR1B,
0125 .imr_offset = REG_GPIO_IMR1B,
0126 }, },
0127 },
0128 [1] = {
0129 .name = "keypad",
0130 .set_cor = true,
0131 SIH_INITIALIZER(KEYPAD_KEYP, 4)
0132 },
0133 [2] = {
0134 .name = "bci",
0135 .module = TWL4030_MODULE_INTERRUPTS,
0136 .control_offset = TWL4030_INTERRUPTS_BCISIHCTRL,
0137 .set_cor = true,
0138 .bits = 12,
0139 .bytes_ixr = 2,
0140 .edr_offset = TWL4030_INTERRUPTS_BCIEDR1,
0141
0142 .bytes_edr = 3,
0143 .irq_lines = 2,
0144 .mask = { {
0145 .isr_offset = TWL4030_INTERRUPTS_BCIISR1A,
0146 .imr_offset = TWL4030_INTERRUPTS_BCIIMR1A,
0147 }, {
0148 .isr_offset = TWL4030_INTERRUPTS_BCIISR1B,
0149 .imr_offset = TWL4030_INTERRUPTS_BCIIMR1B,
0150 }, },
0151 },
0152 [3] = {
0153 .name = "madc",
0154 SIH_INITIALIZER(MADC, 4)
0155 },
0156 [4] = {
0157
0158 .name = "usb",
0159 },
0160 [5] = {
0161 .name = "power",
0162 .set_cor = true,
0163 SIH_INITIALIZER(INT_PWR, 8)
0164 },
0165
0166 };
0167
0168 static const struct sih sih_modules_twl5031[8] = {
0169 [0] = {
0170 .name = "gpio",
0171 .module = TWL4030_MODULE_GPIO,
0172 .control_offset = REG_GPIO_SIH_CTRL,
0173 .set_cor = true,
0174 .bits = TWL4030_GPIO_MAX,
0175 .bytes_ixr = 3,
0176
0177 .edr_offset = REG_GPIO_EDR1,
0178 .bytes_edr = 5,
0179 .irq_lines = 2,
0180 .mask = { {
0181 .isr_offset = REG_GPIO_ISR1A,
0182 .imr_offset = REG_GPIO_IMR1A,
0183 }, {
0184 .isr_offset = REG_GPIO_ISR1B,
0185 .imr_offset = REG_GPIO_IMR1B,
0186 }, },
0187 },
0188 [1] = {
0189 .name = "keypad",
0190 .set_cor = true,
0191 SIH_INITIALIZER(KEYPAD_KEYP, 4)
0192 },
0193 [2] = {
0194 .name = "bci",
0195 .module = TWL5031_MODULE_INTERRUPTS,
0196 .control_offset = TWL5031_INTERRUPTS_BCISIHCTRL,
0197 .bits = 7,
0198 .bytes_ixr = 1,
0199 .edr_offset = TWL5031_INTERRUPTS_BCIEDR1,
0200
0201 .bytes_edr = 2,
0202 .irq_lines = 2,
0203 .mask = { {
0204 .isr_offset = TWL5031_INTERRUPTS_BCIISR1,
0205 .imr_offset = TWL5031_INTERRUPTS_BCIIMR1,
0206 }, {
0207 .isr_offset = TWL5031_INTERRUPTS_BCIISR2,
0208 .imr_offset = TWL5031_INTERRUPTS_BCIIMR2,
0209 }, },
0210 },
0211 [3] = {
0212 .name = "madc",
0213 SIH_INITIALIZER(MADC, 4)
0214 },
0215 [4] = {
0216
0217 .name = "usb",
0218 },
0219 [5] = {
0220 .name = "power",
0221 .set_cor = true,
0222 SIH_INITIALIZER(INT_PWR, 8)
0223 },
0224 [6] = {
0225
0226
0227
0228
0229
0230 .name = "eci_dbi",
0231 .module = TWL5031_MODULE_ACCESSORY,
0232 .bits = 9,
0233 .bytes_ixr = 2,
0234 .irq_lines = 1,
0235 .mask = { {
0236 .isr_offset = TWL5031_ACIIDR_LSB,
0237 .imr_offset = TWL5031_ACIIMR_LSB,
0238 }, },
0239
0240 },
0241 [7] = {
0242
0243 .name = "audio",
0244 .module = TWL5031_MODULE_ACCESSORY,
0245 .control_offset = TWL5031_ACCSIHCTRL,
0246 .bits = 2,
0247 .bytes_ixr = 1,
0248 .edr_offset = TWL5031_ACCEDR1,
0249
0250 .bytes_edr = 1,
0251 .irq_lines = 2,
0252 .mask = { {
0253 .isr_offset = TWL5031_ACCISR1,
0254 .imr_offset = TWL5031_ACCIMR1,
0255 }, {
0256 .isr_offset = TWL5031_ACCISR2,
0257 .imr_offset = TWL5031_ACCIMR2,
0258 }, },
0259 },
0260 };
0261
0262 #undef TWL4030_MODULE_KEYPAD_KEYP
0263 #undef TWL4030_MODULE_INT_PWR
0264 #undef TWL4030_INT_PWR_EDR
0265
0266
0267
0268 static unsigned twl4030_irq_base;
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278
0279 static irqreturn_t handle_twl4030_pih(int irq, void *devid)
0280 {
0281 irqreturn_t ret;
0282 u8 pih_isr;
0283
0284 ret = twl_i2c_read_u8(TWL_MODULE_PIH, &pih_isr,
0285 REG_PIH_ISR_P1);
0286 if (ret) {
0287 pr_warn("twl4030: I2C error %d reading PIH ISR\n", ret);
0288 return IRQ_NONE;
0289 }
0290
0291 while (pih_isr) {
0292 unsigned long pending = __ffs(pih_isr);
0293 unsigned int irq;
0294
0295 pih_isr &= ~BIT(pending);
0296 irq = pending + twl4030_irq_base;
0297 handle_nested_irq(irq);
0298 }
0299
0300 return IRQ_HANDLED;
0301 }
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314 static int twl4030_init_sih_modules(unsigned line)
0315 {
0316 const struct sih *sih;
0317 u8 buf[4];
0318 int i;
0319 int status;
0320
0321
0322 if (line > 1)
0323 return -EINVAL;
0324
0325 irq_line = line;
0326
0327
0328 memset(buf, 0xff, sizeof(buf));
0329 sih = sih_modules;
0330 for (i = 0; i < nr_sih_modules; i++, sih++) {
0331
0332 if (!sih->bytes_ixr)
0333 continue;
0334
0335
0336 if (sih->irq_lines <= line)
0337 continue;
0338
0339 status = twl_i2c_write(sih->module, buf,
0340 sih->mask[line].imr_offset, sih->bytes_ixr);
0341 if (status < 0)
0342 pr_err("twl4030: err %d initializing %s %s\n",
0343 status, sih->name, "IMR");
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353 if (sih->set_cor) {
0354 status = twl_i2c_write_u8(sih->module,
0355 TWL4030_SIH_CTRL_COR_MASK,
0356 sih->control_offset);
0357 if (status < 0)
0358 pr_err("twl4030: err %d initializing %s %s\n",
0359 status, sih->name, "SIH_CTRL");
0360 }
0361 }
0362
0363 sih = sih_modules;
0364 for (i = 0; i < nr_sih_modules; i++, sih++) {
0365 u8 rxbuf[4];
0366 int j;
0367
0368
0369 if (!sih->bytes_ixr)
0370 continue;
0371
0372
0373 if (sih->irq_lines <= line)
0374 continue;
0375
0376
0377
0378
0379
0380
0381
0382 for (j = 0; j < 2; j++) {
0383 status = twl_i2c_read(sih->module, rxbuf,
0384 sih->mask[line].isr_offset, sih->bytes_ixr);
0385 if (status < 0)
0386 pr_warn("twl4030: err %d initializing %s %s\n",
0387 status, sih->name, "ISR");
0388
0389 if (!sih->set_cor) {
0390 status = twl_i2c_write(sih->module, buf,
0391 sih->mask[line].isr_offset,
0392 sih->bytes_ixr);
0393 if (status < 0)
0394 pr_warn("twl4030: write failed: %d\n",
0395 status);
0396 }
0397
0398
0399
0400
0401 }
0402 }
0403
0404 return 0;
0405 }
0406
0407 static inline void activate_irq(int irq)
0408 {
0409 irq_clear_status_flags(irq, IRQ_NOREQUEST | IRQ_NOPROBE);
0410 }
0411
0412
0413
0414 struct sih_agent {
0415 int irq_base;
0416 const struct sih *sih;
0417
0418 u32 imr;
0419 bool imr_change_pending;
0420
0421 u32 edge_change;
0422
0423 struct mutex irq_lock;
0424 char *irq_name;
0425 };
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436 static void twl4030_sih_mask(struct irq_data *data)
0437 {
0438 struct sih_agent *agent = irq_data_get_irq_chip_data(data);
0439
0440 agent->imr |= BIT(data->irq - agent->irq_base);
0441 agent->imr_change_pending = true;
0442 }
0443
0444 static void twl4030_sih_unmask(struct irq_data *data)
0445 {
0446 struct sih_agent *agent = irq_data_get_irq_chip_data(data);
0447
0448 agent->imr &= ~BIT(data->irq - agent->irq_base);
0449 agent->imr_change_pending = true;
0450 }
0451
0452 static int twl4030_sih_set_type(struct irq_data *data, unsigned trigger)
0453 {
0454 struct sih_agent *agent = irq_data_get_irq_chip_data(data);
0455
0456 if (trigger & ~(IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING))
0457 return -EINVAL;
0458
0459 if (irqd_get_trigger_type(data) != trigger)
0460 agent->edge_change |= BIT(data->irq - agent->irq_base);
0461
0462 return 0;
0463 }
0464
0465 static void twl4030_sih_bus_lock(struct irq_data *data)
0466 {
0467 struct sih_agent *agent = irq_data_get_irq_chip_data(data);
0468
0469 mutex_lock(&agent->irq_lock);
0470 }
0471
0472 static void twl4030_sih_bus_sync_unlock(struct irq_data *data)
0473 {
0474 struct sih_agent *agent = irq_data_get_irq_chip_data(data);
0475 const struct sih *sih = agent->sih;
0476 int status;
0477
0478 if (agent->imr_change_pending) {
0479 union {
0480 __le32 word;
0481 u8 bytes[4];
0482 } imr;
0483
0484
0485 imr.word = cpu_to_le32(agent->imr);
0486 agent->imr_change_pending = false;
0487
0488
0489 status = twl_i2c_write(sih->module, imr.bytes,
0490 sih->mask[irq_line].imr_offset,
0491 sih->bytes_ixr);
0492 if (status)
0493 pr_err("twl4030: %s, %s --> %d\n", __func__,
0494 "write", status);
0495 }
0496
0497 if (agent->edge_change) {
0498 u32 edge_change;
0499 u8 bytes[6];
0500
0501 edge_change = agent->edge_change;
0502 agent->edge_change = 0;
0503
0504
0505
0506
0507
0508
0509
0510 status = twl_i2c_read(sih->module, bytes,
0511 sih->edr_offset, sih->bytes_edr);
0512 if (status) {
0513 pr_err("twl4030: %s, %s --> %d\n", __func__,
0514 "read", status);
0515 return;
0516 }
0517
0518
0519 while (edge_change) {
0520 int i = fls(edge_change) - 1;
0521 int byte = i >> 2;
0522 int off = (i & 0x3) * 2;
0523 unsigned int type;
0524
0525 bytes[byte] &= ~(0x03 << off);
0526
0527 type = irq_get_trigger_type(i + agent->irq_base);
0528 if (type & IRQ_TYPE_EDGE_RISING)
0529 bytes[byte] |= BIT(off + 1);
0530 if (type & IRQ_TYPE_EDGE_FALLING)
0531 bytes[byte] |= BIT(off + 0);
0532
0533 edge_change &= ~BIT(i);
0534 }
0535
0536
0537 status = twl_i2c_write(sih->module, bytes,
0538 sih->edr_offset, sih->bytes_edr);
0539 if (status)
0540 pr_err("twl4030: %s, %s --> %d\n", __func__,
0541 "write", status);
0542 }
0543
0544 mutex_unlock(&agent->irq_lock);
0545 }
0546
0547 static struct irq_chip twl4030_sih_irq_chip = {
0548 .name = "twl4030",
0549 .irq_mask = twl4030_sih_mask,
0550 .irq_unmask = twl4030_sih_unmask,
0551 .irq_set_type = twl4030_sih_set_type,
0552 .irq_bus_lock = twl4030_sih_bus_lock,
0553 .irq_bus_sync_unlock = twl4030_sih_bus_sync_unlock,
0554 .flags = IRQCHIP_SKIP_SET_WAKE,
0555 };
0556
0557
0558
0559 static inline int sih_read_isr(const struct sih *sih)
0560 {
0561 int status;
0562 union {
0563 u8 bytes[4];
0564 __le32 word;
0565 } isr;
0566
0567
0568
0569 isr.word = 0;
0570 status = twl_i2c_read(sih->module, isr.bytes,
0571 sih->mask[irq_line].isr_offset, sih->bytes_ixr);
0572
0573 return (status < 0) ? status : le32_to_cpu(isr.word);
0574 }
0575
0576
0577
0578
0579
0580 static irqreturn_t handle_twl4030_sih(int irq, void *data)
0581 {
0582 struct sih_agent *agent = irq_get_handler_data(irq);
0583 const struct sih *sih = agent->sih;
0584 int isr;
0585
0586
0587 isr = sih_read_isr(sih);
0588
0589 if (isr < 0) {
0590 pr_err("twl4030: %s SIH, read ISR error %d\n",
0591 sih->name, isr);
0592
0593 return IRQ_HANDLED;
0594 }
0595
0596 while (isr) {
0597 irq = fls(isr);
0598 irq--;
0599 isr &= ~BIT(irq);
0600
0601 if (irq < sih->bits)
0602 handle_nested_irq(agent->irq_base + irq);
0603 else
0604 pr_err("twl4030: %s SIH, invalid ISR bit %d\n",
0605 sih->name, irq);
0606 }
0607 return IRQ_HANDLED;
0608 }
0609
0610
0611 int twl4030_sih_setup(struct device *dev, int module, int irq_base)
0612 {
0613 int sih_mod;
0614 const struct sih *sih = NULL;
0615 struct sih_agent *agent;
0616 int i, irq;
0617 int status = -EINVAL;
0618
0619
0620 for (sih_mod = 0, sih = sih_modules; sih_mod < nr_sih_modules;
0621 sih_mod++, sih++) {
0622 if (sih->module == module && sih->set_cor) {
0623 status = 0;
0624 break;
0625 }
0626 }
0627
0628 if (status < 0) {
0629 dev_err(dev, "module to setup SIH for not found\n");
0630 return status;
0631 }
0632
0633 agent = kzalloc(sizeof(*agent), GFP_KERNEL);
0634 if (!agent)
0635 return -ENOMEM;
0636
0637 agent->irq_base = irq_base;
0638 agent->sih = sih;
0639 agent->imr = ~0;
0640 mutex_init(&agent->irq_lock);
0641
0642 for (i = 0; i < sih->bits; i++) {
0643 irq = irq_base + i;
0644
0645 irq_set_chip_data(irq, agent);
0646 irq_set_chip_and_handler(irq, &twl4030_sih_irq_chip,
0647 handle_edge_irq);
0648 irq_set_nested_thread(irq, 1);
0649 activate_irq(irq);
0650 }
0651
0652
0653 irq = sih_mod + twl4030_irq_base;
0654 irq_set_handler_data(irq, agent);
0655 agent->irq_name = kasprintf(GFP_KERNEL, "twl4030_%s", sih->name);
0656 status = request_threaded_irq(irq, NULL, handle_twl4030_sih,
0657 IRQF_EARLY_RESUME | IRQF_ONESHOT,
0658 agent->irq_name ?: sih->name, NULL);
0659
0660 dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", sih->name,
0661 irq, irq_base, irq_base + i - 1);
0662
0663 return status < 0 ? status : irq_base;
0664 }
0665
0666
0667
0668
0669
0670
0671 #define twl_irq_line 0
0672
0673 int twl4030_init_irq(struct device *dev, int irq_num)
0674 {
0675 static struct irq_chip twl4030_irq_chip;
0676 int status, i;
0677 int irq_base, irq_end, nr_irqs;
0678 struct device_node *node = dev->of_node;
0679
0680
0681
0682
0683
0684
0685 nr_irqs = TWL4030_PWR_NR_IRQS + TWL4030_CORE_NR_IRQS;
0686
0687 irq_base = irq_alloc_descs(-1, 0, nr_irqs, 0);
0688 if (irq_base < 0) {
0689 dev_err(dev, "Fail to allocate IRQ descs\n");
0690 return irq_base;
0691 }
0692
0693 irq_domain_add_legacy(node, nr_irqs, irq_base, 0,
0694 &irq_domain_simple_ops, NULL);
0695
0696 irq_end = irq_base + TWL4030_CORE_NR_IRQS;
0697
0698
0699
0700
0701
0702 status = twl4030_init_sih_modules(twl_irq_line);
0703 if (status < 0)
0704 return status;
0705
0706 twl4030_irq_base = irq_base;
0707
0708
0709
0710
0711
0712 twl4030_irq_chip = dummy_irq_chip;
0713 twl4030_irq_chip.name = "twl4030";
0714
0715 twl4030_sih_irq_chip.irq_ack = dummy_irq_chip.irq_ack;
0716
0717 for (i = irq_base; i < irq_end; i++) {
0718 irq_set_chip_and_handler(i, &twl4030_irq_chip,
0719 handle_simple_irq);
0720 irq_set_nested_thread(i, 1);
0721 activate_irq(i);
0722 }
0723
0724 dev_info(dev, "%s (irq %d) chaining IRQs %d..%d\n", "PIH",
0725 irq_num, irq_base, irq_end);
0726
0727
0728 status = twl4030_sih_setup(dev, TWL4030_MODULE_INT, irq_end);
0729 if (status < 0) {
0730 dev_err(dev, "sih_setup PWR INT --> %d\n", status);
0731 goto fail;
0732 }
0733
0734
0735 status = request_threaded_irq(irq_num, NULL, handle_twl4030_pih,
0736 IRQF_ONESHOT,
0737 "TWL4030-PIH", NULL);
0738 if (status < 0) {
0739 dev_err(dev, "could not claim irq%d: %d\n", irq_num, status);
0740 goto fail_rqirq;
0741 }
0742 enable_irq_wake(irq_num);
0743
0744 return irq_base;
0745 fail_rqirq:
0746
0747 fail:
0748 for (i = irq_base; i < irq_end; i++) {
0749 irq_set_nested_thread(i, 0);
0750 irq_set_chip_and_handler(i, NULL, NULL);
0751 }
0752
0753 return status;
0754 }
0755
0756 void twl4030_exit_irq(void)
0757 {
0758
0759 if (twl4030_irq_base)
0760 pr_err("twl4030: can't yet clean up IRQs?\n");
0761 }
0762
0763 int twl4030_init_chip_irq(const char *chip)
0764 {
0765 if (!strcmp(chip, "twl5031")) {
0766 sih_modules = sih_modules_twl5031;
0767 nr_sih_modules = ARRAY_SIZE(sih_modules_twl5031);
0768 } else {
0769 sih_modules = sih_modules_twl4030;
0770 nr_sih_modules = ARRAY_SIZE(sih_modules_twl4030);
0771 }
0772
0773 return 0;
0774 }