get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

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

{
    "id": 637,
    "url": "http://patchwork.ozlabs.org/api/patches/637/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/1221837088-19539-1-git-send-email-timur@freescale.com/",
    "project": {
        "id": 2,
        "url": "http://patchwork.ozlabs.org/api/projects/2/?format=api",
        "name": "Linux PPC development",
        "link_name": "linuxppc-dev",
        "list_id": "linuxppc-dev.lists.ozlabs.org",
        "list_email": "linuxppc-dev@lists.ozlabs.org",
        "web_url": "https://github.com/linuxppc/wiki/wiki",
        "scm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git",
        "webscm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/",
        "list_archive_url": "https://lore.kernel.org/linuxppc-dev/",
        "list_archive_url_format": "https://lore.kernel.org/linuxppc-dev/{}/",
        "commit_url_format": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?id={}"
    },
    "msgid": "<1221837088-19539-1-git-send-email-timur@freescale.com>",
    "list_archive_url": "https://lore.kernel.org/linuxppc-dev/1221837088-19539-1-git-send-email-timur@freescale.com/",
    "date": "2008-09-19T15:11:28",
    "name": "fsl-dma: allow Freescale Elo DMA driver to be compiled as a module",
    "commit_ref": null,
    "pull_url": null,
    "state": "changes-requested",
    "archived": true,
    "hash": "50baed21ec56c9e0f937677579b98fe9e0a6ee78",
    "submitter": {
        "id": 124,
        "url": "http://patchwork.ozlabs.org/api/people/124/?format=api",
        "name": "Timur Tabi",
        "email": "timur@freescale.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/1221837088-19539-1-git-send-email-timur@freescale.com/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/637/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/637/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org>",
        "X-Original-To": [
            "patchwork-incoming@ozlabs.org",
            "linuxppc-dev@ozlabs.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@ozlabs.org",
            "linuxppc-dev@ozlabs.org"
        ],
        "Received": [
            "from ozlabs.org (localhost [127.0.0.1])\n\tby ozlabs.org (Postfix) with ESMTP id 1F03DDE59E\n\tfor <patchwork-incoming@ozlabs.org>;\n\tSat, 20 Sep 2008 01:11:52 +1000 (EST)",
            "from de01egw01.freescale.net (de01egw01.freescale.net\n\t[192.88.165.102])\n\t(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))\n\t(Client did not present a certificate)\n\tby ozlabs.org (Postfix) with ESMTPS id C140EDE266\n\tfor <linuxppc-dev@ozlabs.org>; Sat, 20 Sep 2008 01:11:37 +1000 (EST)",
            "from de01smr01.freescale.net (de01smr01.freescale.net\n\t[10.208.0.31])\n\tby de01egw01.freescale.net (8.12.11/az33egw01) with ESMTP id\n\tm8JFBTGN020302; Fri, 19 Sep 2008 08:11:30 -0700 (MST)",
            "from localhost.localdomain (ld0169-tx32.am.freescale.net\n\t[10.82.19.119])\n\tby de01smr01.freescale.net (8.13.1/8.13.0) with ESMTP id\n\tm8JFBS30013057; Fri, 19 Sep 2008 10:11:28 -0500 (CDT)"
        ],
        "From": "Timur Tabi <timur@freescale.com>",
        "To": "leoli@freescale.com, zw@zh-kernel.org, linuxppc-dev@ozlabs.org,\n\tlinux-kernel@vger.kernel.org",
        "Subject": "[PATCH] fsl-dma: allow Freescale Elo DMA driver to be compiled as a\n\tmodule",
        "Date": "Fri, 19 Sep 2008 10:11:28 -0500",
        "Message-Id": "<1221837088-19539-1-git-send-email-timur@freescale.com>",
        "X-Mailer": "git-send-email 1.5.5",
        "X-BeenThere": "linuxppc-dev@ozlabs.org",
        "X-Mailman-Version": "2.1.11",
        "Precedence": "list",
        "List-Id": "Linux on PowerPC Developers Mail List <linuxppc-dev.ozlabs.org>",
        "List-Unsubscribe": "<https://ozlabs.org/mailman/options/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@ozlabs.org?subject=unsubscribe>",
        "List-Archive": "<http://ozlabs.org/pipermail/linuxppc-dev>",
        "List-Post": "<mailto:linuxppc-dev@ozlabs.org>",
        "List-Help": "<mailto:linuxppc-dev-request@ozlabs.org?subject=help>",
        "List-Subscribe": "<https://ozlabs.org/mailman/listinfo/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@ozlabs.org?subject=subscribe>",
        "MIME-Version": "1.0",
        "Content-Type": "text/plain; charset=\"us-ascii\"",
        "Content-Transfer-Encoding": "7bit",
        "Sender": "linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org",
        "Errors-To": "linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@ozlabs.org"
    },
    "content": "Modify the Freescale Elo / Elo Plus DMA driver so that it can be compiled as\na module.\n\nThe primary change is to stop treating the DMA controller as a bus, and the\nDMA channels as devices on the bus.  This is because the Open Firmware (OF)\nkernel code does not allow busses to be removed, so although we can call\nof_platform_bus_probe() to probe the DMA channels, there is no\nof_platform_bus_remove().  Therefore, the DMA channels must be manually probed.\n\nSigned-off-by: Timur Tabi <timur@freescale.com>",
    "diff": "diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig\nindex cd30390..9dfd502 100644\n--- a/drivers/dma/Kconfig\n+++ b/drivers/dma/Kconfig\n@@ -48,13 +48,13 @@ config DW_DMAC\n \t  can be integrated in chips such as the Atmel AT32ap7000.\n \n config FSL_DMA\n-\tbool \"Freescale MPC85xx/MPC83xx DMA support\"\n-\tdepends on PPC\n+\ttristate \"Freescale Elo and Elo Plus DMA support\"\n+\tdepends on PPC_83xx || PPC_85xx || PPC_86xx\n \tselect DMA_ENGINE\n \t---help---\n-\t  Enable support for the Freescale DMA engine. Now, it support\n-\t  MPC8560/40, MPC8555, MPC8548 and MPC8641 processors.\n-\t  The MPC8349, MPC8360 is also supported.\n+\t  Enable support for the Freescale Elo and Elo Plus DMA controllers.\n+\t  The Elo is the DMA controller on 83xx parts, and the Elo Plus is\n+\t  the DMA controller on 85xx and 86xx parts.\n \n config MV_XOR\n \tbool \"Marvell XOR engine support\"\ndiff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c\nindex c0059ca..327c485 100644\n--- a/drivers/dma/fsldma.c\n+++ b/drivers/dma/fsldma.c\n@@ -372,6 +372,10 @@ static int fsl_dma_alloc_chan_resources(struct dma_chan *chan,\n \tstruct fsl_dma_chan *fsl_chan = to_fsl_chan(chan);\n \tLIST_HEAD(tmp_list);\n \n+\t/* Has this channel already been allocated? */\n+\tif (fsl_chan->desc_pool)\n+\t\treturn 1;\n+\n \t/* We need the descriptor to be aligned to 32bytes\n \t * for meeting FSL DMA specification requirement.\n \t */\n@@ -381,7 +385,7 @@ static int fsl_dma_alloc_chan_resources(struct dma_chan *chan,\n \tif (!fsl_chan->desc_pool) {\n \t\tdev_err(fsl_chan->dev, \"No memory for channel %d \"\n \t\t\t\"descriptor dma pool.\\n\", fsl_chan->id);\n-\t\treturn 0;\n+\t\treturn -ENOMEM;\n \t}\n \n \treturn 1;\n@@ -410,6 +414,8 @@ static void fsl_dma_free_chan_resources(struct dma_chan *chan)\n \t}\n \tspin_unlock_irqrestore(&fsl_chan->desc_lock, flags);\n \tdma_pool_destroy(fsl_chan->desc_pool);\n+\n+\tfsl_chan->desc_pool = NULL;\n }\n \n static struct dma_async_tx_descriptor *\n@@ -912,33 +918,37 @@ out:\n \treturn err;\n }\n \n-static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,\n-\t\t\tconst struct of_device_id *match)\n+static int __devinit fsl_dma_chan_probe(struct fsl_dma_device *fdev,\n+\tstruct device_node *node, u32 feature, const char *compatible)\n {\n-\tstruct fsl_dma_device *fdev;\n \tstruct fsl_dma_chan *new_fsl_chan;\n+\tconst u32 *iprop;\n \tint err;\n \n-\tfdev = dev_get_drvdata(dev->dev.parent);\n-\tBUG_ON(!fdev);\n-\n \t/* alloc channel */\n \tnew_fsl_chan = kzalloc(sizeof(struct fsl_dma_chan), GFP_KERNEL);\n \tif (!new_fsl_chan) {\n-\t\tdev_err(&dev->dev, \"No free memory for allocating \"\n+\t\tdev_err(fdev->dev, \"No free memory for allocating \"\n \t\t\t\t\"dma channels!\\n\");\n \t\treturn -ENOMEM;\n \t}\n \n+\tnew_fsl_chan->of_dev = of_platform_device_create(node, NULL, fdev->dev);\n+\tif (!new_fsl_chan->of_dev) {\n+\t\tdev_err(fdev->dev, \"cannot create platform device\\n\");\n+\t\terr = -EINVAL;\n+\t\tgoto err_no_dev;\n+\t}\n+\n \t/* get dma channel register base */\n-\terr = of_address_to_resource(dev->node, 0, &new_fsl_chan->reg);\n+\terr = of_address_to_resource(node, 0, &new_fsl_chan->reg);\n \tif (err) {\n-\t\tdev_err(&dev->dev, \"Can't get %s property 'reg'\\n\",\n-\t\t\t\tdev->node->full_name);\n+\t\tdev_err(fdev->dev, \"Can't get %s property 'reg'\\n\",\n+\t\t\t\tnode->full_name);\n \t\tgoto err_no_reg;\n \t}\n \n-\tnew_fsl_chan->feature = *(u32 *)match->data;\n+\tnew_fsl_chan->feature = feature;\n \n \tif (!fdev->feature)\n \t\tfdev->feature = new_fsl_chan->feature;\n@@ -948,17 +958,22 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,\n \t */\n \tWARN_ON(fdev->feature != new_fsl_chan->feature);\n \n-\tnew_fsl_chan->dev = &dev->dev;\n+\tnew_fsl_chan->dev = &new_fsl_chan->of_dev->dev;\n \tnew_fsl_chan->reg_base = ioremap(new_fsl_chan->reg.start,\n \t\t\tnew_fsl_chan->reg.end - new_fsl_chan->reg.start + 1);\n \n-\tnew_fsl_chan->id = ((new_fsl_chan->reg.start - 0x100) & 0xfff) >> 7;\n-\tif (new_fsl_chan->id > FSL_DMA_MAX_CHANS_PER_DEVICE) {\n-\t\tdev_err(&dev->dev, \"There is no %d channel!\\n\",\n-\t\t\t\tnew_fsl_chan->id);\n+\tiprop = of_get_property(node, \"cell-index\", NULL);\n+\tif (!iprop) {\n+\t\tdev_err(fdev->dev, \"missing cell-index property\\n\");\n+\t\treturn -EINVAL;\n+\t}\n+\tif (*iprop >= FSL_DMA_MAX_CHANS_PER_DEVICE) {\n+\t\tdev_err(fdev->dev, \"invalid cell-index value %u\\n\", *iprop);\n \t\terr = -EINVAL;\n \t\tgoto err_no_chan;\n \t}\n+\tnew_fsl_chan->id = *iprop;\n+\n \tfdev->chan[new_fsl_chan->id] = new_fsl_chan;\n \ttasklet_init(&new_fsl_chan->tasklet, dma_do_tasklet,\n \t\t\t(unsigned long)new_fsl_chan);\n@@ -988,14 +1003,14 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,\n \t\t\t&fdev->common.channels);\n \tfdev->common.chancnt++;\n \n-\tnew_fsl_chan->irq = irq_of_parse_and_map(dev->node, 0);\n+\tnew_fsl_chan->irq = irq_of_parse_and_map(node, 0);\n \tif (new_fsl_chan->irq != NO_IRQ) {\n \t\terr = request_irq(new_fsl_chan->irq,\n \t\t\t\t\t&fsl_dma_chan_do_interrupt, IRQF_SHARED,\n \t\t\t\t\t\"fsldma-channel\", new_fsl_chan);\n \t\tif (err) {\n-\t\t\tdev_err(&dev->dev, \"DMA channel %s request_irq error \"\n-\t\t\t\t\"with return %d\\n\", dev->node->full_name, err);\n+\t\t\tdev_err(fdev->dev, \"DMA channel %s request_irq error \"\n+\t\t\t\t\"with return %d\\n\", node->full_name, err);\n \t\t\tgoto err_no_irq;\n \t\t}\n \t}\n@@ -1004,8 +1019,8 @@ static int __devinit of_fsl_dma_chan_probe(struct of_device *dev,\n \tif (err)\n \t\tgoto err_self_test;\n \n-\tdev_info(&dev->dev, \"#%d (%s), irq %d\\n\", new_fsl_chan->id,\n-\t\t\t\tmatch->compatible, new_fsl_chan->irq);\n+\tdev_info(fdev->dev, \"#%d (%s), irq %d\\n\", new_fsl_chan->id,\n+\t\t\t\tcompatible, new_fsl_chan->irq);\n \n \treturn 0;\n \n@@ -1016,42 +1031,30 @@ err_no_irq:\n err_no_chan:\n \tiounmap(new_fsl_chan->reg_base);\n err_no_reg:\n+\tof_device_unregister(new_fsl_chan->of_dev);\n+err_no_dev:\n \tkfree(new_fsl_chan);\n \treturn err;\n }\n \n-const u32 mpc8540_dma_ip_feature = FSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN;\n-const u32 mpc8349_dma_ip_feature = FSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN;\n-\n-static struct of_device_id of_fsl_dma_chan_ids[] = {\n-\t{\n-\t\t.compatible = \"fsl,eloplus-dma-channel\",\n-\t\t.data = (void *)&mpc8540_dma_ip_feature,\n-\t},\n-\t{\n-\t\t.compatible = \"fsl,elo-dma-channel\",\n-\t\t.data = (void *)&mpc8349_dma_ip_feature,\n-\t},\n-\t{}\n-};\n-\n-static struct of_platform_driver of_fsl_dma_chan_driver = {\n-\t.name = \"of-fsl-dma-channel\",\n-\t.match_table = of_fsl_dma_chan_ids,\n-\t.probe = of_fsl_dma_chan_probe,\n-};\n-\n-static __init int of_fsl_dma_chan_init(void)\n+static void fsl_dma_chan_remove(struct fsl_dma_chan *fchan)\n {\n-\treturn of_register_platform_driver(&of_fsl_dma_chan_driver);\n+\tif (fchan) {\n+\t\tof_device_unregister(fchan->of_dev);\n+\n+\t\tfree_irq(fchan->irq, fchan);\n+\t\tlist_del(&fchan->common.device_node);\n+\t\tiounmap(fchan->reg_base);\n+\t\tkfree(fchan);\n+\t}\n }\n \n static int __devinit of_fsl_dma_probe(struct of_device *dev,\n \t\t\tconst struct of_device_id *match)\n {\n \tint err;\n-\tunsigned int irq;\n \tstruct fsl_dma_device *fdev;\n+\tstruct device_node *child;\n \n \tfdev = kzalloc(sizeof(struct fsl_dma_device), GFP_KERNEL);\n \tif (!fdev) {\n@@ -1085,9 +1088,9 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev,\n \tfdev->common.device_issue_pending = fsl_dma_memcpy_issue_pending;\n \tfdev->common.dev = &dev->dev;\n \n-\tirq = irq_of_parse_and_map(dev->node, 0);\n-\tif (irq != NO_IRQ) {\n-\t\terr = request_irq(irq, &fsl_dma_do_interrupt, IRQF_SHARED,\n+\tfdev->irq = irq_of_parse_and_map(dev->node, 0);\n+\tif (fdev->irq != NO_IRQ) {\n+\t\terr = request_irq(fdev->irq, &fsl_dma_do_interrupt, IRQF_SHARED,\n \t\t\t\t\t\"fsldma-device\", fdev);\n \t\tif (err) {\n \t\t\tdev_err(&dev->dev, \"DMA device request_irq error \"\n@@ -1097,7 +1100,21 @@ static int __devinit of_fsl_dma_probe(struct of_device *dev,\n \t}\n \n \tdev_set_drvdata(&(dev->dev), fdev);\n-\tof_platform_bus_probe(dev->node, of_fsl_dma_chan_ids, &dev->dev);\n+\n+\t/* We cannot use of_platform_bus_probe() because there is no\n+\t * of_platform_bus_remove.  We have to manually instantiate every DMA\n+\t * channel object.\n+\t */\n+\tfor_each_child_of_node(dev->node, child) {\n+\t\tif (of_device_is_compatible(child, \"fsl,eloplus-dma-channel\"))\n+\t\t\tfsl_dma_chan_probe(fdev, child,\n+\t\t\t\tFSL_DMA_IP_85XX | FSL_DMA_BIG_ENDIAN,\n+\t\t\t\t\"fsl,eloplus-dma-channel\");\n+\t\tif (of_device_is_compatible(child, \"fsl,elo-dma-channel\"))\n+\t\t\tfsl_dma_chan_probe(fdev, child,\n+\t\t\t\tFSL_DMA_IP_83XX | FSL_DMA_LITTLE_ENDIAN,\n+\t\t\t\t\"fsl,elo-dma-channel\");\n+\t}\n \n \tdma_async_device_register(&fdev->common);\n \treturn 0;\n@@ -1109,6 +1126,31 @@ err_no_reg:\n \treturn err;\n }\n \n+static int of_fsl_dma_remove(struct of_device *of_dev)\n+{\n+\tstruct fsl_dma_device *fdev;\n+\tunsigned int i;\n+\n+\tfdev = dev_get_drvdata(&of_dev->dev);\n+\n+\tdma_async_device_unregister(&fdev->common);\n+\n+\tfor (i = 0; i < FSL_DMA_MAX_CHANS_PER_DEVICE; i++) {\n+\t\tfsl_dma_chan_remove(fdev->chan[i]);\n+\t\tfdev->chan[i] = NULL;\n+\t}\n+\n+\tif (fdev->irq != NO_IRQ)\n+\t\tfree_irq(fdev->irq, fdev);\n+\n+\tiounmap(fdev->reg_base);\n+\n+\tkfree(fdev);\n+\tdev_set_drvdata(&of_dev->dev, NULL);\n+\n+\treturn 0;\n+}\n+\n static struct of_device_id of_fsl_dma_ids[] = {\n \t{ .compatible = \"fsl,eloplus-dma\", },\n \t{ .compatible = \"fsl,elo-dma\", },\n@@ -1116,15 +1158,32 @@ static struct of_device_id of_fsl_dma_ids[] = {\n };\n \n static struct of_platform_driver of_fsl_dma_driver = {\n-\t.name = \"of-fsl-dma\",\n+\t.name = \"fsl-elo-dma\",\n \t.match_table = of_fsl_dma_ids,\n \t.probe = of_fsl_dma_probe,\n+\t.remove = of_fsl_dma_remove,\n };\n \n static __init int of_fsl_dma_init(void)\n {\n-\treturn of_register_platform_driver(&of_fsl_dma_driver);\n+\tint ret;\n+\n+\tpr_info(\"Freescale Elo / Elo Plus DMA driver\\n\");\n+\n+\tret = of_register_platform_driver(&of_fsl_dma_driver);\n+\tif (ret)\n+\t\tpr_err(\"fsldma: failed to register platform driver\\n\");\n+\n+\treturn ret;\n+}\n+\n+static void __exit of_fsl_dma_exit(void)\n+{\n+\tof_unregister_platform_driver(&of_fsl_dma_driver);\n }\n \n-subsys_initcall(of_fsl_dma_chan_init);\n subsys_initcall(of_fsl_dma_init);\n+module_exit(of_fsl_dma_exit);\n+\n+MODULE_DESCRIPTION(\"Freescale Elo / Elo Plus DMA driver\");\n+MODULE_LICENSE(\"GPL\");\ndiff --git a/drivers/dma/fsldma.h b/drivers/dma/fsldma.h\nindex 6faf07b..e0902dd 100644\n--- a/drivers/dma/fsldma.h\n+++ b/drivers/dma/fsldma.h\n@@ -114,6 +114,7 @@ struct fsl_dma_device {\n \tstruct dma_device common;\n \tstruct fsl_dma_chan *chan[FSL_DMA_MAX_CHANS_PER_DEVICE];\n \tu32 feature;\t\t/* The same as DMA channels */\n+\tint irq;\t\t/* Channel IRQ */\n };\n \n /* Define macros for fsl_dma_chan->feature property */\n@@ -135,6 +136,7 @@ struct fsl_dma_chan {\n \tstruct dma_chan common;\t\t/* DMA common channel */\n \tstruct dma_pool *desc_pool;\t/* Descriptors pool */\n \tstruct device *dev;\t\t/* Channel device */\n+\tstruct of_device *of_dev;\t/* OF device */\n \tstruct resource reg;\t\t/* Resource for register */\n \tint irq;\t\t\t/* Channel IRQ */\n \tint id;\t\t\t\t/* Raw id of this channel */\n",
    "prefixes": []
}