From patchwork Wed Feb 1 17:38:32 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Robert Richter X-Patchwork-Id: 9550441 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 45AFF60424 for ; Wed, 1 Feb 2017 17:52:49 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 366202842E for ; Wed, 1 Feb 2017 17:52:49 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 29CDE2844B; Wed, 1 Feb 2017 17:52:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.8 required=2.0 tests=BAD_ENC_HEADER,BAYES_00, DKIM_SIGNED,T_DKIM_INVALID autolearn=no version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 78E9F2842E for ; Wed, 1 Feb 2017 17:52:48 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1cYz5H-0003HY-F1; Wed, 01 Feb 2017 17:52:43 +0000 Received: from casper.infradead.org ([85.118.1.10]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cYz4p-0002KX-Aa for linux-arm-kernel@bombadil.infradead.org; Wed, 01 Feb 2017 17:52:15 +0000 Received: from mail-sn1nam01on0078.outbound.protection.outlook.com ([104.47.32.78] helo=NAM01-SN1-obe.outbound.protection.outlook.com) by casper.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1cYysw-0001Pl-GG for linux-arm-kernel@lists.infradead.org; Wed, 01 Feb 2017 17:40:00 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=CAVIUMNETWORKS.onmicrosoft.com; s=selector1-cavium-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version; bh=nt/ugxJrLnrWEdrCqjAtTTIZ32QKEYbJTvAyTxgtqGk=; b=B3WODQv5SDlM+pIooKCpTOHTf/Zv+iUPZ7fPfVsrVke7i8CWArhLJG7WaCfh5/UbffunDGkL25wJb41CNW7Hqsx+smTvoSkL3sH5m+xTWcfkUMuTblZAmFdKuhx740cNoiOZu0EguB/RcRi/bq57h771Tw37W6HjfpShSpnZpmI= Authentication-Results: spf=none (sender IP is ) smtp.mailfrom=Robert.Richter@cavium.com; Received: from rric.localdomain (92.229.95.220) by BY2PR07MB2343.namprd07.prod.outlook.com (10.166.114.145) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384_P384) id 15.1.888.16; Wed, 1 Feb 2017 17:39:21 +0000 From: Robert Richter To: Marc Zyngier Subject: [PATCH 8/9] irqchip/gic-v3-its: Handle its nodes as kernel devices Date: Wed, 1 Feb 2017 18:38:32 +0100 Message-ID: <20170201173833.12630-9-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 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: fcb40149-2a63-40e0-9be5-08d44ac9429e X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:(22001); SRVR:BY2PR07MB2343; X-Microsoft-Exchange-Diagnostics: 1; BY2PR07MB2343; 3:Ainx/SWmd++aKw+JQh5lCLcXaML+e3xif0UVDBgvItHET+DvzRyBBbGmCzcZlLJ6JjpVRhigow13FXKxxhbajFYpGziQ7KCei0ukQIKNWPxDUizwvBfHJ7WCCxS5ifmfr7aw2YcQFpBa107SiVhb2/bzOeh9A74H2gr6HxeZa9NHY2FxrDdJ0wIxS0kFJxvObqu/ROGIQyVZ3J8cSaDSuogIlAg26Xv/G+1t9Z1nIguEfzoW6ozMdX3fFOeTVflePl9nLQjLHxmlJCFoGOAvYA==; 25:AV1CfHOPMB9nVbomsCcs1vDzGR4tHcNlIEOZSwdZbruq3AigaNH7XzOzorIRU3QCFqaUIEWA3FZQi2SXuD2uRTvTIHy2LDovGX9VYWSC4o7TBQi+AzqRFbJ82spSfu5I68fbFuqAtEqaOPb+lIGEJQlCTWQJuLGNxTlZKtpFvSLINZ0huk39CJf/O7wwaez1wJ5M1Xiu6++wmDou0QuRODrLroS9PDspUncZ8DudJ8adnAzZhh6Nqj+kGWBP0ilnWueL2F0JDKEDZJJmBcOS6l1VrsTk/HL0NPor3qY12r8U1rab1Ox5mpryw8EVnGNXSHjb487w/9h8hNHgo2RKrPJlXIc0yM5QP/2qSAeRa8RquogGAcyaep1J7PfvpOxqRsObhPlA9Edg2K1WuRybwQ==; 31:Ubs2v0fFc3O9/mwPMuka6Cjmz4NzgEV4UGeZiMpBXAsi8sMpYlAfJArjDwfAOiuCrbJ4sjSW7NM+lejWo+q0tQEBqd3XmpnsSq3uWRRYFk5zVG4NtOj/vGomeBaOtJgsHtlTsGwigJh3BFUN7iN3K3T3ZuQbgROIYnig70lvPmTqoHH83HY7HVFFPxwjKOvg2F5pb7GQsy0X18go5Z+VL4aW6RwUNtJWB2RWaxo//6E= X-Microsoft-Exchange-Diagnostics: 1; BY2PR07MB2343; 20:Deu3GIvY8dPlbs6WdWmIP4KmDJnU5OWH3gikqywJp58f17gs3VhaE4kqUYf+DXvYU1Q7hpkxKelpuRp8el27+braf8XO2WnyKN8U9MyAueD6QZbe8bekleL1xHAeyVbYLpIqzDq5GNMcMgzs6RT+NTYkLo68bTEaokyoF9DTUOMXq9Vjs928F4/5WMcFO3wOnJpN/9M5JfjhVPQtPdC0mazRMaq9xz6yvk7RjHfxbxw2/geIcOnSriWTNIUGA7BNk28Pg1UeQMILj6l+nL+xMseeeHdYQcFDqjA4Lsc1R55sMbxhlFOnV4CIQ2od5cv4k+wjtw2J9V6M6I4dBKHNuEVfEy/DRkSKB93qT5FCeWfZ921/oDDVOjG0KARSClWYP8YdhTpsxVr4W5d75hur+9iipN5LtSfgR/YNbX6eWt17dxXU5h1YRBAopmwkiX2V6ePdXDv+zfhosYaBe3o8Nxjx9eKY9KxoiioI0jKU+utKCj2bVPmf1IZkpOF8HQRo 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:N+klBhQuZBRB5ETM7aO5qJmdKhHHKCo5xgi0yn+YoTRUddazzJDUnI1BMANqwCUjyGwUQDhWhgcfMeBilgEw+taKc0k2D+O1SvTyS6VSAckJ8xOcLWo3OilFQekrHXbSnn6q4MDXzUrLP7Zt6G1ELxJ87GKmsl5B1xMPoKjcPvcitOfvJ/TuEnG2rc6kk6GZGwbehOJQMmks58IGc2ycx4V5m64FNGjKz4sHV9MqIVF+bjLpUK5t1vNiGATqBD5H21aHRedj6rNqxuEqy0jw+2cfdE1xz63TzKuAjmNt4JTC2nFqeEaTiGc2mzGzjBBg+vppkzWSO3prcLhYTlC05mjiJP/tMhuqGMWgjGGRhcUirt7b1/px9CYCx9eJ+k11GLAKMNyw//kU4FFbhzus8y72gRLS5dP0Kfg691TDpFG2LRBoUlZuMCCuR/RzCsPTP5BItKZ0n95wnlfMw4OZVWDTf2BZayA2aG/0yo9pxmee+Uj1y8uQG18Nm0RvKiP3HafLA0YBTYKpuMcSngSkQHX7jYy1yrqjGFS7mI4I+axCrbJaw5T6LyjzkUQA91WbMG/rVwadNOtFmpT8sV6QuAeLtxKn26FRKNl8h1wu8m4= 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; Received-SPF: None (protection.outlook.com: cavium.com does not designate permitted sender hosts) X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1; BY2PR07MB2343; 23:ODV9luCrDmxuYnhrBwD1OXihm4LpbHatSq0h4wjQ7?= =?us-ascii?Q?6lCRuXAMbbGTQ5Kjy7Ht+LUIoxYldYIjjY76w5C95EvB+EZbsORvndxuWHMo?= =?us-ascii?Q?Yn146wLCik9BMGiev5BpkH1H4KjCX4NfLGmC05Jto+z1Nii9oblREPjYoBtT?= =?us-ascii?Q?Rg9aMNHtS+XsyGTD22667z/jvnjVhYzJASK4cYdLOmlga6+UuMBC+f0x+RaK?= =?us-ascii?Q?gsOcU0pQiL9tFcR+T9SwM88pXJAlRWJsvcC5zYZqexbi5ko3LUblkXF51Tn9?= =?us-ascii?Q?QftUDkH0uz0nJmeRRrVI1hIi64HZee/Azf3QqPA+eU2DhXaVy1nNkpavUW3V?= =?us-ascii?Q?wSfcXjjTlpab7CtOH/JMEiUGc1aRmFZLhlbhAYsEVemwUPDuAOGpcShBDtNN?= =?us-ascii?Q?/ZNLuHP+tfusP9d+MC0rujHxm3w+tlygfDLjThKvkZSiqFxpYwSGJRIqKQ/h?= =?us-ascii?Q?zFRwjX4QDz9xEUHpTk1HtI2oNQeLpQzzP5b1d486BWiBDezqYaE0EJBgFK8c?= =?us-ascii?Q?OE7QMequzql3ndNh2TuVz2MUhX7k+qoBr6I3M+dd1H+Up0xPcP8xnYJS5y5B?= =?us-ascii?Q?LsotHZK1iuKiY83ahrhY20C/OqSGUdzi/uGpmFwWXBjeVR1cN+jqCxA61kFP?= =?us-ascii?Q?oZgl4J9f/zgiGHLa9jictV9EMHS6mvXDRQcyUVlH3Uj0e42Cxh7ppi9sD1xA?= =?us-ascii?Q?dH7T1WS8GN8RVZaICvocUkn+FiNbPC+BF3awa/XX8Gp7DXIU0HWyk4ue8vr9?= =?us-ascii?Q?AmmQnG8m4B0FGnNUgeaW5WS5SkRwWZc3Lcxy0ORT/1gocMuB5qsMXqmyFljA?= =?us-ascii?Q?+7o47ZFPuqDpkkUXBFpiVXb83s9tIe7aNGzyocRAOQZ69ba1S+uOczCP7wNl?= =?us-ascii?Q?Egy+fwphO5UM7v4fe8c2TJdCWA/NrWIvtC0lmuzeF3Ddjn8QFKqNB1ZEXq8G?= =?us-ascii?Q?bD1kHSw6Ao13VTHbuRhPA/r4qBwzdJe5OC6x3KMQjxJHO+YSTzmUIaSYFR1D?= =?us-ascii?Q?0PnxiNpkWC67lRCF3uRscg8/mDv5ZEcxGULsF/gins4/4rMqPZJ0kdp91fpI?= =?us-ascii?Q?VptLzYd2ZXVMtGQRCEhft2WDXS2OgoWgcFM9Ws6pX1tW/3ZKQgTi7sM4WMUM?= =?us-ascii?Q?XrWVUunsD3rIHmUB2WVQWOAn2ErRmun?= X-Microsoft-Exchange-Diagnostics: 1; BY2PR07MB2343; 6:mIQYqTmmMwcCqlBXIF0YImBdBb6FbW9JZSL3EAHqZwjWVRq2tgbRw/ukYICSwo5PrxGSTDuSOBofJ8H3ENmgVypfve7k0B/rkHvsks5hTzvg7evzthr0HFzt4x3/vKUUIUuDmrqm2k0zwJDMaqhgbE0t//jN5N1Dz6a6Mgaa6Lh7wep2SBA3TqXKtB5EGe/GxQ4uuXBlnkw0iBKyonoBXKNQ65Z6lrfOoR2dqWkdbfIP2E4HYX5ykUiF4Knqb/UamWmp+dJIH07KelCjNB4FwpDz/QJc0L2pZuC5mBmeydcx1jdzdOoNZEDHrSu8My4qtyyHgW2hZpjUUnyjMGygAJZlfe0/hToqmKviY+G3pw9dAwXPziltLL3cknyUXz+NQ6HJh6vqeYOudGaL7YCZyA==; 5:BbrJYz0jnrI0TywR9EiSnLFflCGs2UPBdrfslYT9tPotqiYOXNvqYU9iqVP3G2cKj37XdsMRVqqGYAyvL2LJxTODfWbPI9dDkNBQcsfDWTgk1LCntHFQt0ZRk4snJdhROM3mdcJz/UvUtGO91eDQsg==; 24:XrtK+wj+nWcsBHqn0/V8wT229P67nNytfRdsoloG8A/IRjGQ8JaAMM7CAicURsM2m6k6u9Q7cSxRw+O+u3U7b5xKS5oj6KkWxtLlCWWz6Zc= SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1; BY2PR07MB2343; 7:fYdmJXPAxKK2O6mMru04kAanD3XaY3AUZWwrD4KX8wJpZiqB0QGMwiyXEhNZJILk2QpX9OKjTWUDOPlakP5x/Y7YBFeTVIUF9Vx3iKJnBaBTKgQ5d8m6xg6s4fWVTngLpcgsdbjKZ2KgzgmhSaF4b+9aNtOpbqEHe9wih5olTJxpuAedBTmHTQc9J2a0v6Pj70HptsD4QtMtORs9cCxpH5NFJnAUW2KKSVb2QeFMy83JqU8TWrLg7NMathNsxXyaqhV4gi+/48YARsxPcZG3gSUykvvbc6nM4Vh4MWGRZMrLaBeankxp6dNf9QnNJxEACjW8dvwxQHv1kV9nB3kXf1L4U2aZqtiJl0LxyDyLZXKYcXsQIiF0XqmBJGk8fnX8fXfkxdV/yht1tSCf6hzN3/qAxBw9qrcQwyhgtF9qUyySbKdsuJH00+GpoAZM9ltVt5qDUPTBFPcivMtBQUrUJ3f1JMBFbXAY8b6z8xlfpydT0yTZQINo+E5tvsDREDwC90RX/2JxhmrZ5l9058KHlQ== X-OriginatorOrg: cavium.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 Feb 2017 17:39:21.7122 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: BY2PR07MB2343 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170201_173958_695156_EDFE8B32 X-CRM114-Status: GOOD ( 23.67 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Robert Richter , Thomas Gleixner , Jason Cooper , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Manage its nodes as kernel devices. We can then use the kernel's device resource management for memory allocation. Freeing memory becomes much easier now. This also allows us to use CMA for the allocation of large its tables. Signed-off-by: Robert Richter --- drivers/irqchip/irq-gic-v3-its.c | 116 +++++++++++++++++++-------------------- 1 file changed, 58 insertions(+), 58 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index e915bb393c87..86b8b9f79f68 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -75,6 +76,7 @@ struct its_baser { * list of devices writing to it. */ struct its_node { + struct device dev; struct fwnode_handle *fwnode; raw_spinlock_t lock; struct list_head entry; @@ -402,7 +404,7 @@ static struct its_cmd_block *its_allocate_entry(struct its_node *its) while (its_queue_full(its)) { count--; if (!count) { - pr_err_ratelimited("ITS queue not draining\n"); + dev_err_ratelimited(&its->dev, "ITS queue not draining\n"); return NULL; } cpu_relax(); @@ -456,7 +458,7 @@ static void its_wait_for_range_completion(struct its_node *its, count--; if (!count) { - pr_err_ratelimited("ITS queue timeout\n"); + dev_err_ratelimited(&its->dev, "ITS queue timeout\n"); return; } cpu_relax(); @@ -476,7 +478,7 @@ static void its_send_single_command(struct its_node *its, cmd = its_allocate_entry(its); if (!cmd) { /* We're soooooo screewed... */ - pr_err_ratelimited("ITS can't allocate, dropping command\n"); + dev_err_ratelimited(&its->dev, "ITS can't allocate, dropping command\n"); raw_spin_unlock_irqrestore(&its->lock, flags); return; } @@ -486,7 +488,7 @@ static void its_send_single_command(struct its_node *its, if (sync_col) { sync_cmd = its_allocate_entry(its); if (!sync_cmd) { - pr_err_ratelimited("ITS can't SYNC, skipping\n"); + dev_err_ratelimited(&its->dev, "ITS can't SYNC, skipping\n"); goto post; } its_encode_cmd(sync_cmd, GITS_CMD_SYNC); @@ -863,14 +865,15 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, retry_alloc_baser: alloc_pages = (PAGE_ORDER_TO_SIZE(order) / psz); if (alloc_pages > GITS_BASER_PAGES_MAX) { - pr_warn("ITS@%pa: %s too large, reduce ITS pages %u->%u\n", - &its->phys_base, its_base_type_string[type], - alloc_pages, GITS_BASER_PAGES_MAX); + dev_warn(&its->dev, "%s too large, reduce ITS pages %u->%u\n", + its_base_type_string[type], alloc_pages, + GITS_BASER_PAGES_MAX); alloc_pages = GITS_BASER_PAGES_MAX; order = get_order(GITS_BASER_PAGES_MAX * psz); } - base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, order); + base = (void *)devm_get_free_pages(&its->dev, GFP_KERNEL | __GFP_ZERO, + order); if (!base) return -ENOMEM; @@ -922,7 +925,7 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, * size and retry. If we reach 4K, then * something is horribly wrong... */ - free_pages((unsigned long)base, order); + devm_free_pages(&its->dev, (unsigned long)base); baser->base = NULL; switch (psz) { @@ -936,10 +939,9 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, } if (val != tmp) { - pr_err("ITS@%pa: %s doesn't stick: %llx %llx\n", - &its->phys_base, its_base_type_string[type], - val, tmp); - free_pages((unsigned long)base, order); + dev_err(&its->dev, "%s doesn't stick: %llx %llx\n", + its_base_type_string[type], val, tmp); + devm_free_pages(&its->dev, (unsigned long)base); return -ENXIO; } @@ -948,8 +950,8 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser, baser->psz = psz; tmp = indirect ? GITS_LVL1_ENTRY_SIZE : esz; - pr_info("ITS@%pa: allocated %d %s @%lx (%s, esz %d, psz %dK, shr %d)\n", - &its->phys_base, (int)(PAGE_ORDER_TO_SIZE(order) / (int)tmp), + dev_info(&its->dev, "allocated %d %s @%lx (%s, esz %d, psz %dK, shr %d)\n", + (int)(PAGE_ORDER_TO_SIZE(order) / (int)tmp), its_base_type_string[type], (unsigned long)virt_to_phys(base), indirect ? "indirect" : "flat", (int)esz, @@ -1000,8 +1002,8 @@ static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser if (new_order >= MAX_ORDER) { new_order = MAX_ORDER - 1; ids = ilog2(PAGE_ORDER_TO_SIZE(new_order) / (int)esz); - pr_warn("ITS@%pa: Device Table too large, reduce ids %u->%u\n", - &its->phys_base, its->device_ids, ids); + dev_warn(&its->dev, "Device Table too large, reduce ids %u->%u\n", + its->device_ids, ids); } *order = new_order; @@ -1009,19 +1011,6 @@ static bool its_parse_baser_device(struct its_node *its, struct its_baser *baser return indirect; } -static void its_free_tables(struct its_node *its) -{ - int i; - - for (i = 0; i < GITS_BASER_NR_REGS; i++) { - if (its->tables[i].base) { - free_pages((unsigned long)its->tables[i].base, - its->tables[i].order); - its->tables[i].base = NULL; - } - } -} - static int its_alloc_tables(struct its_node *its) { u64 typer = gic_read_typer(its->base + GITS_TYPER); @@ -1056,10 +1045,8 @@ static int its_alloc_tables(struct its_node *its) indirect = its_parse_baser_device(its, baser, psz, &order); err = its_setup_baser(its, baser, cache, shr, psz, order, indirect); - if (err < 0) { - its_free_tables(its); + if (err < 0) return err; - } /* Update settings which will be used for next BASERn */ psz = baser->psz; @@ -1343,6 +1330,7 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, gic_flush_dcache_to_poc(itt, sz); + get_device(&its->dev); dev->its = its; dev->itt = itt; dev->nr_ites = nr_ites; @@ -1651,8 +1639,9 @@ static int its_init_domain(struct its_node *its) return 0; } -static void its_free(struct its_node *its) -{ +static void its_device_release(struct device *dev) { + struct its_node *its = container_of(dev, struct its_node, dev); + kfree(its); } @@ -1689,34 +1678,47 @@ static int __init its_init_one(struct its_node *its) u64 baser, tmp; int err; - its_base = ioremap(its->phys_base, its->phys_size); + /* On error always use put_device() to free devices */ + device_initialize(&its->dev); + its->dev.release = its_device_release; + + err = dev_set_name(&its->dev, "its@%pa", &its->phys_base); + if (!err) + err = device_add(&its->dev); + + if (err) { + pr_warn("ITS@%pa: Unable to register device\n", &its->phys_base); + return err; + } + + its_base = devm_ioremap(&its->dev, its->phys_base, its->phys_size); if (!its_base) { - pr_warn("ITS@%pa: Unable to map ITS registers\n", &its->phys_base); + dev_warn(&its->dev, "Unable to map ITS registers\n"); 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", &its->phys_base); + dev_warn(&its->dev, "No ITS detected, giving up\n"); err = -ENODEV; - goto out_unmap; + goto fail; } err = its_force_quiescent(its_base); if (err) { - pr_warn("ITS@%pa: Failed to quiesce, giving up\n", &its->phys_base); - goto out_unmap; + dev_warn(&its->dev, "Failed to quiesce, giving up\n"); + goto fail; } its->base = its_base; its->ite_size = ((gic_read_typer(its_base + GITS_TYPER) >> 4) & 0xf) + 1; - its->cmd_base = (void *)__get_free_pages(GFP_KERNEL | __GFP_ZERO, - get_order(ITS_CMD_QUEUE_SZ)); + its->cmd_base = (void *)devm_get_free_pages(&its->dev, + GFP_KERNEL | __GFP_ZERO, get_order(ITS_CMD_QUEUE_SZ)); if (!its->cmd_base) { err = -ENOMEM; - goto out_unmap; + goto fail; } its->cmd_write = its->cmd_base; @@ -1724,11 +1726,11 @@ static int __init its_init_one(struct its_node *its) err = its_alloc_tables(its); if (err) - goto out_free_cmd; + goto fail; err = its_alloc_collections(its); if (err) - goto out_free_tables; + goto fail; baser = (virt_to_phys(its->cmd_base) | GITS_CBASER_WaWb | @@ -1751,7 +1753,7 @@ static int __init its_init_one(struct its_node *its) baser |= GITS_CBASER_nC; gits_write_cbaser(baser, its->base + GITS_CBASER); } - pr_info("ITS: using cache flushing for cmd queue\n"); + dev_info(&its->dev, "using cache flushing for cmd queue\n"); its->flags |= ITS_FLAGS_CMDQ_NEEDS_FLUSHING; } @@ -1760,20 +1762,14 @@ static int __init its_init_one(struct its_node *its) err = its_init_domain(its); if (err) - goto out_free_tables; + goto fail; - pr_info("ITS@%pa: ITS node added\n", &its->phys_base); + dev_info(&its->dev, "ITS node added\n"); return 0; - -out_free_tables: - its_free_tables(its); -out_free_cmd: - kfree(its->cmd_base); -out_unmap: - iounmap(its_base); fail: - pr_err("ITS@%pa: failed probing (%d)\n", &its->phys_base, err); + device_del(&its->dev); + dev_err(&its->dev, "failed probing (%d)\n", err); return err; } @@ -1907,6 +1903,10 @@ static int __init its_init(void) spin_lock(&its_lock); + /* + * Call this for all entries. We can then use put_device() to + * release the nodes on error. + */ list_for_each_entry(its, &its_nodes, entry) { err2 = its_init_one(its); if (!err && err2) @@ -1918,7 +1918,7 @@ static int __init its_init(void) list_for_each_entry_safe(its, tmp, &its_nodes, entry) { list_del(&its->entry); - its_free(its); + put_device(&its->dev); } unlock: spin_unlock(&its_lock);