From patchwork Fri Mar 7 12:16:09 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: R Sricharan X-Patchwork-Id: 3790421 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 4B5229F369 for ; Fri, 7 Mar 2014 12:19:40 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 4641B20274 for ; Fri, 7 Mar 2014 12:19:39 +0000 (UTC) Received: from casper.infradead.org (casper.infradead.org [85.118.1.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0A9842024C for ; Fri, 7 Mar 2014 12:19: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 1WLtjF-0004Zd-Mq; Fri, 07 Mar 2014 12:18:18 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1WLtiz-00074g-Ej; Fri, 07 Mar 2014 12:18:01 +0000 Received: from casper.infradead.org ([2001:770:15f::2]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WLtiU-00070E-DI for linux-arm-kernel@merlin.infradead.org; Fri, 07 Mar 2014 12:17:30 +0000 Received: from bear.ext.ti.com ([192.94.94.41]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1WLtiP-00048c-BE for linux-arm-kernel@lists.infradead.org; Fri, 07 Mar 2014 12:17:29 +0000 Received: from dflxv15.itg.ti.com ([128.247.5.124]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id s27CGv6K002990; Fri, 7 Mar 2014 06:16:57 -0600 Received: from DLEE70.ent.ti.com (dlee70.ent.ti.com [157.170.170.113]) by dflxv15.itg.ti.com (8.14.3/8.13.8) with ESMTP id s27CGvpo001039; Fri, 7 Mar 2014 06:16:57 -0600 Received: from dflp32.itg.ti.com (10.64.6.15) by DLEE70.ent.ti.com (157.170.170.113) with Microsoft SMTP Server id 14.3.174.1; Fri, 7 Mar 2014 06:16:57 -0600 Received: from localhost.localdomain (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp32.itg.ti.com (8.14.3/8.13.8) with ESMTP id s27CGhvx003967; Fri, 7 Mar 2014 06:16:53 -0600 From: Sricharan R To: , , , , , Subject: [RFC PATCH 2/9] drivers: dma: of-dma: Add support for dma-request line routers Date: Fri, 7 Mar 2014 17:46:09 +0530 Message-ID: <1394194576-23741-3-git-send-email-r.sricharan@ti.com> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1394194576-23741-1-git-send-email-r.sricharan@ti.com> References: <1394194576-23741-1-git-send-email-r.sricharan@ti.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140307_121725_747785_97E93824 X-CRM114-Status: GOOD ( 20.38 ) X-Spam-Score: -6.9 (------) Cc: nm@ti.com, linux@arm.linux.org.uk, tony@atomide.com, rnayak@ti.com, nsekhar@ti.com, vinod.koul@intel.com, santosh.shilimkar@ti.com, dan.j.williams@intel.com 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=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_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 In some socs dma requests lines from the peripherals to the dma controller can be connected either directly or through a crossbar router. The crossbar in turn maps the peripheral request line to a free dma-controller request line. In such cases the crossbar associated with the particular request lines has to configured. This add two APIS, one to register the crossbar router and other to retrieve the router associated with a dma request line. The peripheral's dma-specs mentions the dma-controller, request-line and also the IP to which it is connected to via DT. The dma-controller will have to check if a request line is routed and then use that router's map/unmap function to configure the request line. Signed-off-by: Sricharan R --- drivers/dma/of-dma.c | 82 ++++++++++++++++++++++++++++++++++++++++++++++-- include/linux/of_dma.h | 22 +++++++++++++ 2 files changed, 102 insertions(+), 2 deletions(-) diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c index e8fe9dc..86129ef 100644 --- a/drivers/dma/of-dma.c +++ b/drivers/dma/of-dma.c @@ -19,7 +19,29 @@ #include static LIST_HEAD(of_dma_list); +static LIST_HEAD(of_dma_router_list); static DEFINE_MUTEX(of_dma_lock); +static DEFINE_MUTEX(of_dma_router_lock); + +/** + * of_dma_get_router_data - Get a DMA router in DT DMA routers list + * @phandle: phandle to the dma router + * + * Finds a DMA router using matching phandle and returns the router + * specific data. Should be called from dma-controller xlate callback. + */ +void *of_dma_get_router_data(phandle router) +{ + struct of_dma_router *ofrouter; + + list_for_each_entry(ofrouter, &of_dma_router_list, of_dma_routers) { + if (ofrouter->of_node->phandle == router) + return ofrouter->of_router_data; + } + + return NULL; +} +EXPORT_SYMBOL(of_dma_get_router_data); /** * of_dma_find_controller - Get a DMA controller in DT DMA helpers list @@ -45,6 +67,39 @@ static struct of_dma *of_dma_find_controller(struct of_phandle_args *dma_spec) } /** + * of_dma_router_register - Register a DMA router to DT DMA helpers + * @np: device node of DMA controller + * @data pointer to controller specific data to be used by + * dma-controller + * + * Returns 0 on success or appropriate errno value on error. + * + * Allocated memory should be freed with appropriate of_dma_router_free() + * call. + */ +int of_dma_router_register(struct device_node *np, void *data) +{ + struct of_dma_router *ofrouter; + + if (!np || !data) + return -EINVAL; + + ofrouter = kzalloc(sizeof(*ofrouter), GFP_KERNEL); + if (!ofrouter) + return -ENOMEM; + + ofrouter->of_node = np; + ofrouter->of_router_data = data; + + mutex_lock(&of_dma_router_lock); + list_add_tail(&ofrouter->of_dma_routers, &of_dma_router_list); + mutex_unlock(&of_dma_router_lock); + + return 0; +} +EXPORT_SYMBOL(of_dma_router_register); + +/** * of_dma_controller_register - Register a DMA controller to DT DMA helpers * @np: device node of DMA controller * @of_dma_xlate: translation function which converts a phandle @@ -87,10 +142,10 @@ int of_dma_controller_register(struct device_node *np, EXPORT_SYMBOL_GPL(of_dma_controller_register); /** - * of_dma_controller_free - Remove a DMA controller from DT DMA helpers list + * of_dma_router_free - Remove a DMA router from DT DMA routers list * @np: device node of DMA controller * - * Memory allocated by of_dma_controller_register() is freed here. + * Memory allocated by of_dma_router_register() is freed here. */ void of_dma_controller_free(struct device_node *np) { @@ -110,6 +165,29 @@ void of_dma_controller_free(struct device_node *np) EXPORT_SYMBOL_GPL(of_dma_controller_free); /** + * of_dma_controller_free - Remove a DMA controller from DT DMA helpers list + * @np: device node of DMA controller + * + * Memory allocated by of_dma_router_register() is freed here. + */ +void of_dma_router_free(struct device_node *np) +{ + struct of_dma_router *ofrouter; + + mutex_lock(&of_dma_router_lock); + + list_for_each_entry(ofrouter, &of_dma_router_list, of_dma_routers) + if (ofrouter->of_node == np) { + list_del(&ofrouter->of_dma_routers); + kfree(ofrouter); + break; + } + + mutex_unlock(&of_dma_router_lock); +} +EXPORT_SYMBOL_GPL(of_dma_router_free); + +/** * of_dma_match_channel - Check if a DMA specifier matches name * @np: device node to look for DMA channels * @name: channel name to be matched diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h index ae36298..50962a0 100644 --- a/include/linux/of_dma.h +++ b/include/linux/of_dma.h @@ -26,6 +26,12 @@ struct of_dma { void *of_dma_data; }; +struct of_dma_router { + struct list_head of_dma_routers; + struct device_node *of_node; + void *of_router_data; +}; + struct of_dma_filter_info { dma_cap_mask_t dma_cap; dma_filter_fn filter_fn; @@ -41,6 +47,9 @@ extern struct dma_chan *of_dma_request_slave_channel(struct device_node *np, const char *name); extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec, struct of_dma *ofdma); +extern void *of_dma_get_router_data(phandle router); +extern int of_dma_router_register(struct device_node *np, void *data); +extern void of_dma_router_free(struct device_node *np); #else static inline int of_dma_controller_register(struct device_node *np, struct dma_chan *(*of_dma_xlate) @@ -66,6 +75,19 @@ static inline struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_s return NULL; } +static inline void *of_dma_get_router_data(phandle router) +{ + return NULL; +} + +static inline int of_dma_router_register(struct device_node *np, void *data) +{ + return NULL; +} + +static void of_dma_router_free(struct device_node *np) +{ +} #endif #endif /* __LINUX_OF_DMA_H */