linux/drivers/fpga/xilinx-afi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Xilinx FPGA AFI bridge.
   4 * Copyright (c) 2018 Xilinx Inc.
   5 */
   6
   7#include <linux/err.h>
   8#include <linux/firmware/xlnx-zynqmp.h>
   9#include <linux/io.h>
  10#include <linux/module.h>
  11#include <linux/of.h>
  12#include <linux/platform_device.h>
  13#include <linux/slab.h>
  14
  15/**
  16 * struct afi_fpga - AFI register description
  17 * @value: value to be written to the register
  18 * @regid: Register id for the register to be written
  19 */
  20struct afi_fpga {
  21        u32 value;
  22        u32 regid;
  23};
  24
  25static int afi_fpga_probe(struct platform_device *pdev)
  26{
  27        struct afi_fpga *afi_fpga;
  28        struct device_node *np = pdev->dev.of_node;
  29        int ret;
  30        int i, entries, pairs;
  31        u32 reg, val;
  32
  33        afi_fpga = devm_kzalloc(&pdev->dev, sizeof(*afi_fpga), GFP_KERNEL);
  34        if (!afi_fpga)
  35                return -ENOMEM;
  36        platform_set_drvdata(pdev, afi_fpga);
  37
  38        entries = of_property_count_u32_elems(np, "config-afi");
  39        if (!entries || (entries % 2)) {
  40                dev_err(&pdev->dev, "Invalid number of registers\n");
  41                return -EINVAL;
  42        }
  43        pairs = entries / 2;
  44
  45        for (i = 0; i < pairs; i++) {
  46                ret = of_property_read_u32_index(np, "config-afi", i * 2,
  47                                                 &reg);
  48                if (ret) {
  49                        dev_err(&pdev->dev, "failed to read register\n");
  50                        return -EINVAL;
  51                }
  52                ret = of_property_read_u32_index(np, "config-afi", i * 2 + 1,
  53                                                 &val);
  54                if (ret) {
  55                        dev_err(&pdev->dev, "failed to read value\n");
  56                        return -EINVAL;
  57                }
  58                ret = zynqmp_pm_afi(reg, val);
  59                if (ret < 0) {
  60                        dev_err(&pdev->dev, "AFI register write error %d\n",
  61                                ret);
  62                        return ret;
  63                }
  64        }
  65        return 0;
  66}
  67
  68static const struct of_device_id afi_fpga_ids[] = {
  69        { .compatible = "xlnx,afi-fpga" },
  70        { },
  71};
  72MODULE_DEVICE_TABLE(of, afi_fpga_ids);
  73
  74static struct platform_driver afi_fpga_driver = {
  75        .driver = {
  76                .name = "afi-fpga",
  77                .of_match_table = afi_fpga_ids,
  78        },
  79        .probe = afi_fpga_probe,
  80};
  81module_platform_driver(afi_fpga_driver);
  82
  83MODULE_DESCRIPTION("FPGA afi module");
  84MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti.datta@xilinx.com>");
  85MODULE_LICENSE("GPL v2");
  86