@@ -460,26 +460,49 @@ int xdna_mailbox_send_msg(struct mailbox_channel *mb_chann,
460460 return ret ;
461461}
462462
463- struct mailbox_channel *
464- xdna_mailbox_create_channel (struct mailbox * mb ,
465- const struct xdna_mailbox_chann_res * x2i ,
466- const struct xdna_mailbox_chann_res * i2x ,
467- u32 iohub_int_addr ,
468- int mb_irq )
463+ struct mailbox_channel * xdna_mailbox_alloc_channel (struct mailbox * mb )
469464{
470465 struct mailbox_channel * mb_chann ;
471- int ret ;
472-
473- if (!is_power_of_2 (x2i -> rb_size ) || !is_power_of_2 (i2x -> rb_size )) {
474- pr_err ("Ring buf size must be power of 2" );
475- return NULL ;
476- }
477466
478467 mb_chann = kzalloc_obj (* mb_chann );
479468 if (!mb_chann )
480469 return NULL ;
481470
471+ INIT_WORK (& mb_chann -> rx_work , mailbox_rx_worker );
472+ mb_chann -> work_q = create_singlethread_workqueue (MAILBOX_NAME );
473+ if (!mb_chann -> work_q ) {
474+ MB_ERR (mb_chann , "Create workqueue failed" );
475+ goto free_chann ;
476+ }
482477 mb_chann -> mb = mb ;
478+
479+ return mb_chann ;
480+
481+ free_chann :
482+ kfree (mb_chann );
483+ return NULL ;
484+ }
485+
486+ void xdna_mailbox_free_channel (struct mailbox_channel * mb_chann )
487+ {
488+ destroy_workqueue (mb_chann -> work_q );
489+ kfree (mb_chann );
490+ }
491+
492+ int
493+ xdna_mailbox_start_channel (struct mailbox_channel * mb_chann ,
494+ const struct xdna_mailbox_chann_res * x2i ,
495+ const struct xdna_mailbox_chann_res * i2x ,
496+ u32 iohub_int_addr ,
497+ int mb_irq )
498+ {
499+ int ret ;
500+
501+ if (!is_power_of_2 (x2i -> rb_size ) || !is_power_of_2 (i2x -> rb_size )) {
502+ pr_err ("Ring buf size must be power of 2" );
503+ return - EINVAL ;
504+ }
505+
483506 mb_chann -> msix_irq = mb_irq ;
484507 mb_chann -> iohub_int_addr = iohub_int_addr ;
485508 memcpy (& mb_chann -> res [CHAN_RES_X2I ], x2i , sizeof (* x2i ));
@@ -489,61 +512,37 @@ xdna_mailbox_create_channel(struct mailbox *mb,
489512 mb_chann -> x2i_tail = mailbox_get_tailptr (mb_chann , CHAN_RES_X2I );
490513 mb_chann -> i2x_head = mailbox_get_headptr (mb_chann , CHAN_RES_I2X );
491514
492- INIT_WORK (& mb_chann -> rx_work , mailbox_rx_worker );
493- mb_chann -> work_q = create_singlethread_workqueue (MAILBOX_NAME );
494- if (!mb_chann -> work_q ) {
495- MB_ERR (mb_chann , "Create workqueue failed" );
496- goto free_and_out ;
497- }
498-
499515 /* Everything look good. Time to enable irq handler */
500516 ret = request_irq (mb_irq , mailbox_irq_handler , 0 , MAILBOX_NAME , mb_chann );
501517 if (ret ) {
502518 MB_ERR (mb_chann , "Failed to request irq %d ret %d" , mb_irq , ret );
503- goto destroy_wq ;
519+ return ret ;
504520 }
505521
506522 mb_chann -> bad_state = false;
507523 mailbox_reg_write (mb_chann , mb_chann -> iohub_int_addr , 0 );
508524
509- MB_DBG (mb_chann , "Mailbox channel created (irq: %d)" , mb_chann -> msix_irq );
510- return mb_chann ;
511-
512- destroy_wq :
513- destroy_workqueue (mb_chann -> work_q );
514- free_and_out :
515- kfree (mb_chann );
516- return NULL ;
525+ MB_DBG (mb_chann , "Mailbox channel started (irq: %d)" , mb_chann -> msix_irq );
526+ return 0 ;
517527}
518528
519- int xdna_mailbox_destroy_channel (struct mailbox_channel * mb_chann )
529+ void xdna_mailbox_stop_channel (struct mailbox_channel * mb_chann )
520530{
521531 struct mailbox_msg * mb_msg ;
522532 unsigned long msg_id ;
523533
524- MB_DBG ( mb_chann , "IRQ disabled and RX work cancelled" );
534+ /* Disable an irq and wait. This might sleep. */
525535 free_irq (mb_chann -> msix_irq , mb_chann );
526- destroy_workqueue (mb_chann -> work_q );
527- /* We can clean up and release resources */
528536
537+ /* Cancel RX work and wait for it to finish */
538+ drain_workqueue (mb_chann -> work_q );
539+
540+ /* We can clean up and release resources */
529541 xa_for_each (& mb_chann -> chan_xa , msg_id , mb_msg )
530542 mailbox_release_msg (mb_chann , mb_msg );
531-
532543 xa_destroy (& mb_chann -> chan_xa );
533544
534- MB_DBG (mb_chann , "Mailbox channel destroyed, irq: %d" , mb_chann -> msix_irq );
535- kfree (mb_chann );
536- return 0 ;
537- }
538-
539- void xdna_mailbox_stop_channel (struct mailbox_channel * mb_chann )
540- {
541- /* Disable an irq and wait. This might sleep. */
542- disable_irq (mb_chann -> msix_irq );
543-
544- /* Cancel RX work and wait for it to finish */
545- cancel_work_sync (& mb_chann -> rx_work );
546- MB_DBG (mb_chann , "IRQ disabled and RX work cancelled" );
545+ MB_DBG (mb_chann , "Mailbox channel stopped, irq: %d" , mb_chann -> msix_irq );
547546}
548547
549548struct mailbox * xdnam_mailbox_create (struct drm_device * ddev ,
0 commit comments