Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

spmi: mtk-pmif: Implement Request Capable Slave (RCS) interrupt

Add support for the per-bus RCS interrupt by adding a new linear
irqdomain and its irqchip.

The SPMI controller will raise an interrupt when any of the SPMI
connected devices' irq needs attention (whenever any interrupt
fires on any SID) in one of four registers, where each register
holds four sets of four bits of information about a SID interrupt.

This controller's RCS interrupt status knowledge is limited to the
address of the SID that raised an interrupt, but does not have any
details about the devices irq numbers: as this may change with a
future SPMI controller IP version, the devicetree is meant to hold
three cells, where the first one is the SPMI SID interrupt number,
the second one is a device interrupt number, and the third one is
the irq sense type.

Reviewed-by: Nícolas F. R. A. Prado <nfraprado@collabora.com>
Signed-off-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Signed-off-by: Stephen Boyd <sboyd@kernel.org>
Link: https://patch.msgid.link/20260123182039.224314-5-sboyd@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

AngeloGioacchino Del Regno and committed by
Greg Kroah-Hartman
ab1b3469 63cbabb0

+226 -6
+226 -6
drivers/spmi/spmi-mtk-pmif.c
··· 5 5 // AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> 6 6 7 7 #include <linux/clk.h> 8 + #include <linux/interrupt.h> 8 9 #include <linux/iopoll.h> 10 + #include <linux/irq.h> 11 + #include <linux/irqdomain.h> 9 12 #include <linux/module.h> 10 13 #include <linux/of.h> 14 + #include <linux/of_irq.h> 11 15 #include <linux/platform_device.h> 12 16 #include <linux/property.h> 13 17 #include <linux/spmi.h> 18 + #include <linux/irqchip/chained_irq.h> 14 19 15 20 #define SWINF_IDLE 0x00 16 21 #define SWINF_WFVLDCLR 0x06 ··· 31 26 #define PMIF_TIMEOUT_US (10 * 1000) 32 27 33 28 #define PMIF_CHAN_OFFSET 0x5 29 + #define PMIF_RCS_IRQ_MASK GENMASK(7, 0) 34 30 35 31 #define PMIF_MAX_BUSES 2 36 32 #define PMIF_MAX_CLKS 3 ··· 50 44 const u32 *regs; 51 45 const u32 *spmimst_regs; 52 46 u32 soc_chan; 47 + u8 spmi_ver; 53 48 u32 num_spmi_buses; 54 49 }; 55 50 ··· 58 51 void __iomem *base; 59 52 void __iomem *spmimst_base; 60 53 struct spmi_controller *ctrl; 54 + struct irq_domain *dom; 55 + int irq; 61 56 struct clk_bulk_data clks[PMIF_MAX_CLKS]; 62 57 size_t nclks; 58 + u8 irq_min_sid; 59 + u8 irq_max_sid; 60 + u16 irq_en; 63 61 raw_spinlock_t lock; 64 62 }; 65 63 ··· 299 287 writel(val, pbus->base + arb->data->regs[reg]); 300 288 } 301 289 290 + static u32 mtk_spmi_readl(struct pmif *arb, struct pmif_bus *pbus, enum spmi_regs reg) 291 + { 292 + return readl(pbus->spmimst_base + arb->data->spmimst_regs[reg]); 293 + } 294 + 302 295 static void mtk_spmi_writel(struct pmif *arb, struct pmif_bus *pbus, 303 296 u32 val, enum spmi_regs reg) 304 297 { ··· 360 343 361 344 if (len > 4) { 362 345 dev_err(&ctrl->dev, "pmif supports 1..4 bytes per trans, but:%zu requested", len); 363 - 364 346 return -EINVAL; 365 347 } 366 348 ··· 471 455 return 0; 472 456 } 473 457 458 + static void mtk_spmi_handle_chained_irq(struct irq_desc *desc) 459 + { 460 + struct pmif_bus *pbus = irq_desc_get_handler_data(desc); 461 + struct irq_chip *chip = irq_desc_get_chip(desc); 462 + struct pmif *arb = to_mtk_pmif(pbus->ctrl); 463 + u8 regidx_min, regidx_max; 464 + bool irq_handled = false; 465 + unsigned int i; 466 + 467 + regidx_min = pbus->irq_min_sid / 4; 468 + regidx_min += SPMI_SLV_3_0_EINT; 469 + 470 + regidx_max = pbus->irq_max_sid / 4; 471 + regidx_max += SPMI_SLV_3_0_EINT; 472 + 473 + chained_irq_enter(chip, desc); 474 + 475 + for (i = regidx_min; i <= regidx_max; i++) { 476 + u32 val = mtk_spmi_readl(arb, pbus, i); 477 + 478 + while (val) { 479 + u8 bit = __ffs(val); 480 + u8 bank = bit / 7; 481 + u8 sid = ((i - SPMI_SLV_3_0_EINT) * 4) + bank; 482 + 483 + val &= ~(PMIF_RCS_IRQ_MASK << (8 * bank)); 484 + 485 + /* Check if IRQs for this SID are enabled */ 486 + if (!(pbus->irq_en & BIT(sid))) 487 + continue; 488 + 489 + generic_handle_domain_irq_safe(pbus->dom, sid); 490 + irq_handled = true; 491 + } 492 + } 493 + 494 + if (!irq_handled) 495 + handle_bad_irq(desc); 496 + 497 + chained_irq_exit(chip, desc); 498 + } 499 + 500 + static void mtk_spmi_rcs_irq_eoi(struct irq_data *d) 501 + { 502 + struct pmif_bus *pbus = irq_data_get_irq_chip_data(d); 503 + struct pmif *arb = to_mtk_pmif(pbus->ctrl); 504 + irq_hw_number_t irq = irqd_to_hwirq(d); 505 + unsigned int reg, shift; 506 + 507 + /* There are four interrupts (8 bits each) per register */ 508 + reg = SPMI_SLV_3_0_EINT + d->hwirq / 4; 509 + shift = (irq % 4) * 8; 510 + 511 + mtk_spmi_writel(arb, pbus, PMIF_RCS_IRQ_MASK << shift, reg); 512 + } 513 + 514 + static void mtk_spmi_rcs_irq_enable(struct irq_data *d) 515 + { 516 + struct pmif_bus *pbus = irq_data_get_irq_chip_data(d); 517 + irq_hw_number_t irq = irqd_to_hwirq(d); 518 + 519 + pbus->irq_en |= BIT(irq); 520 + } 521 + 522 + static void mtk_spmi_rcs_irq_disable(struct irq_data *d) 523 + { 524 + struct pmif_bus *pbus = irq_data_get_irq_chip_data(d); 525 + irq_hw_number_t irq = irqd_to_hwirq(d); 526 + 527 + pbus->irq_en &= ~BIT(irq); 528 + } 529 + 530 + static int mtk_spmi_rcs_irq_set_wake(struct irq_data *d, unsigned int on) 531 + { 532 + struct pmif_bus *pbus = irq_data_get_irq_chip_data(d); 533 + 534 + return irq_set_irq_wake(pbus->irq, on); 535 + } 536 + 537 + static const struct irq_chip mtk_spmi_rcs_irq_chip = { 538 + .name = "spmi_rcs", 539 + .irq_eoi = mtk_spmi_rcs_irq_eoi, 540 + .irq_enable = mtk_spmi_rcs_irq_enable, 541 + .irq_disable = mtk_spmi_rcs_irq_disable, 542 + .irq_set_wake = mtk_spmi_rcs_irq_set_wake, 543 + }; 544 + 545 + static int mtk_spmi_rcs_irq_translate(struct irq_domain *d, struct irq_fwspec *fwspec, 546 + unsigned long *out_hwirq, unsigned int *out_type) 547 + { 548 + struct pmif_bus *pbus = d->host_data; 549 + struct device *dev = &pbus->ctrl->dev; 550 + u32 *intspec = fwspec->param; 551 + 552 + if (intspec[0] > SPMI_MAX_SLAVE_ID) 553 + return -EINVAL; 554 + 555 + /* 556 + * The IRQ number in intspec[1] is ignored on purpose here! 557 + * 558 + * The controller only has knowledge of which SID raised an interrupt 559 + * and the type of irq, but doesn't know about any device irq number, 560 + * hence that must be read from the SPMI device's registers. 561 + */ 562 + *out_hwirq = intspec[0]; 563 + *out_type = intspec[2] & IRQ_TYPE_SENSE_MASK; 564 + 565 + if (pbus->irq_min_sid > intspec[0]) 566 + pbus->irq_min_sid = intspec[0]; 567 + 568 + if (pbus->irq_max_sid < intspec[0]) 569 + pbus->irq_max_sid = intspec[0]; 570 + 571 + dev_dbg(dev, "Found SPMI IRQ %u (map: 0x%lx)\n", intspec[0], *out_hwirq); 572 + 573 + return 0; 574 + } 575 + 576 + static struct lock_class_key mtk_spmi_rcs_irqlock_class, mtk_spmi_rcs_irqreq_class; 577 + 578 + static int mtk_spmi_rcs_irq_alloc(struct irq_domain *d, unsigned int virq, 579 + unsigned int nr_irqs, void *data) 580 + { 581 + struct pmif_bus *pbus = d->host_data; 582 + struct device *dev = &pbus->ctrl->dev; 583 + struct irq_fwspec *fwspec = data; 584 + irq_hw_number_t hwirq; 585 + unsigned int irqtype; 586 + int i, ret; 587 + 588 + ret = mtk_spmi_rcs_irq_translate(d, fwspec, &hwirq, &irqtype); 589 + if (ret) 590 + return ret; 591 + 592 + for (i = 0; i < nr_irqs; i++) { 593 + dev_dbg(dev, "Mapping IRQ%u (hwirq %lu) with type %u\n", 594 + virq, hwirq, irqtype); 595 + 596 + irq_set_lockdep_class(virq, &mtk_spmi_rcs_irqlock_class, 597 + &mtk_spmi_rcs_irqreq_class); 598 + irq_domain_set_info(d, virq, hwirq, &mtk_spmi_rcs_irq_chip, 599 + pbus, handle_level_irq, NULL, NULL); 600 + } 601 + 602 + return 0; 603 + } 604 + 605 + static const struct irq_domain_ops mtk_spmi_rcs_irq_domain_ops = { 606 + .alloc = mtk_spmi_rcs_irq_alloc, 607 + .free = irq_domain_free_irqs_common, 608 + .translate = mtk_spmi_rcs_irq_translate, 609 + }; 610 + 474 611 static const struct pmif_data mt6873_pmif_arb = { 475 612 .regs = mt6873_regs, 476 613 .spmimst_regs = mt6873_spmi_regs, ··· 635 466 .spmimst_regs = mt8195_spmi_regs, 636 467 .soc_chan = 2, 637 468 }; 469 + 470 + static int mtk_spmi_irq_init(struct device_node *node, 471 + const struct pmif_data *pdata, 472 + struct pmif_bus *pbus) 473 + { 474 + struct pmif *arb = to_mtk_pmif(pbus->ctrl); 475 + unsigned int i; 476 + 477 + /* No interrupts required for SPMI 1.x controller */ 478 + if (pdata->spmi_ver < 2) { 479 + pbus->dom = NULL; 480 + return 0; 481 + } 482 + 483 + pbus->irq = of_irq_get_byname(node, "rcs"); 484 + if (pbus->irq <= 0) 485 + return pbus->irq ? : -ENXIO; 486 + 487 + pbus->dom = irq_domain_create_tree(of_fwnode_handle(node), 488 + &mtk_spmi_rcs_irq_domain_ops, pbus); 489 + if (!pbus->dom) 490 + return -ENOMEM; 491 + 492 + /* Clear possible unhandled interrupts coming from bootloader SPMI init */ 493 + for (i = SPMI_SLV_3_0_EINT; i <= SPMI_SLV_F_C_EINT; i++) 494 + mtk_spmi_writel(arb, pbus, GENMASK(31, 0), i); 495 + 496 + return 0; 497 + } 498 + 499 + static void mtk_spmi_irq_remove(struct pmif_bus *pbus) 500 + { 501 + if (!pbus->dom) 502 + return; 503 + 504 + irq_set_chained_handler_and_data(pbus->irq, NULL, NULL); 505 + irq_domain_remove(pbus->dom); 506 + } 638 507 639 508 static int mtk_spmi_bus_probe(struct platform_device *pdev, 640 509 struct device_node *node, ··· 719 512 pbus->clks[i].id = pmif_clock_names[i]; 720 513 pbus->clks[i].clk = of_clk_get_by_name(node, pbus->clks[i].id); 721 514 if (IS_ERR(pbus->clks[i].clk)) 722 - return PTR_ERR(pbus->clks[i].clk); 515 + return dev_err_probe(&pdev->dev, PTR_ERR(pbus->clks[i].clk), 516 + "Failed to get clocks\n"); 723 517 } 724 518 725 519 err = clk_bulk_prepare_enable(pbus->nclks, pbus->clks); 726 - if (err) 520 + if (err) { 521 + dev_err_probe(&pdev->dev, err, "Failed to enable clocks\n"); 727 522 goto err_put_clks; 523 + } 524 + 525 + err = mtk_spmi_irq_init(node, pdata, pbus); 526 + if (err) { 527 + dev_err_probe(&pdev->dev, err, "Cannot initialize SPMI IRQs\n"); 528 + goto err_disable_clks; 529 + } 728 530 729 531 ctrl->cmd = pmif_arb_cmd; 730 532 ctrl->read_cmd = pmif_spmi_read_cmd; ··· 745 529 746 530 err = spmi_controller_add(ctrl); 747 531 if (err) 748 - goto err_domain_remove; 532 + goto err_remove_irq; 749 533 750 - pbus->ctrl = ctrl; 534 + if (pbus->dom) 535 + irq_set_chained_handler_and_data(pbus->irq, mtk_spmi_handle_chained_irq, pbus); 751 536 752 537 return 0; 753 538 754 - err_domain_remove: 539 + err_remove_irq: 540 + mtk_spmi_irq_remove(pbus); 541 + err_disable_clks: 755 542 clk_bulk_disable_unprepare(pbus->nclks, pbus->clks); 756 543 err_put_clks: 757 544 clk_bulk_put(pbus->nclks, pbus->clks); ··· 819 600 if (!pbus->ctrl) 820 601 continue; 821 602 603 + mtk_spmi_irq_remove(pbus); 822 604 spmi_controller_remove(pbus->ctrl); 823 605 clk_bulk_disable_unprepare(pbus->nclks, pbus->clks); 824 606 clk_bulk_put(pbus->nclks, pbus->clks);