From patchwork Thu Jun 20 21:06:38 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Fernandes, Joel A" X-Patchwork-Id: 2758711 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id D197A9F39E for ; Thu, 20 Jun 2013 21:24:40 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B17A7202F0 for ; Thu, 20 Jun 2013 21:24:39 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 69787202EC for ; Thu, 20 Jun 2013 21:24:38 +0000 (UTC) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Upm8N-0001a7-8G; Thu, 20 Jun 2013 21:11:15 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1Upm6b-0001jA-Mq; Thu, 20 Jun 2013 21:09:21 +0000 Received: from bear.ext.ti.com ([192.94.94.41]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1Upm4z-0001YD-Eb for linux-arm-kernel@lists.infradead.org; Thu, 20 Jun 2013 21:07:50 +0000 Received: from dlelxv90.itg.ti.com ([172.17.2.17]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id r5KL6vUf016019; Thu, 20 Jun 2013 16:06:57 -0500 Received: from DFLE72.ent.ti.com (dfle72.ent.ti.com [128.247.5.109]) by dlelxv90.itg.ti.com (8.14.3/8.13.8) with ESMTP id r5KL6vjb010682; Thu, 20 Jun 2013 16:06:57 -0500 Received: from dlelxv22.itg.ti.com (172.17.1.197) by DFLE72.ent.ti.com (128.247.5.109) with Microsoft SMTP Server id 14.2.342.3; Thu, 20 Jun 2013 16:06:57 -0500 Received: from localhost.localdomain (lta0273324.am.dhcp.ti.com [128.247.106.216]) by dlelxv22.itg.ti.com (8.13.8/8.13.8) with ESMTP id r5KL6luN008775; Thu, 20 Jun 2013 16:06:57 -0500 From: Joel A Fernandes To: Tony Lindgren , Sekhar Nori , Matt Porter , Grant Likely , Rob Herring , Vinod Koul , Mark Brown , Benoit Cousson , Russell King , Rob Landley , Andrew Morton , Jason Kridner , Koen Kooi Subject: [PATCH v12 02/11] ARM: edma: Add DT and runtime PM support to the private EDMA API Date: Thu, 20 Jun 2013 16:06:38 -0500 Message-ID: <1371762407-24544-3-git-send-email-joelagnel@ti.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1371762407-24544-1-git-send-email-joelagnel@ti.com> References: <1371762407-24544-1-git-send-email-joelagnel@ti.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130620_170742_192496_AA19F368 X-CRM114-Status: GOOD ( 23.72 ) X-Spam-Score: -8.2 (--------) Cc: Joel A Fernandes , Linux DaVinci Kernel List , Arnd Bergmann , Linux Documentation List , Devicetree Discuss , Linux MMC List , Linux Kernel Mailing List , Linux SPI Devel List , Linux OMAP List , Linux ARM Kernel List X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-5.5 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Matt Porter Adds support for parsing the TI EDMA DT data into the required EDMA private API platform data. Enables runtime PM support to initialize the EDMA hwmod. Enables build on OMAP. Changes by Joel: * Setup default one-to-one mapping for queue_priority and queue_tc mapping as discussed in [1]. * Split out xbar stuff to separate patch. [1] * Dropped unused DT helper to convert to array [1] https://patchwork.kernel.org/patch/2226761/ Signed-off-by: Matt Porter Acked-by: Sekhar Nori Signed-off-by: Joel A Fernandes --- arch/arm/common/edma.c | 180 +++++++++++++++++++++++++++++++++--- include/linux/platform_data/edma.h | 4 +- 2 files changed, 169 insertions(+), 15 deletions(-) diff --git a/arch/arm/common/edma.c b/arch/arm/common/edma.c index 7658874..407e01e 100644 --- a/arch/arm/common/edma.c +++ b/arch/arm/common/edma.c @@ -25,6 +25,13 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include #include @@ -1369,13 +1376,102 @@ void edma_clear_event(unsigned channel) } EXPORT_SYMBOL(edma_clear_event); -/*-----------------------------------------------------------------------*/ +static int edma_of_read_u32_to_s16_array(const struct device_node *np, + const char *propname, s16 *out_values, + size_t sz) +{ + int ret; + + ret = of_property_read_u16_array(np, propname, out_values, sz); + if (ret) + return ret; + + /* Terminate it */ + *out_values++ = -1; + *out_values++ = -1; + + return 0; +} + +static int edma_of_parse_dt(struct device *dev, + struct device_node *node, + struct edma_soc_info *pdata) +{ + int ret = 0, i; + u32 value; + struct property *prop; + size_t sz; + struct edma_rsv_info *rsv_info; + s8 (*queue_tc_map)[2], (*queue_priority_map)[2]; + + memset(pdata, 0, sizeof(struct edma_soc_info)); + + ret = of_property_read_u32(node, "dma-channels", &value); + if (ret < 0) + return ret; + pdata->n_channel = value; + + ret = of_property_read_u32(node, "ti,edma-regions", &value); + if (ret < 0) + return ret; + pdata->n_region = value; + + ret = of_property_read_u32(node, "ti,edma-slots", &value); + if (ret < 0) + return ret; + pdata->n_slot = value; + + pdata->n_cc = 1; + pdata->n_tc = 3; + + rsv_info = + devm_kzalloc(dev, sizeof(struct edma_rsv_info), GFP_KERNEL); + if (!rsv_info) + return -ENOMEM; + pdata->rsv = rsv_info; + + queue_tc_map = devm_kzalloc(dev, 8*sizeof(s8), GFP_KERNEL); + if (!queue_tc_map) + return -ENOMEM; + + for (i = 0; i < 3; i++) { + queue_tc_map[i][0] = i; + queue_tc_map[i][1] = i; + } + queue_tc_map[i][0] = -1; + queue_tc_map[i][1] = -1; + + pdata->queue_tc_mapping = queue_tc_map; + + queue_priority_map = devm_kzalloc(dev, 8*sizeof(s8), GFP_KERNEL); + if (!queue_priority_map) + return -ENOMEM; + + for (i = 0; i < 3; i++) { + queue_priority_map[i][0] = i; + queue_priority_map[i][1] = i; + } + queue_priority_map[i][0] = -1; + queue_priority_map[i][1] = -1; + + pdata->queue_priority_mapping = queue_priority_map; + + pdata->default_queue = 0; + + return ret; +} + +static struct of_dma_filter_info edma_filter_info = { + .filter_fn = edma_filter_fn, +}; -static int __init edma_probe(struct platform_device *pdev) +static int edma_probe(struct platform_device *pdev) { struct edma_soc_info **info = pdev->dev.platform_data; - const s8 (*queue_priority_mapping)[2]; - const s8 (*queue_tc_mapping)[2]; + struct edma_soc_info *ninfo[EDMA_MAX_CC] = {NULL}; + struct edma_soc_info tmpinfo; + s8 (*queue_priority_mapping)[2]; + s8 (*queue_tc_mapping)[2]; int i, j, off, ln, found = 0; int status = -1; const s16 (*rsv_chans)[2]; @@ -1383,17 +1479,56 @@ static int __init edma_probe(struct platform_device *pdev) int irq[EDMA_MAX_CC] = {0, 0}; int err_irq[EDMA_MAX_CC] = {0, 0}; struct resource *r[EDMA_MAX_CC] = {NULL}; + struct resource res[EDMA_MAX_CC]; char res_name[10]; char irq_name[10]; + struct device_node *node = pdev->dev.of_node; + struct device *dev = &pdev->dev; + int ret; + + if (node) { + /* Check if this is a second instance registered */ + if (arch_num_cc) { + dev_err(dev, "only one EDMA instance is supported via DT\n"); + return -ENODEV; + } + info = ninfo; + edma_of_parse_dt(dev, node, &tmpinfo); + info[0] = &tmpinfo; + + dma_cap_set(DMA_SLAVE, edma_filter_info.dma_cap); + of_dma_controller_register(dev->of_node, + of_dma_simple_xlate, + &edma_filter_info); + } if (!info) return -ENODEV; + pm_runtime_enable(dev); + ret = pm_runtime_get_sync(dev); + if (ret < 0) { + dev_err(dev, "pm_runtime_get_sync() failed\n"); + return ret; + } + for (j = 0; j < EDMA_MAX_CC; j++) { - sprintf(res_name, "edma_cc%d", j); - r[j] = platform_get_resource_byname(pdev, IORESOURCE_MEM, + if (!info[j]) { + if (!found) + return -ENODEV; + break; + } + if (node) { + ret = of_address_to_resource(node, j, &res[j]); + if (!ret) + r[j] = &res[j]; + } else { + sprintf(res_name, "edma_cc%d", j); + r[j] = platform_get_resource_byname(pdev, + IORESOURCE_MEM, res_name); - if (!r[j] || !info[j]) { + } + if (!r[j]) { if (found) break; else @@ -1440,7 +1575,7 @@ static int __init edma_probe(struct platform_device *pdev) off = rsv_chans[i][0]; ln = rsv_chans[i][1]; clear_bits(off, ln, - edma_cc[j]->edma_unused); + edma_cc[j]->edma_unused); } } @@ -1456,8 +1591,14 @@ static int __init edma_probe(struct platform_device *pdev) } } - sprintf(irq_name, "edma%d", j); - irq[j] = platform_get_irq_byname(pdev, irq_name); + + if (node) { + irq[j] = irq_of_parse_and_map(node, 0); + } + else { + sprintf(irq_name, "edma%d", j); + irq[j] = platform_get_irq_byname(pdev, irq_name); + } edma_cc[j]->irq_res_start = irq[j]; status = devm_request_irq(&pdev->dev, irq[j], dma_irq_handler, 0, "edma", @@ -1469,8 +1610,13 @@ static int __init edma_probe(struct platform_device *pdev) return status; } - sprintf(irq_name, "edma%d_err", j); - err_irq[j] = platform_get_irq_byname(pdev, irq_name); + if (node) { + err_irq[j] = irq_of_parse_and_map(node, 2); + } + else { + sprintf(irq_name, "edma%d_err", j); + err_irq[j] = platform_get_irq_byname(pdev, irq_name); + } edma_cc[j]->irq_res_end = err_irq[j]; status = devm_request_irq(&pdev->dev, err_irq[j], dma_ccerr_handler, 0, @@ -1516,9 +1662,17 @@ static int __init edma_probe(struct platform_device *pdev) return 0; } +static const struct of_device_id edma_of_ids[] = { + { .compatible = "ti,edma3", }, + {} +}; static struct platform_driver edma_driver = { - .driver.name = "edma", + .driver = { + .name = "edma", + .of_match_table = edma_of_ids, + }, + .probe = edma_probe, }; static int __init edma_init(void) diff --git a/include/linux/platform_data/edma.h b/include/linux/platform_data/edma.h index 2344ea2..317f2be 100644 --- a/include/linux/platform_data/edma.h +++ b/include/linux/platform_data/edma.h @@ -175,8 +175,8 @@ struct edma_soc_info { /* Resource reservation for other cores */ struct edma_rsv_info *rsv; - const s8 (*queue_tc_mapping)[2]; - const s8 (*queue_priority_mapping)[2]; + s8 (*queue_tc_mapping)[2]; + s8 (*queue_priority_mapping)[2]; }; #endif