drivers: dai: Enable Zephyr runtime power mgmt in Intel SSP driver

Enable Zephyr device runtime power management mechanisms in Intel SSP
driver. This allows Zephyr to track usage reference for power
domain gating.

Signed-off-by: Krzysztof Frydryk <krzysztofx.frydryk@intel.com>
This commit is contained in:
Krzysztof Frydryk 2022-05-09 09:47:39 +02:00 committed by Carles Cufí
commit 8dd57467cc
5 changed files with 41 additions and 36 deletions

View file

@ -9,6 +9,7 @@ config DAI_INTEL_SSP
bool "Intel I2S (SSP) Bus Driver for Dai interface" bool "Intel I2S (SSP) Bus Driver for Dai interface"
default $(dt_compat_enabled,$(DT_COMPAT_DAI_INTEL_SSP)) default $(dt_compat_enabled,$(DT_COMPAT_DAI_INTEL_SSP))
select DMA select DMA
depends on PM_DEVICE_RUNTIME
help help
Enable Inter Sound (I2S) bus driver based on Enable Inter Sound (I2S) bus driver based on
Synchronous Serial Port (SSP) module. Synchronous Serial Port (SSP) module.

View file

@ -10,6 +10,8 @@
#include <stdint.h> #include <stdint.h>
#include <zephyr/spinlock.h> #include <zephyr/spinlock.h>
#include <zephyr/devicetree.h> #include <zephyr/devicetree.h>
#include <zephyr/pm/device.h>
#include <zephyr/pm/device_runtime.h>
#define LOG_DOMAIN dai_intel_ssp #define LOG_DOMAIN dai_intel_ssp
#include <zephyr/logging/log.h> #include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(LOG_DOMAIN); LOG_MODULE_REGISTER(LOG_DOMAIN);
@ -1928,52 +1930,39 @@ static int dai_ssp_remove(struct dai_intel_ssp *dp)
return 0; return 0;
} }
static int dai_ssp_probe_wrapper(const struct device *dev) static int ssp_pm_action(const struct device *dev, enum pm_device_action action)
{ {
struct dai_intel_ssp *dp = (struct dai_intel_ssp *)dev->data; struct dai_intel_ssp *dp = (struct dai_intel_ssp *)dev->data;
k_spinlock_key_t key; switch (action) {
int ret = 0; case PM_DEVICE_ACTION_SUSPEND:
dai_ssp_remove(dp);
key = k_spin_lock(&dp->lock); break;
case PM_DEVICE_ACTION_RESUME:
if (dp->sref == 0) { dai_ssp_probe(dp);
ret = dai_ssp_probe(dp); break;
case PM_DEVICE_ACTION_TURN_OFF:
case PM_DEVICE_ACTION_TURN_ON:
/* All device pm is handled during resume and suspend */
break;
default:
return -ENOTSUP;
} }
if (!ret) { return 0;
dp->sref++;
}
k_spin_unlock(&dp->lock, key);
return ret;
}
static int dai_ssp_remove_wrapper(const struct device *dev)
{
struct dai_intel_ssp *dp = (struct dai_intel_ssp *)dev->data;
k_spinlock_key_t key;
int ret = 0;
key = k_spin_lock(&dp->lock);
if (--dp->sref == 0) {
ret = dai_ssp_remove(dp);
}
k_spin_unlock(&dp->lock, key);
return ret;
} }
static int ssp_init(const struct device *dev) static int ssp_init(const struct device *dev)
{ {
return 0; int ret;
pm_device_init_suspended(dev);
ret = pm_device_runtime_enable(dev);
return ret;
} }
static struct dai_driver_api dai_intel_ssp_api_funcs = { static struct dai_driver_api dai_intel_ssp_api_funcs = {
.probe = dai_ssp_probe_wrapper, .probe = pm_device_runtime_get,
.remove = dai_ssp_remove_wrapper, .remove = pm_device_runtime_put,
.config_set = dai_ssp_config_set, .config_set = dai_ssp_config_set,
.config_get = dai_ssp_config_get, .config_get = dai_ssp_config_get,
.trigger = dai_ssp_trigger, .trigger = dai_ssp_trigger,
@ -2026,8 +2015,10 @@ static const char irq_name_level5_z[] = "level5";
}, \ }, \
}; \ }; \
\ \
PM_DEVICE_DT_INST_DEFINE(n, ssp_pm_action); \
\
DEVICE_DT_INST_DEFINE(n, \ DEVICE_DT_INST_DEFINE(n, \
ssp_init, NULL, \ ssp_init, PM_DEVICE_DT_INST_GET(n), \
&dai_intel_ssp_data_##n, \ &dai_intel_ssp_data_##n, \
&dai_intel_ssp_config_##n, \ &dai_intel_ssp_config_##n, \
POST_KERNEL, 32, \ POST_KERNEL, 32, \

View file

@ -162,6 +162,7 @@
dmas = <&lpgpdma0 2 dmas = <&lpgpdma0 2
&lpgpdma0 3>; &lpgpdma0 3>;
dma-names = "tx", "rx"; dma-names = "tx", "rx";
power-domain = <&io0_domain>;
status = "okay"; status = "okay";
}; };
@ -176,6 +177,7 @@
dmas = <&lpgpdma0 4 dmas = <&lpgpdma0 4
&lpgpdma0 5>; &lpgpdma0 5>;
dma-names = "tx", "rx"; dma-names = "tx", "rx";
power-domain = <&io0_domain>;
status = "okay"; status = "okay";
}; };
@ -190,6 +192,7 @@
dmas = <&lpgpdma0 6 dmas = <&lpgpdma0 6
&lpgpdma0 7>; &lpgpdma0 7>;
dma-names = "tx", "rx"; dma-names = "tx", "rx";
power-domain = <&io0_domain>;
status = "okay"; status = "okay";
}; };
@ -204,6 +207,7 @@
dmas = <&lpgpdma0 8 dmas = <&lpgpdma0 8
&lpgpdma0 9>; &lpgpdma0 9>;
dma-names = "tx", "rx"; dma-names = "tx", "rx";
power-domain = <&io0_domain>;
status = "okay"; status = "okay";
}; };
@ -218,6 +222,7 @@
dmas = <&lpgpdma0 10 dmas = <&lpgpdma0 10
&lpgpdma0 11>; &lpgpdma0 11>;
dma-names = "tx", "rx"; dma-names = "tx", "rx";
power-domain = <&io0_domain>;
status = "okay"; status = "okay";
}; };
@ -232,6 +237,7 @@
dmas = <&lpgpdma0 12 dmas = <&lpgpdma0 12
&lpgpdma0 13>; &lpgpdma0 13>;
dma-names = "tx", "rx"; dma-names = "tx", "rx";
power-domain = <&io0_domain>;
status = "okay"; status = "okay";
}; };

View file

@ -7,3 +7,7 @@ CONFIG_IPC_MAJOR_4=y
CONFIG_COMP_SRC=n CONFIG_COMP_SRC=n
CONFIG_INTEL_ADSP_TIMER=n CONFIG_INTEL_ADSP_TIMER=n
CONFIG_FORMAT_CONVERT_HIFI3=n CONFIG_FORMAT_CONVERT_HIFI3=n
CONFIG_PM=y
CONFIG_PM_DEVICE=y
CONFIG_PM_DEVICE_RUNTIME=y

View file

@ -5,3 +5,6 @@ CONFIG_INTEL_ALH=y
CONFIG_LP_MEMORY_BANKS=1 CONFIG_LP_MEMORY_BANKS=1
CONFIG_HP_MEMORY_BANKS=30 CONFIG_HP_MEMORY_BANKS=30
CONFIG_RIMAGE_SIGNING_SCHEMA="tgl" CONFIG_RIMAGE_SIGNING_SCHEMA="tgl"
CONFIG_PM=y
CONFIG_PM_DEVICE=y
CONFIG_PM_DEVICE_RUNTIME=y