get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 354081,
    "url": "http://patchwork.ozlabs.org/api/patches/354081/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-tegra/patch/1401448834-32659-10-git-send-email-hdoyu@nvidia.com/",
    "project": {
        "id": 21,
        "url": "http://patchwork.ozlabs.org/api/projects/21/?format=api",
        "name": "Linux Tegra Development",
        "link_name": "linux-tegra",
        "list_id": "linux-tegra.vger.kernel.org",
        "list_email": "linux-tegra@vger.kernel.org",
        "web_url": null,
        "scm_url": null,
        "webscm_url": null,
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<1401448834-32659-10-git-send-email-hdoyu@nvidia.com>",
    "list_archive_url": null,
    "date": "2014-05-30T11:20:22",
    "name": "[PATCHv8,09/21] iommu/tegra: smmu: get swgroups from DT \"iommus=\"",
    "commit_ref": null,
    "pull_url": null,
    "state": "superseded",
    "archived": true,
    "hash": "431df0e0fa6af53218a349fe609aa102f5b89c2a",
    "submitter": {
        "id": 10265,
        "url": "http://patchwork.ozlabs.org/api/people/10265/?format=api",
        "name": "Hiroshi Doyu",
        "email": "hdoyu@nvidia.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-tegra/patch/1401448834-32659-10-git-send-email-hdoyu@nvidia.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/354081/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/354081/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<linux-tegra-owner@vger.kernel.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org",
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id DE8F01400D6\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri, 30 May 2014 21:20:49 +1000 (EST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1752887AbaE3LUq (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);\n\tFri, 30 May 2014 07:20:46 -0400",
            "from hqemgate15.nvidia.com ([216.228.121.64]:17136 \"EHLO\n\thqemgate15.nvidia.com\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1752059AbaE3LUo (ORCPT\n\t<rfc822;linux-tegra@vger.kernel.org>);\n\tFri, 30 May 2014 07:20:44 -0400",
            "from hqnvupgp08.nvidia.com (Not Verified[216.228.121.13]) by\n\thqemgate15.nvidia.com\n\tid <B538869820000>; Fri, 30 May 2014 04:20:34 -0700",
            "from hqemhub01.nvidia.com ([172.20.12.94])\n\tby hqnvupgp08.nvidia.com (PGP Universal service);\n\tFri, 30 May 2014 04:15:41 -0700",
            "from deemhub02.nvidia.com (10.21.69.138) by hqemhub01.nvidia.com\n\t(172.20.150.30) with Microsoft SMTP Server (TLS) id 8.3.342.0;\n\tFri, 30 May 2014 04:20:44 -0700",
            "from oreo.nvidia.com (10.21.65.27) by deemhub02.nvidia.com\n\t(10.21.69.138) with Microsoft SMTP Server (TLS) id 8.3.342.0;\n\tFri, 30 May 2014 13:20:41 +0200"
        ],
        "X-PGP-Universal": "processed;\n\tby hqnvupgp08.nvidia.com on Fri, 30 May 2014 04:15:41 -0700",
        "From": "Hiroshi Doyu <hdoyu@nvidia.com>",
        "To": "<linux-tegra@vger.kernel.org>",
        "Subject": "[PATCHv8 09/21] iommu/tegra: smmu: get swgroups from DT \"iommus=\"",
        "Date": "Fri, 30 May 2014 14:20:22 +0300",
        "Message-ID": "<1401448834-32659-10-git-send-email-hdoyu@nvidia.com>",
        "X-Mailer": "git-send-email 2.0.0.rc1.15.g7e76a2f",
        "In-Reply-To": "<1401448834-32659-1-git-send-email-hdoyu@nvidia.com>",
        "References": "<1401448834-32659-1-git-send-email-hdoyu@nvidia.com>",
        "X-NVConfidentiality": "public",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain",
        "Sender": "linux-tegra-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<linux-tegra.vger.kernel.org>",
        "X-Mailing-List": "linux-tegra@vger.kernel.org"
    },
    "content": "This provides the info about which swgroups a device belongs to. This\ninfo is passed from DT. This is necessary for the unified SMMU driver\namong Tegra SoCs since each has different H/W accelerators.\n\nSigned-off-by: Hiroshi Doyu <hdoyu@nvidia.com>\n---\n drivers/iommu/tegra-smmu.c | 134 +++++++++++++++++++++++++++++++++++++++------\n 1 file changed, 116 insertions(+), 18 deletions(-)",
    "diff": "diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c\nindex fe351cdd5c05..1d3f695d3c66 100644\n--- a/drivers/iommu/tegra-smmu.c\n+++ b/drivers/iommu/tegra-smmu.c\n@@ -190,6 +190,8 @@ enum {\n  * Per client for address space\n  */\n struct smmu_client {\n+\tstruct device_node\t*of_node;\n+\tstruct rb_node\t\tnode;\n \tstruct device\t\t*dev;\n \tstruct list_head\tlist;\n \tstruct smmu_as\t\t*as;\n@@ -233,6 +235,7 @@ struct smmu_device {\n \tspinlock_t\tlock;\n \tchar\t\t*name;\n \tstruct device\t*dev;\n+\tstruct rb_root\tclients;\n \tstruct page *avp_vector_page;\t/* dummy page shared by all AS's */\n \n \t/*\n@@ -310,6 +313,95 @@ static inline void smmu_write(struct smmu_device *smmu, u32 val, size_t offs)\n  */\n #define FLUSH_SMMU_REGS(smmu)\tsmmu_read(smmu, SMMU_CONFIG)\n \n+static struct smmu_client *find_smmu_client(struct smmu_device *smmu,\n+\t\t\t\t\t    struct device_node *dev_node)\n+{\n+\tstruct rb_node *node = smmu->clients.rb_node;\n+\n+\twhile (node) {\n+\t\tstruct smmu_client *client;\n+\n+\t\tclient = container_of(node, struct smmu_client, node);\n+\t\tif (dev_node < client->of_node)\n+\t\t\tnode = node->rb_left;\n+\t\telse if (dev_node > client->of_node)\n+\t\t\tnode = node->rb_right;\n+\t\telse\n+\t\t\treturn client;\n+\t}\n+\n+\treturn NULL;\n+}\n+\n+static int insert_smmu_client(struct smmu_device *smmu,\n+\t\t\t      struct smmu_client *client)\n+{\n+\tstruct rb_node **new, *parent;\n+\n+\tnew = &smmu->clients.rb_node;\n+\tparent = NULL;\n+\twhile (*new) {\n+\t\tstruct smmu_client *this;\n+\n+\t\tthis = container_of(*new, struct smmu_client, node);\n+\t\tparent = *new;\n+\t\tif (client->of_node < this->of_node)\n+\t\t\tnew = &((*new)->rb_left);\n+\t\telse if (client->of_node > this->of_node)\n+\t\t\tnew = &((*new)->rb_right);\n+\t\telse\n+\t\t\treturn -EEXIST;\n+\t}\n+\n+\trb_link_node(&client->node, parent, new);\n+\trb_insert_color(&client->node, &smmu->clients);\n+\treturn 0;\n+}\n+\n+static int register_smmu_client(struct smmu_device *smmu,\n+\t\t\t\tstruct device *dev, unsigned long *swgroups)\n+{\n+\tstruct smmu_client *client;\n+\n+\tclient = find_smmu_client(smmu, dev->of_node);\n+\tif (client) {\n+\t\tdev_err(dev,\n+\t\t\t\"rejecting multiple registrations for client device %s\\n\",\n+\t\t\tdev->of_node->full_name);\n+\t\treturn -EBUSY;\n+\t}\n+\n+\tclient = devm_kzalloc(smmu->dev, sizeof(*client), GFP_KERNEL);\n+\tif (!client)\n+\t\treturn -ENOMEM;\n+\n+\tclient->dev = dev;\n+\tclient->of_node = dev->of_node;\n+\tmemcpy(client->hwgrp, swgroups, sizeof(u64));\n+\treturn insert_smmu_client(smmu, client);\n+}\n+\n+static int smmu_of_get_swgroups(struct device *dev, unsigned long *swgroups)\n+{\n+\tstruct of_phandle_iter iter;\n+\n+\tof_property_for_each_phandle_with_args(iter, dev->of_node, \"iommus\",\n+\t\t\t\t\t       \"iommu-cells\", 0) {\n+\t\tif (iter.out_args.np != smmu_handle->iommu.dev->of_node)\n+\t\t\tcontinue;\n+\n+\t\tBUG_ON(iter.out_args.args_count != 2);\n+\n+\t\tmemcpy(swgroups, iter.out_args.args, sizeof(u64));\n+\t\tpr_debug(\"swgroups=%08lx %08lx ops=%p %s\\n\",\n+\t\t\t swgroups[0], swgroups[1],\n+\t\t\t dev->bus->iommu_ops, dev_name(dev));\n+\t\treturn 0;\n+\t}\n+\n+\treturn -ENODEV;\n+}\n+\n static int __smmu_client_set_hwgrp(struct smmu_client *c,\n \t\t\t\t   unsigned long *map, int on)\n {\n@@ -719,21 +811,16 @@ static int smmu_iommu_attach_dev(struct iommu_domain *domain,\n \tstruct smmu_as *as = domain->priv;\n \tstruct smmu_device *smmu = as->smmu;\n \tstruct smmu_client *client, *c;\n-\tunsigned long *map;\n \tint err;\n \n-\tclient = devm_kzalloc(smmu->dev, sizeof(*c), GFP_KERNEL);\n+\tclient = find_smmu_client(smmu, dev->of_node);\n \tif (!client)\n \t\treturn -ENOMEM;\n-\tclient->dev = dev;\n-\tclient->as = as;\n-\tmap = (unsigned long *)dev->platform_data;\n-\tif (!map)\n-\t\treturn -EINVAL;\n \n-\terr = smmu_client_enable_hwgrp(client, map);\n+\tclient->as = as;\n+\terr = smmu_client_enable_hwgrp(client, client->hwgrp);\n \tif (err)\n-\t\tgoto err_hwgrp;\n+\t\treturn -EINVAL;\n \n \tspin_lock(&as->client_lock);\n \tlist_for_each_entry(c, &as->client, list) {\n@@ -751,7 +838,7 @@ static int smmu_iommu_attach_dev(struct iommu_domain *domain,\n \t * Reserve \"page zero\" for AVP vectors using a common dummy\n \t * page.\n \t */\n-\tif (test_bit(TEGRA_SWGROUP_AVPC, map)) {\n+\tif (test_bit(TEGRA_SWGROUP_AVPC, client->hwgrp)) {\n \t\tstruct page *page;\n \n \t\tpage = as->smmu->avp_vector_page;\n@@ -766,8 +853,6 @@ static int smmu_iommu_attach_dev(struct iommu_domain *domain,\n err_client:\n \tsmmu_client_disable_hwgrp(client);\n \tspin_unlock(&as->client_lock);\n-err_hwgrp:\n-\tdevm_kfree(smmu->dev, client);\n \treturn err;\n }\n \n@@ -784,7 +869,6 @@ static void smmu_iommu_detach_dev(struct iommu_domain *domain,\n \t\tif (c->dev == dev) {\n \t\t\tsmmu_client_disable_hwgrp(c);\n \t\t\tlist_del(&c->list);\n-\t\t\tdevm_kfree(smmu->dev, c);\n \t\t\tc->as = NULL;\n \t\t\tdev_dbg(smmu->dev,\n \t\t\t\t\"%s is detached\\n\", dev_name(c->dev));\n@@ -888,10 +972,23 @@ enum {\n \n static int smmu_iommu_bound_driver(struct device *dev)\n {\n-\tint err = -EPROBE_DEFER;\n-\tu32 swgroups = dev->platform_data;\n+\tint err;\n+\tunsigned long swgroups[2];\n \tstruct dma_iommu_mapping *map = NULL;\n \n+\terr = smmu_of_get_swgroups(dev, swgroups);\n+\tif (err)\n+\t\treturn -ENODEV;\n+\n+\tif (!find_smmu_client(smmu_handle, dev->of_node)) {\n+\t\terr = register_smmu_client(smmu_handle, dev, swgroups);\n+\t\tif (err) {\n+\t\t\tdev_err(dev, \"failed to add client %s\\n\",\n+\t\t\t\tdev_name(dev));\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n \tif (test_bit(TEGRA_SWGROUP_PPCS, swgroups))\n \t\tmap = smmu_handle->map[SYSTEM_PROTECTED];\n \telse\n@@ -900,10 +997,10 @@ static int smmu_iommu_bound_driver(struct device *dev)\n \tif (map)\n \t\terr = arm_iommu_attach_device(dev, map);\n \telse\n-\t\treturn -EPROBE_DEFER;\n+\t\treturn -ENODEV;\n \n-\tpr_debug(\"swgroups=%08lx map=%p err=%d %s\\n\",\n-\t\t swgroups, map, err, dev_name(dev));\n+\tpr_debug(\"swgroups=%08lx %08lx map=%p err=%d %s\\n\",\n+\t\t swgroups[0], swgroups[1], map, err, dev_name(dev));\n \treturn err;\n }\n \n@@ -1156,6 +1253,7 @@ static int tegra_smmu_probe(struct platform_device *pdev)\n \t\treturn -ENOMEM;\n \t}\n \n+\tsmmu->clients = RB_ROOT;\n \tsmmu->map = (struct dma_iommu_mapping **)(smmu->as + asids);\n \tsmmu->nregs = pdev->num_resources;\n \tsmmu->regs = devm_kzalloc(dev, 2 * smmu->nregs * sizeof(*smmu->regs),\n",
    "prefixes": [
        "PATCHv8",
        "09/21"
    ]
}