Skip to content

Commit db40f0a

Browse files
nowicki-tomaszMarc Zyngier
authored andcommitted
irqchip/gicv3-its: Refactor ITS DT init code to prepare for ACPI
In order to add ACPI support we need to isolate ACPI&DT common code and move DT logic to corresponding functions. To achieve this we are using firmware agnostic handle which can be unpacked to either DT or ACPI node. No functional changes other than a very minor one: 1. Terminate its_init call with -ENODEV for non-DT case which allows to remove hack from its-gic-v3.c. 2. Fix ITS base register address type (from 'unsigned long' to 'phys_addr_t'), as a bonus we get nice string formatting. 3. Since there is only one of ITS parent domain convert it to static global variable and drop the parameter from its_probe_one. Users can refer to it in more convenient way then. Signed-off-by: Hanjun Guo <hanjun.guo@linaro.org> Signed-off-by: Tomasz Nowicki <tn@semihalf.com> Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
1 parent d14ae5e commit db40f0a

File tree

3 files changed

+42
-34
lines changed

3 files changed

+42
-34
lines changed

drivers/irqchip/irq-gic-v3-its.c

Lines changed: 38 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ struct its_node {
7575
raw_spinlock_t lock;
7676
struct list_head entry;
7777
void __iomem *base;
78-
unsigned long phys_base;
78+
phys_addr_t phys_base;
7979
struct its_cmd_block *cmd_base;
8080
struct its_cmd_block *cmd_write;
8181
struct its_baser tables[GITS_BASER_NR_REGS];
@@ -115,6 +115,7 @@ struct its_device {
115115
static LIST_HEAD(its_nodes);
116116
static DEFINE_SPINLOCK(its_lock);
117117
static struct rdists *gic_rdists;
118+
static struct irq_domain *its_parent;
118119

119120
#define gic_data_rdist() (raw_cpu_ptr(gic_rdists->rdist))
120121
#define gic_data_rdist_rd_base() (gic_data_rdist()->rd_base)
@@ -1614,8 +1615,7 @@ static void its_enable_quirks(struct its_node *its)
16141615
gic_enable_quirks(iidr, its_quirks, its);
16151616
}
16161617

1617-
static int its_init_domain(struct device_node *node, struct its_node *its,
1618-
struct irq_domain *parent)
1618+
static int its_init_domain(struct fwnode_handle *handle, struct its_node *its)
16191619
{
16201620
struct irq_domain *inner_domain;
16211621
struct msi_domain_info *info;
@@ -1624,13 +1624,13 @@ static int its_init_domain(struct device_node *node, struct its_node *its,
16241624
if (!info)
16251625
return -ENOMEM;
16261626

1627-
inner_domain = irq_domain_add_tree(node, &its_domain_ops, its);
1627+
inner_domain = irq_domain_create_tree(handle, &its_domain_ops, its);
16281628
if (!inner_domain) {
16291629
kfree(info);
16301630
return -ENOMEM;
16311631
}
16321632

1633-
inner_domain->parent = parent;
1633+
inner_domain->parent = its_parent;
16341634
inner_domain->bus_token = DOMAIN_BUS_NEXUS;
16351635
info->ops = &its_msi_domain_ops;
16361636
info->data = its;
@@ -1639,43 +1639,35 @@ static int its_init_domain(struct device_node *node, struct its_node *its,
16391639
return 0;
16401640
}
16411641

1642-
static int __init its_probe(struct device_node *node,
1643-
struct irq_domain *parent)
1642+
static int __init its_probe_one(struct resource *res,
1643+
struct fwnode_handle *handle, int numa_node)
16441644
{
1645-
struct resource res;
16461645
struct its_node *its;
16471646
void __iomem *its_base;
16481647
u32 val;
16491648
u64 baser, tmp;
16501649
int err;
16511650

1652-
err = of_address_to_resource(node, 0, &res);
1653-
if (err) {
1654-
pr_warn("%s: no regs?\n", node->full_name);
1655-
return -ENXIO;
1656-
}
1657-
1658-
its_base = ioremap(res.start, resource_size(&res));
1651+
its_base = ioremap(res->start, resource_size(res));
16591652
if (!its_base) {
1660-
pr_warn("%s: unable to map registers\n", node->full_name);
1653+
pr_warn("ITS@%pa: Unable to map ITS registers\n", &res->start);
16611654
return -ENOMEM;
16621655
}
16631656

16641657
val = readl_relaxed(its_base + GITS_PIDR2) & GIC_PIDR2_ARCH_MASK;
16651658
if (val != 0x30 && val != 0x40) {
1666-
pr_warn("%s: no ITS detected, giving up\n", node->full_name);
1659+
pr_warn("ITS@%pa: No ITS detected, giving up\n", &res->start);
16671660
err = -ENODEV;
16681661
goto out_unmap;
16691662
}
16701663

16711664
err = its_force_quiescent(its_base);
16721665
if (err) {
1673-
pr_warn("%s: failed to quiesce, giving up\n",
1674-
node->full_name);
1666+
pr_warn("ITS@%pa: Failed to quiesce, giving up\n", &res->start);
16751667
goto out_unmap;
16761668
}
16771669

1678-
pr_info("ITS: %s\n", node->full_name);
1670+
pr_info("ITS %pR\n", res);
16791671

16801672
its = kzalloc(sizeof(*its), GFP_KERNEL);
16811673
if (!its) {
@@ -1687,9 +1679,9 @@ static int __init its_probe(struct device_node *node,
16871679
INIT_LIST_HEAD(&its->entry);
16881680
INIT_LIST_HEAD(&its->its_device_list);
16891681
its->base = its_base;
1690-
its->phys_base = res.start;
1682+
its->phys_base = res->start;
16911683
its->ite_size = ((readl_relaxed(its_base + GITS_TYPER) >> 4) & 0xf) + 1;
1692-
its->numa_node = of_node_to_nid(node);
1684+
its->numa_node = numa_node;
16931685

16941686
its->cmd_base = kzalloc(ITS_CMD_QUEUE_SZ, GFP_KERNEL);
16951687
if (!its->cmd_base) {
@@ -1736,7 +1728,7 @@ static int __init its_probe(struct device_node *node,
17361728
writeq_relaxed(0, its->base + GITS_CWRITER);
17371729
writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR);
17381730

1739-
err = its_init_domain(node, its, parent);
1731+
err = its_init_domain(handle, its);
17401732
if (err)
17411733
goto out_free_tables;
17421734

@@ -1754,7 +1746,7 @@ static int __init its_probe(struct device_node *node,
17541746
kfree(its);
17551747
out_unmap:
17561748
iounmap(its_base);
1757-
pr_err("ITS: failed probing %s (%d)\n", node->full_name, err);
1749+
pr_err("ITS@%pa: failed probing (%d)\n", &res->start, err);
17581750
return err;
17591751
}
17601752

@@ -1782,10 +1774,10 @@ static struct of_device_id its_device_id[] = {
17821774
{},
17831775
};
17841776

1785-
int __init its_init(struct device_node *node, struct rdists *rdists,
1786-
struct irq_domain *parent_domain)
1777+
static int __init its_of_probe(struct device_node *node)
17871778
{
17881779
struct device_node *np;
1780+
struct resource res;
17891781

17901782
for (np = of_find_matching_node(node, its_device_id); np;
17911783
np = of_find_matching_node(np, its_device_id)) {
@@ -1795,8 +1787,27 @@ int __init its_init(struct device_node *node, struct rdists *rdists,
17951787
continue;
17961788
}
17971789

1798-
its_probe(np, parent_domain);
1790+
if (of_address_to_resource(np, 0, &res)) {
1791+
pr_warn("%s: no regs?\n", np->full_name);
1792+
continue;
1793+
}
1794+
1795+
its_probe_one(&res, &np->fwnode, of_node_to_nid(np));
17991796
}
1797+
return 0;
1798+
}
1799+
1800+
int __init its_init(struct fwnode_handle *handle, struct rdists *rdists,
1801+
struct irq_domain *parent_domain)
1802+
{
1803+
struct device_node *of_node;
1804+
1805+
its_parent = parent_domain;
1806+
of_node = to_of_node(handle);
1807+
if (of_node)
1808+
its_of_probe(of_node);
1809+
else
1810+
return -ENODEV;
18001811

18011812
if (list_empty(&its_nodes)) {
18021813
pr_warn("ITS: No ITS available, not enabling LPIs\n");

drivers/irqchip/irq-gic-v3.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,6 @@ static int __init gic_init_bases(void __iomem *dist_base,
918918
u64 redist_stride,
919919
struct fwnode_handle *handle)
920920
{
921-
struct device_node *node;
922921
u32 typer;
923922
int gic_irqs;
924923
int err;
@@ -959,10 +958,8 @@ static int __init gic_init_bases(void __iomem *dist_base,
959958

960959
set_handle_irq(gic_handle_irq);
961960

962-
node = to_of_node(handle);
963-
if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis() &&
964-
node) /* Temp hack to prevent ITS init for ACPI */
965-
its_init(node, &gic_data.rdists, gic_data.domain);
961+
if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis())
962+
its_init(handle, &gic_data.rdists, gic_data.domain);
966963

967964
gic_smp_init();
968965
gic_dist_init();

include/linux/irqchip/arm-gic-v3.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -430,9 +430,9 @@ struct rdists {
430430
};
431431

432432
struct irq_domain;
433-
struct device_node;
433+
struct fwnode_handle;
434434
int its_cpu_init(void);
435-
int its_init(struct device_node *node, struct rdists *rdists,
435+
int its_init(struct fwnode_handle *handle, struct rdists *rdists,
436436
struct irq_domain *domain);
437437

438438
static inline bool gic_enable_sre(void)

0 commit comments

Comments
 (0)