get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 811077,
    "url": "http://patchwork.ozlabs.org/api/patches/811077/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/patch/1504798409-32041-2-git-send-email-timur@codeaurora.org/",
    "project": {
        "id": 42,
        "url": "http://patchwork.ozlabs.org/api/projects/42/?format=api",
        "name": "Linux GPIO development",
        "link_name": "linux-gpio",
        "list_id": "linux-gpio.vger.kernel.org",
        "list_email": "linux-gpio@vger.kernel.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<1504798409-32041-2-git-send-email-timur@codeaurora.org>",
    "list_archive_url": null,
    "date": "2017-09-07T15:33:28",
    "name": "[1/2,v5] pinctrl: qcom: disable GPIO groups with no pins",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "89d432c4501d58c27b8c4421e7856d94d308d923",
    "submitter": {
        "id": 66858,
        "url": "http://patchwork.ozlabs.org/api/people/66858/?format=api",
        "name": "Timur Tabi",
        "email": "timur@codeaurora.org"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linux-gpio/patch/1504798409-32041-2-git-send-email-timur@codeaurora.org/mbox/",
    "series": [
        {
            "id": 2018,
            "url": "http://patchwork.ozlabs.org/api/series/2018/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/linux-gpio/list/?series=2018",
            "date": "2017-09-07T15:33:27",
            "name": "pinctrl: qcom: add support for sparse GPIOs",
            "version": 5,
            "mbox": "http://patchwork.ozlabs.org/series/2018/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/811077/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/811077/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<linux-gpio-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-gpio-owner@vger.kernel.org;\n\treceiver=<UNKNOWN>)",
            "ozlabs.org;\n\tdkim=fail reason=\"signature verification failed\" (1024-bit key;\n\tunprotected) header.d=codeaurora.org header.i=@codeaurora.org\n\theader.b=\"kNlpOMFd\"; \n\tdkim=fail reason=\"signature verification failed\" (1024-bit key)\n\theader.d=codeaurora.org header.i=@codeaurora.org\n\theader.b=\"L9VYmaDT\"; dkim-atps=neutral",
            "pdx-caf-mail.web.codeaurora.org;\n\tdmarc=none (p=none dis=none)\n\theader.from=codeaurora.org",
            "pdx-caf-mail.web.codeaurora.org;\n\tspf=none smtp.mailfrom=timur@codeaurora.org"
        ],
        "Received": [
            "from vger.kernel.org (vger.kernel.org [209.132.180.67])\n\tby ozlabs.org (Postfix) with ESMTP id 3xp4HR3TS6z9t2r\n\tfor <incoming@patchwork.ozlabs.org>;\n\tFri,  8 Sep 2017 01:33:55 +1000 (AEST)",
            "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n\tid S1754514AbdIGPdy (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);\n\tThu, 7 Sep 2017 11:33:54 -0400",
            "from smtp.codeaurora.org ([198.145.29.96]:47490 \"EHLO\n\tsmtp.codeaurora.org\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n\twith ESMTP id S1754858AbdIGPdx (ORCPT\n\t<rfc822; linux-gpio@vger.kernel.org>); Thu, 7 Sep 2017 11:33:53 -0400",
            "by smtp.codeaurora.org (Postfix, from userid 1000)\n\tid 0A848611A5; Thu,  7 Sep 2017 15:33:51 +0000 (UTC)",
            "from timur-ubuntu.qualcomm.com (i-global254.qualcomm.com\n\t[199.106.103.254])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits))\n\t(No client certificate requested)\n\t(Authenticated sender: timur@smtp.codeaurora.org)\n\tby smtp.codeaurora.org (Postfix) with ESMTPSA id 1A97560CA5;\n\tThu,  7 Sep 2017 15:33:48 +0000 (UTC)"
        ],
        "DKIM-Signature": [
            "v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org;\n\ts=default; t=1504798433;\n\tbh=oesfOqOwzo6xKcvVlcYc2Bf4qD/Q0M4gqAf6sA4aErw=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=kNlpOMFdVDotUiI1wrSEJmJFgTlBW0OfegbSRAcFmyvplOmMLePnoPWBYv52NBfW6\n\t/TWBpv3tCMC3JOB1iGYPi9Yi6tXkO5HokOFN6+qdT52XOcvZuhy67U3tRwaW58MBWB\n\txjBSouKKuM7BNQF1SO8QPOZJXFd0TLeKLQ5AFdP8=",
            "v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org;\n\ts=default; t=1504798429;\n\tbh=oesfOqOwzo6xKcvVlcYc2Bf4qD/Q0M4gqAf6sA4aErw=;\n\th=From:To:Cc:Subject:Date:In-Reply-To:References:From;\n\tb=L9VYmaDTnxV6PlYXYk/pcbCwZwUfhVpEdUjPW380jK7pVOb2Hcbb8/AUQK1M6QaEK\n\t4caZABpt59UyRfrDHC8pNHoO7mjrdg1Or8gWKJjRxGWWFneDnrv5I3MlHb7w02aEEx\n\t45yQ/Z4nFRjmxku82Zuakse5TswrG2rYkck/JiCE="
        ],
        "X-Spam-Checker-Version": "SpamAssassin 3.4.0 (2014-02-07) on\n\tpdx-caf-mail.web.codeaurora.org",
        "X-Spam-Level": "",
        "X-Spam-Status": "No, score=-2.8 required=2.0 tests=ALL_TRUSTED,BAYES_00,\n\tDKIM_SIGNED,\n\tT_DKIM_INVALID autolearn=no autolearn_force=no version=3.4.0",
        "DMARC-Filter": "OpenDMARC Filter v1.3.2 smtp.codeaurora.org 1A97560CA5",
        "From": "Timur Tabi <timur@codeaurora.org>",
        "To": "Linus Walleij <linus.walleij@linaro.org>, andy.gross@linaro.org,\n\tdavid.brown@linaro.org, anjiandi@codeaurora.org,\n\tBjorn Andersson <bjorn.andersson@linaro.org>,\n\tlinux-gpio@vger.kernel.org, linux-arm-kernel@lists.infradead.org,\n\tlinux-arm-msm@vger.kernel.org",
        "Cc": "timur@codeaurora.org",
        "Subject": "[PATCH 1/2] [v5] pinctrl: qcom: disable GPIO groups with no pins",
        "Date": "Thu,  7 Sep 2017 10:33:28 -0500",
        "Message-Id": "<1504798409-32041-2-git-send-email-timur@codeaurora.org>",
        "X-Mailer": "git-send-email 1.9.1",
        "In-Reply-To": "<1504798409-32041-1-git-send-email-timur@codeaurora.org>",
        "References": "<1504798409-32041-1-git-send-email-timur@codeaurora.org>",
        "Sender": "linux-gpio-owner@vger.kernel.org",
        "Precedence": "bulk",
        "List-ID": "<linux-gpio.vger.kernel.org>",
        "X-Mailing-List": "linux-gpio@vger.kernel.org"
    },
    "content": "pinctrl-msm only accepts an array of GPIOs from 0 to n-1, and it expects\neach group to support have only one pin (npins == 1).\n\nWe can support \"sparse\" GPIO maps if we allow for some groups to have zero\npins (npins == 0).  These pins are \"hidden\" from the rest of the driver\nand gpiolib.\n\nA new boolean 'sparse' indicates whether the GPIO map is sparse.  If any\nGPIO has an 'npins' value of 0, then 'sparse' must be set to True.\n\nMost access to unavailable GPIOs can be blocked via the gpio_chip.request\nfunction.  The one exception is when gpiochip_add_data() scans all of\nthe GPIOs without \"requesting\" them.  To cover this case,\nmsm_gpio_get_direction() separately checks if the GPIO is available.\n\nSigned-off-by: Timur Tabi <timur@codeaurora.org>\n---\n drivers/pinctrl/qcom/pinctrl-msm.c | 110 +++++++++++++++++++++++++++++++++++--\n drivers/pinctrl/qcom/pinctrl-msm.h |   2 +\n 2 files changed, 106 insertions(+), 6 deletions(-)",
    "diff": "diff --git a/drivers/pinctrl/qcom/pinctrl-msm.c b/drivers/pinctrl/qcom/pinctrl-msm.c\nindex ff491da64dab..ca4ae3d76eb4 100644\n--- a/drivers/pinctrl/qcom/pinctrl-msm.c\n+++ b/drivers/pinctrl/qcom/pinctrl-msm.c\n@@ -443,6 +443,14 @@ static int msm_gpio_get_direction(struct gpio_chip *chip, unsigned int offset)\n \n \tg = &pctrl->soc->groups[offset];\n \n+\t/*\n+\t * During initialization, gpiolib may query all GPIOs for their\n+\t * initial direction, regardless if they exist, so block access\n+\t * to those that are unavailable.\n+\t */\n+\tif (!g->npins)\n+\t\treturn -ENODEV;\n+\n \tval = readl(pctrl->regs + g->ctl_reg);\n \n \t/* 0 = output, 1 = input */\n@@ -507,6 +515,11 @@ static void msm_gpio_dbg_show_one(struct seq_file *s,\n \t};\n \n \tg = &pctrl->soc->groups[offset];\n+\n+\t/* If the GPIO group has no pins, then don't show it. */\n+\tif (!g->npins)\n+\t\treturn;\n+\n \tctl_reg = readl(pctrl->regs + g->ctl_reg);\n \n \tis_out = !!(ctl_reg & BIT(g->oe_bit));\n@@ -516,7 +529,7 @@ static void msm_gpio_dbg_show_one(struct seq_file *s,\n \n \tseq_printf(s, \" %-8s: %-3s %d\", g->name, is_out ? \"out\" : \"in\", func);\n \tseq_printf(s, \" %dmA\", msm_regval_to_drive(drive));\n-\tseq_printf(s, \" %s\", pulls[pull]);\n+\tseq_printf(s, \" %s\\n\", pulls[pull]);\n }\n \n static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)\n@@ -524,23 +537,36 @@ static void msm_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip)\n \tunsigned gpio = chip->base;\n \tunsigned i;\n \n-\tfor (i = 0; i < chip->ngpio; i++, gpio++) {\n+\tfor (i = 0; i < chip->ngpio; i++, gpio++)\n \t\tmsm_gpio_dbg_show_one(s, NULL, chip, i, gpio);\n-\t\tseq_puts(s, \"\\n\");\n-\t}\n }\n \n #else\n #define msm_gpio_dbg_show NULL\n #endif\n \n+/*\n+ * If the requested GPIO has no pins, then treat it as unavailable.\n+ * Otherwise, call the standard request function.\n+ */\n+static int msm_gpio_request(struct gpio_chip *chip, unsigned int offset)\n+{\n+\tstruct msm_pinctrl *pctrl = gpiochip_get_data(chip);\n+\tconst struct msm_pingroup *g = &pctrl->soc->groups[offset];\n+\n+\tif (!g->npins)\n+\t\treturn -ENODEV;\n+\n+\treturn gpiochip_generic_request(chip, offset);\n+}\n+\n static const struct gpio_chip msm_gpio_template = {\n \t.direction_input  = msm_gpio_direction_input,\n \t.direction_output = msm_gpio_direction_output,\n \t.get_direction    = msm_gpio_get_direction,\n \t.get              = msm_gpio_get,\n \t.set              = msm_gpio_set,\n-\t.request          = gpiochip_generic_request,\n+\t.request          = msm_gpio_request,\n \t.free             = gpiochip_generic_free,\n \t.dbg_show         = msm_gpio_dbg_show,\n };\n@@ -808,11 +834,57 @@ static void msm_gpio_irq_handler(struct irq_desc *desc)\n \tchained_irq_exit(chip, desc);\n }\n \n+/**\n+ * msm_gpio_get_next_range() - find next range of consecutive gpios\n+ * @pctrl: msm_pinctrl object\n+ * @pstart: pointer to index of next starting position\n+ *\n+ * In a sparse GPIO map, available GPIOs are typically collected into blocks.\n+ * Given a starting index into the groups[] array, this function will scan all\n+ * the gpios until it finds the next block of available GPIOs.\n+ *\n+ * If groups[*pstart] already points to an available GPIO, then assume that\n+ * it is the start of a block.\n+ *\n+ * The caller is responsible for moving *pstart to after the end of the\n+ * previous block so that it this function can find the next block.\n+ *\n+ * Return: The count of the block starting at @pstart, or 0 if there are no\n+ *         more blocks.\n+ */\n+static unsigned int msm_gpio_get_next_range(struct msm_pinctrl *pctrl,\n+\t\t\t\t\t    unsigned int *pstart)\n+{\n+\tconst struct msm_pingroup *groups = pctrl->soc->groups;\n+\tunsigned int ngpio = pctrl->soc->ngpios;\n+\tunsigned int count = 0;\n+\tunsigned int start = *pstart;\n+\n+\t/* Find the first available GPIO */\n+\twhile (!groups[start].npins)\n+\t\tif (++start == ngpio)\n+\t\t\t/* None found, so just exit */\n+\t\t\treturn 0;\n+\n+\t*pstart = start;\n+\n+\t/* Count the number of those GPIOs in a row */\n+\twhile (groups[start].npins) {\n+\t\tcount++;\n+\t\tif (++start == ngpio)\n+\t\t\tbreak;\n+\t}\n+\n+\treturn count;\n+}\n+\n static int msm_gpio_init(struct msm_pinctrl *pctrl)\n {\n \tstruct gpio_chip *chip;\n \tint ret;\n \tunsigned ngpio = pctrl->soc->ngpios;\n+\tconst struct msm_pingroup *groups = pctrl->soc->groups;\n+\tunsigned int i, start = 0, count;\n \n \tif (WARN_ON(ngpio > MAX_NR_GPIO))\n \t\treturn -EINVAL;\n@@ -825,13 +897,39 @@ static int msm_gpio_init(struct msm_pinctrl *pctrl)\n \tchip->owner = THIS_MODULE;\n \tchip->of_node = pctrl->dev->of_node;\n \n+\t/* If the GPIO map is sparse, then we need to disable specific IRQs */\n+\tchip->irq_need_valid_mask = pctrl->soc->sparse;\n+\n \tret = gpiochip_add_data(&pctrl->chip, pctrl);\n \tif (ret) {\n \t\tdev_err(pctrl->dev, \"Failed register gpiochip\\n\");\n \t\treturn ret;\n \t}\n \n-\tret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev), 0, 0, chip->ngpio);\n+\t/*\n+\t * If irq_need_valid_mask is true, then gpiochip_add_data() will\n+\t * initialize irq_valid_mask to all 1s.  We need to clear all the\n+\t * GPIOs that are unavailable, and we need to find each block\n+\t * of consecutive available GPIOs are add them as pin ranges.\n+\t */\n+\tif (chip->irq_need_valid_mask) {\n+\t\tfor (i = 0; i < ngpio; i++)\n+\t\t\tif (!groups[i].npins)\n+\t\t\t\tclear_bit(i, pctrl->chip.irq_valid_mask);\n+\n+\t\twhile ((count = msm_gpio_get_next_range(pctrl, &start))) {\n+\t\t\tret = gpiochip_add_pin_range(&pctrl->chip,\n+\t\t\t\t\t\t     dev_name(pctrl->dev),\n+\t\t\t\t\t\t     start, start, count);\n+\t\t\tif (ret)\n+\t\t\t\tbreak;\n+\t\t\tstart += count;\n+\t\t}\n+\t} else {\n+\t\tret = gpiochip_add_pin_range(&pctrl->chip, dev_name(pctrl->dev),\n+\t\t\t\t\t     0, 0, ngpio);\n+\t}\n+\n \tif (ret) {\n \t\tdev_err(pctrl->dev, \"Failed to add pin range\\n\");\n \t\tgpiochip_remove(&pctrl->chip);\ndiff --git a/drivers/pinctrl/qcom/pinctrl-msm.h b/drivers/pinctrl/qcom/pinctrl-msm.h\nindex 9b9feea540ff..70762bcb84cb 100644\n--- a/drivers/pinctrl/qcom/pinctrl-msm.h\n+++ b/drivers/pinctrl/qcom/pinctrl-msm.h\n@@ -107,6 +107,7 @@ struct msm_pingroup {\n  * @ngroups:\t    The numbmer of entries in @groups.\n  * @ngpio:\t    The number of pingroups the driver should expose as GPIOs.\n  * @pull_no_keeper: The SoC does not support keeper bias.\n+ * @sparse:         The GPIO map is sparse (some GPIOs have npins == 0)\n  */\n struct msm_pinctrl_soc_data {\n \tconst struct pinctrl_pin_desc *pins;\n@@ -117,6 +118,7 @@ struct msm_pinctrl_soc_data {\n \tunsigned ngroups;\n \tunsigned ngpios;\n \tbool pull_no_keeper;\n+\tbool sparse;\n };\n \n int msm_pinctrl_probe(struct platform_device *pdev,\n",
    "prefixes": [
        "1/2",
        "v5"
    ]
}