Commit 48cd6b38 authored by akshatzen's avatar akshatzen Committed by Martin K. Petersen

scsi: pm80xx: Avoid busywait in FW ready check

In function check_fw_ready() we busy wait using udelay. The CPU is not
released and we see need_resched failures.

Busy waiting is not necessary since we are in process context and we can
sleep instead. Replace udelay with msleep of 20 ms intervals while waiting
for firmware to become ready.

It has been verified that check_fw_ready is not being used in interrupt
context anywhere, hence it is safe to make this change.

Link: https://lore.kernel.org/r/20201102165528.26510-4-Viswas.G@microchip.com.comAcked-by: default avatarJack Wang <jinpu.wang@cloud.ionos.com>
Signed-off-by: default avatarakshatzen <akshatzen@google.com>
Signed-off-by: default avatarViswas G <Viswas.G@microchip.com>
Signed-off-by: default avatarRuksar Devadi <Ruksar.devadi@microchip.com>
Signed-off-by: default avatarRadha Ramachandran <radha@google.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 4a2efd4b
...@@ -1042,6 +1042,7 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha) ...@@ -1042,6 +1042,7 @@ static int mpi_init_check(struct pm8001_hba_info *pm8001_ha)
/** /**
* check_fw_ready - The LLDD check if the FW is ready, if not, return error. * check_fw_ready - The LLDD check if the FW is ready, if not, return error.
* This function sleeps hence it must not be used in atomic context.
* @pm8001_ha: our hba card information * @pm8001_ha: our hba card information
*/ */
static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) static int check_fw_ready(struct pm8001_hba_info *pm8001_ha)
...@@ -1052,16 +1053,16 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) ...@@ -1052,16 +1053,16 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha)
int ret = 0; int ret = 0;
/* reset / PCIe ready */ /* reset / PCIe ready */
max_wait_time = max_wait_count = 100 * 1000; /* 100 milli sec */ max_wait_time = max_wait_count = 5; /* 100 milli sec */
do { do {
udelay(1); msleep(FW_READY_INTERVAL);
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
} while ((value == 0xFFFFFFFF) && (--max_wait_count)); } while ((value == 0xFFFFFFFF) && (--max_wait_count));
/* check ila status */ /* check ila status */
max_wait_time = max_wait_count = 1000 * 1000; /* 1000 milli sec */ max_wait_time = max_wait_count = 50; /* 1000 milli sec */
do { do {
udelay(1); msleep(FW_READY_INTERVAL);
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
} while (((value & SCRATCH_PAD_ILA_READY) != } while (((value & SCRATCH_PAD_ILA_READY) !=
SCRATCH_PAD_ILA_READY) && (--max_wait_count)); SCRATCH_PAD_ILA_READY) && (--max_wait_count));
...@@ -1074,9 +1075,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) ...@@ -1074,9 +1075,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha)
} }
/* check RAAE status */ /* check RAAE status */
max_wait_time = max_wait_count = 1800 * 1000; /* 1800 milli sec */ max_wait_time = max_wait_count = 90; /* 1800 milli sec */
do { do {
udelay(1); msleep(FW_READY_INTERVAL);
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
} while (((value & SCRATCH_PAD_RAAE_READY) != } while (((value & SCRATCH_PAD_RAAE_READY) !=
SCRATCH_PAD_RAAE_READY) && (--max_wait_count)); SCRATCH_PAD_RAAE_READY) && (--max_wait_count));
...@@ -1089,9 +1090,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) ...@@ -1089,9 +1090,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha)
} }
/* check iop0 status */ /* check iop0 status */
max_wait_time = max_wait_count = 600 * 1000; /* 600 milli sec */ max_wait_time = max_wait_count = 30; /* 600 milli sec */
do { do {
udelay(1); msleep(FW_READY_INTERVAL);
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
} while (((value & SCRATCH_PAD_IOP0_READY) != SCRATCH_PAD_IOP0_READY) && } while (((value & SCRATCH_PAD_IOP0_READY) != SCRATCH_PAD_IOP0_READY) &&
(--max_wait_count)); (--max_wait_count));
...@@ -1107,9 +1108,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha) ...@@ -1107,9 +1108,9 @@ static int check_fw_ready(struct pm8001_hba_info *pm8001_ha)
if ((pm8001_ha->chip_id != chip_8008) && if ((pm8001_ha->chip_id != chip_8008) &&
(pm8001_ha->chip_id != chip_8009)) { (pm8001_ha->chip_id != chip_8009)) {
/* 200 milli sec */ /* 200 milli sec */
max_wait_time = max_wait_count = 200 * 1000; max_wait_time = max_wait_count = 10;
do { do {
udelay(1); msleep(FW_READY_INTERVAL);
value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1); value = pm8001_cr32(pm8001_ha, 0, MSGU_SCRATCH_PAD_1);
} while (((value & SCRATCH_PAD_IOP1_READY) != } while (((value & SCRATCH_PAD_IOP1_READY) !=
SCRATCH_PAD_IOP1_READY) && (--max_wait_count)); SCRATCH_PAD_IOP1_READY) && (--max_wait_count));
......
...@@ -1639,3 +1639,9 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t; ...@@ -1639,3 +1639,9 @@ typedef struct SASProtocolTimerConfig SASProtocolTimerConfig_t;
#define MEMBASE_II_SHIFT_REGISTER 0x1010 #define MEMBASE_II_SHIFT_REGISTER 0x1010
#endif #endif
/**
* As we know sleep (1~20) ms may result in sleep longer than ~20 ms, hence we
* choose 20 ms interval.
*/
#define FW_READY_INTERVAL 20
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment