@@ -202,29 +202,42 @@ __scmi_xfer_put(struct scmi_xfers_info *minfo, struct scmi_xfer *xfer)
202
202
spin_unlock_irqrestore (& minfo -> xfer_lock , flags );
203
203
}
204
204
205
- /**
206
- * scmi_rx_callback() - callback for receiving messages
207
- *
208
- * @cinfo: SCMI channel info
209
- * @msg_hdr: Message header
210
- *
211
- * Processes one received message to appropriate transfer information and
212
- * signals completion of the transfer.
213
- *
214
- * NOTE: This function will be invoked in IRQ context, hence should be
215
- * as optimal as possible.
216
- */
217
- void scmi_rx_callback (struct scmi_chan_info * cinfo , u32 msg_hdr )
205
+ static void scmi_handle_notification (struct scmi_chan_info * cinfo , u32 msg_hdr )
218
206
{
219
- struct scmi_info * info = handle_to_scmi_info (cinfo -> handle );
220
- struct scmi_xfers_info * minfo = & info -> tx_minfo ;
221
- u16 xfer_id = MSG_XTRACT_TOKEN (msg_hdr );
222
- u8 msg_type = MSG_XTRACT_TYPE (msg_hdr );
223
- struct device * dev = cinfo -> dev ;
224
207
struct scmi_xfer * xfer ;
208
+ struct device * dev = cinfo -> dev ;
209
+ struct scmi_info * info = handle_to_scmi_info (cinfo -> handle );
210
+ struct scmi_xfers_info * minfo = & info -> rx_minfo ;
211
+
212
+ xfer = scmi_xfer_get (cinfo -> handle , minfo );
213
+ if (IS_ERR (xfer )) {
214
+ dev_err (dev , "failed to get free message slot (%ld)\n" ,
215
+ PTR_ERR (xfer ));
216
+ info -> desc -> ops -> clear_notification (cinfo );
217
+ return ;
218
+ }
219
+
220
+ unpack_scmi_header (msg_hdr , & xfer -> hdr );
221
+ scmi_dump_header_dbg (dev , & xfer -> hdr );
222
+ info -> desc -> ops -> fetch_notification (cinfo , info -> desc -> max_msg_size ,
223
+ xfer );
224
+
225
+ trace_scmi_rx_done (xfer -> transfer_id , xfer -> hdr .id ,
226
+ xfer -> hdr .protocol_id , xfer -> hdr .seq ,
227
+ MSG_TYPE_NOTIFICATION );
225
228
226
- if (msg_type == MSG_TYPE_NOTIFICATION )
227
- return ; /* Notifications not yet supported */
229
+ __scmi_xfer_put (minfo , xfer );
230
+
231
+ info -> desc -> ops -> clear_notification (cinfo );
232
+ }
233
+
234
+ static void scmi_handle_response (struct scmi_chan_info * cinfo ,
235
+ u16 xfer_id , u8 msg_type )
236
+ {
237
+ struct scmi_xfer * xfer ;
238
+ struct device * dev = cinfo -> dev ;
239
+ struct scmi_info * info = handle_to_scmi_info (cinfo -> handle );
240
+ struct scmi_xfers_info * minfo = & info -> tx_minfo ;
228
241
229
242
/* Are we even expecting this? */
230
243
if (!test_bit (xfer_id , minfo -> xfer_alloc_table )) {
@@ -248,6 +261,37 @@ void scmi_rx_callback(struct scmi_chan_info *cinfo, u32 msg_hdr)
248
261
complete (& xfer -> done );
249
262
}
250
263
264
+ /**
265
+ * scmi_rx_callback() - callback for receiving messages
266
+ *
267
+ * @cinfo: SCMI channel info
268
+ * @msg_hdr: Message header
269
+ *
270
+ * Processes one received message to appropriate transfer information and
271
+ * signals completion of the transfer.
272
+ *
273
+ * NOTE: This function will be invoked in IRQ context, hence should be
274
+ * as optimal as possible.
275
+ */
276
+ void scmi_rx_callback (struct scmi_chan_info * cinfo , u32 msg_hdr )
277
+ {
278
+ u16 xfer_id = MSG_XTRACT_TOKEN (msg_hdr );
279
+ u8 msg_type = MSG_XTRACT_TYPE (msg_hdr );
280
+
281
+ switch (msg_type ) {
282
+ case MSG_TYPE_NOTIFICATION :
283
+ scmi_handle_notification (cinfo , msg_hdr );
284
+ break ;
285
+ case MSG_TYPE_COMMAND :
286
+ case MSG_TYPE_DELAYED_RESP :
287
+ scmi_handle_response (cinfo , xfer_id , msg_type );
288
+ break ;
289
+ default :
290
+ WARN_ONCE (1 , "received unknown msg_type:%d\n" , msg_type );
291
+ break ;
292
+ }
293
+ }
294
+
251
295
/**
252
296
* scmi_xfer_put() - Release a transmit message
253
297
*
0 commit comments