irqchip/gic-v3-its: Make is_v4 use a TYPER copy
Instead of caching the GICv4 compatibility in a discrete way, cache the TYPER register instead, which can then be used to implement the same functionnality. This will get used more extensively in subsequent patches. Signed-off-by: Marc Zyngier <maz@kernel.org> Reviewed-by: Zenghui Yu <yuzenghui@huawei.com> Link: https://lore.kernel.org/r/20191027144234.8395-5-maz@kernel.org Link: https://lore.kernel.org/r/20191108165805.3071-5-maz@kernel.org
This commit is contained in:
parent
425c09be0f
commit
0dd57fed6b
|
@ -102,6 +102,7 @@ struct its_node {
|
||||||
struct its_collection *collections;
|
struct its_collection *collections;
|
||||||
struct fwnode_handle *fwnode_handle;
|
struct fwnode_handle *fwnode_handle;
|
||||||
u64 (*get_msi_base)(struct its_device *its_dev);
|
u64 (*get_msi_base)(struct its_device *its_dev);
|
||||||
|
u64 typer;
|
||||||
u64 cbaser_save;
|
u64 cbaser_save;
|
||||||
u32 ctlr_save;
|
u32 ctlr_save;
|
||||||
struct list_head its_device_list;
|
struct list_head its_device_list;
|
||||||
|
@ -112,10 +113,11 @@ struct its_node {
|
||||||
int numa_node;
|
int numa_node;
|
||||||
unsigned int msi_domain_flags;
|
unsigned int msi_domain_flags;
|
||||||
u32 pre_its_base; /* for Socionext Synquacer */
|
u32 pre_its_base; /* for Socionext Synquacer */
|
||||||
bool is_v4;
|
|
||||||
int vlpi_redist_offset;
|
int vlpi_redist_offset;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define is_v4(its) (!!((its)->typer & GITS_TYPER_VLPIS))
|
||||||
|
|
||||||
#define ITS_ITT_ALIGN SZ_256
|
#define ITS_ITT_ALIGN SZ_256
|
||||||
|
|
||||||
/* The maximum number of VPEID bits supported by VLPI commands */
|
/* The maximum number of VPEID bits supported by VLPI commands */
|
||||||
|
@ -181,7 +183,7 @@ static u16 get_its_list(struct its_vm *vm)
|
||||||
unsigned long its_list = 0;
|
unsigned long its_list = 0;
|
||||||
|
|
||||||
list_for_each_entry(its, &its_nodes, entry) {
|
list_for_each_entry(its, &its_nodes, entry) {
|
||||||
if (!its->is_v4)
|
if (!is_v4(its))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (vm->vlpi_count[its->list_nr])
|
if (vm->vlpi_count[its->list_nr])
|
||||||
|
@ -1037,7 +1039,7 @@ static void its_send_vmovp(struct its_vpe *vpe)
|
||||||
|
|
||||||
/* Emit VMOVPs */
|
/* Emit VMOVPs */
|
||||||
list_for_each_entry(its, &its_nodes, entry) {
|
list_for_each_entry(its, &its_nodes, entry) {
|
||||||
if (!its->is_v4)
|
if (!is_v4(its))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!vpe->its_vm->vlpi_count[its->list_nr])
|
if (!vpe->its_vm->vlpi_count[its->list_nr])
|
||||||
|
@ -1448,7 +1450,7 @@ static int its_irq_set_vcpu_affinity(struct irq_data *d, void *vcpu_info)
|
||||||
struct its_cmd_info *info = vcpu_info;
|
struct its_cmd_info *info = vcpu_info;
|
||||||
|
|
||||||
/* Need a v4 ITS */
|
/* Need a v4 ITS */
|
||||||
if (!its_dev->its->is_v4)
|
if (!is_v4(its_dev->its))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Unmap request? */
|
/* Unmap request? */
|
||||||
|
@ -2412,7 +2414,7 @@ static bool its_alloc_vpe_table(u32 vpe_id)
|
||||||
list_for_each_entry(its, &its_nodes, entry) {
|
list_for_each_entry(its, &its_nodes, entry) {
|
||||||
struct its_baser *baser;
|
struct its_baser *baser;
|
||||||
|
|
||||||
if (!its->is_v4)
|
if (!is_v4(its))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
baser = its_get_baser(its, GITS_BASER_TYPE_VCPU);
|
baser = its_get_baser(its, GITS_BASER_TYPE_VCPU);
|
||||||
|
@ -2900,7 +2902,7 @@ static void its_vpe_invall(struct its_vpe *vpe)
|
||||||
struct its_node *its;
|
struct its_node *its;
|
||||||
|
|
||||||
list_for_each_entry(its, &its_nodes, entry) {
|
list_for_each_entry(its, &its_nodes, entry) {
|
||||||
if (!its->is_v4)
|
if (!is_v4(its))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (its_list_map && !vpe->its_vm->vlpi_count[its->list_nr])
|
if (its_list_map && !vpe->its_vm->vlpi_count[its->list_nr])
|
||||||
|
@ -3168,7 +3170,7 @@ static int its_vpe_irq_domain_activate(struct irq_domain *domain,
|
||||||
vpe->col_idx = cpumask_first(cpu_online_mask);
|
vpe->col_idx = cpumask_first(cpu_online_mask);
|
||||||
|
|
||||||
list_for_each_entry(its, &its_nodes, entry) {
|
list_for_each_entry(its, &its_nodes, entry) {
|
||||||
if (!its->is_v4)
|
if (!is_v4(its))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
its_send_vmapp(its, vpe, true);
|
its_send_vmapp(its, vpe, true);
|
||||||
|
@ -3194,7 +3196,7 @@ static void its_vpe_irq_domain_deactivate(struct irq_domain *domain,
|
||||||
return;
|
return;
|
||||||
|
|
||||||
list_for_each_entry(its, &its_nodes, entry) {
|
list_for_each_entry(its, &its_nodes, entry) {
|
||||||
if (!its->is_v4)
|
if (!is_v4(its))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
its_send_vmapp(its, vpe, false);
|
its_send_vmapp(its, vpe, false);
|
||||||
|
@ -3632,12 +3634,12 @@ static int __init its_probe_one(struct resource *res,
|
||||||
INIT_LIST_HEAD(&its->entry);
|
INIT_LIST_HEAD(&its->entry);
|
||||||
INIT_LIST_HEAD(&its->its_device_list);
|
INIT_LIST_HEAD(&its->its_device_list);
|
||||||
typer = gic_read_typer(its_base + GITS_TYPER);
|
typer = gic_read_typer(its_base + GITS_TYPER);
|
||||||
|
its->typer = typer;
|
||||||
its->base = its_base;
|
its->base = its_base;
|
||||||
its->phys_base = res->start;
|
its->phys_base = res->start;
|
||||||
its->ite_size = GITS_TYPER_ITT_ENTRY_SIZE(typer);
|
its->ite_size = GITS_TYPER_ITT_ENTRY_SIZE(typer);
|
||||||
its->device_ids = GITS_TYPER_DEVBITS(typer);
|
its->device_ids = GITS_TYPER_DEVBITS(typer);
|
||||||
its->is_v4 = !!(typer & GITS_TYPER_VLPIS);
|
if (is_v4(its)) {
|
||||||
if (its->is_v4) {
|
|
||||||
if (!(typer & GITS_TYPER_VMOVP)) {
|
if (!(typer & GITS_TYPER_VMOVP)) {
|
||||||
err = its_compute_its_list_map(res, its_base);
|
err = its_compute_its_list_map(res, its_base);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -3704,7 +3706,7 @@ static int __init its_probe_one(struct resource *res,
|
||||||
gits_write_cwriter(0, its->base + GITS_CWRITER);
|
gits_write_cwriter(0, its->base + GITS_CWRITER);
|
||||||
ctlr = readl_relaxed(its->base + GITS_CTLR);
|
ctlr = readl_relaxed(its->base + GITS_CTLR);
|
||||||
ctlr |= GITS_CTLR_ENABLE;
|
ctlr |= GITS_CTLR_ENABLE;
|
||||||
if (its->is_v4)
|
if (is_v4(its))
|
||||||
ctlr |= GITS_CTLR_ImDe;
|
ctlr |= GITS_CTLR_ImDe;
|
||||||
writel_relaxed(ctlr, its->base + GITS_CTLR);
|
writel_relaxed(ctlr, its->base + GITS_CTLR);
|
||||||
|
|
||||||
|
@ -4029,7 +4031,7 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
list_for_each_entry(its, &its_nodes, entry)
|
list_for_each_entry(its, &its_nodes, entry)
|
||||||
has_v4 |= its->is_v4;
|
has_v4 |= is_v4(its);
|
||||||
|
|
||||||
if (has_v4 & rdists->has_vlpis) {
|
if (has_v4 & rdists->has_vlpis) {
|
||||||
if (its_init_vpe_domain() ||
|
if (its_init_vpe_domain() ||
|
||||||
|
|
Loading…
Reference in New Issue