From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753879AbdBARjb (ORCPT ); Wed, 1 Feb 2017 12:39:31 -0500 Received: from mail-bl2nam02on0086.outbound.protection.outlook.com ([104.47.38.86]:42928 "EHLO NAM02-BL2-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753794AbdBARj2 (ORCPT ); Wed, 1 Feb 2017 12:39:28 -0500 Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Robert.Richter@cavium.com; From: Robert Richter To: Marc Zyngier CC: Thomas Gleixner , Jason Cooper , , Robert Richter , Subject: [PATCH 4/9] irqchip/gic-v3-its: Split probing from its node initialization Date: Wed, 1 Feb 2017 18:38:28 +0100 Message-ID: <20170201173833.12630-5-rrichter@cavium.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170201173833.12630-1-rrichter@cavium.com> References: <20170201173833.12630-1-rrichter@cavium.com> MIME-Version: 1.0 Content-Type: text/plain X-Originating-IP: [92.229.95.220] X-ClientProxiedBy: DB6PR1001CA0017.EURPRD10.PROD.OUTLOOK.COM (10.171.79.27) To BY2PR07MB2343.namprd07.prod.outlook.com (10.166.114.145) X-MS-Office365-Filtering-Correlation-Id: 287e9b41-9c21-427f-f318-08d44ac93b99 X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:(22001);SRVR:BY2PR07MB2343; X-Microsoft-Exchange-Diagnostics: 1;BY2PR07MB2343;3:U+0y7DThZV6NDOstjkYGmnod3b7K2nfXXaWo+59kSEj87wHsl81NhEyTnNfznC/IwPjKaK6ALSD7s+DjruwBKpYlqXgsHT7nbkcS0ekMUfd8vu4tD+cq2C7bJDON6cPqCftvie2OQ19KeYf1RVSaV+kzLSwouPwwgFiba153sYl8C2b3SSoO3VZp6ez+R3JLXNR0TebrZx7ZiSHyGOTsIi0sHkAKOmi8furzS+BO/D/bxLdMj+k0KvEVBmBNfA1vaFi6t/hifFaBh3fezULFfQ==;25:9EBzc6Su3lv9yU8c4/J4GT0G1JlBn153pQxmCjhCO5K7flpRahUQLmehkqxQ82qJA0VNRPhztKyZuS2L9os0391L6ya0i2+5NqQYMQjvtPY4wgmMUSBIj+W976DROf21ufAaK+twnZ7E+ODSAV6ODhB2m2/kvQSbl3+hIUCzd4gUJF69hHeUWBFDQ1SJYqBN0GFKKUYAMb4VreKLzthQaJkzdNLVyhEBivIW4XSBOzMpTCv/yKEca4vYtw7zsZHhfr8rA8mKBKqGiO0iXxGr1zCGdsPFod/Eq6XaQ3QjOXF4jbRxjJeI/8v3k0f+3pjnQzaIXQUKKe+D0Bl9LWmgThU5DRRNHxRpVGx+pb6OuE3pczbUpD2N4cJvqplxMSodc3k8S690wC7iKOBrcHOivA==;31:zXh6y0SuSnNwUmFXUxR13F8U8Hw6oq1cTdtJwsPUQL8zud4hs32YppnfiZo5GU6aFd1zBLjpz40z35SklTNubyMy6fHZoL2D4/53Ksvn7QvstoOELVoTJuWvBYykJ0cS05ddssSO89ijYAPitq03UnB0ubitFOHXxM+j+c6K08v7asu7N8G3Cy0SYqgt+CSaMAMD1abYtmWi3oF2ueG9DcsC9gJUiKDCCKjCnzPtPUs= X-Microsoft-Exchange-Diagnostics: 1;BY2PR07MB2343;20:4NV7FYnfLQPOGf6TOt0W6qK+vW6yddbwgUSiNS7JUVSWRO5Yka9S6R3SklrhYTC/r0aJjSFU3m3snyCdO4t4F8sVaS52DUnz7F/6Yw9nsiW22eLkrcffByZHCc8fYqZDyQkjn0Ph3BPP6R00Mk4T4xZrGavpeJnXqyGs802Yru0LJiRFMrW16ZfRuEk7rPxt/c3Zb0S3XkNl+O6sAZU6kn3SFNxQVFSh7UZGx0zKH8Zid+LIoW0/iU9Lp9IleIRlQy+7fhqCeOqB/35Zh6hcIJOr4vx5Ixt4SR4JTmP1eB5IpNaPLPXwsjsxlop6Pi7ypfFH+Y+Q18Ry7VbI51e/roBeJc1ENaVBEqiLCR5Osd2adSvtarjXhiZ4vKeulHf9QHWHiRHPtgz+cbjy6z+Gfckgj+btm8Z4xy5fLMg5AAS3uUtPT70RdZADKUVyFasqCOY2UHZ8m5dkU2Iop3/651GOwy9nohcCNwudJ+21RT6wFXUTPrjmURgP0HLoyBXO X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(6040375)(601004)(2401047)(8121501046)(5005006)(10201501046)(3002001)(6041248)(20161123560025)(20161123555025)(20161123564025)(20161123558025)(20161123562025)(6072148);SRVR:BY2PR07MB2343;BCL:0;PCL:0;RULEID:;SRVR:BY2PR07MB2343; X-Microsoft-Exchange-Diagnostics: 1;BY2PR07MB2343;4:DbWh3LmpQBG1jKhuK9ux9U8xJI4jSrGc3IMU9gbmGcUhwBKH3Yjxz4VwZy41tM7wDeljwTu67A/c+AwRyDcQ61EbkT5Y63OvoXRiiVzeyNEtneUIt6TyeHoBtDG2T25qIBqFnYS+ECcdng06we284cWLTM0EhsTm70+OQ/oXMSbcV9SxbDbPz6te0WIr2upVXgPfqE7LXQ+uI57lLq39dOIh/M3iRh5VLjXrEo8D4NFssfi18OQeIfZS6nYq0LysO/l69bm4fwEceW1KEE1pWLNNyQROat8ATGBzAdRHgmXMQ329SIlj/3J/Kp9IwMqyv+IyDyojuae2R/NV/R9EewxhcAsHKAvqfX5dRZc6w8azbaUSojliBe1sVX8tSFkMkcM9yNS1e0NDabamyOL2jGtaFeVki7st7hgShU256AGqoudPM8FCNNvY3JEU3KVp+RSiOTEStngGB5gdzpOzw5IHlmxoLGJcJtaizbffuMZwlRe+1ll9oksrphhVznFwLZ+2QI3ahFZmqI6LRgj4yFj4dNbngwJeFL3cZvDXXGMqqkcpVGruJzrRZu4IMBsJcLcOLayVeK+PXmiRCzYtbqt4qYP0/TowSM2tSU8giqc= X-Forefront-PRVS: 0205EDCD76 X-Forefront-Antispam-Report: SFV:NSPM;SFS:(10009020)(4630300001)(6009001)(7916002)(39450400003)(199003)(189002)(81156014)(81166006)(189998001)(5660300001)(110136003)(97736004)(6916009)(2950100002)(50226002)(6666003)(230783001)(106356001)(105586002)(101416001)(42186005)(66066001)(8676002)(33646002)(47776003)(305945005)(7736002)(38730400001)(6506006)(6486002)(76176999)(68736007)(6512007)(53936002)(54906002)(5003940100001)(25786008)(1076002)(3846002)(6116002)(2906002)(4326007)(48376002)(50466002)(92566002)(50986999)(36756003);DIR:OUT;SFP:1101;SCL:1;SRVR:BY2PR07MB2343;H:rric.localdomain;FPR:;SPF:None;PTR:InfoNoRecords;A:1;MX:1;LANG:en; X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;BY2PR07MB2343;23:n/nIJuv1l8haeXeGVK8xYXh+qu7WIkVkC9pWqmSan?= =?us-ascii?Q?O6SqCo6dDdwv3CIwjI/D9Hjf3uBXfEgptx51wkFvaVz0jULDSV2xn03+Omqp?= =?us-ascii?Q?suNLW6s896Ab58cYBXj3r7ap3BvWAvRPw3rpw6bRSj1ExsCsPr1DHXZHSpgx?= =?us-ascii?Q?l2QQNcYcXUSc1s92bGVUT10z2GKmgWcjG+8nDL2YBKyAVOMMOaFEokIoN4kq?= =?us-ascii?Q?dmO9jt6+RgRREhkqQY+0mhDUBZu1Pi4o2pyP5pIqm7uyUzuT4m2iu/0Ljc3a?= =?us-ascii?Q?ivuOfzbFy2FyPDf5j4VTVfvcY9DnT1OqPq4xVj8+925/JBNpIS+TGN3RdIF2?= =?us-ascii?Q?JKMvU2kgAm4DE1H5aj3P46mPbfHxyoc/Ixs/dYKP1Te2IbuWhPmewMfDgBXw?= =?us-ascii?Q?bjY7RMnaKK2J7AP3LB4IzF3+/HUK0gpNFu4a+K+FwuqfsL6VdEGQfLdZQ62i?= =?us-ascii?Q?UhQKwQ4uGfsTKJj90Riqp8mPtUelBsBBGHJK6bafQ9+3QPpTb5js97G2EWuO?= =?us-ascii?Q?EjDruwdwa9xDKILfff12Wr+wjKGkqlAtkclitfLZg6gcJ7T81v5402Yc/5I/?= =?us-ascii?Q?184GGgqgFlW8jGPITRx9jvuOCz37DkCX6MU2d0ujK1i0bPsQKDeH2D7wZzYa?= =?us-ascii?Q?4PnFo2jwfn5ZC54ccBOWC2dBk9pxEg4YqaZLUZ4Z7RyJV9UI35H8GevedCLB?= =?us-ascii?Q?lSNJiTKOubinnhCj8mdph3xXnzPzDdb9KIC9Yo8XOwMS8IVngPLrRwS9ygbB?= =?us-ascii?Q?7nOwurVC9ZTg9ijnXtF97BxL1dn2+NQNPa6Zveec37/sUesPthJ+QoyO3yA0?= =?us-ascii?Q?9v/OM4qSjZZkmX0oy5sMJYA+eg7fexeEC1RW2+A00Opn2F0c9qkG3bMGsYtA?= =?us-ascii?Q?ofUD4vwl/NbEYSpOZAGCt/OIomk0KgUHIXa9pkE8oTwjRcQrEanYRbHh1SK3?= =?us-ascii?Q?pmHDyPRxLivjHGaierdzGXE/T/VzeL5HVgAWWoPZrwAbmhC0o9q0I2+9u/VP?= =?us-ascii?Q?OA/kiAzV14uHw0wbMKTxw4j6AXXYEeV+Dak0zpVTxWJqah2MAybC430hkkZy?= =?us-ascii?Q?RNCb28J6auw4bx1e0B46q9M08N8zA7RaVc8GieM9pFkd8l5dQD7Q/Un5hXSJ?= =?us-ascii?Q?ARMjpaeGrKABl7V5nSiYTMHvW5YJMUE?= X-Microsoft-Exchange-Diagnostics: 1;BY2PR07MB2343;6:lDlAc9GhfQQPmw0RUyNXaLycKmLGWEzNzD8bqoIRO7OEidQ2tcD32v9nayBrnS20dWZbKWZAjSfjiNjSdloLey4leHxDuqGVxBO8YqWUQiQ6X7D9gb10HQ0CVZUWgQu6YsRrNwiYXTYuIS2LfF57m0gSK2TlG1cxi8J72mmM7eayX0fN2mn/VHq3sOCz9c/PIoCYiHn+4SzBtKkxaUKAVtCoynZUxZMWPNwBcClV3HbUcaC2s9GvqTOvp8MBjN9d+o4EI+90CQsCwvcQOSQDOHrw2BjAAwWObCyEYWp0lbthPMic7ltowdlA3EiO1Cib5JkNKDD4k73/SM0TdeAKleiL+/Ht6KpzvbhojbWJyVM0sj4wBG6rL3GR4BqmJYqnxTvWcMCJW6ENt4XUXWn9+A==;5:089ADuGA7Ir4NDjeA9tIug3wNMIsL4pNkU+2b1VdDMslzl3OzrJqFqaPkYizSl7IBm42eoIZNoe8NtpCSdkA9BKOZfdRn8SZIDePw8nX9yyW/LzCNKN3TaDHz8M4Gfep4LMyVGL8DMUrXKcx4Cqqtg==;24:mp2KDlcV/ueqdnb7Q634gFN1/3qLGTVCtpQdAcD9x3oX7tv8s3q4NvEhdmr7waPZgEeqgkve/wmFTh+WU1P7PL+nBvsJpfPXNK0lUksPt7o= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;BY2PR07MB2343;7:NSeoM4rFsvQUBo6VwGkQXhOiUE5kdCt2BnYNNwdTJ+/utJLaaXU2KHfTCA6G4KWwxHPwBh2/2Op3+TZoFdp+pbYQwE1Rrl9MLnGhy1GPbSnvBWT7KhKbFyCegnwykZ0Yz2franc1Ia8tWPQ0ddK7kcq2jlYCSNbtqaZkwHbzSK76lqkqCGVeX9HuhlyHhyVfSEQljCFKTgw8hiWKU5PU15fnTvuOcuAFv4CTz8wN5D+U+dKNKf7ppZGWMqA2LHabO26RcVZefjgFyp/A3ckhmBAJ7t5N8vQq670tsA4196/dKYH/Kw+cHJGzo0BUC8tP9hSmJbFK73esbmi//pEZn2fKDWZ/aqb8gZcLqjdkv/1Tm9XOFlAVr3Sr3tDS5lhX5+sSeyEerom+aTdCKfzcQE5rvf9fb1/Og4oJeX8cuGlt9Qsysd736YEm6QqsXRlPWqkE4Ri5qjH6BLeXC1ecFPsFa/mQ9NHTJCS6l5ZwX4Ojrx7MsXLiag3IWdznz7LLqZaZ7+dtbWbCiKDOQZAL5w== X-OriginatorOrg: cavium.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Feb 2017 17:39:09.9406 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR07MB2343 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org To initialize the its nodes at a later point during boot, we need to split probing from initialization. Collect all information required for initialization in struct its_node. We can then use the its node list for initialization. Signed-off-by: Robert Richter --- drivers/irqchip/irq-gic-v3-its.c | 97 ++++++++++++++++++++++++++------------ drivers/irqchip/irq-gic-v3.c | 2 +- include/linux/irqchip/arm-gic-v3.h | 4 +- 3 files changed, 69 insertions(+), 34 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index 5dfd489a11d1..dcd3b8722b05 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -75,10 +75,12 @@ struct its_baser { * list of devices writing to it. */ struct its_node { + struct fwnode_handle *fwnode; raw_spinlock_t lock; struct list_head entry; void __iomem *base; phys_addr_t phys_base; + phys_addr_t phys_size; struct its_cmd_block *cmd_base; struct its_cmd_block *cmd_write; struct its_baser tables[GITS_BASER_NR_REGS]; @@ -1625,7 +1627,7 @@ static void its_enable_quirks(struct its_node *its) gic_enable_quirks(iidr, its_quirks, its); } -static int its_init_domain(struct fwnode_handle *handle, struct its_node *its) +static int its_init_domain(struct its_node *its) { struct irq_domain *inner_domain; struct msi_domain_info *info; @@ -1634,7 +1636,7 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its) if (!info) return -ENOMEM; - inner_domain = irq_domain_create_tree(handle, &its_domain_ops, its); + inner_domain = irq_domain_create_tree(its->fwnode, &its_domain_ops, its); if (!inner_domain) { kfree(info); return -ENOMEM; @@ -1649,55 +1651,83 @@ static int its_init_domain(struct fwnode_handle *handle, struct its_node *its) return 0; } +static void its_free(struct its_node *its) +{ + spin_lock(&its_lock); + list_del(&its->entry); + spin_unlock(&its_lock); + + kfree(its); +} + +static int __init its_init_one(struct its_node *its); + static int __init its_probe_one(struct resource *res, struct fwnode_handle *handle, int numa_node) { struct its_node *its; + int err; + + its = kzalloc(sizeof(*its), GFP_KERNEL); + if (!its) + return -ENOMEM; + + raw_spin_lock_init(&its->lock); + INIT_LIST_HEAD(&its->entry); + INIT_LIST_HEAD(&its->its_device_list); + its->fwnode = handle; + its->phys_base = res->start; + its->phys_size = resource_size(res); + its->numa_node = numa_node; + + spin_lock(&its_lock); + list_add_tail(&its->entry, &its_nodes); + spin_unlock(&its_lock); + + pr_info("ITS %pR\n", res); + + err = its_init_one(its); + if (err) + its_free(its); + + return err; +} + +static int __init its_init_one(struct its_node *its) +{ void __iomem *its_base; u32 val; u64 baser, tmp; int err; - its_base = ioremap(res->start, resource_size(res)); + its_base = ioremap(its->phys_base, its->phys_size); if (!its_base) { - pr_warn("ITS@%pa: Unable to map ITS registers\n", &res->start); - return -ENOMEM; + pr_warn("ITS@%pa: Unable to map ITS registers\n", &its->phys_base); + err = -ENOMEM; + goto fail; } val = readl_relaxed(its_base + GITS_PIDR2) & GIC_PIDR2_ARCH_MASK; if (val != 0x30 && val != 0x40) { - pr_warn("ITS@%pa: No ITS detected, giving up\n", &res->start); + pr_warn("ITS@%pa: No ITS detected, giving up\n", &its->phys_base); err = -ENODEV; goto out_unmap; } err = its_force_quiescent(its_base); if (err) { - pr_warn("ITS@%pa: Failed to quiesce, giving up\n", &res->start); - goto out_unmap; - } - - pr_info("ITS %pR\n", res); - - its = kzalloc(sizeof(*its), GFP_KERNEL); - if (!its) { - err = -ENOMEM; + pr_warn("ITS@%pa: Failed to quiesce, giving up\n", &its->phys_base); goto out_unmap; } - raw_spin_lock_init(&its->lock); - INIT_LIST_HEAD(&its->entry); - INIT_LIST_HEAD(&its->its_device_list); its->base = its_base; - its->phys_base = res->start; its->ite_size = ((gic_read_typer(its_base + GITS_TYPER) >> 4) & 0xf) + 1; - its->numa_node = numa_node; its->cmd_base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, get_order(ITS_CMD_QUEUE_SZ)); if (!its->cmd_base) { err = -ENOMEM; - goto out_free_its; + goto out_unmap; } its->cmd_write = its->cmd_base; @@ -1739,13 +1769,11 @@ static int __init its_probe_one(struct resource *res, gits_write_cwriter(0, its->base + GITS_CWRITER); writel_relaxed(GITS_CTLR_ENABLE, its->base + GITS_CTLR); - err = its_init_domain(handle, its); + err = its_init_domain(its); if (err) goto out_free_tables; - spin_lock(&its_lock); - list_add_tail(&its->entry, &its_nodes); - spin_unlock(&its_lock); + pr_info("ITS@%pa: ITS node added\n", &its->phys_base); return 0; @@ -1753,11 +1781,10 @@ static int __init its_probe_one(struct resource *res, its_free_tables(its); out_free_cmd: kfree(its->cmd_base); -out_free_its: - kfree(its); out_unmap: iounmap(its_base); - pr_err("ITS@%pa: failed probing (%d)\n", &res->start, err); +fail: + pr_err("ITS@%pa: failed probing (%d)\n", &its->phys_base, err); return err; } @@ -1859,8 +1886,10 @@ static void __init its_acpi_probe(void) static void __init its_acpi_probe(void) { } #endif -int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, - struct irq_domain *parent_domain) +struct int __init its_init(void); + +int __init its_probe(struct fwnode_handle *handle, struct rdists *rdists, + struct irq_domain *parent_domain) { struct device_node *of_node; @@ -1877,8 +1906,14 @@ int __init its_init(struct fwnode_handle *handle, struct rdists *rdists, } gic_rdists = rdists; + + return its_init(); +} + +struct int __init its_init(void) +{ its_alloc_lpi_tables(); - its_lpi_init(rdists->id_bits); + its_lpi_init(gic_rdists->id_bits); return 0; } diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c index c132f29322cc..b46dc9396331 100644 --- a/drivers/irqchip/irq-gic-v3.c +++ b/drivers/irqchip/irq-gic-v3.c @@ -949,7 +949,7 @@ static int __init gic_init_bases(void __iomem *dist_base, set_handle_irq(gic_handle_irq); if (IS_ENABLED(CONFIG_ARM_GIC_V3_ITS) && gic_dist_supports_lpis()) - its_init(handle, &gic_data.rdists, gic_data.domain); + its_probe(handle, &gic_data.rdists, gic_data.domain); gic_smp_init(); gic_dist_init(); diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index e808f8ae6f14..1f6a5490ad72 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -432,8 +432,8 @@ struct rdists { struct irq_domain; struct fwnode_handle; int its_cpu_init(void); -int its_init(struct fwnode_handle *handle, struct rdists *rdists, - struct irq_domain *domain); +int its_probe(struct fwnode_handle *handle, struct rdists *rdists, + struct irq_domain *domain); static inline bool gic_enable_sre(void) { -- 2.11.0