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

irqchip/gic-v5: Add GICv5 ITS support

The GICv5 architecture implements Interrupt Translation Service
(ITS) components in order to translate events coming from peripherals
into interrupt events delivered to the connected IRSes.

Events (ie MSI memory writes to ITS translate frame), are translated
by the ITS using tables kept in memory.

ITS translation tables for peripherals is kept in memory storage
(device table [DT] and Interrupt Translation Table [ITT]) that
is allocated by the driver on boot.

Both tables can be 1- or 2-level; the structure is chosen by the
driver after probing the ITS HW parameters and checking the
allowed table splits and supported {device/event}_IDbits.

DT table entries are allocated on demand (ie when a device is
probed); the DT table is sized using the number of supported
deviceID bits in that that's a system design decision (ie the
number of deviceID bits implemented should reflect the number
of devices expected in a system) therefore it makes sense to
allocate a DT table that can cater for the maximum number of
devices.

DT and ITT tables are allocated using the kmalloc interface;
the allocation size may be smaller than a page or larger,
and must provide contiguous memory pages.

LPIs INTIDs backing the device events are allocated one-by-one
and only upon Linux IRQ allocation; this to avoid preallocating
a large number of LPIs to cover the HW device MSI vector
size whereas few MSI entries are actually enabled by a device.

ITS cacheability/shareability attributes are programmed
according to the provided firmware ITS description.

The GICv5 partially reuses the GICv3 ITS MSI parent infrastructure
and adds functions required to retrieve the ITS translate frame
addresses out of msi-map and msi-parent properties to implement
the GICv5 ITS MSI parent callbacks.

Co-developed-by: Sascha Bischoff <sascha.bischoff@arm.com>
Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
Co-developed-by: Timothy Hayes <timothy.hayes@arm.com>
Signed-off-by: Timothy Hayes <timothy.hayes@arm.com>
Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20250703-gicv5-host-v7-28-12e71f1b3528@kernel.org
Signed-off-by: Marc Zyngier <maz@kernel.org>

authored by

Lorenzo Pieralisi and committed by
Marc Zyngier
57d72196 8b65db1e

+1561 -1
+1
MAINTAINERS
··· 1970 1970 L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 1971 1971 S: Maintained 1972 1972 F: Documentation/devicetree/bindings/interrupt-controller/arm,gic-v5*.yaml 1973 + F: drivers/irqchip/irq-gic-its-msi-parent.[ch] 1973 1974 F: drivers/irqchip/irq-gic-v5*.[ch] 1974 1975 F: include/linux/irqchip/arm-gic-v5.h 1975 1976
+3
drivers/irqchip/Kconfig
··· 62 62 bool 63 63 select IRQ_DOMAIN_HIERARCHY 64 64 select GENERIC_IRQ_EFFECTIVE_AFF_MASK 65 + select GENERIC_MSI_IRQ 66 + select IRQ_MSI_LIB 67 + select ARM_GIC_ITS_PARENT 65 68 66 69 config ARM_NVIC 67 70 bool
+1 -1
drivers/irqchip/Makefile
··· 37 37 obj-$(CONFIG_ARM_GIC_V3_ITS) += irq-gic-v3-its.o irq-gic-v4.o 38 38 obj-$(CONFIG_ARM_GIC_V3_ITS_FSL_MC) += irq-gic-v3-its-fsl-mc-msi.o 39 39 obj-$(CONFIG_PARTITION_PERCPU) += irq-partition-percpu.o 40 - obj-$(CONFIG_ARM_GIC_V5) += irq-gic-v5.o irq-gic-v5-irs.o 40 + obj-$(CONFIG_ARM_GIC_V5) += irq-gic-v5.o irq-gic-v5-irs.o irq-gic-v5-its.o 41 41 obj-$(CONFIG_HISILICON_IRQ_MBIGEN) += irq-mbigen.o 42 42 obj-$(CONFIG_ARM_NVIC) += irq-nvic.o 43 43 obj-$(CONFIG_ARM_VIC) += irq-vic.o
+166
drivers/irqchip/irq-gic-its-msi-parent.c
··· 5 5 // Copyright (C) 2022 Intel 6 6 7 7 #include <linux/acpi_iort.h> 8 + #include <linux/of_address.h> 8 9 #include <linux/pci.h> 9 10 10 11 #include "irq-gic-its-msi-parent.h" ··· 18 17 #define ITS_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK | \ 19 18 MSI_FLAG_PCI_MSIX | \ 20 19 MSI_FLAG_MULTI_PCI_MSI) 20 + 21 + static int its_translate_frame_address(struct device_node *msi_node, phys_addr_t *pa) 22 + { 23 + struct resource res; 24 + int ret; 25 + 26 + ret = of_property_match_string(msi_node, "reg-names", "ns-translate"); 27 + if (ret < 0) 28 + return ret; 29 + 30 + ret = of_address_to_resource(msi_node, ret, &res); 31 + if (ret) 32 + return ret; 33 + 34 + *pa = res.start; 35 + return 0; 36 + } 21 37 22 38 #ifdef CONFIG_PCI_MSI 23 39 static int its_pci_msi_vec_count(struct pci_dev *pdev, void *data) ··· 100 82 msi_info = msi_get_domain_info(domain->parent); 101 83 return msi_info->ops->msi_prepare(domain->parent, dev, nvec, info); 102 84 } 85 + 86 + static int its_v5_pci_msi_prepare(struct irq_domain *domain, struct device *dev, 87 + int nvec, msi_alloc_info_t *info) 88 + { 89 + struct device_node *msi_node = NULL; 90 + struct msi_domain_info *msi_info; 91 + struct pci_dev *pdev; 92 + phys_addr_t pa; 93 + u32 rid; 94 + int ret; 95 + 96 + if (!dev_is_pci(dev)) 97 + return -EINVAL; 98 + 99 + pdev = to_pci_dev(dev); 100 + 101 + rid = pci_msi_map_rid_ctlr_node(pdev, &msi_node); 102 + if (!msi_node) 103 + return -ENODEV; 104 + 105 + ret = its_translate_frame_address(msi_node, &pa); 106 + if (ret) 107 + return -ENODEV; 108 + 109 + of_node_put(msi_node); 110 + 111 + /* ITS specific DeviceID */ 112 + info->scratchpad[0].ul = rid; 113 + /* ITS translate frame physical address */ 114 + info->scratchpad[1].ul = pa; 115 + 116 + /* Always allocate power of two vectors */ 117 + nvec = roundup_pow_of_two(nvec); 118 + 119 + msi_info = msi_get_domain_info(domain->parent); 120 + return msi_info->ops->msi_prepare(domain->parent, dev, nvec, info); 121 + } 103 122 #else /* CONFIG_PCI_MSI */ 104 123 #define its_pci_msi_prepare NULL 124 + #define its_v5_pci_msi_prepare NULL 105 125 #endif /* !CONFIG_PCI_MSI */ 106 126 107 127 static int of_pmsi_get_dev_id(struct irq_domain *domain, struct device *dev, ··· 174 118 return ret; 175 119 } 176 120 121 + static int of_v5_pmsi_get_msi_info(struct irq_domain *domain, struct device *dev, 122 + u32 *dev_id, phys_addr_t *pa) 123 + { 124 + int ret, index = 0; 125 + /* 126 + * Retrieve the DeviceID and the ITS translate frame node pointer 127 + * out of the msi-parent property. 128 + */ 129 + do { 130 + struct of_phandle_args args; 131 + 132 + ret = of_parse_phandle_with_args(dev->of_node, 133 + "msi-parent", "#msi-cells", 134 + index, &args); 135 + if (ret) 136 + break; 137 + /* 138 + * The IRQ domain fwnode is the msi controller parent 139 + * in GICv5 (where the msi controller nodes are the 140 + * ITS translate frames). 141 + */ 142 + if (args.np->parent == irq_domain_get_of_node(domain)) { 143 + if (WARN_ON(args.args_count != 1)) 144 + return -EINVAL; 145 + *dev_id = args.args[0]; 146 + 147 + ret = its_translate_frame_address(args.np, pa); 148 + if (ret) 149 + return -ENODEV; 150 + break; 151 + } 152 + index++; 153 + } while (!ret); 154 + 155 + if (ret) { 156 + struct device_node *np = NULL; 157 + 158 + ret = of_map_id(dev->of_node, dev->id, "msi-map", "msi-map-mask", &np, dev_id); 159 + if (np) { 160 + ret = its_translate_frame_address(np, pa); 161 + of_node_put(np); 162 + } 163 + } 164 + 165 + return ret; 166 + } 167 + 177 168 int __weak iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id) 178 169 { 179 170 return -1; ··· 249 146 msi_info = msi_get_domain_info(domain->parent); 250 147 return msi_info->ops->msi_prepare(domain->parent, 251 148 dev, nvec, info); 149 + } 150 + 151 + static int its_v5_pmsi_prepare(struct irq_domain *domain, struct device *dev, 152 + int nvec, msi_alloc_info_t *info) 153 + { 154 + struct msi_domain_info *msi_info; 155 + phys_addr_t pa; 156 + u32 dev_id; 157 + int ret; 158 + 159 + if (!dev->of_node) 160 + return -ENODEV; 161 + 162 + ret = of_v5_pmsi_get_msi_info(domain->parent, dev, &dev_id, &pa); 163 + if (ret) 164 + return ret; 165 + 166 + /* ITS specific DeviceID */ 167 + info->scratchpad[0].ul = dev_id; 168 + /* ITS translate frame physical address */ 169 + info->scratchpad[1].ul = pa; 170 + 171 + /* Allocate always as a power of 2 */ 172 + nvec = roundup_pow_of_two(nvec); 173 + 174 + msi_info = msi_get_domain_info(domain->parent); 175 + return msi_info->ops->msi_prepare(domain->parent, dev, nvec, info); 252 176 } 253 177 254 178 static void its_msi_teardown(struct irq_domain *domain, msi_alloc_info_t *info) ··· 329 199 return true; 330 200 } 331 201 202 + static bool its_v5_init_dev_msi_info(struct device *dev, struct irq_domain *domain, 203 + struct irq_domain *real_parent, struct msi_domain_info *info) 204 + { 205 + if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info)) 206 + return false; 207 + 208 + switch (info->bus_token) { 209 + case DOMAIN_BUS_PCI_DEVICE_MSI: 210 + case DOMAIN_BUS_PCI_DEVICE_MSIX: 211 + info->ops->msi_prepare = its_v5_pci_msi_prepare; 212 + info->ops->msi_teardown = its_msi_teardown; 213 + break; 214 + case DOMAIN_BUS_DEVICE_MSI: 215 + case DOMAIN_BUS_WIRED_TO_MSI: 216 + info->ops->msi_prepare = its_v5_pmsi_prepare; 217 + info->ops->msi_teardown = its_msi_teardown; 218 + break; 219 + default: 220 + /* Confused. How did the lib return true? */ 221 + WARN_ON_ONCE(1); 222 + return false; 223 + } 224 + 225 + return true; 226 + } 227 + 332 228 const struct msi_parent_ops gic_v3_its_msi_parent_ops = { 333 229 .supported_flags = ITS_MSI_FLAGS_SUPPORTED, 334 230 .required_flags = ITS_MSI_FLAGS_REQUIRED, ··· 363 207 .bus_select_mask = MATCH_PCI_MSI | MATCH_PLATFORM_MSI, 364 208 .prefix = "ITS-", 365 209 .init_dev_msi_info = its_init_dev_msi_info, 210 + }; 211 + 212 + const struct msi_parent_ops gic_v5_its_msi_parent_ops = { 213 + .supported_flags = ITS_MSI_FLAGS_SUPPORTED, 214 + .required_flags = ITS_MSI_FLAGS_REQUIRED, 215 + .chip_flags = MSI_CHIP_FLAG_SET_EOI, 216 + .bus_select_token = DOMAIN_BUS_NEXUS, 217 + .bus_select_mask = MATCH_PCI_MSI | MATCH_PLATFORM_MSI, 218 + .prefix = "ITS-v5-", 219 + .init_dev_msi_info = its_v5_init_dev_msi_info, 366 220 };
+1
drivers/irqchip/irq-gic-its-msi-parent.h
··· 7 7 #define _IRQ_GIC_ITS_MSI_PARENT_H 8 8 9 9 extern const struct msi_parent_ops gic_v3_its_msi_parent_ops; 10 + extern const struct msi_parent_ops gic_v5_its_msi_parent_ops; 10 11 11 12 #endif /* _IRQ_GIC_ITS_MSI_PARENT_H */
+24
drivers/irqchip/irq-gic-v5-irs.c
··· 484 484 GICV5_IRS_CR0_IDLE, NULL); 485 485 } 486 486 487 + void gicv5_irs_syncr(void) 488 + { 489 + struct gicv5_irs_chip_data *irs_data; 490 + u32 syncr; 491 + 492 + irs_data = list_first_entry_or_null(&irs_nodes, struct gicv5_irs_chip_data, entry); 493 + if (WARN_ON_ONCE(!irs_data)) 494 + return; 495 + 496 + syncr = FIELD_PREP(GICV5_IRS_SYNCR_SYNC, 1); 497 + irs_writel_relaxed(irs_data, syncr, GICV5_IRS_SYNCR); 498 + 499 + gicv5_wait_for_op(irs_data->irs_base, GICV5_IRS_SYNC_STATUSR, 500 + GICV5_IRS_SYNC_STATUSR_IDLE); 501 + } 502 + 487 503 int gicv5_irs_register_cpu(int cpuid) 488 504 { 489 505 struct gicv5_irs_chip_data *irs_data; ··· 794 778 } 795 779 796 780 return 0; 781 + } 782 + 783 + void __init gicv5_irs_its_probe(void) 784 + { 785 + struct gicv5_irs_chip_data *irs_data; 786 + 787 + list_for_each_entry(irs_data, &irs_nodes, entry) 788 + gicv5_its_of_probe(to_of_node(irs_data->fwnode)); 797 789 } 798 790 799 791 int __init gicv5_irs_of_probe(struct device_node *parent)
+1206
drivers/irqchip/irq-gic-v5-its.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Copyright (C) 2024-2025 ARM Limited, All Rights Reserved. 4 + */ 5 + 6 + #define pr_fmt(fmt) "GICv5 ITS: " fmt 7 + 8 + #include <linux/bitmap.h> 9 + #include <linux/iommu.h> 10 + #include <linux/init.h> 11 + #include <linux/kernel.h> 12 + #include <linux/msi.h> 13 + #include <linux/of.h> 14 + #include <linux/of_address.h> 15 + #include <linux/of_irq.h> 16 + #include <linux/slab.h> 17 + 18 + #include <linux/irqchip.h> 19 + #include <linux/irqchip/arm-gic-v5.h> 20 + #include <linux/irqchip/irq-msi-lib.h> 21 + 22 + #include "irq-gic-its-msi-parent.h" 23 + 24 + #define ITS_FLAGS_NON_COHERENT BIT(0) 25 + 26 + struct gicv5_its_chip_data { 27 + struct xarray its_devices; 28 + struct mutex dev_alloc_lock; 29 + struct fwnode_handle *fwnode; 30 + struct gicv5_its_devtab_cfg devtab_cfgr; 31 + void __iomem *its_base; 32 + u32 flags; 33 + unsigned int msi_domain_flags; 34 + }; 35 + 36 + struct gicv5_its_dev { 37 + struct gicv5_its_chip_data *its_node; 38 + struct gicv5_its_itt_cfg itt_cfg; 39 + unsigned long *event_map; 40 + u32 device_id; 41 + u32 num_events; 42 + phys_addr_t its_trans_phys_base; 43 + }; 44 + 45 + static u32 its_readl_relaxed(struct gicv5_its_chip_data *its_node, const u32 reg_offset) 46 + { 47 + return readl_relaxed(its_node->its_base + reg_offset); 48 + } 49 + 50 + static void its_writel_relaxed(struct gicv5_its_chip_data *its_node, const u32 val, 51 + const u32 reg_offset) 52 + { 53 + writel_relaxed(val, its_node->its_base + reg_offset); 54 + } 55 + 56 + static void its_writeq_relaxed(struct gicv5_its_chip_data *its_node, const u64 val, 57 + const u32 reg_offset) 58 + { 59 + writeq_relaxed(val, its_node->its_base + reg_offset); 60 + } 61 + 62 + static void gicv5_its_dcache_clean(struct gicv5_its_chip_data *its, void *start, 63 + size_t sz) 64 + { 65 + void *end = start + sz; 66 + 67 + if (its->flags & ITS_FLAGS_NON_COHERENT) 68 + dcache_clean_inval_poc((unsigned long)start, (unsigned long)end); 69 + else 70 + dsb(ishst); 71 + } 72 + 73 + static void its_write_table_entry(struct gicv5_its_chip_data *its, __le64 *entry, 74 + u64 val) 75 + { 76 + WRITE_ONCE(*entry, cpu_to_le64(val)); 77 + gicv5_its_dcache_clean(its, entry, sizeof(*entry)); 78 + } 79 + 80 + #define devtab_cfgr_field(its, f) \ 81 + FIELD_GET(GICV5_ITS_DT_CFGR_##f, (its)->devtab_cfgr.cfgr) 82 + 83 + static int gicv5_its_cache_sync(struct gicv5_its_chip_data *its) 84 + { 85 + return gicv5_wait_for_op_atomic(its->its_base, GICV5_ITS_STATUSR, 86 + GICV5_ITS_STATUSR_IDLE, NULL); 87 + } 88 + 89 + static void gicv5_its_syncr(struct gicv5_its_chip_data *its, 90 + struct gicv5_its_dev *its_dev) 91 + { 92 + u64 syncr; 93 + 94 + syncr = FIELD_PREP(GICV5_ITS_SYNCR_SYNC, 1) | 95 + FIELD_PREP(GICV5_ITS_SYNCR_DEVICEID, its_dev->device_id); 96 + 97 + its_writeq_relaxed(its, syncr, GICV5_ITS_SYNCR); 98 + 99 + gicv5_wait_for_op(its->its_base, GICV5_ITS_SYNC_STATUSR, GICV5_ITS_SYNC_STATUSR_IDLE); 100 + } 101 + 102 + /* Number of bits required for each L2 {device/interrupt translation} table size */ 103 + #define ITS_L2SZ_64K_L2_BITS 13 104 + #define ITS_L2SZ_16K_L2_BITS 11 105 + #define ITS_L2SZ_4K_L2_BITS 9 106 + 107 + static unsigned int gicv5_its_l2sz_to_l2_bits(unsigned int sz) 108 + { 109 + switch (sz) { 110 + case GICV5_ITS_DT_ITT_CFGR_L2SZ_64k: 111 + return ITS_L2SZ_64K_L2_BITS; 112 + case GICV5_ITS_DT_ITT_CFGR_L2SZ_16k: 113 + return ITS_L2SZ_16K_L2_BITS; 114 + case GICV5_ITS_DT_ITT_CFGR_L2SZ_4k: 115 + default: 116 + return ITS_L2SZ_4K_L2_BITS; 117 + } 118 + } 119 + 120 + static int gicv5_its_itt_cache_inv(struct gicv5_its_chip_data *its, u32 device_id, 121 + u16 event_id) 122 + { 123 + u32 eventr, eidr; 124 + u64 didr; 125 + 126 + didr = FIELD_PREP(GICV5_ITS_DIDR_DEVICEID, device_id); 127 + eidr = FIELD_PREP(GICV5_ITS_EIDR_EVENTID, event_id); 128 + eventr = FIELD_PREP(GICV5_ITS_INV_EVENTR_I, 0x1); 129 + 130 + its_writeq_relaxed(its, didr, GICV5_ITS_DIDR); 131 + its_writel_relaxed(its, eidr, GICV5_ITS_EIDR); 132 + its_writel_relaxed(its, eventr, GICV5_ITS_INV_EVENTR); 133 + 134 + return gicv5_its_cache_sync(its); 135 + } 136 + 137 + static void gicv5_its_free_itt_linear(struct gicv5_its_dev *its_dev) 138 + { 139 + kfree(its_dev->itt_cfg.linear.itt); 140 + } 141 + 142 + static void gicv5_its_free_itt_two_level(struct gicv5_its_dev *its_dev) 143 + { 144 + unsigned int i, num_ents = its_dev->itt_cfg.l2.num_l1_ents; 145 + 146 + for (i = 0; i < num_ents; i++) 147 + kfree(its_dev->itt_cfg.l2.l2ptrs[i]); 148 + 149 + kfree(its_dev->itt_cfg.l2.l2ptrs); 150 + kfree(its_dev->itt_cfg.l2.l1itt); 151 + } 152 + 153 + static void gicv5_its_free_itt(struct gicv5_its_dev *its_dev) 154 + { 155 + if (!its_dev->itt_cfg.l2itt) 156 + gicv5_its_free_itt_linear(its_dev); 157 + else 158 + gicv5_its_free_itt_two_level(its_dev); 159 + } 160 + 161 + static int gicv5_its_create_itt_linear(struct gicv5_its_chip_data *its, 162 + struct gicv5_its_dev *its_dev, 163 + unsigned int event_id_bits) 164 + { 165 + unsigned int num_ents = BIT(event_id_bits); 166 + __le64 *itt; 167 + 168 + itt = kcalloc(num_ents, sizeof(*itt), GFP_KERNEL); 169 + if (!itt) 170 + return -ENOMEM; 171 + 172 + its_dev->itt_cfg.linear.itt = itt; 173 + its_dev->itt_cfg.linear.num_ents = num_ents; 174 + its_dev->itt_cfg.l2itt = false; 175 + its_dev->itt_cfg.event_id_bits = event_id_bits; 176 + 177 + gicv5_its_dcache_clean(its, itt, num_ents * sizeof(*itt)); 178 + 179 + return 0; 180 + } 181 + 182 + /* 183 + * Allocate a two-level ITT. All ITT entries are allocated in one go, unlike 184 + * with the device table. Span may be used to limit the second level table 185 + * size, where possible. 186 + */ 187 + static int gicv5_its_create_itt_two_level(struct gicv5_its_chip_data *its, 188 + struct gicv5_its_dev *its_dev, 189 + unsigned int event_id_bits, 190 + unsigned int itt_l2sz, 191 + unsigned int num_events) 192 + { 193 + unsigned int l1_bits, l2_bits, span, events_per_l2_table; 194 + unsigned int i, complete_tables, final_span, num_ents; 195 + __le64 *itt_l1, *itt_l2, **l2ptrs; 196 + int ret; 197 + u64 val; 198 + 199 + ret = gicv5_its_l2sz_to_l2_bits(itt_l2sz); 200 + if (ret >= event_id_bits) { 201 + pr_debug("Incorrect l2sz (0x%x) for %u EventID bits. Cannot allocate ITT\n", 202 + itt_l2sz, event_id_bits); 203 + return -EINVAL; 204 + } 205 + 206 + l2_bits = ret; 207 + 208 + l1_bits = event_id_bits - l2_bits; 209 + 210 + num_ents = BIT(l1_bits); 211 + 212 + itt_l1 = kcalloc(num_ents, sizeof(*itt_l1), GFP_KERNEL); 213 + if (!itt_l1) 214 + return -ENOMEM; 215 + 216 + l2ptrs = kcalloc(num_ents, sizeof(*l2ptrs), GFP_KERNEL); 217 + if (!l2ptrs) { 218 + kfree(itt_l1); 219 + return -ENOMEM; 220 + } 221 + 222 + its_dev->itt_cfg.l2.l2ptrs = l2ptrs; 223 + 224 + its_dev->itt_cfg.l2.l2sz = itt_l2sz; 225 + its_dev->itt_cfg.l2.l1itt = itt_l1; 226 + its_dev->itt_cfg.l2.num_l1_ents = num_ents; 227 + its_dev->itt_cfg.l2itt = true; 228 + its_dev->itt_cfg.event_id_bits = event_id_bits; 229 + 230 + /* 231 + * Need to determine how many entries there are per L2 - this is based 232 + * on the number of bits in the table. 233 + */ 234 + events_per_l2_table = BIT(l2_bits); 235 + complete_tables = num_events / events_per_l2_table; 236 + final_span = order_base_2(num_events % events_per_l2_table); 237 + 238 + for (i = 0; i < num_ents; i++) { 239 + size_t l2sz; 240 + 241 + span = i == complete_tables ? final_span : l2_bits; 242 + 243 + itt_l2 = kcalloc(BIT(span), sizeof(*itt_l2), GFP_KERNEL); 244 + if (!itt_l2) { 245 + ret = -ENOMEM; 246 + goto out_free; 247 + } 248 + 249 + its_dev->itt_cfg.l2.l2ptrs[i] = itt_l2; 250 + 251 + l2sz = BIT(span) * sizeof(*itt_l2); 252 + 253 + gicv5_its_dcache_clean(its, itt_l2, l2sz); 254 + 255 + val = (virt_to_phys(itt_l2) & GICV5_ITTL1E_L2_ADDR_MASK) | 256 + FIELD_PREP(GICV5_ITTL1E_SPAN, span) | 257 + FIELD_PREP(GICV5_ITTL1E_VALID, 0x1); 258 + 259 + WRITE_ONCE(itt_l1[i], cpu_to_le64(val)); 260 + } 261 + 262 + gicv5_its_dcache_clean(its, itt_l1, num_ents * sizeof(*itt_l1)); 263 + 264 + return 0; 265 + 266 + out_free: 267 + for (i = i - 1; i >= 0; i--) 268 + kfree(its_dev->itt_cfg.l2.l2ptrs[i]); 269 + 270 + kfree(its_dev->itt_cfg.l2.l2ptrs); 271 + kfree(itt_l1); 272 + return ret; 273 + } 274 + 275 + /* 276 + * Function to check whether the device table or ITT table support 277 + * a two-level table and if so depending on the number of id_bits 278 + * requested, determine whether a two-level table is required. 279 + * 280 + * Return the 2-level size value if a two level table is deemed 281 + * necessary. 282 + */ 283 + static bool gicv5_its_l2sz_two_level(bool devtab, u32 its_idr1, u8 id_bits, u8 *sz) 284 + { 285 + unsigned int l2_bits, l2_sz; 286 + 287 + if (devtab && !FIELD_GET(GICV5_ITS_IDR1_DT_LEVELS, its_idr1)) 288 + return false; 289 + 290 + if (!devtab && !FIELD_GET(GICV5_ITS_IDR1_ITT_LEVELS, its_idr1)) 291 + return false; 292 + 293 + /* 294 + * Pick an L2 size that matches the pagesize; if a match 295 + * is not found, go for the smallest supported l2 size granule. 296 + * 297 + * This ensures that we will always be able to allocate 298 + * contiguous memory at L2. 299 + */ 300 + switch (PAGE_SIZE) { 301 + case SZ_64K: 302 + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_64KB(its_idr1)) { 303 + l2_sz = GICV5_ITS_DT_ITT_CFGR_L2SZ_64k; 304 + break; 305 + } 306 + fallthrough; 307 + case SZ_4K: 308 + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_4KB(its_idr1)) { 309 + l2_sz = GICV5_ITS_DT_ITT_CFGR_L2SZ_4k; 310 + break; 311 + } 312 + fallthrough; 313 + case SZ_16K: 314 + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_16KB(its_idr1)) { 315 + l2_sz = GICV5_ITS_DT_ITT_CFGR_L2SZ_16k; 316 + break; 317 + } 318 + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_4KB(its_idr1)) { 319 + l2_sz = GICV5_ITS_DT_ITT_CFGR_L2SZ_4k; 320 + break; 321 + } 322 + if (GICV5_ITS_IDR1_L2SZ_SUPPORT_64KB(its_idr1)) { 323 + l2_sz = GICV5_ITS_DT_ITT_CFGR_L2SZ_64k; 324 + break; 325 + } 326 + 327 + l2_sz = GICV5_ITS_DT_ITT_CFGR_L2SZ_4k; 328 + break; 329 + } 330 + 331 + l2_bits = gicv5_its_l2sz_to_l2_bits(l2_sz); 332 + 333 + if (l2_bits > id_bits) 334 + return false; 335 + 336 + *sz = l2_sz; 337 + 338 + return true; 339 + } 340 + 341 + static __le64 *gicv5_its_device_get_itte_ref(struct gicv5_its_dev *its_dev, 342 + u16 event_id) 343 + { 344 + unsigned int l1_idx, l2_idx, l2_bits; 345 + __le64 *l2_itt; 346 + 347 + if (!its_dev->itt_cfg.l2itt) { 348 + __le64 *itt = its_dev->itt_cfg.linear.itt; 349 + 350 + return &itt[event_id]; 351 + } 352 + 353 + l2_bits = gicv5_its_l2sz_to_l2_bits(its_dev->itt_cfg.l2.l2sz); 354 + l1_idx = event_id >> l2_bits; 355 + l2_idx = event_id & GENMASK(l2_bits - 1, 0); 356 + l2_itt = its_dev->itt_cfg.l2.l2ptrs[l1_idx]; 357 + 358 + return &l2_itt[l2_idx]; 359 + } 360 + 361 + static int gicv5_its_device_cache_inv(struct gicv5_its_chip_data *its, 362 + struct gicv5_its_dev *its_dev) 363 + { 364 + u32 devicer; 365 + u64 didr; 366 + 367 + didr = FIELD_PREP(GICV5_ITS_DIDR_DEVICEID, its_dev->device_id); 368 + devicer = FIELD_PREP(GICV5_ITS_INV_DEVICER_I, 0x1) | 369 + FIELD_PREP(GICV5_ITS_INV_DEVICER_EVENTID_BITS, 370 + its_dev->itt_cfg.event_id_bits) | 371 + FIELD_PREP(GICV5_ITS_INV_DEVICER_L1, 0x0); 372 + its_writeq_relaxed(its, didr, GICV5_ITS_DIDR); 373 + its_writel_relaxed(its, devicer, GICV5_ITS_INV_DEVICER); 374 + 375 + return gicv5_its_cache_sync(its); 376 + } 377 + 378 + /* 379 + * Allocate a level 2 device table entry, update L1 parent to reference it. 380 + * Only used for 2-level device tables, and it is called on demand. 381 + */ 382 + static int gicv5_its_alloc_l2_devtab(struct gicv5_its_chip_data *its, 383 + unsigned int l1_index) 384 + { 385 + __le64 *l2devtab, *l1devtab = its->devtab_cfgr.l2.l1devtab; 386 + u8 span, l2sz, l2_bits; 387 + u64 l1dte; 388 + 389 + if (FIELD_GET(GICV5_DTL1E_VALID, le64_to_cpu(l1devtab[l1_index]))) 390 + return 0; 391 + 392 + span = FIELD_GET(GICV5_DTL1E_SPAN, le64_to_cpu(l1devtab[l1_index])); 393 + l2sz = devtab_cfgr_field(its, L2SZ); 394 + 395 + l2_bits = gicv5_its_l2sz_to_l2_bits(l2sz); 396 + 397 + /* 398 + * Span allows us to create a smaller L2 device table. 399 + * If it is too large, use the number of allowed L2 bits. 400 + */ 401 + if (span > l2_bits) 402 + span = l2_bits; 403 + 404 + l2devtab = kcalloc(BIT(span), sizeof(*l2devtab), GFP_KERNEL); 405 + if (!l2devtab) 406 + return -ENOMEM; 407 + 408 + its->devtab_cfgr.l2.l2ptrs[l1_index] = l2devtab; 409 + 410 + l1dte = FIELD_PREP(GICV5_DTL1E_SPAN, span) | 411 + (virt_to_phys(l2devtab) & GICV5_DTL1E_L2_ADDR_MASK) | 412 + FIELD_PREP(GICV5_DTL1E_VALID, 0x1); 413 + its_write_table_entry(its, &l1devtab[l1_index], l1dte); 414 + 415 + return 0; 416 + } 417 + 418 + static __le64 *gicv5_its_devtab_get_dte_ref(struct gicv5_its_chip_data *its, 419 + u32 device_id, bool alloc) 420 + { 421 + u8 str = devtab_cfgr_field(its, STRUCTURE); 422 + unsigned int l2sz, l2_bits, l1_idx, l2_idx; 423 + __le64 *l2devtab; 424 + int ret; 425 + 426 + if (str == GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR) { 427 + l2devtab = its->devtab_cfgr.linear.devtab; 428 + return &l2devtab[device_id]; 429 + } 430 + 431 + l2sz = devtab_cfgr_field(its, L2SZ); 432 + l2_bits = gicv5_its_l2sz_to_l2_bits(l2sz); 433 + l1_idx = device_id >> l2_bits; 434 + l2_idx = device_id & GENMASK(l2_bits - 1, 0); 435 + 436 + if (alloc) { 437 + /* 438 + * Allocate a new L2 device table here before 439 + * continuing. We make the assumption that the span in 440 + * the L1 table has been set correctly, and blindly use 441 + * that value. 442 + */ 443 + ret = gicv5_its_alloc_l2_devtab(its, l1_idx); 444 + if (ret) 445 + return NULL; 446 + } 447 + 448 + l2devtab = its->devtab_cfgr.l2.l2ptrs[l1_idx]; 449 + return &l2devtab[l2_idx]; 450 + } 451 + 452 + /* 453 + * Register a new device in the device table. Allocate an ITT and 454 + * program the L2DTE entry according to the ITT structure that 455 + * was chosen. 456 + */ 457 + static int gicv5_its_device_register(struct gicv5_its_chip_data *its, 458 + struct gicv5_its_dev *its_dev) 459 + { 460 + u8 event_id_bits, device_id_bits, itt_struct, itt_l2sz; 461 + phys_addr_t itt_phys_base; 462 + bool two_level_itt; 463 + u32 idr1, idr2; 464 + __le64 *dte; 465 + u64 val; 466 + int ret; 467 + 468 + device_id_bits = devtab_cfgr_field(its, DEVICEID_BITS); 469 + 470 + if (its_dev->device_id >= BIT(device_id_bits)) { 471 + pr_err("Supplied DeviceID (%u) outside of Device Table range (%u)!", 472 + its_dev->device_id, (u32)GENMASK(device_id_bits - 1, 0)); 473 + return -EINVAL; 474 + } 475 + 476 + dte = gicv5_its_devtab_get_dte_ref(its, its_dev->device_id, true); 477 + if (!dte) 478 + return -ENOMEM; 479 + 480 + if (FIELD_GET(GICV5_DTL2E_VALID, le64_to_cpu(*dte))) 481 + return -EBUSY; 482 + 483 + /* 484 + * Determine how many bits we need, validate those against the max. 485 + * Based on these, determine if we should go for a 1- or 2-level ITT. 486 + */ 487 + event_id_bits = order_base_2(its_dev->num_events); 488 + 489 + idr2 = its_readl_relaxed(its, GICV5_ITS_IDR2); 490 + 491 + if (event_id_bits > FIELD_GET(GICV5_ITS_IDR2_EVENTID_BITS, idr2)) { 492 + pr_err("Required EventID bits (%u) larger than supported bits (%u)!", 493 + event_id_bits, 494 + (u8)FIELD_GET(GICV5_ITS_IDR2_EVENTID_BITS, idr2)); 495 + return -EINVAL; 496 + } 497 + 498 + idr1 = its_readl_relaxed(its, GICV5_ITS_IDR1); 499 + 500 + /* 501 + * L2 ITT size is programmed into the L2DTE regardless of 502 + * whether a two-level or linear ITT is built, init it. 503 + */ 504 + itt_l2sz = 0; 505 + 506 + two_level_itt = gicv5_its_l2sz_two_level(false, idr1, event_id_bits, 507 + &itt_l2sz); 508 + if (two_level_itt) 509 + ret = gicv5_its_create_itt_two_level(its, its_dev, event_id_bits, 510 + itt_l2sz, 511 + its_dev->num_events); 512 + else 513 + ret = gicv5_its_create_itt_linear(its, its_dev, event_id_bits); 514 + if (ret) 515 + return ret; 516 + 517 + itt_phys_base = two_level_itt ? virt_to_phys(its_dev->itt_cfg.l2.l1itt) : 518 + virt_to_phys(its_dev->itt_cfg.linear.itt); 519 + 520 + itt_struct = two_level_itt ? GICV5_ITS_DT_ITT_CFGR_STRUCTURE_TWO_LEVEL : 521 + GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR; 522 + 523 + val = FIELD_PREP(GICV5_DTL2E_EVENT_ID_BITS, event_id_bits) | 524 + FIELD_PREP(GICV5_DTL2E_ITT_STRUCTURE, itt_struct) | 525 + (itt_phys_base & GICV5_DTL2E_ITT_ADDR_MASK) | 526 + FIELD_PREP(GICV5_DTL2E_ITT_L2SZ, itt_l2sz) | 527 + FIELD_PREP(GICV5_DTL2E_VALID, 0x1); 528 + 529 + its_write_table_entry(its, dte, val); 530 + 531 + ret = gicv5_its_device_cache_inv(its, its_dev); 532 + if (ret) { 533 + its_write_table_entry(its, dte, 0); 534 + gicv5_its_free_itt(its_dev); 535 + return ret; 536 + } 537 + 538 + return 0; 539 + } 540 + 541 + /* 542 + * Unregister a device in the device table. Lookup the device by ID, free the 543 + * corresponding ITT, mark the device as invalid in the device table. 544 + */ 545 + static int gicv5_its_device_unregister(struct gicv5_its_chip_data *its, 546 + struct gicv5_its_dev *its_dev) 547 + { 548 + __le64 *dte; 549 + 550 + dte = gicv5_its_devtab_get_dte_ref(its, its_dev->device_id, false); 551 + 552 + if (!FIELD_GET(GICV5_DTL2E_VALID, le64_to_cpu(*dte))) { 553 + pr_debug("Device table entry for DeviceID 0x%x is not valid. Nothing to clean up!", 554 + its_dev->device_id); 555 + return -EINVAL; 556 + } 557 + 558 + /* Zero everything - make it clear that this is an invalid entry */ 559 + its_write_table_entry(its, dte, 0); 560 + 561 + gicv5_its_free_itt(its_dev); 562 + 563 + return gicv5_its_device_cache_inv(its, its_dev); 564 + } 565 + 566 + /* 567 + * Allocate a 1-level device table. All entries are allocated, but marked 568 + * invalid. 569 + */ 570 + static int gicv5_its_alloc_devtab_linear(struct gicv5_its_chip_data *its, 571 + u8 device_id_bits) 572 + { 573 + __le64 *devtab; 574 + size_t sz; 575 + u64 baser; 576 + u32 cfgr; 577 + 578 + /* 579 + * We expect a GICv5 implementation requiring a large number of 580 + * deviceID bits to support a 2-level device table. If that's not 581 + * the case, cap the number of deviceIDs supported according to the 582 + * kmalloc limits so that the system can chug along with a linear 583 + * device table. 584 + */ 585 + sz = BIT_ULL(device_id_bits) * sizeof(*devtab); 586 + if (sz > KMALLOC_MAX_SIZE) { 587 + u8 device_id_cap = ilog2(KMALLOC_MAX_SIZE/sizeof(*devtab)); 588 + 589 + pr_warn("Limiting device ID bits from %u to %u\n", 590 + device_id_bits, device_id_cap); 591 + device_id_bits = device_id_cap; 592 + } 593 + 594 + devtab = kcalloc(BIT(device_id_bits), sizeof(*devtab), GFP_KERNEL); 595 + if (!devtab) 596 + return -ENOMEM; 597 + 598 + gicv5_its_dcache_clean(its, devtab, sz); 599 + 600 + cfgr = FIELD_PREP(GICV5_ITS_DT_CFGR_STRUCTURE, 601 + GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR) | 602 + FIELD_PREP(GICV5_ITS_DT_CFGR_L2SZ, 0) | 603 + FIELD_PREP(GICV5_ITS_DT_CFGR_DEVICEID_BITS, device_id_bits); 604 + its_writel_relaxed(its, cfgr, GICV5_ITS_DT_CFGR); 605 + 606 + baser = virt_to_phys(devtab) & GICV5_ITS_DT_BASER_ADDR_MASK; 607 + its_writeq_relaxed(its, baser, GICV5_ITS_DT_BASER); 608 + 609 + its->devtab_cfgr.cfgr = cfgr; 610 + its->devtab_cfgr.linear.devtab = devtab; 611 + 612 + return 0; 613 + } 614 + 615 + /* 616 + * Allocate a 2-level device table. L2 entries are not allocated, 617 + * they are allocated on-demand. 618 + */ 619 + static int gicv5_its_alloc_devtab_two_level(struct gicv5_its_chip_data *its, 620 + u8 device_id_bits, 621 + u8 devtab_l2sz) 622 + { 623 + unsigned int l1_bits, l2_bits, i; 624 + __le64 *l1devtab, **l2ptrs; 625 + size_t l1_sz; 626 + u64 baser; 627 + u32 cfgr; 628 + 629 + l2_bits = gicv5_its_l2sz_to_l2_bits(devtab_l2sz); 630 + 631 + l1_bits = device_id_bits - l2_bits; 632 + l1_sz = BIT(l1_bits) * sizeof(*l1devtab); 633 + /* 634 + * With 2-level device table support it is highly unlikely 635 + * that we are not able to allocate the required amount of 636 + * device table memory to cover deviceID space; cap the 637 + * deviceID space if we encounter such set-up. 638 + * If this ever becomes a problem we could revisit the policy 639 + * behind level 2 size selection to reduce level-1 deviceID bits. 640 + */ 641 + if (l1_sz > KMALLOC_MAX_SIZE) { 642 + l1_bits = ilog2(KMALLOC_MAX_SIZE/sizeof(*l1devtab)); 643 + 644 + pr_warn("Limiting device ID bits from %u to %u\n", 645 + device_id_bits, l1_bits + l2_bits); 646 + device_id_bits = l1_bits + l2_bits; 647 + l1_sz = KMALLOC_MAX_SIZE; 648 + } 649 + 650 + l1devtab = kcalloc(BIT(l1_bits), sizeof(*l1devtab), GFP_KERNEL); 651 + if (!l1devtab) 652 + return -ENOMEM; 653 + 654 + l2ptrs = kcalloc(BIT(l1_bits), sizeof(*l2ptrs), GFP_KERNEL); 655 + if (!l2ptrs) { 656 + kfree(l1devtab); 657 + return -ENOMEM; 658 + } 659 + 660 + for (i = 0; i < BIT(l1_bits); i++) 661 + l1devtab[i] = cpu_to_le64(FIELD_PREP(GICV5_DTL1E_SPAN, l2_bits)); 662 + 663 + gicv5_its_dcache_clean(its, l1devtab, l1_sz); 664 + 665 + cfgr = FIELD_PREP(GICV5_ITS_DT_CFGR_STRUCTURE, 666 + GICV5_ITS_DT_ITT_CFGR_STRUCTURE_TWO_LEVEL) | 667 + FIELD_PREP(GICV5_ITS_DT_CFGR_L2SZ, devtab_l2sz) | 668 + FIELD_PREP(GICV5_ITS_DT_CFGR_DEVICEID_BITS, device_id_bits); 669 + its_writel_relaxed(its, cfgr, GICV5_ITS_DT_CFGR); 670 + 671 + baser = virt_to_phys(l1devtab) & GICV5_ITS_DT_BASER_ADDR_MASK; 672 + its_writeq_relaxed(its, baser, GICV5_ITS_DT_BASER); 673 + 674 + its->devtab_cfgr.cfgr = cfgr; 675 + its->devtab_cfgr.l2.l1devtab = l1devtab; 676 + its->devtab_cfgr.l2.l2ptrs = l2ptrs; 677 + 678 + return 0; 679 + } 680 + 681 + /* 682 + * Initialise the device table as either 1- or 2-level depending on what is 683 + * supported by the hardware. 684 + */ 685 + static int gicv5_its_init_devtab(struct gicv5_its_chip_data *its) 686 + { 687 + u8 device_id_bits, devtab_l2sz; 688 + bool two_level_devtab; 689 + u32 idr1; 690 + 691 + idr1 = its_readl_relaxed(its, GICV5_ITS_IDR1); 692 + 693 + device_id_bits = FIELD_GET(GICV5_ITS_IDR1_DEVICEID_BITS, idr1); 694 + two_level_devtab = gicv5_its_l2sz_two_level(true, idr1, device_id_bits, 695 + &devtab_l2sz); 696 + if (two_level_devtab) 697 + return gicv5_its_alloc_devtab_two_level(its, device_id_bits, 698 + devtab_l2sz); 699 + else 700 + return gicv5_its_alloc_devtab_linear(its, device_id_bits); 701 + } 702 + 703 + static void gicv5_its_deinit_devtab(struct gicv5_its_chip_data *its) 704 + { 705 + u8 str = devtab_cfgr_field(its, STRUCTURE); 706 + 707 + if (str == GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR) { 708 + kfree(its->devtab_cfgr.linear.devtab); 709 + } else { 710 + kfree(its->devtab_cfgr.l2.l1devtab); 711 + kfree(its->devtab_cfgr.l2.l2ptrs); 712 + } 713 + } 714 + 715 + static void gicv5_its_compose_msi_msg(struct irq_data *d, struct msi_msg *msg) 716 + { 717 + struct gicv5_its_dev *its_dev = irq_data_get_irq_chip_data(d); 718 + u64 addr = its_dev->its_trans_phys_base; 719 + 720 + msg->data = FIELD_GET(GICV5_ITS_HWIRQ_EVENT_ID, d->hwirq); 721 + msi_msg_set_addr(irq_data_get_msi_desc(d), msg, addr); 722 + } 723 + 724 + static const struct irq_chip gicv5_its_irq_chip = { 725 + .name = "GICv5-ITS-MSI", 726 + .irq_mask = irq_chip_mask_parent, 727 + .irq_unmask = irq_chip_unmask_parent, 728 + .irq_eoi = irq_chip_eoi_parent, 729 + .irq_set_affinity = irq_chip_set_affinity_parent, 730 + .irq_get_irqchip_state = irq_chip_get_parent_state, 731 + .irq_set_irqchip_state = irq_chip_set_parent_state, 732 + .irq_compose_msi_msg = gicv5_its_compose_msi_msg, 733 + }; 734 + 735 + static struct gicv5_its_dev *gicv5_its_find_device(struct gicv5_its_chip_data *its, 736 + u32 device_id) 737 + { 738 + struct gicv5_its_dev *dev = xa_load(&its->its_devices, device_id); 739 + 740 + return dev ? dev : ERR_PTR(-ENODEV); 741 + } 742 + 743 + static struct gicv5_its_dev *gicv5_its_alloc_device(struct gicv5_its_chip_data *its, int nvec, 744 + u32 dev_id) 745 + { 746 + struct gicv5_its_dev *its_dev; 747 + void *entry; 748 + int ret; 749 + 750 + its_dev = gicv5_its_find_device(its, dev_id); 751 + if (!IS_ERR(its_dev)) { 752 + pr_err("A device with this DeviceID (0x%x) has already been registered.\n", 753 + dev_id); 754 + 755 + return ERR_PTR(-EBUSY); 756 + } 757 + 758 + its_dev = kzalloc(sizeof(*its_dev), GFP_KERNEL); 759 + if (!its_dev) 760 + return ERR_PTR(-ENOMEM); 761 + 762 + its_dev->device_id = dev_id; 763 + its_dev->num_events = nvec; 764 + 765 + ret = gicv5_its_device_register(its, its_dev); 766 + if (ret) { 767 + pr_err("Failed to register the device\n"); 768 + goto out_dev_free; 769 + } 770 + 771 + gicv5_its_device_cache_inv(its, its_dev); 772 + 773 + its_dev->its_node = its; 774 + 775 + its_dev->event_map = (unsigned long *)bitmap_zalloc(its_dev->num_events, GFP_KERNEL); 776 + if (!its_dev->event_map) { 777 + ret = -ENOMEM; 778 + goto out_unregister; 779 + } 780 + 781 + entry = xa_store(&its->its_devices, dev_id, its_dev, GFP_KERNEL); 782 + if (xa_is_err(entry)) { 783 + ret = xa_err(entry); 784 + goto out_bitmap_free; 785 + } 786 + 787 + return its_dev; 788 + 789 + out_bitmap_free: 790 + bitmap_free(its_dev->event_map); 791 + out_unregister: 792 + gicv5_its_device_unregister(its, its_dev); 793 + out_dev_free: 794 + kfree(its_dev); 795 + return ERR_PTR(ret); 796 + } 797 + 798 + static int gicv5_its_msi_prepare(struct irq_domain *domain, struct device *dev, 799 + int nvec, msi_alloc_info_t *info) 800 + { 801 + u32 dev_id = info->scratchpad[0].ul; 802 + struct msi_domain_info *msi_info; 803 + struct gicv5_its_chip_data *its; 804 + struct gicv5_its_dev *its_dev; 805 + 806 + msi_info = msi_get_domain_info(domain); 807 + its = msi_info->data; 808 + 809 + guard(mutex)(&its->dev_alloc_lock); 810 + 811 + its_dev = gicv5_its_alloc_device(its, nvec, dev_id); 812 + if (IS_ERR(its_dev)) 813 + return PTR_ERR(its_dev); 814 + 815 + its_dev->its_trans_phys_base = info->scratchpad[1].ul; 816 + info->scratchpad[0].ptr = its_dev; 817 + 818 + return 0; 819 + } 820 + 821 + static void gicv5_its_msi_teardown(struct irq_domain *domain, msi_alloc_info_t *info) 822 + { 823 + struct gicv5_its_dev *its_dev = info->scratchpad[0].ptr; 824 + struct msi_domain_info *msi_info; 825 + struct gicv5_its_chip_data *its; 826 + 827 + msi_info = msi_get_domain_info(domain); 828 + its = msi_info->data; 829 + 830 + guard(mutex)(&its->dev_alloc_lock); 831 + 832 + if (WARN_ON_ONCE(!bitmap_empty(its_dev->event_map, its_dev->num_events))) 833 + return; 834 + 835 + xa_erase(&its->its_devices, its_dev->device_id); 836 + bitmap_free(its_dev->event_map); 837 + gicv5_its_device_unregister(its, its_dev); 838 + kfree(its_dev); 839 + } 840 + 841 + static struct msi_domain_ops gicv5_its_msi_domain_ops = { 842 + .msi_prepare = gicv5_its_msi_prepare, 843 + .msi_teardown = gicv5_its_msi_teardown, 844 + }; 845 + 846 + static int gicv5_its_map_event(struct gicv5_its_dev *its_dev, u16 event_id, u32 lpi) 847 + { 848 + struct gicv5_its_chip_data *its = its_dev->its_node; 849 + u64 itt_entry; 850 + __le64 *itte; 851 + 852 + itte = gicv5_its_device_get_itte_ref(its_dev, event_id); 853 + 854 + if (FIELD_GET(GICV5_ITTL2E_VALID, *itte)) 855 + return -EEXIST; 856 + 857 + itt_entry = FIELD_PREP(GICV5_ITTL2E_LPI_ID, lpi) | 858 + FIELD_PREP(GICV5_ITTL2E_VALID, 0x1); 859 + 860 + its_write_table_entry(its, itte, itt_entry); 861 + 862 + gicv5_its_itt_cache_inv(its, its_dev->device_id, event_id); 863 + 864 + return 0; 865 + } 866 + 867 + static void gicv5_its_unmap_event(struct gicv5_its_dev *its_dev, u16 event_id) 868 + { 869 + struct gicv5_its_chip_data *its = its_dev->its_node; 870 + u64 itte_val; 871 + __le64 *itte; 872 + 873 + itte = gicv5_its_device_get_itte_ref(its_dev, event_id); 874 + 875 + itte_val = le64_to_cpu(*itte); 876 + itte_val &= ~GICV5_ITTL2E_VALID; 877 + 878 + its_write_table_entry(its, itte, itte_val); 879 + 880 + gicv5_its_itt_cache_inv(its, its_dev->device_id, event_id); 881 + } 882 + 883 + static int gicv5_its_alloc_eventid(struct gicv5_its_dev *its_dev, 884 + unsigned int nr_irqs, u32 *eventid) 885 + { 886 + int ret; 887 + 888 + ret = bitmap_find_free_region(its_dev->event_map, 889 + its_dev->num_events, 890 + get_count_order(nr_irqs)); 891 + 892 + if (ret < 0) 893 + return ret; 894 + 895 + *eventid = ret; 896 + 897 + return 0; 898 + } 899 + 900 + static void gicv5_its_free_eventid(struct gicv5_its_dev *its_dev, u32 event_id_base, 901 + unsigned int nr_irqs) 902 + { 903 + bitmap_release_region(its_dev->event_map, event_id_base, 904 + get_count_order(nr_irqs)); 905 + } 906 + 907 + static int gicv5_its_irq_domain_alloc(struct irq_domain *domain, unsigned int virq, 908 + unsigned int nr_irqs, void *arg) 909 + { 910 + u32 device_id, event_id_base, lpi; 911 + struct gicv5_its_dev *its_dev; 912 + msi_alloc_info_t *info = arg; 913 + irq_hw_number_t hwirq; 914 + struct irq_data *irqd; 915 + int ret, i; 916 + 917 + its_dev = info->scratchpad[0].ptr; 918 + 919 + ret = gicv5_its_alloc_eventid(its_dev, nr_irqs, &event_id_base); 920 + if (ret) 921 + return ret; 922 + 923 + ret = iommu_dma_prepare_msi(info->desc, its_dev->its_trans_phys_base); 924 + if (ret) 925 + goto out_eventid; 926 + 927 + device_id = its_dev->device_id; 928 + 929 + for (i = 0; i < nr_irqs; i++) { 930 + lpi = gicv5_alloc_lpi(); 931 + if (ret < 0) { 932 + pr_debug("Failed to find free LPI!\n"); 933 + goto out_eventid; 934 + } 935 + 936 + ret = irq_domain_alloc_irqs_parent(domain, virq + i, 1, &lpi); 937 + if (ret) 938 + goto out_free_lpi; 939 + 940 + /* 941 + * Store eventid and deviceid into the hwirq for later use. 942 + * 943 + * hwirq = event_id << 32 | device_id 944 + */ 945 + hwirq = FIELD_PREP(GICV5_ITS_HWIRQ_DEVICE_ID, device_id) | 946 + FIELD_PREP(GICV5_ITS_HWIRQ_EVENT_ID, (u64)event_id_base + i); 947 + irq_domain_set_info(domain, virq + i, hwirq, 948 + &gicv5_its_irq_chip, its_dev, 949 + handle_fasteoi_irq, NULL, NULL); 950 + 951 + irqd = irq_get_irq_data(virq + i); 952 + irqd_set_single_target(irqd); 953 + irqd_set_affinity_on_activate(irqd); 954 + irqd_set_resend_when_in_progress(irqd); 955 + } 956 + 957 + return 0; 958 + 959 + out_free_lpi: 960 + gicv5_free_lpi(lpi); 961 + out_eventid: 962 + gicv5_its_free_eventid(its_dev, event_id_base, nr_irqs); 963 + return ret; 964 + } 965 + 966 + static void gicv5_its_irq_domain_free(struct irq_domain *domain, unsigned int virq, 967 + unsigned int nr_irqs) 968 + { 969 + struct irq_data *d = irq_domain_get_irq_data(domain, virq); 970 + struct gicv5_its_chip_data *its; 971 + struct gicv5_its_dev *its_dev; 972 + u16 event_id_base; 973 + unsigned int i; 974 + 975 + its_dev = irq_data_get_irq_chip_data(d); 976 + its = its_dev->its_node; 977 + 978 + event_id_base = FIELD_GET(GICV5_ITS_HWIRQ_EVENT_ID, d->hwirq); 979 + 980 + bitmap_release_region(its_dev->event_map, event_id_base, 981 + get_count_order(nr_irqs)); 982 + 983 + /* Hierarchically free irq data */ 984 + for (i = 0; i < nr_irqs; i++) { 985 + d = irq_domain_get_irq_data(domain, virq + i); 986 + 987 + gicv5_free_lpi(d->parent_data->hwirq); 988 + irq_domain_reset_irq_data(d); 989 + irq_domain_free_irqs_parent(domain, virq + i, 1); 990 + } 991 + 992 + gicv5_its_syncr(its, its_dev); 993 + gicv5_irs_syncr(); 994 + } 995 + 996 + static int gicv5_its_irq_domain_activate(struct irq_domain *domain, struct irq_data *d, 997 + bool reserve) 998 + { 999 + struct gicv5_its_dev *its_dev = irq_data_get_irq_chip_data(d); 1000 + u16 event_id; 1001 + u32 lpi; 1002 + 1003 + event_id = FIELD_GET(GICV5_ITS_HWIRQ_EVENT_ID, d->hwirq); 1004 + lpi = d->parent_data->hwirq; 1005 + 1006 + return gicv5_its_map_event(its_dev, event_id, lpi); 1007 + } 1008 + 1009 + static void gicv5_its_irq_domain_deactivate(struct irq_domain *domain, 1010 + struct irq_data *d) 1011 + { 1012 + struct gicv5_its_dev *its_dev = irq_data_get_irq_chip_data(d); 1013 + u16 event_id; 1014 + 1015 + event_id = FIELD_GET(GICV5_ITS_HWIRQ_EVENT_ID, d->hwirq); 1016 + 1017 + gicv5_its_unmap_event(its_dev, event_id); 1018 + } 1019 + 1020 + static const struct irq_domain_ops gicv5_its_irq_domain_ops = { 1021 + .alloc = gicv5_its_irq_domain_alloc, 1022 + .free = gicv5_its_irq_domain_free, 1023 + .activate = gicv5_its_irq_domain_activate, 1024 + .deactivate = gicv5_its_irq_domain_deactivate, 1025 + .select = msi_lib_irq_domain_select, 1026 + }; 1027 + 1028 + static int gicv5_its_write_cr0(struct gicv5_its_chip_data *its, bool enable) 1029 + { 1030 + u32 cr0 = FIELD_PREP(GICV5_ITS_CR0_ITSEN, enable); 1031 + 1032 + its_writel_relaxed(its, cr0, GICV5_ITS_CR0); 1033 + return gicv5_wait_for_op_atomic(its->its_base, GICV5_ITS_CR0, 1034 + GICV5_ITS_CR0_IDLE, NULL); 1035 + } 1036 + 1037 + static int gicv5_its_enable(struct gicv5_its_chip_data *its) 1038 + { 1039 + return gicv5_its_write_cr0(its, true); 1040 + } 1041 + 1042 + static int gicv5_its_disable(struct gicv5_its_chip_data *its) 1043 + { 1044 + return gicv5_its_write_cr0(its, false); 1045 + } 1046 + 1047 + static void gicv5_its_print_info(struct gicv5_its_chip_data *its_node) 1048 + { 1049 + bool devtab_linear; 1050 + u8 device_id_bits; 1051 + u8 str; 1052 + 1053 + device_id_bits = devtab_cfgr_field(its_node, DEVICEID_BITS); 1054 + 1055 + str = devtab_cfgr_field(its_node, STRUCTURE); 1056 + devtab_linear = (str == GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR); 1057 + 1058 + pr_info("ITS %s enabled using %s device table device_id_bits %u\n", 1059 + fwnode_get_name(its_node->fwnode), 1060 + devtab_linear ? "linear" : "2-level", 1061 + device_id_bits); 1062 + } 1063 + 1064 + static int gicv5_its_init_domain(struct gicv5_its_chip_data *its, struct irq_domain *parent) 1065 + { 1066 + struct irq_domain_info dom_info = { 1067 + .fwnode = its->fwnode, 1068 + .ops = &gicv5_its_irq_domain_ops, 1069 + .domain_flags = its->msi_domain_flags, 1070 + .parent = parent, 1071 + }; 1072 + struct msi_domain_info *info; 1073 + 1074 + info = kzalloc(sizeof(*info), GFP_KERNEL); 1075 + if (!info) 1076 + return -ENOMEM; 1077 + 1078 + info->ops = &gicv5_its_msi_domain_ops; 1079 + info->data = its; 1080 + dom_info.host_data = info; 1081 + 1082 + if (!msi_create_parent_irq_domain(&dom_info, &gic_v5_its_msi_parent_ops)) { 1083 + kfree(info); 1084 + return -ENOMEM; 1085 + } 1086 + 1087 + return 0; 1088 + } 1089 + 1090 + static int __init gicv5_its_init_bases(void __iomem *its_base, struct fwnode_handle *handle, 1091 + struct irq_domain *parent_domain) 1092 + { 1093 + struct device_node *np = to_of_node(handle); 1094 + struct gicv5_its_chip_data *its_node; 1095 + u32 cr0, cr1; 1096 + bool enabled; 1097 + int ret; 1098 + 1099 + its_node = kzalloc(sizeof(*its_node), GFP_KERNEL); 1100 + if (!its_node) 1101 + return -ENOMEM; 1102 + 1103 + mutex_init(&its_node->dev_alloc_lock); 1104 + xa_init(&its_node->its_devices); 1105 + its_node->fwnode = handle; 1106 + its_node->its_base = its_base; 1107 + its_node->msi_domain_flags = IRQ_DOMAIN_FLAG_ISOLATED_MSI | 1108 + IRQ_DOMAIN_FLAG_FWNODE_PARENT; 1109 + 1110 + cr0 = its_readl_relaxed(its_node, GICV5_ITS_CR0); 1111 + enabled = FIELD_GET(GICV5_ITS_CR0_ITSEN, cr0); 1112 + if (WARN(enabled, "ITS %s enabled, disabling it before proceeding\n", np->full_name)) { 1113 + ret = gicv5_its_disable(its_node); 1114 + if (ret) 1115 + goto out_free_node; 1116 + } 1117 + 1118 + if (of_property_read_bool(np, "dma-noncoherent")) { 1119 + /* 1120 + * A non-coherent ITS implies that some cache levels cannot be 1121 + * used coherently by the cores and GIC. Our only option is to mark 1122 + * memory attributes for the GIC as non-cacheable; by default, 1123 + * non-cacheable memory attributes imply outer-shareable 1124 + * shareability, the value written into ITS_CR1_SH is ignored. 1125 + */ 1126 + cr1 = FIELD_PREP(GICV5_ITS_CR1_ITT_RA, GICV5_NO_READ_ALLOC) | 1127 + FIELD_PREP(GICV5_ITS_CR1_DT_RA, GICV5_NO_READ_ALLOC) | 1128 + FIELD_PREP(GICV5_ITS_CR1_IC, GICV5_NON_CACHE) | 1129 + FIELD_PREP(GICV5_ITS_CR1_OC, GICV5_NON_CACHE); 1130 + its_node->flags |= ITS_FLAGS_NON_COHERENT; 1131 + } else { 1132 + cr1 = FIELD_PREP(GICV5_ITS_CR1_ITT_RA, GICV5_READ_ALLOC) | 1133 + FIELD_PREP(GICV5_ITS_CR1_DT_RA, GICV5_READ_ALLOC) | 1134 + FIELD_PREP(GICV5_ITS_CR1_IC, GICV5_WB_CACHE) | 1135 + FIELD_PREP(GICV5_ITS_CR1_OC, GICV5_WB_CACHE) | 1136 + FIELD_PREP(GICV5_ITS_CR1_SH, GICV5_INNER_SHARE); 1137 + } 1138 + 1139 + its_writel_relaxed(its_node, cr1, GICV5_ITS_CR1); 1140 + 1141 + ret = gicv5_its_init_devtab(its_node); 1142 + if (ret) 1143 + goto out_free_node; 1144 + 1145 + ret = gicv5_its_enable(its_node); 1146 + if (ret) 1147 + goto out_free_devtab; 1148 + 1149 + ret = gicv5_its_init_domain(its_node, parent_domain); 1150 + if (ret) 1151 + goto out_disable_its; 1152 + 1153 + gicv5_its_print_info(its_node); 1154 + 1155 + return 0; 1156 + 1157 + out_disable_its: 1158 + gicv5_its_disable(its_node); 1159 + out_free_devtab: 1160 + gicv5_its_deinit_devtab(its_node); 1161 + out_free_node: 1162 + kfree(its_node); 1163 + return ret; 1164 + } 1165 + 1166 + static int __init gicv5_its_init(struct device_node *node) 1167 + { 1168 + void __iomem *its_base; 1169 + int ret, idx; 1170 + 1171 + idx = of_property_match_string(node, "reg-names", "ns-config"); 1172 + if (idx < 0) { 1173 + pr_err("%pOF: ns-config reg-name not present\n", node); 1174 + return -ENODEV; 1175 + } 1176 + 1177 + its_base = of_io_request_and_map(node, idx, of_node_full_name(node)); 1178 + if (IS_ERR(its_base)) { 1179 + pr_err("%pOF: unable to map GICv5 ITS_CONFIG_FRAME\n", node); 1180 + return PTR_ERR(its_base); 1181 + } 1182 + 1183 + ret = gicv5_its_init_bases(its_base, of_fwnode_handle(node), 1184 + gicv5_global_data.lpi_domain); 1185 + if (ret) 1186 + goto out_unmap; 1187 + 1188 + return 0; 1189 + 1190 + out_unmap: 1191 + iounmap(its_base); 1192 + return ret; 1193 + } 1194 + 1195 + void __init gicv5_its_of_probe(struct device_node *parent) 1196 + { 1197 + struct device_node *np; 1198 + 1199 + for_each_available_child_of_node(parent, np) { 1200 + if (!of_device_is_compatible(np, "arm,gic-v5-its")) 1201 + continue; 1202 + 1203 + if (gicv5_its_init(np)) 1204 + pr_err("Failed to init ITS %s\n", np->full_name); 1205 + } 1206 + }
+2
drivers/irqchip/irq-gic-v5.c
··· 1071 1071 1072 1072 gicv5_smp_init(); 1073 1073 1074 + gicv5_irs_its_probe(); 1075 + 1074 1076 return 0; 1075 1077 1076 1078 out_int:
+157
include/linux/irqchip/arm-gic-v5.h
··· 50 50 #define GICV5_IRS_IDR7 0x001c 51 51 #define GICV5_IRS_CR0 0x0080 52 52 #define GICV5_IRS_CR1 0x0084 53 + #define GICV5_IRS_SYNCR 0x00c0 54 + #define GICV5_IRS_SYNC_STATUSR 0x00c4 53 55 #define GICV5_IRS_SPI_SELR 0x0108 54 56 #define GICV5_IRS_SPI_CFGR 0x0114 55 57 #define GICV5_IRS_SPI_STATUSR 0x0118 ··· 105 103 #define GICV5_IRS_CR1_OC GENMASK(3, 2) 106 104 #define GICV5_IRS_CR1_SH GENMASK(1, 0) 107 105 106 + #define GICV5_IRS_SYNCR_SYNC BIT(31) 107 + 108 + #define GICV5_IRS_SYNC_STATUSR_IDLE BIT(0) 109 + 108 110 #define GICV5_IRS_SPI_STATUSR_V BIT(1) 109 111 #define GICV5_IRS_SPI_STATUSR_IDLE BIT(0) 110 112 ··· 149 143 #define GICV5_ISTL1E_VALID BIT_ULL(0) 150 144 151 145 #define GICV5_ISTL1E_L2_ADDR_MASK GENMASK_ULL(55, 12) 146 + 147 + /* 148 + * ITS registers and tables structures 149 + */ 150 + #define GICV5_ITS_IDR1 0x0004 151 + #define GICV5_ITS_IDR2 0x0008 152 + #define GICV5_ITS_CR0 0x0080 153 + #define GICV5_ITS_CR1 0x0084 154 + #define GICV5_ITS_DT_BASER 0x00c0 155 + #define GICV5_ITS_DT_CFGR 0x00d0 156 + #define GICV5_ITS_DIDR 0x0100 157 + #define GICV5_ITS_EIDR 0x0108 158 + #define GICV5_ITS_INV_EVENTR 0x010c 159 + #define GICV5_ITS_INV_DEVICER 0x0110 160 + #define GICV5_ITS_STATUSR 0x0120 161 + #define GICV5_ITS_SYNCR 0x0140 162 + #define GICV5_ITS_SYNC_STATUSR 0x0148 163 + 164 + #define GICV5_ITS_IDR1_L2SZ GENMASK(10, 8) 165 + #define GICV5_ITS_IDR1_ITT_LEVELS BIT(7) 166 + #define GICV5_ITS_IDR1_DT_LEVELS BIT(6) 167 + #define GICV5_ITS_IDR1_DEVICEID_BITS GENMASK(5, 0) 168 + 169 + #define GICV5_ITS_IDR1_L2SZ_SUPPORT_4KB(r) FIELD_GET(BIT(8), (r)) 170 + #define GICV5_ITS_IDR1_L2SZ_SUPPORT_16KB(r) FIELD_GET(BIT(9), (r)) 171 + #define GICV5_ITS_IDR1_L2SZ_SUPPORT_64KB(r) FIELD_GET(BIT(10), (r)) 172 + 173 + #define GICV5_ITS_IDR2_XDMN_EVENTs GENMASK(6, 5) 174 + #define GICV5_ITS_IDR2_EVENTID_BITS GENMASK(4, 0) 175 + 176 + #define GICV5_ITS_CR0_IDLE BIT(1) 177 + #define GICV5_ITS_CR0_ITSEN BIT(0) 178 + 179 + #define GICV5_ITS_CR1_ITT_RA BIT(7) 180 + #define GICV5_ITS_CR1_DT_RA BIT(6) 181 + #define GICV5_ITS_CR1_IC GENMASK(5, 4) 182 + #define GICV5_ITS_CR1_OC GENMASK(3, 2) 183 + #define GICV5_ITS_CR1_SH GENMASK(1, 0) 184 + 185 + #define GICV5_ITS_DT_CFGR_STRUCTURE BIT(16) 186 + #define GICV5_ITS_DT_CFGR_L2SZ GENMASK(7, 6) 187 + #define GICV5_ITS_DT_CFGR_DEVICEID_BITS GENMASK(5, 0) 188 + 189 + #define GICV5_ITS_DT_BASER_ADDR_MASK GENMASK_ULL(55, 3) 190 + 191 + #define GICV5_ITS_INV_DEVICER_I BIT(31) 192 + #define GICV5_ITS_INV_DEVICER_EVENTID_BITS GENMASK(5, 1) 193 + #define GICV5_ITS_INV_DEVICER_L1 BIT(0) 194 + 195 + #define GICV5_ITS_DIDR_DEVICEID GENMASK_ULL(31, 0) 196 + 197 + #define GICV5_ITS_EIDR_EVENTID GENMASK(15, 0) 198 + 199 + #define GICV5_ITS_INV_EVENTR_I BIT(31) 200 + #define GICV5_ITS_INV_EVENTR_ITT_L2SZ GENMASK(2, 1) 201 + #define GICV5_ITS_INV_EVENTR_L1 BIT(0) 202 + 203 + #define GICV5_ITS_STATUSR_IDLE BIT(0) 204 + 205 + #define GICV5_ITS_SYNCR_SYNC BIT_ULL(63) 206 + #define GICV5_ITS_SYNCR_SYNCALL BIT_ULL(32) 207 + #define GICV5_ITS_SYNCR_DEVICEID GENMASK_ULL(31, 0) 208 + 209 + #define GICV5_ITS_SYNC_STATUSR_IDLE BIT(0) 210 + 211 + #define GICV5_DTL1E_VALID BIT_ULL(0) 212 + /* Note that there is no shift for the address by design */ 213 + #define GICV5_DTL1E_L2_ADDR_MASK GENMASK_ULL(55, 3) 214 + #define GICV5_DTL1E_SPAN GENMASK_ULL(63, 60) 215 + 216 + #define GICV5_DTL2E_VALID BIT_ULL(0) 217 + #define GICV5_DTL2E_ITT_L2SZ GENMASK_ULL(2, 1) 218 + /* Note that there is no shift for the address by design */ 219 + #define GICV5_DTL2E_ITT_ADDR_MASK GENMASK_ULL(55, 3) 220 + #define GICV5_DTL2E_ITT_DSWE BIT_ULL(57) 221 + #define GICV5_DTL2E_ITT_STRUCTURE BIT_ULL(58) 222 + #define GICV5_DTL2E_EVENT_ID_BITS GENMASK_ULL(63, 59) 223 + 224 + #define GICV5_ITTL1E_VALID BIT_ULL(0) 225 + /* Note that there is no shift for the address by design */ 226 + #define GICV5_ITTL1E_L2_ADDR_MASK GENMASK_ULL(55, 3) 227 + #define GICV5_ITTL1E_SPAN GENMASK_ULL(63, 60) 228 + 229 + #define GICV5_ITTL2E_LPI_ID GENMASK_ULL(23, 0) 230 + #define GICV5_ITTL2E_DAC GENMASK_ULL(29, 28) 231 + #define GICV5_ITTL2E_VIRTUAL BIT_ULL(30) 232 + #define GICV5_ITTL2E_VALID BIT_ULL(31) 233 + #define GICV5_ITTL2E_VM_ID GENMASK_ULL(47, 32) 234 + 235 + #define GICV5_ITS_DT_ITT_CFGR_L2SZ_4k 0b00 236 + #define GICV5_ITS_DT_ITT_CFGR_L2SZ_16k 0b01 237 + #define GICV5_ITS_DT_ITT_CFGR_L2SZ_64k 0b10 238 + 239 + #define GICV5_ITS_DT_ITT_CFGR_STRUCTURE_LINEAR 0 240 + #define GICV5_ITS_DT_ITT_CFGR_STRUCTURE_TWO_LEVEL 1 241 + 242 + #define GICV5_ITS_HWIRQ_DEVICE_ID GENMASK_ULL(31, 0) 243 + #define GICV5_ITS_HWIRQ_EVENT_ID GENMASK_ULL(63, 32) 152 244 153 245 /* 154 246 * Global Data structures and functions ··· 301 197 return 0; 302 198 } 303 199 200 + static inline int gicv5_wait_for_op_s(void __iomem *addr, u32 offset, 201 + const char *reg_s, u32 mask) 202 + { 203 + void __iomem *reg = addr + offset; 204 + u32 val; 205 + int ret; 206 + 207 + ret = readl_poll_timeout(reg, val, val & mask, 1, 10 * USEC_PER_MSEC); 208 + if (unlikely(ret == -ETIMEDOUT)) { 209 + pr_err_ratelimited("%s timeout...\n", reg_s); 210 + return ret; 211 + } 212 + 213 + return 0; 214 + } 215 + 304 216 #define gicv5_wait_for_op_atomic(base, reg, mask, val) \ 305 217 gicv5_wait_for_op_s_atomic(base, reg, #reg, mask, val) 218 + 219 + #define gicv5_wait_for_op(base, reg, mask) \ 220 + gicv5_wait_for_op_s(base, reg, #reg, mask) 306 221 307 222 void __init gicv5_init_lpi_domain(void); 308 223 void __init gicv5_free_lpi_domain(void); ··· 329 206 int gicv5_irs_of_probe(struct device_node *parent); 330 207 void gicv5_irs_remove(void); 331 208 int gicv5_irs_enable(void); 209 + void gicv5_irs_its_probe(void); 332 210 int gicv5_irs_register_cpu(int cpuid); 333 211 int gicv5_irs_cpu_to_iaffid(int cpu_id, u16 *iaffid); 334 212 struct gicv5_irs_chip_data *gicv5_irs_lookup_by_spi_id(u32 spi_id); 335 213 int gicv5_spi_irq_set_type(struct irq_data *d, unsigned int type); 336 214 int gicv5_irs_iste_alloc(u32 lpi); 215 + void gicv5_irs_syncr(void); 216 + 217 + struct gicv5_its_devtab_cfg { 218 + union { 219 + struct { 220 + __le64 *devtab; 221 + } linear; 222 + struct { 223 + __le64 *l1devtab; 224 + __le64 **l2ptrs; 225 + } l2; 226 + }; 227 + u32 cfgr; 228 + }; 229 + 230 + struct gicv5_its_itt_cfg { 231 + union { 232 + struct { 233 + __le64 *itt; 234 + unsigned int num_ents; 235 + } linear; 236 + struct { 237 + __le64 *l1itt; 238 + __le64 **l2ptrs; 239 + unsigned int num_l1_ents; 240 + u8 l2sz; 241 + } l2; 242 + }; 243 + u8 event_id_bits; 244 + bool l2itt; 245 + }; 337 246 338 247 void gicv5_init_lpis(u32 max); 339 248 void gicv5_deinit_lpis(void); 340 249 341 250 int gicv5_alloc_lpi(void); 342 251 void gicv5_free_lpi(u32 lpi); 252 + 253 + void __init gicv5_its_of_probe(struct device_node *parent); 343 254 #endif