mirror of
https://github.com/hardkernel/kernel_common_drivers.git
synced 2026-06-25 12:03:48 +09:00
mailbox: t5m add aocpu alive check mechanism [1/1]
PD#SWPL-155395 Problem: When modules send mailbox message to aocpu, sometimes aocpu can not response because of stuck or interrupt signal lost, at this time driver modules need to know whether aocpu is alive or not, this is helpful to debug. Solution: Add aocpu alive check mechanism, when aocpu did not response, system will check and print aocpu status. Verify: T5M-AY309 Change-Id: Idd1c47fd99505f3a159c86390c28303f5a5b60e9 Signed-off-by: Yao Jie <jie.yao@amlogic.com>
This commit is contained in:
@@ -347,6 +347,8 @@
|
||||
mbox-nums = <T5M_MBOX_NUMS>;
|
||||
mboxids = <T5M_MBOX_AO2REE>,
|
||||
<T5M_MBOX_REE2AO>;
|
||||
aocpu_sts_mboxid = <T5M_MBOX_AO2TEE>;
|
||||
ree2aocpu_mboxid = <T5M_MBOX_REE2AO>;
|
||||
#mbox-cells = <1>;
|
||||
mbox-wr-same;
|
||||
};
|
||||
|
||||
@@ -363,6 +363,9 @@ static int mbox_fifo_parse_dt(struct platform_device *pdev, struct aml_chan_priv
|
||||
u32 irq_nums = 0;
|
||||
u32 mbox_nums = 0;
|
||||
u32 mboxid = 0;
|
||||
u32 spt_ao_alive_det = 0;
|
||||
u32 ao_sts_mboxid = 0;
|
||||
u32 ree2ao_mboxid = 0;
|
||||
int idx = 0;
|
||||
int err = 0;
|
||||
|
||||
@@ -422,6 +425,20 @@ static int mbox_fifo_parse_dt(struct platform_device *pdev, struct aml_chan_priv
|
||||
aml_chan = devm_kzalloc(dev, sizeof(*aml_chan) * mbox_nums, GFP_KERNEL);
|
||||
if (IS_ERR(aml_chan))
|
||||
return PTR_ERR(aml_chan);
|
||||
|
||||
err = of_property_read_u32(dev->of_node,
|
||||
"aocpu_sts_mboxid", &ao_sts_mboxid);
|
||||
if (err) {
|
||||
dev_err(dev, "Do not support aocpu alive detection %d\n", err);
|
||||
} else {
|
||||
err = of_property_read_u32(dev->of_node,
|
||||
"ree2aocpu_mboxid", &ree2ao_mboxid);
|
||||
if (err)
|
||||
dev_err(dev, "failed to get ree2aocpu mbox id, %d\n", err);
|
||||
else
|
||||
spt_ao_alive_det = 1;
|
||||
}
|
||||
|
||||
for (idx = 0; idx < mbox_nums; idx++) {
|
||||
err = of_property_read_u32_index(dev->of_node, "mboxids",
|
||||
idx, &mboxid);
|
||||
@@ -436,6 +453,9 @@ static int mbox_fifo_parse_dt(struct platform_device *pdev, struct aml_chan_priv
|
||||
aml_chan[idx].mbox_fsts_addr = mbox_fsts_base + CTL_OFFSET(mboxid);
|
||||
aml_chan[idx].mbox_irqsts_addr = mbox_irq_base + IRQ_STS_OFFSET(irqctlr);
|
||||
aml_chan[idx].mbox_irqclr_addr = mbox_irq_base + IRQ_CLR_OFFSET(irqclr);
|
||||
if (spt_ao_alive_det && mboxid == ree2ao_mboxid)
|
||||
aml_chan[idx].aocpu_tick_cnt_addr = mbox_rd_base +
|
||||
PAYLOAD_OFFSET(ao_sts_mboxid);
|
||||
mutex_init(&aml_chan[idx].mutex);
|
||||
aml_chan[idx].tx_complete = NULL;
|
||||
}
|
||||
|
||||
@@ -29,4 +29,7 @@
|
||||
#define T5M_MBOX_REE2AO 3
|
||||
#define T5M_MBOX_NUMS 2
|
||||
|
||||
// AOCPU STATUS MBOX CHANNEL ID
|
||||
#define T5M_MBOX_AO2TEE 4
|
||||
|
||||
#endif /* __T5M_MBOX_H__ */
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
#define _AML_MBOX_H_
|
||||
#include <linux/cdev.h>
|
||||
#include <linux/completion.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mailbox_client.h>
|
||||
#include <linux/mailbox_controller.h>
|
||||
#include "aml_mbox_cmd.h"
|
||||
@@ -79,6 +81,7 @@ struct aml_mbox_chan {
|
||||
void __iomem *mbox_fset_addr;
|
||||
void __iomem *mbox_fclr_addr;
|
||||
void __iomem *mbox_fsts_addr;
|
||||
void __iomem *aocpu_tick_cnt_addr;
|
||||
struct mutex mutex; /* for aml mbox chan mutex */
|
||||
struct mbox_controller *mbox;
|
||||
void *tx_complete;
|
||||
@@ -141,6 +144,33 @@ static inline struct mbox_chan *aml_mbox_request_channel_byname(struct device *d
|
||||
return mbox_chan;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if the aocpu is alive
|
||||
* @sts_addr: aocpu tick count read address
|
||||
* return - 0: aocpu is alive
|
||||
* - 1: aocpu is not alive
|
||||
*/
|
||||
static inline int check_aocpu_status(void __iomem *sts_addr)
|
||||
{
|
||||
u32 aocpu_tick_count_1;
|
||||
u32 aocpu_tick_count_2;
|
||||
int ret;
|
||||
|
||||
aocpu_tick_count_1 = readl(sts_addr);
|
||||
pr_info("%s: aocpu_tick_count_1 = 0x%x\n", __func__,
|
||||
aocpu_tick_count_1);
|
||||
/* Sleep for 50 msec to let tick count update */
|
||||
msleep(50);
|
||||
aocpu_tick_count_2 = readl(sts_addr);
|
||||
pr_info("%s: aocpu_tick_count_2 = 0x%x\n", __func__,
|
||||
aocpu_tick_count_2);
|
||||
if (aocpu_tick_count_1 != aocpu_tick_count_2)
|
||||
ret = 0;
|
||||
else
|
||||
ret = 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* aml_mbox_transfer_data - A way for transfer mbox data
|
||||
* @mbox_chan: Mbox channel, this requested by mbox consumer driver
|
||||
@@ -157,7 +187,9 @@ static inline int aml_mbox_transfer_data(struct mbox_chan *mbox_chan, int cmd,
|
||||
{
|
||||
struct aml_mbox_data aml_data;
|
||||
struct aml_mbox_chan *aml_chan;
|
||||
void __iomem *sts_addr;
|
||||
int ret;
|
||||
int chk_ret;
|
||||
|
||||
if (IS_ERR_OR_NULL(mbox_chan)) {
|
||||
pr_err("mbox chan is NULL\n");
|
||||
@@ -176,7 +208,15 @@ static inline int aml_mbox_transfer_data(struct mbox_chan *mbox_chan, int cmd,
|
||||
mutex_unlock(&aml_chan->mutex);
|
||||
if (ret < 0) {
|
||||
dev_err(mbox_chan->cl->dev, "Fail to send mbox data %d\n", ret);
|
||||
return ret;
|
||||
sts_addr = aml_chan->aocpu_tick_cnt_addr;
|
||||
if (sts_addr) {
|
||||
chk_ret = check_aocpu_status(sts_addr);
|
||||
if (!chk_ret)
|
||||
pr_info("Info: aocpu is alive\n");
|
||||
else
|
||||
pr_info("Info: aocpu is not alive\n");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (sync == MBOX_TSYNC)
|
||||
ret = wait_for_completion_killable(&aml_data.complete);
|
||||
|
||||
Reference in New Issue
Block a user