.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0+ |
---|
1 | 2 | /* |
---|
2 | 3 | * Copyright (C) 2015, Michael Lee <igvtee@gmail.com> |
---|
3 | 4 | * MTK HSDMA support |
---|
4 | | - * |
---|
5 | | - * This program is free software; you can redistribute it and/or modify it |
---|
6 | | - * under the terms of the GNU General Public License as published by the |
---|
7 | | - * Free Software Foundation; either version 2 of the License, or (at your |
---|
8 | | - * option) any later version. |
---|
9 | | - * |
---|
10 | 5 | */ |
---|
11 | 6 | |
---|
12 | 7 | #include <linux/dmaengine.h> |
---|
.. | .. |
---|
191 | 186 | } |
---|
192 | 187 | |
---|
193 | 188 | static inline void mtk_hsdma_write(struct mtk_hsdam_engine *hsdma, |
---|
194 | | - unsigned reg, u32 val) |
---|
| 189 | + unsigned int reg, u32 val) |
---|
195 | 190 | { |
---|
196 | 191 | writel(val, hsdma->base + reg); |
---|
197 | 192 | } |
---|
.. | .. |
---|
213 | 208 | |
---|
214 | 209 | static void hsdma_dump_reg(struct mtk_hsdam_engine *hsdma) |
---|
215 | 210 | { |
---|
216 | | - dev_dbg(hsdma->ddev.dev, "tbase %08x, tcnt %08x, " \ |
---|
217 | | - "tctx %08x, tdtx: %08x, rbase %08x, " \ |
---|
| 211 | + dev_dbg(hsdma->ddev.dev, "tbase %08x, tcnt %08x, " |
---|
| 212 | + "tctx %08x, tdtx: %08x, rbase %08x, " |
---|
218 | 213 | "rcnt %08x, rctx %08x, rdtx %08x\n", |
---|
219 | 214 | mtk_hsdma_read(hsdma, HSDMA_REG_TX_BASE), |
---|
220 | 215 | mtk_hsdma_read(hsdma, HSDMA_REG_TX_CNT), |
---|
.. | .. |
---|
225 | 220 | mtk_hsdma_read(hsdma, HSDMA_REG_RX_CRX), |
---|
226 | 221 | mtk_hsdma_read(hsdma, HSDMA_REG_RX_DRX)); |
---|
227 | 222 | |
---|
228 | | - dev_dbg(hsdma->ddev.dev, "info %08x, glo %08x, delay %08x, " \ |
---|
229 | | - "intr_stat %08x, intr_mask %08x\n", |
---|
| 223 | + dev_dbg(hsdma->ddev.dev, "info %08x, glo %08x, delay %08x, intr_stat %08x, intr_mask %08x\n", |
---|
230 | 224 | mtk_hsdma_read(hsdma, HSDMA_REG_INFO), |
---|
231 | 225 | mtk_hsdma_read(hsdma, HSDMA_REG_GLO_CFG), |
---|
232 | 226 | mtk_hsdma_read(hsdma, HSDMA_REG_DELAY_INT), |
---|
.. | .. |
---|
242 | 236 | int i; |
---|
243 | 237 | |
---|
244 | 238 | dev_dbg(hsdma->ddev.dev, "tx idx: %d, rx idx: %d\n", |
---|
245 | | - chan->tx_idx, chan->rx_idx); |
---|
| 239 | + chan->tx_idx, chan->rx_idx); |
---|
246 | 240 | |
---|
247 | 241 | for (i = 0; i < HSDMA_DESCS_NUM; i++) { |
---|
248 | 242 | tx_desc = &chan->tx_ring[i]; |
---|
249 | 243 | rx_desc = &chan->rx_ring[i]; |
---|
250 | 244 | |
---|
251 | | - dev_dbg(hsdma->ddev.dev, "%d tx addr0: %08x, flags %08x, " \ |
---|
| 245 | + dev_dbg(hsdma->ddev.dev, "%d tx addr0: %08x, flags %08x, " |
---|
252 | 246 | "tx addr1: %08x, rx addr0 %08x, flags %08x\n", |
---|
253 | | - i, tx_desc->addr0, tx_desc->flags, \ |
---|
| 247 | + i, tx_desc->addr0, tx_desc->flags, |
---|
254 | 248 | tx_desc->addr1, rx_desc->addr0, rx_desc->flags); |
---|
255 | 249 | } |
---|
256 | 250 | } |
---|
.. | .. |
---|
269 | 263 | /* init desc value */ |
---|
270 | 264 | for (i = 0; i < HSDMA_DESCS_NUM; i++) { |
---|
271 | 265 | chan->tx_ring[i].addr0 = 0; |
---|
272 | | - chan->tx_ring[i].flags = HSDMA_DESC_LS0 | |
---|
273 | | - HSDMA_DESC_DONE; |
---|
| 266 | + chan->tx_ring[i].flags = HSDMA_DESC_LS0 | HSDMA_DESC_DONE; |
---|
274 | 267 | } |
---|
275 | 268 | for (i = 0; i < HSDMA_DESCS_NUM; i++) { |
---|
276 | 269 | chan->rx_ring[i].addr0 = 0; |
---|
.. | .. |
---|
419 | 412 | vchan_cookie_complete(&desc->vdesc); |
---|
420 | 413 | chan_issued = gdma_next_desc(chan); |
---|
421 | 414 | } |
---|
422 | | - } else |
---|
| 415 | + } else { |
---|
423 | 416 | dev_dbg(hsdma->ddev.dev, "no desc to complete\n"); |
---|
| 417 | + } |
---|
424 | 418 | |
---|
425 | 419 | if (chan_issued) |
---|
426 | 420 | set_bit(chan->id, &hsdma->chan_issued); |
---|
.. | .. |
---|
439 | 433 | if (likely(status & HSDMA_INT_RX_Q0)) |
---|
440 | 434 | tasklet_schedule(&hsdma->task); |
---|
441 | 435 | else |
---|
442 | | - dev_dbg(hsdma->ddev.dev, "unhandle irq status %08x\n", |
---|
443 | | - status); |
---|
| 436 | + dev_dbg(hsdma->ddev.dev, "unhandle irq status %08x\n", status); |
---|
444 | 437 | /* clean intr bits */ |
---|
445 | 438 | mtk_hsdma_write(hsdma, HSDMA_REG_INT_STATUS, status); |
---|
446 | 439 | |
---|
.. | .. |
---|
457 | 450 | if (gdma_next_desc(chan)) { |
---|
458 | 451 | set_bit(chan->id, &hsdma->chan_issued); |
---|
459 | 452 | tasklet_schedule(&hsdma->task); |
---|
460 | | - } else |
---|
| 453 | + } else { |
---|
461 | 454 | dev_dbg(hsdma->ddev.dev, "no desc to issue\n"); |
---|
| 455 | + } |
---|
462 | 456 | } |
---|
463 | 457 | spin_unlock_bh(&chan->vchan.lock); |
---|
464 | 458 | } |
---|
.. | .. |
---|
473 | 467 | if (len <= 0) |
---|
474 | 468 | return NULL; |
---|
475 | 469 | |
---|
476 | | - desc = kzalloc(sizeof(struct mtk_hsdma_desc), GFP_ATOMIC); |
---|
| 470 | + desc = kzalloc(sizeof(*desc), GFP_ATOMIC); |
---|
477 | 471 | if (!desc) { |
---|
478 | 472 | dev_err(c->device->dev, "alloc memcpy decs error\n"); |
---|
479 | 473 | return NULL; |
---|
.. | .. |
---|
539 | 533 | mtk_hsdma_chan_done(hsdma, chan); |
---|
540 | 534 | } |
---|
541 | 535 | |
---|
542 | | -static void mtk_hsdma_tasklet(unsigned long arg) |
---|
| 536 | +static void mtk_hsdma_tasklet(struct tasklet_struct *t) |
---|
543 | 537 | { |
---|
544 | | - struct mtk_hsdam_engine *hsdma = (struct mtk_hsdam_engine *)arg; |
---|
| 538 | + struct mtk_hsdam_engine *hsdma = from_tasklet(hsdma, t, task); |
---|
545 | 539 | |
---|
546 | 540 | mtk_hsdma_rx(hsdma); |
---|
547 | 541 | mtk_hsdma_tx(hsdma); |
---|
.. | .. |
---|
553 | 547 | int i; |
---|
554 | 548 | |
---|
555 | 549 | chan->tx_ring = dma_alloc_coherent(hsdma->ddev.dev, |
---|
556 | | - 2 * HSDMA_DESCS_NUM * sizeof(*chan->tx_ring), |
---|
| 550 | + 2 * HSDMA_DESCS_NUM * |
---|
| 551 | + sizeof(*chan->tx_ring), |
---|
557 | 552 | &chan->desc_addr, GFP_ATOMIC | __GFP_ZERO); |
---|
558 | 553 | if (!chan->tx_ring) |
---|
559 | 554 | goto no_mem; |
---|
.. | .. |
---|
574 | 569 | { |
---|
575 | 570 | if (chan->tx_ring) { |
---|
576 | 571 | dma_free_coherent(hsdma->ddev.dev, |
---|
577 | | - 2 * HSDMA_DESCS_NUM * sizeof(*chan->tx_ring), |
---|
578 | | - chan->tx_ring, chan->desc_addr); |
---|
| 572 | + 2 * HSDMA_DESCS_NUM * sizeof(*chan->tx_ring), |
---|
| 573 | + chan->tx_ring, chan->desc_addr); |
---|
579 | 574 | chan->tx_ring = NULL; |
---|
580 | 575 | chan->rx_ring = NULL; |
---|
581 | 576 | } |
---|
.. | .. |
---|
655 | 650 | struct mtk_hsdma_chan *chan; |
---|
656 | 651 | struct mtk_hsdam_engine *hsdma; |
---|
657 | 652 | struct dma_device *dd; |
---|
658 | | - struct resource *res; |
---|
659 | 653 | int ret; |
---|
660 | 654 | int irq; |
---|
661 | 655 | void __iomem *base; |
---|
.. | .. |
---|
669 | 663 | return -EINVAL; |
---|
670 | 664 | |
---|
671 | 665 | hsdma = devm_kzalloc(&pdev->dev, sizeof(*hsdma), GFP_KERNEL); |
---|
672 | | - if (!hsdma) { |
---|
673 | | - dev_err(&pdev->dev, "alloc dma device failed\n"); |
---|
| 666 | + if (!hsdma) |
---|
674 | 667 | return -EINVAL; |
---|
675 | | - } |
---|
676 | 668 | |
---|
677 | | - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
---|
678 | | - base = devm_ioremap_resource(&pdev->dev, res); |
---|
| 669 | + base = devm_platform_ioremap_resource(pdev, 0); |
---|
679 | 670 | if (IS_ERR(base)) |
---|
680 | 671 | return PTR_ERR(base); |
---|
681 | 672 | hsdma->base = base + HSDMA_BASE_OFFSET; |
---|
682 | | - tasklet_init(&hsdma->task, mtk_hsdma_tasklet, (unsigned long)hsdma); |
---|
| 673 | + tasklet_setup(&hsdma->task, mtk_hsdma_tasklet); |
---|
683 | 674 | |
---|
684 | 675 | irq = platform_get_irq(pdev, 0); |
---|
685 | | - if (irq < 0) { |
---|
686 | | - dev_err(&pdev->dev, "failed to get irq\n"); |
---|
| 676 | + if (irq < 0) |
---|
687 | 677 | return -EINVAL; |
---|
688 | | - } |
---|
689 | 678 | ret = devm_request_irq(&pdev->dev, irq, mtk_hsdma_irq, |
---|
690 | 679 | 0, dev_name(&pdev->dev), hsdma); |
---|
691 | 680 | if (ret) { |
---|