131
131
#define PORT_CTRL_LATENCY BIT_ULL(2)
132
132
#define PORT_CTRL_SFTRST_ACK BIT_ULL(4) /* HW ack for reset */
133
133
134
+ /**
135
+ * struct dfl_feature_driver - sub feature's driver
136
+ *
137
+ * @id: sub feature id.
138
+ * @ops: ops of this sub feature.
139
+ */
140
+ struct dfl_feature_driver {
141
+ u64 id ;
142
+ const struct dfl_feature_ops * ops ;
143
+ };
144
+
134
145
/**
135
146
* struct dfl_feature - sub feature of the feature devices
136
147
*
139
150
* this index is used to find its mmio resource from the
140
151
* feature dev (platform device)'s reources.
141
152
* @ioaddr: mapped mmio resource address.
153
+ * @ops: ops of this sub feature.
142
154
*/
143
155
struct dfl_feature {
144
156
u64 id ;
145
157
int resource_index ;
146
158
void __iomem * ioaddr ;
159
+ const struct dfl_feature_ops * ops ;
147
160
};
148
161
162
+ #define DEV_STATUS_IN_USE 0
163
+
149
164
/**
150
165
* struct dfl_feature_platform_data - platform data for feature devices
151
166
*
@@ -156,6 +171,8 @@ struct dfl_feature {
156
171
* @dfl_cdev: ptr to container device.
157
172
* @disable_count: count for port disable.
158
173
* @num: number for sub features.
174
+ * @dev_status: dev status (e.g. DEV_STATUS_IN_USE).
175
+ * @private: ptr to feature dev private data.
159
176
* @features: sub features of this feature dev.
160
177
*/
161
178
struct dfl_feature_platform_data {
@@ -165,11 +182,49 @@ struct dfl_feature_platform_data {
165
182
struct platform_device * dev ;
166
183
struct dfl_fpga_cdev * dfl_cdev ;
167
184
unsigned int disable_count ;
168
-
185
+ unsigned long dev_status ;
186
+ void * private ;
169
187
int num ;
170
188
struct dfl_feature features [0 ];
171
189
};
172
190
191
+ static inline
192
+ int dfl_feature_dev_use_begin (struct dfl_feature_platform_data * pdata )
193
+ {
194
+ /* Test and set IN_USE flags to ensure file is exclusively used */
195
+ if (test_and_set_bit_lock (DEV_STATUS_IN_USE , & pdata -> dev_status ))
196
+ return - EBUSY ;
197
+
198
+ return 0 ;
199
+ }
200
+
201
+ static inline
202
+ void dfl_feature_dev_use_end (struct dfl_feature_platform_data * pdata )
203
+ {
204
+ clear_bit_unlock (DEV_STATUS_IN_USE , & pdata -> dev_status );
205
+ }
206
+
207
+ static inline
208
+ void dfl_fpga_pdata_set_private (struct dfl_feature_platform_data * pdata ,
209
+ void * private )
210
+ {
211
+ pdata -> private = private ;
212
+ }
213
+
214
+ static inline
215
+ void * dfl_fpga_pdata_get_private (struct dfl_feature_platform_data * pdata )
216
+ {
217
+ return pdata -> private ;
218
+ }
219
+
220
+ struct dfl_feature_ops {
221
+ int (* init )(struct platform_device * pdev , struct dfl_feature * feature );
222
+ void (* uinit )(struct platform_device * pdev ,
223
+ struct dfl_feature * feature );
224
+ long (* ioctl )(struct platform_device * pdev , struct dfl_feature * feature ,
225
+ unsigned int cmd , unsigned long arg );
226
+ };
227
+
173
228
#define DFL_FPGA_FEATURE_DEV_FME "dfl-fme"
174
229
#define DFL_FPGA_FEATURE_DEV_PORT "dfl-port"
175
230
@@ -179,11 +234,25 @@ static inline int dfl_feature_platform_data_size(const int num)
179
234
num * sizeof (struct dfl_feature );
180
235
}
181
236
237
+ void dfl_fpga_dev_feature_uinit (struct platform_device * pdev );
238
+ int dfl_fpga_dev_feature_init (struct platform_device * pdev ,
239
+ struct dfl_feature_driver * feature_drvs );
240
+
182
241
int dfl_fpga_dev_ops_register (struct platform_device * pdev ,
183
242
const struct file_operations * fops ,
184
243
struct module * owner );
185
244
void dfl_fpga_dev_ops_unregister (struct platform_device * pdev );
186
245
246
+ static inline
247
+ struct platform_device * dfl_fpga_inode_to_feature_dev (struct inode * inode )
248
+ {
249
+ struct dfl_feature_platform_data * pdata ;
250
+
251
+ pdata = container_of (inode -> i_cdev , struct dfl_feature_platform_data ,
252
+ cdev );
253
+ return pdata -> dev ;
254
+ }
255
+
187
256
#define dfl_fpga_dev_for_each_feature (pdata , feature ) \
188
257
for ((feature) = (pdata)->features; \
189
258
(feature) < (pdata)->features + (pdata)->num; (feature)++)
@@ -213,6 +282,17 @@ void __iomem *dfl_get_feature_ioaddr_by_id(struct device *dev, u64 id)
213
282
return NULL ;
214
283
}
215
284
285
+ static inline bool is_dfl_feature_present (struct device * dev , u64 id )
286
+ {
287
+ return !!dfl_get_feature_ioaddr_by_id (dev , id );
288
+ }
289
+
290
+ static inline
291
+ struct device * dfl_fpga_pdata_to_parent (struct dfl_feature_platform_data * pdata )
292
+ {
293
+ return pdata -> dev -> dev .parent -> parent ;
294
+ }
295
+
216
296
static inline bool dfl_feature_is_fme (void __iomem * base )
217
297
{
218
298
u64 v = readq (base + DFH );
0 commit comments