@@ -465,13 +465,34 @@ static void xgene_hwmon_evt_work(struct work_struct *work)
465
465
}
466
466
}
467
467
468
+ static int xgene_hwmon_rx_ready (struct xgene_hwmon_dev * ctx , void * msg )
469
+ {
470
+ if (IS_ERR_OR_NULL (ctx -> hwmon_dev ) && !ctx -> resp_pending ) {
471
+ /* Enqueue to the FIFO */
472
+ kfifo_in_spinlocked (& ctx -> async_msg_fifo , msg ,
473
+ sizeof (struct slimpro_resp_msg ),
474
+ & ctx -> kfifo_lock );
475
+ return - ENODEV ;
476
+ }
477
+
478
+ return 0 ;
479
+ }
480
+
468
481
/*
469
482
* This function is called when the SLIMpro Mailbox received a message
470
483
*/
471
484
static void xgene_hwmon_rx_cb (struct mbox_client * cl , void * msg )
472
485
{
473
486
struct xgene_hwmon_dev * ctx = to_xgene_hwmon_dev (cl );
474
- struct slimpro_resp_msg amsg ;
487
+
488
+ /*
489
+ * While the driver registers with the mailbox framework, an interrupt
490
+ * can be pending before the probe function completes its
491
+ * initialization. If such condition occurs, just queue up the message
492
+ * as the driver is not ready for servicing the callback.
493
+ */
494
+ if (xgene_hwmon_rx_ready (ctx , msg ) < 0 )
495
+ return ;
475
496
476
497
/*
477
498
* Response message format:
@@ -500,12 +521,8 @@ static void xgene_hwmon_rx_cb(struct mbox_client *cl, void *msg)
500
521
return ;
501
522
}
502
523
503
- amsg .msg = ((u32 * )msg )[0 ];
504
- amsg .param1 = ((u32 * )msg )[1 ];
505
- amsg .param2 = ((u32 * )msg )[2 ];
506
-
507
524
/* Enqueue to the FIFO */
508
- kfifo_in_spinlocked (& ctx -> async_msg_fifo , & amsg ,
525
+ kfifo_in_spinlocked (& ctx -> async_msg_fifo , msg ,
509
526
sizeof (struct slimpro_resp_msg ), & ctx -> kfifo_lock );
510
527
/* Schedule the bottom handler */
511
528
schedule_work (& ctx -> workq );
@@ -520,6 +537,15 @@ static void xgene_hwmon_pcc_rx_cb(struct mbox_client *cl, void *msg)
520
537
struct acpi_pcct_shared_memory * generic_comm_base = ctx -> pcc_comm_addr ;
521
538
struct slimpro_resp_msg amsg ;
522
539
540
+ /*
541
+ * While the driver registers with the mailbox framework, an interrupt
542
+ * can be pending before the probe function completes its
543
+ * initialization. If such condition occurs, just queue up the message
544
+ * as the driver is not ready for servicing the callback.
545
+ */
546
+ if (xgene_hwmon_rx_ready (ctx , & amsg ) < 0 )
547
+ return ;
548
+
523
549
msg = generic_comm_base + 1 ;
524
550
/* Check if platform sends interrupt */
525
551
if (!xgene_word_tst_and_clr (& generic_comm_base -> status ,
@@ -596,6 +622,17 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
596
622
platform_set_drvdata (pdev , ctx );
597
623
cl = & ctx -> mbox_client ;
598
624
625
+ spin_lock_init (& ctx -> kfifo_lock );
626
+ mutex_init (& ctx -> rd_mutex );
627
+
628
+ rc = kfifo_alloc (& ctx -> async_msg_fifo ,
629
+ sizeof (struct slimpro_resp_msg ) * ASYNC_MSG_FIFO_SIZE ,
630
+ GFP_KERNEL );
631
+ if (rc )
632
+ goto out_mbox_free ;
633
+
634
+ INIT_WORK (& ctx -> workq , xgene_hwmon_evt_work );
635
+
599
636
/* Request mailbox channel */
600
637
cl -> dev = & pdev -> dev ;
601
638
cl -> tx_done = xgene_hwmon_tx_done ;
@@ -676,17 +713,6 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
676
713
ctx -> usecs_lat = PCC_NUM_RETRIES * cppc_ss -> latency ;
677
714
}
678
715
679
- spin_lock_init (& ctx -> kfifo_lock );
680
- mutex_init (& ctx -> rd_mutex );
681
-
682
- rc = kfifo_alloc (& ctx -> async_msg_fifo ,
683
- sizeof (struct slimpro_resp_msg ) * ASYNC_MSG_FIFO_SIZE ,
684
- GFP_KERNEL );
685
- if (rc )
686
- goto out_mbox_free ;
687
-
688
- INIT_WORK (& ctx -> workq , xgene_hwmon_evt_work );
689
-
690
716
ctx -> hwmon_dev = hwmon_device_register_with_groups (ctx -> dev ,
691
717
"apm_xgene" ,
692
718
ctx ,
@@ -697,17 +723,22 @@ static int xgene_hwmon_probe(struct platform_device *pdev)
697
723
goto out ;
698
724
}
699
725
726
+ /*
727
+ * Schedule the bottom handler if there is a pending message.
728
+ */
729
+ schedule_work (& ctx -> workq );
730
+
700
731
dev_info (& pdev -> dev , "APM X-Gene SoC HW monitor driver registered\n" );
701
732
702
733
return 0 ;
703
734
704
735
out :
705
- kfifo_free (& ctx -> async_msg_fifo );
706
- out_mbox_free :
707
736
if (acpi_disabled )
708
737
mbox_free_channel (ctx -> mbox_chan );
709
738
else
710
739
pcc_mbox_free_channel (ctx -> mbox_chan );
740
+ out_mbox_free :
741
+ kfifo_free (& ctx -> async_msg_fifo );
711
742
712
743
return rc ;
713
744
}
0 commit comments