dmaengine: axi-dmac: add regmap support
authorAlexandru Ardelean <alexandru.ardelean@analog.com>
Thu, 6 Jun 2019 10:45:50 +0000 (13:45 +0300)
committerVinod Koul <vkoul@kernel.org>
Fri, 14 Jun 2019 05:53:47 +0000 (11:23 +0530)
The registers for AXI DMAC are detailed at:
  https://wiki.analog.com/resources/fpga/docs/axi_dmac#register_map

This change adds regmap support for these registers, in case some wants to
have a more direct access to them via this interface.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
[vkoul: fixed code style issue]
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/dma/Kconfig
drivers/dma/dma-axi-dmac.c

index 76859aa2688cbee1f5a96834905596ce0ade2835..b1d109d62c15058dcf788397137697cd5bb9955b 100644 (file)
@@ -102,6 +102,7 @@ config AXI_DMAC
        depends on MICROBLAZE || NIOS2 || ARCH_ZYNQ || ARCH_ZYNQMP || ARCH_SOCFPGA || COMPILE_TEST
        select DMA_ENGINE
        select DMA_VIRTUAL_CHANNELS
+       select REGMAP_MMIO
        help
          Enable support for the Analog Devices AXI-DMAC peripheral. This DMA
          controller is often used in Analog Device's reference designs for FPGA
index 368f08cc29aa32cbcdbaa2223d97a65dcaed69c1..c12bdc7832b11169e277de0d17ed07cfeea4b5eb 100644 (file)
@@ -18,6 +18,7 @@
 #include <linux/of.h>
 #include <linux/of_dma.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
 #include <linux/slab.h>
 #include <linux/fpga/adi-axi-common.h>
 
@@ -678,6 +679,44 @@ static void axi_dmac_desc_free(struct virt_dma_desc *vdesc)
        kfree(container_of(vdesc, struct axi_dmac_desc, vdesc));
 }
 
+static bool axi_dmac_regmap_rdwr(struct device *dev, unsigned int reg)
+{
+       switch (reg) {
+       case AXI_DMAC_REG_IRQ_MASK:
+       case AXI_DMAC_REG_IRQ_SOURCE:
+       case AXI_DMAC_REG_IRQ_PENDING:
+       case AXI_DMAC_REG_CTRL:
+       case AXI_DMAC_REG_TRANSFER_ID:
+       case AXI_DMAC_REG_START_TRANSFER:
+       case AXI_DMAC_REG_FLAGS:
+       case AXI_DMAC_REG_DEST_ADDRESS:
+       case AXI_DMAC_REG_SRC_ADDRESS:
+       case AXI_DMAC_REG_X_LENGTH:
+       case AXI_DMAC_REG_Y_LENGTH:
+       case AXI_DMAC_REG_DEST_STRIDE:
+       case AXI_DMAC_REG_SRC_STRIDE:
+       case AXI_DMAC_REG_TRANSFER_DONE:
+       case AXI_DMAC_REG_ACTIVE_TRANSFER_ID:
+       case AXI_DMAC_REG_STATUS:
+       case AXI_DMAC_REG_CURRENT_SRC_ADDR:
+       case AXI_DMAC_REG_CURRENT_DEST_ADDR:
+       case AXI_DMAC_REG_PARTIAL_XFER_LEN:
+       case AXI_DMAC_REG_PARTIAL_XFER_ID:
+               return true;
+       default:
+               return false;
+       }
+}
+
+static const struct regmap_config axi_dmac_regmap_config = {
+       .reg_bits = 32,
+       .val_bits = 32,
+       .reg_stride = 4,
+       .max_register = AXI_DMAC_REG_PARTIAL_XFER_ID,
+       .readable_reg = axi_dmac_regmap_rdwr,
+       .writeable_reg = axi_dmac_regmap_rdwr,
+};
+
 /*
  * The configuration stored in the devicetree matches the configuration
  * parameters of the peripheral instance and allows the driver to know which
@@ -882,6 +921,8 @@ static int axi_dmac_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, dmac);
 
+       devm_regmap_init_mmio(&pdev->dev, dmac->base, &axi_dmac_regmap_config);
+
        return 0;
 
 err_unregister_of: