1
0
Fork 0

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: Lokesh Vutla <lokeshvutla@ti.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
hifive-unleashed-5.2
Lokesh Vutla 2019-04-30 15:42:29 +05:30 committed by Marc Zyngier
parent 49b323157b
commit f011df6179
2 changed files with 40 additions and 1 deletions

View File

@ -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.

View File

@ -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 @@
#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 = {
.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)
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);