diff options
author | Xu Yilun <yilun.xu@intel.com> | 2020-09-07 17:23:13 +0300 |
---|---|---|
committer | Moritz Fischer <mdf@kernel.org> | 2020-09-10 06:28:16 +0300 |
commit | 9ba3a0aa09fe505540a3bdd11f0da3b8e9d73055 (patch) | |
tree | 4e04d5a91d2aaa9e0c9b06178d68dc4a31e8739d /drivers/fpga/dfl.h | |
parent | c71e805083af55e0c8eae33bb0653d0105556625 (diff) | |
download | linux-9ba3a0aa09fe505540a3bdd11f0da3b8e9d73055.tar.xz |
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.
[mdf@kernel.org: Add missing Documentation part to MAINTAINERS file]
Signed-off-by: Xu Yilun <yilun.xu@intel.com>
Signed-off-by: Wu Hao <hao.wu@intel.com>
Signed-off-by: Matthew Gerlach <matthew.gerlach@linux.intel.com>
Signed-off-by: Russ Weight <russell.h.weight@intel.com>
Reviewed-by: Tom Rix <trix@redhat.com>
Acked-by: Wu Hao <hao.wu@intel.com>
Signed-off-by: Moritz Fischer <mdf@kernel.org>
Diffstat (limited to 'drivers/fpga/dfl.h')
-rw-r--r-- | drivers/fpga/dfl.h | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/drivers/fpga/dfl.h b/drivers/fpga/dfl.h index 5973769430a7..5dc758f655b7 100644 --- a/drivers/fpga/dfl.h +++ b/drivers/fpga/dfl.h @@ -236,6 +236,7 @@ struct dfl_feature_irq_ctx { * @irq_ctx: interrupt context list. * @nr_irqs: number of interrupt contexts. * @ops: ops of this sub feature. + * @ddev: ptr to the dfl device of this sub feature. * @priv: priv data of this feature. */ struct dfl_feature { @@ -246,6 +247,7 @@ struct dfl_feature { struct dfl_feature_irq_ctx *irq_ctx; unsigned int nr_irqs; const struct dfl_feature_ops *ops; + struct dfl_device *ddev; void *priv; }; @@ -514,4 +516,88 @@ long dfl_feature_ioctl_set_irq(struct platform_device *pdev, struct dfl_feature *feature, unsigned long arg); +/** + * enum dfl_id_type - define the DFL FIU types + */ +enum dfl_id_type { + FME_ID, + PORT_ID, + DFL_ID_MAX, +}; + +/** + * struct dfl_device_id - dfl device identifier + * @type: contains 4 bits DFL FIU type of the device. See enum dfl_id_type. + * @feature_id: contains 12 bits feature identifier local to its DFL FIU type. + * @driver_data: driver specific data. + */ +struct dfl_device_id { + u8 type; + u16 feature_id; + unsigned long driver_data; +}; + +/** + * struct dfl_device - represent an dfl device on dfl bus + * + * @dev: generic device interface. + * @id: id of the dfl device. + * @type: type of DFL FIU of the device. See enum dfl_id_type. + * @feature_id: 16 bits feature identifier local to its DFL FIU type. + * @mmio_res: mmio resource of this dfl device. + * @irqs: list of Linux IRQ numbers of this dfl device. + * @num_irqs: number of IRQs supported by this dfl device. + * @cdev: pointer to DFL FPGA container device this dfl device belongs to. + * @id_entry: matched id entry in dfl driver's id table. + */ +struct dfl_device { + struct device dev; + int id; + u8 type; + u16 feature_id; + struct resource mmio_res; + int *irqs; + unsigned int num_irqs; + struct dfl_fpga_cdev *cdev; + const struct dfl_device_id *id_entry; +}; + +/** + * struct dfl_driver - represent an dfl device driver + * + * @drv: driver model structure. + * @id_table: pointer to table of device IDs the driver is interested in. + * { } member terminated. + * @probe: mandatory callback for device binding. + * @remove: callback for device unbinding. + */ +struct dfl_driver { + struct device_driver drv; + const struct dfl_device_id *id_table; + + int (*probe)(struct dfl_device *dfl_dev); + void (*remove)(struct dfl_device *dfl_dev); +}; + +#define to_dfl_dev(d) container_of(d, struct dfl_device, dev) +#define to_dfl_drv(d) container_of(d, struct dfl_driver, drv) + +/* + * use a macro to avoid include chaining to get THIS_MODULE. + */ +#define dfl_driver_register(drv) \ + __dfl_driver_register(drv, THIS_MODULE) +int __dfl_driver_register(struct dfl_driver *dfl_drv, struct module *owner); +void dfl_driver_unregister(struct dfl_driver *dfl_drv); + +/* + * module_dfl_driver() - Helper macro for drivers that don't do + * anything special in module init/exit. This eliminates a lot of + * boilerplate. Each module may only use this macro once, and + * calling it replaces module_init() and module_exit(). + */ +#define module_dfl_driver(__dfl_driver) \ + module_driver(__dfl_driver, dfl_driver_register, \ + dfl_driver_unregister) + #endif /* __FPGA_DFL_H */ |