@@ -101,6 +101,7 @@ struct ffa_drv_info {
101101 bool bitmap_created ;
102102 bool notif_enabled ;
103103 unsigned int sched_recv_irq ;
104+ unsigned int notif_pend_irq ;
104105 unsigned int cpuhp_state ;
105106 struct ffa_pcpu_irq __percpu * irq_pcpu ;
106107 struct workqueue_struct * notif_pcpu_wq ;
@@ -1301,6 +1302,15 @@ static irqreturn_t ffa_sched_recv_irq_handler(int irq, void *irq_data)
13011302 return IRQ_HANDLED ;
13021303}
13031304
1305+ static irqreturn_t notif_pend_irq_handler (int irq , void * irq_data )
1306+ {
1307+ struct ffa_pcpu_irq * pcpu = irq_data ;
1308+
1309+ ffa_self_notif_handle (smp_processor_id (), true, pcpu -> info );
1310+
1311+ return IRQ_HANDLED ;
1312+ }
1313+
13041314static void ffa_sched_recv_irq_work_fn (struct work_struct * work )
13051315{
13061316 ffa_notification_info_get ();
@@ -1364,13 +1374,19 @@ static void ffa_irq_unmap(unsigned int irq)
13641374
13651375static int ffa_cpuhp_pcpu_irq_enable (unsigned int cpu )
13661376{
1367- enable_percpu_irq (drv_info -> sched_recv_irq , IRQ_TYPE_NONE );
1377+ if (drv_info -> sched_recv_irq )
1378+ enable_percpu_irq (drv_info -> sched_recv_irq , IRQ_TYPE_NONE );
1379+ if (drv_info -> notif_pend_irq )
1380+ enable_percpu_irq (drv_info -> notif_pend_irq , IRQ_TYPE_NONE );
13681381 return 0 ;
13691382}
13701383
13711384static int ffa_cpuhp_pcpu_irq_disable (unsigned int cpu )
13721385{
1373- disable_percpu_irq (drv_info -> sched_recv_irq );
1386+ if (drv_info -> sched_recv_irq )
1387+ disable_percpu_irq (drv_info -> sched_recv_irq );
1388+ if (drv_info -> notif_pend_irq )
1389+ disable_percpu_irq (drv_info -> notif_pend_irq );
13741390 return 0 ;
13751391}
13761392
@@ -1389,13 +1405,16 @@ static void ffa_uninit_pcpu_irq(void)
13891405 if (drv_info -> sched_recv_irq )
13901406 free_percpu_irq (drv_info -> sched_recv_irq , drv_info -> irq_pcpu );
13911407
1408+ if (drv_info -> notif_pend_irq )
1409+ free_percpu_irq (drv_info -> notif_pend_irq , drv_info -> irq_pcpu );
1410+
13921411 if (drv_info -> irq_pcpu ) {
13931412 free_percpu (drv_info -> irq_pcpu );
13941413 drv_info -> irq_pcpu = NULL ;
13951414 }
13961415}
13971416
1398- static int ffa_init_pcpu_irq (unsigned int irq )
1417+ static int ffa_init_pcpu_irq (void )
13991418{
14001419 struct ffa_pcpu_irq __percpu * irq_pcpu ;
14011420 int ret , cpu ;
@@ -1409,11 +1428,26 @@ static int ffa_init_pcpu_irq(unsigned int irq)
14091428
14101429 drv_info -> irq_pcpu = irq_pcpu ;
14111430
1412- ret = request_percpu_irq (irq , ffa_sched_recv_irq_handler , "ARM-FFA-SRI" ,
1413- irq_pcpu );
1414- if (ret ) {
1415- pr_err ("Error registering notification IRQ %d: %d\n" , irq , ret );
1416- return ret ;
1431+ if (drv_info -> sched_recv_irq ) {
1432+ ret = request_percpu_irq (drv_info -> sched_recv_irq ,
1433+ ffa_sched_recv_irq_handler ,
1434+ "ARM-FFA-SRI" , irq_pcpu );
1435+ if (ret ) {
1436+ pr_err ("Error registering percpu SRI nIRQ %d : %d\n" ,
1437+ drv_info -> sched_recv_irq , ret );
1438+ return ret ;
1439+ }
1440+ }
1441+
1442+ if (drv_info -> notif_pend_irq ) {
1443+ ret = request_percpu_irq (drv_info -> notif_pend_irq ,
1444+ notif_pend_irq_handler ,
1445+ "ARM-FFA-NPI" , irq_pcpu );
1446+ if (ret ) {
1447+ pr_err ("Error registering percpu NPI nIRQ %d : %d\n" ,
1448+ drv_info -> notif_pend_irq , ret );
1449+ return ret ;
1450+ }
14171451 }
14181452
14191453 INIT_WORK (& drv_info -> sched_recv_irq_work , ffa_sched_recv_irq_work_fn );
@@ -1438,6 +1472,8 @@ static void ffa_notifications_cleanup(void)
14381472 ffa_uninit_pcpu_irq ();
14391473 ffa_irq_unmap (drv_info -> sched_recv_irq );
14401474 drv_info -> sched_recv_irq = 0 ;
1475+ ffa_irq_unmap (drv_info -> notif_pend_irq );
1476+ drv_info -> notif_pend_irq = 0 ;
14411477
14421478 if (drv_info -> bitmap_created ) {
14431479 ffa_notification_bitmap_destroy ();
@@ -1448,7 +1484,7 @@ static void ffa_notifications_cleanup(void)
14481484
14491485static void ffa_notifications_setup (void )
14501486{
1451- int ret , irq ;
1487+ int ret ;
14521488
14531489 ret = ffa_features (FFA_NOTIFICATION_BITMAP_CREATE , 0 , NULL , NULL );
14541490 if (!ret ) {
@@ -1461,15 +1497,18 @@ static void ffa_notifications_setup(void)
14611497 drv_info -> bitmap_created = true;
14621498 }
14631499
1464- irq = ffa_irq_map (FFA_FEAT_SCHEDULE_RECEIVER_INT );
1465- if (irq <= 0 ) {
1466- ret = irq ;
1467- goto cleanup ;
1468- }
1500+ ret = ffa_irq_map (FFA_FEAT_SCHEDULE_RECEIVER_INT );
1501+ if (ret > 0 )
1502+ drv_info -> sched_recv_irq = ret ;
1503+
1504+ ret = ffa_irq_map (FFA_FEAT_NOTIFICATION_PENDING_INT );
1505+ if (ret > 0 )
1506+ drv_info -> notif_pend_irq = ret ;
14691507
1470- drv_info -> sched_recv_irq = irq ;
1508+ if (!drv_info -> sched_recv_irq && !drv_info -> notif_pend_irq )
1509+ goto cleanup ;
14711510
1472- ret = ffa_init_pcpu_irq (irq );
1511+ ret = ffa_init_pcpu_irq ();
14731512 if (ret )
14741513 goto cleanup ;
14751514
0 commit comments