Skip to content

Commit 7446284

Browse files
Khairul Anuar Romlibroonie
authored andcommitted
spi: cadence-quadspi: Implement refcount to handle unbind during busy
driver support indirect read and indirect write operation with assumption no force device removal(unbind) operation. However force device removal(removal) is still available to root superuser. Unbinding driver during operation causes kernel crash. This changes ensure driver able to handle such operation for indirect read and indirect write by implementing refcount to track attached devices to the controller and gracefully wait and until attached devices remove operation completed before proceed with removal operation. Signed-off-by: Khairul Anuar Romli <[email protected]> Reviewed-by: Matthew Gerlach <[email protected]> Reviewed-by: Niravkumar L Rabara <[email protected]> Link: https://patch.msgid.link/8704fd6bd2ff4d37bba4a0eacf5eba3ba001079e.1756168074.git.khairul.anuar.romli@altera.com Signed-off-by: Mark Brown <[email protected]>
1 parent 89e7353 commit 7446284

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

drivers/spi/spi-cadence-quadspi.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,8 @@ struct cqspi_st {
108108

109109
bool is_jh7110; /* Flag for StarFive JH7110 SoC */
110110
bool disable_stig_mode;
111+
refcount_t refcount;
112+
refcount_t inflight_ops;
111113

112114
const struct cqspi_driver_platdata *ddata;
113115
};
@@ -735,6 +737,9 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata,
735737
u8 *rxbuf_end = rxbuf + n_rx;
736738
int ret = 0;
737739

740+
if (!refcount_read(&cqspi->refcount))
741+
return -ENODEV;
742+
738743
writel(from_addr, reg_base + CQSPI_REG_INDIRECTRDSTARTADDR);
739744
writel(remaining, reg_base + CQSPI_REG_INDIRECTRDBYTES);
740745

@@ -1071,6 +1076,9 @@ static int cqspi_indirect_write_execute(struct cqspi_flash_pdata *f_pdata,
10711076
unsigned int write_bytes;
10721077
int ret;
10731078

1079+
if (!refcount_read(&cqspi->refcount))
1080+
return -ENODEV;
1081+
10741082
writel(to_addr, reg_base + CQSPI_REG_INDIRECTWRSTARTADDR);
10751083
writel(remaining, reg_base + CQSPI_REG_INDIRECTWRBYTES);
10761084

@@ -1461,19 +1469,36 @@ static int cqspi_exec_mem_op(struct spi_mem *mem, const struct spi_mem_op *op)
14611469
struct cqspi_st *cqspi = spi_controller_get_devdata(mem->spi->controller);
14621470
struct device *dev = &cqspi->pdev->dev;
14631471

1472+
if (refcount_read(&cqspi->inflight_ops) == 0)
1473+
return -ENODEV;
1474+
14641475
ret = pm_runtime_resume_and_get(dev);
14651476
if (ret) {
14661477
dev_err(&mem->spi->dev, "resume failed with %d\n", ret);
14671478
return ret;
14681479
}
14691480

1481+
if (!refcount_read(&cqspi->refcount))
1482+
return -EBUSY;
1483+
1484+
refcount_inc(&cqspi->inflight_ops);
1485+
1486+
if (!refcount_read(&cqspi->refcount)) {
1487+
if (refcount_read(&cqspi->inflight_ops))
1488+
refcount_dec(&cqspi->inflight_ops);
1489+
return -EBUSY;
1490+
}
1491+
14701492
ret = cqspi_mem_process(mem, op);
14711493

14721494
pm_runtime_put_autosuspend(dev);
14731495

14741496
if (ret)
14751497
dev_err(&mem->spi->dev, "operation failed with %d\n", ret);
14761498

1499+
if (refcount_read(&cqspi->inflight_ops) > 1)
1500+
refcount_dec(&cqspi->inflight_ops);
1501+
14771502
return ret;
14781503
}
14791504

@@ -1925,6 +1950,9 @@ static int cqspi_probe(struct platform_device *pdev)
19251950
}
19261951
}
19271952

1953+
refcount_set(&cqspi->refcount, 1);
1954+
refcount_set(&cqspi->inflight_ops, 1);
1955+
19281956
ret = devm_request_irq(dev, irq, cqspi_irq_handler, 0,
19291957
pdev->name, cqspi);
19301958
if (ret) {
@@ -1987,6 +2015,11 @@ static void cqspi_remove(struct platform_device *pdev)
19872015
{
19882016
struct cqspi_st *cqspi = platform_get_drvdata(pdev);
19892017

2018+
refcount_set(&cqspi->refcount, 0);
2019+
2020+
if (!refcount_dec_and_test(&cqspi->inflight_ops))
2021+
cqspi_wait_idle(cqspi);
2022+
19902023
spi_unregister_controller(cqspi->host);
19912024
cqspi_controller_enable(cqspi, 0);
19922025

0 commit comments

Comments
 (0)