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

irqchip/gic_v3_mbi: Switch over to parent domain

The MBI chip creates two MSI domains:
- PCI/MSI
- Platform device domain

Both have the MBI domain as parent and differ slightly in the interrupt
chip callbacks and the platform device domain supports level type
signaling.

Convert it over to the MSI parent domain mechanism by:

- Providing the required templates

- Implementing a custom init_dev_msi_info() callback which sets the chip
callbacks and the level support flags depending on the domain bus token
type of the per device domain.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Link: https://lore.kernel.org/r/20240623142235.455849114@linutronix.de

+50 -86
+50 -86
drivers/irqchip/irq-gic-v3-mbi.c
··· 18 18 19 19 #include <linux/irqchip/arm-gic-v3.h> 20 20 21 + #include "irq-msi-lib.h" 22 + 21 23 struct mbi_range { 22 24 u32 spi_start; 23 25 u32 nr_spis; ··· 140 138 } 141 139 142 140 static const struct irq_domain_ops mbi_domain_ops = { 141 + .select = msi_lib_irq_domain_select, 143 142 .alloc = mbi_irq_domain_alloc, 144 143 .free = mbi_irq_domain_free, 145 144 }; ··· 154 151 iommu_dma_compose_msi_msg(irq_data_get_msi_desc(data), msg); 155 152 } 156 153 157 - #ifdef CONFIG_PCI_MSI 158 - /* PCI-specific irqchip */ 159 - static void mbi_mask_msi_irq(struct irq_data *d) 160 - { 161 - pci_msi_mask_irq(d); 162 - irq_chip_mask_parent(d); 163 - } 164 - 165 - static void mbi_unmask_msi_irq(struct irq_data *d) 166 - { 167 - pci_msi_unmask_irq(d); 168 - irq_chip_unmask_parent(d); 169 - } 170 - 171 - static struct irq_chip mbi_msi_irq_chip = { 172 - .name = "MSI", 173 - .irq_mask = mbi_mask_msi_irq, 174 - .irq_unmask = mbi_unmask_msi_irq, 175 - .irq_eoi = irq_chip_eoi_parent, 176 - .irq_compose_msi_msg = mbi_compose_msi_msg, 177 - }; 178 - 179 - static struct msi_domain_info mbi_msi_domain_info = { 180 - .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 181 - MSI_FLAG_PCI_MSIX | MSI_FLAG_MULTI_PCI_MSI), 182 - .chip = &mbi_msi_irq_chip, 183 - }; 184 - 185 - static int mbi_allocate_pci_domain(struct irq_domain *nexus_domain, 186 - struct irq_domain **pci_domain) 187 - { 188 - *pci_domain = pci_msi_create_irq_domain(nexus_domain->parent->fwnode, 189 - &mbi_msi_domain_info, 190 - nexus_domain); 191 - if (!*pci_domain) 192 - return -ENOMEM; 193 - 194 - return 0; 195 - } 196 - #else 197 - static int mbi_allocate_pci_domain(struct irq_domain *nexus_domain, 198 - struct irq_domain **pci_domain) 199 - { 200 - *pci_domain = NULL; 201 - return 0; 202 - } 203 - #endif 204 - 205 154 static void mbi_compose_mbi_msg(struct irq_data *data, struct msi_msg *msg) 206 155 { 207 156 mbi_compose_msi_msg(data, msg); ··· 165 210 iommu_dma_compose_msi_msg(irq_data_get_msi_desc(data), &msg[1]); 166 211 } 167 212 168 - /* Platform-MSI specific irqchip */ 169 - static struct irq_chip mbi_pmsi_irq_chip = { 170 - .name = "pMSI", 171 - .irq_set_type = irq_chip_set_type_parent, 172 - .irq_compose_msi_msg = mbi_compose_mbi_msg, 173 - .flags = IRQCHIP_SUPPORTS_LEVEL_MSI, 174 - }; 175 - 176 - static struct msi_domain_ops mbi_pmsi_ops = { 177 - }; 178 - 179 - static struct msi_domain_info mbi_pmsi_domain_info = { 180 - .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 181 - MSI_FLAG_LEVEL_CAPABLE), 182 - .ops = &mbi_pmsi_ops, 183 - .chip = &mbi_pmsi_irq_chip, 184 - }; 185 - 186 - static int mbi_allocate_domains(struct irq_domain *parent) 213 + static bool mbi_init_dev_msi_info(struct device *dev, struct irq_domain *domain, 214 + struct irq_domain *real_parent, struct msi_domain_info *info) 187 215 { 188 - struct irq_domain *nexus_domain, *pci_domain, *plat_domain; 189 - int err; 216 + if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info)) 217 + return false; 218 + 219 + switch (info->bus_token) { 220 + case DOMAIN_BUS_PCI_DEVICE_MSI: 221 + case DOMAIN_BUS_PCI_DEVICE_MSIX: 222 + info->chip->irq_compose_msi_msg = mbi_compose_msi_msg; 223 + return true; 224 + 225 + case DOMAIN_BUS_DEVICE_MSI: 226 + info->chip->irq_compose_msi_msg = mbi_compose_mbi_msg; 227 + info->chip->irq_set_type = irq_chip_set_type_parent; 228 + info->chip->flags |= IRQCHIP_SUPPORTS_LEVEL_MSI; 229 + info->flags |= MSI_FLAG_LEVEL_CAPABLE; 230 + return true; 231 + 232 + default: 233 + WARN_ON_ONCE(1); 234 + return false; 235 + } 236 + } 237 + 238 + #define MBI_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS | \ 239 + MSI_FLAG_USE_DEF_CHIP_OPS | \ 240 + MSI_FLAG_PCI_MSI_MASK_PARENT) 241 + 242 + #define MBI_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 243 + MSI_FLAG_PCI_MSIX | \ 244 + MSI_FLAG_MULTI_PCI_MSI) 245 + 246 + static const struct msi_parent_ops gic_v3_mbi_msi_parent_ops = { 247 + .supported_flags = MBI_MSI_FLAGS_SUPPORTED, 248 + .required_flags = MBI_MSI_FLAGS_REQUIRED, 249 + .bus_select_token = DOMAIN_BUS_NEXUS, 250 + .bus_select_mask = MATCH_PCI_MSI | MATCH_PLATFORM_MSI, 251 + .prefix = "MBI-", 252 + .init_dev_msi_info = mbi_init_dev_msi_info, 253 + }; 254 + 255 + static int mbi_allocate_domain(struct irq_domain *parent) 256 + { 257 + struct irq_domain *nexus_domain; 190 258 191 259 nexus_domain = irq_domain_create_hierarchy(parent, 0, 0, parent->fwnode, 192 260 &mbi_domain_ops, NULL); ··· 217 239 return -ENOMEM; 218 240 219 241 irq_domain_update_bus_token(nexus_domain, DOMAIN_BUS_NEXUS); 220 - 221 - err = mbi_allocate_pci_domain(nexus_domain, &pci_domain); 222 - 223 - plat_domain = platform_msi_create_irq_domain(parent->fwnode, 224 - &mbi_pmsi_domain_info, 225 - nexus_domain); 226 - 227 - if (err || !plat_domain) { 228 - if (plat_domain) 229 - irq_domain_remove(plat_domain); 230 - if (pci_domain) 231 - irq_domain_remove(pci_domain); 232 - irq_domain_remove(nexus_domain); 233 - return -ENOMEM; 234 - } 235 - 242 + nexus_domain->flags |= IRQ_DOMAIN_FLAG_MSI_PARENT; 243 + nexus_domain->msi_parent_ops = &gic_v3_mbi_msi_parent_ops; 236 244 return 0; 237 245 } 238 246 ··· 281 317 282 318 pr_info("Using MBI frame %pa\n", &mbi_phys_base); 283 319 284 - ret = mbi_allocate_domains(parent); 320 + ret = mbi_allocate_domain(parent); 285 321 if (ret) 286 322 goto err_free_mbi; 287 323