Skip to content

Commit e4664c0

Browse files
WuHao270gregkh
authored andcommitted
fpga: dfl: afu: add header sub feature support
The port header register set is always present for port, it is mainly for capability, control and status of the ports that AFU connected to. This patch implements header sub feature support. Below user interfaces are created by this patch. Sysfs interface: * /sys/class/fpga_region/<regionX>/<dfl-port.x>/id Read-only. Port ID. Ioctl interface: * DFL_FPGA_PORT_RESET Reset the FPGA Port and its AFU. Signed-off-by: Tim Whisonant <[email protected]> Signed-off-by: Enno Luebbers <[email protected]> Signed-off-by: Shiva Rao <[email protected]> Signed-off-by: Christopher Rauer <[email protected]> Signed-off-by: Xiao Guangrong <[email protected]> Signed-off-by: Wu Hao <[email protected]> Acked-by: Alan Tull <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 47c1b19 commit e4664c0

File tree

3 files changed

+102
-1
lines changed

3 files changed

+102
-1
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
What: /sys/bus/platform/devices/dfl-port.0/id
2+
Date: June 2018
3+
KernelVersion: 4.19
4+
Contact: Wu Hao <[email protected]>
5+
Description: Read-only. It returns id of this port. One DFL FPGA device
6+
may have more than one port. Userspace could use this id to
7+
distinguish different ports under same FPGA device.

drivers/fpga/dfl-afu-main.c

Lines changed: 78 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
#include <linux/kernel.h>
1818
#include <linux/module.h>
19+
#include <linux/fpga-dfl.h>
1920

2021
#include "dfl.h"
2122

@@ -87,6 +88,41 @@ static int port_disable(struct platform_device *pdev)
8788
return 0;
8889
}
8990

91+
/*
92+
* This function resets the FPGA Port and its accelerator (AFU) by function
93+
* __port_disable and __port_enable (set port soft reset bit and then clear
94+
* it). Userspace can do Port reset at any time, e.g. during DMA or Partial
95+
* Reconfiguration. But it should never cause any system level issue, only
96+
* functional failure (e.g. DMA or PR operation failure) and be recoverable
97+
* from the failure.
98+
*
99+
* Note: the accelerator (AFU) is not accessible when its port is in reset
100+
* (disabled). Any attempts on MMIO access to AFU while in reset, will
101+
* result errors reported via port error reporting sub feature (if present).
102+
*/
103+
static int __port_reset(struct platform_device *pdev)
104+
{
105+
int ret;
106+
107+
ret = port_disable(pdev);
108+
if (!ret)
109+
port_enable(pdev);
110+
111+
return ret;
112+
}
113+
114+
static int port_reset(struct platform_device *pdev)
115+
{
116+
struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
117+
int ret;
118+
119+
mutex_lock(&pdata->lock);
120+
ret = __port_reset(pdev);
121+
mutex_unlock(&pdata->lock);
122+
123+
return ret;
124+
}
125+
90126
static int port_get_id(struct platform_device *pdev)
91127
{
92128
void __iomem *base;
@@ -96,23 +132,63 @@ static int port_get_id(struct platform_device *pdev)
96132
return FIELD_GET(PORT_CAP_PORT_NUM, readq(base + PORT_HDR_CAP));
97133
}
98134

135+
static ssize_t
136+
id_show(struct device *dev, struct device_attribute *attr, char *buf)
137+
{
138+
int id = port_get_id(to_platform_device(dev));
139+
140+
return scnprintf(buf, PAGE_SIZE, "%d\n", id);
141+
}
142+
static DEVICE_ATTR_RO(id);
143+
144+
static const struct attribute *port_hdr_attrs[] = {
145+
&dev_attr_id.attr,
146+
NULL,
147+
};
148+
99149
static int port_hdr_init(struct platform_device *pdev,
100150
struct dfl_feature *feature)
101151
{
102152
dev_dbg(&pdev->dev, "PORT HDR Init.\n");
103153

104-
return 0;
154+
port_reset(pdev);
155+
156+
return sysfs_create_files(&pdev->dev.kobj, port_hdr_attrs);
105157
}
106158

107159
static void port_hdr_uinit(struct platform_device *pdev,
108160
struct dfl_feature *feature)
109161
{
110162
dev_dbg(&pdev->dev, "PORT HDR UInit.\n");
163+
164+
sysfs_remove_files(&pdev->dev.kobj, port_hdr_attrs);
165+
}
166+
167+
static long
168+
port_hdr_ioctl(struct platform_device *pdev, struct dfl_feature *feature,
169+
unsigned int cmd, unsigned long arg)
170+
{
171+
long ret;
172+
173+
switch (cmd) {
174+
case DFL_FPGA_PORT_RESET:
175+
if (!arg)
176+
ret = port_reset(pdev);
177+
else
178+
ret = -EINVAL;
179+
break;
180+
default:
181+
dev_dbg(&pdev->dev, "%x cmd not handled", cmd);
182+
ret = -ENODEV;
183+
}
184+
185+
return ret;
111186
}
112187

113188
static const struct dfl_feature_ops port_hdr_ops = {
114189
.init = port_hdr_init,
115190
.uinit = port_hdr_uinit,
191+
.ioctl = port_hdr_ioctl,
116192
};
117193

118194
static struct dfl_feature_driver port_feature_drvs[] = {
@@ -154,6 +230,7 @@ static int afu_release(struct inode *inode, struct file *filp)
154230

155231
pdata = dev_get_platdata(&pdev->dev);
156232

233+
port_reset(pdev);
157234
dfl_feature_dev_use_end(pdata);
158235

159236
return 0;

include/uapi/linux/fpga-dfl.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,11 @@
2929
#define DFL_FPGA_MAGIC 0xB6
3030

3131
#define DFL_FPGA_BASE 0
32+
#define DFL_PORT_BASE 0x40
3233
#define DFL_FME_BASE 0x80
3334

35+
/* Common IOCTLs for both FME and AFU file descriptor */
36+
3437
/**
3538
* DFL_FPGA_GET_API_VERSION - _IO(DFL_FPGA_MAGIC, DFL_FPGA_BASE + 0)
3639
*
@@ -49,6 +52,20 @@
4952

5053
#define DFL_FPGA_CHECK_EXTENSION _IO(DFL_FPGA_MAGIC, DFL_FPGA_BASE + 1)
5154

55+
/* IOCTLs for AFU file descriptor */
56+
57+
/**
58+
* DFL_FPGA_PORT_RESET - _IO(DFL_FPGA_MAGIC, DFL_PORT_BASE + 0)
59+
*
60+
* Reset the FPGA Port and its AFU. No parameters are supported.
61+
* Userspace can do Port reset at any time, e.g. during DMA or PR. But
62+
* it should never cause any system level issue, only functional failure
63+
* (e.g. DMA or PR operation failure) and be recoverable from the failure.
64+
* Return: 0 on success, -errno of failure
65+
*/
66+
67+
#define DFL_FPGA_PORT_RESET _IO(DFL_FPGA_MAGIC, DFL_PORT_BASE + 0)
68+
5269
/* IOCTLs for FME file descriptor */
5370

5471
/**

0 commit comments

Comments
 (0)