From patchwork Thu Oct 15 15:39:22 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marc Zyngier X-Patchwork-Id: 7407381 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id A6E8CBEEA4 for ; Thu, 15 Oct 2015 15:42:35 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id D2D9920828 for ; Thu, 15 Oct 2015 15:42:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E0D3C2082B for ; Thu, 15 Oct 2015 15:42:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752224AbbJOPjg (ORCPT ); Thu, 15 Oct 2015 11:39:36 -0400 Received: from foss.arm.com ([217.140.101.70]:36731 "EHLO foss.arm.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753249AbbJOPjf (ORCPT ); Thu, 15 Oct 2015 11:39:35 -0400 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id E0B8749; Thu, 15 Oct 2015 08:39:31 -0700 (PDT) Received: from approximate.cambridge.arm.com (approximate.cambridge.arm.com [10.1.209.125]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 904EC3F49B; Thu, 15 Oct 2015 08:39:33 -0700 (PDT) From: Marc Zyngier To: Thomas Gleixner , Jiang Liu , Jason Cooper Cc: Ma Jun , , , Subject: [PATCH RFC 1/7] platform-msi: Allow MSIs to be allocated in chunks Date: Thu, 15 Oct 2015 16:39:22 +0100 Message-Id: <1444923568-17413-2-git-send-email-marc.zyngier@arm.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1444923568-17413-1-git-send-email-marc.zyngier@arm.com> References: <1444923568-17413-1-git-send-email-marc.zyngier@arm.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP MSIs for a given device are normally all allocated in one go. Make sure the internal code can allocate them one at a time if required. Signed-off-by: Marc Zyngier --- drivers/base/platform-msi.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/drivers/base/platform-msi.c b/drivers/base/platform-msi.c index 5df4575..6148c78 100644 --- a/drivers/base/platform-msi.c +++ b/drivers/base/platform-msi.c @@ -25,6 +25,7 @@ #include #define DEV_ID_SHIFT 24 +#define MAX_DEV_MSIS (1 << (32 - DEV_ID_SHIFT)) /* * Internal data structure containing a (made up, but unique) devid @@ -110,13 +111,16 @@ static void platform_msi_update_chip_ops(struct msi_domain_info *info) chip->irq_write_msi_msg = platform_msi_write_msg; } -static void platform_msi_free_descs(struct device *dev) +static void platform_msi_free_descs(struct device *dev, int base, int nvec) { struct msi_desc *desc, *tmp; list_for_each_entry_safe(desc, tmp, dev_to_msi_list(dev), list) { - list_del(&desc->list); - free_msi_entry(desc); + if (desc->platform.msi_index >= base && + desc->platform.msi_index < (base + nvec)) { + list_del(&desc->list); + free_msi_entry(desc); + } } } @@ -124,17 +128,22 @@ static int platform_msi_alloc_descs(struct device *dev, int nvec, struct platform_msi_priv_data *data) { - int i; + struct msi_desc *desc; + int i, base = 0; - for (i = 0; i < nvec; i++) { - struct msi_desc *desc; + if (!list_empty(dev_to_msi_list(dev))) { + desc = list_last_entry(dev_to_msi_list(dev), + struct msi_desc, list); + base = desc->platform.msi_index + 1; + } + for (i = 0; i < nvec; i++) { desc = alloc_msi_entry(dev); if (!desc) break; desc->platform.msi_priv_data = data; - desc->platform.msi_index = i; + desc->platform.msi_index = base + i; desc->nvec_used = 1; list_add_tail(&desc->list, dev_to_msi_list(dev)); @@ -142,7 +151,7 @@ static int platform_msi_alloc_descs(struct device *dev, int nvec, if (i != nvec) { /* Clean up the mess */ - platform_msi_free_descs(dev); + platform_msi_free_descs(dev, base, nvec); return -ENOMEM; } @@ -201,8 +210,7 @@ int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec, * accordingly (which would impact the max number of MSI * capable devices). */ - if (!dev->msi_domain || !write_msi_msg || !nvec || - nvec > (1 << (32 - DEV_ID_SHIFT))) + if (!dev->msi_domain || !write_msi_msg || !nvec || nvec > MAX_DEV_MSIS) return -EINVAL; if (dev->msi_domain->bus_token != DOMAIN_BUS_PLATFORM_MSI) { @@ -238,7 +246,7 @@ int platform_msi_domain_alloc_irqs(struct device *dev, unsigned int nvec, return 0; out_free_desc: - platform_msi_free_descs(dev); + platform_msi_free_descs(dev, 0, nvec); out_free_id: ida_simple_remove(&platform_msi_devid_ida, priv_data->devid); out_free_data: @@ -266,5 +274,5 @@ void platform_msi_domain_free_irqs(struct device *dev) } msi_domain_free_irqs(dev->msi_domain, dev); - platform_msi_free_descs(dev); + platform_msi_free_descs(dev, 0, MAX_DEV_MSIS); }