提交 3d51969c 编写于 作者: T Thomas Gleixner

Merge tag 'irqchip-4.14-3' of...

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
...@@ -99,7 +99,7 @@ Examples: ...@@ -99,7 +99,7 @@ Examples:
compatible = "arm,gic-v3-its"; compatible = "arm,gic-v3-its";
msi-controller; msi-controller;
#msi-cells = <1>; #msi-cells = <1>;
reg = <0x0 0x2c200000 0 0x200000>; reg = <0x0 0x2c200000 0 0x20000>;
}; };
}; };
...@@ -124,14 +124,14 @@ Examples: ...@@ -124,14 +124,14 @@ Examples:
compatible = "arm,gic-v3-its"; compatible = "arm,gic-v3-its";
msi-controller; msi-controller;
#msi-cells = <1>; #msi-cells = <1>;
reg = <0x0 0x2c200000 0 0x200000>; reg = <0x0 0x2c200000 0 0x20000>;
}; };
gic-its@2c400000 { gic-its@2c400000 {
compatible = "arm,gic-v3-its"; compatible = "arm,gic-v3-its";
msi-controller; msi-controller;
#msi-cells = <1>; #msi-cells = <1>;
reg = <0x0 0x2c400000 0 0x200000>; reg = <0x0 0x2c400000 0 0x20000>;
}; };
ppi-partitions { ppi-partitions {
......
...@@ -107,6 +107,10 @@ struct its_node { ...@@ -107,6 +107,10 @@ struct its_node {
#define ITS_ITT_ALIGN SZ_256 #define ITS_ITT_ALIGN SZ_256
/* The maximum number of VPEID bits supported by VLPI commands */
#define ITS_MAX_VPEID_BITS (16)
#define ITS_MAX_VPEID (1 << (ITS_MAX_VPEID_BITS))
/* Convert page order to size in bytes */ /* Convert page order to size in bytes */
#define PAGE_ORDER_TO_SIZE(o) (PAGE_SIZE << (o)) #define PAGE_ORDER_TO_SIZE(o) (PAGE_SIZE << (o))
...@@ -308,7 +312,7 @@ static void its_encode_size(struct its_cmd_block *cmd, u8 size) ...@@ -308,7 +312,7 @@ static void its_encode_size(struct its_cmd_block *cmd, u8 size)
static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr) static void its_encode_itt(struct its_cmd_block *cmd, u64 itt_addr)
{ {
its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 50, 8); its_mask_encode(&cmd->raw_cmd[2], itt_addr >> 8, 51, 8);
} }
static void its_encode_valid(struct its_cmd_block *cmd, int valid) 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,7 +322,7 @@ static void its_encode_valid(struct its_cmd_block *cmd, int valid)
static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr) static void its_encode_target(struct its_cmd_block *cmd, u64 target_addr)
{ {
its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 50, 16); its_mask_encode(&cmd->raw_cmd[2], target_addr >> 16, 51, 16);
} }
static void its_encode_collection(struct its_cmd_block *cmd, u16 col) 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,7 +362,7 @@ static void its_encode_its_list(struct its_cmd_block *cmd, u16 its_list)
static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa) static void its_encode_vpt_addr(struct its_cmd_block *cmd, u64 vpt_pa)
{ {
its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 50, 16); its_mask_encode(&cmd->raw_cmd[3], vpt_pa >> 16, 51, 16);
} }
static void its_encode_vpt_size(struct its_cmd_block *cmd, u8 vpt_size) 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,9 +1482,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
u64 val = its_read_baser(its, baser); u64 val = its_read_baser(its, baser);
u64 esz = GITS_BASER_ENTRY_SIZE(val); u64 esz = GITS_BASER_ENTRY_SIZE(val);
u64 type = GITS_BASER_TYPE(val); u64 type = GITS_BASER_TYPE(val);
u64 baser_phys, tmp;
u32 alloc_pages; u32 alloc_pages;
void *base; void *base;
u64 tmp;
retry_alloc_baser: retry_alloc_baser:
alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz); alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz);
...@@ -1496,8 +1500,24 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, ...@@ -1496,8 +1500,24 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
if (!base) if (!base)
return -ENOMEM; return -ENOMEM;
baser_phys = virt_to_phys(base);
/* Check if the physical address of the memory is above 48bits */
if (IS_ENABLED(CONFIG_ARM64_64K_PAGES) && (baser_phys >> 48)) {
/* 52bit PA is supported only when PageSize=64K */
if (psz != SZ_64K) {
pr_err("ITS: no 52bit PA support when psz=%d\n", psz);
free_pages((unsigned long)base, order);
return -ENXIO;
}
/* Convert 52bit PA to 48bit field */
baser_phys = GITS_BASER_PHYS_52_to_48(baser_phys);
}
retry_baser: retry_baser:
val = (virt_to_phys(base) | val = (baser_phys |
(type << GITS_BASER_TYPE_SHIFT) | (type << GITS_BASER_TYPE_SHIFT) |
((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) | ((esz - 1) << GITS_BASER_ENTRY_SIZE_SHIFT) |
((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT) | ((alloc_pages - 1) << GITS_BASER_PAGES_SHIFT) |
...@@ -1582,13 +1602,12 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, ...@@ -1582,13 +1602,12 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
static bool its_parse_indirect_baser(struct its_node *its, static bool its_parse_indirect_baser(struct its_node *its,
struct its_baser *baser, struct its_baser *baser,
u32 psz, u32 *order) u32 psz, u32 *order, u32 ids)
{ {
u64 tmp = its_read_baser(its, baser); u64 tmp = its_read_baser(its, baser);
u64 type = GITS_BASER_TYPE(tmp); u64 type = GITS_BASER_TYPE(tmp);
u64 esz = GITS_BASER_ENTRY_SIZE(tmp); u64 esz = GITS_BASER_ENTRY_SIZE(tmp);
u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb; u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb;
u32 ids = its->device_ids;
u32 new_order = *order; u32 new_order = *order;
bool indirect = false; bool indirect = false;
...@@ -1680,9 +1699,13 @@ static int its_alloc_tables(struct its_node *its) ...@@ -1680,9 +1699,13 @@ static int its_alloc_tables(struct its_node *its)
continue; continue;
case GITS_BASER_TYPE_DEVICE: case GITS_BASER_TYPE_DEVICE:
indirect = its_parse_indirect_baser(its, baser,
psz, &order,
its->device_ids);
case GITS_BASER_TYPE_VCPU: case GITS_BASER_TYPE_VCPU:
indirect = its_parse_indirect_baser(its, baser, indirect = its_parse_indirect_baser(its, baser,
psz, &order); psz, &order,
ITS_MAX_VPEID_BITS);
break; break;
} }
...@@ -2551,7 +2574,7 @@ static struct irq_chip its_vpe_irq_chip = { ...@@ -2551,7 +2574,7 @@ static struct irq_chip its_vpe_irq_chip = {
static int its_vpe_id_alloc(void) static int its_vpe_id_alloc(void)
{ {
return ida_simple_get(&its_vpeid_ida, 0, 1 << 16, GFP_KERNEL); return ida_simple_get(&its_vpeid_ida, 0, ITS_MAX_VPEID, GFP_KERNEL);
} }
static void its_vpe_id_free(u16 id) static void its_vpe_id_free(u16 id)
...@@ -2851,7 +2874,7 @@ static int its_init_vpe_domain(void) ...@@ -2851,7 +2874,7 @@ static int its_init_vpe_domain(void)
return -ENOMEM; return -ENOMEM;
} }
BUG_ON(entries != vpe_proxy.dev->nr_ites); BUG_ON(entries > vpe_proxy.dev->nr_ites);
raw_spin_lock_init(&vpe_proxy.lock); raw_spin_lock_init(&vpe_proxy.lock);
vpe_proxy.next_victim = 0; vpe_proxy.next_victim = 0;
......
...@@ -141,7 +141,7 @@ static void __init tangox_irq_init_chip(struct irq_chip_generic *gc, ...@@ -141,7 +141,7 @@ static void __init tangox_irq_init_chip(struct irq_chip_generic *gc,
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
ct[i].chip.irq_ack = irq_gc_ack_set_bit; ct[i].chip.irq_ack = irq_gc_ack_set_bit;
ct[i].chip.irq_mask = irq_gc_mask_disable_reg; ct[i].chip.irq_mask = irq_gc_mask_disable_reg;
ct[i].chip.irq_mask_ack = irq_gc_mask_disable_reg_and_ack; ct[i].chip.irq_mask_ack = irq_gc_mask_disable_and_ack_set;
ct[i].chip.irq_unmask = irq_gc_unmask_enable_reg; ct[i].chip.irq_unmask = irq_gc_unmask_enable_reg;
ct[i].chip.irq_set_type = tangox_irq_set_type; ct[i].chip.irq_set_type = tangox_irq_set_type;
ct[i].chip.name = gc->domain->name; ct[i].chip.name = gc->domain->name;
......
...@@ -1009,7 +1009,7 @@ void irq_gc_mask_clr_bit(struct irq_data *d); ...@@ -1009,7 +1009,7 @@ void irq_gc_mask_clr_bit(struct irq_data *d);
void irq_gc_unmask_enable_reg(struct irq_data *d); void irq_gc_unmask_enable_reg(struct irq_data *d);
void irq_gc_ack_set_bit(struct irq_data *d); void irq_gc_ack_set_bit(struct irq_data *d);
void irq_gc_ack_clr_bit(struct irq_data *d); void irq_gc_ack_clr_bit(struct irq_data *d);
void irq_gc_mask_disable_reg_and_ack(struct irq_data *d); void irq_gc_mask_disable_and_ack_set(struct irq_data *d);
void irq_gc_eoi(struct irq_data *d); void irq_gc_eoi(struct irq_data *d);
int irq_gc_set_wake(struct irq_data *d, unsigned int on); int irq_gc_set_wake(struct irq_data *d, unsigned int on);
......
...@@ -372,6 +372,8 @@ ...@@ -372,6 +372,8 @@
#define GITS_BASER_ENTRY_SIZE_SHIFT (48) #define GITS_BASER_ENTRY_SIZE_SHIFT (48)
#define GITS_BASER_ENTRY_SIZE(r) ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1) #define GITS_BASER_ENTRY_SIZE(r) ((((r) >> GITS_BASER_ENTRY_SIZE_SHIFT) & 0x1f) + 1)
#define GITS_BASER_ENTRY_SIZE_MASK GENMASK_ULL(52, 48) #define GITS_BASER_ENTRY_SIZE_MASK GENMASK_ULL(52, 48)
#define GITS_BASER_PHYS_52_to_48(phys) \
(((phys) & GENMASK_ULL(47, 16)) | (((phys) >> 48) & 0xf) << 12)
#define GITS_BASER_SHAREABILITY_SHIFT (10) #define GITS_BASER_SHAREABILITY_SHIFT (10)
#define GITS_BASER_InnerShareable \ #define GITS_BASER_InnerShareable \
GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable) GIC_BASER_SHAREABILITY(GITS_BASER, InnerShareable)
......
...@@ -135,17 +135,26 @@ void irq_gc_ack_clr_bit(struct irq_data *d) ...@@ -135,17 +135,26 @@ void irq_gc_ack_clr_bit(struct irq_data *d)
} }
/** /**
* irq_gc_mask_disable_reg_and_ack - Mask and ack pending interrupt * irq_gc_mask_disable_and_ack_set - Mask and ack pending interrupt
* @d: irq_data * @d: irq_data
*
* This generic implementation of the irq_mask_ack method is for chips
* with separate enable/disable registers instead of a single mask
* register and where a pending interrupt is acknowledged by setting a
* bit.
*
* Note: This is the only permutation currently used. Similar generic
* functions should be added here if other permutations are required.
*/ */
void irq_gc_mask_disable_reg_and_ack(struct irq_data *d) void irq_gc_mask_disable_and_ack_set(struct irq_data *d)
{ {
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d); struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct irq_chip_type *ct = irq_data_get_chip_type(d); struct irq_chip_type *ct = irq_data_get_chip_type(d);
u32 mask = d->mask; u32 mask = d->mask;
irq_gc_lock(gc); irq_gc_lock(gc);
irq_reg_writel(gc, mask, ct->regs.mask); irq_reg_writel(gc, mask, ct->regs.disable);
*ct->mask_cache &= ~mask;
irq_reg_writel(gc, mask, ct->regs.ack); irq_reg_writel(gc, mask, ct->regs.ack);
irq_gc_unlock(gc); irq_gc_unlock(gc);
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册