Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/807120/?format=api
{ "id": 807120, "url": "http://patchwork.ozlabs.org/api/patches/807120/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/patch/7217503d-5996-f43f-ee56-1b7719d8ac8a@sigmadesigns.com/", "project": { "id": 28, "url": "http://patchwork.ozlabs.org/api/projects/28/?format=api", "name": "Linux PCI development", "link_name": "linux-pci", "list_id": "linux-pci.vger.kernel.org", "list_email": "linux-pci@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<7217503d-5996-f43f-ee56-1b7719d8ac8a@sigmadesigns.com>", "list_archive_url": null, "date": "2017-08-29T14:32:35", "name": "[v11,3/3] PCI: tango: Add MSI controller support", "commit_ref": null, "pull_url": null, "state": "accepted", "archived": false, "hash": "9c8d1e52eebff828f9c3b1858725979aaa87ca16", "submitter": { "id": 67482, "url": "http://patchwork.ozlabs.org/api/people/67482/?format=api", "name": "Marc Gonzalez", "email": "marc_gonzalez@sigmadesigns.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-pci/patch/7217503d-5996-f43f-ee56-1b7719d8ac8a@sigmadesigns.com/mbox/", "series": [ { "id": 381, "url": "http://patchwork.ozlabs.org/api/series/381/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-pci/list/?series=381", "date": "2017-08-29T14:25:55", "name": "Tango PCIe host bridge MSI support + required API", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/381/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/807120/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/807120/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<linux-pci-owner@vger.kernel.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": "ozlabs.org;\n\tspf=none (mailfrom) smtp.mailfrom=vger.kernel.org\n\t(client-ip=209.132.180.67; helo=vger.kernel.org;\n\tenvelope-from=linux-pci-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)", "Received": [ "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xhWS239wqz9t3F\n\tfor <incoming@patchwork.ozlabs.org>;\n\tWed, 30 Aug 2017 00:37:06 +1000 (AEST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1754509AbdH2OhE convert rfc822-to-8bit (ORCPT\n\t<rfc822;incoming@patchwork.ozlabs.org>);\n\tTue, 29 Aug 2017 10:37:04 -0400", "from us-smtp-delivery-107.mimecast.com ([216.205.24.107]:38480\n\t\"EHLO us-smtp-delivery-107.mimecast.com\" rhost-flags-OK-OK-OK-OK)\n\tby vger.kernel.org with ESMTP id S1754506AbdH2OhC (ORCPT\n\t<rfc822; linux-pci@vger.kernel.org>); Tue, 29 Aug 2017 10:37:02 -0400", "from CPH-EX1.SDESIGNS.COM\n\t(195-215-56-170-static.dk.customer.tdc.net [195.215.56.170]) (Using\n\tTLS) by us-smtp-1.mimecast.com with ESMTP id\n\tus-mta-6-kGT937saM9OFqvlXapnUQA-1; Tue, 29 Aug 2017 10:35:36 -0400", "from [172.27.0.114] (172.27.0.114) by CPH-EX1.sdesigns.com\n\t(192.168.10.36) with Microsoft SMTP Server (TLS) id 14.3.294.0;\n\tTue, 29 Aug 2017 16:35:33 +0200" ], "Subject": "[PATCH v11 3/3] PCI: tango: Add MSI controller support", "From": "Marc Gonzalez <marc_gonzalez@sigmadesigns.com>", "To": "Bjorn Helgaas <helgaas@kernel.org>, Marc Zyngier <marc.zyngier@arm.com>", "CC": "linux-pci <linux-pci@vger.kernel.org>,\n\tLinux ARM <linux-arm-kernel@lists.infradead.org>,\n\tRobin Murphy <robin.murphy@arm.com>, Liviu Dudau <liviu.dudau@arm.com>,\n\tThibaud Cornic <thibaud_cornic@sigmadesigns.com>,\n\tMason <slash.tmp@free.fr>", "References": "<f10055cc-4430-ff30-f892-3d3d6f24354c@sigmadesigns.com>", "Message-ID": "<7217503d-5996-f43f-ee56-1b7719d8ac8a@sigmadesigns.com>", "Date": "Tue, 29 Aug 2017 16:32:35 +0200", "User-Agent": "Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101\n\tFirefox/52.0 SeaMonkey/2.49.1", "MIME-Version": "1.0", "In-Reply-To": "<f10055cc-4430-ff30-f892-3d3d6f24354c@sigmadesigns.com>", "X-Originating-IP": "[172.27.0.114]", "X-MC-Unique": "kGT937saM9OFqvlXapnUQA-1", "Content-Type": "text/plain; charset=UTF-8", "Content-Transfer-Encoding": "8BIT", "Sender": "linux-pci-owner@vger.kernel.org", "Precedence": "bulk", "List-ID": "<linux-pci.vger.kernel.org>", "X-Mailing-List": "linux-pci@vger.kernel.org" }, "content": "The MSI controller in Tango supports 256 message-signaled interrupts\nand a single doorbell address.\n\nSigned-off-by: Marc Gonzalez <marc_gonzalez@sigmadesigns.com>\n---\nChanges from v10 to v11\n* Discover msi_doorbell in probe by parsing dma-ranges\n---\n drivers/pci/host/pcie-tango.c | 205 +++++++++++++++++++++++++++++++++++++++++-\n 1 file changed, 202 insertions(+), 3 deletions(-)", "diff": "diff --git a/drivers/pci/host/pcie-tango.c b/drivers/pci/host/pcie-tango.c\nindex 6bbb81f06a53..e23f7383ac33 100644\n--- a/drivers/pci/host/pcie-tango.c\n+++ b/drivers/pci/host/pcie-tango.c\n@@ -1,12 +1,172 @@\n+#include <linux/irqchip/chained_irq.h>\n+#include <linux/irqdomain.h>\n #include <linux/pci-ecam.h>\n #include <linux/delay.h>\n-#include <linux/of.h>\n+#include <linux/msi.h>\n+#include <linux/of_address.h>\n+\n+#define MSI_MAX\t\t\t256\n \n #define SMP8759_MUX\t\t0x48\n #define SMP8759_TEST_OUT\t0x74\n+#define SMP8759_DOORBELL\t0x7c\n+#define SMP8759_STATUS\t\t0x80\n+#define SMP8759_ENABLE\t\t0xa0\n \n struct tango_pcie {\n-\tvoid __iomem *base;\n+\tDECLARE_BITMAP(used_msi, MSI_MAX);\n+\tu64\t\t\tmsi_doorbell;\n+\tspinlock_t\t\tused_msi_lock;\n+\tvoid __iomem\t\t*base;\n+\tstruct irq_domain\t*dom;\n+};\n+\n+static void tango_msi_isr(struct irq_desc *desc)\n+{\n+\tstruct irq_chip *chip = irq_desc_get_chip(desc);\n+\tstruct tango_pcie *pcie = irq_desc_get_handler_data(desc);\n+\tunsigned long status, base, virq, idx, pos = 0;\n+\n+\tchained_irq_enter(chip, desc);\n+\tspin_lock(&pcie->used_msi_lock);\n+\n+\twhile ((pos = find_next_bit(pcie->used_msi, MSI_MAX, pos)) < MSI_MAX) {\n+\t\tbase = round_down(pos, 32);\n+\t\tstatus = readl_relaxed(pcie->base + SMP8759_STATUS + base / 8);\n+\t\tfor_each_set_bit(idx, &status, 32) {\n+\t\t\tvirq = irq_find_mapping(pcie->dom, base + idx);\n+\t\t\tgeneric_handle_irq(virq);\n+\t\t}\n+\t\tpos = base + 32;\n+\t}\n+\n+\tspin_unlock(&pcie->used_msi_lock);\n+\tchained_irq_exit(chip, desc);\n+}\n+\n+static void tango_ack(struct irq_data *d)\n+{\n+\tstruct tango_pcie *pcie = d->chip_data;\n+\tu32 offset = (d->hwirq / 32) * 4;\n+\tu32 bit = BIT(d->hwirq % 32);\n+\n+\twritel_relaxed(bit, pcie->base + SMP8759_STATUS + offset);\n+}\n+\n+static void update_msi_enable(struct irq_data *d, bool unmask)\n+{\n+\tunsigned long flags;\n+\tstruct tango_pcie *pcie = d->chip_data;\n+\tu32 offset = (d->hwirq / 32) * 4;\n+\tu32 bit = BIT(d->hwirq % 32);\n+\tu32 val;\n+\n+\tspin_lock_irqsave(&pcie->used_msi_lock, flags);\n+\tval = readl_relaxed(pcie->base + SMP8759_ENABLE + offset);\n+\tval = unmask ? val | bit : val & ~bit;\n+\twritel_relaxed(val, pcie->base + SMP8759_ENABLE + offset);\n+\tspin_unlock_irqrestore(&pcie->used_msi_lock, flags);\n+}\n+\n+static void tango_mask(struct irq_data *d)\n+{\n+\tupdate_msi_enable(d, false);\n+}\n+\n+static void tango_unmask(struct irq_data *d)\n+{\n+\tupdate_msi_enable(d, true);\n+}\n+\n+static int tango_set_affinity(struct irq_data *d, const struct cpumask *mask,\n+\t\t\t bool force)\n+{\n+\treturn -EINVAL;\n+}\n+\n+static void tango_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)\n+{\n+\tstruct tango_pcie *pcie = d->chip_data;\n+\tmsg->address_lo = lower_32_bits(pcie->msi_doorbell);\n+\tmsg->address_hi = upper_32_bits(pcie->msi_doorbell);\n+\tmsg->data = d->hwirq;\n+}\n+\n+static struct irq_chip tango_chip = {\n+\t.irq_ack\t\t= tango_ack,\n+\t.irq_mask\t\t= tango_mask,\n+\t.irq_unmask\t\t= tango_unmask,\n+\t.irq_set_affinity\t= tango_set_affinity,\n+\t.irq_compose_msi_msg\t= tango_compose_msi_msg,\n+};\n+\n+static void msi_ack(struct irq_data *d)\n+{\n+\tirq_chip_ack_parent(d);\n+}\n+\n+static void msi_mask(struct irq_data *d)\n+{\n+\tpci_msi_mask_irq(d);\n+\tirq_chip_mask_parent(d);\n+}\n+\n+static void msi_unmask(struct irq_data *d)\n+{\n+\tpci_msi_unmask_irq(d);\n+\tirq_chip_unmask_parent(d);\n+}\n+\n+static struct irq_chip msi_chip = {\n+\t.name = \"MSI\",\n+\t.irq_ack = msi_ack,\n+\t.irq_mask = msi_mask,\n+\t.irq_unmask = msi_unmask,\n+};\n+\n+static struct msi_domain_info msi_dom_info = {\n+\t.flags\t= MSI_FLAG_PCI_MSIX\n+\t\t| MSI_FLAG_USE_DEF_DOM_OPS\n+\t\t| MSI_FLAG_USE_DEF_CHIP_OPS,\n+\t.chip\t= &msi_chip,\n+};\n+\n+static int tango_irq_domain_alloc(struct irq_domain *dom, unsigned int virq,\n+\t\t\t\t unsigned int nr_irqs, void *args)\n+{\n+\tstruct tango_pcie *pcie = dom->host_data;\n+\tunsigned long flags;\n+\tint pos;\n+\n+\tspin_lock_irqsave(&pcie->used_msi_lock, flags);\n+\tpos = find_first_zero_bit(pcie->used_msi, MSI_MAX);\n+\tif (pos >= MSI_MAX) {\n+\t\tspin_unlock_irqrestore(&pcie->used_msi_lock, flags);\n+\t\treturn -ENOSPC;\n+\t}\n+\t__set_bit(pos, pcie->used_msi);\n+\tspin_unlock_irqrestore(&pcie->used_msi_lock, flags);\n+\tirq_domain_set_info(dom, virq, pos, &tango_chip,\n+\t\t\tpcie, handle_edge_irq, NULL, NULL);\n+\n+\treturn 0;\n+}\n+\n+static void tango_irq_domain_free(struct irq_domain *dom, unsigned int virq,\n+\t\t\t\t unsigned int nr_irqs)\n+{\n+\tunsigned long flags;\n+\tstruct irq_data *d = irq_domain_get_irq_data(dom, virq);\n+\tstruct tango_pcie *pcie = d->chip_data;\n+\n+\tspin_lock_irqsave(&pcie->used_msi_lock, flags);\n+\t__clear_bit(d->hwirq, pcie->used_msi);\n+\tspin_unlock_irqrestore(&pcie->used_msi_lock, flags);\n+}\n+\n+static const struct irq_domain_ops dom_ops = {\n+\t.alloc\t= tango_irq_domain_alloc,\n+\t.free\t= tango_irq_domain_free,\n };\n \n static int smp8759_config_read(struct pci_bus *bus, unsigned int devfn,\n@@ -76,7 +236,11 @@ static int tango_pcie_probe(struct platform_device *pdev)\n \tstruct device *dev = &pdev->dev;\n \tstruct tango_pcie *pcie;\n \tstruct resource *res;\n-\tint ret;\n+\tstruct fwnode_handle *fwnode = of_node_to_fwnode(dev->of_node);\n+\tstruct irq_domain *msi_dom, *irq_dom;\n+\tstruct of_pci_range_parser parser;\n+\tstruct of_pci_range range;\n+\tint virq, offset;\n \n \tdev_warn(dev, \"simultaneous PCI config and MMIO accesses may cause data corruption\\n\");\n \tadd_taint(TAINT_CRAP, LOCKDEP_STILL_OK);\n@@ -95,6 +259,41 @@ static int tango_pcie_probe(struct platform_device *pdev)\n \tif (!tango_pcie_link_up(pcie))\n \t\treturn -ENODEV;\n \n+\tif (of_pci_dma_range_parser_init(&parser, dev->of_node) < 0)\n+\t\treturn -ENOENT;\n+\n+\tif (of_pci_range_parser_one(&parser, &range) == NULL)\n+\t\treturn -ENOENT;\n+\n+\trange.pci_addr += range.size;\n+\tpcie->msi_doorbell = range.pci_addr + res->start + SMP8759_DOORBELL;\n+\n+\tfor (offset = 0; offset < MSI_MAX / 8; offset += 4)\n+\t\twritel_relaxed(0, pcie->base + SMP8759_ENABLE + offset);\n+\n+\tvirq = platform_get_irq(pdev, 1);\n+\tif (virq <= 0) {\n+\t\tdev_err(dev, \"Failed to map IRQ\\n\");\n+\t\treturn -ENXIO;\n+\t}\n+\n+\tirq_dom = irq_domain_create_linear(fwnode, MSI_MAX, &dom_ops, pcie);\n+\tif (!irq_dom) {\n+\t\tdev_err(dev, \"Failed to create IRQ domain\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tmsi_dom = pci_msi_create_irq_domain(fwnode, &msi_dom_info, irq_dom);\n+\tif (!msi_dom) {\n+\t\tdev_err(dev, \"Failed to create MSI domain\\n\");\n+\t\tirq_domain_remove(irq_dom);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tpcie->dom = irq_dom;\n+\tspin_lock_init(&pcie->used_msi_lock);\n+\tirq_set_chained_handler_and_data(virq, tango_msi_isr, pcie);\n+\n \treturn pci_host_common_probe(pdev, &smp8759_ecam_ops);\n }\n \n", "prefixes": [ "v11", "3/3" ] }