diff options
Diffstat (limited to 'drivers/dma/sa11x0-dma.c')
| -rw-r--r-- | drivers/dma/sa11x0-dma.c | 70 |
1 files changed, 32 insertions, 38 deletions
diff --git a/drivers/dma/sa11x0-dma.c b/drivers/dma/sa11x0-dma.c index 1adeb3265085..dc1a9a05252e 100644 --- a/drivers/dma/sa11x0-dma.c +++ b/drivers/dma/sa11x0-dma.c @@ -1,13 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * SA11x0 DMAengine support * * Copyright (C) 2012 Russell King * Derived in part from arch/arm/mach-sa1100/dma.c, * Copyright (C) 2000, 2001 by Nicolas Pitre - * - * 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/sched.h> #include <linux/device.h> @@ -17,7 +14,6 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/platform_device.h> -#include <linux/sa11x0-dma.h> #include <linux/slab.h> #include <linux/spinlock.h> @@ -82,7 +78,7 @@ struct sa11x0_dma_desc { bool cyclic; unsigned sglen; - struct sa11x0_dma_sg sg[0]; + struct sa11x0_dma_sg sg[] __counted_by(sglen); }; struct sa11x0_dma_phy; @@ -327,9 +323,9 @@ static void sa11x0_dma_start_txd(struct sa11x0_dma_chan *c) } } -static void sa11x0_dma_tasklet(unsigned long arg) +static void sa11x0_dma_tasklet(struct tasklet_struct *t) { - struct sa11x0_dma_dev *d = (struct sa11x0_dma_dev *)arg; + struct sa11x0_dma_dev *d = from_tasklet(d, t, task); struct sa11x0_dma_phy *p; struct sa11x0_dma_chan *c; unsigned pch, pch_alloc = 0; @@ -557,11 +553,12 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg( } } - txd = kzalloc(sizeof(*txd) + j * sizeof(txd->sg[0]), GFP_ATOMIC); + txd = kzalloc(struct_size(txd, sg, j), GFP_ATOMIC); if (!txd) { dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", &c->vc); return NULL; } + txd->sglen = j; j = 0; for_each_sg(sg, sgent, sglen, i) { @@ -597,7 +594,6 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_slave_sg( txd->ddar = c->ddar; txd->size = size; - txd->sglen = j; dev_dbg(chan->device->dev, "vchan %p: txd %p: size %zu nr %u\n", &c->vc, &txd->vd, txd->size, txd->sglen); @@ -627,11 +623,12 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic( if (sglen == 0) return NULL; - txd = kzalloc(sizeof(*txd) + sglen * sizeof(txd->sg[0]), GFP_ATOMIC); + txd = kzalloc(struct_size(txd, sg, sglen), GFP_ATOMIC); if (!txd) { dev_dbg(chan->device->dev, "vchan %p: kzalloc failed\n", &c->vc); return NULL; } + txd->sglen = sglen; for (i = k = 0; i < size / period; i++) { size_t tlen, len = period; @@ -657,7 +654,6 @@ static struct dma_async_tx_descriptor *sa11x0_dma_prep_dma_cyclic( txd->ddar = c->ddar; txd->size = size; - txd->sglen = sglen; txd->cyclic = 1; txd->period = sgperiod; @@ -706,7 +702,6 @@ static int sa11x0_dma_device_pause(struct dma_chan *chan) struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device); struct sa11x0_dma_phy *p; - LIST_HEAD(head); unsigned long flags; dev_dbg(d->slave.dev, "vchan %p: pause\n", &c->vc); @@ -733,7 +728,6 @@ static int sa11x0_dma_device_resume(struct dma_chan *chan) struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); struct sa11x0_dma_dev *d = to_sa11x0_dma(chan->device); struct sa11x0_dma_phy *p; - LIST_HEAD(head); unsigned long flags; dev_dbg(d->slave.dev, "vchan %p: resume\n", &c->vc); @@ -823,6 +817,21 @@ static const struct sa11x0_dma_channel_desc chan_desc[] = { CD(Ser4SSPRc, DDAR_RW), }; +static const struct dma_slave_map sa11x0_dma_map[] = { + { "sa11x0-ir", "tx", "Ser2ICPTr" }, + { "sa11x0-ir", "rx", "Ser2ICPRc" }, + { "sa11x0-ssp", "tx", "Ser4SSPTr" }, + { "sa11x0-ssp", "rx", "Ser4SSPRc" }, +}; + +static bool sa11x0_dma_filter_fn(struct dma_chan *chan, void *param) +{ + struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); + const char *p = param; + + return !strcmp(c->name, p); +} + static int sa11x0_dma_init_dmadev(struct dma_device *dmadev, struct device *dev) { @@ -909,13 +918,17 @@ static int sa11x0_dma_probe(struct platform_device *pdev) spin_lock_init(&d->lock); INIT_LIST_HEAD(&d->chan_pending); + d->slave.filter.fn = sa11x0_dma_filter_fn; + d->slave.filter.mapcnt = ARRAY_SIZE(sa11x0_dma_map); + d->slave.filter.map = sa11x0_dma_map; + d->base = ioremap(res->start, resource_size(res)); if (!d->base) { ret = -ENOMEM; goto err_ioremap; } - tasklet_init(&d->task, sa11x0_dma_tasklet, (unsigned long)d); + tasklet_setup(&d->task, sa11x0_dma_tasklet); for (i = 0; i < NR_PHY_CHAN; i++) { struct sa11x0_dma_phy *p = &d->phy[i]; @@ -971,7 +984,7 @@ static int sa11x0_dma_probe(struct platform_device *pdev) return ret; } -static int sa11x0_dma_remove(struct platform_device *pdev) +static void sa11x0_dma_remove(struct platform_device *pdev) { struct sa11x0_dma_dev *d = platform_get_drvdata(pdev); unsigned pch; @@ -984,11 +997,9 @@ static int sa11x0_dma_remove(struct platform_device *pdev) tasklet_kill(&d->task); iounmap(d->base); kfree(d); - - return 0; } -static int sa11x0_dma_suspend(struct device *dev) +static __maybe_unused int sa11x0_dma_suspend(struct device *dev) { struct sa11x0_dma_dev *d = dev_get_drvdata(dev); unsigned pch; @@ -1026,7 +1037,7 @@ static int sa11x0_dma_suspend(struct device *dev) return 0; } -static int sa11x0_dma_resume(struct device *dev) +static __maybe_unused int sa11x0_dma_resume(struct device *dev) { struct sa11x0_dma_dev *d = dev_get_drvdata(dev); unsigned pch; @@ -1059,12 +1070,7 @@ static int sa11x0_dma_resume(struct device *dev) } static const struct dev_pm_ops sa11x0_dma_pm_ops = { - .suspend_noirq = sa11x0_dma_suspend, - .resume_noirq = sa11x0_dma_resume, - .freeze_noirq = sa11x0_dma_suspend, - .thaw_noirq = sa11x0_dma_resume, - .poweroff_noirq = sa11x0_dma_suspend, - .restore_noirq = sa11x0_dma_resume, + SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(sa11x0_dma_suspend, sa11x0_dma_resume) }; static struct platform_driver sa11x0_dma_driver = { @@ -1076,18 +1082,6 @@ static struct platform_driver sa11x0_dma_driver = { .remove = sa11x0_dma_remove, }; -bool sa11x0_dma_filter_fn(struct dma_chan *chan, void *param) -{ - if (chan->device->dev->driver == &sa11x0_dma_driver.driver) { - struct sa11x0_dma_chan *c = to_sa11x0_dma_chan(chan); - const char *p = param; - - return !strcmp(c->name, p); - } - return false; -} -EXPORT_SYMBOL(sa11x0_dma_filter_fn); - static int __init sa11x0_dma_init(void) { return platform_driver_register(&sa11x0_dma_driver); |
