dmaengine: idxd: add event log size sysfs attribute
[linux-2.6-microblaze.git] / drivers / dma / idxd / sysfs.c
index 2eba8ca..85644e5 100644 (file)
@@ -1573,6 +1573,46 @@ static ssize_t iaa_cap_show(struct device *dev,
 }
 static DEVICE_ATTR_RO(iaa_cap);
 
+static ssize_t event_log_size_show(struct device *dev,
+                                  struct device_attribute *attr, char *buf)
+{
+       struct idxd_device *idxd = confdev_to_idxd(dev);
+
+       if (!idxd->evl)
+               return -EOPNOTSUPP;
+
+       return sysfs_emit(buf, "%u\n", idxd->evl->size);
+}
+
+static ssize_t event_log_size_store(struct device *dev,
+                                   struct device_attribute *attr,
+                                   const char *buf, size_t count)
+{
+       struct idxd_device *idxd = confdev_to_idxd(dev);
+       unsigned long val;
+       int rc;
+
+       if (!idxd->evl)
+               return -EOPNOTSUPP;
+
+       rc = kstrtoul(buf, 10, &val);
+       if (rc < 0)
+               return -EINVAL;
+
+       if (idxd->state == IDXD_DEV_ENABLED)
+               return -EPERM;
+
+       if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
+               return -EPERM;
+
+       if (val < IDXD_EVL_SIZE_MIN || val > IDXD_EVL_SIZE_MAX)
+               return -EINVAL;
+
+       idxd->evl->size = val;
+       return count;
+}
+static DEVICE_ATTR_RW(event_log_size);
+
 static bool idxd_device_attr_max_batch_size_invisible(struct attribute *attr,
                                                      struct idxd_device *idxd)
 {
@@ -1603,6 +1643,13 @@ static bool idxd_device_attr_iaa_cap_invisible(struct attribute *attr,
               idxd->hw.version < DEVICE_VERSION_2);
 }
 
+static bool idxd_device_attr_event_log_size_invisible(struct attribute *attr,
+                                                     struct idxd_device *idxd)
+{
+       return (attr == &dev_attr_event_log_size.attr &&
+               !idxd->hw.gen_cap.evl_support);
+}
+
 static umode_t idxd_device_attr_visible(struct kobject *kobj,
                                        struct attribute *attr, int n)
 {
@@ -1618,6 +1665,9 @@ static umode_t idxd_device_attr_visible(struct kobject *kobj,
        if (idxd_device_attr_iaa_cap_invisible(attr, idxd))
                return 0;
 
+       if (idxd_device_attr_event_log_size_invisible(attr, idxd))
+               return 0;
+
        return attr->mode;
 }
 
@@ -1644,6 +1694,7 @@ static struct attribute *idxd_device_attributes[] = {
        &dev_attr_cdev_major.attr,
        &dev_attr_cmd_status.attr,
        &dev_attr_iaa_cap.attr,
+       &dev_attr_event_log_size.attr,
        NULL,
 };
 
@@ -1665,6 +1716,7 @@ static void idxd_conf_device_release(struct device *dev)
        bitmap_free(idxd->wq_enable_map);
        kfree(idxd->wqs);
        kfree(idxd->engines);
+       kfree(idxd->evl);
        ida_free(&idxd_ida, idxd->id);
        bitmap_free(idxd->opcap_bmap);
        kfree(idxd);