From patchwork Mon Mar 19 03:59:08 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mai La X-Patchwork-Id: 147461 X-Patchwork-Delegate: jwboyer@gmail.com 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 AA8A0B7085 for ; Mon, 19 Mar 2012 15:00:52 +1100 (EST) Received: from exprod5og106.obsmtp.com (exprod5og106.obsmtp.com [64.18.0.182]) by ozlabs.org (Postfix) with SMTP id BB1CAB6EF3 for ; Mon, 19 Mar 2012 14:59:47 +1100 (EST) Received: from mail-pb0-f48.google.com ([209.85.160.48]) (using TLSv1) by exprod5ob106.postini.com ([64.18.4.12]) with SMTP ID DSNKT2avMTD8xfsv1JMHFneKtLwWB3RdOYo5@postini.com; Sun, 18 Mar 2012 20:59:48 PDT Received: by pbbjt11 with SMTP id jt11so1117082pbb.7 for ; Sun, 18 Mar 2012 20:59:45 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:x-gm-message-state; bh=sTcSUENtfvPjRIPDW9FRS/rEGVWvtL7txIL34L/jH3k=; b=PxEuIz10TGP3+efyOLmjdsCKySYnKNlAsLC8hD0iAnJAnp5JI35srioN9vA26qj6S1 9SVm+aWatYHCxsi7aMGEAjiCNf/qXPgszlbe3xzu4eVQk+KThDmemEPvgRzNJVzG+yPr PgzWn1aOtzxBGxlEoivCzBOOt+nfHR7wtXF6ksQFTvI0SctI0W0O5dxSM/Dw5wXwUDka gkBHcMU6eXttf9iTCoTak5BXa/VygX6ixpR9qE0DTo1HK23hXzV+xCNIiUdBHswTSE2U KhNNTn+VgWFL0AU6V2hSGquQtUxjLHGPh2aXvEL278mNsPbI+XqzzZBFRCxynkMsslfb uYqQ== Received: by 10.68.221.229 with SMTP id qh5mr21737593pbc.78.1332129584995; Sun, 18 Mar 2012 20:59:44 -0700 (PDT) Received: from localhost.localdomain ([118.69.219.194]) by mx.google.com with ESMTPS id i6sm10332922pbe.18.2012.03.18.20.59.40 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 18 Mar 2012 20:59:43 -0700 (PDT) From: Mai La To: Benjamin Herrenschmidt , Paul Mackerras , Josh Boyer , Matt Porter , Tirumala R Marri , Grant Likely , Michael Neuling , Kumar Gala , Anton Blanchard , linuxppc-dev@lists.ozlabs.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] [v4] powerpc/44x: Fix PCI MSI support for Maui APM821xx SoC and Bluestone board Date: Mon, 19 Mar 2012 10:59:08 +0700 Message-Id: <1332129548-20379-1-git-send-email-mla@apm.com> X-Mailer: git-send-email 1.7.2.5 X-Gm-Message-State: ALoCoQkgBTrrOWjRcKO1k+bCFmCFhEijyb8pqb62ym1fPcWWu7f9nDJoq5tGwIbRQnXx/kgrGXlH Cc: open-source-review@apm.com, Mai La 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: , MIME-Version: 1.0 Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org This patch consists of: - Enable PCI MSI as default for Bluestone board - Change definition of number of MSI interrupts as it depends on SoC - Fix returning ENODEV as finding MSI node - Fix MSI physical high and low address - Keep MSI data logically Signed-off-by: Mai La --- v4: Per Josh Boyer's comment: * Declare msi_irqs as static * Handle error if allocation of MSI vitual interrupts fails * Return ENODEV if counting MSI interrupts fails v3: * Use upper_32_bits() / lower_32_bits() consistently as Wolfgang Denk recomments v2: * Change definition of number of MSI interrupt from config to count interrupts in device tree --- arch/powerpc/platforms/44x/Kconfig | 2 + arch/powerpc/sysdev/ppc4xx_msi.c | 42 ++++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index fcf6bf2..9f04ce3 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -23,6 +23,8 @@ config BLUESTONE default n select PPC44x_SIMPLE select APM821xx + select PCI_MSI + select PPC4xx_MSI select IBM_EMAC_RGMII help This option enables support for the APM APM821xx Evaluation board. diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c index 1c2d7af..cc17f59 100644 --- a/arch/powerpc/sysdev/ppc4xx_msi.c +++ b/arch/powerpc/sysdev/ppc4xx_msi.c @@ -28,10 +28,11 @@ #include #include #include +#include #include #include #include -#include +#include #include #include @@ -43,13 +44,14 @@ #define PEIH_FLUSH0 0x30 #define PEIH_FLUSH1 0x38 #define PEIH_CNTRST 0x48 -#define NR_MSI_IRQS 4 + +static int msi_irqs; struct ppc4xx_msi { u32 msi_addr_lo; u32 msi_addr_hi; void __iomem *msi_regs; - int msi_virqs[NR_MSI_IRQS]; + int *msi_virqs; struct msi_bitmap bitmap; struct device_node *msi_dev; }; @@ -61,7 +63,7 @@ static int ppc4xx_msi_init_allocator(struct platform_device *dev, { int err; - err = msi_bitmap_alloc(&msi_data->bitmap, NR_MSI_IRQS, + err = msi_bitmap_alloc(&msi_data->bitmap, msi_irqs, dev->dev.of_node); if (err) return err; @@ -83,6 +85,11 @@ static int ppc4xx_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) struct msi_desc *entry; struct ppc4xx_msi *msi_data = &ppc4xx_msi; + msi_data->msi_virqs = kmalloc((msi_irqs) * sizeof(int), + GFP_KERNEL); + if (!msi_data->msi_virqs) + return -ENOMEM; + list_for_each_entry(entry, &dev->msi_list, list) { int_no = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1); if (int_no >= 0) @@ -150,12 +157,11 @@ static int ppc4xx_setup_pcieh_hw(struct platform_device *dev, if (!sdr_addr) return -1; - SDR0_WRITE(sdr_addr, (u64)res.start >> 32); /*HIGH addr */ - SDR0_WRITE(sdr_addr + 1, res.start & 0xFFFFFFFF); /* Low addr */ - + mtdcri(SDR0, *sdr_addr, upper_32_bits(res.start)); /*HIGH addr */ + mtdcri(SDR0, *sdr_addr + 1, lower_32_bits(res.start)); /* Low addr */ msi->msi_dev = of_find_node_by_name(NULL, "ppc4xx-msi"); - if (msi->msi_dev) + if (!msi->msi_dev) return -ENODEV; msi->msi_regs = of_iomap(msi->msi_dev, 0); @@ -167,9 +173,12 @@ static int ppc4xx_setup_pcieh_hw(struct platform_device *dev, (u32) (msi->msi_regs + PEIH_TERMADH), (u32) (msi->msi_regs)); msi_virt = dma_alloc_coherent(&dev->dev, 64, &msi_phys, GFP_KERNEL); - msi->msi_addr_hi = 0x0; - msi->msi_addr_lo = (u32) msi_phys; - dev_dbg(&dev->dev, "PCIE-MSI: msi address 0x%x\n", msi->msi_addr_lo); + if (!msi_virt) + return -ENOMEM; + msi->msi_addr_hi = (u32)(msi_phys >> 32); + msi->msi_addr_lo = (u32)(msi_phys & 0xffffffff); + dev_dbg(&dev->dev, "PCIE-MSI: msi address high 0x%x, low 0x%x\n", + msi->msi_addr_hi, msi->msi_addr_lo); /* Progam the Interrupt handler Termination addr registers */ out_be32(msi->msi_regs + PEIH_TERMADH, msi->msi_addr_hi); @@ -185,6 +194,8 @@ static int ppc4xx_setup_pcieh_hw(struct platform_device *dev, out_be32(msi->msi_regs + PEIH_MSIED, *msi_data); out_be32(msi->msi_regs + PEIH_MSIMK, *msi_mask); + dma_free_coherent(&dev->dev, 64, msi_virt, msi_phys); + return 0; } @@ -194,7 +205,7 @@ static int ppc4xx_of_msi_remove(struct platform_device *dev) int i; int virq; - for (i = 0; i < NR_MSI_IRQS; i++) { + for (i = 0; i < msi_irqs; i++) { virq = msi->msi_virqs[i]; if (virq != NO_IRQ) irq_dispose_mapping(virq); @@ -215,8 +226,6 @@ static int __devinit ppc4xx_msi_probe(struct platform_device *dev) struct resource res; int err = 0; - msi = &ppc4xx_msi;/*keep the msi data for further use*/ - dev_dbg(&dev->dev, "PCIE-MSI: Setting up MSI support...\n"); msi = kzalloc(sizeof(struct ppc4xx_msi), GFP_KERNEL); @@ -234,6 +243,10 @@ static int __devinit ppc4xx_msi_probe(struct platform_device *dev) goto error_out; } + msi_irqs = of_irq_count(dev->dev.of_node); + if (!msi_irqs) + return -ENODEV; + if (ppc4xx_setup_pcieh_hw(dev, res, msi)) goto error_out; @@ -242,6 +255,7 @@ static int __devinit ppc4xx_msi_probe(struct platform_device *dev) dev_err(&dev->dev, "Error allocating MSI bitmap\n"); goto error_out; } + ppc4xx_msi = *msi; ppc_md.setup_msi_irqs = ppc4xx_setup_msi_irqs; ppc_md.teardown_msi_irqs = ppc4xx_teardown_msi_irqs;