@@ -67,8 +67,14 @@ struct tegra_hsp_doorbell {
6767 unsigned int index ;
6868};
6969
70+ struct tegra_hsp_sm_ops {
71+ void (* send )(struct tegra_hsp_channel * channel , void * data );
72+ void (* recv )(struct tegra_hsp_channel * channel );
73+ };
74+
7075struct tegra_hsp_mailbox {
7176 struct tegra_hsp_channel channel ;
77+ const struct tegra_hsp_sm_ops * ops ;
7278 unsigned int index ;
7379 bool producer ;
7480};
@@ -208,8 +214,7 @@ static irqreturn_t tegra_hsp_shared_irq(int irq, void *data)
208214{
209215 struct tegra_hsp * hsp = data ;
210216 unsigned long bit , mask ;
211- u32 status , value ;
212- void * msg ;
217+ u32 status ;
213218
214219 status = tegra_hsp_readl (hsp , HSP_INT_IR ) & hsp -> mask ;
215220
@@ -245,25 +250,8 @@ static irqreturn_t tegra_hsp_shared_irq(int irq, void *data)
245250 for_each_set_bit (bit , & mask , hsp -> num_sm ) {
246251 struct tegra_hsp_mailbox * mb = & hsp -> mailboxes [bit ];
247252
248- if (!mb -> producer ) {
249- value = tegra_hsp_channel_readl (& mb -> channel ,
250- HSP_SM_SHRD_MBOX );
251- value &= ~HSP_SM_SHRD_MBOX_FULL ;
252- msg = (void * )(unsigned long )value ;
253- mbox_chan_received_data (mb -> channel .chan , msg );
254-
255- /*
256- * Need to clear all bits here since some producers,
257- * such as TCU, depend on fields in the register
258- * getting cleared by the consumer.
259- *
260- * The mailbox API doesn't give the consumers a way
261- * of doing that explicitly, so we have to make sure
262- * we cover all possible cases.
263- */
264- tegra_hsp_channel_writel (& mb -> channel , 0x0 ,
265- HSP_SM_SHRD_MBOX );
266- }
253+ if (!mb -> producer )
254+ mb -> ops -> recv (& mb -> channel );
267255 }
268256
269257 return IRQ_HANDLED ;
@@ -372,21 +360,52 @@ static const struct mbox_chan_ops tegra_hsp_db_ops = {
372360 .shutdown = tegra_hsp_doorbell_shutdown ,
373361};
374362
363+ static void tegra_hsp_sm_send32 (struct tegra_hsp_channel * channel , void * data )
364+ {
365+ u32 value ;
366+
367+ /* copy data and mark mailbox full */
368+ value = (u32 )(unsigned long )data ;
369+ value |= HSP_SM_SHRD_MBOX_FULL ;
370+
371+ tegra_hsp_channel_writel (channel , value , HSP_SM_SHRD_MBOX );
372+ }
373+
374+ static void tegra_hsp_sm_recv32 (struct tegra_hsp_channel * channel )
375+ {
376+ u32 value ;
377+ void * msg ;
378+
379+ value = tegra_hsp_channel_readl (channel , HSP_SM_SHRD_MBOX );
380+ value &= ~HSP_SM_SHRD_MBOX_FULL ;
381+ msg = (void * )(unsigned long )value ;
382+ mbox_chan_received_data (channel -> chan , msg );
383+
384+ /*
385+ * Need to clear all bits here since some producers, such as TCU, depend
386+ * on fields in the register getting cleared by the consumer.
387+ *
388+ * The mailbox API doesn't give the consumers a way of doing that
389+ * explicitly, so we have to make sure we cover all possible cases.
390+ */
391+ tegra_hsp_channel_writel (channel , 0x0 , HSP_SM_SHRD_MBOX );
392+ }
393+
394+ static const struct tegra_hsp_sm_ops tegra_hsp_sm_32bit_ops = {
395+ .send = tegra_hsp_sm_send32 ,
396+ .recv = tegra_hsp_sm_recv32 ,
397+ };
398+
375399static int tegra_hsp_mailbox_send_data (struct mbox_chan * chan , void * data )
376400{
377401 struct tegra_hsp_mailbox * mb = chan -> con_priv ;
378402 struct tegra_hsp * hsp = mb -> channel .hsp ;
379403 unsigned long flags ;
380- u32 value ;
381404
382405 if (WARN_ON (!mb -> producer ))
383406 return - EPERM ;
384407
385- /* copy data and mark mailbox full */
386- value = (u32 )(unsigned long )data ;
387- value |= HSP_SM_SHRD_MBOX_FULL ;
388-
389- tegra_hsp_channel_writel (& mb -> channel , value , HSP_SM_SHRD_MBOX );
408+ mb -> ops -> send (& mb -> channel , data );
390409
391410 /* enable EMPTY interrupt for the shared mailbox */
392411 spin_lock_irqsave (& hsp -> lock , flags );
@@ -557,6 +576,7 @@ static struct mbox_chan *tegra_hsp_sm_xlate(struct mbox_controller *mbox,
557576 return ERR_PTR (- ENODEV );
558577
559578 mb = & hsp -> mailboxes [index ];
579+ mb -> ops = & tegra_hsp_sm_32bit_ops ;
560580
561581 if ((args -> args [1 ] & TEGRA_HSP_SM_FLAG_TX ) == 0 )
562582 mb -> producer = false;
0 commit comments