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 */ 1336e8fd6e4SWu Hao /** 1346e8fd6e4SWu Hao * struct dfl_fpga_port_ops - port ops 1356e8fd6e4SWu Hao * 1366e8fd6e4SWu Hao * @name: name of this port ops, to match with port platform device. 1376e8fd6e4SWu Hao * @owner: pointer to the module which owns this port ops. 1386e8fd6e4SWu Hao * @node: node to link port ops to global list. 1396e8fd6e4SWu Hao * @get_id: get port id from hardware. 1406e8fd6e4SWu Hao * @enable_set: enable/disable the port. 1416e8fd6e4SWu Hao */ 1426e8fd6e4SWu Hao struct dfl_fpga_port_ops { 1436e8fd6e4SWu Hao const char *name; 1446e8fd6e4SWu Hao struct module *owner; 1456e8fd6e4SWu Hao struct list_head node; 1466e8fd6e4SWu Hao int (*get_id)(struct platform_device *pdev); 1476e8fd6e4SWu Hao int (*enable_set)(struct platform_device *pdev, bool enable); 1486e8fd6e4SWu Hao }; 1496e8fd6e4SWu Hao 1506e8fd6e4SWu Hao void dfl_fpga_port_ops_add(struct dfl_fpga_port_ops *ops); 1516e8fd6e4SWu Hao void dfl_fpga_port_ops_del(struct dfl_fpga_port_ops *ops); 1526e8fd6e4SWu Hao struct dfl_fpga_port_ops *dfl_fpga_port_ops_get(struct platform_device *pdev); 1536e8fd6e4SWu Hao void dfl_fpga_port_ops_put(struct dfl_fpga_port_ops *ops); 154*d06b004bSWu Hao int dfl_fpga_check_port_id(struct platform_device *pdev, void *pport_id); 155543be3d8SWu Hao 156543be3d8SWu Hao /** 1575b57d02aSXiao Guangrong * struct dfl_feature_driver - sub feature's driver 1585b57d02aSXiao Guangrong * 1595b57d02aSXiao Guangrong * @id: sub feature id. 1605b57d02aSXiao Guangrong * @ops: ops of this sub feature. 1615b57d02aSXiao Guangrong */ 1625b57d02aSXiao Guangrong struct dfl_feature_driver { 1635b57d02aSXiao Guangrong u64 id; 1645b57d02aSXiao Guangrong const struct dfl_feature_ops *ops; 1655b57d02aSXiao Guangrong }; 1665b57d02aSXiao Guangrong 1675b57d02aSXiao Guangrong /** 168543be3d8SWu Hao * struct dfl_feature - sub feature of the feature devices 169543be3d8SWu Hao * 170543be3d8SWu Hao * @id: sub feature id. 171543be3d8SWu Hao * @resource_index: each sub feature has one mmio resource for its registers. 172543be3d8SWu Hao * this index is used to find its mmio resource from the 173543be3d8SWu Hao * feature dev (platform device)'s reources. 174543be3d8SWu Hao * @ioaddr: mapped mmio resource address. 1755b57d02aSXiao Guangrong * @ops: ops of this sub feature. 176543be3d8SWu Hao */ 177543be3d8SWu Hao struct dfl_feature { 178543be3d8SWu Hao u64 id; 179543be3d8SWu Hao int resource_index; 180543be3d8SWu Hao void __iomem *ioaddr; 1815b57d02aSXiao Guangrong const struct dfl_feature_ops *ops; 182543be3d8SWu Hao }; 183543be3d8SWu Hao 1845b57d02aSXiao Guangrong #define DEV_STATUS_IN_USE 0 1855b57d02aSXiao Guangrong 186543be3d8SWu Hao /** 187543be3d8SWu Hao * struct dfl_feature_platform_data - platform data for feature devices 188543be3d8SWu Hao * 189543be3d8SWu Hao * @node: node to link feature devs to container device's port_dev_list. 190543be3d8SWu Hao * @lock: mutex to protect platform data. 191b16c5147SWu Hao * @cdev: cdev of feature dev. 192543be3d8SWu Hao * @dev: ptr to platform device linked with this platform data. 193543be3d8SWu Hao * @dfl_cdev: ptr to container device. 194543be3d8SWu Hao * @disable_count: count for port disable. 195543be3d8SWu Hao * @num: number for sub features. 1965b57d02aSXiao Guangrong * @dev_status: dev status (e.g. DEV_STATUS_IN_USE). 1975b57d02aSXiao Guangrong * @private: ptr to feature dev private data. 198543be3d8SWu Hao * @features: sub features of this feature dev. 199543be3d8SWu Hao */ 200543be3d8SWu Hao struct dfl_feature_platform_data { 201543be3d8SWu Hao struct list_head node; 202543be3d8SWu Hao struct mutex lock; 203b16c5147SWu Hao struct cdev cdev; 204543be3d8SWu Hao struct platform_device *dev; 205543be3d8SWu Hao struct dfl_fpga_cdev *dfl_cdev; 206543be3d8SWu Hao unsigned int disable_count; 2075b57d02aSXiao Guangrong unsigned long dev_status; 2085b57d02aSXiao Guangrong void *private; 209543be3d8SWu Hao int num; 210543be3d8SWu Hao struct dfl_feature features[0]; 211543be3d8SWu Hao }; 212543be3d8SWu Hao 2135b57d02aSXiao Guangrong static inline 2145b57d02aSXiao Guangrong int dfl_feature_dev_use_begin(struct dfl_feature_platform_data *pdata) 2155b57d02aSXiao Guangrong { 2165b57d02aSXiao Guangrong /* Test and set IN_USE flags to ensure file is exclusively used */ 2175b57d02aSXiao Guangrong if (test_and_set_bit_lock(DEV_STATUS_IN_USE, &pdata->dev_status)) 2185b57d02aSXiao Guangrong return -EBUSY; 2195b57d02aSXiao Guangrong 2205b57d02aSXiao Guangrong return 0; 2215b57d02aSXiao Guangrong } 2225b57d02aSXiao Guangrong 2235b57d02aSXiao Guangrong static inline 2245b57d02aSXiao Guangrong void dfl_feature_dev_use_end(struct dfl_feature_platform_data *pdata) 2255b57d02aSXiao Guangrong { 2265b57d02aSXiao Guangrong clear_bit_unlock(DEV_STATUS_IN_USE, &pdata->dev_status); 2275b57d02aSXiao Guangrong } 2285b57d02aSXiao Guangrong 2295b57d02aSXiao Guangrong static inline 2305b57d02aSXiao Guangrong void dfl_fpga_pdata_set_private(struct dfl_feature_platform_data *pdata, 2315b57d02aSXiao Guangrong void *private) 2325b57d02aSXiao Guangrong { 2335b57d02aSXiao Guangrong pdata->private = private; 2345b57d02aSXiao Guangrong } 2355b57d02aSXiao Guangrong 2365b57d02aSXiao Guangrong static inline 2375b57d02aSXiao Guangrong void *dfl_fpga_pdata_get_private(struct dfl_feature_platform_data *pdata) 2385b57d02aSXiao Guangrong { 2395b57d02aSXiao Guangrong return pdata->private; 2405b57d02aSXiao Guangrong } 2415b57d02aSXiao Guangrong 2425b57d02aSXiao Guangrong struct dfl_feature_ops { 2435b57d02aSXiao Guangrong int (*init)(struct platform_device *pdev, struct dfl_feature *feature); 2445b57d02aSXiao Guangrong void (*uinit)(struct platform_device *pdev, 2455b57d02aSXiao Guangrong struct dfl_feature *feature); 2465b57d02aSXiao Guangrong long (*ioctl)(struct platform_device *pdev, struct dfl_feature *feature, 2475b57d02aSXiao Guangrong unsigned int cmd, unsigned long arg); 2485b57d02aSXiao Guangrong }; 2495b57d02aSXiao Guangrong 250543be3d8SWu Hao #define DFL_FPGA_FEATURE_DEV_FME "dfl-fme" 251543be3d8SWu Hao #define DFL_FPGA_FEATURE_DEV_PORT "dfl-port" 252543be3d8SWu Hao 253543be3d8SWu Hao static inline int dfl_feature_platform_data_size(const int num) 254543be3d8SWu Hao { 255543be3d8SWu Hao return sizeof(struct dfl_feature_platform_data) + 256543be3d8SWu Hao num * sizeof(struct dfl_feature); 257543be3d8SWu Hao } 258543be3d8SWu Hao 2595b57d02aSXiao Guangrong void dfl_fpga_dev_feature_uinit(struct platform_device *pdev); 2605b57d02aSXiao Guangrong int dfl_fpga_dev_feature_init(struct platform_device *pdev, 2615b57d02aSXiao Guangrong struct dfl_feature_driver *feature_drvs); 2625b57d02aSXiao Guangrong 263b16c5147SWu Hao int dfl_fpga_dev_ops_register(struct platform_device *pdev, 264b16c5147SWu Hao const struct file_operations *fops, 265b16c5147SWu Hao struct module *owner); 266b16c5147SWu Hao void dfl_fpga_dev_ops_unregister(struct platform_device *pdev); 267b16c5147SWu Hao 2685b57d02aSXiao Guangrong static inline 2695b57d02aSXiao Guangrong struct platform_device *dfl_fpga_inode_to_feature_dev(struct inode *inode) 2705b57d02aSXiao Guangrong { 2715b57d02aSXiao Guangrong struct dfl_feature_platform_data *pdata; 2725b57d02aSXiao Guangrong 2735b57d02aSXiao Guangrong pdata = container_of(inode->i_cdev, struct dfl_feature_platform_data, 2745b57d02aSXiao Guangrong cdev); 2755b57d02aSXiao Guangrong return pdata->dev; 2765b57d02aSXiao Guangrong } 2775b57d02aSXiao Guangrong 278543be3d8SWu Hao #define dfl_fpga_dev_for_each_feature(pdata, feature) \ 279543be3d8SWu Hao for ((feature) = (pdata)->features; \ 280543be3d8SWu Hao (feature) < (pdata)->features + (pdata)->num; (feature)++) 281543be3d8SWu Hao 282543be3d8SWu Hao static inline 283543be3d8SWu Hao struct dfl_feature *dfl_get_feature_by_id(struct device *dev, u64 id) 284543be3d8SWu Hao { 285543be3d8SWu Hao struct dfl_feature_platform_data *pdata = dev_get_platdata(dev); 286543be3d8SWu Hao struct dfl_feature *feature; 287543be3d8SWu Hao 288543be3d8SWu Hao dfl_fpga_dev_for_each_feature(pdata, feature) 289543be3d8SWu Hao if (feature->id == id) 290543be3d8SWu Hao return feature; 291543be3d8SWu Hao 292543be3d8SWu Hao return NULL; 293543be3d8SWu Hao } 294543be3d8SWu Hao 295543be3d8SWu Hao static inline 296543be3d8SWu Hao void __iomem *dfl_get_feature_ioaddr_by_id(struct device *dev, u64 id) 297543be3d8SWu Hao { 298543be3d8SWu Hao struct dfl_feature *feature = dfl_get_feature_by_id(dev, id); 299543be3d8SWu Hao 300543be3d8SWu Hao if (feature && feature->ioaddr) 301543be3d8SWu Hao return feature->ioaddr; 302543be3d8SWu Hao 303543be3d8SWu Hao WARN_ON(1); 304543be3d8SWu Hao return NULL; 305543be3d8SWu Hao } 306543be3d8SWu Hao 3075b57d02aSXiao Guangrong static inline bool is_dfl_feature_present(struct device *dev, u64 id) 3085b57d02aSXiao Guangrong { 3095b57d02aSXiao Guangrong return !!dfl_get_feature_ioaddr_by_id(dev, id); 3105b57d02aSXiao Guangrong } 3115b57d02aSXiao Guangrong 3125b57d02aSXiao Guangrong static inline 3135b57d02aSXiao Guangrong struct device *dfl_fpga_pdata_to_parent(struct dfl_feature_platform_data *pdata) 3145b57d02aSXiao Guangrong { 3155b57d02aSXiao Guangrong return pdata->dev->dev.parent->parent; 3165b57d02aSXiao Guangrong } 3175b57d02aSXiao Guangrong 318543be3d8SWu Hao static inline bool dfl_feature_is_fme(void __iomem *base) 319543be3d8SWu Hao { 320543be3d8SWu Hao u64 v = readq(base + DFH); 321543be3d8SWu Hao 322543be3d8SWu Hao return (FIELD_GET(DFH_TYPE, v) == DFH_TYPE_FIU) && 323543be3d8SWu Hao (FIELD_GET(DFH_ID, v) == DFH_ID_FIU_FME); 324543be3d8SWu Hao } 325543be3d8SWu Hao 326543be3d8SWu Hao static inline bool dfl_feature_is_port(void __iomem *base) 327543be3d8SWu Hao { 328543be3d8SWu Hao u64 v = readq(base + DFH); 329543be3d8SWu Hao 330543be3d8SWu Hao return (FIELD_GET(DFH_TYPE, v) == DFH_TYPE_FIU) && 331543be3d8SWu Hao (FIELD_GET(DFH_ID, v) == DFH_ID_FIU_PORT); 332543be3d8SWu Hao } 333543be3d8SWu Hao 334543be3d8SWu Hao /** 335543be3d8SWu Hao * struct dfl_fpga_enum_info - DFL FPGA enumeration information 336543be3d8SWu Hao * 337543be3d8SWu Hao * @dev: parent device. 338543be3d8SWu Hao * @dfls: list of device feature lists. 339543be3d8SWu Hao */ 340543be3d8SWu Hao struct dfl_fpga_enum_info { 341543be3d8SWu Hao struct device *dev; 342543be3d8SWu Hao struct list_head dfls; 343543be3d8SWu Hao }; 344543be3d8SWu Hao 345543be3d8SWu Hao /** 346543be3d8SWu Hao * struct dfl_fpga_enum_dfl - DFL FPGA enumeration device feature list info 347543be3d8SWu Hao * 348543be3d8SWu Hao * @start: base address of this device feature list. 349543be3d8SWu Hao * @len: size of this device feature list. 350543be3d8SWu Hao * @ioaddr: mapped base address of this device feature list. 351543be3d8SWu Hao * @node: node in list of device feature lists. 352543be3d8SWu Hao */ 353543be3d8SWu Hao struct dfl_fpga_enum_dfl { 354543be3d8SWu Hao resource_size_t start; 355543be3d8SWu Hao resource_size_t len; 356543be3d8SWu Hao 357543be3d8SWu Hao void __iomem *ioaddr; 358543be3d8SWu Hao 359543be3d8SWu Hao struct list_head node; 360543be3d8SWu Hao }; 361543be3d8SWu Hao 362543be3d8SWu Hao struct dfl_fpga_enum_info *dfl_fpga_enum_info_alloc(struct device *dev); 363543be3d8SWu Hao int dfl_fpga_enum_info_add_dfl(struct dfl_fpga_enum_info *info, 364543be3d8SWu Hao resource_size_t start, resource_size_t len, 365543be3d8SWu Hao void __iomem *ioaddr); 366543be3d8SWu Hao void dfl_fpga_enum_info_free(struct dfl_fpga_enum_info *info); 367543be3d8SWu Hao 368543be3d8SWu Hao /** 369543be3d8SWu Hao * struct dfl_fpga_cdev - container device of DFL based FPGA 370543be3d8SWu Hao * 371543be3d8SWu Hao * @parent: parent device of this container device. 372543be3d8SWu Hao * @region: base fpga region. 373543be3d8SWu Hao * @fme_dev: FME feature device under this container device. 374543be3d8SWu Hao * @lock: mutex lock to protect the port device list. 375543be3d8SWu Hao * @port_dev_list: list of all port feature devices under this container device. 376543be3d8SWu Hao */ 377543be3d8SWu Hao struct dfl_fpga_cdev { 378543be3d8SWu Hao struct device *parent; 379543be3d8SWu Hao struct fpga_region *region; 380543be3d8SWu Hao struct device *fme_dev; 381543be3d8SWu Hao struct mutex lock; 382543be3d8SWu Hao struct list_head port_dev_list; 383543be3d8SWu Hao }; 384543be3d8SWu Hao 385543be3d8SWu Hao struct dfl_fpga_cdev * 386543be3d8SWu Hao dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info); 387543be3d8SWu Hao void dfl_fpga_feature_devs_remove(struct dfl_fpga_cdev *cdev); 388543be3d8SWu Hao 3895d56e117SWu Hao /* 3905d56e117SWu Hao * need to drop the device reference with put_device() after use port platform 3915d56e117SWu Hao * device returned by __dfl_fpga_cdev_find_port and dfl_fpga_cdev_find_port 3925d56e117SWu Hao * functions. 3935d56e117SWu Hao */ 3945d56e117SWu Hao struct platform_device * 3955d56e117SWu Hao __dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data, 3965d56e117SWu Hao int (*match)(struct platform_device *, void *)); 3975d56e117SWu Hao 3985d56e117SWu Hao static inline struct platform_device * 3995d56e117SWu Hao dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data, 4005d56e117SWu Hao int (*match)(struct platform_device *, void *)) 4015d56e117SWu Hao { 4025d56e117SWu Hao struct platform_device *pdev; 4035d56e117SWu Hao 4045d56e117SWu Hao mutex_lock(&cdev->lock); 4055d56e117SWu Hao pdev = __dfl_fpga_cdev_find_port(cdev, data, match); 4065d56e117SWu Hao mutex_unlock(&cdev->lock); 4075d56e117SWu Hao 4085d56e117SWu Hao return pdev; 4095d56e117SWu Hao } 410543be3d8SWu Hao #endif /* __FPGA_DFL_H */ 411