diff options
Diffstat (limited to 'drivers/fpga/dfl-afu-main.c')
-rw-r--r-- | drivers/fpga/dfl-afu-main.c | 165 |
1 files changed, 157 insertions, 8 deletions
diff --git a/drivers/fpga/dfl-afu-main.c b/drivers/fpga/dfl-afu-main.c index 02baa6a227c0..e50c45ed40ac 100644 --- a/drivers/fpga/dfl-afu-main.c +++ b/drivers/fpga/dfl-afu-main.c @@ -141,10 +141,148 @@ id_show(struct device *dev, struct device_attribute *attr, char *buf) } static DEVICE_ATTR_RO(id); -static const struct attribute *port_hdr_attrs[] = { +static ssize_t +ltr_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct dfl_feature_platform_data *pdata = dev_get_platdata(dev); + void __iomem *base; + u64 v; + + base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER); + + mutex_lock(&pdata->lock); + v = readq(base + PORT_HDR_CTRL); + mutex_unlock(&pdata->lock); + + return sprintf(buf, "%x\n", (u8)FIELD_GET(PORT_CTRL_LATENCY, v)); +} + +static ssize_t +ltr_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct dfl_feature_platform_data *pdata = dev_get_platdata(dev); + void __iomem *base; + bool ltr; + u64 v; + + if (kstrtobool(buf, <r)) + return -EINVAL; + + base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER); + + mutex_lock(&pdata->lock); + v = readq(base + PORT_HDR_CTRL); + v &= ~PORT_CTRL_LATENCY; + v |= FIELD_PREP(PORT_CTRL_LATENCY, ltr ? 1 : 0); + writeq(v, base + PORT_HDR_CTRL); + mutex_unlock(&pdata->lock); + + return count; +} +static DEVICE_ATTR_RW(ltr); + +static ssize_t +ap1_event_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct dfl_feature_platform_data *pdata = dev_get_platdata(dev); + void __iomem *base; + u64 v; + + base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER); + + mutex_lock(&pdata->lock); + v = readq(base + PORT_HDR_STS); + mutex_unlock(&pdata->lock); + + return sprintf(buf, "%x\n", (u8)FIELD_GET(PORT_STS_AP1_EVT, v)); +} + +static ssize_t +ap1_event_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct dfl_feature_platform_data *pdata = dev_get_platdata(dev); + void __iomem *base; + bool clear; + + if (kstrtobool(buf, &clear) || !clear) + return -EINVAL; + + base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER); + + mutex_lock(&pdata->lock); + writeq(PORT_STS_AP1_EVT, base + PORT_HDR_STS); + mutex_unlock(&pdata->lock); + + return count; +} +static DEVICE_ATTR_RW(ap1_event); + +static ssize_t +ap2_event_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct dfl_feature_platform_data *pdata = dev_get_platdata(dev); + void __iomem *base; + u64 v; + + base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER); + + mutex_lock(&pdata->lock); + v = readq(base + PORT_HDR_STS); + mutex_unlock(&pdata->lock); + + return sprintf(buf, "%x\n", (u8)FIELD_GET(PORT_STS_AP2_EVT, v)); +} + +static ssize_t +ap2_event_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + struct dfl_feature_platform_data *pdata = dev_get_platdata(dev); + void __iomem *base; + bool clear; + + if (kstrtobool(buf, &clear) || !clear) + return -EINVAL; + + base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER); + + mutex_lock(&pdata->lock); + writeq(PORT_STS_AP2_EVT, base + PORT_HDR_STS); + mutex_unlock(&pdata->lock); + + return count; +} +static DEVICE_ATTR_RW(ap2_event); + +static ssize_t +power_state_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct dfl_feature_platform_data *pdata = dev_get_platdata(dev); + void __iomem *base; + u64 v; + + base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER); + + mutex_lock(&pdata->lock); + v = readq(base + PORT_HDR_STS); + mutex_unlock(&pdata->lock); + + return sprintf(buf, "0x%x\n", (u8)FIELD_GET(PORT_STS_PWR_STATE, v)); +} +static DEVICE_ATTR_RO(power_state); + +static struct attribute *port_hdr_attrs[] = { &dev_attr_id.attr, + &dev_attr_ltr.attr, + &dev_attr_ap1_event.attr, + &dev_attr_ap2_event.attr, + &dev_attr_power_state.attr, NULL, }; +ATTRIBUTE_GROUPS(port_hdr); static int port_hdr_init(struct platform_device *pdev, struct dfl_feature *feature) @@ -153,7 +291,7 @@ static int port_hdr_init(struct platform_device *pdev, port_reset(pdev); - return sysfs_create_files(&pdev->dev.kobj, port_hdr_attrs); + return device_add_groups(&pdev->dev, port_hdr_groups); } static void port_hdr_uinit(struct platform_device *pdev, @@ -161,7 +299,7 @@ static void port_hdr_uinit(struct platform_device *pdev, { dev_dbg(&pdev->dev, "PORT HDR UInit.\n"); - sysfs_remove_files(&pdev->dev.kobj, port_hdr_attrs); + device_remove_groups(&pdev->dev, port_hdr_groups); } static long @@ -185,6 +323,11 @@ port_hdr_ioctl(struct platform_device *pdev, struct dfl_feature *feature, return ret; } +static const struct dfl_feature_id port_hdr_id_table[] = { + {.id = PORT_FEATURE_ID_HEADER,}, + {0,} +}; + static const struct dfl_feature_ops port_hdr_ops = { .init = port_hdr_init, .uinit = port_hdr_uinit, @@ -214,10 +357,11 @@ afu_id_show(struct device *dev, struct device_attribute *attr, char *buf) } static DEVICE_ATTR_RO(afu_id); -static const struct attribute *port_afu_attrs[] = { +static struct attribute *port_afu_attrs[] = { &dev_attr_afu_id.attr, NULL }; +ATTRIBUTE_GROUPS(port_afu); static int port_afu_init(struct platform_device *pdev, struct dfl_feature *feature) @@ -234,7 +378,7 @@ static int port_afu_init(struct platform_device *pdev, if (ret) return ret; - return sysfs_create_files(&pdev->dev.kobj, port_afu_attrs); + return device_add_groups(&pdev->dev, port_afu_groups); } static void port_afu_uinit(struct platform_device *pdev, @@ -242,9 +386,14 @@ static void port_afu_uinit(struct platform_device *pdev, { dev_dbg(&pdev->dev, "PORT AFU UInit.\n"); - sysfs_remove_files(&pdev->dev.kobj, port_afu_attrs); + device_remove_groups(&pdev->dev, port_afu_groups); } +static const struct dfl_feature_id port_afu_id_table[] = { + {.id = PORT_FEATURE_ID_AFU,}, + {0,} +}; + static const struct dfl_feature_ops port_afu_ops = { .init = port_afu_init, .uinit = port_afu_uinit, @@ -252,11 +401,11 @@ static const struct dfl_feature_ops port_afu_ops = { static struct dfl_feature_driver port_feature_drvs[] = { { - .id = PORT_FEATURE_ID_HEADER, + .id_table = port_hdr_id_table, .ops = &port_hdr_ops, }, { - .id = PORT_FEATURE_ID_AFU, + .id_table = port_afu_id_table, .ops = &port_afu_ops, }, { |