From 4b751410f17d7b81e39346b7c5efad21fb5c7c40 Mon Sep 17 00:00:00 2001 From: yuanbo Date: Thu, 15 Jul 2021 20:05:55 +0800 Subject: [PATCH] fix hdf power management feature on kernel Signed-off-by: yuanbo --- ability/sbuf/src/hdf_sbuf.c | 23 +++-- .../adapter/syscall/src/hdf_syscall_adapter.c | 11 --- core/common/src/devmgr_service_start.c | 5 +- core/common/src/hdf_attribute.c | 10 +- core/host/include/hdf_device.h | 2 +- core/host/include/hdf_device_node.h | 5 +- core/host/include/power_state_token.h | 4 +- core/host/src/devhost_service.c | 81 +++++++++++++--- core/host/src/hdf_device.c | 10 +- core/host/src/hdf_device_node.c | 7 +- core/host/src/power_state_token.c | 49 +++------- core/manager/include/devhost_service_clnt.h | 4 +- core/manager/include/devmgr_service.h | 6 +- core/manager/include/power_state_token_clnt.h | 2 +- core/manager/src/devhost_service_clnt.c | 3 +- core/manager/src/devmgr_service.c | 95 +++++++++++-------- core/manager/src/power_state_manager.c | 83 ---------------- core/manager/src/power_state_token_clnt.c | 2 +- .../unittest/common/hdf_ioservice_test.cpp | 36 +++++++ core/shared/include/devhost_service_if.h | 7 +- core/shared/include/devmgr_service_if.h | 4 +- .../include/hdf_power_state.h} | 31 +++--- core/shared/include/power_state_token_if.h | 8 +- include/core/hdf_pm.h | 19 ++-- include/utils/hdf_dlist.h | 11 +++ test/unittest/manager/sample_driver_test.c | 56 ++++++++++- test/unittest/manager/sample_driver_test.h | 1 + 27 files changed, 316 insertions(+), 259 deletions(-) delete mode 100644 core/manager/src/power_state_manager.c rename core/{manager/include/power_state_manager.h => shared/include/hdf_power_state.h} (34%) diff --git a/ability/sbuf/src/hdf_sbuf.c b/ability/sbuf/src/hdf_sbuf.c index 9aea25fcf..2db96ff64 100644 --- a/ability/sbuf/src/hdf_sbuf.c +++ b/ability/sbuf/src/hdf_sbuf.c @@ -120,7 +120,7 @@ bool HdfSbufWriteUnpadBuffer(struct HdfSBuf *sbuf, const uint8_t *data, uint32_t const uint8_t *HdfSbufReadUnpadBuffer(struct HdfSBuf *sbuf, size_t length) { - HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUnpadBuffer, false); + HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readUnpadBuffer, NULL); return sbuf->impl->readUnpadBuffer(sbuf->impl, length); } @@ -240,7 +240,7 @@ bool HdfSbufReadInt8(struct HdfSBuf *sbuf, int8_t *value) const char *HdfSbufReadString(struct HdfSBuf *sbuf) { - HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString, false); + HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString, NULL); return sbuf->impl->readString(sbuf->impl); } @@ -252,7 +252,7 @@ bool HdfSBufWriteString16(struct HdfSBuf *sbuf, const char16_t *value, uint32_t const char16_t *HdfSBufReadString16(struct HdfSBuf *sbuf) { - HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString16, false); + HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readString16, NULL); return sbuf->impl->readString16(sbuf->impl); } @@ -264,7 +264,7 @@ int32_t HdfSBufWriteRemoteService(struct HdfSBuf *sbuf, const struct HdfRemoteSe struct HdfRemoteService *HdfSBufReadRemoteService(struct HdfSBuf *sbuf) { - HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readRemoteService, false); + HDF_SBUF_IMPL_CHECK_RETURN(sbuf, readRemoteService, NULL); return sbuf->impl->readRemoteService(sbuf->impl); } @@ -306,6 +306,7 @@ bool HdfSbufReadFloat(struct HdfSBuf *sbuf, float *data) struct HdfSBuf *HdfSBufTypedObtainCapacity(uint32_t type, size_t capacity) { + struct HdfSBuf *sbuf = NULL; const struct HdfSbufConstructor *constructor = HdfSbufConstructorGet(type); if (constructor == NULL) { HDF_LOGE("sbuf constructor %d not implement", type); @@ -316,7 +317,7 @@ struct HdfSBuf *HdfSBufTypedObtainCapacity(uint32_t type, size_t capacity) return NULL; } - struct HdfSBuf *sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf)); + sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf)); if (sbuf == NULL) { HDF_LOGE("instance sbuf failure"); return NULL; @@ -334,11 +335,12 @@ struct HdfSBuf *HdfSBufTypedObtainCapacity(uint32_t type, size_t capacity) struct HdfSBuf *HdfSBufTypedObtainInplace(uint32_t type, struct HdfSbufImpl *impl) { + struct HdfSBuf *sbuf = NULL; if (type >= SBUF_TYPE_MAX || impl == NULL) { return NULL; } - struct HdfSBuf *sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf)); + sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf)); if (sbuf == NULL) { HDF_LOGE("obtain in-place sbuf failure"); return NULL; @@ -356,6 +358,7 @@ struct HdfSBuf *HdfSBufTypedObtain(uint32_t type) struct HdfSBuf *HdfSBufTypedBind(uint32_t type, uintptr_t base, size_t size) { + struct HdfSBuf *sbuf = NULL; const struct HdfSbufConstructor *constructor = HdfSbufConstructorGet(type); if (constructor == NULL) { HDF_LOGE("sbuf constructor %d not implement", type); @@ -367,7 +370,7 @@ struct HdfSBuf *HdfSBufTypedBind(uint32_t type, uintptr_t base, size_t size) return NULL; } - struct HdfSBuf *sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf)); + sbuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf)); if (sbuf == NULL) { HDF_LOGE("instance sbuf failure"); return NULL; @@ -400,8 +403,9 @@ struct HdfSBuf *HdfSBufBind(uintptr_t base, size_t size) struct HdfSBuf *HdfSBufCopy(const struct HdfSBuf *sbuf) { + struct HdfSBuf *newBuf = NULL; HDF_SBUF_IMPL_CHECK_RETURN(sbuf, copy, NULL); - struct HdfSBuf *newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf)); + newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf)); if (newBuf == NULL) { return NULL; } @@ -416,8 +420,9 @@ struct HdfSBuf *HdfSBufCopy(const struct HdfSBuf *sbuf) struct HdfSBuf *HdfSBufMove(struct HdfSBuf *sbuf) { + struct HdfSBuf *newBuf = NULL; HDF_SBUF_IMPL_CHECK_RETURN(sbuf, move, NULL); - struct HdfSBuf *newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf)); + newBuf = (struct HdfSBuf *)OsalMemAlloc(sizeof(struct HdfSBuf)); if (newBuf == NULL) { return NULL; } diff --git a/core/adapter/syscall/src/hdf_syscall_adapter.c b/core/adapter/syscall/src/hdf_syscall_adapter.c index 908022746..8bbdb0126 100644 --- a/core/adapter/syscall/src/hdf_syscall_adapter.c +++ b/core/adapter/syscall/src/hdf_syscall_adapter.c @@ -1046,17 +1046,6 @@ void HdfIoServiceGroupRemoveService(struct HdfIoServiceGroup *group, struct HdfI adapter->group = NULL; } -static int DlistGetCount(const struct DListHead *head) -{ - struct DListHead *next = head->next; - int count = 0; - while (next != head) { - next = next->next; - count++; - } - return count; -} - int HdfIoserviceGetListenerCount(const struct HdfIoService *service) { if (service == NULL) { diff --git a/core/common/src/devmgr_service_start.c b/core/common/src/devmgr_service_start.c index 6dbaa0741..a7d27eb9c 100644 --- a/core/common/src/devmgr_service_start.c +++ b/core/common/src/devmgr_service_start.c @@ -22,7 +22,6 @@ static int g_isQuickLoad = DEV_MGR_SLOW_LOAD; static void GetDeviceServiceNameByClass(DeviceClass deviceClass, struct HdfSBuf *reply) { - struct HdfSListIterator itHost; struct HdfSListIterator itDeviceInfo; struct HdfDeviceInfo *deviceInfo = NULL; struct DevHostServiceClnt *hostClnt = NULL; @@ -32,9 +31,7 @@ static void GetDeviceServiceNameByClass(DeviceClass deviceClass, struct HdfSBuf } HdfSbufFlush(reply); - HdfSListIteratorInit(&itHost, &devMgrSvc->hosts); - while (HdfSListIteratorHasNext(&itHost)) { - hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost); + DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) { HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos); while (HdfSListIteratorHasNext(&itDeviceInfo)) { deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo); diff --git a/core/common/src/hdf_attribute.c b/core/common/src/hdf_attribute.c index 83b609fd2..d9ce26d00 100644 --- a/core/common/src/hdf_attribute.c +++ b/core/common/src/hdf_attribute.c @@ -288,7 +288,6 @@ struct HdfSList *HdfAttributeManagerGetDeviceList(uint16_t hostId, const char *h bool HdfDeviceListAdd(const char *moduleName, const char *serviceName) { - struct HdfSListIterator itHost; struct HdfSListIterator itDeviceInfo; struct HdfDeviceInfo *deviceInfo = NULL; struct DevHostServiceClnt *hostClnt = NULL; @@ -301,9 +300,7 @@ bool HdfDeviceListAdd(const char *moduleName, const char *serviceName) if (deviceNodeInfo == NULL) { return false; } - HdfSListIteratorInit(&itHost, &devMgrSvc->hosts); - while (HdfSListIteratorHasNext(&itHost)) { - hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost); + DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) { HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos); while (HdfSListIteratorHasNext(&itDeviceInfo)) { deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo); @@ -342,7 +339,6 @@ bool HdfDeviceListAdd(const char *moduleName, const char *serviceName) void HdfDeviceListDel(const char *moduleName, const char *serviceName) { - struct HdfSListIterator itHost; struct HdfSListIterator itDeviceInfo; struct HdfDeviceInfo *deviceInfo = NULL; struct DevHostServiceClnt *hostClnt = NULL; @@ -351,9 +347,7 @@ void HdfDeviceListDel(const char *moduleName, const char *serviceName) return; } - HdfSListIteratorInit(&itHost, &devMgrSvc->hosts); - while (HdfSListIteratorHasNext(&itHost)) { - hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost); + DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) { HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos); while (HdfSListIteratorHasNext(&itDeviceInfo)) { deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo); diff --git a/core/host/include/hdf_device.h b/core/host/include/hdf_device.h index e15132a1d..25e2a0650 100644 --- a/core/host/include/hdf_device.h +++ b/core/host/include/hdf_device.h @@ -28,7 +28,7 @@ struct IHdfDevice { struct HdfDevice { struct IHdfDevice super; struct DListHead node; - struct HdfSList services; + struct DListHead devNodes; uint16_t deviceId; uint16_t hostId; }; diff --git a/core/host/include/hdf_device_node.h b/core/host/include/hdf_device_node.h index 87b9da5f5..475158ead 100644 --- a/core/host/include/hdf_device_node.h +++ b/core/host/include/hdf_device_node.h @@ -12,6 +12,7 @@ #include "hdf_device.h" #include "hdf_device_info.h" #include "hdf_device_desc.h" +#include "hdf_dlist.h" #include "hdf_pm.h" struct HdfDeviceNode; @@ -25,7 +26,7 @@ struct IDeviceNode { struct HdfDeviceNode { struct IDeviceNode super; - struct HdfSListNode entry; + struct DListHead entry; struct PowerStateToken *powerToken; struct DevHostService *hostService; struct HdfDeviceObject deviceObject; @@ -42,7 +43,7 @@ void HdfDeviceNodeConstruct(struct HdfDeviceNode *service); void HdfDeviceNodeDestruct(struct HdfDeviceNode *service); struct HdfDeviceNode *HdfDeviceNodeNewInstance(void); void HdfDeviceNodeFreeInstance(struct HdfDeviceNode *service); -void HdfDeviceNodeDelete(struct HdfSListNode *deviceEntry); +void HdfDeviceNodeDelete(struct HdfDeviceNode *devNode); int HdfDeviceNodePublishPublicService(struct HdfDeviceNode *service, const char *svcName); void HdfDeviceNodeReclaimService(const char *svcName); diff --git a/core/host/include/power_state_token.h b/core/host/include/power_state_token.h index f82d0a222..327564494 100644 --- a/core/host/include/power_state_token.h +++ b/core/host/include/power_state_token.h @@ -18,12 +18,12 @@ struct PowerStateToken { const struct IPowerEventListener *listener; struct HdfDeviceObject *deviceObject; struct HdfSRef wakeRef; - HdfPowerState state; + HdfPsmState psmState; uint32_t mode; }; struct PowerStateToken *PowerStateTokenNewInstance( struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener); void PowerStateTokenFreeInstance(struct PowerStateToken *stateToken); -int PowerStateOnSysStateChange(struct PowerStateToken *stateToken, int32_t state); +int PowerStateChange(struct PowerStateToken *stateToken, uint32_t pEvent); #endif /* POWER_STATE_TOKEN_H */ \ No newline at end of file diff --git a/core/host/src/devhost_service.c b/core/host/src/devhost_service.c index 48814c6f6..bd0c84135 100644 --- a/core/host/src/devhost_service.c +++ b/core/host/src/devhost_service.c @@ -14,6 +14,7 @@ #include "hdf_log.h" #include "hdf_object_manager.h" #include "osal_mem.h" +#include "power_state_token.h" #define HDF_LOG_TAG devhost_service @@ -63,16 +64,16 @@ int DevHostServiceAddDevice(struct IDevHostService *inst, const struct HdfDevice int ret = HDF_FAILURE; struct HdfDevice *device = NULL; struct HdfDeviceNode *devNode = NULL; - struct DevHostService *hostService = (struct DevHostService *)inst; + struct DevHostService *hostService = CONTAINER_OF(inst, struct DevHostService, super); struct IDriverLoader *driverLoader = HdfDriverLoaderGetInstance(); - if ((deviceInfo == NULL) || (driverLoader == NULL) || (driverLoader->LoadNode == NULL)) { + if (inst == NULL || deviceInfo == NULL || driverLoader == NULL || driverLoader->LoadNode == NULL) { HDF_LOGE("failed to add device, input param is null"); return ret; } device = DevHostServiceGetDevice(hostService, deviceInfo->deviceId); - if ((device == NULL) || (device->super.Attach == NULL)) { + if (device == NULL || device->super.Attach == NULL) { ret = HDF_DEV_ERR_NO_DEVICE; goto error; } @@ -94,18 +95,14 @@ error: return ret; } -static struct HdfDeviceNode *DevHostServiceGetDeviceNode(struct HdfSList *deviceNodes, +static struct HdfDeviceNode *DevHostServiceSeparateDeviceNode(struct DListHead *deviceNodes, const struct HdfDeviceInfo *deviceInfo) { - struct HdfSListIterator it; struct HdfDeviceNode *deviceNode = NULL; - HdfSListIteratorInit(&it, deviceNodes); - while (HdfSListIteratorHasNext(&it)) { - deviceNode = HDF_SLIST_CONTAINER_OF( - struct HdfSListNode, HdfSListIteratorNext(&it), struct HdfDeviceNode, entry); + DLIST_FOR_EACH_ENTRY(deviceNode, deviceNodes, struct HdfDeviceNode, entry) { if (strcmp(deviceNode->deviceInfo->svcName, deviceInfo->svcName) == 0 && strcmp(deviceNode->deviceInfo->moduleName, deviceInfo->moduleName) == 0) { - HdfSListRemove(deviceNodes, &deviceNode->entry); + DListRemove(&deviceNode->entry); return deviceNode; } } @@ -130,14 +127,14 @@ int DevHostServiceDelDevice(struct IDevHostService *inst, const struct HdfDevice } driverLoader->UnLoadNode(driverLoader, deviceInfo); - struct HdfDeviceNode *devNode = DevHostServiceGetDeviceNode(&device->services, deviceInfo); + struct HdfDeviceNode *devNode = DevHostServiceSeparateDeviceNode(&device->devNodes, deviceInfo); if (device->super.Detach != NULL) { device->super.Detach(&device->super, devNode); } else { HdfDeviceNodeFreeInstance(devNode); } DevSvcManagerClntRemoveService(deviceInfo->svcName); - if (HdfSListIsEmpty(&device->services)) { + if (DListIsEmpty(&device->devNodes)) { DevHostServiceFreeDevice(hostService, device->deviceId); } return HDF_SUCCESS; @@ -153,6 +150,64 @@ static int DevHostServiceStartService(struct IDevHostService *service) return DevmgrServiceClntAttachDeviceHost(hostService->hostId, service); } +static int ApplyDevicesPowerState(struct HdfDevice *device, uint32_t state) +{ + struct HdfDeviceNode *deviceNode = NULL; + int ret = HDF_SUCCESS; + + /* The power management strategy is to ignore devices that fail to + operate and avoid more devices that fail to sleep or wake up */ + if (IsPowerWakeState(state)) { + DLIST_FOR_EACH_ENTRY(deviceNode, &device->devNodes, struct HdfDeviceNode, entry) { + if (deviceNode->powerToken != NULL) { + ret = PowerStateChange(deviceNode->powerToken, state); + if (ret != HDF_SUCCESS) { + HDF_LOGE("device %s failed to resume(%d)", deviceNode->driverEntry->moduleName, state); + } + } + } + } else { + DLIST_FOR_EACH_ENTRY_REVERSE(deviceNode, &device->devNodes, struct HdfDeviceNode, entry) { + if (deviceNode->powerToken != NULL) { + ret = PowerStateChange(deviceNode->powerToken, state); + if (ret != HDF_SUCCESS) { + HDF_LOGE("device %s failed to suspend(%d)", deviceNode->driverEntry->moduleName, state); + } + } + } + } + + return HDF_SUCCESS; +} + +static int DevHostServicePmNotify(struct IDevHostService *service, uint32_t state) +{ + struct HdfDevice *device = NULL; + int ret = HDF_SUCCESS; + struct DevHostService *hostService = CONTAINER_OF(service, struct DevHostService, super); + if (hostService == NULL) { + HDF_LOGE("failed to start device service, hostService is null"); + return HDF_FAILURE; + } + + HDF_LOGD("host(%s) set power state=%u", hostService->hostName, state); + if (IsPowerWakeState(state)) { + DLIST_FOR_EACH_ENTRY_REVERSE(device, &hostService->devices, struct HdfDevice, node) { + if (ApplyDevicesPowerState(device, state) != HDF_SUCCESS) { + ret = HDF_FAILURE; + } + } + } else { + DLIST_FOR_EACH_ENTRY(device, &hostService->devices, struct HdfDevice, node) { + if (ApplyDevicesPowerState(device, state) != HDF_SUCCESS) { + ret = HDF_FAILURE; + } + } + } + + return ret; +} + void DevHostServiceConstruct(struct DevHostService *service) { struct IDevHostService *hostServiceIf = &service->super; @@ -160,6 +215,7 @@ void DevHostServiceConstruct(struct DevHostService *service) hostServiceIf->AddDevice = DevHostServiceAddDevice; hostServiceIf->DelDevice = DevHostServiceDelDevice; hostServiceIf->StartService = DevHostServiceStartService; + hostServiceIf->PmNotify = DevHostServicePmNotify; DListHeadInit(&service->devices); HdfServiceObserverConstruct(&service->observer); } @@ -214,4 +270,3 @@ void DevHostServiceFreeInstance(struct IDevHostService *service) HdfObjectManagerFreeObject(&service->object); } } - diff --git a/core/host/src/hdf_device.c b/core/host/src/hdf_device.c index af7a6e810..d61036007 100644 --- a/core/host/src/hdf_device.c +++ b/core/host/src/hdf_device.c @@ -26,19 +26,23 @@ static int HdfDeviceAttach(struct IHdfDevice *devInst, struct HdfDeviceNode *dev HDF_LOGE("failed to attach device, input params invalid"); return HDF_ERR_INVALID_PARAM; } - HdfSListAdd(&device->services, &devNode->entry); + DListInsertTail(&devNode->entry, &device->devNodes); return nodeIf->LaunchNode(devNode, devInst); } void HdfDeviceConstruct(struct HdfDevice *device) { device->super.Attach = HdfDeviceAttach; - HdfSListInit(&device->services); + DListHeadInit(&device->devNodes); } void HdfDeviceDestruct(struct HdfDevice *device) { - HdfSListFlush(&device->services, HdfDeviceNodeDelete); + struct HdfDeviceNode *devNode = NULL; + DLIST_FOR_EACH_ENTRY(devNode, &device->devNodes, struct HdfDeviceNode, entry) { + HdfDeviceNodeDelete(devNode); + } + DListHeadInit(&device->devNodes); } struct HdfObject *HdfDeviceCreate() diff --git a/core/host/src/hdf_device_node.c b/core/host/src/hdf_device_node.c index c76398b26..06f46b436 100644 --- a/core/host/src/hdf_device_node.c +++ b/core/host/src/hdf_device_node.c @@ -170,13 +170,12 @@ void HdfDeviceNodeFreeInstance(struct HdfDeviceNode *devNode) HdfObjectManagerFreeObject((struct HdfObject *) devNode); } -void HdfDeviceNodeDelete(struct HdfSListNode *deviceEntry) +void HdfDeviceNodeDelete(struct HdfDeviceNode *devNode) { - if (deviceEntry == NULL) { + if (devNode == NULL) { return; } - struct HdfDeviceNode *devNode = - HDF_SLIST_CONTAINER_OF(struct HdfSListNode, deviceEntry, struct HdfDeviceNode, entry); + if (devNode->driverEntry->Release != NULL) { devNode->driverEntry->Release(&devNode->deviceObject); } diff --git a/core/host/src/power_state_token.c b/core/host/src/power_state_token.c index ab65bbf68..f32c21354 100644 --- a/core/host/src/power_state_token.c +++ b/core/host/src/power_state_token.c @@ -11,7 +11,7 @@ #include "hdf_device_desc.h" #include "hdf_slist.h" #include "osal_mem.h" -#include "osal_sysevent.h" +#include "hdf_power_state.h" static void PowerStateTokenOnFirstAcquire(struct HdfSRef *sref) { @@ -21,27 +21,17 @@ static void PowerStateTokenOnFirstAcquire(struct HdfSRef *sref) struct PowerStateToken *stateToken = (struct PowerStateToken *)HDF_SLIST_CONTAINER_OF( struct HdfSRef, sref, struct PowerStateToken, wakeRef); - if (stateToken->state == POWER_STATE_ACTIVE) { + if (stateToken->psmState == PSM_STATE_ACTIVE) { return; } - struct IDevmgrService *devMgrSvcIf = NULL; - struct DevmgrServiceClnt *inst = DevmgrServiceClntGetInstance(); - if (inst == NULL) { - return; - } - devMgrSvcIf = (struct IDevmgrService *)inst->devMgrSvcIf; - if (devMgrSvcIf != NULL && devMgrSvcIf->AcquireWakeLock != NULL) { - devMgrSvcIf->AcquireWakeLock(devMgrSvcIf, &stateToken->super); - } - - if (stateToken->state == POWER_STATE_INACTIVE || stateToken->state == POWER_STATE_IDLE) { + if (stateToken->psmState == PSM_STATE_INACTIVE || stateToken->psmState == PSM_STATE_IDLE) { const struct IPowerEventListener *listener = stateToken->listener; if ((listener != NULL) && (listener->Resume != NULL)) { listener->Resume(stateToken->deviceObject); } } - stateToken->state = POWER_STATE_ACTIVE; + stateToken->psmState = PSM_STATE_ACTIVE; } static void PowerStateTokenOnLastRelease(struct HdfSRef *sref) @@ -52,53 +42,40 @@ static void PowerStateTokenOnLastRelease(struct HdfSRef *sref) struct PowerStateToken *stateToken = (struct PowerStateToken *)HDF_SLIST_CONTAINER_OF( struct HdfSRef, sref, struct PowerStateToken, wakeRef); - if (stateToken->state != POWER_STATE_ACTIVE && stateToken->state != POWER_STATE_IDLE) { + if (stateToken->psmState != PSM_STATE_ACTIVE && stateToken->psmState != PSM_STATE_IDLE) { return; } - struct IDevmgrService *devMgrSvcIf = NULL; const struct IPowerEventListener *listener = stateToken->listener; - struct DevmgrServiceClnt *inst = DevmgrServiceClntGetInstance(); - if (inst == NULL) { - return; - } - - if (stateToken->state == POWER_STATE_ACTIVE) { - devMgrSvcIf = (struct IDevmgrService *)inst->devMgrSvcIf; - if ((devMgrSvcIf != NULL) && (devMgrSvcIf->AcquireWakeLock != NULL)) { - devMgrSvcIf->ReleaseWakeLock(devMgrSvcIf, &stateToken->super); - } - } - if ((listener != NULL) && (listener->Suspend != NULL)) { listener->Suspend(stateToken->deviceObject); } - stateToken->state = POWER_STATE_INACTIVE; + stateToken->psmState = PSM_STATE_INACTIVE; } -int PowerStateOnSysStateChange(struct PowerStateToken *stateToken, int32_t state) +int PowerStateChange(struct PowerStateToken *stateToken, uint32_t pEvent) { if (stateToken == NULL || stateToken->listener == NULL || stateToken->mode != HDF_POWER_SYS_CTRL) { return HDF_SUCCESS; } - switch (state) { - case KEVENT_POWER_SUSPEND: + switch (pEvent) { + case POWER_STATE_SUSPEND: if (stateToken->listener->Suspend != NULL) { return stateToken->listener->Suspend(stateToken->deviceObject); } break; - case KEVENT_POWER_RESUME: + case POWER_STATE_RESUME: if (stateToken->listener->Resume != NULL) { return stateToken->listener->Resume(stateToken->deviceObject); } break; - case KEVENT_POWER_DISPLAY_OFF: + case POWER_STATE_DOZE_SUSPEND: if (stateToken->listener->DozeSuspend != NULL) { return stateToken->listener->DozeSuspend(stateToken->deviceObject); } break; - case KEVENT_POWER_DISPLAY_ON: + case POWER_STATE_DOZE_RESUME: if (stateToken->listener->DozeResume != NULL) { return stateToken->listener->DozeResume(stateToken->deviceObject); } @@ -158,7 +135,7 @@ static int32_t PowerStateTokenConstruct(struct PowerStateToken *powerStateToken, srefListener->OnFirstAcquire = PowerStateTokenOnFirstAcquire; srefListener->OnLastRelease = PowerStateTokenOnLastRelease; - powerStateToken->state = POWER_STATE_IDLE; + powerStateToken->psmState = PSM_STATE_IDLE; powerStateToken->listener = listener; powerStateToken->deviceObject = deviceObject; HdfSRefConstruct(&powerStateToken->wakeRef, srefListener); diff --git a/core/manager/include/devhost_service_clnt.h b/core/manager/include/devhost_service_clnt.h index c80f3b1c1..cbc34d64a 100644 --- a/core/manager/include/devhost_service_clnt.h +++ b/core/manager/include/devhost_service_clnt.h @@ -14,7 +14,7 @@ #include "hdf_map.h" struct DevHostServiceClnt { - struct HdfSListNode node; + struct DListHead node; struct HdfSList devices; struct HdfSList *deviceInfos; Map *deviceHashMap; @@ -28,6 +28,6 @@ struct DevHostServiceClnt { int DevHostServiceClntInstallDriver(struct DevHostServiceClnt *hostClnt); struct DevHostServiceClnt *DevHostServiceClntNewInstance(uint16_t hostId, const char *hostName); void DevHostServiceClntFreeInstance(struct DevHostServiceClnt *hostClnt); -void DevHostServiceClntDelete(struct HdfSListNode *listEntry); +void DevHostServiceClntDelete(struct DevHostServiceClnt *hostClnt); #endif /* DEVHOST_SERVICE_CLNT_H */ diff --git a/core/manager/include/devmgr_service.h b/core/manager/include/devmgr_service.h index 1d255d189..56f0e02cc 100644 --- a/core/manager/include/devmgr_service.h +++ b/core/manager/include/devmgr_service.h @@ -10,12 +10,12 @@ #define DEVICE_MANAGER_SERVICE_H #include "devmgr_service_if.h" -#include "hdf_slist.h" +#include "hdf_dlist.h" #include "osal_mutex.h" struct DevmgrService { struct IDevmgrService super; - struct HdfSList hosts; + struct DListHead hosts; struct OsalMutex devMgrMutex; }; @@ -27,7 +27,5 @@ struct IDevmgrService *DevmgrServiceGetInstance(void); int DevmgrServiceLoadDevice(const char *svcName); int DevmgrServiceUnLoadDevice(const char *svcName); int32_t DevmgrServiceLoadLeftDriver(struct DevmgrService *devMgrSvc); -void DevmgrServiceAcquireWakeLock(struct IDevmgrService *inst, struct IPowerStateToken *tokenIf); -void DevmgrServiceReleaseWakeLock(struct IDevmgrService *inst, struct IPowerStateToken *tokenIf); #endif /* DEVICE_MANAGER_SERVICE_H */ diff --git a/core/manager/include/power_state_token_clnt.h b/core/manager/include/power_state_token_clnt.h index 1915a985e..64c2885ab 100644 --- a/core/manager/include/power_state_token_clnt.h +++ b/core/manager/include/power_state_token_clnt.h @@ -15,7 +15,7 @@ struct PowerStateTokenClnt { struct HdfSListNode entry; - HdfPowerState powerState; + HdfPsmState powerState; struct IPowerStateToken *tokenIf; }; diff --git a/core/manager/src/devhost_service_clnt.c b/core/manager/src/devhost_service_clnt.c index 490cf0405..43b4f1ca9 100644 --- a/core/manager/src/devhost_service_clnt.c +++ b/core/manager/src/devhost_service_clnt.c @@ -84,9 +84,8 @@ void DevHostServiceClntFreeInstance(struct DevHostServiceClnt *hostClnt) } } -void DevHostServiceClntDelete(struct HdfSListNode *listEntry) +void DevHostServiceClntDelete(struct DevHostServiceClnt *hostClnt) { - struct DevHostServiceClnt *hostClnt = (struct DevHostServiceClnt *)listEntry; if (hostClnt != NULL) { DevHostServiceClntFreeInstance(hostClnt); } diff --git a/core/manager/src/devmgr_service.c b/core/manager/src/devmgr_service.c index 545d8675a..da78d39e2 100644 --- a/core/manager/src/devmgr_service.c +++ b/core/manager/src/devmgr_service.c @@ -15,11 +15,11 @@ #include "hdf_host_info.h" #include "hdf_log.h" #include "hdf_object_manager.h" -#include "power_state_manager.h" #define HDF_LOG_TAG devmgr_service -static int DevmgrServiceActiveDevice(struct DevHostServiceClnt *hostClnt, struct HdfDeviceInfo *deviceInfo, bool isLoad) +static int DevmgrServiceActiveDevice(struct DevHostServiceClnt *hostClnt, + struct HdfDeviceInfo *deviceInfo, bool isLoad) { struct IDevHostService *devHostSvcIf = (struct IDevHostService *)hostClnt->hostService; if (devHostSvcIf == NULL) { @@ -43,7 +43,6 @@ static int DevmgrServiceActiveDevice(struct DevHostServiceClnt *hostClnt, struct static int DevmgrServiceFindAndActiveDevice(const char *svcName, bool isLoad) { - struct HdfSListIterator itHost; struct HdfSListIterator itDeviceInfo; struct HdfDeviceInfo *deviceInfo = NULL; struct DevHostServiceClnt *hostClnt = NULL; @@ -52,9 +51,7 @@ static int DevmgrServiceFindAndActiveDevice(const char *svcName, bool isLoad) return HDF_ERR_INVALID_PARAM; } - HdfSListIteratorInit(&itHost, &devMgrSvc->hosts); - while (HdfSListIteratorHasNext(&itHost)) { - hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost); + DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) { HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos); while (HdfSListIteratorHasNext(&itDeviceInfo)) { deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo); @@ -63,13 +60,13 @@ static int DevmgrServiceFindAndActiveDevice(const char *svcName, bool isLoad) } } } + return HDF_FAILURE; } int32_t DevmgrServiceLoadLeftDriver(struct DevmgrService *devMgrSvc) { int32_t ret; - struct HdfSListIterator itHost; struct HdfSListIterator itDeviceInfo; struct HdfDeviceInfo *deviceInfo = NULL; struct DevHostServiceClnt *hostClnt = NULL; @@ -77,9 +74,7 @@ int32_t DevmgrServiceLoadLeftDriver(struct DevmgrService *devMgrSvc) return HDF_FAILURE; } - HdfSListIteratorInit(&itHost, &devMgrSvc->hosts); - while (HdfSListIteratorHasNext(&itHost)) { - hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&itHost); + DLIST_FOR_EACH_ENTRY(hostClnt, &devMgrSvc->hosts, struct DevHostServiceClnt, node) { HdfSListIteratorInit(&itDeviceInfo, hostClnt->deviceInfos); while (HdfSListIteratorHasNext(&itDeviceInfo)) { deviceInfo = (struct HdfDeviceInfo *)HdfSListIteratorNext(&itDeviceInfo); @@ -106,16 +101,14 @@ int DevmgrServiceUnLoadDevice(const char *svcName) static struct DevHostServiceClnt *DevmgrServiceFindDeviceHost(struct IDevmgrService *inst, uint16_t hostId) { - struct HdfSListIterator it; struct DevHostServiceClnt *hostClnt = NULL; struct DevmgrService *dmService = (struct DevmgrService *)inst; if (dmService == NULL) { HDF_LOGE("failed to find device host, dmService is null"); return NULL; } - HdfSListIteratorInit(&it, &dmService->hosts); - while (HdfSListIteratorHasNext(&it)) { - hostClnt = (struct DevHostServiceClnt *)HdfSListIteratorNext(&it); + + DLIST_FOR_EACH_ENTRY(hostClnt, &dmService->hosts, struct DevHostServiceClnt, node) { if (hostClnt->hostId == hostId) { return hostClnt; } @@ -198,7 +191,7 @@ static int DevmgrServiceStartDeviceHosts(struct DevmgrService *inst) struct DevHostServiceClnt *hostClnt = NULL; struct IDriverInstaller *installer = NULL; installer = DriverInstallerGetInstance(); - if ((installer == NULL) || (installer->StartDeviceHost == NULL)) { + if (installer == NULL || installer->StartDeviceHost == NULL) { HDF_LOGE("installer or installer->StartDeviceHost is null"); return HDF_FAILURE; } @@ -215,11 +208,11 @@ static int DevmgrServiceStartDeviceHosts(struct DevmgrService *inst) HDF_LOGW("failed to create new device host client"); continue; } - HdfSListAdd(&inst->hosts, &hostClnt->node); + DListInsertTail(&hostClnt->node, &inst->hosts); hostClnt->hostPid = installer->StartDeviceHost(hostAttr->hostId, hostAttr->hostName); if (hostClnt->hostPid == HDF_FAILURE) { HDF_LOGW("failed to start device host, host id is %u", hostAttr->hostId); - HdfSListRemove(&inst->hosts, &hostClnt->node); + DListRemove(&hostClnt->node); DevHostServiceClntFreeInstance(hostClnt); } } @@ -237,6 +230,45 @@ int DevmgrServiceStartService(struct IDevmgrService *inst) return DevmgrServiceStartDeviceHosts(dmService); } +int DevmgrServicePowerStateChange(struct IDevmgrService *devmgrService, enum HdfPowerState powerState) +{ + struct DevHostServiceClnt *hostClient = NULL; + struct DevmgrService *devmgr = NULL; + int result = HDF_SUCCESS; + + if (devmgrService == NULL) { + return HDF_ERR_INVALID_OBJECT; + } + + if (!IsValidPowerState(powerState)) { + HDF_LOGE("%s:invalid power event %u", __func__, powerState); + return HDF_ERR_INVALID_PARAM; + } + devmgr = CONTAINER_OF(devmgrService, struct DevmgrService, super); + + if (IsPowerWakeState(powerState)) { + HDF_LOGI("%s:wake state %u", __func__, powerState); + DLIST_FOR_EACH_ENTRY(hostClient, &devmgr->hosts, struct DevHostServiceClnt, node) { + if (hostClient->hostService != NULL) { + if (hostClient->hostService->PmNotify(hostClient->hostService, powerState) != HDF_SUCCESS) { + result = HDF_FAILURE; + } + } + } + } else { + HDF_LOGI("%s:suspend state %u", __func__, powerState); + DLIST_FOR_EACH_ENTRY_REVERSE(hostClient, &devmgr->hosts, struct DevHostServiceClnt, node) { + if (hostClient->hostService != NULL) { + if (hostClient->hostService->PmNotify(hostClient->hostService, powerState) != HDF_SUCCESS) { + result = HDF_FAILURE; + } + } + } + } + + return result; +} + bool DevmgrServiceConstruct(struct DevmgrService *inst) { if (OsalMutexInit(&inst->devMgrMutex) != HDF_SUCCESS) { @@ -248,9 +280,8 @@ bool DevmgrServiceConstruct(struct DevmgrService *inst) devMgrSvcIf->AttachDevice = DevmgrServiceAttachDevice; devMgrSvcIf->AttachDeviceHost = DevmgrServiceAttachDeviceHost; devMgrSvcIf->StartService = DevmgrServiceStartService; - devMgrSvcIf->AcquireWakeLock = DevmgrServiceAcquireWakeLock; - devMgrSvcIf->ReleaseWakeLock = DevmgrServiceReleaseWakeLock; - HdfSListInit(&inst->hosts); + devMgrSvcIf->PowerStateChange = DevmgrServicePowerStateChange; + DListHeadInit(&inst->hosts); return true; } else { return false; @@ -285,24 +316,12 @@ void DevmgrServiceRelease(struct HdfObject *object) if (devmgrService == NULL) { return; } - HdfSListFlush(&devmgrService->hosts, DevHostServiceClntDelete); - OsalMutexDestroy(&devmgrService->devMgrMutex); -} - -void DevmgrServiceAcquireWakeLock(struct IDevmgrService *inst, struct IPowerStateToken *tokenIf) -{ - (void)inst; - struct PowerStateManager *stateManager = PowerStateManagerGetInstance(); - if ((stateManager != NULL) && (stateManager->AcquireWakeLock != NULL)) { - stateManager->AcquireWakeLock(stateManager, tokenIf); + struct DevHostServiceClnt *hostClnt = NULL; + struct DevHostServiceClnt *hostClntTmp = NULL; + DLIST_FOR_EACH_ENTRY_SAFE(hostClnt, hostClntTmp, &devmgrService->hosts, struct DevHostServiceClnt, node) { + DevHostServiceClntDelete(hostClnt); + DListRemove(&hostClnt->node); } -} -void DevmgrServiceReleaseWakeLock(struct IDevmgrService *inst, struct IPowerStateToken *tokenIf) -{ - (void)inst; - struct PowerStateManager *stateManager = PowerStateManagerGetInstance(); - if ((stateManager != NULL) && (stateManager->ReleaseWakeLock != NULL)) { - stateManager->ReleaseWakeLock(stateManager, tokenIf); - } + OsalMutexDestroy(&devmgrService->devMgrMutex); } diff --git a/core/manager/src/power_state_manager.c b/core/manager/src/power_state_manager.c deleted file mode 100644 index 29dcc7b1c..000000000 --- a/core/manager/src/power_state_manager.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. - * - * HDF is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * See the LICENSE file in the root of this repository for complete details. - */ - -#include "power_state_manager.h" -#include "hdf_object_manager.h" -#include "power_state_token_clnt.h" - -static struct PowerStateTokenClnt *PowerStateManagerGetStateTokenClnt( - struct PowerStateManager *inst, struct IPowerStateToken *tokenIf) -{ - struct HdfSListIterator it; - if (inst == NULL) { - return NULL; - } - HdfSListIteratorInit(&it, &inst->tokens); - while (HdfSListIteratorHasNext(&it)) { - struct PowerStateTokenClnt *tokenClnt = - (struct PowerStateTokenClnt *)HdfSListIteratorNext(&it); - if (tokenClnt->tokenIf == tokenIf) { - return tokenClnt; - } - } - return NULL; -} - -static void PowerStateManagerAcquireWakeLock( - struct PowerStateManager *inst, struct IPowerStateToken *tokenIf) -{ - if (inst == NULL) { - return; - } - struct HdfSRef *sref = &inst->wakeRef; - struct PowerStateTokenClnt *stateTokenClnt = PowerStateManagerGetStateTokenClnt(inst, tokenIf); - if (stateTokenClnt == NULL) { - return; - } - stateTokenClnt->powerState = POWER_STATE_ACTIVE; - if (sref->Acquire != NULL) { - sref->Acquire(sref); - } -} - -static void PowerStateManagerReleaseWakeLock( - struct PowerStateManager *inst, struct IPowerStateToken *tokenIf) -{ - struct HdfSRef *sref = NULL; - struct PowerStateTokenClnt *stateTokenClnt = PowerStateManagerGetStateTokenClnt(inst, tokenIf); - if (inst == NULL || stateTokenClnt == NULL) { - return; - } - stateTokenClnt->powerState = POWER_STATE_INACTIVE; - sref = &inst->wakeRef; - if (sref->Release != NULL) { - sref->Release(sref); - } -} - -static void PowerStateManagerConstruct(struct PowerStateManager *inst) -{ - static struct IHdfSRefListener wakeLockRefListener = { - .OnFirstAcquire = NULL, - .OnLastRelease = NULL, - }; - - inst->AcquireWakeLock = PowerStateManagerAcquireWakeLock; - inst->ReleaseWakeLock = PowerStateManagerReleaseWakeLock; - HdfSListInit(&inst->tokens); - HdfSRefConstruct(&inst->wakeRef, &wakeLockRefListener); -} - -struct PowerStateManager *PowerStateManagerGetInstance() -{ - static struct PowerStateManager powerStateManager = { 0 }; - if (powerStateManager.AcquireWakeLock == NULL) { - PowerStateManagerConstruct(&powerStateManager); - } - return &powerStateManager; -} diff --git a/core/manager/src/power_state_token_clnt.c b/core/manager/src/power_state_token_clnt.c index 31eedb881..7bf1abd4a 100644 --- a/core/manager/src/power_state_token_clnt.c +++ b/core/manager/src/power_state_token_clnt.c @@ -12,7 +12,7 @@ static void PowerStateTokenClntConstruct(struct PowerStateTokenClnt *clnt, struct IPowerStateToken *tokenIf) { clnt->tokenIf = tokenIf; - clnt->powerState = POWER_STATE_INACTIVE; + clnt->powerState = PSM_STATE_INACTIVE; } struct PowerStateTokenClnt *PowerStateTokenClntNewInstance(struct IPowerStateToken *tokenIf) diff --git a/core/manager/test/unittest/common/hdf_ioservice_test.cpp b/core/manager/test/unittest/common/hdf_ioservice_test.cpp index 9057d7beb..ce24f0fd3 100644 --- a/core/manager/test/unittest/common/hdf_ioservice_test.cpp +++ b/core/manager/test/unittest/common/hdf_ioservice_test.cpp @@ -18,6 +18,7 @@ #include "osal_time.h" #include "sample_driver_test.h" #include "hdf_log.h" +#include "hdf_power_state.h" using namespace testing::ext; @@ -596,3 +597,38 @@ HWTEST_F(IoServiceTest, HdfIoService012, TestSize.Level0) HdfIoServiceRecycle(serv); } + +/* * + * @tc.name: HdfIoService013 + * @tc.desc: devmgr power state change test + * @tc.type: FUNC + */ +HWTEST_F(IoServiceTest, HdfIoService013, TestSize.Level0) +{ + struct HdfSBuf *data = HdfSBufObtainDefaultSize(); + ASSERT_NE(data, nullptr); + + struct HdfIoService *serv = HdfIoServiceBind(testSvcName); + ASSERT_NE(serv, nullptr); + + HdfSbufWriteUint32(data, POWER_STATE_SUSPEND); + int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_DRIVER_PM_STATE_INJECT, data, NULL); + ASSERT_EQ(ret, HDF_SUCCESS); + + HdfSbufFlush(data); + HdfSbufWriteUint32(data, POWER_STATE_RESUME); + ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_DRIVER_PM_STATE_INJECT, data, NULL); + ASSERT_EQ(ret, HDF_SUCCESS); + + HdfSbufFlush(data); + HdfSbufWriteUint32(data, POWER_STATE_DOZE_SUSPEND); + ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_DRIVER_PM_STATE_INJECT, data, NULL); + ASSERT_EQ(ret, HDF_SUCCESS); + + HdfSbufFlush(data); + HdfSbufWriteUint32(data, POWER_STATE_DOZE_RESUME); + ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_DRIVER_PM_STATE_INJECT, data, NULL); + ASSERT_EQ(ret, HDF_SUCCESS); + HdfIoServiceRecycle(serv); + HdfSBufRecycle(data); +} diff --git a/core/shared/include/devhost_service_if.h b/core/shared/include/devhost_service_if.h index 83e9d21ac..a1c226915 100644 --- a/core/shared/include/devhost_service_if.h +++ b/core/shared/include/devhost_service_if.h @@ -14,9 +14,10 @@ struct IDevHostService { struct HdfObject object; - int (*AddDevice)(struct IDevHostService *, const struct HdfDeviceInfo *); - int (*DelDevice)(struct IDevHostService *, const struct HdfDeviceInfo *); - int (*StartService)(struct IDevHostService *); + int (*AddDevice)(struct IDevHostService *hostService, const struct HdfDeviceInfo *devInfo); + int (*DelDevice)(struct IDevHostService *hostService, const struct HdfDeviceInfo *devInfo); + int (*StartService)(struct IDevHostService *hostService); + int (*PmNotify)(struct IDevHostService *service, uint32_t powerState); }; #endif /* DEVHOST_SERVICE_IF_H */ diff --git a/core/shared/include/devmgr_service_if.h b/core/shared/include/devmgr_service_if.h index 136f2832a..55df8e426 100644 --- a/core/shared/include/devmgr_service_if.h +++ b/core/shared/include/devmgr_service_if.h @@ -13,6 +13,7 @@ #include "device_token_if.h" #include "hdf_object.h" #include "power_state_token_if.h" +#include "hdf_power_state.h" struct IDevmgrService { struct HdfObject base; @@ -20,8 +21,7 @@ struct IDevmgrService { int (*AttachDeviceHost)(struct IDevmgrService *, uint16_t, struct IDevHostService *); int (*AttachDevice)(struct IDevmgrService *, const struct HdfDeviceInfo *, struct IHdfDeviceToken *); int (*StartService)(struct IDevmgrService *); - void (*AcquireWakeLock)(struct IDevmgrService *, struct IPowerStateToken *); - void (*ReleaseWakeLock)(struct IDevmgrService *, struct IPowerStateToken *); + int (*PowerStateChange)(struct IDevmgrService *, enum HdfPowerState pEvent); }; #endif /* DEVMGR_SERVICE_IF_H */ diff --git a/core/manager/include/power_state_manager.h b/core/shared/include/hdf_power_state.h similarity index 34% rename from core/manager/include/power_state_manager.h rename to core/shared/include/hdf_power_state.h index 0cf87de32..d10557113 100644 --- a/core/manager/include/power_state_manager.h +++ b/core/shared/include/hdf_power_state.h @@ -6,20 +6,25 @@ * See the LICENSE file in the root of this repository for complete details. */ -#ifndef POWER_STATE_MANAGER_H -#define POWER_STATE_MANAGER_H +#ifndef HDF_POWER_STATE_H +#define HDF_POWER_STATE_H -#include "hdf_sref.h" -#include "hdf_slist.h" -#include "power_state_token_if.h" - -struct PowerStateManager { - struct HdfSRef wakeRef; - struct HdfSList tokens; - void (*AcquireWakeLock)(struct PowerStateManager *, struct IPowerStateToken *); - void (*ReleaseWakeLock)(struct PowerStateManager *, struct IPowerStateToken *); +enum HdfPowerState { + POWER_STATE_DOZE_RESUME, + POWER_STATE_DOZE_SUSPEND, + POWER_STATE_RESUME, + POWER_STATE_SUSPEND, + POWER_STATE_MAX, }; -struct PowerStateManager *PowerStateManagerGetInstance(void); +static inline bool IsPowerWakeState(uint32_t state) +{ + return state == POWER_STATE_DOZE_RESUME || state == POWER_STATE_RESUME; +} + +static inline bool IsValidPowerState(uint32_t state) +{ + return state < POWER_STATE_MAX; +} -#endif /* POWER_STATE_MANAGER_H */ \ No newline at end of file +#endif /* HDF_POWER_STATE_H */ \ No newline at end of file diff --git a/core/shared/include/power_state_token_if.h b/core/shared/include/power_state_token_if.h index fe828f1eb..0e054c01a 100644 --- a/core/shared/include/power_state_token_if.h +++ b/core/shared/include/power_state_token_if.h @@ -10,10 +10,10 @@ #define POWER_STATE_TOKEN_IF_H typedef enum { - POWER_STATE_IDLE, /* Idle state */ - POWER_STATE_ACTIVE, /* Activated state */ - POWER_STATE_INACTIVE, /* Error state */ -} HdfPowerState; + PSM_STATE_IDLE, /* Idle state */ + PSM_STATE_ACTIVE, /* Activated state */ + PSM_STATE_INACTIVE, /* Error state */ +} HdfPsmState; struct IPowerStateToken { void (*AcquireWakeLock)(struct IPowerStateToken *); diff --git a/include/core/hdf_pm.h b/include/core/hdf_pm.h index fbf6e3af4..1c8412fa4 100644 --- a/include/core/hdf_pm.h +++ b/include/core/hdf_pm.h @@ -1,10 +1,10 @@ -/* - * Copyright (c) 2020-2021 Huawei Device Co., Ltd. - * - * HDF is dual licensed: you can use it either under the terms of - * the GPL, or the BSD license, at your option. - * See the LICENSE file in the root of this repository for complete details. - */ +/* + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. + * + * HDF is dual licensed: you can use it either under the terms of + * the GPL, or the BSD license, at your option. + * See the LICENSE file in the root of this repository for complete details. + */ #ifndef HDF_POWER_MANAGEMENT_H #define HDF_POWER_MANAGEMENT_H @@ -34,11 +34,6 @@ struct IPowerEventListener { int (*Suspend)(struct HdfDeviceObject *deviceObject); }; -static inline bool HdfPmIsWakeEvent(int sysEvent) -{ - return sysEvent >= KEVENT_POWER_RESUME && sysEvent <= KEVENT_POWER_DISPLAY_ON; -} - int HdfPmRegisterPowerListener(struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener); void HdfPmUnregisterPowerListener(struct HdfDeviceObject *deviceObject, const struct IPowerEventListener *listener); void HdfPmAcquireDevice(struct HdfDeviceObject *deviceObject); diff --git a/include/utils/hdf_dlist.h b/include/utils/hdf_dlist.h index 369cb089f..196a4d2c8 100644 --- a/include/utils/hdf_dlist.h +++ b/include/utils/hdf_dlist.h @@ -143,6 +143,17 @@ static inline void DListMerge(struct DListHead *list, struct DListHead *head) DListHeadInit(list); } + +static inline int DlistGetCount(const struct DListHead *head) +{ + struct DListHead *next = head->next; + int count = 0; + while (next != head) { + next = next->next; + count++; + } + return count; +} /** * @brief Obtains the address of a structure variable from its member address. * diff --git a/test/unittest/manager/sample_driver_test.c b/test/unittest/manager/sample_driver_test.c index bf69825f9..f997f567e 100644 --- a/test/unittest/manager/sample_driver_test.c +++ b/test/unittest/manager/sample_driver_test.c @@ -7,8 +7,10 @@ */ #include "sample_driver_test.h" #include "devsvc_manager_clnt.h" +#include "devmgr_service.h" #include "hdf_log.h" #include "hdf_device_desc.h" +#include "hdf_pm.h" #define HDF_LOG_TAG sample_driver_test @@ -67,12 +69,22 @@ int32_t SampleDriverSendEvent(struct HdfDeviceIoClient *client, int id, struct H return broadcast ? HdfDeviceSendEvent(client->device, id, data) : HdfDeviceSendEventToClient(client, id, data); } +int32_t SampleDriverPowerStateInject(uint32_t powerState) +{ + struct IDevmgrService *devmgrService = DevmgrServiceGetInstance(); + int ret = devmgrService->PowerStateChange(devmgrService, powerState); + + HDF_LOGI("%s: inject power state(%d) done, ret = %d", __func__, powerState, ret); + return ret; +} + int32_t SampleDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct HdfSBuf *data, struct HdfSBuf *reply) { int32_t ret = HDF_SUCCESS; if (reply == NULL || client == NULL) { return HDF_FAILURE; } + uint32_t powerState = 0; switch (cmdId) { case SAMPLE_DRIVER_REGISTER_DEVICE: { ret = SampleDriverRegisterDevice(data); @@ -91,6 +103,9 @@ int32_t SampleDriverDispatch(struct HdfDeviceIoClient *client, int cmdId, struct ret = SampleDriverSendEvent(client, cmdId, data, true); HdfSbufWriteInt32(reply, INT32_MAX); break; + case SAMPLE_DRIVER_PM_STATE_INJECT: + HdfSbufReadUint32(data, &powerState); + return SampleDriverPowerStateInject(powerState); default: break; } @@ -113,14 +128,53 @@ int HdfSampleDriverBind(struct HdfDeviceObject *deviceObject) return HDF_SUCCESS; } +int HdfSampleDozeResume(struct HdfDeviceObject *deviceObject) +{ + HDF_LOGI("%s:called, object = %llx", __func__, (uint64_t)deviceObject); + return HDF_SUCCESS; +} + +int HdfSampleDozeSuspend(struct HdfDeviceObject *deviceObject) +{ + HDF_LOGI("%s:called, object = %llx", __func__, (uint64_t)deviceObject); + return HDF_SUCCESS; +} + +int HdfSampleResume(struct HdfDeviceObject *deviceObject) +{ + HDF_LOGI("%s:called, object = %llx", __func__, (uint64_t)deviceObject); + return HDF_SUCCESS; +} + +int HdfSampleSuspend(struct HdfDeviceObject *deviceObject) +{ + HDF_LOGI("%s:called, object = %llx", __func__, (uint64_t)deviceObject); + return HDF_SUCCESS; +} + +struct SampleDriverPmListener { + struct IPowerEventListener powerListener; + void *p; +}; + int HdfSampleDriverInit(struct HdfDeviceObject *deviceObject) { - HDF_LOGD("%s::enter!, deviceObject=%p", __func__, deviceObject); + HDF_LOGI("%s::enter!, deviceObject=%llx", __func__, (uint64_t)deviceObject); if (deviceObject == NULL) { HDF_LOGE("%s::ptr is null!", __func__); return HDF_FAILURE; } HDF_LOGD("%s:Init success", __func__); + + static struct SampleDriverPmListener pmListener = {0}; + pmListener.powerListener.DozeResume = HdfSampleDozeResume; + pmListener.powerListener.DozeSuspend = HdfSampleDozeSuspend; + pmListener.powerListener.Resume = HdfSampleResume; + pmListener.powerListener.Suspend = HdfSampleSuspend; + + int ret = HdfPmRegisterPowerListener(deviceObject, &pmListener.powerListener); + HDF_LOGI("%s:register power listener, ret = %d", __func__, ret); + return HDF_SUCCESS; } diff --git a/test/unittest/manager/sample_driver_test.h b/test/unittest/manager/sample_driver_test.h index 3241601bb..a2ce58f49 100644 --- a/test/unittest/manager/sample_driver_test.h +++ b/test/unittest/manager/sample_driver_test.h @@ -18,6 +18,7 @@ typedef enum { SAMPLE_DRIVER_UNREGISTER_DEVICE, SAMPLE_DRIVER_SENDEVENT_SINGLE_DEVICE, SAMPLE_DRIVER_SENDEVENT_BROADCAST_DEVICE, + SAMPLE_DRIVER_PM_STATE_INJECT, } SAMPLE_DRIVER_CMDID; struct HdfDeviceObject *GetDeviceObject(void); -- Gitee