+79
-22
drivers/irqchip/irq-gic-v3-its.c
+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
+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
+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)