Commit f011df61 authored by Lokesh Vutla's avatar Lokesh Vutla Committed by Marc Zyngier

irqchip/ti-sci-inta: Add msi domain support

Add a msi domain that is child to the INTA domain. Clients
uses the INTA MSI bus layer to allocate irqs in this
MSI domain.
Signed-off-by: default avatarLokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: default avatarMarc Zyngier <marc.zyngier@arm.com>
parent 49b32315
...@@ -433,6 +433,7 @@ config TI_SCI_INTA_IRQCHIP ...@@ -433,6 +433,7 @@ config TI_SCI_INTA_IRQCHIP
bool bool
depends on TI_SCI_PROTOCOL depends on TI_SCI_PROTOCOL
select IRQ_DOMAIN_HIERARCHY select IRQ_DOMAIN_HIERARCHY
select TI_SCI_INTA_MSI_DOMAIN
help help
This enables the irqchip driver support for K3 Interrupt aggregator This enables the irqchip driver support for K3 Interrupt aggregator
over TI System Control Interface available on some new TI's SoCs. over TI System Control Interface available on some new TI's SoCs.
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/irqchip/chained_irq.h> #include <linux/irqchip/chained_irq.h>
#include <linux/soc/ti/ti_sci_inta_msi.h>
#include <linux/soc/ti/ti_sci_protocol.h> #include <linux/soc/ti/ti_sci_protocol.h>
#include <asm-generic/msi.h> #include <asm-generic/msi.h>
...@@ -28,6 +29,9 @@ ...@@ -28,6 +29,9 @@
#define HWIRQ_TO_DEVID(hwirq) (((hwirq) >> (TI_SCI_DEV_ID_SHIFT)) & \ #define HWIRQ_TO_DEVID(hwirq) (((hwirq) >> (TI_SCI_DEV_ID_SHIFT)) & \
(TI_SCI_DEV_ID_MASK)) (TI_SCI_DEV_ID_MASK))
#define HWIRQ_TO_IRQID(hwirq) ((hwirq) & (TI_SCI_IRQ_ID_MASK)) #define HWIRQ_TO_IRQID(hwirq) ((hwirq) & (TI_SCI_IRQ_ID_MASK))
#define TO_HWIRQ(dev, index) ((((dev) & TI_SCI_DEV_ID_MASK) << \
TI_SCI_DEV_ID_SHIFT) | \
((index) & TI_SCI_IRQ_ID_MASK))
#define MAX_EVENTS_PER_VINT 64 #define MAX_EVENTS_PER_VINT 64
#define VINT_ENABLE_SET_OFFSET 0x0 #define VINT_ENABLE_SET_OFFSET 0x0
...@@ -484,9 +488,34 @@ static const struct irq_domain_ops ti_sci_inta_irq_domain_ops = { ...@@ -484,9 +488,34 @@ static const struct irq_domain_ops ti_sci_inta_irq_domain_ops = {
.alloc = ti_sci_inta_irq_domain_alloc, .alloc = ti_sci_inta_irq_domain_alloc,
}; };
static struct irq_chip ti_sci_inta_msi_irq_chip = {
.name = "MSI-INTA",
.flags = IRQCHIP_SUPPORTS_LEVEL_MSI,
};
static void ti_sci_inta_msi_set_desc(msi_alloc_info_t *arg,
struct msi_desc *desc)
{
struct platform_device *pdev = to_platform_device(desc->dev);
arg->desc = desc;
arg->hwirq = TO_HWIRQ(pdev->id, desc->inta.dev_index);
}
static struct msi_domain_ops ti_sci_inta_msi_ops = {
.set_desc = ti_sci_inta_msi_set_desc,
};
static struct msi_domain_info ti_sci_inta_msi_domain_info = {
.flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
MSI_FLAG_LEVEL_CAPABLE),
.ops = &ti_sci_inta_msi_ops,
.chip = &ti_sci_inta_msi_irq_chip,
};
static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev) static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev)
{ {
struct irq_domain *parent_domain, *domain; struct irq_domain *parent_domain, *domain, *msi_domain;
struct device_node *parent_node, *node; struct device_node *parent_node, *node;
struct ti_sci_inta_irq_domain *inta; struct ti_sci_inta_irq_domain *inta;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
...@@ -551,6 +580,15 @@ static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev) ...@@ -551,6 +580,15 @@ static int ti_sci_inta_irq_domain_probe(struct platform_device *pdev)
return -ENOMEM; return -ENOMEM;
} }
msi_domain = ti_sci_inta_msi_create_irq_domain(of_node_to_fwnode(node),
&ti_sci_inta_msi_domain_info,
domain);
if (!msi_domain) {
irq_domain_remove(domain);
dev_err(dev, "Failed to allocate msi domain\n");
return -ENOMEM;
}
INIT_LIST_HEAD(&inta->vint_list); INIT_LIST_HEAD(&inta->vint_list);
mutex_init(&inta->vint_mutex); mutex_init(&inta->vint_mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment