Re: [PATCH v4 3/4] fpga: dfl: create a dfl bus type to support DFL devices
On Mon, Aug 10, 2020 at 02:36:44PM +0800, Wu, Hao wrote: > > > > A new bus type "dfl" is introduced for private features which are not > > initialized by DFL feature drivers (dfl-fme & dfl-afu drivers). So these > > private features could be handled by separate driver modules. > > > > DFL feature drivers (dfl-fme, dfl-port) will create DFL devices on > > enumeration. DFL drivers could be registered on this bus to match these > > DFL devices. They are matched by dfl type & feature_id. > > > > Signed-off-by: Xu Yilun > > Signed-off-by: Wu Hao > > Signed-off-by: Matthew Gerlach > > Signed-off-by: Russ Weight > > Reviewed-by: Tom Rix > > --- > > v2: change the bus uevent format. > > change the dfl device's sysfs name format. > > refactor dfl_dev_add(). > > minor fixes for comments from Hao and Tom. > > v3: no change. > > v4: improve the uevent format, 4 bits for type & 12 bits for id. > > change dfl_device->type to u8. > > A dedicate field in struct dfl_feature for dfl device instance. > > error out if dfl_device already exist on dfl_devs_init(). > > --- > > Documentation/ABI/testing/sysfs-bus-dfl | 15 ++ > > drivers/fpga/dfl.c | 263 > > +++- > > drivers/fpga/dfl.h | 85 +++ > > 3 files changed, 355 insertions(+), 8 deletions(-) > > create mode 100644 Documentation/ABI/testing/sysfs-bus-dfl > > > > diff --git a/Documentation/ABI/testing/sysfs-bus-dfl > > b/Documentation/ABI/testing/sysfs-bus-dfl > > new file mode 100644 > > index 000..4d74cc0 > > --- /dev/null > > +++ b/Documentation/ABI/testing/sysfs-bus-dfl > > @@ -0,0 +1,15 @@ > > +What:/sys/bus/dfl/devices/dfl_dev.X/type > > +Date:July 2020 > > +KernelVersion:5.10 > > +Contact:Xu Yilun > > +Description:Read-only. It returns type of DFL FIU of the device. Now DFL > > +supports 2 FIU types, 0 for FME, 1 for PORT. > > +Format: 0x%x > > + > > +What:/sys/bus/dfl/devices/dfl_dev.X/feature_id > > +Date:July 2020 > > +KernelVersion:5.10 > > +Contact:Xu Yilun > > +Description:Read-only. It returns feature identifier local to its DFL FIU > > +type. > > +Format: 0x%x > > diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c > > index b5257d7..51cef85 100644 > > --- a/drivers/fpga/dfl.c > > +++ b/drivers/fpga/dfl.c > > @@ -30,12 +30,6 @@ static DEFINE_MUTEX(dfl_id_mutex); > > * index to dfl_chardevs table. If no chardev support just set devt_type > > * as one invalid index (DFL_FPGA_DEVT_MAX). > > */ > > -enum dfl_id_type { > > -FME_ID,/* fme id allocation and mapping */ > > -PORT_ID,/* port id allocation and mapping */ > > -DFL_ID_MAX, > > -}; > > - > > enum dfl_fpga_devt_type { > > DFL_FPGA_DEVT_FME, > > DFL_FPGA_DEVT_PORT, > > @@ -250,6 +244,245 @@ int dfl_fpga_check_port_id(struct platform_device > > *pdev, void *pport_id) > > } > > EXPORT_SYMBOL_GPL(dfl_fpga_check_port_id); > > > > +static DEFINE_IDA(dfl_device_ida); > > + > > +static const struct dfl_device_id * > > +dfl_match_one_device(const struct dfl_device_id *id, struct dfl_device > > *ddev) > > +{ > > +if (id->type == ddev->type && id->feature_id == ddev->feature_id) > > +return id; > > + > > +return NULL; > > +} > > + > > +static int dfl_bus_match(struct device *dev, struct device_driver *drv) > > +{ > > +struct dfl_device *ddev = to_dfl_dev(dev); > > +struct dfl_driver *ddrv = to_dfl_drv(drv); > > +const struct dfl_device_id *id_entry = ddrv->id_table; > > + > > +if (id_entry) { > > +while (id_entry->feature_id) { > > +if (dfl_match_one_device(id_entry, ddev)) { > > +ddev->id_entry = id_entry; > > +return 1; > > +} > > +id_entry++; > > +} > > +} > > + > > +return 0; > > +} > > + > > +static int dfl_bus_probe(struct device *dev) > > +{ > > +struct dfl_device *ddev = to_dfl_dev(dev); > > +struct dfl_driver *ddrv = to_dfl_drv(dev->driver); > > + > > +return ddrv->probe(ddev); > > +} > > + > > +static int dfl_bus_remove(struct device *dev) > > +{ > > +struct dfl_device *ddev = to_dfl_dev(dev); > > +struct dfl_driver *ddrv = to_dfl_drv(dev->driver); > > + > > +if (ddrv->remove) > > +ddrv->remove(ddev); > > + > > +return 0; > > +} > > + > > +static int dfl_bus_uevent(struct device *dev, struct kobj_uevent_env *env) > > +{ > > +struct dfl_device *ddev = to_dfl_dev(dev); > > + > > +/* The type has 4 valid bits and feature_id has 12 valid bits */ > > +return add_uevent_var(env, "MODALIAS=dfl:t%01Xf%03X", > > + ddev->type, ddev->feature_id); > > +} > > + > > +/* show dfl info fields */ > > +#define dfl_info_attr(field, format_string)\ > > +static ssize_t\ > > +field##_show(struct device *dev, struct device_attribute *attr, > > \ > > + char *buf)\ > > +{\ > > +struct dfl_device *ddev = to_dfl_dev(dev);\ > > +\ > > +return sprintf(buf, format_string, ddev->field);\ > > +}\ > > +static DEVICE_ATTR_RO(field) > > + > > +dfl_info_attr(type, "0x%x\n"); > > +dfl_info_attr(feature_id, "0x%x\n"); > > + > > +static struct attribute *dfl_dev_attrs[] = { > > +_attr_type.attr, > >
RE: [PATCH v4 3/4] fpga: dfl: create a dfl bus type to support DFL devices
> > A new bus type "dfl" is introduced for private features which are not > initialized by DFL feature drivers (dfl-fme & dfl-afu drivers). So these > private features could be handled by separate driver modules. > > DFL feature drivers (dfl-fme, dfl-port) will create DFL devices on > enumeration. DFL drivers could be registered on this bus to match these > DFL devices. They are matched by dfl type & feature_id. > > Signed-off-by: Xu Yilun > Signed-off-by: Wu Hao > Signed-off-by: Matthew Gerlach > Signed-off-by: Russ Weight > Reviewed-by: Tom Rix > --- > v2: change the bus uevent format. > change the dfl device's sysfs name format. > refactor dfl_dev_add(). > minor fixes for comments from Hao and Tom. > v3: no change. > v4: improve the uevent format, 4 bits for type & 12 bits for id. > change dfl_device->type to u8. > A dedicate field in struct dfl_feature for dfl device instance. > error out if dfl_device already exist on dfl_devs_init(). > --- > Documentation/ABI/testing/sysfs-bus-dfl | 15 ++ > drivers/fpga/dfl.c | 263 > +++- > drivers/fpga/dfl.h | 85 +++ > 3 files changed, 355 insertions(+), 8 deletions(-) > create mode 100644 Documentation/ABI/testing/sysfs-bus-dfl > > diff --git a/Documentation/ABI/testing/sysfs-bus-dfl > b/Documentation/ABI/testing/sysfs-bus-dfl > new file mode 100644 > index 000..4d74cc0 > --- /dev/null > +++ b/Documentation/ABI/testing/sysfs-bus-dfl > @@ -0,0 +1,15 @@ > +What:/sys/bus/dfl/devices/dfl_dev.X/type > +Date:July 2020 > +KernelVersion: 5.10 > +Contact: Xu Yilun > +Description: Read-only. It returns type of DFL FIU of the device. Now DFL > + supports 2 FIU types, 0 for FME, 1 for PORT. > + Format: 0x%x > + > +What:/sys/bus/dfl/devices/dfl_dev.X/feature_id > +Date:July 2020 > +KernelVersion: 5.10 > +Contact: Xu Yilun > +Description: Read-only. It returns feature identifier local to its DFL FIU > + type. > + Format: 0x%x > diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c > index b5257d7..51cef85 100644 > --- a/drivers/fpga/dfl.c > +++ b/drivers/fpga/dfl.c > @@ -30,12 +30,6 @@ static DEFINE_MUTEX(dfl_id_mutex); > * index to dfl_chardevs table. If no chardev support just set devt_type > * as one invalid index (DFL_FPGA_DEVT_MAX). > */ > -enum dfl_id_type { > - FME_ID, /* fme id allocation and mapping */ > - PORT_ID,/* port id allocation and mapping */ > - DFL_ID_MAX, > -}; > - > enum dfl_fpga_devt_type { > DFL_FPGA_DEVT_FME, > DFL_FPGA_DEVT_PORT, > @@ -250,6 +244,245 @@ int dfl_fpga_check_port_id(struct platform_device > *pdev, void *pport_id) > } > EXPORT_SYMBOL_GPL(dfl_fpga_check_port_id); > > +static DEFINE_IDA(dfl_device_ida); > + > +static const struct dfl_device_id * > +dfl_match_one_device(const struct dfl_device_id *id, struct dfl_device > *ddev) > +{ > + if (id->type == ddev->type && id->feature_id == ddev->feature_id) > + return id; > + > + return NULL; > +} > + > +static int dfl_bus_match(struct device *dev, struct device_driver *drv) > +{ > + struct dfl_device *ddev = to_dfl_dev(dev); > + struct dfl_driver *ddrv = to_dfl_drv(drv); > + const struct dfl_device_id *id_entry = ddrv->id_table; > + > + if (id_entry) { > + while (id_entry->feature_id) { > + if (dfl_match_one_device(id_entry, ddev)) { > + ddev->id_entry = id_entry; > + return 1; > + } > + id_entry++; > + } > + } > + > + return 0; > +} > + > +static int dfl_bus_probe(struct device *dev) > +{ > + struct dfl_device *ddev = to_dfl_dev(dev); > + struct dfl_driver *ddrv = to_dfl_drv(dev->driver); > + > + return ddrv->probe(ddev); > +} > + > +static int dfl_bus_remove(struct device *dev) > +{ > + struct dfl_device *ddev = to_dfl_dev(dev); > + struct dfl_driver *ddrv = to_dfl_drv(dev->driver); > + > + if (ddrv->remove) > + ddrv->remove(ddev); > + > + return 0; > +} > + > +static int dfl_bus_uevent(struct device *dev, struct kobj_uevent_env *env) > +{ > + struct dfl_device *ddev = to_dfl_dev(dev); > + > + /* The type has 4 valid bits and feature_id has 12 valid bits */ > + return add_uevent_var(env, "MODALIAS=dfl:t%01Xf%03X", > + ddev->type, ddev->feature_id); > +} > + > +/* show dfl info fields */ > +#define dfl_info_attr(field, format_string) \ > +static ssize_t > \ > +field##_show(struct device *dev, struct device_attribute *attr, > \ > + char *buf) \ > +{
[PATCH v4 3/4] fpga: dfl: create a dfl bus type to support DFL devices
A new bus type "dfl" is introduced for private features which are not initialized by DFL feature drivers (dfl-fme & dfl-afu drivers). So these private features could be handled by separate driver modules. DFL feature drivers (dfl-fme, dfl-port) will create DFL devices on enumeration. DFL drivers could be registered on this bus to match these DFL devices. They are matched by dfl type & feature_id. Signed-off-by: Xu Yilun Signed-off-by: Wu Hao Signed-off-by: Matthew Gerlach Signed-off-by: Russ Weight Reviewed-by: Tom Rix --- v2: change the bus uevent format. change the dfl device's sysfs name format. refactor dfl_dev_add(). minor fixes for comments from Hao and Tom. v3: no change. v4: improve the uevent format, 4 bits for type & 12 bits for id. change dfl_device->type to u8. A dedicate field in struct dfl_feature for dfl device instance. error out if dfl_device already exist on dfl_devs_init(). --- Documentation/ABI/testing/sysfs-bus-dfl | 15 ++ drivers/fpga/dfl.c | 263 +++- drivers/fpga/dfl.h | 85 +++ 3 files changed, 355 insertions(+), 8 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-dfl diff --git a/Documentation/ABI/testing/sysfs-bus-dfl b/Documentation/ABI/testing/sysfs-bus-dfl new file mode 100644 index 000..4d74cc0 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-dfl @@ -0,0 +1,15 @@ +What: /sys/bus/dfl/devices/dfl_dev.X/type +Date: July 2020 +KernelVersion: 5.10 +Contact: Xu Yilun +Description: Read-only. It returns type of DFL FIU of the device. Now DFL + supports 2 FIU types, 0 for FME, 1 for PORT. + Format: 0x%x + +What: /sys/bus/dfl/devices/dfl_dev.X/feature_id +Date: July 2020 +KernelVersion: 5.10 +Contact: Xu Yilun +Description: Read-only. It returns feature identifier local to its DFL FIU + type. + Format: 0x%x diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index b5257d7..51cef85 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -30,12 +30,6 @@ static DEFINE_MUTEX(dfl_id_mutex); * index to dfl_chardevs table. If no chardev support just set devt_type * as one invalid index (DFL_FPGA_DEVT_MAX). */ -enum dfl_id_type { - FME_ID, /* fme id allocation and mapping */ - PORT_ID,/* port id allocation and mapping */ - DFL_ID_MAX, -}; - enum dfl_fpga_devt_type { DFL_FPGA_DEVT_FME, DFL_FPGA_DEVT_PORT, @@ -250,6 +244,245 @@ int dfl_fpga_check_port_id(struct platform_device *pdev, void *pport_id) } EXPORT_SYMBOL_GPL(dfl_fpga_check_port_id); +static DEFINE_IDA(dfl_device_ida); + +static const struct dfl_device_id * +dfl_match_one_device(const struct dfl_device_id *id, struct dfl_device *ddev) +{ + if (id->type == ddev->type && id->feature_id == ddev->feature_id) + return id; + + return NULL; +} + +static int dfl_bus_match(struct device *dev, struct device_driver *drv) +{ + struct dfl_device *ddev = to_dfl_dev(dev); + struct dfl_driver *ddrv = to_dfl_drv(drv); + const struct dfl_device_id *id_entry = ddrv->id_table; + + if (id_entry) { + while (id_entry->feature_id) { + if (dfl_match_one_device(id_entry, ddev)) { + ddev->id_entry = id_entry; + return 1; + } + id_entry++; + } + } + + return 0; +} + +static int dfl_bus_probe(struct device *dev) +{ + struct dfl_device *ddev = to_dfl_dev(dev); + struct dfl_driver *ddrv = to_dfl_drv(dev->driver); + + return ddrv->probe(ddev); +} + +static int dfl_bus_remove(struct device *dev) +{ + struct dfl_device *ddev = to_dfl_dev(dev); + struct dfl_driver *ddrv = to_dfl_drv(dev->driver); + + if (ddrv->remove) + ddrv->remove(ddev); + + return 0; +} + +static int dfl_bus_uevent(struct device *dev, struct kobj_uevent_env *env) +{ + struct dfl_device *ddev = to_dfl_dev(dev); + + /* The type has 4 valid bits and feature_id has 12 valid bits */ + return add_uevent_var(env, "MODALIAS=dfl:t%01Xf%03X", + ddev->type, ddev->feature_id); +} + +/* show dfl info fields */ +#define dfl_info_attr(field, format_string)\ +static ssize_t \ +field##_show(struct device *dev, struct device_attribute *attr, \ +char *buf) \ +{ \ + struct dfl_device *ddev = to_dfl_dev(dev); \ + \ + return sprintf(buf, format_string, ddev->field);