[bug report] dmaengine: tegra: Add tegra gpcdma driver

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Akhil R,

The patch ee17028009d4: "dmaengine: tegra: Add tegra gpcdma driver"
from Feb 25, 2022, leads to the following Smatch static checker
warning:

	drivers/dma/tegra186-gpc-dma.c:1071 tegra_dma_prep_slave_sg()
	error: uninitialized symbol 'slave_bw'.

drivers/dma/tegra186-gpc-dma.c
    981 static struct dma_async_tx_descriptor *
    982 tegra_dma_prep_slave_sg(struct dma_chan *dc, struct scatterlist *sgl,
    983                         unsigned int sg_len, enum dma_transfer_direction direction,
    984                         unsigned long flags, void *context)
    985 {
    986         struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc);
    987         unsigned int max_dma_count = tdc->tdma->chip_data->max_dma_count;
    988         u32 csr, mc_seq, apb_ptr = 0, mmio_seq = 0;
    989         enum dma_slave_buswidth slave_bw;
    990         struct tegra_dma_sg_req *sg_req;
    991         struct tegra_dma_desc *dma_desc;
    992         struct scatterlist *sg;
    993         u32 burst_size;
    994         unsigned int i;
    995         int ret;
    996 
    997         if (!tdc->config_init) {
    998                 dev_err(tdc2dev(tdc), "DMA channel is not configured\n");
    999                 return NULL;
    1000         }
    1001         if (sg_len < 1) {
    1002                 dev_err(tdc2dev(tdc), "Invalid segment length %d\n", sg_len);
    1003                 return NULL;
    1004         }
    1005 
    1006         ret = tegra_dma_sid_reserve(tdc, direction);
    1007         if (ret)
    1008                 return NULL;
    1009 
    1010         ret = get_transfer_param(tdc, direction, &apb_ptr, &mmio_seq, &csr,
    1011                                  &burst_size, &slave_bw);

*slave_bw is not set fro the DMA_MEM_TO_MEM case.

    1012         if (ret < 0)
    1013                 return NULL;
    1014 
    1015         /* Enable once or continuous mode */
    1016         csr |= TEGRA_GPCDMA_CSR_ONCE;
    1017         /* Program the slave id in requestor select */
    1018         csr |= FIELD_PREP(TEGRA_GPCDMA_CSR_REQ_SEL_MASK, tdc->slave_id);
    1019         /* Enable IRQ mask */
    1020         csr |= TEGRA_GPCDMA_CSR_IRQ_MASK;
    1021         /* Configure default priority weight for the channel*/
    1022         csr |= FIELD_PREP(TEGRA_GPCDMA_CSR_WEIGHT, 1);
    1023 
    1024         /* Enable the DMA interrupt */
    1025         if (flags & DMA_PREP_INTERRUPT)
    1026                 csr |= TEGRA_GPCDMA_CSR_IE_EOC;
    1027 
    1028         mc_seq =  tdc_read(tdc, TEGRA_GPCDMA_CHAN_MCSEQ);
    1029         /* retain stream-id and clean rest */
    1030         mc_seq &= TEGRA_GPCDMA_MCSEQ_STREAM_ID0_MASK;
    1031 
    1032         /* Set the address wrapping on both MC and MMIO side */
    1033 
    1034         mc_seq |= FIELD_PREP(TEGRA_GPCDMA_MCSEQ_WRAP0,
    1035                              TEGRA_GPCDMA_MCSEQ_WRAP_NONE);
    1036         mc_seq |= FIELD_PREP(TEGRA_GPCDMA_MCSEQ_WRAP1,
    1037                              TEGRA_GPCDMA_MCSEQ_WRAP_NONE);
    1038         mmio_seq |= FIELD_PREP(TEGRA_GPCDMA_MMIOSEQ_WRAP_WORD, 1);
    1039 
    1040         /* Program 2 MC outstanding requests by default. */
    1041         mc_seq |= FIELD_PREP(TEGRA_GPCDMA_MCSEQ_REQ_COUNT, 1);
    1042 
    1043         /* Setting MC burst size depending on MMIO burst size */
    1044         if (burst_size == 64)
    1045                 mc_seq |= TEGRA_GPCDMA_MCSEQ_BURST_16;
    1046         else
    1047                 mc_seq |= TEGRA_GPCDMA_MCSEQ_BURST_2;
    1048 
    1049         dma_desc = kzalloc(struct_size(dma_desc, sg_req, sg_len), GFP_NOWAIT);
    1050         if (!dma_desc)
    1051                 return NULL;
    1052 
    1053         dma_desc->sg_count = sg_len;
    1054         sg_req = dma_desc->sg_req;
    1055 
    1056         /* Make transfer requests */
    1057         for_each_sg(sgl, sg, sg_len, i) {
    1058                 u32 len;
    1059                 dma_addr_t mem;
    1060 
    1061                 mem = sg_dma_address(sg);
    1062                 len = sg_dma_len(sg);
    1063 
    1064                 if ((len & 3) || (mem & 3) || len > max_dma_count) {
    1065                         dev_err(tdc2dev(tdc),
    1066                                 "DMA length/memory address is not supported\n");
    1067                         kfree(dma_desc);
    1068                         return NULL;
    1069                 }
    1070 
--> 1071                 mmio_seq |= get_burst_size(tdc, burst_size, slave_bw, len);
                                                                     ^^^^^^^^
used here.

    1072                 dma_desc->bytes_req += len;
    1073 
    1074                 if (direction == DMA_MEM_TO_DEV) {
    1075                         sg_req[i].ch_regs.src_ptr = mem;
    1076                         sg_req[i].ch_regs.dst_ptr = apb_ptr;
    1077                         sg_req[i].ch_regs.high_addr_ptr =
    1078                                 FIELD_PREP(TEGRA_GPCDMA_HIGH_ADDR_SRC_PTR, (mem >> 32));
    1079                 } else if (direction == DMA_DEV_TO_MEM) {
    1080                         sg_req[i].ch_regs.src_ptr = apb_ptr;
    1081                         sg_req[i].ch_regs.dst_ptr = mem;
    1082                         sg_req[i].ch_regs.high_addr_ptr =
    1083                                 FIELD_PREP(TEGRA_GPCDMA_HIGH_ADDR_DST_PTR, (mem >> 32));
    1084                 }
    1085 
    1086                 /*
    1087                  * Word count register takes input in words. Writing a value
    1088                  * of N into word count register means a req of (N+1) words.
    1089                  */
    1090                 sg_req[i].ch_regs.wcount = ((len - 4) >> 2);
    1091                 sg_req[i].ch_regs.csr = csr;
    1092                 sg_req[i].ch_regs.mmio_seq = mmio_seq;
    1093                 sg_req[i].ch_regs.mc_seq = mc_seq;
    1094                 sg_req[i].len = len;
    1095         }
    1096 
    1097         dma_desc->cyclic = false;
    1098         return vchan_tx_prep(&tdc->vc, &dma_desc->vd, flags);
    1099 }

regards,
dan carpenter



[Index of Archives]     [ARM Kernel]     [Linux ARM]     [Linux ARM MSM]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux