diff options
| -rw-r--r-- | drivers/irqchip/Kconfig | 1 | ||||
| -rw-r--r-- | drivers/irqchip/irq-ti-sci-inta.c | 40 |
2 files changed, 40 insertions, 1 deletions
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 2c8d5daad57c..fcf9457cc1d9 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig | |||
| @@ -433,6 +433,7 @@ config TI_SCI_INTA_IRQCHIP | |||
| 433 | bool | 433 | bool |
| 434 | depends on TI_SCI_PROTOCOL | 434 | depends on TI_SCI_PROTOCOL |
| 435 | select IRQ_DOMAIN_HIERARCHY | 435 | select IRQ_DOMAIN_HIERARCHY |
| 436 | select TI_SCI_INTA_MSI_DOMAIN | ||
| 436 | help | 437 | help |
| 437 | This enables the irqchip driver support for K3 Interrupt aggregator | 438 | This enables the irqchip driver support for K3 Interrupt aggregator |
| 438 | over TI System Control Interface available on some new TI's SoCs. | 439 | over TI System Control Interface available on some new TI's SoCs. |
diff --git a/drivers/irqchip/irq-ti-sci-inta.c b/drivers/irqchip/irq-ti-sci-inta.c index 87e0abe0041f..011b60a49e3f 100644 --- a/drivers/irqchip/irq-ti-sci-inta.c +++ b/drivers/irqchip/irq-ti-sci-inta.c | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/of_irq.h> | 18 | #include <linux/of_irq.h> |
| 19 | #include <linux/of_platform.h> | 19 | #include <linux/of_platform.h> |
| 20 | #include <linux/irqchip/chained_irq.h> | 20 | #include <linux/irqchip/chained_irq.h> |
| 21 | #include <linux/soc/ti/ti_sci_inta_msi.h> | ||
| 21 | #include <linux/soc/ti/ti_sci_protocol.h> | 22 | #include <linux/soc/ti/ti_sci_protocol.h> |
| 22 | #include <asm-generic/msi.h> | 23 | #include <asm-generic/msi.h> |
| 23 | 24 | ||
| @@ -28,6 +29,9 @@ | |||
| 28 | #define HWIRQ_TO_DEVID(hwirq) (((hwirq) >> (TI_SCI_DEV_ID_SHIFT)) & \ | 29 | #define HWIRQ_TO_DEVID(hwirq) (((hwirq) >> (TI_SCI_DEV_ID_SHIFT)) & \ |
| 29 | (TI_SCI_DEV_ID_MASK)) | 30 | (TI_SCI_DEV_ID_MASK)) |
| 30 | #define HWIRQ_TO_IRQID(hwirq) ((hwirq) & (TI_SCI_IRQ_ID_MASK)) | 31 | #define HWIRQ_TO_IRQID(hwirq) ((hwirq) & (TI_SCI_IRQ_ID_MASK)) |
| 32 | #define TO_HWIRQ(dev, index) ((((dev) & TI_SCI_DEV_ID_MASK) << \ | ||
| 33 | TI_SCI_DEV_ID_SHIFT) | \ | ||
| 34 | ((index) & TI_SCI_IRQ_ID_MASK)) | ||
| 31 | 35 | ||
| 32 | #define MAX_EVENTS_PER_VINT 64 | 36 | #define MAX_EVENTS_PER_VINT 64 |
| 33 | #define VINT_ENABLE_SET_OFFSET 0x0 | 37 | #define VINT_ENABLE_SET_OFFSET 0x0 |
| @@ -484,9 +488,34 @@ static const struct irq_domain_ops ti_sci_inta_irq_domain_ops = { | |||
| 484 | .alloc = ti_sci_inta_irq_domain_alloc, | 488 | .alloc = ti_sci_inta_irq_domain_alloc, |
| 485 | }; | 489 | }; |
| 486 | 490 | ||
| 491 | static struct irq_chip ti_sci_inta_msi_irq_chip = { | ||
| 492 | .name = "MSI-INTA", | ||
| 493 | .flags = IRQCHIP_SUPPORTS_LEVEL_MSI, | ||
| 494 | }; | ||
| 495 | |||
| 496 | static void ti_sci_inta_msi_set_desc(msi_alloc_info_t *arg, | ||
| 497 | struct msi_desc *desc) | ||
| 498 | { | ||
| 499 | struct platform_device *pdev = to_platform_device(desc->dev); | ||
| 500 | |||
| 501 | arg->desc = desc; | ||
| 502 | arg->hwirq = TO_HWIRQ(pdev->id, desc->inta.dev_index); | ||
| 503 | } | ||
| 504 | |||
| 505 | static struct msi_domain_ops ti_sci_inta_msi_ops = { | ||
| 506 | .set_desc = ti_sci_inta_msi_set_desc, | ||
| 507 | }; | ||
| 508 | |||
| 509 | static struct msi_domain_info ti_sci_inta_msi_domain_info = { | ||
| 510 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | ||
| 511 | MSI_FLAG_LEVEL_CAPABLE), | ||
| 512 | .ops = &ti_sci_inta_msi_ops, | ||
| 513 | .chip = &ti_sci_inta_msi_irq_chip, | ||
| 514 | }; | ||
| 515 | |||
| 487 | static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev) | 516 | static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev) |
| 488 | { | 517 | { |
| 489 | struct irq_domain *parent_domain, *domain; | 518 | struct irq_domain *parent_domain, *domain, *msi_domain; |
| 490 | struct device_node *parent_node, *node; | 519 | struct device_node *parent_node, *node; |
| 491 | struct ti_sci_inta_irq_domain *inta; | 520 | struct ti_sci_inta_irq_domain *inta; |
| 492 | struct device *dev = &pdev->dev; | 521 | struct device *dev = &pdev->dev; |
| @@ -551,6 +580,15 @@ static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev) | |||
| 551 | return -ENOMEM; | 580 | return -ENOMEM; |
| 552 | } | 581 | } |
| 553 | 582 | ||
| 583 | msi_domain = ti_sci_inta_msi_create_irq_domain(of_node_to_fwnode(node), | ||
| 584 | &ti_sci_inta_msi_domain_info, | ||
| 585 | domain); | ||
| 586 | if (!msi_domain) { | ||
| 587 | irq_domain_remove(domain); | ||
| 588 | dev_err(dev, "Failed to allocate msi domain\n"); | ||
| 589 | return -ENOMEM; | ||
| 590 | } | ||
| 591 | |||
| 554 | INIT_LIST_HEAD(&inta->vint_list); | 592 | INIT_LIST_HEAD(&inta->vint_list); |
| 555 | mutex_init(&inta->vint_mutex); | 593 | mutex_init(&inta->vint_mutex); |
| 556 | 594 | ||
