Skip to content

Commit 75b3cb9

Browse files
Kamal Dasubroonie
authored andcommitted
spi: bcm-qspi: clear MSPI spifie interrupt during probe
Intermittent Kernel crash has been observed on probe in bcm_qspi_mspi_l2_isr() handler when the MSPI spifie interrupt bit has not been cleared before registering for interrupts. Fix the driver to move SoC specific custom interrupt handling code before we register IRQ in probe. Also clear MSPI interrupt status resgiter prior to registering IRQ handlers. Fixes: cc20a38 ("spi: iproc-qspi: Add Broadcom iProc SoCs support") Signed-off-by: Kamal Dasu <[email protected]> Acked-by: Florian Fainelli <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 67a12ae commit 75b3cb9

File tree

1 file changed

+45
-32
lines changed

1 file changed

+45
-32
lines changed

drivers/spi/spi-bcm-qspi.c

Lines changed: 45 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,10 +1250,14 @@ static void bcm_qspi_hw_init(struct bcm_qspi *qspi)
12501250

12511251
static void bcm_qspi_hw_uninit(struct bcm_qspi *qspi)
12521252
{
1253+
u32 status = bcm_qspi_read(qspi, MSPI, MSPI_MSPI_STATUS);
1254+
12531255
bcm_qspi_write(qspi, MSPI, MSPI_SPCR2, 0);
12541256
if (has_bspi(qspi))
12551257
bcm_qspi_write(qspi, MSPI, MSPI_WRITE_LOCK, 0);
12561258

1259+
/* clear interrupt */
1260+
bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status & ~1);
12571261
}
12581262

12591263
static const struct spi_controller_mem_ops bcm_qspi_mem_ops = {
@@ -1397,6 +1401,47 @@ int bcm_qspi_probe(struct platform_device *pdev,
13971401
if (!qspi->dev_ids)
13981402
return -ENOMEM;
13991403

1404+
/*
1405+
* Some SoCs integrate spi controller (e.g., its interrupt bits)
1406+
* in specific ways
1407+
*/
1408+
if (soc_intc) {
1409+
qspi->soc_intc = soc_intc;
1410+
soc_intc->bcm_qspi_int_set(soc_intc, MSPI_DONE, true);
1411+
} else {
1412+
qspi->soc_intc = NULL;
1413+
}
1414+
1415+
if (qspi->clk) {
1416+
ret = clk_prepare_enable(qspi->clk);
1417+
if (ret) {
1418+
dev_err(dev, "failed to prepare clock\n");
1419+
goto qspi_probe_err;
1420+
}
1421+
qspi->base_clk = clk_get_rate(qspi->clk);
1422+
} else {
1423+
qspi->base_clk = MSPI_BASE_FREQ;
1424+
}
1425+
1426+
if (data->has_mspi_rev) {
1427+
rev = bcm_qspi_read(qspi, MSPI, MSPI_REV);
1428+
/* some older revs do not have a MSPI_REV register */
1429+
if ((rev & 0xff) == 0xff)
1430+
rev = 0;
1431+
}
1432+
1433+
qspi->mspi_maj_rev = (rev >> 4) & 0xf;
1434+
qspi->mspi_min_rev = rev & 0xf;
1435+
qspi->mspi_spcr3_sysclk = data->has_spcr3_sysclk;
1436+
1437+
qspi->max_speed_hz = qspi->base_clk / (bcm_qspi_spbr_min(qspi) * 2);
1438+
1439+
/*
1440+
* On SW resets it is possible to have the mask still enabled
1441+
* Need to disable the mask and clear the status while we init
1442+
*/
1443+
bcm_qspi_hw_uninit(qspi);
1444+
14001445
for (val = 0; val < num_irqs; val++) {
14011446
irq = -1;
14021447
name = qspi_irq_tab[val].irq_name;
@@ -1433,38 +1478,6 @@ int bcm_qspi_probe(struct platform_device *pdev,
14331478
goto qspi_probe_err;
14341479
}
14351480

1436-
/*
1437-
* Some SoCs integrate spi controller (e.g., its interrupt bits)
1438-
* in specific ways
1439-
*/
1440-
if (soc_intc) {
1441-
qspi->soc_intc = soc_intc;
1442-
soc_intc->bcm_qspi_int_set(soc_intc, MSPI_DONE, true);
1443-
} else {
1444-
qspi->soc_intc = NULL;
1445-
}
1446-
1447-
ret = clk_prepare_enable(qspi->clk);
1448-
if (ret) {
1449-
dev_err(dev, "failed to prepare clock\n");
1450-
goto qspi_probe_err;
1451-
}
1452-
1453-
qspi->base_clk = clk_get_rate(qspi->clk);
1454-
1455-
if (data->has_mspi_rev) {
1456-
rev = bcm_qspi_read(qspi, MSPI, MSPI_REV);
1457-
/* some older revs do not have a MSPI_REV register */
1458-
if ((rev & 0xff) == 0xff)
1459-
rev = 0;
1460-
}
1461-
1462-
qspi->mspi_maj_rev = (rev >> 4) & 0xf;
1463-
qspi->mspi_min_rev = rev & 0xf;
1464-
qspi->mspi_spcr3_sysclk = data->has_spcr3_sysclk;
1465-
1466-
qspi->max_speed_hz = qspi->base_clk / (bcm_qspi_spbr_min(qspi) * 2);
1467-
14681481
bcm_qspi_hw_init(qspi);
14691482
init_completion(&qspi->mspi_done);
14701483
init_completion(&qspi->bspi_done);

0 commit comments

Comments
 (0)