cec: cec a bus busy cause system hold [1/1]

PD#SWPL-23547

Problem:
when spin lock, recursive call will cause system hold.

Solution:
void recussive calling.

Verify:
P21AS-S905X

Signed-off-by: Yong Qin <yong.qin@amlogic.com>
Change-Id: I84260b159211995e30c0ac14205895b851fdff1f
This commit is contained in:
Yong Qin
2020-04-02 10:29:32 +08:00
committed by Chris
parent e0ac309ca6
commit 3814b0ecbc
2 changed files with 35 additions and 42 deletions

View File

@@ -226,39 +226,6 @@ static const char * const ceca_reg_name3[] = {
"STAT_1_2"
};
#if 1
unsigned int waiting_aocec_free(unsigned int r)
{
unsigned int cnt = 0;
int ret = true;
while (readl(cec_dev->cec_reg + r) & (1<<23)) {
if (cnt++ >= 3500) {
pr_info("waiting aocec %x free time out %d\n", r, cnt);
if (cec_dev->proble_finish)
cec_hw_reset(CEC_A);
ret = false;
break;
}
}
return ret;
}
#else
#define waiting_aocec_free(r) \
do {\
unsigned long cnt = 0;\
while (readl(cec_dev->cec_reg + r) & (1<<23)) {\
if (cnt++ == 3500) { \
pr_info("waiting aocec %x free time out\n", r);\
if (cec_dev->proble_finish) \
cec_hw_reset(CEC_A);\
break;\
} \
} \
} while (0)
#endif
static void cec_set_reg_bits(unsigned int addr, unsigned int value,
unsigned int offset, unsigned int len)
{
@@ -270,26 +237,52 @@ static void cec_set_reg_bits(unsigned int addr, unsigned int value,
writel(data32, cec_dev->cec_reg + addr);
}
unsigned int waiting_aocec_free(unsigned int r)
{
unsigned int cnt = 0;
int ret = true;
while (readl(cec_dev->cec_reg + r) & (1<<23)) {
if (cnt++ >= 3500) {
pr_info("waiting aocec %x free time out %d\n", r, cnt);
if (cec_dev->proble_finish) {
/*reset cec b*/
writel(0x1, cec_dev->cec_reg + AO_CEC_GEN_CNTL);
/* Enable gated clock (Normal mode). */
cec_set_reg_bits(AO_CEC_GEN_CNTL, 1, 1, 1);
/* Release SW reset */
udelay(100);
cec_set_reg_bits(AO_CEC_GEN_CNTL, 0, 0, 1);
udelay(100);
}
/*re check cec hw module internal bus is busy*/
if (readl(cec_dev->cec_reg + r) & (1<<23))
ret = false;
else
ret = true;
break;
}
}
return ret;
}
unsigned int aocec_rd_reg(unsigned long addr)
{
unsigned int data32;
unsigned long flags;
spin_lock_irqsave(&cec_dev->cec_reg_lock, flags);
if (!waiting_aocec_free(AO_CEC_RW_REG)) {
spin_unlock_irqrestore(&cec_dev->cec_reg_lock, flags);
return 0;
}
spin_lock_irqsave(&cec_dev->cec_reg_lock, flags);
data32 = 0;
data32 |= 0 << 16; /* [16] cec_reg_wr */
data32 |= 0 << 8; /* [15:8] cec_reg_wrdata */
data32 |= addr << 0; /* [7:0] cec_reg_addr */
writel(data32, cec_dev->cec_reg + AO_CEC_RW_REG);
if (!waiting_aocec_free(AO_CEC_RW_REG)) {
spin_unlock_irqrestore(&cec_dev->cec_reg_lock, flags);
return 0;
}
data32 = ((readl(cec_dev->cec_reg + AO_CEC_RW_REG)) >> 24) & 0xff;
spin_unlock_irqrestore(&cec_dev->cec_reg_lock, flags);
return data32;
@@ -300,11 +293,11 @@ void aocec_wr_reg(unsigned long addr, unsigned long data)
unsigned long data32;
unsigned long flags;
spin_lock_irqsave(&cec_dev->cec_reg_lock, flags);
if (!waiting_aocec_free(AO_CEC_RW_REG)) {
spin_unlock_irqrestore(&cec_dev->cec_reg_lock, flags);
/*spin_unlock_irqrestore(&cec_dev->cec_reg_lock, flags);*/
return;
}
spin_lock_irqsave(&cec_dev->cec_reg_lock, flags);
data32 = 0;
data32 |= 1 << 16; /* [16] cec_reg_wr */
data32 |= data << 8; /* [15:8] cec_reg_wrdata */

View File

@@ -18,7 +18,7 @@
#ifndef __AO_CEC_H__
#define __AO_CEC_H__
#define CEC_DRIVER_VERSION "2020/03/16:reduece no msg in sleep time\n"
#define CEC_DRIVER_VERSION "2020/04/02: read reg cause recursive call"
#define CEC_FRAME_DELAY msecs_to_jiffies(30)
#define CEC_CHK_BUS_CNT 20