Skip to content

Commit cb62b8f

Browse files
dgerlachJassiBrar
authored andcommitted
mailbox: ti-msgmgr: Refactor message read during interrupt handler
Refactor the portion of code that actually reads received messages from a queue into its own function, ti_msgmgr_queue_rx_data, that is called by the interrupt handler instead of reading directly from the handler. Signed-off-by: Dave Gerlach <d-gerlach@ti.com> Signed-off-by: Jassi Brar <jaswinder.singh@linaro.org>
1 parent 0184cc2 commit cb62b8f

File tree

1 file changed

+49
-39
lines changed

1 file changed

+49
-39
lines changed

drivers/mailbox/ti-msgmgr.c

Lines changed: 49 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,53 @@ static inline bool ti_msgmgr_queue_is_error(const struct ti_msgmgr_desc *d,
190190
return val ? true : false;
191191
}
192192

193+
static int ti_msgmgr_queue_rx_data(struct mbox_chan *chan, struct ti_queue_inst *qinst,
194+
const struct ti_msgmgr_desc *desc)
195+
{
196+
int num_words;
197+
struct ti_msgmgr_message message;
198+
void __iomem *data_reg;
199+
u32 *word_data;
200+
201+
/*
202+
* I have no idea about the protocol being used to communicate with the
203+
* remote producer - 0 could be valid data, so I wont make a judgement
204+
* of how many bytes I should be reading. Let the client figure this
205+
* out.. I just read the full message and pass it on..
206+
*/
207+
message.len = desc->max_message_size;
208+
message.buf = (u8 *)qinst->rx_buff;
209+
210+
/*
211+
* NOTE about register access involved here:
212+
* the hardware block is implemented with 32bit access operations and no
213+
* support for data splitting. We don't want the hardware to misbehave
214+
* with sub 32bit access - For example: if the last register read is
215+
* split into byte wise access, it can result in the queue getting
216+
* stuck or indeterminate behavior. An out of order read operation may
217+
* result in weird data results as well.
218+
* Hence, we do not use memcpy_fromio or __ioread32_copy here, instead
219+
* we depend on readl for the purpose.
220+
*
221+
* Also note that the final register read automatically marks the
222+
* queue message as read.
223+
*/
224+
for (data_reg = qinst->queue_buff_start, word_data = qinst->rx_buff,
225+
num_words = (desc->max_message_size / sizeof(u32));
226+
num_words; num_words--, data_reg += sizeof(u32), word_data++)
227+
*word_data = readl(data_reg);
228+
229+
/*
230+
* Last register read automatically clears the IRQ if only 1 message
231+
* is pending - so send the data up the stack..
232+
* NOTE: Client is expected to be as optimal as possible, since
233+
* we invoke the handler in IRQ context.
234+
*/
235+
mbox_chan_received_data(chan, (void *)&message);
236+
237+
return 0;
238+
}
239+
193240
/**
194241
* ti_msgmgr_queue_rx_interrupt() - Interrupt handler for receive Queue
195242
* @irq: Interrupt number
@@ -206,10 +253,7 @@ static irqreturn_t ti_msgmgr_queue_rx_interrupt(int irq, void *p)
206253
struct ti_msgmgr_inst *inst = dev_get_drvdata(dev);
207254
struct ti_queue_inst *qinst = chan->con_priv;
208255
const struct ti_msgmgr_desc *desc;
209-
int msg_count, num_words;
210-
struct ti_msgmgr_message message;
211-
void __iomem *data_reg;
212-
u32 *word_data;
256+
int msg_count;
213257

214258
if (WARN_ON(!inst)) {
215259
dev_err(dev, "no platform drv data??\n");
@@ -237,41 +281,7 @@ static irqreturn_t ti_msgmgr_queue_rx_interrupt(int irq, void *p)
237281
return IRQ_NONE;
238282
}
239283

240-
/*
241-
* I have no idea about the protocol being used to communicate with the
242-
* remote producer - 0 could be valid data, so I won't make a judgement
243-
* of how many bytes I should be reading. Let the client figure this
244-
* out.. I just read the full message and pass it on..
245-
*/
246-
message.len = desc->max_message_size;
247-
message.buf = (u8 *)qinst->rx_buff;
248-
249-
/*
250-
* NOTE about register access involved here:
251-
* the hardware block is implemented with 32bit access operations and no
252-
* support for data splitting. We don't want the hardware to misbehave
253-
* with sub 32bit access - For example: if the last register read is
254-
* split into byte wise access, it can result in the queue getting
255-
* stuck or indeterminate behavior. An out of order read operation may
256-
* result in weird data results as well.
257-
* Hence, we do not use memcpy_fromio or __ioread32_copy here, instead
258-
* we depend on readl for the purpose.
259-
*
260-
* Also note that the final register read automatically marks the
261-
* queue message as read.
262-
*/
263-
for (data_reg = qinst->queue_buff_start, word_data = qinst->rx_buff,
264-
num_words = (desc->max_message_size / sizeof(u32));
265-
num_words; num_words--, data_reg += sizeof(u32), word_data++)
266-
*word_data = readl(data_reg);
267-
268-
/*
269-
* Last register read automatically clears the IRQ if only 1 message
270-
* is pending - so send the data up the stack..
271-
* NOTE: Client is expected to be as optimal as possible, since
272-
* we invoke the handler in IRQ context.
273-
*/
274-
mbox_chan_received_data(chan, (void *)&message);
284+
ti_msgmgr_queue_rx_data(chan, qinst, desc);
275285

276286
return IRQ_HANDLED;
277287
}

0 commit comments

Comments
 (0)