Merge tag 'irqchip-5.0-3' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent

Pull irqchip updates from Marc Zyngier:

- Another GICv3 ITS fix for devices sharing the same DevID
- Don't return invalid data on exhaustion of the GICv3 LPI pool
- Fix a GICv3 field decoding bug leading to memory over-allocation
- Init GICv4 at boot time instead of lazy init
- Fix interrupt masking on PJ4

Changed files
+85 -24
drivers
include
linux
irqchip
+79 -22
drivers/irqchip/irq-gic-v3-its.c
··· 97 97 * The ITS structure - contains most of the infrastructure, with the 98 98 * top-level MSI domain, the command queue, the collections, and the 99 99 * list of devices writing to it. 100 + * 101 + * dev_alloc_lock has to be taken for device allocations, while the 102 + * spinlock must be taken to parse data structures such as the device 103 + * list. 100 104 */ 101 105 struct its_node { 102 106 raw_spinlock_t lock; 107 + struct mutex dev_alloc_lock; 103 108 struct list_head entry; 104 109 void __iomem *base; 105 110 phys_addr_t phys_base; ··· 161 156 void *itt; 162 157 u32 nr_ites; 163 158 u32 device_id; 159 + bool shared; 164 160 }; 165 161 166 162 static struct { ··· 1586 1580 nr_irqs /= 2; 1587 1581 } while (nr_irqs > 0); 1588 1582 1583 + if (!nr_irqs) 1584 + err = -ENOSPC; 1585 + 1589 1586 if (err) 1590 1587 goto out; 1591 1588 ··· 2068 2059 return 0; 2069 2060 } 2070 2061 2062 + static u64 its_clear_vpend_valid(void __iomem *vlpi_base) 2063 + { 2064 + u32 count = 1000000; /* 1s! */ 2065 + bool clean; 2066 + u64 val; 2067 + 2068 + val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); 2069 + val &= ~GICR_VPENDBASER_Valid; 2070 + gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER); 2071 + 2072 + do { 2073 + val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); 2074 + clean = !(val & GICR_VPENDBASER_Dirty); 2075 + if (!clean) { 2076 + count--; 2077 + cpu_relax(); 2078 + udelay(1); 2079 + } 2080 + } while (!clean && count); 2081 + 2082 + return val; 2083 + } 2084 + 2071 2085 static void its_cpu_init_lpis(void) 2072 2086 { 2073 2087 void __iomem *rbase = gic_data_rdist_rd_base(); ··· 2175 2143 val = readl_relaxed(rbase + GICR_CTLR); 2176 2144 val |= GICR_CTLR_ENABLE_LPIS; 2177 2145 writel_relaxed(val, rbase + GICR_CTLR); 2146 + 2147 + if (gic_rdists->has_vlpis) { 2148 + void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); 2149 + 2150 + /* 2151 + * It's possible for CPU to receive VLPIs before it is 2152 + * sheduled as a vPE, especially for the first CPU, and the 2153 + * VLPI with INTID larger than 2^(IDbits+1) will be considered 2154 + * as out of range and dropped by GIC. 2155 + * So we initialize IDbits to known value to avoid VLPI drop. 2156 + */ 2157 + val = (LPI_NRBITS - 1) & GICR_VPROPBASER_IDBITS_MASK; 2158 + pr_debug("GICv4: CPU%d: Init IDbits to 0x%llx for GICR_VPROPBASER\n", 2159 + smp_processor_id(), val); 2160 + gits_write_vpropbaser(val, vlpi_base + GICR_VPROPBASER); 2161 + 2162 + /* 2163 + * Also clear Valid bit of GICR_VPENDBASER, in case some 2164 + * ancient programming gets left in and has possibility of 2165 + * corrupting memory. 2166 + */ 2167 + val = its_clear_vpend_valid(vlpi_base); 2168 + WARN_ON(val & GICR_VPENDBASER_Dirty); 2169 + } 2178 2170 2179 2171 /* Make sure the GIC has seen the above */ 2180 2172 dsb(sy); ··· 2478 2422 struct its_device *its_dev; 2479 2423 struct msi_domain_info *msi_info; 2480 2424 u32 dev_id; 2425 + int err = 0; 2481 2426 2482 2427 /* 2483 2428 * We ignore "dev" entierely, and rely on the dev_id that has ··· 2501 2444 return -EINVAL; 2502 2445 } 2503 2446 2447 + mutex_lock(&its->dev_alloc_lock); 2504 2448 its_dev = its_find_device(its, dev_id); 2505 2449 if (its_dev) { 2506 2450 /* ··· 2509 2451 * another alias (PCI bridge of some sort). No need to 2510 2452 * create the device. 2511 2453 */ 2454 + its_dev->shared = true; 2512 2455 pr_debug("Reusing ITT for devID %x\n", dev_id); 2513 2456 goto out; 2514 2457 } 2515 2458 2516 2459 its_dev = its_create_device(its, dev_id, nvec, true); 2517 - if (!its_dev) 2518 - return -ENOMEM; 2460 + if (!its_dev) { 2461 + err = -ENOMEM; 2462 + goto out; 2463 + } 2519 2464 2520 2465 pr_debug("ITT %d entries, %d bits\n", nvec, ilog2(nvec)); 2521 2466 out: 2467 + mutex_unlock(&its->dev_alloc_lock); 2522 2468 info->scratchpad[0].ptr = its_dev; 2523 - return 0; 2469 + return err; 2524 2470 } 2525 2471 2526 2472 static struct msi_domain_ops its_msi_domain_ops = { ··· 2628 2566 { 2629 2567 struct irq_data *d = irq_domain_get_irq_data(domain, virq); 2630 2568 struct its_device *its_dev = irq_data_get_irq_chip_data(d); 2569 + struct its_node *its = its_dev->its; 2631 2570 int i; 2632 2571 2633 2572 for (i = 0; i < nr_irqs; i++) { ··· 2643 2580 irq_domain_reset_irq_data(data); 2644 2581 } 2645 2582 2646 - /* If all interrupts have been freed, start mopping the floor */ 2647 - if (bitmap_empty(its_dev->event_map.lpi_map, 2583 + mutex_lock(&its->dev_alloc_lock); 2584 + 2585 + /* 2586 + * If all interrupts have been freed, start mopping the 2587 + * floor. This is conditionned on the device not being shared. 2588 + */ 2589 + if (!its_dev->shared && 2590 + bitmap_empty(its_dev->event_map.lpi_map, 2648 2591 its_dev->event_map.nr_lpis)) { 2649 2592 its_lpi_free(its_dev->event_map.lpi_map, 2650 2593 its_dev->event_map.lpi_base, ··· 2661 2592 its_send_mapd(its_dev, 0); 2662 2593 its_free_device(its_dev); 2663 2594 } 2595 + 2596 + mutex_unlock(&its->dev_alloc_lock); 2664 2597 2665 2598 irq_domain_free_irqs_parent(domain, virq, nr_irqs); 2666 2599 } ··· 2826 2755 static void its_vpe_deschedule(struct its_vpe *vpe) 2827 2756 { 2828 2757 void __iomem *vlpi_base = gic_data_rdist_vlpi_base(); 2829 - u32 count = 1000000; /* 1s! */ 2830 - bool clean; 2831 2758 u64 val; 2832 2759 2833 - /* We're being scheduled out */ 2834 - val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); 2835 - val &= ~GICR_VPENDBASER_Valid; 2836 - gits_write_vpendbaser(val, vlpi_base + GICR_VPENDBASER); 2760 + val = its_clear_vpend_valid(vlpi_base); 2837 2761 2838 - do { 2839 - val = gits_read_vpendbaser(vlpi_base + GICR_VPENDBASER); 2840 - clean = !(val & GICR_VPENDBASER_Dirty); 2841 - if (!clean) { 2842 - count--; 2843 - cpu_relax(); 2844 - udelay(1); 2845 - } 2846 - } while (!clean && count); 2847 - 2848 - if (unlikely(!clean && !count)) { 2762 + if (unlikely(val & GICR_VPENDBASER_Dirty)) { 2849 2763 pr_err_ratelimited("ITS virtual pending table not cleaning\n"); 2850 2764 vpe->idai = false; 2851 2765 vpe->pending_last = true; ··· 3573 3517 } 3574 3518 3575 3519 raw_spin_lock_init(&its->lock); 3520 + mutex_init(&its->dev_alloc_lock); 3576 3521 INIT_LIST_HEAD(&its->entry); 3577 3522 INIT_LIST_HEAD(&its->its_device_list); 3578 3523 typer = gic_read_typer(its_base + GITS_TYPER);
+5 -1
drivers/irqchip/irq-mmp.c
··· 34 34 #define SEL_INT_PENDING (1 << 6) 35 35 #define SEL_INT_NUM_MASK 0x3f 36 36 37 + #define MMP2_ICU_INT_ROUTE_PJ4_IRQ (1 << 5) 38 + #define MMP2_ICU_INT_ROUTE_PJ4_FIQ (1 << 6) 39 + 37 40 struct icu_chip_data { 38 41 int nr_irqs; 39 42 unsigned int virq_base; ··· 193 190 static const struct mmp_intc_conf mmp2_conf = { 194 191 .conf_enable = 0x20, 195 192 .conf_disable = 0x0, 196 - .conf_mask = 0x7f, 193 + .conf_mask = MMP2_ICU_INT_ROUTE_PJ4_IRQ | 194 + MMP2_ICU_INT_ROUTE_PJ4_FIQ, 197 195 }; 198 196 199 197 static void __exception_irq_entry mmp_handle_irq(struct pt_regs *regs)
+1 -1
include/linux/irqchip/arm-gic-v3.h
··· 319 319 #define GITS_TYPER_PLPIS (1UL << 0) 320 320 #define GITS_TYPER_VLPIS (1UL << 1) 321 321 #define GITS_TYPER_ITT_ENTRY_SIZE_SHIFT 4 322 - #define GITS_TYPER_ITT_ENTRY_SIZE(r) ((((r) >> GITS_TYPER_ITT_ENTRY_SIZE_SHIFT) & 0x1f) + 1) 322 + #define GITS_TYPER_ITT_ENTRY_SIZE(r) ((((r) >> GITS_TYPER_ITT_ENTRY_SIZE_SHIFT) & 0xf) + 1) 323 323 #define GITS_TYPER_IDBITS_SHIFT 8 324 324 #define GITS_TYPER_DEVBITS_SHIFT 13 325 325 #define GITS_TYPER_DEVBITS(r) ((((r) >> GITS_TYPER_DEVBITS_SHIFT) & 0x1f) + 1)