<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>i.MX ProcessorsのトピックI.MX7. Linux SPI Slave with DMA</title>
    <link>https://community.nxp.com/t5/i-MX-Processors/I-MX7-Linux-SPI-Slave-with-DMA/m-p/952334#M142333</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Dear all,&lt;/P&gt;&lt;P&gt;I am trying to create a custom linux driver &lt;SPAN class="" lang="en"&gt;&lt;SPAN class="" title=""&gt;with support spi slave dma mode.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN class=""&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN class=""&gt;I changed imx7d-var-som.dtsi.&lt;/SPAN&gt;&lt;/P&gt;&lt;BLOCKQUOTE class="jive_macro_quote jive-quote jive_text_macro"&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; custom_spi {&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #address-cells = &amp;lt;1&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #size-cells = &amp;lt;0&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; compatible = "oct, custom_spi";&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; reg = &amp;lt;0x30830000 0x10000&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pinctrl-names = "default", "sleep";&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pinctrl-0 = &amp;lt;&amp;amp;pinctrl_ecspi2&amp;gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; interrupts = &amp;lt;GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clocks = &amp;lt;&amp;amp;clks IMX7D_ECSPI2_ROOT_CLK&amp;gt;,&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&amp;amp;clks IMX7D_ECSPI2_ROOT_CLK&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clock-names = "ipg", "per";&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dmas = &amp;lt;&amp;amp;sdma 2 7 1&amp;gt;, &amp;lt;&amp;amp;sdma 3 7 2&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dma-names = "rx", "tx";&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; status = "okay";&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;amp;ecspi2 {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;fsl,spi-num-chipselects = &amp;lt;1&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;pinctrl-names = "default", "sleep";&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;pinctrl-0 = &amp;lt;&amp;amp;pinctrl_ecspi2&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;cs-gpios = &amp;lt;&amp;amp;gpio4 23 0&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;status = "disable";&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;spidev0: spi@0 {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;compatible = "spidev";&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;reg = &amp;lt;0&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;spi-max-frequency = &amp;lt;54000000&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;};&lt;BR /&gt;};&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;&lt;SPAN class=""&gt;My driver custom_spi.c:&lt;/SPAN&gt;&lt;/P&gt;&lt;BLOCKQUOTE class="jive_macro_quote jive-quote jive_text_macro"&gt;&lt;P&gt;static int custom_spi_probe(struct platform_device *pdev){&amp;nbsp; &lt;BR /&gt;&amp;nbsp; int ret_val = 0;&lt;BR /&gt;&amp;nbsp; int spi_addr = 0x30830000; &amp;nbsp;&lt;BR /&gt;&amp;nbsp; u32 temp;&lt;BR /&gt;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; dev = &amp;amp;pdev-&amp;gt;dev; &amp;nbsp;&lt;BR /&gt;&amp;nbsp; ret_val = register_chrdev(MAJOR_NUM_CUSTOM_SPI, DEVICE_NAME, &amp;amp;Fops);&lt;BR /&gt;&amp;nbsp;&lt;BR /&gt;&amp;nbsp; if (ret_val &amp;lt; 0) { &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; printk("%s failed with %d\n",&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Sorry, registering the character device ", ret_val);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ret_val;&lt;BR /&gt;&amp;nbsp; }&lt;BR /&gt;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; clk_ipg = devm_clk_get(&amp;amp;pdev-&amp;gt;dev, "ipg");&lt;BR /&gt;&amp;nbsp; clk_per = devm_clk_get(&amp;amp;pdev-&amp;gt;dev, "per");&lt;BR /&gt;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; clk_prepare_enable(clk_per);&lt;BR /&gt;&amp;nbsp; clk_prepare_enable(clk_ipg);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; spi_base = ioremap(0x30830000, 0x1000);&lt;BR /&gt;&amp;nbsp; // Disable SPI&lt;BR /&gt;&amp;nbsp; ctrl = readl(spi_base + MX51_ECSPI_CTRL);&lt;BR /&gt;&amp;nbsp; ctrl &amp;amp;= ~MX51_ECSPI_CTRL_ENABLE;&lt;BR /&gt;&amp;nbsp; //writel(MX51_ECSPI_CTRL_ENABLE, spi_base + MX51_ECSPI_CTRL);&lt;BR /&gt;&amp;nbsp; writel(ctrl, spi_base + MX51_ECSPI_CTRL);&lt;BR /&gt;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; ccm_base = ioremap(0x30380000, 0x10000);&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;BR /&gt;&amp;nbsp; gpio_base = ioremap(0x30200000, 0x100); &lt;BR /&gt;&amp;nbsp; temp = readl(gpio_base + 0x04);&lt;BR /&gt;&amp;nbsp; writel(temp | (0x1 &amp;lt;&amp;lt; 13), gpio_base + 0x04);&lt;BR /&gt;&amp;nbsp; writel((0x1 &amp;lt;&amp;lt; 13), gpio_base);&lt;BR /&gt;&amp;nbsp; iomux_base = ioremap(0x30330000, 0x10000);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; return ret_val;&lt;BR /&gt;}&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;&lt;SPAN class="" lang="en"&gt;&lt;SPAN class="" title=""&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN class="" lang="en"&gt;&lt;SPAN class="" title=""&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;BLOCKQUOTE class="jive_macro_quote jive-quote jive_text_macro"&gt;&lt;P&gt;static void dma_callback(void *data){&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;enum dma_status dmastat; &lt;BR /&gt;&amp;nbsp;&amp;nbsp; struct dma_tx_state state; &lt;BR /&gt;&amp;nbsp;&amp;nbsp; size_t count;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; printk("dma_callback\n");&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;dmastat = dmaengine_tx_status(dma_rx, cookie, &amp;amp;state);&lt;BR /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;if (dmastat == DMA_ERROR) {&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;printk("dma_callback error\n");&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;return;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;int slave_read_dma(unsigned long ioctl_param){&lt;BR /&gt; &amp;nbsp; &amp;nbsp; int res = 0;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unsigned int ii, jj;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; u32 ctrl, cfg;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; u32 clock, pre, post, length, temp;&lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int irq_num; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int ret_val = 0;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int spi_addr = 0x30830000; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dma_cap_mask_t mask;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct dma_slave_config slave_config;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void *data; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int nent; &lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; memset(&amp;amp;rx_ring, 0, sizeof(rx_ring)); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; data = kmalloc(SPI_MAX_DMA_XFER, GFP_KERNEL); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rx_ring.buf = data;&lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dma_cap_zero(mask);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dma_cap_set(DMA_CYCLIC, mask);&lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dma_rx = dma_request_slave_channel(dev, "rx");&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (IS_ERR(dma_rx)){&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printk("can't get the RX DMA channel, error %ld\n", PTR_ERR(dma_rx));&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sg_init_table(&amp;amp;sg_rx, 1); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sg_set_page(&amp;amp;sg_rx, virt_to_page(rx_ring.buf), SPI_MAX_DMA_XFER, offset_in_page(rx_ring.buf)); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nent = dma_map_sg(dev, &amp;amp;sg_rx, 1, DMA_FROM_DEVICE); &lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Configure the slave DMA&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; memset(&amp;amp;slave_config, 0, sizeof(slave_config));&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;slave_config.direction = DMA_DEV_TO_MEM; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slave_config.src_addr = spi_addr + MXC_CSPIRXDATA;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slave_config.src_maxburst = 1;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //slave_config.device_fc = true; &lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret_val = dmaengine_slave_config(dma_rx, &amp;amp;slave_config);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ret_val)&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printk("RX dma configuration failed with %d\n", ret_val);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;rxdesc = dmaengine_prep_dma_cyclic(dma_rx, sg_dma_address(&amp;amp;sg_rx), sg_dma_len(&amp;amp;sg_rx), &amp;nbsp;&amp;nbsp;&amp;nbsp;sg_dma_len(&amp;amp;sg_rx)/2, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;rxdesc-&amp;gt;callback = dma_callback;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cookie = dmaengine_submit(rxdesc);&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; writel(0x00, iomux_base + 0x0184);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ctrl = MX51_ECSPI_CTRL_ENABLE;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // set Master or Slave mode&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //ctrl |= MX51_ECSPI_CTRL_MODE_MASK;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// Enable SPI_RDY handling (falling edge/level triggered).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// set clock speed&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pre = 0x04;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; post = 0x00;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; clock = (pre &amp;lt;&amp;lt; MX51_ECSPI_CTRL_PREDIV_OFFSET) | (post &amp;lt;&amp;lt; MX51_ECSPI_CTRL_POSTDIV_OFFSET);&lt;BR /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;ctrl |= clock;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// set chip select to use&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctrl |= MX51_ECSPI_CTRL_CS(0);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// set burst length&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; length = 32;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctrl |= (length - 1) &amp;lt;&amp;lt; MX51_ECSPI_CTRL_BL_OFFSET; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctrl |= MX51_ECSPI_CTRL_SMC;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// write CONTROLREG&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; writel(ctrl, spi_base + MX51_ECSPI_CTRL);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;udelay(50); &lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cfg = readl(spi_base + MX51_ECSPI_CONFIG); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //cfg |= MX51_ECSPI_CONFIG_SBBCTRL(0); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cfg |= MX51_ECSPI_CONFIG_SCLKPOL(0);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cfg &amp;amp;= ~MX51_ECSPI_CONFIG_SSBPOL(0);&lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // write CONFIGREG&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; writel(cfg, spi_base + MX51_ECSPI_CONFIG);&lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //writel(0xBA0B, spi_base + MX51_ECSPI_DMA);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //writel(0x9190, spi_base + MX51_ECSPI_DMA);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; writel(0xA09F, spi_base + MX51_ECSPI_DMA); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mdelay(50);&lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return res;&lt;BR /&gt;}&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;&lt;SPAN class=""&gt;But I don't received any byte. And the callback function from DMA engine not called.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN class=""&gt;Without DMA my driver works fine.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN class="" lang="en"&gt;&lt;SPAN class="" title=""&gt;Maybe what other settings are needed for DMA?&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN class=""&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Mon, 07 Oct 2019 07:17:57 GMT</pubDate>
    <dc:creator>r_gabdulhakov</dc:creator>
    <dc:date>2019-10-07T07:17:57Z</dc:date>
    <item>
      <title>I.MX7. Linux SPI Slave with DMA</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/I-MX7-Linux-SPI-Slave-with-DMA/m-p/952334#M142333</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Dear all,&lt;/P&gt;&lt;P&gt;I am trying to create a custom linux driver &lt;SPAN class="" lang="en"&gt;&lt;SPAN class="" title=""&gt;with support spi slave dma mode.&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN class=""&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN class=""&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN class=""&gt;I changed imx7d-var-som.dtsi.&lt;/SPAN&gt;&lt;/P&gt;&lt;BLOCKQUOTE class="jive_macro_quote jive-quote jive_text_macro"&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; custom_spi {&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #address-cells = &amp;lt;1&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; #size-cells = &amp;lt;0&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; compatible = "oct, custom_spi";&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; reg = &amp;lt;0x30830000 0x10000&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pinctrl-names = "default", "sleep";&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; pinctrl-0 = &amp;lt;&amp;amp;pinctrl_ecspi2&amp;gt;;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; interrupts = &amp;lt;GIC_SPI 32 IRQ_TYPE_LEVEL_HIGH&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clocks = &amp;lt;&amp;amp;clks IMX7D_ECSPI2_ROOT_CLK&amp;gt;,&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&amp;amp;clks IMX7D_ECSPI2_ROOT_CLK&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; clock-names = "ipg", "per";&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dmas = &amp;lt;&amp;amp;sdma 2 7 1&amp;gt;, &amp;lt;&amp;amp;sdma 3 7 2&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dma-names = "rx", "tx";&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; status = "okay";&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;amp;ecspi2 {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;fsl,spi-num-chipselects = &amp;lt;1&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;pinctrl-names = "default", "sleep";&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;pinctrl-0 = &amp;lt;&amp;amp;pinctrl_ecspi2&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;cs-gpios = &amp;lt;&amp;amp;gpio4 23 0&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;status = "disable";&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;spidev0: spi@0 {&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;compatible = "spidev";&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;reg = &amp;lt;0&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;spi-max-frequency = &amp;lt;54000000&amp;gt;;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;};&lt;BR /&gt;};&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;&lt;SPAN class=""&gt;My driver custom_spi.c:&lt;/SPAN&gt;&lt;/P&gt;&lt;BLOCKQUOTE class="jive_macro_quote jive-quote jive_text_macro"&gt;&lt;P&gt;static int custom_spi_probe(struct platform_device *pdev){&amp;nbsp; &lt;BR /&gt;&amp;nbsp; int ret_val = 0;&lt;BR /&gt;&amp;nbsp; int spi_addr = 0x30830000; &amp;nbsp;&lt;BR /&gt;&amp;nbsp; u32 temp;&lt;BR /&gt;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; dev = &amp;amp;pdev-&amp;gt;dev; &amp;nbsp;&lt;BR /&gt;&amp;nbsp; ret_val = register_chrdev(MAJOR_NUM_CUSTOM_SPI, DEVICE_NAME, &amp;amp;Fops);&lt;BR /&gt;&amp;nbsp;&lt;BR /&gt;&amp;nbsp; if (ret_val &amp;lt; 0) { &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; printk("%s failed with %d\n",&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "Sorry, registering the character device ", ret_val);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return ret_val;&lt;BR /&gt;&amp;nbsp; }&lt;BR /&gt;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; clk_ipg = devm_clk_get(&amp;amp;pdev-&amp;gt;dev, "ipg");&lt;BR /&gt;&amp;nbsp; clk_per = devm_clk_get(&amp;amp;pdev-&amp;gt;dev, "per");&lt;BR /&gt;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; clk_prepare_enable(clk_per);&lt;BR /&gt;&amp;nbsp; clk_prepare_enable(clk_ipg);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; spi_base = ioremap(0x30830000, 0x1000);&lt;BR /&gt;&amp;nbsp; // Disable SPI&lt;BR /&gt;&amp;nbsp; ctrl = readl(spi_base + MX51_ECSPI_CTRL);&lt;BR /&gt;&amp;nbsp; ctrl &amp;amp;= ~MX51_ECSPI_CTRL_ENABLE;&lt;BR /&gt;&amp;nbsp; //writel(MX51_ECSPI_CTRL_ENABLE, spi_base + MX51_ECSPI_CTRL);&lt;BR /&gt;&amp;nbsp; writel(ctrl, spi_base + MX51_ECSPI_CTRL);&lt;BR /&gt;&amp;nbsp; &lt;BR /&gt;&amp;nbsp; ccm_base = ioremap(0x30380000, 0x10000);&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;BR /&gt;&amp;nbsp; gpio_base = ioremap(0x30200000, 0x100); &lt;BR /&gt;&amp;nbsp; temp = readl(gpio_base + 0x04);&lt;BR /&gt;&amp;nbsp; writel(temp | (0x1 &amp;lt;&amp;lt; 13), gpio_base + 0x04);&lt;BR /&gt;&amp;nbsp; writel((0x1 &amp;lt;&amp;lt; 13), gpio_base);&lt;BR /&gt;&amp;nbsp; iomux_base = ioremap(0x30330000, 0x10000);&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp; return ret_val;&lt;BR /&gt;}&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;&lt;SPAN class="" lang="en"&gt;&lt;SPAN class="" title=""&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN class="" lang="en"&gt;&lt;SPAN class="" title=""&gt;&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;BLOCKQUOTE class="jive_macro_quote jive-quote jive_text_macro"&gt;&lt;P&gt;static void dma_callback(void *data){&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;enum dma_status dmastat; &lt;BR /&gt;&amp;nbsp;&amp;nbsp; struct dma_tx_state state; &lt;BR /&gt;&amp;nbsp;&amp;nbsp; size_t count;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp; printk("dma_callback\n");&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;dmastat = dmaengine_tx_status(dma_rx, cookie, &amp;amp;state);&lt;BR /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;if (dmastat == DMA_ERROR) {&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;printk("dma_callback error\n");&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;return;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;BR /&gt;}&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;int slave_read_dma(unsigned long ioctl_param){&lt;BR /&gt; &amp;nbsp; &amp;nbsp; int res = 0;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; unsigned int ii, jj;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; u32 ctrl, cfg;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; u32 clock, pre, post, length, temp;&lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int irq_num; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int ret_val = 0;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int spi_addr = 0x30830000; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dma_cap_mask_t mask;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; struct dma_slave_config slave_config;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void *data; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; int nent; &lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; memset(&amp;amp;rx_ring, 0, sizeof(rx_ring)); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; data = kmalloc(SPI_MAX_DMA_XFER, GFP_KERNEL); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rx_ring.buf = data;&lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dma_cap_zero(mask);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dma_cap_set(DMA_CYCLIC, mask);&lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; dma_rx = dma_request_slave_channel(dev, "rx");&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (IS_ERR(dma_rx)){&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printk("can't get the RX DMA channel, error %ld\n", PTR_ERR(dma_rx));&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sg_init_table(&amp;amp;sg_rx, 1); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; sg_set_page(&amp;amp;sg_rx, virt_to_page(rx_ring.buf), SPI_MAX_DMA_XFER, offset_in_page(rx_ring.buf)); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; nent = dma_map_sg(dev, &amp;amp;sg_rx, 1, DMA_FROM_DEVICE); &lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Configure the slave DMA&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; memset(&amp;amp;slave_config, 0, sizeof(slave_config));&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;slave_config.direction = DMA_DEV_TO_MEM; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slave_config.src_addr = spi_addr + MXC_CSPIRXDATA;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; slave_config.src_maxburst = 1;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //slave_config.device_fc = true; &lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ret_val = dmaengine_slave_config(dma_rx, &amp;amp;slave_config);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ret_val)&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; printk("RX dma configuration failed with %d\n", ret_val);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;rxdesc = dmaengine_prep_dma_cyclic(dma_rx, sg_dma_address(&amp;amp;sg_rx), sg_dma_len(&amp;amp;sg_rx), &amp;nbsp;&amp;nbsp;&amp;nbsp;sg_dma_len(&amp;amp;sg_rx)/2, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;rxdesc-&amp;gt;callback = dma_callback;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cookie = dmaengine_submit(rxdesc);&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; writel(0x00, iomux_base + 0x0184);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;ctrl = MX51_ECSPI_CTRL_ENABLE;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // set Master or Slave mode&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //ctrl |= MX51_ECSPI_CTRL_MODE_MASK;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// Enable SPI_RDY handling (falling edge/level triggered).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// set clock speed&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; pre = 0x04;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; post = 0x00;&lt;BR /&gt;&amp;nbsp;&amp;nbsp; clock = (pre &amp;lt;&amp;lt; MX51_ECSPI_CTRL_PREDIV_OFFSET) | (post &amp;lt;&amp;lt; MX51_ECSPI_CTRL_POSTDIV_OFFSET);&lt;BR /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;ctrl |= clock;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// set chip select to use&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctrl |= MX51_ECSPI_CTRL_CS(0);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// set burst length&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; length = 32;&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctrl |= (length - 1) &amp;lt;&amp;lt; MX51_ECSPI_CTRL_BL_OFFSET; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctrl |= MX51_ECSPI_CTRL_SMC;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;// write CONTROLREG&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; writel(ctrl, spi_base + MX51_ECSPI_CTRL);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;udelay(50); &lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cfg = readl(spi_base + MX51_ECSPI_CONFIG); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //cfg |= MX51_ECSPI_CONFIG_SBBCTRL(0); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cfg |= MX51_ECSPI_CONFIG_SCLKPOL(0);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cfg &amp;amp;= ~MX51_ECSPI_CONFIG_SSBPOL(0);&lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; // write CONFIGREG&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; writel(cfg, spi_base + MX51_ECSPI_CONFIG);&lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //writel(0xBA0B, spi_base + MX51_ECSPI_DMA);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; //writel(0x9190, spi_base + MX51_ECSPI_DMA);&lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; writel(0xA09F, spi_base + MX51_ECSPI_DMA); &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mdelay(50);&lt;BR /&gt; &lt;BR /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; return res;&lt;BR /&gt;}&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;&lt;SPAN class=""&gt;But I don't received any byte. And the callback function from DMA engine not called.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN class=""&gt;Without DMA my driver works fine.&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN class="" lang="en"&gt;&lt;SPAN class="" title=""&gt;Maybe what other settings are needed for DMA?&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;P&gt;&lt;SPAN class=""&gt;&amp;nbsp;&lt;/SPAN&gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 07 Oct 2019 07:17:57 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/I-MX7-Linux-SPI-Slave-with-DMA/m-p/952334#M142333</guid>
      <dc:creator>r_gabdulhakov</dc:creator>
      <dc:date>2019-10-07T07:17:57Z</dc:date>
    </item>
    <item>
      <title>Re: I.MX7. Linux SPI Slave with DMA</title>
      <link>https://community.nxp.com/t5/i-MX-Processors/I-MX7-Linux-SPI-Slave-with-DMA/m-p/952335#M142334</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Renat&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I am afraid spi slave with dma is not supported in nxp linux releases, standard&lt;/P&gt;&lt;P&gt;way is to proceed with extended support of &lt;A class="link-titled" href="https://www.nxp.com/design/engineering-services:SW-SUPPORT" title="https://www.nxp.com/design/engineering-services:SW-SUPPORT"&gt;Commercial Support and Engineering Services | NXP&lt;/A&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Best regards&lt;BR /&gt;igor&lt;BR /&gt;-----------------------------------------------------------------------------------------------------------------------&lt;BR /&gt;Note: If this post answers your question, please click the Correct Answer button. Thank you!&lt;BR /&gt;-----------------------------------------------------------------------------------------------------------------------&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 07 Oct 2019 23:16:39 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-Processors/I-MX7-Linux-SPI-Slave-with-DMA/m-p/952335#M142334</guid>
      <dc:creator>igorpadykov</dc:creator>
      <dc:date>2019-10-07T23:16:39Z</dc:date>
    </item>
  </channel>
</rss>

