Merge tag 'driver-core-5.15-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[linux-2.6-microblaze.git] / drivers / fpga / dfl.c
index 1ae6779..c99b78e 100644 (file)
@@ -379,6 +379,7 @@ dfl_dev_add(struct dfl_feature_platform_data *pdata,
 
        ddev->type = feature_dev_id_type(pdev);
        ddev->feature_id = feature->id;
+       ddev->revision = feature->revision;
        ddev->cdev = pdata->dfl_cdev;
 
        /* add mmio resource */
@@ -715,6 +716,7 @@ struct build_feature_devs_info {
  */
 struct dfl_feature_info {
        u16 fid;
+       u8 revision;
        struct resource mmio_res;
        void __iomem *ioaddr;
        struct list_head node;
@@ -794,6 +796,7 @@ static int build_info_commit_dev(struct build_feature_devs_info *binfo)
                /* save resource information for each feature */
                feature->dev = fdev;
                feature->id = finfo->fid;
+               feature->revision = finfo->revision;
 
                /*
                 * the FIU header feature has some fundamental functions (sriov
@@ -908,19 +911,17 @@ static void build_info_free(struct build_feature_devs_info *binfo)
        devm_kfree(binfo->dev, binfo);
 }
 
-static inline u32 feature_size(void __iomem *start)
+static inline u32 feature_size(u64 value)
 {
-       u64 v = readq(start + DFH);
-       u32 ofst = FIELD_GET(DFH_NEXT_HDR_OFST, v);
+       u32 ofst = FIELD_GET(DFH_NEXT_HDR_OFST, value);
        /* workaround for private features with invalid size, use 4K instead */
        return ofst ? ofst : 4096;
 }
 
-static u16 feature_id(void __iomem *start)
+static u16 feature_id(u64 value)
 {
-       u64 v = readq(start + DFH);
-       u16 id = FIELD_GET(DFH_ID, v);
-       u8 type = FIELD_GET(DFH_TYPE, v);
+       u16 id = FIELD_GET(DFH_ID, value);
+       u8 type = FIELD_GET(DFH_TYPE, value);
 
        if (type == DFH_TYPE_FIU)
                return FEATURE_ID_FIU_HEADER;
@@ -1019,10 +1020,15 @@ create_feature_instance(struct build_feature_devs_info *binfo,
        unsigned int irq_base, nr_irqs;
        struct dfl_feature_info *finfo;
        int ret;
+       u8 revision;
+       u64 v;
+
+       v = readq(binfo->ioaddr + ofst);
+       revision = FIELD_GET(DFH_REVISION, v);
 
        /* read feature size and id if inputs are invalid */
-       size = size ? size : feature_size(binfo->ioaddr + ofst);
-       fid = fid ? fid : feature_id(binfo->ioaddr + ofst);
+       size = size ? size : feature_size(v);
+       fid = fid ? fid : feature_id(v);
 
        if (binfo->len - ofst < size)
                return -EINVAL;
@@ -1036,6 +1042,7 @@ create_feature_instance(struct build_feature_devs_info *binfo,
                return -ENOMEM;
 
        finfo->fid = fid;
+       finfo->revision = revision;
        finfo->mmio_res.start = binfo->start + ofst;
        finfo->mmio_res.end = finfo->mmio_res.start + size - 1;
        finfo->mmio_res.flags = IORESOURCE_MEM;
@@ -1164,7 +1171,7 @@ static int parse_feature_private(struct build_feature_devs_info *binfo,
 {
        if (!is_feature_dev_detected(binfo)) {
                dev_err(binfo->dev, "the private feature 0x%x does not belong to any AFU.\n",
-                       feature_id(binfo->ioaddr + ofst));
+                       feature_id(readq(binfo->ioaddr + ofst)));
                return -EINVAL;
        }