1543be3d8SWu Hao /* SPDX-License-Identifier: GPL-2.0 */ 2543be3d8SWu Hao /* 3543be3d8SWu Hao * Driver Header File for FPGA Device Feature List (DFL) Support 4543be3d8SWu Hao * 5543be3d8SWu Hao * Copyright (C) 2017-2018 Intel Corporation, Inc. 6543be3d8SWu Hao * 7543be3d8SWu Hao * Authors: 8543be3d8SWu Hao * Kang Luwei <luwei.kang@intel.com> 9543be3d8SWu Hao * Zhang Yi <yi.z.zhang@intel.com> 10543be3d8SWu Hao * Wu Hao <hao.wu@intel.com> 11543be3d8SWu Hao * Xiao Guangrong <guangrong.xiao@linux.intel.com> 12543be3d8SWu Hao */ 13543be3d8SWu Hao 14543be3d8SWu Hao #ifndef __FPGA_DFL_H 15543be3d8SWu Hao #define __FPGA_DFL_H 16543be3d8SWu Hao 17543be3d8SWu Hao #include <linux/bitfield.h> 18b16c5147SWu Hao #include <linux/cdev.h> 19543be3d8SWu Hao #include <linux/delay.h> 20543be3d8SWu Hao #include <linux/fs.h> 21543be3d8SWu Hao #include <linux/iopoll.h> 22543be3d8SWu Hao #include <linux/io-64-nonatomic-lo-hi.h> 23543be3d8SWu Hao #include <linux/platform_device.h> 24543be3d8SWu Hao #include <linux/slab.h> 25543be3d8SWu Hao #include <linux/uuid.h> 26543be3d8SWu Hao #include <linux/fpga/fpga-region.h> 27543be3d8SWu Hao 28543be3d8SWu Hao /* maximum supported number of ports */ 29543be3d8SWu Hao #define MAX_DFL_FPGA_PORT_NUM 4 30543be3d8SWu Hao /* plus one for fme device */ 31543be3d8SWu Hao #define MAX_DFL_FEATURE_DEV_NUM (MAX_DFL_FPGA_PORT_NUM + 1) 32543be3d8SWu Hao 33543be3d8SWu Hao /* Reserved 0x0 for Header Group Register and 0xff for AFU */ 34543be3d8SWu Hao #define FEATURE_ID_FIU_HEADER 0x0 35543be3d8SWu Hao #define FEATURE_ID_AFU 0xff 36543be3d8SWu Hao 37543be3d8SWu Hao #define FME_FEATURE_ID_HEADER FEATURE_ID_FIU_HEADER 38543be3d8SWu Hao #define FME_FEATURE_ID_THERMAL_MGMT 0x1 39543be3d8SWu Hao #define FME_FEATURE_ID_POWER_MGMT 0x2 40543be3d8SWu Hao #define FME_FEATURE_ID_GLOBAL_IPERF 0x3 41543be3d8SWu Hao #define FME_FEATURE_ID_GLOBAL_ERR 0x4 42543be3d8SWu Hao #define FME_FEATURE_ID_PR_MGMT 0x5 43543be3d8SWu Hao #define FME_FEATURE_ID_HSSI 0x6 44543be3d8SWu Hao #define FME_FEATURE_ID_GLOBAL_DPERF 0x7 45543be3d8SWu Hao 46543be3d8SWu Hao #define PORT_FEATURE_ID_HEADER FEATURE_ID_FIU_HEADER 47543be3d8SWu Hao #define PORT_FEATURE_ID_AFU FEATURE_ID_AFU 48543be3d8SWu Hao #define PORT_FEATURE_ID_ERROR 0x10 49543be3d8SWu Hao #define PORT_FEATURE_ID_UMSG 0x11 50543be3d8SWu Hao #define PORT_FEATURE_ID_UINT 0x12 51543be3d8SWu Hao #define PORT_FEATURE_ID_STP 0x13 52543be3d8SWu Hao 53543be3d8SWu Hao /* 54543be3d8SWu Hao * Device Feature Header Register Set 55543be3d8SWu Hao * 56543be3d8SWu Hao * For FIUs, they all have DFH + GUID + NEXT_AFU as common header registers. 57543be3d8SWu Hao * For AFUs, they have DFH + GUID as common header registers. 58543be3d8SWu Hao * For private features, they only have DFH register as common header. 59543be3d8SWu Hao */ 60543be3d8SWu Hao #define DFH 0x0 61543be3d8SWu Hao #define GUID_L 0x8 62543be3d8SWu Hao #define GUID_H 0x10 63543be3d8SWu Hao #define NEXT_AFU 0x18 64543be3d8SWu Hao 65543be3d8SWu Hao #define DFH_SIZE 0x8 66543be3d8SWu Hao 67543be3d8SWu Hao /* Device Feature Header Register Bitfield */ 68543be3d8SWu Hao #define DFH_ID GENMASK_ULL(11, 0) /* Feature ID */ 69543be3d8SWu Hao #define DFH_ID_FIU_FME 0 70543be3d8SWu Hao #define DFH_ID_FIU_PORT 1 71543be3d8SWu Hao #define DFH_REVISION GENMASK_ULL(15, 12) /* Feature revision */ 72543be3d8SWu Hao #define DFH_NEXT_HDR_OFST GENMASK_ULL(39, 16) /* Offset to next DFH */ 73543be3d8SWu Hao #define DFH_EOL BIT_ULL(40) /* End of list */ 74543be3d8SWu Hao #define DFH_TYPE GENMASK_ULL(63, 60) /* Feature type */ 75543be3d8SWu Hao #define DFH_TYPE_AFU 1 76543be3d8SWu Hao #define DFH_TYPE_PRIVATE 3 77543be3d8SWu Hao #define DFH_TYPE_FIU 4 78543be3d8SWu Hao 79543be3d8SWu Hao /* Next AFU Register Bitfield */ 80543be3d8SWu Hao #define NEXT_AFU_NEXT_DFH_OFST GENMASK_ULL(23, 0) /* Offset to next AFU */ 81543be3d8SWu Hao 82543be3d8SWu Hao /* FME Header Register Set */ 83543be3d8SWu Hao #define FME_HDR_DFH DFH 84543be3d8SWu Hao #define FME_HDR_GUID_L GUID_L 85543be3d8SWu Hao #define FME_HDR_GUID_H GUID_H 86543be3d8SWu Hao #define FME_HDR_NEXT_AFU NEXT_AFU 87543be3d8SWu Hao #define FME_HDR_CAP 0x30 88543be3d8SWu Hao #define FME_HDR_PORT_OFST(n) (0x38 + ((n) * 0x8)) 89543be3d8SWu Hao #define FME_HDR_BITSTREAM_ID 0x60 90543be3d8SWu Hao #define FME_HDR_BITSTREAM_MD 0x68 91543be3d8SWu Hao 92543be3d8SWu Hao /* FME Fab Capability Register Bitfield */ 93543be3d8SWu Hao #define FME_CAP_FABRIC_VERID GENMASK_ULL(7, 0) /* Fabric version ID */ 94543be3d8SWu Hao #define FME_CAP_SOCKET_ID BIT_ULL(8) /* Socket ID */ 95543be3d8SWu Hao #define FME_CAP_PCIE0_LINK_AVL BIT_ULL(12) /* PCIE0 Link */ 96543be3d8SWu Hao #define FME_CAP_PCIE1_LINK_AVL BIT_ULL(13) /* PCIE1 Link */ 97543be3d8SWu Hao #define FME_CAP_COHR_LINK_AVL BIT_ULL(14) /* Coherent Link */ 98543be3d8SWu Hao #define FME_CAP_IOMMU_AVL BIT_ULL(16) /* IOMMU available */ 99543be3d8SWu Hao #define FME_CAP_NUM_PORTS GENMASK_ULL(19, 17) /* Number of ports */ 100543be3d8SWu Hao #define FME_CAP_ADDR_WIDTH GENMASK_ULL(29, 24) /* Address bus width */ 101543be3d8SWu Hao #define FME_CAP_CACHE_SIZE GENMASK_ULL(43, 32) /* cache size in KB */ 102543be3d8SWu Hao #define FME_CAP_CACHE_ASSOC GENMASK_ULL(47, 44) /* Associativity */ 103543be3d8SWu Hao 104543be3d8SWu Hao /* FME Port Offset Register Bitfield */ 105543be3d8SWu Hao /* Offset to port device feature header */ 106543be3d8SWu Hao #define FME_PORT_OFST_DFH_OFST GENMASK_ULL(23, 0) 107543be3d8SWu Hao /* PCI Bar ID for this port */ 108543be3d8SWu Hao #define FME_PORT_OFST_BAR_ID GENMASK_ULL(34, 32) 109543be3d8SWu Hao /* AFU MMIO access permission. 1 - VF, 0 - PF. */ 110543be3d8SWu Hao #define FME_PORT_OFST_ACC_CTRL BIT_ULL(55) 111543be3d8SWu Hao #define FME_PORT_OFST_ACC_PF 0 112543be3d8SWu Hao #define FME_PORT_OFST_ACC_VF 1 113543be3d8SWu Hao #define FME_PORT_OFST_IMP BIT_ULL(60) 114543be3d8SWu Hao 115543be3d8SWu Hao /* PORT Header Register Set */ 116543be3d8SWu Hao #define PORT_HDR_DFH DFH 117543be3d8SWu Hao #define PORT_HDR_GUID_L GUID_L 118543be3d8SWu Hao #define PORT_HDR_GUID_H GUID_H 119543be3d8SWu Hao #define PORT_HDR_NEXT_AFU NEXT_AFU 120543be3d8SWu Hao #define PORT_HDR_CAP 0x30 121543be3d8SWu Hao #define PORT_HDR_CTRL 0x38 122543be3d8SWu Hao 123543be3d8SWu Hao /* Port Capability Register Bitfield */ 124543be3d8SWu Hao #define PORT_CAP_PORT_NUM GENMASK_ULL(1, 0) /* ID of this port */ 125543be3d8SWu Hao #define PORT_CAP_MMIO_SIZE GENMASK_ULL(23, 8) /* MMIO size in KB */ 126543be3d8SWu Hao #define PORT_CAP_SUPP_INT_NUM GENMASK_ULL(35, 32) /* Interrupts num */ 127543be3d8SWu Hao 128543be3d8SWu Hao /* Port Control Register Bitfield */ 129543be3d8SWu Hao #define PORT_CTRL_SFTRST BIT_ULL(0) /* Port soft reset */ 130543be3d8SWu Hao /* Latency tolerance reporting. '1' >= 40us, '0' < 40us.*/ 131543be3d8SWu Hao #define PORT_CTRL_LATENCY BIT_ULL(2) 132543be3d8SWu Hao #define PORT_CTRL_SFTRST_ACK BIT_ULL(4) /* HW ack for reset */ 133*6e8fd6e4SWu Hao /** 134*6e8fd6e4SWu Hao * struct dfl_fpga_port_ops - port ops 135*6e8fd6e4SWu Hao * 136*6e8fd6e4SWu Hao * @name: name of this port ops, to match with port platform device. 137*6e8fd6e4SWu Hao * @owner: pointer to the module which owns this port ops. 138*6e8fd6e4SWu Hao * @node: node to link port ops to global list. 139*6e8fd6e4SWu Hao * @get_id: get port id from hardware. 140*6e8fd6e4SWu Hao * @enable_set: enable/disable the port. 141*6e8fd6e4SWu Hao */ 142*6e8fd6e4SWu Hao struct dfl_fpga_port_ops { 143*6e8fd6e4SWu Hao const char *name; 144*6e8fd6e4SWu Hao struct module *owner; 145*6e8fd6e4SWu Hao struct list_head node; 146*6e8fd6e4SWu Hao int (*get_id)(struct platform_device *pdev); 147*6e8fd6e4SWu Hao int (*enable_set)(struct platform_device *pdev, bool enable); 148*6e8fd6e4SWu Hao }; 149*6e8fd6e4SWu Hao 150*6e8fd6e4SWu Hao void dfl_fpga_port_ops_add(struct dfl_fpga_port_ops *ops); 151*6e8fd6e4SWu Hao void dfl_fpga_port_ops_del(struct dfl_fpga_port_ops *ops); 152*6e8fd6e4SWu Hao struct dfl_fpga_port_ops *dfl_fpga_port_ops_get(struct platform_device *pdev); 153*6e8fd6e4SWu Hao void dfl_fpga_port_ops_put(struct dfl_fpga_port_ops *ops); 154543be3d8SWu Hao 155543be3d8SWu Hao /** 1565b57d02aSXiao Guangrong * struct dfl_feature_driver - sub feature's driver 1575b57d02aSXiao Guangrong * 1585b57d02aSXiao Guangrong * @id: sub feature id. 1595b57d02aSXiao Guangrong * @ops: ops of this sub feature. 1605b57d02aSXiao Guangrong */ 1615b57d02aSXiao Guangrong struct dfl_feature_driver { 1625b57d02aSXiao Guangrong u64 id; 1635b57d02aSXiao Guangrong const struct dfl_feature_ops *ops; 1645b57d02aSXiao Guangrong }; 1655b57d02aSXiao Guangrong 1665b57d02aSXiao Guangrong /** 167543be3d8SWu Hao * struct dfl_feature - sub feature of the feature devices 168543be3d8SWu Hao * 169543be3d8SWu Hao * @id: sub feature id. 170543be3d8SWu Hao * @resource_index: each sub feature has one mmio resource for its registers. 171543be3d8SWu Hao * this index is used to find its mmio resource from the 172543be3d8SWu Hao * feature dev (platform device)'s reources. 173543be3d8SWu Hao * @ioaddr: mapped mmio resource address. 1745b57d02aSXiao Guangrong * @ops: ops of this sub feature. 175543be3d8SWu Hao */ 176543be3d8SWu Hao struct dfl_feature { 177543be3d8SWu Hao u64 id; 178543be3d8SWu Hao int resource_index; 179543be3d8SWu Hao void __iomem *ioaddr; 1805b57d02aSXiao Guangrong const struct dfl_feature_ops *ops; 181543be3d8SWu Hao }; 182543be3d8SWu Hao 1835b57d02aSXiao Guangrong #define DEV_STATUS_IN_USE 0 1845b57d02aSXiao Guangrong 185543be3d8SWu Hao /** 186543be3d8SWu Hao * struct dfl_feature_platform_data - platform data for feature devices 187543be3d8SWu Hao * 188543be3d8SWu Hao * @node: node to link feature devs to container device's port_dev_list. 189543be3d8SWu Hao * @lock: mutex to protect platform data. 190b16c5147SWu Hao * @cdev: cdev of feature dev. 191543be3d8SWu Hao * @dev: ptr to platform device linked with this platform data. 192543be3d8SWu Hao * @dfl_cdev: ptr to container device. 193543be3d8SWu Hao * @disable_count: count for port disable. 194543be3d8SWu Hao * @num: number for sub features. 1955b57d02aSXiao Guangrong * @dev_status: dev status (e.g. DEV_STATUS_IN_USE). 1965b57d02aSXiao Guangrong * @private: ptr to feature dev private data. 197543be3d8SWu Hao * @features: sub features of this feature dev. 198543be3d8SWu Hao */ 199543be3d8SWu Hao struct dfl_feature_platform_data { 200543be3d8SWu Hao struct list_head node; 201543be3d8SWu Hao struct mutex lock; 202b16c5147SWu Hao struct cdev cdev; 203543be3d8SWu Hao struct platform_device *dev; 204543be3d8SWu Hao struct dfl_fpga_cdev *dfl_cdev; 205543be3d8SWu Hao unsigned int disable_count; 2065b57d02aSXiao Guangrong unsigned long dev_status; 2075b57d02aSXiao Guangrong void *private; 208543be3d8SWu Hao int num; 209543be3d8SWu Hao struct dfl_feature features[0]; 210543be3d8SWu Hao }; 211543be3d8SWu Hao 2125b57d02aSXiao Guangrong static inline 2135b57d02aSXiao Guangrong int dfl_feature_dev_use_begin(struct dfl_feature_platform_data *pdata) 2145b57d02aSXiao Guangrong { 2155b57d02aSXiao Guangrong /* Test and set IN_USE flags to ensure file is exclusively used */ 2165b57d02aSXiao Guangrong if (test_and_set_bit_lock(DEV_STATUS_IN_USE, &pdata->dev_status)) 2175b57d02aSXiao Guangrong return -EBUSY; 2185b57d02aSXiao Guangrong 2195b57d02aSXiao Guangrong return 0; 2205b57d02aSXiao Guangrong } 2215b57d02aSXiao Guangrong 2225b57d02aSXiao Guangrong static inline 2235b57d02aSXiao Guangrong void dfl_feature_dev_use_end(struct dfl_feature_platform_data *pdata) 2245b57d02aSXiao Guangrong { 2255b57d02aSXiao Guangrong clear_bit_unlock(DEV_STATUS_IN_USE, &pdata->dev_status); 2265b57d02aSXiao Guangrong } 2275b57d02aSXiao Guangrong 2285b57d02aSXiao Guangrong static inline 2295b57d02aSXiao Guangrong void dfl_fpga_pdata_set_private(struct dfl_feature_platform_data *pdata, 2305b57d02aSXiao Guangrong void *private) 2315b57d02aSXiao Guangrong { 2325b57d02aSXiao Guangrong pdata->private = private; 2335b57d02aSXiao Guangrong } 2345b57d02aSXiao Guangrong 2355b57d02aSXiao Guangrong static inline 2365b57d02aSXiao Guangrong void *dfl_fpga_pdata_get_private(struct dfl_feature_platform_data *pdata) 2375b57d02aSXiao Guangrong { 2385b57d02aSXiao Guangrong return pdata->private; 2395b57d02aSXiao Guangrong } 2405b57d02aSXiao Guangrong 2415b57d02aSXiao Guangrong struct dfl_feature_ops { 2425b57d02aSXiao Guangrong int (*init)(struct platform_device *pdev, struct dfl_feature *feature); 2435b57d02aSXiao Guangrong void (*uinit)(struct platform_device *pdev, 2445b57d02aSXiao Guangrong struct dfl_feature *feature); 2455b57d02aSXiao Guangrong long (*ioctl)(struct platform_device *pdev, struct dfl_feature *feature, 2465b57d02aSXiao Guangrong unsigned int cmd, unsigned long arg); 2475b57d02aSXiao Guangrong }; 2485b57d02aSXiao Guangrong 249543be3d8SWu Hao #define DFL_FPGA_FEATURE_DEV_FME "dfl-fme" 250543be3d8SWu Hao #define DFL_FPGA_FEATURE_DEV_PORT "dfl-port" 251543be3d8SWu Hao 252543be3d8SWu Hao static inline int dfl_feature_platform_data_size(const int num) 253543be3d8SWu Hao { 254543be3d8SWu Hao return sizeof(struct dfl_feature_platform_data) + 255543be3d8SWu Hao num * sizeof(struct dfl_feature); 256543be3d8SWu Hao } 257543be3d8SWu Hao 2585b57d02aSXiao Guangrong void dfl_fpga_dev_feature_uinit(struct platform_device *pdev); 2595b57d02aSXiao Guangrong int dfl_fpga_dev_feature_init(struct platform_device *pdev, 2605b57d02aSXiao Guangrong struct dfl_feature_driver *feature_drvs); 2615b57d02aSXiao Guangrong 262b16c5147SWu Hao int dfl_fpga_dev_ops_register(struct platform_device *pdev, 263b16c5147SWu Hao const struct file_operations *fops, 264b16c5147SWu Hao struct module *owner); 265b16c5147SWu Hao void dfl_fpga_dev_ops_unregister(struct platform_device *pdev); 266b16c5147SWu Hao 2675b57d02aSXiao Guangrong static inline 2685b57d02aSXiao Guangrong struct platform_device *dfl_fpga_inode_to_feature_dev(struct inode *inode) 2695b57d02aSXiao Guangrong { 2705b57d02aSXiao Guangrong struct dfl_feature_platform_data *pdata; 2715b57d02aSXiao Guangrong 2725b57d02aSXiao Guangrong pdata = container_of(inode->i_cdev, struct dfl_feature_platform_data, 2735b57d02aSXiao Guangrong cdev); 2745b57d02aSXiao Guangrong return pdata->dev; 2755b57d02aSXiao Guangrong } 2765b57d02aSXiao Guangrong 277543be3d8SWu Hao #define dfl_fpga_dev_for_each_feature(pdata, feature) \ 278543be3d8SWu Hao for ((feature) = (pdata)->features; \ 279543be3d8SWu Hao (feature) < (pdata)->features + (pdata)->num; (feature)++) 280543be3d8SWu Hao 281543be3d8SWu Hao static inline 282543be3d8SWu Hao struct dfl_feature *dfl_get_feature_by_id(struct device *dev, u64 id) 283543be3d8SWu Hao { 284543be3d8SWu Hao struct dfl_feature_platform_data *pdata = dev_get_platdata(dev); 285543be3d8SWu Hao struct dfl_feature *feature; 286543be3d8SWu Hao 287543be3d8SWu Hao dfl_fpga_dev_for_each_feature(pdata, feature) 288543be3d8SWu Hao if (feature->id == id) 289543be3d8SWu Hao return feature; 290543be3d8SWu Hao 291543be3d8SWu Hao return NULL; 292543be3d8SWu Hao } 293543be3d8SWu Hao 294543be3d8SWu Hao static inline 295543be3d8SWu Hao void __iomem *dfl_get_feature_ioaddr_by_id(struct device *dev, u64 id) 296543be3d8SWu Hao { 297543be3d8SWu Hao struct dfl_feature *feature = dfl_get_feature_by_id(dev, id); 298543be3d8SWu Hao 299543be3d8SWu Hao if (feature && feature->ioaddr) 300543be3d8SWu Hao return feature->ioaddr; 301543be3d8SWu Hao 302543be3d8SWu Hao WARN_ON(1); 303543be3d8SWu Hao return NULL; 304543be3d8SWu Hao } 305543be3d8SWu Hao 3065b57d02aSXiao Guangrong static inline bool is_dfl_feature_present(struct device *dev, u64 id) 3075b57d02aSXiao Guangrong { 3085b57d02aSXiao Guangrong return !!dfl_get_feature_ioaddr_by_id(dev, id); 3095b57d02aSXiao Guangrong } 3105b57d02aSXiao Guangrong 3115b57d02aSXiao Guangrong static inline 3125b57d02aSXiao Guangrong struct device *dfl_fpga_pdata_to_parent(struct dfl_feature_platform_data *pdata) 3135b57d02aSXiao Guangrong { 3145b57d02aSXiao Guangrong return pdata->dev->dev.parent->parent; 3155b57d02aSXiao Guangrong } 3165b57d02aSXiao Guangrong 317543be3d8SWu Hao static inline bool dfl_feature_is_fme(void __iomem *base) 318543be3d8SWu Hao { 319543be3d8SWu Hao u64 v = readq(base + DFH); 320543be3d8SWu Hao 321543be3d8SWu Hao return (FIELD_GET(DFH_TYPE, v) == DFH_TYPE_FIU) && 322543be3d8SWu Hao (FIELD_GET(DFH_ID, v) == DFH_ID_FIU_FME); 323543be3d8SWu Hao } 324543be3d8SWu Hao 325543be3d8SWu Hao static inline bool dfl_feature_is_port(void __iomem *base) 326543be3d8SWu Hao { 327543be3d8SWu Hao u64 v = readq(base + DFH); 328543be3d8SWu Hao 329543be3d8SWu Hao return (FIELD_GET(DFH_TYPE, v) == DFH_TYPE_FIU) && 330543be3d8SWu Hao (FIELD_GET(DFH_ID, v) == DFH_ID_FIU_PORT); 331543be3d8SWu Hao } 332543be3d8SWu Hao 333543be3d8SWu Hao /** 334543be3d8SWu Hao * struct dfl_fpga_enum_info - DFL FPGA enumeration information 335543be3d8SWu Hao * 336543be3d8SWu Hao * @dev: parent device. 337543be3d8SWu Hao * @dfls: list of device feature lists. 338543be3d8SWu Hao */ 339543be3d8SWu Hao struct dfl_fpga_enum_info { 340543be3d8SWu Hao struct device *dev; 341543be3d8SWu Hao struct list_head dfls; 342543be3d8SWu Hao }; 343543be3d8SWu Hao 344543be3d8SWu Hao /** 345543be3d8SWu Hao * struct dfl_fpga_enum_dfl - DFL FPGA enumeration device feature list info 346543be3d8SWu Hao * 347543be3d8SWu Hao * @start: base address of this device feature list. 348543be3d8SWu Hao * @len: size of this device feature list. 349543be3d8SWu Hao * @ioaddr: mapped base address of this device feature list. 350543be3d8SWu Hao * @node: node in list of device feature lists. 351543be3d8SWu Hao */ 352543be3d8SWu Hao struct dfl_fpga_enum_dfl { 353543be3d8SWu Hao resource_size_t start; 354543be3d8SWu Hao resource_size_t len; 355543be3d8SWu Hao 356543be3d8SWu Hao void __iomem *ioaddr; 357543be3d8SWu Hao 358543be3d8SWu Hao struct list_head node; 359543be3d8SWu Hao }; 360543be3d8SWu Hao 361543be3d8SWu Hao struct dfl_fpga_enum_info *dfl_fpga_enum_info_alloc(struct device *dev); 362543be3d8SWu Hao int dfl_fpga_enum_info_add_dfl(struct dfl_fpga_enum_info *info, 363543be3d8SWu Hao resource_size_t start, resource_size_t len, 364543be3d8SWu Hao void __iomem *ioaddr); 365543be3d8SWu Hao void dfl_fpga_enum_info_free(struct dfl_fpga_enum_info *info); 366543be3d8SWu Hao 367543be3d8SWu Hao /** 368543be3d8SWu Hao * struct dfl_fpga_cdev - container device of DFL based FPGA 369543be3d8SWu Hao * 370543be3d8SWu Hao * @parent: parent device of this container device. 371543be3d8SWu Hao * @region: base fpga region. 372543be3d8SWu Hao * @fme_dev: FME feature device under this container device. 373543be3d8SWu Hao * @lock: mutex lock to protect the port device list. 374543be3d8SWu Hao * @port_dev_list: list of all port feature devices under this container device. 375543be3d8SWu Hao */ 376543be3d8SWu Hao struct dfl_fpga_cdev { 377543be3d8SWu Hao struct device *parent; 378543be3d8SWu Hao struct fpga_region *region; 379543be3d8SWu Hao struct device *fme_dev; 380543be3d8SWu Hao struct mutex lock; 381543be3d8SWu Hao struct list_head port_dev_list; 382543be3d8SWu Hao }; 383543be3d8SWu Hao 384543be3d8SWu Hao struct dfl_fpga_cdev * 385543be3d8SWu Hao dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info); 386543be3d8SWu Hao void dfl_fpga_feature_devs_remove(struct dfl_fpga_cdev *cdev); 387543be3d8SWu Hao 3885d56e117SWu Hao /* 3895d56e117SWu Hao * need to drop the device reference with put_device() after use port platform 3905d56e117SWu Hao * device returned by __dfl_fpga_cdev_find_port and dfl_fpga_cdev_find_port 3915d56e117SWu Hao * functions. 3925d56e117SWu Hao */ 3935d56e117SWu Hao struct platform_device * 3945d56e117SWu Hao __dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data, 3955d56e117SWu Hao int (*match)(struct platform_device *, void *)); 3965d56e117SWu Hao 3975d56e117SWu Hao static inline struct platform_device * 3985d56e117SWu Hao dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data, 3995d56e117SWu Hao int (*match)(struct platform_device *, void *)) 4005d56e117SWu Hao { 4015d56e117SWu Hao struct platform_device *pdev; 4025d56e117SWu Hao 4035d56e117SWu Hao mutex_lock(&cdev->lock); 4045d56e117SWu Hao pdev = __dfl_fpga_cdev_find_port(cdev, data, match); 4055d56e117SWu Hao mutex_unlock(&cdev->lock); 4065d56e117SWu Hao 4075d56e117SWu Hao return pdev; 4085d56e117SWu Hao } 409543be3d8SWu Hao #endif /* __FPGA_DFL_H */ 410