From 2f7c68cb55ecb7331f2381deb497c27155f32faf Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Wed, 03 Jan 2024 09:43:39 +0000 Subject: [PATCH] update kernel to 5.10.198 --- kernel/drivers/irqchip/irq-gic-v3-its.c | 115 +++++++++++++++++++++++++++++++++++++-------------------- 1 files changed, 75 insertions(+), 40 deletions(-) diff --git a/kernel/drivers/irqchip/irq-gic-v3-its.c b/kernel/drivers/irqchip/irq-gic-v3-its.c index 8ccff68..8f0b4a3 100644 --- a/kernel/drivers/irqchip/irq-gic-v3-its.c +++ b/kernel/drivers/irqchip/irq-gic-v3-its.c @@ -268,13 +268,23 @@ raw_spin_unlock_irqrestore(&vpe->vpe_lock, flags); } +static struct irq_chip its_vpe_irq_chip; + static int irq_to_cpuid_lock(struct irq_data *d, unsigned long *flags) { - struct its_vlpi_map *map = get_vlpi_map(d); + struct its_vpe *vpe = NULL; int cpu; - if (map) { - cpu = vpe_to_cpuid_lock(map->vpe, flags); + if (d->chip == &its_vpe_irq_chip) { + vpe = irq_data_get_irq_chip_data(d); + } else { + struct its_vlpi_map *map = get_vlpi_map(d); + if (map) + vpe = map->vpe; + } + + if (vpe) { + cpu = vpe_to_cpuid_lock(vpe, flags); } else { /* Physical LPIs are already locked via the irq_desc lock */ struct its_device *its_dev = irq_data_get_irq_chip_data(d); @@ -288,10 +298,18 @@ static void irq_to_cpuid_unlock(struct irq_data *d, unsigned long flags) { - struct its_vlpi_map *map = get_vlpi_map(d); + struct its_vpe *vpe = NULL; - if (map) - vpe_to_cpuid_unlock(map->vpe, flags); + if (d->chip == &its_vpe_irq_chip) { + vpe = irq_data_get_irq_chip_data(d); + } else { + struct its_vlpi_map *map = get_vlpi_map(d); + if (map) + vpe = map->vpe; + } + + if (vpe) + vpe_to_cpuid_unlock(vpe, flags); } static struct its_collection *valid_col(struct its_collection *col) @@ -1423,13 +1441,28 @@ cpu_relax(); } +static void __direct_lpi_inv(struct irq_data *d, u64 val) +{ + void __iomem *rdbase; + unsigned long flags; + int cpu; + + /* Target the redistributor this LPI is currently routed to */ + cpu = irq_to_cpuid_lock(d, &flags); + raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock); + + rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base; + gic_write_lpir(val, rdbase + GICR_INVLPIR); + wait_for_syncr(rdbase); + + raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock); + irq_to_cpuid_unlock(d, flags); +} + static void direct_lpi_inv(struct irq_data *d) { struct its_vlpi_map *map = get_vlpi_map(d); - void __iomem *rdbase; - unsigned long flags; u64 val; - int cpu; if (map) { struct its_device *its_dev = irq_data_get_irq_chip_data(d); @@ -1443,15 +1476,7 @@ val = d->hwirq; } - /* Target the redistributor this LPI is currently routed to */ - cpu = irq_to_cpuid_lock(d, &flags); - raw_spin_lock(&gic_data_rdist_cpu(cpu)->rd_lock); - rdbase = per_cpu_ptr(gic_rdists->rdist, cpu)->rd_base; - gic_write_lpir(val, rdbase + GICR_INVLPIR); - - wait_for_syncr(rdbase); - raw_spin_unlock(&gic_data_rdist_cpu(cpu)->rd_lock); - irq_to_cpuid_unlock(d, flags); + __direct_lpi_inv(d, val); } static void lpi_update_config(struct irq_data *d, u8 clr, u8 set) @@ -1493,7 +1518,7 @@ * * Ideally, we'd issue a VMAPTI to set the doorbell to its LPI * value or to 1023, depending on the enable bit. But that - * would be issueing a mapping for an /existing/ DevID+EventID + * would be issuing a mapping for an /existing/ DevID+EventID * pair, which is UNPREDICTABLE. Instead, let's issue a VMOVI * to the /same/ vPE, using this opportunity to adjust the * doorbell. Mouahahahaha. We loves it, Precious. @@ -2168,7 +2193,9 @@ { struct page *prop_page; - if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566")) + if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || + of_machine_is_compatible("rockchip,rk3566")) gfp_flags |= GFP_DMA32; prop_page = alloc_pages(gfp_flags, get_order(LPI_PROPBASE_SZ)); if (!prop_page) @@ -2306,7 +2333,9 @@ } gfp_flags = GFP_KERNEL | __GFP_ZERO; - if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566")) + if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || + of_machine_is_compatible("rockchip,rk3566")) gfp_flags |= GFP_DMA32; page = alloc_pages_node(its->numa_node, gfp_flags, order); if (!page) @@ -2357,6 +2386,7 @@ if (IS_ENABLED(CONFIG_NO_GKI) && (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))) { if (tmp & GITS_BASER_SHAREABILITY_MASK) @@ -2947,7 +2977,9 @@ { struct page *pend_page; - if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566")) + if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || + of_machine_is_compatible("rockchip,rk3566")) gfp_flags |= GFP_DMA32; pend_page = alloc_pages(gfp_flags | __GFP_ZERO, get_order(LPI_PENDBASE_SZ)); @@ -3108,6 +3140,7 @@ if (IS_ENABLED(CONFIG_NO_GKI) && (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))) tmp &= ~GICR_PROPBASER_SHAREABILITY_MASK; @@ -3138,6 +3171,7 @@ if (IS_ENABLED(CONFIG_NO_GKI) && (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))) tmp &= ~GICR_PENDBASER_SHAREABILITY_MASK; @@ -3163,7 +3197,7 @@ /* * It's possible for CPU to receive VLPIs before it is - * sheduled as a vPE, especially for the first CPU, and the + * scheduled as a vPE, especially for the first CPU, and the * VLPI with INTID larger than 2^(IDbits+1) will be considered * as out of range and dropped by GIC. * So we initialize IDbits to known value to avoid VLPI drop. @@ -3306,7 +3340,9 @@ if (!table[idx]) { gfp_t gfp_flags = GFP_KERNEL | __GFP_ZERO; - if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566")) + if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || + of_machine_is_compatible("rockchip,rk3566")) gfp_flags |= GFP_DMA32; page = alloc_pages_node(its->numa_node, gfp_flags, get_order(baser->psz)); @@ -3414,7 +3450,9 @@ sz = nr_ites * (FIELD_GET(GITS_TYPER_ITT_ENTRY_SIZE, its->typer) + 1); sz = max(sz, ITS_ITT_ALIGN) + ITS_ITT_ALIGN - 1; gfp_flags = GFP_KERNEL; - if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566")) { + if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || + of_machine_is_compatible("rockchip,rk3566")) { gfp_flags |= GFP_DMA32; itt = (void *)__get_free_pages(gfp_flags, get_order(sz)); } else { @@ -3436,6 +3474,7 @@ kfree(dev); if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || of_machine_is_compatible("rockchip,rk3566")) free_pages((unsigned long)itt, get_order(sz)); else @@ -3480,6 +3519,7 @@ kfree(its_dev->event_map.col_map); if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || of_machine_is_compatible("rockchip,rk3566")) free_pages((unsigned long)its_dev->itt, get_order(its_dev->itt_sz)); else @@ -3679,7 +3719,7 @@ /* * If all interrupts have been freed, start mopping the - * floor. This is conditionned on the device not being shared. + * floor. This is conditioned on the device not being shared. */ if (!its_dev->shared && bitmap_empty(its_dev->event_map.lpi_map, @@ -3984,18 +4024,10 @@ { struct its_vpe *vpe = irq_data_get_irq_chip_data(d); - if (gic_rdists->has_direct_lpi) { - void __iomem *rdbase; - - /* Target the redistributor this VPE is currently known on */ - raw_spin_lock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock); - rdbase = per_cpu_ptr(gic_rdists->rdist, vpe->col_idx)->rd_base; - gic_write_lpir(d->parent_data->hwirq, rdbase + GICR_INVLPIR); - wait_for_syncr(rdbase); - raw_spin_unlock(&gic_data_rdist_cpu(vpe->col_idx)->rd_lock); - } else { + if (gic_rdists->has_direct_lpi) + __direct_lpi_inv(d, d->parent_data->hwirq); + else its_vpe_send_cmd(vpe, its_send_inv); - } } static void its_vpe_mask_irq(struct irq_data *d) @@ -4257,7 +4289,7 @@ { /* * There is no notion of affinity for virtual SGIs, at least - * not on the host (since they can only be targetting a vPE). + * not on the host (since they can only be targeting a vPE). * Tell the kernel we've done whatever it asked for. */ irq_data_update_effective_affinity(d, mask_val); @@ -4302,7 +4334,7 @@ /* * Locking galore! We can race against two different events: * - * - Concurent vPE affinity change: we must make sure it cannot + * - Concurrent vPE affinity change: we must make sure it cannot * happen, or we'll talk to the wrong redistributor. This is * identical to what happens with vLPIs. * @@ -5085,7 +5117,9 @@ its->numa_node = numa_node; gfp_flags = GFP_KERNEL | __GFP_ZERO; - if (of_machine_is_compatible("rockchip,rk3568") || of_machine_is_compatible("rockchip,rk3566")) + if (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || + of_machine_is_compatible("rockchip,rk3566")) gfp_flags |= GFP_DMA32; page = alloc_pages_node(its->numa_node, gfp_flags, get_order(ITS_CMD_QUEUE_SZ)); @@ -5120,6 +5154,7 @@ if (IS_ENABLED(CONFIG_NO_GKI) && (of_machine_is_compatible("rockchip,rk3568") || + of_machine_is_compatible("rockchip,rk3567") || of_machine_is_compatible("rockchip,rk3566") || of_machine_is_compatible("rockchip,rk3588"))) tmp &= ~GITS_CBASER_SHAREABILITY_MASK; -- Gitblit v1.6.2