mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-28 22:54:05 +08:00
dmaengine: fsl-edma: add drvdata for fsl-edma
There are some differences between vf610 and next i.mx7ulp. Put such differences into static driver data for distinguishing easily at driver level. Change mcf-edma accordingly. Signed-off-by: Robin Gong <yibin.gong@nxp.com> Tested-by: Angelo Dureghello <angelo@sysam.it> Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
fc4a903078
commit
af802728e4
@ -47,7 +47,7 @@ static void fsl_edma_enable_request(struct fsl_edma_chan *fsl_chan)
|
||||
struct edma_regs *regs = &fsl_chan->edma->regs;
|
||||
u32 ch = fsl_chan->vchan.chan.chan_id;
|
||||
|
||||
if (fsl_chan->edma->version == v1) {
|
||||
if (fsl_chan->edma->drvdata->version == v1) {
|
||||
edma_writeb(fsl_chan->edma, EDMA_SEEI_SEEI(ch), regs->seei);
|
||||
edma_writeb(fsl_chan->edma, ch, regs->serq);
|
||||
} else {
|
||||
@ -64,7 +64,7 @@ void fsl_edma_disable_request(struct fsl_edma_chan *fsl_chan)
|
||||
struct edma_regs *regs = &fsl_chan->edma->regs;
|
||||
u32 ch = fsl_chan->vchan.chan.chan_id;
|
||||
|
||||
if (fsl_chan->edma->version == v1) {
|
||||
if (fsl_chan->edma->drvdata->version == v1) {
|
||||
edma_writeb(fsl_chan->edma, ch, regs->cerq);
|
||||
edma_writeb(fsl_chan->edma, EDMA_CEEI_CEEI(ch), regs->ceei);
|
||||
} else {
|
||||
@ -83,8 +83,9 @@ void fsl_edma_chan_mux(struct fsl_edma_chan *fsl_chan,
|
||||
u32 ch = fsl_chan->vchan.chan.chan_id;
|
||||
void __iomem *muxaddr;
|
||||
unsigned int chans_per_mux, ch_off;
|
||||
u32 dmamux_nr = fsl_chan->edma->drvdata->dmamuxs;
|
||||
|
||||
chans_per_mux = fsl_chan->edma->n_chans / DMAMUX_NR;
|
||||
chans_per_mux = fsl_chan->edma->n_chans / dmamux_nr;
|
||||
ch_off = fsl_chan->vchan.chan.chan_id % chans_per_mux;
|
||||
muxaddr = fsl_chan->edma->muxbase[ch / chans_per_mux];
|
||||
slot = EDMAMUX_CHCFG_SOURCE(slot);
|
||||
@ -647,28 +648,28 @@ void fsl_edma_setup_regs(struct fsl_edma_engine *edma)
|
||||
edma->regs.erql = edma->membase + EDMA_ERQ;
|
||||
edma->regs.eeil = edma->membase + EDMA_EEI;
|
||||
|
||||
edma->regs.serq = edma->membase + ((edma->version == v1) ?
|
||||
edma->regs.serq = edma->membase + ((edma->drvdata->version == v1) ?
|
||||
EDMA_SERQ : EDMA64_SERQ);
|
||||
edma->regs.cerq = edma->membase + ((edma->version == v1) ?
|
||||
edma->regs.cerq = edma->membase + ((edma->drvdata->version == v1) ?
|
||||
EDMA_CERQ : EDMA64_CERQ);
|
||||
edma->regs.seei = edma->membase + ((edma->version == v1) ?
|
||||
edma->regs.seei = edma->membase + ((edma->drvdata->version == v1) ?
|
||||
EDMA_SEEI : EDMA64_SEEI);
|
||||
edma->regs.ceei = edma->membase + ((edma->version == v1) ?
|
||||
edma->regs.ceei = edma->membase + ((edma->drvdata->version == v1) ?
|
||||
EDMA_CEEI : EDMA64_CEEI);
|
||||
edma->regs.cint = edma->membase + ((edma->version == v1) ?
|
||||
edma->regs.cint = edma->membase + ((edma->drvdata->version == v1) ?
|
||||
EDMA_CINT : EDMA64_CINT);
|
||||
edma->regs.cerr = edma->membase + ((edma->version == v1) ?
|
||||
edma->regs.cerr = edma->membase + ((edma->drvdata->version == v1) ?
|
||||
EDMA_CERR : EDMA64_CERR);
|
||||
edma->regs.ssrt = edma->membase + ((edma->version == v1) ?
|
||||
edma->regs.ssrt = edma->membase + ((edma->drvdata->version == v1) ?
|
||||
EDMA_SSRT : EDMA64_SSRT);
|
||||
edma->regs.cdne = edma->membase + ((edma->version == v1) ?
|
||||
edma->regs.cdne = edma->membase + ((edma->drvdata->version == v1) ?
|
||||
EDMA_CDNE : EDMA64_CDNE);
|
||||
edma->regs.intl = edma->membase + ((edma->version == v1) ?
|
||||
edma->regs.intl = edma->membase + ((edma->drvdata->version == v1) ?
|
||||
EDMA_INTR : EDMA64_INTL);
|
||||
edma->regs.errl = edma->membase + ((edma->version == v1) ?
|
||||
edma->regs.errl = edma->membase + ((edma->drvdata->version == v1) ?
|
||||
EDMA_ERR : EDMA64_ERRL);
|
||||
|
||||
if (edma->version == v2) {
|
||||
if (edma->drvdata->version == v2) {
|
||||
edma->regs.erqh = edma->membase + EDMA64_ERQH;
|
||||
edma->regs.eeih = edma->membase + EDMA64_EEIH;
|
||||
edma->regs.errh = edma->membase + EDMA64_ERRH;
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define _FSL_EDMA_COMMON_H_
|
||||
|
||||
#include <linux/dma-direction.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include "virt-dma.h"
|
||||
|
||||
#define EDMA_CR_EDBG BIT(1)
|
||||
@ -140,17 +141,24 @@ enum edma_version {
|
||||
v2, /* 64ch Coldfire */
|
||||
};
|
||||
|
||||
struct fsl_edma_drvdata {
|
||||
enum edma_version version;
|
||||
u32 dmamuxs;
|
||||
int (*setup_irq)(struct platform_device *pdev,
|
||||
struct fsl_edma_engine *fsl_edma);
|
||||
};
|
||||
|
||||
struct fsl_edma_engine {
|
||||
struct dma_device dma_dev;
|
||||
void __iomem *membase;
|
||||
void __iomem *muxbase[DMAMUX_NR];
|
||||
struct clk *muxclk[DMAMUX_NR];
|
||||
struct mutex fsl_edma_mutex;
|
||||
const struct fsl_edma_drvdata *drvdata;
|
||||
u32 n_chans;
|
||||
int txirq;
|
||||
int errirq;
|
||||
bool big_endian;
|
||||
enum edma_version version;
|
||||
struct edma_regs regs;
|
||||
struct fsl_edma_chan chans[];
|
||||
};
|
||||
|
@ -96,7 +96,8 @@ static struct dma_chan *fsl_edma_xlate(struct of_phandle_args *dma_spec,
|
||||
struct fsl_edma_engine *fsl_edma = ofdma->of_dma_data;
|
||||
struct dma_chan *chan, *_chan;
|
||||
struct fsl_edma_chan *fsl_chan;
|
||||
unsigned long chans_per_mux = fsl_edma->n_chans / DMAMUX_NR;
|
||||
u32 dmamux_nr = fsl_edma->drvdata->dmamuxs;
|
||||
unsigned long chans_per_mux = fsl_edma->n_chans / dmamux_nr;
|
||||
|
||||
if (dma_spec->args_count != 2)
|
||||
return NULL;
|
||||
@ -184,16 +185,38 @@ static void fsl_disable_clocks(struct fsl_edma_engine *fsl_edma, int nr_clocks)
|
||||
clk_disable_unprepare(fsl_edma->muxclk[i]);
|
||||
}
|
||||
|
||||
static struct fsl_edma_drvdata vf610_data = {
|
||||
.version = v1,
|
||||
.dmamuxs = DMAMUX_NR,
|
||||
.setup_irq = fsl_edma_irq_init,
|
||||
};
|
||||
|
||||
static const struct of_device_id fsl_edma_dt_ids[] = {
|
||||
{ .compatible = "fsl,vf610-edma", .data = &vf610_data},
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
|
||||
|
||||
static int fsl_edma_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *of_id =
|
||||
of_match_device(fsl_edma_dt_ids, &pdev->dev);
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct fsl_edma_engine *fsl_edma;
|
||||
const struct fsl_edma_drvdata *drvdata = NULL;
|
||||
struct fsl_edma_chan *fsl_chan;
|
||||
struct edma_regs *regs;
|
||||
struct resource *res;
|
||||
int len, chans;
|
||||
int ret, i;
|
||||
|
||||
if (of_id)
|
||||
drvdata = of_id->data;
|
||||
if (!drvdata) {
|
||||
dev_err(&pdev->dev, "unable to find driver data\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(np, "dma-channels", &chans);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "Can't get dma-channels.\n");
|
||||
@ -205,7 +228,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
|
||||
if (!fsl_edma)
|
||||
return -ENOMEM;
|
||||
|
||||
fsl_edma->version = v1;
|
||||
fsl_edma->drvdata = drvdata;
|
||||
fsl_edma->n_chans = chans;
|
||||
mutex_init(&fsl_edma->fsl_edma_mutex);
|
||||
|
||||
@ -217,7 +240,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
|
||||
fsl_edma_setup_regs(fsl_edma);
|
||||
regs = &fsl_edma->regs;
|
||||
|
||||
for (i = 0; i < DMAMUX_NR; i++) {
|
||||
for (i = 0; i < fsl_edma->drvdata->dmamuxs; i++) {
|
||||
char clkname[32];
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1 + i);
|
||||
@ -263,7 +286,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
edma_writel(fsl_edma, ~0, regs->intl);
|
||||
ret = fsl_edma_irq_init(pdev, fsl_edma);
|
||||
ret = fsl_edma->drvdata->setup_irq(pdev, fsl_edma);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -295,7 +318,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev,
|
||||
"Can't register Freescale eDMA engine. (%d)\n", ret);
|
||||
fsl_disable_clocks(fsl_edma, DMAMUX_NR);
|
||||
fsl_disable_clocks(fsl_edma, fsl_edma->drvdata->dmamuxs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -304,7 +327,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
|
||||
dev_err(&pdev->dev,
|
||||
"Can't register Freescale eDMA of_dma. (%d)\n", ret);
|
||||
dma_async_device_unregister(&fsl_edma->dma_dev);
|
||||
fsl_disable_clocks(fsl_edma, DMAMUX_NR);
|
||||
fsl_disable_clocks(fsl_edma, fsl_edma->drvdata->dmamuxs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -323,7 +346,7 @@ static int fsl_edma_remove(struct platform_device *pdev)
|
||||
fsl_edma_cleanup_vchan(&fsl_edma->dma_dev);
|
||||
of_dma_controller_free(np);
|
||||
dma_async_device_unregister(&fsl_edma->dma_dev);
|
||||
fsl_disable_clocks(fsl_edma, DMAMUX_NR);
|
||||
fsl_disable_clocks(fsl_edma, fsl_edma->drvdata->dmamuxs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -382,12 +405,6 @@ static const struct dev_pm_ops fsl_edma_pm_ops = {
|
||||
.resume_early = fsl_edma_resume_early,
|
||||
};
|
||||
|
||||
static const struct of_device_id fsl_edma_dt_ids[] = {
|
||||
{ .compatible = "fsl,vf610-edma", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
|
||||
|
||||
static struct platform_driver fsl_edma_driver = {
|
||||
.driver = {
|
||||
.name = "fsl-edma",
|
||||
|
@ -164,6 +164,11 @@ static void mcf_edma_irq_free(struct platform_device *pdev,
|
||||
free_irq(irq, mcf_edma);
|
||||
}
|
||||
|
||||
static struct fsl_edma_drvdata mcf_data = {
|
||||
.version = v2,
|
||||
.setup_irq = mcf_edma_irq_init,
|
||||
};
|
||||
|
||||
static int mcf_edma_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct mcf_edma_platform_data *pdata;
|
||||
@ -187,8 +192,8 @@ static int mcf_edma_probe(struct platform_device *pdev)
|
||||
|
||||
mcf_edma->n_chans = chans;
|
||||
|
||||
/* Set up version for ColdFire edma */
|
||||
mcf_edma->version = v2;
|
||||
/* Set up drvdata for ColdFire edma */
|
||||
mcf_edma->drvdata = &mcf_data;
|
||||
mcf_edma->big_endian = 1;
|
||||
|
||||
if (!mcf_edma->n_chans) {
|
||||
@ -223,7 +228,7 @@ static int mcf_edma_probe(struct platform_device *pdev)
|
||||
iowrite32(~0, regs->inth);
|
||||
iowrite32(~0, regs->intl);
|
||||
|
||||
ret = mcf_edma_irq_init(pdev, mcf_edma);
|
||||
ret = mcf_edma->drvdata->setup_irq(pdev, mcf_edma);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user