Skip to content

Commit b3a4b15

Browse files
JordanYatesfabiobaltieri
authored andcommitted
sdhc: sdhc_spi: handle PM on SPI bus
Handle SPI buses that have device runtime PM enabled. Signed-off-by: Jordan Yates <[email protected]>
1 parent 48c05bb commit b3a4b15

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

drivers/sdhc/sdhc_spi.c

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <zephyr/sys/byteorder.h>
1515
#include <zephyr/drivers/spi.h>
1616
#include <zephyr/sys/crc.h>
17+
#include <zephyr/pm/device_runtime.h>
1718

1819
LOG_MODULE_REGISTER(sdhc_spi, CONFIG_SDHC_LOG_LEVEL);
1920

@@ -148,24 +149,30 @@ static int sdhc_spi_init_card(const struct device *dev)
148149
const struct sdhc_spi_config *config = dev->config;
149150
struct sdhc_spi_data *data = dev->data;
150151
struct spi_config *spi_cfg = data->spi_cfg;
151-
int ret;
152+
int ret, ret2;
152153

153154
if (spi_cfg->frequency == 0) {
154155
/* Use default 400KHZ frequency */
155156
spi_cfg->frequency = SDMMC_CLOCK_400KHZ;
156157
}
158+
159+
/* Request SPI bus to be active */
160+
if (pm_device_runtime_get(config->spi_dev) < 0) {
161+
return -EIO;
162+
}
163+
157164
/* the initial 74 clocks must be sent while CS is high */
158165
spi_cfg->operation |= SPI_CS_ACTIVE_HIGH;
159166
ret = sdhc_spi_rx(config->spi_dev, spi_cfg, data->scratch, 10);
160-
if (ret != 0) {
161-
spi_release(config->spi_dev, spi_cfg);
162-
spi_cfg->operation &= ~SPI_CS_ACTIVE_HIGH;
163-
return ret;
164-
}
167+
165168
/* Release lock on SPI bus */
166-
ret = spi_release(config->spi_dev, spi_cfg);
169+
ret2 = spi_release(config->spi_dev, spi_cfg);
167170
spi_cfg->operation &= ~SPI_CS_ACTIVE_HIGH;
168-
return ret;
171+
172+
/* Release request for SPI bus to be active */
173+
(void)pm_device_runtime_put(config->spi_dev);
174+
175+
return ret ? ret : ret2;
169176
}
170177

171178
/* Checks if SPI SD card is sending busy signal */
@@ -623,14 +630,20 @@ static int sdhc_spi_request(const struct device *dev,
623630
{
624631
const struct sdhc_spi_config *config = dev->config;
625632
struct sdhc_spi_data *dev_data = dev->data;
626-
int ret, stop_ret, retries = cmd->retries;
633+
int ret, ret2, stop_ret, retries = cmd->retries;
627634
const struct sdhc_command stop_cmd = {
628635
.opcode = SD_STOP_TRANSMISSION,
629636
.arg = 0,
630637
.response_type = SD_SPI_RSP_TYPE_R1b,
631638
.timeout_ms = 1000,
632639
.retries = 1,
633640
};
641+
642+
/* Request SPI bus to be active */
643+
if (pm_device_runtime_get(config->spi_dev) < 0) {
644+
return -EIO;
645+
}
646+
634647
if (data == NULL) {
635648
do {
636649
ret = sdhc_spi_send_cmd(dev, cmd, false);
@@ -667,13 +680,14 @@ static int sdhc_spi_request(const struct device *dev,
667680
}
668681
} while ((ret != 0) && (retries > 0));
669682
}
670-
if (ret) {
671-
/* Release SPI bus */
672-
spi_release(config->spi_dev, dev_data->spi_cfg);
673-
return ret;
674-
}
683+
675684
/* Release SPI bus */
676-
return spi_release(config->spi_dev, dev_data->spi_cfg);
685+
ret2 = spi_release(config->spi_dev, dev_data->spi_cfg);
686+
687+
/* Release request for SPI bus to be active */
688+
(void)pm_device_runtime_put(config->spi_dev);
689+
690+
return ret ? ret : ret2;
677691
}
678692

679693
static int sdhc_spi_set_io(const struct device *dev, struct sdhc_io *ios)

0 commit comments

Comments
 (0)