Skip to content

Commit 8a380ed

Browse files
inochisaRevySR
authored andcommitted
FROMLIST: PCI/MSI: Add startup/shutdown for per device domains
As the RISC-V PLIC can not apply affinity setting without calling irq_enable(), it will make the interrupt unavailble when using as an underlying IRQ chip for MSI controller. Implement .irq_startup() and .irq_shutdown() for the PCI MSI and MSI-X templates. For chips that specify MSI_FLAG_PCI_MSI_STARTUP_PARENT, these startup and shutdown the parent as well, which allows the irq on the parent chip to be enabled if the irq is not enabled when allocating. This is necessary for the MSI controllers which use PLIC as underlying IRQ chip. Suggested-by: Thomas Gleixner <[email protected]> Signed-off-by: Inochi Amaoto <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Han Gao <[email protected]>
1 parent 00eee2a commit 8a380ed

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

drivers/pci/msi/irqdomain.c

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,23 @@ static void pci_device_domain_set_desc(msi_alloc_info_t *arg, struct msi_desc *d
148148
arg->hwirq = desc->msi_index;
149149
}
150150

151+
static void cond_shutdown_parent(struct irq_data *data)
152+
{
153+
struct msi_domain_info *info = data->domain->host_data;
154+
155+
if (unlikely(info->flags & MSI_FLAG_PCI_MSI_STARTUP_PARENT))
156+
irq_chip_shutdown_parent(data);
157+
}
158+
159+
static unsigned int cond_startup_parent(struct irq_data *data)
160+
{
161+
struct msi_domain_info *info = data->domain->host_data;
162+
163+
if (unlikely(info->flags & MSI_FLAG_PCI_MSI_STARTUP_PARENT))
164+
return irq_chip_startup_parent(data);
165+
return 0;
166+
}
167+
151168
static __always_inline void cond_mask_parent(struct irq_data *data)
152169
{
153170
struct msi_domain_info *info = data->domain->host_data;
@@ -164,6 +181,23 @@ static __always_inline void cond_unmask_parent(struct irq_data *data)
164181
irq_chip_unmask_parent(data);
165182
}
166183

184+
static void pci_irq_shutdown_msi(struct irq_data *data)
185+
{
186+
struct msi_desc *desc = irq_data_get_msi_desc(data);
187+
188+
pci_msi_mask(desc, BIT(data->irq - desc->irq));
189+
cond_shutdown_parent(data);
190+
}
191+
192+
static unsigned int pci_irq_startup_msi(struct irq_data *data)
193+
{
194+
struct msi_desc *desc = irq_data_get_msi_desc(data);
195+
unsigned int ret = cond_startup_parent(data);
196+
197+
pci_msi_unmask(desc, BIT(data->irq - desc->irq));
198+
return ret;
199+
}
200+
167201
static void pci_irq_mask_msi(struct irq_data *data)
168202
{
169203
struct msi_desc *desc = irq_data_get_msi_desc(data);
@@ -194,6 +228,8 @@ static void pci_irq_unmask_msi(struct irq_data *data)
194228
static const struct msi_domain_template pci_msi_template = {
195229
.chip = {
196230
.name = "PCI-MSI",
231+
.irq_startup = pci_irq_startup_msi,
232+
.irq_shutdown = pci_irq_shutdown_msi,
197233
.irq_mask = pci_irq_mask_msi,
198234
.irq_unmask = pci_irq_unmask_msi,
199235
.irq_write_msi_msg = pci_msi_domain_write_msg,
@@ -210,6 +246,20 @@ static const struct msi_domain_template pci_msi_template = {
210246
},
211247
};
212248

249+
static void pci_irq_shutdown_msix(struct irq_data *data)
250+
{
251+
pci_msix_mask(irq_data_get_msi_desc(data));
252+
cond_shutdown_parent(data);
253+
}
254+
255+
static unsigned int pci_irq_startup_msix(struct irq_data *data)
256+
{
257+
unsigned int ret = cond_startup_parent(data);
258+
259+
pci_msix_unmask(irq_data_get_msi_desc(data));
260+
return ret;
261+
}
262+
213263
static void pci_irq_mask_msix(struct irq_data *data)
214264
{
215265
pci_msix_mask(irq_data_get_msi_desc(data));
@@ -233,6 +283,8 @@ static void pci_msix_prepare_desc(struct irq_domain *domain, msi_alloc_info_t *a
233283
static const struct msi_domain_template pci_msix_template = {
234284
.chip = {
235285
.name = "PCI-MSIX",
286+
.irq_startup = pci_irq_startup_msix,
287+
.irq_shutdown = pci_irq_shutdown_msix,
236288
.irq_mask = pci_irq_mask_msix,
237289
.irq_unmask = pci_irq_unmask_msix,
238290
.irq_write_msi_msg = pci_msi_domain_write_msg,

include/linux/msi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,8 @@ enum {
566566
MSI_FLAG_PARENT_PM_DEV = (1 << 8),
567567
/* Support for parent mask/unmask */
568568
MSI_FLAG_PCI_MSI_MASK_PARENT = (1 << 9),
569+
/* Support for parent startup/shutdown */
570+
MSI_FLAG_PCI_MSI_STARTUP_PARENT = (1 << 10),
569571

570572
/* Mask for the generic functionality */
571573
MSI_GENERIC_FLAGS_MASK = GENMASK(15, 0),

0 commit comments

Comments
 (0)