Skip to content
Snippets Groups Projects
Commit 59ec8ff7 authored by Dmitry Osipenko's avatar Dmitry Osipenko
Browse files

WIP: spi: rockchip: Support atomic transfers

parent 180d42a6
No related branches found
No related tags found
No related merge requests found
......@@ -379,6 +379,26 @@ static irqreturn_t rockchip_spi_isr(int irq, void *dev_id)
return IRQ_HANDLED;
}
static void rockchip_spi_poll_completion(struct rockchip_spi *rs,
struct spi_controller *ctlr,
unsigned int timeout_ms)
{
ktime_t ktime = ktime_get();
ktime_t ktimeout = ktime_add_ms(ktime, timeout_ms);
do {
rockchip_spi_isr(0, ctlr);
if (completion_done(&ctlr->xfer_completion))
return;
ktime = ktime_get();
} while (ktime_before(ktime, ktimeout));
dev_err(rs->dev, "atomic transfer timeout\n");
}
static int rockchip_spi_prepare_irq(struct rockchip_spi *rs,
struct spi_controller *ctlr,
struct spi_transfer *xfer)
......@@ -400,6 +420,11 @@ static int rockchip_spi_prepare_irq(struct rockchip_spi *rs,
else
writel_relaxed(INT_RF_FULL, rs->regs + ROCKCHIP_SPI_IMR);
if (ctlr->atomic_xfer) {
rockchip_spi_poll_completion(rs, ctlr, 1000);
return 0;
}
/* 1 means the transfer is in progress */
return 1;
}
......@@ -677,7 +702,7 @@ static int rockchip_spi_transfer_one(
{
struct rockchip_spi *rs = spi_controller_get_devdata(ctlr);
int ret;
bool use_dma;
bool use_dma = false;
/* Zero length transfers won't trigger an interrupt on completion */
if (!xfer->len) {
......@@ -700,6 +725,8 @@ static int rockchip_spi_transfer_one(
rs->n_bytes = xfer->bits_per_word <= 8 ? 1 : 2;
rs->xfer = xfer;
if (!ctlr->atomic_xfer)
use_dma = ctlr->can_dma ? ctlr->can_dma(ctlr, spi, xfer) : false;
ret = rockchip_spi_config(rs, spi, xfer, use_dma, ctlr->target);
......@@ -1015,6 +1042,11 @@ static int rockchip_spi_runtime_resume(struct device *dev)
}
#endif /* CONFIG_PM */
static void rockchip_spi_shutdown(struct platform_device *pdev)
{
pm_runtime_get_sync(&pdev->dev);
}
static const struct dev_pm_ops rockchip_spi_pm = {
SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(rockchip_spi_suspend, rockchip_spi_resume)
SET_RUNTIME_PM_OPS(rockchip_spi_runtime_suspend,
......@@ -1046,6 +1078,7 @@ static struct platform_driver rockchip_spi_driver = {
},
.probe = rockchip_spi_probe,
.remove = rockchip_spi_remove,
.shutdown = rockchip_spi_shutdown,
  • I suppose this is a hack to ensure that the SPI controller is runtime PM enabled when the PMIC wants to do the shutdown? In that case maybe the poweroff prepare handler should be used instead to avoid doing this on rockchip boards not using SPI PMIC for shutdown (i.e. anything that is not RK3588)?

  • Please register or sign in to reply
};
module_platform_driver(rockchip_spi_driver);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment