Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'dmaengine-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine

Pull dmaengine updates from Vinod Koul:

- Renesas driver conversion to RUNTIME_PM_OPS() etc

- Dropping module alias on bunch of drivers

- GPI Block event interrupt support in Qualcomm driver and updates to
I2C driver as well

* tag 'dmaengine-6.19-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine: (23 commits)
dt-bindings: dma: xilinx: Simplify dma-coherent property
dmaengine: fsl-edma: configure tcd attr with separate src and dst settings
dmaengine: st_fdma: drop unused module alias
dmaengine: bcm2835: enable compile testing
dmaengine: tegra210-adma: drop unused module alias
dmaengine: sprd: drop unused module alias
dmaengine: mmp_tdma: drop unnecessary OF node check in remove
dmaengine: mmp_tdma: drop unused module alias
dmaengine: k3dma: drop unused module alias
dmaengine: fsl-qdma: drop unused module alias
dmaengine: fsl-edma: drop unused module alias
dmaengine: dw: drop unused module alias
dmaengine: bcm2835: drop unused module alias
dmaengine: at_hdmac: add COMPILE_TEST support
dmaengine: at_hdmac: fix formats under 64-bit
i2c: i2c-qcom-geni: Add Block event interrupt support
dmaengine: qcom: gpi: Add GPI Block event interrupt support
dmaengine: idxd: drain ATS translations when disabling WQ
dmaengine: sh: Kconfig: Drop ARCH_R7S72100/ARCH_RZG2L dependency
dmaengine: rcar-dmac: Convert to NOIRQ_SYSTEM_SLEEP/RUNTIME_PM_OPS()
...

+302 -85
+1 -2
Documentation/devicetree/bindings/dma/xilinx/xlnx,zynqmp-dma-1.0.yaml
··· 59 59 power-domains: 60 60 maxItems: 1 61 61 62 - dma-coherent: 63 - description: present if dma operations are coherent 62 + dma-coherent: true 64 63 65 64 required: 66 65 - "#dma-cells"
+2 -2
drivers/dma/Kconfig
··· 102 102 103 103 config AT_HDMAC 104 104 tristate "Atmel AHB DMA support" 105 - depends on ARCH_AT91 105 + depends on ARCH_AT91 || COMPILE_TEST 106 106 select DMA_ENGINE 107 107 select DMA_VIRTUAL_CHANNELS 108 108 help ··· 143 143 144 144 config DMA_BCM2835 145 145 tristate "BCM2835 DMA engine support" 146 - depends on ARCH_BCM2835 146 + depends on ARCH_BCM2835 || COMPILE_TEST 147 147 select DMA_ENGINE 148 148 select DMA_VIRTUAL_CHANNELS 149 149
+3 -3
drivers/dma/at_hdmac.c
··· 887 887 first = xt->sgl; 888 888 889 889 dev_info(chan2dev(chan), 890 - "%s: src=%pad, dest=%pad, numf=%d, frame_size=%d, flags=0x%lx\n", 890 + "%s: src=%pad, dest=%pad, numf=%zu, frame_size=%zu, flags=0x%lx\n", 891 891 __func__, &xt->src_start, &xt->dst_start, xt->numf, 892 892 xt->frame_size, flags); 893 893 ··· 1174 1174 int i; 1175 1175 int ret; 1176 1176 1177 - dev_vdbg(chan2dev(chan), "%s: v0x%x l0x%zx f0x%lx\n", __func__, 1177 + dev_vdbg(chan2dev(chan), "%s: v0x%x l0x%x f0x%lx\n", __func__, 1178 1178 value, sg_len, flags); 1179 1179 1180 1180 if (unlikely(!sgl || !sg_len)) { ··· 1503 1503 unsigned int periods = buf_len / period_len; 1504 1504 unsigned int i; 1505 1505 1506 - dev_vdbg(chan2dev(chan), "prep_dma_cyclic: %s buf@%pad - %d (%d/%d)\n", 1506 + dev_vdbg(chan2dev(chan), "prep_dma_cyclic: %s buf@%pad - %d (%zu/%zu)\n", 1507 1507 direction == DMA_MEM_TO_DEV ? "TO DEVICE" : "FROM DEVICE", 1508 1508 &buf_addr, 1509 1509 periods, buf_len, period_len);
-1
drivers/dma/bcm2835-dma.c
··· 1060 1060 1061 1061 module_platform_driver(bcm2835_dma_driver); 1062 1062 1063 - MODULE_ALIAS("platform:bcm2835-dma"); 1064 1063 MODULE_DESCRIPTION("BCM2835 DMA engine driver"); 1065 1064 MODULE_AUTHOR("Florian Meier <florian.meier@koalo.de>"); 1066 1065 MODULE_LICENSE("GPL");
+1 -4
drivers/dma/dw/platform.c
··· 21 21 22 22 #include "internal.h" 23 23 24 - #define DRV_NAME "dw_dmac" 25 - 26 24 static int dw_probe(struct platform_device *pdev) 27 25 { 28 26 const struct dw_dma_chip_pdata *match; ··· 188 190 .remove = dw_remove, 189 191 .shutdown = dw_shutdown, 190 192 .driver = { 191 - .name = DRV_NAME, 193 + .name = "dw_dmac", 192 194 .pm = pm_sleep_ptr(&dw_dev_pm_ops), 193 195 .of_match_table = of_match_ptr(dw_dma_of_id_table), 194 196 .acpi_match_table = ACPI_PTR(dw_dma_acpi_id_table), ··· 209 211 210 212 MODULE_LICENSE("GPL v2"); 211 213 MODULE_DESCRIPTION("Synopsys DesignWare DMA Controller platform driver"); 212 - MODULE_ALIAS("platform:" DRV_NAME);
+33 -12
drivers/dma/fsl-edma-common.c
··· 206 206 mux_configure8(fsl_chan, muxaddr, ch_off, slot, enable); 207 207 } 208 208 209 - static unsigned int fsl_edma_get_tcd_attr(enum dma_slave_buswidth addr_width) 209 + static unsigned int fsl_edma_get_tcd_attr(enum dma_slave_buswidth src_addr_width, 210 + enum dma_slave_buswidth dst_addr_width) 210 211 { 211 - u32 val; 212 + u32 src_val, dst_val; 212 213 213 - if (addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) 214 - addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 214 + if (src_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) 215 + src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 216 + if (dst_addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) 217 + dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; 215 218 216 - val = ffs(addr_width) - 1; 217 - return val | (val << 8); 219 + src_val = ffs(src_addr_width) - 1; 220 + dst_val = ffs(dst_addr_width) - 1; 221 + return dst_val | (src_val << 8); 218 222 } 219 223 220 224 void fsl_edma_free_desc(struct virt_dma_desc *vdesc) ··· 616 612 617 613 dma_buf_next = dma_addr; 618 614 if (direction == DMA_MEM_TO_DEV) { 615 + if (!fsl_chan->cfg.src_addr_width) 616 + fsl_chan->cfg.src_addr_width = fsl_chan->cfg.dst_addr_width; 619 617 fsl_chan->attr = 620 - fsl_edma_get_tcd_attr(fsl_chan->cfg.dst_addr_width); 618 + fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width, 619 + fsl_chan->cfg.dst_addr_width); 621 620 nbytes = fsl_chan->cfg.dst_addr_width * 622 621 fsl_chan->cfg.dst_maxburst; 623 622 } else { 623 + if (!fsl_chan->cfg.dst_addr_width) 624 + fsl_chan->cfg.dst_addr_width = fsl_chan->cfg.src_addr_width; 624 625 fsl_chan->attr = 625 - fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width); 626 + fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width, 627 + fsl_chan->cfg.dst_addr_width); 626 628 nbytes = fsl_chan->cfg.src_addr_width * 627 629 fsl_chan->cfg.src_maxburst; 628 630 } ··· 699 689 fsl_desc->dirn = direction; 700 690 701 691 if (direction == DMA_MEM_TO_DEV) { 692 + if (!fsl_chan->cfg.src_addr_width) 693 + fsl_chan->cfg.src_addr_width = fsl_chan->cfg.dst_addr_width; 702 694 fsl_chan->attr = 703 - fsl_edma_get_tcd_attr(fsl_chan->cfg.dst_addr_width); 695 + fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width, 696 + fsl_chan->cfg.dst_addr_width); 704 697 nbytes = fsl_chan->cfg.dst_addr_width * 705 698 fsl_chan->cfg.dst_maxburst; 706 699 } else { 700 + if (!fsl_chan->cfg.dst_addr_width) 701 + fsl_chan->cfg.dst_addr_width = fsl_chan->cfg.src_addr_width; 707 702 fsl_chan->attr = 708 - fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width); 703 + fsl_edma_get_tcd_attr(fsl_chan->cfg.src_addr_width, 704 + fsl_chan->cfg.dst_addr_width); 709 705 nbytes = fsl_chan->cfg.src_addr_width * 710 706 fsl_chan->cfg.src_maxburst; 711 707 } ··· 782 766 { 783 767 struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan); 784 768 struct fsl_edma_desc *fsl_desc; 769 + u32 src_bus_width, dst_bus_width; 770 + 771 + src_bus_width = min_t(u32, DMA_SLAVE_BUSWIDTH_32_BYTES, 1 << (ffs(dma_src) - 1)); 772 + dst_bus_width = min_t(u32, DMA_SLAVE_BUSWIDTH_32_BYTES, 1 << (ffs(dma_dst) - 1)); 785 773 786 774 fsl_desc = fsl_edma_alloc_desc(fsl_chan, 1); 787 775 if (!fsl_desc) ··· 798 778 799 779 /* To match with copy_align and max_seg_size so 1 tcd is enough */ 800 780 fsl_edma_fill_tcd(fsl_chan, fsl_desc->tcd[0].vtcd, dma_src, dma_dst, 801 - fsl_edma_get_tcd_attr(DMA_SLAVE_BUSWIDTH_32_BYTES), 802 - 32, len, 0, 1, 1, 32, 0, true, true, false); 781 + fsl_edma_get_tcd_attr(src_bus_width, dst_bus_width), 782 + src_bus_width, len, 0, 1, 1, dst_bus_width, 0, true, 783 + true, false); 803 784 804 785 return vchan_tx_prep(&fsl_chan->vchan, &fsl_desc->vdesc, flags); 805 786 }
-1
drivers/dma/fsl-edma-main.c
··· 999 999 } 1000 1000 module_exit(fsl_edma_exit); 1001 1001 1002 - MODULE_ALIAS("platform:fsl-edma"); 1003 1002 MODULE_DESCRIPTION("Freescale eDMA engine driver"); 1004 1003 MODULE_LICENSE("GPL v2");
-1
drivers/dma/fsl-qdma.c
··· 1296 1296 1297 1297 module_platform_driver(fsl_qdma_driver); 1298 1298 1299 - MODULE_ALIAS("platform:fsl-qdma"); 1300 1299 MODULE_LICENSE("GPL v2"); 1301 1300 MODULE_DESCRIPTION("NXP Layerscape qDMA engine driver");
+17 -2
drivers/dma/idxd/device.c
··· 16 16 u32 *status); 17 17 static void idxd_device_wqs_clear_state(struct idxd_device *idxd); 18 18 static void idxd_wq_disable_cleanup(struct idxd_wq *wq); 19 + static int idxd_wq_config_write(struct idxd_wq *wq); 19 20 20 21 /* Interrupt control bits */ 21 22 void idxd_unmask_error_interrupts(struct idxd_device *idxd) ··· 216 215 return 0; 217 216 } 218 217 218 + /* 219 + * Disable WQ does not drain address translations, if WQ attributes are 220 + * changed before translations are drained, pending translations can 221 + * be issued using updated WQ attibutes, resulting in invalid 222 + * translations being cached in the device translation cache. 223 + * 224 + * To make sure pending translations are drained before WQ 225 + * attributes are changed, we use a WQ Drain followed by WQ Reset and 226 + * then restore the WQ configuration. 227 + */ 228 + idxd_wq_drain(wq); 229 + 219 230 operand = BIT(wq->id % 16) | ((wq->id / 16) << 16); 220 - idxd_cmd_exec(idxd, IDXD_CMD_DISABLE_WQ, operand, &status); 231 + idxd_cmd_exec(idxd, IDXD_CMD_RESET_WQ, operand, &status); 221 232 222 233 if (status != IDXD_CMDSTS_SUCCESS) { 223 - dev_dbg(dev, "WQ disable failed: %#x\n", status); 234 + dev_dbg(dev, "WQ reset failed: %#x\n", status); 224 235 return -ENXIO; 225 236 } 237 + 238 + idxd_wq_config_write(wq); 226 239 227 240 if (reset_config) 228 241 idxd_wq_disable_cleanup(wq);
-1
drivers/dma/k3dma.c
··· 1034 1034 module_platform_driver(k3_pdma_driver); 1035 1035 1036 1036 MODULE_DESCRIPTION("HiSilicon k3 DMA Driver"); 1037 - MODULE_ALIAS("platform:k3dma"); 1038 1037 MODULE_LICENSE("GPL v2");
+1 -3
drivers/dma/mmp_tdma.c
··· 554 554 555 555 static void mmp_tdma_remove(struct platform_device *pdev) 556 556 { 557 - if (pdev->dev.of_node) 558 - of_dma_controller_free(pdev->dev.of_node); 557 + of_dma_controller_free(pdev->dev.of_node); 559 558 } 560 559 561 560 static int mmp_tdma_chan_init(struct mmp_tdma_device *tdev, ··· 742 743 743 744 MODULE_LICENSE("GPL"); 744 745 MODULE_DESCRIPTION("MMP Two-Channel DMA Driver"); 745 - MODULE_ALIAS("platform:mmp-tdma"); 746 746 MODULE_AUTHOR("Leo Yan <leoy@marvell.com>"); 747 747 MODULE_AUTHOR("Zhangfei Gao <zhangfei.gao@marvell.com>");
+2 -4
drivers/dma/nbpfaxi.c
··· 1500 1500 }; 1501 1501 MODULE_DEVICE_TABLE(platform, nbpf_ids); 1502 1502 1503 - #ifdef CONFIG_PM 1504 1503 static int nbpf_runtime_suspend(struct device *dev) 1505 1504 { 1506 1505 struct nbpf_device *nbpf = dev_get_drvdata(dev); ··· 1512 1513 struct nbpf_device *nbpf = dev_get_drvdata(dev); 1513 1514 return clk_prepare_enable(nbpf->clk); 1514 1515 } 1515 - #endif 1516 1516 1517 1517 static const struct dev_pm_ops nbpf_pm_ops = { 1518 - SET_RUNTIME_PM_OPS(nbpf_runtime_suspend, nbpf_runtime_resume, NULL) 1518 + RUNTIME_PM_OPS(nbpf_runtime_suspend, nbpf_runtime_resume, NULL) 1519 1519 }; 1520 1520 1521 1521 static struct platform_driver nbpf_driver = { 1522 1522 .driver = { 1523 1523 .name = "dma-nbpf", 1524 1524 .of_match_table = nbpf_match, 1525 - .pm = &nbpf_pm_ops, 1525 + .pm = pm_ptr(&nbpf_pm_ops), 1526 1526 }, 1527 1527 .id_table = nbpf_ids, 1528 1528 .probe = nbpf_probe,
+9 -2
drivers/dma/qcom/gpi.c
··· 1619 1619 } 1620 1620 1621 1621 static int gpi_create_i2c_tre(struct gchan *chan, struct gpi_desc *desc, 1622 - struct scatterlist *sgl, enum dma_transfer_direction direction) 1622 + struct scatterlist *sgl, enum dma_transfer_direction direction, 1623 + unsigned long flags) 1623 1624 { 1624 1625 struct gpi_i2c_config *i2c = chan->config; 1625 1626 struct device *dev = chan->gpii->gpi_dev->dev; ··· 1685 1684 1686 1685 tre->dword[3] = u32_encode_bits(TRE_TYPE_DMA, TRE_FLAGS_TYPE); 1687 1686 tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_IEOT); 1687 + 1688 + if (!(flags & DMA_PREP_INTERRUPT)) 1689 + tre->dword[3] |= u32_encode_bits(1, TRE_FLAGS_BEI); 1688 1690 } 1689 1691 1690 1692 for (i = 0; i < tre_idx; i++) ··· 1831 1827 return NULL; 1832 1828 } 1833 1829 1830 + if (!(flags & DMA_PREP_INTERRUPT) && (nr - nr_tre < 2)) 1831 + return NULL; 1832 + 1834 1833 gpi_desc = kzalloc(sizeof(*gpi_desc), GFP_NOWAIT); 1835 1834 if (!gpi_desc) 1836 1835 return NULL; ··· 1842 1835 if (gchan->protocol == QCOM_GPI_SPI) { 1843 1836 i = gpi_create_spi_tre(gchan, gpi_desc, sgl, direction); 1844 1837 } else if (gchan->protocol == QCOM_GPI_I2C) { 1845 - i = gpi_create_i2c_tre(gchan, gpi_desc, sgl, direction); 1838 + i = gpi_create_i2c_tre(gchan, gpi_desc, sgl, direction, flags); 1846 1839 } else { 1847 1840 dev_err(dev, "invalid peripheral: %d\n", gchan->protocol); 1848 1841 kfree(gpi_desc);
+1 -1
drivers/dma/sh/Kconfig
··· 50 50 51 51 config RZ_DMAC 52 52 tristate "Renesas RZ DMA Controller" 53 - depends on ARCH_R7S72100 || ARCH_RZG2L || COMPILE_TEST 53 + depends on ARCH_RENESAS || COMPILE_TEST 54 54 select RENESAS_DMA 55 55 select DMA_VIRTUAL_CHANNELS 56 56 help
+4 -12
drivers/dma/sh/rcar-dmac.c
··· 1728 1728 * Power management 1729 1729 */ 1730 1730 1731 - #ifdef CONFIG_PM 1732 - static int rcar_dmac_runtime_suspend(struct device *dev) 1733 - { 1734 - return 0; 1735 - } 1736 - 1737 1731 static int rcar_dmac_runtime_resume(struct device *dev) 1738 1732 { 1739 1733 struct rcar_dmac *dmac = dev_get_drvdata(dev); 1740 1734 1741 1735 return rcar_dmac_init(dmac); 1742 1736 } 1743 - #endif 1744 1737 1745 1738 static const struct dev_pm_ops rcar_dmac_pm = { 1746 1739 /* ··· 1741 1748 * - Wait for the current transfer to complete and stop the device, 1742 1749 * - Resume transfers, if any. 1743 1750 */ 1744 - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1745 - pm_runtime_force_resume) 1746 - SET_RUNTIME_PM_OPS(rcar_dmac_runtime_suspend, rcar_dmac_runtime_resume, 1747 - NULL) 1751 + NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 1752 + pm_runtime_force_resume) 1753 + RUNTIME_PM_OPS(NULL, rcar_dmac_runtime_resume, NULL) 1748 1754 }; 1749 1755 1750 1756 /* ----------------------------------------------------------------------------- ··· 2028 2036 2029 2037 static struct platform_driver rcar_dmac_driver = { 2030 2038 .driver = { 2031 - .pm = &rcar_dmac_pm, 2039 + .pm = pm_ptr(&rcar_dmac_pm), 2032 2040 .name = "rcar-dmac", 2033 2041 .of_match_table = rcar_dmac_of_ids, 2034 2042 },
+4 -7
drivers/dma/sh/usb-dmac.c
··· 670 670 * Power management 671 671 */ 672 672 673 - #ifdef CONFIG_PM 674 673 static int usb_dmac_runtime_suspend(struct device *dev) 675 674 { 676 675 struct usb_dmac *dmac = dev_get_drvdata(dev); ··· 690 691 691 692 return usb_dmac_init(dmac); 692 693 } 693 - #endif /* CONFIG_PM */ 694 694 695 695 static const struct dev_pm_ops usb_dmac_pm = { 696 - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 697 - pm_runtime_force_resume) 698 - SET_RUNTIME_PM_OPS(usb_dmac_runtime_suspend, usb_dmac_runtime_resume, 699 - NULL) 696 + NOIRQ_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, 697 + pm_runtime_force_resume) 698 + RUNTIME_PM_OPS(usb_dmac_runtime_suspend, usb_dmac_runtime_resume, NULL) 700 699 }; 701 700 702 701 /* ----------------------------------------------------------------------------- ··· 891 894 892 895 static struct platform_driver usb_dmac_driver = { 893 896 .driver = { 894 - .pm = &usb_dmac_pm, 897 + .pm = pm_ptr(&usb_dmac_pm), 895 898 .name = "usb-dmac", 896 899 .of_match_table = usb_dmac_of_ids, 897 900 },
-1
drivers/dma/sprd-dma.c
··· 1311 1311 MODULE_DESCRIPTION("DMA driver for Spreadtrum"); 1312 1312 MODULE_AUTHOR("Baolin Wang <baolin.wang@spreadtrum.com>"); 1313 1313 MODULE_AUTHOR("Eric Long <eric.long@spreadtrum.com>"); 1314 - MODULE_ALIAS("platform:sprd-dma");
-1
drivers/dma/st_fdma.c
··· 866 866 MODULE_DESCRIPTION("STMicroelectronics FDMA engine driver"); 867 867 MODULE_AUTHOR("Ludovic.barre <Ludovic.barre@st.com>"); 868 868 MODULE_AUTHOR("Peter Griffin <peter.griffin@linaro.org>"); 869 - MODULE_ALIAS("platform:" DRIVER_NAME);
-1
drivers/dma/tegra210-adma.c
··· 1230 1230 1231 1231 module_platform_driver(tegra_admac_driver); 1232 1232 1233 - MODULE_ALIAS("platform:tegra210-adma"); 1234 1233 MODULE_DESCRIPTION("NVIDIA Tegra ADMA driver"); 1235 1234 MODULE_AUTHOR("Dara Ramesh <dramesh@nvidia.com>"); 1236 1235 MODULE_AUTHOR("Jon Hunter <jonathanh@nvidia.com>");
+224 -24
drivers/i2c/busses/i2c-qcom-geni.c
··· 77 77 #define XFER_TIMEOUT HZ 78 78 #define RST_TIMEOUT HZ 79 79 80 + #define QCOM_I2C_MIN_NUM_OF_MSGS_MULTI_DESC 2 81 + 82 + /** 83 + * struct geni_i2c_gpi_multi_desc_xfer - Structure for multi transfer support 84 + * 85 + * @msg_idx_cnt: Current message index being processed in the transfer 86 + * @unmap_msg_cnt: Number of messages that have been unmapped 87 + * @irq_cnt: Number of transfer completion interrupts received 88 + * @dma_buf: Array of virtual addresses for DMA-safe buffers 89 + * @dma_addr: Array of DMA addresses corresponding to the buffers 90 + */ 91 + struct geni_i2c_gpi_multi_desc_xfer { 92 + u32 msg_idx_cnt; 93 + u32 unmap_msg_cnt; 94 + u32 irq_cnt; 95 + void **dma_buf; 96 + dma_addr_t *dma_addr; 97 + }; 98 + 80 99 struct geni_i2c_dev { 81 100 struct geni_se se; 82 101 u32 tx_wm; ··· 118 99 struct dma_chan *rx_c; 119 100 bool gpi_mode; 120 101 bool abort_done; 102 + bool is_tx_multi_desc_xfer; 103 + u32 num_msgs; 104 + struct geni_i2c_gpi_multi_desc_xfer i2c_multi_desc_config; 121 105 }; 122 106 123 107 struct geni_i2c_desc { ··· 521 499 static void i2c_gpi_cb_result(void *cb, const struct dmaengine_result *result) 522 500 { 523 501 struct geni_i2c_dev *gi2c = cb; 502 + struct geni_i2c_gpi_multi_desc_xfer *tx_multi_xfer; 524 503 525 504 if (result->result != DMA_TRANS_NOERROR) { 526 505 dev_err(gi2c->se.dev, "DMA txn failed:%d\n", result->result); 527 506 gi2c->err = -EIO; 528 507 } else if (result->residue) { 529 508 dev_dbg(gi2c->se.dev, "DMA xfer has pending: %d\n", result->residue); 509 + } 510 + 511 + if (gi2c->is_tx_multi_desc_xfer) { 512 + tx_multi_xfer = &gi2c->i2c_multi_desc_config; 513 + tx_multi_xfer->irq_cnt++; 530 514 } 531 515 532 516 complete(&gi2c->done); ··· 553 525 } 554 526 } 555 527 556 - static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg *msg, 528 + /** 529 + * geni_i2c_gpi_multi_desc_unmap() - Unmaps DMA buffers post multi message TX transfers 530 + * @gi2c: I2C dev handle 531 + * @msgs: Array of I2C messages 532 + * @peripheral: Pointer to gpi_i2c_config 533 + */ 534 + static void geni_i2c_gpi_multi_desc_unmap(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], 535 + struct gpi_i2c_config *peripheral) 536 + { 537 + u32 msg_xfer_cnt, wr_idx = 0; 538 + struct geni_i2c_gpi_multi_desc_xfer *tx_multi_xfer = &gi2c->i2c_multi_desc_config; 539 + 540 + msg_xfer_cnt = gi2c->err ? tx_multi_xfer->msg_idx_cnt : tx_multi_xfer->irq_cnt; 541 + 542 + /* Unmap the processed DMA buffers based on the received interrupt count */ 543 + for (; tx_multi_xfer->unmap_msg_cnt < msg_xfer_cnt; tx_multi_xfer->unmap_msg_cnt++) { 544 + wr_idx = tx_multi_xfer->unmap_msg_cnt; 545 + geni_i2c_gpi_unmap(gi2c, &msgs[wr_idx], 546 + tx_multi_xfer->dma_buf[wr_idx], 547 + tx_multi_xfer->dma_addr[wr_idx], 548 + NULL, 0); 549 + 550 + if (tx_multi_xfer->unmap_msg_cnt == gi2c->num_msgs - 1) { 551 + kfree(tx_multi_xfer->dma_buf); 552 + kfree(tx_multi_xfer->dma_addr); 553 + break; 554 + } 555 + } 556 + } 557 + 558 + /** 559 + * geni_i2c_gpi_multi_xfer_timeout_handler() - Handles multi message transfer timeout 560 + * @dev: Pointer to the corresponding dev node 561 + * @multi_xfer: Pointer to the geni_i2c_gpi_multi_desc_xfer 562 + * @transfer_timeout_msecs: Timeout value in milliseconds 563 + * @transfer_comp: Completion object of the transfer 564 + * 565 + * This function waits for the completion of each processed transfer messages 566 + * based on the interrupts generated upon transfer completion. 567 + * 568 + * Return: On success returns 0, -ETIMEDOUT on timeout. 569 + */ 570 + static int geni_i2c_gpi_multi_xfer_timeout_handler(struct device *dev, 571 + struct geni_i2c_gpi_multi_desc_xfer *multi_xfer, 572 + u32 transfer_timeout_msecs, 573 + struct completion *transfer_comp) 574 + { 575 + int i; 576 + u32 time_left; 577 + 578 + for (i = 0; i < multi_xfer->msg_idx_cnt - 1; i++) { 579 + reinit_completion(transfer_comp); 580 + 581 + if (multi_xfer->msg_idx_cnt != multi_xfer->irq_cnt) { 582 + time_left = wait_for_completion_timeout(transfer_comp, 583 + transfer_timeout_msecs); 584 + if (!time_left) { 585 + dev_err(dev, "%s: Transfer timeout\n", __func__); 586 + return -ETIMEDOUT; 587 + } 588 + } 589 + } 590 + return 0; 591 + } 592 + 593 + static int geni_i2c_gpi(struct geni_i2c_dev *gi2c, struct i2c_msg msgs[], 557 594 struct dma_slave_config *config, dma_addr_t *dma_addr_p, 558 595 void **buf, unsigned int op, struct dma_chan *dma_chan) 559 596 { ··· 630 537 enum dma_transfer_direction dma_dirn; 631 538 struct dma_async_tx_descriptor *desc; 632 539 int ret; 540 + struct geni_i2c_gpi_multi_desc_xfer *gi2c_gpi_xfer; 541 + dma_cookie_t cookie; 542 + u32 msg_idx; 633 543 634 544 peripheral = config->peripheral_config; 545 + gi2c_gpi_xfer = &gi2c->i2c_multi_desc_config; 546 + msg_idx = gi2c_gpi_xfer->msg_idx_cnt; 635 547 636 - dma_buf = i2c_get_dma_safe_msg_buf(msg, 1); 637 - if (!dma_buf) 638 - return -ENOMEM; 548 + dma_buf = i2c_get_dma_safe_msg_buf(&msgs[msg_idx], 1); 549 + if (!dma_buf) { 550 + ret = -ENOMEM; 551 + goto out; 552 + } 639 553 640 554 if (op == I2C_WRITE) 641 555 map_dirn = DMA_TO_DEVICE; 642 556 else 643 557 map_dirn = DMA_FROM_DEVICE; 644 558 645 - addr = dma_map_single(gi2c->se.dev->parent, dma_buf, msg->len, map_dirn); 559 + addr = dma_map_single(gi2c->se.dev->parent, dma_buf, 560 + msgs[msg_idx].len, map_dirn); 646 561 if (dma_mapping_error(gi2c->se.dev->parent, addr)) { 647 - i2c_put_dma_safe_msg_buf(dma_buf, msg, false); 648 - return -ENOMEM; 562 + i2c_put_dma_safe_msg_buf(dma_buf, &msgs[msg_idx], false); 563 + ret = -ENOMEM; 564 + goto out; 565 + } 566 + 567 + if (gi2c->is_tx_multi_desc_xfer) { 568 + flags = DMA_CTRL_ACK; 569 + 570 + /* BEI bit to be cleared for last TRE */ 571 + if (msg_idx == gi2c->num_msgs - 1) 572 + flags |= DMA_PREP_INTERRUPT; 573 + } else { 574 + flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; 649 575 } 650 576 651 577 /* set the length as message for rx txn */ 652 - peripheral->rx_len = msg->len; 578 + peripheral->rx_len = msgs[msg_idx].len; 653 579 peripheral->op = op; 654 580 655 581 ret = dmaengine_slave_config(dma_chan, config); ··· 679 567 680 568 peripheral->set_config = 0; 681 569 peripheral->multi_msg = true; 682 - flags = DMA_PREP_INTERRUPT | DMA_CTRL_ACK; 683 570 684 571 if (op == I2C_WRITE) 685 572 dma_dirn = DMA_MEM_TO_DEV; 686 573 else 687 574 dma_dirn = DMA_DEV_TO_MEM; 688 575 689 - desc = dmaengine_prep_slave_single(dma_chan, addr, msg->len, dma_dirn, flags); 576 + desc = dmaengine_prep_slave_single(dma_chan, addr, msgs[msg_idx].len, 577 + dma_dirn, flags); 578 + if (!desc && !(flags & DMA_PREP_INTERRUPT)) { 579 + /* Retry with interrupt if not enough TREs */ 580 + flags |= DMA_PREP_INTERRUPT; 581 + desc = dmaengine_prep_slave_single(dma_chan, addr, msgs[msg_idx].len, 582 + dma_dirn, flags); 583 + } 584 + 690 585 if (!desc) { 691 586 dev_err(gi2c->se.dev, "prep_slave_sg failed\n"); 692 587 ret = -EIO; ··· 703 584 desc->callback_result = i2c_gpi_cb_result; 704 585 desc->callback_param = gi2c; 705 586 706 - dmaengine_submit(desc); 707 - *buf = dma_buf; 708 - *dma_addr_p = addr; 587 + if (!((msgs[msg_idx].flags & I2C_M_RD) && op == I2C_WRITE)) 588 + gi2c_gpi_xfer->msg_idx_cnt++; 709 589 590 + cookie = dmaengine_submit(desc); 591 + if (dma_submit_error(cookie)) { 592 + dev_err(gi2c->se.dev, 593 + "%s: dmaengine_submit failed (%d)\n", __func__, cookie); 594 + ret = -EINVAL; 595 + goto err_config; 596 + } 597 + 598 + if (gi2c->is_tx_multi_desc_xfer) { 599 + gi2c_gpi_xfer->dma_buf[msg_idx] = dma_buf; 600 + gi2c_gpi_xfer->dma_addr[msg_idx] = addr; 601 + 602 + dma_async_issue_pending(gi2c->tx_c); 603 + 604 + if ((msg_idx == (gi2c->num_msgs - 1)) || flags & DMA_PREP_INTERRUPT) { 605 + ret = geni_i2c_gpi_multi_xfer_timeout_handler(gi2c->se.dev, gi2c_gpi_xfer, 606 + XFER_TIMEOUT, &gi2c->done); 607 + if (ret) { 608 + dev_err(gi2c->se.dev, 609 + "I2C multi write msg transfer timeout: %d\n", 610 + ret); 611 + gi2c->err = ret; 612 + return ret; 613 + } 614 + } 615 + } else { 616 + /* Non multi descriptor message transfer */ 617 + *buf = dma_buf; 618 + *dma_addr_p = addr; 619 + } 710 620 return 0; 711 621 712 622 err_config: 713 - dma_unmap_single(gi2c->se.dev->parent, addr, msg->len, map_dirn); 714 - i2c_put_dma_safe_msg_buf(dma_buf, msg, false); 623 + dma_unmap_single(gi2c->se.dev->parent, addr, 624 + msgs[msg_idx].len, map_dirn); 625 + i2c_put_dma_safe_msg_buf(dma_buf, &msgs[msg_idx], false); 626 + 627 + out: 628 + gi2c->err = ret; 715 629 return ret; 716 630 } 717 631 ··· 756 604 unsigned long time_left; 757 605 dma_addr_t tx_addr, rx_addr; 758 606 void *tx_buf = NULL, *rx_buf = NULL; 607 + struct geni_i2c_gpi_multi_desc_xfer *tx_multi_xfer; 759 608 const struct geni_i2c_clk_fld *itr = gi2c->clk_fld; 760 609 761 610 config.peripheral_config = &peripheral; ··· 770 617 peripheral.set_config = 1; 771 618 peripheral.multi_msg = false; 772 619 620 + gi2c->num_msgs = num; 621 + gi2c->is_tx_multi_desc_xfer = false; 622 + 623 + tx_multi_xfer = &gi2c->i2c_multi_desc_config; 624 + memset(tx_multi_xfer, 0, sizeof(struct geni_i2c_gpi_multi_desc_xfer)); 625 + 626 + /* 627 + * If number of write messages are two and higher then 628 + * configure hardware for multi descriptor transfers with BEI. 629 + */ 630 + if (num >= QCOM_I2C_MIN_NUM_OF_MSGS_MULTI_DESC) { 631 + gi2c->is_tx_multi_desc_xfer = true; 632 + for (i = 0; i < num; i++) { 633 + if (msgs[i].flags & I2C_M_RD) { 634 + /* 635 + * Multi descriptor transfer with BEI 636 + * support is enabled for write transfers. 637 + * TODO: Add BEI optimization support for 638 + * read transfers later. 639 + */ 640 + gi2c->is_tx_multi_desc_xfer = false; 641 + break; 642 + } 643 + } 644 + } 645 + 646 + if (gi2c->is_tx_multi_desc_xfer) { 647 + tx_multi_xfer->dma_buf = kcalloc(num, sizeof(void *), GFP_KERNEL); 648 + tx_multi_xfer->dma_addr = kcalloc(num, sizeof(dma_addr_t), GFP_KERNEL); 649 + if (!tx_multi_xfer->dma_buf || !tx_multi_xfer->dma_addr) { 650 + ret = -ENOMEM; 651 + goto err; 652 + } 653 + } 654 + 773 655 for (i = 0; i < num; i++) { 774 656 gi2c->cur = &msgs[i]; 775 657 gi2c->err = 0; ··· 815 627 peripheral.stretch = 1; 816 628 817 629 peripheral.addr = msgs[i].addr; 630 + if (i > 0 && (!(msgs[i].flags & I2C_M_RD))) 631 + peripheral.multi_msg = false; 818 632 819 - ret = geni_i2c_gpi(gi2c, &msgs[i], &config, 633 + ret = geni_i2c_gpi(gi2c, msgs, &config, 820 634 &tx_addr, &tx_buf, I2C_WRITE, gi2c->tx_c); 821 635 if (ret) 822 636 goto err; 823 637 824 638 if (msgs[i].flags & I2C_M_RD) { 825 - ret = geni_i2c_gpi(gi2c, &msgs[i], &config, 639 + ret = geni_i2c_gpi(gi2c, msgs, &config, 826 640 &rx_addr, &rx_buf, I2C_READ, gi2c->rx_c); 827 641 if (ret) 828 642 goto err; ··· 832 642 dma_async_issue_pending(gi2c->rx_c); 833 643 } 834 644 835 - dma_async_issue_pending(gi2c->tx_c); 836 - 837 - time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT); 838 - if (!time_left) 839 - gi2c->err = -ETIMEDOUT; 645 + if (!gi2c->is_tx_multi_desc_xfer) { 646 + dma_async_issue_pending(gi2c->tx_c); 647 + time_left = wait_for_completion_timeout(&gi2c->done, XFER_TIMEOUT); 648 + if (!time_left) { 649 + dev_err(gi2c->se.dev, "%s:I2C timeout\n", __func__); 650 + gi2c->err = -ETIMEDOUT; 651 + } 652 + } 840 653 841 654 if (gi2c->err) { 842 655 ret = gi2c->err; 843 656 goto err; 844 657 } 845 658 846 - geni_i2c_gpi_unmap(gi2c, &msgs[i], tx_buf, tx_addr, rx_buf, rx_addr); 659 + if (!gi2c->is_tx_multi_desc_xfer) 660 + geni_i2c_gpi_unmap(gi2c, &msgs[i], tx_buf, tx_addr, rx_buf, rx_addr); 661 + else if (tx_multi_xfer->unmap_msg_cnt != tx_multi_xfer->irq_cnt) 662 + geni_i2c_gpi_multi_desc_unmap(gi2c, msgs, &peripheral); 847 663 } 848 664 849 665 return num; ··· 858 662 dev_err(gi2c->se.dev, "GPI transfer failed: %d\n", ret); 859 663 dmaengine_terminate_sync(gi2c->rx_c); 860 664 dmaengine_terminate_sync(gi2c->tx_c); 861 - geni_i2c_gpi_unmap(gi2c, &msgs[i], tx_buf, tx_addr, rx_buf, rx_addr); 665 + if (gi2c->is_tx_multi_desc_xfer) 666 + geni_i2c_gpi_multi_desc_unmap(gi2c, msgs, &peripheral); 667 + else 668 + geni_i2c_gpi_unmap(gi2c, &msgs[i], tx_buf, tx_addr, rx_buf, rx_addr); 669 + 862 670 return ret; 863 671 } 864 672