get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/1.2/patches/805592/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 805592,
    "url": "http://patchwork.ozlabs.org/api/1.2/patches/805592/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-pci/patch/20170824184321.19432-3-ard.biesheuvel@linaro.org/",
    "project": {
        "id": 28,
        "url": "http://patchwork.ozlabs.org/api/1.2/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": "<20170824184321.19432-3-ard.biesheuvel@linaro.org>",
    "list_archive_url": null,
    "date": "2017-08-24T18:43:20",
    "name": "[v2,2/3] pci: designware: add separate driver for the MSI part of the RC",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": false,
    "hash": "e91b1d87c1cba9f15a775c50ec39d49c82252bdc",
    "submitter": {
        "id": 26857,
        "url": "http://patchwork.ozlabs.org/api/1.2/people/26857/?format=api",
        "name": "Ard Biesheuvel",
        "email": "ard.biesheuvel@linaro.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-pci/patch/20170824184321.19432-3-ard.biesheuvel@linaro.org/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/805592/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/805592/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>)",
            "ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=linaro.org header.i=@linaro.org\n\theader.b=\"dN2evIXy\"; dkim-atps=neutral"
        ],
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xdY950Vpjz9s8P\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 25 Aug 2017 04:43:53 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1753470AbdHXSnv (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);\n\tThu, 24 Aug 2017 14:43:51 -0400",
            "from mail-wm0-f41.google.com ([74.125.82.41]:36274 \"EHLO\n\tmail-wm0-f41.google.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1752909AbdHXSnv (ORCPT\n\t<rfc822; linux-pci@vger.kernel.org>); Thu, 24 Aug 2017 14:43:51 -0400",
            "by mail-wm0-f41.google.com with SMTP id z132so2102711wmg.1\n\tfor <linux-pci@vger.kernel.org>; Thu, 24 Aug 2017 11:43:50 -0700 (PDT)",
            "from localhost.localdomain ([196.71.110.206])\n\tby smtp.gmail.com with ESMTPSA id\n\te2sm3531945wrd.60.2017.08.24.11.43.45\n\t(version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128);\n\tThu, 24 Aug 2017 11:43:47 -0700 (PDT)"
        ],
        "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google;\n\th=from:to:cc:subject:date:message-id:in-reply-to:references;\n\tbh=yJzSqSRvIDsV/vnpwrpwXeDEEqFQC2yqBMcAopw1wYc=;\n\tb=dN2evIXyDkUlT6Cca0DguTtzH56A517b3nNan2fKQJz8Kbwy89h3xJeSetUxNOysdA\n\t63SU2emmuKFDTEREQtOzrOr1iLe6wCP3ySDKID5eF3jPpAq33FhgFWVyTlkUP4yk53P9\n\tXwXMJLmlHq9iiDYC5hP+zBp2oGcvR2ECiw2x8=",
        "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n\td=1e100.net; s=20161025;\n\th=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to\n\t:references;\n\tbh=yJzSqSRvIDsV/vnpwrpwXeDEEqFQC2yqBMcAopw1wYc=;\n\tb=BAbewMt5Q45DHq7FBZSBjbkJ14n/RSfIYE0Vlg9eTV2JKQmKok+4MeHwTmvNt4J7hb\n\t9no2nFRz7EB5Ye+JunZcQz/z+lW84H5vJ/Y1FlhUQ1veIqy65FGVLwdcj4K93Zb4lT/i\n\tP3n/sovwgfL5sqF2+SpSfwwVH1Mo/uRoNcTvHT64BvgM1nTRB8fb13NcxP194zjzDM4y\n\tU5PvkalIBMeBchI/2fyiay0PnBuIt1IVFgHpN7XOgv8TasztHIUjOroqUsYRwICblOSM\n\tJtwVOfcS8f3ttv6IfGeoFNSH+Dl2XjgrAedtYSPGoF/pW2lCWp2oJ9tOx5dshZctj7N2\n\t3Lqg==",
        "X-Gm-Message-State": "AHYfb5gYWfa9dUz2gsTN/jOrH2+nTWt6LuE7hXOH9XWAK4YpGzo1TrxN\n\tVQf8wVpwZrmPwPPWBOrinA==",
        "X-Received": "by 10.28.73.9 with SMTP id w9mr3812466wma.63.1503600227970;\n\tThu, 24 Aug 2017 11:43:47 -0700 (PDT)",
        "From": "Ard Biesheuvel <ard.biesheuvel@linaro.org>",
        "To": "linux-pci@vger.kernel.org",
        "Cc": "mw@semihalf.com, Ard Biesheuvel <ard.biesheuvel@linaro.org>,\n\tLeif Lindholm <leif.lindholm@linaro.org>,\n\tGraeme Gregory <graeme.gregory@linaro.org>,\n\tBjorn Helgaas <bhelgaas@google.com>, Jingoo Han <jingoohan1@gmail.com>,\n\tJoao Pinto <Joao.Pinto@synopsys.com>, Marc Zyngier <marc.zyngier@arm.com>",
        "Subject": "[PATCH v2 2/3] pci: designware: add separate driver for the MSI\n\tpart of the RC",
        "Date": "Thu, 24 Aug 2017 19:43:20 +0100",
        "Message-Id": "<20170824184321.19432-3-ard.biesheuvel@linaro.org>",
        "X-Mailer": "git-send-email 2.11.0",
        "In-Reply-To": "<20170824184321.19432-1-ard.biesheuvel@linaro.org>",
        "References": "<20170824184321.19432-1-ard.biesheuvel@linaro.org>",
        "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": "Most drivers that currently exist for the Synopsys Designware PCIe\ncontroller in RC mode hardcode the relation with the embedded MSI\ncontroller. This makes it more difficult than necessary to use a\ngeneric driver to drive the RC, which is especially unfortunate\nin cases where the firmware already configures the RC to the extent\nthat it can be driven by the generic ECAM driver. It also makes it\nimpossible to use an existing driver but use another IP block for\nMSI support, i.e., a GICv2m or GICv3-ITS.\n\nSo add a separate driver for the MSI part, which can be referenced\nfrom the DT node describing the RC via its msi-parent property.\n\nSigned-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>\n---\n drivers/pci/dwc/Makefile              |   3 +-\n drivers/pci/dwc/pcie-designware-msi.c | 255 ++++++++++++++++++++\n 2 files changed, 257 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile\nindex 7d5a23e5b767..7607a2b686a0 100644\n--- a/drivers/pci/dwc/Makefile\n+++ b/drivers/pci/dwc/Makefile\n@@ -1,5 +1,6 @@\n obj-$(CONFIG_PCIE_DW) += pcie-designware.o\n-obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o\n+msi-obj-$(CONFIG_PCI_MSI_IRQ_DOMAIN) += pcie-designware-msi.o\n+obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o $(msi-obj-y)\n obj-$(CONFIG_PCIE_DW_HOST_ECAM) += pcie-designware-ecam.o\n obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o\n obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o\ndiff --git a/drivers/pci/dwc/pcie-designware-msi.c b/drivers/pci/dwc/pcie-designware-msi.c\nnew file mode 100644\nindex 000000000000..16b02151177d\n--- /dev/null\n+++ b/drivers/pci/dwc/pcie-designware-msi.c\n@@ -0,0 +1,255 @@\n+/*\n+ * Copyright (C) 2017 Linaro Limited <ard.biesheuvel@linaro.org>\n+ *\n+ * Based on code posted for the tango platform by\n+ *                            Marc Gonzalez <marc_gonzalez@sigmadesigns.com>\n+ *\n+ * This program is free software; you can redistribute it and/or modify\n+ * it under the terms of the GNU General Public License version 2 as\n+ * published by the Free Software Foundation.\n+ */\n+\n+#include <linux/irq.h>\n+#include <linux/irqchip/chained_irq.h>\n+#include <linux/irqdomain.h>\n+#include <linux/msi.h>\n+#include <linux/of_pci.h>\n+#include <linux/platform_device.h>\n+\n+#include \"pcie-designware.h\"\n+\n+struct dw_pcie_msi {\n+\tvoid __iomem\t\t*regbase;\n+\tint\t\t\tirq;\n+\tstruct irq_domain\t*irqd;\n+\tstruct irq_domain\t*msid;\n+\tDECLARE_BITMAP(\t\tused_msi, MAX_MSI_IRQS);\n+\tspinlock_t\t\tused_msi_lock;\n+\tu32\t\t\tdoorbell;\n+};\n+\n+static void dw_pcie_msi_isr(struct irq_desc *desc)\n+{\n+\tstruct irq_chip *chip = irq_desc_get_chip(desc);\n+\tstruct dw_pcie_msi *dw_msi = irq_desc_get_handler_data(desc);\n+\tunsigned long status, base, virq, idx, pos;\n+\n+\tchained_irq_enter(chip, desc);\n+\tspin_lock(&dw_msi->used_msi_lock);\n+\n+\tfor (pos = 0; pos < MAX_MSI_IRQS;\n+\t     pos = find_next_bit(dw_msi->used_msi, MAX_MSI_IRQS, pos)) {\n+\t\tbase = round_down(pos, 32);\n+\t\tstatus = readl_relaxed(dw_msi->regbase + PCIE_MSI_INTR0_STATUS +\n+\t\t\t\t       (base / 32) * 12);\n+\t\tfor_each_set_bit(idx, &status, 32) {\n+\t\t\tvirq = irq_find_mapping(dw_msi->irqd, base + idx);\n+\t\t\tgeneric_handle_irq(virq);\n+\t\t}\n+\t\tpos = base + 32;\n+\t}\n+\n+\tspin_unlock(&dw_msi->used_msi_lock);\n+\tchained_irq_exit(chip, desc);\n+}\n+\n+static void dw_pcie_ack(struct irq_data *d)\n+{\n+\tstruct dw_pcie_msi *dw_msi = d->chip_data;\n+\tu32 offset = (d->hwirq / 32) * 12;\n+\tu32 bit = BIT(d->hwirq % 32);\n+\n+\twritel_relaxed(bit, dw_msi->regbase + PCIE_MSI_INTR0_STATUS + offset);\n+}\n+\n+static void dw_pcie_update_msi_enable(struct irq_data *d, bool unmask)\n+{\n+\tunsigned long flags;\n+\tstruct dw_pcie_msi *dw_msi = d->chip_data;\n+\tu32 offset = (d->hwirq / 32) * 12;\n+\tu32 bit = BIT(d->hwirq % 32);\n+\tu32 val;\n+\n+\tspin_lock_irqsave(&dw_msi->used_msi_lock, flags);\n+\tval = readl_relaxed(dw_msi->regbase + PCIE_MSI_INTR0_ENABLE + offset);\n+\tval = unmask ? (val | bit) : (val & ~bit);\n+\twritel_relaxed(val, dw_msi->regbase + PCIE_MSI_INTR0_ENABLE + offset);\n+\tspin_unlock_irqrestore(&dw_msi->used_msi_lock, flags);\n+}\n+\n+static void dw_pcie_mask(struct irq_data *d)\n+{\n+\tdw_pcie_update_msi_enable(d, false);\n+}\n+\n+static void dw_pcie_unmask(struct irq_data *d)\n+{\n+\tdw_pcie_update_msi_enable(d, true);\n+}\n+\n+static int dw_pcie_set_affinity(struct irq_data *d,\n+\t\t\t\t    const struct cpumask *mask, bool force)\n+{\n+\treturn -EINVAL;\n+}\n+\n+static void dw_pcie_compose_msi_msg(struct irq_data *d, struct msi_msg *msg)\n+{\n+\tstruct dw_pcie_msi *dw_msi = d->chip_data;\n+\n+\tmsg->address_lo = lower_32_bits(virt_to_phys(&dw_msi->doorbell));\n+\tmsg->address_hi = upper_32_bits(virt_to_phys(&dw_msi->doorbell));\n+\tmsg->data = d->hwirq;\n+}\n+\n+static struct irq_chip dw_pcie_chip = {\n+\t.irq_ack\t\t= dw_pcie_ack,\n+\t.irq_mask\t\t= dw_pcie_mask,\n+\t.irq_unmask\t\t= dw_pcie_unmask,\n+\t.irq_set_affinity\t= dw_pcie_set_affinity,\n+\t.irq_compose_msi_msg\t= dw_pcie_compose_msi_msg,\n+};\n+\n+static void dw_pcie_msi_ack(struct irq_data *d)\n+{\n+\tirq_chip_ack_parent(d);\n+}\n+\n+static void dw_pcie_msi_mask(struct irq_data *d)\n+{\n+\tpci_msi_mask_irq(d);\n+\tirq_chip_mask_parent(d);\n+}\n+\n+static void dw_pcie_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 dw_pcie_msi_chip = {\n+\t.name\t\t\t= \"DW-MSI\",\n+\t.irq_ack\t\t= dw_pcie_msi_ack,\n+\t.irq_mask\t\t= dw_pcie_msi_mask,\n+\t.irq_unmask\t\t= dw_pcie_msi_unmask,\n+};\n+\n+static struct msi_domain_info dw_pcie_msi_dom_info = {\n+\t.flags\t= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS,\n+\t.chip\t= &dw_pcie_msi_chip,\n+};\n+\n+static int dw_pcie_msi_irq_domain_alloc(struct irq_domain *dom,\n+\t\t\t\t\tunsigned int virq,\n+\t\t\t\t\tunsigned int nr_irqs, void *args)\n+{\n+\tstruct dw_pcie_msi *dw_msi = dom->host_data;\n+\tunsigned long flags;\n+\tint pos;\n+\n+\tspin_lock_irqsave(&dw_msi->used_msi_lock, flags);\n+\tpos = find_first_zero_bit(dw_msi->used_msi, MAX_MSI_IRQS);\n+\tif (pos >= MAX_MSI_IRQS) {\n+\t\tspin_unlock_irqrestore(&dw_msi->used_msi_lock, flags);\n+\t\treturn -ENOSPC;\n+\t}\n+\t__set_bit(pos, dw_msi->used_msi);\n+\tspin_unlock_irqrestore(&dw_msi->used_msi_lock, flags);\n+\tirq_domain_set_info(dom, virq, pos, &dw_pcie_chip, dw_msi,\n+\t\t\t    handle_edge_irq, NULL, NULL);\n+\n+\treturn 0;\n+}\n+\n+static void dw_pcie_msi_irq_domain_free(struct irq_domain *dom,\n+\t\t\t\t\tunsigned int virq,\n+\t\t\t\t\tunsigned int nr_irqs)\n+{\n+\tstruct irq_data *d = irq_domain_get_irq_data(dom, virq);\n+\tstruct dw_pcie_msi *dw_msi = d->chip_data;\n+\tunsigned long flags;\n+\n+\tspin_lock_irqsave(&dw_msi->used_msi_lock, flags);\n+\t__clear_bit(d->hwirq, dw_msi->used_msi);\n+\tspin_unlock_irqrestore(&dw_msi->used_msi_lock, flags);\n+}\n+\n+static const struct irq_domain_ops irq_dom_ops = {\n+\t.alloc\t= dw_pcie_msi_irq_domain_alloc,\n+\t.free\t= dw_pcie_msi_irq_domain_free,\n+};\n+\n+static int dw_pcie_msi_probe(struct platform_device *pdev)\n+{\n+\tstruct device *dev = &pdev->dev;\n+\tstruct dw_pcie_msi *dw_msi;\n+\tstruct resource *res;\n+\n+\tdw_msi = devm_kzalloc(dev, sizeof(*dw_msi), GFP_KERNEL);\n+\tif (!dw_msi)\n+\t\treturn -ENOMEM;\n+\n+\t/* get the control register and map it */\n+\tres = platform_get_resource(pdev, IORESOURCE_MEM, 0);\n+\tdw_msi->regbase = devm_ioremap_resource(dev, res);\n+\tif (IS_ERR(dw_msi->regbase))\n+\t\treturn PTR_ERR(dw_msi->regbase);\n+\n+\t/* get the wired interrupt that gets raised when we receive an MSI */\n+\tdw_msi->irq = platform_get_irq(pdev, 0);\n+\tif (dw_msi->irq <= 0) {\n+\t\tdev_err(dev, \"No IRQ resource found\\n\");\n+\t\treturn -ENXIO;\n+\t}\n+\n+\tdw_msi->irqd = irq_domain_create_linear(dev->fwnode, MAX_MSI_IRQS,\n+\t\t\t\t\t\t&irq_dom_ops, dw_msi);\n+\tif (!dw_msi->irqd) {\n+\t\tdev_err(dev, \"Failed to create IRQ domain\\n\");\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tdw_msi->msid = pci_msi_create_irq_domain(dev->fwnode,\n+\t\t\t\t\t\t &dw_pcie_msi_dom_info,\n+\t\t\t\t\t\t dw_msi->irqd);\n+\tif (!dw_msi->msid) {\n+\t\tdev_err(dev, \"Failed to create MSI domain\\n\");\n+\t\tirq_domain_remove(dw_msi->irqd);\n+\t\treturn -ENOMEM;\n+\t}\n+\n+\tirq_set_chained_handler_and_data(dw_msi->irq, dw_pcie_msi_isr, dw_msi);\n+\tplatform_set_drvdata(pdev, dw_msi);\n+\n+\t/* program the msi_data */\n+\twritel_relaxed(lower_32_bits(virt_to_phys(&dw_msi->doorbell)),\n+\t\t       dw_msi->regbase + PCIE_MSI_ADDR_LO);\n+\twritel_relaxed(upper_32_bits(virt_to_phys(&dw_msi->doorbell)),\n+\t\t       dw_msi->regbase + PCIE_MSI_ADDR_HI);\n+\n+\treturn 0;\n+}\n+\n+static int dw_pcie_msi_remove(struct platform_device *pdev)\n+{\n+\tstruct dw_pcie_msi *dw_msi = platform_get_drvdata(pdev);\n+\n+\tirq_set_chained_handler_and_data(dw_msi->irq, NULL, NULL);\n+\tirq_domain_remove(dw_msi->msid);\n+\tirq_domain_remove(dw_msi->irqd);\n+\n+\treturn 0;\n+}\n+\n+static const struct of_device_id dw_pcie_dw_msi_of_match[] = {\n+\t{ .compatible = \"snps,dw-pcie-msi\" },\n+\t{ },\n+};\n+\n+static struct platform_driver pci_dw_msi_driver = {\n+\t.driver.name\t\t\t= \"pcie-designware-msi\",\n+\t.driver.of_match_table\t\t= dw_pcie_dw_msi_of_match,\n+\t.probe\t\t\t\t= dw_pcie_msi_probe,\n+\t.remove\t\t\t\t= dw_pcie_msi_remove,\n+};\n+builtin_platform_driver(pci_dw_msi_driver);\n",
    "prefixes": [
        "v2",
        "2/3"
    ]
}