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

irqchip/gic-v3-its: Add probing for VLPI properties

Add the probing code for the ITS VLPI support. This includes
configuring the ITS number if not supporting the single VMOVP
command feature.

Reviewed-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>

+72 -4
+67 -4
drivers/irqchip/irq-gic-v3-its.c
··· 101 101 u32 ite_size; 102 102 u32 device_ids; 103 103 int numa_node; 104 + bool is_v4; 104 105 }; 105 106 106 107 #define ITS_ITT_ALIGN SZ_256 ··· 133 132 static DEFINE_SPINLOCK(its_lock); 134 133 static struct rdists *gic_rdists; 135 134 static struct irq_domain *its_parent; 135 + 136 + /* 137 + * We have a maximum number of 16 ITSs in the whole system if we're 138 + * using the ITSList mechanism 139 + */ 140 + #define ITS_LIST_MAX 16 141 + 142 + static unsigned long its_list_map; 136 143 137 144 #define gic_data_rdist() (raw_cpu_ptr(gic_rdists->rdist)) 138 145 #define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base) ··· 1688 1679 return 0; 1689 1680 } 1690 1681 1682 + static int __init its_compute_its_list_map(struct resource *res, 1683 + void __iomem *its_base) 1684 + { 1685 + int its_number; 1686 + u32 ctlr; 1687 + 1688 + /* 1689 + * This is assumed to be done early enough that we're 1690 + * guaranteed to be single-threaded, hence no 1691 + * locking. Should this change, we should address 1692 + * this. 1693 + */ 1694 + its_number = find_first_zero_bit(&its_list_map, ITS_LIST_MAX); 1695 + if (its_number >= ITS_LIST_MAX) { 1696 + pr_err("ITS@%pa: No ITSList entry available!\n", 1697 + &res->start); 1698 + return -EINVAL; 1699 + } 1700 + 1701 + ctlr = readl_relaxed(its_base + GITS_CTLR); 1702 + ctlr &= ~GITS_CTLR_ITS_NUMBER; 1703 + ctlr |= its_number << GITS_CTLR_ITS_NUMBER_SHIFT; 1704 + writel_relaxed(ctlr, its_base + GITS_CTLR); 1705 + ctlr = readl_relaxed(its_base + GITS_CTLR); 1706 + if ((ctlr & GITS_CTLR_ITS_NUMBER) != (its_number << GITS_CTLR_ITS_NUMBER_SHIFT)) { 1707 + its_number = ctlr & GITS_CTLR_ITS_NUMBER; 1708 + its_number >>= GITS_CTLR_ITS_NUMBER_SHIFT; 1709 + } 1710 + 1711 + if (test_and_set_bit(its_number, &its_list_map)) { 1712 + pr_err("ITS@%pa: Duplicate ITSList entry %d\n", 1713 + &res->start, its_number); 1714 + return -EINVAL; 1715 + } 1716 + 1717 + return its_number; 1718 + } 1719 + 1691 1720 static int __init its_probe_one(struct resource *res, 1692 1721 struct fwnode_handle *handle, int numa_node) 1693 1722 { 1694 1723 struct its_node *its; 1695 1724 void __iomem *its_base; 1696 - u32 val; 1697 - u64 baser, tmp; 1725 + u32 val, ctlr; 1726 + u64 baser, tmp, typer; 1698 1727 int err; 1699 1728 1700 1729 its_base = ioremap(res->start, resource_size(res)); ··· 1765 1718 raw_spin_lock_init(&its->lock); 1766 1719 INIT_LIST_HEAD(&its->entry); 1767 1720 INIT_LIST_HEAD(&its->its_device_list); 1721 + typer = gic_read_typer(its_base + GITS_TYPER); 1768 1722 its->base = its_base; 1769 1723 its->phys_base = res->start; 1770 - its->ite_size = ((gic_read_typer(its_base + GITS_TYPER) >> 4) & 0xf) + 1; 1724 + its->ite_size = GITS_TYPER_ITT_ENTRY_SIZE(typer); 1725 + its->is_v4 = !!(typer & GITS_TYPER_VLPIS); 1726 + if (its->is_v4) { 1727 + if (!(typer & GITS_TYPER_VMOVP)) { 1728 + err = its_compute_its_list_map(res, its_base); 1729 + if (err < 0) 1730 + goto out_free_its; 1731 + 1732 + pr_info("ITS@%pa: Using ITS number %d\n", 1733 + &res->start, err); 1734 + } else { 1735 + pr_info("ITS@%pa: Single VMOVP capable\n", &res->start); 1736 + } 1737 + } 1738 + 1771 1739 its->numa_node = numa_node; 1772 1740 1773 1741 its->cmd_base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, ··· 1829 1767 } 1830 1768 1831 1769 gits_write_cwriter(0, its->base + GITS_CWRITER); 1832 - writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR); 1770 + ctlr = readl_relaxed(its->base + GITS_CTLR); 1771 + writel_relaxed(ctlr | GITS_CTLR_ENABLE, its->base + GITS_CTLR); 1833 1772 1834 1773 err = its_init_domain(handle, its); 1835 1774 if (err)
+5
include/linux/irqchip/arm-gic-v3.h
··· 235 235 #define GITS_TRANSLATER 0x10040 236 236 237 237 #define GITS_CTLR_ENABLE (1U << 0) 238 + #define GITS_CTLR_ITS_NUMBER_SHIFT 4 239 + #define GITS_CTLR_ITS_NUMBER (0xFU << GITS_CTLR_ITS_NUMBER_SHIFT) 238 240 #define GITS_CTLR_QUIESCENT (1U << 31) 239 241 240 242 #define GITS_TYPER_PLPIS (1UL << 0) 243 + #define GITS_TYPER_VLPIS (1UL << 1) 241 244 #define GITS_TYPER_ITT_ENTRY_SIZE_SHIFT 4 245 + #define GITS_TYPER_ITT_ENTRY_SIZE(r) ((((r) >> GITS_TYPER_ITT_ENTRY_SIZE_SHIFT) & 0x1f) + 1) 242 246 #define GITS_TYPER_IDBITS_SHIFT 8 243 247 #define GITS_TYPER_DEVBITS_SHIFT 13 244 248 #define GITS_TYPER_DEVBITS(r) ((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1) 245 249 #define GITS_TYPER_PTA (1UL << 19) 246 250 #define GITS_TYPER_HWCOLLCNT_SHIFT 24 251 + #define GITS_TYPER_VMOVP (1ULL << 37) 247 252 248 253 #define GITS_IIDR_REV_SHIFT 12 249 254 #define GITS_IIDR_REV_MASK (0xf << GITS_IIDR_REV_SHIFT)