From patchwork Wed Oct 26 22:30:15 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Timur Tabi X-Patchwork-Id: 122034 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from ozlabs.org (localhost [IPv6:::1]) by ozlabs.org (Postfix) with ESMTP id 5DBD11007F3 for ; Thu, 27 Oct 2011 09:30:40 +1100 (EST) Received: by ozlabs.org (Postfix) id 03F861007D8; Thu, 27 Oct 2011 09:30:26 +1100 (EST) Delivered-To: linuxppc-dev@ozlabs.org Received: from AM1EHSOBE002.bigfish.com (am1ehsobe002.messaging.microsoft.com [213.199.154.205]) (using TLSv1 with cipher AES128-SHA (128/128 bits)) (Client CN "mail.global.frontbridge.com", Issuer "Microsoft Secure Server Authority" (verified OK)) by ozlabs.org (Postfix) with ESMTPS id 58C371007D7 for ; Thu, 27 Oct 2011 09:30:23 +1100 (EST) Received: from mail49-am1-R.bigfish.com (10.3.201.240) by AM1EHSOBE002.bigfish.com (10.3.204.22) with Microsoft SMTP Server id 14.1.225.22; Wed, 26 Oct 2011 22:30:12 +0000 Received: from mail49-am1 (localhost.localdomain [127.0.0.1]) by mail49-am1-R.bigfish.com (Postfix) with ESMTP id 2518C1BD0373; Wed, 26 Oct 2011 22:30:16 +0000 (UTC) X-SpamScore: 3 X-BigFish: VS3(z37d5kzzz1202hzz8275bhz2dh2a8h668h839h61h) X-Spam-TCS-SCL: 0:0 X-Forefront-Antispam-Report: CIP:70.37.183.190; KIP:(null); UIP:(null); IPVD:NLI; H:mail.freescale.net; RD:none; EFVD:NLI X-FB-SS: 0, Received: from mail49-am1 (localhost.localdomain [127.0.0.1]) by mail49-am1 (MessageSwitch) id 1319668215918427_17598; Wed, 26 Oct 2011 22:30:15 +0000 (UTC) Received: from AM1EHSMHS001.bigfish.com (unknown [10.3.201.253]) by mail49-am1.bigfish.com (Postfix) with ESMTP id D6DA11730051; Wed, 26 Oct 2011 22:30:15 +0000 (UTC) Received: from mail.freescale.net (70.37.183.190) by AM1EHSMHS001.bigfish.com (10.3.207.101) with Microsoft SMTP Server (TLS) id 14.1.225.22; Wed, 26 Oct 2011 22:30:12 +0000 Received: from az33smr02.freescale.net (10.64.34.200) by 039-SN1MMR1-001.039d.mgd.msft.net (10.84.1.13) with Microsoft SMTP Server id 14.1.339.2; Wed, 26 Oct 2011 17:30:16 -0500 Received: from efes.am.freescale.net (efes.am.freescale.net [10.82.123.3]) by az33smr02.freescale.net (8.13.1/8.13.0) with ESMTP id p9QMUFC8029165; Wed, 26 Oct 2011 17:30:15 -0500 (CDT) From: Timur Tabi To: , , , , , Subject: [PATCH] [v2] powerpc/fsl_msi: add support for the fsl, msi property in PCI nodes Date: Wed, 26 Oct 2011 17:30:15 -0500 Message-ID: <1319668215-20089-1-git-send-email-timur@freescale.com> X-Mailer: git-send-email 1.7.3.4 MIME-Version: 1.0 X-OriginatorOrg: freescale.com X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org On Freescale parts with multiple MSI controllers, the controllers are combined into one "pool" of interrupts. Whenever a device requests an MSI interrupt, the next available interrupt from the pool is selected, regardless of which MSI controller the interrupt is from. This works because each PCI bus has an ATMU to all of CCSR, so any PCI device can access any MSI interrupt register. The fsl,msi property is used to specify that a given PCI bus should only use a specific MSI device. This is necessary, for example, with the Freescale hypervisor, because the MSI devices are assigned to specific partitions. Ideally, we'd like to be able to assign MSI devices to PCI busses within the MSI or PCI layers. However, there does not appear to be a mechanism to do that. Whenever the MSI layer wants to allocate an MSI interrupt to a PCI device, it just calls arch_setup_msi_irqs(). It would be nice if we could register an MSI device with a specific PCI bus. So instead we remember the phandles of each MSI device, and we use that to limit our search for an available interrupt. Whenever we are asked to allocate a new interrupt for a PCI device, we check the fsl,msi property of the PCI bus for that device. If it exists, then as we are looping over all MSI devices, we skip the ones that don't have a matching phandle. Signed-off-by: Timur Tabi --- arch/powerpc/sysdev/fsl_msi.c | 33 +++++++++++++++++++++++++++++++++ arch/powerpc/sysdev/fsl_msi.h | 3 +++ 2 files changed, 36 insertions(+), 0 deletions(-) diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c index e5c344d..155ccb2 100644 --- a/arch/powerpc/sysdev/fsl_msi.c +++ b/arch/powerpc/sysdev/fsl_msi.c @@ -148,14 +148,41 @@ static void fsl_compose_msi_msg(struct pci_dev *pdev, int hwirq, static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type) { + struct pci_controller *hose = pci_bus_to_host(pdev->bus); + struct device_node *np; + phandle phandle = 0; int rc, hwirq = -ENOMEM; unsigned int virq; struct msi_desc *entry; struct msi_msg msg; struct fsl_msi *msi_data; + /* + * If the PCI node has an fsl,msi property, then we need to use it + * to find the specific MSI. + */ + np = of_parse_phandle(hose->dn, "fsl,msi", 0); + if (np) + phandle = np->phandle; + list_for_each_entry(entry, &pdev->msi_list, list) { + /* + * Loop over all the available MSI devices until we find one + * that has an available interrupt. + */ list_for_each_entry(msi_data, &msi_head, list) { + /* + * If the PCI node has an fsl,msi property, then we + * need to restrict our search to the corresponding + * MSI node. The simplest way is to skip over MSI + * nodes with the wrong phandle. Under the Freescale + * hypervisor, this has the additional benefit of + * skipping over MSI nodes that are not mapped in the + * PAMU. + */ + if (phandle && (phandle != msi_data->phandle)) + continue; + hwirq = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); if (hwirq >= 0) break; @@ -370,6 +397,12 @@ static int __devinit fsl_of_msi_probe(struct platform_device *dev) msi->msiir_offset = features->msiir_offset + (res.start & 0xfffff); + /* + * Remember the phandle, so that we can match with any PCI nodes + * that have an "fsl,msi" property. + */ + msi->phandle = dev->dev.of_node->phandle; + rc = fsl_msi_init_allocator(msi); if (rc) { dev_err(&dev->dev, "Error allocating MSI bitmap\n"); diff --git a/arch/powerpc/sysdev/fsl_msi.h b/arch/powerpc/sysdev/fsl_msi.h index 1313abb..b5d25ba 100644 --- a/arch/powerpc/sysdev/fsl_msi.h +++ b/arch/powerpc/sysdev/fsl_msi.h @@ -13,6 +13,7 @@ #ifndef _POWERPC_SYSDEV_FSL_MSI_H #define _POWERPC_SYSDEV_FSL_MSI_H +#include #include #define NR_MSI_REG 8 @@ -36,6 +37,8 @@ struct fsl_msi { struct msi_bitmap bitmap; struct list_head list; /* support multiple MSI banks */ + + phandle phandle; }; #endif /* _POWERPC_SYSDEV_FSL_MSI_H */