@@ -172,8 +172,6 @@ struct pispbe_node {
172172 struct mutex node_lock ;
173173 /* vb2_queue lock */
174174 struct mutex queue_lock ;
175- /* Protect pispbe_node->ready_queue and pispbe_buffer->ready_list */
176- spinlock_t ready_lock ;
177175 struct list_head ready_queue ;
178176 struct vb2_queue queue ;
179177 struct v4l2_format format ;
@@ -219,6 +217,9 @@ struct pispbe_hw_enables {
219217
220218/* Records a job configuration and memory addresses. */
221219struct pispbe_job_descriptor {
220+ struct list_head queue ;
221+ struct pispbe_buffer * buffers [PISPBE_NUM_NODES ];
222+ struct pispbe_node_group * node_group ;
222223 dma_addr_t hw_dma_addrs [N_HW_ADDRESSES ];
223224 struct pisp_be_tiles_config * config ;
224225 struct pispbe_hw_enables hw_enables ;
@@ -235,8 +236,10 @@ struct pispbe_dev {
235236 struct clk * clk ;
236237 struct pispbe_node_group node_group [PISPBE_NUM_NODE_GROUPS ];
237238 struct pispbe_job queued_job , running_job ;
238- spinlock_t hw_lock ; /* protects "hw_busy" flag and streaming_map */
239+ /* protects "hw_busy" flag, streaming_map and job_queue */
240+ spinlock_t hw_lock ;
239241 bool hw_busy ; /* non-zero if a job is queued or is being started */
242+ struct list_head job_queue ;
240243 int irq ;
241244 u32 hw_version ;
242245 u8 done , started ;
@@ -460,42 +463,48 @@ static void pispbe_xlate_addrs(struct pispbe_job_descriptor *job,
460463 * For Output0, Output1, Tdn and Stitch, a buffer only needs to be
461464 * available if the blocks are enabled in the config.
462465 *
463- * Needs to be called with hw_lock held.
466+ * If all the buffers required to form a job are available, append the
467+ * job descriptor to the job queue to be later queued to the HW.
464468 *
465469 * Returns 0 if a job has been successfully prepared, < 0 otherwise.
466470 */
467- static int pispbe_prepare_job (struct pispbe_node_group * node_group ,
468- struct pispbe_job_descriptor * job )
471+ static int pispbe_prepare_job (struct pispbe_node_group * node_group )
469472{
470473 struct pispbe_buffer * buf [PISPBE_NUM_NODES ] = {};
471474 struct pispbe_dev * pispbe = node_group -> pispbe ;
475+ struct pispbe_job_descriptor * job ;
476+ unsigned int streaming_map ;
472477 unsigned int config_index ;
473478 struct pispbe_node * node ;
474- unsigned long flags ;
475479
476- lockdep_assert_held (& pispbe -> hw_lock );
480+ scoped_guard (spinlock_irq , & pispbe -> hw_lock ) {
481+ static const u32 mask = BIT (CONFIG_NODE ) | BIT (MAIN_INPUT_NODE );
477482
478- memset (job , 0 , sizeof (struct pispbe_job_descriptor ));
483+ if ((node_group -> streaming_map & mask ) != mask )
484+ return - ENODEV ;
479485
480- if (((BIT (CONFIG_NODE ) | BIT (MAIN_INPUT_NODE )) &
481- node_group -> streaming_map ) !=
482- (BIT (CONFIG_NODE ) | BIT (MAIN_INPUT_NODE )))
483- return - ENODEV ;
486+ /*
487+ * Take a copy of streaming_map: nodes activated after this
488+ * point are ignored when preparing this job.
489+ */
490+ streaming_map = node_group -> streaming_map ;
491+ }
492+
493+ job = kzalloc (sizeof (* job ), GFP_KERNEL );
494+ if (!job )
495+ return - ENOMEM ;
484496
485497 node = & node_group -> node [CONFIG_NODE ];
486- spin_lock_irqsave (& node -> ready_lock , flags );
487498 buf [CONFIG_NODE ] = list_first_entry_or_null (& node -> ready_queue ,
488499 struct pispbe_buffer ,
489500 ready_list );
490- if (buf [CONFIG_NODE ]) {
491- list_del ( & buf [ CONFIG_NODE ] -> ready_list );
492- pispbe -> queued_job . buf [ CONFIG_NODE ] = buf [ CONFIG_NODE ] ;
501+ if (! buf [CONFIG_NODE ]) {
502+ kfree ( job );
503+ return - ENODEV ;
493504 }
494- spin_unlock_irqrestore (& node -> ready_lock , flags );
495505
496- /* Exit early if no config buffer has been queued. */
497- if (!buf [CONFIG_NODE ])
498- return - ENODEV ;
506+ list_del (& buf [CONFIG_NODE ]-> ready_list );
507+ job -> buffers [CONFIG_NODE ] = buf [CONFIG_NODE ];
499508
500509 config_index = buf [CONFIG_NODE ]-> vb .vb2_buf .index ;
501510 job -> config = & node_group -> config [config_index ];
@@ -516,7 +525,7 @@ static int pispbe_prepare_job(struct pispbe_node_group *node_group,
516525 continue ;
517526
518527 buf [i ] = NULL ;
519- if (!(node_group -> streaming_map & BIT (i )))
528+ if (!(streaming_map & BIT (i )))
520529 continue ;
521530
522531 if ((!(rgb_en & PISP_BE_RGB_ENABLE_OUTPUT0 ) &&
@@ -543,25 +552,27 @@ static int pispbe_prepare_job(struct pispbe_node_group *node_group,
543552 node = & node_group -> node [i ];
544553
545554 /* Pull a buffer from each V4L2 queue to form the queued job */
546- spin_lock_irqsave (& node -> ready_lock , flags );
547555 buf [i ] = list_first_entry_or_null (& node -> ready_queue ,
548556 struct pispbe_buffer ,
549557 ready_list );
550558 if (buf [i ]) {
551559 list_del (& buf [i ]-> ready_list );
552- pispbe -> queued_job . buf [i ] = buf [i ];
560+ job -> buffers [i ] = buf [i ];
553561 }
554- spin_unlock_irqrestore (& node -> ready_lock , flags );
555562
556563 if (!buf [i ] && !ignore_buffers )
557564 goto err_return_buffers ;
558565 }
559566
560- pispbe -> queued_job . node_group = node_group ;
567+ job -> node_group = node_group ;
561568
562569 /* Convert buffers to DMA addresses for the hardware */
563570 pispbe_xlate_addrs (job , buf , node_group );
564571
572+ spin_lock (& pispbe -> hw_lock );
573+ list_add_tail (& job -> queue , & pispbe -> job_queue );
574+ spin_unlock (& pispbe -> hw_lock );
575+
565576 return 0 ;
566577
567578err_return_buffers :
@@ -572,12 +583,10 @@ static int pispbe_prepare_job(struct pispbe_node_group *node_group,
572583 continue ;
573584
574585 /* Return the buffer to the ready_list queue */
575- spin_lock_irqsave (& n -> ready_lock , flags );
576586 list_add (& buf [i ]-> ready_list , & n -> ready_queue );
577- spin_unlock_irqrestore (& n -> ready_lock , flags );
578587 }
579588
580- memset ( & pispbe -> queued_job , 0 , sizeof ( pispbe -> queued_job ) );
589+ kfree ( job );
581590
582591 return - ENODEV ;
583592}
@@ -586,49 +595,41 @@ static void pispbe_schedule(struct pispbe_dev *pispbe,
586595 struct pispbe_node_group * node_group ,
587596 bool clear_hw_busy )
588597{
589- struct pispbe_job_descriptor job ;
590- unsigned long flags ;
591-
592- spin_lock_irqsave (& pispbe -> hw_lock , flags );
593-
594- if (clear_hw_busy )
595- pispbe -> hw_busy = false;
598+ struct pispbe_job_descriptor * job ;
596599
597- if (pispbe -> hw_busy )
598- goto unlock_and_return ;
600+ scoped_guard (spinlock_irqsave , & pispbe -> hw_lock ) {
601+ if (clear_hw_busy )
602+ pispbe -> hw_busy = false;
599603
600- for ( unsigned int i = 0 ; i < PISPBE_NUM_NODE_GROUPS ; i ++ ) {
601- int ret ;
604+ if ( pispbe -> hw_busy )
605+ return ;
602606
603- /* Schedule jobs only for a specific group. */
604- if (node_group && & pispbe -> node_group [i ] != node_group )
605- continue ;
607+ job = list_first_entry_or_null (& pispbe -> job_queue ,
608+ struct pispbe_job_descriptor ,
609+ queue );
610+ if (!job )
611+ return ;
606612
607- /*
608- * Prepare a job for this group, if the group is not ready
609- * continue and try with the next one.
610- */
611- ret = pispbe_prepare_job (& pispbe -> node_group [i ], & job );
612- if (ret )
613+ if (node_group && job -> node_group != node_group )
613614 continue ;
614615
615- /*
616- * We can kick the job off without the hw_lock, as this can
617- * never run again until hw_busy is cleared, which will happen
618- * only when the following job has been queued and an interrupt
619- * is rised.
620- */
621- pispbe -> hw_busy = true;
622- spin_unlock_irqrestore (& pispbe -> hw_lock , flags );
616+ list_del (& job -> queue );
623617
624- pispbe_queue_job (pispbe , & job );
618+ for (unsigned int i = 0 ; i < PISPBE_NUM_NODES ; i ++ )
619+ pispbe -> queued_job .buf [i ] = job -> buffers [i ];
620+ pispbe -> queued_job .node_group = job -> node_group ;
625621
626- return ;
622+ pispbe -> hw_busy = true ;
627623 }
628624
629- unlock_and_return :
630- /* No job has been queued, just release the lock and return. */
631- spin_unlock_irqrestore (& pispbe -> hw_lock , flags );
625+ /*
626+ * We can kick the job off without the hw_lock, as this can
627+ * never run again until hw_busy is cleared, which will happen
628+ * only when the following job has been queued and an interrupt
629+ * is rised.
630+ */
631+ pispbe_queue_job (pispbe , job );
632+ kfree (job );
632633}
633634
634635static void pispbe_isr_jobdone (struct pispbe_dev * pispbe ,
@@ -881,18 +882,16 @@ static void pispbe_node_buffer_queue(struct vb2_buffer *buf)
881882 struct pispbe_node * node = vb2_get_drv_priv (buf -> vb2_queue );
882883 struct pispbe_node_group * node_group = node -> node_group ;
883884 struct pispbe_dev * pispbe = node -> node_group -> pispbe ;
884- unsigned long flags ;
885885
886886 dev_dbg (pispbe -> dev , "%s: for node %s\n" , __func__ , NODE_NAME (node ));
887- spin_lock_irqsave (& node -> ready_lock , flags );
888887 list_add_tail (& buffer -> ready_list , & node -> ready_queue );
889- spin_unlock_irqrestore (& node -> ready_lock , flags );
890888
891889 /*
892890 * Every time we add a buffer, check if there's now some work for the hw
893891 * to do, but only for this client.
894892 */
895- pispbe_schedule (node_group -> pispbe , node_group , false);
893+ if (!pispbe_prepare_job (node_group ))
894+ pispbe_schedule (pispbe , node_group , false);
896895}
897896
898897static int pispbe_node_start_streaming (struct vb2_queue * q , unsigned int count )
@@ -901,35 +900,33 @@ static int pispbe_node_start_streaming(struct vb2_queue *q, unsigned int count)
901900 struct pispbe_node_group * node_group = node -> node_group ;
902901 struct pispbe_dev * pispbe = node_group -> pispbe ;
903902 struct pispbe_buffer * buf , * tmp ;
904- unsigned long flags ;
905903 int ret ;
906904
907905 ret = pm_runtime_resume_and_get (pispbe -> dev );
908906 if (ret < 0 )
909907 goto err_return_buffers ;
910908
911- spin_lock_irqsave (& pispbe -> hw_lock , flags );
909+ spin_lock_irq (& pispbe -> hw_lock );
912910 node -> node_group -> streaming_map |= BIT (node -> id );
913911 node -> node_group -> sequence = 0 ;
914- spin_unlock_irqrestore (& pispbe -> hw_lock , flags );
912+ spin_unlock_irq (& pispbe -> hw_lock );
915913
916914 dev_dbg (pispbe -> dev , "%s: for node %s (count %u)\n" ,
917915 __func__ , NODE_NAME (node ), count );
918916 dev_dbg (pispbe -> dev , "Nodes streaming for this group now 0x%x\n" ,
919917 node -> node_group -> streaming_map );
920918
921919 /* Maybe we're ready to run. */
922- pispbe_schedule (node_group -> pispbe , node_group , false);
920+ if (!pispbe_prepare_job (node_group ))
921+ pispbe_schedule (pispbe , node_group , false);
923922
924923 return 0 ;
925924
926925err_return_buffers :
927- spin_lock_irqsave (& pispbe -> hw_lock , flags );
928926 list_for_each_entry_safe (buf , tmp , & node -> ready_queue , ready_list ) {
929927 list_del (& buf -> ready_list );
930928 vb2_buffer_done (& buf -> vb .vb2_buf , VB2_BUF_STATE_QUEUED );
931929 }
932- spin_unlock_irqrestore (& pispbe -> hw_lock , flags );
933930
934931 return ret ;
935932}
@@ -940,7 +937,6 @@ static void pispbe_node_stop_streaming(struct vb2_queue *q)
940937 struct pispbe_node_group * node_group = node -> node_group ;
941938 struct pispbe_dev * pispbe = node_group -> pispbe ;
942939 struct pispbe_buffer * buf ;
943- unsigned long flags ;
944940
945941 /*
946942 * Now this is a bit awkward. In a simple M2M device we could just wait
@@ -952,27 +948,34 @@ static void pispbe_node_stop_streaming(struct vb2_queue *q)
952948 * This may return buffers out of order.
953949 */
954950 dev_dbg (pispbe -> dev , "%s: for node %s\n" , __func__ , NODE_NAME (node ));
955- spin_lock_irqsave (& pispbe -> hw_lock , flags );
956951 do {
957- unsigned long flags1 ;
958-
959- spin_lock_irqsave (& node -> ready_lock , flags1 );
960952 buf = list_first_entry_or_null (& node -> ready_queue ,
961953 struct pispbe_buffer ,
962954 ready_list );
963955 if (buf ) {
964956 list_del (& buf -> ready_list );
965957 vb2_buffer_done (& buf -> vb .vb2_buf , VB2_BUF_STATE_ERROR );
966958 }
967- spin_unlock_irqrestore (& node -> ready_lock , flags1 );
968959 } while (buf );
969- spin_unlock_irqrestore (& pispbe -> hw_lock , flags );
970960
971961 vb2_wait_for_all_buffers (& node -> queue );
972962
973- spin_lock_irqsave (& pispbe -> hw_lock , flags );
963+ spin_lock_irq (& pispbe -> hw_lock );
974964 node_group -> streaming_map &= ~BIT (node -> id );
975- spin_unlock_irqrestore (& pispbe -> hw_lock , flags );
965+
966+ /* Release all jobs in the group once all nodes have stopped streaming. */
967+ if (node_group -> streaming_map == 0 ) {
968+ struct pispbe_job_descriptor * job , * temp ;
969+
970+ list_for_each_entry_safe (job , temp , & pispbe -> job_queue , queue ) {
971+ if (job -> node_group != node_group )
972+ continue ;
973+
974+ list_del (& job -> queue );
975+ kfree (job );
976+ }
977+ }
978+ spin_unlock_irq (& pispbe -> hw_lock );
976979
977980 pm_runtime_mark_last_busy (pispbe -> dev );
978981 pm_runtime_put_autosuspend (pispbe -> dev );
@@ -1432,7 +1435,6 @@ static int pispbe_init_node(struct pispbe_node_group *node_group,
14321435 mutex_init (& node -> node_lock );
14331436 mutex_init (& node -> queue_lock );
14341437 INIT_LIST_HEAD (& node -> ready_queue );
1435- spin_lock_init (& node -> ready_lock );
14361438
14371439 node -> format .type = node -> buf_type ;
14381440 pispbe_node_def_fmt (node );
@@ -1731,6 +1733,8 @@ static int pispbe_probe(struct platform_device *pdev)
17311733 if (!pispbe )
17321734 return - ENOMEM ;
17331735
1736+ INIT_LIST_HEAD (& pispbe -> job_queue );
1737+
17341738 dev_set_drvdata (& pdev -> dev , pispbe );
17351739 pispbe -> dev = & pdev -> dev ;
17361740 platform_set_drvdata (pdev , pispbe );
0 commit comments