diff options
author | Thomas Gleixner <tglx@linutronix.de> | 2017-10-16 04:26:46 -0400 |
---|---|---|
committer | Thomas Gleixner <tglx@linutronix.de> | 2017-10-16 04:26:46 -0400 |
commit | 3d51969ce318963e5330bda74dcfac22da180c71 (patch) | |
tree | d6a12a35eb4c30b3d7800e2bec274914b6ccf3a3 | |
parent | 33d930e59a98fa10a0db9f56c7fa2f21a4aef9b9 (diff) | |
parent | 0d08af35f16a0cc418ad2afde3bc5f70ace82705 (diff) |
Merge tag 'irqchip-4.14-3' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent
Pull irqchip updates for 4.14-rc5 from Marc Zyngier:
- Fix unfortunate mistake in the GICv3 ITS binding example
- Two fixes for the recently merged GICv4 support
- GICv3 ITS 52bit PA fixes
- Generic irqchip mask-ack fix, and its application to the tango irqchip
-rw-r--r-- | Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt | 6 | ||||
-rw-r--r-- | drivers/irqchip/irq-gic-v3-its.c | 43 | ||||
-rw-r--r-- | drivers/irqchip/irq-tango.c | 2 | ||||
-rw-r--r-- | include/linux/irq.h | 2 | ||||
-rw-r--r-- | include/linux/irqchip/arm-gic-v3.h | 2 | ||||
-rw-r--r-- | kernel/irq/generic-chip.c | 15 |
6 files changed, 52 insertions, 18 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt index 4c29cdab0ea5..5eb108e180fa 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.txt | |||
@@ -99,7 +99,7 @@ Examples: | |||
99 | compatible = "arm,gic-v3-its"; | 99 | compatible = "arm,gic-v3-its"; |
100 | msi-controller; | 100 | msi-controller; |
101 | #msi-cells = <1>; | 101 | #msi-cells = <1>; |
102 | reg = <0x0 0x2c200000 0 0x200000>; | 102 | reg = <0x0 0x2c200000 0 0x20000>; |
103 | }; | 103 | }; |
104 | }; | 104 | }; |
105 | 105 | ||
@@ -124,14 +124,14 @@ Examples: | |||
124 | compatible = "arm,gic-v3-its"; | 124 | compatible = "arm,gic-v3-its"; |
125 | msi-controller; | 125 | msi-controller; |
126 | #msi-cells = <1>; | 126 | #msi-cells = <1>; |
127 | reg = <0x0 0x2c200000 0 0x200000>; | 127 | reg = <0x0 0x2c200000 0 0x20000>; |
128 | }; | 128 | }; |
129 | 129 | ||
130 | gic-its@2c400000 { | 130 | gic-its@2c400000 { |
131 | compatible = "arm,gic-v3-its"; | 131 | compatible = "arm,gic-v3-its"; |
132 | msi-controller; | 132 | msi-controller; |
133 | #msi-cells = <1>; | 133 | #msi-cells = <1>; |
134 | reg = <0x0 0x2c400000 0 0x200000>; | 134 | reg = <0x0 0x2c400000 0 0x20000>; |
135 | }; | 135 | }; |
136 | 136 | ||
137 | ppi-partitions { | 137 | ppi-partitions { |
diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index e8d89343d613..e88395605e32 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c | |||
@@ -107,6 +107,10 @@ struct its_node { | |||
107 | 107 | ||
108 | #define ITS_ITT_ALIGN SZ_256 | 108 | #define ITS_ITT_ALIGN SZ_256 |
109 | 109 | ||
110 | /* The maximum number of VPEID bits supported by VLPI commands */ | ||
111 | #define ITS_MAX_VPEID_BITS (16) | ||
112 | #define ITS_MAX_VPEID (1 << (ITS_MAX_VPEID_BITS)) | ||
113 | |||
110 | /* Convert page order to size in bytes */ | 114 | /* Convert page order to size in bytes */ |
111 | #define PAGE_ORDER_TO_SIZE(o) (PAGE_SIZE << (o)) | 115 | #define PAGE_ORDER_TO_SIZE(o) (PAGE_SIZE << (o)) |
112 | 116 | ||
@@ -308,7 +312,7 @@ static void its_encode_size(struct its_cmd_block *cmd, u8 size) | |||
308 | 312 | ||
309 | static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr) | 313 | static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr) |
310 | { | 314 | { |
311 | its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 50, 8); | 315 | its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 51, 8); |
312 | } | 316 | } |
313 | 317 | ||
314 | static void its_encode_valid(struct its_cmd_block *cmd, int valid) | 318 | static void its_encode_valid(struct its_cmd_block *cmd, int valid) |
@@ -318,7 +322,7 @@ static void its_encode_valid(struct its_cmd_block *cmd, int valid) | |||
318 | 322 | ||
319 | static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr) | 323 | static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr) |
320 | { | 324 | { |
321 | its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 50, 16); | 325 | its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 51, 16); |
322 | } | 326 | } |
323 | 327 | ||
324 | static void its_encode_collection(struct its_cmd_block *cmd, u16 col) | 328 | static void its_encode_collection(struct its_cmd_block *cmd, u16 col) |
@@ -358,7 +362,7 @@ static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list) | |||
358 | 362 | ||
359 | static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa) | 363 | static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa) |
360 | { | 364 | { |
361 | its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16); | 365 | its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 51, 16); |
362 | } | 366 | } |
363 | 367 | ||
364 | static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size) | 368 | static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size) |
@@ -1478,9 +1482,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, | |||
1478 | u64 val = its_read_baser(its, baser); | 1482 | u64 val = its_read_baser(its, baser); |
1479 | u64 esz = GITS_BASER_ENTRY_SIZE(val); | 1483 | u64 esz = GITS_BASER_ENTRY_SIZE(val); |
1480 | u64 type = GITS_BASER_TYPE(val); | 1484 | u64 type = GITS_BASER_TYPE(val); |
1485 | u64 baser_phys, tmp; | ||
1481 | u32 alloc_pages; | 1486 | u32 alloc_pages; |
1482 | void *base; | 1487 | void *base; |
1483 | u64 tmp; | ||
1484 | 1488 | ||
1485 | retry_alloc_baser: | 1489 | retry_alloc_baser: |
1486 | alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz); | 1490 | alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz); |
@@ -1496,8 +1500,24 @@ retry_alloc_baser: | |||
1496 | if (!base) | 1500 | if (!base) |
1497 | return -ENOMEM; | 1501 | return -ENOMEM; |
1498 | 1502 | ||
1503 | baser_phys = virt_to_phys(base); | ||
1504 | |||
1505 | /* Check if the physical address of the memory is above 48bits */ | ||
1506 | if (IS_ENABLED(CONFIG_ARM64_64K_PAGES) && (baser_phys >> 48)) { | ||
1507 | |||
1508 | /* 52bit PA is supported only when PageSize=64K */ | ||
1509 | if (psz != SZ_64K) { | ||
1510 | pr_err("ITS: no 52bit PA support when psz=%d\n", psz); | ||
1511 | free_pages((unsigned long)base, order); | ||
1512 | return -ENXIO; | ||
1513 | } | ||
1514 | |||
1515 | /* Convert 52bit PA to 48bit field */ | ||
1516 | baser_phys = GITS_BASER_PHYS_52_to_48(baser_phys); | ||
1517 | } | ||
1518 | |||
1499 | retry_baser: | 1519 | retry_baser: |
1500 | val = (virt_to_phys(base) | | 1520 | val = (baser_phys | |
1501 | (type << GITS_BASER_TYPE_SHIFT) | | 1521 | (type << GITS_BASER_TYPE_SHIFT) | |
1502 | ((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) | | 1522 | ((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) | |
1503 | ((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT) | | 1523 | ((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT) | |
@@ -1582,13 +1602,12 @@ retry_baser: | |||
1582 | 1602 | ||
1583 | static bool its_parse_indirect_baser(struct its_node *its, | 1603 | static bool its_parse_indirect_baser(struct its_node *its, |
1584 | struct its_baser *baser, | 1604 | struct its_baser *baser, |
1585 | u32 psz, u32 *order) | 1605 | u32 psz, u32 *order, u32 ids) |
1586 | { | 1606 | { |
1587 | u64 tmp = its_read_baser(its, baser); | 1607 | u64 tmp = its_read_baser(its, baser); |
1588 | u64 type = GITS_BASER_TYPE(tmp); | 1608 | u64 type = GITS_BASER_TYPE(tmp); |
1589 | u64 esz = GITS_BASER_ENTRY_SIZE(tmp); | 1609 | u64 esz = GITS_BASER_ENTRY_SIZE(tmp); |
1590 | u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb; | 1610 | u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb; |
1591 | u32 ids = its->device_ids; | ||
1592 | u32 new_order = *order; | 1611 | u32 new_order = *order; |
1593 | bool indirect = false; | 1612 | bool indirect = false; |
1594 | 1613 | ||
@@ -1680,9 +1699,13 @@ static int its_alloc_tables(struct its_node *its) | |||
1680 | continue; | 1699 | continue; |
1681 | 1700 | ||
1682 | case GITS_BASER_TYPE_DEVICE: | 1701 | case GITS_BASER_TYPE_DEVICE: |
1702 | indirect = its_parse_indirect_baser(its, baser, | ||
1703 | psz, &order, | ||
1704 | its->device_ids); | ||
1683 | case GITS_BASER_TYPE_VCPU: | 1705 | case GITS_BASER_TYPE_VCPU: |
1684 | indirect = its_parse_indirect_baser(its, baser, | 1706 | indirect = its_parse_indirect_baser(its, baser, |
1685 | psz, &order); | 1707 | psz, &order, |
1708 | ITS_MAX_VPEID_BITS); | ||
1686 | break; | 1709 | break; |
1687 | } | 1710 | } |
1688 | 1711 | ||
@@ -2551,7 +2574,7 @@ static struct irq_chip its_vpe_irq_chip = { | |||
2551 | 2574 | ||
2552 | static int its_vpe_id_alloc(void) | 2575 | static int its_vpe_id_alloc(void) |
2553 | { | 2576 | { |
2554 | return ida_simple_get(&its_vpeid_ida, 0, 1 << 16, GFP_KERNEL); | 2577 | return ida_simple_get(&its_vpeid_ida, 0, ITS_MAX_VPEID, GFP_KERNEL); |
2555 | } | 2578 | } |
2556 | 2579 | ||
2557 | static void its_vpe_id_free(u16 id) | 2580 | static void its_vpe_id_free(u16 id) |
@@ -2851,7 +2874,7 @@ static int its_init_vpe_domain(void) | |||
2851 | return -ENOMEM; | 2874 | return -ENOMEM; |
2852 | } | 2875 | } |
2853 | 2876 | ||
2854 | BUG_ON(entries != vpe_proxy.dev->nr_ites); | 2877 | BUG_ON(entries > vpe_proxy.dev->nr_ites); |
2855 | 2878 | ||
2856 | raw_spin_lock_init(&vpe_proxy.lock); | 2879 | raw_spin_lock_init(&vpe_proxy.lock); |
2857 | vpe_proxy.next_victim = 0; | 2880 | vpe_proxy.next_victim = 0; |
diff --git a/drivers/irqchip/irq-tango.c b/drivers/irqchip/irq-tango.c index bdbb5c0ff7fe..0c085303a583 100644 --- a/drivers/irqchip/irq-tango.c +++ b/drivers/irqchip/irq-tango.c | |||
@@ -141,7 +141,7 @@ static void __init tangox_irq_init_chip(struct irq_chip_generic *gc, | |||
141 | for (i = 0; i < 2; i++) { | 141 | for (i = 0; i < 2; i++) { |
142 | ct[i].chip.irq_ack = irq_gc_ack_set_bit; | 142 | ct[i].chip.irq_ack = irq_gc_ack_set_bit; |
143 | ct[i].chip.irq_mask = irq_gc_mask_disable_reg; | 143 | ct[i].chip.irq_mask = irq_gc_mask_disable_reg; |
144 | ct[i].chip.irq_mask_ack = irq_gc_mask_disable_reg_and_ack; | 144 | ct[i].chip.irq_mask_ack = irq_gc_mask_disable_and_ack_set; |
145 | ct[i].chip.irq_unmask = irq_gc_unmask_enable_reg; | 145 | ct[i].chip.irq_unmask = irq_gc_unmask_enable_reg; |
146 | ct[i].chip.irq_set_type = tangox_irq_set_type; | 146 | ct[i].chip.irq_set_type = tangox_irq_set_type; |
147 | ct[i].chip.name = gc->domain->name; | 147 | ct[i].chip.name = gc->domain->name; |
diff --git a/include/linux/irq.h b/include/linux/irq.h index d4728bf6a537..5ad10948ea95 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -1009,7 +1009,7 @@ void irq_gc_mask_clr_bit(struct irq_data *d); | |||
1009 | void irq_gc_unmask_enable_reg(struct irq_data *d); | 1009 | void irq_gc_unmask_enable_reg(struct irq_data *d); |
1010 | void irq_gc_ack_set_bit(struct irq_data *d); | 1010 | void irq_gc_ack_set_bit(struct irq_data *d); |
1011 | void irq_gc_ack_clr_bit(struct irq_data *d); | 1011 | void irq_gc_ack_clr_bit(struct irq_data *d); |
1012 | void irq_gc_mask_disable_reg_and_ack(struct irq_data *d); | 1012 | void irq_gc_mask_disable_and_ack_set(struct irq_data *d); |
1013 | void irq_gc_eoi(struct irq_data *d); | 1013 | void irq_gc_eoi(struct irq_data *d); |
1014 | int irq_gc_set_wake(struct irq_data *d, unsigned int on); | 1014 | int irq_gc_set_wake(struct irq_data *d, unsigned int on); |
1015 | 1015 | ||
diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index 1ea576c8126f..14b74f22d43c 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h | |||
@@ -372,6 +372,8 @@ | |||
372 | #define GITS_BASER_ENTRY_SIZE_SHIFT (48) | 372 | #define GITS_BASER_ENTRY_SIZE_SHIFT (48) |
373 | #define GITS_BASER_ENTRY_SIZE(r) ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1) | 373 | #define GITS_BASER_ENTRY_SIZE(r) ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1) |
374 | #define GITS_BASER_ENTRY_SIZE_MASK GENMASK_ULL(52, 48) | 374 | #define GITS_BASER_ENTRY_SIZE_MASK GENMASK_ULL(52, 48) |
375 | #define GITS_BASER_PHYS_52_to_48(phys) \ | ||
376 | (((phys) & GENMASK_ULL(47, 16)) | (((phys) >> 48) & 0xf) << 12) | ||
375 | #define GITS_BASER_SHAREABILITY_SHIFT (10) | 377 | #define GITS_BASER_SHAREABILITY_SHIFT (10) |
376 | #define GITS_BASER_InnerShareable \ | 378 | #define GITS_BASER_InnerShareable \ |
377 | GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable) | 379 | GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable) |
diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c index 5270a54b9fa4..c26c5bb6b491 100644 --- a/kernel/irq/generic-chip.c +++ b/kernel/irq/generic-chip.c | |||
@@ -135,17 +135,26 @@ void irq_gc_ack_clr_bit(struct irq_data *d) | |||
135 | } | 135 | } |
136 | 136 | ||
137 | /** | 137 | /** |
138 | * irq_gc_mask_disable_reg_and_ack - Mask and ack pending interrupt | 138 | * irq_gc_mask_disable_and_ack_set - Mask and ack pending interrupt |
139 | * @d: irq_data | 139 | * @d: irq_data |
140 | * | ||
141 | * This generic implementation of the irq_mask_ack method is for chips | ||
142 | * with separate enable/disable registers instead of a single mask | ||
143 | * register and where a pending interrupt is acknowledged by setting a | ||
144 | * bit. | ||
145 | * | ||
146 | * Note: This is the only permutation currently used. Similar generic | ||
147 | * functions should be added here if other permutations are required. | ||
140 | */ | 148 | */ |
141 | void irq_gc_mask_disable_reg_and_ack(struct irq_data *d) | 149 | void irq_gc_mask_disable_and_ack_set(struct irq_data *d) |
142 | { | 150 | { |
143 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); | 151 | struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); |
144 | struct irq_chip_type *ct = irq_data_get_chip_type(d); | 152 | struct irq_chip_type *ct = irq_data_get_chip_type(d); |
145 | u32 mask = d->mask; | 153 | u32 mask = d->mask; |
146 | 154 | ||
147 | irq_gc_lock(gc); | 155 | irq_gc_lock(gc); |
148 | irq_reg_writel(gc, mask, ct->regs.mask); | 156 | irq_reg_writel(gc, mask, ct->regs.disable); |
157 | *ct->mask_cache &= ~mask; | ||
149 | irq_reg_writel(gc, mask, ct->regs.ack); | 158 | irq_reg_writel(gc, mask, ct->regs.ack); |
150 | irq_gc_unlock(gc); | 159 | irq_gc_unlock(gc); |
151 | } | 160 | } |