Skip to content

Commit 5ff0e74

Browse files
claudiubezneaduraikvddp
authored andcommitted
spi: atmel-quadspi: fix runtime PM
Fix runtime PM by adapting the OSPI support added for SAMA7G5. Runtime PM support comes from mainline and at the moment OSPI is not integrated in mainline. The current adaptation doesn't touch the GCLK as it is sensible and need more investment. From current investigation (code behavior only) it seems that GCLK feeds TX/RX and pad calibration hardware logic and thus special handling (and hardware behavior investigation) need to be done for this to be enabled/disable at runtime. Thus, at the moment don't touch it and keep the runtime support on SAMA7G5 only for PCLK. The runtime PM is kept though for all clocks of the other IP variants (available on the other AT91 SoCs). Fixes: 16a72d7 ("spi: atmel-quadspi: Add support for sama7g5 QSPI") Signed-off-by: Claudiu Beznea <claudiu.beznea@microchip.com> [durai.manickamkr@microchip.com: fixed conflicts and ported to 6.6.9] Signed-off-by: Durai Manickam KR <durai.manickamkr@microchip.com>
1 parent e59f646 commit 5ff0e74

1 file changed

Lines changed: 41 additions & 30 deletions

File tree

drivers/spi/atmel-quadspi.c

Lines changed: 41 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include <linux/bitfield.h>
1515
#include <linux/clk.h>
16+
#include <linux/clk-provider.h>
1617
#include <linux/delay.h>
1718
#include <linux/dma-mapping.h>
1819
#include <linux/dmaengine.h>
@@ -949,13 +950,15 @@ static int atmel_qspi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op)
949950
return err;
950951

951952
err = aq->ops->set_cfg(aq, op, &offset);
952-
if (err) {
953-
pm_runtime_mark_last_busy(&aq->pdev->dev);
954-
pm_runtime_put_autosuspend(&aq->pdev->dev);
955-
return err;
956-
}
953+
if (err)
954+
goto pm_runtime_put;
955+
956+
err = aq->ops->transfer(mem, op, offset);
957957

958-
return aq->ops->transfer(mem, op, offset);
958+
pm_runtime_put:
959+
pm_runtime_mark_last_busy(&aq->pdev->dev);
960+
pm_runtime_put_autosuspend(&aq->pdev->dev);
961+
return err;
959962
}
960963

961964
static const char *atmel_qspi_get_name(struct spi_mem *spimem)
@@ -1073,14 +1076,18 @@ static int atmel_qspi_sama7g5_init(struct atmel_qspi *aq)
10731076
u32 val;
10741077
int ret;
10751078

1079+
ret = pm_runtime_resume_and_get(&aq->pdev->dev);
1080+
if (ret < 0)
1081+
return ret;
1082+
10761083
ret = atmel_qspi_set_gclk(aq);
10771084
if (ret)
1078-
return ret;
1085+
goto pm_runtime_put;
10791086

10801087
if (aq->caps->octal) {
10811088
ret = atmel_qspi_set_pad_calibration(aq);
10821089
if (ret)
1083-
return ret;
1090+
goto pm_runtime_put;
10841091
} else {
10851092
atmel_qspi_write(QSPI_CR_DLLON, aq, QSPI_CR);
10861093
ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
@@ -1093,15 +1100,15 @@ static int atmel_qspi_sama7g5_init(struct atmel_qspi *aq)
10931100
aq->mr = QSPI_MR_SMM;
10941101
ret = atmel_qspi_update_config(aq);
10951102
if (ret)
1096-
return ret;
1103+
goto pm_runtime_put;
10971104

10981105
/* Enable the QSPI controller. */
10991106
atmel_qspi_write(QSPI_CR_QSPIEN, aq, QSPI_CR);
11001107
ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
11011108
val & QSPI_SR2_QSPIENS, 40,
11021109
ATMEL_QSPI_SYNC_TIMEOUT);
11031110
if (ret)
1104-
return ret;
1111+
goto pm_runtime_put;
11051112

11061113
if (aq->caps->octal) {
11071114
ret = readl_poll_timeout(aq->regs + QSPI_SR, val,
@@ -1110,6 +1117,10 @@ static int atmel_qspi_sama7g5_init(struct atmel_qspi *aq)
11101117
}
11111118

11121119
atmel_qspi_write(QSPI_TOUT_TCNTM, aq, QSPI_TOUT);
1120+
1121+
pm_runtime_put:
1122+
pm_runtime_mark_last_busy(&aq->pdev->dev);
1123+
pm_runtime_put_autosuspend(&aq->pdev->dev);
11131124
return ret;
11141125
}
11151126

@@ -1473,14 +1484,9 @@ static int atmel_qspi_sama7g5_suspend(struct atmel_qspi *aq)
14731484
if (ret)
14741485
return ret;
14751486

1476-
ret = readl_poll_timeout(aq->regs + QSPI_SR2, val,
1487+
return readl_poll_timeout(aq->regs + QSPI_SR2, val,
14771488
!(val & QSPI_SR2_CALBSY), 40,
14781489
ATMEL_QSPI_TIMEOUT);
1479-
if (ret)
1480-
return ret;
1481-
1482-
clk_disable_unprepare(aq->pclk);
1483-
return 0;
14841490
}
14851491

14861492
static void atmel_qspi_remove(struct platform_device *pdev)
@@ -1529,17 +1535,18 @@ static int __maybe_unused atmel_qspi_suspend(struct device *dev)
15291535
return ret;
15301536

15311537
if (aq->caps->has_gclk)
1532-
return atmel_qspi_sama7g5_suspend(aq);
1533-
1534-
atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
1538+
ret = atmel_qspi_sama7g5_suspend(aq);
1539+
else
1540+
atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR);
15351541

15361542
pm_runtime_mark_last_busy(dev);
15371543
pm_runtime_force_suspend(dev);
15381544

1539-
clk_unprepare(aq->qspick);
1545+
if (aq->caps->has_qspick)
1546+
clk_unprepare(aq->qspick);
15401547
clk_unprepare(aq->pclk);
15411548

1542-
return 0;
1549+
return ret;
15431550
}
15441551

15451552
static int __maybe_unused atmel_qspi_resume(struct device *dev)
@@ -1549,31 +1556,33 @@ static int __maybe_unused atmel_qspi_resume(struct device *dev)
15491556
int ret;
15501557

15511558
clk_prepare(aq->pclk);
1552-
clk_prepare(aq->qspick);
1553-
1554-
if (aq->caps->has_gclk)
1555-
return atmel_qspi_sama7g5_init(aq);
1559+
if (aq->caps->has_qspick)
1560+
clk_prepare(aq->qspick);
15561561

15571562
ret = pm_runtime_force_resume(dev);
15581563
if (ret < 0)
15591564
return ret;
15601565

1561-
atmel_qspi_init(aq);
1562-
1563-
atmel_qspi_write(aq->scr, aq, QSPI_SCR);
1566+
if (aq->caps->has_gclk) {
1567+
ret = atmel_qspi_sama7g5_init(aq);
1568+
} else {
1569+
atmel_qspi_init(aq);
1570+
atmel_qspi_write(aq->scr, aq, QSPI_SCR);
1571+
}
15641572

15651573
pm_runtime_mark_last_busy(dev);
15661574
pm_runtime_put_autosuspend(dev);
15671575

1568-
return 0;
1576+
return ret;
15691577
}
15701578

15711579
static int __maybe_unused atmel_qspi_runtime_suspend(struct device *dev)
15721580
{
15731581
struct spi_controller *ctrl = dev_get_drvdata(dev);
15741582
struct atmel_qspi *aq = spi_controller_get_devdata(ctrl);
15751583

1576-
clk_disable(aq->qspick);
1584+
if (aq->caps->has_qspick)
1585+
clk_disable(aq->qspick);
15771586
clk_disable(aq->pclk);
15781587

15791588
return 0;
@@ -1588,6 +1597,8 @@ static int __maybe_unused atmel_qspi_runtime_resume(struct device *dev)
15881597
ret = clk_enable(aq->pclk);
15891598
if (ret)
15901599
return ret;
1600+
if (aq->caps->has_qspick)
1601+
ret = clk_enable(aq->qspick);
15911602

15921603
ret = clk_enable(aq->qspick);
15931604
if (ret)

0 commit comments

Comments
 (0)