Skip to content

Commit b37a8d3

Browse files
inochisaRevySR
authored andcommitted
FROMLIST: PCI/MSI: Add startup/shutdown support for per device MSI[X] domains
As The RISC-V PLIC can not apply affinity setting without calling irq_enable(), it will make the interrupt unavaible when using as an underlying irq chip for MSI controller. Introduce the irq_startup/irq_shutdown for PCI domain template with new MSI domain flag. This allow the PLIC can be properly configurated when calling irq_startup(). 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 972f90f commit b37a8d3

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 __always_inline 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 __always_inline 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)