// SPDX-License-Identifier: GPL-2.0-only /* * Device tree helpers for DMA request / controller * * Based on of_gpio.c * * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/ */ #include <linux/device.h> #include <linux/err.h> #include <linux/module.h> #include <linux/mutex.h> #include <linux/slab.h> #include <linux/of.h> #include <linux/of_dma.h> #include "dmaengine.h" static LIST_HEAD(of_dma_list); static DEFINE_MUTEX(of_dma_lock); /** * of_dma_find_controller - Get a DMA controller in DT DMA helpers list * @dma_spec: pointer to DMA specifier as found in the device tree * * Finds a DMA controller with matching device node and number for dma cells * in a list of registered DMA controllers. If a match is found a valid pointer * to the DMA data stored is returned. A NULL pointer is returned if no match is * found. */ static struct of_dma *of_dma_find_controller(const struct of_phandle_args *dma_spec) { … } /** * of_dma_router_xlate - translation function for router devices * @dma_spec: pointer to DMA specifier as found in the device tree * @ofdma: pointer to DMA controller data (router information) * * The function creates new dma_spec to be passed to the router driver's * of_dma_route_allocate() function to prepare a dma_spec which will be used * to request channel from the real DMA controller. */ static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec, struct of_dma *ofdma) { … } /** * 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 * arguments list into a dma_chan structure * @data: pointer to controller specific data to be used by * translation function * * Returns 0 on success or appropriate errno value on error. * * Allocated memory should be freed with appropriate of_dma_controller_free() * call. */ int of_dma_controller_register(struct device_node *np, struct dma_chan *(*of_dma_xlate) (struct of_phandle_args *, struct of_dma *), void *data) { … } EXPORT_SYMBOL_GPL(…); /** * of_dma_controller_free - Remove a DMA controller from DT DMA helpers list * @np: device node of DMA controller * * Memory allocated by of_dma_controller_register() is freed here. */ void of_dma_controller_free(struct device_node *np) { … } EXPORT_SYMBOL_GPL(…); /** * of_dma_router_register - Register a DMA router to DT DMA helpers as a * controller * @np: device node of DMA router * @of_dma_route_allocate: setup function for the router which need to * modify the dma_spec for the DMA controller to * use and to set up the requested route. * @dma_router: pointer to dma_router structure to be used when * the route need to be free up. * * Returns 0 on success or appropriate errno value on error. * * Allocated memory should be freed with appropriate of_dma_controller_free() * call. */ int of_dma_router_register(struct device_node *np, void *(*of_dma_route_allocate) (struct of_phandle_args *, struct of_dma *), struct dma_router *dma_router) { … } EXPORT_SYMBOL_GPL(…); /** * 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 * @index: index of DMA specifier in list of DMA specifiers * @dma_spec: pointer to DMA specifier as found in the device tree * * Check if the DMA specifier pointed to by the index in a list of DMA * specifiers, matches the name provided. Returns 0 if the name matches and * a valid pointer to the DMA specifier is found. Otherwise returns -ENODEV. */ static int of_dma_match_channel(struct device_node *np, const char *name, int index, struct of_phandle_args *dma_spec) { … } /** * of_dma_request_slave_channel - Get the DMA slave channel * @np: device node to get DMA request from * @name: name of desired channel * * Returns pointer to appropriate DMA channel on success or an error pointer. */ struct dma_chan *of_dma_request_slave_channel(struct device_node *np, const char *name) { … } EXPORT_SYMBOL_GPL(…); /** * of_dma_simple_xlate - Simple DMA engine translation function * @dma_spec: pointer to DMA specifier as found in the device tree * @ofdma: pointer to DMA controller data * * A simple translation function for devices that use a 32-bit value for the * filter_param when calling the DMA engine dma_request_channel() function. * Note that this translation function requires that #dma-cells is equal to 1 * and the argument of the dma specifier is the 32-bit filter_param. Returns * pointer to appropriate dma channel on success or NULL on error. */ struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec, struct of_dma *ofdma) { … } EXPORT_SYMBOL_GPL(…); /** * of_dma_xlate_by_chan_id - Translate dt property to DMA channel by channel id * @dma_spec: pointer to DMA specifier as found in the device tree * @ofdma: pointer to DMA controller data * * This function can be used as the of xlate callback for DMA driver which wants * to match the channel based on the channel id. When using this xlate function * the #dma-cells property of the DMA controller dt node needs to be set to 1. * The data parameter of of_dma_controller_register must be a pointer to the * dma_device struct the function should match upon. * * Returns pointer to appropriate dma channel on success or NULL on error. */ struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec, struct of_dma *ofdma) { … } EXPORT_SYMBOL_GPL(…);