forked from Minki/linux
Merge branch 'topic/omap' into for-linus
This commit is contained in:
commit
0e0fa66e39
@ -31,6 +31,34 @@ Example:
|
||||
dma-requests = <127>;
|
||||
};
|
||||
|
||||
* DMA router
|
||||
|
||||
DMA routers are transparent IP blocks used to route DMA request lines from
|
||||
devices to the DMA controller. Some SoCs (like TI DRA7x) have more peripherals
|
||||
integrated with DMA requests than what the DMA controller can handle directly.
|
||||
|
||||
Required property:
|
||||
- dma-masters: phandle of the DMA controller or list of phandles for
|
||||
the DMA controllers the router can direct the signal to.
|
||||
- #dma-cells: Must be at least 1. Used to provide DMA router specific
|
||||
information. See DMA client binding below for more
|
||||
details.
|
||||
|
||||
Optional properties:
|
||||
- dma-requests: Number of incoming request lines the router can handle.
|
||||
- In the node pointed by the dma-masters:
|
||||
- dma-requests: The router driver might need to look for this in order
|
||||
to configure the routing.
|
||||
|
||||
Example:
|
||||
sdma_xbar: dma-router@4a002b78 {
|
||||
compatible = "ti,dra7-dma-crossbar";
|
||||
reg = <0x4a002b78 0xfc>;
|
||||
#dma-cells = <1>;
|
||||
dma-requests = <205>;
|
||||
ti,dma-safe-map = <0>;
|
||||
dma-masters = <&sdma>;
|
||||
};
|
||||
|
||||
* DMA client
|
||||
|
||||
|
52
Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
Normal file
52
Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
Normal file
@ -0,0 +1,52 @@
|
||||
Texas Instruments DMA Crossbar (DMA request router)
|
||||
|
||||
Required properties:
|
||||
- compatible: "ti,dra7-dma-crossbar" for DRA7xx DMA crossbar
|
||||
- reg: Memory map for accessing module
|
||||
- #dma-cells: Should be set to <1>.
|
||||
Clients should use the crossbar request number (input)
|
||||
- dma-requests: Number of DMA requests the crossbar can receive
|
||||
- dma-masters: phandle pointing to the DMA controller
|
||||
|
||||
The DMA controller node need to have the following poroperties:
|
||||
- dma-requests: Number of DMA requests the controller can handle
|
||||
|
||||
Optional properties:
|
||||
- ti,dma-safe-map: Safe routing value for unused request lines
|
||||
|
||||
Example:
|
||||
|
||||
/* DMA controller */
|
||||
sdma: dma-controller@4a056000 {
|
||||
compatible = "ti,omap4430-sdma";
|
||||
reg = <0x4a056000 0x1000>;
|
||||
interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
|
||||
<GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
|
||||
#dma-cells = <1>;
|
||||
dma-channels = <32>;
|
||||
dma-requests = <127>;
|
||||
};
|
||||
|
||||
/* DMA crossbar */
|
||||
sdma_xbar: dma-router@4a002b78 {
|
||||
compatible = "ti,dra7-dma-crossbar";
|
||||
reg = <0x4a002b78 0xfc>;
|
||||
#dma-cells = <1>;
|
||||
dma-requests = <205>;
|
||||
ti,dma-safe-map = <0>;
|
||||
dma-masters = <&sdma>;
|
||||
};
|
||||
|
||||
/* DMA client */
|
||||
uart1: serial@4806a000 {
|
||||
compatible = "ti,omap4-uart";
|
||||
reg = <0x4806a000 0x100>;
|
||||
interrupts-extended = <&gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
|
||||
ti,hwmods = "uart1";
|
||||
clock-frequency = <48000000>;
|
||||
status = "disabled";
|
||||
dmas = <&sdma_xbar 49>, <&sdma_xbar 50>;
|
||||
dma-names = "tx", "rx";
|
||||
};
|
@ -245,6 +245,9 @@ config TI_EDMA
|
||||
Enable support for the TI EDMA controller. This DMA
|
||||
engine is found on TI DaVinci and AM33xx parts.
|
||||
|
||||
config TI_DMA_CROSSBAR
|
||||
bool
|
||||
|
||||
config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
|
||||
bool
|
||||
|
||||
@ -330,6 +333,7 @@ config DMA_OMAP
|
||||
depends on ARCH_OMAP
|
||||
select DMA_ENGINE
|
||||
select DMA_VIRTUAL_CHANNELS
|
||||
select TI_DMA_CROSSBAR if SOC_DRA7XX
|
||||
|
||||
config DMA_BCM2835
|
||||
tristate "BCM2835 DMA engine support"
|
||||
|
@ -38,6 +38,7 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
|
||||
obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
|
||||
obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
|
||||
obj-$(CONFIG_DMA_OMAP) += omap-dma.o
|
||||
obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
|
||||
obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
|
||||
obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
|
||||
obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
|
||||
|
@ -267,6 +267,13 @@ static void dma_chan_put(struct dma_chan *chan)
|
||||
/* This channel is not in use anymore, free it */
|
||||
if (!chan->client_count && chan->device->device_free_chan_resources)
|
||||
chan->device->device_free_chan_resources(chan);
|
||||
|
||||
/* If the channel is used via a DMA request router, free the mapping */
|
||||
if (chan->router && chan->router->route_free) {
|
||||
chan->router->route_free(chan->router->dev, chan->route_data);
|
||||
chan->router = NULL;
|
||||
chan->route_data = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)
|
||||
|
@ -44,6 +44,50 @@ static struct of_dma *of_dma_find_controller(struct of_phandle_args *dma_spec)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_dma_router_xlate - translation function for router devices
|
||||
* @dma_spec: pointer to DMA specifier as found in the device tree
|
||||
* @of_dma: 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)
|
||||
{
|
||||
struct dma_chan *chan;
|
||||
struct of_dma *ofdma_target;
|
||||
struct of_phandle_args dma_spec_target;
|
||||
void *route_data;
|
||||
|
||||
/* translate the request for the real DMA controller */
|
||||
memcpy(&dma_spec_target, dma_spec, sizeof(dma_spec_target));
|
||||
route_data = ofdma->of_dma_route_allocate(&dma_spec_target, ofdma);
|
||||
if (IS_ERR(route_data))
|
||||
return NULL;
|
||||
|
||||
ofdma_target = of_dma_find_controller(&dma_spec_target);
|
||||
if (!ofdma_target)
|
||||
return NULL;
|
||||
|
||||
chan = ofdma_target->of_dma_xlate(&dma_spec_target, ofdma_target);
|
||||
if (chan) {
|
||||
chan->router = ofdma->dma_router;
|
||||
chan->route_data = route_data;
|
||||
} else {
|
||||
ofdma->dma_router->route_free(ofdma->dma_router->dev,
|
||||
route_data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Need to put the node back since the ofdma->of_dma_route_allocate
|
||||
* has taken it for generating the new, translated dma_spec
|
||||
*/
|
||||
of_node_put(dma_spec_target.np);
|
||||
return chan;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_dma_controller_register - Register a DMA controller to DT DMA helpers
|
||||
* @np: device node of DMA controller
|
||||
@ -109,6 +153,51 @@ void of_dma_controller_free(struct device_node *np)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_dma_controller_free);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
struct of_dma *ofdma;
|
||||
|
||||
if (!np || !of_dma_route_allocate || !dma_router) {
|
||||
pr_err("%s: not enough information provided\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ofdma = kzalloc(sizeof(*ofdma), GFP_KERNEL);
|
||||
if (!ofdma)
|
||||
return -ENOMEM;
|
||||
|
||||
ofdma->of_node = np;
|
||||
ofdma->of_dma_xlate = of_dma_router_xlate;
|
||||
ofdma->of_dma_route_allocate = of_dma_route_allocate;
|
||||
ofdma->dma_router = dma_router;
|
||||
|
||||
/* Now queue of_dma controller structure in list */
|
||||
mutex_lock(&of_dma_lock);
|
||||
list_add_tail(&ofdma->of_dma_controllers, &of_dma_list);
|
||||
mutex_unlock(&of_dma_lock);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_dma_router_register);
|
||||
|
||||
/**
|
||||
* of_dma_match_channel - Check if a DMA specifier matches name
|
||||
* @np: device node to look for DMA channels
|
||||
|
@ -22,6 +22,9 @@
|
||||
|
||||
#include "virt-dma.h"
|
||||
|
||||
#define OMAP_SDMA_REQUESTS 127
|
||||
#define OMAP_SDMA_CHANNELS 32
|
||||
|
||||
struct omap_dmadev {
|
||||
struct dma_device ddev;
|
||||
spinlock_t lock;
|
||||
@ -31,9 +34,10 @@ struct omap_dmadev {
|
||||
const struct omap_dma_reg *reg_map;
|
||||
struct omap_system_dma_plat_info *plat;
|
||||
bool legacy;
|
||||
unsigned dma_requests;
|
||||
spinlock_t irq_lock;
|
||||
uint32_t irq_enable_mask;
|
||||
struct omap_chan *lch_map[32];
|
||||
struct omap_chan *lch_map[OMAP_SDMA_CHANNELS];
|
||||
};
|
||||
|
||||
struct omap_chan {
|
||||
@ -589,6 +593,7 @@ static void omap_dma_free_chan_resources(struct dma_chan *chan)
|
||||
omap_free_dma(c->dma_ch);
|
||||
|
||||
dev_dbg(od->ddev.dev, "freeing channel for %u\n", c->dma_sig);
|
||||
c->dma_sig = 0;
|
||||
}
|
||||
|
||||
static size_t omap_dma_sg_size(struct omap_sg *sg)
|
||||
@ -1082,7 +1087,7 @@ static int omap_dma_resume(struct dma_chan *chan)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omap_dma_chan_init(struct omap_dmadev *od, int dma_sig)
|
||||
static int omap_dma_chan_init(struct omap_dmadev *od)
|
||||
{
|
||||
struct omap_chan *c;
|
||||
|
||||
@ -1091,7 +1096,6 @@ static int omap_dma_chan_init(struct omap_dmadev *od, int dma_sig)
|
||||
return -ENOMEM;
|
||||
|
||||
c->reg_map = od->reg_map;
|
||||
c->dma_sig = dma_sig;
|
||||
c->vc.desc_free = omap_dma_desc_free;
|
||||
vchan_init(&c->vc, &od->ddev);
|
||||
INIT_LIST_HEAD(&c->node);
|
||||
@ -1163,8 +1167,17 @@ static int omap_dma_probe(struct platform_device *pdev)
|
||||
|
||||
tasklet_init(&od->task, omap_dma_sched, (unsigned long)od);
|
||||
|
||||
for (i = 0; i < 127; i++) {
|
||||
rc = omap_dma_chan_init(od, i);
|
||||
od->dma_requests = OMAP_SDMA_REQUESTS;
|
||||
if (pdev->dev.of_node && of_property_read_u32(pdev->dev.of_node,
|
||||
"dma-requests",
|
||||
&od->dma_requests)) {
|
||||
dev_info(&pdev->dev,
|
||||
"Missing dma-requests property, using %u.\n",
|
||||
OMAP_SDMA_REQUESTS);
|
||||
}
|
||||
|
||||
for (i = 0; i < OMAP_SDMA_CHANNELS; i++) {
|
||||
rc = omap_dma_chan_init(od);
|
||||
if (rc) {
|
||||
omap_dma_free(od);
|
||||
return rc;
|
||||
@ -1255,10 +1268,14 @@ static struct platform_driver omap_dma_driver = {
|
||||
bool omap_dma_filter_fn(struct dma_chan *chan, void *param)
|
||||
{
|
||||
if (chan->device->dev->driver == &omap_dma_driver.driver) {
|
||||
struct omap_dmadev *od = to_omap_dma_dev(chan->device);
|
||||
struct omap_chan *c = to_omap_dma_chan(chan);
|
||||
unsigned req = *(unsigned *)param;
|
||||
|
||||
return req == c->dma_sig;
|
||||
if (req <= od->dma_requests) {
|
||||
c->dma_sig = req;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
188
drivers/dma/ti-dma-crossbar.c
Normal file
188
drivers/dma/ti-dma-crossbar.c
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
|
||||
* Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/idr.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_dma.h>
|
||||
|
||||
#define TI_XBAR_OUTPUTS 127
|
||||
#define TI_XBAR_INPUTS 256
|
||||
|
||||
static DEFINE_IDR(map_idr);
|
||||
|
||||
struct ti_dma_xbar_data {
|
||||
void __iomem *iomem;
|
||||
|
||||
struct dma_router dmarouter;
|
||||
|
||||
u16 safe_val; /* Value to rest the crossbar lines */
|
||||
u32 xbar_requests; /* number of DMA requests connected to XBAR */
|
||||
u32 dma_requests; /* number of DMA requests forwarded to DMA */
|
||||
};
|
||||
|
||||
struct ti_dma_xbar_map {
|
||||
u16 xbar_in;
|
||||
int xbar_out;
|
||||
};
|
||||
|
||||
static inline void ti_dma_xbar_write(void __iomem *iomem, int xbar, u16 val)
|
||||
{
|
||||
writew_relaxed(val, iomem + (xbar * 2));
|
||||
}
|
||||
|
||||
static void ti_dma_xbar_free(struct device *dev, void *route_data)
|
||||
{
|
||||
struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
|
||||
struct ti_dma_xbar_map *map = route_data;
|
||||
|
||||
dev_dbg(dev, "Unmapping XBAR%u (was routed to %d)\n",
|
||||
map->xbar_in, map->xbar_out);
|
||||
|
||||
ti_dma_xbar_write(xbar->iomem, map->xbar_out, xbar->safe_val);
|
||||
idr_remove(&map_idr, map->xbar_out);
|
||||
kfree(map);
|
||||
}
|
||||
|
||||
static void *ti_dma_xbar_route_allocate(struct of_phandle_args *dma_spec,
|
||||
struct of_dma *ofdma)
|
||||
{
|
||||
struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
|
||||
struct ti_dma_xbar_data *xbar = platform_get_drvdata(pdev);
|
||||
struct ti_dma_xbar_map *map;
|
||||
|
||||
if (dma_spec->args[0] >= xbar->xbar_requests) {
|
||||
dev_err(&pdev->dev, "Invalid XBAR request number: %d\n",
|
||||
dma_spec->args[0]);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
/* The of_node_put() will be done in the core for the node */
|
||||
dma_spec->np = of_parse_phandle(ofdma->of_node, "dma-masters", 0);
|
||||
if (!dma_spec->np) {
|
||||
dev_err(&pdev->dev, "Can't get DMA master\n");
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
map = kzalloc(sizeof(*map), GFP_KERNEL);
|
||||
if (!map) {
|
||||
of_node_put(dma_spec->np);
|
||||
return ERR_PTR(-ENOMEM);
|
||||
}
|
||||
|
||||
map->xbar_out = idr_alloc(&map_idr, NULL, 0, xbar->dma_requests,
|
||||
GFP_KERNEL);
|
||||
map->xbar_in = (u16)dma_spec->args[0];
|
||||
|
||||
/* The DMA request is 1 based in sDMA */
|
||||
dma_spec->args[0] = map->xbar_out + 1;
|
||||
|
||||
dev_dbg(&pdev->dev, "Mapping XBAR%u to DMA%d\n",
|
||||
map->xbar_in, map->xbar_out);
|
||||
|
||||
ti_dma_xbar_write(xbar->iomem, map->xbar_out, map->xbar_in);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
static int ti_dma_xbar_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct device_node *dma_node;
|
||||
struct ti_dma_xbar_data *xbar;
|
||||
struct resource *res;
|
||||
u32 safe_val;
|
||||
void __iomem *iomem;
|
||||
int i, ret;
|
||||
|
||||
if (!node)
|
||||
return -ENODEV;
|
||||
|
||||
xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL);
|
||||
if (!xbar)
|
||||
return -ENOMEM;
|
||||
|
||||
dma_node = of_parse_phandle(node, "dma-masters", 0);
|
||||
if (!dma_node) {
|
||||
dev_err(&pdev->dev, "Can't get DMA master node\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
if (of_property_read_u32(dma_node, "dma-requests",
|
||||
&xbar->dma_requests)) {
|
||||
dev_info(&pdev->dev,
|
||||
"Missing XBAR output information, using %u.\n",
|
||||
TI_XBAR_OUTPUTS);
|
||||
xbar->dma_requests = TI_XBAR_OUTPUTS;
|
||||
}
|
||||
of_node_put(dma_node);
|
||||
|
||||
if (of_property_read_u32(node, "dma-requests", &xbar->xbar_requests)) {
|
||||
dev_info(&pdev->dev,
|
||||
"Missing XBAR input information, using %u.\n",
|
||||
TI_XBAR_INPUTS);
|
||||
xbar->xbar_requests = TI_XBAR_INPUTS;
|
||||
}
|
||||
|
||||
if (!of_property_read_u32(node, "ti,dma-safe-map", &safe_val))
|
||||
xbar->safe_val = (u16)safe_val;
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
return -ENODEV;
|
||||
|
||||
iomem = devm_ioremap_resource(&pdev->dev, res);
|
||||
if (!iomem)
|
||||
return -ENOMEM;
|
||||
|
||||
xbar->iomem = iomem;
|
||||
|
||||
xbar->dmarouter.dev = &pdev->dev;
|
||||
xbar->dmarouter.route_free = ti_dma_xbar_free;
|
||||
|
||||
platform_set_drvdata(pdev, xbar);
|
||||
|
||||
/* Reset the crossbar */
|
||||
for (i = 0; i < xbar->dma_requests; i++)
|
||||
ti_dma_xbar_write(xbar->iomem, i, xbar->safe_val);
|
||||
|
||||
ret = of_dma_router_register(node, ti_dma_xbar_route_allocate,
|
||||
&xbar->dmarouter);
|
||||
if (ret) {
|
||||
/* Restore the defaults for the crossbar */
|
||||
for (i = 0; i < xbar->dma_requests; i++)
|
||||
ti_dma_xbar_write(xbar->iomem, i, i);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct of_device_id ti_dma_xbar_match[] = {
|
||||
{ .compatible = "ti,dra7-dma-crossbar" },
|
||||
{},
|
||||
};
|
||||
|
||||
static struct platform_driver ti_dma_xbar_driver = {
|
||||
.driver = {
|
||||
.name = "ti-dma-crossbar",
|
||||
.of_match_table = of_match_ptr(ti_dma_xbar_match),
|
||||
},
|
||||
.probe = ti_dma_xbar_probe,
|
||||
};
|
||||
|
||||
int omap_dmaxbar_init(void)
|
||||
{
|
||||
return platform_driver_register(&ti_dma_xbar_driver);
|
||||
}
|
||||
arch_initcall(omap_dmaxbar_init);
|
@ -230,6 +230,16 @@ struct dma_chan_percpu {
|
||||
unsigned long bytes_transferred;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dma_router - DMA router structure
|
||||
* @dev: pointer to the DMA router device
|
||||
* @route_free: function to be called when the route can be disconnected
|
||||
*/
|
||||
struct dma_router {
|
||||
struct device *dev;
|
||||
void (*route_free)(struct device *dev, void *route_data);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dma_chan - devices supply DMA channels, clients use them
|
||||
* @device: ptr to the dma device who supplies this channel, always !%NULL
|
||||
@ -241,6 +251,8 @@ struct dma_chan_percpu {
|
||||
* @local: per-cpu pointer to a struct dma_chan_percpu
|
||||
* @client_count: how many clients are using this channel
|
||||
* @table_count: number of appearances in the mem-to-mem allocation table
|
||||
* @router: pointer to the DMA router structure
|
||||
* @route_data: channel specific data for the router
|
||||
* @private: private data for certain client-channel associations
|
||||
*/
|
||||
struct dma_chan {
|
||||
@ -256,6 +268,11 @@ struct dma_chan {
|
||||
struct dma_chan_percpu __percpu *local;
|
||||
int client_count;
|
||||
int table_count;
|
||||
|
||||
/* DMA router */
|
||||
struct dma_router *router;
|
||||
void *route_data;
|
||||
|
||||
void *private;
|
||||
};
|
||||
|
||||
|
@ -23,6 +23,9 @@ struct of_dma {
|
||||
struct device_node *of_node;
|
||||
struct dma_chan *(*of_dma_xlate)
|
||||
(struct of_phandle_args *, struct of_dma *);
|
||||
void *(*of_dma_route_allocate)
|
||||
(struct of_phandle_args *, struct of_dma *);
|
||||
struct dma_router *dma_router;
|
||||
void *of_dma_data;
|
||||
};
|
||||
|
||||
@ -37,12 +40,20 @@ extern int of_dma_controller_register(struct device_node *np,
|
||||
(struct of_phandle_args *, struct of_dma *),
|
||||
void *data);
|
||||
extern void of_dma_controller_free(struct device_node *np);
|
||||
|
||||
extern 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);
|
||||
#define of_dma_router_free of_dma_controller_free
|
||||
|
||||
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 struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
|
||||
struct of_dma *ofdma);
|
||||
|
||||
#else
|
||||
static inline int of_dma_controller_register(struct device_node *np,
|
||||
struct dma_chan *(*of_dma_xlate)
|
||||
@ -56,6 +67,16 @@ static inline void of_dma_controller_free(struct device_node *np)
|
||||
{
|
||||
}
|
||||
|
||||
static inline 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)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#define of_dma_router_free of_dma_controller_free
|
||||
|
||||
static inline struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
|
||||
const char *name)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user