Skip to content

Commit 49b3231

Browse files
lokeshvutlaMarc Zyngier
authored andcommitted
soc: ti: Add MSI domain bus support for Interrupt Aggregator
With the system coprocessor managing the range allocation of the inputs to Interrupt Aggregator, it is difficult to represent the device IRQs from DT. The suggestion is to use MSI in such cases where devices wants to allocate and group interrupts dynamically. Create a MSI domain bus layer that allocates and frees MSIs for a device. APIs that are implemented: - ti_sci_inta_msi_create_irq_domain() that creates a MSI domain - ti_sci_inta_msi_domain_alloc_irqs() that creates MSIs for the specified device and resource. - ti_sci_inta_msi_domain_free_irqs() frees the irqs attached to the device. - ti_sci_inta_msi_get_virq() for getting the virq attached to a specific event. Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
1 parent 9f1463b commit 49b3231

File tree

7 files changed

+189
-0
lines changed

7 files changed

+189
-0
lines changed

MAINTAINERS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15353,6 +15353,8 @@ F: Documentation/devicetree/bindings/interrupt-controller/ti,sci-intr.txt
1535315353
F: Documentation/devicetree/bindings/interrupt-controller/ti,sci-inta.txt
1535415354
F: drivers/irqchip/irq-ti-sci-intr.c
1535515355
F: drivers/irqchip/irq-ti-sci-inta.c
15356+
F: include/linux/soc/ti/ti_sci_inta_msi.h
15357+
F: drivers/soc/ti/ti_sci_inta_msi.c
1535615358

1535715359
Texas Instruments ASoC drivers
1535815360
M: Peter Ujfalusi <peter.ujfalusi@ti.com>

drivers/soc/ti/Kconfig

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,4 +73,10 @@ config TI_SCI_PM_DOMAINS
7373
called ti_sci_pm_domains. Note this is needed early in boot before
7474
rootfs may be available.
7575

76+
config TI_SCI_INTA_MSI_DOMAIN
77+
bool
78+
select GENERIC_MSI_IRQ_DOMAIN
79+
help
80+
Driver to enable Interrupt Aggregator specific MSI Domain.
81+
7682
endif # SOC_TI

drivers/soc/ti/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,4 @@ obj-$(CONFIG_KEYSTONE_NAVIGATOR_DMA) += knav_dma.o
88
obj-$(CONFIG_AMX3_PM) += pm33xx.o
99
obj-$(CONFIG_WKUP_M3_IPC) += wkup_m3_ipc.o
1010
obj-$(CONFIG_TI_SCI_PM_DOMAINS) += ti_sci_pm_domains.o
11+
obj-$(CONFIG_TI_SCI_INTA_MSI_DOMAIN) += ti_sci_inta_msi.o

drivers/soc/ti/ti_sci_inta_msi.c

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
/*
3+
* Texas Instruments' K3 Interrupt Aggregator MSI bus
4+
*
5+
* Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
6+
* Lokesh Vutla <lokeshvutla@ti.com>
7+
*/
8+
9+
#include <linux/irq.h>
10+
#include <linux/irqdomain.h>
11+
#include <linux/msi.h>
12+
#include <linux/of_address.h>
13+
#include <linux/of_device.h>
14+
#include <linux/of_irq.h>
15+
#include <linux/soc/ti/ti_sci_inta_msi.h>
16+
#include <linux/soc/ti/ti_sci_protocol.h>
17+
18+
static void ti_sci_inta_msi_write_msg(struct irq_data *data,
19+
struct msi_msg *msg)
20+
{
21+
/* Nothing to do */
22+
}
23+
24+
static void ti_sci_inta_msi_compose_msi_msg(struct irq_data *data,
25+
struct msi_msg *msg)
26+
{
27+
/* Nothing to do */
28+
}
29+
30+
static void ti_sci_inta_msi_update_chip_ops(struct msi_domain_info *info)
31+
{
32+
struct irq_chip *chip = info->chip;
33+
34+
if (WARN_ON(!chip))
35+
return;
36+
37+
chip->irq_request_resources = irq_chip_request_resources_parent;
38+
chip->irq_release_resources = irq_chip_release_resources_parent;
39+
chip->irq_compose_msi_msg = ti_sci_inta_msi_compose_msi_msg;
40+
chip->irq_write_msi_msg = ti_sci_inta_msi_write_msg;
41+
chip->irq_set_type = irq_chip_set_type_parent;
42+
chip->irq_unmask = irq_chip_unmask_parent;
43+
chip->irq_mask = irq_chip_mask_parent;
44+
chip->irq_ack = irq_chip_ack_parent;
45+
}
46+
47+
struct irq_domain *ti_sci_inta_msi_create_irq_domain(struct fwnode_handle *fwnode,
48+
struct msi_domain_info *info,
49+
struct irq_domain *parent)
50+
{
51+
struct irq_domain *domain;
52+
53+
ti_sci_inta_msi_update_chip_ops(info);
54+
55+
domain = msi_create_irq_domain(fwnode, info, parent);
56+
if (domain)
57+
irq_domain_update_bus_token(domain, DOMAIN_BUS_TI_SCI_INTA_MSI);
58+
59+
return domain;
60+
}
61+
EXPORT_SYMBOL_GPL(ti_sci_inta_msi_create_irq_domain);
62+
63+
static void ti_sci_inta_msi_free_descs(struct device *dev)
64+
{
65+
struct msi_desc *desc, *tmp;
66+
67+
list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) {
68+
list_del(&desc->list);
69+
free_msi_entry(desc);
70+
}
71+
}
72+
73+
static int ti_sci_inta_msi_alloc_descs(struct device *dev,
74+
struct ti_sci_resource *res)
75+
{
76+
struct msi_desc *msi_desc;
77+
int set, i, count = 0;
78+
79+
for (set = 0; set < res->sets; set++) {
80+
for (i = 0; i < res->desc[set].num; i++) {
81+
msi_desc = alloc_msi_entry(dev, 1, NULL);
82+
if (!msi_desc) {
83+
ti_sci_inta_msi_free_descs(dev);
84+
return -ENOMEM;
85+
}
86+
87+
msi_desc->inta.dev_index = res->desc[set].start + i;
88+
INIT_LIST_HEAD(&msi_desc->list);
89+
list_add_tail(&msi_desc->list, dev_to_msi_list(dev));
90+
count++;
91+
}
92+
}
93+
94+
return count;
95+
}
96+
97+
int ti_sci_inta_msi_domain_alloc_irqs(struct device *dev,
98+
struct ti_sci_resource *res)
99+
{
100+
struct platform_device *pdev = to_platform_device(dev);
101+
struct irq_domain *msi_domain;
102+
int ret, nvec;
103+
104+
msi_domain = dev_get_msi_domain(dev);
105+
if (!msi_domain)
106+
return -EINVAL;
107+
108+
if (pdev->id < 0)
109+
return -ENODEV;
110+
111+
nvec = ti_sci_inta_msi_alloc_descs(dev, res);
112+
if (nvec <= 0)
113+
return nvec;
114+
115+
ret = msi_domain_alloc_irqs(msi_domain, dev, nvec);
116+
if (ret) {
117+
dev_err(dev, "Failed to allocate IRQs %d\n", ret);
118+
goto cleanup;
119+
}
120+
121+
return 0;
122+
123+
cleanup:
124+
ti_sci_inta_msi_free_descs(&pdev->dev);
125+
return ret;
126+
}
127+
EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain_alloc_irqs);
128+
129+
void ti_sci_inta_msi_domain_free_irqs(struct device *dev)
130+
{
131+
msi_domain_free_irqs(dev->msi_domain, dev);
132+
ti_sci_inta_msi_free_descs(dev);
133+
}
134+
EXPORT_SYMBOL_GPL(ti_sci_inta_msi_domain_free_irqs);
135+
136+
unsigned int ti_sci_inta_msi_get_virq(struct device *dev, u32 dev_index)
137+
{
138+
struct msi_desc *desc;
139+
140+
for_each_msi_entry(desc, dev)
141+
if (desc->inta.dev_index == dev_index)
142+
return desc->irq;
143+
144+
return -ENODEV;
145+
}
146+
EXPORT_SYMBOL_GPL(ti_sci_inta_msi_get_virq);

include/linux/irqdomain.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ enum irq_domain_bus_token {
8282
DOMAIN_BUS_NEXUS,
8383
DOMAIN_BUS_IPI,
8484
DOMAIN_BUS_FSL_MC_MSI,
85+
DOMAIN_BUS_TI_SCI_INTA_MSI,
8586
};
8687

8788
/**

include/linux/msi.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,14 @@ struct fsl_mc_msi_desc {
4747
u16 msi_index;
4848
};
4949

50+
/**
51+
* ti_sci_inta_msi_desc - TISCI based INTA specific msi descriptor data
52+
* @dev_index: TISCI device index
53+
*/
54+
struct ti_sci_inta_msi_desc {
55+
u16 dev_index;
56+
};
57+
5058
/**
5159
* struct msi_desc - Descriptor structure for MSI based interrupts
5260
* @list: List head for management
@@ -68,6 +76,7 @@ struct fsl_mc_msi_desc {
6876
* @mask_base: [PCI MSI-X] Mask register base address
6977
* @platform: [platform] Platform device specific msi descriptor data
7078
* @fsl_mc: [fsl-mc] FSL MC device specific msi descriptor data
79+
* @inta: [INTA] TISCI based INTA specific msi descriptor data
7180
*/
7281
struct msi_desc {
7382
/* Shared device/bus type independent data */
@@ -106,6 +115,7 @@ struct msi_desc {
106115
*/
107116
struct platform_msi_desc platform;
108117
struct fsl_mc_msi_desc fsl_mc;
118+
struct ti_sci_inta_msi_desc inta;
109119
};
110120
};
111121

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
/*
3+
* Texas Instruments' K3 TI SCI INTA MSI helper
4+
*
5+
* Copyright (C) 2018-2019 Texas Instruments Incorporated - http://www.ti.com/
6+
* Lokesh Vutla <lokeshvutla@ti.com>
7+
*/
8+
9+
#ifndef __INCLUDE_LINUX_TI_SCI_INTA_MSI_H
10+
#define __INCLUDE_LINUX_TI_SCI_INTA_MSI_H
11+
12+
#include <linux/msi.h>
13+
#include <linux/soc/ti/ti_sci_protocol.h>
14+
15+
struct irq_domain
16+
*ti_sci_inta_msi_create_irq_domain(struct fwnode_handle *fwnode,
17+
struct msi_domain_info *info,
18+
struct irq_domain *parent);
19+
int ti_sci_inta_msi_domain_alloc_irqs(struct device *dev,
20+
struct ti_sci_resource *res);
21+
unsigned int ti_sci_inta_msi_get_virq(struct device *dev, u32 index);
22+
void ti_sci_inta_msi_domain_free_irqs(struct device *dev);
23+
#endif /* __INCLUDE_LINUX_IRQCHIP_TI_SCI_INTA_H */

0 commit comments

Comments
 (0)