|
@@ -19,10 +19,77 @@
|
|
|
|
|
|
#include "dfl.h"
|
|
|
|
|
|
+static ssize_t ports_num_show(struct device *dev,
|
|
|
+ struct device_attribute *attr, char *buf)
|
|
|
+{
|
|
|
+ void __iomem *base;
|
|
|
+ u64 v;
|
|
|
+
|
|
|
+ base = dfl_get_feature_ioaddr_by_id(dev, FME_FEATURE_ID_HEADER);
|
|
|
+
|
|
|
+ v = readq(base + FME_HDR_CAP);
|
|
|
+
|
|
|
+ return scnprintf(buf, PAGE_SIZE, "%u\n",
|
|
|
+ (unsigned int)FIELD_GET(FME_CAP_NUM_PORTS, v));
|
|
|
+}
|
|
|
+static DEVICE_ATTR_RO(ports_num);
|
|
|
+
|
|
|
+/*
|
|
|
+ * Bitstream (static FPGA region) identifier number. It contains the
|
|
|
+ * detailed version and other information of this static FPGA region.
|
|
|
+ */
|
|
|
+static ssize_t bitstream_id_show(struct device *dev,
|
|
|
+ struct device_attribute *attr, char *buf)
|
|
|
+{
|
|
|
+ void __iomem *base;
|
|
|
+ u64 v;
|
|
|
+
|
|
|
+ base = dfl_get_feature_ioaddr_by_id(dev, FME_FEATURE_ID_HEADER);
|
|
|
+
|
|
|
+ v = readq(base + FME_HDR_BITSTREAM_ID);
|
|
|
+
|
|
|
+ return scnprintf(buf, PAGE_SIZE, "0x%llx\n", (unsigned long long)v);
|
|
|
+}
|
|
|
+static DEVICE_ATTR_RO(bitstream_id);
|
|
|
+
|
|
|
+/*
|
|
|
+ * Bitstream (static FPGA region) meta data. It contains the synthesis
|
|
|
+ * date, seed and other information of this static FPGA region.
|
|
|
+ */
|
|
|
+static ssize_t bitstream_metadata_show(struct device *dev,
|
|
|
+ struct device_attribute *attr, char *buf)
|
|
|
+{
|
|
|
+ void __iomem *base;
|
|
|
+ u64 v;
|
|
|
+
|
|
|
+ base = dfl_get_feature_ioaddr_by_id(dev, FME_FEATURE_ID_HEADER);
|
|
|
+
|
|
|
+ v = readq(base + FME_HDR_BITSTREAM_MD);
|
|
|
+
|
|
|
+ return scnprintf(buf, PAGE_SIZE, "0x%llx\n", (unsigned long long)v);
|
|
|
+}
|
|
|
+static DEVICE_ATTR_RO(bitstream_metadata);
|
|
|
+
|
|
|
+static const struct attribute *fme_hdr_attrs[] = {
|
|
|
+ &dev_attr_ports_num.attr,
|
|
|
+ &dev_attr_bitstream_id.attr,
|
|
|
+ &dev_attr_bitstream_metadata.attr,
|
|
|
+ NULL,
|
|
|
+};
|
|
|
+
|
|
|
static int fme_hdr_init(struct platform_device *pdev,
|
|
|
struct dfl_feature *feature)
|
|
|
{
|
|
|
+ void __iomem *base = feature->ioaddr;
|
|
|
+ int ret;
|
|
|
+
|
|
|
dev_dbg(&pdev->dev, "FME HDR Init.\n");
|
|
|
+ dev_dbg(&pdev->dev, "FME cap %llx.\n",
|
|
|
+ (unsigned long long)readq(base + FME_HDR_CAP));
|
|
|
+
|
|
|
+ ret = sysfs_create_files(&pdev->dev.kobj, fme_hdr_attrs);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -31,6 +98,7 @@ static void fme_hdr_uinit(struct platform_device *pdev,
|
|
|
struct dfl_feature *feature)
|
|
|
{
|
|
|
dev_dbg(&pdev->dev, "FME HDR UInit.\n");
|
|
|
+ sysfs_remove_files(&pdev->dev.kobj, fme_hdr_attrs);
|
|
|
}
|
|
|
|
|
|
static const struct dfl_feature_ops fme_hdr_ops = {
|