Commit 5e46a484 authored by Marc Zyngier's avatar Marc Zyngier

irqchip/gic-v4.1: Map the ITS SGIR register page

One of the new features of GICv4.1 is to allow virtual SGIs to be
directly signaled to a VPE. For that, the ITS has grown a new
64kB page containing only a single register that is used to
signal a SGI to a given VPE.

Add a second mapping covering this new 64kB range, and take this
opportunity to limit the original mapping to 64kB, which is enough
to cover the span of the ITS registers.
Signed-off-by: default avatarMarc Zyngier <maz@kernel.org>
Reviewed-by: default avatarZenghui Yu <yuzenghui@huawei.com>
Reviewed-by: default avatarEric Auger <eric.auger@redhat.com>
Link: https://lore.kernel.org/r/20200304203330.4967-8-maz@kernel.org
parent 3c40706d
...@@ -96,6 +96,7 @@ struct its_node { ...@@ -96,6 +96,7 @@ struct its_node {
struct mutex dev_alloc_lock; struct mutex dev_alloc_lock;
struct list_head entry; struct list_head entry;
void __iomem *base; void __iomem *base;
void __iomem *sgir_base;
phys_addr_t phys_base; phys_addr_t phys_base;
struct its_cmd_block *cmd_base; struct its_cmd_block *cmd_base;
struct its_cmd_block *cmd_write; struct its_cmd_block *cmd_write;
...@@ -4456,7 +4457,7 @@ static int __init its_probe_one(struct resource *res, ...@@ -4456,7 +4457,7 @@ static int __init its_probe_one(struct resource *res,
struct page *page; struct page *page;
int err; int err;
its_base = ioremap(res->start, resource_size(res)); its_base = ioremap(res->start, SZ_64K);
if (!its_base) { if (!its_base) {
pr_warn("ITS@%pa: Unable to map ITS registers\n", &res->start); pr_warn("ITS@%pa: Unable to map ITS registers\n", &res->start);
return -ENOMEM; return -ENOMEM;
...@@ -4507,6 +4508,13 @@ static int __init its_probe_one(struct resource *res, ...@@ -4507,6 +4508,13 @@ static int __init its_probe_one(struct resource *res,
if (is_v4_1(its)) { if (is_v4_1(its)) {
u32 svpet = FIELD_GET(GITS_TYPER_SVPET, typer); u32 svpet = FIELD_GET(GITS_TYPER_SVPET, typer);
its->sgir_base = ioremap(res->start + SZ_128K, SZ_64K);
if (!its->sgir_base) {
err = -ENOMEM;
goto out_free_its;
}
its->mpidr = readl_relaxed(its_base + GITS_MPIDR); its->mpidr = readl_relaxed(its_base + GITS_MPIDR);
pr_info("ITS@%pa: Using GICv4.1 mode %08x %08x\n", pr_info("ITS@%pa: Using GICv4.1 mode %08x %08x\n",
...@@ -4520,7 +4528,7 @@ static int __init its_probe_one(struct resource *res, ...@@ -4520,7 +4528,7 @@ static int __init its_probe_one(struct resource *res,
get_order(ITS_CMD_QUEUE_SZ)); get_order(ITS_CMD_QUEUE_SZ));
if (!page) { if (!page) {
err = -ENOMEM; err = -ENOMEM;
goto out_free_its; goto out_unmap_sgir;
} }
its->cmd_base = (void *)page_address(page); its->cmd_base = (void *)page_address(page);
its->cmd_write = its->cmd_base; its->cmd_write = its->cmd_base;
...@@ -4587,6 +4595,9 @@ static int __init its_probe_one(struct resource *res, ...@@ -4587,6 +4595,9 @@ static int __init its_probe_one(struct resource *res,
its_free_tables(its); its_free_tables(its);
out_free_cmd: out_free_cmd:
free_pages((unsigned long)its->cmd_base, get_order(ITS_CMD_QUEUE_SZ)); free_pages((unsigned long)its->cmd_base, get_order(ITS_CMD_QUEUE_SZ));
out_unmap_sgir:
if (its->sgir_base)
iounmap(its->sgir_base);
out_free_its: out_free_its:
kfree(its); kfree(its);
out_unmap: out_unmap:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment