Skip to content

Commit bd4d74e

Browse files
committed
Merge tag 'dmaengine-fix-5.10-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine
Pull dmaengine fixes from Vinod Koul: "A solitary core fix and a few driver fixes: Core: - channel_register error handling Driver fixes: - idxd: wq config registers programming and mapping of portal size - ioatdma: unused fn removal - pl330: fix burst size - ti: pm fix on busy and -Wenum-conversion warns - xilinx: SG capability check, usage of xilinx_aximcdma_tx_segment, readl_poll_timeout_atomic variant" * tag 'dmaengine-fix-5.10-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine: dmaengine: fix error codes in channel_register() dmaengine: pl330: _prep_dma_memcpy: Fix wrong burst size dmaengine: ioatdma: remove unused function missed during dma_v2 removal dmaengine: idxd: fix mapping of portal size dmaengine: ti: omap-dma: Block PM if SDMA is busy to fix audio dmaengine: xilinx_dma: Fix SG capability check for MCDMA dmaengine: xilinx_dma: Fix usage of xilinx_aximcdma_tx_segment dmaengine: xilinx_dma: use readl_poll_timeout_atomic variant dmaengine: ti: k3-udma: fix -Wenum-conversion warning dmaengine: idxd: fix wq config registers offset programming
2 parents fc8299f + 7e4be12 commit bd4d74e

11 files changed

Lines changed: 111 additions & 63 deletions

File tree

drivers/dma/dmaengine.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,16 +1039,15 @@ static int get_dma_id(struct dma_device *device)
10391039
static int __dma_async_device_channel_register(struct dma_device *device,
10401040
struct dma_chan *chan)
10411041
{
1042-
int rc = 0;
1042+
int rc;
10431043

10441044
chan->local = alloc_percpu(typeof(*chan->local));
10451045
if (!chan->local)
1046-
goto err_out;
1046+
return -ENOMEM;
10471047
chan->dev = kzalloc(sizeof(*chan->dev), GFP_KERNEL);
10481048
if (!chan->dev) {
1049-
free_percpu(chan->local);
1050-
chan->local = NULL;
1051-
goto err_out;
1049+
rc = -ENOMEM;
1050+
goto err_free_local;
10521051
}
10531052

10541053
/*
@@ -1061,7 +1060,8 @@ static int __dma_async_device_channel_register(struct dma_device *device,
10611060
if (chan->chan_id < 0) {
10621061
pr_err("%s: unable to alloc ida for chan: %d\n",
10631062
__func__, chan->chan_id);
1064-
goto err_out;
1063+
rc = chan->chan_id;
1064+
goto err_free_dev;
10651065
}
10661066

10671067
chan->dev->device.class = &dma_devclass;
@@ -1082,9 +1082,10 @@ static int __dma_async_device_channel_register(struct dma_device *device,
10821082
mutex_lock(&device->chan_mutex);
10831083
ida_free(&device->chan_ida, chan->chan_id);
10841084
mutex_unlock(&device->chan_mutex);
1085-
err_out:
1086-
free_percpu(chan->local);
1085+
err_free_dev:
10871086
kfree(chan->dev);
1087+
err_free_local:
1088+
free_percpu(chan->local);
10881089
return rc;
10891090
}
10901091

drivers/dma/idxd/device.c

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ int idxd_wq_map_portal(struct idxd_wq *wq)
271271
resource_size_t start;
272272

273273
start = pci_resource_start(pdev, IDXD_WQ_BAR);
274-
start = start + wq->id * IDXD_PORTAL_SIZE;
274+
start += idxd_get_wq_portal_full_offset(wq->id, IDXD_PORTAL_LIMITED);
275275

276276
wq->dportal = devm_ioremap(dev, start, IDXD_PORTAL_SIZE);
277277
if (!wq->dportal)
@@ -295,7 +295,7 @@ void idxd_wq_disable_cleanup(struct idxd_wq *wq)
295295
int i, wq_offset;
296296

297297
lockdep_assert_held(&idxd->dev_lock);
298-
memset(&wq->wqcfg, 0, sizeof(wq->wqcfg));
298+
memset(wq->wqcfg, 0, idxd->wqcfg_size);
299299
wq->type = IDXD_WQT_NONE;
300300
wq->size = 0;
301301
wq->group = NULL;
@@ -304,8 +304,8 @@ void idxd_wq_disable_cleanup(struct idxd_wq *wq)
304304
clear_bit(WQ_FLAG_DEDICATED, &wq->flags);
305305
memset(wq->name, 0, WQ_NAME_SIZE);
306306

307-
for (i = 0; i < 8; i++) {
308-
wq_offset = idxd->wqcfg_offset + wq->id * 32 + i * sizeof(u32);
307+
for (i = 0; i < WQCFG_STRIDES(idxd); i++) {
308+
wq_offset = WQCFG_OFFSET(idxd, wq->id, i);
309309
iowrite32(0, idxd->reg_base + wq_offset);
310310
dev_dbg(dev, "WQ[%d][%d][%#x]: %#x\n",
311311
wq->id, i, wq_offset,
@@ -539,33 +539,32 @@ static int idxd_wq_config_write(struct idxd_wq *wq)
539539
if (!wq->group)
540540
return 0;
541541

542-
memset(&wq->wqcfg, 0, sizeof(union wqcfg));
542+
memset(wq->wqcfg, 0, idxd->wqcfg_size);
543543

544544
/* byte 0-3 */
545-
wq->wqcfg.wq_size = wq->size;
545+
wq->wqcfg->wq_size = wq->size;
546546

547547
if (wq->size == 0) {
548548
dev_warn(dev, "Incorrect work queue size: 0\n");
549549
return -EINVAL;
550550
}
551551

552552
/* bytes 4-7 */
553-
wq->wqcfg.wq_thresh = wq->threshold;
553+
wq->wqcfg->wq_thresh = wq->threshold;
554554

555555
/* byte 8-11 */
556-
wq->wqcfg.priv = !!(wq->type == IDXD_WQT_KERNEL);
557-
wq->wqcfg.mode = 1;
558-
559-
wq->wqcfg.priority = wq->priority;
556+
wq->wqcfg->priv = !!(wq->type == IDXD_WQT_KERNEL);
557+
wq->wqcfg->mode = 1;
558+
wq->wqcfg->priority = wq->priority;
560559

561560
/* bytes 12-15 */
562-
wq->wqcfg.max_xfer_shift = ilog2(wq->max_xfer_bytes);
563-
wq->wqcfg.max_batch_shift = ilog2(wq->max_batch_size);
561+
wq->wqcfg->max_xfer_shift = ilog2(wq->max_xfer_bytes);
562+
wq->wqcfg->max_batch_shift = ilog2(wq->max_batch_size);
564563

565564
dev_dbg(dev, "WQ %d CFGs\n", wq->id);
566-
for (i = 0; i < 8; i++) {
567-
wq_offset = idxd->wqcfg_offset + wq->id * 32 + i * sizeof(u32);
568-
iowrite32(wq->wqcfg.bits[i], idxd->reg_base + wq_offset);
565+
for (i = 0; i < WQCFG_STRIDES(idxd); i++) {
566+
wq_offset = WQCFG_OFFSET(idxd, wq->id, i);
567+
iowrite32(wq->wqcfg->bits[i], idxd->reg_base + wq_offset);
569568
dev_dbg(dev, "WQ[%d][%d][%#x]: %#x\n",
570569
wq->id, i, wq_offset,
571570
ioread32(idxd->reg_base + wq_offset));

drivers/dma/idxd/idxd.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ struct idxd_wq {
103103
u32 priority;
104104
enum idxd_wq_state state;
105105
unsigned long flags;
106-
union wqcfg wqcfg;
106+
union wqcfg *wqcfg;
107107
u32 vec_ptr; /* interrupt steering */
108108
struct dsa_hw_desc **hw_descs;
109109
int num_descs;
@@ -183,6 +183,7 @@ struct idxd_device {
183183
int max_wq_size;
184184
int token_limit;
185185
int nr_tokens; /* non-reserved tokens */
186+
unsigned int wqcfg_size;
186187

187188
union sw_err_reg sw_err;
188189
wait_queue_head_t cmd_waitq;

drivers/dma/idxd/init.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,9 @@ static int idxd_setup_internals(struct idxd_device *idxd)
178178
wq->idxd_cdev.minor = -1;
179179
wq->max_xfer_bytes = idxd->max_xfer_bytes;
180180
wq->max_batch_size = idxd->max_batch_size;
181+
wq->wqcfg = devm_kzalloc(dev, idxd->wqcfg_size, GFP_KERNEL);
182+
if (!wq->wqcfg)
183+
return -ENOMEM;
181184
}
182185

183186
for (i = 0; i < idxd->max_engines; i++) {
@@ -251,6 +254,8 @@ static void idxd_read_caps(struct idxd_device *idxd)
251254
dev_dbg(dev, "total workqueue size: %u\n", idxd->max_wq_size);
252255
idxd->max_wqs = idxd->hw.wq_cap.num_wqs;
253256
dev_dbg(dev, "max workqueues: %u\n", idxd->max_wqs);
257+
idxd->wqcfg_size = 1 << (idxd->hw.wq_cap.wqcfg_size + IDXD_WQCFG_MIN);
258+
dev_dbg(dev, "wqcfg size: %u\n", idxd->wqcfg_size);
254259

255260
/* reading operation capabilities */
256261
for (i = 0; i < 4; i++) {

drivers/dma/idxd/registers.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
#define IDXD_MMIO_BAR 0
1010
#define IDXD_WQ_BAR 2
11-
#define IDXD_PORTAL_SIZE 0x4000
11+
#define IDXD_PORTAL_SIZE PAGE_SIZE
1212

1313
/* MMIO Device BAR0 Registers */
1414
#define IDXD_VER_OFFSET 0x00
@@ -43,7 +43,8 @@ union wq_cap_reg {
4343
struct {
4444
u64 total_wq_size:16;
4545
u64 num_wqs:8;
46-
u64 rsvd:24;
46+
u64 wqcfg_size:4;
47+
u64 rsvd:20;
4748
u64 shared_mode:1;
4849
u64 dedicated_mode:1;
4950
u64 rsvd2:1;
@@ -55,6 +56,7 @@ union wq_cap_reg {
5556
u64 bits;
5657
} __packed;
5758
#define IDXD_WQCAP_OFFSET 0x20
59+
#define IDXD_WQCFG_MIN 5
5860

5961
union group_cap_reg {
6062
struct {
@@ -333,4 +335,23 @@ union wqcfg {
333335
};
334336
u32 bits[8];
335337
} __packed;
338+
339+
/*
340+
* This macro calculates the offset into the WQCFG register
341+
* idxd - struct idxd *
342+
* n - wq id
343+
* ofs - the index of the 32b dword for the config register
344+
*
345+
* The WQCFG register block is divided into groups per each wq. The n index
346+
* allows us to move to the register group that's for that particular wq.
347+
* Each register is 32bits. The ofs gives us the number of register to access.
348+
*/
349+
#define WQCFG_OFFSET(_idxd_dev, n, ofs) \
350+
({\
351+
typeof(_idxd_dev) __idxd_dev = (_idxd_dev); \
352+
(__idxd_dev)->wqcfg_offset + (n) * (__idxd_dev)->wqcfg_size + sizeof(u32) * (ofs); \
353+
})
354+
355+
#define WQCFG_STRIDES(_idxd_dev) ((_idxd_dev)->wqcfg_size / sizeof(u32))
356+
336357
#endif

drivers/dma/idxd/submit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ int idxd_submit_desc(struct idxd_wq *wq, struct idxd_desc *desc)
7474
if (idxd->state != IDXD_DEV_ENABLED)
7575
return -EIO;
7676

77-
portal = wq->dportal + idxd_get_wq_portal_offset(IDXD_PORTAL_UNLIMITED);
77+
portal = wq->dportal;
7878
/*
7979
* The wmb() flushes writes to coherent DMA data before possibly
8080
* triggering a DMA read. The wmb() is necessary even on UP because

drivers/dma/ioat/dca.c

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,16 +40,6 @@
4040
#define DCA2_TAG_MAP_BYTE3 0x82
4141
#define DCA2_TAG_MAP_BYTE4 0x82
4242

43-
/* verify if tag map matches expected values */
44-
static inline int dca2_tag_map_valid(u8 *tag_map)
45-
{
46-
return ((tag_map[0] == DCA2_TAG_MAP_BYTE0) &&
47-
(tag_map[1] == DCA2_TAG_MAP_BYTE1) &&
48-
(tag_map[2] == DCA2_TAG_MAP_BYTE2) &&
49-
(tag_map[3] == DCA2_TAG_MAP_BYTE3) &&
50-
(tag_map[4] == DCA2_TAG_MAP_BYTE4));
51-
}
52-
5343
/*
5444
* "Legacy" DCA systems do not implement the DCA register set in the
5545
* I/OAT device. Software needs direct support for their tag mappings.

drivers/dma/pl330.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2799,7 +2799,7 @@ pl330_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dst,
27992799
* If burst size is smaller than bus width then make sure we only
28002800
* transfer one at a time to avoid a burst stradling an MFIFO entry.
28012801
*/
2802-
if (desc->rqcfg.brst_size * 8 < pl330->pcfg.data_bus_width)
2802+
if (burst * 8 < pl330->pcfg.data_bus_width)
28032803
desc->rqcfg.brst_len = 1;
28042804

28052805
desc->bytes_requested = len;

drivers/dma/ti/k3-udma-private.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ EXPORT_SYMBOL(xudma_rflow_is_gp);
8383
#define XUDMA_GET_PUT_RESOURCE(res) \
8484
struct udma_##res *xudma_##res##_get(struct udma_dev *ud, int id) \
8585
{ \
86-
return __udma_reserve_##res(ud, false, id); \
86+
return __udma_reserve_##res(ud, UDMA_TP_NORMAL, id); \
8787
} \
8888
EXPORT_SYMBOL(xudma_##res##_get); \
8989
\

drivers/dma/ti/omap-dma.c

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1522,29 +1522,38 @@ static void omap_dma_free(struct omap_dmadev *od)
15221522
}
15231523
}
15241524

1525+
/* Currently used by omap2 & 3 to block deeper SoC idle states */
1526+
static bool omap_dma_busy(struct omap_dmadev *od)
1527+
{
1528+
struct omap_chan *c;
1529+
int lch = -1;
1530+
1531+
while (1) {
1532+
lch = find_next_bit(od->lch_bitmap, od->lch_count, lch + 1);
1533+
if (lch >= od->lch_count)
1534+
break;
1535+
c = od->lch_map[lch];
1536+
if (!c)
1537+
continue;
1538+
if (omap_dma_chan_read(c, CCR) & CCR_ENABLE)
1539+
return true;
1540+
}
1541+
1542+
return false;
1543+
}
1544+
15251545
/* Currently only used for omap2. For omap1, also a check for lcd_dma is needed */
15261546
static int omap_dma_busy_notifier(struct notifier_block *nb,
15271547
unsigned long cmd, void *v)
15281548
{
15291549
struct omap_dmadev *od;
1530-
struct omap_chan *c;
1531-
int lch = -1;
15321550

15331551
od = container_of(nb, struct omap_dmadev, nb);
15341552

15351553
switch (cmd) {
15361554
case CPU_CLUSTER_PM_ENTER:
1537-
while (1) {
1538-
lch = find_next_bit(od->lch_bitmap, od->lch_count,
1539-
lch + 1);
1540-
if (lch >= od->lch_count)
1541-
break;
1542-
c = od->lch_map[lch];
1543-
if (!c)
1544-
continue;
1545-
if (omap_dma_chan_read(c, CCR) & CCR_ENABLE)
1546-
return NOTIFY_BAD;
1547-
}
1555+
if (omap_dma_busy(od))
1556+
return NOTIFY_BAD;
15481557
break;
15491558
case CPU_CLUSTER_PM_ENTER_FAILED:
15501559
case CPU_CLUSTER_PM_EXIT:
@@ -1595,6 +1604,8 @@ static int omap_dma_context_notifier(struct notifier_block *nb,
15951604

15961605
switch (cmd) {
15971606
case CPU_CLUSTER_PM_ENTER:
1607+
if (omap_dma_busy(od))
1608+
return NOTIFY_BAD;
15981609
omap_dma_context_save(od);
15991610
break;
16001611
case CPU_CLUSTER_PM_ENTER_FAILED:

0 commit comments

Comments
 (0)