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:
Robin Gong 2019-06-25 17:43:19 +08:00 committed by Vinod Koul
parent fc4a903078
commit af802728e4
4 changed files with 62 additions and 31 deletions

View File

@ -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;

View File

@ -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[];
};

View File

@ -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",

View File

@ -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;