Skip to content

Commit 8f585d1

Browse files
KartikJassiBrar
authored andcommitted
mailbox: tegra-hsp: Add tegra_hsp_sm_ops
This patch introduces tegra_hsp_sm_ops to abstract send & receive API's for shared mailboxes. Signed-off-by: Kartik <kkartik@nvidia.com> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
1 parent 1b3418a commit 8f585d1

1 file changed

Lines changed: 47 additions & 27 deletions

File tree

drivers/mailbox/tegra-hsp.c

Lines changed: 47 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
7075
struct 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+
375399
static 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

Comments
 (0)