Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

irqchip/imx-mu-msi: Switch to MSI parent

All platform MSI users and the PCI/MSI code handle per device MSI domains
when the irqdomain associated to the device provides MSI parent
functionality.

Remove the "global" platform domain related code and provide the MSI parent
functionality by filling in msi_parent_ops.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Anna-Maria Behnsen <anna-maria@linutronix.de>
Signed-off-by: Shivamurthy Shastri <shivamurthy.shastri@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240623142235.574932935@linutronix.de



+24 -27
+1
drivers/irqchip/Kconfig
··· 492 492 select IRQ_DOMAIN 493 493 select IRQ_DOMAIN_HIERARCHY 494 494 select GENERIC_MSI_IRQ 495 + select IRQ_MSI_LIB 495 496 help 496 497 Provide a driver for the i.MX Messaging Unit block used as a 497 498 CPU-to-CPU MSI controller. This requires a specially crafted DT
+21 -27
drivers/irqchip/irq-imx-mu-msi.c
··· 24 24 #include <linux/pm_domain.h> 25 25 #include <linux/spinlock.h> 26 26 27 + #include "irq-msi-lib.h" 28 + 27 29 #define IMX_MU_CHANS 4 28 30 29 31 enum imx_mu_xcr { ··· 116 114 imx_mu_read(msi_data, msi_data->cfg->xRR + data->hwirq * 4); 117 115 } 118 116 119 - static struct irq_chip imx_mu_msi_irq_chip = { 120 - .name = "MU-MSI", 121 - .irq_ack = irq_chip_ack_parent, 122 - }; 123 - 124 - static struct msi_domain_ops imx_mu_msi_irq_ops = { 125 - }; 126 - 127 - static struct msi_domain_info imx_mu_msi_domain_info = { 128 - .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS), 129 - .ops = &imx_mu_msi_irq_ops, 130 - .chip = &imx_mu_msi_irq_chip, 131 - }; 132 - 133 117 static void imx_mu_msi_parent_compose_msg(struct irq_data *data, 134 118 struct msi_msg *msg) 135 119 { ··· 183 195 } 184 196 185 197 static const struct irq_domain_ops imx_mu_msi_domain_ops = { 198 + .select = msi_lib_irq_domain_select, 186 199 .alloc = imx_mu_msi_domain_irq_alloc, 187 200 .free = imx_mu_msi_domain_irq_free, 188 201 }; ··· 205 216 chained_irq_exit(chip, desc); 206 217 } 207 218 219 + #define IMX_MU_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 220 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 221 + MSI_FLAG_PARENT_PM_DEV) 222 + 223 + #define IMX_MU_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK) 224 + 225 + static const struct msi_parent_ops imx_mu_msi_parent_ops = { 226 + .supported_flags = IMX_MU_MSI_FLAGS_SUPPORTED, 227 + .required_flags = IMX_MU_MSI_FLAGS_REQUIRED, 228 + .bus_select_token = DOMAIN_BUS_NEXUS, 229 + .bus_select_mask = MATCH_PLATFORM_MSI, 230 + .prefix = "MU-MSI-", 231 + .init_dev_msi_info = msi_lib_init_dev_msi_info, 232 + }; 233 + 208 234 static int imx_mu_msi_domains_init(struct imx_mu_msi *msi_data, struct device *dev) 209 235 { 210 236 struct fwnode_handle *fwnodes = dev_fwnode(dev); ··· 234 230 } 235 231 236 232 irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS); 237 - 238 - msi_data->msi_domain = platform_msi_create_irq_domain(fwnodes, 239 - &imx_mu_msi_domain_info, 240 - parent); 241 - 242 - if (!msi_data->msi_domain) { 243 - dev_err(dev, "failed to create MSI domain\n"); 244 - irq_domain_remove(parent); 245 - return -ENOMEM; 246 - } 247 - 248 - irq_domain_set_pm_device(msi_data->msi_domain, dev); 249 - 233 + parent->dev = parent->pm_dev = dev; 234 + parent->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT; 235 + parent->msi_parent_ops = &imx_mu_msi_parent_ops; 250 236 return 0; 251 237 } 252 238
+2
drivers/irqchip/irq-msi-lib.c
··· 94 94 /* Chip updates for all child bus types */ 95 95 if (!info->chip->irq_eoi) 96 96 info->chip->irq_eoi = irq_chip_eoi_parent; 97 + if (!info->chip->irq_ack) 98 + info->chip->irq_ack = irq_chip_ack_parent; 97 99 98 100 /* 99 101 * The device MSI domain can never have a set affinity callback. It