summaryrefslogtreecommitdiff
path: root/drivers/dma/sa11x0-dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/dma/sa11x0-dma.c')
-rw-r--r--drivers/dma/sa11x0-dma.c70
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);